Skip to content

Commit 164e129

Browse files
committed
Auto merge of rust-lang#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 rust-lang#116652
2 parents fc555cd + 45da035 commit 164e129

21 files changed

+330
-61
lines changed

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! Test that we allow unsizing `Trait<Concrete>` to `Trait<Opaque>` and vice versa
2+
3+
//@ check-pass
4+
5+
trait Trait<T> {}
6+
7+
impl<T, U> Trait<T> for U {}
8+
9+
fn 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+
17+
fn 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+
26+
fn main() {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//! Show an uninformative diagnostic that we could possibly improve in the future
2+
3+
trait Trait<T> {}
4+
5+
impl<T, U> Trait<T> for U {}
6+
7+
fn 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+
18+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/trait_upcasting_reference_mismatch.rs:7:35
3+
|
4+
LL | fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
5+
| ^^^^^^^^^^ cannot infer type
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0282`.

tests/ui/impl-trait/unsize_adt.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
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

35
struct Foo<T: ?Sized>(T);
46

57
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

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/ui/impl-trait/unsize_slice.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

35
fn 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

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/ui/impl-trait/unsize_tuple.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
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

57
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

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)