use no type in ProjectionElem::Field for PlaceBuilder::UpVar
This commit is contained in:
parent
c39de61d2a
commit
9061ffba8c
9 changed files with 105 additions and 52 deletions
|
@ -1517,7 +1517,7 @@ impl<'tcx> StatementKind<'tcx> {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Places
|
// 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
|
/// Returns `true` if the target of this projection may refer to a different region of memory
|
||||||
/// than the base.
|
/// than the base.
|
||||||
fn is_indirect(&self) -> bool {
|
fn is_indirect(&self) -> bool {
|
||||||
|
@ -1546,7 +1546,7 @@ impl<V, T> ProjectionElem<V, T> {
|
||||||
|
|
||||||
/// Alias for projections as they appear in `UserTypeProjection`, where we
|
/// Alias for projections as they appear in `UserTypeProjection`, where we
|
||||||
/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
|
/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
|
||||||
pub type ProjectionKind = ProjectionElem<(), ()>;
|
pub type ProjectionKind = ProjectionElem<(), (), ()>;
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
/// A [newtype'd][wrapper] index type in the MIR [control-flow graph][CFG]
|
/// A [newtype'd][wrapper] index type in the MIR [control-flow graph][CFG]
|
||||||
|
|
|
@ -877,9 +877,9 @@ pub struct Place<'tcx> {
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub enum ProjectionElem<V, T> {
|
pub enum ProjectionElem<V, T1, T2> {
|
||||||
Deref,
|
Deref,
|
||||||
Field(Field, T),
|
Field(Field, T1),
|
||||||
/// Index into a slice/array.
|
/// Index into a slice/array.
|
||||||
///
|
///
|
||||||
/// Note that this does not also dereference, and so it does not exactly correspond to slice
|
/// Note that this does not also dereference, and so it does not exactly correspond to slice
|
||||||
|
@ -935,12 +935,36 @@ pub enum ProjectionElem<V, T> {
|
||||||
|
|
||||||
/// Like an explicit cast from an opaque type to a concrete type, but without
|
/// Like an explicit cast from an opaque type to a concrete type, but without
|
||||||
/// requiring an intermediate variable.
|
/// requiring an intermediate variable.
|
||||||
OpaqueCast(T),
|
OpaqueCast(T2),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Alias for projections as they appear in places, where the base is a place
|
/// Alias for projections as they appear in places, where the base is a place
|
||||||
/// and the index is a local.
|
/// 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
|
// Operands
|
||||||
|
|
|
@ -28,8 +28,8 @@ impl<'tcx> PlaceTy<'tcx> {
|
||||||
/// `place_ty.field_ty(tcx, f)` computes the type at a given field
|
/// `place_ty.field_ty(tcx, f)` computes the type at a given field
|
||||||
/// of a record or enum-variant. (Most clients of `PlaceTy` can
|
/// of a record or enum-variant. (Most clients of `PlaceTy` can
|
||||||
/// instead just extract the relevant type directly from their
|
/// instead just extract the relevant type directly from their
|
||||||
/// `PlaceElem`, but some instances of `ProjectionElem<V, T>` do
|
/// `PlaceElem`, but some instances of `ProjectionElem<V, T1, T2>` do
|
||||||
/// not carry a `Ty` for `T`.)
|
/// not carry a `Ty` for `T1` or `T2`.)
|
||||||
///
|
///
|
||||||
/// Note that the resulting type has not been normalized.
|
/// Note that the resulting type has not been normalized.
|
||||||
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: Field) -> Ty<'tcx> {
|
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.
|
/// `Ty` or downcast variant corresponding to that projection.
|
||||||
/// The `handle_field` callback must map a `Field` to its `Ty`,
|
/// The `handle_field` callback must map a `Field` to its `Ty`,
|
||||||
/// (which should be trivial when `T` = `Ty`).
|
/// (which should be trivial when `T` = `Ty`).
|
||||||
pub fn projection_ty_core<V, T>(
|
pub fn projection_ty_core<V, T1, T2>(
|
||||||
self,
|
self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
elem: &ProjectionElem<V, T>,
|
elem: &ProjectionElem<V, T1, T2>,
|
||||||
mut handle_field: impl FnMut(&Self, Field, T) -> Ty<'tcx>,
|
mut handle_field: impl FnMut(&Self, Field, T1) -> Ty<'tcx>,
|
||||||
mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>,
|
mut handle_opaque_cast: impl FnMut(&Self, T2) -> Ty<'tcx>,
|
||||||
) -> PlaceTy<'tcx>
|
) -> PlaceTy<'tcx>
|
||||||
where
|
where
|
||||||
V: ::std::fmt::Debug,
|
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(..)) {
|
if self.variant_index.is_some() && !matches!(elem, ProjectionElem::Field(..)) {
|
||||||
bug!("cannot use non field projection on downcasted place")
|
bug!("cannot use non field projection on downcasted place")
|
||||||
|
|
|
@ -19,6 +19,7 @@ use rustc_target::abi::VariantIdx;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
|
|
||||||
use std::assert_matches::assert_matches;
|
use std::assert_matches::assert_matches;
|
||||||
|
use std::convert::From;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
/// `PlaceBuilder` is used to create places during MIR construction. It allows you to "build up" a
|
/// `PlaceBuilder` is used to create places during MIR construction. It allows you to "build up" a
|
||||||
|
@ -66,7 +67,7 @@ pub(in crate::build) enum PlaceBuilder<'tcx> {
|
||||||
///
|
///
|
||||||
/// Note: in contrast to `PlaceBuilder::Local` we have not yet determined all `Field` types
|
/// Note: in contrast to `PlaceBuilder::Local` we have not yet determined all `Field` types
|
||||||
/// and will only do so once converting to `PlaceBuilder::Local`.
|
/// and will only do so once converting to `PlaceBuilder::Local`.
|
||||||
UpVar(UpVar, Vec<PlaceElem<'tcx>>),
|
UpVar(UpVar, Vec<UpvarProjectionElem<'tcx>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
@ -82,7 +83,7 @@ pub(crate) struct UpVar {
|
||||||
/// part of a path that is captured by a closure. We stop applying projections once we see the first
|
/// part of a path that is captured by a closure. We stop applying projections once we see the first
|
||||||
/// projection that isn't captured by a closure.
|
/// projection that isn't captured by a closure.
|
||||||
fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
|
fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
|
||||||
mir_projections: &[PlaceElem<'tcx>],
|
mir_projections: &[UpvarProjectionElem<'tcx>],
|
||||||
) -> Vec<HirProjectionKind> {
|
) -> Vec<HirProjectionKind> {
|
||||||
let mut hir_projections = Vec::new();
|
let mut hir_projections = Vec::new();
|
||||||
let mut variant = None;
|
let mut variant = None;
|
||||||
|
@ -156,7 +157,7 @@ fn is_ancestor_or_same_capture(
|
||||||
fn find_capture_matching_projections<'a, 'tcx>(
|
fn find_capture_matching_projections<'a, 'tcx>(
|
||||||
upvars: &'a CaptureMap<'tcx>,
|
upvars: &'a CaptureMap<'tcx>,
|
||||||
var_hir_id: LocalVarId,
|
var_hir_id: LocalVarId,
|
||||||
projections: &[PlaceElem<'tcx>],
|
projections: &[UpvarProjectionElem<'tcx>],
|
||||||
) -> Option<(usize, &'a Capture<'tcx>)> {
|
) -> Option<(usize, &'a Capture<'tcx>)> {
|
||||||
let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections);
|
let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections);
|
||||||
|
|
||||||
|
@ -212,8 +213,7 @@ fn to_upvars_resolved_place_builder<'tcx>(
|
||||||
capture.captured_place.place.base_ty,
|
capture.captured_place.place.base_ty,
|
||||||
projection,
|
projection,
|
||||||
&capture.captured_place.place.projections,
|
&capture.captured_place.place.projections,
|
||||||
)
|
);
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let upvar_resolved_place_builder = PlaceBuilder::construct_local_place_builder(
|
let upvar_resolved_place_builder = PlaceBuilder::construct_local_place_builder(
|
||||||
cx,
|
cx,
|
||||||
|
@ -222,6 +222,37 @@ fn to_upvars_resolved_place_builder<'tcx>(
|
||||||
upvar_projection,
|
upvar_projection,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
debug_assert!({
|
||||||
|
let builder = upvar_resolved_place_builder.clone();
|
||||||
|
let mut valid_conversion = true;
|
||||||
|
match builder {
|
||||||
|
PlaceBuilder::Local(_, projections) => {
|
||||||
|
for proj in projections.iter() {
|
||||||
|
match proj {
|
||||||
|
ProjectionElem::Field(_, field_ty) => {
|
||||||
|
if matches!(field_ty.kind(), ty::Infer(..)) {
|
||||||
|
debug!(
|
||||||
|
"field ty should have been converted for projection {:?} in PlaceBuilder {:?}",
|
||||||
|
proj,
|
||||||
|
upvar_resolved_place_builder.clone()
|
||||||
|
);
|
||||||
|
|
||||||
|
valid_conversion = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlaceBuilder::UpVar(..) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_conversion
|
||||||
|
});
|
||||||
|
|
||||||
Some(upvar_resolved_place_builder)
|
Some(upvar_resolved_place_builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,14 +264,14 @@ fn to_upvars_resolved_place_builder<'tcx>(
|
||||||
/// projection kinds are unsupported.
|
/// projection kinds are unsupported.
|
||||||
fn strip_prefix<'a, 'tcx>(
|
fn strip_prefix<'a, 'tcx>(
|
||||||
mut base_ty: Ty<'tcx>,
|
mut base_ty: Ty<'tcx>,
|
||||||
projections: &'a [PlaceElem<'tcx>],
|
projections: &'a [UpvarProjectionElem<'tcx>],
|
||||||
prefix_projections: &[HirProjection<'tcx>],
|
prefix_projections: &[HirProjection<'tcx>],
|
||||||
) -> impl Iterator<Item = PlaceElem<'tcx>> + 'a {
|
) -> Vec<UpvarProjectionElem<'tcx>> {
|
||||||
let mut iter = projections
|
let mut iter = projections
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
|
||||||
// Filter out opaque casts, they are unnecessary in the prefix.
|
// Filter out opaque casts, they are unnecessary in the prefix.
|
||||||
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..)));
|
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..)))
|
||||||
|
.map(|elem| *elem);
|
||||||
for projection in prefix_projections {
|
for projection in prefix_projections {
|
||||||
debug!(?projection, ?projection.ty);
|
debug!(?projection, ?projection.ty);
|
||||||
|
|
||||||
|
@ -261,7 +292,8 @@ fn strip_prefix<'a, 'tcx>(
|
||||||
|
|
||||||
base_ty = projection.ty;
|
base_ty = projection.ty;
|
||||||
}
|
}
|
||||||
iter
|
|
||||||
|
iter.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PlaceBuilder<'tcx> {
|
impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
|
@ -292,11 +324,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
cx: &Builder<'_, 'tcx>,
|
cx: &Builder<'_, 'tcx>,
|
||||||
) -> Option<PlaceBuilder<'tcx>> {
|
) -> Option<PlaceBuilder<'tcx>> {
|
||||||
let PlaceBuilder::Upvar( Upvar {var_hir_id, closure_def_id }, projection) = self else {
|
let PlaceBuilder::UpVar( UpVar {var_hir_id, closure_def_id }, projection) = self else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
to_upvars_resolved_place_builder(cx, var_hir_id, closure_def_id, &projection)
|
to_upvars_resolved_place_builder(cx, *var_hir_id, *closure_def_id, &projection)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_local_projection(&self) -> &[PlaceElem<'tcx>] {
|
pub(crate) fn get_local_projection(&self) -> &[PlaceElem<'tcx>] {
|
||||||
|
@ -309,19 +341,16 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(cx), level = "debug")]
|
#[instrument(skip(cx), level = "debug")]
|
||||||
pub(crate) fn field(
|
pub(crate) fn field(self, cx: &Builder<'_, 'tcx>, f: Field) -> Self {
|
||||||
self,
|
|
||||||
cx: &Builder<'_, 'tcx>,
|
|
||||||
f: Field,
|
|
||||||
default_field_ty: Ty<'tcx>,
|
|
||||||
) -> Self {
|
|
||||||
let field_ty = match self {
|
let field_ty = match self {
|
||||||
PlaceBuilder::Local(..) => {
|
PlaceBuilder::Local(..) => {
|
||||||
let base_place = self.clone();
|
let base_place = self.clone();
|
||||||
PlaceBuilder::try_compute_field_ty(cx, f, base_place)
|
PlaceBuilder::compute_field_ty(cx, f, base_place)
|
||||||
.unwrap_or_else(|| default_field_ty)
|
}
|
||||||
|
PlaceBuilder::UpVar(..) => {
|
||||||
|
let dummy_ty = cx.tcx.mk_ty_infer(ty::FreshTy(0));
|
||||||
|
dummy_ty
|
||||||
}
|
}
|
||||||
PlaceBuilder::UpVar(..) => default_field_ty,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.project(ProjectionElem::Field(f, field_ty))
|
self.project(ProjectionElem::Field(f, field_ty))
|
||||||
|
@ -347,7 +376,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
PlaceBuilder::Local(local, proj)
|
PlaceBuilder::Local(local, proj)
|
||||||
}
|
}
|
||||||
PlaceBuilder::UpVar(upvar, mut proj) => {
|
PlaceBuilder::UpVar(upvar, mut proj) => {
|
||||||
proj.push(elem);
|
proj.push(elem.into());
|
||||||
PlaceBuilder::UpVar(upvar, proj)
|
PlaceBuilder::UpVar(upvar, proj)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -363,8 +392,8 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
*local,
|
*local,
|
||||||
Vec::from_iter(proj.iter().copied().chain([elem.into()])),
|
Vec::from_iter(proj.iter().copied().chain([elem.into()])),
|
||||||
),
|
),
|
||||||
PlaceBuilder::Upvar(upvar, proj) => PlaceBuilder::UpVar(
|
PlaceBuilder::UpVar(upvar, proj) => PlaceBuilder::UpVar(
|
||||||
upvar,
|
*upvar,
|
||||||
Vec::from_iter(proj.iter().copied().chain([elem.into()])),
|
Vec::from_iter(proj.iter().copied().chain([elem.into()])),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -378,11 +407,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
/// Fallible as the root of this place may be an upvar for
|
/// Fallible as the root of this place may be an upvar for
|
||||||
/// which no base type can be determined.
|
/// which no base type can be determined.
|
||||||
#[instrument(skip(cx), level = "debug")]
|
#[instrument(skip(cx), level = "debug")]
|
||||||
fn try_compute_field_ty(
|
fn compute_field_ty(
|
||||||
cx: &Builder<'_, 'tcx>,
|
cx: &Builder<'_, 'tcx>,
|
||||||
field: Field,
|
field: Field,
|
||||||
base_place: PlaceBuilder<'tcx>,
|
base_place: PlaceBuilder<'tcx>,
|
||||||
) -> Option<Ty<'tcx>> {
|
) -> Ty<'tcx> {
|
||||||
let field_idx = field.as_usize();
|
let field_idx = field.as_usize();
|
||||||
let PlaceTy { ty, variant_index } = base_place.to_place(cx).ty(&cx.local_decls, cx.tcx);
|
let PlaceTy { ty, variant_index } = base_place.to_place(cx).ty(&cx.local_decls, cx.tcx);
|
||||||
let base_ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
|
let base_ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
|
||||||
|
@ -442,7 +471,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
_ => bug!("couldn't create field type, unexpected base type: {:?}", base_ty),
|
_ => bug!("couldn't create field type, unexpected base type: {:?}", base_ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(cx.tcx.normalize_erasing_regions(cx.param_env, field_ty))
|
cx.tcx.normalize_erasing_regions(cx.param_env, field_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a `PlaceBuilder::Local` from a `PlaceBuilder::UpVar` whose upvars
|
/// Creates a `PlaceBuilder::Local` from a `PlaceBuilder::UpVar` whose upvars
|
||||||
|
@ -455,7 +484,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
cx: &Builder<'_, 'tcx>,
|
cx: &Builder<'_, 'tcx>,
|
||||||
local: Local,
|
local: Local,
|
||||||
mut local_projection: Vec<PlaceElem<'tcx>>,
|
mut local_projection: Vec<PlaceElem<'tcx>>,
|
||||||
upvar_projection: Vec<PlaceElem<'tcx>>,
|
upvar_projection: Vec<UpvarProjectionElem<'tcx>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// We iterate through `upvar_projection` and whenever we find a `ProjectionElem::Field` we use
|
// We iterate through `upvar_projection` and whenever we find a `ProjectionElem::Field` we use
|
||||||
// the ancestor projections, i.e. those projection elements that come before the field projection,
|
// the ancestor projections, i.e. those projection elements that come before the field projection,
|
||||||
|
@ -464,11 +493,10 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
for proj in upvar_projection.iter() {
|
for proj in upvar_projection.iter() {
|
||||||
debug!("proj: {:?}, local_projection: {:?}", proj, local_projection);
|
debug!("proj: {:?}, local_projection: {:?}", proj, local_projection);
|
||||||
match *proj {
|
match *proj {
|
||||||
ProjectionElem::Field(field, default_field_ty) => {
|
ProjectionElem::Field(field, _) => {
|
||||||
let ancestor_proj = local_projection.to_vec();
|
let ancestor_proj = local_projection.to_vec();
|
||||||
let base_place = PlaceBuilder::Local(local, ancestor_proj);
|
let base_place = PlaceBuilder::Local(local, ancestor_proj);
|
||||||
let field_ty = PlaceBuilder::try_compute_field_ty(cx, field, base_place)
|
let field_ty = PlaceBuilder::compute_field_ty(cx, field, base_place);
|
||||||
.unwrap_or_else(|| default_field_ty);
|
|
||||||
debug!(?field_ty);
|
debug!(?field_ty);
|
||||||
|
|
||||||
local_projection.push(ProjectionElem::Field(field, field_ty));
|
local_projection.push(ProjectionElem::Field(field, field_ty));
|
||||||
|
@ -593,7 +621,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
place_builder = place_builder.downcast(*adt_def, variant_index);
|
place_builder = place_builder.downcast(*adt_def, variant_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block.and(place_builder.field(this, name, expr.ty))
|
block.and(place_builder.field(this, name))
|
||||||
}
|
}
|
||||||
ExprKind::Deref { arg } => {
|
ExprKind::Deref { arg } => {
|
||||||
let place_builder = unpack!(
|
let place_builder = unpack!(
|
||||||
|
|
|
@ -355,12 +355,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// base-supplied field, generate an operand that
|
// base-supplied field, generate an operand that
|
||||||
// reads it from the base.
|
// reads it from the base.
|
||||||
iter::zip(field_names, &**field_types)
|
iter::zip(field_names, &**field_types)
|
||||||
.map(|(n, ty)| match fields_map.get(&n) {
|
.map(|(n, _ty)| match fields_map.get(&n) {
|
||||||
Some(v) => v.clone(),
|
Some(v) => v.clone(),
|
||||||
None => {
|
None => {
|
||||||
let place_builder = place_builder.clone();
|
let place_builder = place_builder.clone();
|
||||||
this.consume_by_copy_or_move(
|
this.consume_by_copy_or_move(
|
||||||
place_builder.field(this, n, *ty).to_place(this),
|
place_builder.field(this, n).to_place(this),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -760,7 +760,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let downcast_place = match_pair.place.downcast(adt_def, variant_index); // `(x as Variant)`
|
let downcast_place = match_pair.place.downcast(adt_def, variant_index); // `(x as Variant)`
|
||||||
let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
|
let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
|
||||||
// e.g., `(x as Variant).0`
|
// e.g., `(x as Variant).0`
|
||||||
let place = downcast_place.clone().field(self, subpattern.field, subpattern.pattern.ty);
|
let place = downcast_place.clone().field(self, subpattern.field);
|
||||||
// e.g., `(x as Variant).0 @ P1`
|
// e.g., `(x as Variant).0 @ P1`
|
||||||
MatchPair::new(place, &subpattern.pattern, self)
|
MatchPair::new(place, &subpattern.pattern, self)
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,7 +17,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
subpatterns
|
subpatterns
|
||||||
.iter()
|
.iter()
|
||||||
.map(|fieldpat| {
|
.map(|fieldpat| {
|
||||||
let place = place.clone().field(self, fieldpat.field, fieldpat.pattern.ty);
|
let place = place.clone().field(self, fieldpat.field);
|
||||||
|
|
||||||
MatchPair::new(place, &fieldpat.pattern, self)
|
MatchPair::new(place, &fieldpat.pattern, self)
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,7 +18,7 @@ use rustc_middle::ty::Ty;
|
||||||
pub struct AbstractOperand;
|
pub struct AbstractOperand;
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct AbstractType;
|
pub struct AbstractType;
|
||||||
pub type AbstractElem = ProjectionElem<AbstractOperand, AbstractType>;
|
pub type AbstractElem = ProjectionElem<AbstractOperand, AbstractType, AbstractType>;
|
||||||
|
|
||||||
pub trait Lift {
|
pub trait Lift {
|
||||||
type Abstract;
|
type Abstract;
|
||||||
|
|
|
@ -777,10 +777,10 @@ pub enum TrackElem {
|
||||||
Field(Field),
|
Field(Field),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V, T> TryFrom<ProjectionElem<V, T>> for TrackElem {
|
impl<V, T1, T2> TryFrom<ProjectionElem<V, T1, T2>> for TrackElem {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn try_from(value: ProjectionElem<V, T>) -> Result<Self, Self::Error> {
|
fn try_from(value: ProjectionElem<V, T1, T2>) -> Result<Self, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
ProjectionElem::Field(field, _) => Ok(TrackElem::Field(field)),
|
ProjectionElem::Field(field, _) => Ok(TrackElem::Field(field)),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue