From 3088c4b0466085a81f83fbe3a10822fac75591b5 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Tue, 3 Oct 2023 13:19:00 +0300 Subject: [PATCH] move subtyper change reveal_all --- .../src/add_subtyping_projections.rs | 6 ++- compiler/rustc_mir_transform/src/lib.rs | 2 +- .../rustc_mir_transform/src/reveal_all.rs | 4 +- ...ine_generator.main.Inline.panic-abort.diff | 48 +++++++++---------- ...ne_generator.main.Inline.panic-unwind.diff | 48 +++++++++---------- tests/ui/impl-trait/impl-subtyper.rs | 18 +++++++ tests/ui/impl-trait/impl-subtyper2.rs | 7 +++ .../normalize-alias-type.rs | 32 +++++++++++++ .../type-alias-impl-trait/tait-normalize.rs | 14 ++++++ tests/ui/type/subtyping-opaque-type.rs | 19 ++++++++ 10 files changed, 143 insertions(+), 55 deletions(-) create mode 100644 tests/ui/impl-trait/impl-subtyper.rs create mode 100644 tests/ui/impl-trait/impl-subtyper2.rs create mode 100644 tests/ui/type-alias-impl-trait/normalize-alias-type.rs create mode 100644 tests/ui/type-alias-impl-trait/tait-normalize.rs create mode 100644 tests/ui/type/subtyping-opaque-type.rs diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs index 1cc049d5a2265..e5be7c0ca76e2 100644 --- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs +++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs @@ -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 }; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 22381844d6dc2..c0a09b7a76127 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -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 diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index 55f1eac6f8468..1626cf3c035e6 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -46,16 +46,18 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) .collect::>(), ); + 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] diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff index d592ddfd183a0..06ee8c464d5ba 100644 --- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff @@ -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::::Yielded(move _9); -+ discriminant((*_7)) = 3; ++ _1 = GeneratorState::::Yielded(move _8); ++ discriminant((*_6)) = 3; + goto -> bb1; + } + @@ -102,10 +98,10 @@ + } + + bb8: { -+ StorageLive(_9); -+ StorageDead(_9); -+ _1 = GeneratorState::::Complete(_6); -+ discriminant((*_7)) = 1; ++ StorageLive(_8); ++ StorageDead(_8); ++ _1 = GeneratorState::::Complete(_5); ++ discriminant((*_6)) = 1; + goto -> bb1; + } + diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff index 120aa52ac0129..da29ba5f50d73 100644 --- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff @@ -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>::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::::Yielded(move _9); -+ discriminant((*_7)) = 3; ++ _1 = GeneratorState::::Yielded(move _8); ++ discriminant((*_6)) = 3; + goto -> bb1; + } + @@ -114,10 +110,10 @@ + } + + bb10: { -+ StorageLive(_9); -+ StorageDead(_9); -+ _1 = GeneratorState::::Complete(_6); -+ discriminant((*_7)) = 1; ++ StorageLive(_8); ++ StorageDead(_8); ++ _1 = GeneratorState::::Complete(_5); ++ discriminant((*_6)) = 1; + goto -> bb1; + } + diff --git a/tests/ui/impl-trait/impl-subtyper.rs b/tests/ui/impl-trait/impl-subtyper.rs new file mode 100644 index 0000000000000..2d99cdd4f506e --- /dev/null +++ b/tests/ui/impl-trait/impl-subtyper.rs @@ -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(); + }) +} diff --git a/tests/ui/impl-trait/impl-subtyper2.rs b/tests/ui/impl-trait/impl-subtyper2.rs new file mode 100644 index 0000000000000..2e0acbae68b82 --- /dev/null +++ b/tests/ui/impl-trait/impl-subtyper2.rs @@ -0,0 +1,7 @@ +// check-pass + +fn ages() -> Option { + None::> +} + +fn main(){} diff --git a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs new file mode 100644 index 0000000000000..7c62002b931be --- /dev/null +++ b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs @@ -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(), + } +} diff --git a/tests/ui/type-alias-impl-trait/tait-normalize.rs b/tests/ui/type-alias-impl-trait/tait-normalize.rs new file mode 100644 index 0000000000000..26d94dbb42a36 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/tait-normalize.rs @@ -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(){} diff --git a/tests/ui/type/subtyping-opaque-type.rs b/tests/ui/type/subtyping-opaque-type.rs new file mode 100644 index 0000000000000..beda232ea8b37 --- /dev/null +++ b/tests/ui/type/subtyping-opaque-type.rs @@ -0,0 +1,19 @@ +// check-pass +// compile-flags: -Zvalidate-mir +trait Duh {} + +impl Duh for i32 {} + +trait Trait { + type Assoc: Duh; +} + +impl R> Trait for F { + type Assoc = R; +} + +fn foo() -> impl Trait { + || 42 +} + +fn main() {}