From 4dcb70b8cf3a12bb3bf0ef38cd05e6ab3720402c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 24 May 2024 13:41:20 +0000 Subject: [PATCH 1/5] Allow constraining opaque types during unsizing --- .../src/traits/select/confirmation.rs | 6 +++--- tests/ui/impl-trait/unsize_adt.rs | 5 +++-- tests/ui/impl-trait/unsize_adt.stderr | 17 ----------------- tests/ui/impl-trait/unsize_slice.rs | 5 +++-- tests/ui/impl-trait/unsize_slice.stderr | 17 ----------------- tests/ui/impl-trait/unsize_tuple.rs | 5 +++-- tests/ui/impl-trait/unsize_tuple.stderr | 17 ----------------- 7 files changed, 12 insertions(+), 60 deletions(-) delete mode 100644 tests/ui/impl-trait/unsize_adt.stderr delete mode 100644 tests/ui/impl-trait/unsize_slice.stderr delete mode 100644 tests/ui/impl-trait/unsize_tuple.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index af599108c49dc..84c744be381a3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1228,7 +1228,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, b, a) + .eq(DefineOpaqueTypes::Yes, b, a) .map_err(|_| Unimplemented)?; ImplSource::Builtin(BuiltinImplSource::Misc, obligations) @@ -1276,7 +1276,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, target, new_struct) + .eq(DefineOpaqueTypes::Yes, target, new_struct) .map_err(|_| Unimplemented)?; nested.extend(obligations); @@ -1309,7 +1309,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { mut obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, target, new_tuple) + .eq(DefineOpaqueTypes::Yes, target, new_tuple) .map_err(|_| Unimplemented)?; // Add a nested `T: Unsize` predicate. diff --git a/tests/ui/impl-trait/unsize_adt.rs b/tests/ui/impl-trait/unsize_adt.rs index fce5094bd404c..825384b61e87a 100644 --- a/tests/ui/impl-trait/unsize_adt.rs +++ b/tests/ui/impl-trait/unsize_adt.rs @@ -1,4 +1,6 @@ -//! Test that we do not allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`. +//! Test that we allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`. + +//@check-pass struct Foo(T); @@ -6,7 +8,6 @@ fn hello() -> Foo<[impl Sized; 2]> { if false { let x = hello(); let _: &Foo<[i32]> = &x; - //~^ ERROR: mismatched types } todo!() } diff --git a/tests/ui/impl-trait/unsize_adt.stderr b/tests/ui/impl-trait/unsize_adt.stderr deleted file mode 100644 index 2b93b4a571b1b..0000000000000 --- a/tests/ui/impl-trait/unsize_adt.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/unsize_adt.rs:8:30 - | -LL | fn hello() -> Foo<[impl Sized; 2]> { - | ---------- the found opaque type -... -LL | let _: &Foo<[i32]> = &x; - | ----------- ^^ expected `&Foo<[i32]>`, found `&Foo<[impl Sized; 2]>` - | | - | expected due to this - | - = note: expected reference `&Foo<[i32]>` - found reference `&Foo<[impl Sized; 2]>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsize_slice.rs b/tests/ui/impl-trait/unsize_slice.rs index ec0f162656400..b0cf1c7ca6d26 100644 --- a/tests/ui/impl-trait/unsize_slice.rs +++ b/tests/ui/impl-trait/unsize_slice.rs @@ -1,10 +1,11 @@ -//! Test that we do not allow unsizing `[Opaque; N]` to `[Concrete]`. +//! Test that we allow unsizing `[Opaque; N]` to `[Concrete]`. + +//@check-pass fn hello() -> [impl Sized; 2] { if false { let x = hello(); let _: &[i32] = &x; - //~^ ERROR: mismatched types } todo!() } diff --git a/tests/ui/impl-trait/unsize_slice.stderr b/tests/ui/impl-trait/unsize_slice.stderr deleted file mode 100644 index 6a7fdb46163b9..0000000000000 --- a/tests/ui/impl-trait/unsize_slice.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/unsize_slice.rs:6:25 - | -LL | fn hello() -> [impl Sized; 2] { - | ---------- the found opaque type -... -LL | let _: &[i32] = &x; - | ------ ^^ expected `&[i32]`, found `&[impl Sized; 2]` - | | - | expected due to this - | - = note: expected reference `&[i32]` - found reference `&[impl Sized; 2]` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsize_tuple.rs b/tests/ui/impl-trait/unsize_tuple.rs index 630b8fd430f1a..2678564f0e869 100644 --- a/tests/ui/impl-trait/unsize_tuple.rs +++ b/tests/ui/impl-trait/unsize_tuple.rs @@ -1,4 +1,6 @@ -//! Test that we do not allow unsizing `([Opaque; N],)` to `([Concrete],)`. +//! Test that we allow unsizing `([Opaque; N],)` to `([Concrete],)`. + +//@check-pass #![feature(unsized_tuple_coercion)] @@ -6,7 +8,6 @@ fn hello() -> ([impl Sized; 2],) { if false { let x = hello(); let _: &([i32],) = &x; - //~^ ERROR: mismatched types } todo!() } diff --git a/tests/ui/impl-trait/unsize_tuple.stderr b/tests/ui/impl-trait/unsize_tuple.stderr deleted file mode 100644 index 8d3cf15887c08..0000000000000 --- a/tests/ui/impl-trait/unsize_tuple.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/unsize_tuple.rs:8:28 - | -LL | fn hello() -> ([impl Sized; 2],) { - | ---------- the found opaque type -... -LL | let _: &([i32],) = &x; - | --------- ^^ expected `&([i32],)`, found `&([impl Sized; 2],)` - | | - | expected due to this - | - = note: expected reference `&([i32],)` - found reference `&([impl Sized; 2],)` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. From cbadf786bc482baf467f601d03a074000c422914 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 24 May 2024 14:17:54 +0000 Subject: [PATCH 2/5] Add tests --- tests/ui/impl-trait/trait_upcasting.rs | 26 +++++++++++++++++++ tests/ui/impl-trait/trait_upcasting.stderr | 29 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/ui/impl-trait/trait_upcasting.rs create mode 100644 tests/ui/impl-trait/trait_upcasting.stderr diff --git a/tests/ui/impl-trait/trait_upcasting.rs b/tests/ui/impl-trait/trait_upcasting.rs new file mode 100644 index 0000000000000..cb3c17e87b413 --- /dev/null +++ b/tests/ui/impl-trait/trait_upcasting.rs @@ -0,0 +1,26 @@ +//! Test that we allow unsizing `Trait` to `Trait` and vice versa + +trait Trait {} + +impl Trait for U {} + +fn hello() -> &'static (dyn Trait + Send) { + if false { + let x = hello(); + let _: &'static dyn Trait<()> = x; + //~^ ERROR: mismatched types + } + todo!() +} + +fn bye() -> &'static dyn Trait { + if false { + let mut x = bye(); + let y: &'static (dyn Trait<()> + Send) = &(); + x = y; + //~^ ERROR: mismatched types + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/trait_upcasting.stderr b/tests/ui/impl-trait/trait_upcasting.stderr new file mode 100644 index 0000000000000..2c1aa4bbf8079 --- /dev/null +++ b/tests/ui/impl-trait/trait_upcasting.stderr @@ -0,0 +1,29 @@ +error[E0308]: mismatched types + --> $DIR/trait_upcasting.rs:10:41 + | +LL | fn hello() -> &'static (dyn Trait + Send) { + | ---------- the found opaque type +... +LL | let _: &'static dyn Trait<()> = x; + | ---------------------- ^ expected trait `Trait<()>`, found trait `Trait + Send` + | | + | expected due to this + | + = note: expected reference `&'static (dyn Trait<()> + 'static)` + found reference `&dyn Trait + Send` + +error[E0308]: mismatched types + --> $DIR/trait_upcasting.rs:20:13 + | +LL | fn bye() -> &'static dyn Trait { + | ---------- the expected opaque type +... +LL | x = y; + | ^ expected trait `Trait`, found trait `Trait<()> + Send` + | + = note: expected reference `&dyn Trait` + found reference `&'static (dyn Trait<()> + Send + 'static)` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 4a86ef6f4c6069e94e8ea6ebb2b62206dce31cbf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 27 May 2024 10:44:35 +0000 Subject: [PATCH 3/5] Allow constraining opaque types during auto trait casting --- .../src/traits/select/confirmation.rs | 2 +- tests/ui/impl-trait/trait_upcasting.rs | 4 +-- tests/ui/impl-trait/trait_upcasting.stderr | 29 ------------------- .../trait_upcasting_reference_mismatch.rs | 18 ++++++++++++ .../trait_upcasting_reference_mismatch.stderr | 9 ++++++ 5 files changed, 30 insertions(+), 32 deletions(-) delete mode 100644 tests/ui/impl-trait/trait_upcasting.stderr create mode 100644 tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs create mode 100644 tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 84c744be381a3..f883cd7189387 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1161,7 +1161,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { mut obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, target, source_trait) + .sup(DefineOpaqueTypes::Yes, target, source_trait) .map_err(|_| Unimplemented)?; // Register one obligation for 'a: 'b. diff --git a/tests/ui/impl-trait/trait_upcasting.rs b/tests/ui/impl-trait/trait_upcasting.rs index cb3c17e87b413..ce811004fae19 100644 --- a/tests/ui/impl-trait/trait_upcasting.rs +++ b/tests/ui/impl-trait/trait_upcasting.rs @@ -1,5 +1,7 @@ //! Test that we allow unsizing `Trait` to `Trait` and vice versa +//@ check-pass + trait Trait {} impl Trait for U {} @@ -8,7 +10,6 @@ fn hello() -> &'static (dyn Trait + Send) { if false { let x = hello(); let _: &'static dyn Trait<()> = x; - //~^ ERROR: mismatched types } todo!() } @@ -18,7 +19,6 @@ fn bye() -> &'static dyn Trait { let mut x = bye(); let y: &'static (dyn Trait<()> + Send) = &(); x = y; - //~^ ERROR: mismatched types } todo!() } diff --git a/tests/ui/impl-trait/trait_upcasting.stderr b/tests/ui/impl-trait/trait_upcasting.stderr deleted file mode 100644 index 2c1aa4bbf8079..0000000000000 --- a/tests/ui/impl-trait/trait_upcasting.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/trait_upcasting.rs:10:41 - | -LL | fn hello() -> &'static (dyn Trait + Send) { - | ---------- the found opaque type -... -LL | let _: &'static dyn Trait<()> = x; - | ---------------------- ^ expected trait `Trait<()>`, found trait `Trait + Send` - | | - | expected due to this - | - = note: expected reference `&'static (dyn Trait<()> + 'static)` - found reference `&dyn Trait + Send` - -error[E0308]: mismatched types - --> $DIR/trait_upcasting.rs:20:13 - | -LL | fn bye() -> &'static dyn Trait { - | ---------- the expected opaque type -... -LL | x = y; - | ^ expected trait `Trait`, found trait `Trait<()> + Send` - | - = note: expected reference `&dyn Trait` - found reference `&'static (dyn Trait<()> + Send + 'static)` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs new file mode 100644 index 0000000000000..bed88db1accee --- /dev/null +++ b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs @@ -0,0 +1,18 @@ +//! Show an uninformative diagnostic that we could possibly improve in the future + +trait Trait {} + +impl Trait for U {} + +fn hello() -> &'static (dyn Trait + Send) { + //~^ ERROR: type annotations needed + if false { + let x = hello(); + let _: &'static dyn Trait<()> = &x; + //^ Note the extra `&`, paired with the blanket impl causing + // `impl Sized` to never get a hidden type registered. + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr new file mode 100644 index 0000000000000..92da47b08e9f1 --- /dev/null +++ b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/trait_upcasting_reference_mismatch.rs:7:35 + | +LL | fn hello() -> &'static (dyn Trait + Send) { + | ^^^^^^^^^^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. From f5f298dad4f8ed383cac22d90659b55a820f7ba0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 28 May 2024 15:38:18 +0000 Subject: [PATCH 4/5] Add more tests --- .../impl-trait/unsized_coercion.next.stderr | 26 +++++++++++++++++++ tests/ui/impl-trait/unsized_coercion.rs | 21 +++++++++++++++ .../impl-trait/unsized_coercion2.old.stderr | 12 +++++++++ tests/ui/impl-trait/unsized_coercion2.rs | 21 +++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 tests/ui/impl-trait/unsized_coercion.next.stderr create mode 100644 tests/ui/impl-trait/unsized_coercion.rs create mode 100644 tests/ui/impl-trait/unsized_coercion2.old.stderr create mode 100644 tests/ui/impl-trait/unsized_coercion2.rs diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr new file mode 100644 index 0000000000000..49ac3f1845fb3 --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion.next.stderr @@ -0,0 +1,26 @@ +error[E0271]: type mismatch resolving `impl Trait <: dyn Trait` + --> $DIR/unsized_coercion.rs:14:17 + | +LL | let x = hello(); + | ^^^^^^^ types differ + +error[E0308]: mismatched types + --> $DIR/unsized_coercion.rs:18:14 + | +LL | fn hello() -> Box { + | ---------- the expected opaque type +... +LL | Box::new(1u32) + | -------- ^^^^ types differ + | | + | arguments to this function are incorrect + | + = note: expected opaque type `impl Trait` + found type `u32` +note: associated function defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0308. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs new file mode 100644 index 0000000000000..46e040c1428a4 --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion.rs @@ -0,0 +1,21 @@ +//! This test checks that opaque types get unsized instead of +//! constraining their hidden type to a trait object. + +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@[old] check-pass + +trait Trait {} + +impl Trait for u32 {} + +fn hello() -> Box { + if true { + let x = hello(); + //[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait` + let y: Box = x; + } + Box::new(1u32) //[next]~ ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsized_coercion2.old.stderr b/tests/ui/impl-trait/unsized_coercion2.old.stderr new file mode 100644 index 0000000000000..a89d40f1130c1 --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion2.old.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time + --> $DIR/unsized_coercion2.rs:15:33 + | +LL | let y: Box = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Trait + ?Sized` + = note: required for the cast from `Box` to `Box` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion2.rs b/tests/ui/impl-trait/unsized_coercion2.rs new file mode 100644 index 0000000000000..7368d47dbe2c0 --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion2.rs @@ -0,0 +1,21 @@ +//! This test checks that opaque types get unsized instead of +//! constraining their hidden type to a trait object. + +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +trait Trait {} + +impl Trait for u32 {} + +fn hello() -> Box { + if true { + let x = hello(); + let y: Box = x; + //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know + } + Box::new(1u32) +} + +fn main() {} From 45da03541c0a07f63f1b8c15cccd2fc8692cca7e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 31 May 2024 09:51:10 +0000 Subject: [PATCH 5/5] More tests --- .../impl-trait/unsized_coercion3.next.stderr | 38 +++++++++++++++++++ .../impl-trait/unsized_coercion3.old.stderr | 26 +++++++++++++ tests/ui/impl-trait/unsized_coercion3.rs | 24 ++++++++++++ tests/ui/impl-trait/unsized_coercion4.rs | 20 ++++++++++ .../impl-trait/unsized_coercion5.next.stderr | 14 +++++++ .../impl-trait/unsized_coercion5.old.stderr | 38 +++++++++++++++++++ tests/ui/impl-trait/unsized_coercion5.rs | 24 ++++++++++++ 7 files changed, 184 insertions(+) create mode 100644 tests/ui/impl-trait/unsized_coercion3.next.stderr create mode 100644 tests/ui/impl-trait/unsized_coercion3.old.stderr create mode 100644 tests/ui/impl-trait/unsized_coercion3.rs create mode 100644 tests/ui/impl-trait/unsized_coercion4.rs create mode 100644 tests/ui/impl-trait/unsized_coercion5.next.stderr create mode 100644 tests/ui/impl-trait/unsized_coercion5.old.stderr create mode 100644 tests/ui/impl-trait/unsized_coercion5.rs diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr new file mode 100644 index 0000000000000..bab8d1cd83b30 --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr @@ -0,0 +1,38 @@ +error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send` + --> $DIR/unsized_coercion3.rs:13:17 + | +LL | let x = hello(); + | ^^^^^^^ types differ + +error[E0308]: mismatched types + --> $DIR/unsized_coercion3.rs:19:14 + | +LL | fn hello() -> Box { + | ------------------- the expected opaque type +... +LL | Box::new(1u32) + | -------- ^^^^ types differ + | | + | arguments to this function are incorrect + | + = note: expected opaque type `impl Trait + ?Sized` + found type `u32` +note: associated function defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time + --> $DIR/unsized_coercion3.rs:19:14 + | +LL | Box::new(1u32) + | -------- ^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `impl Trait + ?Sized` +note: required by a bound in `Box::::new` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0271, E0277, E0308. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr new file mode 100644 index 0000000000000..24a302d7007ab --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr @@ -0,0 +1,26 @@ +error: cannot check whether the hidden type of opaque type satisfies auto traits + --> $DIR/unsized_coercion3.rs:15:32 + | +LL | let y: Box = x; + | ^ + | + = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule +note: opaque type is declared here + --> $DIR/unsized_coercion3.rs:11:19 + | +LL | fn hello() -> Box { + | ^^^^^^^^^^^^^^^^^^^ + = note: required for the cast from `Box` to `Box` + +error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time + --> $DIR/unsized_coercion3.rs:15:32 + | +LL | let y: Box = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Trait + ?Sized` + = note: required for the cast from `Box` to `Box` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs new file mode 100644 index 0000000000000..85950ac583ebc --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion3.rs @@ -0,0 +1,24 @@ +//! This test checks that opaque types get unsized instead of +//! constraining their hidden type to a trait object. + +//@ revisions: next old +//@[next] compile-flags: -Znext-solver + +trait Trait {} + +impl Trait for u32 {} + +fn hello() -> Box { + if true { + let x = hello(); + //[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send` + let y: Box = x; + //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know + //[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits + } + Box::new(1u32) + //[next]~^ ERROR: mismatched types + //[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsized_coercion4.rs b/tests/ui/impl-trait/unsized_coercion4.rs new file mode 100644 index 0000000000000..1c4d5462ceeb2 --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion4.rs @@ -0,0 +1,20 @@ +//! This test checks that opaque types get unsized instead of +//! constraining their hidden type to a trait object. + +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@check-pass + +trait Trait {} + +impl Trait for u32 {} + +fn hello() -> Box { + if true { + let x = hello() as Box; + let y: Box = x; + } + Box::new(1u32) +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsized_coercion5.next.stderr b/tests/ui/impl-trait/unsized_coercion5.next.stderr new file mode 100644 index 0000000000000..5644ac7ab04bc --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion5.next.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/unsized_coercion5.rs:16:32 + | +LL | let y: Box = x as Box; + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Send`, found trait `Trait + Send` + | | + | expected due to this + | + = note: expected struct `Box` + found struct `Box` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsized_coercion5.old.stderr b/tests/ui/impl-trait/unsized_coercion5.old.stderr new file mode 100644 index 0000000000000..b6437266f27dd --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion5.old.stderr @@ -0,0 +1,38 @@ +error[E0308]: mismatched types + --> $DIR/unsized_coercion5.rs:16:32 + | +LL | let y: Box = x as Box; + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Send`, found trait `Trait + Send` + | | + | expected due to this + | + = note: expected struct `Box` + found struct `Box` + +error: cannot check whether the hidden type of opaque type satisfies auto traits + --> $DIR/unsized_coercion5.rs:16:32 + | +LL | let y: Box = x as Box; + | ^ + | + = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule +note: opaque type is declared here + --> $DIR/unsized_coercion5.rs:13:19 + | +LL | fn hello() -> Box { + | ^^^^^^^^^^^^^^^^^^^ + = note: required for the cast from `Box` to `Box` + +error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time + --> $DIR/unsized_coercion5.rs:16:32 + | +LL | let y: Box = x as Box; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Trait + ?Sized` + = note: required for the cast from `Box` to `Box` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion5.rs b/tests/ui/impl-trait/unsized_coercion5.rs new file mode 100644 index 0000000000000..b007267a0066f --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion5.rs @@ -0,0 +1,24 @@ +//! This test checks that opaque types get unsized instead of +//! constraining their hidden type to a trait object. + +//@ revisions: next old +//@[next] compile-flags: -Znext-solver + +#![feature(trait_upcasting)] + +trait Trait {} + +impl Trait for u32 {} + +fn hello() -> Box { + if true { + let x = hello(); + let y: Box = x as Box; + //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know + //[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits + //~^^^ ERROR: mismatched types + } + Box::new(1u32) +} + +fn main() {}