Skip to content

Commit 124f194

Browse files
committed
Tweak output for bare dyn Trait in arguments
Fix #35825.
1 parent ba64ba8 commit 124f194

File tree

10 files changed

+85
-23
lines changed

10 files changed

+85
-23
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16181618
let trait_obj = if has_dyn { &snippet[4..] } else { &snippet };
16191619
if only_never_return {
16201620
// No return paths, probably using `panic!()` or similar.
1621-
// Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, `-> Box<dyn Trait>`.
1621+
// Suggest `-> impl Trait`, and if `Trait` is object safe, `-> Box<dyn Trait>`.
16221622
suggest_trait_object_return_type_alternatives(
16231623
err,
16241624
ret_ty.span,
@@ -2540,6 +2540,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
25402540
}
25412541
ObligationCauseCode::SizedArgumentType(sp) => {
25422542
if let Some(span) = sp {
2543+
if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
2544+
&& let ty::Clause::Trait(trait_pred) = clause
2545+
&& let ty::Dynamic(..) = trait_pred.self_ty().kind()
2546+
{
2547+
let span = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
2548+
&& snippet.starts_with("dyn ")
2549+
{
2550+
let pos = snippet.len() - snippet[3..].trim_start().len();
2551+
span.with_hi(span.lo() + BytePos(pos as u32))
2552+
} else {
2553+
span.shrink_to_lo()
2554+
};
2555+
err.span_suggestion_verbose(
2556+
span,
2557+
"you can use `impl Trait` as the argument type",
2558+
"impl ".to_string(),
2559+
Applicability::MaybeIncorrect,
2560+
);
2561+
}
25432562
err.span_suggestion_verbose(
25442563
span.shrink_to_lo(),
25452564
"function arguments must have a statically known size, borrowed types \
@@ -3580,13 +3599,6 @@ fn suggest_trait_object_return_type_alternatives(
35803599
trait_obj: &str,
35813600
is_object_safe: bool,
35823601
) {
3583-
err.span_suggestion(
3584-
ret_ty,
3585-
"use some type `T` that is `T: Sized` as the return type if all return paths have the \
3586-
same type",
3587-
"T",
3588-
Applicability::MaybeIncorrect,
3589-
);
35903602
err.span_suggestion(
35913603
ret_ty,
35923604
&format!(

src/test/ui/feature-gates/feature-gate-unsized_fn_params.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
#![allow(unused, bare_trait_objects)]
12
#[repr(align(256))]
2-
#[allow(dead_code)]
33
struct A {
44
v: u8,
55
}
@@ -14,13 +14,17 @@ impl Foo for A {
1414
}
1515
}
1616

17-
fn foo(x: dyn Foo) {
18-
//~^ ERROR [E0277]
17+
fn foo(x: dyn Foo) { //~ ERROR [E0277]
1918
x.foo()
2019
}
2120

21+
fn bar(x: Foo) { //~ ERROR [E0277]
22+
x.foo()
23+
}
24+
25+
fn qux(_: [()]) {} //~ ERROR [E0277]
26+
2227
fn main() {
2328
let x: Box<dyn Foo> = Box::new(A { v: 22 });
24-
foo(*x);
25-
//~^ ERROR [E0277]
29+
foo(*x); //~ ERROR [E0277]
2630
}

src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr

+36-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,47 @@ LL | fn foo(x: dyn Foo) {
66
|
77
= help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
88
= help: unsized fn params are gated as an unstable feature
9+
help: you can use `impl Trait` as the argument type
10+
|
11+
LL | fn foo(x: impl Foo) {
12+
| ~~~~
913
help: function arguments must have a statically known size, borrowed types always have a known size
1014
|
1115
LL | fn foo(x: &dyn Foo) {
1216
| +
1317

1418
error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
15-
--> $DIR/feature-gate-unsized_fn_params.rs:24:9
19+
--> $DIR/feature-gate-unsized_fn_params.rs:21:8
20+
|
21+
LL | fn bar(x: Foo) {
22+
| ^ doesn't have a size known at compile-time
23+
|
24+
= help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
25+
= help: unsized fn params are gated as an unstable feature
26+
help: you can use `impl Trait` as the argument type
27+
|
28+
LL | fn bar(x: impl Foo) {
29+
| ++++
30+
help: function arguments must have a statically known size, borrowed types always have a known size
31+
|
32+
LL | fn bar(x: &Foo) {
33+
| +
34+
35+
error[E0277]: the size for values of type `[()]` cannot be known at compilation time
36+
--> $DIR/feature-gate-unsized_fn_params.rs:25:8
37+
|
38+
LL | fn qux(_: [()]) {}
39+
| ^ doesn't have a size known at compile-time
40+
|
41+
= help: the trait `Sized` is not implemented for `[()]`
42+
= help: unsized fn params are gated as an unstable feature
43+
help: function arguments must have a statically known size, borrowed types always have a known size
44+
|
45+
LL | fn qux(_: &[()]) {}
46+
| +
47+
48+
error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
49+
--> $DIR/feature-gate-unsized_fn_params.rs:29:9
1650
|
1751
LL | foo(*x);
1852
| ^^ doesn't have a size known at compile-time
@@ -21,6 +55,6 @@ LL | foo(*x);
2155
= note: all function arguments must have a statically known size
2256
= help: unsized fn params are gated as an unstable feature
2357

24-
error: aborting due to 2 previous errors
58+
error: aborting due to 4 previous errors
2559

2660
For more information about this error, try `rustc --explain E0277`.

src/test/ui/feature-gates/feature-gate-unsized_locals.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ LL | fn f(f: dyn FnOnce()) {}
66
|
77
= help: the trait `Sized` is not implemented for `(dyn FnOnce() + 'static)`
88
= help: unsized fn params are gated as an unstable feature
9+
help: you can use `impl Trait` as the argument type
10+
|
11+
LL | fn f(f: impl FnOnce()) {}
12+
| ~~~~
913
help: function arguments must have a statically known size, borrowed types always have a known size
1014
|
1115
LL | fn f(f: &dyn FnOnce()) {}

src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ error[E0746]: return type cannot have an unboxed trait object
7070
LL | fn bak() -> dyn Trait { unimplemented!() }
7171
| ^^^^^^^^^ doesn't have a size known at compile-time
7272
|
73-
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
74-
|
75-
LL | fn bak() -> T { unimplemented!() }
76-
| ~
7773
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
7874
|
7975
LL | fn bak() -> impl Trait { unimplemented!() }

src/test/ui/issues/issue-18107.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ error[E0746]: return type cannot have an unboxed trait object
44
LL | dyn AbstractRenderer
55
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
7-
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
8-
|
9-
LL | T
10-
|
117
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
128
|
139
LL | impl AbstractRenderer

src/test/ui/issues/issue-42312.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ LL | pub fn f(_: dyn ToString) {}
2323
|
2424
= help: the trait `Sized` is not implemented for `(dyn ToString + 'static)`
2525
= help: unsized fn params are gated as an unstable feature
26+
help: you can use `impl Trait` as the argument type
27+
|
28+
LL | pub fn f(_: impl ToString) {}
29+
| ~~~~
2630
help: function arguments must have a statically known size, borrowed types always have a known size
2731
|
2832
LL | pub fn f(_: &dyn ToString) {}

src/test/ui/issues/issue-5883.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ LL | r: dyn A + 'static
66
|
77
= help: the trait `Sized` is not implemented for `(dyn A + 'static)`
88
= help: unsized fn params are gated as an unstable feature
9+
help: you can use `impl Trait` as the argument type
10+
|
11+
LL | r: impl A + 'static
12+
| ~~~~
913
help: function arguments must have a statically known size, borrowed types always have a known size
1014
|
1115
LL | r: &dyn A + 'static

src/test/ui/resolve/issue-5035-2.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ LL | fn foo(_x: K) {}
66
|
77
= help: the trait `Sized` is not implemented for `(dyn I + 'static)`
88
= help: unsized fn params are gated as an unstable feature
9+
help: you can use `impl Trait` as the argument type
10+
|
11+
LL | fn foo(_x: impl K) {}
12+
| ++++
913
help: function arguments must have a statically known size, borrowed types always have a known size
1014
|
1115
LL | fn foo(_x: &K) {}

src/test/ui/traits/bound/not-on-bare-trait.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ LL | fn foo(_x: Foo + Send) {
2020
|
2121
= help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)`
2222
= help: unsized fn params are gated as an unstable feature
23+
help: you can use `impl Trait` as the argument type
24+
|
25+
LL | fn foo(_x: impl Foo + Send) {
26+
| ++++
2327
help: function arguments must have a statically known size, borrowed types always have a known size
2428
|
2529
LL | fn foo(_x: &Foo + Send) {

0 commit comments

Comments
 (0)