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.
Normalize all opaque types when converting ParamEnv to Reveal::All
When we normalize a type using a ParamEnv with a reveal mode of RevealMode::All, we will normalize opaque types to their underlying types (e.g. `type MyOpaque = impl Foo` -> `StructThatImplsFoo`). However, the ParamEnv may still have predicates referring to the un-normalized opaque type (e.g. `<T as MyTrait<MyOpaque>>`). This can cause trait projection to fail, since a type containing normalized opaque types will not match up with the un-normalized type in the `ParamEnv`. To fix this, we now explicitly normalize all opaque types in caller_bounds of a `ParamEnv` when changing its mode to `RevealMode::All`. This ensures that all predicatse will refer to the underlying types of any opaque types involved, allowing them to be matched up properly during projection. To reflect the fact that normalization is occuring, `ParamEnv::with_reveal_all` is renamed to `ParamEnv::with_reveal_all_normalized` Fixes rust-lang#65918
- Loading branch information
Showing
9 changed files
with
155 additions
and
76 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
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
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
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
52 changes: 52 additions & 0 deletions
52
src/test/ui/type-alias-impl-trait/opaque-type-in-predicate.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,52 @@ | ||
// run-pass | ||
// Regression test for issue #65918 - checks that we do not | ||
// ICE when attempting to normalize a predicate containting | ||
// opaque types | ||
|
||
#![feature(type_alias_impl_trait)] | ||
|
||
use std::marker::PhantomData; | ||
|
||
/* copied Index and TryFrom for convinience (and simplicity) */ | ||
trait MyIndex<T> { | ||
type O; | ||
fn my_index(self) -> Self::O; | ||
} | ||
trait MyFrom<T>: Sized { | ||
type Error; | ||
fn my_from(value: T) -> Result<Self, Self::Error>; | ||
} | ||
|
||
/* MCVE starts here */ | ||
trait F {} | ||
impl F for () {} | ||
type DummyT<T> = impl F; | ||
fn _dummy_t<T>() -> DummyT<T> {} | ||
|
||
struct Phantom1<T>(PhantomData<T>); | ||
struct Phantom2<T>(PhantomData<T>); | ||
struct Scope<T>(Phantom2<DummyT<T>>); | ||
|
||
impl<T> Scope<T> { | ||
fn new() -> Self { | ||
Scope(Phantom2(PhantomData)) | ||
} | ||
} | ||
|
||
impl<T> MyFrom<Phantom2<T>> for Phantom1<T> { | ||
type Error = (); | ||
fn my_from(_: Phantom2<T>) -> Result<Self, Self::Error> { | ||
Ok(Phantom1(PhantomData)) | ||
} | ||
} | ||
|
||
impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> { | ||
type O = T; | ||
fn my_index(self) -> Self::O { | ||
MyFrom::my_from(self.0).ok().unwrap() | ||
} | ||
} | ||
|
||
fn main() { | ||
let _pos: Phantom1<DummyT<()>> = Scope::new().my_index(); | ||
} |