Rollup merge of #116415 - ouz-a:move_subtyper, r=oli-obk
Move subtyper below reveal_all and change reveal_all In previous attempt https://github.com/rust-lang/rust/pull/116378 we tried to handle `Opaque` in few different places, but this isn't necessary, after moving subtyper below reveal_all and calling `super_place` on reveal_all, issues cease to exist. r? ``@oli-obk`` Fixes https://github.com/rust-lang/rust/issues/116332 Fixes https://github.com/rust-lang/rust/issues/116265 Fixes https://github.com/rust-lang/rust/issues/116383 Fixes https://github.com/rust-lang/rust/issues/116333
This commit is contained in:
commit
08cc7428d9
10 changed files with 143 additions and 55 deletions
|
@ -24,6 +24,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
|
|||
rvalue: &mut Rvalue<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
// We don't need to do anything for deref temps as they are
|
||||
// not part of the source code, but used for desugaring purposes.
|
||||
if self.local_decls[place.local].is_deref_temp() {
|
||||
return;
|
||||
}
|
||||
let mut place_ty = place.ty(self.local_decls, self.tcx).ty;
|
||||
let mut rval_ty = rvalue.ty(self.local_decls, self.tcx);
|
||||
// Not erasing this causes `Free Regions` errors in validator,
|
||||
|
@ -48,7 +53,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
|
|||
// // gets transformed to
|
||||
// let temp: rval_ty = rval;
|
||||
// let place: place_ty = temp as place_ty;
|
||||
//
|
||||
pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let patch = MirPatch::new(body);
|
||||
let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };
|
||||
|
|
|
@ -467,7 +467,6 @@ pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
|
|||
/// After this series of passes, no lifetime analysis based on borrowing can be done.
|
||||
fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let passes: &[&dyn MirPass<'tcx>] = &[
|
||||
&add_subtyping_projections::Subtyper,
|
||||
&cleanup_post_borrowck::CleanupPostBorrowck,
|
||||
&remove_noop_landing_pads::RemoveNoopLandingPads,
|
||||
&simplify::SimplifyCfg::EarlyOpt,
|
||||
|
@ -483,6 +482,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
// These next passes must be executed together
|
||||
&add_call_guards::CriticalCallEdges,
|
||||
&reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too.
|
||||
&add_subtyping_projections::Subtyper, // calling this after reveal_all ensures that we don't deal with opaque types
|
||||
&elaborate_drops::ElaborateDrops,
|
||||
// This will remove extraneous landing pads which are no longer
|
||||
// necessary as well as well as forcing any call in a non-unwinding
|
||||
|
|
|
@ -46,16 +46,18 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
|
|||
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
self.super_place(place, _context, _location);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) {
|
||||
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
|
||||
// We have to use `try_normalize_erasing_regions` here, since it's
|
||||
// possible that we visit impossible-to-satisfy where clauses here,
|
||||
// see #91745
|
||||
if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) {
|
||||
constant.const_ = c;
|
||||
}
|
||||
self.super_constant(constant, location);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -7,12 +7,11 @@
|
|||
let mut _2: std::pin::Pin<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>;
|
||||
let mut _3: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
let mut _4: {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ let mut _6: bool;
|
||||
+ let mut _5: bool;
|
||||
scope 1 {
|
||||
debug _r => _1;
|
||||
}
|
||||
+ scope 2 (inlined g) {
|
||||
+ let mut _5: {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ }
|
||||
+ scope 3 (inlined Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new) {
|
||||
+ debug pointer => _3;
|
||||
|
@ -23,10 +22,10 @@
|
|||
+ }
|
||||
+ }
|
||||
+ scope 6 (inlined g::{closure#0}) {
|
||||
+ debug a => _6;
|
||||
+ let mut _7: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ let mut _8: u32;
|
||||
+ let mut _9: i32;
|
||||
+ debug a => _5;
|
||||
+ let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ let mut _7: u32;
|
||||
+ let mut _8: i32;
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
|
@ -35,28 +34,25 @@
|
|||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
- _4 = g() -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
|
||||
+ _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
|
||||
+ StorageDead(_5);
|
||||
+ _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
|
||||
+ _3 = &mut _4;
|
||||
+ _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
|
||||
+ StorageDead(_3);
|
||||
+ StorageLive(_5);
|
||||
+ _5 = const false;
|
||||
+ StorageLive(_6);
|
||||
+ _6 = const false;
|
||||
+ StorageLive(_7);
|
||||
+ StorageLive(_8);
|
||||
+ _7 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
|
||||
+ _8 = discriminant((*_7));
|
||||
+ switchInt(move _8) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
|
||||
+ _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
|
||||
+ _7 = discriminant((*_6));
|
||||
+ switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _3 = &mut _4;
|
||||
- _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind unreachable];
|
||||
+ StorageDead(_8);
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ StorageDead(_2);
|
||||
+ drop(_4) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
@ -73,8 +69,8 @@
|
|||
bb3: {
|
||||
- StorageDead(_2);
|
||||
- drop(_4) -> [return: bb4, unwind unreachable];
|
||||
+ StorageLive(_9);
|
||||
+ switchInt(_6) -> [0: bb4, otherwise: bb5];
|
||||
+ StorageLive(_8);
|
||||
+ switchInt(_5) -> [0: bb4, otherwise: bb5];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
|
@ -82,18 +78,18 @@
|
|||
- _0 = const ();
|
||||
- StorageDead(_1);
|
||||
- return;
|
||||
+ _9 = const 13_i32;
|
||||
+ _8 = const 13_i32;
|
||||
+ goto -> bb6;
|
||||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ _9 = const 7_i32;
|
||||
+ _8 = const 7_i32;
|
||||
+ goto -> bb6;
|
||||
+ }
|
||||
+
|
||||
+ bb6: {
|
||||
+ _1 = GeneratorState::<i32, bool>::Yielded(move _9);
|
||||
+ discriminant((*_7)) = 3;
|
||||
+ _1 = GeneratorState::<i32, bool>::Yielded(move _8);
|
||||
+ discriminant((*_6)) = 3;
|
||||
+ goto -> bb1;
|
||||
+ }
|
||||
+
|
||||
|
@ -102,10 +98,10 @@
|
|||
+ }
|
||||
+
|
||||
+ bb8: {
|
||||
+ StorageLive(_9);
|
||||
+ StorageDead(_9);
|
||||
+ _1 = GeneratorState::<i32, bool>::Complete(_6);
|
||||
+ discriminant((*_7)) = 1;
|
||||
+ StorageLive(_8);
|
||||
+ StorageDead(_8);
|
||||
+ _1 = GeneratorState::<i32, bool>::Complete(_5);
|
||||
+ discriminant((*_6)) = 1;
|
||||
+ goto -> bb1;
|
||||
+ }
|
||||
+
|
||||
|
|
|
@ -7,12 +7,11 @@
|
|||
let mut _2: std::pin::Pin<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>;
|
||||
let mut _3: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
let mut _4: {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ let mut _6: bool;
|
||||
+ let mut _5: bool;
|
||||
scope 1 {
|
||||
debug _r => _1;
|
||||
}
|
||||
+ scope 2 (inlined g) {
|
||||
+ let mut _5: {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ }
|
||||
+ scope 3 (inlined Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new) {
|
||||
+ debug pointer => _3;
|
||||
|
@ -23,10 +22,10 @@
|
|||
+ }
|
||||
+ }
|
||||
+ scope 6 (inlined g::{closure#0}) {
|
||||
+ debug a => _6;
|
||||
+ let mut _7: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ let mut _8: u32;
|
||||
+ let mut _9: i32;
|
||||
+ debug a => _5;
|
||||
+ let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
|
||||
+ let mut _7: u32;
|
||||
+ let mut _8: i32;
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
|
@ -38,10 +37,7 @@
|
|||
- }
|
||||
-
|
||||
- bb1: {
|
||||
+ StorageLive(_5);
|
||||
+ _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
|
||||
+ _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
|
||||
+ StorageDead(_5);
|
||||
+ _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
|
||||
_3 = &mut _4;
|
||||
- _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind: bb5];
|
||||
- }
|
||||
|
@ -50,20 +46,20 @@
|
|||
+ _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
|
||||
StorageDead(_3);
|
||||
- _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = const false;
|
||||
+ StorageLive(_6);
|
||||
+ _6 = const false;
|
||||
+ StorageLive(_7);
|
||||
+ StorageLive(_8);
|
||||
+ _7 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
|
||||
+ _8 = discriminant((*_7));
|
||||
+ switchInt(move _8) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
|
||||
+ _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
|
||||
+ _7 = discriminant((*_6));
|
||||
+ switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
|
||||
}
|
||||
|
||||
- bb3: {
|
||||
+ bb1: {
|
||||
+ StorageDead(_8);
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_2);
|
||||
- drop(_4) -> [return: bb4, unwind: bb6];
|
||||
+ drop(_4) -> [return: bb2, unwind: bb4];
|
||||
|
@ -89,23 +85,23 @@
|
|||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ StorageLive(_9);
|
||||
+ switchInt(_6) -> [0: bb6, otherwise: bb7];
|
||||
+ StorageLive(_8);
|
||||
+ switchInt(_5) -> [0: bb6, otherwise: bb7];
|
||||
+ }
|
||||
+
|
||||
+ bb6: {
|
||||
+ _9 = const 13_i32;
|
||||
+ _8 = const 13_i32;
|
||||
+ goto -> bb8;
|
||||
+ }
|
||||
+
|
||||
+ bb7: {
|
||||
+ _9 = const 7_i32;
|
||||
+ _8 = const 7_i32;
|
||||
+ goto -> bb8;
|
||||
+ }
|
||||
+
|
||||
+ bb8: {
|
||||
+ _1 = GeneratorState::<i32, bool>::Yielded(move _9);
|
||||
+ discriminant((*_7)) = 3;
|
||||
+ _1 = GeneratorState::<i32, bool>::Yielded(move _8);
|
||||
+ discriminant((*_6)) = 3;
|
||||
+ goto -> bb1;
|
||||
+ }
|
||||
+
|
||||
|
@ -114,10 +110,10 @@
|
|||
+ }
|
||||
+
|
||||
+ bb10: {
|
||||
+ StorageLive(_9);
|
||||
+ StorageDead(_9);
|
||||
+ _1 = GeneratorState::<i32, bool>::Complete(_6);
|
||||
+ discriminant((*_7)) = 1;
|
||||
+ StorageLive(_8);
|
||||
+ StorageDead(_8);
|
||||
+ _1 = GeneratorState::<i32, bool>::Complete(_5);
|
||||
+ discriminant((*_6)) = 1;
|
||||
+ goto -> bb1;
|
||||
+ }
|
||||
+
|
||||
|
|
18
tests/ui/impl-trait/impl-subtyper.rs
Normal file
18
tests/ui/impl-trait/impl-subtyper.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// check-pass
|
||||
|
||||
#![crate_type = "lib"]
|
||||
fn checkpoints() -> impl Iterator {
|
||||
Some(()).iter().flat_map(|_| std::iter::once(()))
|
||||
}
|
||||
|
||||
fn block_checkpoints() -> impl Iterator {
|
||||
checkpoints()
|
||||
}
|
||||
|
||||
fn iter_raw() -> impl Iterator {
|
||||
let mut iter = block_checkpoints();
|
||||
|
||||
(0..9).map(move |_| {
|
||||
iter.next();
|
||||
})
|
||||
}
|
7
tests/ui/impl-trait/impl-subtyper2.rs
Normal file
7
tests/ui/impl-trait/impl-subtyper2.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
// check-pass
|
||||
|
||||
fn ages() -> Option<impl Iterator> {
|
||||
None::<std::slice::Iter<()>>
|
||||
}
|
||||
|
||||
fn main(){}
|
32
tests/ui/type-alias-impl-trait/normalize-alias-type.rs
Normal file
32
tests/ui/type-alias-impl-trait/normalize-alias-type.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
// check-pass
|
||||
// compile-flags: -Z mir-opt-level=3
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![crate_type = "lib"]
|
||||
pub trait Tr {
|
||||
fn get(&self) -> u32;
|
||||
}
|
||||
|
||||
impl Tr for (u32,) {
|
||||
#[inline]
|
||||
fn get(&self) -> u32 { self.0 }
|
||||
}
|
||||
|
||||
pub fn tr1() -> impl Tr {
|
||||
(32,)
|
||||
}
|
||||
|
||||
pub fn tr2() -> impl Tr {
|
||||
struct Inner {
|
||||
x: X,
|
||||
}
|
||||
type X = impl Tr;
|
||||
impl Tr for Inner {
|
||||
fn get(&self) -> u32 {
|
||||
self.x.get()
|
||||
}
|
||||
}
|
||||
|
||||
Inner {
|
||||
x: tr1(),
|
||||
}
|
||||
}
|
14
tests/ui/type-alias-impl-trait/tait-normalize.rs
Normal file
14
tests/ui/type-alias-impl-trait/tait-normalize.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
fn enum_upvar() {
|
||||
type T = impl Copy;
|
||||
let foo: T = Some((1u32, 2u32));
|
||||
let x = move || match foo {
|
||||
None => (),
|
||||
Some((a, b)) => (),
|
||||
};
|
||||
}
|
||||
|
||||
fn main(){}
|
19
tests/ui/type/subtyping-opaque-type.rs
Normal file
19
tests/ui/type/subtyping-opaque-type.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// check-pass
|
||||
// compile-flags: -Zvalidate-mir
|
||||
trait Duh {}
|
||||
|
||||
impl Duh for i32 {}
|
||||
|
||||
trait Trait {
|
||||
type Assoc: Duh;
|
||||
}
|
||||
|
||||
impl<R: Duh, F: FnMut() -> R> Trait for F {
|
||||
type Assoc = R;
|
||||
}
|
||||
|
||||
fn foo() -> impl Trait<Assoc = impl Send> {
|
||||
|| 42
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Reference in a new issue