From 893ab67f288f00d67d04329d93e3f0653c5e8a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 3 Oct 2019 11:41:27 -0700 Subject: [PATCH 01/14] Custom lifetime error for `impl` item doesn't conform to `trait` --- .../error_reporting/nice_region_error/mod.rs | 2 + .../trait_impl_difference.rs | 53 +++++++++++++++++++ .../mismatched_trait_impl-2.rs | 2 +- .../mismatched_trait_impl-2.stderr | 17 ++---- .../mismatched_trait_impl.rs | 2 +- .../mismatched_trait_impl.stderr | 21 ++------ ...ifetime-mismatch-between-trait-and-impl.rs | 12 +++++ ...ime-mismatch-between-trait-and-impl.stderr | 11 ++++ src/test/ui/reject-specialized-drops-8142.rs | 2 +- .../ui/reject-specialized-drops-8142.stderr | 19 ++----- 10 files changed, 93 insertions(+), 48 deletions(-) create mode 100644 src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs create mode 100644 src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs create mode 100644 src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs index 1edb1c601bf1a..cd003aa8dab70 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs @@ -12,6 +12,7 @@ mod named_anon_conflict; mod placeholder_error; mod outlives_closure; mod static_impl_trait; +mod trait_impl_difference; mod util; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { @@ -73,6 +74,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { .or_else(|| self.try_report_anon_anon_conflict()) .or_else(|| self.try_report_outlives_closure()) .or_else(|| self.try_report_static_impl_trait()) + .or_else(|| self.try_report_impl_not_conforming_to_trait()) } pub fn get_regions(&self) -> (Span, ty::Region<'tcx>, ty::Region<'tcx>) { diff --git a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs new file mode 100644 index 0000000000000..bd5be89358939 --- /dev/null +++ b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -0,0 +1,53 @@ +//! Error Reporting for `impl` items that do not match the obligations from their `trait`. + +use crate::infer::{ValuePairs, Subtype}; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::infer::lexical_region_resolve::RegionResolutionError; +use crate::util::common::ErrorReported; + +impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { + /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`. + pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option { + if let Some(ref error) = self.error { + if let RegionResolutionError::SubSupConflict( + _, + var_origin, + sub_origin, + _sub, + sup_origin, + _sup, + ) = error.clone() { + match (&sup_origin, &sub_origin) { + (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) => { + if let ( + ValuePairs::Types(sub_expected_found), + ValuePairs::Types(sup_expected_found), + ) = (&sub_trace.values, &sup_trace.values) { + if sup_expected_found == sub_expected_found { + let sp = var_origin.span(); + let mut err = self.tcx().sess.struct_span_err( + sp, + "`impl` item doesn't match `trait` item" + ); + err.note(&format!( + "expected: {:?}\n found: {:?}", + sub_expected_found.expected, + sub_expected_found.found, + )); + err.span_label(sp, &format!( + "found {:?}", + sub_expected_found.found, + )); + // FIXME: recover the `FnPtr`'s `HirId`/`Node` to point to it. + err.emit(); + return Some(ErrorReported); + } + } + } + _ => {} + } + } + } + None + } +} diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs index d131a944721d0..3c44af7188f81 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs @@ -9,6 +9,6 @@ impl Deref for Struct { unimplemented!(); } } -//~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter +//~^^^^ ERROR `impl` item doesn't match `trait` item fn main() {} diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr index c1ec536ef4362..d3228951b2596 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -1,20 +1,11 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements +error: `impl` item doesn't match `trait` item --> $DIR/mismatched_trait_impl-2.rs:8:5 | LL | fn deref(&self) -> &dyn Trait { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait | -note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5... - --> $DIR/mismatched_trait_impl-2.rs:8:5 - | -LL | / fn deref(&self) -> &dyn Trait { -LL | | unimplemented!(); -LL | | } - | |_____^ - = note: ...but the lifetime must also be valid for the static lifetime... - = note: ...so that the method type is compatible with trait: - expected fn(&Struct) -> &(dyn Trait + 'static) - found fn(&Struct) -> &dyn Trait + = note: expected: fn(&Struct) -> &(dyn Trait + 'static) + found: fn(&Struct) -> &dyn Trait error: aborting due to previous error diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs index f2ba81af9b638..a9b80a7c46fdc 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs @@ -6,7 +6,7 @@ trait Get { } impl Get for i32 { - fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer + fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR `impl` item doesn't match `trait` x //~ ERROR lifetime mismatch } } diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index 734ca0819e416..ae65125a3dfd8 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -1,24 +1,11 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements +error: `impl` item doesn't match `trait` item --> $DIR/mismatched_trait_impl.rs:9:5 | LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32 | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 9:5... - --> $DIR/mismatched_trait_impl.rs:9:5 - | -LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { -LL | | x -LL | | } - | |_____^ -note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32... - --> $DIR/mismatched_trait_impl.rs:9:32 - | -LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { - | ^^ - = note: ...so that the method type is compatible with trait: - expected fn(&i32, &'a u32, &u32) -> &'a u32 - found fn(&i32, &u32, &u32) -> &u32 + = note: expected: fn(&i32, &'a u32, &u32) -> &'a u32 + found: fn(&i32, &u32, &u32) -> &u32 error[E0623]: lifetime mismatch --> $DIR/mismatched_trait_impl.rs:10:9 diff --git a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs new file mode 100644 index 0000000000000..cd285e70bc8f3 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs @@ -0,0 +1,12 @@ +trait Foo { + fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; +} + +impl Foo for () { + fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { + //~^ ERROR `impl` item doesn't match `trait` item + if x > y { x } else { y } + } +} + +fn main() {} diff --git a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr new file mode 100644 index 0000000000000..099e5e97e17e0 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr @@ -0,0 +1,11 @@ +error: `impl` item doesn't match `trait` item + --> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5 + | +LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &i32) -> &i32 + | + = note: expected: fn(&i32, &'a i32) -> &'a i32 + found: fn(&i32, &i32) -> &i32 + +error: aborting due to previous error + diff --git a/src/test/ui/reject-specialized-drops-8142.rs b/src/test/ui/reject-specialized-drops-8142.rs index f047e16bc0b94..39b959a2206c3 100644 --- a/src/test/ui/reject-specialized-drops-8142.rs +++ b/src/test/ui/reject-specialized-drops-8142.rs @@ -52,6 +52,6 @@ impl Drop for V { fn drop(&mut self) { } } // REJECT //~^ ERROR Implementations of Drop cannot be specialized impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT -//~^ ERROR cannot infer an appropriate lifetime +//~^ ERROR `impl` item doesn't match `trait` item pub fn main() { } diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index 609a40163a30c..7aa766dc50341 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -89,25 +89,14 @@ note: Use same sequence of generic type and region parameters that is on the str LL | struct V { x: *const Tva, y: *const Tvb } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'lw` due to conflicting requirements +error: `impl` item doesn't match `trait` item --> $DIR/reject-specialized-drops-8142.rs:54:1 | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 17:10... - --> $DIR/reject-specialized-drops-8142.rs:17:10 - | -LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } - | ^^^ -note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 17:15... - --> $DIR/reject-specialized-drops-8142.rs:17:15 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found W<'_, '_> | -LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } - | ^^^ - = note: ...so that the types are compatible: - expected W<'l1, 'l2> - found W<'_, '_> + = note: expected: W<'l1, 'l2> + found: W<'_, '_> error: aborting due to 8 previous errors From 3e2bc19a46f7947e536bdb0eb2510c2508e36ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 3 Oct 2019 20:14:48 -0700 Subject: [PATCH 02/14] review comments --- .../trait_impl_difference.rs | 27 ++++++++++--------- .../mismatched_trait_impl-2.rs | 2 +- .../mismatched_trait_impl-2.stderr | 2 +- .../mismatched_trait_impl.rs | 2 +- .../mismatched_trait_impl.stderr | 2 +- ...ifetime-mismatch-between-trait-and-impl.rs | 2 +- ...ime-mismatch-between-trait-and-impl.stderr | 2 +- src/test/ui/reject-specialized-drops-8142.rs | 2 +- .../ui/reject-specialized-drops-8142.stderr | 2 +- 9 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs index bd5be89358939..f546acdb87859 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -1,5 +1,7 @@ //! Error Reporting for `impl` items that do not match the obligations from their `trait`. +use syntax_pos::Span; +use crate::ty::Ty; use crate::infer::{ValuePairs, Subtype}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; @@ -25,21 +27,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) = (&sub_trace.values, &sup_trace.values) { if sup_expected_found == sub_expected_found { let sp = var_origin.span(); - let mut err = self.tcx().sess.struct_span_err( + self.emit_err( sp, - "`impl` item doesn't match `trait` item" - ); - err.note(&format!( - "expected: {:?}\n found: {:?}", sub_expected_found.expected, sub_expected_found.found, - )); - err.span_label(sp, &format!( - "found {:?}", - sub_expected_found.found, - )); - // FIXME: recover the `FnPtr`'s `HirId`/`Node` to point to it. - err.emit(); + ); return Some(ErrorReported); } } @@ -50,4 +42,15 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } None } + + fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>) { + let mut err = self.tcx().sess.struct_span_err( + sp, + "`impl` item signature doesn't match `trait` item signature", + ); + err.note(&format!("expected: {:?}\n found: {:?}", expected, found)); + err.span_label(sp, &format!("found {:?}", found)); + // FIXME: recover the `FnPtr`'s `HirId`/`Node` to point to it. + err.emit(); + } } diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs index 3c44af7188f81..60e1585a51a80 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs @@ -9,6 +9,6 @@ impl Deref for Struct { unimplemented!(); } } -//~^^^^ ERROR `impl` item doesn't match `trait` item +//~^^^^ ERROR `impl` item signature doesn't match `trait` item signature fn main() {} diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr index d3228951b2596..ea88cb14f0118 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -1,4 +1,4 @@ -error: `impl` item doesn't match `trait` item +error: `impl` item signature doesn't match `trait` item signature --> $DIR/mismatched_trait_impl-2.rs:8:5 | LL | fn deref(&self) -> &dyn Trait { diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs index a9b80a7c46fdc..b9e02e967c126 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs @@ -6,7 +6,7 @@ trait Get { } impl Get for i32 { - fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR `impl` item doesn't match `trait` + fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR `impl` item signature doesn't match x //~ ERROR lifetime mismatch } } diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index ae65125a3dfd8..4b0af292bbc24 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -1,4 +1,4 @@ -error: `impl` item doesn't match `trait` item +error: `impl` item signature doesn't match `trait` item signature --> $DIR/mismatched_trait_impl.rs:9:5 | LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { diff --git a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs index cd285e70bc8f3..2ce1a0f454651 100644 --- a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs +++ b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs @@ -4,7 +4,7 @@ trait Foo { impl Foo for () { fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { - //~^ ERROR `impl` item doesn't match `trait` item + //~^ ERROR `impl` item signature doesn't match `trait` item signature if x > y { x } else { y } } } diff --git a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr index 099e5e97e17e0..cdb4c16eca35b 100644 --- a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr +++ b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr @@ -1,4 +1,4 @@ -error: `impl` item doesn't match `trait` item +error: `impl` item signature doesn't match `trait` item signature --> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5 | LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { diff --git a/src/test/ui/reject-specialized-drops-8142.rs b/src/test/ui/reject-specialized-drops-8142.rs index 39b959a2206c3..621626f3a0d91 100644 --- a/src/test/ui/reject-specialized-drops-8142.rs +++ b/src/test/ui/reject-specialized-drops-8142.rs @@ -52,6 +52,6 @@ impl Drop for V { fn drop(&mut self) { } } // REJECT //~^ ERROR Implementations of Drop cannot be specialized impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT -//~^ ERROR `impl` item doesn't match `trait` item +//~^ ERROR `impl` item signature doesn't match `trait` item signature pub fn main() { } diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index 7aa766dc50341..bc7604cdede57 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -89,7 +89,7 @@ note: Use same sequence of generic type and region parameters that is on the str LL | struct V { x: *const Tva, y: *const Tvb } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `impl` item doesn't match `trait` item +error: `impl` item signature doesn't match `trait` item signature --> $DIR/reject-specialized-drops-8142.rs:54:1 | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT From 1e95b5c0006406bb5d42810241644521b82adad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 15 Oct 2019 10:36:26 -0700 Subject: [PATCH 03/14] Point at the trait item and tweak wording --- .../nice_region_error/trait_impl_difference.rs | 18 +++++++++++++++--- .../mismatched_trait_impl-2.rs | 2 +- .../mismatched_trait_impl-2.stderr | 10 +++++++--- .../mismatched_trait_impl.stderr | 8 +++++--- ...time-mismatch-between-trait-and-impl.stderr | 7 +++++-- .../ui/reject-specialized-drops-8142.stderr | 6 +++--- 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs index f546acdb87859..565ba6b33b8c0 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -6,11 +6,13 @@ use crate::infer::{ValuePairs, Subtype}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::util::common::ErrorReported; +use crate::traits::ObligationCauseCode::CompareImplMethodObligation; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`. pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option { if let Some(ref error) = self.error { + debug!("try_report_impl_not_conforming_to_trait {:?}", error); if let RegionResolutionError::SubSupConflict( _, var_origin, @@ -27,10 +29,18 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) = (&sub_trace.values, &sup_trace.values) { if sup_expected_found == sub_expected_found { let sp = var_origin.span(); + let impl_sp = if let CompareImplMethodObligation { + trait_item_def_id, .. + } = &sub_trace.cause.code { + Some(self.tcx().def_span(*trait_item_def_id)) + } else { + None + }; self.emit_err( sp, sub_expected_found.expected, sub_expected_found.found, + impl_sp, ); return Some(ErrorReported); } @@ -43,14 +53,16 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { None } - fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>) { + fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Option) { let mut err = self.tcx().sess.struct_span_err( sp, "`impl` item signature doesn't match `trait` item signature", ); - err.note(&format!("expected: {:?}\n found: {:?}", expected, found)); + err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found)); err.span_label(sp, &format!("found {:?}", found)); - // FIXME: recover the `FnPtr`'s `HirId`/`Node` to point to it. + if let Some(span) = impl_sp { + err.span_label(span, &format!("expected {:?}", expected)); + } err.emit(); } } diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs index 60e1585a51a80..1b524ec3833e8 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs @@ -6,9 +6,9 @@ struct Struct; impl Deref for Struct { type Target = dyn Trait; fn deref(&self) -> &dyn Trait { + //~^ ERROR `impl` item signature doesn't match `trait` item signature unimplemented!(); } } -//~^^^^ ERROR `impl` item signature doesn't match `trait` item signature fn main() {} diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr index ea88cb14f0118..c1c4ec9ed7b92 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -3,10 +3,14 @@ error: `impl` item signature doesn't match `trait` item signature | LL | fn deref(&self) -> &dyn Trait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait + | + ::: $SRC_DIR/libcore/ops/deref.rs:LL:COL | - = note: expected: fn(&Struct) -> &(dyn Trait + 'static) - found: fn(&Struct) -> &dyn Trait +LL | fn deref(&self) -> &Self::Target; + | --------------------------------- expected fn(&Struct) -> &(dyn Trait + 'static) + | + = note: expected `fn(&Struct) -> &(dyn Trait + 'static)` + found `fn(&Struct) -> &dyn Trait` error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index 4b0af292bbc24..bc302e91c1c51 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -1,11 +1,14 @@ error: `impl` item signature doesn't match `trait` item signature --> $DIR/mismatched_trait_impl.rs:9:5 | +LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32; + | ---------------------------------------------- expected fn(&i32, &'a u32, &u32) -> &'a u32 +... LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32 | - = note: expected: fn(&i32, &'a u32, &u32) -> &'a u32 - found: fn(&i32, &u32, &u32) -> &u32 + = note: expected `fn(&i32, &'a u32, &u32) -> &'a u32` + found `fn(&i32, &u32, &u32) -> &u32` error[E0623]: lifetime mismatch --> $DIR/mismatched_trait_impl.rs:10:9 @@ -19,4 +22,3 @@ LL | x error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr index cdb4c16eca35b..d07f305954b6e 100644 --- a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr +++ b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr @@ -1,11 +1,14 @@ error: `impl` item signature doesn't match `trait` item signature --> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5 | +LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; + | ------------------------------------------- expected fn(&i32, &'a i32) -> &'a i32 +... LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &i32) -> &i32 | - = note: expected: fn(&i32, &'a i32) -> &'a i32 - found: fn(&i32, &i32) -> &i32 + = note: expected `fn(&i32, &'a i32) -> &'a i32` + found `fn(&i32, &i32) -> &i32` error: aborting due to previous error diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index bc7604cdede57..887edc7299375 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -95,10 +95,10 @@ error: `impl` item signature doesn't match `trait` item signature LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found W<'_, '_> | - = note: expected: W<'l1, 'l2> - found: W<'_, '_> + = note: expected `W<'l1, 'l2>` + found `W<'_, '_>` error: aborting due to 8 previous errors -Some errors have detailed explanations: E0308, E0366, E0367, E0495. +Some errors have detailed explanations: E0308, E0366, E0367. For more information about an error, try `rustc --explain E0308`. From e383b7c57f9b0adbb095b2a8c5c1234be224f255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 15 Oct 2019 10:47:48 -0700 Subject: [PATCH 04/14] Make error apply only to impl/trait mismatch --- .../trait_impl_difference.rs | 21 ++++++------------- src/test/ui/reject-specialized-drops-8142.rs | 2 +- .../ui/reject-specialized-drops-8142.stderr | 21 ++++++++++++++----- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 565ba6b33b8c0..0194300c50721 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -26,21 +26,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if let ( ValuePairs::Types(sub_expected_found), ValuePairs::Types(sup_expected_found), - ) = (&sub_trace.values, &sup_trace.values) { + CompareImplMethodObligation { trait_item_def_id, .. }, + ) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code) { if sup_expected_found == sub_expected_found { - let sp = var_origin.span(); - let impl_sp = if let CompareImplMethodObligation { - trait_item_def_id, .. - } = &sub_trace.cause.code { - Some(self.tcx().def_span(*trait_item_def_id)) - } else { - None - }; self.emit_err( - sp, + var_origin.span(), sub_expected_found.expected, sub_expected_found.found, - impl_sp, + self.tcx().def_span(*trait_item_def_id), ); return Some(ErrorReported); } @@ -53,16 +46,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { None } - fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Option) { + fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Span) { let mut err = self.tcx().sess.struct_span_err( sp, "`impl` item signature doesn't match `trait` item signature", ); err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found)); err.span_label(sp, &format!("found {:?}", found)); - if let Some(span) = impl_sp { - err.span_label(span, &format!("expected {:?}", expected)); - } + err.span_label(impl_sp, &format!("expected {:?}", expected)); err.emit(); } } diff --git a/src/test/ui/reject-specialized-drops-8142.rs b/src/test/ui/reject-specialized-drops-8142.rs index 621626f3a0d91..b3cb83f94e053 100644 --- a/src/test/ui/reject-specialized-drops-8142.rs +++ b/src/test/ui/reject-specialized-drops-8142.rs @@ -52,6 +52,6 @@ impl Drop for V { fn drop(&mut self) { } } // REJECT //~^ ERROR Implementations of Drop cannot be specialized impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT -//~^ ERROR `impl` item signature doesn't match `trait` item signature +//~^ ERROR cannot infer an appropriate lifetime for lifetime parameter `'lw` pub fn main() { } diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index 887edc7299375..609a40163a30c 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -89,16 +89,27 @@ note: Use same sequence of generic type and region parameters that is on the str LL | struct V { x: *const Tva, y: *const Tvb } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `impl` item signature doesn't match `trait` item signature +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'lw` due to conflicting requirements --> $DIR/reject-specialized-drops-8142.rs:54:1 | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found W<'_, '_> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 17:10... + --> $DIR/reject-specialized-drops-8142.rs:17:10 + | +LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } + | ^^^ +note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 17:15... + --> $DIR/reject-specialized-drops-8142.rs:17:15 | - = note: expected `W<'l1, 'l2>` - found `W<'_, '_>` +LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } + | ^^^ + = note: ...so that the types are compatible: + expected W<'l1, 'l2> + found W<'_, '_> error: aborting due to 8 previous errors -Some errors have detailed explanations: E0308, E0366, E0367. +Some errors have detailed explanations: E0308, E0366, E0367, E0495. For more information about an error, try `rustc --explain E0308`. From 3aba2d060a0184d38c261bee218c973457135aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 15 Oct 2019 10:57:52 -0700 Subject: [PATCH 05/14] Fix NLL test --- .../mismatched_trait_impl.nll.stderr | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr index b5287f32a5045..c245d78ae828f 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr @@ -1,25 +1,14 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements +error: `impl` item signature doesn't match `trait` item signature --> $DIR/mismatched_trait_impl.rs:9:5 | +LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32; + | ---------------------------------------------- expected fn(&i32, &'a u32, &u32) -> &'a u32 +... LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32 | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 9:5... - --> $DIR/mismatched_trait_impl.rs:9:5 - | -LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { -LL | | x -LL | | } - | |_____^ -note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32... - --> $DIR/mismatched_trait_impl.rs:9:32 - | -LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { - | ^^ - = note: ...so that the method type is compatible with trait: - expected fn(&i32, &'a u32, &u32) -> &'a u32 - found fn(&i32, &u32, &u32) -> &u32 + = note: expected `fn(&i32, &'a u32, &u32) -> &'a u32` + found `fn(&i32, &u32, &u32) -> &u32` error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. From 76b8fd81e299498266923f1470c216f553b2927b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Oct 2019 19:00:09 +0200 Subject: [PATCH 06/14] Add long error explanation for E0587 --- src/librustc_typeck/error_codes.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 3d41c6e09c6bc..6405b77c1054b 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -3891,6 +3891,25 @@ details. [issue #33685]: https://github.com/rust-lang/rust/issues/33685 "##, +E0587: r##" +A type has both `packed` and `align` representation hints. + +Erroneous code example: + +```compile_fail,E0587 +#[repr(packed, align(8))] // error! +struct Umbrella(i32); +``` + +You cannot use `packed` and `align` hints on a same type. If you want to pack a +type to a given size, you should provide a size to packed: + +``` +#[repr(packed)] // ok! +struct Umbrella(i32); +``` +"##, + E0588: r##" A type with `packed` representation hint has a field with `align` representation hint. @@ -5073,7 +5092,6 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC. // E0563, // cannot determine a type for this `impl Trait` removed in 6383de15 // E0564, // only named lifetimes are allowed in `impl Trait`, // but `{}` was found in the type `{}` - E0587, // type has conflicting packed and align representation hints // E0611, // merged into E0616 // E0612, // merged into E0609 // E0613, // Removed (merged with E0609) From 42a805e4d2b057f58f5ad72b35afaee1bf8358ef Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Oct 2019 19:00:35 +0200 Subject: [PATCH 07/14] Update ui tests --- src/test/ui/conflicting-repr-hints.stderr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/conflicting-repr-hints.stderr b/src/test/ui/conflicting-repr-hints.stderr index 832f5c3ac2bb7..414c15f93bc18 100644 --- a/src/test/ui/conflicting-repr-hints.stderr +++ b/src/test/ui/conflicting-repr-hints.stderr @@ -66,4 +66,5 @@ LL | | } error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0566`. +Some errors have detailed explanations: E0566, E0587. +For more information about an error, try `rustc --explain E0566`. From 6661db006a85bdb1530716da26fb5b2829643f2a Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 20 Oct 2019 23:44:41 +0100 Subject: [PATCH 08/14] Correct handling of type flags with `ConstValue::Placeholder` --- src/librustc/ty/flags.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index d3a3f51cfa47b..dad7144a6e969 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -114,6 +114,7 @@ impl FlagComputation { } &ty::Placeholder(..) => { + self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER); } @@ -123,8 +124,7 @@ impl FlagComputation { match infer { ty::FreshTy(_) | ty::FreshIntTy(_) | - ty::FreshFloatTy(_) => { - } + ty::FreshFloatTy(_) => {} ty::TyVar(_) | ty::IntVar(_) | @@ -245,14 +245,16 @@ impl FlagComputation { } } ConstValue::Param(_) => { - self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_PARAMS); + self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); + self.add_flags(TypeFlags::HAS_PARAMS); } ConstValue::Placeholder(_) => { - self.add_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_CT_PLACEHOLDER); + self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); + self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER); } - ConstValue::Scalar(_) => { } - ConstValue::Slice { data: _, start: _, end: _ } => { } - ConstValue::ByRef { alloc: _, offset: _ } => { } + ConstValue::Scalar(_) => {} + ConstValue::Slice { .. } => {} + ConstValue::ByRef { .. } => {} } } From 2af50a91fa0adc03b52c0e028bf732b729bbb720 Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Fri, 18 Oct 2019 18:05:54 +0200 Subject: [PATCH 09/14] Improve the "try using a variant of the expected type" hint. --- src/librustc/hir/print.rs | 2 -- src/librustc_typeck/check/demand.rs | 9 +++++++-- src/test/ui/did_you_mean/issue-42764.rs | 2 +- src/test/ui/did_you_mean/issue-42764.stderr | 2 +- src/test/ui/error-codes/E0164.stderr | 2 +- src/test/ui/fn-in-pat.stderr | 2 +- .../fully-qualified-type-name1.stderr | 2 +- src/test/ui/issues/issue-28992-empty.rs | 2 +- src/test/ui/issues/issue-28992-empty.stderr | 2 +- src/test/ui/issues/issue-46112.stderr | 2 +- src/test/ui/issues/issue-55587.stderr | 2 +- src/test/ui/match/match-fn-call.stderr | 4 ++-- src/test/ui/methods/method-path-in-pattern.rs | 12 ++++++------ .../ui/methods/method-path-in-pattern.stderr | 12 ++++++------ src/test/ui/qualified/qualified-path-params.rs | 2 +- .../ui/qualified/qualified-path-params.stderr | 2 +- ...ariant-form-through-Self-issue-58006.stderr | 2 +- ...orrect-variant-form-through-alias-caught.rs | 10 +++++----- ...ct-variant-form-through-alias-caught.stderr | 18 +++++++++--------- 19 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index b852098d4cef7..b6001c30cb030 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1523,9 +1523,7 @@ impl<'a> State<'a> { colons_before_params) } hir::QPath::TypeRelative(ref qself, ref item_segment) => { - self.s.word("<"); self.print_type(qself); - self.s.word(">"); self.s.word("::"); self.print_ident(item_segment.ident); self.print_generic_args(item_segment.generic_args(), diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 3509d6566ec93..b4e07e4a0dfb4 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -172,10 +172,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }).peekable(); if compatible_variants.peek().is_some() { - let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr)); + let expr_text = self.tcx.sess + .source_map() + .span_to_snippet(expr.span) + .unwrap_or_else(|_| { + print::to_string(print::NO_ANN, |s| s.print_expr(expr)) + }); let suggestions = compatible_variants .map(|v| format!("{}({})", v, expr_text)); - let msg = "try using a variant of the expected type"; + let msg = "try using a variant of the expected enum"; err.span_suggestions(expr.span, msg, suggestions, Applicability::MaybeIncorrect); } } diff --git a/src/test/ui/did_you_mean/issue-42764.rs b/src/test/ui/did_you_mean/issue-42764.rs index 5dd70aade67f5..700f8128a939a 100644 --- a/src/test/ui/did_you_mean/issue-42764.rs +++ b/src/test/ui/did_you_mean/issue-42764.rs @@ -10,7 +10,7 @@ fn main() { let n: usize = 42; this_function_expects_a_double_option(n); //~^ ERROR mismatched types - //~| HELP try using a variant of the expected type + //~| HELP try using a variant of the expected enum } diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr index 64868c414efb7..0b3e44446aec2 100644 --- a/src/test/ui/did_you_mean/issue-42764.stderr +++ b/src/test/ui/did_you_mean/issue-42764.stderr @@ -6,7 +6,7 @@ LL | this_function_expects_a_double_option(n); | = note: expected type `DoubleOption<_>` found type `usize` -help: try using a variant of the expected type +help: try using a variant of the expected enum | LL | this_function_expects_a_double_option(DoubleOption::FirstSome(n)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0164.stderr b/src/test/ui/error-codes/E0164.stderr index 0a153d85b4215..eb2921317131e 100644 --- a/src/test/ui/error-codes/E0164.stderr +++ b/src/test/ui/error-codes/E0164.stderr @@ -1,4 +1,4 @@ -error[E0164]: expected tuple struct/variant, found associated constant `::B` +error[E0164]: expected tuple struct/variant, found associated constant `Foo::B` --> $DIR/E0164.rs:9:9 | LL | Foo::B(i) => i, diff --git a/src/test/ui/fn-in-pat.stderr b/src/test/ui/fn-in-pat.stderr index 0bb24365ef42b..5d7e541e2e805 100644 --- a/src/test/ui/fn-in-pat.stderr +++ b/src/test/ui/fn-in-pat.stderr @@ -1,4 +1,4 @@ -error[E0164]: expected tuple struct/variant, found method `::new` +error[E0164]: expected tuple struct/variant, found method `A::new` --> $DIR/fn-in-pat.rs:11:9 | LL | A::new() => (), diff --git a/src/test/ui/fully-qualified-type/fully-qualified-type-name1.stderr b/src/test/ui/fully-qualified-type/fully-qualified-type-name1.stderr index 62ded3e255a44..e488b1f6b0cb6 100644 --- a/src/test/ui/fully-qualified-type/fully-qualified-type-name1.stderr +++ b/src/test/ui/fully-qualified-type/fully-qualified-type-name1.stderr @@ -5,7 +5,7 @@ LL | x = 5; | ^ | | | expected enum `std::option::Option`, found integer - | help: try using a variant of the expected type: `Some(5)` + | help: try using a variant of the expected enum: `Some(5)` | = note: expected type `std::option::Option` found type `{integer}` diff --git a/src/test/ui/issues/issue-28992-empty.rs b/src/test/ui/issues/issue-28992-empty.rs index 22961fc61d134..c555d1768d453 100644 --- a/src/test/ui/issues/issue-28992-empty.rs +++ b/src/test/ui/issues/issue-28992-empty.rs @@ -12,5 +12,5 @@ impl S { fn main() { if let C1(..) = 0 {} //~ ERROR expected tuple struct/variant, found constant `C1` if let S::C2(..) = 0 {} - //~^ ERROR expected tuple struct/variant, found associated constant `::C2` + //~^ ERROR expected tuple struct/variant, found associated constant `S::C2` } diff --git a/src/test/ui/issues/issue-28992-empty.stderr b/src/test/ui/issues/issue-28992-empty.stderr index 9f9f574aa5dd4..71841d0be1638 100644 --- a/src/test/ui/issues/issue-28992-empty.stderr +++ b/src/test/ui/issues/issue-28992-empty.stderr @@ -4,7 +4,7 @@ error[E0532]: expected tuple struct/variant, found constant `C1` LL | if let C1(..) = 0 {} | ^^ not a tuple struct/variant -error[E0164]: expected tuple struct/variant, found associated constant `::C2` +error[E0164]: expected tuple struct/variant, found associated constant `S::C2` --> $DIR/issue-28992-empty.rs:14:12 | LL | if let S::C2(..) = 0 {} diff --git a/src/test/ui/issues/issue-46112.stderr b/src/test/ui/issues/issue-46112.stderr index 939d945c19133..07e90c567480f 100644 --- a/src/test/ui/issues/issue-46112.stderr +++ b/src/test/ui/issues/issue-46112.stderr @@ -5,7 +5,7 @@ LL | fn main() { test(Ok(())); } | ^^ | | | expected enum `std::option::Option`, found () - | help: try using a variant of the expected type: `Some(())` + | help: try using a variant of the expected enum: `Some(())` | = note: expected type `std::option::Option<()>` found type `()` diff --git a/src/test/ui/issues/issue-55587.stderr b/src/test/ui/issues/issue-55587.stderr index 3928a3cd53201..2a181fb896c41 100644 --- a/src/test/ui/issues/issue-55587.stderr +++ b/src/test/ui/issues/issue-55587.stderr @@ -1,4 +1,4 @@ -error[E0164]: expected tuple struct/variant, found method `::new` +error[E0164]: expected tuple struct/variant, found method `Path::new` --> $DIR/issue-55587.rs:4:9 | LL | let Path::new(); diff --git a/src/test/ui/match/match-fn-call.stderr b/src/test/ui/match/match-fn-call.stderr index bd918428351b9..41a67f920027e 100644 --- a/src/test/ui/match/match-fn-call.stderr +++ b/src/test/ui/match/match-fn-call.stderr @@ -1,4 +1,4 @@ -error[E0164]: expected tuple struct/variant, found method `::new` +error[E0164]: expected tuple struct/variant, found method `Path::new` --> $DIR/match-fn-call.rs:6:9 | LL | Path::new("foo") => println!("foo"), @@ -6,7 +6,7 @@ LL | Path::new("foo") => println!("foo"), | = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html -error[E0164]: expected tuple struct/variant, found method `::new` +error[E0164]: expected tuple struct/variant, found method `Path::new` --> $DIR/match-fn-call.rs:8:9 | LL | Path::new("bar") => println!("bar"), diff --git a/src/test/ui/methods/method-path-in-pattern.rs b/src/test/ui/methods/method-path-in-pattern.rs index 21a91f3f32b24..a4a3504d29cfc 100644 --- a/src/test/ui/methods/method-path-in-pattern.rs +++ b/src/test/ui/methods/method-path-in-pattern.rs @@ -13,20 +13,20 @@ impl MyTrait for Foo {} fn main() { match 0u32 { Foo::bar => {} - //~^ ERROR expected unit struct/variant or constant, found method `::bar` + //~^ ERROR expected unit struct/variant or constant, found method `Foo::bar` } match 0u32 { ::bar => {} - //~^ ERROR expected unit struct/variant or constant, found method `::bar` + //~^ ERROR expected unit struct/variant or constant, found method `Foo::bar` } match 0u32 { ::trait_bar => {} - //~^ ERROR expected unit struct/variant or constant, found method `::trait_bar` + //~^ ERROR expected unit struct/variant or constant, found method `Foo::trait_bar` } if let Foo::bar = 0u32 {} - //~^ ERROR expected unit struct/variant or constant, found method `::bar` + //~^ ERROR expected unit struct/variant or constant, found method `Foo::bar` if let ::bar = 0u32 {} - //~^ ERROR expected unit struct/variant or constant, found method `::bar` + //~^ ERROR expected unit struct/variant or constant, found method `Foo::bar` if let Foo::trait_bar = 0u32 {} - //~^ ERROR expected unit struct/variant or constant, found method `::trait_bar` + //~^ ERROR expected unit struct/variant or constant, found method `Foo::trait_bar` } diff --git a/src/test/ui/methods/method-path-in-pattern.stderr b/src/test/ui/methods/method-path-in-pattern.stderr index 257fff4c37dc0..211378be9b57e 100644 --- a/src/test/ui/methods/method-path-in-pattern.stderr +++ b/src/test/ui/methods/method-path-in-pattern.stderr @@ -1,34 +1,34 @@ -error[E0533]: expected unit struct/variant or constant, found method `::bar` +error[E0533]: expected unit struct/variant or constant, found method `Foo::bar` --> $DIR/method-path-in-pattern.rs:15:9 | LL | Foo::bar => {} | ^^^^^^^^ -error[E0533]: expected unit struct/variant or constant, found method `::bar` +error[E0533]: expected unit struct/variant or constant, found method `Foo::bar` --> $DIR/method-path-in-pattern.rs:19:9 | LL | ::bar => {} | ^^^^^^^^^^ -error[E0533]: expected unit struct/variant or constant, found method `::trait_bar` +error[E0533]: expected unit struct/variant or constant, found method `Foo::trait_bar` --> $DIR/method-path-in-pattern.rs:23:9 | LL | ::trait_bar => {} | ^^^^^^^^^^^^^^^^ -error[E0533]: expected unit struct/variant or constant, found method `::bar` +error[E0533]: expected unit struct/variant or constant, found method `Foo::bar` --> $DIR/method-path-in-pattern.rs:26:12 | LL | if let Foo::bar = 0u32 {} | ^^^^^^^^ -error[E0533]: expected unit struct/variant or constant, found method `::bar` +error[E0533]: expected unit struct/variant or constant, found method `Foo::bar` --> $DIR/method-path-in-pattern.rs:28:12 | LL | if let ::bar = 0u32 {} | ^^^^^^^^^^ -error[E0533]: expected unit struct/variant or constant, found method `::trait_bar` +error[E0533]: expected unit struct/variant or constant, found method `Foo::trait_bar` --> $DIR/method-path-in-pattern.rs:30:12 | LL | if let Foo::trait_bar = 0u32 {} diff --git a/src/test/ui/qualified/qualified-path-params.rs b/src/test/ui/qualified/qualified-path-params.rs index ea2ae0e86bf64..aefec2e76732a 100644 --- a/src/test/ui/qualified/qualified-path-params.rs +++ b/src/test/ui/qualified/qualified-path-params.rs @@ -18,7 +18,7 @@ impl S { fn main() { match 10 { ::A::f:: => {} - //~^ ERROR expected unit struct/variant or constant, found method `<::A>::f` + //~^ ERROR expected unit struct/variant or constant, found method `::A::f` 0 ..= ::A::f:: => {} //~ ERROR only char and numeric types are allowed in range } } diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr index 3e8fcdc7ca3e2..b0cd3eb8947ea 100644 --- a/src/test/ui/qualified/qualified-path-params.stderr +++ b/src/test/ui/qualified/qualified-path-params.stderr @@ -1,4 +1,4 @@ -error[E0533]: expected unit struct/variant or constant, found method `<::A>::f` +error[E0533]: expected unit struct/variant or constant, found method `::A::f` --> $DIR/qualified-path-params.rs:20:9 | LL | ::A::f:: => {} diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr index 357b33de51b84..1938326c9cdf6 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr @@ -1,4 +1,4 @@ -error[E0533]: expected unit struct/variant or constant, found tuple variant `::A` +error[E0533]: expected unit struct/variant or constant, found tuple variant `Self::A` --> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13 | LL | Self::A => (), diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs index ce45d59198af8..29e1c15cf28bb 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs @@ -8,14 +8,14 @@ type Alias = Enum; fn main() { Alias::Braced; - //~^ ERROR expected unit struct/variant or constant, found struct variant `::Braced` [E0533] + //~^ ERROR expected unit struct/variant or constant, found struct variant `Alias::Braced` [E0533] let Alias::Braced = panic!(); - //~^ ERROR expected unit struct/variant or constant, found struct variant `::Braced` [E0533] + //~^ ERROR expected unit struct/variant or constant, found struct variant `Alias::Braced` [E0533] let Alias::Braced(..) = panic!(); - //~^ ERROR expected tuple struct/variant, found struct variant `::Braced` [E0164] + //~^ ERROR expected tuple struct/variant, found struct variant `Alias::Braced` [E0164] Alias::Unit(); - //~^ ERROR expected function, found enum variant `::Unit` + //~^ ERROR expected function, found enum variant `Alias::Unit` let Alias::Unit() = panic!(); - //~^ ERROR expected tuple struct/variant, found unit variant `::Unit` [E0164] + //~^ ERROR expected tuple struct/variant, found unit variant `Alias::Unit` [E0164] } diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr index 801ca5f013b3e..ee01a9fc67a42 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr @@ -1,38 +1,38 @@ -error[E0533]: expected unit struct/variant or constant, found struct variant `::Braced` +error[E0533]: expected unit struct/variant or constant, found struct variant `Alias::Braced` --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:5 | LL | Alias::Braced; | ^^^^^^^^^^^^^ -error[E0533]: expected unit struct/variant or constant, found struct variant `::Braced` +error[E0533]: expected unit struct/variant or constant, found struct variant `Alias::Braced` --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9 | LL | let Alias::Braced = panic!(); | ^^^^^^^^^^^^^ -error[E0164]: expected tuple struct/variant, found struct variant `::Braced` +error[E0164]: expected tuple struct/variant, found struct variant `Alias::Braced` --> $DIR/incorrect-variant-form-through-alias-caught.rs:14:9 | LL | let Alias::Braced(..) = panic!(); | ^^^^^^^^^^^^^^^^^ not a tuple variant or struct -error[E0618]: expected function, found enum variant `::Unit` +error[E0618]: expected function, found enum variant `Alias::Unit` --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:5 | LL | enum Enum { Braced {}, Unit, Tuple() } - | ---- `::Unit` defined here + | ---- `Alias::Unit` defined here ... LL | Alias::Unit(); | ^^^^^^^^^^^-- | | | call expression requires function | -help: `::Unit` is a unit variant, you need to write it without the parenthesis +help: `Alias::Unit` is a unit variant, you need to write it without the parenthesis | -LL | ::Unit; - | ^^^^^^^^^^^^^ +LL | Alias::Unit; + | ^^^^^^^^^^^ -error[E0164]: expected tuple struct/variant, found unit variant `::Unit` +error[E0164]: expected tuple struct/variant, found unit variant `Alias::Unit` --> $DIR/incorrect-variant-form-through-alias-caught.rs:19:9 | LL | let Alias::Unit() = panic!(); From 97b10b735cb1eac7891506b66b0b19f1ddab65fd Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Sat, 26 Oct 2019 15:48:27 +0200 Subject: [PATCH 10/14] Fix a previously forgotten pretty-printing test after a change to the pretty-printing mechanism. --- src/test/pretty/issue-4264.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index 4cf2e90e635fd..b545146c9646e 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -30,7 +30,7 @@ ((::alloc::fmt::format as - for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<::core::fmt::Arguments>::new_v1 + for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((::core::fmt::Arguments::new_v1 as fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test" as From 1c5d0be925927ba098b691ef58250b6fb98e5b24 Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Sun, 27 Oct 2019 16:43:42 +0100 Subject: [PATCH 11/14] Improve pretty-printing for compound qualified paths. --- src/librustc/hir/print.rs | 12 +++++++++++- src/test/ui/qualified/qualified-path-params.rs | 2 +- src/test/ui/qualified/qualified-path-params.stderr | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index b6001c30cb030..64b355f6ec9d1 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1523,7 +1523,17 @@ impl<'a> State<'a> { colons_before_params) } hir::QPath::TypeRelative(ref qself, ref item_segment) => { - self.print_type(qself); + // If we've got a compound-qualified-path, let's push an additional pair of angle + // brackets, so that we pretty-print `<::C>` as `::C`, instead of just + // `A::B::C` (since the latter could be ambiguous to the user) + if let hir::TyKind::Path(hir::QPath::Resolved(None, _)) = &qself.kind { + self.print_type(qself); + } else { + self.s.word("<"); + self.print_type(qself); + self.s.word(">"); + } + self.s.word("::"); self.print_ident(item_segment.ident); self.print_generic_args(item_segment.generic_args(), diff --git a/src/test/ui/qualified/qualified-path-params.rs b/src/test/ui/qualified/qualified-path-params.rs index aefec2e76732a..ea2ae0e86bf64 100644 --- a/src/test/ui/qualified/qualified-path-params.rs +++ b/src/test/ui/qualified/qualified-path-params.rs @@ -18,7 +18,7 @@ impl S { fn main() { match 10 { ::A::f:: => {} - //~^ ERROR expected unit struct/variant or constant, found method `::A::f` + //~^ ERROR expected unit struct/variant or constant, found method `<::A>::f` 0 ..= ::A::f:: => {} //~ ERROR only char and numeric types are allowed in range } } diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr index b0cd3eb8947ea..3e8fcdc7ca3e2 100644 --- a/src/test/ui/qualified/qualified-path-params.stderr +++ b/src/test/ui/qualified/qualified-path-params.stderr @@ -1,4 +1,4 @@ -error[E0533]: expected unit struct/variant or constant, found method `::A::f` +error[E0533]: expected unit struct/variant or constant, found method `<::A>::f` --> $DIR/qualified-path-params.rs:20:9 | LL | ::A::f:: => {} From e2c450b8dacd6edce4bdc66db9da4ddfc81f4dc1 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Mon, 28 Oct 2019 05:39:37 +0000 Subject: [PATCH 12/14] doc: mention `get(_mut)` in Vec --- src/liballoc/vec.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 641f9eafa8d23..272150110eba9 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -154,8 +154,8 @@ use crate::raw_vec::RawVec; /// println!("{}", v[6]); // it will panic! /// ``` /// -/// In conclusion: always check if the index you want to get really exists -/// before doing it. +/// Use [`get`] and [`get_mut`] if you want to check whether the index is in +/// the `Vec`. /// /// # Slicing /// @@ -277,6 +277,8 @@ use crate::raw_vec::RawVec; /// The order has changed in the past and may change again. /// /// [`vec!`]: ../../std/macro.vec.html +/// [`get`]: ../../std/vec/struct.Vec.html#method.get +/// [`get_mut`]: ../../std/vec/struct.Vec.html#method.get_mut /// [`Index`]: ../../std/ops/trait.Index.html /// [`String`]: ../../std/string/struct.String.html /// [`&str`]: ../../std/primitive.str.html From cc575a6ad50c3b15f4073b3ac210ed6e5423230d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 25 Oct 2019 20:30:11 +0300 Subject: [PATCH 13/14] rustc: use IndexVec instead of Vec. --- src/librustc/hir/map/collector.rs | 8 ++------ src/librustc/hir/map/definitions.rs | 18 +++++++++--------- src/librustc/hir/map/mod.rs | 14 ++++++-------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 307dbe7dab080..b0fa844c81881 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -149,7 +149,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { let mut collector = NodeCollector { krate, source_map: sess.source_map(), - map: vec![None; definitions.def_index_count()], + map: IndexVec::from_elem_n(IndexVec::new(), definitions.def_index_count()), parent_node: hir::CRATE_HIR_ID, current_signature_dep_index: root_mod_sig_dep_index, current_full_dep_index: root_mod_full_dep_index, @@ -227,12 +227,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) { debug!("hir_map: {:?} => {:?}", id, entry); - let local_map = &mut self.map[id.owner.index()]; + let local_map = &mut self.map[id.owner]; let i = id.local_id.as_u32() as usize; - if local_map.is_none() { - *local_map = Some(IndexVec::with_capacity(i + 1)); - } - let local_map = local_map.as_mut().unwrap(); let len = local_map.len(); if i >= len { local_map.extend(repeat(None).take(i - len + 1)); diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 4e163314f6b07..be8d82173e481 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -27,8 +27,8 @@ use syntax_pos::{Span, DUMMY_SP}; /// There is one `DefPathTable` for each crate. #[derive(Clone, Default, RustcDecodable, RustcEncodable)] pub struct DefPathTable { - index_to_key: Vec, - def_path_hashes: Vec, + index_to_key: IndexVec, + def_path_hashes: IndexVec, } impl DefPathTable { @@ -53,14 +53,14 @@ impl DefPathTable { #[inline(always)] pub fn def_key(&self, index: DefIndex) -> DefKey { - self.index_to_key[index.index()] + self.index_to_key[index] } #[inline(always)] pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash { - let ret = self.def_path_hashes[index.index()]; - debug!("def_path_hash({:?}) = {:?}", index, ret); - return ret + let hash = self.def_path_hashes[index]; + debug!("def_path_hash({:?}) = {:?}", index, hash); + hash } pub fn add_def_path_hashes_to(&self, @@ -92,7 +92,7 @@ impl DefPathTable { pub struct Definitions { table: DefPathTable, node_to_def_index: NodeMap, - def_index_to_node: Vec, + def_index_to_node: IndexVec, pub(super) node_to_hir_id: IndexVec, /// If `ExpnId` is an ID of some macro expansion, /// then `DefId` is the normal module (`mod`) in which the expanded macro was defined. @@ -375,7 +375,7 @@ impl Definitions { #[inline] pub fn as_local_node_id(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { - let node_id = self.def_index_to_node[def_id.index.index()]; + let node_id = self.def_index_to_node[def_id.index]; if node_id != ast::DUMMY_NODE_ID { return Some(node_id); } @@ -404,7 +404,7 @@ impl Definitions { #[inline] pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId { - let node_id = self.def_index_to_node[def_index.index()]; + let node_id = self.def_index_to_node[def_index]; self.node_to_hir_id[node_id] } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index cd36944253dbb..acadd77cc36c0 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -156,9 +156,9 @@ impl Forest { /// This type is effectively a `HashMap>`, /// but it is implemented as 2 layers of arrays. -/// - first we have `A = Vec>` mapping a `DefIndex`'s index to an inner value +/// - first we have `A = IndexVec` mapping `DefIndex`s to an inner value /// - which is `B = IndexVec>` which gives you the `Entry`. -pub(super) type HirEntryMap<'hir> = Vec>>>>; +pub(super) type HirEntryMap<'hir> = IndexVec>>>; /// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s. #[derive(Clone)] @@ -222,8 +222,8 @@ impl<'map> Iterator for ParentHirIterator<'map> { impl<'hir> Map<'hir> { #[inline] fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> { - let local_map = self.map.get(id.owner.index())?; - local_map.as_ref()?.get(id.local_id)?.as_ref() + let local_map = self.map.get(id.owner)?; + local_map.get(id.local_id)?.as_ref() } /// Registers a read in the dependency graph of the AST node with @@ -1031,14 +1031,12 @@ impl<'hir> Map<'hir> { // see the comment on `HirEntryMap`. // Iterate over all the indices and return a reference to // local maps and their index given that they exist. - self.map.iter().enumerate().filter_map(|(i, local_map)| { - local_map.as_ref().map(|m| (i, m)) - }).flat_map(move |(array_index, local_map)| { + self.map.iter_enumerated().flat_map(move |(owner, local_map)| { // Iterate over each valid entry in the local map. local_map.iter_enumerated().filter_map(move |(i, entry)| entry.map(move |_| { // Reconstruct the `HirId` based on the 3 indices we used to find it. HirId { - owner: DefIndex::from(array_index), + owner, local_id: i, } })) From 46a39a2d424cefb2d0c56fae9682cfa253a79d47 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 28 Oct 2019 10:57:54 +0100 Subject: [PATCH 14/14] self-profiling: Record something more useful for crate metadata generation event. Before this commit, we had an event that would only track the compression step for proc-macros and Rust dylibs. After the commit we measure the time for acutally generating the crate metadata bytes. --- src/librustc/ty/context.rs | 1 + src/librustc_codegen_ssa/base.rs | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0f7d5d9a25e61..bdf9b2d7f3f27 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1408,6 +1408,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn encode_metadata(self)-> EncodedMetadata { + let _prof_timer = self.prof.generic_activity("generate_crate_metadata"); self.cstore.encode_metadata(self) } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index bf687f846357e..ee4ec7fb41eac 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -574,8 +574,6 @@ pub fn codegen_crate( if need_metadata_module { // Codegen the encoded metadata. - let _prof_timer = tcx.prof.generic_activity("codegen_crate_metadata"); - let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).as_str()