提交 45f60271 编写于 作者: N Niko Matsakis

break type-checking of aggregate-kind out into helper function

上级 31d61f1f
......@@ -1031,13 +1031,13 @@ fn check_local(&mut self, mir: &Mir<'tcx>, local: Local, local_decl: &LocalDecl<
fn aggregate_field_ty(
&mut self,
ak: &Box<AggregateKind<'tcx>>,
ak: &AggregateKind<'tcx>,
field_index: usize,
location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();
match **ak {
match *ak {
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);
......@@ -1069,56 +1069,17 @@ fn aggregate_field_ty(
}
}
}
AggregateKind::Array(ty) => {
Ok(ty)
}
AggregateKind::Array(ty) => Ok(ty),
AggregateKind::Tuple => {
unreachable!("This should have been covered in check_rvalues");
}
}
}
fn check_rvalue(&mut self, mir: &Mir<'tcx>, rv: &Rvalue<'tcx>, location: Location) {
let tcx = self.tcx();
match rv {
fn check_rvalue(&mut self, mir: &Mir<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
match rvalue {
Rvalue::Aggregate(ak, ops) => {
match **ak {
// tuple rvalue field type is always the type of the op. Nothing to check here.
AggregateKind::Tuple => {}
_ => {
for (i, op) in ops.iter().enumerate() {
let field_ty = match self.aggregate_field_ty(ak, i, location) {
Ok(field_ty) => field_ty,
Err(FieldAccessError::OutOfRange { field_count }) => {
span_mirbug!(
self,
rv,
"accessed field #{} but variant only has {}",
i,
field_count
);
continue;
}
};
let op_ty = op.ty(mir, tcx);
if let Err(terr) = self.sub_types(
op_ty,
field_ty,
location.at_successor_within_block(),
)
{
span_mirbug!(
self,
rv,
"{:?} is not a subtype of {:?}: {:?}",
op_ty,
field_ty,
terr
);
}
}
}
}
self.check_aggregate_rvalue(mir, rvalue, ak, ops, location)
}
// FIXME: These other cases have to be implemented in future PRs
Rvalue::Use(..) |
......@@ -1134,6 +1095,52 @@ fn check_rvalue(&mut self, mir: &Mir<'tcx>, rv: &Rvalue<'tcx>, location: Locatio
}
}
fn check_aggregate_rvalue(
&mut self,
mir: &Mir<'tcx>,
rvalue: &Rvalue<'tcx>,
aggregate_kind: &AggregateKind<'tcx>,
operands: &[Operand<'tcx>],
location: Location,
) {
match aggregate_kind {
// tuple rvalue field type is always the type of the op. Nothing to check here.
AggregateKind::Tuple => return,
_ => {}
}
let tcx = self.tcx();
for (i, operand) in operands.iter().enumerate() {
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
Ok(field_ty) => field_ty,
Err(FieldAccessError::OutOfRange { field_count }) => {
span_mirbug!(
self,
rvalue,
"accessed field #{} but variant only has {}",
i,
field_count
);
continue;
}
};
let operand_ty = operand.ty(mir, tcx);
if let Err(terr) =
self.sub_types(operand_ty, field_ty, location.at_successor_within_block())
{
span_mirbug!(
self,
rvalue,
"{:?} is not a subtype of {:?}: {:?}",
operand_ty,
field_ty,
terr
);
}
}
}
fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
self.last_span = mir.span;
debug!("run_on_mir: {:?}", mir.span);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册