Tweak output for bare dyn Trait in arguments

Fix #35825.
This commit is contained in:
Esteban Küber 2022-12-14 18:51:55 -08:00
parent ba64ba8b0d
commit 124f19485d
10 changed files with 85 additions and 23 deletions

View File

@ -1618,7 +1618,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_obj = if has_dyn { &snippet[4..] } else { &snippet }; let trait_obj = if has_dyn { &snippet[4..] } else { &snippet };
if only_never_return { if only_never_return {
// No return paths, probably using `panic!()` or similar. // No return paths, probably using `panic!()` or similar.
// Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, `-> Box<dyn Trait>`. // Suggest `-> impl Trait`, and if `Trait` is object safe, `-> Box<dyn Trait>`.
suggest_trait_object_return_type_alternatives( suggest_trait_object_return_type_alternatives(
err, err,
ret_ty.span, ret_ty.span,
@ -2540,6 +2540,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} }
ObligationCauseCode::SizedArgumentType(sp) => { ObligationCauseCode::SizedArgumentType(sp) => {
if let Some(span) = sp { if let Some(span) = sp {
if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
&& let ty::Clause::Trait(trait_pred) = clause
&& let ty::Dynamic(..) = trait_pred.self_ty().kind()
{
let span = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
&& snippet.starts_with("dyn ")
{
let pos = snippet.len() - snippet[3..].trim_start().len();
span.with_hi(span.lo() + BytePos(pos as u32))
} else {
span.shrink_to_lo()
};
err.span_suggestion_verbose(
span,
"you can use `impl Trait` as the argument type",
"impl ".to_string(),
Applicability::MaybeIncorrect,
);
}
err.span_suggestion_verbose( err.span_suggestion_verbose(
span.shrink_to_lo(), span.shrink_to_lo(),
"function arguments must have a statically known size, borrowed types \ "function arguments must have a statically known size, borrowed types \
@ -3580,13 +3599,6 @@ fn suggest_trait_object_return_type_alternatives(
trait_obj: &str, trait_obj: &str,
is_object_safe: bool, is_object_safe: bool,
) { ) {
err.span_suggestion(
ret_ty,
"use some type `T` that is `T: Sized` as the return type if all return paths have the \
same type",
"T",
Applicability::MaybeIncorrect,
);
err.span_suggestion( err.span_suggestion(
ret_ty, ret_ty,
&format!( &format!(

View File

@ -1,5 +1,5 @@
#![allow(unused, bare_trait_objects)]
#[repr(align(256))] #[repr(align(256))]
#[allow(dead_code)]
struct A { struct A {
v: u8, v: u8,
} }
@ -14,13 +14,17 @@ impl Foo for A {
} }
} }
fn foo(x: dyn Foo) { fn foo(x: dyn Foo) { //~ ERROR [E0277]
//~^ ERROR [E0277]
x.foo() x.foo()
} }
fn bar(x: Foo) { //~ ERROR [E0277]
x.foo()
}
fn qux(_: [()]) {} //~ ERROR [E0277]
fn main() { fn main() {
let x: Box<dyn Foo> = Box::new(A { v: 22 }); let x: Box<dyn Foo> = Box::new(A { v: 22 });
foo(*x); foo(*x); //~ ERROR [E0277]
//~^ ERROR [E0277]
} }

View File

@ -6,13 +6,47 @@ LL | fn foo(x: dyn Foo) {
| |
= help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature
help: you can use `impl Trait` as the argument type
|
LL | fn foo(x: impl Foo) {
| ~~~~
help: function arguments must have a statically known size, borrowed types always have a known size help: function arguments must have a statically known size, borrowed types always have a known size
| |
LL | fn foo(x: &dyn Foo) { LL | fn foo(x: &dyn Foo) {
| + | +
error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
--> $DIR/feature-gate-unsized_fn_params.rs:24:9 --> $DIR/feature-gate-unsized_fn_params.rs:21:8
|
LL | fn bar(x: Foo) {
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
= help: unsized fn params are gated as an unstable feature
help: you can use `impl Trait` as the argument type
|
LL | fn bar(x: impl Foo) {
| ++++
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | fn bar(x: &Foo) {
| +
error[E0277]: the size for values of type `[()]` cannot be known at compilation time
--> $DIR/feature-gate-unsized_fn_params.rs:25:8
|
LL | fn qux(_: [()]) {}
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[()]`
= help: unsized fn params are gated as an unstable feature
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | fn qux(_: &[()]) {}
| +
error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
--> $DIR/feature-gate-unsized_fn_params.rs:29:9
| |
LL | foo(*x); LL | foo(*x);
| ^^ doesn't have a size known at compile-time | ^^ doesn't have a size known at compile-time
@ -21,6 +55,6 @@ LL | foo(*x);
= note: all function arguments must have a statically known size = note: all function arguments must have a statically known size
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature
error: aborting due to 2 previous errors error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -6,6 +6,10 @@ LL | fn f(f: dyn FnOnce()) {}
| |
= help: the trait `Sized` is not implemented for `(dyn FnOnce() + 'static)` = help: the trait `Sized` is not implemented for `(dyn FnOnce() + 'static)`
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature
help: you can use `impl Trait` as the argument type
|
LL | fn f(f: impl FnOnce()) {}
| ~~~~
help: function arguments must have a statically known size, borrowed types always have a known size help: function arguments must have a statically known size, borrowed types always have a known size
| |
LL | fn f(f: &dyn FnOnce()) {} LL | fn f(f: &dyn FnOnce()) {}

View File

@ -70,10 +70,6 @@ error[E0746]: return type cannot have an unboxed trait object
LL | fn bak() -> dyn Trait { unimplemented!() } LL | fn bak() -> dyn Trait { unimplemented!() }
| ^^^^^^^^^ doesn't have a size known at compile-time | ^^^^^^^^^ doesn't have a size known at compile-time
| |
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
|
LL | fn bak() -> T { unimplemented!() }
| ~
help: use `impl Trait` as the return type if all return paths have the same type but you want to expose only the trait in the signature help: use `impl Trait` as the return type if all return paths have the same type but you want to expose only the trait in the signature
| |
LL | fn bak() -> impl Trait { unimplemented!() } LL | fn bak() -> impl Trait { unimplemented!() }

View File

@ -4,10 +4,6 @@ error[E0746]: return type cannot have an unboxed trait object
LL | dyn AbstractRenderer LL | dyn AbstractRenderer
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| |
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
|
LL | T
|
help: use `impl AbstractRenderer` as the return type if all return paths have the same type but you want to expose only the trait in the signature help: use `impl AbstractRenderer` as the return type if all return paths have the same type but you want to expose only the trait in the signature
| |
LL | impl AbstractRenderer LL | impl AbstractRenderer

View File

@ -23,6 +23,10 @@ LL | pub fn f(_: dyn ToString) {}
| |
= help: the trait `Sized` is not implemented for `(dyn ToString + 'static)` = help: the trait `Sized` is not implemented for `(dyn ToString + 'static)`
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature
help: you can use `impl Trait` as the argument type
|
LL | pub fn f(_: impl ToString) {}
| ~~~~
help: function arguments must have a statically known size, borrowed types always have a known size help: function arguments must have a statically known size, borrowed types always have a known size
| |
LL | pub fn f(_: &dyn ToString) {} LL | pub fn f(_: &dyn ToString) {}

View File

@ -6,6 +6,10 @@ LL | r: dyn A + 'static
| |
= help: the trait `Sized` is not implemented for `(dyn A + 'static)` = help: the trait `Sized` is not implemented for `(dyn A + 'static)`
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature
help: you can use `impl Trait` as the argument type
|
LL | r: impl A + 'static
| ~~~~
help: function arguments must have a statically known size, borrowed types always have a known size help: function arguments must have a statically known size, borrowed types always have a known size
| |
LL | r: &dyn A + 'static LL | r: &dyn A + 'static

View File

@ -6,6 +6,10 @@ LL | fn foo(_x: K) {}
| |
= help: the trait `Sized` is not implemented for `(dyn I + 'static)` = help: the trait `Sized` is not implemented for `(dyn I + 'static)`
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature
help: you can use `impl Trait` as the argument type
|
LL | fn foo(_x: impl K) {}
| ++++
help: function arguments must have a statically known size, borrowed types always have a known size help: function arguments must have a statically known size, borrowed types always have a known size
| |
LL | fn foo(_x: &K) {} LL | fn foo(_x: &K) {}

View File

@ -20,6 +20,10 @@ LL | fn foo(_x: Foo + Send) {
| |
= help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)` = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)`
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature
help: you can use `impl Trait` as the argument type
|
LL | fn foo(_x: impl Foo + Send) {
| ++++
help: function arguments must have a statically known size, borrowed types always have a known size help: function arguments must have a statically known size, borrowed types always have a known size
| |
LL | fn foo(_x: &Foo + Send) { LL | fn foo(_x: &Foo + Send) {