From c0f0f457b8e6723a6e3d1e29a6aa91a36edfc169 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 5 Jan 2019 12:55:30 +0100 Subject: [PATCH 01/25] Don't actually create a full MIR stack frame when not needed --- src/librustc_mir/const_eval.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index b9432997b7e19..947b94b61da8f 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -68,12 +68,36 @@ pub fn mk_eval_cx<'a, 'tcx>( debug!("mk_eval_cx: {:?}, {:?}", instance, param_env); let span = tcx.def_span(instance.def_id()); let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new()); - let mir = ecx.load_mir(instance.def)?; + let mir = mir::Mir::new( + ::std::iter::once( + mir::BasicBlockData { + statements: Vec::new(), + is_cleanup: false, + terminator: Some(mir::Terminator { + source_info: mir::SourceInfo { + scope: mir::OUTERMOST_SOURCE_SCOPE, + span: DUMMY_SP, + }, + kind: mir::TerminatorKind::Return, + }), + } + ).collect(), // basic blocks + IndexVec::new(), // source_scopes + mir::ClearCrossCrate::Clear, // source_scope_local_data + IndexVec::new(), // promoted + None, // yield ty + ::std::iter::once(mir::LocalDecl::new_return_place(tcx.types.unit, DUMMY_SP)).collect(), + IndexVec::new(), //user_type_annotations + 0, // arg_count + Vec::new(), // upvar_decls + DUMMY_SP, // span + Vec::new(), // control_flow_destroyed + ); // insert a stack frame so any queries have the correct substs ecx.push_stack_frame( instance, - mir.span, - mir, + span, + tcx.alloc_mir(mir), None, StackPopCleanup::Goto(None), // never pop )?; From ddff2ed649340fc07d3f6a3357c85b61d4b22b5f Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Sun, 6 Jan 2019 15:33:11 +0900 Subject: [PATCH 02/25] Remove unnecessary adapter --- src/libcore/fmt/mod.rs | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index ec1aeb8a7d1e9..bb6f511acf7e5 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -191,29 +191,8 @@ pub trait Write { /// assert_eq!(&buf, "world"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - fn write_fmt(&mut self, args: Arguments) -> Result { - // This Adapter is needed to allow `self` (of type `&mut - // Self`) to be cast to a Write (below) without - // requiring a `Sized` bound. - struct Adapter<'a,T: ?Sized +'a>(&'a mut T); - - impl Write for Adapter<'_, T> - where T: Write - { - fn write_str(&mut self, s: &str) -> Result { - self.0.write_str(s) - } - - fn write_char(&mut self, c: char) -> Result { - self.0.write_char(c) - } - - fn write_fmt(&mut self, args: Arguments) -> Result { - self.0.write_fmt(args) - } - } - - write(&mut Adapter(self), args) + fn write_fmt(mut self: &mut Self, args: Arguments) -> Result { + write(&mut self, args) } } From f67124245cc24babd0345347a77089ba698acd14 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Sun, 6 Jan 2019 15:33:42 +0900 Subject: [PATCH 03/25] Derive Clone for ArgumentV1 manual impl was a workaround for #28229. --- src/libcore/fmt/mod.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index bb6f511acf7e5..0127277d9cfc8 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -247,7 +247,7 @@ struct Void { /// family of functions. It contains a function to format the given value. At /// compile time it is ensured that the function and the value have the correct /// types, and then this struct is used to canonicalize arguments to one type. -#[derive(Copy)] +#[derive(Copy, Clone)] #[allow(missing_debug_implementations)] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")] @@ -257,14 +257,6 @@ pub struct ArgumentV1<'a> { formatter: fn(&Void, &mut Formatter) -> Result, } -#[unstable(feature = "fmt_internals", reason = "internal to format_args!", - issue = "0")] -impl Clone for ArgumentV1<'_> { - fn clone(&self) -> Self { - *self - } -} - impl<'a> ArgumentV1<'a> { #[inline(never)] fn show_usize(x: &usize, f: &mut Formatter) -> Result { From 6e742dbb3f5f9dde10dda8ba1930e03a0f057b5e Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 6 Jan 2019 01:02:55 +1100 Subject: [PATCH 04/25] Optimise floating point `is_finite` (2x) and `is_infinite` (1.6x). These can both rely on IEEE754 semantics to be made faster, by folding away the sign with an abs (left private for now), and then comparing to infinity, letting the NaN semantics of a direct float comparison handle NaN input properly. The `abs` bit-fiddling is simple (a single and), and so these new forms compile down to a few instructions, without branches, e.g. for f32: ```asm is_infinite: andps xmm0, xmmword ptr [rip + .LCPI2_0] ; 0x7FFF_FFFF ucomiss xmm0, dword ptr [rip + .LCPI2_1] ; 0x7F80_0000 setae al ret is_finite: andps xmm0, xmmword ptr [rip + .LCPI1_0] ; 0x7FFF_FFFF movss xmm1, dword ptr [rip + .LCPI1_1] ; 0x7F80_0000 ucomiss xmm1, xmm0 seta al ret ``` When used in loops/repeatedly, they get even better: the memory operations (loading the mask 0x7FFFFFFF for abs, and infinity 0x7F80_0000) are likely to be hoisted out of the individual calls, to be shared, and the `seta`/`setae` are likely to be collapsed into conditional jumps or moves (or similar). The old `is_infinite` did two comparisons, and the old `is_finite` did three (with a branch), and both of them had to check the flags after every one of those comparison. These functions have had that old implementation since they were added in https://github.com/rust-lang/rust/commit/6284190ef9918e05cb9147a2a81100ddcb06fea8 7 years ago. Benchmark (`abs` is the new form, `std` is the old): ``` test f32_is_finite_abs ... bench: 55 ns/iter (+/- 10) test f32_is_finite_std ... bench: 118 ns/iter (+/- 5) test f32_is_infinite_abs ... bench: 53 ns/iter (+/- 1) test f32_is_infinite_std ... bench: 84 ns/iter (+/- 6) test f64_is_finite_abs ... bench: 52 ns/iter (+/- 12) test f64_is_finite_std ... bench: 128 ns/iter (+/- 25) test f64_is_infinite_abs ... bench: 54 ns/iter (+/- 5) test f64_is_infinite_std ... bench: 93 ns/iter (+/- 23) ``` ```rust #![feature(test)] extern crate test; use std::{f32, f64}; use test::Bencher; const VALUES_F32: &[f32] = &[0.910, 0.135, 0.735, -0.874, 0.518, 0.150, -0.527, -0.418, 0.449, -0.158, -0.064, -0.144, -0.948, -0.103, 0.225, -0.104, -0.795, 0.435, 0.860, 0.027, 0.625, -0.848, -0.454, 0.359, -0.930, 0.067, 0.642, 0.976, -0.682, -0.035, 0.750, 0.005, -0.825, 0.731, -0.850, -0.740, -0.118, -0.972, 0.888, -0.958, 0.086, 0.237, -0.580, 0.488, 0.028, -0.552, 0.302, 0.058, -0.229, -0.166, -0.248, -0.430, 0.789, -0.122, 0.120, -0.934, -0.911, -0.976, 0.882, -0.410, 0.311, -0.611, -0.758, 0.786, -0.711, 0.378, 0.803, -0.068, 0.932, 0.483, 0.085, 0.247, -0.128, -0.839, -0.737, -0.605, 0.637, -0.230, -0.502, 0.231, -0.694, -0.400, -0.441, 0.142, 0.174, 0.681, -0.763, -0.608, 0.848, -0.550, 0.883, -0.212, 0.876, 0.186, -0.909, 0.401, -0.533, -0.961, 0.539, -0.298, -0.448, 0.223, -0.307, -0.594, 0.629, -0.534, 0.959, 0.349, -0.926, -0.523, -0.895, -0.157, -0.074, -0.060, 0.513, -0.647, -0.649, 0.428, 0.401, 0.391, 0.426, 0.700, 0.880, -0.101, 0.862, 0.493, 0.819, -0.597]; #[bench] fn f32_is_infinite_std(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F32).iter().any(|x| x.is_infinite())); } #[bench] fn f32_is_infinite_abs(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F32).iter().any(|x| x.abs()== f32::INFINITY)); } #[bench] fn f32_is_finite_std(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F32).iter().all(|x| x.is_finite())); } #[bench] fn f32_is_finite_abs(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F32).iter().all(|x| x.abs() < f32::INFINITY)); } const VALUES_F64: &[f64] = &[0.910, 0.135, 0.735, -0.874, 0.518, 0.150, -0.527, -0.418, 0.449, -0.158, -0.064, -0.144, -0.948, -0.103, 0.225, -0.104, -0.795, 0.435, 0.860, 0.027, 0.625, -0.848, -0.454, 0.359, -0.930, 0.067, 0.642, 0.976, -0.682, -0.035, 0.750, 0.005, -0.825, 0.731, -0.850, -0.740, -0.118, -0.972, 0.888, -0.958, 0.086, 0.237, -0.580, 0.488, 0.028, -0.552, 0.302, 0.058, -0.229, -0.166, -0.248, -0.430, 0.789, -0.122, 0.120, -0.934, -0.911, -0.976, 0.882, -0.410, 0.311, -0.611, -0.758, 0.786, -0.711, 0.378, 0.803, -0.068, 0.932, 0.483, 0.085, 0.247, -0.128, -0.839, -0.737, -0.605, 0.637, -0.230, -0.502, 0.231, -0.694, -0.400, -0.441, 0.142, 0.174, 0.681, -0.763, -0.608, 0.848, -0.550, 0.883, -0.212, 0.876, 0.186, -0.909, 0.401, -0.533, -0.961, 0.539, -0.298, -0.448, 0.223, -0.307, -0.594, 0.629, -0.534, 0.959, 0.349, -0.926, -0.523, -0.895, -0.157, -0.074, -0.060, 0.513, -0.647, -0.649, 0.428, 0.401, 0.391, 0.426, 0.700, 0.880, -0.101, 0.862, 0.493, 0.819, -0.597]; #[bench] fn f64_is_infinite_std(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F64).iter().any(|x| x.is_infinite())); } #[bench] fn f64_is_infinite_abs(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F64).iter().any(|x| x.abs() == f64::INFINITY)); } #[bench] fn f64_is_finite_std(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F64).iter().all(|x| x.is_finite())); } #[bench] fn f64_is_finite_abs(b: &mut Bencher) { b.iter(|| test::black_box(VALUES_F64).iter().all(|x| x.abs() < f64::INFINITY)); } ``` --- src/libcore/num/f32.rs | 14 ++++++++++++-- src/libcore/num/f64.rs | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index d1bd97552024d..68da79135d3a3 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -161,6 +161,14 @@ impl f32 { self != self } + // FIXME(#50145): `abs` is publicly unavailable in libcore due to + // concerns about portability, so this implementation is for + // private use internally. + #[inline] + fn abs_private(self) -> f32 { + f32::from_bits(self.to_bits() & 0x7fff_ffff) + } + /// Returns `true` if this value is positive infinity or negative infinity and /// false otherwise. /// @@ -181,7 +189,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_infinite(self) -> bool { - self == INFINITY || self == NEG_INFINITY + self.abs_private() == INFINITY } /// Returns `true` if this number is neither infinite nor `NaN`. @@ -203,7 +211,9 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_finite(self) -> bool { - !(self.is_nan() || self.is_infinite()) + // There's no need to handle NaN separately: if self is NaN, + // the comparison is not true, exactly as desired. + self.abs_private() < INFINITY } /// Returns `true` if the number is neither zero, infinite, diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 8ada5b6756c38..b677391548146 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -161,6 +161,14 @@ impl f64 { self != self } + // FIXME(#50145): `abs` is publicly unavailable in libcore due to + // concerns about portability, so this implementation is for + // private use internally. + #[inline] + fn abs_private(self) -> f64 { + f64::from_bits(self.to_bits() & 0x7fff_ffff_ffff_ffff) + } + /// Returns `true` if this value is positive infinity or negative infinity and /// false otherwise. /// @@ -181,7 +189,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_infinite(self) -> bool { - self == INFINITY || self == NEG_INFINITY + self.abs_private() == INFINITY } /// Returns `true` if this number is neither infinite nor `NaN`. @@ -203,7 +211,9 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_finite(self) -> bool { - !(self.is_nan() || self.is_infinite()) + // There's no need to handle NaN separately: if self is NaN, + // the comparison is not true, exactly as desired. + self.abs_private() < INFINITY } /// Returns `true` if the number is neither zero, infinite, From 6a790d3786f4a4d499991ad4bc52f9eba1771728 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 8 Jan 2019 02:32:14 +0900 Subject: [PATCH 05/25] Improve the wording --- src/librustc_typeck/coherence/orphan.rs | 2 +- src/test/ui/coherence/coherence-cow.re_a.stderr | 2 +- src/test/ui/coherence/coherence-cow.re_b.stderr | 2 +- src/test/ui/coherence/coherence-cow.re_c.stderr | 2 +- .../coherence-fundamental-trait-objects.old.stderr | 2 +- .../coherence-fundamental-trait-objects.re.stderr | 2 +- src/test/ui/coherence/coherence-impls-copy.old.stderr | 8 ++++---- src/test/ui/coherence/coherence-impls-copy.re.stderr | 8 ++++---- src/test/ui/coherence/coherence-impls-send.old.stderr | 6 +++--- src/test/ui/coherence/coherence-impls-send.re.stderr | 6 +++--- src/test/ui/coherence/coherence-impls-sized.old.stderr | 6 +++--- src/test/ui/coherence/coherence-impls-sized.re.stderr | 6 +++--- src/test/ui/coherence/coherence-orphan.old.stderr | 4 ++-- src/test/ui/coherence/coherence-orphan.re.stderr | 4 ++-- .../ui/coherence/coherence-overlapping-pairs.re.stderr | 2 +- .../coherence-pair-covered-uncovered-1.re.stderr | 2 +- .../coherence/coherence-pair-covered-uncovered.re.stderr | 2 +- src/test/ui/coherence/coherence-vec-local-2.re.stderr | 2 +- src/test/ui/coherence/coherence-vec-local.old.stderr | 2 +- src/test/ui/coherence/coherence-vec-local.re.stderr | 2 +- .../ui/coherence/coherence_local_err_struct.old.stderr | 2 +- .../ui/coherence/coherence_local_err_struct.re.stderr | 2 +- .../ui/coherence/coherence_local_err_tuple.old.stderr | 2 +- src/test/ui/coherence/coherence_local_err_tuple.re.stderr | 2 +- src/test/ui/dropck/drop-on-non-struct.stderr | 2 +- src/test/ui/error-codes/E0117.stderr | 2 +- src/test/ui/error-codes/E0206.stderr | 2 +- ...typeck-default-trait-impl-cross-crate-coherence.stderr | 6 +++--- 28 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 54e4a86cc4ec5..2df137c3f5094 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -40,7 +40,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { "only traits defined in the current crate can be \ implemented for arbitrary types") .span_label(sp, "impl doesn't use types inside crate") - .note("the impl does not reference any types defined in this crate") + .note("the impl does not reference only types defined in this crate") .note("define and implement a trait or new type instead") .emit(); return; diff --git a/src/test/ui/coherence/coherence-cow.re_a.stderr b/src/test/ui/coherence/coherence-cow.re_a.stderr index ed627600b0f5d..b0ec55a9bc578 100644 --- a/src/test/ui/coherence/coherence-cow.re_a.stderr +++ b/src/test/ui/coherence/coherence-cow.re_a.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for Pair> { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-cow.re_b.stderr b/src/test/ui/coherence/coherence-cow.re_b.stderr index 1a85887ae7bc4..ce2611270938d 100644 --- a/src/test/ui/coherence/coherence-cow.re_b.stderr +++ b/src/test/ui/coherence/coherence-cow.re_b.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for Pair,T> { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-cow.re_c.stderr b/src/test/ui/coherence/coherence-cow.re_c.stderr index 8043b6702b07e..1c2030d8dfea8 100644 --- a/src/test/ui/coherence/coherence-cow.re_c.stderr +++ b/src/test/ui/coherence/coherence-cow.re_c.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for Pair,U> { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr b/src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr index 756ab2b102b56..2d1247e831ec4 100644 --- a/src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr +++ b/src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Misc for dyn Fundamental {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr b/src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr index 756ab2b102b56..2d1247e831ec4 100644 --- a/src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr +++ b/src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Misc for dyn Fundamental {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-impls-copy.old.stderr b/src/test/ui/coherence/coherence-impls-copy.old.stderr index defbbbadd5598..e870c267ce141 100644 --- a/src/test/ui/coherence/coherence-impls-copy.old.stderr +++ b/src/test/ui/coherence/coherence-impls-copy.old.stderr @@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for i32 {} | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -60,7 +60,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -69,7 +69,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -78,7 +78,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 10 previous errors diff --git a/src/test/ui/coherence/coherence-impls-copy.re.stderr b/src/test/ui/coherence/coherence-impls-copy.re.stderr index defbbbadd5598..e870c267ce141 100644 --- a/src/test/ui/coherence/coherence-impls-copy.re.stderr +++ b/src/test/ui/coherence/coherence-impls-copy.re.stderr @@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for i32 {} | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -60,7 +60,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -69,7 +69,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -78,7 +78,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 10 previous errors diff --git a/src/test/ui/coherence/coherence-impls-send.old.stderr b/src/test/ui/coherence/coherence-impls-send.old.stderr index ca45c28ec2d74..3ede8363d119e 100644 --- a/src/test/ui/coherence/coherence-impls-send.old.stderr +++ b/src/test/ui/coherence/coherence-impls-send.old.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | unsafe impl Send for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static NotSync` @@ -19,7 +19,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | unsafe impl Send for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -28,7 +28,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | unsafe impl Send for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 4 previous errors diff --git a/src/test/ui/coherence/coherence-impls-send.re.stderr b/src/test/ui/coherence/coherence-impls-send.re.stderr index ca45c28ec2d74..3ede8363d119e 100644 --- a/src/test/ui/coherence/coherence-impls-send.re.stderr +++ b/src/test/ui/coherence/coherence-impls-send.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | unsafe impl Send for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static NotSync` @@ -19,7 +19,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | unsafe impl Send for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -28,7 +28,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | unsafe impl Send for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 4 previous errors diff --git a/src/test/ui/coherence/coherence-impls-sized.old.stderr b/src/test/ui/coherence/coherence-impls-sized.old.stderr index c9c7dd0ed6688..86a0996554d41 100644 --- a/src/test/ui/coherence/coherence-impls-sized.old.stderr +++ b/src/test/ui/coherence/coherence-impls-sized.old.stderr @@ -40,7 +40,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Sized for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -49,7 +49,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Sized for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -58,7 +58,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Sized for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 9 previous errors diff --git a/src/test/ui/coherence/coherence-impls-sized.re.stderr b/src/test/ui/coherence/coherence-impls-sized.re.stderr index c9c7dd0ed6688..86a0996554d41 100644 --- a/src/test/ui/coherence/coherence-impls-sized.re.stderr +++ b/src/test/ui/coherence/coherence-impls-sized.re.stderr @@ -40,7 +40,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Sized for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -49,7 +49,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Sized for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -58,7 +58,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Sized for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 9 previous errors diff --git a/src/test/ui/coherence/coherence-orphan.old.stderr b/src/test/ui/coherence/coherence-orphan.old.stderr index da5de461bf41b..e6dc17d95a241 100644 --- a/src/test/ui/coherence/coherence-orphan.old.stderr +++ b/src/test/ui/coherence/coherence-orphan.old.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl TheTrait for isize { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -13,7 +13,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl !Send for Vec { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/coherence-orphan.re.stderr b/src/test/ui/coherence/coherence-orphan.re.stderr index da5de461bf41b..e6dc17d95a241 100644 --- a/src/test/ui/coherence/coherence-orphan.re.stderr +++ b/src/test/ui/coherence/coherence-orphan.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl TheTrait for isize { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -13,7 +13,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl !Send for Vec { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.re.stderr b/src/test/ui/coherence/coherence-overlapping-pairs.re.stderr index 0f2ec6f4ce069..a6fa609deb214 100644 --- a/src/test/ui/coherence/coherence-overlapping-pairs.re.stderr +++ b/src/test/ui/coherence/coherence-overlapping-pairs.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for lib::Pair { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr index 0c654ca41835d..e45cd78363ca7 100644 --- a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote1>> for i32 { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr index 9bddc15390212..54d5f3058a85c 100644 --- a/src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for Pair> { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-vec-local-2.re.stderr b/src/test/ui/coherence/coherence-vec-local-2.re.stderr index 37859f7cfa285..6992aa7a0bdc6 100644 --- a/src/test/ui/coherence/coherence-vec-local-2.re.stderr +++ b/src/test/ui/coherence/coherence-vec-local-2.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for Vec> { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-vec-local.old.stderr b/src/test/ui/coherence/coherence-vec-local.old.stderr index 304aaaf36875c..b35e7a8ba8bed 100644 --- a/src/test/ui/coherence/coherence-vec-local.old.stderr +++ b/src/test/ui/coherence/coherence-vec-local.old.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for Vec { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-vec-local.re.stderr b/src/test/ui/coherence/coherence-vec-local.re.stderr index 304aaaf36875c..b35e7a8ba8bed 100644 --- a/src/test/ui/coherence/coherence-vec-local.re.stderr +++ b/src/test/ui/coherence/coherence-vec-local.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Remote for Vec { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence_local_err_struct.old.stderr b/src/test/ui/coherence/coherence_local_err_struct.old.stderr index 61c94c1c7cad7..e1f651493f67c 100644 --- a/src/test/ui/coherence/coherence_local_err_struct.old.stderr +++ b/src/test/ui/coherence/coherence_local_err_struct.old.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl lib::MyCopy for lib::MyStruct { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence_local_err_struct.re.stderr b/src/test/ui/coherence/coherence_local_err_struct.re.stderr index 61c94c1c7cad7..e1f651493f67c 100644 --- a/src/test/ui/coherence/coherence_local_err_struct.re.stderr +++ b/src/test/ui/coherence/coherence_local_err_struct.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl lib::MyCopy for lib::MyStruct { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence_local_err_tuple.old.stderr b/src/test/ui/coherence/coherence_local_err_tuple.old.stderr index 934e2fcb890e3..171daa54861fe 100644 --- a/src/test/ui/coherence/coherence_local_err_tuple.old.stderr +++ b/src/test/ui/coherence/coherence_local_err_tuple.old.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl lib::MyCopy for (MyType,) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence_local_err_tuple.re.stderr b/src/test/ui/coherence/coherence_local_err_tuple.re.stderr index 934e2fcb890e3..171daa54861fe 100644 --- a/src/test/ui/coherence/coherence_local_err_tuple.re.stderr +++ b/src/test/ui/coherence/coherence_local_err_tuple.re.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl lib::MyCopy for (MyType,) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to previous error diff --git a/src/test/ui/dropck/drop-on-non-struct.stderr b/src/test/ui/dropck/drop-on-non-struct.stderr index c458635040a21..6b670d5d434e4 100644 --- a/src/test/ui/dropck/drop-on-non-struct.stderr +++ b/src/test/ui/dropck/drop-on-non-struct.stderr @@ -10,7 +10,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl<'a> Drop for &'a mut isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr index 8e32db49cedee..b007ca05ab2cf 100644 --- a/src/test/ui/error-codes/E0117.stderr +++ b/src/test/ui/error-codes/E0117.stderr @@ -10,7 +10,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Drop for u32 {} //~ ERROR E0117 | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0206.stderr b/src/test/ui/error-codes/E0206.stderr index 499c6ae3f8852..a0c4b0149a099 100644 --- a/src/test/ui/error-codes/E0206.stderr +++ b/src/test/ui/error-codes/E0206.stderr @@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Copy for Foo { } | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 3 previous errors diff --git a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr index b8b743d3f4072..2bfb4110603f5 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl DefaultedTrait for (A,) { } //~ ERROR E0117 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types @@ -13,7 +13,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl !DefaultedTrait for (B,) { } //~ ERROR E0117 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `lib::DefaultedTrait`, can only be implemented for a struct/enum type defined in the current crate @@ -28,7 +28,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl DefaultedTrait for lib::Something { } //~ ERROR E0117 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error: aborting due to 4 previous errors From eed163e11042c197c3e6aff65b1011abe1ca3980 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 7 Jan 2019 23:55:55 +0100 Subject: [PATCH 06/25] save-analysis: use a fallback when access levels couldn't be computed --- src/librustc_save_analysis/dump_visitor.rs | 6 +++--- src/librustc_save_analysis/lib.rs | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 891537309177e..0c9e443efe0db 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -14,7 +14,7 @@ //! recording the output. use rustc::hir::def::Def as HirDef; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def_id::DefId; use rustc::session::config::Input; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashSet; @@ -56,14 +56,14 @@ macro_rules! access_from { ($save_ctxt:expr, $vis:expr, $id:expr) => { Access { public: $vis.node.is_pub(), - reachable: $save_ctxt.tcx.privacy_access_levels(LOCAL_CRATE).is_reachable($id), + reachable: $save_ctxt.access_levels.is_reachable($id), } }; ($save_ctxt:expr, $item:expr) => { Access { public: $item.vis.node.is_pub(), - reachable: $save_ctxt.tcx.privacy_access_levels(LOCAL_CRATE).is_reachable($item.id), + reachable: $save_ctxt.access_levels.is_reachable($item.id), } }; } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d5b3070372ba5..13ecc6b8a956f 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -35,11 +35,13 @@ use rustc::hir; use rustc::hir::def::Def as HirDef; use rustc::hir::Node; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::middle::privacy::AccessLevels; use rustc::middle::cstore::ExternCrate; use rustc::session::config::{CrateType, Input, OutputType}; use rustc::ty::{self, TyCtxt}; use rustc_typeck::hir_ty_to_ty; use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; +use rustc_data_structures::sync::Lrc; use std::cell::Cell; use std::default::Default; @@ -68,6 +70,7 @@ use rls_data::config::Config; pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, tables: &'l ty::TypeckTables<'tcx>, + access_levels: &'l AccessLevels, analysis: &'l ty::CrateAnalysis, span_utils: SpanUtils<'tcx>, config: Config, @@ -1126,10 +1129,18 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( info!("Dumping crate {}", cratename); + // Privacy checking requires and is done after type checking; use a + // fallback in case the access levels couldn't have been correctly computed. + let access_levels = match tcx.sess.compile_status() { + Ok(..) => tcx.privacy_access_levels(LOCAL_CRATE), + Err(..) => Lrc::new(AccessLevels::default()), + }; + let save_ctxt = SaveContext { tcx, tables: &ty::TypeckTables::empty(None), analysis, + access_levels: &access_levels, span_utils: SpanUtils::new(&tcx.sess), config: find_config(config), impl_counter: Cell::new(0), From 14e662d8c56c54b6c04256cdf202e6636c96516b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 8 Jan 2019 10:54:24 +0100 Subject: [PATCH 07/25] Manually push a stack frame where no valid frame is needed --- src/librustc_mir/const_eval.rs | 47 +++++++++------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 947b94b61da8f..8a93328659eec 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -43,6 +43,16 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( ) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> { debug!("mk_borrowck_eval_cx: {:?}", instance); let param_env = tcx.param_env(instance.def_id()); + mk_eval_cx_inner(tcx, instance, mir, span, param_env) +} + +fn mk_eval_cx_inner<'a, 'mir, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + instance: Instance<'tcx>, + mir: &'mir mir::Mir<'tcx>, + span: Span, + param_env: ty::ParamEnv<'tcx>, +) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> { let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new()); // insert a stack frame so any queries have the correct substs // cannot use `push_stack_frame`; if we do `const_prop` explodes @@ -67,41 +77,8 @@ pub fn mk_eval_cx<'a, 'tcx>( ) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'tcx, 'tcx>> { debug!("mk_eval_cx: {:?}, {:?}", instance, param_env); let span = tcx.def_span(instance.def_id()); - let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new()); - let mir = mir::Mir::new( - ::std::iter::once( - mir::BasicBlockData { - statements: Vec::new(), - is_cleanup: false, - terminator: Some(mir::Terminator { - source_info: mir::SourceInfo { - scope: mir::OUTERMOST_SOURCE_SCOPE, - span: DUMMY_SP, - }, - kind: mir::TerminatorKind::Return, - }), - } - ).collect(), // basic blocks - IndexVec::new(), // source_scopes - mir::ClearCrossCrate::Clear, // source_scope_local_data - IndexVec::new(), // promoted - None, // yield ty - ::std::iter::once(mir::LocalDecl::new_return_place(tcx.types.unit, DUMMY_SP)).collect(), - IndexVec::new(), //user_type_annotations - 0, // arg_count - Vec::new(), // upvar_decls - DUMMY_SP, // span - Vec::new(), // control_flow_destroyed - ); - // insert a stack frame so any queries have the correct substs - ecx.push_stack_frame( - instance, - span, - tcx.alloc_mir(mir), - None, - StackPopCleanup::Goto(None), // never pop - )?; - Ok(ecx) + let mir = tcx.optimized_mir(instance.def.def_id()); + mk_eval_cx_inner(tcx, instance, mir, span, param_env) } pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( From cea282bcfda7bf47a95eae7be822467a97d0a9b2 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 8 Jan 2019 10:54:40 +0100 Subject: [PATCH 08/25] Make `mk_eval_cx` private to const eval --- src/librustc_mir/const_eval.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 8a93328659eec..6f464030b331d 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -70,7 +70,7 @@ fn mk_eval_cx_inner<'a, 'mir, 'tcx>( Ok(ecx) } -pub fn mk_eval_cx<'a, 'tcx>( +fn mk_eval_cx<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, param_env: ty::ParamEnv<'tcx>, From d9ddc39052c91568936427e3dee087b608140cf4 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 8 Jan 2019 13:19:50 -0800 Subject: [PATCH 09/25] lldb_batchmode.py: try `import _thread` for Python 3 --- src/etc/lldb_batchmode.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py index 6b4c44806740f..537b419b3279f 100644 --- a/src/etc/lldb_batchmode.py +++ b/src/etc/lldb_batchmode.py @@ -18,10 +18,15 @@ import os import sys import threading -import thread import re import time +try: + import thread +except ModuleNotFoundError: + # The `thread` module was renamed to `_thread` in Python 3. + import _thread as thread + # Set this to True for additional output DEBUG_OUTPUT = False From 12ae3651f891d22f804c67923d02cbdfa10fa60d Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Sun, 6 Jan 2019 15:36:14 +0900 Subject: [PATCH 10/25] Misc cleanups --- src/libcore/fmt/mod.rs | 12 ++++++------ src/libcore/str/pattern.rs | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 0127277d9cfc8..214b5d3a84f24 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1076,7 +1076,7 @@ impl<'a> Formatter<'a> { self.args[i].as_usize() } rt::v1::Count::NextParam => { - self.curarg.next().and_then(|arg| arg.as_usize()) + self.curarg.next()?.as_usize() } } } @@ -1142,15 +1142,15 @@ impl<'a> Formatter<'a> { sign = Some('+'); width += 1; } - let mut prefixed = false; - if self.alternate() { - prefixed = true; width += prefix.chars().count(); + let prefixed = self.alternate(); + if prefixed { + width += prefix.chars().count(); } // Writes the sign if it exists, and then the prefix if it was requested let write_prefix = |f: &mut Formatter| { if let Some(c) = sign { - f.buf.write_str(c.encode_utf8(&mut [0; 4]))?; + f.buf.write_char(c)?; } if prefixed { f.buf.write_str(prefix) } else { Ok(()) } @@ -1312,7 +1312,7 @@ impl<'a> Formatter<'a> { // remove the sign from the formatted parts formatted.sign = b""; - width = if width < sign.len() { 0 } else { width - sign.len() }; + width = width.saturating_sub(sign.len()); align = rt::v1::Alignment::Right; self.fill = '0'; self.align = rt::v1::Alignment::Right; diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index b4eae4d1bb742..55a7ba181e527 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -425,8 +425,7 @@ impl<'a> Pattern<'a> for char { #[inline] fn into_searcher(self, haystack: &'a str) -> Self::Searcher { let mut utf8_encoded = [0; 4]; - self.encode_utf8(&mut utf8_encoded); - let utf8_size = self.len_utf8(); + let utf8_size = self.encode_utf8(&mut utf8_encoded).len(); CharSearcher { haystack, finger: 0, From 46fa818d3443d4a62cd97be086d4d7a416b2d03e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 9 Jan 2019 15:16:19 +1100 Subject: [PATCH 11/25] Change `String` to `&'static str` in `ParseResult::Failure`. This avoids 770,000 allocations when compiling the `html5ever` benchmark, reducing instruction counts by up to 2%. --- src/libsyntax/ext/tt/macro_parser.rs | 6 +++--- src/libsyntax/ext/tt/macro_rules.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index d55f785bd9b4b..b4003ac729add 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -271,7 +271,7 @@ pub enum ParseResult { Success(T), /// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected /// end of macro invocation. Otherwise, it indicates that no rules expected the given token. - Failure(syntax_pos::Span, Token, String), + Failure(syntax_pos::Span, Token, &'static str), /// Fatal error (malformed macro?). Abort compilation. Error(syntax_pos::Span, String), } @@ -721,7 +721,7 @@ pub fn parse( sess.source_map().next_point(parser.span) }, token::Eof, - "missing tokens in macro arguments".to_string(), + "missing tokens in macro arguments", ); } } @@ -760,7 +760,7 @@ pub fn parse( return Failure( parser.span, parser.token, - "no rules expected this token in macro call".to_string(), + "no rules expected this token in macro call", ); } // Dump all possible `next_items` into `cur_items` for the next iteration. diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index cb8fbce66978b..24202ca8fbdc0 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -202,7 +202,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, let best_fail_msg = parse_failure_msg(best_fail_tok.expect("ran no matchers")); let span = best_fail_spot.substitute_dummy(sp); let mut err = cx.struct_span_err(span, &best_fail_msg); - err.span_label(span, best_fail_text.unwrap_or(best_fail_msg)); + err.span_label(span, best_fail_text.unwrap_or(&best_fail_msg)); if let Some(sp) = def_span { if cx.source_map().span_to_filename(sp).is_real() && !sp.is_dummy() { err.span_label(cx.source_map().def_span(sp), "when calling this macro"); From f174b73cafae574f62e5d890bdfc74835774b1f2 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 9 Jan 2019 16:08:07 +0100 Subject: [PATCH 12/25] Document the `mk_*_eval_cx` functions --- src/librustc_mir/const_eval.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 6f464030b331d..9b62743e9c64c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -35,6 +35,8 @@ const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000; /// Should be a power of two for performance reasons. const DETECTOR_SNAPSHOT_PERIOD: isize = 256; +/// Warning: do not use this function if you expect to start interpreting the given `Mir`. +/// The `EvalContext` is only meant to be used to query values from constants and statics. pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, @@ -46,6 +48,8 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( mk_eval_cx_inner(tcx, instance, mir, span, param_env) } +/// This is just a helper function to reduce code duplication between `mk_borrowck_eval_cx` and +/// `mk_eval_cx`. Do not call this function directly. fn mk_eval_cx_inner<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, @@ -54,8 +58,9 @@ fn mk_eval_cx_inner<'a, 'mir, 'tcx>( param_env: ty::ParamEnv<'tcx>, ) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> { let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new()); - // insert a stack frame so any queries have the correct substs - // cannot use `push_stack_frame`; if we do `const_prop` explodes + // Insert a stack frame so any queries have the correct substs. + // We also avoid all the extra work performed by push_stack_frame, + // like initializing local variables ecx.stack.push(interpret::Frame { block: mir::START_BLOCK, locals: IndexVec::new(), @@ -70,6 +75,9 @@ fn mk_eval_cx_inner<'a, 'mir, 'tcx>( Ok(ecx) } +/// Warning: do not use this function if you expect to start interpreting the given `Mir`. +/// The `EvalContext` is only meant to be used to do field and index projections into constants for +/// `simd_shuffle` and const patterns in match arms. fn mk_eval_cx<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, From cd5a9e04da9a2a76e79dde90c394cd0b7c570a42 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 9 Jan 2019 16:27:33 +0100 Subject: [PATCH 13/25] Explain the arguments of the `mk_*_eval_cx` functions --- src/librustc_mir/const_eval.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 9b62743e9c64c..594496fe9722c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -37,6 +37,14 @@ const DETECTOR_SNAPSHOT_PERIOD: isize = 256; /// Warning: do not use this function if you expect to start interpreting the given `Mir`. /// The `EvalContext` is only meant to be used to query values from constants and statics. +/// +/// This function is used during const propagation. We cannot use `mk_eval_cx`, because copy +/// propagation happens *during* the computation of the MIR of the current function. So if we +/// tried to call the `optimized_mir` query, we'd get a cycle error because we are (transitively) +/// inside the `optimized_mir` query of the `Instance` given. +/// +/// Since we are looking at the MIR of the function in an abstract manner, we don't have a +/// `ParamEnv` available to us. This function creates a `ParamEnv` for the given instance. pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, @@ -78,6 +86,11 @@ fn mk_eval_cx_inner<'a, 'mir, 'tcx>( /// Warning: do not use this function if you expect to start interpreting the given `Mir`. /// The `EvalContext` is only meant to be used to do field and index projections into constants for /// `simd_shuffle` and const patterns in match arms. +/// +/// The function containing the `match` that is currently being analyzed may have generic bounds +/// that inform us about the generic bounds of the constant. E.g. using an associated constant +/// of a function's generic parameter will require knowledge about the bounds on the generic +/// parameter. fn mk_eval_cx<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, From dec79e44705992d607b001cd349c98807761d3d8 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 9 Jan 2019 16:34:31 +0100 Subject: [PATCH 14/25] Not seeing the forest because there are too many trees in the way --- src/librustc_mir/const_eval.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 594496fe9722c..d79e0a817eeed 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -90,7 +90,7 @@ fn mk_eval_cx_inner<'a, 'mir, 'tcx>( /// The function containing the `match` that is currently being analyzed may have generic bounds /// that inform us about the generic bounds of the constant. E.g. using an associated constant /// of a function's generic parameter will require knowledge about the bounds on the generic -/// parameter. +/// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument. fn mk_eval_cx<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, From c47ed149b2efe537822632c11d0675bdfb3d790c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 9 Jan 2019 17:31:16 +0100 Subject: [PATCH 15/25] save-analysis: Get path def from parent in case there's no def for the path itself. This fixes #57462. The relevant part from the hir type collector is: ``` DEBUG 2019-01-09T15:42:58Z: rustc::hir::map::collector: hir_map: NodeId(32) => Entry { parent: NodeId(33), dep_node: 4294967040, node: Expr(expr(32: ::new)) } DEBUG 2019-01-09T15:42:58Z: rustc::hir::map::collector: hir_map: NodeId(48) => Entry { parent: NodeId(32), dep_node: 4294967040, node: Ty(type(Foo)) } DEBUG 2019-01-09T15:42:58Z: rustc::hir::map::collector: hir_map: NodeId(30) => Entry { parent: NodeId(48), dep_node: 4294967040, node: PathSegment(PathSegment { ident: Foo#0, id: Some(NodeId(30)), def: Some(Err), args: None, infer_types: true }) } DEBUG 2019-01-09T15:42:58Z: rustc::hir::map::collector: hir_map: NodeId(31) => Entry { parent: NodeId(32), dep_node: 4294967040, node: PathSegment(PathSegment { ident: new#0, id: Some(NodeId(31)), def: Some(Err), args: None, infer_types: true }) } ``` We have the right ID when looking for NodeId(31) and try with NodeId(32) (which is the right thing to look for) from get_path_data, but not for the segments that we write from `write_sub_paths_truncated`. Basically `process_path` takes an id which is always the parent, and that we fall back to in `get_path_data()`, so we get the right result for the last path segment, but not for the other segments that get written to from `write_sub_paths_truncated`. I think we can stop passing the explicit id around to `get_path_data` now, will consider sending that as a followup. --- src/librustc_save_analysis/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d5b3070372ba5..00431f86cf588 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -622,9 +622,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Node::Visibility(&Spanned { node: hir::VisibilityKind::Restricted { ref path, .. }, .. }) => path.def, - Node::PathSegment(seg) => match seg.def { - Some(def) => def, - None => HirDef::Err, + Node::PathSegment(seg) => { + match seg.def { + Some(def) if def != HirDef::Err => def, + _ => self.get_path_def(self.tcx.hir().get_parent_node(id)), + } }, Node::Expr(&hir::Expr { node: hir::ExprKind::Struct(ref qpath, ..), From bbb5448de447eeef2eae09a6df93553a6d1ccac7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 9 Jan 2019 09:35:09 -0800 Subject: [PATCH 16/25] std: Render large exit codes as hex on Windows On Windows process exit codes are never signals but rather always 32-bit integers. Most faults like segfaults and such end up having large integers used to represent them, like STATUS_ACCESS_VIOLATION being 0xC0000005. Currently, however, when an `ExitStatus` is printed this ends up getting rendered as 3221225477 which is somewhat more difficult to debug. This commit adds a branch in `Display for ExitStatus` on Windows which handles exit statuses where the high bit is set and prints those exit statuses as hex instead of with decimals. This will hopefully preserve the current display for small exit statuses (like `exit code: 22`), but assist in quickly debugging segfaults/access violations/etc. I've found at least that the hex codes are easier to search for than decimal. I wasn't able to find any official documentation saying that all system exit codes have the high bit set, but I figure it's a good enough heuristic for now. --- src/libstd/sys/windows/process.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 06c58659c08ae..08a166bd8c504 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -393,7 +393,16 @@ impl From for ExitStatus { impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "exit code: {}", self.0) + // Windows exit codes with the high bit set typically mean some form of + // unhandled exception or warning. In this scenario printing the exit + // code in decimal doesn't always make sense because it's a very large + // and somewhat gibberish number. The hex code is a bit more + // recognizable and easier to search for, so print that. + if self.0 & 0x80000000 != 0 { + write!(f, "exit code: {:#x}", self.0) + } else { + write!(f, "exit code: {}", self.0) + } } } From 07600c939b594b39f560bc969caca2e92498435a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 9 Jan 2019 18:40:30 +0100 Subject: [PATCH 17/25] Drop "solved" constraints during region expansion Once a region has been expanded to cover a fixed region, a corresponding RegSubVar constraint won't have any effect on the expansion anymore, the same is true for constraints where the variable on the RHS has already reached static scope. By removing those constraints from the set that we're iterating over, we remove a lot of needless overhead in case of slow convergences (i.e. lots of iterations). For the unicode_normalization crate, this about cuts the time required for item_bodies checking in half. --- .../infer/lexical_region_resolve/mod.rs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index dbf8f270ab0c9..2a93217b9b423 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -13,6 +13,7 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use smallvec::SmallVec; use std::fmt; use std::u32; use ty::fold::TypeFoldable; @@ -190,19 +191,24 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - self.expand_node(a_region, b_vid, b_data) + (self.expand_node(a_region, b_vid, b_data), false) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { - VarValue::ErrorValue => false, + VarValue::ErrorValue => (false, false), VarValue::Value(a_region) => { let b_node = var_values.value_mut(b_vid); - self.expand_node(a_region, b_vid, b_node) + let changed = self.expand_node(a_region, b_vid, b_node); + let retain = match *b_node { + VarValue::Value(ReStatic) | VarValue::ErrorValue => false, + _ => true + }; + (changed, retain) } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { // These constraints are checked after expansion // is done, in `collect_errors`. - false + (false, false) } } }) @@ -710,21 +716,23 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { fn iterate_until_fixed_point(&self, tag: &str, mut body: F) where - F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> bool, + F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> (bool, bool), { + let mut constraints: SmallVec<[_; 16]> = self.data.constraints.iter().collect(); let mut iteration = 0; let mut changed = true; while changed { changed = false; iteration += 1; debug!("---- {} Iteration {}{}", "#", tag, iteration); - for (constraint, origin) in &self.data.constraints { - let edge_changed = body(constraint, origin); + constraints.retain(|(constraint, origin)| { + let (edge_changed, retain) = body(constraint, origin); if edge_changed { debug!("Updated due to constraint {:?}", constraint); changed = true; } - } + retain + }); } debug!("---- {} Complete after {} iteration(s)", tag, iteration); } From 5f402b827726607b04887c7c7b8d8b95cce8f487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Thu, 10 Jan 2019 19:28:42 +0100 Subject: [PATCH 18/25] Add a fast path for identical regions in lub_concrete_regions In functions with lots of region constraint, if the fixed point iteration converges only slowly, a lot of the var/var constraints will have equal regions most of the time. Yet, we still perform the LUB calculation and try to intern the result. Especially the latter incurs quite some overhead. This reduces the take taken by the item bodies checking pass for the unicode_normalization crate by about 75%. --- src/librustc/infer/lexical_region_resolve/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 2a93217b9b423..39ce8cc621b49 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -274,6 +274,13 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { let tcx = self.tcx(); + + // Equal scopes can show up quite often, if the fixed point + // iteration converges slowly, skip them + if a == b { + return a; + } + match (a, b) { (&ty::ReClosureBound(..), _) | (_, &ty::ReClosureBound(..)) From 3f032979562e9b245ac452ec91ec3204176c27fe Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Thu, 10 Jan 2019 20:27:44 -0500 Subject: [PATCH 19/25] inline pub extern crate statements --- src/librustdoc/clean/mod.rs | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 37c6407fbd1c0..6eea95b61c990 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -587,7 +587,7 @@ impl Clean for doctree::Module { let attrs = self.attrs.clean(cx); let mut items: Vec = vec![]; - items.extend(self.extern_crates.iter().map(|x| x.clean(cx))); + items.extend(self.extern_crates.iter().flat_map(|x| x.clean(cx))); items.extend(self.imports.iter().flat_map(|x| x.clean(cx))); items.extend(self.structs.iter().map(|x| x.clean(cx))); items.extend(self.unions.iter().map(|x| x.clean(cx))); @@ -3503,9 +3503,30 @@ fn build_deref_target_impls(cx: &DocContext, } } -impl Clean for doctree::ExternCrate { - fn clean(&self, cx: &DocContext) -> Item { - Item { +impl Clean> for doctree::ExternCrate { + fn clean(&self, cx: &DocContext) -> Vec { + + let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| { + a.name() == "doc" && match a.meta_item_list() { + Some(l) => attr::list_contains_name(&l, "inline"), + None => false, + } + }); + + if please_inline { + let mut visited = FxHashSet::default(); + + let def = Def::Mod(DefId { + krate: self.cnum, + index: CRATE_DEF_INDEX, + }); + + if let Some(items) = inline::try_inline(cx, def, self.name, &mut visited) { + return items; + } + } + + vec![Item { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), @@ -3514,7 +3535,7 @@ impl Clean for doctree::ExternCrate { stability: None, deprecation: None, inner: ExternCrateItem(self.name.clean(cx), self.path.clone()) - } + }] } } From ca47808479f7b5eccdbb595c7769ea6009db9a9c Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Thu, 10 Jan 2019 21:18:46 -0500 Subject: [PATCH 20/25] add test for pub extern crate --- src/test/rustdoc/auxiliary/pub-extern-crate.rs | 2 ++ src/test/rustdoc/pub-extern-crate.rs | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/test/rustdoc/auxiliary/pub-extern-crate.rs create mode 100644 src/test/rustdoc/pub-extern-crate.rs diff --git a/src/test/rustdoc/auxiliary/pub-extern-crate.rs b/src/test/rustdoc/auxiliary/pub-extern-crate.rs new file mode 100644 index 0000000000000..8c89c8d6c76c5 --- /dev/null +++ b/src/test/rustdoc/auxiliary/pub-extern-crate.rs @@ -0,0 +1,2 @@ +#![crate_name = "inner"] +pub struct SomeStruct; diff --git a/src/test/rustdoc/pub-extern-crate.rs b/src/test/rustdoc/pub-extern-crate.rs new file mode 100644 index 0000000000000..26747a4d1aca5 --- /dev/null +++ b/src/test/rustdoc/pub-extern-crate.rs @@ -0,0 +1,9 @@ +// aux-build:pub-extern-crate.rs + +// @has pub_extern_crate/index.html +// @!has - '//code' 'pub extern crate inner' +// @has - '//a/@href' 'inner/index.html' +// @has pub_extern_crate/inner/index.html +// @has pub_extern_crate/inner/struct.SomeStruct.html +#[doc(inline)] +pub extern crate inner; From 186d5d7fd4de3ffeb06503134477fd453a185936 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 10 Jan 2019 15:21:01 -0500 Subject: [PATCH 21/25] re-do docs for core::cmp Fixes #32934 --- src/libcore/cmp.rs | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index f420d0d00a401..86f28a957cd2c 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -1,27 +1,22 @@ //! Functionality for ordering and comparison. //! -//! This module defines both [`PartialOrd`] and [`PartialEq`] traits which are used -//! by the compiler to implement comparison operators. Rust programs may -//! implement [`PartialOrd`] to overload the `<`, `<=`, `>`, and `>=` operators, -//! and may implement [`PartialEq`] to overload the `==` and `!=` operators. +//! This module contains various tools for ordering and comparing values. In +//! summary: //! -//! [`PartialOrd`]: trait.PartialOrd.html -//! [`PartialEq`]: trait.PartialEq.html +//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and +//! partial equality between values, respectively. Implementing them overloads +//! the `==` and `!=` operators. +//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and +//! partial orderings between values, respectively. Implementing them overloads +//! the `<`, `<=`, `>`, and `>=` operators. +//! * [`Ordering`][cmp::Ordering] is an enum returned by the +//! main functions of [`Ord`] and [`PartialOrd`], and describes an ordering. +//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse +//! an ordering. +//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of +//! [`Ord`] and allow you to find the maximum or minimum of two values. //! -//! # Examples -//! -//! ``` -//! let x: u32 = 0; -//! let y: u32 = 1; -//! -//! // these two lines are equivalent -//! assert_eq!(x < y, true); -//! assert_eq!(x.lt(&y), true); -//! -//! // these two lines are also equivalent -//! assert_eq!(x == y, false); -//! assert_eq!(x.eq(&y), false); -//! ``` +//! For more details, see the respective documentation of each item in the list. #![stable(feature = "rust1", since = "1.0.0")] From 7948b184146c961e552716ead12bcb443cdd07e9 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sat, 12 Jan 2019 16:13:33 +0100 Subject: [PATCH 22/25] Use `ptr::eq` where applicable --- src/librustc/ty/context.rs | 17 +++++++---------- src/librustc_codegen_llvm/debuginfo/metadata.rs | 2 +- src/librustc_codegen_llvm/type_.rs | 3 ++- src/librustc_codegen_llvm/value.rs | 3 ++- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c0ba4329ae05c..d26d6f20041e2 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -59,6 +59,7 @@ use std::hash::{Hash, Hasher}; use std::fmt; use std::mem; use std::ops::{Deref, Bound}; +use std::ptr; use std::iter; use std::sync::mpsc; use std::sync::Arc; @@ -168,7 +169,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { // Make sure we don't end up with inference // types/regions in the global interner - if local as *const _ as usize == global as *const _ as usize { + if ptr::eq(local, global) { bug!("Attempted to intern `{:?}` which contains \ inference types/regions in the global type context", &ty_struct); @@ -1125,9 +1126,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns true if self is the same as self.global_tcx(). fn is_global(self) -> bool { - let local = self.interners as *const _; - let global = &self.global_interners as *const _; - local as usize == global as usize + ptr::eq(self.interners, &self.global_interners) } /// Create a type context and call the closure with a `TyCtxt` reference @@ -1777,6 +1776,7 @@ pub mod tls { use std::fmt; use std::mem; use std::marker::PhantomData; + use std::ptr; use syntax_pos; use ty::query; use errors::{Diagnostic, TRACK_DIAGNOSTICS}; @@ -2011,8 +2011,7 @@ pub mod tls { { with_context(|context| { unsafe { - let gcx = tcx.gcx as *const _ as usize; - assert!(context.tcx.gcx as *const _ as usize == gcx); + assert!(ptr::eq(context.tcx.gcx, tcx.gcx)); let context: &ImplicitCtxt<'_, '_, '_> = mem::transmute(context); f(context) } @@ -2030,10 +2029,8 @@ pub mod tls { { with_context(|context| { unsafe { - let gcx = tcx.gcx as *const _ as usize; - let interners = tcx.interners as *const _ as usize; - assert!(context.tcx.gcx as *const _ as usize == gcx); - assert!(context.tcx.interners as *const _ as usize == interners); + assert!(ptr::eq(context.tcx.gcx, tcx.gcx)); + assert!(ptr::eq(context.tcx.interners, tcx.interners)); let context: &ImplicitCtxt<'_, '_, '_> = mem::transmute(context); f(context) } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 72ed55df94658..6deedd0b5ea33 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -47,7 +47,7 @@ use syntax_pos::{self, Span, FileName}; impl PartialEq for llvm::Metadata { fn eq(&self, other: &Self) -> bool { - self as *const _ == other as *const _ + ptr::eq(self, other) } } diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 1462423d0da2a..958e00506d62a 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -20,12 +20,13 @@ use abi::{LlvmType, FnTypeExt}; use std::fmt; use std::cell::RefCell; +use std::ptr; use libc::c_uint; impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { - self as *const _ == other as *const _ + ptr::eq(self, other) } } diff --git a/src/librustc_codegen_llvm/value.rs b/src/librustc_codegen_llvm/value.rs index 0ec964d4c422f..3ad1521be9393 100644 --- a/src/librustc_codegen_llvm/value.rs +++ b/src/librustc_codegen_llvm/value.rs @@ -4,10 +4,11 @@ use llvm; use std::fmt; use std::hash::{Hash, Hasher}; +use std::ptr; impl PartialEq for Value { fn eq(&self, other: &Self) -> bool { - self as *const _ == other as *const _ + ptr::eq(self, other) } } From 6aa78563697245ff7835a57c7e7eb331e9ecec08 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 13 Jan 2019 00:58:45 +0300 Subject: [PATCH 23/25] resolve: Mark extern crate items as used in more cases --- src/librustc_resolve/lib.rs | 3 ++ src/test/ui/imports/extern-crate-used.rs | 28 +++++++++++++++ src/test/ui/imports/extern-crate-used.stderr | 38 ++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/test/ui/imports/extern-crate-used.rs create mode 100644 src/test/ui/imports/extern-crate-used.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cf949b62a634e..378f1c9fd668d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -5089,6 +5089,9 @@ impl<'a> Resolver<'a> { } self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| { if let Some(binding) = entry.extern_crate_item { + if !speculative && entry.introduced_by_item { + self.record_use(ident, TypeNS, binding, false); + } Some(binding) } else { let crate_id = if !speculative { diff --git a/src/test/ui/imports/extern-crate-used.rs b/src/test/ui/imports/extern-crate-used.rs new file mode 100644 index 0000000000000..2d91cbc00f27d --- /dev/null +++ b/src/test/ui/imports/extern-crate-used.rs @@ -0,0 +1,28 @@ +// Extern crate items are marked as used if they are used +// through extern prelude entries introduced by them. + +// edition:2018 + +#![deny(unused_extern_crates)] + +extern crate core as iso1; //~ ERROR `extern crate` is not idiomatic in the new edition +extern crate core as iso2; //~ ERROR `extern crate` is not idiomatic in the new edition +extern crate core as iso3; //~ ERROR `extern crate` is not idiomatic in the new edition +extern crate core as iso4; //~ ERROR `extern crate` is not idiomatic in the new edition + +// Doesn't introduce its extern prelude entry, so it's still considered unused. +extern crate core; //~ ERROR unused extern crate + +mod m { + use iso1::any as are_you_okay1; + use ::iso2::any as are_you_okay2; + type AreYouOkay1 = iso3::any::Any; + type AreYouOkay2 = ::iso4::any::Any; + + use core::any as are_you_okay3; + use ::core::any as are_you_okay4; + type AreYouOkay3 = core::any::Any; + type AreYouOkay4 = ::core::any::Any; +} + +fn main() {} diff --git a/src/test/ui/imports/extern-crate-used.stderr b/src/test/ui/imports/extern-crate-used.stderr new file mode 100644 index 0000000000000..3f9aab9dc79cb --- /dev/null +++ b/src/test/ui/imports/extern-crate-used.stderr @@ -0,0 +1,38 @@ +error: `extern crate` is not idiomatic in the new edition + --> $DIR/extern-crate-used.rs:8:1 + | +LL | extern crate core as iso1; //~ ERROR `extern crate` is not idiomatic in the new edition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` + | +note: lint level defined here + --> $DIR/extern-crate-used.rs:6:9 + | +LL | #![deny(unused_extern_crates)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: `extern crate` is not idiomatic in the new edition + --> $DIR/extern-crate-used.rs:9:1 + | +LL | extern crate core as iso2; //~ ERROR `extern crate` is not idiomatic in the new edition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` + +error: `extern crate` is not idiomatic in the new edition + --> $DIR/extern-crate-used.rs:10:1 + | +LL | extern crate core as iso3; //~ ERROR `extern crate` is not idiomatic in the new edition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` + +error: `extern crate` is not idiomatic in the new edition + --> $DIR/extern-crate-used.rs:11:1 + | +LL | extern crate core as iso4; //~ ERROR `extern crate` is not idiomatic in the new edition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` + +error: unused extern crate + --> $DIR/extern-crate-used.rs:14:1 + | +LL | extern crate core; //~ ERROR unused extern crate + | ^^^^^^^^^^^^^^^^^^ help: remove it + +error: aborting due to 5 previous errors + From 805099cf3eddf06f0ae6ead6f152dd1d4c37eee2 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 13 Jan 2019 01:59:51 +0300 Subject: [PATCH 24/25] hygiene: Do not treat `Self` ctor as a local variable --- src/librustc_resolve/lib.rs | 16 +++++++--------- src/test/ui/resolve/issue-57523.rs | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/resolve/issue-57523.rs diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7c05913467c54..683c9c7c35418 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2017,16 +2017,14 @@ impl<'a> Resolver<'a> { if ident.name == keywords::Invalid.name() { return Some(LexicalScopeBinding::Def(Def::Err)); } - if ns == TypeNS { - ident.span = if ident.name == keywords::SelfUpper.name() { - // FIXME(jseyfried) improve `Self` hygiene - ident.span.with_ctxt(SyntaxContext::empty()) - } else { - ident.span.modern() - } + ident.span = if ident.name == keywords::SelfUpper.name() { + // FIXME(jseyfried) improve `Self` hygiene + ident.span.with_ctxt(SyntaxContext::empty()) + } else if ns == TypeNS { + ident.span.modern() } else { - ident = ident.modern_and_legacy(); - } + ident.span.modern_and_legacy() + }; // Walk backwards up the ribs in scope. let record_used = record_used_id.is_some(); diff --git a/src/test/ui/resolve/issue-57523.rs b/src/test/ui/resolve/issue-57523.rs new file mode 100644 index 0000000000000..c2a2f28254226 --- /dev/null +++ b/src/test/ui/resolve/issue-57523.rs @@ -0,0 +1,21 @@ +// compile-pass + +struct S(u8); + +impl S { + fn method1() -> Self { + Self(0) + } +} + +macro_rules! define_method { () => { + impl S { + fn method2() -> Self { + Self(0) // OK + } + } +}} + +define_method!(); + +fn main() {} From 1e4a8a01c4e89e1485e56ba482e592a9d337d2ef Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 13 Jan 2019 01:55:44 +0000 Subject: [PATCH 25/25] Update the const fn tracking issue to the new metabug --- .../unstable-book/src/language-features/const-fn.md | 4 ++-- src/librustc_mir/diagnostics.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/libsyntax/feature_gate.rs | 2 +- .../ui/feature-gates/feature-gate-const_fn.stderr | 4 ++-- .../ui/feature-gates/feature-gate-min_const_fn.stderr | 4 ++-- src/tools/tidy/src/features.rs | 11 +++++------ 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/const-fn.md b/src/doc/unstable-book/src/language-features/const-fn.md index d5a2243683862..50dbbaf56743c 100644 --- a/src/doc/unstable-book/src/language-features/const-fn.md +++ b/src/doc/unstable-book/src/language-features/const-fn.md @@ -1,8 +1,8 @@ # `const_fn` -The tracking issue for this feature is: [#24111] +The tracking issue for this feature is: [#57563] -[#24111]: https://github.com/rust-lang/rust/issues/24111 +[#57563]: https://github.com/rust-lang/rust/issues/57563 ------------------------ diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index a324761f06ab5..ea9e19c75c215 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -573,7 +573,7 @@ const Y: i32 = A; ``` "##, -// FIXME(#24111) Change the language here when const fn stabilizes +// FIXME(#57563) Change the language here when const fn stabilizes E0015: r##" The only functions that can be called in static or constant expressions are `const` functions, and struct/enum constructors. `const` functions are only diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 193b0fe05f002..78cf7153500c9 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -901,7 +901,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { err.emit(); } } else { - // FIXME(#24111): remove this check when const fn stabilizes. + // FIXME(#57563): remove this check when const fn stabilizes. let (msg, note) = if let UnstableFeatures::Disallow = self.tcx.sess.opts.unstable_features { (format!("calls in {}s are limited to \ diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 89da1a219b70a..9b4231d8803a3 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -191,7 +191,7 @@ declare_features! ( (active, slice_patterns, "1.0.0", Some(23121), None), // Allows the definition of `const` functions with some advanced features. - (active, const_fn, "1.2.0", Some(24111), None), + (active, const_fn, "1.2.0", Some(57563), None), // Allows accessing fields of unions inside `const` functions. (active, const_fn_union, "1.27.0", Some(51909), None), diff --git a/src/test/ui/feature-gates/feature-gate-const_fn.stderr b/src/test/ui/feature-gates/feature-gate-const_fn.stderr index b3fc587b1cf77..be5237fbfcf3b 100644 --- a/src/test/ui/feature-gates/feature-gate-const_fn.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_fn.stderr @@ -16,7 +16,7 @@ error[E0379]: trait fns cannot be declared const LL | const fn foo() -> u32 { 0 } //~ ERROR trait fns cannot be declared const | ^^^^^ trait fns cannot be const -error[E0658]: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #57563) --> $DIR/feature-gate-const_fn.rs:6:5 | LL | const fn foo() -> u32; //~ ERROR const fn is unstable @@ -24,7 +24,7 @@ LL | const fn foo() -> u32; //~ ERROR const fn is unstable | = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0658]: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #57563) --> $DIR/feature-gate-const_fn.rs:8:5 | LL | const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable diff --git a/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr b/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr index bcc5b0198c319..056e33111f0df 100644 --- a/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr +++ b/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr @@ -16,7 +16,7 @@ error[E0379]: trait fns cannot be declared const LL | const fn foo() -> u32 { 0 } //~ ERROR trait fns cannot be declared const | ^^^^^ trait fns cannot be const -error[E0658]: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #57563) --> $DIR/feature-gate-min_const_fn.rs:6:5 | LL | const fn foo() -> u32; //~ ERROR const fn is unstable @@ -24,7 +24,7 @@ LL | const fn foo() -> u32; //~ ERROR const fn is unstable | = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0658]: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #57563) --> $DIR/feature-gate-min_const_fn.rs:8:5 | LL | const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 049a0ee49f0a4..2435a0cfd4e38 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -336,12 +336,11 @@ fn map_lib_features(base_src_path: &Path, level: Status::Unstable, since: "None".to_owned(), has_gate_test: false, - // Whether there is a common tracking issue - // for these feature gates remains an open question - // https://github.com/rust-lang/rust/issues/24111#issuecomment-340283184 - // But we take 24111 otherwise they will be shown as - // "internal to the compiler" which they are not. - tracking_issue: Some(24111), + // FIXME(#57563): #57563 is now used as a common tracking issue, + // although we would like to have specific tracking + // issues for each `rustc_const_unstable` in the + // future. + tracking_issue: Some(57563), }; mf(Ok((feature_name, feature)), file, i + 1); continue;