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:
Matthias Krüger 2023-10-05 19:24:34 +02:00 committed by GitHub
commit 08cc7428d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 143 additions and 55 deletions

View file

@ -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 };

View file

@ -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

View file

@ -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]

View file

@ -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;
+ }
+

View file

@ -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;
+ }
+

View 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();
})
}

View file

@ -0,0 +1,7 @@
// check-pass
fn ages() -> Option<impl Iterator> {
None::<std::slice::Iter<()>>
}
fn main(){}

View 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(),
}
}

View 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(){}

View 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() {}