From ee065595767a7e024f1933e175dd52936f0f1b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 26 Jan 2018 16:38:07 -0800 Subject: [PATCH 1/3] Tweak presentation on lifetime trait mismatch --- src/librustc/infer/error_reporting/note.rs | 10 ++++------ .../mismatched_trait_impl.stderr | 20 ++++++------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index e46613b3e4d..02ec9fe74c1 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -23,12 +23,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some((expected, found)) = self.values_str(&trace.values) { let expected = expected.content(); let found = found.content(); - // FIXME: do we want a "the" here? - err.span_note(trace.cause.span, - &format!("...so that {} (expected {}, found {})", - trace.cause.as_requirement_str(), - expected, - found)); + err.note(&format!("...so that the {}:\nexpected {}\n found {}", + trace.cause.as_requirement_str(), + expected, + found)); } else { // FIXME: this really should be handled at some earlier stage. Our // handling of region checking when type errors are present is 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 e96f7181a6d..e559405dbd8 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -13,13 +13,9 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th 20 | | x 21 | | } | |_____^ -note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32) - --> $DIR/mismatched_trait_impl.rs:19:5 - | -19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer -20 | | x -21 | | } - | |_____^ + = note: ...so that the method type is compatible with trait: + expected fn(&i32, &'a u32, &u32) -> &'a u32 + found fn(&i32, &u32, &u32) -> &u32 note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 19:5... --> $DIR/mismatched_trait_impl.rs:19:5 | @@ -27,13 +23,9 @@ note: but, the lifetime must be valid for the lifetime 'a as defined on the meth 20 | | x 21 | | } | |_____^ -note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32) - --> $DIR/mismatched_trait_impl.rs:19:5 - | -19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer -20 | | x -21 | | } - | |_____^ + = note: ...so that the method type is compatible with trait: + expected fn(&i32, &'a u32, &u32) -> &'a u32 + found fn(&i32, &u32, &u32) -> &u32 error: aborting due to previous error From 6c026997bf1696ee64313135b82dfba3b0857805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 26 Jan 2018 17:41:59 -0800 Subject: [PATCH 2/3] For named lifetimes point only at method signature When refering to named lifetime conflict, point only at the method's signature span instead of the entire method. When the expected and found sup and sub traces are the same, avoid redundant text. --- src/librustc/infer/error_reporting/mod.rs | 65 +++++++++++++------ .../regions-bound-missing-bound-in-impl.rs | 0 ...regions-bound-missing-bound-in-impl.stderr | 52 +++++++++++++++ .../expect-region-supply-region.stderr | 20 ++---- .../mismatched_trait_impl-2.rs | 22 +++++++ .../mismatched_trait_impl-2.stderr | 24 +++++++ .../mismatched_trait_impl.stderr | 11 +--- 7 files changed, 150 insertions(+), 44 deletions(-) rename src/test/{compile-fail => ui/borrowck}/regions-bound-missing-bound-in-impl.rs (100%) create mode 100644 src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr create mode 100644 src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs create mode 100644 src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 541c1356dd4..a10bd40af36 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -175,25 +175,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::ReEarlyBound(_) | ty::ReFree(_) => { let scope = region.free_region_binding_scope(self); - let prefix = match *region { - ty::ReEarlyBound(ref br) => { - format!("the lifetime {} as defined on", br.name) - } - ty::ReFree(ref fr) => { - match fr.bound_region { - ty::BrAnon(idx) => { - format!("the anonymous lifetime #{} defined on", idx + 1) - } - ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(), - _ => { - format!("the lifetime {} as defined on", - fr.bound_region) - } - } - } - _ => bug!() - }; - let node = self.hir.as_local_node_id(scope) .unwrap_or(DUMMY_NODE_ID); let unknown; @@ -218,7 +199,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { &unknown } }; - let (msg, opt_span) = explain_span(self, tag, self.hir.span(node)); + let (prefix, span) = match *region { + ty::ReEarlyBound(ref br) => { + (format!("the lifetime {} as defined on", br.name), + self.sess.codemap().def_span(self.hir.span(node))) + } + ty::ReFree(ref fr) => { + match fr.bound_region { + ty::BrAnon(idx) => { + (format!("the anonymous lifetime #{} defined on", idx + 1), + self.hir.span(node)) + } + ty::BrFresh(_) => ("an anonymous lifetime defined on".to_owned(), + self.hir.span(node)), + _ => (format!("the lifetime {} as defined on", fr.bound_region), + self.sess.codemap().def_span(self.hir.span(node))), + } + } + _ => bug!() + }; + let (msg, opt_span) = explain_span(self, tag, span); (format!("{} {}", prefix, msg), opt_span) } @@ -1075,6 +1075,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { sup_region, "..."); + match (&sup_origin, &sub_origin) { + (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) => { + if let (Some((sup_expected, sup_found)), + Some((sub_expected, sub_found))) = (self.values_str(&sup_trace.values), + self.values_str(&sub_trace.values)) { + if sub_expected == sup_expected && sub_found == sup_found { + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "...but the lifetime must also be valid for ", + sub_region, + "...", + ); + err.note(&format!("...so that the {}:\nexpected {}\n found {}", + sup_trace.cause.as_requirement_str(), + sup_expected.content(), + sup_found.content())); + err.emit(); + return; + } + } + } + _ => {} + } + self.note_region_origin(&mut err, &sup_origin); self.tcx.note_and_explain_region(region_scope_tree, &mut err, diff --git a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs similarity index 100% rename from src/test/compile-fail/regions-bound-missing-bound-in-impl.rs rename to src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs 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 new file mode 100644 index 00000000000..81aec9fd0b0 --- /dev/null +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -0,0 +1,52 @@ +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 + +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 + +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 + | + = 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 + | +36 | 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 + | +36 | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0276]: impl has stricter requirements than trait + --> $DIR/regions-bound-missing-bound-in-impl.rs:53:5 + | +24 | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); + | ------------------------------------------------------- definition of `another_bound` from trait +... +53 | 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 + diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr index ebb1e561e57..5c612522d9a 100644 --- a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr @@ -41,14 +41,8 @@ note: the anonymous lifetime #2 defined on the body at 47:29... note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1 --> $DIR/expect-region-supply-region.rs:42:1 | -42 | / fn expect_bound_supply_named<'x>() { -43 | | let mut f: Option<&u32> = None; -44 | | -45 | | // Here we give a type annotation that `x` should be free. We get -... | -54 | | }); -55 | | } - | |_^ +42 | fn expect_bound_supply_named<'x>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/expect-region-supply-region.rs:47:33 @@ -61,14 +55,8 @@ error[E0308]: mismatched types note: the lifetime 'x as defined on the function body at 42:1... --> $DIR/expect-region-supply-region.rs:42:1 | -42 | / fn expect_bound_supply_named<'x>() { -43 | | let mut f: Option<&u32> = None; -44 | | -45 | | // Here we give a type annotation that `x` should be free. We get -... | -54 | | }); -55 | | } - | |_^ +42 | fn expect_bound_supply_named<'x>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29 --> $DIR/expect-region-supply-region.rs:47:29 | diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs new file mode 100644 index 00000000000..f845762cefd --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ops::Deref; +trait Trait {} + +struct Struct; + +impl Deref for Struct { + type Target = Trait; + fn deref(&self) -> &Trait { + unimplemented!(); + } +} +//~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter 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 new file mode 100644 index 00000000000..770520f2e8c --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -0,0 +1,24 @@ +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 | | } + | |_____^ + | +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 + | +18 | / fn deref(&self) -> &Trait { +19 | | unimplemented!(); +20 | | } + | |_____^ + = note: ...but the lifetime must also be valid for the static lifetime... + = note: ...so that the method type is compatible with trait: + expected fn(&Struct) -> &Trait + 'static + found fn(&Struct) -> &Trait + +error: aborting due to 2 previous errors + 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 e559405dbd8..18aa980d6f3 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -13,16 +13,11 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th 20 | | x 21 | | } | |_____^ - = note: ...so that the method type is compatible with trait: - expected fn(&i32, &'a u32, &u32) -> &'a u32 - found fn(&i32, &u32, &u32) -> &u32 -note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 19:5... +note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 19:5... --> $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: ...so that the method type is compatible with trait: expected fn(&i32, &'a u32, &u32) -> &'a u32 found fn(&i32, &u32, &u32) -> &u32 From 67696be160cc35ba5e54086a42225d9c1f81b275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 28 Jan 2018 13:42:49 -0800 Subject: [PATCH 3/3] Point only at method signatures and point at trait - On mismatch between impl and trait method, point at the trait signature. - Point only at the method signature instead of the whole body on trait/impl mismatch errors. --- src/librustc/infer/error_reporting/mod.rs | 6 +-- src/librustc/traits/mod.rs | 13 +++++++ src/librustc_typeck/check/compare_method.rs | 37 ++++++++++++------- src/test/compile-fail/E0195.rs | 3 +- src/test/compile-fail/issue-16048.rs | 5 ++- ...ssociated-const-impl-wrong-lifetime.stderr | 7 +--- ...regions-bound-missing-bound-in-impl.stderr | 28 ++++++-------- src/test/ui/impl-trait/trait_type.stderr | 4 +- .../mismatched_trait_impl-2.stderr | 6 +-- .../mismatched_trait_impl.stderr | 6 +-- src/test/ui/issue-27942.stderr | 20 ++-------- src/test/ui/issue-37884.stderr | 10 +---- src/test/ui/issue-46472.stderr | 16 ++------ src/test/ui/static-lifetime.stderr | 2 +- 14 files changed, 75 insertions(+), 88 deletions(-) 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