From 42b26cd6e27f4a825269e4fb159fd77f882cb350 Mon Sep 17 00:00:00 2001 From: threadexception Date: Sun, 26 Dec 2021 11:39:26 +0100 Subject: [PATCH] Fix late-bound ICE --- compiler/rustc_typeck/src/check/check.rs | 2 +- ...n-trait-return-should-be-impl-trait.stderr | 24 ++++---- ...type-err-cause-on-impl-trait-return.stderr | 61 +++++++++---------- .../ui/unsized/expect_unsized_return_sized.rs | 8 +++ .../expect_unsized_return_sized.stderr | 36 +++++++++++ 5 files changed, 87 insertions(+), 44 deletions(-) create mode 100644 src/test/ui/unsized/expect_unsized_return_sized.rs create mode 100644 src/test/ui/unsized/expect_unsized_return_sized.stderr diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index fd7b3a55dfb97..5f8a2dede220a 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -208,8 +208,8 @@ pub(super) fn check_fn<'a, 'tcx>( // case that a newcomer might make, returning a bare trait, and in that case we populate // the tail expression's type so that the suggestion will be correct, but ignore all other // possible cases. - fcx.check_expr(&body.value); fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); + fcx.check_expr(&body.value); } else { fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); fcx.check_return_expr(&body.value, false); diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 0d4f82bfc153f..95ea610c83ebe 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -102,18 +102,6 @@ LL | } LL ~ Box::new(42) | -error[E0308]: `if` and `else` have incompatible types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:9 - | -LL | / if true { -LL | | Struct - | | ------ expected because of this -LL | | } else { -LL | | 42 - | | ^^ expected struct `Struct`, found integer -LL | | } - | |_____- `if` and `else` have incompatible types - error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13 | @@ -133,6 +121,18 @@ LL | } else { LL ~ Box::new(42) | +error[E0308]: `if` and `else` have incompatible types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:9 + | +LL | / if true { +LL | | Struct + | | ------ expected because of this +LL | | } else { +LL | | 42 + | | ^^ expected struct `Struct`, found integer +LL | | } + | |_____- `if` and `else` have incompatible types + error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:16 | diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr index 970abad5c72e9..1f33539845207 100644 --- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr @@ -236,19 +236,37 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn hat() -> dyn std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = note: for information on trait objects, see - = note: if all the returned values were of the same type you could use `impl std::fmt::Display` as the return type - = note: for information on `impl Trait`, see - = note: you can create a new `enum` with a variant for each returned type -help: return a boxed trait object instead +help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type | -LL ~ fn hat() -> Box { -LL | match 13 { -LL | 0 => { -LL ~ return Box::new(0i32); -LL | } -LL | _ => { - ... +LL | fn hat() -> T { + | ~ +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 + | +LL | fn hat() -> impl std::fmt::Display { + | ~~~~~~~~~~~~~~~~~~~~~~ +help: use a boxed trait object if all return paths implement trait `std::fmt::Display` + | +LL | fn hat() -> Box { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13 + | +LL | fn pug() -> dyn std::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^^^ 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 pug() -> T { + | ~ +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 + | +LL | fn pug() -> impl std::fmt::Display { + | ~~~~~~~~~~~~~~~~~~~~~~ +help: use a boxed trait object if all return paths implement trait `std::fmt::Display` + | +LL | fn pug() -> Box { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0308]: `match` arms have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:80:14 @@ -262,25 +280,6 @@ LL | | _ => 2u32, LL | | } | |_____- `match` arms have incompatible types -error[E0746]: return type cannot have an unboxed trait object - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13 - | -LL | fn pug() -> dyn std::fmt::Display { - | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = note: for information on trait objects, see - = note: if all the returned values were of the same type you could use `impl std::fmt::Display` as the return type - = note: for information on `impl Trait`, see - = note: you can create a new `enum` with a variant for each returned type -help: return a boxed trait object instead - | -LL ~ fn pug() -> Box { -LL | match 13 { -LL ~ 0 => Box::new(0i32), -LL ~ 1 => Box::new(1u32), -LL ~ _ => Box::new(2u32), - | - error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:89:9 | diff --git a/src/test/ui/unsized/expect_unsized_return_sized.rs b/src/test/ui/unsized/expect_unsized_return_sized.rs new file mode 100644 index 0000000000000..cc9c57085a905 --- /dev/null +++ b/src/test/ui/unsized/expect_unsized_return_sized.rs @@ -0,0 +1,8 @@ +// compile-flags: --crate-type lib +trait Foo<'x> {} + +fn or<'a>(first: dyn Foo<'a>) -> dyn Foo<'a> { + //~^ ERROR: the size for values of type `(dyn Foo<'a> + 'static)` cannot be known at compilation time [E0277] + //~| ERROR: return type cannot have an unboxed trait object [E0746] + return Box::new(0); +} diff --git a/src/test/ui/unsized/expect_unsized_return_sized.stderr b/src/test/ui/unsized/expect_unsized_return_sized.stderr new file mode 100644 index 0000000000000..db830c029ec03 --- /dev/null +++ b/src/test/ui/unsized/expect_unsized_return_sized.stderr @@ -0,0 +1,36 @@ +error[E0277]: the size for values of type `(dyn Foo<'a> + 'static)` cannot be known at compilation time + --> $DIR/expect_unsized_return_sized.rs:4:11 + | +LL | fn or<'a>(first: dyn Foo<'a>) -> dyn Foo<'a> { + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Foo<'a> + 'static)` + = 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 or<'a>(first: &dyn Foo<'a>) -> dyn Foo<'a> { + | + + +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/expect_unsized_return_sized.rs:4:34 + | +LL | fn or<'a>(first: dyn Foo<'a>) -> dyn Foo<'a> { + | ^^^^^^^^^^^ 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 or<'a>(first: dyn Foo<'a>) -> T { + | ~ +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 + | +LL | fn or<'a>(first: dyn Foo<'a>) -> impl Foo<'a> { + | ~~~~~~~~~~~~ +help: use a boxed trait object if all return paths implement trait `Foo<'a>` + | +LL | fn or<'a>(first: dyn Foo<'a>) -> Box> { + | ~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0746. +For more information about an error, try `rustc --explain E0277`.