Make sanitize_place iterate instead of recurse

This commit is contained in:
Santiago Pastorino 2019-05-23 21:41:10 +02:00
parent 27cc0db7a2
commit 03dc30d3d5

View File

@ -29,7 +29,7 @@ use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionV
use rustc::infer::type_variable::TypeVariableOrigin; use rustc::infer::type_variable::TypeVariableOrigin;
use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue}; use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
use rustc::mir::tcx::PlaceTy; use rustc::mir::tcx::PlaceTy;
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext}; use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
use rustc::mir::*; use rustc::mir::*;
use rustc::traits::query::type_op; use rustc::traits::query::type_op;
use rustc::traits::query::type_op::custom::CustomTypeOp; use rustc::traits::query::type_op::custom::CustomTypeOp;
@ -447,10 +447,12 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
context: PlaceContext, context: PlaceContext,
) -> PlaceTy<'tcx> { ) -> PlaceTy<'tcx> {
debug!("sanitize_place: {:?}", place); debug!("sanitize_place: {:?}", place);
let place_ty = match place {
Place::Base(PlaceBase::Local(index)) => place.iterate(|place_base, place_projection| {
let mut place_ty = match place_base {
PlaceBase::Local(index) =>
PlaceTy::from_ty(self.mir.local_decls[*index].ty), PlaceTy::from_ty(self.mir.local_decls[*index].ty),
Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => { PlaceBase::Static(box Static { kind, ty: sty }) => {
let sty = self.sanitize_type(place, sty); let sty = self.sanitize_type(place, sty);
let check_err = let check_err =
|verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>, |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
@ -492,22 +494,10 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
} }
PlaceTy::from_ty(sty) PlaceTy::from_ty(sty)
} }
Place::Projection(ref proj) => {
let base_context = if context.is_mutating_use() {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
} else {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
};
let base_ty = self.sanitize_place(&proj.base, location, base_context);
if base_ty.variant_index.is_none() {
if base_ty.ty.references_error() {
assert!(self.errors_reported);
return PlaceTy::from_ty(self.tcx().types.err);
}
}
self.sanitize_projection(base_ty, &proj.elem, place, location)
}
}; };
// FIXME use place_projection.is_empty() when is available
if let Place::Base(_) = place {
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let tcx = self.tcx(); let tcx = self.tcx();
let trait_ref = ty::TraitRef { let trait_ref = ty::TraitRef {
@ -532,7 +522,20 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
ConstraintCategory::CopyBound, ConstraintCategory::CopyBound,
); );
} }
}
for proj in place_projection {
if place_ty.variant_index.is_none() {
if place_ty.ty.references_error() {
assert!(self.errors_reported);
return PlaceTy::from_ty(self.tcx().types.err);
}
}
place_ty = self.sanitize_projection(place_ty, &proj.elem, place, location)
}
place_ty place_ty
})
} }
fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location) { fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location) {