mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
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
This commit is contained in:
@@ -1162,7 +1162,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
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.
|
||||
@@ -1229,7 +1229,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
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)
|
||||
@@ -1277,7 +1277,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
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);
|
||||
|
||||
@@ -1310,7 +1310,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
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<U>` predicate.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//! Test that we allow unsizing `Trait<Concrete>` to `Trait<Opaque>` and vice versa
|
||||
|
||||
//@ check-pass
|
||||
|
||||
trait Trait<T> {}
|
||||
|
||||
impl<T, U> Trait<T> for U {}
|
||||
|
||||
fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
|
||||
if false {
|
||||
let x = hello();
|
||||
let _: &'static dyn Trait<()> = x;
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn bye() -> &'static dyn Trait<impl Sized> {
|
||||
if false {
|
||||
let mut x = bye();
|
||||
let y: &'static (dyn Trait<()> + Send) = &();
|
||||
x = y;
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,18 @@
|
||||
//! Show an uninformative diagnostic that we could possibly improve in the future
|
||||
|
||||
trait Trait<T> {}
|
||||
|
||||
impl<T, U> Trait<T> for U {}
|
||||
|
||||
fn hello() -> &'static (dyn Trait<impl Sized> + 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() {}
|
||||
@@ -0,0 +1,9 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/trait_upcasting_reference_mismatch.rs:7:35
|
||||
|
|
||||
LL | fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
|
||||
| ^^^^^^^^^^ cannot infer type
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
@@ -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: ?Sized>(T);
|
||||
|
||||
@@ -6,7 +8,6 @@
|
||||
if false {
|
||||
let x = hello();
|
||||
let _: &Foo<[i32]> = &x;
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
@@ -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!()
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
@@ -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 @@
|
||||
if false {
|
||||
let x = hello();
|
||||
let _: &([i32],) = &x;
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
@@ -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<impl Trait> {
|
||||
| ---------- 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`.
|
||||
@@ -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<impl Trait> {
|
||||
if true {
|
||||
let x = hello();
|
||||
//[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait`
|
||||
let y: Box<dyn Trait> = x;
|
||||
}
|
||||
Box::new(1u32) //[next]~ ERROR: mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -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<dyn Trait> = 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<impl Trait + ?Sized>` to `Box<dyn Trait>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
@@ -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<impl Trait + ?Sized> {
|
||||
if true {
|
||||
let x = hello();
|
||||
let y: Box<dyn Trait> = x;
|
||||
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
|
||||
}
|
||||
Box::new(1u32)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -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<impl Trait + ?Sized> {
|
||||
| ------------------- 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::<T>::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`.
|
||||
@@ -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<dyn Send> = 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<impl Trait + ?Sized> {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
|
||||
|
||||
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<dyn Send> = 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<impl Trait + ?Sized>` to `Box<dyn Send>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
@@ -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<impl Trait + ?Sized> {
|
||||
if true {
|
||||
let x = hello();
|
||||
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
|
||||
let y: Box<dyn Send> = 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() {}
|
||||
@@ -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<impl Trait + ?Sized> {
|
||||
if true {
|
||||
let x = hello() as Box<u32>;
|
||||
let y: Box<dyn Send> = x;
|
||||
}
|
||||
Box::new(1u32)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unsized_coercion5.rs:16:32
|
||||
|
|
||||
LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
||||
| ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Send`, found trait `Trait + Send`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected struct `Box<dyn Send>`
|
||||
found struct `Box<dyn Trait + Send>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
@@ -0,0 +1,38 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unsized_coercion5.rs:16:32
|
||||
|
|
||||
LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
||||
| ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Send`, found trait `Trait + Send`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected struct `Box<dyn Send>`
|
||||
found struct `Box<dyn Trait + Send>`
|
||||
|
||||
error: cannot check whether the hidden type of opaque type satisfies auto traits
|
||||
--> $DIR/unsized_coercion5.rs:16:32
|
||||
|
|
||||
LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
||||
| ^
|
||||
|
|
||||
= 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<impl Trait + ?Sized> {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`
|
||||
|
||||
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<dyn Send> = x as Box<dyn Trait + Send>;
|
||||
| ^ 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<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
@@ -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<impl Trait + ?Sized> {
|
||||
if true {
|
||||
let x = hello();
|
||||
let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
||||
//[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() {}
|
||||
Reference in New Issue
Block a user