Skip to content

Commit f7eedfa

Browse files
committed
Simplify value field access
1 parent 47f37d6 commit f7eedfa

File tree

3 files changed

+30
-39
lines changed

3 files changed

+30
-39
lines changed

src/librustc_mir/interpret/place.rs

+23-10
Original file line numberDiff line numberDiff line change
@@ -120,29 +120,42 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
120120
variant: Option<usize>,
121121
field: mir::Field,
122122
base_ty: Ty<'tcx>,
123-
) -> EvalResult<'tcx, Option<(Value, Ty<'tcx>)>> {
123+
) -> EvalResult<'tcx, ValTy<'tcx>> {
124124
let mut base_layout = self.layout_of(base_ty)?;
125125
if let Some(variant_index) = variant {
126126
base_layout = base_layout.for_variant(self, variant_index);
127127
}
128128
let field_index = field.index();
129129
let field = base_layout.field(self, field_index)?;
130130
if field.size.bytes() == 0 {
131-
return Ok(Some((Value::Scalar(Scalar::undef()), field.ty)))
131+
return Ok(ValTy {
132+
value: Value::Scalar(Scalar::undef()),
133+
ty: field.ty,
134+
});
132135
}
133136
let offset = base_layout.fields.offset(field_index);
134-
match base {
137+
let value = match base {
135138
// the field covers the entire type
136139
Value::ScalarPair(..) |
137-
Value::Scalar(_) if offset.bytes() == 0 && field.size == base_layout.size => Ok(Some((base, field.ty))),
138-
// split fat pointers, 2 element tuples, ...
140+
Value::Scalar(_) if offset.bytes() == 0 && field.size == base_layout.size => base,
141+
// extract fields from types with `ScalarPair` ABI
139142
Value::ScalarPair(a, b) => {
140143
let val = if offset.bytes() == 0 { a } else { b };
141-
Ok(Some((Value::Scalar(val), field.ty)))
144+
Value::Scalar(val)
142145
},
143-
// FIXME(oli-obk): figure out whether we should be calling `try_read_value` here
144-
_ => Ok(None),
145-
}
146+
Value::ByRef(base_ptr, align) => {
147+
let offset = base_layout.fields.offset(field_index);
148+
let ptr = base_ptr.ptr_offset(offset, self)?;
149+
let align = align.min(base_layout.align).min(field.align);
150+
assert!(!field.is_unsized());
151+
Value::ByRef(ptr, align)
152+
},
153+
Value::Scalar(val) => bug!("field access on non aggregate {:?}, {:?}", val, base_ty),
154+
};
155+
Ok(ValTy {
156+
value,
157+
ty: field.ty,
158+
})
146159
}
147160

148161
fn try_read_place_projection(
@@ -156,7 +169,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
156169
};
157170
let base_ty = self.place_ty(&proj.base);
158171
match proj.elem {
159-
Field(field, _) => Ok(self.read_field(base, None, field, base_ty)?.map(|(f, _)| f)),
172+
Field(field, _) => Ok(Some(self.read_field(base, None, field, base_ty)?.value)),
160173
// The NullablePointer cases should work fine, need to take care for normal enums
161174
Downcast(..) |
162175
Subslice { .. } |

src/librustc_mir/interpret/terminator/mod.rs

+4-26
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc::ty::layout::LayoutOf;
44
use syntax::codemap::Span;
55
use rustc_target::spec::abi::Abi;
66

7-
use rustc::mir::interpret::{EvalResult, Value};
7+
use rustc::mir::interpret::EvalResult;
88
use super::{EvalContext, Place, Machine, ValTy};
99

1010
use rustc_data_structures::indexed_vec::Idx;
@@ -345,31 +345,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
345345
}
346346
if self.frame().mir.args_iter().count() == layout.fields.count() + 1 {
347347
for (i, arg_local) in arg_locals.enumerate() {
348-
let field = layout.field(&self, i)?;
349-
if field.is_zst() {
350-
continue;
351-
}
352-
let offset = layout.fields.offset(i);
353-
let value = match args[1].value {
354-
Value::ByRef(ptr, align) => Value::ByRef(
355-
ptr.ptr_offset(offset, &self)?,
356-
align.min(field.align),
357-
),
358-
other if field.size == layout.size => {
359-
// this is the case where the field covers the entire type
360-
assert_eq!(offset.bytes(), 0);
361-
other
362-
},
363-
Value::ScalarPair(a, _) if offset.bytes() == 0 => Value::Scalar(a),
364-
Value::ScalarPair(_, b) => Value::Scalar(b),
365-
Value::Scalar(_) => bug!("Scalar does not cover entire type"),
366-
};
367-
let dest =
368-
self.eval_place(&mir::Place::Local(arg_local))?;
369-
let valty = ValTy {
370-
value,
371-
ty: field.ty,
372-
};
348+
let field = mir::Field::new(i);
349+
let valty = self.read_field(args[1].value, None, field, args[1].ty)?;
350+
let dest = self.eval_place(&mir::Place::Local(arg_local))?;
373351
self.write_value(valty, dest)?;
374352
}
375353
} else {

src/librustc_mir/transform/const_prop.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,10 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
214214
ProjectionElem::Field(field, _) => {
215215
trace!("field proj on {:?}", proj.base);
216216
let (base, ty, span) = self.eval_place(&proj.base)?;
217-
let (value, field_ty) = self.use_ecx(span, |this| {
217+
let valty = self.use_ecx(span, |this| {
218218
this.ecx.read_field(base, None, field, ty)
219-
})??;
220-
Some((value, field_ty, span))
219+
})?;
220+
Some((valty.value, valty.ty, span))
221221
},
222222
_ => None,
223223
},

0 commit comments

Comments
 (0)