Skip to content

Commit cd8ca26

Browse files
committed
Point at lifetimes instead of def span for E0195
1 parent 5d95db3 commit cd8ca26

File tree

5 files changed

+63
-26
lines changed

5 files changed

+63
-26
lines changed

src/librustc/hir/map/mod.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_target::spec::abi::Abi;
2525
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
2626
use syntax::codemap::Spanned;
2727
use syntax::ext::base::MacroKind;
28-
use syntax_pos::Span;
28+
use syntax_pos::{Span, DUMMY_SP};
2929

3030
use hir::*;
3131
use hir::print::Nested;
@@ -664,6 +664,26 @@ impl<'hir> Map<'hir> {
664664
self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get`
665665
}
666666

667+
pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics> {
668+
self.get_if_local(id).and_then(|node| {
669+
match node {
670+
NodeImplItem(ref impl_item) => Some(&impl_item.generics),
671+
NodeTraitItem(ref trait_item) => Some(&trait_item.generics),
672+
NodeItem(ref item) => {
673+
match item.node {
674+
ItemFn(_, _, ref generics, _) => Some(generics),
675+
_ => None,
676+
}
677+
}
678+
_ => None,
679+
}
680+
})
681+
}
682+
683+
pub fn get_generics_span(&self, id: DefId) -> Option<Span> {
684+
self.get_generics(id).map(|generics| generics.span).filter(|sp| *sp != DUMMY_SP)
685+
}
686+
667687
/// Retrieve the Node corresponding to `id`, returning None if
668688
/// cannot be found.
669689
pub fn find(&self, id: NodeId) -> Option<Node<'hir>> {

src/librustc_typeck/check/compare_method.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,6 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
356356
impl_generics: &ty::Generics,
357357
trait_to_skol_substs: &Substs<'tcx>)
358358
-> Result<(), ErrorReported> {
359-
let span = tcx.sess.codemap().def_span(span);
360359
let trait_params = trait_generics.own_counts().lifetimes;
361360
let impl_params = impl_generics.own_counts().lifetimes;
362361

@@ -378,16 +377,20 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
378377
// are zero. Since I don't quite know how to phrase things at
379378
// the moment, give a kind of vague error message.
380379
if trait_params != impl_params {
381-
let mut err = struct_span_err!(tcx.sess,
382-
span,
383-
E0195,
384-
"lifetime parameters or bounds on method `{}` do not match \
385-
the trait declaration",
386-
impl_m.ident);
380+
let def_span = tcx.sess.codemap().def_span(span);
381+
let span = tcx.hir.get_generics_span(impl_m.def_id).unwrap_or(def_span);
382+
let mut err = struct_span_err!(
383+
tcx.sess,
384+
span,
385+
E0195,
386+
"lifetime parameters or bounds on method `{}` do not match the trait declaration",
387+
impl_m.ident,
388+
);
387389
err.span_label(span, "lifetimes do not match method in trait");
388390
if let Some(sp) = tcx.hir.span_if_local(trait_m.def_id) {
389-
err.span_label(tcx.sess.codemap().def_span(sp),
390-
"lifetimes in impl do not match this method in trait");
391+
let def_sp = tcx.sess.codemap().def_span(sp);
392+
let sp = tcx.hir.get_generics_span(trait_m.def_id).unwrap_or(def_sp);
393+
err.span_label(sp, "lifetimes in impl do not match this method in trait");
391394
}
392395
err.emit();
393396
return Err(ErrorReported);

src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub trait Foo<'a, 't> {
2020
fn no_bound<'b>(self, b: Inv<'b>);
2121
fn has_bound<'b:'a>(self, b: Inv<'b>);
2222
fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
23+
fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
2324
fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
2425
fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
2526
}
@@ -47,6 +48,10 @@ impl<'a, 't> Foo<'a, 't> for &'a isize {
4748
// cases.
4849
}
4950

51+
fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
52+
//~^ ERROR lifetime parameters or bounds on method `wrong_bound2` do not match the trait
53+
}
54+
5055
fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
5156
}
5257

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,59 @@
11
error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration
2-
--> $DIR/regions-bound-missing-bound-in-impl.rs:28:5
2+
--> $DIR/regions-bound-missing-bound-in-impl.rs:29:16
33
|
44
LL | fn no_bound<'b>(self, b: Inv<'b>);
5-
| ---------------------------------- lifetimes in impl do not match this method in trait
5+
| ---- lifetimes in impl do not match this method in trait
66
...
77
LL | fn no_bound<'b:'a>(self, b: Inv<'b>) {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
8+
| ^^^^^^^ lifetimes do not match method in trait
99

1010
error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration
11-
--> $DIR/regions-bound-missing-bound-in-impl.rs:32:5
11+
--> $DIR/regions-bound-missing-bound-in-impl.rs:33:17
1212
|
1313
LL | fn has_bound<'b:'a>(self, b: Inv<'b>);
14-
| -------------------------------------- lifetimes in impl do not match this method in trait
14+
| ------- lifetimes in impl do not match this method in trait
1515
...
1616
LL | fn has_bound<'b>(self, b: Inv<'b>) {
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
17+
| ^^^^ lifetimes do not match method in trait
1818

1919
error[E0308]: method not compatible with trait
20-
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
20+
--> $DIR/regions-bound-missing-bound-in-impl.rs:37:5
2121
|
2222
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
2424
|
2525
= note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)`
2626
found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)`
27-
note: the lifetime 'c as defined on the method body at 36:5...
28-
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
27+
note: the lifetime 'c as defined on the method body at 37:5...
28+
--> $DIR/regions-bound-missing-bound-in-impl.rs:37:5
2929
|
3030
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
3131
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32-
note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 36:5
33-
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
32+
note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 37:5
33+
--> $DIR/regions-bound-missing-bound-in-impl.rs:37:5
3434
|
3535
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3737

38+
error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration
39+
--> $DIR/regions-bound-missing-bound-in-impl.rs:51:5
40+
|
41+
LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
42+
| ---------------- lifetimes in impl do not match this method in trait
43+
...
44+
LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
46+
3847
error[E0276]: impl has stricter requirements than trait
39-
--> $DIR/regions-bound-missing-bound-in-impl.rs:53:5
48+
--> $DIR/regions-bound-missing-bound-in-impl.rs:58:5
4049
|
4150
LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
4251
| ------------------------------------------------------- definition of `another_bound` from trait
4352
...
4453
LL | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
4554
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't`
4655

47-
error: aborting due to 4 previous errors
56+
error: aborting due to 5 previous errors
4857

4958
Some errors occurred: E0195, E0276, E0308.
5059
For more information about an error, try `rustc --explain E0195`.

src/test/ui/error-codes/E0195.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0195]: lifetime parameters or bounds on method `bar` do not match the trait declaration
2-
--> $DIR/E0195.rs:19:5
2+
--> $DIR/E0195.rs:19:11
33
|
44
LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
5-
| ----------------------------------------- lifetimes in impl do not match this method in trait
5+
| ---------- lifetimes in impl do not match this method in trait
66
...
77
LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
8+
| ^^^^^^^ lifetimes do not match method in trait
99

1010
error: aborting due to previous error
1111

0 commit comments

Comments
 (0)