prevent opaque types from appearing in impl headers
This commit is contained in:
parent
d00e77078c
commit
7d5bbf55f2
@ -141,13 +141,22 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
|
||||
}
|
||||
}
|
||||
|
||||
if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() {
|
||||
let reported = tcx
|
||||
.sess
|
||||
.struct_span_err(sp, "cannot implement trait on type alias impl trait")
|
||||
.span_note(tcx.def_span(def_id), "type alias impl trait defined here")
|
||||
.emit();
|
||||
return Err(reported);
|
||||
// Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples,
|
||||
// and #84660 where it would otherwise allow unsoundness.
|
||||
if trait_ref.has_opaque_types() {
|
||||
for ty in trait_ref.substs {
|
||||
for ty in ty.walk() {
|
||||
let ty::subst::GenericArgKind::Type(ty) = ty.unpack() else { continue };
|
||||
let ty::Opaque(def_id, _) = ty.kind() else { continue };
|
||||
let reported = tcx
|
||||
.sess
|
||||
.struct_span_err(sp, "cannot implement trait on type alias impl trait")
|
||||
.span_note(tcx.def_span(def_id), "type alias impl trait defined here")
|
||||
.emit();
|
||||
return Err(reported);
|
||||
}
|
||||
}
|
||||
span_bug!(sp, "opque type not found, but `has_opaque_types` is set")
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -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() {}
|
||||
|
@ -1,3 +1,15 @@
|
||||
error: cannot implement trait on type alias impl trait
|
||||
--> $DIR/auto-trait.rs:21:1
|
||||
|
|
||||
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`.
|
||||
|
@ -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() {}
|
||||
|
@ -1,3 +1,15 @@
|
||||
error: cannot implement trait on type alias impl trait
|
||||
--> $DIR/negative-reasoning.rs:19:1
|
||||
|
|
||||
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`.
|
||||
|
@ -5,13 +5,14 @@
|
||||
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() {}
|
||||
|
@ -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:1
|
||||
|
|
||||
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`.
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
mod a {
|
||||
type Foo = impl PartialEq<(Foo, i32)>;
|
||||
//~^ ERROR unconstrained opaque type
|
||||
|
||||
struct Bar;
|
||||
|
||||
@ -15,13 +14,12 @@ fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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:5
|
||||
|
|
||||
LL | impl PartialEq<(Foo, i32)> for Bar {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
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: unconstrained opaque type
|
||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:17:16
|
||||
|
|
||||
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||
error: aborting due to previous error
|
||||
|
||||
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
|
||||
|
||||
For more information about this error, try `rustc --explain E0276`.
|
||||
|
@ -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> {
|
||||
()
|
||||
|
@ -1,10 +1,14 @@
|
||||
error: unconstrained opaque type
|
||||
error: cannot implement trait on type alias impl trait
|
||||
--> $DIR/nested-tait-inference3.rs:10:1
|
||||
|
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user