diff options
| author | ouz-a <ouz.agz@gmail.com> | 2023-08-28 11:19:19 +0300 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2023-12-04 09:55:14 -0500 |
| commit | caab4b7d945532fc543db99a26e20ee9907ea412 (patch) | |
| tree | 2cb85a9532223faaebd800f3bb6990ef5e686434 | |
| parent | fa7a3184b49946e6bc6e77c0d79ed231ea29c69a (diff) | |
| download | rust-caab4b7d945532fc543db99a26e20ee9907ea412.tar.gz rust-caab4b7d945532fc543db99a26e20ee9907ea412.zip | |
Add docs, remove code, change subtyper code
24 files changed, 106 insertions, 363 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 745949d3ff0..8d4028de90d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -318,13 +318,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { PlaceRef { local, projection: [proj_base @ .., elem] } => match elem { ProjectionElem::Deref | ProjectionElem::Index(..) - | ProjectionElem::Subtype(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx) } ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx), - ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(*ty), + ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => { + PlaceTy::from_ty(*ty) + } ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type), }, }; diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index fcf45179b9d..777ebf0d438 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -243,13 +243,13 @@ fn place_components_conflict<'tcx>( } (ProjectionElem::Deref, _, Deep) - | (ProjectionElem::Subtype(_), _, _) | (ProjectionElem::Deref, _, AccessDepth::Drop) | (ProjectionElem::Field { .. }, _, _) | (ProjectionElem::Index { .. }, _, _) | (ProjectionElem::ConstantIndex { .. }, _, _) | (ProjectionElem::Subslice { .. }, _, _) | (ProjectionElem::OpaqueCast { .. }, _, _) + | (ProjectionElem::Subtype(_), _, _) | (ProjectionElem::Downcast { .. }, _, _) => { // Recursive case. This can still be disjoint on a // further iteration if this a shallow access and @@ -360,7 +360,6 @@ fn place_projection_conflict<'tcx>( ( ProjectionElem::Index(..), ProjectionElem::Index(..) - | ProjectionElem::Subtype(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. }, ) @@ -505,12 +504,12 @@ fn place_projection_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-OR-EQ-SLICE-SUBSLICES"); Overlap::EqualOrDisjoint } - (ProjectionElem::Subtype(_), _) => Overlap::EqualOrDisjoint, ( ProjectionElem::Deref | ProjectionElem::Field(..) | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subtype(_) | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Subslice { .. } | ProjectionElem::Downcast(..), diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 72c22d217b4..e9c9709bd1f 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -89,7 +89,9 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { cursor = cursor_base; continue 'cursor; } - ProjectionElem::Subtype(..) => continue 'cursor, + ProjectionElem::Subtype(..) => { + panic!("Subtype projection is not allowed before borrow check") + } ProjectionElem::Deref => { // (handled below) } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 33687792701..a3724c391d2 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -621,7 +621,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { span_mirbug_and_err!(self, place, "deref of non-pointer {:?}", base_ty) })) } - ProjectionElem::Subtype(ty) => PlaceTy::from_ty(ty), ProjectionElem::Index(i) => { let index_ty = Place::from(i).ty(self.body(), tcx).ty; if index_ty != tcx.types.usize { @@ -717,6 +716,14 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { } PlaceTy::from_ty(fty) } + ProjectionElem::Subtype(_) => { + let guard = span_mirbug_and_err!( + self, + place, + "ProjectionElem::Subtype shouldn't exist in borrowck" + ); + PlaceTy::from_ty(Ty::new_error(tcx, guard)) + } ProjectionElem::OpaqueCast(ty) => { let ty = self.sanitize_type(place, ty); let ty = self.cx.normalize(ty, location); diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 06780567fb8..a13d3a0e115 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -872,13 +872,11 @@ pub(crate) fn codegen_place<'tcx>( for elem in place.projection { match elem { - PlaceElem::Subtype(_) => { - continue; - } PlaceElem::Deref => { cplace = cplace.place_deref(fx); } PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"), + PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, ty), PlaceElem::Field(field, _ty) => { cplace = cplace.place_field(fx, field); } diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index d4273c0b593..34cde0a0e78 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -674,6 +674,14 @@ impl<'tcx> CPlace<'tcx> { } } + pub(crate) fn place_transmute_type( + self, + fx: &mut FunctionCx<'_, '_, 'tcx>, + ty: Ty<'tcx>, + ) -> CPlace<'tcx> { + CPlace { inner: self.inner, layout: fx.layout_of(fx.monomorphize(ty)) } + } + pub(crate) fn place_field( self, fx: &mut FunctionCx<'_, '_, 'tcx>, diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 9ff73aab907..eb590a45a63 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -466,6 +466,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::ProjectionElem::OpaqueCast(ty) => { bug!("encountered OpaqueCast({ty}) in codegen") } + mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)), mir::ProjectionElem::Index(index) => { let index = &mir::Operand::Copy(mir::Place::from(index)); let index = self.codegen_operand(bx, index); @@ -499,7 +500,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { subslice } mir::ProjectionElem::Downcast(_, v) => cg_base.project_downcast(bx, v), - mir::ProjectionElem::Subtype(_) => continue, }; } debug!("codegen_place(place={:?}) => {:?}", place_ref, cg_base); diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index b33396de33b..a32ea204f98 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -665,9 +665,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mut op = self.local_to_op(self.frame(), mir_place.local, layout)?; // Using `try_fold` turned out to be bad for performance, hence the loop. for elem in mir_place.projection.iter() { - if elem.is_subtype() { - continue; - } op = self.project(&op, elem)? } diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 3c24381f93d..70df3d8fd78 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -319,6 +319,8 @@ where OpaqueCast(ty) => { span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck") } + // We don't want anything happening here, this is here as a dummy. + Subtype(_) => base.transmute(base.layout(), self)?, Field(field, _) => self.project_field(base, field.index())?, Downcast(_, variant) => self.project_downcast(base, variant)?, Deref => self.deref_pointer(&base.to_op(self)?)?.into(), @@ -332,7 +334,6 @@ where self.project_constant_index(base, offset, min_length, from_end)? } Subslice { from, to, from_end } => self.project_subslice(base, from, to, from_end)?, - Subtype(ty) => base.transmute(self.layout_of(ty)?, self)?, }) } } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index ecedfc74450..a8e5254d860 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -16,6 +16,8 @@ use rustc_target::spec::abi::Abi; use crate::util::is_within_packed; +use crate::util::is_subtype; + #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { Unwind, @@ -602,35 +604,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - crate::util::is_subtype(self.tcx, self.param_env, src, dest) + return crate::util::is_subtype(self.tcx, self.param_env, src, dest); } } impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { - match operand { - Operand::Copy(place) | Operand::Move(place) => { - if let Some(stmt) = self.body.stmt_at(location).left() { - match &stmt.kind { - StatementKind::Assign(box (lval, rvalue)) => { - let place_ty = place.ty(&self.body.local_decls, self.tcx).ty; - let lval_ty = lval.ty(&self.body.local_decls, self.tcx).ty; - - if !place.is_subtype() - && place_ty != lval_ty - && rvalue.ty(&self.body.local_decls, self.tcx) != lval_ty - && (rvalue.ty(&self.body.local_decls, self.tcx).is_closure() - != lval_ty.is_closure()) - { - self.fail(location, format!("Subtyping is not allowed between types {place_ty:#?} and {lval_ty:#?}")) - } - } - _ => (), - } - } - } - _ => (), - } // This check is somewhat expensive, so only run it when -Zvalidate-mir is passed. if self.tcx.sess.opts.unstable_opts.validate_mir && self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) @@ -776,6 +755,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } + ProjectionElem::Subtype(ty) => { + if !is_subtype( + self.tcx, + self.param_env, + ty, + place_ref.ty(&self.body.local_decls, self.tcx).ty, + ) { + self.fail( + location, + format!( + "Failed subtyping {ty:#?} and {:#?}", + place_ref.ty(&self.body.local_decls, self.tcx).ty + ), + ) + } + } _ => {} } self.super_projection_elem(place_ref, elem, context, location); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 27105eae665..0a72289f1bb 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1103,6 +1103,7 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> for &elem in projection.iter().rev() { match elem { ProjectionElem::OpaqueCast(_) + | ProjectionElem::Subtype(_) | ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => { write!(fmt, "(").unwrap(); @@ -1125,6 +1126,9 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> ProjectionElem::OpaqueCast(ty) => { write!(fmt, " as {ty})")?; } + ProjectionElem::Subtype(ty) => { + write!(fmt, "as {ty})")?; + } ProjectionElem::Downcast(Some(name), _index) => { write!(fmt, " as {name})")?; } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index b308fb51993..3471d620ee6 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -57,6 +57,7 @@ impl<V, T> ProjectionElem<V, T> { Self::Field(_, _) | Self::Index(_) | Self::OpaqueCast(_) + | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) => false, @@ -70,6 +71,7 @@ impl<V, T> ProjectionElem<V, T> { Self::Deref | Self::Index(_) => false, Self::Field(_, _) | Self::OpaqueCast(_) + | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) => true, @@ -95,6 +97,7 @@ impl<V, T> ProjectionElem<V, T> { | Self::Field(_, _) => true, Self::ConstantIndex { from_end: true, .. } | Self::Index(_) + | Self::Subtype(_) | Self::OpaqueCast(_) | Self::Subslice { .. } => false, } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index e405de90ee5..fea7819d545 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1076,6 +1076,13 @@ pub enum ProjectionElem<V, T> { /// requiring an intermediate variable. OpaqueCast(T), + /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where + /// type of lvalue doesn't match type of rvalue, primary goal being making subtyping + /// explicit during optimizations and codegen. + /// + /// This goal is achieved with mir_transform pass `Subtyper`, which runs right after + /// borrowchecker, as we only care about subtyping that can affect trait selection and + /// `TypeId`. Subtype(T), } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 5ea8325412b..f2745b32cf9 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1109,8 +1109,12 @@ macro_rules! visit_place_fns { self.visit_ty(&mut new_ty, TyContext::Location(location)); if ty != new_ty { Some(PlaceElem::OpaqueCast(new_ty)) } else { None } } + PlaceElem::Subtype(ty) => { + let mut new_ty = ty; + self.visit_ty(&mut new_ty, TyContext::Location(location)); + if ty != new_ty { Some(PlaceElem::Subtype(new_ty)) } else { None } + } PlaceElem::Deref - | PlaceElem::Subtype { .. } | PlaceElem::ConstantIndex { .. } | PlaceElem::Subslice { .. } | PlaceElem::Downcast(..) => None, diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 0e4fc2447e1..4447ff0798c 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -112,9 +112,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { let mut union_path = None; for (place_ref, elem) in data.rev_lookup.un_derefer.iter_projections(place.as_ref()) { - if elem.is_subtype() { - continue; - } + // We don't care creating `MovePath` for `ProjectionElem::Subtype(T)` because it's for debugging/validating + // purposes it's movement doesn't affect anything. let body = self.builder.body; let tcx = self.builder.tcx; let place_ty = place_ref.ty(body, tcx).ty; @@ -233,7 +232,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // `OpaqueCast` only transmutes the type, so no moves there and // `Downcast` only changes information about a `Place` without moving // So it's safe to skip these. - ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (), + ProjectionElem::OpaqueCast(_) + | ProjectionElem::Subtype(_) + | ProjectionElem::Downcast(_, _) => (), } if union_path.is_none() { // inlined from add_move_path because of a borrowck conflict with the iterator diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs index e51f4a2ff21..594bb9bf142 100644 --- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs +++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs @@ -7,13 +7,13 @@ use rustc_middle::ty::TyCtxt; pub struct Subtyper; -pub struct SubTypeCheker<'a, 'tcx> { +pub struct SubTypeChecker<'a, 'tcx> { tcx: TyCtxt<'tcx>, patcher: MirPatch<'tcx>, local_decls: &'a IndexVec<Local, LocalDecl<'tcx>>, } -impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeCheker<'a, 'tcx> { +impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -25,28 +25,30 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeCheker<'a, 'tcx> { location: Location, ) { let place_ty = place.ty(self.local_decls, self.tcx); - let rval_ty = rvalue.ty(self.local_decls, self.tcx); + let mut rval_ty = rvalue.ty(self.local_decls, self.tcx); if place_ty.ty != rval_ty { + // Not erasing this causes `Free Regions` errors in validator, + // when rval is `ReStatic`. + rval_ty = self.tcx.erase_regions_ty(rval_ty); let temp = self .patcher .new_temp(rval_ty, self.local_decls[place.as_ref().local].source_info.span); - let new_place = - Place::from(temp).project_deeper(&[ProjectionElem::Subtype(place_ty.ty)], self.tcx); + let new_place = Place::from(temp); self.patcher.add_assign(location, new_place, rvalue.clone()); - let new_rval = Rvalue::Use(Operand::Move(new_place)); - *rvalue = new_rval; + let subtyped = + new_place.project_deeper(&[ProjectionElem::Subtype(place_ty.ty)], self.tcx); + *rvalue = Rvalue::Use(Operand::Move(subtyped)); } } } pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let patch = MirPatch::new(body); - let mut checker = SubTypeCheker { tcx, patcher: patch, local_decls: &body.local_decls }; + let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls }; for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() { checker.visit_basic_block_data(bb, data); } - checker.patcher.apply(body); } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 449bade3322..56bdc5a171a 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -306,6 +306,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index), ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), + ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty), }; value = self.insert(Value::Projection(value, proj)); } diff --git a/tabula.rs b/tabula.rs new file mode 100644 index 00000000000..19400a870e7 --- /dev/null +++ b/tabula.rs @@ -0,0 +1,14 @@ +// run-pass +#![deny(drop_bounds)] +// As a special exemption, `impl Drop` in the return position raises no error. +// This allows a convenient way to return an unnamed drop guard. +fn voldemort_type() -> impl Drop { + struct Voldemort; + impl Drop for Voldemort { + fn drop(&mut self) {} + } + Voldemort +} +fn main() { + let _ = voldemort_type(); +} 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 6779003b693..23e0ab67121 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 @@ -12,6 +12,7 @@ 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; 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 31744be99ec..a5488f6fb28 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 @@ -12,6 +12,7 @@ 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; @@ -55,7 +56,7 @@ - bb3: { + bb1: { -+ StorageDead(_5); ++ StorageDead(_6); StorageDead(_2); - drop(_4) -> [return: bb4, unwind: bb6]; + drop(_4) -> [return: bb2, unwind: bb4]; diff --git a/tests/mir-opt/mir_subtyping.main.Subtyper.diff b/tests/mir-opt/mir_subtyping.main.Subtyper.diff deleted file mode 100644 index 233915d48d7..00000000000 --- a/tests/mir-opt/mir_subtyping.main.Subtyper.diff +++ /dev/null @@ -1,262 +0,0 @@ -- // MIR for `main` before Subtyper -+ // MIR for `main` after Subtyper - - | User Type Annotations - | 0: user_ty: Canonical { value: TypeOf(DefId(5:284 ~ alloc[be7e]::boxed::{impl#0}::new), UserArgs { args: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(5:282 ~ alloc[be7e]::boxed::{impl#0}), self_ty: std::boxed::Box<^1, ^2> }) }), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/mir_subtyping.rs:34:10: 34:18, inferred_ty: fn(Foo<fn(&u8)>) -> std::boxed::Box<Foo<fn(&u8)>> {std::boxed::Box::<Foo<fn(&u8)>>::new} - | 1: user_ty: Canonical { value: Ty(fn(&'static u8)), max_universe: U0, variables: [] }, span: $DIR/mir_subtyping.rs:34:23: 34:48, inferred_ty: fn(&u8) - | 2: user_ty: Canonical { value: Ty(std::boxed::Box<dyn GetInner<Assoc = std::string::String>>), max_universe: U1, variables: [CanonicalVarInfo { kind: Region(U1) }] }, span: $DIR/mir_subtyping.rs:34:10: 34:87, inferred_ty: std::boxed::Box<dyn GetInner<Assoc = std::string::String>> - | 3: user_ty: Canonical { value: TypeOf(DefId(5:284 ~ alloc[be7e]::boxed::{impl#0}::new), UserArgs { args: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(5:282 ~ alloc[be7e]::boxed::{impl#0}), self_ty: std::boxed::Box<^1, ^2> }) }), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/mir_subtyping.rs:35:10: 35:18, inferred_ty: fn(Foo<for<'a> fn(&'a u8)>) -> std::boxed::Box<Foo<for<'a> fn(&'a u8)>> {std::boxed::Box::<Foo<for<'a> fn(&'a u8)>>::new} - | 4: user_ty: Canonical { value: Ty(std::boxed::Box<dyn GetInner<Assoc = [usize; 3]>>), max_universe: U1, variables: [CanonicalVarInfo { kind: Region(U1) }] }, span: $DIR/mir_subtyping.rs:35:10: 35:83, inferred_ty: std::boxed::Box<dyn GetInner<Assoc = [usize; 3]>> - | 5: user_ty: Canonical { value: TypeOf(DefId(5:284 ~ alloc[be7e]::boxed::{impl#0}::new), UserArgs { args: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(5:282 ~ alloc[be7e]::boxed::{impl#0}), self_ty: std::boxed::Box<^1, ^2> }) }), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/mir_subtyping.rs:37:20: 37:28, inferred_ty: fn(Foo<for<'a> fn(&'a u8)>) -> std::boxed::Box<Foo<for<'a> fn(&'a u8)>> {std::boxed::Box::<Foo<for<'a> fn(&'a u8)>>::new} - | 6: user_ty: Canonical { value: Ty(std::boxed::Box<Foo<fn(&'static u8)>>), max_universe: U0, variables: [] }, span: $DIR/mir_subtyping.rs:38:20: 38:57, inferred_ty: std::boxed::Box<Foo<fn(&u8)>> - | 7: user_ty: Canonical { value: Ty(std::boxed::Box<dyn GetInner<Assoc = std::string::String>>), max_universe: U1, variables: [CanonicalVarInfo { kind: Region(U1) }] }, span: $DIR/mir_subtyping.rs:39:19: 39:64, inferred_ty: std::boxed::Box<dyn GetInner<Assoc = std::string::String>> - | - fn main() -> () { - let mut _0: (); - let _1: Wrapper; - let mut _2: for<'a> fn(&'a u8); - let _3: (); - let mut _4: std::boxed::Box<dyn GetInner<Assoc = std::string::String>>; - let mut _5: std::boxed::Box<dyn GetInner<Assoc = std::string::String>>; - let mut _6: std::boxed::Box<Foo<fn(&u8)>>; - let mut _7: Foo<fn(&u8)>; - let mut _8: fn(&u8); - let mut _9: fn(&u8); - let _10: (); - let mut _11: std::boxed::Box<dyn GetInner<Assoc = [usize; 3]>>; - let mut _12: std::boxed::Box<dyn GetInner<Assoc = [usize; 3]>>; - let mut _13: std::boxed::Box<Foo<for<'a> fn(&'a u8)>>; - let mut _14: Foo<for<'a> fn(&'a u8)>; - let mut _15: for<'a> fn(&'a u8); - let mut _17: Foo<for<'a> fn(&'a u8)>; - let mut _18: for<'b> fn(&'b u8); - let mut _20: std::boxed::Box<Foo<fn(&u8)>>; - let mut _22: std::boxed::Box<dyn GetInner<Assoc = std::string::String>>; - let mut _23: std::boxed::Box<Foo<fn(&u8)>>; - let mut _25: &mut dyn GetInner<Assoc = std::string::String>; - let _26: (); - let mut _27: std::string::String; -+ let mut _28: std::boxed::Box<Foo<for<'a> fn(&'a u8)>>; - scope 1 { - debug wrapper => _1; - let _16: std::boxed::Box<Foo<for<'a> fn(&'a u8)>>; - scope 2 { - debug hr_fnptr => _16; - let _19: std::boxed::Box<Foo<fn(&u8)>>; - scope 3 { - debug lr_fnptr => _19; - let mut _21: std::boxed::Box<dyn GetInner<Assoc = std::string::String>>; - scope 4 { - debug any => _21; - let _24: std::string::String; - scope 5 { - debug evil_string => _24; - } - } - } - } - } - - bb0: { - StorageLive(_1); - StorageLive(_2); - _2 = useful as for<'a> fn(&'a u8) (PointerCoercion(ReifyFnPointer)); - _1 = Wrapper(move _2); - StorageDead(_2); - FakeRead(ForLet(None), _1); - StorageLive(_3); - StorageLive(_4); - StorageLive(_5); - StorageLive(_6); - StorageLive(_7); - StorageLive(_8); - StorageLive(_9); - _9 = useful as for<'a> fn(&'a u8) (PointerCoercion(ReifyFnPointer)); - AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); - _8 = _9; - _7 = Foo::<fn(&u8)>(move _8); - StorageDead(_8); - _6 = Box::<Foo<fn(&u8)>>::new(move _7) -> [return: bb1, unwind: bb28]; - } - - bb1: { - _5 = move _6 as std::boxed::Box<dyn GetInner<Assoc = std::string::String>> (PointerCoercion(Unsize)); - drop(_6) -> [return: bb2, unwind: bb28]; - } - - bb2: { - StorageDead(_7); - StorageDead(_6); - AscribeUserType(_5, o, UserTypeProjection { base: UserType(2), projs: [] }); - _4 = move _5; - _3 = std::mem::drop::<Box<dyn GetInner<Assoc = String>>>(move _4) -> [return: bb3, unwind: bb26]; - } - - bb3: { - StorageDead(_4); - drop(_5) -> [return: bb4, unwind: bb28]; - } - - bb4: { - StorageDead(_9); - StorageDead(_5); - StorageDead(_3); - StorageLive(_10); - StorageLive(_11); - StorageLive(_12); - StorageLive(_13); - StorageLive(_14); - StorageLive(_15); - _15 = useful as for<'a> fn(&'a u8) (PointerCoercion(ReifyFnPointer)); - _14 = Foo::<for<'a> fn(&'a u8)>(move _15); - StorageDead(_15); - _13 = Box::<Foo<for<'a> fn(&'a u8)>>::new(move _14) -> [return: bb5, unwind: bb28]; - } - - bb5: { - _12 = move _13 as std::boxed::Box<dyn GetInner<Assoc = [usize; 3]>> (PointerCoercion(Unsize)); - drop(_13) -> [return: bb6, unwind: bb28]; - } - - bb6: { - StorageDead(_14); - StorageDead(_13); - AscribeUserType(_12, o, UserTypeProjection { base: UserType(4), projs: [] }); - _11 = move _12; - _10 = std::mem::drop::<Box<dyn GetInner<Assoc = [usize; 3]>>>(move _11) -> [return: bb7, unwind: bb24]; - } - - bb7: { - StorageDead(_11); - drop(_12) -> [return: bb8, unwind: bb28]; - } - - bb8: { - StorageDead(_12); - StorageDead(_10); - StorageLive(_16); - StorageLive(_17); - StorageLive(_18); - _18 = (_1.0: for<'b> fn(&'b u8)); - _17 = Foo::<for<'a> fn(&'a u8)>(move _18); - StorageDead(_18); - _16 = Box::<Foo<for<'a> fn(&'a u8)>>::new(move _17) -> [return: bb9, unwind: bb28]; - } - - bb9: { - StorageDead(_17); - FakeRead(ForLet(None), _16); - StorageLive(_19); - StorageLive(_20); -- _20 = move _16; -+ _20 = move (_16 Subtyped as Box<Foo<fn(&u8)>>; - AscribeUserType(_20, o, UserTypeProjection { base: UserType(6), projs: [] }); - _19 = move _20; - FakeRead(ForLet(None), _19); - drop(_20) -> [return: bb10, unwind: bb22]; - } - - bb10: { - StorageDead(_20); - StorageLive(_21); - StorageLive(_22); - StorageLive(_23); - _23 = move _19; - _22 = move _23 as std::boxed::Box<dyn GetInner<Assoc = std::string::String>> (PointerCoercion(Unsize)); - drop(_23) -> [return: bb11, unwind: bb22]; - } - - bb11: { - StorageDead(_23); - AscribeUserType(_22, o, UserTypeProjection { base: UserType(7), projs: [] }); - _21 = move _22; - FakeRead(ForLet(None), _21); - drop(_22) -> [return: bb12, unwind: bb21]; - } - - bb12: { - StorageDead(_22); - StorageLive(_24); - StorageLive(_25); - _25 = &mut (*_21); - _24 = <dyn GetInner<Assoc = String> as GetInner>::muahaha(move _25) -> [return: bb13, unwind: bb21]; - } - - bb13: { - StorageDead(_25); - FakeRead(ForLet(None), _24); - StorageLive(_26); - StorageLive(_27); - _27 = move _24; - _26 = std::mem::drop::<String>(move _27) -> [return: bb14, unwind: bb19]; - } - - bb14: { - StorageDead(_27); - StorageDead(_26); - _0 = const (); - drop(_24) -> [return: bb15, unwind: bb21]; - } - - bb15: { - StorageDead(_24); - drop(_21) -> [return: bb16, unwind: bb22]; - } - - bb16: { - StorageDead(_21); - drop(_19) -> [return: bb17, unwind: bb23]; - } - - bb17: { - StorageDead(_19); - drop(_16) -> [return: bb18, unwind: bb28]; - } - - bb18: { - StorageDead(_16); - StorageDead(_1); - return; - } - - bb19 (cleanup): { - drop(_27) -> [return: bb20, unwind terminate]; - } - - bb20 (cleanup): { - drop(_24) -> [return: bb21, unwind terminate]; - } - - bb21 (cleanup): { - drop(_21) -> [return: bb22, unwind terminate]; - } - - bb22 (cleanup): { - drop(_19) -> [return: bb23, unwind terminate]; - } - - bb23 (cleanup): { - drop(_16) -> [return: bb28, unwind terminate]; - } - - bb24 (cleanup): { - drop(_11) -> [return: bb25, unwind terminate]; - } - - bb25 (cleanup): { - drop(_12) -> [return: bb28, unwind terminate]; - } - - bb26 (cleanup): { - drop(_4) -> [return: bb27, unwind terminate]; - } - - bb27 (cleanup): { - drop(_5) -> [return: bb28, unwind terminate]; - } - - bb28 (cleanup): { - resume; - } - } - diff --git a/tests/mir-opt/mir_subtyping.rs b/tests/mir-opt/mir_subtyping.rs deleted file mode 100644 index 558ccaca9f3..00000000000 --- a/tests/mir-opt/mir_subtyping.rs +++ /dev/null @@ -1,43 +0,0 @@ -// compile-flags: -Z mir-opt-level=0 - -// EMIT_MIR mir_subtyping.main.Subtyper.diff -#![allow(coherence_leak_check)] - -struct Foo<T: 'static>(T); - -fn useful<'a>(_: &'a u8) {} - -pub struct Wrapper(for<'b> fn(&'b u8)); - -trait GetInner { - type Assoc; - fn muahaha(&mut self) -> Self::Assoc; -} - -impl GetInner for Foo<fn(&'static u8)> { - type Assoc = String; - fn muahaha(&mut self) -> String { - panic!("cant do it boss") - } -} - -impl GetInner for Foo<for<'a> fn(&'a u8)> { - type Assoc = [usize; 3]; - fn muahaha(&mut self) -> [usize; 3] { - [100; 3] - } -} - -fn main() { - let wrapper = Wrapper(useful); - - drop(Box::new(Foo(useful as fn(&'static u8))) as Box<dyn GetInner<Assoc = String>>); - drop(Box::new(Foo(useful as fn(&u8))) as Box<dyn GetInner<Assoc = [usize; 3]>>); - - let hr_fnptr = Box::new(Foo::<for<'a> fn(&'a u8)>(wrapper.0)); - let lr_fnptr = hr_fnptr as Box<Foo<fn(&'static u8)>>; - let mut any = lr_fnptr as Box<dyn GetInner<Assoc = String>>; - - let evil_string = any.muahaha(); - drop(evil_string); -} diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir index 67afa50bd58..8a0eb36701a 100644 --- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir +++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -22,7 +22,7 @@ fn main() -> () { let _24: i32; let mut _26: *const i32; let _27: (); - let mut _29: [closure@main::{closure#0}]; + let mut _29: for<'a> fn(&'a i32) -> &'a i32; scope 1 { debug x => _1; let _3: &mut i32; @@ -106,7 +106,8 @@ fn main() -> () { StorageLive(_14); _14 = {closure@main::{closure#0}}; Retag(_14); - _13 = move (_14 Subtyped as for<'a> fn(&'a i32) -> &'a i32 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal))); + _29 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal))); + _13 = move (_29 Subtyped as for<'a> fn(&'a i32) -> &'a i32); StorageDead(_14); StorageLive(_15); StorageLive(_16); diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir index 467b4493bf3..ac1fe555900 100644 --- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir +++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir @@ -22,7 +22,7 @@ fn main() -> () { let _24: i32; let mut _26: *const i32; let _27: (); - let mut _29: [closure@main::{closure#0}]; + let mut _29: for<'a> fn(&'a i32) -> &'a i32; scope 1 { debug x => _1; let _3: &mut i32; @@ -106,7 +106,8 @@ fn main() -> () { StorageLive(_14); _14 = {closure@main::{closure#0}}; Retag(_14); - _13 = move (_14 Subtyped as for<'a> fn(&'a i32) -> &'a i32 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal))); + _29 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal))); + _13 = move (_29 Subtyped as for<'a> fn(&'a i32) -> &'a i32); StorageDead(_14); StorageLive(_15); StorageLive(_16); |
