diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-04-12 23:17:01 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-12 23:17:01 +0200 |
| commit | e96304b73d7913ab4bc14358b0d3fee7586ab62a (patch) | |
| tree | f4db843f4bf7b5ed135024b22c30c38777b68b8b /src | |
| parent | d63a46ad2845683266479ee6e945ac476a85edc6 (diff) | |
| parent | 6d0349d2ea97e2a3e208e0342a6a95d6b90d92ea (diff) | |
| download | rust-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')
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 |
