forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes rust-lang#63677 This commit treats all opaque types as 'remote' with respect to coherence checking, instead of causing an ICE. This ensures that opaque types cannot ever 'leak' information about the underlying type (e.g. whether or not it is a local or remote type)
- Loading branch information
Showing
5 changed files
with
85 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub trait ForeignTrait {} | ||
pub struct ForeignType<T>(pub T); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// aux-build:foreign-crate.rs | ||
// This test ensures that an opaque type cannot be used | ||
// to bypass the normal orphan impl rules. | ||
// Specifically, it should not be possible to implement | ||
// a trait for a local opaque type which resolves to a foreign type. | ||
// | ||
// This should also be prevented by the fact that writing impls for opaque | ||
// types is not allowed at all, but this test makes sure to test | ||
// the orphan rule specifically | ||
#![feature(type_alias_impl_trait)] | ||
|
||
extern crate foreign_crate; | ||
|
||
trait LocalTrait {} | ||
impl<T> LocalTrait for foreign_crate::ForeignType<T> {} | ||
|
||
type AliasOfForeignType<T> = impl LocalTrait; | ||
fn use_alias<T>(val: T) -> AliasOfForeignType<T> { | ||
foreign_crate::ForeignType(val) | ||
} | ||
|
||
impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {} | ||
//~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates | ||
--> $DIR/coherence.rs:22:6 | ||
| | ||
LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {} | ||
| ^ unconstrained type parameter | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0207`. |
21 changes: 21 additions & 0 deletions
21
src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// check-pass | ||
// Regression test for issue #63677 - ensure that | ||
// coherence checking can properly handle 'impl trait' | ||
// in type aliases | ||
#![feature(type_alias_impl_trait)] | ||
|
||
pub trait Trait {} | ||
pub struct S1<T>(T); | ||
pub struct S2<T>(T); | ||
|
||
pub type T1 = impl Trait; | ||
pub type T2 = S1<T1>; | ||
pub type T3 = S2<T2>; | ||
|
||
impl<T> Trait for S1<T> {} | ||
impl<T: Trait> S2<T> {} | ||
impl T3 {} | ||
|
||
pub fn use_t1() -> T1 { S1(()) } | ||
|
||
fn main() {} |