Modify wording

This commit is contained in:
Esteban Küber 2020-02-16 17:59:29 -08:00
parent d0d30b0a3e
commit 2b35247d7a
5 changed files with 84 additions and 20 deletions

View File

@ -2,15 +2,17 @@
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::{Subtype, ValuePairs};
use crate::infer::{Subtype, TyCtxtInferExt, ValuePairs};
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::ItemKind;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@ -59,8 +61,8 @@ fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id:
.tcx()
.sess
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
err.span_label(sp, &format!("found {:?}", found));
err.span_label(trait_sp, &format!("expected {:?}", expected));
err.span_label(sp, &format!("found `{:?}`", found));
err.span_label(trait_sp, &format!("expected `{:?}`", expected));
let trait_fn_sig = tcx.fn_sig(trait_def_id);
// Check the `trait`'s method's output to look for type parameters that might have
@ -73,7 +75,6 @@ fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id:
struct AssocTypeFinder(FxIndexSet<ty::ParamTy>);
impl<'tcx> ty::fold::TypeVisitor<'tcx> for AssocTypeFinder {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
debug!("assoc type finder ty {:?} {:?}", ty, ty.kind);
if let ty::Param(param) = ty.kind {
self.0.insert(param);
}
@ -86,18 +87,40 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
let parent_id = tcx.hir().get_parent_item(id);
let trait_item = tcx.hir().expect_item(parent_id);
if let ItemKind::Trait(_, _, generics, _, _) = &trait_item.kind {
for param_ty in visitor.0 {
for param_ty in &visitor.0 {
if let Some(generic) = generics.get_named(param_ty.name) {
err.span_label(generic.span, &format!(
"for `impl` items to implement the method, this type parameter might \
need a lifetime restriction like `{}: 'a`",
param_ty.name,
));
err.span_label(
generic.span,
"this type parameter might not have a lifetime compatible with the \
`impl`",
);
}
}
}
}
// Get the span of all the used type parameters in the method.
let assoc_item = self.tcx().associated_item(trait_def_id);
let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] };
match assoc_item.kind {
ty::AssocKind::Method => {
let hir = self.tcx().hir();
if let Some(hir_id) = hir.as_local_hir_id(assoc_item.def_id) {
if let Some(decl) = hir.fn_decl_by_hir_id(hir_id) {
visitor.visit_fn_decl(decl);
}
}
}
_ => {}
}
for span in visitor.types {
err.span_label(
span,
"you might want to borrow this type parameter in the trait to make it match the \
`impl`",
);
}
if let Some((expected, found)) = tcx
.infer_ctxt()
.enter(|infcx| infcx.expected_found_str_ty(&ExpectedFound { expected, found }))
@ -116,3 +139,41 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
err.emit();
}
}
struct TypeParamSpanVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
types: Vec<Span>,
}
impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
type Map = hir::intravisit::Map<'tcx>;
fn nested_visit_map<'this>(
&'this mut self,
) -> hir::intravisit::NestedVisitorMap<'this, Self::Map> {
hir::intravisit::NestedVisitorMap::OnlyBodies(&self.tcx.hir())
}
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
match arg.kind {
hir::TyKind::Slice(_) | hir::TyKind::Tup(_) | hir::TyKind::Array(..) => {
hir::intravisit::walk_ty(self, arg);
}
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
[segment]
if segment
.res
.map(|res| match res {
hir::def::Res::Def(hir::def::DefKind::TyParam, _) => true,
_ => false,
})
.unwrap_or(false) =>
{
self.types.push(path.span);
}
_ => {}
},
_ => {}
}
}
}

View File

@ -2,12 +2,12 @@ error: `impl` item signature doesn't match `trait` item signature
--> $DIR/mismatched_trait_impl-2.rs:8:5
|
LL | fn deref(&self) -> &dyn Trait {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Struct) -> &dyn Trait`
|
::: $SRC_DIR/libcore/ops/deref.rs:LL:COL
|
LL | fn deref(&self) -> &Self::Target;
| --------------------------------- expected fn(&Struct) -> &(dyn Trait + 'static)
| --------------------------------- expected `fn(&Struct) -> &(dyn Trait + 'static)`
|
= note: expected `fn(&Struct) -> &(dyn Trait + 'static)`
found `fn(&Struct) -> &dyn Trait`

View File

@ -2,10 +2,10 @@ error: `impl` item signature doesn't match `trait` item signature
--> $DIR/mismatched_trait_impl.rs:9:5
|
LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32;
| ---------------------------------------------- expected fn(&i32, &'a u32, &u32) -> &'a u32
| ---------------------------------------------- expected `fn(&i32, &'a u32, &u32) -> &'a u32`
...
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &u32, &u32) -> &u32`
|
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
found `fn(&i32, &u32, &u32) -> &u32`

View File

@ -2,10 +2,10 @@ error: `impl` item signature doesn't match `trait` item signature
--> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5
|
LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
| ------------------------------------------- expected fn(&i32, &'a i32) -> &'a i32
| ------------------------------------------- expected `fn(&i32, &'a i32) -> &'a i32`
...
LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &i32) -> &i32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &i32) -> &i32`
|
= note: expected `fn(&i32, &'a i32) -> &'a i32`
found `fn(&i32, &i32) -> &i32`

View File

@ -2,12 +2,15 @@ error: `impl` item signature doesn't match `trait` item signature
--> $DIR/trait-param-without-lifetime-constraint.rs:14:5
|
LL | pub trait HaveRelationship<To> {
| -- for `impl` items to implement the method, this type parameter might need a lifetime restriction like `To: 'a`
| -- this type parameter might not have a lifetime compatible with the `impl`
LL | fn get_relation(&self) -> To;
| ----------------------------- expected fn(&Article) -> &ProofReader
| -----------------------------
| | |
| | you might want to borrow this type parameter in the trait to make it match the `impl`
| expected `fn(&Article) -> &ProofReader`
...
LL | fn get_relation(&self) -> &ProofReader {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Article) -> &ProofReader
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Article) -> &ProofReader`
|
= note: expected `fn(&Article) -> &ProofReader`
found `fn(&Article) -> &ProofReader`