Be cautious of calling upvar_tys before mir
This commit is contained in:
parent
5da2bf197d
commit
e35e46c113
2 changed files with 136 additions and 110 deletions
|
@ -2105,6 +2105,21 @@ where
|
|||
}
|
||||
|
||||
fn field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout {
|
||||
enum TyMaybeWithLayout<C: LayoutOf> {
|
||||
Ty(C::Ty),
|
||||
TyAndLayout(C::TyAndLayout),
|
||||
}
|
||||
|
||||
fn ty_and_layout_kind<
|
||||
C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout: MaybeResult<TyAndLayout<'tcx>>>
|
||||
+ HasTyCtxt<'tcx>
|
||||
+ HasParamEnv<'tcx>,
|
||||
>(
|
||||
this: TyAndLayout<'tcx>,
|
||||
cx: &C,
|
||||
i: usize,
|
||||
ty: C::Ty,
|
||||
) -> TyMaybeWithLayout<C> {
|
||||
let tcx = cx.tcx();
|
||||
let tag_layout = |tag: &Scalar| -> C::TyAndLayout {
|
||||
let layout = Layout::scalar(cx, tag.clone());
|
||||
|
@ -2114,7 +2129,7 @@ where
|
|||
}))
|
||||
};
|
||||
|
||||
cx.layout_of(match *this.ty.kind() {
|
||||
match *ty.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
|
@ -2137,23 +2152,26 @@ where
|
|||
// as the `Abi` or `FieldsShape` is checked by users.
|
||||
if i == 0 {
|
||||
let nil = tcx.mk_unit();
|
||||
let ptr_ty = if this.ty.is_unsafe_ptr() {
|
||||
let ptr_ty = if ty.is_unsafe_ptr() {
|
||||
tcx.mk_mut_ptr(nil)
|
||||
} else {
|
||||
tcx.mk_mut_ref(tcx.lifetimes.re_static, nil)
|
||||
};
|
||||
return MaybeResult::from(cx.layout_of(ptr_ty).to_result().map(
|
||||
|mut ptr_layout| {
|
||||
ptr_layout.ty = this.ty;
|
||||
return TyMaybeWithLayout::TyAndLayout(MaybeResult::from(
|
||||
cx.layout_of(ptr_ty).to_result().map(|mut ptr_layout| {
|
||||
ptr_layout.ty = ty;
|
||||
ptr_layout
|
||||
},
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
|
||||
ty::Slice(_) | ty::Str => tcx.types.usize,
|
||||
ty::Slice(_) | ty::Str => TyMaybeWithLayout::Ty(tcx.types.usize),
|
||||
ty::Dynamic(_, _) => {
|
||||
tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.usize, 3))
|
||||
TyMaybeWithLayout::Ty(tcx.mk_imm_ref(
|
||||
tcx.lifetimes.re_static,
|
||||
tcx.mk_array(tcx.types.usize, 3),
|
||||
))
|
||||
/* FIXME: use actual fn pointers
|
||||
Warning: naively computing the number of entries in the
|
||||
vtable by counting the methods on the trait + methods on
|
||||
|
@ -2173,39 +2191,45 @@ where
|
|||
}
|
||||
|
||||
// Arrays and slices.
|
||||
ty::Array(element, _) | ty::Slice(element) => element,
|
||||
ty::Str => tcx.types.u8,
|
||||
ty::Array(element, _) | ty::Slice(element) => TyMaybeWithLayout::Ty(element),
|
||||
ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
|
||||
|
||||
// Tuples, generators and closures.
|
||||
ty::Closure(_, ref substs) => substs.as_closure().upvar_tys().nth(i).unwrap(),
|
||||
ty::Closure(_, ref substs) => {
|
||||
ty_and_layout_kind(this, cx, i, substs.as_closure().tupled_upvars_ty())
|
||||
}
|
||||
|
||||
ty::Generator(def_id, ref substs, _) => match this.variants {
|
||||
Variants::Single { index } => substs
|
||||
Variants::Single { index } => TyMaybeWithLayout::Ty(
|
||||
substs
|
||||
.as_generator()
|
||||
.state_tys(def_id, tcx)
|
||||
.nth(index.as_usize())
|
||||
.unwrap()
|
||||
.nth(i)
|
||||
.unwrap(),
|
||||
),
|
||||
Variants::Multiple { ref tag, tag_field, .. } => {
|
||||
if i == tag_field {
|
||||
return tag_layout(tag);
|
||||
return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
|
||||
}
|
||||
substs.as_generator().prefix_tys().nth(i).unwrap()
|
||||
TyMaybeWithLayout::Ty(substs.as_generator().prefix_tys().nth(i).unwrap())
|
||||
}
|
||||
},
|
||||
|
||||
ty::Tuple(tys) => tys[i].expect_ty(),
|
||||
ty::Tuple(tys) => TyMaybeWithLayout::Ty(tys[i].expect_ty()),
|
||||
|
||||
// ADTs.
|
||||
ty::Adt(def, substs) => {
|
||||
match this.variants {
|
||||
Variants::Single { index } => def.variants[index].fields[i].ty(tcx, substs),
|
||||
Variants::Single { index } => {
|
||||
TyMaybeWithLayout::Ty(def.variants[index].fields[i].ty(tcx, substs))
|
||||
}
|
||||
|
||||
// Discriminant field for enums (where applicable).
|
||||
Variants::Multiple { ref tag, .. } => {
|
||||
assert_eq!(i, 0);
|
||||
return tag_layout(tag);
|
||||
return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2217,6 +2241,12 @@ where
|
|||
| ty::Param(_)
|
||||
| ty::Infer(_)
|
||||
| ty::Error(_) => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty),
|
||||
}
|
||||
}
|
||||
|
||||
cx.layout_of(match ty_and_layout_kind(this, cx, i, this.ty) {
|
||||
TyMaybeWithLayout::Ty(result) => result,
|
||||
TyMaybeWithLayout::TyAndLayout(result) => return result,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -94,16 +94,12 @@ where
|
|||
_ if component.is_copy_modulo_regions(tcx.at(DUMMY_SP), self.param_env) => (),
|
||||
|
||||
ty::Closure(_, substs) => {
|
||||
for upvar_ty in substs.as_closure().upvar_tys() {
|
||||
queue_type(self, upvar_ty);
|
||||
}
|
||||
queue_type(self, substs.as_closure().tupled_upvars_ty());
|
||||
}
|
||||
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let substs = substs.as_generator();
|
||||
for upvar_ty in substs.upvar_tys() {
|
||||
queue_type(self, upvar_ty);
|
||||
}
|
||||
queue_type(self, substs.tupled_upvars_ty());
|
||||
|
||||
let witness = substs.witness();
|
||||
let interior_tys = match witness.kind() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue