summaryrefslogtreecommitdiffstats
path: root/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs')
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs41
1 files changed, 41 insertions, 0 deletions
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 000000000..f12d1b6d9
--- /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 transmute: an opaque type in an
+// impl header being accepted was used to create unsoundness.
+
+#![feature(type_alias_impl_trait)]
+
+trait Foo {}
+impl Foo for () {}
+type Bar = impl Foo;
+fn _defining_use() -> Bar {}
+
+trait Trait<T, In> {
+ type Out;
+ fn convert(i: In) -> Self::Out;
+}
+
+impl<In, Out> Trait<Bar, In> for Out { //~ ERROR cannot implement trait
+ type Out = Out;
+ fn convert(_i: In) -> Self::Out {
+ unreachable!();
+ }
+}
+
+impl<In, Out> Trait<(), In> for Out {
+ type Out = In;
+ fn convert(i: In) -> Self::Out {
+ i
+ }
+}
+
+fn transmute<In, Out>(i: In) -> Out {
+ <Out as Trait<Bar, In>>::convert(i)
+}
+
+fn main() {
+ let d;
+ {
+ let x = "Hello World".to_string();
+ d = transmute::<&String, &String>(&x);
+ }
+ println!("{}", d);
+}