Skip to content

Commit

Permalink
Fix buggy field access translation
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Sep 3, 2016
1 parent bea0b15 commit 0cb1938
Show file tree
Hide file tree
Showing 10 changed files with 30 additions and 24 deletions.
7 changes: 5 additions & 2 deletions src/librustc/mir/repr.rs
Expand Up @@ -962,7 +962,10 @@ pub enum CastKind {
pub enum AggregateKind<'tcx> {
Vec,
Tuple,
Adt(AdtDef<'tcx>, usize, &'tcx Substs<'tcx>),
/// 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.
Adt(AdtDef<'tcx>, usize, &'tcx Substs<'tcx>, Option<usize>),
Closure(DefId, ClosureSubsts<'tcx>),
}

Expand Down Expand Up @@ -1069,7 +1072,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
}
}

Adt(adt_def, variant, substs) => {
Adt(adt_def, variant, substs, _) => {
let variant_def = &adt_def.variants[variant];

ppaux::parameterized(fmt, substs, variant_def.did,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/tcx.rs
Expand Up @@ -187,7 +187,7 @@ impl<'tcx> Rvalue<'tcx> {
ops.iter().map(|op| op.ty(mir, tcx)).collect()
))
}
AggregateKind::Adt(def, _, substs) => {
AggregateKind::Adt(def, _, substs, _) => {
Some(tcx.lookup_item_type(def.did).ty.subst(tcx, substs))
}
AggregateKind::Closure(did, substs) => {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/mir/visit.rs
Expand Up @@ -536,7 +536,8 @@ macro_rules! make_mir_visitor {
}
AggregateKind::Adt(_adt_def,
_variant_index,
ref $($mutability)* substs) => {
ref $($mutability)* substs,
_active_field_index) => {
self.visit_substs(substs);
}
AggregateKind::Closure(ref $($mutability)* def_id,
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_mir/build/expr/as_rvalue.rs
Expand Up @@ -181,6 +181,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ExprKind::Adt {
adt_def, variant_index, substs, fields, base
} => { // see (*) above
let is_union = adt_def.adt_kind() == ty::AdtKind::Union;
let active_field_index = if is_union { Some(fields[0].name.index()) } else { None };

// first process the set of fields that were provided
// (evaluating them in order given by user)
let fields_map: FnvHashMap<_, _> =
Expand All @@ -204,11 +207,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
})
.collect()
} else {
field_names.iter().map(|n| fields_map[n].clone()).collect()
field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect()
};

block.and(Rvalue::Aggregate(AggregateKind::Adt(adt_def, variant_index, substs),
fields))
let adt = AggregateKind::Adt(adt_def, variant_index, substs, active_field_index);
block.and(Rvalue::Aggregate(adt, fields))
}
ExprKind::Assign { .. } |
ExprKind::AssignOp { .. } => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/transform/deaggregator.rs
Expand Up @@ -57,7 +57,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
_ => span_bug!(src_info.span, "expected aggregate, not {:?}", rhs),
};
let (adt_def, variant, substs) = match agg_kind {
&AggregateKind::Adt(adt_def, variant, substs) => (adt_def, variant, substs),
&AggregateKind::Adt(adt_def, variant, substs, None) => (adt_def, variant, substs),
_ => span_bug!(src_info.span, "expected struct, not {:?}", rhs),
};
let n = bb.statements.len();
Expand Down Expand Up @@ -120,7 +120,7 @@ fn get_aggregate_statement_index<'a, 'tcx, 'b>(start: usize,
_ => continue,
};
let (adt_def, variant) = match kind {
&AggregateKind::Adt(adt_def, variant, _) => (adt_def, variant),
&AggregateKind::Adt(adt_def, variant, _, None) => (adt_def, variant),
_ => continue,
};
if operands.len() == 0 {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/qualify_consts.rs
Expand Up @@ -705,7 +705,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
}

Rvalue::Aggregate(ref kind, _) => {
if let AggregateKind::Adt(def, _, _) = *kind {
if let AggregateKind::Adt(def, _, _, _) = *kind {
if def.has_dtor() {
self.add(Qualif::NEEDS_DROP);
self.deny_drop();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/mir/constant.rs
Expand Up @@ -547,7 +547,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
self.monomorphize(&substs));
}

let val = if let mir::AggregateKind::Adt(adt_def, index, _) = *kind {
let val = if let mir::AggregateKind::Adt(adt_def, index, _, _) = *kind {
let repr = adt::represent_type(self.ccx, dest_ty);
let disr = Disr::from(adt_def.variants[index].disr_val);
adt::trans_const(self.ccx, &repr, disr, &fields)
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_trans/mir/rvalue.rs
Expand Up @@ -110,9 +110,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {

mir::Rvalue::Aggregate(ref kind, ref operands) => {
match *kind {
mir::AggregateKind::Adt(adt_def, index, _) => {
mir::AggregateKind::Adt(adt_def, variant_index, _, active_field_index) => {
let repr = adt::represent_type(bcx.ccx(), dest.ty.to_ty(bcx.tcx()));
let disr = Disr::from(adt_def.variants[index].disr_val);
let disr = Disr::from(adt_def.variants[variant_index].disr_val);
bcx.with_block(|bcx| {
adt::trans_set_discr(bcx, &repr, dest.llval, Disr::from(disr));
});
Expand All @@ -121,8 +121,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
// Do not generate stores and GEPis for zero-sized fields.
if !common::type_is_zero_size(bcx.ccx(), op.ty) {
let val = adt::MaybeSizedValue::sized(dest.llval);
let lldest_i = adt::trans_field_ptr_builder(&bcx, &repr,
val, disr, i);
let field_index = active_field_index.unwrap_or(i);
let lldest_i = adt::trans_field_ptr_builder(&bcx, &repr, val,
disr, field_index);
self.store_operand(&bcx, lldest_i, op);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/run-pass/union-basic.rs
Expand Up @@ -48,12 +48,12 @@ fn main() {
assert_eq!(a, 10);
}

let mut w: W = unsafe { zeroed() };
let mut w = W { b: 0 };
unsafe {
assert_eq!(w.a, 0);
assert_eq!(w.b, 0);
// w.a = 1;
// assert_eq!(w.a, 0);
// assert_eq!(w.b, 0);
assert_eq!(w.a, 0);
assert_eq!(w.b, 0);
}
}
10 changes: 4 additions & 6 deletions src/test/run-pass/union-pat-refutability.rs
Expand Up @@ -54,11 +54,9 @@ fn refut(w: W) {
}

fn main() {
// ICE
// let v = Value { tag: Tag::I, u: U { i: 1 } };
// assert_eq!(is_zero(v), false);
let v = Value { tag: Tag::I, u: U { i: 1 } };
assert_eq!(is_zero(v), false);

// ICE
// let w = W { a: 11 };
// refut(w);
let w = W { a: 11 };
refut(w);
}

0 comments on commit 0cb1938

Please sign in to comment.