diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs new file mode 100644 index 00000000000..1a0acca7881 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs @@ -0,0 +1,23 @@ +// Regression test for issues #84660 and #86411: both are variations on #76202. +// Tests that we don't ICE when we have an opaque type appearing anywhere in an impl header. + +#![feature(min_type_alias_impl_trait)] + +trait Foo {} +impl Foo for () {} +type Bar = impl Foo; +fn _defining_use() -> Bar {} + +trait TraitArg { + fn f(); +} + +impl TraitArg for () { //~ ERROR cannot implement trait + fn f() { + println!("ho"); + } +} + +fn main() { + <() as TraitArg>::f(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr new file mode 100644 index 00000000000..1b8eee40717 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/issue-84660-trait-impl-for-tait.rs:15:1 + | +LL | impl TraitArg for () { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type alias impl trait defined here + --> $DIR/issue-84660-trait-impl-for-tait.rs:8:12 + | +LL | type Bar = impl Foo; + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs new file mode 100644 index 00000000000..18213dfbe5b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -0,0 +1,41 @@ +// Another example from issue #84660, this time weaponized as a safe transmut: an opaque type in an +// impl header being accepted was used to create unsoundness. + +#![feature(min_type_alias_impl_trait)] + +trait Foo {} +impl Foo for () {} +type Bar = impl Foo; +fn _defining_use() -> Bar {} + +trait Trait { + type Out; + fn convert(i: In) -> Self::Out; +} + +impl Trait for Out { //~ ERROR cannot implement trait + type Out = Out; + fn convert(_i: In) -> Self::Out { + unreachable!(); + } +} + +impl Trait<(), In> for Out { + type Out = In; + fn convert(i: In) -> Self::Out { + i + } +} + +fn transmute(i: In) -> Out { + >::convert(i) +} + +fn main() { + let d; + { + let x = "Hello World".to_string(); + d = transmute::<&String, &String>(&x); + } + println!("{}", d); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr new file mode 100644 index 00000000000..b1128d830f9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/issue-84660-unsoundness.rs:16:1 + | +LL | impl Trait for Out { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type alias impl trait defined here + --> $DIR/issue-84660-unsoundness.rs:8:12 + | +LL | type Bar = impl Foo; + | ^^^^^^^^ + +error: aborting due to previous error +