Auto merge of #63408 - Centril:rollup-skqrez3, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #62672 (Deprecate `try!` macro)
 - #62950 (Check rustbook links on all platforms when running locally)
 - #63114 (Remove gensym in format_args)
 - #63397 (Add tests for some ICEs)
 - #63403 (Improve test output)
 - #63404 (enable flt2dec tests in Miri)
 - #63407 (reduce some test sizes in Miri)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-08-09 12:14:57 +00:00
commit 534b42394d
44 changed files with 538 additions and 99 deletions

View file

@ -9,7 +9,7 @@ use build_helper::t;
use crate::Mode;
use crate::Compiler;
use crate::builder::{Step, RunConfig, ShouldRun, Builder};
use crate::util::{exe, add_lib_path};
use crate::util::{exe, add_lib_path, CiEnv};
use crate::compile;
use crate::channel::GitInfo;
use crate::channel;
@ -279,11 +279,26 @@ pub fn prepare_tool_cargo(
cargo
}
fn rustbook_features() -> Vec<String> {
let mut features = Vec::new();
// Due to CI budged and risk of spurious failures we want to limit jobs running this check.
// At same time local builds should run it regardless of the platform.
// `CiEnv::None` means it's local build and `CHECK_LINKS` is defined in x86_64-gnu-tools to
// explicitly enable it on single job
if CiEnv::current() == CiEnv::None || env::var("CHECK_LINKS").is_ok() {
features.push("linkcheck".to_string());
}
features
}
macro_rules! bootstrap_tool {
($(
$name:ident, $path:expr, $tool_name:expr
$(,llvm_tools = $llvm:expr)*
$(,is_external_tool = $external:expr)*
$(,features = $features:expr)*
;
)+) => {
#[derive(Copy, PartialEq, Eq, Clone)]
@ -350,7 +365,12 @@ macro_rules! bootstrap_tool {
} else {
SourceType::InTree
},
extra_features: Vec::new(),
extra_features: {
// FIXME(#60643): avoid this lint by using `_`
let mut _tmp = Vec::new();
$(_tmp.extend($features);)*
_tmp
},
}).expect("expected to build -- essential tool")
}
}
@ -359,7 +379,7 @@ macro_rules! bootstrap_tool {
}
bootstrap_tool!(
Rustbook, "src/tools/rustbook", "rustbook";
Rustbook, "src/tools/rustbook", "rustbook", features = rustbook_features();
UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
Tidy, "src/tools/tidy", "tidy";
Linkchecker, "src/tools/linkchecker", "linkchecker";

View file

@ -21,6 +21,9 @@ COPY x86_64-gnu-tools/checkregression.py /tmp/
COPY x86_64-gnu-tools/checktools.sh /tmp/
COPY x86_64-gnu-tools/repo.sh /tmp/
# Run rustbook with `linkcheck` feature enabled
ENV CHECK_LINKS 1
ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
--save-toolstates=/tmp/toolstates.json

View file

@ -689,7 +689,10 @@ fn test_split_off_empty_left() {
#[test]
fn test_split_off_large_random_sorted() {
#[cfg(not(miri))] // Miri is too slow
let mut data = rand_data(1529);
#[cfg(miri)]
let mut data = rand_data(529);
// special case with maximum height.
data.sort();

View file

@ -10,7 +10,7 @@ fn test_clone_eq() {
m.insert(1);
m.insert(2);
assert!(m.clone() == m);
assert_eq!(m.clone(), m);
}
#[test]
@ -28,7 +28,7 @@ fn test_hash() {
y.insert(2);
y.insert(1);
assert!(hash(&x) == hash(&y));
assert_eq!(hash(&x), hash(&y));
}
fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
@ -69,6 +69,11 @@ fn test_intersection() {
check_intersection(&[11, 1, 3, 77, 103, 5, -5],
&[2, 11, 77, -9, -42, 5, 3],
&[3, 5, 11, 77]);
if cfg!(miri) { // Miri is too slow
return;
}
let large = (0..1000).collect::<Vec<_>>();
check_intersection(&[], &large, &[]);
check_intersection(&large, &[], &[]);
@ -98,6 +103,11 @@ fn test_difference() {
check_difference(&[-5, 11, 22, 33, 40, 42],
&[-12, -5, 14, 23, 34, 38, 39, 50],
&[11, 22, 33, 40, 42]);
if cfg!(miri) { // Miri is too slow
return;
}
let large = (0..1000).collect::<Vec<_>>();
check_difference(&[], &large, &[]);
check_difference(&[-1], &large, &[-1]);
@ -166,6 +176,17 @@ fn test_is_subset() {
assert_eq!(is_subset(&[1, 2], &[1]), false);
assert_eq!(is_subset(&[1, 2], &[1, 2]), true);
assert_eq!(is_subset(&[1, 2], &[2, 3]), false);
assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
&[-12, -5, 14, 23, 11, 34, 22, 38, 33, 42, 39, 40]),
true);
assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
&[-12, -5, 14, 23, 34, 38, 22, 11]),
false);
if cfg!(miri) { // Miri is too slow
return;
}
let large = (0..1000).collect::<Vec<_>>();
assert_eq!(is_subset(&[], &large), true);
assert_eq!(is_subset(&large, &[]), false);
@ -371,7 +392,10 @@ fn test_split_off_empty_left() {
#[test]
fn test_split_off_large_random_sorted() {
#[cfg(not(miri))] // Miri is too slow
let mut data = rand_data(1529);
#[cfg(miri)]
let mut data = rand_data(529);
// special case with maximum height.
data.sort();

View file

@ -302,6 +302,7 @@ macro_rules! debug_assert_ne {
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")]
#[doc(alias = "?")]
macro_rules! r#try {
($expr:expr) => (match $expr {
@ -767,7 +768,6 @@ pub(crate) mod builtin {
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(fmt_internals)]
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro format_args {
($fmt:expr) => ({ /* compiler built-in */ }),
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
@ -779,7 +779,6 @@ pub(crate) mod builtin {
language use and is subject to change")]
#[allow_internal_unstable(fmt_internals)]
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro format_args_nl {
($fmt:expr) => ({ /* compiler built-in */ }),
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })

View file

@ -77,6 +77,7 @@ fn infinity() {
fn zero() {
test_literal!(0.0);
test_literal!(1e-325);
#[cfg(not(miri))] // Miri is too slow
test_literal!(1e-326);
#[cfg(not(miri))] // Miri is too slow
test_literal!(1e-500);

View file

@ -42,7 +42,12 @@ fn test_estimate_scaling_factor() {
assert_almost_eq!(estimate_scaling_factor(1, -1074), -323);
assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309);
for i in -1074..972 {
#[cfg(not(miri))] // Miri is too slow
let iter = -1074..972;
#[cfg(miri)]
let iter = (-1074..972).step_by(37);
for i in iter {
let expected = super::ldexp_f64(1.0, i).log10().ceil();
assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
}

View file

@ -1,5 +1,3 @@
#![cfg(not(miri))] // Miri does not implement ldexp, which most tests here need
use std::prelude::v1::*;
use std::{str, i16, f32, f64, fmt};
@ -257,6 +255,7 @@ pub fn f32_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
check_shortest!(f(minf32) => b"1", -44);
}
#[cfg(not(miri))] // Miri is too slow
pub fn f32_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf32 = ldexp_f32(1.0, -149);
@ -362,6 +361,7 @@ pub fn f64_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
check_shortest!(f(minf64) => b"5", -323);
}
#[cfg(not(miri))] // Miri is too slow
pub fn f64_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf64 = ldexp_f64(1.0, -1074);
@ -553,6 +553,10 @@ pub fn to_shortest_str_test<F>(mut f_: F)
assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", ""));
assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", ""));
if cfg!(miri) { // Miri is too slow
return;
}
// very large output
assert_eq!(to_string(f, 1.1, Minus, 80000, false), format!("1.1{:0>79999}", ""));
}
@ -807,6 +811,10 @@ pub fn to_exact_exp_str_test<F>(mut f_: F)
"1.401298464324817070923729583289916131280261941876515771757068283\
8897910826858606014866381883621215820312500000000000000000000000e-45");
if cfg!(miri) { // Miri is too slow
return;
}
assert_eq!(to_string(f, f64::MAX, Minus, 1, false), "2e308");
assert_eq!(to_string(f, f64::MAX, Minus, 2, false), "1.8e308");
assert_eq!(to_string(f, f64::MAX, Minus, 4, false), "1.798e308");
@ -1040,6 +1048,10 @@ pub fn to_exact_fixed_str_test<F>(mut f_: F)
assert_eq!(to_string(f, f32::MAX, Minus, 2, false),
"340282346638528859811704183484516925440.00");
if cfg!(miri) { // Miri is too slow
return;
}
let minf32 = ldexp_f32(1.0, -149);
assert_eq!(to_string(f, minf32, Minus, 0, false), "0");
assert_eq!(to_string(f, minf32, Minus, 1, false), "0.0");

View file

@ -109,8 +109,13 @@ pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
#[test]
fn shortest_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
#[cfg(not(miri))] // Miri is too slow
const N: usize = 10_000;
#[cfg(miri)]
const N: usize = 10;
f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
}
#[test] #[ignore] // it is too expensive
@ -138,17 +143,27 @@ fn shortest_f64_hard_random_equivalence_test() {
#[test]
fn exact_f32_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
#[cfg(not(miri))] // Miri is too slow
const N: usize = 1_000;
#[cfg(miri)]
const N: usize = 3;
for k in 1..21 {
f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN), k, 1_000);
|d, buf| fallback(d, buf, i16::MIN), k, N);
}
}
#[test]
fn exact_f64_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
#[cfg(not(miri))] // Miri is too slow
const N: usize = 1_000;
#[cfg(miri)]
const N: usize = 3;
for k in 1..21 {
f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN), k, 1_000);
|d, buf| fallback(d, buf, i16::MIN), k, N);
}
}

View file

@ -23,6 +23,7 @@ fn shortest_sanity_test() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
fn exact_sanity_test() {
// This test ends up running what I can only assume is some corner-ish case
// of the `exp2` library function, defined in whatever C runtime we're

View file

@ -36,6 +36,7 @@ fn shortest_sanity_test() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
fn exact_sanity_test() {
// See comments in dragon.rs's exact_sanity_test for why this test is
// ignored on MSVC

View file

@ -3,19 +3,19 @@ use core::result::Result::{Ok, Err};
#[test]
fn test_position() {
let b = [1, 2, 3, 5, 5];
assert!(b.iter().position(|&v| v == 9) == None);
assert!(b.iter().position(|&v| v == 5) == Some(3));
assert!(b.iter().position(|&v| v == 3) == Some(2));
assert!(b.iter().position(|&v| v == 0) == None);
assert_eq!(b.iter().position(|&v| v == 9), None);
assert_eq!(b.iter().position(|&v| v == 5), Some(3));
assert_eq!(b.iter().position(|&v| v == 3), Some(2));
assert_eq!(b.iter().position(|&v| v == 0), None);
}
#[test]
fn test_rposition() {
let b = [1, 2, 3, 5, 5];
assert!(b.iter().rposition(|&v| v == 9) == None);
assert!(b.iter().rposition(|&v| v == 5) == Some(4));
assert!(b.iter().rposition(|&v| v == 3) == Some(2));
assert!(b.iter().rposition(|&v| v == 0) == None);
assert_eq!(b.iter().rposition(|&v| v == 9), None);
assert_eq!(b.iter().rposition(|&v| v == 5), Some(4));
assert_eq!(b.iter().rposition(|&v| v == 3), Some(2));
assert_eq!(b.iter().rposition(|&v| v == 0), None);
}
#[test]
@ -1153,7 +1153,7 @@ fn test_rotate_right() {
}
#[test]
#[cfg(not(miri))]
#[cfg(not(miri))] // Miri is too slow
fn brute_force_rotate_test_0() {
// In case of edge cases involving multiple algorithms
let n = 300;

View file

@ -2,7 +2,7 @@ use core::time::Duration;
#[test]
fn creation() {
assert!(Duration::from_secs(1) != Duration::from_secs(0));
assert_ne!(Duration::from_secs(1), Duration::from_secs(0));
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
Duration::from_secs(3));
assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),

View file

@ -14,8 +14,8 @@ pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
micro: 0,
_priv: (),
};
pub mod general_category {
pub const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
pub(crate) mod general_category {
const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
r1: &[
0, 1, 0
],
@ -28,7 +28,7 @@ pub mod general_category {
Cc_table.lookup(c)
}
pub const N_table: &super::BoolTrie = &super::BoolTrie {
const N_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x03ff000000000000, 0x0000000000000000, 0x720c000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@ -141,8 +141,8 @@ pub mod general_category {
}
pub mod derived_property {
pub const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
pub(crate) mod derived_property {
const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
@ -327,7 +327,7 @@ pub mod derived_property {
Alphabetic_table.lookup(c)
}
pub const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0400408000000000, 0x0000000140000000, 0x0190a10000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@ -464,7 +464,7 @@ pub mod derived_property {
Case_Ignorable_table.lookup(c)
}
pub const Cased_table: &super::BoolTrie = &super::BoolTrie {
const Cased_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xf7ffffffffffffff, 0xfffffffffffffff0,
@ -565,7 +565,7 @@ pub mod derived_property {
Cased_table.lookup(c)
}
pub const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@ -689,7 +689,7 @@ pub mod derived_property {
Grapheme_Extend_table.lookup(c)
}
pub const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000,
0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129, 0xaa29aaaab5555240,
@ -789,7 +789,7 @@ pub mod derived_property {
Lowercase_table.lookup(c)
}
pub const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x0000000007fffffe, 0x0000000000000000, 0x000000007f7fffff,
0xaa55555555555555, 0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490,
@ -890,7 +890,7 @@ pub mod derived_property {
Uppercase_table.lookup(c)
}
pub const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
@ -1068,7 +1068,7 @@ pub mod derived_property {
XID_Continue_table.lookup(c)
}
pub const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
@ -1250,8 +1250,8 @@ pub mod derived_property {
}
pub mod property {
pub const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
pub(crate) mod property {
const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
r1: &[
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -1268,7 +1268,7 @@ pub mod property {
Pattern_White_Space_table.lookup(c)
}
pub const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
r1: &[
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -1290,7 +1290,7 @@ pub mod property {
}
pub mod conversions {
pub(crate) mod conversions {
pub fn to_lower(c: char) -> [char; 3] {
match bsearch_case_table(c, to_lowercase_table) {
None => [c, '\0', '\0'],

View file

@ -606,7 +606,7 @@ def compute_trie(raw_data, chunk_size):
return root, child_data
def generate_bool_trie(name, codepoint_ranges, is_pub=True):
def generate_bool_trie(name, codepoint_ranges, is_pub=False):
# type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
"""
Generate Rust code for BoolTrie struct.
@ -681,7 +681,7 @@ def generate_bool_trie(name, codepoint_ranges, is_pub=True):
yield " };\n\n"
def generate_small_bool_trie(name, codepoint_ranges, is_pub=True):
def generate_small_bool_trie(name, codepoint_ranges, is_pub=False):
# type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
"""
Generate Rust code for `SmallBoolTrie` struct.
@ -726,7 +726,7 @@ def generate_property_module(mod, grouped_categories, category_subset):
Generate Rust code for module defining properties.
"""
yield "pub mod %s {\n" % mod
yield "pub(crate) mod %s {\n" % mod
for cat in sorted(category_subset):
if cat in ("Cc", "White_Space", "Pattern_White_Space"):
generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat])
@ -749,7 +749,7 @@ def generate_conversions_module(unicode_data):
Generate Rust code for module defining conversions.
"""
yield "pub mod conversions {"
yield "pub(crate) mod conversions {"
yield """
pub fn to_lower(c: char) -> [char; 3] {
match bsearch_case_table(c, to_lowercase_table) {

View file

@ -229,6 +229,13 @@ fn def_id_visibility<'tcx>(
let vis = match tcx.hir().get(hir_id) {
Node::Item(item) => &item.vis,
Node::ForeignItem(foreign_item) => &foreign_item.vis,
Node::MacroDef(macro_def) => {
if attr::contains_name(&macro_def.attrs, sym::macro_export) {
return (ty::Visibility::Public, macro_def.span, "public");
} else {
&macro_def.vis
}
},
Node::TraitItem(..) | Node::Variant(..) => {
return def_id_visibility(tcx, tcx.hir().get_parent_did(hir_id));
}
@ -433,11 +440,24 @@ impl VisibilityLike for Option<AccessLevel> {
struct EmbargoVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
// Accessibility levels for reachable nodes.
/// Accessibility levels for reachable nodes.
access_levels: AccessLevels,
// Previous accessibility level; `None` means unreachable.
/// A set of pairs corresponding to modules, where the first module is
/// reachable via a macro that's defined in the second module. This cannot
/// be represented as reachable because it can't handle the following case:
///
/// pub mod n { // Should be `Public`
/// pub(crate) mod p { // Should *not* be accessible
/// pub fn f() -> i32 { 12 } // Must be `Reachable`
/// }
/// }
/// pub macro m() {
/// n::p::f()
/// }
macro_reachable: FxHashSet<(hir::HirId, DefId)>,
/// Previous accessibility level; `None` means unreachable.
prev_level: Option<AccessLevel>,
// Has something changed in the level map?
/// Has something changed in the level map?
changed: bool,
}
@ -452,7 +472,7 @@ impl EmbargoVisitor<'tcx> {
self.access_levels.map.get(&id).cloned()
}
// Updates node level and returns the updated level.
/// Updates node level and returns the updated level.
fn update(&mut self, id: hir::HirId, level: Option<AccessLevel>) -> Option<AccessLevel> {
let old_level = self.get(id);
// Accessibility levels can only grow.
@ -477,6 +497,127 @@ impl EmbargoVisitor<'tcx> {
}
}
/// Updates the item as being reachable through a macro defined in the given
/// module. Returns `true` if the level has changed.
fn update_macro_reachable(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) -> bool {
if self.macro_reachable.insert((reachable_mod, defining_mod)) {
self.update_macro_reachable_mod(reachable_mod, defining_mod);
true
} else {
false
}
}
fn update_macro_reachable_mod(
&mut self,
reachable_mod: hir::HirId,
defining_mod: DefId,
) {
let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
let module = self.tcx.hir().get_module(module_def_id).0;
for item_id in &module.item_ids {
let hir_id = item_id.id;
let item_def_id = self.tcx.hir().local_def_id(hir_id);
if let Some(def_kind) = self.tcx.def_kind(item_def_id) {
let item = self.tcx.hir().expect_item(hir_id);
let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx);
self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
}
}
if let Some(exports) = self.tcx.module_exports(module_def_id) {
for export in exports {
if export.vis.is_accessible_from(defining_mod, self.tcx) {
if let Res::Def(def_kind, def_id) = export.res {
let vis = def_id_visibility(self.tcx, def_id).0;
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
self.update_macro_reachable_def(
hir_id,
def_kind,
vis,
defining_mod,
);
}
}
}
}
}
}
fn update_macro_reachable_def(
&mut self,
hir_id: hir::HirId,
def_kind: DefKind,
vis: ty::Visibility,
module: DefId,
) {
let level = Some(AccessLevel::Reachable);
if let ty::Visibility::Public = vis {
self.update(hir_id, level);
}
match def_kind {
// No type privacy, so can be directly marked as reachable.
DefKind::Const
| DefKind::Macro(_)
| DefKind::Static
| DefKind::TraitAlias
| DefKind::TyAlias => {
if vis.is_accessible_from(module, self.tcx) {
self.update(hir_id, level);
}
},
// We can't use a module name as the final segment of a path, except
// in use statements. Since re-export checking doesn't consider
// hygiene these don't need to be marked reachable. The contents of
// the module, however may be reachable.
DefKind::Mod => {
if vis.is_accessible_from(module, self.tcx) {
self.update_macro_reachable(hir_id, module);
}
}
DefKind::Struct | DefKind::Union => {
// While structs and unions have type privacy, their fields do
// not.
if let ty::Visibility::Public = vis {
let item = self.tcx.hir().expect_item(hir_id);
if let hir::ItemKind::Struct(ref struct_def, _)
| hir::ItemKind::Union(ref struct_def, _) = item.node
{
for field in struct_def.fields() {
let field_vis = ty::Visibility::from_hir(
&field.vis,
field.hir_id,
self.tcx,
);
if field_vis.is_accessible_from(module, self.tcx) {
self.reach(field.hir_id, level).ty();
}
}
} else {
bug!("item {:?} with DefKind {:?}", item, def_kind);
}
}
}
// These have type privacy, so are not reachable unless they're
// public
DefKind::AssocConst
| DefKind::AssocTy
| DefKind::AssocOpaqueTy
| DefKind::ConstParam
| DefKind::Ctor(_, _)
| DefKind::Enum
| DefKind::ForeignTy
| DefKind::Fn
| DefKind::OpaqueTy
| DefKind::Method
| DefKind::Trait
| DefKind::TyParam
| DefKind::Variant => (),
}
}
/// Given the path segments of a `ItemKind::Use`, then we need
/// to update the visibility of the intermediate use so that it isn't linted
@ -746,40 +887,21 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
return
}
let module_did = ty::DefIdTree::parent(
let macro_module_def_id = ty::DefIdTree::parent(
self.tcx,
self.tcx.hir().local_def_id(md.hir_id)
).unwrap();
let mut module_id = self.tcx.hir().as_local_hir_id(module_did).unwrap();
let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
let level = self.update(md.hir_id, level);
if level.is_none() {
let new_level = self.update(md.hir_id, level);
if new_level.is_none() {
return
}
loop {
let module = if module_id == hir::CRATE_HIR_ID {
&self.tcx.hir().krate().module
} else if let hir::ItemKind::Mod(ref module) =
self.tcx.hir().expect_item(module_id).node {
module
} else {
unreachable!()
};
for id in &module.item_ids {
self.update(id.id, level);
}
let def_id = self.tcx.hir().local_def_id(module_id);
if let Some(exports) = self.tcx.module_exports(def_id) {
for export in exports.iter() {
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.res.def_id()) {
self.update(hir_id, level);
}
}
}
if module_id == hir::CRATE_HIR_ID {
break
let changed_reachability = self.update_macro_reachable(module_id, macro_module_def_id);
if changed_reachability || module_id == hir::CRATE_HIR_ID {
break;
}
module_id = self.tcx.hir().get_parent_node(module_id);
}
@ -826,8 +948,13 @@ impl DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> { self.ev.tcx }
fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool {
if let Some(hir_id) = self.ev.tcx.hir().as_local_hir_id(def_id) {
if let ((ty::Visibility::Public, ..), _)
| (_, Some(AccessLevel::ReachableFromImplTrait))
= (def_id_visibility(self.tcx(), def_id), self.access_level)
{
self.ev.update(hir_id, self.access_level);
}
}
false
}
}
@ -1865,6 +1992,7 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, krate: CrateNum) -> &AccessLevels {
let mut visitor = EmbargoVisitor {
tcx,
access_levels: Default::default(),
macro_reachable: Default::default(),
prev_level: Some(AccessLevel::Public),
changed: false,
};

View file

@ -330,7 +330,11 @@ use prelude::v1::*;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::{unreachable, unimplemented, write, writeln, r#try, todo};
pub use core::{unreachable, unimplemented, write, writeln, todo};
// FIXME: change this to `#[allow(deprecated)]` when we update nightly compiler.
#[allow(deprecated_in_future)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::r#try;
#[allow(unused_imports)] // macros from `alloc` are not used on all platforms
#[macro_use]

View file

@ -645,7 +645,7 @@ impl<'a, 'b> Context<'a, 'b> {
let mut heads = Vec::with_capacity(self.args.len());
let names_pos: Vec<_> = (0..self.args.len())
.map(|i| self.ecx.ident_of(&format!("arg{}", i)).gensym())
.map(|i| ast::Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
.collect();
// First, build up the static array which will become our precompiled
@ -842,7 +842,7 @@ pub fn expand_preparsed_format_args(
let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect();
let mut macsp = ecx.call_site();
macsp = macsp.apply_mark(ecx.current_expansion.id);
macsp = macsp.with_ctxt(ecx.backtrace());
let msg = "format argument must be a string literal";
let fmt_sp = efmt.span;

View file

@ -1,5 +1,7 @@
// check-pass
#![allow(deprecated)]
pub type ParseResult<T> = Result<T, ()>;
pub enum Item<'a> {

View file

@ -0,0 +1,23 @@
#![feature(decl_macro)]
mod n {
pub struct B(pub(crate) p::C);
impl B {
pub fn new() -> Self {
B(p::C)
}
}
mod p {
pub struct C;
impl C {
pub fn foo(&self) -> i32 {
33
}
}
}
}
pub macro m() {
n::B::new().0.foo()
}

View file

@ -0,0 +1,11 @@
#![feature(decl_macro)]
mod n {
pub(crate) mod p {
pub fn f() -> i32 { 12 }
}
}
pub macro m() {
n::p::f()
}

View file

@ -0,0 +1,11 @@
#![feature(decl_macro)]
mod n {
pub static S: i32 = 57;
}
use n::S;
pub macro m() {
S
}

View file

@ -0,0 +1,11 @@
// Check that functions accessible through a field visible to a macro are
// considered reachable
// aux-build:nested-fn-macro.rs
// run-pass
extern crate nested_fn_macro;
fn main() {
assert_eq!(nested_fn_macro::m!(), 12);
}

View file

@ -0,0 +1,11 @@
// Check that functions visible to macros through paths with >2 segements are
// considered reachable
// aux-build:field-method-macro.rs
// run-pass
extern crate field_method_macro;
fn main() {
assert_eq!(field_method_macro::m!(), 33);
}

View file

@ -0,0 +1,21 @@
// Check that we don't require stability annotations for private modules,
// imports and fields that are accessible to opaque macros.
// check-pass
#![feature(decl_macro, staged_api)]
#![stable(feature = "test", since = "1.0.0")]
extern crate std as local_std;
use local_std::marker::Copy as LocalCopy;
mod private_mod {
#[stable(feature = "test", since = "1.0.0")]
pub struct A {
pub(crate) f: i32,
}
}
#[stable(feature = "test", since = "1.0.0")]
pub macro m() {}
fn main() {}

View file

@ -0,0 +1,19 @@
// Check that type privacy is taken into account when considering reachability
// check-pass
#![feature(decl_macro, staged_api)]
#![stable(feature = "test", since = "1.0.0")]
// Type privacy should prevent use of these in other crates, so we shouldn't
// need a stability annotation.
fn private_function() {}
struct PrivateStruct { f: () }
enum PrivateEnum { V }
union PrivateUnion { g: () }
trait PrivateTrait {}
#[stable(feature = "test", since = "1.0.0")]
pub macro m() {}
fn main() {}

View file

@ -0,0 +1,10 @@
// Check that private use statements can be used by
// run-pass
// aux-build:private-use-macro.rs
extern crate private_use_macro;
fn main() {
assert_eq!(private_use_macro::m!(), 57);
}

View file

@ -1,5 +1,6 @@
// Test that the resolve failure does not lead to downstream type errors.
// See issue #31997.
#![allow(deprecated)]
trait TheTrait { }

View file

@ -1,5 +1,5 @@
error[E0425]: cannot find function `bar` in this scope
--> $DIR/issue-31997.rs:13:21
--> $DIR/issue-31997.rs:14:21
|
LL | try!(closure(|| bar(core::ptr::null_mut())));
| ^^^ not found in this scope

View file

@ -1,8 +0,0 @@
// run-pass
#![allow(non_upper_case_globals)]
pub const arg0: u8 = 1;
pub fn main() {
format!("{}", 1);
}

View file

@ -0,0 +1,12 @@
// check-pass
#![allow(non_upper_case_globals)]
#![feature(format_args_nl)]
static arg0: () = ();
fn main() {
static arg1: () = ();
format_args!("{} {:?}", 0, 1);
format_args_nl!("{} {:?}", 0, 1);
}

View file

@ -0,0 +1,19 @@
pub trait Trait<'a> {
type Assoc;
}
pub struct Type;
impl<'a> Trait<'a> for Type {
type Assoc = ();
}
pub fn break_me<T, F>(f: F)
where T: for<'b> Trait<'b>,
F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
break_me::<Type, fn(_)>;
//~^ ERROR: type mismatch in function arguments
//~| ERROR: type mismatch resolving
}
fn main() {}

View file

@ -0,0 +1,42 @@
error[E0631]: type mismatch in function arguments
--> $DIR/issue-43623.rs:14:5
|
LL | break_me::<Type, fn(_)>;
| ^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
| found signature of `fn(_) -> _`
|
note: required by `break_me`
--> $DIR/issue-43623.rs:11:1
|
LL | / pub fn break_me<T, F>(f: F)
LL | | where T: for<'b> Trait<'b>,
LL | | F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
LL | | break_me::<Type, fn(_)>;
LL | |
LL | |
LL | | }
| |_^
error[E0271]: type mismatch resolving `for<'b> <fn(_) as std::ops::FnOnce<(<Type as Trait<'b>>::Assoc,)>>::Output == ()`
--> $DIR/issue-43623.rs:14:5
|
LL | break_me::<Type, fn(_)>;
| ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
|
note: required by `break_me`
--> $DIR/issue-43623.rs:11:1
|
LL | / pub fn break_me<T, F>(f: F)
LL | | where T: for<'b> Trait<'b>,
LL | | F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
LL | | break_me::<Type, fn(_)>;
LL | |
LL | |
LL | | }
| |_^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0271`.

View file

@ -0,0 +1,22 @@
use std::ops::Index;
struct Test;
struct Container(Test);
impl Test {
fn test(&mut self) {}
}
impl<'a> Index<&'a bool> for Container {
type Output = Test;
fn index(&self, _index: &'a bool) -> &Test {
&self.0
}
}
fn main() {
let container = Container(Test);
let mut val = true;
container[&mut val].test(); //~ ERROR: cannot borrow data
}

View file

@ -0,0 +1,11 @@
error[E0596]: cannot borrow data in an index of `Container` as mutable
--> $DIR/issue-44405.rs:21:5
|
LL | container[&mut val].test();
| ^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Container`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,4 +1,5 @@
#![deny(unused_qualifications)]
#[allow(deprecated)]
mod foo {
pub fn bar() {}

View file

@ -1,5 +1,5 @@
error: unnecessary qualification
--> $DIR/lint-qualification.rs:9:5
--> $DIR/lint-qualification.rs:10:5
|
LL | foo::bar();
| ^^^^^^^^

View file

@ -15,6 +15,7 @@
#![cfg_attr(core, no_std)]
#![allow(deprecated)] // for deprecated `try!()` macro
#![feature(concat_idents)]
#[cfg(std)] use std::fmt;

View file

@ -1,4 +1,5 @@
// run-pass
#![allow(deprecated)] // for deprecated `try!()` macro
use std::num::{ParseFloatError, ParseIntError};
fn main() {

View file

@ -6,6 +6,7 @@
#![warn(rust_2018_compatibility)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(deprecated)]
fn foo() -> Result<usize, ()> {
let x: Result<usize, ()> = Ok(22);

View file

@ -6,6 +6,7 @@
#![warn(rust_2018_compatibility)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(deprecated)]
fn foo() -> Result<usize, ()> {
let x: Result<usize, ()> = Ok(22);

View file

@ -1,5 +1,5 @@
warning: `try` is a keyword in the 2018 edition
--> $DIR/try-macro.rs:12:5
--> $DIR/try-macro.rs:13:5
|
LL | try!(x);
| ^^^ help: you can use a raw identifier to stay compatible: `r#try`

View file

@ -5,14 +5,15 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
edition = "2018"
[features]
linkcheck = ["mdbook-linkcheck"]
[dependencies]
clap = "2.25.0"
failure = "0.1"
mdbook-linkcheck = { version = "0.3.0", optional = true }
[dependencies.mdbook]
version = "0.3.0"
default-features = false
features = ["search"]
[target.'cfg(all(target_arch = "x86_64", target_os = "linux"))'.dependencies]
mdbook-linkcheck = "0.3.0"

View file

@ -8,10 +8,9 @@ use clap::{App, ArgMatches, SubCommand, AppSettings};
use mdbook::MDBook;
use mdbook::errors::{Result as Result3};
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
#[cfg(feature = "linkcheck")]
use mdbook::renderer::RenderContext;
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
#[cfg(feature = "linkcheck")]
use mdbook_linkcheck::{self, errors::BrokenLinks};
use failure::Error;
@ -52,7 +51,7 @@ fn main() {
if let Err(err) = linkcheck(sub_matches) {
eprintln!("Error: {}", err);
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
#[cfg(feature = "linkcheck")]
{
if let Ok(broken_links) = err.downcast::<BrokenLinks>() {
for cause in broken_links.links().iter() {
@ -68,7 +67,7 @@ fn main() {
};
}
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
#[cfg(feature = "linkcheck")]
pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
let book_dir = get_book_dir(args);
let book = MDBook::load(&book_dir).unwrap();
@ -78,9 +77,9 @@ pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
mdbook_linkcheck::check_links(&render_ctx)
}
#[cfg(not(all(target_arch = "x86_64", target_os = "linux")))]
#[cfg(not(feature = "linkcheck"))]
pub fn linkcheck(_args: &ArgMatches<'_>) -> Result<(), Error> {
println!("mdbook-linkcheck only works on x86_64 linux targets.");
println!("mdbook-linkcheck is disabled.");
Ok(())
}