Skip to content

Commit

Permalink
Tweak output for bare dyn Trait in arguments
Browse files Browse the repository at this point in the history
Fix #35825.
  • Loading branch information
estebank committed Dec 15, 2022
1 parent ba64ba8 commit 124f194
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1618,7 +1618,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_obj = if has_dyn { &snippet[4..] } else { &snippet };
if only_never_return {
// 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(
err,
ret_ty.span,
Expand Down Expand Up @@ -2540,6 +2540,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
ObligationCauseCode::SizedArgumentType(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(
span.shrink_to_lo(),
"function arguments must have a statically known size, borrowed types \
Expand Down Expand Up @@ -3580,13 +3599,6 @@ fn suggest_trait_object_return_type_alternatives(
trait_obj: &str,
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(
ret_ty,
&format!(
Expand Down
14 changes: 9 additions & 5 deletions src/test/ui/feature-gates/feature-gate-unsized_fn_params.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(unused, bare_trait_objects)]
#[repr(align(256))]
#[allow(dead_code)]
struct A {
v: u8,
}
Expand All @@ -14,13 +14,17 @@ impl Foo for A {
}
}

fn foo(x: dyn Foo) {
//~^ ERROR [E0277]
fn foo(x: dyn Foo) { //~ ERROR [E0277]
x.foo()
}

fn bar(x: Foo) { //~ ERROR [E0277]
x.foo()
}

fn qux(_: [()]) {} //~ ERROR [E0277]

fn main() {
let x: Box<dyn Foo> = Box::new(A { v: 22 });
foo(*x);
//~^ ERROR [E0277]
foo(*x); //~ ERROR [E0277]
}
38 changes: 36 additions & 2 deletions src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,47 @@ LL | fn foo(x: dyn Foo) {
|
= 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 foo(x: impl Foo) {
| ~~~~
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | fn foo(x: &dyn Foo) {
| +

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);
| ^^ doesn't have a size known at compile-time
Expand All @@ -21,6 +55,6 @@ LL | foo(*x);
= note: all function arguments must have a statically known size
= 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`.
4 changes: 4 additions & 0 deletions src/test/ui/feature-gates/feature-gate-unsized_locals.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ LL | fn f(f: dyn FnOnce()) {}
|
= help: the trait `Sized` is not implemented for `(dyn FnOnce() + 'static)`
= 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
|
LL | fn f(f: &dyn FnOnce()) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@ error[E0746]: return type cannot have an unboxed trait object
LL | fn bak() -> dyn Trait { unimplemented!() }
| ^^^^^^^^^ 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
|
LL | fn bak() -> impl Trait { unimplemented!() }
Expand Down
4 changes: 0 additions & 4 deletions src/test/ui/issues/issue-18107.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ error[E0746]: return type cannot have an unboxed trait object
LL | dyn AbstractRenderer
| ^^^^^^^^^^^^^^^^^^^^ 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
|
LL | impl AbstractRenderer
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/issues/issue-42312.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ LL | pub fn f(_: dyn ToString) {}
|
= help: the trait `Sized` is not implemented for `(dyn ToString + 'static)`
= 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
|
LL | pub fn f(_: &dyn ToString) {}
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/issues/issue-5883.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ LL | r: 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: 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
|
LL | r: &dyn A + 'static
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/resolve/issue-5035-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ LL | fn foo(_x: K) {}
|
= help: the trait `Sized` is not implemented for `(dyn I + 'static)`
= 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
|
LL | fn foo(_x: &K) {}
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/traits/bound/not-on-bare-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ LL | fn foo(_x: Foo + Send) {
|
= help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)`
= 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
|
LL | fn foo(_x: &Foo + Send) {
Expand Down

0 comments on commit 124f194

Please sign in to comment.