diff options
| author | bors <bors@rust-lang.org> | 2022-12-16 12:47:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-12-16 12:47:49 +0000 |
| commit | 03770f0e2b60c02db8fcf52fed5fb36aac70cedc (patch) | |
| tree | fa8e7aea22d80f0b44cd5d982b6d3418a2ccb787 /compiler/rustc_middle | |
| parent | 01ef4b21dc5251b58bd9c6fd6face2ae95d56da1 (diff) | |
| parent | ff41359e6535ca7dc1261f282b1601136fedee21 (diff) | |
Auto merge of #103880 - b-naber:field-ty-mir, r=lcnr
Use non-ascribed type as field's type in mir Fixes https://github.com/rust-lang/rust/issues/96514 r? `@lcnr`
Diffstat (limited to 'compiler/rustc_middle')
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/syntax.rs | 39 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/tcx.rs | 15 |
3 files changed, 45 insertions, 13 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index bdaa586c698..e909b2f74aa 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1488,7 +1488,7 @@ impl<'tcx> StatementKind<'tcx> { /////////////////////////////////////////////////////////////////////////// // Places -impl<V, T> ProjectionElem<V, T> { +impl<V, T, U> ProjectionElem<V, T, U> { /// Returns `true` if the target of this projection may refer to a different region of memory /// than the base. fn is_indirect(&self) -> bool { @@ -1517,7 +1517,7 @@ impl<V, T> ProjectionElem<V, T> { /// Alias for projections as they appear in `UserTypeProjection`, where we /// need neither the `V` parameter for `Index` nor the `T` for `Field`. -pub type ProjectionKind = ProjectionElem<(), ()>; +pub type ProjectionKind = ProjectionElem<(), (), ()>; rustc_index::newtype_index! { /// A [newtype'd][wrapper] index type in the MIR [control-flow graph][CFG] diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 99e59c770d7..a6ca04f5e62 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -890,11 +890,18 @@ pub struct Place<'tcx> { pub projection: &'tcx List<PlaceElem<'tcx>>, } +/// The different kinds of projections that can be used in the projection of a `Place`. +/// +/// `T1` is the generic type for a field projection. For an actual projection on a `Place` +/// this parameter will always be `Ty`, but the field type can be unavailable when +/// building (by using `PlaceBuilder`) places that correspond to upvars. +/// `T2` is the generic type for an `OpaqueCast` (is generic since it's abstracted over +/// in dataflow analysis, see `AbstractElem`). #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] -pub enum ProjectionElem<V, T> { +pub enum ProjectionElem<V, T1, T2> { Deref, - Field(Field, T), + Field(Field, T1), /// Index into a slice/array. /// /// Note that this does not also dereference, and so it does not exactly correspond to slice @@ -950,12 +957,36 @@ pub enum ProjectionElem<V, T> { /// Like an explicit cast from an opaque type to a concrete type, but without /// requiring an intermediate variable. - OpaqueCast(T), + OpaqueCast(T2), } /// Alias for projections as they appear in places, where the base is a place /// and the index is a local. -pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>; +pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>, Ty<'tcx>>; + +/// Alias for projections that appear in `PlaceBuilder::Upvar`, for which +/// we cannot provide any field types. +pub type UpvarProjectionElem<'tcx> = ProjectionElem<Local, (), Ty<'tcx>>; + +impl<'tcx> From<PlaceElem<'tcx>> for UpvarProjectionElem<'tcx> { + fn from(elem: PlaceElem<'tcx>) -> Self { + match elem { + ProjectionElem::Deref => ProjectionElem::Deref, + ProjectionElem::Field(field, _) => ProjectionElem::Field(field, ()), + ProjectionElem::Index(v) => ProjectionElem::Index(v), + ProjectionElem::ConstantIndex { offset, min_length, from_end } => { + ProjectionElem::ConstantIndex { offset, min_length, from_end } + } + ProjectionElem::Subslice { from, to, from_end } => { + ProjectionElem::Subslice { from, to, from_end } + } + ProjectionElem::Downcast(opt_sym, variant_idx) => { + ProjectionElem::Downcast(opt_sym, variant_idx) + } + ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), + } + } +} /////////////////////////////////////////////////////////////////////////// // Operands diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index fa3adafd4b8..e3ca1f41d7e 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -28,8 +28,8 @@ impl<'tcx> PlaceTy<'tcx> { /// `place_ty.field_ty(tcx, f)` computes the type at a given field /// of a record or enum-variant. (Most clients of `PlaceTy` can /// instead just extract the relevant type directly from their - /// `PlaceElem`, but some instances of `ProjectionElem<V, T>` do - /// not carry a `Ty` for `T`.) + /// `PlaceElem`, but some instances of `ProjectionElem<V, T1, T2>` do + /// not carry a `Ty` for `T1` or `T2`.) /// /// Note that the resulting type has not been normalized. pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: Field) -> Ty<'tcx> { @@ -64,17 +64,18 @@ impl<'tcx> PlaceTy<'tcx> { /// `Ty` or downcast variant corresponding to that projection. /// The `handle_field` callback must map a `Field` to its `Ty`, /// (which should be trivial when `T` = `Ty`). - pub fn projection_ty_core<V, T>( + pub fn projection_ty_core<V, T1, T2>( self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - elem: &ProjectionElem<V, T>, - mut handle_field: impl FnMut(&Self, Field, T) -> Ty<'tcx>, - mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>, + elem: &ProjectionElem<V, T1, T2>, + mut handle_field: impl FnMut(&Self, Field, T1) -> Ty<'tcx>, + mut handle_opaque_cast: impl FnMut(&Self, T2) -> Ty<'tcx>, ) -> PlaceTy<'tcx> where V: ::std::fmt::Debug, - T: ::std::fmt::Debug + Copy, + T1: ::std::fmt::Debug + Copy, + T2: ::std::fmt::Debug + Copy, { if self.variant_index.is_some() && !matches!(elem, ProjectionElem::Field(..)) { bug!("cannot use non field projection on downcasted place") |
