diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 1cc5daafed14e..cff83c3d5cda2 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -193,9 +193,18 @@ impl Diagnostic { expected_extra: &dyn fmt::Display, found_extra: &dyn fmt::Display, ) -> &mut Self { - let expected_label = format!("expected {}", expected_label); - - let found_label = format!("found {}", found_label); + let expected_label = expected_label.to_string(); + let expected_label = if expected_label.is_empty() { + "expected".to_string() + } else { + format!("expected {}", expected_label) + }; + let found_label = found_label.to_string(); + let found_label = if found_label.is_empty() { + "found".to_string() + } else { + format!("found {}", found_label) + }; let (found_padding, expected_padding) = if expected_label.len() > found_label.len() { (expected_label.len() - found_label.len(), 0) } else { diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index cc479aa17ce95..ae9019828170f 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -987,12 +987,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } fn push_ty_ref<'tcx>( - r: &ty::Region<'tcx>, + region: &ty::Region<'tcx>, ty: Ty<'tcx>, mutbl: hir::Mutability, s: &mut DiagnosticStyledString, ) { - let mut r = r.to_string(); + let mut r = region.to_string(); if r == "'_" { r.clear(); } else { diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 695f3e47fb5d7..5f14f799fc7aa 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -2,11 +2,16 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; -use crate::infer::{Subtype, ValuePairs}; +use crate::infer::{Subtype, TyCtxtInferExt, ValuePairs}; use crate::traits::ObligationCauseCode::CompareImplMethodObligation; use rustc_errors::ErrorReported; -use rustc_middle::ty::Ty; -use rustc_span::Span; +use rustc_hir as hir; +use rustc_hir::def::Res; +use rustc_hir::def_id::DefId; +use rustc_hir::intravisit::Visitor; +use rustc_middle::ty::error::ExpectedFound; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::{MultiSpan, Span}; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`. @@ -36,7 +41,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { var_origin.span(), sub_expected_found.expected, sub_expected_found.found, - self.tcx().def_span(*trait_item_def_id), + *trait_item_def_id, ); return Some(ErrorReported); } @@ -47,14 +52,100 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { None } - fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Span) { + fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) { + let tcx = self.tcx(); + let trait_sp = self.tcx().def_span(trait_def_id); let mut err = self .tcx() .sess .struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature"); - err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found)); - err.span_label(sp, &format!("found {:?}", found)); - err.span_label(impl_sp, &format!("expected {:?}", expected)); + err.span_label(sp, &format!("found `{:?}`", found)); + err.span_label(trait_sp, &format!("expected `{:?}`", expected)); + + // Get the span of all the used type parameters in the method. + let assoc_item = self.tcx().associated_item(trait_def_id); + let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] }; + match assoc_item.kind { + ty::AssocKind::Fn => { + let hir = self.tcx().hir(); + if let Some(hir_id) = assoc_item.def_id.as_local().map(|id| hir.as_local_hir_id(id)) + { + if let Some(decl) = hir.fn_decl_by_hir_id(hir_id) { + visitor.visit_fn_decl(decl); + } + } + } + _ => {} + } + let mut type_param_span: MultiSpan = + visitor.types.iter().cloned().collect::>().into(); + for &span in &visitor.types { + type_param_span.push_span_label( + span, + "consider borrowing this type parameter in the trait".to_string(), + ); + } + + if let Some((expected, found)) = tcx + .infer_ctxt() + .enter(|infcx| infcx.expected_found_str_ty(&ExpectedFound { expected, found })) + { + // Highlighted the differences when showing the "expected/found" note. + err.note_expected_found(&"", expected, &"", found); + } else { + // This fallback shouldn't be necessary, but let's keep it in just in case. + err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found)); + } + err.span_help( + type_param_span, + "the lifetime requirements from the `impl` do not correspond to the requirements in \ + the `trait`", + ); + if visitor.types.is_empty() { + err.help( + "verify the lifetime relationships in the `trait` and `impl` between the `self` \ + argument, the other inputs and its output", + ); + } err.emit(); } } + +struct TypeParamSpanVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + types: Vec, +} + +impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> { + type Map = rustc_middle::hir::map::Map<'tcx>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap { + hir::intravisit::NestedVisitorMap::OnlyBodies(self.tcx.hir()) + } + + fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) { + match arg.kind { + hir::TyKind::Rptr(_, ref mut_ty) => { + // We don't want to suggest looking into borrowing `&T` or `&Self`. + hir::intravisit::walk_ty(self, mut_ty.ty); + return; + } + hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments { + [segment] + if segment + .res + .map(|res| match res { + Res::SelfTy(_, _) | Res::Def(hir::def::DefKind::TyParam, _) => true, + _ => false, + }) + .unwrap_or(false) => + { + self.types.push(path.span); + } + _ => {} + }, + _ => {} + } + hir::intravisit::walk_ty(self, arg); + } +} diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 3e39c8a792446..137cb83ccd327 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -14,16 +14,16 @@ note: ...so that the expression is assignable | LL | bar(foo, x) | ^ - = note: expected `Type<'_>` - found `Type<'a>` + = note: expected `Type<'_>` + found `Type<'a>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that the expression is assignable --> $DIR/project-fn-ret-invariant.rs:48:4 | LL | bar(foo, x) | ^^^^^^^^^^^ - = note: expected `Type<'static>` - found `Type<'_>` + = note: expected `Type<'static>` + found `Type<'_>` error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0490.stderr b/src/test/ui/error-codes/E0490.stderr index 03fce213605e3..9ba5bc330ea93 100644 --- a/src/test/ui/error-codes/E0490.stderr +++ b/src/test/ui/error-codes/E0490.stderr @@ -58,8 +58,8 @@ note: ...so that the expression is assignable | LL | let x: &'a _ = &y; | ^^ - = note: expected `&'a &()` - found `&'a &'b ()` + = note: expected `&'a &()` + found `&'a &'b ()` note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 1:6... --> $DIR/E0490.rs:1:6 | diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr index 3300293bb36ca..268008c211129 100644 --- a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr +++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr @@ -14,16 +14,16 @@ note: ...so that the expression is assignable | LL | static_val(x); | ^ - = note: expected `std::boxed::Box` - found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>` + = note: expected `std::boxed::Box` + found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that the types are compatible --> $DIR/dyn-trait.rs:20:5 | LL | static_val(x); | ^^^^^^^^^^ - = note: expected `StaticTrait` - found `StaticTrait` + = note: expected `StaticTrait` + found `StaticTrait` error: aborting due to previous 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 c1c4ec9ed7b92..b93d98ca39f47 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 @@ -2,15 +2,17 @@ error: `impl` item signature doesn't match `trait` item signature --> $DIR/mismatched_trait_impl-2.rs:8:5 | LL | fn deref(&self) -> &dyn Trait { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Struct) -> &dyn Trait` | ::: $SRC_DIR/libcore/ops/deref.rs:LL:COL | LL | fn deref(&self) -> &Self::Target; - | --------------------------------- expected fn(&Struct) -> &(dyn Trait + 'static) + | --------------------------------- expected `fn(&Struct) -> &(dyn Trait + 'static)` | = note: expected `fn(&Struct) -> &(dyn Trait + 'static)` found `fn(&Struct) -> &dyn Trait` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output error: aborting due to previous error diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr index c245d78ae828f..149c2aeb958c0 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr @@ -2,13 +2,15 @@ error: `impl` item signature doesn't match `trait` item signature --> $DIR/mismatched_trait_impl.rs:9:5 | LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32; - | ---------------------------------------------- expected fn(&i32, &'a u32, &u32) -> &'a u32 + | ---------------------------------------------- expected `fn(&i32, &'a u32, &u32) -> &'a u32` ... LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &u32, &u32) -> &u32` | = note: expected `fn(&i32, &'a u32, &u32) -> &'a u32` found `fn(&i32, &u32, &u32) -> &u32` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output error: aborting due to previous error 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 15891c9e7a62d..9a0bd827850cf 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -2,13 +2,15 @@ error: `impl` item signature doesn't match `trait` item signature --> $DIR/mismatched_trait_impl.rs:9:5 | LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32; - | ---------------------------------------------- expected fn(&i32, &'a u32, &u32) -> &'a u32 + | ---------------------------------------------- expected `fn(&i32, &'a u32, &u32) -> &'a u32` ... LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &u32, &u32) -> &u32` | = note: expected `fn(&i32, &'a u32, &u32) -> &'a u32` found `fn(&i32, &u32, &u32) -> &u32` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output error[E0623]: lifetime mismatch --> $DIR/mismatched_trait_impl.rs:10:9 diff --git a/src/test/ui/issues/issue-16683.stderr b/src/test/ui/issues/issue-16683.stderr index 99700f2084e4a..4f65833075814 100644 --- a/src/test/ui/issues/issue-16683.stderr +++ b/src/test/ui/issues/issue-16683.stderr @@ -26,8 +26,8 @@ note: ...so that the types are compatible | LL | self.a(); | ^ - = note: expected `&'a Self` - found `&Self` + = note: expected `&'a Self` + found `&Self` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17758.stderr b/src/test/ui/issues/issue-17758.stderr index adfc3f5085826..31788cfa61c4c 100644 --- a/src/test/ui/issues/issue-17758.stderr +++ b/src/test/ui/issues/issue-17758.stderr @@ -27,8 +27,8 @@ note: ...so that the types are compatible | LL | self.foo(); | ^^^ - = note: expected `&'a Self` - found `&Self` + = note: expected `&'a Self` + found `&Self` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index a785a956ca9f5..e7c1dcc5d698c 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -87,8 +87,8 @@ note: ...so that the types are compatible | LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `Publisher<'_>` - found `Publisher<'_>` + = note: expected `Publisher<'_>` + found `Publisher<'_>` error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> $DIR/issue-20831-debruijn.rs:28:33 @@ -117,8 +117,8 @@ note: ...so that the types are compatible | LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `Publisher<'_>` - found `Publisher<'_>` + = note: expected `Publisher<'_>` + found `Publisher<'_>` error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-52213.stderr b/src/test/ui/issues/issue-52213.stderr index a8960f7756367..7463af9332a76 100644 --- a/src/test/ui/issues/issue-52213.stderr +++ b/src/test/ui/issues/issue-52213.stderr @@ -14,8 +14,8 @@ note: ...so that the types are compatible | LL | match (&t,) { | ^^^^^ - = note: expected `(&&(T,),)` - found `(&&'a (T,),)` + = note: expected `(&&(T,),)` + found `(&&'a (T,),)` note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 1:27... --> $DIR/issue-52213.rs:1:27 | diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr index b8cafdc5c14b5..6bfb7af54446d 100644 --- a/src/test/ui/issues/issue-55796.stderr +++ b/src/test/ui/issues/issue-55796.stderr @@ -20,8 +20,8 @@ note: ...so that the expression is assignable | LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)>` - found `std::boxed::Box>::Node>>` + = note: expected `std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)>` + found `std::boxed::Box>::Node>>` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/issue-55796.rs:21:9 @@ -45,8 +45,8 @@ note: ...so that the expression is assignable | LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)>` - found `std::boxed::Box>::Node>>` + = note: expected `std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)>` + found `std::boxed::Box>::Node>>` error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr index d07f305954b6e..060e6954403c0 100644 --- a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr +++ b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr @@ -2,13 +2,15 @@ error: `impl` item signature doesn't match `trait` item signature --> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5 | LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; - | ------------------------------------------- expected fn(&i32, &'a i32) -> &'a i32 + | ------------------------------------------- expected `fn(&i32, &'a i32) -> &'a i32` ... LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &i32) -> &i32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&i32, &i32) -> &i32` | = note: expected `fn(&i32, &'a i32) -> &'a i32` found `fn(&i32, &i32) -> &i32` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output error: aborting due to previous error diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr index 69a6ab004fd91..ba8d91b8455bf 100644 --- a/src/test/ui/nll/issue-55394.stderr +++ b/src/test/ui/nll/issue-55394.stderr @@ -26,8 +26,8 @@ note: ...so that the expression is assignable | LL | Foo { bar } | ^^^^^^^^^^^ - = note: expected `Foo<'_>` - found `Foo<'_>` + = note: expected `Foo<'_>` + found `Foo<'_>` error: aborting due to previous error diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr index 58f206742f4f5..d003acd879a77 100644 --- a/src/test/ui/nll/normalization-bounds-error.stderr +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -19,8 +19,8 @@ note: ...so that the types are compatible | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `Visitor<'d>` - found `Visitor<'_>` + = note: expected `Visitor<'d>` + found `Visitor<'_>` error: aborting due to previous error diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr index 5191deca281cc..3317aae83bb08 100644 --- a/src/test/ui/nll/type-alias-free-regions.stderr +++ b/src/test/ui/nll/type-alias-free-regions.stderr @@ -16,8 +16,8 @@ note: ...so that the expression is assignable | LL | C { f: b } | ^ - = note: expected `std::boxed::Box>` - found `std::boxed::Box>` + = note: expected `std::boxed::Box>` + found `std::boxed::Box>` note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 15:6... --> $DIR/type-alias-free-regions.rs:15:6 | @@ -28,8 +28,8 @@ note: ...so that the expression is assignable | LL | C { f: b } | ^^^^^^^^^^ - = note: expected `C<'a>` - found `C<'_>` + = note: expected `C<'a>` + found `C<'_>` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/type-alias-free-regions.rs:27:16 @@ -49,8 +49,8 @@ note: ...so that the expression is assignable | LL | C { f: Box::new(b.0) } | ^^^ - = note: expected `std::boxed::Box<&isize>` - found `std::boxed::Box<&isize>` + = note: expected `std::boxed::Box<&isize>` + found `std::boxed::Box<&isize>` note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 25:6... --> $DIR/type-alias-free-regions.rs:25:6 | @@ -61,8 +61,8 @@ note: ...so that the expression is assignable | LL | C { f: Box::new(b.0) } | ^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `C<'a>` - found `C<'_>` + = note: expected `C<'a>` + found `C<'_>` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr index 37be450fd0a79..8421dc1d0c130 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -14,8 +14,8 @@ note: ...so that the types are compatible | LL | >::C | ^^^^^^^^^^^^ - = note: expected `Foo<'_>` - found `Foo<'a>` + = note: expected `Foo<'_>` + found `Foo<'a>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that reference does not outlive borrowed content --> $DIR/constant-in-expr-inherent-1.rs:8:5 diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr index 4ee32847c5ec8..ba0a1748c5e9f 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr @@ -14,8 +14,8 @@ note: ...so that the types are compatible | LL | T::C | ^^^^ - = note: expected `Foo<'_>` - found `Foo<'a>` + = note: expected `Foo<'_>` + found `Foo<'a>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that reference does not outlive borrowed content --> $DIR/constant-in-expr-trait-item-3.rs:10:5 diff --git a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr index 1952ee8269d5b..79ded5fc875a2 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr @@ -24,8 +24,8 @@ note: ...so that the expression is assignable | LL | ss | ^^ - = note: expected `&'b (dyn SomeTrait + 'b)` - found `&dyn SomeTrait` + = note: expected `&'b (dyn SomeTrait + 'b)` + found `&dyn SomeTrait` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/object-lifetime-default-elision.rs:71:5 @@ -53,8 +53,8 @@ note: ...so that the expression is assignable | LL | ss | ^^ - = note: expected `&'b (dyn SomeTrait + 'b)` - found `&dyn SomeTrait` + = note: expected `&'b (dyn SomeTrait + 'b)` + found `&dyn SomeTrait` error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index e889651647034..069b897603cb9 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -39,8 +39,8 @@ note: ...so that the expression is assignable | LL | Box::new(v) | ^ - = note: expected `&[u8]` - found `&'a [u8]` + = note: expected `&[u8]` + found `&'a [u8]` note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9... --> $DIR/region-object-lifetime-in-coercion.rs:25:9 | @@ -51,8 +51,8 @@ note: ...so that the expression is assignable | LL | Box::new(v) | ^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn Foo + 'b)>` - found `std::boxed::Box` + = note: expected `std::boxed::Box<(dyn Foo + 'b)>` + found `std::boxed::Box` error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr index 865e967fba32e..c134b3b3ed554 100644 --- a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr +++ b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr @@ -14,8 +14,8 @@ note: ...so that the types are compatible | LL | impl<'a> Foo<'static> for &'a i32 { | ^^^^^^^^^^^^ - = note: expected `Foo<'static>` - found `Foo<'static>` + = note: expected `Foo<'static>` + found `Foo<'static>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that the type `&i32` will meet its required lifetime bounds --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:14:10 @@ -39,8 +39,8 @@ note: ...so that the types are compatible | LL | impl<'a,'b> Foo<'b> for &'a i64 { | ^^^^^^^ - = note: expected `Foo<'b>` - found `Foo<'_>` + = note: expected `Foo<'b>` + found `Foo<'_>` note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 19:9... --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:9 | diff --git a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr index 6a34871c07efd..ac8c55ccc8fd4 100644 --- a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr +++ b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr @@ -14,8 +14,8 @@ note: ...so that the types are compatible | LL | impl<'a> Foo for &'a i32 { | ^^^ - = note: expected `Foo` - found `Foo` + = note: expected `Foo` + found `Foo` = note: but, the lifetime must be valid for the static lifetime... note: ...so that the type `&i32` will meet its required lifetime bounds --> $DIR/regions-assoc-type-static-bound-in-trait-not-met.rs:9:10 diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 28873ab807f8d..147f7f3541816 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -20,8 +20,8 @@ note: ...so that the expression is assignable | LL | box B(&*v) as Box | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn X + 'static)>` - found `std::boxed::Box` + = note: expected `std::boxed::Box<(dyn X + 'static)>` + found `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 449a5b5fdd4d6..6e7d6152cd09a 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -20,8 +20,8 @@ note: ...so that the expression is assignable | LL | box B(&*v) as Box | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn X + 'static)>` - found `std::boxed::Box` + = note: expected `std::boxed::Box<(dyn X + 'static)>` + found `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr index b2a7afaf1b452..2070ce257b18d 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr @@ -24,8 +24,8 @@ note: ...so that the expression is assignable | LL | box v as Box | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn SomeTrait + 'c)>` - found `std::boxed::Box` + = note: expected `std::boxed::Box<(dyn SomeTrait + 'c)>` + found `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-creating-enums4.stderr b/src/test/ui/regions/regions-creating-enums4.stderr index 58f74e4ee142d..b24db1df18b0a 100644 --- a/src/test/ui/regions/regions-creating-enums4.stderr +++ b/src/test/ui/regions/regions-creating-enums4.stderr @@ -14,8 +14,8 @@ note: ...so that the expression is assignable | LL | Ast::Add(x, y) | ^ - = note: expected `&Ast<'_>` - found `&Ast<'a>` + = note: expected `&Ast<'_>` + found `&Ast<'a>` note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 6:19... --> $DIR/regions-creating-enums4.rs:6:19 | @@ -26,8 +26,8 @@ note: ...so that the expression is assignable | LL | Ast::Add(x, y) | ^^^^^^^^^^^^^^ - = note: expected `Ast<'b>` - found `Ast<'_>` + = note: expected `Ast<'b>` + found `Ast<'_>` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.stderr index 8fce1609d7830..9e405d83140d8 100644 --- a/src/test/ui/regions/regions-nested-fns.stderr +++ b/src/test/ui/regions/regions-nested-fns.stderr @@ -39,8 +39,8 @@ LL | | if false { return ay; } LL | | return z; LL | | })); | |_____^ - = note: expected `&isize` - found `&isize` + = note: expected `&isize` + found `&isize` error[E0312]: lifetime of reference outlives lifetime of borrowed content... --> $DIR/regions-nested-fns.rs:14:27 diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr index c35516d2c0871..dc93d620ca637 100644 --- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -29,8 +29,8 @@ LL | | where <() as Project<'a, 'b>>::Item : Eq LL | | { LL | | } | |_^ - = note: expected `Project<'a, 'b>` - found `Project<'_, '_>` + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 @@ -63,8 +63,8 @@ LL | | where <() as Project<'a, 'b>>::Item : Eq LL | | { LL | | } | |_^ - = note: expected `Project<'a, 'b>` - found `Project<'_, '_>` + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> $DIR/regions-normalize-in-where-clause-list.rs:22:4 @@ -87,8 +87,8 @@ note: ...so that the types are compatible | LL | fn bar<'a, 'b>() | ^^^ - = note: expected `Project<'a, 'b>` - found `Project<'_, '_>` + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` error: aborting due to 3 previous errors diff --git a/src/test/ui/regions/regions-ret-borrowed-1.stderr b/src/test/ui/regions/regions-ret-borrowed-1.stderr index 2895a0ccdeec8..2c4769d8e3751 100644 --- a/src/test/ui/regions/regions-ret-borrowed-1.stderr +++ b/src/test/ui/regions/regions-ret-borrowed-1.stderr @@ -14,8 +14,8 @@ note: ...so that the expression is assignable | LL | with(|o| o) | ^ - = note: expected `&isize` - found `&isize` + = note: expected `&isize` + found `&isize` note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 9:14... --> $DIR/regions-ret-borrowed-1.rs:9:14 | diff --git a/src/test/ui/regions/regions-ret-borrowed.stderr b/src/test/ui/regions/regions-ret-borrowed.stderr index b74f10f5075eb..da560107cea99 100644 --- a/src/test/ui/regions/regions-ret-borrowed.stderr +++ b/src/test/ui/regions/regions-ret-borrowed.stderr @@ -14,8 +14,8 @@ note: ...so that the expression is assignable | LL | with(|o| o) | ^ - = note: expected `&isize` - found `&isize` + = note: expected `&isize` + found `&isize` note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 12:14... --> $DIR/regions-ret-borrowed.rs:12:14 | diff --git a/src/test/ui/regions/regions-trait-object-subtyping.stderr b/src/test/ui/regions/regions-trait-object-subtyping.stderr index 58b79d212700c..7478b53bd3ccc 100644 --- a/src/test/ui/regions/regions-trait-object-subtyping.stderr +++ b/src/test/ui/regions/regions-trait-object-subtyping.stderr @@ -41,8 +41,8 @@ note: ...so that the expression is assignable | LL | x | ^ - = note: expected `&'b mut (dyn Dummy + 'b)` - found `&mut (dyn Dummy + 'b)` + = note: expected `&'b mut (dyn Dummy + 'b)` + found `&mut (dyn Dummy + 'b)` error[E0308]: mismatched types --> $DIR/regions-trait-object-subtyping.rs:22:5 diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index c09418de51830..f819faa278995 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -118,8 +118,8 @@ note: ...so that the types are compatible | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `W<'l1, 'l2>` - found `W<'_, '_>` + = note: expected `W<'l1, 'l2>` + found `W<'_, '_>` error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the enum it is implemented for does not --> $DIR/reject-specialized-drops-8142.rs:61:14 diff --git a/src/test/ui/traits/self-without-lifetime-constraint.rs b/src/test/ui/traits/self-without-lifetime-constraint.rs new file mode 100644 index 0000000000000..99013d32ab8d0 --- /dev/null +++ b/src/test/ui/traits/self-without-lifetime-constraint.rs @@ -0,0 +1,53 @@ +use std::error::Error; +use std::fmt; + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ValueRef<'a> { + Null, + Integer(i64), + Real(f64), + Text(&'a [u8]), + Blob(&'a [u8]), +} + +impl<'a> ValueRef<'a> { + pub fn as_str(&self) -> FromSqlResult<&'a str, &'a &'a str> { + match *self { + ValueRef::Text(t) => { + std::str::from_utf8(t).map_err(|_| FromSqlError::InvalidType).map(|x| (x, &x)) + } + _ => Err(FromSqlError::InvalidType), + } + } +} + +#[derive(Debug)] +#[non_exhaustive] +pub enum FromSqlError { + InvalidType +} + +impl fmt::Display for FromSqlError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "InvalidType") + } +} + +impl Error for FromSqlError {} + +pub type FromSqlResult = Result<(T, K), FromSqlError>; + +pub trait FromSql: Sized { + fn column_result(value: ValueRef<'_>) -> FromSqlResult; +} + +impl FromSql for &str { + fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> { + //~^ ERROR `impl` item signature doesn't match `trait` item signature + value.as_str() + } +} + +pub fn main() { + println!("{}", "Hello World"); +} diff --git a/src/test/ui/traits/self-without-lifetime-constraint.stderr b/src/test/ui/traits/self-without-lifetime-constraint.stderr new file mode 100644 index 0000000000000..6c7abe753e2bf --- /dev/null +++ b/src/test/ui/traits/self-without-lifetime-constraint.stderr @@ -0,0 +1,19 @@ +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/self-without-lifetime-constraint.rs:45:5 + | +LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult; + | -------------------------------------------------------------------- expected `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), FromSqlError>` +... +LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), FromSqlError>` + | + = note: expected `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), _>` + found `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), _>` +help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + --> $DIR/self-without-lifetime-constraint.rs:41:60 + | +LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult; + | ^^^^ consider borrowing this type parameter in the trait + +error: aborting due to previous error + diff --git a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr index 9fdcd4de495c0..46aa7db967ad4 100644 --- a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr +++ b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr @@ -19,8 +19,8 @@ note: ...so that the types are compatible | LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { | ^^^^^^^^^^ - = note: expected `T1<'a>` - found `T1<'_>` + = note: expected `T1<'a>` + found `T1<'_>` error: aborting due to previous error diff --git a/src/test/ui/traits/trait-param-without-lifetime-constraint.rs b/src/test/ui/traits/trait-param-without-lifetime-constraint.rs new file mode 100644 index 0000000000000..a79b74dcddead --- /dev/null +++ b/src/test/ui/traits/trait-param-without-lifetime-constraint.rs @@ -0,0 +1,20 @@ +struct Article { + proof_reader: ProofReader, +} + +struct ProofReader { + name: String, +} + +pub trait HaveRelationship { + fn get_relation(&self) -> To; +} + +impl HaveRelationship<&ProofReader> for Article { + fn get_relation(&self) -> &ProofReader { + //~^ ERROR `impl` item signature doesn't match `trait` item signature + &self.proof_reader + } +} + +fn main() {} diff --git a/src/test/ui/traits/trait-param-without-lifetime-constraint.stderr b/src/test/ui/traits/trait-param-without-lifetime-constraint.stderr new file mode 100644 index 0000000000000..4942dbe480ba3 --- /dev/null +++ b/src/test/ui/traits/trait-param-without-lifetime-constraint.stderr @@ -0,0 +1,19 @@ +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/trait-param-without-lifetime-constraint.rs:14:5 + | +LL | fn get_relation(&self) -> To; + | ----------------------------- expected `fn(&Article) -> &ProofReader` +... +LL | fn get_relation(&self) -> &ProofReader { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Article) -> &ProofReader` + | + = note: expected `fn(&Article) -> &ProofReader` + found `fn(&Article) -> &ProofReader` +help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + --> $DIR/trait-param-without-lifetime-constraint.rs:10:31 + | +LL | fn get_relation(&self) -> To; + | ^^ consider borrowing this type parameter in the trait + +error: aborting due to previous error + diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index e6029e0d4623a..e3c9d50dfe5b3 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -23,8 +23,8 @@ note: ...so that the expression is assignable | LL | Box::new(items.iter()) | ^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn std::iter::Iterator + 'static)>` - found `std::boxed::Box>` + = note: expected `std::boxed::Box<(dyn std::iter::Iterator + 'static)>` + found `std::boxed::Box>` error: aborting due to previous error