From fca5c64abdf3422b3dc22910abd5460cca450d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 18 Jan 2020 14:57:56 -0800 Subject: [PATCH 01/23] Point at arguments or output when fn obligations come from them, or ident when they don't --- src/librustc_typeck/check/wfcheck.rs | 29 ++++++-- .../bad-bounds-on-assoc-in-trait.stderr | 67 +++++------------ ...ds-cant-promote-superkind-in-struct.stderr | 18 ++--- src/test/ui/error-codes/E0038.stderr | 4 +- ...ature-gate-object_safe_for_dispatch.stderr | 16 ++-- .../generic-associated-types/iterable.stderr | 26 +++---- src/test/ui/issues/issue-18919.stderr | 8 +- src/test/ui/issues/issue-18959.stderr | 4 +- src/test/ui/issues/issue-20005.stderr | 18 ++--- src/test/ui/issues/issue-20413.stderr | 13 ++-- src/test/ui/issues/issue-20433.stderr | 4 +- .../ui/issues/issue-20831-debruijn.stderr | 48 +++--------- src/test/ui/issues/issue-21974.stderr | 16 ++-- src/test/ui/issues/issue-23281.stderr | 4 +- src/test/ui/issues/issue-24204.stderr | 4 +- src/test/ui/issues/issue-27942.stderr | 8 +- .../lifetime-doesnt-live-long-enough.stderr | 74 +++++++------------ ...bject-safety-associated-consts.curr.stderr | 4 +- .../object-safety-generics.curr.stderr | 8 +- .../object-safety-mentions-Self.curr.stderr | 8 +- .../object-safety-no-static.curr.stderr | 4 +- .../object-safety-sized-2.curr.stderr | 4 +- .../object-safety-sized.curr.stderr | 4 +- ...gions-free-region-ordering-callee-4.stderr | 10 +-- ...-implied-bounds-projection-gap-hr-1.stderr | 9 +-- ...ions-normalize-in-where-clause-list.stderr | 22 ++---- src/test/ui/resolve/issue-3907-2.stderr | 4 +- ...-bounds-on-structs-and-enums-in-fns.stderr | 8 +- ...rait-bounds-on-structs-and-enums-xc.stderr | 8 +- .../generic_duplicate_lifetime_param.stderr | 8 +- .../ui/type/type-check/issue-40294.stderr | 16 ++-- src/test/ui/wf/wf-fn-where-clause.stderr | 25 +++---- src/test/ui/wf/wf-in-fn-arg.stderr | 17 ++--- src/test/ui/wf/wf-in-fn-ret.stderr | 17 ++--- src/test/ui/wf/wf-in-fn-where-clause.stderr | 16 ++-- ...f-inherent-impl-method-where-clause.stderr | 15 ++-- src/test/ui/wf/wf-trait-default-fn-arg.stderr | 19 ++--- src/test/ui/wf/wf-trait-default-fn-ret.stderr | 20 ++--- .../wf-trait-default-fn-where-clause.stderr | 19 ++--- src/test/ui/wf/wf-trait-fn-arg.stderr | 9 +-- src/test/ui/wf/wf-trait-fn-ret.stderr | 9 +-- .../ui/wf/wf-trait-fn-where-clause.stderr | 9 +-- 42 files changed, 261 insertions(+), 392 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 82811826ae7e7..ef3dcf1587301 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -219,9 +219,17 @@ fn check_associated_item( ty::AssocKind::Method => { let sig = fcx.tcx.fn_sig(item.def_id); let sig = fcx.normalize_associated_types_in(span, &sig); - check_fn_or_method(tcx, fcx, span, sig, item.def_id, &mut implied_bounds); - let sig_if_method = sig_if_method.expect("bad signature for method"); - check_method_receiver(fcx, sig_if_method, &item, self_ty); + let hir_sig = sig_if_method.expect("bad signature for method"); + check_fn_or_method( + tcx, + fcx, + item.ident.span, + sig, + hir_sig, + item.def_id, + &mut implied_bounds, + ); + check_method_receiver(fcx, hir_sig, &item, self_ty); } ty::AssocKind::Type => { if item.defaultness.has_value() { @@ -364,7 +372,11 @@ fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { let sig = fcx.tcx.fn_sig(def_id); let sig = fcx.normalize_associated_types_in(item.span, &sig); let mut implied_bounds = vec![]; - check_fn_or_method(tcx, fcx, item.span, sig, def_id, &mut implied_bounds); + let hir_sig = match &item.kind { + ItemKind::Fn(sig, ..) => sig, + _ => bug!("expected `ItemKind::Fn`, found `{:?}`", item.kind), + }; + check_fn_or_method(tcx, fcx, item.ident.span, sig, hir_sig, def_id, &mut implied_bounds); implied_bounds }) } @@ -609,18 +621,23 @@ fn check_fn_or_method<'fcx, 'tcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, sig: ty::PolyFnSig<'tcx>, + hir_sig: &hir::FnSig<'_>, def_id: DefId, implied_bounds: &mut Vec>, ) { let sig = fcx.normalize_associated_types_in(span, &sig); let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); - for input_ty in sig.inputs() { + for (input_ty, span) in sig.inputs().iter().zip(hir_sig.decl.inputs.iter().map(|t| t.span)) { fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); } implied_bounds.extend(sig.inputs()); - fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::ReturnType); + fcx.register_wf_obligation( + sig.output(), + hir_sig.decl.output.span(), + ObligationCauseCode::ReturnType, + ); // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 5303a09644d50..33fe8a3124083 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -9,74 +9,47 @@ LL | impl Case1 for S1 { error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterator --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | fn assume_case1() { - | ^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` - | _| - | | -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<::C as std::iter::Iterator>::Item` is not an iterator +LL | fn assume_case1() { + | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` + | | + | `<::C as std::iter::Iterator>::Item` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | trait Case1 { - | ----------- required by `Case1` +LL | trait Case1 { + | ----------- required by `Case1` ... -LL | fn assume_case1() { - | ^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` - | _| - | | -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely +LL | fn assume_case1() { + | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` + | | + | `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely | = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | trait Case1 { - | ----------- required by `Case1` +LL | trait Case1 { + | ----------- required by `Case1` ... -LL | fn assume_case1() { - | ^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` - | _| - | | -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely +LL | fn assume_case1() { + | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` + | | + | `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely | = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | trait Case1 { - | ----------- required by `Case1` +LL | trait Case1 { + | ----------- required by `Case1` ... -LL | / fn assume_case1() { -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` +LL | fn assume_case1() { + | ^^^^^^^^^^^^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App` diff --git a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr index 3c8f637e13369..0834014b31c35 100644 --- a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr +++ b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr @@ -1,17 +1,13 @@ error[E0277]: `F` cannot be sent between threads safely - --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:5:1 + --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:5:22 | -LL | struct X where F: FnOnce() + 'static + Send { - | ---------------------------------------------- required by `X` +LL | struct X where F: FnOnce() + 'static + Send { + | ---------------------------------------------- required by `X` ... -LL | fn foo(blk: F) -> X where F: FnOnce() + 'static { - | ^ - help: consider further restricting type parameter `F`: `, F: std::marker::Send` - | _| - | | -LL | | -LL | | return X { field: blk }; -LL | | } - | |_^ `F` cannot be sent between threads safely +LL | fn foo(blk: F) -> X where F: FnOnce() + 'static { + | ^^^^ - help: consider further restricting type parameter `F`: `, F: std::marker::Send` + | | + | `F` cannot be sent between threads safely | = help: the trait `std::marker::Send` is not implemented for `F` diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index 5c4d6d53c4626..6eaf6e4a8aad1 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/E0038.rs:5:1 + --> $DIR/E0038.rs:5:16 | LL | fn foo(&self) -> Self; | --- method `foo` references the `Self` type in its parameters or return type ... LL | fn call_foo(x: Box) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index 54e64e2fc1bd4..a2409621db310 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -1,37 +1,37 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object | = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `NonObjectSafe2` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36 | LL | fn static_fn() {} | --------- associated function `static_fn` has no `self` parameter ... LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object error[E0038]: the trait `NonObjectSafe3` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 | LL | fn foo(&self); | --- method `foo` has generic type parameters ... LL | fn takes_non_object_safe_box(obj: Box) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object error[E0038]: the trait `NonObjectSafe4` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35 | LL | fn foo(&self, &Self); | --- method `foo` references the `Self` type in its parameters or return type ... LL | fn return_non_object_safe_rc() -> std::rc::Rc { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr index d0d75f3cc6336..ccb1c9bcc7f4e 100644 --- a/src/test/ui/generic-associated-types/iterable.stderr +++ b/src/test/ui/generic-associated-types/iterable.stderr @@ -25,16 +25,13 @@ LL | type Item<'a> where T: 'a = as Iterator>::Item = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> < as Iterable>::Iter<'a> as std::iter::Iterator>::Item == as Iterable>::Item<'a>` - --> $DIR/iterable.rs:19:5 + --> $DIR/iterable.rs:19:30 | -LL | trait Iterable { - | -------------- required by `Iterable` +LL | trait Iterable { + | -------------- required by `Iterable` ... -LL | / fn iter<'a>(&'a self) -> Self::Iter<'a> { -LL | | -LL | | self.iter() -LL | | } - | |_____^ expected associated type, found reference +LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { + | ^^^^^^^^^^^^^^ expected associated type, found reference | = note: expected associated type ` as Iterable>::Item<'_>` found reference `&T` @@ -42,16 +39,13 @@ LL | | } = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>` - --> $DIR/iterable.rs:31:5 + --> $DIR/iterable.rs:31:30 | -LL | trait Iterable { - | -------------- required by `Iterable` +LL | trait Iterable { + | -------------- required by `Iterable` ... -LL | / fn iter<'a>(&'a self) -> Self::Iter<'a> { -LL | | -LL | | self.iter() -LL | | } - | |_____^ expected associated type, found reference +LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { + | ^^^^^^^^^^^^^^ expected associated type, found reference | = note: expected associated type `<[T] as Iterable>::Item<'_>` found reference `&T` diff --git a/src/test/ui/issues/issue-18919.stderr b/src/test/ui/issues/issue-18919.stderr index 87528652bd482..c8b9045efe6a0 100644 --- a/src/test/ui/issues/issue-18919.stderr +++ b/src/test/ui/issues/issue-18919.stderr @@ -1,10 +1,8 @@ error[E0277]: the size for values of type `dyn for<'r> std::ops::Fn(&'r isize) -> isize` cannot be known at compilation time - --> $DIR/issue-18919.rs:3:1 + --> $DIR/issue-18919.rs:3:15 | -LL | / fn ho_func(f: Option) { -LL | | -LL | | } - | |_^ doesn't have a size known at compile-time +LL | fn ho_func(f: Option) { + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `dyn for<'r> std::ops::Fn(&'r isize) -> isize` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index d5e7092801ecd..0c59486b416b8 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/issue-18959.rs:11:1 + --> $DIR/issue-18959.rs:11:11 | LL | pub trait Foo { fn foo(&self, ext_thing: &T); } | --- method `foo` has generic type parameters ... LL | fn foo(b: &dyn Bar) { - | ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20005.stderr b/src/test/ui/issues/issue-20005.stderr index 31376f2d1be0f..7c4115b4d3f7c 100644 --- a/src/test/ui/issues/issue-20005.stderr +++ b/src/test/ui/issues/issue-20005.stderr @@ -1,16 +1,14 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-20005.rs:8:5 + --> $DIR/issue-20005.rs:8:8 | -LL | trait From { - | --------------- required by `From` +LL | trait From { + | --------------- required by `From` ... -LL | / fn to( -LL | | self -LL | | ) -> >::Result where Dst: From { - | | - help: consider further restricting `Self`: `, Self: std::marker::Sized` -LL | | From::from(self) -LL | | } - | |_____^ doesn't have a size known at compile-time +LL | fn to( + | ^^ doesn't have a size known at compile-time +LL | self +LL | ) -> >::Result where Dst: From { + | - help: consider further restricting `Self`: `, Self: std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `Self` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 6ecb4e736acd9..7aec4a847c9d4 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -151,16 +151,13 @@ LL | | } = note: required because of the requirements on the impl of `Foo` for `NoData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:10:3 + --> $DIR/issue-20413.rs:10:6 | -LL | trait Foo { - | --------- required by `Foo` +LL | trait Foo { + | --------- required by `Foo` ... -LL | / fn answer(self) { -LL | | -LL | | let val: NoData = NoData; -LL | | } - | |___^ +LL | fn answer(self) { + | ^^^^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/issues/issue-20433.stderr b/src/test/ui/issues/issue-20433.stderr index f7cb28edd6216..abd2290952baf 100644 --- a/src/test/ui/issues/issue-20433.stderr +++ b/src/test/ui/issues/issue-20433.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/issue-20433.rs:6:5 + --> $DIR/issue-20433.rs:6:18 | LL | fn iceman(c: Vec<[i32]>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `[i32]` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index a4ea1cd9834c8..a785a956ca9f5 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -61,16 +61,10 @@ LL | | } | |_____^ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 28:5... --> $DIR/issue-20831-debruijn.rs:28:5 @@ -89,30 +83,18 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined on LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ^^ note: ...so that the types are compatible - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 28:5... --> $DIR/issue-20831-debruijn.rs:28:5 @@ -131,16 +113,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined on LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ^^ note: ...so that the types are compatible - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected `Publisher<'_>` found `Publisher<'_>` diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr index b1536bd8ddb0a..ebaef10cfef5b 100644 --- a/src/test/ui/issues/issue-21974.stderr +++ b/src/test/ui/issues/issue-21974.stderr @@ -1,17 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-21974.rs:10:1 + --> $DIR/issue-21974.rs:10:4 | -LL | trait Foo { - | --------- required by `Foo` +LL | trait Foo { + | --------- required by `Foo` ... -LL | / fn foo<'a,'b,T>(x: &'a T, y: &'b T) -LL | | where &'a T : Foo, -LL | | &'b T : Foo -LL | | { -LL | | x.foo(); -LL | | y.foo(); -LL | | } - | |_^ cannot infer type for reference `&'a T` +LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/issues/issue-23281.stderr b/src/test/ui/issues/issue-23281.stderr index f1def47458368..68a90c6d80f3b 100644 --- a/src/test/ui/issues/issue-23281.stderr +++ b/src/test/ui/issues/issue-23281.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `(dyn std::ops::Fn() + 'static)` cannot be known at compilation time - --> $DIR/issue-23281.rs:4:5 + --> $DIR/issue-23281.rs:4:27 | LL | pub fn function(funs: Vec ()>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::Fn() + 'static)` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr index 3eb1f1b4f6e81..a1a6960a3f7ae 100644 --- a/src/test/ui/issues/issue-24204.stderr +++ b/src/test/ui/issues/issue-24204.stderr @@ -1,11 +1,11 @@ error[E0271]: type mismatch resolving `<::A as MultiDispatch>::O == T` - --> $DIR/issue-24204.rs:14:1 + --> $DIR/issue-24204.rs:14:4 | LL | trait Trait: Sized { | ------------------ required by `Trait` ... LL | fn test>(b: i32) -> T where T::A: MultiDispatch { T::new(b) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type + | ^^^^ expected type parameter `T`, found associated type | = note: expected type parameter `T` found associated type `<::A as MultiDispatch>::O` diff --git a/src/test/ui/issues/issue-27942.stderr b/src/test/ui/issues/issue-27942.stderr index d290b176161be..6ce0fa37a8840 100644 --- a/src/test/ui/issues/issue-27942.stderr +++ b/src/test/ui/issues/issue-27942.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/issue-27942.rs:5:5 + --> $DIR/issue-27942.rs:5:25 | LL | fn select(&self) -> BufferViewHandle; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected type `Resources<'_>` found type `Resources<'a>` @@ -18,10 +18,10 @@ LL | pub trait Buffer<'a, R: Resources<'a>> { | ^^ error[E0308]: mismatched types - --> $DIR/issue-27942.rs:5:5 + --> $DIR/issue-27942.rs:5:25 | LL | fn select(&self) -> BufferViewHandle; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected type `Resources<'_>` found type `Resources<'a>` diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr index 7b823f012b9f9..3154c502625a6 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr @@ -13,87 +13,69 @@ LL | foo: &'static T | ^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 | LL | trait X: Sized { | - help: consider adding an explicit lifetime bound `K: 'a`... LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 | LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = help: consider adding an explicit lifetime bound `Self: 'a`... note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ error[E0309]: the parameter type `L` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 | -LL | fn baz<'a, L, M: X<&'a Nested>>() { - | ^ - help: consider adding an explicit lifetime bound `L: 'a`... - | _____| - | | -LL | | -LL | | } - | |_____^ +LL | fn baz<'a, L, M: X<&'a Nested>>() { + | ^^^ - help: consider adding an explicit lifetime bound `L: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 | -LL | / fn baz<'a, L, M: X<&'a Nested>>() { -LL | | -LL | | } - | |_____^ +LL | fn baz<'a, L, M: X<&'a Nested>>() { + | ^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 | -LL | impl Nested { - | - help: consider adding an explicit lifetime bound `K: 'a`... -LL | / fn generic_in_parent<'a, L: X<&'a Nested>>() { -LL | | -LL | | } - | |_____^ +LL | impl Nested { + | - help: consider adding an explicit lifetime bound `K: 'a`... +LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { + | ^^^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 | -LL | / fn generic_in_parent<'a, L: X<&'a Nested>>() { -LL | | -LL | | } - | |_____^ +LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { + | ^^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `M` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 | -LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { - | ^ -- help: consider adding an explicit lifetime bound `M: 'a`... - | _____| - | | -LL | | -LL | | } - | |_____^ +LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { + | ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound `M: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 | -LL | / fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { -LL | | -LL | | } - | |_____^ +LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { + | ^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index 67ef7a62f1052..b67b0e4f40e8c 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-associated-consts.rs:12:1 + --> $DIR/object-safety-associated-consts.rs:12:30 | LL | const X: usize; | - the trait cannot contain associated consts like `X` ... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr index 8ae9236a5c322..2469467f084a3 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -1,20 +1,20 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:18:1 + --> $DIR/object-safety-generics.rs:18:30 | LL | fn bar(&self, t: T); | --- method `bar` has generic type parameters ... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:24:1 + --> $DIR/object-safety-generics.rs:24:39 | LL | fn bar(&self, t: T); | --- method `bar` has generic type parameters ... LL | fn make_bar_explicit(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index 297cd876187fe..2123e306b16a4 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -1,20 +1,20 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:22:1 + --> $DIR/object-safety-mentions-Self.rs:22:30 | LL | fn bar(&self, x: &Self); | --- method `bar` references the `Self` type in its parameters or return type ... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error[E0038]: the trait `Baz` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:28:1 + --> $DIR/object-safety-mentions-Self.rs:28:30 | LL | fn baz(&self) -> Self; | --- method `baz` references the `Self` type in its parameters or return type ... LL | fn make_baz(t: &T) -> &dyn Baz { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object + | ^^^^^^^^ the trait `Baz` cannot be made into an object error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index 1641ce577719e..099876c562aec 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety-no-static.rs:12:1 + --> $DIR/object-safety-no-static.rs:12:18 | LL | fn foo() {} | --- associated function `foo` has no `self` parameter ... LL | fn diverges() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 1e1d2bf64c427..28fb4f36115f0 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized-2.rs:14:1 + --> $DIR/object-safety-sized-2.rs:14:30 | LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 1a67e79e83d32..0f284fc85073e 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized.rs:12:1 + --> $DIR/object-safety-sized.rs:12:30 | LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr index ad555efadf7ec..ad300f38ca5c1 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr @@ -1,12 +1,8 @@ error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references - --> $DIR/regions-free-region-ordering-callee-4.rs:5:1 + --> $DIR/regions-free-region-ordering-callee-4.rs:5:4 | -LL | / fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { -LL | | -LL | | // Do not infer ordering from closure argument types. -LL | | let z: Option<&'a &'b usize> = None; -LL | | } - | |_^ +LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { + | ^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined on the function body at 5:14 --> $DIR/regions-free-region-ordering-callee-4.rs:5:14 diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index c4ca7e970749c..6470ebf541b5b 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -1,11 +1,8 @@ error[E0491]: in type `&'x (dyn for<'z> Trait1<>::Foo> + 'x)`, reference has a longer lifetime than the data it references - --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1 + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25 | -LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) -LL | | -LL | | { -LL | | } - | |_^ +LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'x` as defined on the function body at 21:11 --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:11 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 cc2245f81ace5..c35516d2c0871 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 @@ -67,15 +67,10 @@ LL | | } 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 + --> $DIR/regions-normalize-in-where-clause-list.rs:22:4 | -LL | / fn bar<'a, 'b>() -LL | | -LL | | -LL | | where <() as Project<'a, 'b>>::Item : Eq -LL | | { -LL | | } - | |_^ +LL | fn bar<'a, 'b>() + | ^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8... --> $DIR/regions-normalize-in-where-clause-list.rs:22:8 @@ -88,15 +83,10 @@ note: ...but the lifetime must also be valid for the lifetime `'b` as defined on LL | fn bar<'a, 'b>() | ^^ note: ...so that the types are compatible - --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + --> $DIR/regions-normalize-in-where-clause-list.rs:22:4 | -LL | / fn bar<'a, 'b>() -LL | | -LL | | -LL | | where <() as Project<'a, 'b>>::Item : Eq -LL | | { -LL | | } - | |_^ +LL | fn bar<'a, 'b>() + | ^^^ = note: expected `Project<'a, 'b>` found `Project<'_, '_>` diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 63ac11dc8ae01..1d6b378b9c8a7 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object - --> $DIR/issue-3907-2.rs:11:1 + --> $DIR/issue-3907-2.rs:11:12 | LL | fn bar(_x: Foo) {} - | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object + | ^^^ the trait `issue_3907::Foo` cannot be made into an object | = note: associated function `bar` has no `self` parameter diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr index 3c68d461f80d6..a2253021a7f1f 100644 --- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr +++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr @@ -1,20 +1,20 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:13:1 + --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:13:15 | LL | struct Foo { | ------------------- required by `Foo` ... LL | fn explode(x: Foo) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u32` + | ^^^^^^^^ the trait `Trait` is not implemented for `u32` error[E0277]: the trait bound `f32: Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:16:1 + --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:16:14 | LL | enum Bar { | ----------------- required by `Bar` ... LL | fn kaboom(y: Bar) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `f32` + | ^^^^^^^^ the trait `Trait` is not implemented for `f32` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr index 2f2c903a45c19..c5a7746afdfdb 100644 --- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr +++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr @@ -1,16 +1,16 @@ error[E0277]: the trait bound `usize: trait_bounds_on_structs_and_enums_xc::Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:7:1 + --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:7:15 | LL | fn explode(x: Foo) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `usize` + | ^^^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `usize` | = note: required by `trait_bounds_on_structs_and_enums_xc::Foo` error[E0277]: the trait bound `f32: trait_bounds_on_structs_and_enums_xc::Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:10:1 + --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:10:14 | LL | fn kaboom(y: Bar) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `f32` + | ^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `f32` | = note: required by `trait_bounds_on_structs_and_enums_xc::Bar` diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index a4d9a672154fb..8cc6f7c303787 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,10 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:7:1 + --> $DIR/generic_duplicate_lifetime_param.rs:7:4 | -LL | / fn one<'a>(t: &'a ()) -> Two<'a, 'a> { -LL | | t -LL | | } - | |_^ +LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { + | ^^^ | note: lifetime used multiple times --> $DIR/generic_duplicate_lifetime_param.rs:5:10 diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr index 4fc0285509149..4a04b71d82f71 100644 --- a/src/test/ui/type/type-check/issue-40294.stderr +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -1,17 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-40294.rs:5:1 + --> $DIR/issue-40294.rs:5:4 | -LL | trait Foo: Sized { - | ---------------- required by `Foo` +LL | trait Foo: Sized { + | ---------------- required by `Foo` ... -LL | / fn foo<'a,'b,T>(x: &'a T, y: &'b T) -LL | | where &'a T : Foo, -LL | | &'b T : Foo -LL | | { -LL | | x.foo(); -LL | | y.foo(); -LL | | } - | |_^ cannot infer type for reference `&'a T` +LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 9b8b04a7b86a3..5d41dc77d8bc2 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -1,32 +1,29 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-fn-where-clause.rs:8:1 + --> $DIR/wf-fn-where-clause.rs:8:4 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` LL | -LL | fn foo() where T: ExtraCopy - | ^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | fn foo() where T: ExtraCopy + | ^^^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error[E0277]: the size for values of type `(dyn std::marker::Copy + 'static)` cannot be known at compilation time - --> $DIR/wf-fn-where-clause.rs:12:1 + --> $DIR/wf-fn-where-clause.rs:12:4 | LL | fn bar() where Vec:, {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `(dyn std::marker::Copy + 'static)` = note: to learn more, visit = note: required by `std::vec::Vec` error[E0038]: the trait `std::marker::Copy` cannot be made into an object - --> $DIR/wf-fn-where-clause.rs:12:1 + --> $DIR/wf-fn-where-clause.rs:12:4 | LL | fn bar() where Vec:, {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object + | ^^^ the trait `std::marker::Copy` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr index 3798ba1ec6e75..b8e88de54c2f1 100644 --- a/src/test/ui/wf/wf-in-fn-arg.stderr +++ b/src/test/ui/wf/wf-in-fn-arg.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-arg.rs:10:1 + --> $DIR/wf-in-fn-arg.rs:10:14 | -LL | struct MustBeCopy { - | ------------------------- required by `MustBeCopy` +LL | struct MustBeCopy { + | ------------------------- required by `MustBeCopy` ... -LL | fn bar(_: &MustBeCopy) - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | fn bar(_: &MustBeCopy) + | - ^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-ret.stderr b/src/test/ui/wf/wf-in-fn-ret.stderr index 2e46ce4900033..6ca1626d3aef5 100644 --- a/src/test/ui/wf/wf-in-fn-ret.stderr +++ b/src/test/ui/wf/wf-in-fn-ret.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-ret.rs:10:1 + --> $DIR/wf-in-fn-ret.rs:10:16 | -LL | struct MustBeCopy { - | ------------------------- required by `MustBeCopy` +LL | struct MustBeCopy { + | ------------------------- required by `MustBeCopy` ... -LL | fn bar() -> MustBeCopy - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | fn bar() -> MustBeCopy + | - ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr index 979802dec4998..e1a281626b9b7 100644 --- a/src/test/ui/wf/wf-in-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr @@ -1,15 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-where-clause.rs:9:1 + --> $DIR/wf-in-fn-where-clause.rs:9:4 | -LL | trait MustBeCopy { - | ------------------------ required by `MustBeCopy` +LL | trait MustBeCopy { + | ------------------------ required by `MustBeCopy` ... -LL | / fn bar() -LL | | where T: MustBeCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | fn bar() + | ^^^ the trait `std::marker::Copy` is not implemented for `U` +LL | where T: MustBeCopy + | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr index 21f825ac9ef9a..16079c8197cb1 100644 --- a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-inherent-impl-method-where-clause.rs:12:5 + --> $DIR/wf-inherent-impl-method-where-clause.rs:12:8 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` ... -LL | impl Foo { - | - help: consider restricting this bound: `U: std::marker::Copy` -LL | / fn foo(self) where T: ExtraCopy -LL | | {} - | |______^ the trait `std::marker::Copy` is not implemented for `U` +LL | impl Foo { + | - help: consider restricting this bound: `U: std::marker::Copy` +LL | fn foo(self) where T: ExtraCopy + | ^^^ the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.stderr b/src/test/ui/wf/wf-trait-default-fn-arg.stderr index 9f3545b9c6a6b..6a97d31cf3e65 100644 --- a/src/test/ui/wf/wf-trait-default-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-arg.stderr @@ -1,18 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-arg.rs:11:5 + --> $DIR/wf-trait-default-fn-arg.rs:11:22 | -LL | struct Bar { value: Box } - | ----------------------- required by `Bar` +LL | struct Bar { value: Box } + | ----------------------- required by `Bar` ... -LL | fn bar(&self, x: &Bar) { - | ^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | _____| - | | -LL | | -LL | | // -LL | | // Here, Eq ought to be implemented. -LL | | } - | |_____^ the trait `std::cmp::Eq` is not implemented for `Self` +LL | fn bar(&self, x: &Bar) { + | ^^^^^^^^^^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-ret.stderr b/src/test/ui/wf/wf-trait-default-fn-ret.stderr index e32630a5a4a40..36c1e486269f6 100644 --- a/src/test/ui/wf/wf-trait-default-fn-ret.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-ret.stderr @@ -1,19 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-ret.rs:11:5 + --> $DIR/wf-trait-default-fn-ret.rs:11:22 | -LL | struct Bar { value: Box } - | ----------------------- required by `Bar` +LL | struct Bar { value: Box } + | ----------------------- required by `Bar` ... -LL | fn bar(&self) -> Bar { - | ^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | _____| - | | -LL | | -LL | | // -LL | | // Here, Eq ought to be implemented. -LL | | loop { } -LL | | } - | |_____^ the trait `std::cmp::Eq` is not implemented for `Self` +LL | fn bar(&self) -> Bar { + | ^^^^^^^^^- help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr index a443ff1bb6396..984237ce3b497 100644 --- a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr @@ -1,18 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-where-clause.rs:11:5 + --> $DIR/wf-trait-default-fn-where-clause.rs:11:8 | -LL | trait Bar { } - | ---------------------- required by `Bar` +LL | trait Bar { } + | ---------------------- required by `Bar` ... -LL | fn bar(&self) where A: Bar { - | ^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | _____| - | | -LL | | -LL | | // -LL | | // Here, Eq ought to be implemented. -LL | | } - | |_____^ the trait `std::cmp::Eq` is not implemented for `Self` +LL | fn bar(&self) where A: Bar { + | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-arg.stderr b/src/test/ui/wf/wf-trait-fn-arg.stderr index 42a28ee676373..69e2ab72912d4 100644 --- a/src/test/ui/wf/wf-trait-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-fn-arg.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-arg.rs:10:5 + --> $DIR/wf-trait-fn-arg.rs:10:22 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self, x: &Bar); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-ret.stderr b/src/test/ui/wf/wf-trait-fn-ret.stderr index 7ec4dbe0056b4..bfc6265662e48 100644 --- a/src/test/ui/wf/wf-trait-fn-ret.stderr +++ b/src/test/ui/wf/wf-trait-fn-ret.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-ret.rs:10:5 + --> $DIR/wf-trait-fn-ret.rs:10:22 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self) -> &Bar; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^^- help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-fn-where-clause.stderr index 256edb5b2ca1d..34cda077963b5 100644 --- a/src/test/ui/wf/wf-trait-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-fn-where-clause.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-where-clause.rs:10:5 + --> $DIR/wf-trait-fn-where-clause.rs:10:8 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self) where Self: Sized, Bar: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error From 1c9242f83fdea3e4c7a452d1453370ee81a900af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 19 Jan 2020 14:53:37 -0800 Subject: [PATCH 02/23] Point at `Sized` bound --- src/librustc/traits/object_safety.rs | 40 +++++++++++++++---- ...ature-gate-object_safe_for_dispatch.stderr | 6 +++ src/test/ui/issues/issue-20692.stderr | 6 +++ src/test/ui/issues/issue-50781.stderr | 3 +- .../object-safety-sized.curr.stderr | 3 ++ ...fety-sized.object_safe_for_dispatch.stderr | 3 ++ .../wf/wf-convert-unsafe-trait-obj-box.stderr | 9 +++++ .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 9 +++++ .../ui/wf/wf-unsafe-trait-obj-match.stderr | 6 +++ 9 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 15f81bb3f47ed..bca0ecb1e79dc 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -26,7 +26,7 @@ use std::iter::{self}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation { /// `Self: Sized` declared on the trait. - SizedSelf, + SizedSelf(Span), /// Supertrait reference references `Self` an in illegal location /// (e.g., `trait Foo : Bar`). @@ -42,7 +42,7 @@ pub enum ObjectSafetyViolation { impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { - ObjectSafetyViolation::SizedSelf => { + ObjectSafetyViolation::SizedSelf(_) => { "the trait cannot require that `Self : Sized`".into() } ObjectSafetyViolation::SupertraitSelf => { @@ -80,6 +80,7 @@ impl ObjectSafetyViolation { // diagnostics use a `note` instead of a `span_label`. match *self { ObjectSafetyViolation::AssocConst(_, span) + | ObjectSafetyViolation::SizedSelf(span) | ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => { @@ -179,7 +180,7 @@ fn object_safety_violations_for_trait( { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. - tcx.struct_span_lint_hir( + let mut err = tcx.struct_span_lint_hir( WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, *span, @@ -187,9 +188,12 @@ fn object_safety_violations_for_trait( "the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id) ), - ) - .note(&violation.error_msg()) - .emit(); + ); + match violation.span() { + Some(span) => err.span_label(span, violation.error_msg()), + None => err.note(&violation.error_msg()), + }; + err.emit(); false } else { true @@ -199,7 +203,8 @@ fn object_safety_violations_for_trait( // Check the trait itself. if trait_has_sized_self(tcx, trait_def_id) { - violations.push(ObjectSafetyViolation::SizedSelf); + let span = get_sized_bound(tcx, trait_def_id); + violations.push(ObjectSafetyViolation::SizedSelf(span)); } if predicates_reference_self(tcx, trait_def_id, false) { violations.push(ObjectSafetyViolation::SupertraitSelf); @@ -219,6 +224,27 @@ fn object_safety_violations_for_trait( violations } +fn get_sized_bound(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Span { + tcx.hir() + .get_if_local(trait_def_id) + .and_then(|node| match node { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => bounds + .iter() + .filter_map(|b| match b { + hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) + if Some(trait_ref.trait_ref.trait_def_id()) + == tcx.lang_items().sized_trait() => + { + Some(trait_ref.span) + } + _ => None, + }) + .next(), + _ => None, + }) + .unwrap_or(DUMMY_SP) +} + fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool { let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); let predicates = if supertraits_only { diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index a2409621db310..de362e1cef0fd 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | +LL | trait NonObjectSafe1: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object | @@ -36,6 +39,9 @@ LL | fn return_non_object_safe_rc() -> std::rc::Rc { error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 | +LL | trait NonObjectSafe1: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object | diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 06c83f65be26c..4757742a707b1 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | +LL | trait Array: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object | @@ -9,6 +12,9 @@ LL | &dyn Array; error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | +LL | trait Array: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let _ = x | ^ the trait `Array` cannot be made into an object | diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index cb6ca24c7124a..c161e9efd1261 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -2,7 +2,7 @@ error: the trait `X` cannot be made into an object --> $DIR/issue-50781.rs:6:8 | LL | fn foo(&self) where Self: Trait; - | ^^^ + | ^^^ method `foo` references the `Self` type in where clauses | note: the lint level is defined here --> $DIR/issue-50781.rs:1:9 @@ -11,7 +11,6 @@ LL | #![deny(where_clauses_object_safety)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #51443 - = note: method `foo` references the `Self` type in where clauses error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 0f284fc85073e..be0a2519a469b 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:12:30 | +LL | trait Bar : Sized { + | ----- the trait cannot require that `Self : Sized` +... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object | diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 3d88dfc40ed38..c20ddee54c07e 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:14:5 | +LL | trait Bar : Sized { + | ----- the trait cannot require that `Self : Sized` +... LL | t | ^ the trait `Bar` cannot be made into an object | diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 0b63aef2bce10..4c033cfcd898b 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | @@ -11,6 +14,9 @@ LL | let t_box: Box = Box::new(S); error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | @@ -21,6 +27,9 @@ LL | takes_box(Box::new(S)); error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index 7aeefd731fb28..ba3792c362e86 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object | @@ -11,6 +14,9 @@ LL | let t: &dyn Trait = &S; error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object | @@ -21,6 +27,9 @@ LL | takes_trait(&S); error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object | diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index 594fad4138505..a0082578d4d06 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -15,6 +15,9 @@ LL | | } error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object | @@ -25,6 +28,9 @@ LL | Some(()) => &S, error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | From d72bcdb42cc10a20c2eef49e5f8cd2782f44b922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 19 Jan 2020 17:27:37 -0800 Subject: [PATCH 03/23] When object unsafe trait uses itself in associated item suggest using `Self` --- src/librustc_typeck/check/wfcheck.rs | 69 ++++++++++++++++++- .../object-unsafe-trait-should-use-self.rs | 16 +++++ ...object-unsafe-trait-should-use-self.stderr | 47 +++++++++++++ 3 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index ef3dcf1587301..faeaedce8d00d 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -10,10 +10,10 @@ use rustc::ty::{ self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::def_id::DefId; use rustc_hir::ItemKind; -use rustc_span::symbol::sym; +use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use syntax::ast; @@ -176,9 +176,74 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { hir::TraitItemKind::Method(ref sig, _) => Some(sig), _ => None, }; + check_bare_self_trait_by_name(tcx, &trait_item); check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); } +fn could_be_self(trait_name: Ident, ty: &hir::Ty<'_>) -> bool { + match ty.kind { + hir::TyKind::TraitObject([trait_ref], ..) => { + let mut p = trait_ref.trait_ref.path.segments.iter().map(|s| s.ident); + match (p.next(), p.next()) { + (Some(ident), None) => ident == trait_name, + _ => false, + } + } + _ => false, + } +} + +/// Detect when an object unsafe trait is referring to itself in one of its associated items. +/// When this is done, suggest using `Self` instead. +fn check_bare_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { + let (trait_name, trait_def_id) = match tcx.hir().get(tcx.hir().get_parent_item(item.hir_id)) { + hir::Node::Item(item) => match item.kind { + hir::ItemKind::Trait(..) => (item.ident, tcx.hir().local_def_id(item.hir_id)), + _ => return, + }, + _ => return, + }; + let mut trait_should_be_self = vec![]; + match &item.kind { + hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty)) + if could_be_self(trait_name, ty) => + { + trait_should_be_self.push(ty.span) + } + hir::TraitItemKind::Method(sig, _) => { + for ty in sig.decl.inputs { + if could_be_self(trait_name, ty) { + trait_should_be_self.push(ty.span); + } + } + match sig.decl.output { + hir::FunctionRetTy::Return(ty) if could_be_self(trait_name, ty) => { + trait_should_be_self.push(ty.span); + } + _ => {} + } + } + _ => {} + } + if !trait_should_be_self.is_empty() { + if rustc::traits::object_safety_violations(tcx, trait_def_id).is_empty() { + return; + } + let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect(); + let mut err = tcx.sess.struct_span_err( + trait_should_be_self, + "associated item referring to unboxed trait object for its own trait", + ); + err.span_label(trait_name.span, "in this trait"); + err.multipart_suggestion( + "you might have meant to use `Self` to refer to the materialized type", + sugg, + Applicability::MachineApplicable, + ); + err.emit(); + } +} + pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let impl_item = tcx.hir().expect_impl_item(hir_id); diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs new file mode 100644 index 0000000000000..75f99075eb18f --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs @@ -0,0 +1,16 @@ +#![allow(bare_trait_objects)] +trait A: Sized { + fn f(a: A) -> A; + //~^ ERROR associated item referring to unboxed trait object for its own trait + //~| ERROR the trait `A` cannot be made into an object +} +trait B { + fn f(a: B) -> B; + //~^ ERROR associated item referring to unboxed trait object for its own trait + //~| ERROR the trait `B` cannot be made into an object +} +trait C { + fn f(&self, a: C) -> C; +} + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr new file mode 100644 index 0000000000000..70d069d2aa29b --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -0,0 +1,47 @@ +error: associated item referring to unboxed trait object for its own trait + --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 + | +LL | trait A: Sized { + | - in this trait +LL | fn f(a: A) -> A; + | ^ ^ + | +help: you might have meant to use `Self` to refer to the materialized type + | +LL | fn f(a: Self) -> Self; + | ^^^^ ^^^^ + +error[E0038]: the trait `A` cannot be made into an object + --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 + | +LL | trait A: Sized { + | ----- the trait cannot require that `Self : Sized` +LL | fn f(a: A) -> A; + | ^ the trait `A` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + +error: associated item referring to unboxed trait object for its own trait + --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 + | +LL | trait B { + | - in this trait +LL | fn f(a: B) -> B; + | ^ ^ + | +help: you might have meant to use `Self` to refer to the materialized type + | +LL | fn f(a: Self) -> Self; + | ^^^^ ^^^^ + +error[E0038]: the trait `B` cannot be made into an object + --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 + | +LL | fn f(a: B) -> B; + | - ^ the trait `B` cannot be made into an object + | | + | associated function `f` has no `self` parameter + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0038`. From 0eb29d1a441a47ea45970c01332ebe157dba7039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 19 Jan 2020 19:22:15 -0800 Subject: [PATCH 04/23] fix test --- ...bject-unsafe-trait-in-return-position-dyn-trait.stderr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 0c8d267c13434..ff4bfc30a4a62 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -1,20 +1,20 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object - --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:1 + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13 | LL | fn foo() -> Self; | --- associated function `foo` has no `self` parameter ... LL | fn car() -> dyn NotObjectSafe { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object error[E0038]: the trait `NotObjectSafe` cannot be made into an object - --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:1 + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 | LL | fn foo() -> Self; | --- associated function `foo` has no `self` parameter ... LL | fn cat() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object error: aborting due to 2 previous errors From d137b7ac1173e3bbed6a3d4dfb02c741b64077db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 25 Jan 2020 14:28:23 -0800 Subject: [PATCH 05/23] review comments --- src/librustc_typeck/check/wfcheck.rs | 27 ++++++++++--------- ...object-unsafe-trait-should-use-self.stderr | 4 +-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index faeaedce8d00d..214e7d066eabc 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -176,7 +176,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { hir::TraitItemKind::Method(ref sig, _) => Some(sig), _ => None, }; - check_bare_self_trait_by_name(tcx, &trait_item); + check_object_unsafe_self_trait_by_name(tcx, &trait_item); check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); } @@ -195,7 +195,7 @@ fn could_be_self(trait_name: Ident, ty: &hir::Ty<'_>) -> bool { /// Detect when an object unsafe trait is referring to itself in one of its associated items. /// When this is done, suggest using `Self` instead. -fn check_bare_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { +fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { let (trait_name, trait_def_id) = match tcx.hir().get(tcx.hir().get_parent_item(item.hir_id)) { hir::Node::Item(item) => match item.kind { hir::ItemKind::Trait(..) => (item.ident, tcx.hir().local_def_id(item.hir_id)), @@ -230,17 +230,18 @@ fn check_bare_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { return; } let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect(); - let mut err = tcx.sess.struct_span_err( - trait_should_be_self, - "associated item referring to unboxed trait object for its own trait", - ); - err.span_label(trait_name.span, "in this trait"); - err.multipart_suggestion( - "you might have meant to use `Self` to refer to the materialized type", - sugg, - Applicability::MachineApplicable, - ); - err.emit(); + tcx.sess + .struct_span_err( + trait_should_be_self, + "associated item referring to unboxed trait object for its own trait", + ) + .span_label(trait_name.span, "in this trait") + .multipart_suggestion( + "you might have meant to use `Self` to refer to the implementing type", + sugg, + Applicability::MachineApplicable, + ) + .emit(); } } diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 70d069d2aa29b..f1c1a6bb9728b 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -6,7 +6,7 @@ LL | trait A: Sized { LL | fn f(a: A) -> A; | ^ ^ | -help: you might have meant to use `Self` to refer to the materialized type +help: you might have meant to use `Self` to refer to the implementing type | LL | fn f(a: Self) -> Self; | ^^^^ ^^^^ @@ -29,7 +29,7 @@ LL | trait B { LL | fn f(a: B) -> B; | ^ ^ | -help: you might have meant to use `Self` to refer to the materialized type +help: you might have meant to use `Self` to refer to the implementing type | LL | fn f(a: Self) -> Self; | ^^^^ ^^^^ From 4b2f1db6e464b74067557b1748e79cb11a2c5e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 12:59:04 -0800 Subject: [PATCH 06/23] Tweak `Self: Sized` restriction diagnostic output --- src/librustc/traits/error_reporting/mod.rs | 19 ++++-- src/librustc/traits/object_safety.rs | 63 ++++++++++--------- ...ature-gate-object_safe_for_dispatch.stderr | 4 -- src/test/ui/issues/issue-20692.rs | 2 +- src/test/ui/issues/issue-20692.stderr | 15 ++--- .../kindck-inherited-copy-bound.curr.stderr | 9 ++- ...copy-bound.object_safe_for_dispatch.stderr | 4 +- .../object-safety-sized.curr.stderr | 2 - ...fety-sized.object_safe_for_dispatch.stderr | 1 - ...object-unsafe-trait-should-use-self.stderr | 2 - .../wf/wf-convert-unsafe-trait-obj-box.stderr | 3 - .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 3 - .../ui/wf/wf-unsafe-trait-obj-match.stderr | 2 - 13 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 28084c9d4ac49..f15fa779534e0 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1046,11 +1046,22 @@ pub fn report_object_safety_error( let mut reported_violations = FxHashSet::default(); for violation in violations { + if let ObjectSafetyViolation::SizedSelf(sp) = &violation { + if !sp.is_empty() { + // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations + // with a `Span`. + reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into())); + } + } if reported_violations.insert(violation.clone()) { - match violation.span() { - Some(span) => err.span_label(span, violation.error_msg()), - None => err.note(&violation.error_msg()), - }; + let spans = violation.spans(); + if spans.is_empty() { + err.note(&violation.error_msg()); + } else { + for span in spans { + err.span_label(span, violation.error_msg()); + } + } } } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index bca0ecb1e79dc..8ceefb0abf038 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -18,15 +18,16 @@ use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; +use smallvec::SmallVec; use syntax::ast; use std::borrow::Cow; use std::iter::{self}; -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation { /// `Self: Sized` declared on the trait. - SizedSelf(Span), + SizedSelf(SmallVec<[Span; 1]>), /// Supertrait reference references `Self` an in illegal location /// (e.g., `trait Foo : Bar`). @@ -75,18 +76,18 @@ impl ObjectSafetyViolation { } } - pub fn span(&self) -> Option { + pub fn spans(&self) -> SmallVec<[Span; 1]> { // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so // diagnostics use a `note` instead of a `span_label`. - match *self { + match self { + ObjectSafetyViolation::SizedSelf(spans) => spans.clone(), ObjectSafetyViolation::AssocConst(_, span) - | ObjectSafetyViolation::SizedSelf(span) | ObjectSafetyViolation::Method(_, _, span) - if span != DUMMY_SP => + if *span != DUMMY_SP => { - Some(span) + vec![*span].into() } - _ => None, + _ => vec![].into(), } } } @@ -189,10 +190,14 @@ fn object_safety_violations_for_trait( tcx.def_path_str(trait_def_id) ), ); - match violation.span() { - Some(span) => err.span_label(span, violation.error_msg()), - None => err.note(&violation.error_msg()), - }; + let spans = violation.spans(); + if spans.is_empty() { + err.note(&violation.error_msg()); + } else { + for span in spans { + err.span_label(span, violation.error_msg()); + } + } err.emit(); false } else { @@ -203,8 +208,9 @@ fn object_safety_violations_for_trait( // Check the trait itself. if trait_has_sized_self(tcx, trait_def_id) { - let span = get_sized_bound(tcx, trait_def_id); - violations.push(ObjectSafetyViolation::SizedSelf(span)); + // We don't want to include the requirement from `Sized` itself to be `Sized` in the list. + let spans = get_sized_bounds(tcx, trait_def_id); + violations.push(ObjectSafetyViolation::SizedSelf(spans)); } if predicates_reference_self(tcx, trait_def_id, false) { violations.push(ObjectSafetyViolation::SupertraitSelf); @@ -224,25 +230,26 @@ fn object_safety_violations_for_trait( violations } -fn get_sized_bound(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Span { +fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> { tcx.hir() .get_if_local(trait_def_id) .and_then(|node| match node { - hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => bounds - .iter() - .filter_map(|b| match b { - hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) - if Some(trait_ref.trait_ref.trait_def_id()) - == tcx.lang_items().sized_trait() => - { - Some(trait_ref.span) - } - _ => None, - }) - .next(), + hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => Some( + bounds + .iter() + .filter_map(|b| match b { + hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) + if trait_has_sized_self(tcx, trait_ref.trait_ref.trait_def_id()) => + { + Some(trait_ref.span) + } + _ => None, + }) + .collect::>(), + ), _ => None, }) - .unwrap_or(DUMMY_SP) + .unwrap_or_else(SmallVec::new) } fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool { diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index de362e1cef0fd..237c22d3bf09a 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -6,8 +6,6 @@ LL | trait NonObjectSafe1: Sized {} ... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `NonObjectSafe2` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36 @@ -44,8 +42,6 @@ LL | trait NonObjectSafe1: Sized {} ... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: aborting due to 5 previous errors diff --git a/src/test/ui/issues/issue-20692.rs b/src/test/ui/issues/issue-20692.rs index 2a05bba7b1632..1cb2d8c7302a0 100644 --- a/src/test/ui/issues/issue-20692.rs +++ b/src/test/ui/issues/issue-20692.rs @@ -1,4 +1,4 @@ -trait Array: Sized {} +trait Array: Sized + Copy {} fn f(x: &T) { let _ = x diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 4757742a707b1..62efdfb2e91bf 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -1,24 +1,25 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | -LL | trait Array: Sized {} - | ----- the trait cannot require that `Self : Sized` +LL | trait Array: Sized + Copy {} + | ----- ---- the trait cannot require that `Self : Sized` + | | + | the trait cannot require that `Self : Sized` ... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | -LL | trait Array: Sized {} - | ----- the trait cannot require that `Self : Sized` +LL | trait Array: Sized + Copy {} + | ----- ---- the trait cannot require that `Self : Sized` + | | + | the trait cannot require that `Self : Sized` ... LL | let _ = x | ^ the trait `Array` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Array>` for `&T` = note: required by cast to type `&dyn Array` diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index da1a7a7520e07..a0ecca3020e15 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -12,18 +12,21 @@ LL | take_param(&x); error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:19 | +LL | trait Foo : Copy { + | ---- the trait cannot require that `Self : Sized` +... LL | let z = &x as &dyn Foo; | ^^^^^^^^ the trait `Foo` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | +LL | trait Foo : Copy { + | ---- the trait cannot require that `Self : Sized` +... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box<{integer}>` = note: required by cast to type `&dyn Foo` diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index f272f829ba600..5694150ed7cc5 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -12,10 +12,12 @@ LL | take_param(&x); error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | +LL | trait Foo : Copy { + | ---- the trait cannot require that `Self : Sized` +... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box` = note: required by cast to type `&dyn Foo` diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index be0a2519a469b..473c8f8e6faaf 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -6,8 +6,6 @@ LL | trait Bar : Sized { ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index c20ddee54c07e..217e2aa00da16 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -7,7 +7,6 @@ LL | trait Bar : Sized { LL | t | ^ the trait `Bar` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index f1c1a6bb9728b..91fa144032fc9 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -18,8 +18,6 @@ LL | trait A: Sized { | ----- the trait cannot require that `Self : Sized` LL | fn f(a: A) -> A; | ^ the trait `A` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: associated item referring to unboxed trait object for its own trait --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 4c033cfcd898b..461ad97f2f0ac 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -7,7 +7,6 @@ LL | trait Trait: Sized {} LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` @@ -20,7 +19,6 @@ LL | trait Trait: Sized {} LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box<(dyn Trait + 'static)>` @@ -33,7 +31,6 @@ LL | trait Trait: Sized {} LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index ba3792c362e86..6fc57369b4e73 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -7,7 +7,6 @@ LL | trait Trait: Sized {} LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` @@ -20,7 +19,6 @@ LL | trait Trait: Sized {} LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` @@ -33,7 +31,6 @@ LL | trait Trait: Sized {} LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index a0082578d4d06..36c60aefa6bb5 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -21,7 +21,6 @@ LL | trait Trait: Sized {} LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` @@ -34,7 +33,6 @@ LL | trait Trait: Sized {} LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&R` = note: required by cast to type `&dyn Trait` From 972ae5afe5c38cbf80552179fc9051d78f983ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 13:27:53 -0800 Subject: [PATCH 07/23] Point at the `Sized` obligation in `where` clauses --- src/librustc/traits/object_safety.rs | 39 +++++++++++++++++-- .../object-safety-sized-2.curr.stderr | 5 ++- ...ty-sized-2.object_safe_for_dispatch.stderr | 4 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 8ceefb0abf038..08b980480c576 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -234,17 +234,48 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> tcx.hir() .get_if_local(trait_def_id) .and_then(|node| match node { - hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => Some( - bounds + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Trait(.., generics, bounds, _), + .. + }) => Some( + generics + .where_clause + .predicates .iter() - .filter_map(|b| match b { + .filter_map(|pred| { + match pred { + hir::WherePredicate::BoundPredicate(pred) + if pred.bounded_ty.hir_id.owner_def_id() == trait_def_id => + { + // Fetch spans for trait bounds that are Sized: + // `trait T where Self: Pred` + Some(pred.bounds.iter().filter_map(|b| match b { + hir::GenericBound::Trait( + trait_ref, + hir::TraitBoundModifier::None, + ) if trait_has_sized_self( + tcx, + trait_ref.trait_ref.trait_def_id(), + ) => + { + Some(trait_ref.span) + } + _ => None, + })) + } + _ => None, + } + }) + .flatten() + .chain(bounds.iter().filter_map(|b| match b { hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) if trait_has_sized_self(tcx, trait_ref.trait_ref.trait_def_id()) => { + // Fetch spans for supertraits that are `Sized`: `trait T: Super` Some(trait_ref.span) } _ => None, - }) + })) .collect::>(), ), _ => None, diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 28fb4f36115f0..1ab33261111f8 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:14:30 | +LL | where Self : Sized + | ----- the trait cannot require that `Self : Sized` +... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index 06ecfd019c841..fa1c89575198c 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -1,10 +1,12 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:16:5 | +LL | where Self : Sized + | ----- the trait cannot require that `Self : Sized` +... LL | t | ^ the trait `Bar` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` From 8d48597b76ef656a1a1f600c96176d1aaeab32ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 14:16:31 -0800 Subject: [PATCH 08/23] Point at return type obligations instead of at `fn` ident --- src/librustc_typeck/check/wfcheck.rs | 6 +++--- .../generic_duplicate_lifetime_param.stderr | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 214e7d066eabc..3a4a015c14a50 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -530,7 +530,7 @@ fn check_where_clauses<'tcx, 'fcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, def_id: DefId, - return_ty: Option>, + return_ty: Option<(Ty<'tcx>, Span)>, ) { debug!("check_where_clauses(def_id={:?}, return_ty={:?})", def_id, return_ty); @@ -664,7 +664,7 @@ fn check_where_clauses<'tcx, 'fcx>( let mut predicates = predicates.instantiate_identity(fcx.tcx); - if let Some(return_ty) = return_ty { + if let Some((return_ty, span)) = return_ty { predicates.predicates.extend(check_opaque_types(tcx, fcx, def_id, span, return_ty)); } @@ -708,7 +708,7 @@ fn check_fn_or_method<'fcx, 'tcx>( // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); - check_where_clauses(tcx, fcx, span, def_id, Some(sig.output())); + check_where_clauses(tcx, fcx, span, def_id, Some((sig.output(), hir_sig.decl.output.span()))); } /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index 8cc6f7c303787..08b26b8fc1307 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:7:4 + --> $DIR/generic_duplicate_lifetime_param.rs:7:26 | LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { - | ^^^ + | ^^^^^^^^^^^ | note: lifetime used multiple times --> $DIR/generic_duplicate_lifetime_param.rs:5:10 From 6870f79e9c06c6e3a80654a07301e23c705e1408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 16:55:37 -0800 Subject: [PATCH 09/23] Use more accurate failed predicate spans --- src/librustc/ty/mod.rs | 9 +++- src/librustc_traits/lowering/environment.rs | 2 +- src/librustc_ty/ty.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 15 ++++--- .../bad-bounds-on-assoc-in-trait.stderr | 20 ++++----- ...associated-types-overridden-binding.stderr | 8 ++-- src/test/ui/error-codes/E0275.stderr | 4 +- .../issue-62326-parameter-out-of-range.rs | 2 +- .../issue-62326-parameter-out-of-range.stderr | 15 +++---- src/test/ui/issues/issue-20005.rs | 4 +- src/test/ui/issues/issue-20005.stderr | 9 ++-- src/test/ui/issues/issue-20413.rs | 4 +- src/test/ui/issues/issue-20413.stderr | 22 ++++------ src/test/ui/issues/issue-21974.rs | 4 +- src/test/ui/issues/issue-21974.stderr | 6 +-- src/test/ui/issues/issue-24204.stderr | 4 +- src/test/ui/issues/issue-24424.stderr | 4 +- .../lifetime-doesnt-live-long-enough.stderr | 42 ++++++++++--------- ...gions-free-region-ordering-callee-4.stderr | 4 +- ...issing-assoc-type-bound-restriction.stderr | 21 ++++------ .../traits/trait-alias/trait-alias-wf.stderr | 9 ++-- src/test/ui/type/type-check-defaults.stderr | 9 ++-- src/test/ui/type/type-check/issue-40294.rs | 4 +- .../ui/type/type-check/issue-40294.stderr | 6 +-- src/test/ui/wf/wf-enum-bound.rs | 4 +- src/test/ui/wf/wf-enum-bound.stderr | 19 ++++----- src/test/ui/wf/wf-fn-where-clause.stderr | 16 +++---- src/test/ui/wf/wf-in-fn-where-clause.rs | 4 +- src/test/ui/wf/wf-in-fn-where-clause.stderr | 8 ++-- ...f-inherent-impl-method-where-clause.stderr | 4 +- .../wf/wf-inherent-impl-where-clause.stderr | 17 ++++---- src/test/ui/wf/wf-struct-bound.rs | 4 +- src/test/ui/wf/wf-struct-bound.stderr | 19 ++++----- .../ui/wf/wf-trait-associated-type-bound.rs | 4 +- .../wf/wf-trait-associated-type-bound.stderr | 17 ++++---- src/test/ui/wf/wf-trait-bound.rs | 4 +- src/test/ui/wf/wf-trait-bound.stderr | 18 ++++---- .../wf-trait-default-fn-where-clause.stderr | 8 ++-- .../ui/wf/wf-trait-fn-where-clause.stderr | 8 ++-- src/test/ui/wf/wf-trait-superbound.stderr | 16 ++++--- 40 files changed, 187 insertions(+), 212 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..0781feee84541 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1015,6 +1015,7 @@ impl<'tcx> GenericPredicates<'tcx> { ) -> InstantiatedPredicates<'tcx> { InstantiatedPredicates { predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(), + spans: self.predicates.iter().map(|(_, sp)| *sp).collect(), } } @@ -1028,6 +1029,7 @@ impl<'tcx> GenericPredicates<'tcx> { tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); } instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p.subst(tcx, substs))); + instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp)); } pub fn instantiate_identity(&self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> { @@ -1044,7 +1046,8 @@ impl<'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated); } - instantiated.predicates.extend(self.predicates.iter().map(|&(p, _)| p)) + instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p)); + instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s)); } pub fn instantiate_supertrait( @@ -1059,6 +1062,7 @@ impl<'tcx> GenericPredicates<'tcx> { .iter() .map(|(pred, _)| pred.subst_supertrait(tcx, poly_trait_ref)) .collect(), + spans: self.predicates.iter().map(|(_, sp)| *sp).collect(), } } } @@ -1511,11 +1515,12 @@ impl<'tcx> Predicate<'tcx> { #[derive(Clone, Debug, TypeFoldable)] pub struct InstantiatedPredicates<'tcx> { pub predicates: Vec>, + pub spans: Vec, } impl<'tcx> InstantiatedPredicates<'tcx> { pub fn empty() -> InstantiatedPredicates<'tcx> { - InstantiatedPredicates { predicates: vec![] } + InstantiatedPredicates { predicates: vec![], spans: vec![] } } pub fn is_empty(&self) -> bool { diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 7df27e67d5b1c..0e26e9461f4c3 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -161,7 +161,7 @@ crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> { } // Compute the bounds on `Self` and the type parameters. - let ty::InstantiatedPredicates { predicates } = + let ty::InstantiatedPredicates { predicates, .. } = tcx.predicates_of(def_id).instantiate_identity(tcx); let clauses = predicates diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 8f882be1a090e..9f867cf8ab464 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -228,7 +228,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { } // Compute the bounds on Self and the type parameters. - let ty::InstantiatedPredicates { predicates } = + let ty::InstantiatedPredicates { predicates, .. } = tcx.predicates_of(def_id).instantiate_identity(tcx); // Finally, we have to normalize the bounds in the environment, in diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 3a4a015c14a50..41171117b47d4 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -665,16 +665,21 @@ fn check_where_clauses<'tcx, 'fcx>( let mut predicates = predicates.instantiate_identity(fcx.tcx); if let Some((return_ty, span)) = return_ty { - predicates.predicates.extend(check_opaque_types(tcx, fcx, def_id, span, return_ty)); + let opaque_types = check_opaque_types(tcx, fcx, def_id, span, return_ty); + for _ in 0..opaque_types.len() { + predicates.spans.push(span); + } + predicates.predicates.extend(opaque_types); } let predicates = fcx.normalize_associated_types_in(span, &predicates); debug!("check_where_clauses: predicates={:?}", predicates.predicates); - let wf_obligations = predicates - .predicates - .iter() - .flat_map(|p| traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, span)); + assert_eq!(predicates.predicates.len(), predicates.spans.len()); + let wf_obligations = + predicates.predicates.iter().zip(predicates.spans.iter()).flat_map(|(p, sp)| { + traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, *sp) + }); for obligation in wf_obligations.chain(default_obligations) { debug!("next obligation cause: {:?}", obligation.cause); diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 33fe8a3124083..5713e259362fd 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -10,9 +10,9 @@ error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterato --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | LL | fn assume_case1() { - | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` - | | - | `<::C as std::iter::Iterator>::Item` is not an iterator + | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` + | | + | `<::C as std::iter::Iterator>::Item` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` @@ -23,9 +23,9 @@ LL | trait Case1 { | ----------- required by `Case1` ... LL | fn assume_case1() { - | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` - | | - | `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely + | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` + | | + | `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely | = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` @@ -36,9 +36,9 @@ LL | trait Case1 { | ----------- required by `Case1` ... LL | fn assume_case1() { - | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` - | | - | `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely + | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` + | | + | `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely | = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` @@ -49,7 +49,7 @@ LL | trait Case1 { | ----------- required by `Case1` ... LL | fn assume_case1() { - | ^^^^^^^^^^^^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App` diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr index 069da955b674e..9e10ed7b72952 100644 --- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr +++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr @@ -1,20 +1,20 @@ error[E0284]: type annotations needed - --> $DIR/associated-types-overridden-binding.rs:4:1 + --> $DIR/associated-types-overridden-binding.rs:4:12 | LL | trait Foo: Iterator {} | ------------------------------- required by `Foo` LL | trait Bar: Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` + | ^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` | = note: cannot resolve `::Item == i32` error[E0284]: type annotations needed - --> $DIR/associated-types-overridden-binding.rs:7:1 + --> $DIR/associated-types-overridden-binding.rs:7:21 | LL | trait I32Iterator = Iterator; | ----------------------------------------- required by `I32Iterator` LL | trait U32Iterator = I32Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` | = note: cannot resolve `::Item == i32` diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index f607a9fbbf269..1d087a465942e 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -1,11 +1,11 @@ error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/E0275.rs:5:1 + --> $DIR/E0275.rs:5:33 | LL | trait Foo {} | --------- required by `Foo` ... LL | impl Foo for T where Bar: Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs index 60466d0bcd040..1a79dbf2279a0 100644 --- a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs @@ -4,8 +4,8 @@ // FIXME(generic-associated-types) Investigate why this doesn't compile. trait Iterator { - //~^ ERROR the requirement `for<'a> ::Item<'a>: 'a` is not satisfied type Item<'a>: 'a; + //~^ ERROR the requirement `for<'a> ::Item<'a>: 'a` is not satisfied } fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr index 4dc69cdd1dcf0..687423962361b 100644 --- a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr @@ -1,15 +1,10 @@ error[E0280]: the requirement `for<'a> ::Item<'a>: 'a` is not satisfied - --> $DIR/issue-62326-parameter-out-of-range.rs:6:1 + --> $DIR/issue-62326-parameter-out-of-range.rs:7:20 | -LL | trait Iterator { - | ^------------- - | | - | _required by `Iterator` - | | -LL | | -LL | | type Item<'a>: 'a; -LL | | } - | |_^ +LL | trait Iterator { + | -------------- required by `Iterator` +LL | type Item<'a>: 'a; + | ^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20005.rs b/src/test/ui/issues/issue-20005.rs index 6d63c9e5b613a..36350bff100dd 100644 --- a/src/test/ui/issues/issue-20005.rs +++ b/src/test/ui/issues/issue-20005.rs @@ -5,9 +5,9 @@ trait From { } trait To { - fn to( //~ ERROR the size for values of type + fn to( self - ) -> >::Result where Dst: From { + ) -> >::Result where Dst: From { //~ ERROR the size for values of type From::from(self) } } diff --git a/src/test/ui/issues/issue-20005.stderr b/src/test/ui/issues/issue-20005.stderr index 7c4115b4d3f7c..529571a6b74dd 100644 --- a/src/test/ui/issues/issue-20005.stderr +++ b/src/test/ui/issues/issue-20005.stderr @@ -1,14 +1,13 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-20005.rs:8:8 + --> $DIR/issue-20005.rs:10:49 | LL | trait From { | --------------- required by `From` ... -LL | fn to( - | ^^ doesn't have a size known at compile-time -LL | self LL | ) -> >::Result where Dst: From { - | - help: consider further restricting `Self`: `, Self: std::marker::Sized` + | ^^^^^^^^^^- help: consider further restricting `Self`: `, Self: std::marker::Sized` + | | + | doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `Self` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-20413.rs b/src/test/ui/issues/issue-20413.rs index 7eb6d5c0ecbaa..19ef52af65736 100644 --- a/src/test/ui/issues/issue-20413.rs +++ b/src/test/ui/issues/issue-20413.rs @@ -6,9 +6,9 @@ struct NoData; //~^ ERROR: parameter `T` is never used impl Foo for T where NoData: Foo { -//~^ ERROR: overflow evaluating the requirement - fn answer(self) { //~^ ERROR: overflow evaluating the requirement + //~| ERROR: overflow evaluating the requirement + fn answer(self) { let val: NoData = NoData; } } diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 7aec4a847c9d4..e765144ff0b48 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -7,19 +7,13 @@ LL | struct NoData; = help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:8:1 + --> $DIR/issue-20413.rs:8:36 | -LL | trait Foo { - | --------- required by `Foo` +LL | trait Foo { + | --------- required by `Foo` ... -LL | / impl Foo for T where NoData: Foo { -LL | | -LL | | fn answer(self) { -LL | | -LL | | let val: NoData = NoData; -LL | | } -LL | | } - | |_^ +LL | impl Foo for T where NoData: Foo { + | ^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` @@ -151,13 +145,13 @@ LL | | } = note: required because of the requirements on the impl of `Foo` for `NoData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:10:6 + --> $DIR/issue-20413.rs:8:36 | LL | trait Foo { | --------- required by `Foo` ... -LL | fn answer(self) { - | ^^^^^^ +LL | impl Foo for T where NoData: Foo { + | ^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/issues/issue-21974.rs b/src/test/ui/issues/issue-21974.rs index 0cbe38d6ec0b6..f7c659be148db 100644 --- a/src/test/ui/issues/issue-21974.rs +++ b/src/test/ui/issues/issue-21974.rs @@ -7,8 +7,8 @@ trait Foo { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed - where &'a T : Foo, +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, //~ ERROR type annotations needed &'b T : Foo { x.foo(); diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr index ebaef10cfef5b..19823499066eb 100644 --- a/src/test/ui/issues/issue-21974.stderr +++ b/src/test/ui/issues/issue-21974.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-21974.rs:10:4 + --> $DIR/issue-21974.rs:11:19 | LL | trait Foo { | --------- required by `Foo` ... -LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) - | ^^^ cannot infer type for reference `&'a T` +LL | where &'a T : Foo, + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr index a1a6960a3f7ae..2a714861da1fd 100644 --- a/src/test/ui/issues/issue-24204.stderr +++ b/src/test/ui/issues/issue-24204.stderr @@ -1,11 +1,11 @@ error[E0271]: type mismatch resolving `<::A as MultiDispatch>::O == T` - --> $DIR/issue-24204.rs:14:4 + --> $DIR/issue-24204.rs:14:12 | LL | trait Trait: Sized { | ------------------ required by `Trait` ... LL | fn test>(b: i32) -> T where T::A: MultiDispatch { T::new(b) } - | ^^^^ expected type parameter `T`, found associated type + | ^^^^^^^^^^^^ expected type parameter `T`, found associated type | = note: expected type parameter `T` found associated type `<::A as MultiDispatch>::O` diff --git a/src/test/ui/issues/issue-24424.stderr b/src/test/ui/issues/issue-24424.stderr index 8f0850328b446..538d44c3b2ef3 100644 --- a/src/test/ui/issues/issue-24424.stderr +++ b/src/test/ui/issues/issue-24424.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-24424.rs:4:1 + --> $DIR/issue-24424.rs:4:57 | LL | trait Trait0<'l0> {} | ----------------- required by `Trait0` LL | LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T0` + | ^^^^^^^^^^^ cannot infer type for type parameter `T0` | = note: cannot resolve `T0: Trait0<'l0>` diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr index 3154c502625a6..4e50064efb4ec 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr @@ -13,69 +13,71 @@ LL | foo: &'static T | ^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19 | LL | trait X: Sized { | - help: consider adding an explicit lifetime bound `K: 'a`... LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19 | LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `Self: 'a`... note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `L` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22 | LL | fn baz<'a, L, M: X<&'a Nested>>() { - | ^^^ - help: consider adding an explicit lifetime bound `L: 'a`... + | - ^^^^^^^^^^^^^^^^ + | | + | help: consider adding an explicit lifetime bound `L: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22 | LL | fn baz<'a, L, M: X<&'a Nested>>() { - | ^^^ + | ^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33 | LL | impl Nested { | - help: consider adding an explicit lifetime bound `K: 'a`... LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33 | LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `M` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36 | LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { - | ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound `M: 'a`... + | ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound `M: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36 | LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr index ad300f38ca5c1..5ab423d9e2077 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr @@ -1,8 +1,8 @@ error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references - --> $DIR/regions-free-region-ordering-callee-4.rs:5:4 + --> $DIR/regions-free-region-ordering-callee-4.rs:5:68 | LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined on the function body at 5:14 --> $DIR/regions-free-region-ordering-callee-4.rs:5:14 diff --git a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr index c6f2e5cda66af..31d974ed43d99 100644 --- a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr +++ b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr @@ -1,20 +1,13 @@ error[E0277]: the trait bound `::Assoc: Child` is not satisfied - --> $DIR/missing-assoc-type-bound-restriction.rs:17:1 + --> $DIR/missing-assoc-type-bound-restriction.rs:17:19 | -LL | trait Parent { - | ------------ required by `Parent` +LL | trait Parent { + | ------------ required by `Parent` ... -LL | impl> Parent for ParentWrapper { - | ^ - help: consider further restricting the associated type: `where ::Assoc: Child` - | _| - | | -LL | | -LL | | type Ty = A; -LL | | type Assoc = ChildWrapper; -LL | | -LL | | -LL | | } - | |_^ the trait `Child` is not implemented for `::Assoc` +LL | impl> Parent for ParentWrapper { + | ^^^^^^ - help: consider further restricting the associated type: `where ::Assoc: Child` + | | + | the trait `Child` is not implemented for `::Assoc` error[E0277]: the trait bound `::Assoc: Child` is not satisfied --> $DIR/missing-assoc-type-bound-restriction.rs:20:5 diff --git a/src/test/ui/traits/trait-alias/trait-alias-wf.stderr b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr index 4355a517bd724..b71c0d719ff3f 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-wf.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr @@ -1,13 +1,12 @@ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/trait-alias-wf.rs:5:1 + --> $DIR/trait-alias-wf.rs:5:14 | LL | trait A {} | --------------- required by `A` LL | trait B = A; - | ^^^^^^^^-^^^^^^^^^ - | | | - | | help: consider restricting this bound: `T: Foo` - | the trait `Foo` is not implemented for `T` + | - ^^^^ the trait `Foo` is not implemented for `T` + | | + | help: consider restricting this bound: `T: Foo` error: aborting due to previous error diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr index 6f84b37d61249..e5d2ebda31858 100644 --- a/src/test/ui/type/type-check-defaults.stderr +++ b/src/test/ui/type/type-check-defaults.stderr @@ -47,15 +47,14 @@ LL | trait TraitBound {} | required by `TraitBound` error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/type-check-defaults.rs:21:1 + --> $DIR/type-check-defaults.rs:21:25 | LL | trait Super { } | -------------------- required by `Super` LL | trait Base: Super { } - | ^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | help: consider restricting this bound: `T: std::marker::Copy` - | the trait `std::marker::Copy` is not implemented for `T` + | - ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error[E0277]: cannot add `u8` to `i32` --> $DIR/type-check-defaults.rs:24:66 diff --git a/src/test/ui/type/type-check/issue-40294.rs b/src/test/ui/type/type-check/issue-40294.rs index 7e6429ccfbe30..5493a4e5f10a8 100644 --- a/src/test/ui/type/type-check/issue-40294.rs +++ b/src/test/ui/type/type-check/issue-40294.rs @@ -2,8 +2,8 @@ trait Foo: Sized { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed - where &'a T : Foo, +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, //~ ERROR type annotations needed &'b T : Foo { x.foo(); diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr index 4a04b71d82f71..2c889b6c2ca0a 100644 --- a/src/test/ui/type/type-check/issue-40294.stderr +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-40294.rs:5:4 + --> $DIR/issue-40294.rs:6:19 | LL | trait Foo: Sized { | ---------------- required by `Foo` ... -LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) - | ^^^ cannot infer type for reference `&'a T` +LL | where &'a T : Foo, + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/wf/wf-enum-bound.rs b/src/test/ui/wf/wf-enum-bound.rs index c9eb9d894331e..042a2cb09d27b 100644 --- a/src/test/ui/wf/wf-enum-bound.rs +++ b/src/test/ui/wf/wf-enum-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -enum SomeEnum //~ ERROR E0277 - where T: ExtraCopy +enum SomeEnum + where T: ExtraCopy //~ ERROR E0277 { SomeVariant(T,U) } diff --git a/src/test/ui/wf/wf-enum-bound.stderr b/src/test/ui/wf/wf-enum-bound.stderr index eaacd6b6881ef..0d22d18bf6fd9 100644 --- a/src/test/ui/wf/wf-enum-bound.stderr +++ b/src/test/ui/wf/wf-enum-bound.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-enum-bound.rs:9:1 + --> $DIR/wf-enum-bound.rs:10:14 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` -LL | -LL | / enum SomeEnum -LL | | where T: ExtraCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | SomeVariant(T,U) -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` +... +LL | where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 5d41dc77d8bc2..3bef38d2fd2c3 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -1,29 +1,29 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-fn-where-clause.rs:8:4 + --> $DIR/wf-fn-where-clause.rs:8:24 | LL | trait ExtraCopy { } | ----------------------- required by `ExtraCopy` LL | LL | fn foo() where T: ExtraCopy - | ^^^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` - | | - | the trait `std::marker::Copy` is not implemented for `U` + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error[E0277]: the size for values of type `(dyn std::marker::Copy + 'static)` cannot be known at compilation time - --> $DIR/wf-fn-where-clause.rs:12:4 + --> $DIR/wf-fn-where-clause.rs:12:16 | LL | fn bar() where Vec:, {} - | ^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `(dyn std::marker::Copy + 'static)` = note: to learn more, visit = note: required by `std::vec::Vec` error[E0038]: the trait `std::marker::Copy` cannot be made into an object - --> $DIR/wf-fn-where-clause.rs:12:4 + --> $DIR/wf-fn-where-clause.rs:12:16 | LL | fn bar() where Vec:, {} - | ^^^ the trait `std::marker::Copy` cannot be made into an object + | ^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/wf/wf-in-fn-where-clause.rs b/src/test/ui/wf/wf-in-fn-where-clause.rs index 65a1771d41a48..e55295a3b2578 100644 --- a/src/test/ui/wf/wf-in-fn-where-clause.rs +++ b/src/test/ui/wf/wf-in-fn-where-clause.rs @@ -6,8 +6,8 @@ trait MustBeCopy { } -fn bar() //~ ERROR E0277 - where T: MustBeCopy +fn bar() + where T: MustBeCopy //~ ERROR E0277 { } diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr index e1a281626b9b7..495041b7dadf8 100644 --- a/src/test/ui/wf/wf-in-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-where-clause.rs:9:4 + --> $DIR/wf-in-fn-where-clause.rs:10:14 | LL | trait MustBeCopy { | ------------------------ required by `MustBeCopy` ... -LL | fn bar() - | ^^^ the trait `std::marker::Copy` is not implemented for `U` LL | where T: MustBeCopy - | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | ^^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr index 16079c8197cb1..e9c1c8ddaf640 100644 --- a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-inherent-impl-method-where-clause.rs:12:8 + --> $DIR/wf-inherent-impl-method-where-clause.rs:12:27 | LL | trait ExtraCopy { } | ----------------------- required by `ExtraCopy` @@ -7,7 +7,7 @@ LL | trait ExtraCopy { } LL | impl Foo { | - help: consider restricting this bound: `U: std::marker::Copy` LL | fn foo(self) where T: ExtraCopy - | ^^^ the trait `std::marker::Copy` is not implemented for `U` + | ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr index 35b9093381329..a4e6dce39cdcd 100644 --- a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-inherent-impl-where-clause.rs:11:1 + --> $DIR/wf-inherent-impl-where-clause.rs:11:29 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` ... -LL | impl Foo where T: ExtraCopy - | ^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | impl Foo where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-struct-bound.rs b/src/test/ui/wf/wf-struct-bound.rs index 69be71cd130b0..6e558ca8ff0b0 100644 --- a/src/test/ui/wf/wf-struct-bound.rs +++ b/src/test/ui/wf/wf-struct-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -struct SomeStruct //~ ERROR E0277 - where T: ExtraCopy +struct SomeStruct + where T: ExtraCopy //~ ERROR E0277 { data: (T,U) } diff --git a/src/test/ui/wf/wf-struct-bound.stderr b/src/test/ui/wf/wf-struct-bound.stderr index 2155977349256..3f4047d9b5609 100644 --- a/src/test/ui/wf/wf-struct-bound.stderr +++ b/src/test/ui/wf/wf-struct-bound.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-struct-bound.rs:9:1 + --> $DIR/wf-struct-bound.rs:10:14 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` -LL | -LL | / struct SomeStruct -LL | | where T: ExtraCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | data: (T,U) -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` +... +LL | where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.rs b/src/test/ui/wf/wf-trait-associated-type-bound.rs index 29e305577acbc..2f20e65e5021a 100644 --- a/src/test/ui/wf/wf-trait-associated-type-bound.rs +++ b/src/test/ui/wf/wf-trait-associated-type-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -trait SomeTrait { //~ ERROR E0277 - type Type1: ExtraCopy; +trait SomeTrait { + type Type1: ExtraCopy; //~ ERROR E0277 } diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.stderr b/src/test/ui/wf/wf-trait-associated-type-bound.stderr index af0433fd22f6e..3370cfc86939d 100644 --- a/src/test/ui/wf/wf-trait-associated-type-bound.stderr +++ b/src/test/ui/wf/wf-trait-associated-type-bound.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-trait-associated-type-bound.rs:9:1 + --> $DIR/wf-trait-associated-type-bound.rs:10:17 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` LL | -LL | trait SomeTrait { - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | type Type1: ExtraCopy; -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | trait SomeTrait { + | - help: consider restricting this bound: `T: std::marker::Copy` +LL | type Type1: ExtraCopy; + | ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-bound.rs b/src/test/ui/wf/wf-trait-bound.rs index d8746ba4d6e52..62a1eb5b08864 100644 --- a/src/test/ui/wf/wf-trait-bound.rs +++ b/src/test/ui/wf/wf-trait-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -trait SomeTrait //~ ERROR E0277 - where T: ExtraCopy +trait SomeTrait + where T: ExtraCopy //~ ERROR E0277 { } diff --git a/src/test/ui/wf/wf-trait-bound.stderr b/src/test/ui/wf/wf-trait-bound.stderr index 13e2f8f590149..87c33714ff879 100644 --- a/src/test/ui/wf/wf-trait-bound.stderr +++ b/src/test/ui/wf/wf-trait-bound.stderr @@ -1,15 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-trait-bound.rs:9:1 + --> $DIR/wf-trait-bound.rs:10:14 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` -LL | -LL | / trait SomeTrait -LL | | where T: ExtraCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` +... +LL | where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr index 984237ce3b497..6b63feaba89a3 100644 --- a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-where-clause.rs:11:8 + --> $DIR/wf-trait-default-fn-where-clause.rs:11:31 | LL | trait Bar { } | ---------------------- required by `Bar` ... LL | fn bar(&self) where A: Bar { - | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^- help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-fn-where-clause.stderr index 34cda077963b5..ec8f02c9c4fed 100644 --- a/src/test/ui/wf/wf-trait-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-fn-where-clause.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-where-clause.rs:10:8 + --> $DIR/wf-trait-fn-where-clause.rs:10:49 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self) where Self: Sized, Bar: Copy; - | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^- help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-superbound.stderr b/src/test/ui/wf/wf-trait-superbound.stderr index a61b8dd3a3849..9ea9d046b2602 100644 --- a/src/test/ui/wf/wf-trait-superbound.stderr +++ b/src/test/ui/wf/wf-trait-superbound.stderr @@ -1,15 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-trait-superbound.rs:9:1 + --> $DIR/wf-trait-superbound.rs:9:21 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` LL | -LL | trait SomeTrait: ExtraCopy { - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | trait SomeTrait: ExtraCopy { + | - ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error: aborting due to previous error From 144e2594458fedc5c62f760f30789c21e3e0198e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 10:20:47 -0800 Subject: [PATCH 10/23] Slight rewording of diagnostic message --- src/librustc/traits/object_safety.rs | 2 +- ...rait-object-reference-without-parens-suggestion.stderr | 2 +- .../feature-gate-object_safe_for_dispatch.stderr | 4 ++-- src/test/ui/issues/issue-20692.stderr | 8 ++++---- .../ui/kindck/kindck-inherited-copy-bound.curr.stderr | 4 ++-- ...k-inherited-copy-bound.object_safe_for_dispatch.stderr | 2 +- .../ui/object-safety/object-safety-sized-2.curr.stderr | 2 +- .../object-safety-sized-2.object_safe_for_dispatch.stderr | 2 +- src/test/ui/object-safety/object-safety-sized.curr.stderr | 2 +- .../object-safety-sized.object_safe_for_dispatch.stderr | 2 +- .../object-unsafe-trait-should-use-self.stderr | 2 +- src/test/ui/traits/trait-object-macro-matcher.stderr | 2 +- src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr | 6 +++--- src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr | 6 +++--- src/test/ui/wf/wf-fn-where-clause.stderr | 2 +- src/test/ui/wf/wf-unsafe-trait-obj-match.stderr | 4 ++-- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 08b980480c576..50d355f9d0a0d 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -44,7 +44,7 @@ impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { ObjectSafetyViolation::SizedSelf(_) => { - "the trait cannot require that `Self : Sized`".into() + "traits that require `Self: Sized` cannot be made into an object".into() } ObjectSafetyViolation::SupertraitSelf => { "the trait cannot use `Self` as a type parameter \ diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index 8c6c33b11865b..070917f2db98a 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -16,7 +16,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | let _: &Copy + 'static; | ^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` + = note: traits that require `Self: Sized` cannot be made into an object error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index 237c22d3bf09a..ce98306940512 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | LL | trait NonObjectSafe1: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object @@ -38,7 +38,7 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 | LL | trait NonObjectSafe1: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 62efdfb2e91bf..552b65b362094 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -2,9 +2,9 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | LL | trait Array: Sized + Copy {} - | ----- ---- the trait cannot require that `Self : Sized` + | ----- ---- traits that require `Self: Sized` cannot be made into an object | | - | the trait cannot require that `Self : Sized` + | traits that require `Self: Sized` cannot be made into an object ... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object @@ -13,9 +13,9 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | LL | trait Array: Sized + Copy {} - | ----- ---- the trait cannot require that `Self : Sized` + | ----- ---- traits that require `Self: Sized` cannot be made into an object | | - | the trait cannot require that `Self : Sized` + | traits that require `Self: Sized` cannot be made into an object ... LL | let _ = x | ^ the trait `Array` cannot be made into an object diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index a0ecca3020e15..728a5ea6faa9f 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -13,7 +13,7 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:19 | LL | trait Foo : Copy { - | ---- the trait cannot require that `Self : Sized` + | ---- traits that require `Self: Sized` cannot be made into an object ... LL | let z = &x as &dyn Foo; | ^^^^^^^^ the trait `Foo` cannot be made into an object @@ -22,7 +22,7 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- the trait cannot require that `Self : Sized` + | ---- traits that require `Self: Sized` cannot be made into an object ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index 5694150ed7cc5..b4fba9706bc0d 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -13,7 +13,7 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- the trait cannot require that `Self : Sized` + | ---- traits that require `Self: Sized` cannot be made into an object ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 1ab33261111f8..49f98e0085082 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:14:30 | LL | where Self : Sized - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index fa1c89575198c..9b189c48f9301 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:16:5 | LL | where Self : Sized - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 473c8f8e6faaf..3b588034e3322 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:12:30 | LL | trait Bar : Sized { - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 217e2aa00da16..6b60eef30d3d3 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:14:5 | LL | trait Bar : Sized { - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 91fa144032fc9..4a9242b1f4fac 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -15,7 +15,7 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 | LL | trait A: Sized { - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object LL | fn f(a: A) -> A; | ^ the trait `A` cannot be made into an object diff --git a/src/test/ui/traits/trait-object-macro-matcher.stderr b/src/test/ui/traits/trait-object-macro-matcher.stderr index 6b5effaad9bc4..f41ebf4166d06 100644 --- a/src/test/ui/traits/trait-object-macro-matcher.stderr +++ b/src/test/ui/traits/trait-object-macro-matcher.stderr @@ -10,7 +10,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | m!(dyn Copy + Send + 'static); | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` + = note: traits that require `Self: Sized` cannot be made into an object error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 461ad97f2f0ac..7e055d746f676 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -14,7 +14,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -26,7 +26,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index 6fc57369b4e73..9e7fe7f3e1dfc 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object @@ -14,7 +14,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object @@ -26,7 +26,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 3bef38d2fd2c3..f17391520a32c 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -25,7 +25,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | fn bar() where Vec:, {} | ^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` + = note: traits that require `Self: Sized` cannot be made into an object error: aborting due to 3 previous errors diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index 36c60aefa6bb5..452a2a5e58b7f 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -16,7 +16,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object @@ -28,7 +28,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object From 132921bc521ef351192019f9336ae7a6f5809b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 10:34:38 -0800 Subject: [PATCH 11/23] Remove duplicated code --- src/librustc/traits/object_safety.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 50d355f9d0a0d..9128851b91cf3 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -190,14 +190,7 @@ fn object_safety_violations_for_trait( tcx.def_path_str(trait_def_id) ), ); - let spans = violation.spans(); - if spans.is_empty() { - err.note(&violation.error_msg()); - } else { - for span in spans { - err.span_label(span, violation.error_msg()); - } - } + err.span_label(*span, violation.error_msg()); err.emit(); false } else { From 06fea9235642cec6e360da5654db9262245dc862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 19:35:48 -0800 Subject: [PATCH 12/23] review comments --- src/librustc/traits/object_safety.rs | 6 +++--- src/librustc_typeck/check/wfcheck.rs | 21 +++++++++------------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 9128851b91cf3..dec9ef4f4216f 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -18,7 +18,7 @@ use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use syntax::ast; use std::borrow::Cow; @@ -85,9 +85,9 @@ impl ObjectSafetyViolation { | ObjectSafetyViolation::Method(_, _, span) if *span != DUMMY_SP => { - vec![*span].into() + smallvec![*span] } - _ => vec![].into(), + _ => smallvec![], } } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 41171117b47d4..fc194e3af97f2 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -13,7 +13,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::def_id::DefId; use rustc_hir::ItemKind; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::symbol::sym; use rustc_span::Span; use syntax::ast; @@ -180,15 +180,12 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); } -fn could_be_self(trait_name: Ident, ty: &hir::Ty<'_>) -> bool { +fn could_be_self(trait_def_id: DefId, ty: &hir::Ty<'_>) -> bool { match ty.kind { - hir::TyKind::TraitObject([trait_ref], ..) => { - let mut p = trait_ref.trait_ref.path.segments.iter().map(|s| s.ident); - match (p.next(), p.next()) { - (Some(ident), None) => ident == trait_name, - _ => false, - } - } + hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments { + [s] => s.res.and_then(|r| r.opt_def_id()) == Some(trait_def_id), + _ => false, + }, _ => false, } } @@ -206,18 +203,18 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem let mut trait_should_be_self = vec![]; match &item.kind { hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty)) - if could_be_self(trait_name, ty) => + if could_be_self(trait_def_id, ty) => { trait_should_be_self.push(ty.span) } hir::TraitItemKind::Method(sig, _) => { for ty in sig.decl.inputs { - if could_be_self(trait_name, ty) { + if could_be_self(trait_def_id, ty) { trait_should_be_self.push(ty.span); } } match sig.decl.output { - hir::FunctionRetTy::Return(ty) if could_be_self(trait_name, ty) => { + hir::FunctionRetTy::Return(ty) if could_be_self(trait_def_id, ty) => { trait_should_be_self.push(ty.span); } _ => {} From 3ca1c5d5b5e0d19f55570f5d49d97100e9b524b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 20:12:46 -0800 Subject: [PATCH 13/23] Point at `Sized` requirements Make #47990 easier to understand --- src/librustc_typeck/check/method/confirm.rs | 24 ++++++++++++------- src/librustc_typeck/check/method/mod.rs | 6 ++--- src/librustc_typeck/check/method/suggest.rs | 3 ++- src/test/ui/issues/issue-35976.stderr | 3 +++ .../suggestions/imm-ref-trait-object.stderr | 5 ++++ .../by-value-trait-object-safety.stderr | 3 +++ 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 832aa9f62ff4d..eee9dc99d35b4 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> { pub struct ConfirmResult<'tcx> { pub callee: MethodCallee<'tcx>, - pub illegal_sized_bound: bool, + pub illegal_sized_bound: Option, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -112,7 +112,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // Add any trait/regions obligations specified on the method's type parameters. // We won't add these if we encountered an illegal sized bound, so that we can use // a custom error in that case. - if !illegal_sized_bound { + if illegal_sized_bound.is_none() { let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig)); self.add_obligations(method_ty, all_substs, &method_predicates); } @@ -561,23 +561,31 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn predicates_require_illegal_sized_bound( &self, predicates: &ty::InstantiatedPredicates<'tcx>, - ) -> bool { + ) -> Option { let sized_def_id = match self.tcx.lang_items().sized_trait() { Some(def_id) => def_id, - None => return false, + None => return None, }; traits::elaborate_predicates(self.tcx, predicates.predicates.clone()) .filter_map(|predicate| match predicate { ty::Predicate::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => { - Some(trait_pred) + let span = predicates + .predicates + .iter() + .zip(predicates.spans.iter()) + .filter_map(|(p, span)| if *p == predicate { Some(*span) } else { None }) + .next() + .unwrap_or(rustc_span::DUMMY_SP); + Some((trait_pred, span)) } _ => None, }) - .any(|trait_pred| match trait_pred.skip_binder().self_ty().kind { - ty::Dynamic(..) => true, - _ => false, + .filter_map(|(trait_pred, span)| match trait_pred.skip_binder().self_ty().kind { + ty::Dynamic(..) => Some(span), + _ => None, }) + .next() } fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) { diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index c1cf3522b5d9c..e90c2ef5e4361 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -58,7 +58,7 @@ pub enum MethodError<'tcx> { // Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have // forgotten to import a trait. - IllegalSizedBound(Vec, bool), + IllegalSizedBound(Vec, bool, Span), // Found a match, but the return type is wrong BadReturnType, @@ -204,7 +204,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = self.confirm_method(span, self_expr, call_expr, self_ty, pick.clone(), segment); - if result.illegal_sized_bound { + if let Some(span) = result.illegal_sized_bound { let mut needs_mut = false; if let ty::Ref(region, t_type, mutability) = self_ty.kind { let trait_type = self @@ -249,7 +249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Vec::new(), }; - return Err(IllegalSizedBound(candidates, needs_mut)); + return Err(IllegalSizedBound(candidates, needs_mut, span)); } Ok(result.callee) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 490c69b55362b..789bac2705b07 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -640,9 +640,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - MethodError::IllegalSizedBound(candidates, needs_mut) => { + MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => { let msg = format!("the `{}` method cannot be invoked on a trait object", item_name); let mut err = self.sess().struct_span_err(span, &msg); + err.span_label(bound_span, "this has a `Sized` requirement"); if !candidates.is_empty() { let help = format!( "{an}other candidate{s} {were} found in the following trait{s}, perhaps \ diff --git a/src/test/ui/issues/issue-35976.stderr b/src/test/ui/issues/issue-35976.stderr index 99b243a077792..f9b9b7dbd34bb 100644 --- a/src/test/ui/issues/issue-35976.stderr +++ b/src/test/ui/issues/issue-35976.stderr @@ -1,6 +1,9 @@ error: the `wait` method cannot be invoked on a trait object --> $DIR/issue-35976.rs:14:9 | +LL | fn wait(&self) where Self: Sized; + | ----- this has a `Sized` requirement +... LL | arg.wait(); | ^^^^ | diff --git a/src/test/ui/suggestions/imm-ref-trait-object.stderr b/src/test/ui/suggestions/imm-ref-trait-object.stderr index 9185eaa65c06d..37c2053522961 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object.stderr @@ -3,6 +3,11 @@ error: the `min` method cannot be invoked on a trait object | LL | t.min().unwrap() | ^^^ + | + ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL + | +LL | Self: Sized, + | ----- this has a `Sized` requirement | = note: you need `&mut dyn std::iter::Iterator` instead of `&dyn std::iter::Iterator` diff --git a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr index 7e9a2316be2bf..4cd2098eef256 100644 --- a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr +++ b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr @@ -1,6 +1,9 @@ error: the `foo` method cannot be invoked on a trait object --> $DIR/by-value-trait-object-safety.rs:18:7 | +LL | fn foo(self) -> String where Self: Sized; + | ----- this has a `Sized` requirement +... LL | x.foo(); | ^^^ From 413bfa4b98ac3a59c57ea9fa8cff2d87062fdc23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Jan 2020 16:47:00 -0800 Subject: [PATCH 14/23] Wording changes to object unsafe trait errors Stemming from the thread at https://twitter.com/indygreg/status/1223279056398929920 --- src/librustc/traits/error_reporting/mod.rs | 22 +++++++- src/librustc/traits/object_safety.rs | 53 ++++++++++++++++--- .../associated-const-in-trait.stderr | 6 ++- .../ui/associated-item/issue-48027.stderr | 6 ++- ...ce-impl-trait-for-trait-object-safe.stderr | 6 ++- ...reference-without-parens-suggestion.stderr | 2 +- src/test/ui/error-codes/E0033-teach.stderr | 6 ++- src/test/ui/error-codes/E0033.stderr | 6 ++- src/test/ui/error-codes/E0038.stderr | 6 ++- ...ature-gate-object_safe_for_dispatch.stderr | 26 +++++++-- ...-trait-in-return-position-dyn-trait.stderr | 12 ++++- src/test/ui/issues/issue-18959.stderr | 6 ++- src/test/ui/issues/issue-19380.stderr | 6 ++- src/test/ui/issues/issue-19538.stderr | 13 ++++- src/test/ui/issues/issue-20692.stderr | 14 ++--- src/test/ui/issues/issue-26056.stderr | 2 +- src/test/ui/issues/issue-28576.stderr | 2 +- src/test/ui/issues/issue-38404.stderr | 2 +- src/test/ui/issues/issue-38604.stderr | 4 +- src/test/ui/issues/issue-50781.stderr | 5 +- .../kindck-inherited-copy-bound.curr.stderr | 8 ++- ...copy-bound.object_safe_for_dispatch.stderr | 4 +- ...bject-safety-associated-consts.curr.stderr | 6 ++- ...ted-consts.object_safe_for_dispatch.stderr | 5 +- .../object-safety-generics.curr.stderr | 12 ++++- ...y-generics.object_safe_for_dispatch.stderr | 10 +++- .../object-safety-issue-22040.stderr | 2 +- .../object-safety-mentions-Self.curr.stderr | 12 ++++- ...tions-Self.object_safe_for_dispatch.stderr | 10 +++- .../object-safety-no-static.curr.stderr | 6 ++- ...-no-static.object_safe_for_dispatch.stderr | 5 +- .../object-safety-sized-2.curr.stderr | 4 +- ...ty-sized-2.object_safe_for_dispatch.stderr | 4 +- .../object-safety-sized.curr.stderr | 4 +- ...fety-sized.object_safe_for_dispatch.stderr | 4 +- ...ect-safety-supertrait-mentions-Self.stderr | 2 +- src/test/ui/resolve/issue-3907-2.stderr | 2 +- ...ary-self-types-not-object-safe.curr.stderr | 11 +++- ...bject-safe.object_safe_for_dispatch.stderr | 5 +- ...object-unsafe-trait-should-use-self.stderr | 10 +++- .../trait-alias-object-fail.stderr | 2 +- src/test/ui/traits/trait-item-privacy.stderr | 12 +++-- .../traits/trait-object-macro-matcher.stderr | 2 +- src/test/ui/traits/trait-object-safety.stderr | 11 +++- src/test/ui/traits/trait-test-2.stderr | 19 ++++--- ...ter-defaults-referencing-Self-ppaux.stderr | 6 ++- .../wf/wf-convert-unsafe-trait-obj-box.stderr | 12 +++-- .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 12 +++-- src/test/ui/wf/wf-fn-where-clause.stderr | 2 +- src/test/ui/wf/wf-object-safe.stderr | 6 ++- .../ui/wf/wf-unsafe-trait-obj-match.stderr | 8 ++- 51 files changed, 332 insertions(+), 91 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index f15fa779534e0..f2cc8a303a952 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1034,6 +1034,10 @@ pub fn report_object_safety_error( violations: Vec, ) -> DiagnosticBuilder<'tcx> { let trait_str = tcx.def_path_str(trait_def_id); + let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node { + hir::Node::Item(item) => Some(item.ident.span), + _ => None, + }); let span = tcx.sess.source_map().def_span(span); let mut err = struct_span_err!( tcx.sess, @@ -1045,6 +1049,7 @@ pub fn report_object_safety_error( err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); let mut reported_violations = FxHashSet::default(); + let mut had_span_label = false; for violation in violations { if let ObjectSafetyViolation::SizedSelf(sp) = &violation { if !sp.is_empty() { @@ -1055,15 +1060,28 @@ pub fn report_object_safety_error( } if reported_violations.insert(violation.clone()) { let spans = violation.spans(); + let msg = if trait_span.is_none() || spans.is_empty() { + format!("the trait cannot be made into an object because {}", violation.error_msg()) + } else { + had_span_label = true; + format!("...because {}", violation.error_msg()) + }; if spans.is_empty() { - err.note(&violation.error_msg()); + err.note(&msg); } else { for span in spans { - err.span_label(span, violation.error_msg()); + err.span_label(span, &msg); } } + if let (Some(_), Some(note)) = (trait_span, violation.solution()) { + // Only provide the help if its a local trait, otherwise it's not actionable. + err.help(¬e); + } } } + if let (Some(trait_span), true) = (trait_span, had_span_label) { + err.span_label(trait_span, "this trait cannot be made into an object..."); + } if tcx.sess.trait_methods_not_found.borrow().contains(&span) { // Avoid emitting error caused by non-existing method (#58734) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index dec9ef4f4216f..ac9e4950b72cf 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -43,12 +43,9 @@ pub enum ObjectSafetyViolation { impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { - ObjectSafetyViolation::SizedSelf(_) => { - "traits that require `Self: Sized` cannot be made into an object".into() - } + ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(), ObjectSafetyViolation::SupertraitSelf => { - "the trait cannot use `Self` as a type parameter \ - in the supertraits or where-clauses" + "it cannot use `Self` as a type parameter in the supertraits or `where`-clauses" .into() } ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => { @@ -63,19 +60,45 @@ impl ObjectSafetyViolation { name, MethodViolationCode::WhereClauseReferencesSelf, _, - ) => format!("method `{}` references the `Self` type in where clauses", name).into(), + ) => { + format!("method `{}` references the `Self` type in its `where` clause", name).into() + } ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => { format!("method `{}` has generic type parameters", name).into() } ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { format!("method `{}`'s `self` parameter cannot be dispatched on", name).into() } + ObjectSafetyViolation::AssocConst(_, DUMMY_SP) => { + "it cannot contain associated consts".into() + } ObjectSafetyViolation::AssocConst(name, _) => { - format!("the trait cannot contain associated consts like `{}`", name).into() + format!("it cannot contain associated consts like `{}`", name).into() } } } + pub fn solution(&self) -> Option { + Some(match *self { + ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf => { + return None; + } + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => format!( + "consider turning `{}` into a method by giving it a `&self` argument or \ + constraining it with `where Self: Sized`", + name + ), + ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { + format!("consider changing method `{}`'s `self` parameter to be `&self`", name) + .into() + } + ObjectSafetyViolation::AssocConst(name, _) + | ObjectSafetyViolation::Method(name, ..) => { + format!("consider moving `{}` to another trait", name) + } + }) + } + pub fn spans(&self) -> SmallVec<[Span; 1]> { // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so // diagnostics use a `note` instead of a `span_label`. @@ -190,7 +213,21 @@ fn object_safety_violations_for_trait( tcx.def_path_str(trait_def_id) ), ); - err.span_label(*span, violation.error_msg()); + let node = tcx.hir().get_if_local(trait_def_id); + let msg = if let Some(hir::Node::Item(item)) = node { + err.span_label(item.ident.span, "this trait cannot be made into an object..."); + format!("...because {}", violation.error_msg()) + } else { + format!( + "the trait cannot be made into an object because {}", + violation.error_msg() + ) + }; + err.span_label(*span, &msg); + if let (Some(_), Some(note)) = (node, violation.solution()) { + // Only provide the help if its a local trait, otherwise it's not actionable. + err.help(¬e); + } err.emit(); false } else { diff --git a/src/test/ui/associated-const/associated-const-in-trait.stderr b/src/test/ui/associated-const/associated-const-in-trait.stderr index a5d7fc5b70246..b9101c86d218a 100644 --- a/src/test/ui/associated-const/associated-const-in-trait.stderr +++ b/src/test/ui/associated-const/associated-const-in-trait.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/associated-const-in-trait.rs:9:6 | +LL | trait Trait { + | ----- this trait cannot be made into an object... LL | const N: usize; - | - the trait cannot contain associated consts like `N` + | - ...because it cannot contain associated consts like `N` ... LL | impl dyn Trait { | ^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = help: consider moving `N` to another trait error: aborting due to previous error diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr index ddabd552897a8..e8442c6c9ac14 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-48027.rs:6:6 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | const X: usize; - | - the trait cannot contain associated consts like `X` + | - ...because it cannot contain associated consts like `X` ... LL | impl dyn Bar {} | ^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `X` to another trait error[E0283]: type annotations needed --> $DIR/issue-48027.rs:3:32 diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr index ed6be60de460c..c999cabcc1413 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr @@ -2,9 +2,13 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6 | LL | trait NotObjectSafe { fn eq(&self, other: Self); } - | -- method `eq` references the `Self` type in its parameters or return type + | ------------- -- ...because method `eq` references the `Self` type in its parameters or return type + | | + | this trait cannot be made into an object... LL | impl NotObjectSafe for dyn NotObjectSafe { } | ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | + = help: consider moving `eq` to another trait error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index 070917f2db98a..333754891c164 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -16,7 +16,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | let _: &Copy + 'static; | ^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: traits that require `Self: Sized` cannot be made into an object + = note: the trait cannot be made into an object because it requires `Self: Sized` error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr index 80f3d4441bd9f..050ea63aa4fa8 100644 --- a/src/test/ui/error-codes/E0033-teach.stderr +++ b/src/test/ui/error-codes/E0033-teach.stderr @@ -7,11 +7,15 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033-teach.rs:8:20 | +LL | trait SomeTrait { + | --------- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033-teach.rs:12:9 diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr index c2843796cc851..c736fbcf92a8e 100644 --- a/src/test/ui/error-codes/E0033.stderr +++ b/src/test/ui/error-codes/E0033.stderr @@ -7,11 +7,15 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033.rs:6:20 | +LL | trait SomeTrait { + | --------- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033.rs:10:9 diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index 6eaf6e4a8aad1..62b6f4cf24692 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/E0038.rs:5:16 | +LL | trait Trait { + | ----- this trait cannot be made into an object... LL | fn foo(&self) -> Self; - | --- method `foo` references the `Self` type in its parameters or return type + | --- ...because method `foo` references the `Self` type in its parameters or return type ... LL | fn call_foo(x: Box) { | ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index ce98306940512..2905988066898 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | LL | trait NonObjectSafe1: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | -------------- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object @@ -10,35 +12,49 @@ LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { error[E0038]: the trait `NonObjectSafe2` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36 | +LL | trait NonObjectSafe2 { + | -------------- this trait cannot be made into an object... LL | fn static_fn() {} - | --------- associated function `static_fn` has no `self` parameter + | --------- ...because associated function `static_fn` has no `self` parameter ... LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object + | + = help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0038]: the trait `NonObjectSafe3` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 | +LL | trait NonObjectSafe3 { + | -------------- this trait cannot be made into an object... LL | fn foo(&self); - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters ... LL | fn takes_non_object_safe_box(obj: Box) { | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object + | + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe4` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35 | +LL | trait NonObjectSafe4 { + | -------------- this trait cannot be made into an object... LL | fn foo(&self, &Self); - | --- method `foo` references the `Self` type in its parameters or return type + | --- ...because method `foo` references the `Self` type in its parameters or return type ... LL | fn return_non_object_safe_rc() -> std::rc::Rc { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object + | + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 | LL | trait NonObjectSafe1: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | -------------- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index ff4bfc30a4a62..1443be0b30ebe 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -1,20 +1,28 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13 | +LL | trait NotObjectSafe { + | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | fn car() -> dyn NotObjectSafe { | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 | +LL | trait NotObjectSafe { + | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | fn cat() -> Box { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index 0c59486b416b8..b3ba7aecad0db 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -2,10 +2,14 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-18959.rs:11:11 | LL | pub trait Foo { fn foo(&self, ext_thing: &T); } - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters +LL | pub trait Bar: Foo { } + | --- this trait cannot be made into an object... ... LL | fn foo(b: &dyn Bar) { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr index 92bfdf1f26e93..22e744f884171 100644 --- a/src/test/ui/issues/issue-19380.stderr +++ b/src/test/ui/issues/issue-19380.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Qiz` cannot be made into an object --> $DIR/issue-19380.rs:11:3 | +LL | trait Qiz { + | --- this trait cannot be made into an object... LL | fn qiz(); - | --- associated function `qiz` has no `self` parameter + | --- ...because associated function `qiz` has no `self` parameter ... LL | foos: &'static [&'static (dyn Qiz + 'static)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object + | + = help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr index 83c03b514ddcc..b6033e47b1a44 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/issues/issue-19538.stderr @@ -2,20 +2,29 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:15 | LL | fn foo(&self, val: T); - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... ... LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `foo` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:30 | LL | fn foo(&self, val: T); - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... ... LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^ the trait `Bar` cannot be made into an object | + = help: consider moving `foo` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing` = note: required by cast to type `&mut dyn Bar` diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 552b65b362094..ca2611e0f9eb5 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -2,9 +2,10 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | LL | trait Array: Sized + Copy {} - | ----- ---- traits that require `Self: Sized` cannot be made into an object - | | - | traits that require `Self: Sized` cannot be made into an object + | ----- ----- ---- ...because it requires `Self: Sized` + | | | + | | ...because it requires `Self: Sized` + | this trait cannot be made into an object... ... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object @@ -13,9 +14,10 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | LL | trait Array: Sized + Copy {} - | ----- ---- traits that require `Self: Sized` cannot be made into an object - | | - | traits that require `Self: Sized` cannot be made into an object + | ----- ----- ---- ...because it requires `Self: Sized` + | | | + | | ...because it requires `Self: Sized` + | this trait cannot be made into an object... ... LL | let _ = x | ^ the trait `Array` cannot be made into an object diff --git a/src/test/ui/issues/issue-26056.stderr b/src/test/ui/issues/issue-26056.stderr index 9c4cf0b18acfe..2744fb91d6fe1 100644 --- a/src/test/ui/issues/issue-26056.stderr +++ b/src/test/ui/issues/issue-26056.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Map` cannot be made into an object LL | as &dyn Map; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Map` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28576.stderr b/src/test/ui/issues/issue-28576.stderr index 3249d76e69b57..5bed9a77d1891 100644 --- a/src/test/ui/issues/issue-28576.stderr +++ b/src/test/ui/issues/issue-28576.stderr @@ -5,7 +5,7 @@ LL | / dyn Bar LL | | | |________________________^ the trait `Bar` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38404.stderr b/src/test/ui/issues/issue-38404.stderr index d18a26b3a7638..613888758cab4 100644 --- a/src/test/ui/issues/issue-38404.stderr +++ b/src/test/ui/issues/issue-38404.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `B` cannot be made into an object LL | trait C: A> {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `B` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr index 8b923a2c6b23f..b3ad71e174a97 100644 --- a/src/test/ui/issues/issue-38604.stderr +++ b/src/test/ui/issues/issue-38604.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | let _f: Box = | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:15:9 @@ -12,7 +12,7 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | Box::new(()); | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<()>` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index c161e9efd1261..03e3a7f227a23 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -1,8 +1,10 @@ error: the trait `X` cannot be made into an object --> $DIR/issue-50781.rs:6:8 | +LL | trait X { + | - this trait cannot be made into an object... LL | fn foo(&self) where Self: Trait; - | ^^^ method `foo` references the `Self` type in where clauses + | ^^^ ...because method `foo` references the `Self` type in its `where` clause | note: the lint level is defined here --> $DIR/issue-50781.rs:1:9 @@ -11,6 +13,7 @@ LL | #![deny(where_clauses_object_safety)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #51443 + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 728a5ea6faa9f..2a9fd13be5f01 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -13,7 +13,9 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:19 | LL | trait Foo : Copy { - | ---- traits that require `Self: Sized` cannot be made into an object + | --- ---- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let z = &x as &dyn Foo; | ^^^^^^^^ the trait `Foo` cannot be made into an object @@ -22,7 +24,9 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- traits that require `Self: Sized` cannot be made into an object + | --- ---- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index b4fba9706bc0d..6227ada4dc938 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -13,7 +13,9 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- traits that require `Self: Sized` cannot be made into an object + | --- ---- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index b67b0e4f40e8c..e0e0344af7591 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-associated-consts.rs:12:30 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | const X: usize; - | - the trait cannot contain associated consts like `X` + | - ...because it cannot contain associated consts like `X` ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `X` to another trait error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index 20993a680ba48..ff0bd17dccce5 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -1,12 +1,15 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-associated-consts.rs:14:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | const X: usize; - | - the trait cannot contain associated consts like `X` + | - ...because it cannot contain associated consts like `X` ... LL | t | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `X` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr index 2469467f084a3..9e70abbd32fc6 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -1,20 +1,28 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:18:30 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `bar` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:24:39 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | fn make_bar_explicit(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `bar` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index d3d8d36888836..7443d38470c03 100644 --- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -1,24 +1,30 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:20:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | t | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:26:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | t as &dyn Bar | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr index 1f5c472ddc25a..55baf69401b0a 100644 --- a/src/test/ui/object-safety/object-safety-issue-22040.stderr +++ b/src/test/ui/object-safety/object-safety-issue-22040.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Expr` cannot be made into an object LL | elements: Vec>, | ^^^^^^^^^^^^^ the trait `Expr` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index 2123e306b16a4..e90f9b6d0a0cc 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -1,20 +1,28 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:22:30 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- method `bar` references the `Self` type in its parameters or return type + | --- ...because method `bar` references the `Self` type in its parameters or return type ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `bar` to another trait error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:28:30 | +LL | trait Baz { + | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- method `baz` references the `Self` type in its parameters or return type + | --- ...because method `baz` references the `Self` type in its parameters or return type ... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^ the trait `Baz` cannot be made into an object + | + = help: consider moving `baz` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 03b2b8da07533..4a23fb56e91a9 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -1,24 +1,30 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:24:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- method `bar` references the `Self` type in its parameters or return type + | --- ...because method `bar` references the `Self` type in its parameters or return type ... LL | t | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:30:5 | +LL | trait Baz { + | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- method `baz` references the `Self` type in its parameters or return type + | --- ...because method `baz` references the `Self` type in its parameters or return type ... LL | t | ^ the trait `Baz` cannot be made into an object | + = help: consider moving `baz` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Baz>` for `&T` = note: required by cast to type `&dyn Baz` diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index 099876c562aec..2f79d53d1c124 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety-no-static.rs:12:18 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo() {} - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | fn diverges() -> Box { | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index 91a9285b63ccc..bed6757fc6803 100644 --- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -1,12 +1,15 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety-no-static.rs:22:27 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo() {} - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let b: Box = Box::new(Bar); | ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 49f98e0085082..2f605d8e904c5 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,8 +1,10 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:14:30 | +LL | trait Bar + | --- this trait cannot be made into an object... LL | where Self : Sized - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ...because it requires `Self: Sized` ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index 9b189c48f9301..2f1f06f4cf5fa 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -1,8 +1,10 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:16:5 | +LL | trait Bar + | --- this trait cannot be made into an object... LL | where Self : Sized - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ...because it requires `Self: Sized` ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 3b588034e3322..54f65c43d9cde 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:12:30 | LL | trait Bar : Sized { - | ----- traits that require `Self: Sized` cannot be made into an object + | --- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 6b60eef30d3d3..58c2b7721474f 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:14:5 | LL | trait Bar : Sized { - | ----- traits that require `Self: Sized` cannot be made into an object + | --- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr index 8ae89832703d1..04f630d5dacb7 100644 --- a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^ the trait `Baz` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 1d6b378b9c8a7..d0c278d12d70a 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object LL | fn bar(_x: Foo) {} | ^^^ the trait `issue_3907::Foo` cannot be made into an object | - = note: associated function `bar` has no `self` parameter + = note: the trait cannot be made into an object because associated function `bar` has no `self` parameter error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index 653ccb9db949a..c06538fae3b4e 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -1,21 +1,28 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:32 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on + | --- ...because method `foo`'s `self` parameter cannot be dispatched on ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | + = help: consider changing method `foo`'s `self` parameter to be `&self` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on + | --- ...because method `foo`'s `self` parameter cannot be dispatched on ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | + = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index 33f1fa2e51be3..bebd5cbcf780c 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -1,12 +1,15 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on + | --- ...because method `foo`'s `self` parameter cannot be dispatched on ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | + = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 4a9242b1f4fac..55185a2c8cdd1 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -15,7 +15,9 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 | LL | trait A: Sized { - | ----- traits that require `Self: Sized` cannot be made into an object + | - ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... LL | fn f(a: A) -> A; | ^ the trait `A` cannot be made into an object @@ -35,10 +37,14 @@ LL | fn f(a: Self) -> Self; error[E0038]: the trait `B` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 | +LL | trait B { + | - this trait cannot be made into an object... LL | fn f(a: B) -> B; | - ^ the trait `B` cannot be made into an object | | - | associated function `f` has no `self` parameter + | ...because associated function `f` has no `self` parameter + | + = help: consider turning `f` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to 4 previous errors diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr index 5551b1303b927..1f9ffb6a4cfbf 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `std::cmp::Eq` cannot be made into an object LL | let _: &dyn EqAlias = &123; | ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified --> $DIR/trait-alias-object-fail.rs:9:17 diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index 4df8845de279a..e050d6940abc3 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -111,16 +111,22 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/trait-item-privacy.rs:101:5 | LL | const A: u8 = 0; - | - the trait cannot contain associated consts like `A` + | - ...because it cannot contain associated consts like `A` ... LL | const B: u8 = 0; - | - the trait cannot contain associated consts like `B` + | - ...because it cannot contain associated consts like `B` ... +LL | pub trait C: A + B { + | - this trait cannot be made into an object... LL | const C: u8 = 0; - | - the trait cannot contain associated consts like `C` + | - ...because it cannot contain associated consts like `C` ... LL | C::A; | ^^^^ the trait `assoc_const::C` cannot be made into an object + | + = help: consider moving `C` to another trait + = help: consider moving `B` to another trait + = help: consider moving `A` to another trait error[E0223]: ambiguous associated type --> $DIR/trait-item-privacy.rs:115:12 diff --git a/src/test/ui/traits/trait-object-macro-matcher.stderr b/src/test/ui/traits/trait-object-macro-matcher.stderr index f41ebf4166d06..a8511f63c16a5 100644 --- a/src/test/ui/traits/trait-object-macro-matcher.stderr +++ b/src/test/ui/traits/trait-object-macro-matcher.stderr @@ -10,7 +10,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | m!(dyn Copy + Send + 'static); | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: traits that require `Self: Sized` cannot be made into an object + = note: the trait cannot be made into an object because it requires `Self: Sized` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr index 028e9eedd641a..5eb8cd0d80636 100644 --- a/src/test/ui/traits/trait-object-safety.stderr +++ b/src/test/ui/traits/trait-object-safety.stderr @@ -1,23 +1,30 @@ error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:22 | +LL | trait Tr { + | -- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let _: &dyn Tr = &St; | ^^^ the trait `Tr` cannot be made into an object | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St` = note: required by cast to type `&dyn Tr` error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:12 | +LL | trait Tr { + | -- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let _: &dyn Tr = &St; | ^^^^^^^ the trait `Tr` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 9b750d382ec96..5b2b7b51f3dae 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -14,24 +14,31 @@ error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:16 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- ---- method `blah` has generic type parameters - | | - | method `dup` references the `Self` type in its parameters or return type + | --- --- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its parameters or return type + | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); | ^^^^^^^^^^^^ the trait `bar` cannot be made into an object + | + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:6 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- ---- method `blah` has generic type parameters - | | - | method `dup` references the `Self` type in its parameters or return type + | --- --- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its parameters or return type + | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); | ^^^^^^ the trait `bar` cannot be made into an object | + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<{integer}>` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index b315fe9df8afd..fa6c5a92fb437 100644 --- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -14,10 +14,14 @@ error[E0038]: the trait `MyAdd` cannot be made into an object --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 | LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } - | --- method `add` references the `Self` type in its parameters or return type + | ----- --- ...because method `add` references the `Self` type in its parameters or return type + | | + | this trait cannot be made into an object... ... LL | let y = x as dyn MyAdd; | ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object + | + = help: consider moving `add` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 7e055d746f676..eefb450155cdb 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -14,7 +16,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -26,7 +30,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index 9e7fe7f3e1dfc..5e645382d1b21 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object @@ -14,7 +16,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object @@ -26,7 +30,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index f17391520a32c..1c530ece29580 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -25,7 +25,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | fn bar() where Vec:, {} | ^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: traits that require `Self: Sized` cannot be made into an object + = note: the trait cannot be made into an object because it requires `Self: Sized` error: aborting due to 3 previous errors diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 0d8441f87e7e7..2ff6383bc80eb 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/wf-object-safe.rs:9:13 | +LL | trait A { + | - this trait cannot be made into an object... LL | fn foo(&self, _x: &Self); - | --- method `foo` references the `Self` type in its parameters or return type + | --- ...because method `foo` references the `Self` type in its parameters or return type ... LL | let _x: &dyn A; | ^^^^^^ the trait `A` cannot be made into an object + | + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index 452a2a5e58b7f..9319e3382c2d4 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -16,7 +16,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object @@ -28,7 +30,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object From a52ec87a1720bda5a2aac437a909af01cd35e3f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Jan 2020 18:48:35 -0800 Subject: [PATCH 15/23] Use more appropriate spans on object unsafe traits and provide structured suggestions when possible --- src/librustc/traits/error_reporting/mod.rs | 10 +- src/librustc/traits/object_safety.rs | 103 +++++++++++++----- src/librustc_hir/hir.rs | 21 ++++ src/librustc_parse/parser/generics.rs | 2 +- ...ce-impl-trait-for-trait-object-safe.stderr | 2 +- src/test/ui/error-codes/E0033-teach.stderr | 5 +- src/test/ui/error-codes/E0033.stderr | 5 +- src/test/ui/error-codes/E0038.stderr | 2 +- ...ature-gate-object_safe_for_dispatch.stderr | 7 +- ...-trait-in-return-position-dyn-trait.stderr | 10 +- src/test/ui/issues/issue-19380.stderr | 5 +- .../object-safety-mentions-Self.curr.stderr | 4 +- ...tions-Self.object_safe_for_dispatch.stderr | 4 +- .../object-safety-no-static.curr.stderr | 5 +- ...-no-static.object_safe_for_dispatch.stderr | 5 +- ...ary-self-types-not-object-safe.curr.stderr | 13 ++- ...bject-safe.object_safe_for_dispatch.stderr | 6 +- ...object-unsafe-trait-should-use-self.stderr | 5 +- src/test/ui/traits/trait-object-safety.stderr | 10 +- src/test/ui/traits/trait-test-2.stderr | 12 +- ...ter-defaults-referencing-Self-ppaux.stderr | 2 +- src/test/ui/wf/wf-object-safe.stderr | 2 +- 22 files changed, 178 insertions(+), 62 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index f2cc8a303a952..0ea0f271fd60e 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1073,9 +1073,15 @@ pub fn report_object_safety_error( err.span_label(span, &msg); } } - if let (Some(_), Some(note)) = (trait_span, violation.solution()) { + match (trait_span, violation.solution()) { + (Some(_), Some((note, None))) => { + err.help(¬e); + } + (Some(_), Some((note, Some((sugg, span))))) => { + err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable); + } // Only provide the help if its a local trait, otherwise it's not actionable. - err.help(¬e); + _ => {} } } } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ac9e4950b72cf..efb46a1b8d3ee 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -13,6 +13,7 @@ use super::elaborate_predicates; use crate::traits::{self, Obligation, ObligationCause}; use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; @@ -48,14 +49,20 @@ impl ObjectSafetyViolation { "it cannot use `Self` as a type parameter in the supertraits or `where`-clauses" .into() } - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => { + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => { format!("associated function `{}` has no `self` parameter", name).into() } - ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!( - "method `{}` references the `Self` type in its parameters or return type", + ObjectSafetyViolation::Method( name, - ) - .into(), + MethodViolationCode::ReferencesSelfInput(_), + DUMMY_SP, + ) => format!("method `{}` references the `Self` type in its parameters", name).into(), + ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfInput(_), _) => { + format!("method `{}` references the `Self` type in this parameter", name).into() + } + ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => { + format!("method `{}` references the `Self` type in its return type", name).into() + } ObjectSafetyViolation::Method( name, MethodViolationCode::WhereClauseReferencesSelf, @@ -78,23 +85,31 @@ impl ObjectSafetyViolation { } } - pub fn solution(&self) -> Option { + pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> { Some(match *self { ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf => { return None; } - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => format!( - "consider turning `{}` into a method by giving it a `&self` argument or \ - constraining it with `where Self: Sized`", - name + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => ( + format!( + "consider turning `{}` into a method by giving it a `&self` argument or \ + constraining it so it does not apply to trait objects", + name + ), + sugg.map(|(sugg, sp)| (sugg.to_string(), sp)), ), - ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { + ObjectSafetyViolation::Method( + name, + MethodViolationCode::UndispatchableReceiver, + span, + ) => ( format!("consider changing method `{}`'s `self` parameter to be `&self`", name) - .into() - } + .into(), + Some(("&Self".to_string(), span)), + ), ObjectSafetyViolation::AssocConst(name, _) | ObjectSafetyViolation::Method(name, ..) => { - format!("consider moving `{}` to another trait", name) + (format!("consider moving `{}` to another trait", name), None) } }) } @@ -119,10 +134,13 @@ impl ObjectSafetyViolation { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum MethodViolationCode { /// e.g., `fn foo()` - StaticMethod, + StaticMethod(Option<(&'static str, Span)>), + + /// e.g., `fn foo(&self, x: Self)` + ReferencesSelfInput(usize), - /// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self` - ReferencesSelf, + /// e.g., `fn foo(&self) -> Self` + ReferencesSelfOutput, /// e.g., `fn foo(&self) where Self: Clone` WhereClauseReferencesSelf, @@ -193,7 +211,7 @@ fn object_safety_violations_for_trait( .filter(|item| item.kind == ty::AssocKind::Method) .filter_map(|item| { object_safety_violation_for_method(tcx, trait_def_id, &item) - .map(|code| ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)) + .map(|(code, span)| ObjectSafetyViolation::Method(item.ident.name, code, span)) }) .filter(|violation| { if let ObjectSafetyViolation::Method( @@ -224,9 +242,15 @@ fn object_safety_violations_for_trait( ) }; err.span_label(*span, &msg); - if let (Some(_), Some(note)) = (node, violation.solution()) { + match (node, violation.solution()) { + (Some(_), Some((note, None))) => { + err.help(¬e); + } + (Some(_), Some((note, Some((sugg, span))))) => { + err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable); + } // Only provide the help if its a local trait, otherwise it's not actionable. - err.help(¬e); + _ => {} } err.emit(); false @@ -398,7 +422,7 @@ fn object_safety_violation_for_method( tcx: TyCtxt<'_>, trait_def_id: DefId, method: &ty::AssocItem, -) -> Option { +) -> Option<(MethodViolationCode, Span)> { debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method); // Any method that has a `Self : Sized` requisite is otherwise // exempt from the regulations. @@ -406,7 +430,26 @@ fn object_safety_violation_for_method( return None; } - virtual_call_violation_for_method(tcx, trait_def_id, method) + let violation = virtual_call_violation_for_method(tcx, trait_def_id, method); + // Get an accurate span depending on the violation. + violation.map(|v| { + let node = tcx.hir().get_if_local(method.def_id); + let span = match (v, node) { + (MethodViolationCode::ReferencesSelfInput(arg), Some(node)) => node + .fn_decl() + .and_then(|decl| decl.inputs.get(arg + 1)) + .map_or(method.ident.span, |arg| arg.span), + (MethodViolationCode::UndispatchableReceiver, Some(node)) => node + .fn_decl() + .and_then(|decl| decl.inputs.get(0)) + .map_or(method.ident.span, |arg| arg.span), + (MethodViolationCode::ReferencesSelfOutput, Some(node)) => { + node.fn_decl().map_or(method.ident.span, |decl| decl.output.span()) + } + _ => method.ident.span, + }; + (v, span) + }) } /// Returns `Some(_)` if this method cannot be called on a trait @@ -420,18 +463,26 @@ fn virtual_call_violation_for_method<'tcx>( ) -> Option { // The method's first parameter must be named `self` if !method.method_has_self_argument { - return Some(MethodViolationCode::StaticMethod); + // We'll attempt to provide a structured suggestion for `Self: Sized`. + let sugg = + tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map( + |generics| match generics.where_clause.predicates { + [] => (" where Self: Sized", generics.where_clause.span), + [.., pred] => (", Self: Sized", pred.span().shrink_to_hi()), + }, + ); + return Some(MethodViolationCode::StaticMethod(sugg)); } let sig = tcx.fn_sig(method.def_id); - for input_ty in &sig.skip_binder().inputs()[1..] { + for (i, input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() { if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) { - return Some(MethodViolationCode::ReferencesSelf); + return Some(MethodViolationCode::ReferencesSelfInput(i)); } } if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output().skip_binder()) { - return Some(MethodViolationCode::ReferencesSelf); + return Some(MethodViolationCode::ReferencesSelfOutput); } // We can't monomorphize things like `fn foo(...)`. diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 0db75454aee38..3ed0ad16eebf2 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2631,4 +2631,25 @@ impl Node<'_> { _ => None, } } + + pub fn fn_decl(&self) -> Option<&FnDecl<'_>> { + match self { + Node::TraitItem(TraitItem { kind: TraitItemKind::Method(fn_sig, _), .. }) + | Node::ImplItem(ImplItem { kind: ImplItemKind::Method(fn_sig, _), .. }) + | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl), + Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => { + Some(fn_decl) + } + _ => None, + } + } + + pub fn generics(&self) -> Option<&Generics<'_>> { + match self { + Node::TraitItem(TraitItem { generics, .. }) + | Node::ImplItem(ImplItem { generics, .. }) + | Node::Item(Item { kind: ItemKind::Fn(_, generics, _), .. }) => Some(generics), + _ => None, + } + } } diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 075583711f5d3..0984263bb283e 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -172,7 +172,7 @@ impl<'a> Parser<'a> { /// ``` pub(super) fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { let mut where_clause = - WhereClause { predicates: Vec::new(), span: self.prev_span.to(self.prev_span) }; + WhereClause { predicates: Vec::new(), span: self.prev_span.shrink_to_hi() }; if !self.eat_keyword(kw::Where) { return Ok(where_clause); diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr index c999cabcc1413..85ed360a1f74a 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6 | LL | trait NotObjectSafe { fn eq(&self, other: Self); } - | ------------- -- ...because method `eq` references the `Self` type in its parameters or return type + | ------------- ---- ...because method `eq` references the `Self` type in this parameter | | | this trait cannot be made into an object... LL | impl NotObjectSafe for dyn NotObjectSafe { } diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr index 050ea63aa4fa8..f323a9904557a 100644 --- a/src/test/ui/error-codes/E0033-teach.stderr +++ b/src/test/ui/error-codes/E0033-teach.stderr @@ -15,7 +15,10 @@ LL | fn foo(); LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033-teach.rs:12:9 diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr index c736fbcf92a8e..84481ff16c07e 100644 --- a/src/test/ui/error-codes/E0033.stderr +++ b/src/test/ui/error-codes/E0033.stderr @@ -15,7 +15,10 @@ LL | fn foo(); LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033.rs:10:9 diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index 62b6f4cf24692..638e924b0eb43 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn foo(&self) -> Self; - | --- ...because method `foo` references the `Self` type in its parameters or return type + | ---- ...because method `foo` references the `Self` type in its return type ... LL | fn call_foo(x: Box) { | ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index 2905988066898..c66bbb0c5045f 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -20,7 +20,10 @@ LL | fn static_fn() {} LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object | - = help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn static_fn() where Self: Sized {} + | ^^^^^^^^^^^^^^^^^ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 @@ -41,7 +44,7 @@ error[E0038]: the trait `NonObjectSafe4` cannot be made into an object LL | trait NonObjectSafe4 { | -------------- this trait cannot be made into an object... LL | fn foo(&self, &Self); - | --- ...because method `foo` references the `Self` type in its parameters or return type + | ----- ...because method `foo` references the `Self` type in this parameter ... LL | fn return_non_object_safe_rc() -> std::rc::Rc { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 1443be0b30ebe..9df5188bbdd08 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -9,7 +9,10 @@ LL | fn foo() -> Self; LL | fn car() -> dyn NotObjectSafe { | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() -> Self where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 @@ -22,7 +25,10 @@ LL | fn foo() -> Self; LL | fn cat() -> Box { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() -> Self where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr index 22e744f884171..0a080171a7951 100644 --- a/src/test/ui/issues/issue-19380.stderr +++ b/src/test/ui/issues/issue-19380.stderr @@ -9,7 +9,10 @@ LL | fn qiz(); LL | foos: &'static [&'static (dyn Qiz + 'static)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object | - = help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn qiz() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index e90f9b6d0a0cc..4dbb27b425b32 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- ...because method `bar` references the `Self` type in its parameters or return type + | ----- ...because method `bar` references the `Self` type in this parameter ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object @@ -17,7 +17,7 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- ...because method `baz` references the `Self` type in its parameters or return type + | ---- ...because method `baz` references the `Self` type in its return type ... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^ the trait `Baz` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 4a23fb56e91a9..89b273fb8adde 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- ...because method `bar` references the `Self` type in its parameters or return type + | ----- ...because method `bar` references the `Self` type in this parameter ... LL | t | ^ the trait `Bar` cannot be made into an object @@ -19,7 +19,7 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- ...because method `baz` references the `Self` type in its parameters or return type + | ---- ...because method `baz` references the `Self` type in its return type ... LL | t | ^ the trait `Baz` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index 2f79d53d1c124..f878cf8b46241 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -9,7 +9,10 @@ LL | fn foo() {} LL | fn diverges() -> Box { | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index bed6757fc6803..de56843962bea 100644 --- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -9,9 +9,12 @@ LL | fn foo() {} LL | let b: Box = Box::new(Bar); | ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index c06538fae3b4e..7948f7e9d6bc6 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -4,12 +4,13 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- ...because method `foo`'s `self` parameter cannot be dispatched on + | --------- + | | + | ...because method `foo`'s `self` parameter cannot be dispatched on + | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | - = help: consider changing method `foo`'s `self` parameter to be `&self` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 @@ -17,12 +18,14 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- ...because method `foo`'s `self` parameter cannot be dispatched on + | --------- + | | + | ...because method `foo`'s `self` parameter cannot be dispatched on + | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index bebd5cbcf780c..74e76b8265f70 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -4,12 +4,14 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- ...because method `foo`'s `self` parameter cannot be dispatched on + | --------- + | | + | ...because method `foo`'s `self` parameter cannot be dispatched on + | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 55185a2c8cdd1..58be59602b9c5 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -44,7 +44,10 @@ LL | fn f(a: B) -> B; | | | ...because associated function `f` has no `self` parameter | - = help: consider turning `f` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `f` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn f(a: B) -> B where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr index 5eb8cd0d80636..162e9249b880e 100644 --- a/src/test/ui/traits/trait-object-safety.stderr +++ b/src/test/ui/traits/trait-object-safety.stderr @@ -9,9 +9,12 @@ LL | fn foo(); LL | let _: &dyn Tr = &St; | ^^^ the trait `Tr` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St` = note: required by cast to type `&dyn Tr` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:12 @@ -24,7 +27,10 @@ LL | fn foo(); LL | let _: &dyn Tr = &St; | ^^^^^^^ the trait `Tr` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 5b2b7b51f3dae..9d1eef547568e 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -14,9 +14,9 @@ error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:16 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- --- ---- ...because method `blah` has generic type parameters - | | | - | | ...because method `dup` references the `Self` type in its parameters or return type + | --- ---- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); @@ -29,9 +29,9 @@ error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:6 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- --- ---- ...because method `blah` has generic type parameters - | | | - | | ...because method `dup` references the `Self` type in its parameters or return type + | --- ---- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index fa6c5a92fb437..539189982a8d7 100644 --- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -14,7 +14,7 @@ error[E0038]: the trait `MyAdd` cannot be made into an object --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 | LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } - | ----- --- ...because method `add` references the `Self` type in its parameters or return type + | ----- ---- ...because method `add` references the `Self` type in its return type | | | this trait cannot be made into an object... ... diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 2ff6383bc80eb..8935d766354fe 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `A` cannot be made into an object LL | trait A { | - this trait cannot be made into an object... LL | fn foo(&self, _x: &Self); - | --- ...because method `foo` references the `Self` type in its parameters or return type + | ----- ...because method `foo` references the `Self` type in this parameter ... LL | let _x: &dyn A; | ^^^^^^ the trait `A` cannot be made into an object From 542130bde94decf458cdeec2a6d61314fb1f427a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Jan 2020 19:04:58 -0800 Subject: [PATCH 16/23] add tests for structured suggestion --- .../object-unsafe-trait-references-self.rs | 12 +++++++ ...object-unsafe-trait-references-self.stderr | 30 ++++++++++++++++ ...-unsafe-trait-should-use-where-sized.fixed | 13 +++++++ ...ect-unsafe-trait-should-use-where-sized.rs | 13 +++++++ ...unsafe-trait-should-use-where-sized.stderr | 35 +++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 src/test/ui/suggestions/object-unsafe-trait-references-self.rs create mode 100644 src/test/ui/suggestions/object-unsafe-trait-references-self.stderr create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.rs b/src/test/ui/suggestions/object-unsafe-trait-references-self.rs new file mode 100644 index 0000000000000..07bf053e99665 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.rs @@ -0,0 +1,12 @@ +trait Trait { + fn baz(&self, _: Self) {} + fn bat(&self) -> Self {} +} + +fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object + +trait Other: Sized {} + +fn foo(x: &dyn Other) {} //~ ERROR the trait `Other` cannot be made into an object + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr new file mode 100644 index 0000000000000..c3cfad70bf430 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -0,0 +1,30 @@ +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/object-unsafe-trait-references-self.rs:6:11 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +LL | fn baz(&self, _: Self) {} + | ---- ...because method `baz` references the `Self` type in this parameter +LL | fn bat(&self) -> Self {} + | ---- ...because method `bat` references the `Self` type in its return type +... +LL | fn bar(x: &dyn Trait) {} + | ^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = help: consider moving `baz` to another trait + = help: consider moving `bat` to another trait + +error[E0038]: the trait `Other` cannot be made into an object + --> $DIR/object-unsafe-trait-references-self.rs:10:11 + | +LL | trait Other: Sized {} + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... +LL | +LL | fn foo(x: &dyn Other) {} + | ^^^^^^^^^^ the trait `Other` cannot be made into an object + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed new file mode 100644 index 0000000000000..c4b8960b65e4a --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed @@ -0,0 +1,13 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] + +trait Trait { + fn foo() where Self: Other, Self: Sized, { } + fn bar(self: &Self) {} //~ ERROR invalid `self` parameter type +} + +fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object + +trait Other {} + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs new file mode 100644 index 0000000000000..38d9aea16ebf6 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs @@ -0,0 +1,13 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] + +trait Trait { + fn foo() where Self: Other, { } + fn bar(self: ()) {} //~ ERROR invalid `self` parameter type +} + +fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object + +trait Other {} + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr new file mode 100644 index 0000000000000..6466a768ecbe9 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr @@ -0,0 +1,35 @@ +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +LL | fn foo() where Self: Other, { } + | --- ...because associated function `foo` has no `self` parameter +LL | fn bar(self: ()) {} + | -- ...because method `bar`'s `self` parameter cannot be dispatched on +... +LL | fn bar(x: &dyn Trait) {} + | ^^^^^^^^^^ the trait `Trait` cannot be made into an object + | +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Other, Self: Sized, { } + | ^^^^^^^^^^^^^ +help: consider changing method `bar`'s `self` parameter to be `&self` + | +LL | fn bar(self: &Self) {} + | ^^^^^ + +error[E0307]: invalid `self` parameter type: () + --> $DIR/object-unsafe-trait-should-use-where-sized.rs:6:18 + | +LL | fn bar(self: ()) {} + | ^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0307. +For more information about an error, try `rustc --explain E0038`. From cb6dfeaf61ae7e0ef5f0d2d1637fa9c385874117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 00:54:13 -0800 Subject: [PATCH 17/23] Suggest `?Sized` on type parameters --- src/librustc/traits/error_reporting/mod.rs | 38 +++++++++++++++++++ .../ui/extern/extern-types-unsized.stderr | 4 +- src/test/ui/str/str-mut-idx.stderr | 4 +- src/test/ui/unsized3.stderr | 20 ++++++++-- 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 0ea0f271fd60e..0b627f9d15e0a 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1340,6 +1340,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &obligation.cause.code, &mut vec![], ); + self.suggest_unsized_bound_if_applicable(err, obligation); + } + } + + fn suggest_unsized_bound_if_applicable( + &self, + err: &mut DiagnosticBuilder<'_>, + obligation: &PredicateObligation<'tcx>, + ) { + if let ( + ty::Predicate::Trait(pred, _), + ObligationCauseCode::BindingObligation(item_def_id, span), + ) = (&obligation.predicate, &obligation.cause.code) + { + if let (Some(generics), true) = ( + self.tcx.hir().get_if_local(*item_def_id).as_ref().and_then(|n| n.generics()), + Some(pred.def_id()) == self.tcx.lang_items().sized_trait(), + ) { + for param in generics.params { + if param.span == *span + && !param.bounds.iter().any(|bound| { + bound.trait_def_id() == self.tcx.lang_items().sized_trait() + }) + { + let (span, separator) = match param.bounds { + [] => (span.shrink_to_hi(), ":"), + [.., bound] => (bound.span().shrink_to_hi(), " + "), + }; + err.span_suggestion( + span, + "consider relaxing the implicit `Sized` restriction", + format!("{} ?Sized", separator), + Applicability::MachineApplicable, + ); + return; + } + } + } } } diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr index 0417186eed346..0c9165fd9585d 100644 --- a/src/test/ui/extern/extern-types-unsized.stderr +++ b/src/test/ui/extern/extern-types-unsized.stderr @@ -2,7 +2,9 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim --> $DIR/extern-types-unsized.rs:22:20 | LL | fn assert_sized() { } - | ------------ - required by this bound in `assert_sized` + | ------------ -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `assert_sized` ... LL | assert_sized::(); | ^ doesn't have a size known at compile-time diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index 3c957970e51c2..a9ec6b9c02fe8 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -2,7 +2,9 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/str-mut-idx.rs:4:15 | LL | fn bot() -> T { loop {} } - | --- - required by this bound in `bot` + | --- -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `bot` ... LL | s[1..2] = bot(); | ^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr index 232296ad09126..0c37828229e34 100644 --- a/src/test/ui/unsized3.stderr +++ b/src/test/ui/unsized3.stderr @@ -1,8 +1,6 @@ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:7:13 | -LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` LL | f2::(x); | ^ doesn't have a size known at compile-time ... @@ -11,12 +9,18 @@ LL | fn f2(x: &X) { | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit +help: consider further restricting this bound + | +LL | fn f1(x: &X) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f2(x: &X) { + | ^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:18:13 | -LL | fn f3(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` LL | f4::(x); | ^ doesn't have a size known at compile-time ... @@ -25,6 +29,14 @@ LL | fn f4(x: &X) { | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit +help: consider further restricting this bound + | +LL | fn f3(x: &X) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f4(x: &X) { + | ^^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:33:8 From d216b731f61d85a5cc6cddfdd7f91628bc594b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 01:38:12 -0800 Subject: [PATCH 18/23] Remove duplicated code --- src/librustc/traits/error_reporting/mod.rs | 72 ------------------- .../diagnostics/conflict_errors.rs | 2 +- 2 files changed, 1 insertion(+), 73 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 0b627f9d15e0a..6d3719b32d07e 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -27,7 +27,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_span::source_map::SourceMap; use rustc_span::{ExpnKind, Span, DUMMY_SP}; use std::fmt; use syntax::ast; @@ -1427,74 +1426,3 @@ impl ArgKind { } } } - -/// Suggest restricting a type param with a new bound. -pub fn suggest_constraining_type_param( - generics: &hir::Generics<'_>, - err: &mut DiagnosticBuilder<'_>, - param_name: &str, - constraint: &str, - source_map: &SourceMap, - span: Span, -) -> bool { - let restrict_msg = "consider further restricting this bound"; - if let Some(param) = - generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next() - { - if param_name.starts_with("impl ") { - // `impl Trait` in argument: - // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}` - err.span_suggestion( - param.span, - restrict_msg, - // `impl CurrentTrait + MissingTrait` - format!("{} + {}", param_name, constraint), - Applicability::MachineApplicable, - ); - } else if generics.where_clause.predicates.is_empty() && param.bounds.is_empty() { - // If there are no bounds whatsoever, suggest adding a constraint - // to the type parameter: - // `fn foo(t: T) {}` → `fn foo(t: T) {}` - err.span_suggestion( - param.span, - "consider restricting this bound", - format!("{}: {}", param_name, constraint), - Applicability::MachineApplicable, - ); - } else if !generics.where_clause.predicates.is_empty() { - // There is a `where` clause, so suggest expanding it: - // `fn foo(t: T) where T: Debug {}` → - // `fn foo(t: T) where T: Debug, T: Trait {}` - err.span_suggestion( - generics.where_clause.span().unwrap().shrink_to_hi(), - &format!("consider further restricting type parameter `{}`", param_name), - format!(", {}: {}", param_name, constraint), - Applicability::MachineApplicable, - ); - } else { - // If there is no `where` clause lean towards constraining to the - // type parameter: - // `fn foo(t: T, x: X) {}` → `fn foo(t: T) {}` - // `fn foo(t: T) {}` → `fn foo(t: T) {}` - let sp = param.span.with_hi(span.hi()); - let span = source_map.span_through_char(sp, ':'); - if sp != param.span && sp != span { - // Only suggest if we have high certainty that the span - // covers the colon in `foo`. - err.span_suggestion( - span, - restrict_msg, - format!("{}: {} + ", param_name, constraint), - Applicability::MachineApplicable, - ); - } else { - err.span_label( - param.span, - &format!("consider adding a `where {}: {}` bound", param_name, constraint), - ); - } - } - return true; - } - false -} diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index a8e534a9f650c..810882d3bbdb8 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -3,7 +3,7 @@ use rustc::mir::{ FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, }; -use rustc::traits::error_reporting::suggest_constraining_type_param; +use rustc::traits::error_reporting::suggestions::suggest_constraining_type_param; use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DiagnosticBuilder}; From 342db717e2aa52decc812084c31fdcbeaf03b255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 02:03:54 -0800 Subject: [PATCH 19/23] Account for `?Sized` type parameter bounds --- .../traits/error_reporting/suggestions.rs | 12 ++++++- .../diagnostics/conflict_errors.rs | 2 ++ .../ui/consts/too_generic_eval_ice.stderr | 4 +-- .../dst/dst-object-from-unsized-type.stderr | 4 +-- src/test/ui/issues/issue-27060-2.stderr | 2 +- .../traits/trait-suggest-where-clause.stderr | 4 +-- src/test/ui/union/union-sized-field.stderr | 6 ++-- .../ui/unsized/unsized-bare-typaram.stderr | 4 +-- src/test/ui/unsized/unsized-enum.stderr | 4 +-- src/test/ui/unsized/unsized-enum2.stderr | 8 ++--- .../unsized-inherent-impl-self-type.stderr | 4 +-- src/test/ui/unsized/unsized-struct.stderr | 8 ++--- .../unsized-trait-impl-self-type.stderr | 4 +-- .../unsized-trait-impl-trait-arg.stderr | 4 +-- src/test/ui/unsized3.stderr | 36 ++++++++----------- src/test/ui/unsized5.stderr | 8 ++--- src/test/ui/unsized6.stderr | 30 ++++++++-------- src/test/ui/unsized7.stderr | 4 +-- 18 files changed, 76 insertions(+), 72 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 72629c6a3cffa..c1facd34dfee5 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -145,12 +145,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let param_name = self_ty.to_string(); let constraint = trait_ref.print_only_trait_path().to_string(); if suggest_constraining_type_param( + self.tcx, generics, &mut err, ¶m_name, &constraint, self.tcx.sess.source_map(), *span, + Some(trait_ref.def_id()), ) { return; } @@ -1652,18 +1654,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Suggest restricting a type param with a new bound. pub fn suggest_constraining_type_param( + tcx: TyCtxt<'_>, generics: &hir::Generics<'_>, err: &mut DiagnosticBuilder<'_>, param_name: &str, constraint: &str, source_map: &SourceMap, span: Span, + def_id: Option, ) -> bool { let restrict_msg = "consider further restricting this bound"; if let Some(param) = generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next() { - if param_name.starts_with("impl ") { + if def_id == tcx.lang_items().sized_trait() { + // Type parameters are already `Sized` by default. + err.span_label( + param.span, + &format!("this type parameter needs to be `{}`", constraint), + ); + } else if param_name.starts_with("impl ") { // `impl Trait` in argument: // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}` err.span_suggestion( diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 810882d3bbdb8..b0b9790abb12a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -217,12 +217,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { tcx.hir().get_generics(tcx.closure_base_def_id(self.mir_def_id)) { suggest_constraining_type_param( + tcx, generics, &mut err, ¶m.name.as_str(), "Copy", tcx.sess.source_map(), span, + None, ); } } diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr index 599d1d79e7555..fd68cb9c6cf85 100644 --- a/src/test/ui/consts/too_generic_eval_ice.stderr +++ b/src/test/ui/consts/too_generic_eval_ice.stderr @@ -18,7 +18,7 @@ LL | pub struct Foo(A, B); | --------------------------- required by `Foo` LL | LL | impl Foo { - | - help: consider restricting this bound: `A: std::marker::Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | [5; Self::HOST_SIZE] == [6; 0] | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -33,7 +33,7 @@ LL | pub struct Foo(A, B); | --------------------------- required by `Foo` LL | LL | impl Foo { - | - help: consider restricting this bound: `B: std::marker::Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | [5; Self::HOST_SIZE] == [6; 0] | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr index 40db575eabd38..80d188bf2f89b 100644 --- a/src/test/ui/dst/dst-object-from-unsized-type.stderr +++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/dst-object-from-unsized-type.rs:8:23 | LL | fn test1(t: &T) { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let u: &dyn Foo = t; | ^ doesn't have a size known at compile-time | @@ -14,7 +14,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/dst-object-from-unsized-type.rs:13:23 | LL | fn test2(t: &T) { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let v: &dyn Foo = t as &dyn Foo; | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/issues/issue-27060-2.stderr b/src/test/ui/issues/issue-27060-2.stderr index 553041c5106c5..1ddea73e00ae0 100644 --- a/src/test/ui/issues/issue-27060-2.stderr +++ b/src/test/ui/issues/issue-27060-2.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/issue-27060-2.rs:3:5 | LL | pub struct Bad { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | data: T, | ^^^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr index 831dd439298d9..9680d58b8c0c7 100644 --- a/src/test/ui/traits/trait-suggest-where-clause.stderr +++ b/src/test/ui/traits/trait-suggest-where-clause.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim --> $DIR/trait-suggest-where-clause.rs:11:20 | LL | fn check() { - | -- help: consider further restricting this bound: `U: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | // suggest a where-clause, if needed LL | mem::size_of::(); | ^ doesn't have a size known at compile-time @@ -19,7 +19,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim --> $DIR/trait-suggest-where-clause.rs:14:5 | LL | fn check() { - | -- help: consider further restricting this bound: `U: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | mem::size_of::>(); | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr index c9fec1d21d152..62dacd064bed0 100644 --- a/src/test/ui/union/union-sized-field.stderr +++ b/src/test/ui/union/union-sized-field.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:4:5 | LL | union Foo { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^^^^^^^^ doesn't have a size known at compile-time | @@ -14,7 +14,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:9:5 | LL | struct Foo2 { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^^^^^^^^ doesn't have a size known at compile-time | @@ -26,7 +26,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:15:11 | LL | enum Foo3 { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | Value(T), | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr index bd97b0203b510..772de23e64cf0 100644 --- a/src/test/ui/unsized/unsized-bare-typaram.stderr +++ b/src/test/ui/unsized/unsized-bare-typaram.stderr @@ -4,9 +4,9 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim LL | fn bar() { } | --- - required by this bound in `bar` LL | fn foo() { bar::() } - | -- ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr index 341d3e4cc2df2..88f7b1f77aee0 100644 --- a/src/test/ui/unsized/unsized-enum.stderr +++ b/src/test/ui/unsized/unsized-enum.stderr @@ -5,9 +5,9 @@ LL | enum Foo { FooSome(U), FooNone } | ----------- required by `Foo` LL | fn foo1() { not_sized::>() } // Hunky dory. LL | fn foo2() { not_sized::>() } - | -- ^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-enum2.stderr b/src/test/ui/unsized/unsized-enum2.stderr index e85b6d662f9d5..bc3b3831f3269 100644 --- a/src/test/ui/unsized/unsized-enum2.stderr +++ b/src/test/ui/unsized/unsized-enum2.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `W` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:23:8 | LL | enum E { - | -- help: consider further restricting this bound: `W: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | // parameter LL | VA(W), | ^ doesn't have a size known at compile-time @@ -15,7 +15,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:25:8 | LL | enum E { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | VB{x: X}, | ^^^^ doesn't have a size known at compile-time @@ -28,7 +28,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:27:15 | LL | enum E { - | -- help: consider further restricting this bound: `Y: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | VC(isize, Y), | ^ doesn't have a size known at compile-time @@ -41,7 +41,7 @@ error[E0277]: the size for values of type `Z` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:29:18 | LL | enum E { - | -- help: consider further restricting this bound: `Z: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | VD{u: isize, x: Z}, | ^^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr index 280b8fd43cab0..5688ae5b89a04 100644 --- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -5,9 +5,9 @@ LL | struct S5(Y); | ---------------- required by `S5` LL | LL | impl S5 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index 2894d5d56710d..653fb5c1ae8dc 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -5,9 +5,9 @@ LL | struct Foo { data: T } | ------------- required by `Foo` LL | fn foo1() { not_sized::>() } // Hunky dory. LL | fn foo2() { not_sized::>() } - | -- ^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit @@ -19,9 +19,9 @@ LL | fn is_sized() { } | -------- - required by this bound in `is_sized` ... LL | fn bar2() { is_sized::>() } - | -- ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: within `Bar`, the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr index ba1550439c0d9..3597073e7e6c6 100644 --- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr @@ -5,9 +5,9 @@ LL | struct S5(Y); | ---------------- required by `S5` LL | LL | impl T3 for S5 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr index 41371d63f9e53..b37d9f9d5369e 100644 --- a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -2,9 +2,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized-trait-impl-trait-arg.rs:8:17 | LL | impl T2 for S4 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr index 0c37828229e34..e97d00fc4741d 100644 --- a/src/test/ui/unsized3.stderr +++ b/src/test/ui/unsized3.stderr @@ -1,42 +1,34 @@ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:7:13 | +LL | fn f1(x: &X) { + | - this type parameter needs to be `std::marker::Sized` LL | f2::(x); | ^ doesn't have a size known at compile-time ... LL | fn f2(x: &X) { - | -- - required by this bound in `f2` + | -- -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `f2` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit -help: consider further restricting this bound - | -LL | fn f1(x: &X) { - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: consider relaxing the implicit `Sized` restriction - | -LL | fn f2(x: &X) { - | ^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:18:13 | +LL | fn f3(x: &X) { + | - this type parameter needs to be `std::marker::Sized` LL | f4::(x); | ^ doesn't have a size known at compile-time ... LL | fn f4(x: &X) { - | -- - required by this bound in `f4` + | -- - - help: consider relaxing the implicit `Sized` restriction: `+ ?Sized` + | | + | required by this bound in `f4` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit -help: consider further restricting this bound - | -LL | fn f3(x: &X) { - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: consider relaxing the implicit `Sized` restriction - | -LL | fn f4(x: &X) { - | ^^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:33:8 @@ -45,7 +37,7 @@ LL | fn f5(x: &Y) {} | -- - required by this bound in `f5` ... LL | fn f8(x1: &S, x2: &S) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(x1); | ^^ doesn't have a size known at compile-time | @@ -57,7 +49,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:40:8 | LL | fn f9(x1: Box>) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(*x1, 34)); | ^^^^^^^^^^ doesn't have a size known at compile-time | @@ -70,7 +62,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:45:9 | LL | fn f10(x1: Box>) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); | ^^^^^^^^^ doesn't have a size known at compile-time | @@ -87,7 +79,7 @@ LL | fn f5(x: &Y) {} | -- - required by this bound in `f5` ... LL | fn f10(x1: Box>) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); | ^^^^^^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized5.stderr b/src/test/ui/unsized5.stderr index bfd3f4aa691eb..de4da309791c0 100644 --- a/src/test/ui/unsized5.stderr +++ b/src/test/ui/unsized5.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:4:5 | LL | struct S1 { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f1: X, | ^^^^^ doesn't have a size known at compile-time | @@ -14,7 +14,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:10:5 | LL | struct S2 { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f: isize, LL | g: X, | ^^^^ doesn't have a size known at compile-time @@ -47,7 +47,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:25:8 | LL | enum E { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | V1(X, isize), | ^ doesn't have a size known at compile-time | @@ -59,7 +59,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:29:8 | LL | enum F { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | V2{f1: X, f: isize}, | ^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized6.stderr b/src/test/ui/unsized6.stderr index 95acd987a5a27..337afd2ee7e10 100644 --- a/src/test/ui/unsized6.stderr +++ b/src/test/ui/unsized6.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized6.rs:9:9 | LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `Y: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: Y; | ^ doesn't have a size known at compile-time @@ -16,7 +16,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:7:12 | LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let _: W; // <-- this is OK, no bindings created, no initializer. LL | let _: (isize, (X, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -29,7 +29,7 @@ error[E0277]: the size for values of type `Z` cannot be known at compilation tim --> $DIR/unsized6.rs:11:12 | LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `Z: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: (isize, (Z, usize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -42,7 +42,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:15:9 | LL | fn f2(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X; | ^ doesn't have a size known at compile-time | @@ -55,7 +55,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized6.rs:17:12 | LL | fn f2(x: &X) { - | -- help: consider further restricting this bound: `Y: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: (isize, (Y, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -68,7 +68,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:22:9 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | @@ -81,7 +81,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:24:9 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y = *x2; | ^ doesn't have a size known at compile-time @@ -95,7 +95,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:26:10 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time @@ -109,7 +109,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:30:9 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | @@ -122,7 +122,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:32:9 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y = *x2; | ^ doesn't have a size known at compile-time @@ -136,7 +136,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:34:10 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time @@ -150,9 +150,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:38:18 | LL | fn g1(x: X) {} - | -- ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit @@ -163,9 +163,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:40:22 | LL | fn g2(x: X) {} - | -- ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized7.stderr b/src/test/ui/unsized7.stderr index c77503a6f87aa..0f71c5f6f8fe6 100644 --- a/src/test/ui/unsized7.stderr +++ b/src/test/ui/unsized7.stderr @@ -2,9 +2,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized7.rs:12:21 | LL | impl T1 for S3 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit From 16d935e72582ad833aed735022cdf3808b229e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 12:50:07 -0800 Subject: [PATCH 20/23] fix rebase --- .../bad-bounds-on-assoc-in-trait.stderr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 5713e259362fd..efd5a92a4fced 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -7,7 +7,7 @@ LL | impl Case1 for S1 { = help: the trait `for<'a> std::fmt::Debug` is not implemented for `>::App` error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterator - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | fn assume_case1() { | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` @@ -17,7 +17,7 @@ LL | fn assume_case1() { = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | trait Case1 { | ----------- required by `Case1` @@ -30,7 +30,7 @@ LL | fn assume_case1() { = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | trait Case1 { | ----------- required by `Case1` @@ -43,7 +43,7 @@ LL | fn assume_case1() { = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | trait Case1 { | ----------- required by `Case1` From 865216b3ad4158e31d583f5f3cae12afe91c52d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 12:51:30 -0800 Subject: [PATCH 21/23] Point at reason in object unsafe trait with `Self` in supertraits or `where`-clause --- src/librustc/traits/object_safety.rs | 54 +++++++++++++------ src/test/ui/issues/issue-26056.stderr | 7 ++- src/test/ui/issues/issue-28576.stderr | 9 +++- src/test/ui/issues/issue-38404.stderr | 6 ++- src/test/ui/issues/issue-38604.stderr | 13 +++-- .../object-safety-issue-22040.stderr | 7 ++- ...ect-safety-supertrait-mentions-Self.stderr | 7 ++- .../trait-alias-object-fail.stderr | 5 +- 8 files changed, 78 insertions(+), 30 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index efb46a1b8d3ee..2745d3205dec0 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -32,7 +32,7 @@ pub enum ObjectSafetyViolation { /// Supertrait reference references `Self` an in illegal location /// (e.g., `trait Foo : Bar`). - SupertraitSelf, + SupertraitSelf(SmallVec<[Span; 1]>), /// Method has something illegal. Method(ast::Name, MethodViolationCode, Span), @@ -45,9 +45,13 @@ impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(), - ObjectSafetyViolation::SupertraitSelf => { - "it cannot use `Self` as a type parameter in the supertraits or `where`-clauses" - .into() + ObjectSafetyViolation::SupertraitSelf(ref spans) => { + if spans.iter().any(|sp| *sp != DUMMY_SP) { + "it uses `Self` as a type parameter in this".into() + } else { + "it cannot use `Self` as a type parameter in a supertrait or `where`-clause" + .into() + } } ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => { format!("associated function `{}` has no `self` parameter", name).into() @@ -87,7 +91,7 @@ impl ObjectSafetyViolation { pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> { Some(match *self { - ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf => { + ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => { return None; } ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => ( @@ -118,7 +122,8 @@ impl ObjectSafetyViolation { // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so // diagnostics use a `note` instead of a `span_label`. match self { - ObjectSafetyViolation::SizedSelf(spans) => spans.clone(), + ObjectSafetyViolation::SupertraitSelf(spans) + | ObjectSafetyViolation::SizedSelf(spans) => spans.clone(), ObjectSafetyViolation::AssocConst(_, span) | ObjectSafetyViolation::Method(_, _, span) if *span != DUMMY_SP => @@ -162,8 +167,9 @@ pub fn astconv_object_safety_violations( ) -> Vec { debug_assert!(tcx.generics_of(trait_def_id).has_self); let violations = traits::supertrait_def_ids(tcx, trait_def_id) - .filter(|&def_id| predicates_reference_self(tcx, def_id, true)) - .map(|_| ObjectSafetyViolation::SupertraitSelf) + .map(|def_id| predicates_reference_self(tcx, def_id, true)) + .filter(|spans| !spans.is_empty()) + .map(|spans| ObjectSafetyViolation::SupertraitSelf(spans)) .collect(); debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", trait_def_id, violations); @@ -266,8 +272,9 @@ fn object_safety_violations_for_trait( let spans = get_sized_bounds(tcx, trait_def_id); violations.push(ObjectSafetyViolation::SizedSelf(spans)); } - if predicates_reference_self(tcx, trait_def_id, false) { - violations.push(ObjectSafetyViolation::SupertraitSelf); + let spans = predicates_reference_self(tcx, trait_def_id, false); + if !spans.is_empty() { + violations.push(ObjectSafetyViolation::SupertraitSelf(spans)); } violations.extend( @@ -337,7 +344,11 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> .unwrap_or_else(SmallVec::new) } -fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool { +fn predicates_reference_self( + tcx: TyCtxt<'_>, + trait_def_id: DefId, + supertraits_only: bool, +) -> SmallVec<[Span; 1]> { let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); let predicates = if supertraits_only { tcx.super_predicates_of(trait_def_id) @@ -349,12 +360,16 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o predicates .predicates .iter() - .map(|(predicate, _)| predicate.subst_supertrait(tcx, &trait_ref)) - .any(|predicate| { + .map(|(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp)) + .filter_map(|(predicate, &sp)| { match predicate { ty::Predicate::Trait(ref data, _) => { // In the case of a trait predicate, we can skip the "self" type. - data.skip_binder().input_types().skip(1).any(has_self_ty) + if data.skip_binder().input_types().skip(1).any(has_self_ty) { + Some(sp) + } else { + None + } } ty::Predicate::Projection(ref data) => { // And similarly for projections. This should be redundant with @@ -369,12 +384,18 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o // // This is ALT2 in issue #56288, see that for discussion of the // possible alternatives. - data.skip_binder() + if data + .skip_binder() .projection_ty .trait_ref(tcx) .input_types() .skip(1) .any(has_self_ty) + { + Some(sp) + } else { + None + } } ty::Predicate::WellFormed(..) | ty::Predicate::ObjectSafe(..) @@ -382,9 +403,10 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o | ty::Predicate::RegionOutlives(..) | ty::Predicate::ClosureKind(..) | ty::Predicate::Subtype(..) - | ty::Predicate::ConstEvaluatable(..) => false, + | ty::Predicate::ConstEvaluatable(..) => None, } }) + .collect() } fn trait_has_sized_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { diff --git a/src/test/ui/issues/issue-26056.stderr b/src/test/ui/issues/issue-26056.stderr index 2744fb91d6fe1..be438ef9ac7ba 100644 --- a/src/test/ui/issues/issue-26056.stderr +++ b/src/test/ui/issues/issue-26056.stderr @@ -1,10 +1,13 @@ error[E0038]: the trait `Map` cannot be made into an object --> $DIR/issue-26056.rs:20:13 | +LL | trait Map: MapLookup<::Key> { + | --- ----------------------------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | as &dyn Map; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Map` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28576.stderr b/src/test/ui/issues/issue-28576.stderr index 5bed9a77d1891..658199003c18d 100644 --- a/src/test/ui/issues/issue-28576.stderr +++ b/src/test/ui/issues/issue-28576.stderr @@ -1,11 +1,16 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-28576.rs:7:12 | +LL | pub trait Bar: Foo { + | --- ------------- + | | | | + | | | ...because it uses `Self` as a type parameter in this + | | ...because it uses `Self` as a type parameter in this + | this trait cannot be made into an object... +LL | fn new(&self, b: & LL | / dyn Bar LL | | | |________________________^ the trait `Bar` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38404.stderr b/src/test/ui/issues/issue-38404.stderr index 613888758cab4..50c5195dc93b0 100644 --- a/src/test/ui/issues/issue-38404.stderr +++ b/src/test/ui/issues/issue-38404.stderr @@ -1,10 +1,12 @@ error[E0038]: the trait `B` cannot be made into an object --> $DIR/issue-38404.rs:3:15 | +LL | trait A: std::ops::Add + Sized {} + | ------------------- ...because it uses `Self` as a type parameter in this +LL | trait B: A {} + | - this trait cannot be made into an object... LL | trait C: A> {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `B` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr index b3ad71e174a97..2bba50e1f41c8 100644 --- a/src/test/ui/issues/issue-38604.stderr +++ b/src/test/ui/issues/issue-38604.stderr @@ -1,18 +1,25 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:14:13 | +LL | trait Foo where u32: Q { + | --- ------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | let _f: Box = | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:15:9 | +LL | trait Foo where u32: Q { + | --- ------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | Box::new(()); | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<()>` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/object-safety/object-safety-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr index 55baf69401b0a..fe9ca5b6fa4b7 100644 --- a/src/test/ui/object-safety/object-safety-issue-22040.stderr +++ b/src/test/ui/object-safety/object-safety-issue-22040.stderr @@ -1,10 +1,13 @@ error[E0038]: the trait `Expr` cannot be made into an object --> $DIR/object-safety-issue-22040.rs:12:23 | +LL | trait Expr: Debug + PartialEq { + | ---- --------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | elements: Vec>, | ^^^^^^^^^^^^^ the trait `Expr` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr index 04f630d5dacb7..ef7f6bacd1233 100644 --- a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -1,10 +1,13 @@ error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-supertrait-mentions-Self.rs:15:31 | +LL | trait Baz : Bar { + | --- --------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^ the trait `Baz` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr index 1f9ffb6a4cfbf..56ecb7256f8cd 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr @@ -3,8 +3,11 @@ error[E0038]: the trait `std::cmp::Eq` cannot be made into an object | LL | let _: &dyn EqAlias = &123; | ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object + | + ::: $SRC_DIR/libcore/cmp.rs:LL:COL | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses +LL | pub trait Eq: PartialEq { + | --------------- the trait cannot be made into an object because it uses `Self` as a type parameter in this error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified --> $DIR/trait-alias-object-fail.rs:9:17 From b9c125af751d05c656aa40a38e51af6a03d5ca0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 13:51:23 -0800 Subject: [PATCH 22/23] Deal with spans showing `std` lib Address #53081 --- src/test/ui/suggestions/imm-ref-trait-object.rs | 5 +++++ src/test/ui/suggestions/imm-ref-trait-object.stderr | 2 +- src/test/ui/traits/trait-alias/trait-alias-object-fail.rs | 5 +++++ .../ui/traits/trait-alias/trait-alias-object-fail.stderr | 4 ++-- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/test/ui/suggestions/imm-ref-trait-object.rs b/src/test/ui/suggestions/imm-ref-trait-object.rs index 288d6c699f59a..241dde9fec1d6 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.rs +++ b/src/test/ui/suggestions/imm-ref-trait-object.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn test(t: &dyn Iterator) -> u64 { t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object } diff --git a/src/test/ui/suggestions/imm-ref-trait-object.stderr b/src/test/ui/suggestions/imm-ref-trait-object.stderr index 37c2053522961..c5fe6ddb8a9bf 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object.stderr @@ -1,5 +1,5 @@ error: the `min` method cannot be invoked on a trait object - --> $DIR/imm-ref-trait-object.rs:2:8 + --> $DIR/imm-ref-trait-object.rs:7:8 | LL | t.min().unwrap() | ^^^ diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs b/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs index d62fd7e59c920..3be8db8663ab7 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #![feature(trait_alias)] trait EqAlias = Eq; diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr index 56ecb7256f8cd..21818097bd6a0 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `std::cmp::Eq` cannot be made into an object - --> $DIR/trait-alias-object-fail.rs:7:13 + --> $DIR/trait-alias-object-fail.rs:12:13 | LL | let _: &dyn EqAlias = &123; | ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object @@ -10,7 +10,7 @@ LL | pub trait Eq: PartialEq { | --------------- the trait cannot be made into an object because it uses `Self` as a type parameter in this error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified - --> $DIR/trait-alias-object-fail.rs:9:17 + --> $DIR/trait-alias-object-fail.rs:14:17 | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); | ^^^^^^^^^^^^^ help: specify the associated type: `IteratorAlias` From 0e584114c6153a3d7ff94349729c46a4735cb838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Feb 2020 10:43:45 -0800 Subject: [PATCH 23/23] Change wording for object unsafe because of assoc const --- src/librustc/traits/object_safety.rs | 8 +++----- .../ui/associated-const/associated-const-in-trait.stderr | 2 +- src/test/ui/associated-item/issue-48027.stderr | 2 +- .../object-safety-associated-consts.curr.stderr | 2 +- ...fety-associated-consts.object_safe_for_dispatch.stderr | 2 +- src/test/ui/traits/trait-item-privacy.stderr | 6 +++--- 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 2745d3205dec0..d0dbfe73c91d5 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -80,12 +80,10 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { format!("method `{}`'s `self` parameter cannot be dispatched on", name).into() } - ObjectSafetyViolation::AssocConst(_, DUMMY_SP) => { - "it cannot contain associated consts".into() - } - ObjectSafetyViolation::AssocConst(name, _) => { - format!("it cannot contain associated consts like `{}`", name).into() + ObjectSafetyViolation::AssocConst(name, DUMMY_SP) => { + format!("it contains associated `const` `{}`", name).into() } + ObjectSafetyViolation::AssocConst(..) => "it contains this associated `const`".into(), } } diff --git a/src/test/ui/associated-const/associated-const-in-trait.stderr b/src/test/ui/associated-const/associated-const-in-trait.stderr index b9101c86d218a..a8a8d01ed78fb 100644 --- a/src/test/ui/associated-const/associated-const-in-trait.stderr +++ b/src/test/ui/associated-const/associated-const-in-trait.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | trait Trait { | ----- this trait cannot be made into an object... LL | const N: usize; - | - ...because it cannot contain associated consts like `N` + | - ...because it contains this associated `const` ... LL | impl dyn Trait { | ^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr index e8442c6c9ac14..62a380732a8bb 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; - | - ...because it cannot contain associated consts like `X` + | - ...because it contains this associated `const` ... LL | impl dyn Bar {} | ^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index e0e0344af7591..890acde35c4f8 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; - | - ...because it cannot contain associated consts like `X` + | - ...because it contains this associated `const` ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index ff0bd17dccce5..e2a95d95a13ed 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; - | - ...because it cannot contain associated consts like `X` + | - ...because it contains this associated `const` ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index e050d6940abc3..072328ab50c70 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -111,15 +111,15 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/trait-item-privacy.rs:101:5 | LL | const A: u8 = 0; - | - ...because it cannot contain associated consts like `A` + | - ...because it contains this associated `const` ... LL | const B: u8 = 0; - | - ...because it cannot contain associated consts like `B` + | - ...because it contains this associated `const` ... LL | pub trait C: A + B { | - this trait cannot be made into an object... LL | const C: u8 = 0; - | - ...because it cannot contain associated consts like `C` + | - ...because it contains this associated `const` ... LL | C::A; | ^^^^ the trait `assoc_const::C` cannot be made into an object