Skip to content

Commit 8120780

Browse files
authored
Rollup merge of #67460 - estebank:named-lts, r=nikomatsakis
Tweak impl signature mismatch errors involving `RegionKind::ReVar` lifetimes Fix #66406, fix #72106. ``` error: `impl` item signature doesn't match `trait` item signature --> $DIR/trait-param-without-lifetime-constraint.rs:14:5 | LL | fn get_relation(&self) -> To; | ----------------------------- expected `fn(&Article) -> &ProofReader` ... LL | fn get_relation(&self) -> &ProofReader { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Article) -> &ProofReader` | = note: expected `fn(&Article) -> &ProofReader` found `fn(&Article) -> &ProofReader` help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` --> $DIR/trait-param-without-lifetime-constraint.rs:10:31 | LL | fn get_relation(&self) -> To; | ^^ consider borrowing this type parameter in the trait ``` r? @nikomatsakis
2 parents 96dd469 + 1bd6970 commit 8120780

File tree

40 files changed

+324
-105
lines changed

40 files changed

+324
-105
lines changed

src/librustc_errors/diagnostic.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,18 @@ impl Diagnostic {
193193
expected_extra: &dyn fmt::Display,
194194
found_extra: &dyn fmt::Display,
195195
) -> &mut Self {
196-
let expected_label = format!("expected {}", expected_label);
197-
198-
let found_label = format!("found {}", found_label);
196+
let expected_label = expected_label.to_string();
197+
let expected_label = if expected_label.is_empty() {
198+
"expected".to_string()
199+
} else {
200+
format!("expected {}", expected_label)
201+
};
202+
let found_label = found_label.to_string();
203+
let found_label = if found_label.is_empty() {
204+
"found".to_string()
205+
} else {
206+
format!("found {}", found_label)
207+
};
199208
let (found_padding, expected_padding) = if expected_label.len() > found_label.len() {
200209
(expected_label.len() - found_label.len(), 0)
201210
} else {

src/librustc_infer/infer/error_reporting/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -987,12 +987,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
987987
}
988988

989989
fn push_ty_ref<'tcx>(
990-
r: &ty::Region<'tcx>,
990+
region: &ty::Region<'tcx>,
991991
ty: Ty<'tcx>,
992992
mutbl: hir::Mutability,
993993
s: &mut DiagnosticStyledString,
994994
) {
995-
let mut r = r.to_string();
995+
let mut r = region.to_string();
996996
if r == "'_" {
997997
r.clear();
998998
} else {

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

+99-8
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
33
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
44
use crate::infer::lexical_region_resolve::RegionResolutionError;
5-
use crate::infer::{Subtype, ValuePairs};
5+
use crate::infer::{Subtype, TyCtxtInferExt, ValuePairs};
66
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
77
use rustc_errors::ErrorReported;
8-
use rustc_middle::ty::Ty;
9-
use rustc_span::Span;
8+
use rustc_hir as hir;
9+
use rustc_hir::def::Res;
10+
use rustc_hir::def_id::DefId;
11+
use rustc_hir::intravisit::Visitor;
12+
use rustc_middle::ty::error::ExpectedFound;
13+
use rustc_middle::ty::{self, Ty, TyCtxt};
14+
use rustc_span::{MultiSpan, Span};
1015

1116
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
1217
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
@@ -36,7 +41,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
3641
var_origin.span(),
3742
sub_expected_found.expected,
3843
sub_expected_found.found,
39-
self.tcx().def_span(*trait_item_def_id),
44+
*trait_item_def_id,
4045
);
4146
return Some(ErrorReported);
4247
}
@@ -47,14 +52,100 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
4752
None
4853
}
4954

50-
fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Span) {
55+
fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) {
56+
let tcx = self.tcx();
57+
let trait_sp = self.tcx().def_span(trait_def_id);
5158
let mut err = self
5259
.tcx()
5360
.sess
5461
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
55-
err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found));
56-
err.span_label(sp, &format!("found {:?}", found));
57-
err.span_label(impl_sp, &format!("expected {:?}", expected));
62+
err.span_label(sp, &format!("found `{:?}`", found));
63+
err.span_label(trait_sp, &format!("expected `{:?}`", expected));
64+
65+
// Get the span of all the used type parameters in the method.
66+
let assoc_item = self.tcx().associated_item(trait_def_id);
67+
let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] };
68+
match assoc_item.kind {
69+
ty::AssocKind::Fn => {
70+
let hir = self.tcx().hir();
71+
if let Some(hir_id) = assoc_item.def_id.as_local().map(|id| hir.as_local_hir_id(id))
72+
{
73+
if let Some(decl) = hir.fn_decl_by_hir_id(hir_id) {
74+
visitor.visit_fn_decl(decl);
75+
}
76+
}
77+
}
78+
_ => {}
79+
}
80+
let mut type_param_span: MultiSpan =
81+
visitor.types.iter().cloned().collect::<Vec<_>>().into();
82+
for &span in &visitor.types {
83+
type_param_span.push_span_label(
84+
span,
85+
"consider borrowing this type parameter in the trait".to_string(),
86+
);
87+
}
88+
89+
if let Some((expected, found)) = tcx
90+
.infer_ctxt()
91+
.enter(|infcx| infcx.expected_found_str_ty(&ExpectedFound { expected, found }))
92+
{
93+
// Highlighted the differences when showing the "expected/found" note.
94+
err.note_expected_found(&"", expected, &"", found);
95+
} else {
96+
// This fallback shouldn't be necessary, but let's keep it in just in case.
97+
err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found));
98+
}
99+
err.span_help(
100+
type_param_span,
101+
"the lifetime requirements from the `impl` do not correspond to the requirements in \
102+
the `trait`",
103+
);
104+
if visitor.types.is_empty() {
105+
err.help(
106+
"verify the lifetime relationships in the `trait` and `impl` between the `self` \
107+
argument, the other inputs and its output",
108+
);
109+
}
58110
err.emit();
59111
}
60112
}
113+
114+
struct TypeParamSpanVisitor<'tcx> {
115+
tcx: TyCtxt<'tcx>,
116+
types: Vec<Span>,
117+
}
118+
119+
impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
120+
type Map = rustc_middle::hir::map::Map<'tcx>;
121+
122+
fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
123+
hir::intravisit::NestedVisitorMap::OnlyBodies(self.tcx.hir())
124+
}
125+
126+
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
127+
match arg.kind {
128+
hir::TyKind::Rptr(_, ref mut_ty) => {
129+
// We don't want to suggest looking into borrowing `&T` or `&Self`.
130+
hir::intravisit::walk_ty(self, mut_ty.ty);
131+
return;
132+
}
133+
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
134+
[segment]
135+
if segment
136+
.res
137+
.map(|res| match res {
138+
Res::SelfTy(_, _) | Res::Def(hir::def::DefKind::TyParam, _) => true,
139+
_ => false,
140+
})
141+
.unwrap_or(false) =>
142+
{
143+
self.types.push(path.span);
144+
}
145+
_ => {}
146+
},
147+
_ => {}
148+
}
149+
hir::intravisit::walk_ty(self, arg);
150+
}
151+
}

src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ note: ...so that the expression is assignable
1414
|
1515
LL | bar(foo, x)
1616
| ^
17-
= note: expected `Type<'_>`
18-
found `Type<'a>`
17+
= note: expected `Type<'_>`
18+
found `Type<'a>`
1919
= note: but, the lifetime must be valid for the static lifetime...
2020
note: ...so that the expression is assignable
2121
--> $DIR/project-fn-ret-invariant.rs:48:4
2222
|
2323
LL | bar(foo, x)
2424
| ^^^^^^^^^^^
25-
= note: expected `Type<'static>`
26-
found `Type<'_>`
25+
= note: expected `Type<'static>`
26+
found `Type<'_>`
2727

2828
error: aborting due to previous error
2929

src/test/ui/error-codes/E0490.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ note: ...so that the expression is assignable
5858
|
5959
LL | let x: &'a _ = &y;
6060
| ^^
61-
= note: expected `&'a &()`
62-
found `&'a &'b ()`
61+
= note: expected `&'a &()`
62+
found `&'a &'b ()`
6363
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 1:6...
6464
--> $DIR/E0490.rs:1:6
6565
|

src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ note: ...so that the expression is assignable
1414
|
1515
LL | static_val(x);
1616
| ^
17-
= note: expected `std::boxed::Box<dyn std::fmt::Debug>`
18-
found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>`
17+
= note: expected `std::boxed::Box<dyn std::fmt::Debug>`
18+
found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>`
1919
= note: but, the lifetime must be valid for the static lifetime...
2020
note: ...so that the types are compatible
2121
--> $DIR/dyn-trait.rs:20:5
2222
|
2323
LL | static_val(x);
2424
| ^^^^^^^^^^
25-
= note: expected `StaticTrait`
26-
found `StaticTrait`
25+
= note: expected `StaticTrait`
26+
found `StaticTrait`
2727

2828
error: aborting due to previous error
2929

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ 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(&Struct) -> &dyn Trait`
66
|
77
::: $SRC_DIR/libcore/ops/deref.rs:LL:COL
88
|
99
LL | fn deref(&self) -> &Self::Target;
10-
| --------------------------------- expected fn(&Struct) -> &(dyn Trait + 'static)
10+
| --------------------------------- expected `fn(&Struct) -> &(dyn Trait + 'static)`
1111
|
1212
= note: expected `fn(&Struct) -> &(dyn Trait + 'static)`
1313
found `fn(&Struct) -> &dyn Trait`
14+
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
15+
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1416

1517
error: aborting due to previous error
1618

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ 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(&i32, &'a u32, &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(&i32, &u32, &u32) -> &u32`
99
|
1010
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
1111
found `fn(&i32, &u32, &u32) -> &u32`
12+
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
13+
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1214

1315
error: aborting due to previous error
1416

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ 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(&i32, &'a u32, &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(&i32, &u32, &u32) -> &u32`
99
|
1010
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
1111
found `fn(&i32, &u32, &u32) -> &u32`
12+
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
13+
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1214

1315
error[E0623]: lifetime mismatch
1416
--> $DIR/mismatched_trait_impl.rs:10:9

src/test/ui/issues/issue-16683.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ note: ...so that the types are compatible
2626
|
2727
LL | self.a();
2828
| ^
29-
= note: expected `&'a Self`
30-
found `&Self`
29+
= note: expected `&'a Self`
30+
found `&Self`
3131

3232
error: aborting due to previous error
3333

src/test/ui/issues/issue-17758.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ note: ...so that the types are compatible
2727
|
2828
LL | self.foo();
2929
| ^^^
30-
= note: expected `&'a Self`
31-
found `&Self`
30+
= note: expected `&'a Self`
31+
found `&Self`
3232

3333
error: aborting due to previous error
3434

src/test/ui/issues/issue-20831-debruijn.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ note: ...so that the types are compatible
8787
|
8888
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
8989
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90-
= note: expected `Publisher<'_>`
91-
found `Publisher<'_>`
90+
= note: expected `Publisher<'_>`
91+
found `Publisher<'_>`
9292

9393
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
9494
--> $DIR/issue-20831-debruijn.rs:28:33
@@ -117,8 +117,8 @@ note: ...so that the types are compatible
117117
|
118118
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
119119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120-
= note: expected `Publisher<'_>`
121-
found `Publisher<'_>`
120+
= note: expected `Publisher<'_>`
121+
found `Publisher<'_>`
122122

123123
error: aborting due to 4 previous errors
124124

src/test/ui/issues/issue-52213.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ note: ...so that the types are compatible
1414
|
1515
LL | match (&t,) {
1616
| ^^^^^
17-
= note: expected `(&&(T,),)`
18-
found `(&&'a (T,),)`
17+
= note: expected `(&&(T,),)`
18+
found `(&&'a (T,),)`
1919
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 1:27...
2020
--> $DIR/issue-52213.rs:1:27
2121
|

src/test/ui/issues/issue-55796.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ note: ...so that the expression is assignable
2020
|
2121
LL | Box::new(self.out_edges(u).map(|e| e.target()))
2222
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23-
= note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node> + 'static)>`
24-
found `std::boxed::Box<dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node>>`
23+
= note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node> + 'static)>`
24+
found `std::boxed::Box<dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node>>`
2525

2626
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
2727
--> $DIR/issue-55796.rs:21:9
@@ -45,8 +45,8 @@ note: ...so that the expression is assignable
4545
|
4646
LL | Box::new(self.in_edges(u).map(|e| e.target()))
4747
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48-
= note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node> + 'static)>`
49-
found `std::boxed::Box<dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node>>`
48+
= note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node> + 'static)>`
49+
found `std::boxed::Box<dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node>>`
5050

5151
error: aborting due to 2 previous errors
5252

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ 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(&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(&i32, &i32) -> &i32`
99
|
1010
= note: expected `fn(&i32, &'a i32) -> &'a i32`
1111
found `fn(&i32, &i32) -> &i32`
12+
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
13+
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1214

1315
error: aborting due to previous error
1416

src/test/ui/nll/issue-55394.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ note: ...so that the expression is assignable
2626
|
2727
LL | Foo { bar }
2828
| ^^^^^^^^^^^
29-
= note: expected `Foo<'_>`
30-
found `Foo<'_>`
29+
= note: expected `Foo<'_>`
30+
found `Foo<'_>`
3131

3232
error: aborting due to previous error
3333

src/test/ui/nll/normalization-bounds-error.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ note: ...so that the types are compatible
1919
|
2020
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
2121
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22-
= note: expected `Visitor<'d>`
23-
found `Visitor<'_>`
22+
= note: expected `Visitor<'d>`
23+
found `Visitor<'_>`
2424

2525
error: aborting due to previous error
2626

0 commit comments

Comments
 (0)