Skip to content

Commit f213acf

Browse files
committed
review comments: change wording and visual output
1 parent cb6408a commit f213acf

File tree

6 files changed

+26
-59
lines changed

6 files changed

+26
-59
lines changed

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

+16-47
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
44
use crate::infer::lexical_region_resolve::RegionResolutionError;
55
use crate::infer::{Subtype, TyCtxtInferExt, ValuePairs};
66
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
7-
use rustc_data_structures::fx::FxIndexSet;
87
use rustc_errors::ErrorReported;
98
use rustc_hir as hir;
109
use rustc_hir::def_id::DefId;
1110
use rustc_hir::intravisit::Visitor;
12-
use rustc_hir::ItemKind;
1311
use rustc_middle::ty::error::ExpectedFound;
14-
use rustc_middle::ty::fold::TypeFoldable;
1512
use rustc_middle::ty::{self, Ty, TyCtxt};
16-
use rustc_span::Span;
13+
use rustc_span::{MultiSpan, Span};
1714

1815
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
1916
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
@@ -63,41 +60,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
6360
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
6461
err.span_label(sp, &format!("found `{:?}`", found));
6562
err.span_label(trait_sp, &format!("expected `{:?}`", expected));
66-
let trait_fn_sig = tcx.fn_sig(trait_def_id);
67-
68-
// Check the `trait`'s method's output to look for type parameters that might have
69-
// unconstrained lifetimes. If the method returns a type parameter and the `impl` has a
70-
// borrow as the type parameter being implemented, the lifetimes will not match because
71-
// a new lifetime is being introduced in the `impl` that is not present in the `trait`.
72-
// Because this is confusing as hell the first time you see it, we give a short message
73-
// explaining the situation and proposing constraining the type param with a named lifetime
74-
// so that the `impl` will have one to tie them together.
75-
struct AssocTypeFinder(FxIndexSet<ty::ParamTy>);
76-
impl<'tcx> ty::fold::TypeVisitor<'tcx> for AssocTypeFinder {
77-
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
78-
if let ty::Param(param) = ty.kind {
79-
self.0.insert(param);
80-
}
81-
ty.super_visit_with(self)
82-
}
83-
}
84-
let mut visitor = AssocTypeFinder(FxIndexSet::default());
85-
trait_fn_sig.output().visit_with(&mut visitor);
86-
if let Some(id) = trait_def_id.as_local().map(|id| tcx.hir().as_local_hir_id(id)) {
87-
let parent_id = tcx.hir().get_parent_item(id);
88-
let trait_item = tcx.hir().expect_item(parent_id);
89-
if let ItemKind::Trait(_, _, generics, _, _) = &trait_item.kind {
90-
for param_ty in &visitor.0 {
91-
if let Some(generic) = generics.get_named(param_ty.name) {
92-
err.span_label(
93-
generic.span,
94-
"this type parameter might not have a lifetime compatible with the \
95-
`impl`",
96-
);
97-
}
98-
}
99-
}
100-
}
10163

10264
// Get the span of all the used type parameters in the method.
10365
let assoc_item = self.tcx().associated_item(trait_def_id);
@@ -114,11 +76,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
11476
}
11577
_ => {}
11678
}
117-
for span in visitor.types {
118-
err.span_label(
79+
let mut type_param_span: MultiSpan =
80+
visitor.types.iter().cloned().collect::<Vec<_>>().into();
81+
for &span in &visitor.types {
82+
type_param_span.push_span_label(
11983
span,
120-
"you might want to borrow this type parameter in the trait to make it match the \
121-
`impl`",
84+
"consider borrowing this type parameter in the trait".to_string(),
12285
);
12386
}
12487

@@ -132,11 +95,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
13295
// This fallback shouldn't be necessary, but let's keep it in just in case.
13396
err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found));
13497
}
135-
err.note("the lifetime requirements from the `trait` could not be satisfied by the `impl`");
136-
err.help(
137-
"verify the lifetime relationships in the `trait` and `impl` between the `self` \
138-
argument, the other inputs and its output",
98+
err.span_help(
99+
type_param_span,
100+
"the lifetime requirements from the `impl` do not correspond to the requirements in \
101+
the `trait`",
139102
);
103+
if visitor.types.is_empty() {
104+
err.help(
105+
"verify the lifetime relationships in the `trait` and `impl` between the `self` \
106+
argument, the other inputs and its output",
107+
);
108+
}
140109
err.emit();
141110
}
142111
}

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

+1-1
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 satisfied by the `impl`
14+
= 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

1717
error: aborting due to previous error

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

+1-1
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 satisfied by the `impl`
12+
= 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

1515
error: aborting due to previous error

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

+1-1
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 satisfied by the `impl`
12+
= 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

1515
error[E0623]: lifetime mismatch

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

+1-1
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 satisfied by the `impl`
12+
= 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

1515
error: aborting due to previous error
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
error: `impl` item signature doesn't match `trait` item signature
22
--> $DIR/trait-param-without-lifetime-constraint.rs:14:5
33
|
4-
LL | pub trait HaveRelationship<To> {
5-
| -- this type parameter might not have a lifetime compatible with the `impl`
64
LL | fn get_relation(&self) -> To;
7-
| -----------------------------
8-
| | |
9-
| | you might want to borrow this type parameter in the trait to make it match the `impl`
10-
| expected `fn(&Article) -> &ProofReader`
5+
| ----------------------------- expected `fn(&Article) -> &ProofReader`
116
...
127
LL | fn get_relation(&self) -> &ProofReader {
138
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Article) -> &ProofReader`
149
|
1510
= note: expected `fn(&Article) -> &ProofReader`
1611
found `fn(&Article) -> &ProofReader`
17-
= note: the lifetime requirements from the `trait` could not be satisfied by the `impl`
18-
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
12+
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
13+
--> $DIR/trait-param-without-lifetime-constraint.rs:10:31
14+
|
15+
LL | fn get_relation(&self) -> To;
16+
| ^^ consider borrowing this type parameter in the trait
1917

2018
error: aborting due to previous error
2119

0 commit comments

Comments
 (0)