Skip to content

Commit 2b35247

Browse files
committed
Modify wording
1 parent d0d30b0 commit 2b35247

File tree

5 files changed

+84
-20
lines changed

5 files changed

+84
-20
lines changed

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

+72-11
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
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_data_structures::fx::FxIndexSet;
88
use rustc_errors::ErrorReported;
9+
use rustc_hir as hir;
910
use rustc_hir::def_id::DefId;
11+
use rustc_hir::intravisit::Visitor;
1012
use rustc_hir::ItemKind;
1113
use rustc_middle::ty::error::ExpectedFound;
1214
use rustc_middle::ty::fold::TypeFoldable;
13-
use rustc_middle::ty::{self, Ty};
15+
use rustc_middle::ty::{self, Ty, TyCtxt};
1416
use rustc_span::Span;
1517

1618
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@@ -59,8 +61,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
5961
.tcx()
6062
.sess
6163
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
62-
err.span_label(sp, &format!("found {:?}", found));
63-
err.span_label(trait_sp, &format!("expected {:?}", expected));
64+
err.span_label(sp, &format!("found `{:?}`", found));
65+
err.span_label(trait_sp, &format!("expected `{:?}`", expected));
6466
let trait_fn_sig = tcx.fn_sig(trait_def_id);
6567

6668
// Check the `trait`'s method's output to look for type parameters that might have
@@ -73,7 +75,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
7375
struct AssocTypeFinder(FxIndexSet<ty::ParamTy>);
7476
impl<'tcx> ty::fold::TypeVisitor<'tcx> for AssocTypeFinder {
7577
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
76-
debug!("assoc type finder ty {:?} {:?}", ty, ty.kind);
7778
if let ty::Param(param) = ty.kind {
7879
self.0.insert(param);
7980
}
@@ -86,18 +87,40 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
8687
let parent_id = tcx.hir().get_parent_item(id);
8788
let trait_item = tcx.hir().expect_item(parent_id);
8889
if let ItemKind::Trait(_, _, generics, _, _) = &trait_item.kind {
89-
for param_ty in visitor.0 {
90+
for param_ty in &visitor.0 {
9091
if let Some(generic) = generics.get_named(param_ty.name) {
91-
err.span_label(generic.span, &format!(
92-
"for `impl` items to implement the method, this type parameter might \
93-
need a lifetime restriction like `{}: 'a`",
94-
param_ty.name,
95-
));
92+
err.span_label(
93+
generic.span,
94+
"this type parameter might not have a lifetime compatible with the \
95+
`impl`",
96+
);
9697
}
9798
}
9899
}
99100
}
100101

102+
// Get the span of all the used type parameters in the method.
103+
let assoc_item = self.tcx().associated_item(trait_def_id);
104+
let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] };
105+
match assoc_item.kind {
106+
ty::AssocKind::Method => {
107+
let hir = self.tcx().hir();
108+
if let Some(hir_id) = hir.as_local_hir_id(assoc_item.def_id) {
109+
if let Some(decl) = hir.fn_decl_by_hir_id(hir_id) {
110+
visitor.visit_fn_decl(decl);
111+
}
112+
}
113+
}
114+
_ => {}
115+
}
116+
for span in visitor.types {
117+
err.span_label(
118+
span,
119+
"you might want to borrow this type parameter in the trait to make it match the \
120+
`impl`",
121+
);
122+
}
123+
101124
if let Some((expected, found)) = tcx
102125
.infer_ctxt()
103126
.enter(|infcx| infcx.expected_found_str_ty(&ExpectedFound { expected, found }))
@@ -116,3 +139,41 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
116139
err.emit();
117140
}
118141
}
142+
143+
struct TypeParamSpanVisitor<'tcx> {
144+
tcx: TyCtxt<'tcx>,
145+
types: Vec<Span>,
146+
}
147+
148+
impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
149+
type Map = hir::intravisit::Map<'tcx>;
150+
151+
fn nested_visit_map<'this>(
152+
&'this mut self,
153+
) -> hir::intravisit::NestedVisitorMap<'this, Self::Map> {
154+
hir::intravisit::NestedVisitorMap::OnlyBodies(&self.tcx.hir())
155+
}
156+
157+
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
158+
match arg.kind {
159+
hir::TyKind::Slice(_) | hir::TyKind::Tup(_) | hir::TyKind::Array(..) => {
160+
hir::intravisit::walk_ty(self, arg);
161+
}
162+
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
163+
[segment]
164+
if segment
165+
.res
166+
.map(|res| match res {
167+
hir::def::Res::Def(hir::def::DefKind::TyParam, _) => true,
168+
_ => false,
169+
})
170+
.unwrap_or(false) =>
171+
{
172+
self.types.push(path.span);
173+
}
174+
_ => {}
175+
},
176+
_ => {}
177+
}
178+
}
179+
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ 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`

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ 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`

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ 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`

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ 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-
| -- for `impl` items to implement the method, this type parameter might need a lifetime restriction like `To: 'a`
5+
| -- this type parameter might not have a lifetime compatible with the `impl`
66
LL | fn get_relation(&self) -> To;
7-
| ----------------------------- expected fn(&Article) -> &ProofReader
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`
811
...
912
LL | fn get_relation(&self) -> &ProofReader {
10-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Article) -> &ProofReader
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Article) -> &ProofReader`
1114
|
1215
= note: expected `fn(&Article) -> &ProofReader`
1316
found `fn(&Article) -> &ProofReader`

0 commit comments

Comments
 (0)