diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index c11103af476e3..58ce3e6e60446 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3971,7 +3971,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } - | ProjectionElem::Subtype(_) | ProjectionElem::Index(_) => kind, }, place_ty.projection_ty(tcx, elem), diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index bda9672673873..b272c50816da9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -243,7 +243,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ProjectionElem::Downcast(..) if opt.including_downcast => return None, ProjectionElem::Downcast(..) => (), ProjectionElem::OpaqueCast(..) => (), - ProjectionElem::Subtype(..) => (), ProjectionElem::Field(field, _ty) => { // FIXME(project-rfc_2229#36): print capture precisely here. if let Some(field) = self.is_upvar_field_projection(PlaceRef { @@ -324,9 +323,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx) } ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx), - ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => { - PlaceTy::from_ty(*ty) - } + ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(*ty), ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type), }, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index c5ebf3c547e9d..5da131c4d7398 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -164,7 +164,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { [ .., ProjectionElem::Index(_) - | ProjectionElem::Subtype(_) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Subslice { .. } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 03f7b05d1e3be..41e5d6e3810bb 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1712,11 +1712,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { }, // `OpaqueCast`: only transmutes the type, so no moves there. // `Downcast` : only changes information about a `Place` without moving. - // `Subtype` : only transmutes the type, so no moves. // So it's safe to skip these. - ProjectionElem::OpaqueCast(_) - | ProjectionElem::Subtype(_) - | ProjectionElem::Downcast(_, _) => (), + ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (), } place_ty = place_ty.projection_ty(tcx, elem); @@ -1940,7 +1937,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { for (place_base, elem) in place.iter_projections().rev() { match elem { ProjectionElem::Index(_/*operand*/) | - ProjectionElem::Subtype(_) | ProjectionElem::OpaqueCast(_) | ProjectionElem::ConstantIndex { .. } | // assigning to P[i] requires P to be valid. @@ -2332,7 +2328,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } - | ProjectionElem::Subtype(..) | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Downcast(..) => { let upvar_field_projection = self.is_upvar_field_projection(place); diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 679e111caa984..60cedc77c4dcf 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -249,7 +249,6 @@ fn place_components_conflict<'tcx>( | (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 @@ -509,7 +508,6 @@ fn place_projection_conflict<'tcx>( | 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 fc7e6e586410a..631ef04f09574 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -73,9 +73,6 @@ impl<'tcx> Iterator for Prefixes<'tcx> { | ProjectionElem::Index(_) => { cursor = cursor_base; } - ProjectionElem::Subtype(..) => { - panic!("Subtype projection is not allowed before borrow check") - } ProjectionElem::Deref => { match self.kind { PrefixSet::Shallow => { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c6b34d5bf1dae..f1fac3672e65a 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -698,9 +698,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { } PlaceTy::from_ty(fty) } - ProjectionElem::Subtype(_) => { - bug!("ProjectionElem::Subtype shouldn't exist in borrowck") - } ProjectionElem::OpaqueCast(ty) => { let ty = self.sanitize_type(place, ty); let ty = self.cx.normalize(ty, location); @@ -2700,9 +2697,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | ProjectionElem::Subslice { .. } => { // other field access } - ProjectionElem::Subtype(_) => { - bug!("ProjectionElem::Subtype shouldn't exist in borrowck") - } } } } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 77ee977394056..18df72324a7c1 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -981,7 +981,6 @@ pub(crate) fn codegen_place<'tcx>( cplace = cplace.place_deref(fx); } PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"), - PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, fx.monomorphize(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 6676e684ca025..818d9408c2592 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -708,16 +708,6 @@ impl<'tcx> CPlace<'tcx> { } } - /// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before - /// passed on. - pub(crate) fn place_transmute_type( - self, - fx: &mut FunctionCx<'_, '_, 'tcx>, - ty: Ty<'tcx>, - ) -> CPlace<'tcx> { - CPlace { inner: self.inner, layout: fx.layout_of(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 b8fa8c0351b1e..bd8508587a714 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -495,7 +495,6 @@ 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); diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index bc416acc58d7b..695830604bb59 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -290,7 +290,6 @@ where ProjectionElem::Index(index) if in_local(index) => return true, ProjectionElem::Deref - | ProjectionElem::Subtype(_) | ProjectionElem::Field(_, _) | ProjectionElem::OpaqueCast(_) | ProjectionElem::ConstantIndex { .. } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 42fdf32e91ecf..9780b333db1d9 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -12,7 +12,7 @@ use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout, }; -use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv}; use rustc_middle::{mir, span_bug}; use rustc_session::Limit; use rustc_span::Span; @@ -113,8 +113,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { } } -/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value. -/// This test should be symmetric, as it is primarily about layout compatibility. +/// Test if it is valid for a MIR assignment to store a `src`-typed value in a `dest`-typed place. pub(super) fn mir_assign_valid_types<'tcx>( tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>, @@ -125,7 +124,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( // all normal lifetimes are erased, higher-ranked types with their // late-bound lifetimes are still around and can lead to type // differences. - if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) { + if util::sub_types(tcx, typing_env, src.ty, dest.ty) { // Make sure the layout is equal, too -- just to be safe. Miri really // needs layout equality. For performance reason we skip this check when // the types are equal. Equal types *can* have different layouts when diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 65a93784e2cc7..efe44b1afa8ee 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -381,8 +381,6 @@ 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(), diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 9eed1a20f1523..6609676cf938a 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -20,9 +20,8 @@ pub fn sub_types<'tcx>( /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. /// -/// When validating assignments, the variance should be `Covariant`. When checking -/// during `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial)` variance should be `Invariant` -/// because we want to check for type equality. +/// When validating assignments, the variance should be `Covariant` and +/// `sub_types` should be used instead. pub fn relate_types<'tcx>( tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>, diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f0e2b7a376cd3..f3ec79b438e34 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1270,7 +1270,6 @@ 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, "(")?; @@ -1293,9 +1292,6 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> ProjectionElem::OpaqueCast(ty) => { write!(fmt, " as {ty})")?; } - ProjectionElem::Subtype(ty) => { - write!(fmt, " as subtype {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 1ce735cec6313..e93c84a9b9ab0 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -59,7 +59,6 @@ impl ProjectionElem { Self::Field(_, _) | Self::Index(_) | Self::OpaqueCast(_) - | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) => false, @@ -73,7 +72,6 @@ impl ProjectionElem { Self::Deref | Self::Index(_) => false, Self::Field(_, _) | Self::OpaqueCast(_) - | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) => true, @@ -99,7 +97,6 @@ impl ProjectionElem { | 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 2083279e12861..3df06376d31e1 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1182,18 +1182,6 @@ pub enum ProjectionElem { /// Like an explicit cast from an opaque type to a concrete type, but without /// requiring an intermediate variable. OpaqueCast(T), - - /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where - /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping - /// explicit during optimizations and codegen. - /// - /// This projection doesn't impact the runtime behavior of the program except for potentially changing - /// some type metadata of the interpreter or codegen backend. - /// - /// 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), } /// Alias for projections as they appear in places, where the base is a place diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 476e352ed9227..d158e23c79b69 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -68,7 +68,7 @@ impl<'tcx> PlaceTy<'tcx> { tcx: TyCtxt<'tcx>, elem: &ProjectionElem, mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>, - mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>, + mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>, ) -> PlaceTy<'tcx> where V: ::std::fmt::Debug, @@ -105,12 +105,7 @@ impl<'tcx> PlaceTy<'tcx> { PlaceTy { ty: self.ty, variant_index: Some(index) } } ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)), - ProjectionElem::OpaqueCast(ty) => { - PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) - } - ProjectionElem::Subtype(ty) => { - PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) - } + ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(handle_opaque_cast(&self, ty)), }; debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); answer diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 9f9ee8497b60b..b8704d81f0321 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1142,11 +1142,6 @@ 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::ConstantIndex { .. } | PlaceElem::Subslice { .. } @@ -1213,9 +1208,7 @@ macro_rules! visit_place_fns { location: Location, ) { match elem { - ProjectionElem::OpaqueCast(ty) - | ProjectionElem::Subtype(ty) - | ProjectionElem::Field(_, ty) => { + ProjectionElem::OpaqueCast(ty) | ProjectionElem::Field(_, ty) => { self.visit_ty(ty, TyContext::Location(location)); } ProjectionElem::Index(local) => { diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 9f6e0735b4822..164341a2f0f24 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -102,8 +102,8 @@ fn convert_to_hir_projections_and_truncate_for_capture( variant = Some(*idx); continue; } - // These do not affect anything, they just make sure we know the right type. - ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(..) => continue, + // This does not affect anything, it just makes sure we know the right type. + ProjectionElem::OpaqueCast(_) => continue, ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { @@ -712,7 +712,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ProjectionElem::Field(..) | ProjectionElem::Downcast(..) | ProjectionElem::OpaqueCast(..) - | ProjectionElem::Subtype(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => (), } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs index df4c0593246cf..8277e52acec57 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs @@ -57,7 +57,6 @@ impl<'tcx> Lift for PlaceElem<'tcx> { ProjectionElem::ConstantIndex { offset, min_length, from_end } } ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u), - ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty.lift()), } } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index fd8e403ebc26e..00870e904ef55 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -226,11 +226,8 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { }, // `OpaqueCast`:Only transmutes the type, so no moves there. // `Downcast` :Only changes information about a `Place` without moving. - // `Subtype` :Only transmutes the type, so moves. // So it's safe to skip these. - ProjectionElem::OpaqueCast(_) - | ProjectionElem::Subtype(_) - | ProjectionElem::Downcast(_, _) => (), + ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (), } let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty; if !(self.filter)(elem_ty) { diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs deleted file mode 100644 index e585e338613d8..0000000000000 --- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs +++ /dev/null @@ -1,64 +0,0 @@ -use rustc_middle::mir::patch::MirPatch; -use rustc_middle::mir::visit::MutVisitor; -use rustc_middle::mir::*; -use rustc_middle::ty::TyCtxt; - -pub(super) struct Subtyper; - -struct SubTypeChecker<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - patcher: MirPatch<'tcx>, - local_decls: &'a LocalDecls<'tcx>, -} - -impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_assign( - &mut self, - place: &mut Place<'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, - // when rval is `ReStatic`. - rval_ty = self.tcx.erase_regions_ty(rval_ty); - place_ty = self.tcx.erase_regions(place_ty); - if place_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); - self.patcher.add_assign(location, new_place, rvalue.clone()); - let subtyped = new_place.project_deeper(&[ProjectionElem::Subtype(place_ty)], self.tcx); - *rvalue = Rvalue::Use(Operand::Move(subtyped)); - } - } -} - -// Aim here is to do this kind of transformation: -// -// let place: place_ty = rval; -// // gets transformed to -// let temp: rval_ty = rval; -// let place: place_ty = temp as place_ty; -impl<'tcx> crate::MirPass<'tcx> for Subtyper { - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let patch = MirPatch::new(body); - 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 b3d9af3720410..db7aaac445c18 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -471,7 +471,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ProjectionElem::Subslice { from, to, from_end } } ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), - ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty), // This should have been replaced by a `ConstantIndex` earlier. ProjectionElem::Index(_) => return None, }; @@ -704,7 +703,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ProjectionElem::Subslice { from, to, from_end } } ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), - ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty), }; Some(self.insert(Value::Projection(value, proj))) @@ -922,7 +920,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } ProjectionElem::Downcast(symbol, idx) => ProjectionElem::Downcast(symbol, idx), ProjectionElem::OpaqueCast(idx) => ProjectionElem::OpaqueCast(idx), - ProjectionElem::Subtype(idx) => ProjectionElem::Subtype(idx), }) } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 5651bf469d54d..2ab602b03c11b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -112,7 +112,6 @@ declare_passes! { mod add_call_guards : AddCallGuards { AllCallEdges, CriticalCallEdges }; mod add_moves_for_packed_drops : AddMovesForPackedDrops; mod add_retag : AddRetag; - mod add_subtyping_projections : Subtyper; mod check_alignment : CheckAlignment; mod check_const_item_mutation : CheckConstItemMutation; mod check_packed_ref : CheckPackedRef; @@ -603,8 +602,6 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &add_call_guards::CriticalCallEdges, // Must be done before drop elaboration because we need to drop opaque types, too. &reveal_all::RevealAll, - // Calling this after reveal_all ensures that we don't deal with opaque types. - &add_subtyping_projections::Subtyper, &elaborate_drops::ElaborateDrops, // This will remove extraneous landing pads which are no longer // necessary as well as forcing any call in a non-unwinding diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 6be95b1f0f1e6..58686c76f7d8a 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -287,9 +287,7 @@ impl<'tcx> Validator<'_, 'tcx> { // Validate topmost projection, then recurse. match elem { // Recurse directly. - ProjectionElem::ConstantIndex { .. } - | ProjectionElem::Subtype(_) - | ProjectionElem::Subslice { .. } => {} + ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {} // Never recurse. ProjectionElem::OpaqueCast(..) | ProjectionElem::Downcast(..) => { diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index 587032ee72088..8bff339cfe410 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -34,19 +34,19 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { _location: Location, ) { // Performance optimization: don't reintern if there is no `OpaqueCast` to remove. - if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) { - return; + if place.projection.iter().any(|elem| matches!(elem, ProjectionElem::OpaqueCast(_))) { + // `OpaqueCast` projections are only needed if there are opaque types on which projections + // are performed. After the `RevealAll` pass, all opaque types are replaced with their + // hidden types, so we don't need these projections anymore. + place.projection = self.tcx.mk_place_elems( + &place + .projection + .into_iter() + .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) + .collect::>(), + ); } - // `OpaqueCast` projections are only needed if there are opaque types on which projections - // are performed. After the `RevealAll` pass, all opaque types are replaced with their - // hidden types, so we don't need these projections anymore. - place.projection = self.tcx.mk_place_elems( - &place - .projection - .into_iter() - .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) - .collect::>(), - ); + self.super_place(place, _context, _location); } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 724238ecfc93e..434a9b5d5d71f 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -12,13 +12,13 @@ use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ - self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Variance, + self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, }; use rustc_middle::{bug, span_bug}; use rustc_trait_selection::traits::ObligationCtxt; use rustc_type_ir::Upcast; -use crate::util::{self, is_within_packed}; +use crate::util::is_within_packed; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { @@ -574,15 +574,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - // After borrowck subtyping should be fully explicit via - // `Subtype` projections. - let variance = if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { - Variance::Invariant - } else { - Variance::Covariant - }; - - crate::util::relate_types(self.tcx, self.typing_env, variance, src, dest) + crate::util::sub_types(self.tcx, self.typing_env, src, dest) } /// Check that the given predicate definitely holds in the param-env of this MIR body. @@ -671,7 +663,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let fail_out_of_bounds = |this: &mut Self, location| { this.fail(location, format!("Out of bounds field {f:?} for {parent_ty:?}")); }; - let check_equal = |this: &mut Self, location, f_ty| { + let check_assign_valid = |this: &mut Self, location, f_ty| { if !this.mir_assign_valid_types(ty, f_ty) { this.fail( location, @@ -682,20 +674,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } }; - let kind = match parent_ty.ty.kind() { - &ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { - self.tcx.type_of(def_id).instantiate(self.tcx, args).kind() - } - kind => kind, - }; - - match kind { + match parent_ty.ty.kind() { ty::Tuple(fields) => { let Some(f_ty) = fields.get(f.as_usize()) else { fail_out_of_bounds(self, location); return; }; - check_equal(self, location, *f_ty); + check_assign_valid(self, location, *f_ty); } ty::Adt(adt_def, args) => { // see @@ -714,7 +699,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { fail_out_of_bounds(self, location); return; }; - check_equal(self, location, field.ty(self.tcx, args)); + check_assign_valid(self, location, field.ty(self.tcx, args)); } ty::Closure(_, args) => { let args = args.as_closure(); @@ -722,7 +707,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { fail_out_of_bounds(self, location); return; }; - check_equal(self, location, f_ty); + check_assign_valid(self, location, f_ty); } ty::CoroutineClosure(_, args) => { let args = args.as_coroutine_closure(); @@ -730,7 +715,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { fail_out_of_bounds(self, location); return; }; - check_equal(self, location, f_ty); + check_assign_valid(self, location, f_ty); } &ty::Coroutine(def_id, args) => { let f_ty = if let Some(var) = parent_ty.variant_index { @@ -785,29 +770,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { f_ty }; - check_equal(self, location, f_ty); + check_assign_valid(self, location, f_ty); } _ => { self.fail(location, format!("{:?} does not have fields", parent_ty.ty)); } } } - ProjectionElem::Subtype(ty) => { - if !util::sub_types( - self.tcx, - self.typing_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_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index dec2a77619bad..7ecd4aa8d1543 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -547,9 +547,6 @@ impl RustcInternal for ProjectionElem { ProjectionElem::OpaqueCast(ty) => { rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, tcx)) } - ProjectionElem::Subtype(ty) => { - rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, tcx)) - } } } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 820d8a6be25ca..327c684f3527b 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -378,7 +378,6 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { // found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486 Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)), OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)), - Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)), } } } diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index f96487cc53c9f..a5708a680ee0b 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -795,14 +795,6 @@ pub enum ProjectionElem { /// Like an explicit cast from an opaque type to a concrete type, but without /// requiring an intermediate variable. OpaqueCast(Ty), - - /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where - /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping - /// explicit during optimizations and codegen. - /// - /// This projection doesn't impact the runtime behavior of the program except for potentially changing - /// some type metadata of the interpreter or codegen backend. - Subtype(Ty), } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] @@ -1031,7 +1023,7 @@ impl ProjectionElem { Self::subslice_ty(ty, *from, *to, *from_end) } ProjectionElem::Downcast(_) => Ok(ty), - ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty), + ProjectionElem::OpaqueCast(ty) => Ok(*ty), } } diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index d73e79c48937e..f7a6672d0a551 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -299,9 +299,7 @@ pub trait MirVisitor { | ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location), ProjectionElem::Index(local) => self.visit_local(local, ptx, location), - ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => { - self.visit_ty(ty, location) - } + ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), } } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index abadca7140019..1c6f194ed2181 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -286,7 +286,6 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B | ProjectionElem::OpaqueCast(..) | ProjectionElem::Downcast(..) | ProjectionElem::Subslice { .. } - | ProjectionElem::Subtype(_) | ProjectionElem::Index(_) => {}, } } diff --git a/tests/crashes/120016.rs b/tests/ui/type-alias-impl-trait/hidden-ty-mismatch-tainting-issue-120016.rs similarity index 53% rename from tests/crashes/120016.rs rename to tests/ui/type-alias-impl-trait/hidden-ty-mismatch-tainting-issue-120016.rs index 09175689256a7..40c2dd27b9d06 100644 --- a/tests/crashes/120016.rs +++ b/tests/ui/type-alias-impl-trait/hidden-ty-mismatch-tainting-issue-120016.rs @@ -1,5 +1,4 @@ -//@ known-bug: #120016 -//@ compile-flags: -Zcrate-attr=feature(const_async_blocks) --edition=2021 +//@ compile-flags: --edition=2021 #![feature(type_alias_impl_trait, const_async_blocks)] @@ -7,11 +6,11 @@ struct Bug { V1: [(); { type F = impl std::future::Future; fn concrete_use() -> F { - //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` async {} } let f: F = async { 1 }; - //~^ ERROR `async` blocks are not allowed in constants + //~^ ERROR concrete type differs from previous defining opaque type use + //~| ERROR concrete type differs from previous defining opaque type use 1 }], } diff --git a/tests/ui/type-alias-impl-trait/hidden-ty-mismatch-tainting-issue-120016.stderr b/tests/ui/type-alias-impl-trait/hidden-ty-mismatch-tainting-issue-120016.stderr new file mode 100644 index 0000000000000..24a3a657a76f3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/hidden-ty-mismatch-tainting-issue-120016.stderr @@ -0,0 +1,26 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/hidden-ty-mismatch-tainting-issue-120016.rs:11:20 + | +LL | let f: F = async { 1 }; + | ^^^^^^^^^^^ expected `{async block@$DIR/hidden-ty-mismatch-tainting-issue-120016.rs:9:13: 9:18}`, got `{async block@$DIR/hidden-ty-mismatch-tainting-issue-120016.rs:11:20: 11:25}` + | +note: previous use here + --> $DIR/hidden-ty-mismatch-tainting-issue-120016.rs:9:13 + | +LL | async {} + | ^^^^^^^^ + +error: concrete type differs from previous defining opaque type use + --> $DIR/hidden-ty-mismatch-tainting-issue-120016.rs:11:20 + | +LL | let f: F = async { 1 }; + | ^^^^^^^^^^^ expected `()`, got `i32` + | +note: previous use here + --> $DIR/hidden-ty-mismatch-tainting-issue-120016.rs:9:13 + | +LL | async {} + | ^^^^^^^^ + +error: aborting due to 2 previous errors +