Tweak output for mismatched impl item
Detect type parameter that might require lifetime constraint. Do not name `ReVar`s in expected/found output. Reword text suggesting to check the lifetimes.
This commit is contained in:
parent
5ba22205a4
commit
eb0f4d51df
38 changed files with 126 additions and 56 deletions
|
@ -993,10 +993,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
s: &mut DiagnosticStyledString,
|
||||
) {
|
||||
let mut r = region.to_string();
|
||||
if let ty::RegionKind::ReVar(var) = region {
|
||||
// Show these named, not as `'_` or elide them in "expected/found" notes.
|
||||
r = format!("'z{} ", var.index());
|
||||
} else if r == "'_" {
|
||||
if r == "'_" {
|
||||
r.clear();
|
||||
} else {
|
||||
r.push(' ');
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Error Reporting for `impl` items that do not match the obligations from their `trait`.
|
||||
|
||||
use crate::hir;
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||
|
@ -40,7 +41,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
var_origin.span(),
|
||||
sub_expected_found.expected,
|
||||
sub_expected_found.found,
|
||||
self.tcx().def_span(*trait_item_def_id),
|
||||
*trait_item_def_id,
|
||||
);
|
||||
return Some(ErrorReported);
|
||||
}
|
||||
|
@ -51,23 +52,56 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
None
|
||||
}
|
||||
|
||||
fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Span) {
|
||||
fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) {
|
||||
let tcx = self.tcx();
|
||||
let trait_sp = self.tcx().def_span(trait_def_id);
|
||||
let mut err = self
|
||||
.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(impl_sp, &format!("expected {:?}", expected));
|
||||
err.span_label(trait_sp, &format!("expected {:?}", expected));
|
||||
let trait_fn_sig = tcx.fn_sig(trait_def_id);
|
||||
|
||||
struct AssocTypeFinder(FxHashSet<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);
|
||||
match ty.kind {
|
||||
ty::Param(param) => {
|
||||
self.0.insert(param);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
let mut visitor = AssocTypeFinder(FxHashSet::default());
|
||||
trait_fn_sig.output().visit_with(&mut visitor);
|
||||
|
||||
if let Some(id) = tcx.hir().as_local_hir_id(trait_def_id) {
|
||||
let parent_id = tcx.hir().get_parent_item(id);
|
||||
let trait_item = tcx.hir().expect_item(parent_id);
|
||||
if let hir::ItemKind::Trait(_, _, generics, _, _) = &trait_item.kind {
|
||||
for param_ty in visitor.0 {
|
||||
if let Some(generic) = generics.get_named(param_ty.name) {
|
||||
err.span_label(generic.span, &format!(
|
||||
"in order for `impl` items to be able to implement the method, this \
|
||||
type parameter might need a lifetime restriction like `{}: 'a`",
|
||||
param_ty.name,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct EarlyBoundRegionHighlighter(FxHashSet<DefId>);
|
||||
impl<'tcx> ty::fold::TypeVisitor<'tcx> for EarlyBoundRegionHighlighter {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
debug!("LateBoundRegionNameCollector visit_region {:?}", r);
|
||||
match *r {
|
||||
ty::ReFree(free) => {
|
||||
self.0.insert(free.scope);
|
||||
}
|
||||
|
||||
ty::ReEarlyBound(bound) => {
|
||||
self.0.insert(bound.def_id);
|
||||
}
|
||||
|
@ -94,12 +128,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
}
|
||||
if note {
|
||||
err.note(
|
||||
"the lifetime requirements from the `trait` could not be fulfilled by the \
|
||||
`impl`",
|
||||
"the lifetime requirements from the `trait` could not be fulfilled by the `impl`",
|
||||
);
|
||||
err.help(
|
||||
"consider adding a named lifetime to the `trait` that constrains the item's \
|
||||
`self` argument, its inputs and its output with it",
|
||||
"verify the lifetime relationships in the `trait` and `impl` between the \
|
||||
`self` argument, the other inputs and its output",
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
|
|
|
@ -4,7 +4,7 @@ fn main() {
|
|||
let x = 0;
|
||||
f(&x);
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected mutable reference `&'z1 mut i32`
|
||||
//~| found reference `&'z2 {integer}`
|
||||
//~| expected mutable reference `&mut i32`
|
||||
//~| found reference `&{integer}`
|
||||
//~| types differ in mutability
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ error[E0308]: mismatched types
|
|||
LL | f(&x);
|
||||
| ^^ types differ in mutability
|
||||
|
|
||||
= note: expected mutable reference `&'z1 mut i32`
|
||||
found reference `&'z2 {integer}`
|
||||
= note: expected mutable reference `&mut i32`
|
||||
found reference `&{integer}`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ LL | fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
|
|||
| expected type parameter
|
||||
|
|
||||
= note: expected fn pointer `fn(&E, F) -> F`
|
||||
found fn pointer `fn(&'z0 E, G) -> G`
|
||||
found fn pointer `fn(&E, G) -> G`
|
||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | let _: for<'b> fn(&'b u32) = foo();
|
|||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `for<'b> fn(&'b u32)`
|
||||
found fn pointer `fn(&'z0 u32)`
|
||||
found fn pointer `fn(&u32)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ LL | fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
|
|||
| expected type parameter
|
||||
|
|
||||
= note: expected fn pointer `fn(&(), &B, &impl Debug)`
|
||||
found fn pointer `fn(&'z0 (), &impl Debug, &B)`
|
||||
found fn pointer `fn(&(), &impl Debug, &B)`
|
||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | fn fmt(&self, x: &str) -> () { }
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected fn pointer `fn(&MyType, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
|
||||
found fn pointer `fn(&'z0 MyType, &str)`
|
||||
found fn pointer `fn(&MyType, &str)`
|
||||
|
||||
error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2
|
||||
--> $DIR/trait_type.rs:12:11
|
||||
|
|
|
@ -10,9 +10,9 @@ LL | fn deref(&self) -> &Self::Target;
|
|||
| --------------------------------- expected fn(&Struct) -> &(dyn Trait + 'static)
|
||||
|
|
||||
= note: expected `fn(&Struct) -> &(dyn Trait + 'static)`
|
||||
found `fn(&'z0 Struct) -> &dyn Trait`
|
||||
found `fn(&Struct) -> &dyn Trait`
|
||||
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
|
||||
= help: consider adding a named lifetime to the `trait` that constrains the item's `self` argument, its inputs and its output with it
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
|
|||
|
|
||||
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
|
||||
found `fn(&i32, &u32, &u32) -> &u32`
|
||||
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32
|
||||
|
|
||||
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32`
|
||||
found `fn(&'z0 i32, &'z1 u32, &'z2 u32) -> &'z2 u32`
|
||||
found `fn(&i32, &u32, &u32) -> &u32`
|
||||
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
|
||||
= help: consider adding a named lifetime to the `trait` that constrains the item's `self` argument, its inputs and its output with it
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/mismatched_trait_impl.rs:10:9
|
||||
|
|
|
@ -8,7 +8,7 @@ impl Foo for Baz {
|
|||
fn bar(&mut self, other: &dyn Foo) {}
|
||||
//~^ ERROR method `bar` has an incompatible type for trait
|
||||
//~| expected fn pointer `fn(&mut Baz, &mut dyn Foo)`
|
||||
//~| found fn pointer `fn(&'z0 mut Baz, &dyn Foo)`
|
||||
//~| found fn pointer `fn(&mut Baz, &dyn Foo)`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | fn bar(&mut self, other: &dyn Foo) {}
|
|||
| ^^^^^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected fn pointer `fn(&mut Baz, &mut dyn Foo)`
|
||||
found fn pointer `fn(&'z0 mut Baz, &dyn Foo)`
|
||||
found fn pointer `fn(&mut Baz, &dyn Foo)`
|
||||
help: consider change the type to match the mutability in trait
|
||||
|
|
||||
LL | fn bar(&mut self, other: &mut dyn Foo) {}
|
||||
|
|
|
@ -27,7 +27,7 @@ note: ...so that the types are compatible
|
|||
LL | self.a();
|
||||
| ^
|
||||
= note: expected `&'a Self`
|
||||
found `&'z0 Self`
|
||||
found `&Self`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ note: ...so that the types are compatible
|
|||
LL | self.foo();
|
||||
| ^^^
|
||||
= note: expected `&'a Self`
|
||||
found `&'z0 Self`
|
||||
found `&Self`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&T`, found type parameter `T`
|
||||
|
|
||||
= note: expected fn pointer `extern "rust-call" fn(&Foo, (&'a T,))`
|
||||
found fn pointer `extern "rust-call" fn(&'z0 Foo, (T,))`
|
||||
found fn pointer `extern "rust-call" fn(&Foo, (T,))`
|
||||
= help: type parameters must be constrained to match other types
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
|
||||
|
@ -20,7 +20,7 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&T`, found type parameter `T`
|
||||
|
|
||||
= note: expected fn pointer `extern "rust-call" fn(&mut Foo, (&'a T,))`
|
||||
found fn pointer `extern "rust-call" fn(&'z0 mut Foo, (T,))`
|
||||
found fn pointer `extern "rust-call" fn(&mut Foo, (T,))`
|
||||
= help: type parameters must be constrained to match other types
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | fn next(&mut self) -> Result<i32, i32> { Ok(7) }
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
|
||||
|
|
||||
= note: expected fn pointer `fn(&mut S) -> std::option::Option<i32>`
|
||||
found fn pointer `fn(&'z0 mut S) -> std::result::Result<i32, i32>`
|
||||
found fn pointer `fn(&mut S) -> std::result::Result<i32, i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &i32) -> &i32
|
||||
|
|
||||
= note: expected `fn(&i32, &'a i32) -> &'a i32`
|
||||
found `fn(&'z0 i32, &'z0 i32) -> &'z0 i32`
|
||||
found `fn(&i32, &i32) -> &i32`
|
||||
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
|
||||
= help: consider adding a named lifetime to the `trait` that constrains the item's `self` argument, its inputs and its output with it
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ LL | fn bar(&mut self) { }
|
|||
| ^^^^^^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected fn pointer `fn(&Bar)`
|
||||
found fn pointer `fn(&'z0 mut Bar)`
|
||||
found fn pointer `fn(&mut Bar)`
|
||||
help: consider change the type to match the mutability in trait
|
||||
|
|
||||
LL | fn bar(&self) { }
|
||||
|
|
|
@ -20,7 +20,7 @@ LL | fn bar(&mut self, bar: &Bar) { }
|
|||
| ^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected fn pointer `fn(&mut Bar, &mut Bar)`
|
||||
found fn pointer `fn(&'z0 mut Bar, &'z1 Bar)`
|
||||
found fn pointer `fn(&mut Bar, &Bar)`
|
||||
help: consider change the type to match the mutability in trait
|
||||
|
|
||||
LL | fn bar(&mut self, bar: &mut Bar) { }
|
||||
|
|
|
@ -16,7 +16,7 @@ note: ...so that the expression is assignable
|
|||
|
|
||||
LL | C { f: b }
|
||||
| ^
|
||||
= note: expected `std::boxed::Box<std::boxed::Box<&'z0 isize>>`
|
||||
= note: expected `std::boxed::Box<std::boxed::Box<&isize>>`
|
||||
found `std::boxed::Box<std::boxed::Box<&isize>>`
|
||||
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 15:6...
|
||||
--> $DIR/type-alias-free-regions.rs:15:6
|
||||
|
@ -49,7 +49,7 @@ note: ...so that the expression is assignable
|
|||
|
|
||||
LL | C { f: Box::new(b.0) }
|
||||
| ^^^
|
||||
= note: expected `std::boxed::Box<&'z1 isize>`
|
||||
= note: expected `std::boxed::Box<&isize>`
|
||||
found `std::boxed::Box<&isize>`
|
||||
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 25:6...
|
||||
--> $DIR/type-alias-free-regions.rs:25:6
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | want_F(bar);
|
|||
| ^^^ expected concrete lifetime, found bound lifetime parameter 'cx
|
||||
|
|
||||
= note: expected fn pointer `for<'cx> fn(&'cx S) -> &'cx S`
|
||||
found fn item `for<'a> fn(&'a S) -> &'z2 S {bar::<'_>}`
|
||||
found fn item `for<'a> fn(&'a S) -> &S {bar::<'_>}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12
|
||||
|
|
|
@ -39,7 +39,7 @@ note: ...so that the expression is assignable
|
|||
|
|
||||
LL | Box::new(v)
|
||||
| ^
|
||||
= note: expected `&'z1 [u8]`
|
||||
= note: expected `&[u8]`
|
||||
found `&'a [u8]`
|
||||
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9...
|
||||
--> $DIR/region-object-lifetime-in-coercion.rs:25:9
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | want_F(bar);
|
|||
| ^^^ expected concrete lifetime, found bound lifetime parameter 'cx
|
||||
|
|
||||
= note: expected fn pointer `for<'cx> fn(&'cx S) -> &'cx S`
|
||||
found fn item `for<'a> fn(&'a S) -> &'z2 S {bar::<'_>}`
|
||||
found fn item `for<'a> fn(&'a S) -> &S {bar::<'_>}`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ LL | | return z;
|
|||
LL | | }));
|
||||
| |_____^
|
||||
= note: expected `&isize`
|
||||
found `&'z13 isize`
|
||||
found `&isize`
|
||||
|
||||
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
|
||||
--> $DIR/regions-nested-fns.rs:14:27
|
||||
|
|
|
@ -14,7 +14,7 @@ note: ...so that the expression is assignable
|
|||
|
|
||||
LL | with(|o| o)
|
||||
| ^
|
||||
= note: expected `&'z0 isize`
|
||||
= note: expected `&isize`
|
||||
found `&isize`
|
||||
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 9:14...
|
||||
--> $DIR/regions-ret-borrowed-1.rs:9:14
|
||||
|
|
|
@ -14,7 +14,7 @@ note: ...so that the expression is assignable
|
|||
|
|
||||
LL | with(|o| o)
|
||||
| ^
|
||||
= note: expected `&'z0 isize`
|
||||
= note: expected `&isize`
|
||||
found `&isize`
|
||||
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 12:14...
|
||||
--> $DIR/regions-ret-borrowed.rs:12:14
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | fn get_ctxt(&self) -> &'a Ctxt {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected fn pointer `fn(&HasCtxt<'a>) -> &Ctxt`
|
||||
found fn pointer `fn(&'z0 HasCtxt<'a>) -> &'a Ctxt`
|
||||
found fn pointer `fn(&HasCtxt<'a>) -> &'a Ctxt`
|
||||
note: the lifetime `'a` as defined on the impl at 12:6...
|
||||
--> $DIR/regions-trait-1.rs:12:6
|
||||
|
|
||||
|
|
|
@ -42,7 +42,7 @@ note: ...so that the expression is assignable
|
|||
LL | x
|
||||
| ^
|
||||
= note: expected `&'b mut (dyn Dummy + 'b)`
|
||||
found `&'z1 mut (dyn Dummy + 'b)`
|
||||
found `&mut (dyn Dummy + 'b)`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/regions-trait-object-subtyping.rs:22:5
|
||||
|
|
|
@ -54,8 +54,8 @@ LL | Opts::A(ref mut i) | Opts::B(ref i) => {}
|
|||
| |
|
||||
| first introduced with type `&mut isize` here
|
||||
|
|
||||
= note: expected type `&'z0 mut isize`
|
||||
found type `&'z1 isize`
|
||||
= note: expected type `&mut isize`
|
||||
found type `&isize`
|
||||
= note: in the same arm, a binding must have the same type in all alternatives
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
|
|
@ -22,8 +22,8 @@ error[E0308]: mismatched types
|
|||
LL | test(&y);
|
||||
| ^^ types differ in mutability
|
||||
|
|
||||
= note: expected mutable reference `&'z2 mut std::string::String`
|
||||
found reference `&'z3 std::string::String`
|
||||
= note: expected mutable reference `&mut std::string::String`
|
||||
found reference `&std::string::String`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coerce-suggestions.rs:14:11
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | unsafe fn jumbo(&self, x: &usize) { *self + *x; }
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected normal fn, found unsafe fn
|
||||
|
|
||||
= note: expected fn pointer `fn(&usize, &usize) -> usize`
|
||||
found fn pointer `unsafe fn(&'z0 usize, &'z1 usize)`
|
||||
found fn pointer `unsafe fn(&usize, &usize)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
struct Article {
|
||||
proof_reader: ProofReader,
|
||||
}
|
||||
|
||||
struct ProofReader {
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub trait HaveRelationship<To> {
|
||||
fn get_relation(&self) -> To;
|
||||
}
|
||||
|
||||
impl HaveRelationship<&ProofReader> for Article {
|
||||
fn get_relation(&self) -> &ProofReader {
|
||||
//~^ ERROR `impl` item signature doesn't match `trait` item signature
|
||||
&self.proof_reader
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,18 @@
|
|||
error: `impl` item signature doesn't match `trait` item signature
|
||||
--> $DIR/trait-param-without-lifetime-constraint.rs:14:5
|
||||
|
|
||||
LL | pub trait HaveRelationship<To> {
|
||||
| -- in order for `impl` items to be able to implement the method, this type parameter might need a lifetime restriction like `To: 'a`
|
||||
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`
|
||||
= note: the lifetime requirements from the `trait` could not be fulfilled by the `impl`
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -211,7 +211,7 @@ LL | want::<&Foo<foo>>(f);
|
|||
| expected `&Foo<foo>`, found struct `Foo`
|
||||
| help: consider borrowing here: `&f`
|
||||
|
|
||||
= note: expected reference `&'z0 Foo<foo>`
|
||||
= note: expected reference `&Foo<foo>`
|
||||
found struct `Foo<foo>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
|
@ -313,7 +313,7 @@ LL | want::<&Foo<foo, B>>(f);
|
|||
| expected `&Foo<foo, B>`, found struct `Foo`
|
||||
| help: consider borrowing here: `&f`
|
||||
|
|
||||
= note: expected reference `&'z1 Foo<foo, B>`
|
||||
= note: expected reference `&Foo<foo, B>`
|
||||
found struct `Foo<foo, B>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
|
|
|
@ -8,7 +8,7 @@ impl Foo for u32 {
|
|||
fn len(&self) -> u32 { *self }
|
||||
//~^ ERROR method `len` has an incompatible type for trait
|
||||
//~| expected fn pointer `unsafe fn(&u32) -> _`
|
||||
//~| found fn pointer `fn(&'z0 u32) -> _`
|
||||
//~| found fn pointer `fn(&u32) -> _`
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | fn len(&self) -> u32 { *self }
|
|||
| ^^^^^^^^^^^^^^^^^^^^ expected unsafe fn, found normal fn
|
||||
|
|
||||
= note: expected fn pointer `unsafe fn(&u32) -> _`
|
||||
found fn pointer `fn(&'z0 u32) -> _`
|
||||
found fn pointer `fn(&u32) -> _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | fn mul(self, s: &f64) -> Vec1 {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `f64`, found `&f64`
|
||||
|
|
||||
= note: expected fn pointer `fn(Vec1, f64) -> Vec1`
|
||||
found fn pointer `fn(Vec1, &'z0 f64) -> Vec1`
|
||||
found fn pointer `fn(Vec1, &f64) -> Vec1`
|
||||
|
||||
error[E0053]: method `mul` has an incompatible type for trait
|
||||
--> $DIR/wrong-mul-method-signature.rs:33:5
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue