Use structured suggestion for restricting bounds

When a trait bound is not met and restricting a type parameter would
make the restriction hold, use a structured suggestion pointing at an
appropriate place (type param in param list or `where` clause).

Account for opaque parameters where instead of suggesting extending
the `where` clause, we suggest appending the new restriction:
`fn foo(impl Trait + UnmetTrait)`.
This commit is contained in:
Esteban Küber 2019-10-07 14:23:56 -07:00
parent 237d54ff6c
commit 190589f8a7
25 changed files with 335 additions and 68 deletions

View File

@ -715,8 +715,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// these notes will often be of the form
// "the type `T` can't be frobnicated"
// which is somewhat confusing.
err.help(&format!("consider adding a `where {}` bound",
trait_ref.to_predicate()));
self.suggest_restricting_param_bound(
&mut err,
&trait_ref,
obligation.cause.body_id,
);
} else {
if !have_alt_message {
// Can't show anything else useful, try to find similar impls.
@ -960,6 +963,96 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err.emit();
}
fn suggest_restricting_param_bound(
&self,
err: &mut DiagnosticBuilder<'_>,
trait_ref: &ty::PolyTraitRef<'_>,
body_id: hir::HirId,
) {
let node = self.tcx.hir().find(self.tcx.hir().get_parent_item(body_id));
if let ty::Param(param_ty) = &trait_ref.self_ty().kind {
let restrict_msg = "consider further restricting this bound";
let param_name = param_ty.name.as_str();
if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Struct(_, generics), span, ..
})) |
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Enum(_, generics), span, ..
})) |
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Union(_, generics), span, ..
})) |
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, generics, ..), span, ..
})) |
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(_, _, _, generics, ..), span, ..
})) |
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_, _, generics, _), span, ..
})) = &node {
for param in &generics.params {
if param_name == param.name.ident().as_str() {
if param_name.starts_with("impl ") {
err.span_suggestion(
param.span,
restrict_msg,
// `impl CurrentTrait + MissingTrait`
format!("{} + {}", param.name.ident(), trait_ref),
Applicability::MachineApplicable,
);
} else {
if generics.where_clause.predicates.is_empty() &&
param.bounds.is_empty()
{
err.span_suggestion(
param.span,
"consider restricting this bound",
format!("{}", trait_ref.to_predicate()),
Applicability::MachineApplicable,
);
} else if !generics.where_clause.predicates.is_empty() {
err.span_suggestion(
generics.where_clause.span().unwrap().shrink_to_hi(),
&format!(
"consider further restricting type parameter `{}`",
param_ty,
),
format!(", {}", trait_ref.to_predicate()),
Applicability::MachineApplicable,
);
} else {
let sp = param.span.with_hi(span.hi());
let span = self.tcx.sess.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<T: Trait>`.
err.span_suggestion(span, restrict_msg, format!(
"{} + ",
trait_ref.to_predicate(),
), Applicability::MachineApplicable);
} else {
err.span_label(param.span, &format!(
"consider adding a `where {}` bound",
trait_ref.to_predicate(),
));
}
}
}
return;
}
}
}
}
// FIXME: Add special check for `?Sized` so we don't suggest `T: Sized + ?Sized`.
// Fallback in case we didn't find the type argument. Can happen on associated types
// bounds and when `Self` needs to be restricted, like in the ui test
// `associated-types-projection-to-unrelated-trait-in-method-without-default.rs`.
err.help(&format!("consider adding a `where {}` bound", trait_ref.to_predicate()));
}
/// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
/// suggestion to borrow the initializer in order to use have a slice instead.
fn suggest_borrow_on_unsized_slice(

View File

@ -4,10 +4,10 @@ error[E0277]: the trait bound `A: Foo` is not satisfied
LL | const Y: usize;
| --------------- required by `Foo::Y`
...
LL | pub fn test<A: Foo, B: Foo>() {
| -- help: consider further restricting this bound: `A: Foo +`
LL | let _array = [4; <A as Foo>::Y];
| ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
|
= help: consider adding a `where A: Foo` bound
error: aborting due to previous error

View File

@ -4,10 +4,10 @@ error[E0277]: the trait bound `A: Foo` is not satisfied
LL | const Y: usize;
| --------------- required by `Foo::Y`
...
LL | pub fn test<A: Foo, B: Foo>() {
| -- help: consider further restricting this bound: `A: Foo +`
LL | let _array: [u32; <A as Foo>::Y];
| ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
|
= help: consider adding a `where A: Foo` bound
error: aborting due to previous error

View File

@ -1,10 +1,10 @@
error[E0277]: the trait bound `T: Foo<usize>` is not satisfied
--> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:12
|
LL | fn f<T:Foo<isize>>(t: &T) {
| -- help: consider further restricting this bound: `T: Foo<usize> +`
LL | let u: <T as Foo<usize>>::Bar = t.get_bar();
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `T`
|
= help: consider adding a `where T: Foo<usize>` bound
error: aborting due to previous error

View File

@ -1,11 +1,12 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/bad-method-typaram-kind.rs:2:7
|
LL | fn foo<T:'static>() {
| -- help: consider further restricting this bound: `T: std::marker::Send +`
LL | 1.bar::<T>();
| ^^^ `T` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `T`
= help: consider adding a `where T: std::marker::Send` bound
error: aborting due to previous error

View File

@ -4,11 +4,13 @@ error[E0277]: `F` cannot be shared between threads safely
LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
| ---------------- ---- required by this bound in `take_const_owned`
...
LL | fn give_owned<F>(f: F) where F: FnOnce() + Send {
| - help: consider further restricting type parameter `F`: `, F: std::marker::Sync`
LL | take_any(f);
LL | take_const_owned(f);
| ^ `F` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `F`
= help: consider adding a `where F: std::marker::Sync` bound
error: aborting due to previous error

View File

@ -1,23 +1,25 @@
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/dst-object-from-unsized-type.rs:8:23
|
LL | fn test1<T: ?Sized + Foo>(t: &T) {
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
LL | let u: &dyn Foo = t;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound
= note: required for the cast to the object type `dyn Foo`
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/dst-object-from-unsized-type.rs:13:23
|
LL | fn test2<T: ?Sized + Foo>(t: &T) {
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
LL | let v: &dyn Foo = t as &dyn Foo;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound
= note: required for the cast to the object type `dyn Foo`
error[E0277]: the size for values of type `str` cannot be known at compilation time

View File

@ -6,10 +6,11 @@ LL | fn want_bar_for_any_ccx<B>(b: &B)
LL | where B : for<'ccx> Bar<'ccx>
| ------------------- required by this bound in `want_bar_for_any_ccx`
...
LL | where B : Qux
| - help: consider further restricting type parameter `B`: `, for<'ccx> B: Bar<'ccx>`
...
LL | want_bar_for_any_ccx(b);
| ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
|
= help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
error: aborting due to previous error

View File

@ -1,6 +1,9 @@
error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
--> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
|
LL | where F : Foo<'x>
| - help: consider further restricting type parameter `F`: `, for<'tcx> F: Foo<'tcx>`
...
LL | want_foo_for_any_tcx(f);
| ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
...
@ -8,12 +11,13 @@ LL | fn want_foo_for_any_tcx<F>(f: &F)
| --------------------
LL | where F : for<'tcx> Foo<'tcx>
| ------------------- required by this bound in `want_foo_for_any_tcx`
|
= help: consider adding a `where for<'tcx> F: Foo<'tcx>` bound
error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
--> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
|
LL | where B : Bar<'x>
| - help: consider further restricting type parameter `B`: `, for<'ccx> B: Bar<'ccx>`
...
LL | want_bar_for_any_ccx(b);
| ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
...
@ -21,8 +25,6 @@ LL | fn want_bar_for_any_ccx<B>(b: &B)
| --------------------
LL | where B : for<'ccx> Bar<'ccx>
| ------------------- required by this bound in `want_bar_for_any_ccx`
|
= help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
error: aborting due to 2 previous errors

View File

@ -1,42 +1,50 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/kindck-impl-type-params.rs:18:13
|
LL | fn f<T>(val: T) {
| - help: consider restricting this bound: `T: std::marker::Send`
LL | let t: S<T> = S(marker::PhantomData);
LL | let a = &t as &dyn Gettable<T>;
| ^^ `T` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `T`
= help: consider adding a `where T: std::marker::Send` bound
= note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
= note: required for the cast to the object type `dyn Gettable<T>`
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> $DIR/kindck-impl-type-params.rs:18:13
|
LL | fn f<T>(val: T) {
| - help: consider restricting this bound: `T: std::marker::Copy`
LL | let t: S<T> = S(marker::PhantomData);
LL | let a = &t as &dyn Gettable<T>;
| ^^ the trait `std::marker::Copy` is not implemented for `T`
|
= help: consider adding a `where T: std::marker::Copy` bound
= note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
= note: required for the cast to the object type `dyn Gettable<T>`
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/kindck-impl-type-params.rs:25:31
|
LL | fn g<T>(val: T) {
| - help: consider restricting this bound: `T: std::marker::Send`
LL | let t: S<T> = S(marker::PhantomData);
LL | let a: &dyn Gettable<T> = &t;
| ^^ `T` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `T`
= help: consider adding a `where T: std::marker::Send` bound
= note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
= note: required for the cast to the object type `dyn Gettable<T>`
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> $DIR/kindck-impl-type-params.rs:25:31
|
LL | fn g<T>(val: T) {
| - help: consider restricting this bound: `T: std::marker::Copy`
LL | let t: S<T> = S(marker::PhantomData);
LL | let a: &dyn Gettable<T> = &t;
| ^^ the trait `std::marker::Copy` is not implemented for `T`
|
= help: consider adding a `where T: std::marker::Copy` bound
= note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
= note: required for the cast to the object type `dyn Gettable<T>`

View File

@ -3,12 +3,13 @@ error[E0277]: `T` cannot be shared between threads safely
|
LL | fn is_zen<T: Zen>(_: T) {}
| ------ --- required by this bound in `is_zen`
...
LL |
LL | fn not_sync<T>(x: Guard<T>) {
| - help: consider restricting this bound: `T: std::marker::Sync`
LL | is_zen(x)
| ^ `T` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `T`
= help: consider adding a `where T: std::marker::Sync` bound
= note: required because of the requirements on the impl of `Zen` for `&T`
= note: required because it appears within the type `std::marker::PhantomData<&T>`
= note: required because it appears within the type `Guard<'_, T>`
@ -19,11 +20,12 @@ error[E0277]: `T` cannot be shared between threads safely
LL | fn is_zen<T: Zen>(_: T) {}
| ------ --- required by this bound in `is_zen`
...
LL | fn nested_not_sync<T>(x: Nested<Guard<T>>) {
| - help: consider restricting this bound: `T: std::marker::Sync`
LL | is_zen(x)
| ^ `T` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `T`
= help: consider adding a `where T: std::marker::Sync` bound
= note: required because of the requirements on the impl of `Zen` for `&T`
= note: required because it appears within the type `std::marker::PhantomData<&T>`
= note: required because it appears within the type `Guard<'_, T>`

View File

@ -0,0 +1,31 @@
fn is_send<T: Send>(val: T) {}
fn use_impl_sync(val: impl Sync) {
is_send(val); //~ ERROR `impl Sync` cannot be sent between threads safely
}
fn use_where<S>(val: S) where S: Sync {
is_send(val); //~ ERROR `S` cannot be sent between threads safely
}
fn use_bound<S: Sync>(val: S) {
is_send(val); //~ ERROR `S` cannot be sent between threads safely
}
fn use_bound_2<
S // Make sure we can synthezise a correct suggestion span for this case
:
Sync
>(val: S) {
is_send(val); //~ ERROR `S` cannot be sent between threads safely
}
fn use_bound_and_where<S: Sync>(val: S) where S: std::fmt::Debug {
is_send(val); //~ ERROR `S` cannot be sent between threads safely
}
fn use_unbound<S>(val: S) {
is_send(val); //~ ERROR `S` cannot be sent between threads safely
}
fn main() {}

View File

@ -0,0 +1,83 @@
error[E0277]: `impl Sync` cannot be sent between threads safely
--> $DIR/restrict-type-argument.rs:4:13
|
LL | fn is_send<T: Send>(val: T) {}
| ------- ---- required by this bound in `is_send`
LL |
LL | fn use_impl_sync(val: impl Sync) {
| --------- help: consider further restricting this bound: `impl Sync + std::marker::Send`
LL | is_send(val);
| ^^^ `impl Sync` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `impl Sync`
error[E0277]: `S` cannot be sent between threads safely
--> $DIR/restrict-type-argument.rs:8:13
|
LL | fn is_send<T: Send>(val: T) {}
| ------- ---- required by this bound in `is_send`
...
LL | fn use_where<S>(val: S) where S: Sync {
| - help: consider further restricting type parameter `S`: `, S: std::marker::Send`
LL | is_send(val);
| ^^^ `S` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `S`
error[E0277]: `S` cannot be sent between threads safely
--> $DIR/restrict-type-argument.rs:12:13
|
LL | fn is_send<T: Send>(val: T) {}
| ------- ---- required by this bound in `is_send`
...
LL | fn use_bound<S: Sync>(val: S) {
| -- help: consider further restricting this bound: `S: std::marker::Send +`
LL | is_send(val);
| ^^^ `S` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `S`
error[E0277]: `S` cannot be sent between threads safely
--> $DIR/restrict-type-argument.rs:20:13
|
LL | fn is_send<T: Send>(val: T) {}
| ------- ---- required by this bound in `is_send`
...
LL | / S // Make sure we can synthezise a correct suggestion span for this case
LL | | :
| |_____- help: consider further restricting this bound: `S: std::marker::Send +`
...
LL | is_send(val);
| ^^^ `S` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `S`
error[E0277]: `S` cannot be sent between threads safely
--> $DIR/restrict-type-argument.rs:24:13
|
LL | fn is_send<T: Send>(val: T) {}
| ------- ---- required by this bound in `is_send`
...
LL | fn use_bound_and_where<S: Sync>(val: S) where S: std::fmt::Debug {
| - help: consider further restricting type parameter `S`: `, S: std::marker::Send`
LL | is_send(val);
| ^^^ `S` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `S`
error[E0277]: `S` cannot be sent between threads safely
--> $DIR/restrict-type-argument.rs:28:13
|
LL | fn is_send<T: Send>(val: T) {}
| ------- ---- required by this bound in `is_send`
...
LL | fn use_unbound<S>(val: S) {
| - help: consider restricting this bound: `S: std::marker::Send`
LL | is_send(val);
| ^^^ `S` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `S`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,6 +1,9 @@
error[E0277]: the size for values of type `U` cannot be known at compilation time
--> $DIR/trait-suggest-where-clause.rs:9:20
|
LL | fn check<T: Iterator, U: ?Sized>() {
| -- help: consider further restricting this bound: `U: std::marker::Sized +`
LL | // suggest a where-clause, if needed
LL | mem::size_of::<U>();
| ^ doesn't have a size known at compile-time
|
@ -11,11 +14,13 @@ LL | pub const fn size_of<T>() -> usize {
|
= help: the trait `std::marker::Sized` is not implemented for `U`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where U: std::marker::Sized` bound
error[E0277]: the size for values of type `U` cannot be known at compilation time
--> $DIR/trait-suggest-where-clause.rs:12:5
|
LL | fn check<T: Iterator, U: ?Sized>() {
| -- help: consider further restricting this bound: `U: std::marker::Sized +`
...
LL | mem::size_of::<Misc<U>>();
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
@ -26,7 +31,6 @@ LL | pub const fn size_of<T>() -> usize {
|
= help: within `Misc<U>`, the trait `std::marker::Sized` is not implemented for `U`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where U: std::marker::Sized` bound
= note: required because it appears within the type `Misc<U>`
error[E0277]: the trait bound `u64: std::convert::From<T>` is not satisfied

View File

@ -7,10 +7,10 @@ LL | c.same_as(22)
error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
--> $DIR/traits-repeated-supertrait-ambig.rs:30:7
|
LL | fn with_trait<C:CompareToInts>(c: &C) -> bool {
| -- help: consider further restricting this bound: `C: CompareTo<i32> +`
LL | c.same_as(22)
| ^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
|
= help: consider adding a `where C: CompareTo<i32>` bound
error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
--> $DIR/traits-repeated-supertrait-ambig.rs:34:5
@ -27,10 +27,10 @@ error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
LL | fn same_as(&self, t: T) -> bool;
| -------------------------------- required by `CompareTo::same_as`
...
LL | fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
| -- help: consider further restricting this bound: `C: CompareTo<i32> +`
LL | CompareTo::same_as(c, 22)
| ^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
|
= help: consider adding a `where C: CompareTo<i32>` bound
error[E0277]: the trait bound `i64: CompareTo<i32>` is not satisfied
--> $DIR/traits-repeated-supertrait-ambig.rs:42:23

View File

@ -9,8 +9,10 @@ error[E0277]: the trait bound `T: Trait` is not satisfied
|
LL | type Underconstrained<T: Trait> = impl 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
...
LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
| - help: consider restricting this bound: `T: Trait`
|
= help: consider adding a `where T: Trait` bound
= note: the return type of a function must have a statically known size
error: aborting due to 2 previous errors

View File

@ -15,9 +15,11 @@ error[E0277]: `U` doesn't implement `std::fmt::Debug`
|
LL | type Underconstrained<T: std::fmt::Debug> = impl 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
...
LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
| - help: consider restricting this bound: `U: std::fmt::Debug`
|
= help: the trait `std::fmt::Debug` is not implemented for `U`
= help: consider adding a `where U: std::fmt::Debug` bound
= note: the return type of a function must have a statically known size
error[E0277]: `V` doesn't implement `std::fmt::Debug`
@ -25,9 +27,11 @@ error[E0277]: `V` doesn't implement `std::fmt::Debug`
|
LL | type Underconstrained2<T: std::fmt::Debug> = impl 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
...
LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
| - help: consider restricting this bound: `V: std::fmt::Debug`
|
= help: the trait `std::fmt::Debug` is not implemented for `V`
= help: consider adding a `where V: std::fmt::Debug` bound
= note: the return type of a function must have a statically known size
error: aborting due to 4 previous errors

View File

@ -1,6 +1,8 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/typeck-default-trait-impl-send-param.rs:5:15
|
LL | fn foo<T>() {
| - help: consider restricting this bound: `T: std::marker::Send`
LL | is_send::<T>()
| ^ `T` cannot be sent between threads safely
...
@ -8,7 +10,6 @@ LL | fn is_send<T:Send>() {
| ------- ---- required by this bound in `is_send`
|
= help: the trait `std::marker::Send` is not implemented for `T`
= help: consider adding a `where T: std::marker::Send` bound
error: aborting due to previous error

View File

@ -4,11 +4,12 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
LL | fn bar<T: Sized>() { }
| --- - required by this bound in `bar`
LL | fn foo<T: ?Sized>() { bar::<T>() }
| ^ 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 +`
|
= help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound
error: aborting due to previous error

View File

@ -5,11 +5,12 @@ LL | enum Foo<U> { FooSome(U), FooNone }
| ----------- required by `Foo`
LL | fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
| ^^^^^^ 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 +`
|
= help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound
error: aborting due to previous error

View File

@ -5,11 +5,12 @@ LL | struct Foo<T> { data: T }
| ------------- required by `Foo`
LL | fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
| ^^^^^^ 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 +`
|
= help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/unsized-struct.rs:13:24
@ -18,11 +19,12 @@ LL | fn is_sized<T:Sized>() { }
| -------- - required by this bound in `is_sized`
...
LL | fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
| ^^^^^^^^^^^^^^^^^^ 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 +`
|
= help: within `Bar<T>`, the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound
= note: required because it appears within the type `Bar<T>`
error: aborting due to 2 previous errors

View File

@ -1,6 +1,8 @@
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized3.rs:7:13
|
LL | fn f1<X: ?Sized>(x: &X) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | f2::<X>(x);
| ^ doesn't have a size known at compile-time
...
@ -9,11 +11,12 @@ LL | fn f2<X>(x: &X) {
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized3.rs:18:13
|
LL | fn f3<X: ?Sized + T>(x: &X) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | f4::<X>(x);
| ^ doesn't have a size known at compile-time
...
@ -22,7 +25,6 @@ LL | fn f4<X: T>(x: &X) {
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized3.rs:33:8
@ -30,35 +32,38 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
LL | fn f5<Y>(x: &Y) {}
| -- - required by this bound in `f5`
...
LL | fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | f5(x1);
| ^^ doesn't have a size known at compile-time
|
= help: within `S<X>`, the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: required because it appears within the type `S<X>`
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized3.rs:40:8
|
LL | fn f9<X: ?Sized>(x1: Box<S<X>>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | f5(&(*x1, 34));
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `S<X>`, the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: required because it appears within the type `S<X>`
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized3.rs:45:9
|
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | f5(&(32, *x1));
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `({integer}, S<X>)`, the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: required because it appears within the type `S<X>`
= note: required because it appears within the type `({integer}, S<X>)`
= note: tuples must have a statically known size to be initialized
@ -69,12 +74,13 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
LL | fn f5<Y>(x: &Y) {}
| -- - required by this bound in `f5`
...
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | f5(&(32, *x1));
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `({integer}, S<X>)`, the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: required because it appears within the type `S<X>`
= note: required because it appears within the type `({integer}, S<X>)`

View File

@ -1,129 +1,148 @@
error[E0277]: the size for values of type `Y` cannot be known at compilation time
--> $DIR/unsized6.rs:9:9
|
LL | fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
| -- help: consider further restricting this bound: `Y: std::marker::Sized +`
...
LL | let y: Y;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Y`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where Y: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:7:12
|
LL | fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
| -- help: consider further restricting this bound: `X: 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
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `Z` cannot be known at compilation time
--> $DIR/unsized6.rs:11:12
|
LL | fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
| -- help: consider further restricting this bound: `Z: std::marker::Sized +`
...
LL | let y: (isize, (Z, usize));
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Z`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where Z: std::marker::Sized` bound
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:15:9
|
LL | fn f2<X: ?Sized, Y: ?Sized>(x: &X) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | let y: X;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `Y` cannot be known at compilation time
--> $DIR/unsized6.rs:17:12
|
LL | fn f2<X: ?Sized, Y: ?Sized>(x: &X) {
| -- help: consider further restricting this bound: `Y: std::marker::Sized +`
...
LL | let y: (isize, (Y, isize));
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Y`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where Y: std::marker::Sized` bound
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:22:9
|
LL | fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | let y: X = *x1;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:24:9
|
LL | fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
...
LL | let y = *x2;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:26:10
|
LL | fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
...
LL | let (y, z) = (*x3, 4);
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:30:9
|
LL | fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
LL | let y: X = *x1;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:32:9
|
LL | fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
...
LL | let y = *x2;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:34:10
|
LL | fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
...
LL | let (y, z) = (*x3, 4);
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
@ -131,11 +150,12 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
--> $DIR/unsized6.rs:38:18
|
LL | fn g1<X: ?Sized>(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 +`
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
@ -143,11 +163,12 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
--> $DIR/unsized6.rs:40:22
|
LL | fn g2<X: ?Sized + T>(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 +`
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where X: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature

View File

@ -4,10 +4,10 @@ error[E0277]: the trait bound `T: MyHash` is not satisfied
LL | pub struct MySet<T:MyHash> {
| -------------------------- required by `MySet`
...
LL | impl<T> Foo for T {
| - help: consider restricting this bound: `T: MyHash`
LL | type Bar = MySet<T>;
| ^^^^^^^^^^^^^^^^^^^^ the trait `MyHash` is not implemented for `T`
|
= help: consider adding a `where T: MyHash` bound
error: aborting due to previous error

View File

@ -4,11 +4,11 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
LL | trait ExtraCopy<T:Copy> { }
| ----------------------- required by `ExtraCopy`
...
LL | impl<T,U> Foo<T,U> {
| - help: consider restricting this bound: `U: std::marker::Copy`
LL | / fn foo(self) where T: ExtraCopy<U>
LL | | {}
| |______^ the trait `std::marker::Copy` is not implemented for `U`
|
= help: consider adding a `where U: std::marker::Copy` bound
error: aborting due to previous error