Rollup merge of #124080 - oli-obk:define_opaque_types10, r=compiler-errors
Some unstable changes to where opaque types get defined None of these can be reached from stable afaict. r? ``@compiler-errors`` cc https://github.com/rust-lang/rust/issues/116652
This commit is contained in:
commit
1e841638e3
35 changed files with 363 additions and 121 deletions
|
@ -2539,7 +2539,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
let InferOk { obligations, .. } = self
|
let InferOk { obligations, .. } = self
|
||||||
.infcx
|
.infcx
|
||||||
.at(&cause, obligation.param_env)
|
.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| {
|
.map_err(|e| {
|
||||||
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
|
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
|
||||||
})?;
|
})?;
|
||||||
|
@ -2594,7 +2594,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
self.infcx
|
self.infcx
|
||||||
.at(&obligation.cause, obligation.param_env)
|
.at(&obligation.cause, obligation.param_env)
|
||||||
.eq(
|
.eq(
|
||||||
DefineOpaqueTypes::No,
|
DefineOpaqueTypes::Yes,
|
||||||
upcast_principal.map_bound(|trait_ref| {
|
upcast_principal.map_bound(|trait_ref| {
|
||||||
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
|
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
|
||||||
}),
|
}),
|
||||||
|
@ -2631,7 +2631,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
nested.extend(
|
nested.extend(
|
||||||
self.infcx
|
self.infcx
|
||||||
.at(&obligation.cause, obligation.param_env)
|
.at(&obligation.cause, obligation.param_env)
|
||||||
.eq(DefineOpaqueTypes::No, source_projection, target_projection)
|
.eq(DefineOpaqueTypes::Yes, source_projection, target_projection)
|
||||||
.map_err(|_| SelectionError::Unimplemented)?
|
.map_err(|_| SelectionError::Unimplemented)?
|
||||||
.into_obligations(),
|
.into_obligations(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
n + sum_to(n - 1)
|
n + sum_to(n - 1)
|
||||||
//~^ ERROR cannot add `impl Foo` to `u32`
|
//~^ ERROR cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +32,15 @@ trait Leak: Sized {
|
||||||
}
|
}
|
||||||
impl<T> Leak for T {
|
impl<T> Leak for T {
|
||||||
default type T = ();
|
default type T = ();
|
||||||
default fn leak(self) -> Self::T { panic!() }
|
default fn leak(self) -> Self::T {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl Leak for i32 {
|
impl Leak for i32 {
|
||||||
type T = i32;
|
type T = i32;
|
||||||
fn leak(self) -> i32 { self }
|
fn leak(self) -> i32 {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {}
|
||||||
}
|
|
||||||
|
|
|
@ -22,20 +22,13 @@ help: change the type of the numeric literal from `u32` to `i32`
|
||||||
LL | 0_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
|
--> $DIR/equality.rs:24:11
|
||||||
|
|
|
|
||||||
LL | n + sum_to(n - 1)
|
LL | n + sum_to(n - 1)
|
||||||
| ^ no implementation for `u32 + impl Foo`
|
| ^ cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
|
||||||
|
|
|
||||||
= 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>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
Some errors have detailed explanations: E0284, E0308.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0284`.
|
||||||
|
|
|
@ -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
|
--> $DIR/nested_impl_trait.rs:6:46
|
||||||
|
|
|
|
||||||
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
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`
|
help: consider further restricting this bound
|
||||||
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
|
|
||||||
|
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
|
error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
|
||||||
--> $DIR/nested_impl_trait.rs:19:34
|
--> $DIR/nested_impl_trait.rs:19:34
|
||||||
|
|
|
|
||||||
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
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: the trait `Into<U>` is implemented for `T`
|
help: consider further restricting this bound
|
||||||
= 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
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo() -> Foo {
|
fn foo() -> Foo {
|
||||||
//~^ ERROR can't compare `Bar` with `(Foo, i32)`
|
//~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>`
|
||||||
Bar
|
Bar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
--> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Foo {
|
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
|
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
tests/ui/impl-trait/unsize_adt.rs
Normal file
14
tests/ui/impl-trait/unsize_adt.rs
Normal file
|
@ -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
tests/ui/impl-trait/unsize_adt.stderr
Normal file
17
tests/ui/impl-trait/unsize_adt.stderr
Normal file
|
@ -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
tests/ui/impl-trait/unsize_slice.rs
Normal file
12
tests/ui/impl-trait/unsize_slice.rs
Normal file
|
@ -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
tests/ui/impl-trait/unsize_slice.stderr
Normal file
17
tests/ui/impl-trait/unsize_slice.stderr
Normal file
|
@ -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
tests/ui/impl-trait/unsize_tuple.rs
Normal file
14
tests/ui/impl-trait/unsize_tuple.rs
Normal file
|
@ -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
tests/ui/impl-trait/unsize_tuple.stderr
Normal file
17
tests/ui/impl-trait/unsize_tuple.stderr
Normal file
|
@ -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`.
|
|
@ -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() {}
|
|
@ -11,6 +11,10 @@ fn test_correct(x: &dyn Foo<'static>) {
|
||||||
let _ = x as &dyn Bar<'static, '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) {
|
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
let _ = x as &dyn Bar<'static, 'a>; // Error
|
let _ = x as &dyn Bar<'static, 'a>; // Error
|
||||||
//~^ ERROR lifetime may not live long enough
|
//~^ ERROR lifetime may not live long enough
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: lifetime may not live long enough
|
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) {
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
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) {
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
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> {
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
@ -24,7 +24,7 @@ LL | y.get_b() // ERROR
|
||||||
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
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> {
|
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
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> {
|
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
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> {
|
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
|
|
@ -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() {}
|
|
@ -1,17 +0,0 @@
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/upcast-defining-opaque.rs:21:5
|
|
||||||
|
|
|
||||||
LL | type Foo = impl Sized;
|
|
||||||
| ---------- the found opaque type
|
|
||||||
LL |
|
|
||||||
LL | fn upcast(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
|
|
||||||
| ----------------------- expected `&dyn Super<Assoc = i32>` because of return type
|
|
||||||
LL | x
|
|
||||||
| ^ expected trait `Super`, found trait `Sub`
|
|
||||||
|
|
|
||||||
= note: expected reference `&dyn Super<Assoc = i32>`
|
|
||||||
found reference `&dyn Sub<Assoc = Foo>`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
|
@ -1,7 +1,7 @@
|
||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@[next] check-pass
|
//@check-pass
|
||||||
|
|
||||||
#![feature(trait_upcasting, type_alias_impl_trait)]
|
#![feature(trait_upcasting, type_alias_impl_trait)]
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ impl<T: ?Sized> Super for T {
|
||||||
type Foo = impl Sized;
|
type Foo = impl Sized;
|
||||||
|
|
||||||
fn upcast(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
|
fn upcast(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
|
||||||
x //[current]~ mismatched types
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
27
tests/ui/type-alias-impl-trait/constrain_in_projection.rs
Normal file
27
tests/ui/type-alias-impl-trait/constrain_in_projection.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//! Check that projections will constrain opaque types while looking for
|
||||||
|
//! matching impls.
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@check-pass
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
type Bar = impl Sized;
|
||||||
|
|
||||||
|
trait Trait<T> {
|
||||||
|
type Assoc: Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait<()> for Foo {
|
||||||
|
type Assoc = u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bop(_: Bar) {
|
||||||
|
let x = <Foo as Trait<Bar>>::Assoc::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>`
|
||||||
|
--> $DIR/constrain_in_projection2.rs:27:14
|
||||||
|
|
|
||||||
|
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
|
||||||
|
| ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc`
|
||||||
|
|
|
||||||
|
note: multiple `impl`s satisfying `Foo: Trait<Bar>` found
|
||||||
|
--> $DIR/constrain_in_projection2.rs:18:1
|
||||||
|
|
|
||||||
|
LL | impl Trait<()> for Foo {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | impl Trait<u32> for Foo {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0283`.
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>`
|
||||||
|
--> $DIR/constrain_in_projection2.rs:27:14
|
||||||
|
|
|
||||||
|
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
|
||||||
|
| ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc`
|
||||||
|
|
|
||||||
|
note: multiple `impl`s satisfying `Foo: Trait<Bar>` found
|
||||||
|
--> $DIR/constrain_in_projection2.rs:18:1
|
||||||
|
|
|
||||||
|
LL | impl Trait<()> for Foo {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | impl Trait<u32> for Foo {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0283`.
|
31
tests/ui/type-alias-impl-trait/constrain_in_projection2.rs
Normal file
31
tests/ui/type-alias-impl-trait/constrain_in_projection2.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
//! Check that projections will constrain opaque types while looking for
|
||||||
|
//! matching impls and error if ambiguous.
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
type Bar = impl Sized;
|
||||||
|
|
||||||
|
trait Trait<T> {
|
||||||
|
type Assoc: Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait<()> for Foo {
|
||||||
|
type Assoc = u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait<u32> for Foo {
|
||||||
|
type Assoc = u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bop(_: Bar) {
|
||||||
|
let x = <Foo as Trait<Bar>>::Assoc::default();
|
||||||
|
//~^ ERROR: cannot satisfy `Foo: Trait<Bar>`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
||||||
--> $DIR/issue-84660-unsoundness.rs:23:1
|
--> $DIR/issue-84660-unsoundness.rs:28:1
|
||||||
|
|
|
|
||||||
LL | impl<In, Out> Trait<Bar, In> for Out {
|
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
| ------------------------------------ first implementation here
|
| ------------------------------------ first implementation here
|
|
@ -0,0 +1,23 @@
|
||||||
|
error[E0284]: type annotations needed: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
||||||
|
--> $DIR/issue-84660-unsoundness.rs:22:37
|
||||||
|
|
|
||||||
|
LL | fn convert(_i: In) -> Self::Out {
|
||||||
|
| _____________________________________^
|
||||||
|
LL | |
|
||||||
|
LL | | unreachable!();
|
||||||
|
LL | | }
|
||||||
|
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
||||||
|
|
||||||
|
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
||||||
|
--> $DIR/issue-84660-unsoundness.rs:28:1
|
||||||
|
|
|
||||||
|
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
|
| ------------------------------------ first implementation here
|
||||||
|
...
|
||||||
|
LL | impl<In, Out> Trait<(), In> for Out {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0119, E0284.
|
||||||
|
For more information about an error, try `rustc --explain E0119`.
|
|
@ -1,6 +1,10 @@
|
||||||
// Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an
|
// Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an
|
||||||
// impl header being accepted was used to create unsoundness.
|
// impl header being accepted was used to create unsoundness.
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
|
@ -16,11 +20,13 @@ trait Trait<T, In> {
|
||||||
impl<In, Out> Trait<Bar, In> for Out {
|
impl<In, Out> Trait<Bar, In> for Out {
|
||||||
type Out = Out;
|
type Out = Out;
|
||||||
fn convert(_i: In) -> Self::Out {
|
fn convert(_i: In) -> Self::Out {
|
||||||
|
//[next]~^ ERROR: type annotations needed
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<In, Out> Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait<Bar, _>`
|
impl<In, Out> Trait<(), In> for Out {
|
||||||
|
//~^ ERROR conflicting implementations of trait `Trait<Bar, _>`
|
||||||
type Out = In;
|
type Out = In;
|
||||||
fn convert(i: In) -> Self::Out {
|
fn convert(i: In) -> Self::Out {
|
||||||
i
|
i
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@check-pass
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
type FooX = impl Debug;
|
type FooX = impl Debug;
|
||||||
|
@ -10,8 +15,6 @@ trait Foo<A> { }
|
||||||
impl Foo<()> for () {}
|
impl Foo<()> for () {}
|
||||||
|
|
||||||
fn foo() -> impl Foo<FooX> {
|
fn foo() -> impl Foo<FooX> {
|
||||||
//~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
|
|
||||||
// FIXME(type-alias-impl-trait): We could probably make this work.
|
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0283]: type annotations needed: cannot satisfy `(): Foo<FooX>`
|
||||||
|
--> $DIR/nested-tait-inference2.rs:17:13
|
||||||
|
|
|
||||||
|
LL | fn foo() -> impl Foo<FooX> {
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: multiple `impl`s satisfying `(): Foo<FooX>` found
|
||||||
|
--> $DIR/nested-tait-inference2.rs:14:1
|
||||||
|
|
|
||||||
|
LL | impl Foo<()> for () {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | impl Foo<u32> for () {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0283`.
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0284]: type annotations needed: cannot satisfy `impl Foo<FooX> == ()`
|
||||||
|
--> $DIR/nested-tait-inference2.rs:19:5
|
||||||
|
|
|
||||||
|
LL | ()
|
||||||
|
| ^^ cannot satisfy `impl Foo<FooX> == ()`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0284`.
|
|
@ -1,6 +1,10 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
type FooX = impl Debug;
|
type FooX = impl Debug;
|
||||||
|
@ -11,8 +15,9 @@ impl Foo<()> for () {}
|
||||||
impl Foo<u32> for () {}
|
impl Foo<u32> for () {}
|
||||||
|
|
||||||
fn foo() -> impl Foo<FooX> {
|
fn foo() -> impl Foo<FooX> {
|
||||||
//~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
|
//[current]~^ ERROR: cannot satisfy `(): Foo<FooX>`
|
||||||
()
|
()
|
||||||
|
//[next]~^ ERROR: cannot satisfy `impl Foo<FooX> == ()`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
|
|
||||||
--> $DIR/nested-tait-inference2.rs:13:13
|
|
||||||
|
|
|
||||||
LL | fn foo() -> impl Foo<FooX> {
|
|
||||||
| ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
|
|
||||||
LL |
|
|
||||||
LL | ()
|
|
||||||
| -- return type was inferred to be `()` here
|
|
||||||
|
|
|
||||||
= help: the following other types implement trait `Foo<A>`:
|
|
||||||
<() as Foo<()>>
|
|
||||||
<() as Foo<u32>>
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -22,21 +22,17 @@ note: previous use here
|
||||||
LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) }
|
LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) }
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: concrete type differs from previous defining opaque type use
|
||||||
--> $DIR/normalize-hidden-types.rs:43:25
|
--> $DIR/normalize-hidden-types.rs:43:25
|
||||||
|
|
|
|
||||||
LL | type Opaque = impl Sized;
|
|
||||||
| ---------- the expected opaque type
|
|
||||||
...
|
|
||||||
LL | let _: Opaque = dyn_hoops::<u8>(0);
|
LL | let _: Opaque = dyn_hoops::<u8>(0);
|
||||||
| ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())`
|
| ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
|
||||||
| |
|
|
||||||
| expected due to this
|
|
||||||
|
|
|
|
||||||
= note: expected opaque type `typeck::Opaque`
|
note: previous use here
|
||||||
found raw pointer `*const (dyn FnOnce(()) + 'static)`
|
--> $DIR/normalize-hidden-types.rs:44:9
|
||||||
= help: consider constraining the associated type `<u8 as Trait>::Gat<'_>` to `()` or calling a method that returns `<u8 as Trait>::Gat<'_>`
|
|
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
LL | None
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: concrete type differs from previous defining opaque type use
|
error: concrete type differs from previous defining opaque type use
|
||||||
--> $DIR/normalize-hidden-types.rs:52:25
|
--> $DIR/normalize-hidden-types.rs:52:25
|
||||||
|
@ -52,4 +48,3 @@ LL | None
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
error[E0277]: can't compare `i32` with `Foo`
|
|
||||||
--> $DIR/self-referential-2.rs:10:13
|
|
||||||
|
|
|
||||||
LL | fn bar() -> Bar {
|
|
||||||
| ^^^ no implementation for `i32 == Foo`
|
|
||||||
LL | 42_i32
|
|
||||||
| ------ return type was inferred to be `i32` here
|
|
||||||
|
|
|
||||||
= help: the trait `PartialEq<Foo>` is not implemented for `i32`
|
|
||||||
= help: the trait `PartialEq` is implemented for `i32`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,14 +1,14 @@
|
||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@[next] check-pass
|
//@ check-pass
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type Foo = impl std::fmt::Debug;
|
type Foo = impl std::fmt::Debug;
|
||||||
type Bar = impl PartialEq<Foo>;
|
type Bar = impl PartialEq<Foo>;
|
||||||
|
|
||||||
fn bar() -> Bar {
|
fn bar() -> Bar {
|
||||||
42_i32 //[current]~^ ERROR can't compare `i32` with `Foo`
|
42_i32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
|
type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
|
||||||
|
|
||||||
fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
||||||
//~^ ERROR can't compare `&i32` with `Bar<'a, 'b>`
|
//~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>`
|
||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
error[E0277]: can't compare `&i32` with `Bar<'a, 'b>`
|
error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>`
|
||||||
--> $DIR/self-referential-3.rs:7:31
|
--> $DIR/self-referential-3.rs:7:31
|
||||||
|
|
|
|
||||||
LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
||||||
| ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>`
|
| ^^^^^^^^^^^
|
||||||
LL |
|
|
||||||
LL | i
|
|
||||||
| - return type was inferred to be `&i32` here
|
|
||||||
|
|
|
|
||||||
= help: the trait `PartialEq<Bar<'a, 'b>>` is not implemented for `&i32`
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
|
||||||
= help: the trait `PartialEq` is implemented for `i32`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
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`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue