Point at lifetimes instead of def span for E0195
This commit is contained in:
parent
5d95db34a4
commit
cd8ca26257
5 changed files with 63 additions and 26 deletions
|
@ -25,7 +25,7 @@ use rustc_target::spec::abi::Abi;
|
|||
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax::ext::base::MacroKind;
|
||||
use syntax_pos::Span;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use hir::*;
|
||||
use hir::print::Nested;
|
||||
|
@ -664,6 +664,26 @@ impl<'hir> Map<'hir> {
|
|||
self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get`
|
||||
}
|
||||
|
||||
pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics> {
|
||||
self.get_if_local(id).and_then(|node| {
|
||||
match node {
|
||||
NodeImplItem(ref impl_item) => Some(&impl_item.generics),
|
||||
NodeTraitItem(ref trait_item) => Some(&trait_item.generics),
|
||||
NodeItem(ref item) => {
|
||||
match item.node {
|
||||
ItemFn(_, _, ref generics, _) => Some(generics),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_generics_span(&self, id: DefId) -> Option<Span> {
|
||||
self.get_generics(id).map(|generics| generics.span).filter(|sp| *sp != DUMMY_SP)
|
||||
}
|
||||
|
||||
/// Retrieve the Node corresponding to `id`, returning None if
|
||||
/// cannot be found.
|
||||
pub fn find(&self, id: NodeId) -> Option<Node<'hir>> {
|
||||
|
|
|
@ -356,7 +356,6 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
impl_generics: &ty::Generics,
|
||||
trait_to_skol_substs: &Substs<'tcx>)
|
||||
-> Result<(), ErrorReported> {
|
||||
let span = tcx.sess.codemap().def_span(span);
|
||||
let trait_params = trait_generics.own_counts().lifetimes;
|
||||
let impl_params = impl_generics.own_counts().lifetimes;
|
||||
|
||||
|
@ -378,16 +377,20 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// are zero. Since I don't quite know how to phrase things at
|
||||
// the moment, give a kind of vague error message.
|
||||
if trait_params != impl_params {
|
||||
let mut err = struct_span_err!(tcx.sess,
|
||||
span,
|
||||
E0195,
|
||||
"lifetime parameters or bounds on method `{}` do not match \
|
||||
the trait declaration",
|
||||
impl_m.ident);
|
||||
let def_span = tcx.sess.codemap().def_span(span);
|
||||
let span = tcx.hir.get_generics_span(impl_m.def_id).unwrap_or(def_span);
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0195,
|
||||
"lifetime parameters or bounds on method `{}` do not match the trait declaration",
|
||||
impl_m.ident,
|
||||
);
|
||||
err.span_label(span, "lifetimes do not match method in trait");
|
||||
if let Some(sp) = tcx.hir.span_if_local(trait_m.def_id) {
|
||||
err.span_label(tcx.sess.codemap().def_span(sp),
|
||||
"lifetimes in impl do not match this method in trait");
|
||||
let def_sp = tcx.sess.codemap().def_span(sp);
|
||||
let sp = tcx.hir.get_generics_span(trait_m.def_id).unwrap_or(def_sp);
|
||||
err.span_label(sp, "lifetimes in impl do not match this method in trait");
|
||||
}
|
||||
err.emit();
|
||||
return Err(ErrorReported);
|
||||
|
|
|
@ -20,6 +20,7 @@ pub trait Foo<'a, 't> {
|
|||
fn no_bound<'b>(self, b: Inv<'b>);
|
||||
fn has_bound<'b:'a>(self, b: Inv<'b>);
|
||||
fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
|
||||
fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
|
||||
fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
|
||||
fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
|
||||
}
|
||||
|
@ -47,6 +48,10 @@ impl<'a, 't> Foo<'a, 't> for &'a isize {
|
|||
// cases.
|
||||
}
|
||||
|
||||
fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
|
||||
//~^ ERROR lifetime parameters or bounds on method `wrong_bound2` do not match the trait
|
||||
}
|
||||
|
||||
fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,42 +1,51 @@
|
|||
error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:28:5
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:29:16
|
||||
|
|
||||
LL | fn no_bound<'b>(self, b: Inv<'b>);
|
||||
| ---------------------------------- lifetimes in impl do not match this method in trait
|
||||
| ---- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
LL | fn no_bound<'b:'a>(self, b: Inv<'b>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
|
||||
| ^^^^^^^ lifetimes do not match method in trait
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:32:5
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:33:17
|
||||
|
|
||||
LL | fn has_bound<'b:'a>(self, b: Inv<'b>);
|
||||
| -------------------------------------- lifetimes in impl do not match this method in trait
|
||||
| ------- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
LL | fn has_bound<'b>(self, b: Inv<'b>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
|
||||
| ^^^^ lifetimes do not match method in trait
|
||||
|
||||
error[E0308]: method not compatible with trait
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:37:5
|
||||
|
|
||||
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)`
|
||||
found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)`
|
||||
note: the lifetime 'c as defined on the method body at 36:5...
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
|
||||
note: the lifetime 'c as defined on the method body at 37:5...
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:37:5
|
||||
|
|
||||
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 36:5
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
|
||||
note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 37:5
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:37:5
|
||||
|
|
||||
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:51:5
|
||||
|
|
||||
LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
|
||||
| ---------------- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
|
||||
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:53:5
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:58:5
|
||||
|
|
||||
LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
|
||||
| ------------------------------------------------------- definition of `another_bound` from trait
|
||||
|
@ -44,7 +53,7 @@ LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
|
|||
LL | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors occurred: E0195, E0276, E0308.
|
||||
For more information about an error, try `rustc --explain E0195`.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0195]: lifetime parameters or bounds on method `bar` do not match the trait declaration
|
||||
--> $DIR/E0195.rs:19:5
|
||||
--> $DIR/E0195.rs:19:11
|
||||
|
|
||||
LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
|
||||
| ----------------------------------------- lifetimes in impl do not match this method in trait
|
||||
| ---------- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
|
||||
| ^^^^^^^ lifetimes do not match method in trait
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue