Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak output for bare dyn Trait in arguments #105727

Merged
merged 1 commit into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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