Add spans to E0277 for impl/trait type/fn obligation disparity

This commit is contained in:
Esteban Küber 2021-03-31 16:53:26 -07:00
parent 2375b8ae7e
commit 60c7f37f7c
3 changed files with 96 additions and 25 deletions

View File

@ -2179,19 +2179,60 @@ fn note_obligation_cause_code<T>(
)
});
}
ObligationCauseCode::CompareImplMethodObligation { .. } => {
err.note(&format!(
"the requirement `{}` appears on the impl method but not on the corresponding \
trait method",
predicate
));
ObligationCauseCode::CompareImplMethodObligation {
item_name,
trait_item_def_id,
..
} => {
let msg = format!(
"the requirement `{}` appears on the impl method `{}` but not on the \
corresponding trait method",
predicate, item_name,
);
let sp = self
.tcx
.opt_item_name(trait_item_def_id)
.map(|i| i.span)
.unwrap_or_else(|| self.tcx.def_span(trait_item_def_id));
let mut assoc_span: MultiSpan = sp.into();
assoc_span.push_span_label(
sp,
format!("this trait method doesn't have the requirement `{}`", predicate),
);
if let Some(ident) = self
.tcx
.opt_associated_item(trait_item_def_id)
.and_then(|i| self.tcx.opt_item_name(i.container.id()))
{
assoc_span.push_span_label(ident.span, "in this trait".into());
}
err.span_note(assoc_span, &msg);
}
ObligationCauseCode::CompareImplTypeObligation { .. } => {
err.note(&format!(
"the requirement `{}` appears on the associated impl type but not on the \
ObligationCauseCode::CompareImplTypeObligation {
item_name, trait_item_def_id, ..
} => {
let msg = format!(
"the requirement `{}` appears on the associated impl type `{}` but not on the \
corresponding associated trait type",
predicate
));
predicate, item_name,
);
let sp = self.tcx.def_span(trait_item_def_id);
let mut assoc_span: MultiSpan = sp.into();
assoc_span.push_span_label(
sp,
format!(
"this trait associated type doesn't have the requirement `{}`",
predicate,
),
);
if let Some(ident) = self
.tcx
.opt_associated_item(trait_item_def_id)
.and_then(|i| self.tcx.opt_item_name(i.container.id()))
{
assoc_span.push_span_label(ident.span, "in this trait".into());
}
err.span_note(assoc_span, &msg);
}
ObligationCauseCode::CompareImplConstObligation => {
err.note(&format!(

View File

@ -6,6 +6,7 @@ trait Foo {
type A<'a> where Self: 'a;
type B<'a, 'b> where 'a: 'b;
type C where Self: Clone;
fn d() where Self: Clone;
}
#[derive(Copy, Clone)]
@ -19,6 +20,8 @@ impl<T> Foo for Fooy<T> {
//~| ERROR lifetime bound not satisfied
type C where Self: Copy = String;
//~^ ERROR the trait bound `T: Copy` is not satisfied
fn d() where Self: Copy {}
//~^ ERROR the trait bound `T: Copy` is not satisfied
}
fn main() {}

View File

@ -1,5 +1,5 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/impl_bounds.rs:15:5
--> $DIR/impl_bounds.rs:16:5
|
LL | type A<'a> where Self: 'static = (&'a ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -8,53 +8,80 @@ LL | type A<'a> where Self: 'static = (&'a ());
= note: ...so that the type `Fooy<T>` will meet its required lifetime bounds
error[E0478]: lifetime bound not satisfied
--> $DIR/impl_bounds.rs:17:5
--> $DIR/impl_bounds.rs:18:5
|
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'b` as defined on the associated item at 17:16
--> $DIR/impl_bounds.rs:17:16
note: lifetime parameter instantiated with the lifetime `'b` as defined on the associated item at 18:16
--> $DIR/impl_bounds.rs:18:16
|
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
| ^^
note: but lifetime parameter must outlive the lifetime `'a` as defined on the associated item at 17:12
--> $DIR/impl_bounds.rs:17:12
note: but lifetime parameter must outlive the lifetime `'a` as defined on the associated item at 18:12
--> $DIR/impl_bounds.rs:18:12
|
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
| ^^
error[E0478]: lifetime bound not satisfied
--> $DIR/impl_bounds.rs:17:5
--> $DIR/impl_bounds.rs:18:5
|
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined on the associated item at 17:12
--> $DIR/impl_bounds.rs:17:12
note: lifetime parameter instantiated with the lifetime `'a` as defined on the associated item at 18:12
--> $DIR/impl_bounds.rs:18:12
|
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
| ^^
note: but lifetime parameter must outlive the lifetime `'b` as defined on the associated item at 17:16
--> $DIR/impl_bounds.rs:17:16
note: but lifetime parameter must outlive the lifetime `'b` as defined on the associated item at 18:16
--> $DIR/impl_bounds.rs:18:16
|
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
| ^^
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/impl_bounds.rs:20:5
--> $DIR/impl_bounds.rs:21:5
|
LL | type C where Self: Copy = String;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
= note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
= note: the requirement `Fooy<T>: Copy` appears on the associated impl type but not on the corresponding associated trait type
note: the requirement `Fooy<T>: Copy` appears on the associated impl type `C` but not on the corresponding associated trait type
--> $DIR/impl_bounds.rs:8:5
|
LL | trait Foo {
| --- in this trait
...
LL | type C where Self: Clone;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ this trait associated type doesn't have the requirement `Fooy<T>: Copy`
help: consider restricting type parameter `T`
|
LL | impl<T: Copy> Foo for Fooy<T> {
| ^^^^^^
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/impl_bounds.rs:23:5
|
LL | fn d() where Self: Copy {}
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
= note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
note: the requirement `Fooy<T>: Copy` appears on the impl method `d` but not on the corresponding trait method
--> $DIR/impl_bounds.rs:9:8
|
LL | trait Foo {
| --- in this trait
...
LL | fn d() where Self: Clone;
| ^ this trait method doesn't have the requirement `Fooy<T>: Copy`
help: consider restricting type parameter `T`
|
LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0310, E0478.
For more information about an error, try `rustc --explain E0277`.