Skip to content

Commit 3811232

Browse files
committed
review comments
1 parent eb0f4d5 commit 3811232

File tree

6 files changed

+24
-46
lines changed

6 files changed

+24
-46
lines changed

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

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -63,78 +63,56 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
6363
err.span_label(trait_sp, &format!("expected {:?}", expected));
6464
let trait_fn_sig = tcx.fn_sig(trait_def_id);
6565

66+
// Check the `trait`'s method's output to look for type parameters that might have
67+
// unconstrained lifetimes. If the method returns a type parameter and the `impl` has a
68+
// borrow as the type parameter being implemented, the lifetimes will not match because
69+
// a new lifetime is being introduced in the `impl` that is not present in the `trait`.
70+
// Because this is confusing as hell the first time you see it, we give a short message
71+
// explaining the situation and proposing constraining the type param with a named lifetime
72+
// so that the `impl` will have one to tie them together.
6673
struct AssocTypeFinder(FxHashSet<ty::ParamTy>);
6774
impl<'tcx> ty::fold::TypeVisitor<'tcx> for AssocTypeFinder {
6875
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
6976
debug!("assoc type finder ty {:?} {:?}", ty, ty.kind);
70-
match ty.kind {
71-
ty::Param(param) => {
72-
self.0.insert(param);
73-
}
74-
_ => {}
77+
if let ty::Param(param) = ty.kind {
78+
self.0.insert(param);
7579
}
7680
ty.super_visit_with(self)
7781
}
7882
}
7983
let mut visitor = AssocTypeFinder(FxHashSet::default());
8084
trait_fn_sig.output().visit_with(&mut visitor);
81-
8285
if let Some(id) = tcx.hir().as_local_hir_id(trait_def_id) {
8386
let parent_id = tcx.hir().get_parent_item(id);
8487
let trait_item = tcx.hir().expect_item(parent_id);
8588
if let hir::ItemKind::Trait(_, _, generics, _, _) = &trait_item.kind {
8689
for param_ty in visitor.0 {
8790
if let Some(generic) = generics.get_named(param_ty.name) {
8891
err.span_label(generic.span, &format!(
89-
"in order for `impl` items to be able to implement the method, this \
90-
type parameter might need a lifetime restriction like `{}: 'a`",
92+
"for `impl` items to implement the method, this type parameter might \
93+
need a lifetime restriction like `{}: 'a`",
9194
param_ty.name,
9295
));
9396
}
9497
}
9598
}
9699
}
97100

98-
struct EarlyBoundRegionHighlighter(FxHashSet<DefId>);
99-
impl<'tcx> ty::fold::TypeVisitor<'tcx> for EarlyBoundRegionHighlighter {
100-
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
101-
match *r {
102-
ty::ReFree(free) => {
103-
self.0.insert(free.scope);
104-
}
105-
ty::ReEarlyBound(bound) => {
106-
self.0.insert(bound.def_id);
107-
}
108-
_ => {}
109-
}
110-
r.super_visit_with(self)
111-
}
112-
}
113-
114-
let mut visitor = EarlyBoundRegionHighlighter(FxHashSet::default());
115-
expected.visit_with(&mut visitor);
116-
117-
let note = !visitor.0.is_empty();
118-
119-
if let Some((expected, found)) = self
120-
.tcx()
101+
if let Some((expected, found)) = tcx
121102
.infer_ctxt()
122103
.enter(|infcx| infcx.expected_found_str_ty(&ExpectedFound { expected, found }))
123104
{
105+
// Highlighted the differences when showing the "expected/found" note.
124106
err.note_expected_found(&"", expected, &"", found);
125107
} else {
126108
// This fallback shouldn't be necessary, but let's keep it in just in case.
127109
err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found));
128110
}
129-
if note {
130-
err.note(
131-
"the lifetime requirements from the `trait` could not be fulfilled by the `impl`",
132-
);
133-
err.help(
134-
"verify the lifetime relationships in the `trait` and `impl` between the \
135-
`self` argument, the other inputs and its output",
136-
);
137-
}
111+
err.note("the lifetime requirements from the `trait` could not be satisfied by the `impl`");
112+
err.help(
113+
"verify the lifetime relationships in the `trait` and `impl` between the `self` \
114+
argument, the other inputs and its output",
115+
);
138116
err.emit();
139117
}
140118
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | fn deref(&self) -> &Self::Target;
1111
|
1212
= note: expected `fn(&Struct) -> &(dyn Trait + 'static)`
1313
found `fn(&Struct) -> &dyn Trait`
14-
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
14+
= note: the lifetime requirements from the `trait` could not be satisfied by the `impl`
1515
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1616

1717
error: aborting due to previous error

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
99
|
1010
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
1111
found `fn(&i32, &u32, &u32) -> &u32`
12-
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
12+
= note: the lifetime requirements from the `trait` could not be satisfied by the `impl`
1313
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1414

1515
error: aborting due to previous error

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
99
|
1010
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
1111
found `fn(&i32, &u32, &u32) -> &u32`
12-
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
12+
= note: the lifetime requirements from the `trait` could not be satisfied by the `impl`
1313
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1414

1515
error[E0623]: lifetime mismatch

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
99
|
1010
= note: expected `fn(&i32, &'a i32) -> &'a i32`
1111
found `fn(&i32, &i32) -> &i32`
12-
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
12+
= note: the lifetime requirements from the `trait` could not be satisfied by the `impl`
1313
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1414

1515
error: aborting due to previous error

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/trait-param-without-lifetime-constraint.rs:14:5
33
|
44
LL | pub trait HaveRelationship<To> {
5-
| -- in order for `impl` items to be able to implement the method, this type parameter might need a lifetime restriction like `To: 'a`
5+
| -- for `impl` items to implement the method, this type parameter might need a lifetime restriction like `To: 'a`
66
LL | fn get_relation(&self) -> To;
77
| ----------------------------- expected fn(&Article) -> &ProofReader
88
...
@@ -11,7 +11,7 @@ LL | fn get_relation(&self) -> &ProofReader {
1111
|
1212
= note: expected `fn(&Article) -> &ProofReader`
1313
found `fn(&Article) -> &ProofReader`
14-
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
14+
= note: the lifetime requirements from the `trait` could not be satisfied by the `impl`
1515
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
1616

1717
error: aborting due to previous error

0 commit comments

Comments
 (0)