about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-04-12 23:17:01 +0200
committerGitHub <noreply@github.com>2022-04-12 23:17:01 +0200
commite96304b73d7913ab4bc14358b0d3fee7586ab62a (patch)
treef4db843f4bf7b5ed135024b22c30c38777b68b8b /src
parentd63a46ad2845683266479ee6e945ac476a85edc6 (diff)
parent6d0349d2ea97e2a3e208e0342a6a95d6b90d92ea (diff)
downloadrust-e96304b73d7913ab4bc14358b0d3fee7586ab62a.tar.gz
rust-e96304b73d7913ab4bc14358b0d3fee7586ab62a.zip
Rollup merge of #95973 - oli-obk:tait_ub3, r=compiler-errors
prevent opaque types from appearing in impl headers

cc `@lqd`

opaque types are not distinguishable from their hidden type at the codegen stage. So we could either end up with cases where the hidden type doesn't implement the trait (which will thus ICE) or where the hidden type does implement the trait (so we'd be using its impl instead of the one written for the opaque type). This can even lead to unsound behaviour without unsafe code.

Fixes https://github.com/rust-lang/rust/issues/86411.
Fixes https://github.com/rust-lang/rust/issues/84660.

rebase of #87382 plus some diagnostic tweaks
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/impl-trait/auto-trait.rs1
-rw-r--r--src/test/ui/impl-trait/auto-trait.stderr14
-rw-r--r--src/test/ui/impl-trait/negative-reasoning.rs1
-rw-r--r--src/test/ui/impl-trait/negative-reasoning.stderr14
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs3
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr16
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs4
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr25
-rw-r--r--src/test/ui/traits/alias/issue-83613.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs41
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr10
17 files changed, 153 insertions, 41 deletions
diff --git a/src/test/ui/impl-trait/auto-trait.rs b/src/test/ui/impl-trait/auto-trait.rs
index 35994e4a5ba..afa95645a27 100644
--- a/src/test/ui/impl-trait/auto-trait.rs
+++ b/src/test/ui/impl-trait/auto-trait.rs
@@ -20,6 +20,7 @@ impl<T: Send> AnotherTrait for T {}
 // in the future.)
 impl AnotherTrait for D<OpaqueType> {
     //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+    //~| ERROR cannot implement trait on type alias impl trait
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr
index 81009413c9a..3b360f492b7 100644
--- a/src/test/ui/impl-trait/auto-trait.stderr
+++ b/src/test/ui/impl-trait/auto-trait.stderr
@@ -1,3 +1,15 @@
+error: cannot implement trait on type alias impl trait
+  --> $DIR/auto-trait.rs:21:25
+   |
+LL | impl AnotherTrait for D<OpaqueType> {
+   |                         ^^^^^^^^^^
+   |
+note: type alias impl trait defined here
+  --> $DIR/auto-trait.rs:7:19
+   |
+LL | type OpaqueType = impl OpaqueTrait;
+   |                   ^^^^^^^^^^^^^^^^
+
 error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
   --> $DIR/auto-trait.rs:21:1
    |
@@ -7,6 +19,6 @@ LL | impl<T: Send> AnotherTrait for T {}
 LL | impl AnotherTrait for D<OpaqueType> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/negative-reasoning.rs b/src/test/ui/impl-trait/negative-reasoning.rs
index 70e24a3a9d0..da69bb349ae 100644
--- a/src/test/ui/impl-trait/negative-reasoning.rs
+++ b/src/test/ui/impl-trait/negative-reasoning.rs
@@ -18,6 +18,7 @@ impl<T: std::fmt::Debug> AnotherTrait for T {}
 // This is in error, because we cannot assume that `OpaqueType: !Debug`
 impl AnotherTrait for D<OpaqueType> {
     //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+    //~| ERROR cannot implement trait on type alias impl trait
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr
index 6b8cc9e7374..98f9fbd8fef 100644
--- a/src/test/ui/impl-trait/negative-reasoning.stderr
+++ b/src/test/ui/impl-trait/negative-reasoning.stderr
@@ -1,3 +1,15 @@
+error: cannot implement trait on type alias impl trait
+  --> $DIR/negative-reasoning.rs:19:25
+   |
+LL | impl AnotherTrait for D<OpaqueType> {
+   |                         ^^^^^^^^^^
+   |
+note: type alias impl trait defined here
+  --> $DIR/negative-reasoning.rs:7:19
+   |
+LL | type OpaqueType = impl OpaqueTrait;
+   |                   ^^^^^^^^^^^^^^^^
+
 error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
   --> $DIR/negative-reasoning.rs:19:1
    |
@@ -9,6 +21,6 @@ LL | impl AnotherTrait for D<OpaqueType> {
    |
    = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
index 6b200d7e3a8..621c4ea6e0d 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
@@ -5,13 +5,14 @@ type Foo = impl PartialEq<(Foo, i32)>;
 struct Bar;
 
 impl PartialEq<(Foo, i32)> for Bar {
+//~^ ERROR cannot implement trait on type alias impl trait
     fn eq(&self, _other: &(Foo, i32)) -> bool {
         true
     }
 }
 
 fn foo() -> Foo {
-    Bar //~ ERROR can't compare `Bar` with `(Bar, i32)`
+    Bar
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
index 6cd63db44fa..2ef1697ba34 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
@@ -1,12 +1,14 @@
-error[E0277]: can't compare `Bar` with `(Bar, i32)`
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:14:5
+error: cannot implement trait on type alias impl trait
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:7:17
    |
-LL |     Bar
-   |     ^^^ no implementation for `Bar == (Bar, i32)`
+LL | impl PartialEq<(Foo, i32)> for Bar {
+   |                 ^^^
    |
-   = help: the trait `PartialEq<(Bar, i32)>` is not implemented for `Bar`
-   = help: the trait `PartialEq<(Foo, i32)>` is implemented for `Bar`
+note: type alias impl trait defined here
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:3:12
+   |
+LL | type Foo = impl PartialEq<(Foo, i32)>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
index 6aa832cde71..df7966f00e1 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
@@ -2,7 +2,6 @@
 
 mod a {
     type Foo = impl PartialEq<(Foo, i32)>;
-    //~^ ERROR unconstrained opaque type
 
     struct Bar;
 
@@ -15,13 +14,12 @@ mod a {
 
 mod b {
     type Foo = impl PartialEq<(Foo, i32)>;
-    //~^ ERROR unconstrained opaque type
 
     struct Bar;
 
     impl PartialEq<(Foo, i32)> for Bar {
+        //~^ ERROR cannot implement trait on type alias impl trait
         fn eq(&self, _other: &(Bar, i32)) -> bool {
-            //~^ ERROR impl has stricter requirements than trait
             true
         }
     }
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index 19d5cdb9d0a..6cd63dcf81c 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -1,25 +1,14 @@
-error: unconstrained opaque type
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
+error: cannot implement trait on type alias impl trait
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:20:21
    |
-LL |     type Foo = impl PartialEq<(Foo, i32)>;
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     impl PartialEq<(Foo, i32)> for Bar {
+   |                     ^^^
    |
-   = note: `Foo` must be used in combination with a concrete type within the same module
-
-error: unconstrained opaque type
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:17:16
+note: type alias impl trait defined here
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:16:16
    |
 LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same module
-
-error[E0276]: impl has stricter requirements than trait
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:23:9
-   |
-LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `b::Bar: PartialEq<(b::Bar, i32)>`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0276`.
diff --git a/src/test/ui/traits/alias/issue-83613.stderr b/src/test/ui/traits/alias/issue-83613.stderr
index 4f19e6607c8..bbc240b6aec 100644
--- a/src/test/ui/traits/alias/issue-83613.stderr
+++ b/src/test/ui/traits/alias/issue-83613.stderr
@@ -1,8 +1,8 @@
 error: cannot implement trait on type alias impl trait
-  --> $DIR/issue-83613.rs:10:1
+  --> $DIR/issue-83613.rs:10:23
    |
 LL | impl AnotherTrait for OpaqueType {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^
    |
 note: type alias impl trait defined here
   --> $DIR/issue-83613.rs:4:19
diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.stderr b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
index 27680f0ad75..41bcea27e1f 100644
--- a/src/test/ui/type-alias-impl-trait/issue-65384.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
@@ -1,8 +1,8 @@
 error: cannot implement trait on type alias impl trait
-  --> $DIR/issue-65384.rs:10:1
+  --> $DIR/issue-65384.rs:10:18
    |
 LL | impl MyTrait for Bar {}
-   | ^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^
    |
 note: type alias impl trait defined here
   --> $DIR/issue-65384.rs:8:12
diff --git a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr
index 8689ee53660..2d4a6854a92 100644
--- a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr
@@ -1,8 +1,8 @@
 error: cannot implement trait on type alias impl trait
-  --> $DIR/issue-76202-trait-impl-for-tait.rs:16:1
+  --> $DIR/issue-76202-trait-impl-for-tait.rs:16:15
    |
 LL | impl Test for F {
-   | ^^^^^^^^^^^^^^^
+   |               ^
    |
 note: type alias impl trait defined here
   --> $DIR/issue-76202-trait-impl-for-tait.rs:9:10
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..fa25d8f762e
--- /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(type_alias_impl_trait)]
+
+trait Foo {}
+impl Foo for () {}
+type Bar = impl Foo;
+fn _defining_use() -> Bar {}
+
+trait TraitArg<T> {
+    fn f();
+}
+
+impl TraitArg<Bar> for () { //~ ERROR cannot implement trait
+    fn f() {
+        println!("ho");
+    }
+}
+
+fn main() {
+    <() as TraitArg<Bar>>::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..bb70d07be59
--- /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:15
+   |
+LL | impl TraitArg<Bar> 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..f12d1b6d953
--- /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);
+}
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..f2d600fb46c
--- /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:21
+   |
+LL | impl<In, Out> Trait<Bar, In> 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
+
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
index fbab5470b4f..ebf3a99bbf9 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
@@ -4,11 +4,11 @@
 use std::fmt::Debug;
 
 type FooX = impl Debug;
-//~^ unconstrained opaque type
 
 trait Foo<A> { }
 
 impl Foo<FooX> for () { }
+//~^ cannot implement trait on type alias impl trait
 
 fn foo() -> impl Foo<FooX> {
     ()
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
index b1d947a9ccf..4a3fb16733e 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
@@ -1,10 +1,14 @@
-error: unconstrained opaque type
+error: cannot implement trait on type alias impl trait
+  --> $DIR/nested-tait-inference3.rs:10:10
+   |
+LL | impl Foo<FooX> for () { }
+   |          ^^^^
+   |
+note: type alias impl trait defined here
   --> $DIR/nested-tait-inference3.rs:6:13
    |
 LL | type FooX = impl Debug;
    |             ^^^^^^^^^^
-   |
-   = note: `FooX` must be used in combination with a concrete type within the same module
 
 error: aborting due to previous error