authorbors <bors@rust-lang.org> 2024-06-25 05:09:30 UTC
committerbors <bors@rust-lang.org> 2024-06-25 05:09:30 UTC
log164e1297e1bce47a241e4d93a9f044452b288715
tree89d6725b38c02bd32b7b407ec422edded564be0e
parentfc555cd832ee743ff5410c35de2b0dd59ec4322e
parent45da03541c0a07f63f1b8c15cccd2fc8692cca7e

Auto merge of #125610 - oli-obk:define_opaque_types14, r=compiler-errors

Allow constraining opaque types during various unsizing casts allows unsizing of tuples, arrays and Adts to constraint opaque types in their generic parameters to concrete types on either side of the unsizing cast. Also allows constraining opaque types during trait object casts that only differ in auto traits or lifetimes. cc #116652

21 files changed, 330 insertions(+), 61 deletions(-)

compiler/rustc_trait_selection/src/traits/select/confirmation.rs+4-4
......@@ -1162,7 +1162,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11621162 let InferOk { mut obligations, .. } = self
11631163 .infcx
11641164 .at(&obligation.cause, obligation.param_env)
1165 .sup(DefineOpaqueTypes::No, target, source_trait)
1165 .sup(DefineOpaqueTypes::Yes, target, source_trait)
11661166 .map_err(|_| Unimplemented)?;
11671167
11681168 // Register one obligation for 'a: 'b.
......@@ -1229,7 +1229,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12291229 let InferOk { obligations, .. } = self
12301230 .infcx
12311231 .at(&obligation.cause, obligation.param_env)
1232 .eq(DefineOpaqueTypes::No, b, a)
1232 .eq(DefineOpaqueTypes::Yes, b, a)
12331233 .map_err(|_| Unimplemented)?;
12341234
12351235 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
......@@ -1277,7 +1277,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12771277 let InferOk { obligations, .. } = self
12781278 .infcx
12791279 .at(&obligation.cause, obligation.param_env)
1280 .eq(DefineOpaqueTypes::No, target, new_struct)
1280 .eq(DefineOpaqueTypes::Yes, target, new_struct)
12811281 .map_err(|_| Unimplemented)?;
12821282 nested.extend(obligations);
12831283
......@@ -1310,7 +1310,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13101310 let InferOk { mut obligations, .. } = self
13111311 .infcx
13121312 .at(&obligation.cause, obligation.param_env)
1313 .eq(DefineOpaqueTypes::No, target, new_tuple)
1313 .eq(DefineOpaqueTypes::Yes, target, new_tuple)
13141314 .map_err(|_| Unimplemented)?;
13151315
13161316 // Add a nested `T: Unsize<U>` predicate.
tests/ui/impl-trait/trait_upcasting.rs created+26
......@@ -0,0 +1,26 @@
1//! Test that we allow unsizing `Trait<Concrete>` to `Trait<Opaque>` and vice versa
2
3//@ check-pass
4
5trait Trait<T> {}
6
7impl<T, U> Trait<T> for U {}
8
9fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
10 if false {
11 let x = hello();
12 let _: &'static dyn Trait<()> = x;
13 }
14 todo!()
15}
16
17fn bye() -> &'static dyn Trait<impl Sized> {
18 if false {
19 let mut x = bye();
20 let y: &'static (dyn Trait<()> + Send) = &();
21 x = y;
22 }
23 todo!()
24}
25
26fn main() {}
tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs created+18
......@@ -0,0 +1,18 @@
1//! Show an uninformative diagnostic that we could possibly improve in the future
2
3trait Trait<T> {}
4
5impl<T, U> Trait<T> for U {}
6
7fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
8 //~^ ERROR: type annotations needed
9 if false {
10 let x = hello();
11 let _: &'static dyn Trait<()> = &x;
12 //^ Note the extra `&`, paired with the blanket impl causing
13 // `impl Sized` to never get a hidden type registered.
14 }
15 todo!()
16}
17
18fn main() {}
tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr created+9
......@@ -0,0 +1,9 @@
1error[E0282]: type annotations needed
2 --> $DIR/trait_upcasting_reference_mismatch.rs:7:35
3 |
4LL | fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
5 | ^^^^^^^^^^ cannot infer type
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0282`.
tests/ui/impl-trait/unsize_adt.rs+3-2
......@@ -1,4 +1,6 @@
1//! Test that we do not allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`.
1//! Test that we allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`.
2
3//@check-pass
24
35struct Foo<T: ?Sized>(T);
46
......@@ -6,7 +8,6 @@ fn hello() -> Foo<[impl Sized; 2]> {
68 if false {
79 let x = hello();
810 let _: &Foo<[i32]> = &x;
9 //~^ ERROR: mismatched types
1011 }
1112 todo!()
1213}
tests/ui/impl-trait/unsize_adt.stderr deleted-17
......@@ -1,17 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/unsize_adt.rs:8:30
3 |
4LL | fn hello() -> Foo<[impl Sized; 2]> {
5 | ---------- the found opaque type
6...
7LL | let _: &Foo<[i32]> = &x;
8 | ----------- ^^ expected `&Foo<[i32]>`, found `&Foo<[impl Sized; 2]>`
9 | |
10 | expected due to this
11 |
12 = note: expected reference `&Foo<[i32]>`
13 found reference `&Foo<[impl Sized; 2]>`
14
15error: aborting due to 1 previous error
16
17For more information about this error, try `rustc --explain E0308`.
tests/ui/impl-trait/unsize_slice.rs+3-2
......@@ -1,10 +1,11 @@
1//! Test that we do not allow unsizing `[Opaque; N]` to `[Concrete]`.
1//! Test that we allow unsizing `[Opaque; N]` to `[Concrete]`.
2
3//@check-pass
24
35fn hello() -> [impl Sized; 2] {
46 if false {
57 let x = hello();
68 let _: &[i32] = &x;
7 //~^ ERROR: mismatched types
89 }
910 todo!()
1011}
tests/ui/impl-trait/unsize_slice.stderr deleted-17
......@@ -1,17 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/unsize_slice.rs:6:25
3 |
4LL | fn hello() -> [impl Sized; 2] {
5 | ---------- the found opaque type
6...
7LL | let _: &[i32] = &x;
8 | ------ ^^ expected `&[i32]`, found `&[impl Sized; 2]`
9 | |
10 | expected due to this
11 |
12 = note: expected reference `&[i32]`
13 found reference `&[impl Sized; 2]`
14
15error: aborting due to 1 previous error
16
17For more information about this error, try `rustc --explain E0308`.
tests/ui/impl-trait/unsize_tuple.rs+3-2
......@@ -1,4 +1,6 @@
1//! Test that we do not allow unsizing `([Opaque; N],)` to `([Concrete],)`.
1//! Test that we allow unsizing `([Opaque; N],)` to `([Concrete],)`.
2
3//@check-pass
24
35#![feature(unsized_tuple_coercion)]
46
......@@ -6,7 +8,6 @@ fn hello() -> ([impl Sized; 2],) {
68 if false {
79 let x = hello();
810 let _: &([i32],) = &x;
9 //~^ ERROR: mismatched types
1011 }
1112 todo!()
1213}
tests/ui/impl-trait/unsize_tuple.stderr deleted-17
......@@ -1,17 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/unsize_tuple.rs:8:28
3 |
4LL | fn hello() -> ([impl Sized; 2],) {
5 | ---------- the found opaque type
6...
7LL | let _: &([i32],) = &x;
8 | --------- ^^ expected `&([i32],)`, found `&([impl Sized; 2],)`
9 | |
10 | expected due to this
11 |
12 = note: expected reference `&([i32],)`
13 found reference `&([impl Sized; 2],)`
14
15error: aborting due to 1 previous error
16
17For more information about this error, try `rustc --explain E0308`.
tests/ui/impl-trait/unsized_coercion.next.stderr created+26
......@@ -0,0 +1,26 @@
1error[E0271]: type mismatch resolving `impl Trait <: dyn Trait`
2 --> $DIR/unsized_coercion.rs:14:17
3 |
4LL | let x = hello();
5 | ^^^^^^^ types differ
6
7error[E0308]: mismatched types
8 --> $DIR/unsized_coercion.rs:18:14
9 |
10LL | fn hello() -> Box<impl Trait> {
11 | ---------- the expected opaque type
12...
13LL | Box::new(1u32)
14 | -------- ^^^^ types differ
15 | |
16 | arguments to this function are incorrect
17 |
18 = note: expected opaque type `impl Trait`
19 found type `u32`
20note: associated function defined here
21 --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
22
23error: aborting due to 2 previous errors
24
25Some errors have detailed explanations: E0271, E0308.
26For more information about an error, try `rustc --explain E0271`.
tests/ui/impl-trait/unsized_coercion.rs created+21
......@@ -0,0 +1,21 @@
1//! This test checks that opaque types get unsized instead of
2//! constraining their hidden type to a trait object.
3
4//@ revisions: next old
5//@[next] compile-flags: -Znext-solver
6//@[old] check-pass
7
8trait Trait {}
9
10impl Trait for u32 {}
11
12fn hello() -> Box<impl Trait> {
13 if true {
14 let x = hello();
15 //[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait`
16 let y: Box<dyn Trait> = x;
17 }
18 Box::new(1u32) //[next]~ ERROR: mismatched types
19}
20
21fn main() {}
tests/ui/impl-trait/unsized_coercion2.old.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
2 --> $DIR/unsized_coercion2.rs:15:33
3 |
4LL | let y: Box<dyn Trait> = x;
5 | ^ doesn't have a size known at compile-time
6 |
7 = help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
8 = note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait>`
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0277`.
tests/ui/impl-trait/unsized_coercion2.rs created+21
......@@ -0,0 +1,21 @@
1//! This test checks that opaque types get unsized instead of
2//! constraining their hidden type to a trait object.
3
4//@ revisions: next old
5//@[next] compile-flags: -Znext-solver
6//@[next] check-pass
7
8trait Trait {}
9
10impl Trait for u32 {}
11
12fn hello() -> Box<impl Trait + ?Sized> {
13 if true {
14 let x = hello();
15 let y: Box<dyn Trait> = x;
16 //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
17 }
18 Box::new(1u32)
19}
20
21fn main() {}
tests/ui/impl-trait/unsized_coercion3.next.stderr created+38
......@@ -0,0 +1,38 @@
1error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
2 --> $DIR/unsized_coercion3.rs:13:17
3 |
4LL | let x = hello();
5 | ^^^^^^^ types differ
6
7error[E0308]: mismatched types
8 --> $DIR/unsized_coercion3.rs:19:14
9 |
10LL | fn hello() -> Box<impl Trait + ?Sized> {
11 | ------------------- the expected opaque type
12...
13LL | Box::new(1u32)
14 | -------- ^^^^ types differ
15 | |
16 | arguments to this function are incorrect
17 |
18 = note: expected opaque type `impl Trait + ?Sized`
19 found type `u32`
20note: associated function defined here
21 --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
22
23error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
24 --> $DIR/unsized_coercion3.rs:19:14
25 |
26LL | Box::new(1u32)
27 | -------- ^^^^ doesn't have a size known at compile-time
28 | |
29 | required by a bound introduced by this call
30 |
31 = help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
32note: required by a bound in `Box::<T>::new`
33 --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
34
35error: aborting due to 3 previous errors
36
37Some errors have detailed explanations: E0271, E0277, E0308.
38For more information about an error, try `rustc --explain E0271`.
tests/ui/impl-trait/unsized_coercion3.old.stderr created+26
......@@ -0,0 +1,26 @@
1error: cannot check whether the hidden type of opaque type satisfies auto traits
2 --> $DIR/unsized_coercion3.rs:15:32
3 |
4LL | let y: Box<dyn Send> = x;
5 | ^
6 |
7 = 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
8note: opaque type is declared here
9 --> $DIR/unsized_coercion3.rs:11:19
10 |
11LL | fn hello() -> Box<impl Trait + ?Sized> {
12 | ^^^^^^^^^^^^^^^^^^^
13 = note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
14
15error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
16 --> $DIR/unsized_coercion3.rs:15:32
17 |
18LL | let y: Box<dyn Send> = x;
19 | ^ doesn't have a size known at compile-time
20 |
21 = help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
22 = note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
23
24error: aborting due to 2 previous errors
25
26For more information about this error, try `rustc --explain E0277`.
tests/ui/impl-trait/unsized_coercion3.rs created+24
......@@ -0,0 +1,24 @@
1//! This test checks that opaque types get unsized instead of
2//! constraining their hidden type to a trait object.
3
4//@ revisions: next old
5//@[next] compile-flags: -Znext-solver
6
7trait Trait {}
8
9impl Trait for u32 {}
10
11fn hello() -> Box<impl Trait + ?Sized> {
12 if true {
13 let x = hello();
14 //[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
15 let y: Box<dyn Send> = x;
16 //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
17 //[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
18 }
19 Box::new(1u32)
20 //[next]~^ ERROR: mismatched types
21 //[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
22}
23
24fn main() {}
tests/ui/impl-trait/unsized_coercion4.rs created+20
......@@ -0,0 +1,20 @@
1//! This test checks that opaque types get unsized instead of
2//! constraining their hidden type to a trait object.
3
4//@ revisions: next old
5//@[next] compile-flags: -Znext-solver
6//@check-pass
7
8trait Trait {}
9
10impl Trait for u32 {}
11
12fn hello() -> Box<impl Trait + ?Sized> {
13 if true {
14 let x = hello() as Box<u32>;
15 let y: Box<dyn Send> = x;
16 }
17 Box::new(1u32)
18}
19
20fn main() {}
tests/ui/impl-trait/unsized_coercion5.next.stderr created+14
......@@ -0,0 +1,14 @@
1error[E0308]: mismatched types
2 --> $DIR/unsized_coercion5.rs:16:32
3 |
4LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
5 | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Send`, found trait `Trait + Send`
6 | |
7 | expected due to this
8 |
9 = note: expected struct `Box<dyn Send>`
10 found struct `Box<dyn Trait + Send>`
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0308`.
tests/ui/impl-trait/unsized_coercion5.old.stderr created+38
......@@ -0,0 +1,38 @@
1error[E0308]: mismatched types
2 --> $DIR/unsized_coercion5.rs:16:32
3 |
4LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
5 | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Send`, found trait `Trait + Send`
6 | |
7 | expected due to this
8 |
9 = note: expected struct `Box<dyn Send>`
10 found struct `Box<dyn Trait + Send>`
11
12error: cannot check whether the hidden type of opaque type satisfies auto traits
13 --> $DIR/unsized_coercion5.rs:16:32
14 |
15LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
16 | ^
17 |
18 = 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
19note: opaque type is declared here
20 --> $DIR/unsized_coercion5.rs:13:19
21 |
22LL | fn hello() -> Box<impl Trait + ?Sized> {
23 | ^^^^^^^^^^^^^^^^^^^
24 = note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`
25
26error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
27 --> $DIR/unsized_coercion5.rs:16:32
28 |
29LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
30 | ^ doesn't have a size known at compile-time
31 |
32 = help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
33 = note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`
34
35error: aborting due to 3 previous errors
36
37Some errors have detailed explanations: E0277, E0308.
38For more information about an error, try `rustc --explain E0277`.
tests/ui/impl-trait/unsized_coercion5.rs created+24
......@@ -0,0 +1,24 @@
1//! This test checks that opaque types get unsized instead of
2//! constraining their hidden type to a trait object.
3
4//@ revisions: next old
5//@[next] compile-flags: -Znext-solver
6
7#![feature(trait_upcasting)]
8
9trait Trait {}
10
11impl Trait for u32 {}
12
13fn hello() -> Box<impl Trait + ?Sized> {
14 if true {
15 let x = hello();
16 let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
17 //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
18 //[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
19 //~^^^ ERROR: mismatched types
20 }
21 Box::new(1u32)
22}
23
24fn main() {}