Skip to content

Commit 42b26cd

Browse files
committed
Fix late-bound ICE
1 parent 59337cd commit 42b26cd

File tree

5 files changed

+87
-44
lines changed

5 files changed

+87
-44
lines changed

compiler/rustc_typeck/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ pub(super) fn check_fn<'a, 'tcx>(
208208
// case that a newcomer might make, returning a bare trait, and in that case we populate
209209
// the tail expression's type so that the suggestion will be correct, but ignore all other
210210
// possible cases.
211-
fcx.check_expr(&body.value);
212211
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
212+
fcx.check_expr(&body.value);
213213
} else {
214214
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
215215
fcx.check_return_expr(&body.value, false);

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,6 @@ LL | }
102102
LL ~ Box::new(42)
103103
|
104104

105-
error[E0308]: `if` and `else` have incompatible types
106-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:9
107-
|
108-
LL | / if true {
109-
LL | | Struct
110-
| | ------ expected because of this
111-
LL | | } else {
112-
LL | | 42
113-
| | ^^ expected struct `Struct`, found integer
114-
LL | | }
115-
| |_____- `if` and `else` have incompatible types
116-
117105
error[E0746]: return type cannot have an unboxed trait object
118106
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13
119107
|
@@ -133,6 +121,18 @@ LL | } else {
133121
LL ~ Box::new(42)
134122
|
135123

124+
error[E0308]: `if` and `else` have incompatible types
125+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:9
126+
|
127+
LL | / if true {
128+
LL | | Struct
129+
| | ------ expected because of this
130+
LL | | } else {
131+
LL | | 42
132+
| | ^^ expected struct `Struct`, found integer
133+
LL | | }
134+
| |_____- `if` and `else` have incompatible types
135+
136136
error[E0308]: mismatched types
137137
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:16
138138
|

src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr

+30-31
Original file line numberDiff line numberDiff line change
@@ -236,19 +236,37 @@ error[E0746]: return type cannot have an unboxed trait object
236236
LL | fn hat() -> dyn std::fmt::Display {
237237
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
238238
|
239-
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
240-
= note: if all the returned values were of the same type you could use `impl std::fmt::Display` as the return type
241-
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
242-
= note: you can create a new `enum` with a variant for each returned type
243-
help: return a boxed trait object instead
239+
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
244240
|
245-
LL ~ fn hat() -> Box<dyn std::fmt::Display> {
246-
LL | match 13 {
247-
LL | 0 => {
248-
LL ~ return Box::new(0i32);
249-
LL | }
250-
LL | _ => {
251-
...
241+
LL | fn hat() -> T {
242+
| ~
243+
help: use `impl std::fmt::Display` as the return type if all return paths have the same type but you want to expose only the trait in the signature
244+
|
245+
LL | fn hat() -> impl std::fmt::Display {
246+
| ~~~~~~~~~~~~~~~~~~~~~~
247+
help: use a boxed trait object if all return paths implement trait `std::fmt::Display`
248+
|
249+
LL | fn hat() -> Box<dyn std::fmt::Display> {
250+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
251+
252+
error[E0746]: return type cannot have an unboxed trait object
253+
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
254+
|
255+
LL | fn pug() -> dyn std::fmt::Display {
256+
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
257+
|
258+
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
259+
|
260+
LL | fn pug() -> T {
261+
| ~
262+
help: use `impl std::fmt::Display` as the return type if all return paths have the same type but you want to expose only the trait in the signature
263+
|
264+
LL | fn pug() -> impl std::fmt::Display {
265+
| ~~~~~~~~~~~~~~~~~~~~~~
266+
help: use a boxed trait object if all return paths implement trait `std::fmt::Display`
267+
|
268+
LL | fn pug() -> Box<dyn std::fmt::Display> {
269+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
252270

253271
error[E0308]: `match` arms have incompatible types
254272
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:80:14
@@ -262,25 +280,6 @@ LL | | _ => 2u32,
262280
LL | | }
263281
| |_____- `match` arms have incompatible types
264282

265-
error[E0746]: return type cannot have an unboxed trait object
266-
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
267-
|
268-
LL | fn pug() -> dyn std::fmt::Display {
269-
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
270-
|
271-
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
272-
= note: if all the returned values were of the same type you could use `impl std::fmt::Display` as the return type
273-
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
274-
= note: you can create a new `enum` with a variant for each returned type
275-
help: return a boxed trait object instead
276-
|
277-
LL ~ fn pug() -> Box<dyn std::fmt::Display> {
278-
LL | match 13 {
279-
LL ~ 0 => Box::new(0i32),
280-
LL ~ 1 => Box::new(1u32),
281-
LL ~ _ => Box::new(2u32),
282-
|
283-
284283
error[E0308]: `if` and `else` have incompatible types
285284
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:89:9
286285
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// compile-flags: --crate-type lib
2+
trait Foo<'x> {}
3+
4+
fn or<'a>(first: dyn Foo<'a>) -> dyn Foo<'a> {
5+
//~^ ERROR: the size for values of type `(dyn Foo<'a> + 'static)` cannot be known at compilation time [E0277]
6+
//~| ERROR: return type cannot have an unboxed trait object [E0746]
7+
return Box::new(0);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0277]: the size for values of type `(dyn Foo<'a> + 'static)` cannot be known at compilation time
2+
--> $DIR/expect_unsized_return_sized.rs:4:11
3+
|
4+
LL | fn or<'a>(first: dyn Foo<'a>) -> dyn Foo<'a> {
5+
| ^^^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `(dyn Foo<'a> + 'static)`
8+
= help: unsized fn params are gated as an unstable feature
9+
help: function arguments must have a statically known size, borrowed types always have a known size
10+
|
11+
LL | fn or<'a>(first: &dyn Foo<'a>) -> dyn Foo<'a> {
12+
| +
13+
14+
error[E0746]: return type cannot have an unboxed trait object
15+
--> $DIR/expect_unsized_return_sized.rs:4:34
16+
|
17+
LL | fn or<'a>(first: dyn Foo<'a>) -> dyn Foo<'a> {
18+
| ^^^^^^^^^^^ doesn't have a size known at compile-time
19+
|
20+
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
21+
|
22+
LL | fn or<'a>(first: dyn Foo<'a>) -> T {
23+
| ~
24+
help: use `impl Foo<'a>` as the return type if all return paths have the same type but you want to expose only the trait in the signature
25+
|
26+
LL | fn or<'a>(first: dyn Foo<'a>) -> impl Foo<'a> {
27+
| ~~~~~~~~~~~~
28+
help: use a boxed trait object if all return paths implement trait `Foo<'a>`
29+
|
30+
LL | fn or<'a>(first: dyn Foo<'a>) -> Box<dyn Foo<'a>> {
31+
| ~~~~~~~~~~~~~~~~
32+
33+
error: aborting due to 2 previous errors
34+
35+
Some errors have detailed explanations: E0277, E0746.
36+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)