From 4ed0c6a464e89116d862773320aeab50464acd5f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 10 Aug 2020 08:05:43 -0400 Subject: [PATCH] Use existing `infcx` when emitting trait impl diagnostic Fixes #75361 Fixes #74918 Previously, we were creating a new `InferCtxt`, which caused an ICE when used with type variables from the existing `InferCtxt` --- .../trait_impl_difference.rs | 8 ++--- .../issue-74918-missing-lifetime.rs | 28 +++++++++++++++++ .../issue-74918-missing-lifetime.stderr | 30 +++++++++++++++++++ .../issue-75361-mismatched-impl.rs | 24 +++++++++++++++ .../issue-75361-mismatched-impl.stderr | 19 ++++++++++++ 5 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/mismatched_types/issue-74918-missing-lifetime.rs create mode 100644 src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr create mode 100644 src/test/ui/mismatched_types/issue-75361-mismatched-impl.rs create mode 100644 src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 45aee2b39654d..1ddf88c030660 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -2,7 +2,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; -use crate::infer::{Subtype, TyCtxtInferExt, ValuePairs}; +use crate::infer::{Subtype, ValuePairs}; use crate::traits::ObligationCauseCode::CompareImplMethodObligation; use rustc_errors::ErrorReported; use rustc_hir as hir; @@ -53,7 +53,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) { - let tcx = self.tcx(); let trait_sp = self.tcx().def_span(trait_def_id); let mut err = self .tcx() @@ -85,9 +84,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); } - if let Some((expected, found)) = tcx - .infer_ctxt() - .enter(|infcx| infcx.expected_found_str_ty(&ExpectedFound { expected, found })) + if let Some((expected, found)) = + self.infcx.expected_found_str_ty(&ExpectedFound { expected, found }) { // Highlighted the differences when showing the "expected/found" note. err.note_expected_found(&"", expected, &"", found); diff --git a/src/test/ui/mismatched_types/issue-74918-missing-lifetime.rs b/src/test/ui/mismatched_types/issue-74918-missing-lifetime.rs new file mode 100644 index 0000000000000..0e3ea4bc8c9de --- /dev/null +++ b/src/test/ui/mismatched_types/issue-74918-missing-lifetime.rs @@ -0,0 +1,28 @@ +// Regression test for issue #74918 +// Tests that we don't ICE after emitting an error + +struct ChunkingIterator> { + source: S, +} + +impl> Iterator for ChunkingIterator { + type Item = IteratorChunk; //~ ERROR missing lifetime + + fn next(&mut self) -> Option> { //~ ERROR `impl` + todo!() + } +} + +struct IteratorChunk<'a, T, S: Iterator> { + source: &'a mut S, +} + +impl> Iterator for IteratorChunk<'_, T, S> { + type Item = T; + + fn next(&mut self) -> Option { + todo!() + } +} + +fn main() {} diff --git a/src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr b/src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr new file mode 100644 index 0000000000000..da3056eac9009 --- /dev/null +++ b/src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr @@ -0,0 +1,30 @@ +error[E0106]: missing lifetime specifier + --> $DIR/issue-74918-missing-lifetime.rs:9:31 + | +LL | type Item = IteratorChunk; + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type Item<'a> = IteratorChunk<<'a>T, S>; + | ^^^^ ^^^^ + +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/issue-74918-missing-lifetime.rs:11:5 + | +LL | fn next(&mut self) -> Option> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&mut ChunkingIterator) -> std::option::Option>` + | + ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | fn next(&mut self) -> Option; + | ----------------------------------------- expected `fn(&mut ChunkingIterator) -> std::option::Option>` + | + = note: expected `fn(&mut ChunkingIterator) -> std::option::Option>` + found `fn(&mut ChunkingIterator) -> std::option::Option>` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/mismatched_types/issue-75361-mismatched-impl.rs b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.rs new file mode 100644 index 0000000000000..4410514476dc1 --- /dev/null +++ b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.rs @@ -0,0 +1,24 @@ +// Regresison test for issue #75361 +// Tests that we don't ICE on mismatched types with inference variables + + +trait MyTrait { + type Item; +} + +pub trait Graph { + type EdgeType; + + fn adjacent_edges(&self) -> Box>; +} + +impl Graph for T { + type EdgeType = T; + + fn adjacent_edges(&self) -> Box + '_> { //~ ERROR `impl` + panic!() + } + +} + +fn main() {} diff --git a/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr new file mode 100644 index 0000000000000..5be7f5271dee8 --- /dev/null +++ b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr @@ -0,0 +1,19 @@ +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/issue-75361-mismatched-impl.rs:18:3 + | +LL | fn adjacent_edges(&self) -> Box>; + | --------------------------------------------------------------------- expected `fn(&T) -> std::boxed::Box<(dyn MyTrait + 'static)>` +... +LL | fn adjacent_edges(&self) -> Box + '_> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&T) -> std::boxed::Box>` + | + = note: expected `fn(&T) -> std::boxed::Box<(dyn MyTrait + 'static)>` + found `fn(&T) -> std::boxed::Box>` +help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + --> $DIR/issue-75361-mismatched-impl.rs:12:55 + | +LL | fn adjacent_edges(&self) -> Box>; + | ^^^^^^^^^^^^^^ consider borrowing this type parameter in the trait + +error: aborting due to previous error +