handle the active field index in unions

This commit is contained in:
Niko Matsakis 2017-11-12 07:03:18 -05:00
parent b3a10db03e
commit 10b8faccd0
2 changed files with 16 additions and 10 deletions

View file

@ -1375,10 +1375,14 @@ pub enum AggregateKind<'tcx> {
/// The type is of the element
Array(Ty<'tcx>),
Tuple,
/// The second field is variant number (discriminant), it's equal to 0
/// for struct and union expressions. The fourth field is active field
/// number and is present only for union expressions.
/// The second field is variant number (discriminant), it's equal
/// to 0 for struct and union expressions. The fourth field is
/// active field number and is present only for union expressions
/// -- e.g. for a union expression `SomeUnion { c: .. }`, the
/// active field index would identity the field `c`
Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<usize>),
Closure(DefId, ClosureSubsts<'tcx>),
Generator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>),
}

View file

@ -1031,14 +1031,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
fn aggregate_field_ty(
&mut self,
ak: &Box<AggregateKind<'tcx>>,
field: usize,
field_index: usize,
location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();
match **ak {
AggregateKind::Adt(def, variant, substs, _) => {
if let Some(field) = def.variants[variant].fields.get(field) {
AggregateKind::Adt(def, variant_index, substs, active_field_index) => {
let variant = &def.variants[variant_index];
let adj_field_index = active_field_index.unwrap_or(field_index);
if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(&field.ty(tcx, substs), location))
} else {
Err(FieldAccessError::OutOfRange {
@ -1047,7 +1049,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}
AggregateKind::Closure(def_id, substs) => {
match substs.upvar_tys(def_id, tcx).nth(field) {
match substs.upvar_tys(def_id, tcx).nth(field_index) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.upvar_tys(def_id, tcx).count(),
@ -1055,10 +1057,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}
AggregateKind::Generator(def_id, substs, _) => {
if let Some(ty) = substs.upvar_tys(def_id, tcx).nth(field) {
Ok(ty);
if let Some(ty) = substs.upvar_tys(def_id, tcx).nth(field_index) {
Ok(ty)
} else {
match substs.field_tys(def_id, tcx).nth(field) {
match substs.field_tys(def_id, tcx).nth(field_index) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.field_tys(def_id, tcx).count() + 1,