Skip to content

Commit

Permalink
Rollup merge of #124080 - oli-obk:define_opaque_types10, r=compiler-e…
Browse files Browse the repository at this point in the history
…rrors

Some unstable changes to where opaque types get defined

None of these can be reached from stable afaict.

r? ``@compiler-errors``

cc #116652
  • Loading branch information
matthiaskrgr authored May 25, 2024
2 parents 7fb8122 + 4387eea commit 1e84163
Show file tree
Hide file tree
Showing 35 changed files with 364 additions and 122 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2539,7 +2539,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
let InferOk { obligations, .. } = self
.infcx
.at(&cause, obligation.param_env)
.eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref)
.eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref)
.map_err(|e| {
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
})?;
Expand Down Expand Up @@ -2594,7 +2594,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
self.infcx
.at(&obligation.cause, obligation.param_env)
.eq(
DefineOpaqueTypes::No,
DefineOpaqueTypes::Yes,
upcast_principal.map_bound(|trait_ref| {
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
}),
Expand Down Expand Up @@ -2631,7 +2631,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
nested.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::No, source_projection, target_projection)
.eq(DefineOpaqueTypes::Yes, source_projection, target_projection)
.map_err(|_| SelectionError::Unimplemented)?
.into_obligations(),
);
Expand Down
13 changes: 8 additions & 5 deletions tests/ui/impl-trait/equality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo {
0
} else {
n + sum_to(n - 1)
//~^ ERROR cannot add `impl Foo` to `u32`
//~^ ERROR cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
}
}

Expand All @@ -32,12 +32,15 @@ trait Leak: Sized {
}
impl<T> Leak for T {
default type T = ();
default fn leak(self) -> Self::T { panic!() }
default fn leak(self) -> Self::T {
panic!()
}
}
impl Leak for i32 {
type T = i32;
fn leak(self) -> i32 { self }
fn leak(self) -> i32 {
self
}
}

fn main() {
}
fn main() {}
15 changes: 4 additions & 11 deletions tests/ui/impl-trait/equality.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,13 @@ help: change the type of the numeric literal from `u32` to `i32`
LL | 0_i32
| ~~~

error[E0277]: cannot add `impl Foo` to `u32`
error[E0284]: type annotations needed: cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
--> $DIR/equality.rs:24:11
|
LL | n + sum_to(n - 1)
| ^ no implementation for `u32 + impl Foo`
|
= help: the trait `Add<impl Foo>` is not implemented for `u32`
= help: the following other types implement trait `Add<Rhs>`:
<&'a u32 as Add<u32>>
<&u32 as Add<&u32>>
<u32 as Add<&u32>>
<u32 as Add>
| ^ cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`

error: aborting due to 2 previous errors; 1 warning emitted

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0284, E0308.
For more information about an error, try `rustc --explain E0284`.
16 changes: 10 additions & 6 deletions tests/ui/impl-trait/nested_impl_trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,23 @@ error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfie
--> $DIR/nested_impl_trait.rs:6:46
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into<u32>`
|
= help: the trait `Into<U>` is implemented for `T`
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
help: consider further restricting this bound
|
LL | fn bad_in_ret_position(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++

error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
--> $DIR/nested_impl_trait.rs:19:34
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into<u32>`
|
help: consider further restricting this bound
|
= help: the trait `Into<U>` is implemented for `T`
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
LL | fn bad(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++

error: aborting due to 7 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar {
}

fn foo() -> Foo {
//~^ ERROR can't compare `Bar` with `(Foo, i32)`
//~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>`
Bar
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
error[E0277]: can't compare `Bar` with `(Foo, i32)`
error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>`
--> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13
|
LL | fn foo() -> Foo {
| ^^^ no implementation for `Bar == (Foo, i32)`
LL |
LL | Bar
| --- return type was inferred to be `Bar` here
|
= help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar`
= help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar`
| ^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0275`.
14 changes: 14 additions & 0 deletions tests/ui/impl-trait/unsize_adt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Test that we do not allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`.

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

fn hello() -> Foo<[impl Sized; 2]> {
if false {
let x = hello();
let _: &Foo<[i32]> = &x;
//~^ ERROR: mismatched types
}
todo!()
}

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/impl-trait/unsize_adt.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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`.
12 changes: 12 additions & 0 deletions tests/ui/impl-trait/unsize_slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! Test that we do not allow unsizing `[Opaque; N]` to `[Concrete]`.

fn hello() -> [impl Sized; 2] {
if false {
let x = hello();
let _: &[i32] = &x;
//~^ ERROR: mismatched types
}
todo!()
}

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/impl-trait/unsize_slice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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`.
14 changes: 14 additions & 0 deletions tests/ui/impl-trait/unsize_tuple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Test that we do not allow unsizing `([Opaque; N],)` to `([Concrete],)`.

#![feature(unsized_tuple_coercion)]

fn hello() -> ([impl Sized; 2],) {
if false {
let x = hello();
let _: &([i32],) = &x;
//~^ ERROR: mismatched types
}
todo!()
}

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/impl-trait/unsize_tuple.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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`.
28 changes: 28 additions & 0 deletions tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@[next] failure-status: 101
//@[next] known-bug: unknown
//@[next] normalize-stderr-test "note: .*\n\n" -> ""
//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> ""
//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
//@[next] normalize-stderr-test "delayed at .*" -> ""
//@[next] rustc-env:RUST_BACKTRACE=0
//@ check-pass

#![feature(trait_upcasting)]

trait Super {
type Assoc;
}

trait Sub: Super {}

impl<T: ?Sized> Super for T {
type Assoc = i32;
}

fn illegal(x: &dyn Sub<Assoc = i32>) -> &dyn Super<Assoc = impl Sized> {
x
}

fn main() {}
4 changes: 4 additions & 0 deletions tests/ui/traits/trait-upcasting/type-checking-test-4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ fn test_correct(x: &dyn Foo<'static>) {
let _ = x as &dyn Bar<'static, 'static>;
}

fn test_correct2<'a>(x: &dyn Foo<'a>) {
let _ = x as &dyn Bar<'_, '_>;
}

fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
let _ = x as &dyn Bar<'static, 'a>; // Error
//~^ ERROR lifetime may not live long enough
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/traits/trait-upcasting/type-checking-test-4.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:15:13
--> $DIR/type-checking-test-4.rs:19:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`

error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:20:13
--> $DIR/type-checking-test-4.rs:24:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'a, 'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`

error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:26:5
--> $DIR/type-checking-test-4.rs:30:5
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
Expand All @@ -24,23 +24,23 @@ LL | y.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`

error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:31:5
--> $DIR/type-checking-test-4.rs:35:5
|
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
LL | <_ as Bar>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`

error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:36:5
--> $DIR/type-checking-test-4.rs:40:5
|
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`

error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:44:5
--> $DIR/type-checking-test-4.rs:48:5
|
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
Expand Down
22 changes: 22 additions & 0 deletions tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#![feature(trait_upcasting, type_alias_impl_trait)]

//@ check-pass

type Tait = impl Sized;

trait Foo<'a>: Bar<'a, 'a, Tait> {}
trait Bar<'a, 'b, T> {}

fn test_correct(x: &dyn Foo<'static>) {
let _ = x as &dyn Bar<'static, 'static, Tait>;
}

fn test_correct2<'a>(x: &dyn Foo<'a>) {
let _ = x as &dyn Bar<'_, '_, Tait>;
}

fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) {
let _ = x as &dyn Bar<'_, '_, ()>;
}

fn main() {}

This file was deleted.

4 changes: 2 additions & 2 deletions tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] check-pass
//@check-pass

#![feature(trait_upcasting, type_alias_impl_trait)]

Expand All @@ -18,7 +18,7 @@ impl<T: ?Sized> Super for T {
type Foo = impl Sized;

fn upcast(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
x //[current]~ mismatched types
x
}

fn main() {}
Loading

0 comments on commit 1e84163

Please sign in to comment.