Skip to content

Commit 4ed0c6a

Browse files
committed
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`
1 parent 13290e8 commit 4ed0c6a

File tree

5 files changed

+104
-5
lines changed

5 files changed

+104
-5
lines changed

src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
44
use crate::infer::lexical_region_resolve::RegionResolutionError;
5-
use crate::infer::{Subtype, TyCtxtInferExt, ValuePairs};
5+
use crate::infer::{Subtype, ValuePairs};
66
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
77
use rustc_errors::ErrorReported;
88
use rustc_hir as hir;
@@ -53,7 +53,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
5353
}
5454

5555
fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) {
56-
let tcx = self.tcx();
5756
let trait_sp = self.tcx().def_span(trait_def_id);
5857
let mut err = self
5958
.tcx()
@@ -85,9 +84,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
8584
);
8685
}
8786

88-
if let Some((expected, found)) = tcx
89-
.infer_ctxt()
90-
.enter(|infcx| infcx.expected_found_str_ty(&ExpectedFound { expected, found }))
87+
if let Some((expected, found)) =
88+
self.infcx.expected_found_str_ty(&ExpectedFound { expected, found })
9189
{
9290
// Highlighted the differences when showing the "expected/found" note.
9391
err.note_expected_found(&"", expected, &"", found);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Regression test for issue #74918
2+
// Tests that we don't ICE after emitting an error
3+
4+
struct ChunkingIterator<T, S: 'static + Iterator<Item = T>> {
5+
source: S,
6+
}
7+
8+
impl<T, S: Iterator<Item = T>> Iterator for ChunkingIterator<T, S> {
9+
type Item = IteratorChunk<T, S>; //~ ERROR missing lifetime
10+
11+
fn next(&mut self) -> Option<IteratorChunk<T, S>> { //~ ERROR `impl`
12+
todo!()
13+
}
14+
}
15+
16+
struct IteratorChunk<'a, T, S: Iterator<Item = T>> {
17+
source: &'a mut S,
18+
}
19+
20+
impl<T, S: Iterator<Item = T>> Iterator for IteratorChunk<'_, T, S> {
21+
type Item = T;
22+
23+
fn next(&mut self) -> Option<T> {
24+
todo!()
25+
}
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/issue-74918-missing-lifetime.rs:9:31
3+
|
4+
LL | type Item = IteratorChunk<T, S>;
5+
| ^ expected named lifetime parameter
6+
|
7+
help: consider introducing a named lifetime parameter
8+
|
9+
LL | type Item<'a> = IteratorChunk<<'a>T, S>;
10+
| ^^^^ ^^^^
11+
12+
error: `impl` item signature doesn't match `trait` item signature
13+
--> $DIR/issue-74918-missing-lifetime.rs:11:5
14+
|
15+
LL | fn next(&mut self) -> Option<IteratorChunk<T, S>> {
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&mut ChunkingIterator<T, S>) -> std::option::Option<IteratorChunk<'_, T, S>>`
17+
|
18+
::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
19+
|
20+
LL | fn next(&mut self) -> Option<Self::Item>;
21+
| ----------------------------------------- expected `fn(&mut ChunkingIterator<T, S>) -> std::option::Option<IteratorChunk<'static, _, _>>`
22+
|
23+
= note: expected `fn(&mut ChunkingIterator<T, S>) -> std::option::Option<IteratorChunk<'static, _, _>>`
24+
found `fn(&mut ChunkingIterator<T, S>) -> std::option::Option<IteratorChunk<'_, _, _>>`
25+
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
26+
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
27+
28+
error: aborting due to 2 previous errors
29+
30+
For more information about this error, try `rustc --explain E0106`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Regresison test for issue #75361
2+
// Tests that we don't ICE on mismatched types with inference variables
3+
4+
5+
trait MyTrait {
6+
type Item;
7+
}
8+
9+
pub trait Graph {
10+
type EdgeType;
11+
12+
fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
13+
}
14+
15+
impl<T> Graph for T {
16+
type EdgeType = T;
17+
18+
fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType> + '_> { //~ ERROR `impl`
19+
panic!()
20+
}
21+
22+
}
23+
24+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: `impl` item signature doesn't match `trait` item signature
2+
--> $DIR/issue-75361-mismatched-impl.rs:18:3
3+
|
4+
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
5+
| --------------------------------------------------------------------- expected `fn(&T) -> std::boxed::Box<(dyn MyTrait<Item = &_> + 'static)>`
6+
...
7+
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType> + '_> {
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&T) -> std::boxed::Box<dyn MyTrait<Item = &_>>`
9+
|
10+
= note: expected `fn(&T) -> std::boxed::Box<(dyn MyTrait<Item = &T> + 'static)>`
11+
found `fn(&T) -> std::boxed::Box<dyn MyTrait<Item = &T>>`
12+
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
13+
--> $DIR/issue-75361-mismatched-impl.rs:12:55
14+
|
15+
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
16+
| ^^^^^^^^^^^^^^ consider borrowing this type parameter in the trait
17+
18+
error: aborting due to previous error
19+

0 commit comments

Comments
 (0)