Skip to content

Commit d64b3a7

Browse files
authored
Rollup merge of #89416 - notriddle:notriddle/do-not-elide-lifetimes-in-region-errors, r=jackh726
nice_region_error: Include lifetime placeholders in error output As you can see in src/test/ui/traits/self-without-lifetime-constraint.stderr you can get very confusing type names if you don't have this. Fixes #87763
2 parents df43062 + 98ed554 commit d64b3a7

8 files changed

+76
-39
lines changed

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs

+48-11
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ use rustc_hir as hir;
99
use rustc_hir::def::Res;
1010
use rustc_hir::def_id::DefId;
1111
use rustc_hir::intravisit::Visitor;
12-
use rustc_middle::ty::error::ExpectedFound;
13-
use rustc_middle::ty::{self, Ty, TyCtxt};
12+
use rustc_middle::ty::print::RegionHighlightMode;
13+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor};
14+
1415
use rustc_span::{MultiSpan, Span, Symbol};
1516

17+
use std::ops::ControlFlow;
18+
1619
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
1720
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
1821
pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option<ErrorReported> {
@@ -69,6 +72,47 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
6972
.tcx()
7073
.sess
7174
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
75+
76+
// Mark all unnamed regions in the type with a number.
77+
// This diagnostic is called in response to lifetime errors, so be informative.
78+
struct HighlightBuilder<'tcx> {
79+
highlight: RegionHighlightMode,
80+
tcx: TyCtxt<'tcx>,
81+
counter: usize,
82+
}
83+
84+
impl HighlightBuilder<'tcx> {
85+
fn build(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> RegionHighlightMode {
86+
let mut builder =
87+
HighlightBuilder { highlight: RegionHighlightMode::default(), counter: 1, tcx };
88+
builder.visit_ty(ty);
89+
builder.highlight
90+
}
91+
}
92+
93+
impl<'tcx> ty::fold::TypeVisitor<'tcx> for HighlightBuilder<'tcx> {
94+
fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
95+
Some(self.tcx)
96+
}
97+
98+
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
99+
if !r.has_name() && self.counter <= 3 {
100+
self.highlight.highlighting_region(r, self.counter);
101+
self.counter += 1;
102+
}
103+
r.super_visit_with(self)
104+
}
105+
}
106+
107+
let expected_highlight = HighlightBuilder::build(self.tcx(), expected);
108+
let expected = self
109+
.infcx
110+
.extract_inference_diagnostics_data(expected.into(), Some(expected_highlight))
111+
.name;
112+
let found_highlight = HighlightBuilder::build(self.tcx(), found);
113+
let found =
114+
self.infcx.extract_inference_diagnostics_data(found.into(), Some(found_highlight)).name;
115+
72116
err.span_label(sp, &format!("found `{}`", found));
73117
err.span_label(trait_sp, &format!("expected `{}`", expected));
74118

@@ -96,15 +140,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
96140
);
97141
}
98142

99-
if let Some((expected, found)) =
100-
self.infcx.expected_found_str_ty(ExpectedFound { expected, found })
101-
{
102-
// Highlighted the differences when showing the "expected/found" note.
103-
err.note_expected_found(&"", expected, &"", found);
104-
} else {
105-
// This fallback shouldn't be necessary, but let's keep it in just in case.
106-
err.note(&format!("expected `{}`\n found `{}`", expected, found));
107-
}
143+
err.note(&format!("expected `{}`\n found `{}`", expected, found));
144+
108145
err.span_help(
109146
type_param_span,
110147
"the lifetime requirements from the `impl` do not correspond to the requirements in \

src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/mismatched_trait_impl-2.rs:8:5
33
|
44
LL | fn deref(&self) -> &dyn Trait {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Struct) -> &dyn Trait`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Struct) -> &'1 (dyn Trait + '1)`
66
|
77
::: $SRC_DIR/core/src/ops/deref.rs:LL:COL
88
|
99
LL | fn deref(&self) -> &Self::Target;
10-
| --------------------------------- expected `fn(&Struct) -> &(dyn Trait + 'static)`
10+
| --------------------------------- expected `fn(&'1 Struct) -> &'1 (dyn Trait + 'static)`
1111
|
12-
= note: expected `fn(&Struct) -> &(dyn Trait + 'static)`
13-
found `fn(&Struct) -> &dyn Trait`
12+
= note: expected `fn(&'1 Struct) -> &'1 (dyn Trait + 'static)`
13+
found `fn(&'1 Struct) -> &'1 (dyn Trait + '1)`
1414
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
1515
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1616

src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/mismatched_trait_impl.rs:9:5
33
|
44
LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32;
5-
| ---------------------------------------------- expected `fn(&i32, &'a u32, &u32) -> &'a u32`
5+
| ---------------------------------------------- expected `fn(&'1 i32, &'a u32, &'2 u32) -> &'a u32`
66
...
77
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &u32, &u32) -> &u32`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 i32, &'2 u32, &'3 u32) -> &'3 u32`
99
|
10-
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
11-
found `fn(&i32, &u32, &u32) -> &u32`
10+
= note: expected `fn(&'1 i32, &'a u32, &'2 u32) -> &'a u32`
11+
found `fn(&'1 i32, &'2 u32, &'3 u32) -> &'3 u32`
1212
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
1313
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1414

src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/mismatched_trait_impl.rs:9:5
33
|
44
LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32;
5-
| ---------------------------------------------- expected `fn(&i32, &'a u32, &u32) -> &'a u32`
5+
| ---------------------------------------------- expected `fn(&'1 i32, &'a u32, &'2 u32) -> &'a u32`
66
...
77
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &u32, &u32) -> &u32`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 i32, &'2 u32, &'3 u32) -> &'3 u32`
99
|
10-
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
11-
found `fn(&i32, &u32, &u32) -> &u32`
10+
= note: expected `fn(&'1 i32, &'a u32, &'2 u32) -> &'a u32`
11+
found `fn(&'1 i32, &'2 u32, &'3 u32) -> &'3 u32`
1212
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
1313
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1414

src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5
33
|
44
LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
5-
| ------------------------------------------- expected `fn(&i32, &'a i32) -> &'a i32`
5+
| ------------------------------------------- expected `fn(&'1 i32, &'a i32) -> &'a i32`
66
...
77
LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &i32) -> &i32`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 i32, &'1 i32) -> &'1 i32`
99
|
10-
= note: expected `fn(&i32, &'a i32) -> &'a i32`
11-
found `fn(&i32, &i32) -> &i32`
10+
= note: expected `fn(&'1 i32, &'a i32) -> &'a i32`
11+
found `fn(&'1 i32, &'1 i32) -> &'1 i32`
1212
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
1313
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1414

src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/issue-75361-mismatched-impl.rs:18:3
33
|
44
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
5-
| --------------------------------------------------------------------- expected `fn(&T) -> Box<(dyn MyTrait<Item = &T> + 'static)>`
5+
| --------------------------------------------------------------------- expected `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + 'static)>`
66
...
77
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType> + '_> {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&T) -> Box<dyn MyTrait<Item = &T>>`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + '1)>`
99
|
10-
= note: expected `fn(&T) -> Box<(dyn MyTrait<Item = &T> + 'static)>`
11-
found `fn(&T) -> Box<dyn MyTrait<Item = &T>>`
10+
= note: expected `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + 'static)>`
11+
found `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + '1)>`
1212
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
1313
--> $DIR/issue-75361-mismatched-impl.rs:12:55
1414
|

src/test/ui/traits/param-without-lifetime-constraint.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/param-without-lifetime-constraint.rs:14:5
33
|
44
LL | fn get_relation(&self) -> To;
5-
| ----------------------------- expected `fn(&Article) -> &ProofReader`
5+
| ----------------------------- expected `fn(&'1 Article) -> &'2 ProofReader`
66
...
77
LL | fn get_relation(&self) -> &ProofReader {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Article) -> &ProofReader`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Article) -> &'1 ProofReader`
99
|
10-
= note: expected `fn(&Article) -> &ProofReader`
11-
found `fn(&Article) -> &ProofReader`
10+
= note: expected `fn(&'1 Article) -> &'2 ProofReader`
11+
found `fn(&'1 Article) -> &'1 ProofReader`
1212
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
1313
--> $DIR/param-without-lifetime-constraint.rs:10:31
1414
|

src/test/ui/traits/self-without-lifetime-constraint.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/self-without-lifetime-constraint.rs:45:5
33
|
44
LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self, &Self>;
5-
| -------------------------------------------------------------------- expected `fn(ValueRef<'_>) -> Result<(&str, &&str), FromSqlError>`
5+
| -------------------------------------------------------------------- expected `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>`
66
...
77
LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(ValueRef<'_>) -> Result<(&str, &&str), FromSqlError>`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>`
99
|
10-
= note: expected `fn(ValueRef<'_>) -> Result<(&str, &&str), _>`
11-
found `fn(ValueRef<'_>) -> Result<(&str, &&str), _>`
10+
= note: expected `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>`
11+
found `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>`
1212
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
1313
--> $DIR/self-without-lifetime-constraint.rs:41:60
1414
|

0 commit comments

Comments
 (0)