diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index a10bd40af36..6a4f6ad0e19 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -807,7 +807,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } }; - let span = cause.span; + let span = cause.span(&self.tcx); diag.span_label(span, terr.to_string()); if let Some((sp, msg)) = secondary_span { @@ -842,7 +842,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "did you mean `{}(/* fields */)`?", self.tcx.item_path_str(def_id) ); - diag.span_label(cause.span, message); + diag.span_label(span, message); } } } @@ -870,7 +870,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trace, terr); - let span = trace.cause.span; + let span = trace.cause.span(&self.tcx); let failure_code = trace.cause.as_failure_code(terr); let mut diag = match failure_code { FailureCode::Error0317(failure_str) => { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index fd47e09aad7..0616dda228e 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -100,6 +100,19 @@ pub struct ObligationCause<'tcx> { pub code: ObligationCauseCode<'tcx> } +impl<'tcx> ObligationCause<'tcx> { + pub fn span<'a, 'gcx>(&self, tcx: &TyCtxt<'a, 'gcx, 'tcx>) -> Span { + match self.code { + ObligationCauseCode::CompareImplMethodObligation { .. } | + ObligationCauseCode::MainFunctionType | + ObligationCauseCode::StartFunctionType => { + tcx.sess.codemap().def_span(self.span) + } + _ => self.span, + } + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub enum ObligationCauseCode<'tcx> { /// Not well classified or should be obvious from span. diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 570eecfc267..4c10f28eb8e 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -40,6 +40,8 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref); + let impl_m_span = tcx.sess.codemap().def_span(impl_m_span); + if let Err(ErrorReported) = compare_self_type(tcx, impl_m, impl_m_span, @@ -186,6 +188,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, check_region_bounds_on_impl_method(tcx, impl_m_span, impl_m, + trait_m, &trait_m_generics, &impl_m_generics, trait_to_skol_substs)?; @@ -310,7 +313,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; let mut diag = struct_span_err!(tcx.sess, - cause.span, + cause.span(&tcx), E0053, "method `{}` has an incompatible type for trait", trait_m.name); @@ -346,10 +349,12 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, impl_m: &ty::AssociatedItem, + trait_m: &ty::AssociatedItem, trait_generics: &ty::Generics, 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.regions[..]; let impl_params = &impl_generics.regions[..]; @@ -371,14 +376,18 @@ 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.len() != impl_params.len() { - struct_span_err!(tcx.sess, - span, - E0195, - "lifetime parameters or bounds on method `{}` do not match the \ - trait declaration", - impl_m.name) - .span_label(span, "lifetimes do not match trait") - .emit(); + let mut err = struct_span_err!(tcx.sess, + span, + E0195, + "lifetime parameters or bounds on method `{}` do not match \ + the trait declaration", + impl_m.name); + 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"); + } + err.emit(); return Err(ErrorReported); } @@ -424,9 +433,9 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a }).map(|(ref impl_arg, ref trait_arg)| { (impl_arg.span, Some(trait_arg.span)) }) - .unwrap_or_else(|| (cause.span, tcx.hir.span_if_local(trait_m.def_id))) + .unwrap_or_else(|| (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))) } else { - (cause.span, tcx.hir.span_if_local(trait_m.def_id)) + (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)) } } TypeError::Sorts(ExpectedFound { .. }) => { @@ -459,14 +468,14 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a { (impl_m_output.span(), Some(trait_m_output.span())) } else { - (cause.span, tcx.hir.span_if_local(trait_m.def_id)) + (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)) } }) } else { - (cause.span, tcx.hir.span_if_local(trait_m.def_id)) + (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)) } } - _ => (cause.span, tcx.hir.span_if_local(trait_m.def_id)), + _ => (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)), } } diff --git a/src/test/compile-fail/E0195.rs b/src/test/compile-fail/E0195.rs index 06dd903b23d..4f4d7ce0dba 100644 --- a/src/test/compile-fail/E0195.rs +++ b/src/test/compile-fail/E0195.rs @@ -10,13 +10,14 @@ trait Trait { fn bar<'a,'b:'a>(x: &'a str, y: &'b str); + //~^ NOTE lifetimes in impl do not match this method in trait } struct Foo; impl Trait for Foo { fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195 - //~^ lifetimes do not match trait + //~^ NOTE lifetimes do not match method in trait } } diff --git a/src/test/compile-fail/issue-16048.rs b/src/test/compile-fail/issue-16048.rs index 5012556dedd..cda83fe54b0 100644 --- a/src/test/compile-fail/issue-16048.rs +++ b/src/test/compile-fail/issue-16048.rs @@ -10,6 +10,7 @@ trait NoLifetime { fn get<'p, T : Test<'p>>(&self) -> T; + //~^ NOTE lifetimes in impl do not match this method in trait } trait Test<'p> { @@ -28,8 +29,8 @@ impl<'a> Test<'a> for Foo<'a> { impl<'a> NoLifetime for Foo<'a> { fn get<'p, T : Test<'a>>(&self) -> T { -//~^ ERROR E0195 -//~| lifetimes do not match trait + //~^ ERROR E0195 + //~| NOTE lifetimes do not match method in trait return *self as T; } } diff --git a/src/test/ui/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-const-impl-wrong-lifetime.stderr index a7aee9b19f1..ab0e1003a9e 100644 --- a/src/test/ui/associated-const-impl-wrong-lifetime.stderr +++ b/src/test/ui/associated-const-impl-wrong-lifetime.stderr @@ -9,11 +9,8 @@ error[E0308]: mismatched types note: the lifetime 'a as defined on the impl at 17:1... --> $DIR/associated-const-impl-wrong-lifetime.rs:17:1 | -17 | / impl<'a> Foo for &'a () { -18 | | const NAME: &'a str = "unit"; -19 | | //~^ ERROR mismatched types [E0308] -20 | | } - | |_^ +17 | impl<'a> Foo for &'a () { + | ^^^^^^^^^^^^^^^^^^^^^^^ = note: ...does not necessarily outlive the static lifetime error: aborting due to previous error diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 81aec9fd0b0..e8323247af9 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -1,30 +1,26 @@ 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 | -28 | / fn no_bound<'b:'a>(self, b: Inv<'b>) { -29 | | //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match -30 | | } - | |_____^ lifetimes do not match trait +20 | fn no_bound<'b>(self, b: Inv<'b>); + | ---------------------------------- lifetimes in impl do not match this method in trait +... +28 | fn no_bound<'b:'a>(self, b: Inv<'b>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 | -32 | / fn has_bound<'b>(self, b: Inv<'b>) { -33 | | //~^ ERROR lifetime parameters or bounds on method `has_bound` do not match -34 | | } - | |_____^ lifetimes do not match trait +21 | fn has_bound<'b:'a>(self, b: Inv<'b>); + | -------------------------------------- lifetimes in impl do not match this method in trait +... +32 | fn has_bound<'b>(self, b: Inv<'b>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait error[E0308]: method not compatible with trait --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5 | -36 | / fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { -37 | | //~^ ERROR method not compatible with trait -38 | | // -39 | | // Note: This is a terrible error message. It is caused -... | -47 | | // cases. -48 | | } - | |_____^ lifetime mismatch +36 | 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>)` diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr index 7a0d01a8ec2..1417c71ca12 100644 --- a/src/test/ui/impl-trait/trait_type.stderr +++ b/src/test/ui/impl-trait/trait_type.stderr @@ -2,7 +2,7 @@ error[E0053]: method `fmt` has an incompatible type for trait --> $DIR/trait_type.rs:17:4 | 17 | fn fmt(&self, x: &str) -> () { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability | = note: expected type `fn(&MyType, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` found type `fn(&MyType, &str)` @@ -19,7 +19,7 @@ error[E0186]: method `fmt` has a `&self` declaration in the trait, but not in th --> $DIR/trait_type.rs:27:4 | 27 | fn fmt() -> () { } - | ^^^^^^^^^^^^^^^^^^ expected `&self` in impl + | ^^^^^^^^^^^^^^ expected `&self` in impl | = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr index 770520f2e8c..7aab31eb909 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -3,10 +3,8 @@ error[E0601]: main function not found error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements --> $DIR/mismatched_trait_impl-2.rs:18:5 | -18 | / fn deref(&self) -> &Trait { -19 | | unimplemented!(); -20 | | } - | |_____^ +18 | fn deref(&self) -> &Trait { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 18:5... --> $DIR/mismatched_trait_impl-2.rs:18:5 diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index 18aa980d6f3..fd6be01da9f 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -1,10 +1,8 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements --> $DIR/mismatched_trait_impl.rs:19:5 | -19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer -20 | | x -21 | | } - | |_____^ +19 | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 19:5... --> $DIR/mismatched_trait_impl.rs:19:5 diff --git a/src/test/ui/issue-27942.stderr b/src/test/ui/issue-27942.stderr index b580b8e7313..b24544743d8 100644 --- a/src/test/ui/issue-27942.stderr +++ b/src/test/ui/issue-27942.stderr @@ -14,14 +14,8 @@ note: the anonymous lifetime #1 defined on the method body at 15:5... note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 13:1 --> $DIR/issue-27942.rs:13:1 | -13 | / pub trait Buffer<'a, R: Resources<'a>> { -14 | | -15 | | fn select(&self) -> BufferViewHandle; -16 | | //~^ ERROR mismatched types -... | -19 | | //~| lifetime mismatch -20 | | } - | |_^ +13 | pub trait Buffer<'a, R: Resources<'a>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/issue-27942.rs:15:5 @@ -34,14 +28,8 @@ error[E0308]: mismatched types note: the lifetime 'a as defined on the trait at 13:1... --> $DIR/issue-27942.rs:13:1 | -13 | / pub trait Buffer<'a, R: Resources<'a>> { -14 | | -15 | | fn select(&self) -> BufferViewHandle; -16 | | //~^ ERROR mismatched types -... | -19 | | //~| lifetime mismatch -20 | | } - | |_^ +13 | pub trait Buffer<'a, R: Resources<'a>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...does not necessarily outlive the anonymous lifetime #1 defined on the method body at 15:5 --> $DIR/issue-27942.rs:15:5 | diff --git a/src/test/ui/issue-37884.stderr b/src/test/ui/issue-37884.stderr index 439b123975f..c4ad232ae7e 100644 --- a/src/test/ui/issue-37884.stderr +++ b/src/test/ui/issue-37884.stderr @@ -24,14 +24,8 @@ note: the anonymous lifetime #1 defined on the method body at 16:5... note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 13:1 --> $DIR/issue-37884.rs:13:1 | -13 | / impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { -14 | | -15 | | type Item = &'a mut T; -16 | | fn next(&'a mut self) -> Option -... | -21 | | } -22 | | } - | |_^ +13 | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issue-46472.stderr b/src/test/ui/issue-46472.stderr index 50df72fc2a0..38ed7c60086 100644 --- a/src/test/ui/issue-46472.stderr +++ b/src/test/ui/issue-46472.stderr @@ -10,12 +10,8 @@ error[E0597]: borrowed value does not live long enough (Ast) note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1... --> $DIR/issue-46472.rs:13:1 | -13 | / fn bar<'a>() -> &'a mut u32 { -14 | | &mut 4 -15 | | //~^ ERROR borrowed value does not live long enough (Ast) [E0597] -16 | | //~| ERROR borrowed value does not live long enough (Mir) [E0597] -17 | | } - | |_^ +13 | fn bar<'a>() -> &'a mut u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0597]: borrowed value does not live long enough (Mir) --> $DIR/issue-46472.rs:14:10 @@ -29,12 +25,8 @@ error[E0597]: borrowed value does not live long enough (Mir) note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1... --> $DIR/issue-46472.rs:13:1 | -13 | / fn bar<'a>() -> &'a mut u32 { -14 | | &mut 4 -15 | | //~^ ERROR borrowed value does not live long enough (Ast) [E0597] -16 | | //~| ERROR borrowed value does not live long enough (Mir) [E0597] -17 | | } - | |_^ +13 | fn bar<'a>() -> &'a mut u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr index a99dbf21e54..24ba27b27ad 100644 --- a/src/test/ui/static-lifetime.stderr +++ b/src/test/ui/static-lifetime.stderr @@ -8,7 +8,7 @@ note: lifetime parameter instantiated with the lifetime 'a as defined on the imp --> $DIR/static-lifetime.rs:13:1 | 13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but lifetime parameter must outlive the static lifetime error: aborting due to previous error