Skip to content

Commit cd95523

Browse files
authored
Rollup merge of rust-lang#61092 - spastorino:sanitize-place-iterative, r=oli-obk
Make sanitize_place iterate instead of recurse r? @oli-obk
2 parents 5cbb7a1 + 03dc30d commit cd95523

File tree

1 file changed

+78
-75
lines changed
  • src/librustc_mir/borrow_check/nll/type_check

1 file changed

+78
-75
lines changed

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+78-75
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionV
2929
use rustc::infer::type_variable::TypeVariableOrigin;
3030
use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
3131
use rustc::mir::tcx::PlaceTy;
32-
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
32+
use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
3333
use rustc::mir::*;
3434
use rustc::traits::query::type_op;
3535
use rustc::traits::query::type_op::custom::CustomTypeOp;
@@ -447,92 +447,95 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
447447
context: PlaceContext,
448448
) -> PlaceTy<'tcx> {
449449
debug!("sanitize_place: {:?}", place);
450-
let place_ty = match place {
451-
Place::Base(PlaceBase::Local(index)) =>
452-
PlaceTy::from_ty(self.mir.local_decls[*index].ty),
453-
Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => {
454-
let sty = self.sanitize_type(place, sty);
455-
let check_err =
456-
|verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
457-
place: &Place<'tcx>,
458-
ty,
459-
sty| {
460-
if let Err(terr) = verifier.cx.eq_types(
461-
sty,
462-
ty,
463-
location.to_locations(),
464-
ConstraintCategory::Boring,
465-
) {
466-
span_mirbug!(
467-
verifier,
468-
place,
469-
"bad promoted type ({:?}: {:?}): {:?}",
470-
ty,
471-
sty,
472-
terr
473-
);
450+
451+
place.iterate(|place_base, place_projection| {
452+
let mut place_ty = match place_base {
453+
PlaceBase::Local(index) =>
454+
PlaceTy::from_ty(self.mir.local_decls[*index].ty),
455+
PlaceBase::Static(box Static { kind, ty: sty }) => {
456+
let sty = self.sanitize_type(place, sty);
457+
let check_err =
458+
|verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
459+
place: &Place<'tcx>,
460+
ty,
461+
sty| {
462+
if let Err(terr) = verifier.cx.eq_types(
463+
sty,
464+
ty,
465+
location.to_locations(),
466+
ConstraintCategory::Boring,
467+
) {
468+
span_mirbug!(
469+
verifier,
470+
place,
471+
"bad promoted type ({:?}: {:?}): {:?}",
472+
ty,
473+
sty,
474+
terr
475+
);
476+
};
474477
};
475-
};
476-
match kind {
477-
StaticKind::Promoted(promoted) => {
478-
if !self.errors_reported {
479-
let promoted_mir = &self.mir.promoted[*promoted];
480-
self.sanitize_promoted(promoted_mir, location);
481-
482-
let promoted_ty = promoted_mir.return_ty();
483-
check_err(self, place, promoted_ty, sty);
478+
match kind {
479+
StaticKind::Promoted(promoted) => {
480+
if !self.errors_reported {
481+
let promoted_mir = &self.mir.promoted[*promoted];
482+
self.sanitize_promoted(promoted_mir, location);
483+
484+
let promoted_ty = promoted_mir.return_ty();
485+
check_err(self, place, promoted_ty, sty);
486+
}
484487
}
485-
}
486-
StaticKind::Static(def_id) => {
487-
let ty = self.tcx().type_of(*def_id);
488-
let ty = self.cx.normalize(ty, location);
488+
StaticKind::Static(def_id) => {
489+
let ty = self.tcx().type_of(*def_id);
490+
let ty = self.cx.normalize(ty, location);
489491

490-
check_err(self, place, ty, sty);
492+
check_err(self, place, ty, sty);
493+
}
491494
}
495+
PlaceTy::from_ty(sty)
496+
}
497+
};
498+
499+
// FIXME use place_projection.is_empty() when is available
500+
if let Place::Base(_) = place {
501+
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
502+
let tcx = self.tcx();
503+
let trait_ref = ty::TraitRef {
504+
def_id: tcx.lang_items().copy_trait().unwrap(),
505+
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
506+
};
507+
508+
// In order to have a Copy operand, the type T of the
509+
// value must be Copy. Note that we prove that T: Copy,
510+
// rather than using the `is_copy_modulo_regions`
511+
// test. This is important because
512+
// `is_copy_modulo_regions` ignores the resulting region
513+
// obligations and assumes they pass. This can result in
514+
// bounds from Copy impls being unsoundly ignored (e.g.,
515+
// #29149). Note that we decide to use Copy before knowing
516+
// whether the bounds fully apply: in effect, the rule is
517+
// that if a value of some type could implement Copy, then
518+
// it must.
519+
self.cx.prove_trait_ref(
520+
trait_ref,
521+
location.to_locations(),
522+
ConstraintCategory::CopyBound,
523+
);
492524
}
493-
PlaceTy::from_ty(sty)
494525
}
495-
Place::Projection(ref proj) => {
496-
let base_context = if context.is_mutating_use() {
497-
PlaceContext::MutatingUse(MutatingUseContext::Projection)
498-
} else {
499-
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
500-
};
501-
let base_ty = self.sanitize_place(&proj.base, location, base_context);
502-
if base_ty.variant_index.is_none() {
503-
if base_ty.ty.references_error() {
526+
527+
for proj in place_projection {
528+
if place_ty.variant_index.is_none() {
529+
if place_ty.ty.references_error() {
504530
assert!(self.errors_reported);
505531
return PlaceTy::from_ty(self.tcx().types.err);
506532
}
507533
}
508-
self.sanitize_projection(base_ty, &proj.elem, place, location)
534+
place_ty = self.sanitize_projection(place_ty, &proj.elem, place, location)
509535
}
510-
};
511-
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
512-
let tcx = self.tcx();
513-
let trait_ref = ty::TraitRef {
514-
def_id: tcx.lang_items().copy_trait().unwrap(),
515-
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
516-
};
517536

518-
// In order to have a Copy operand, the type T of the
519-
// value must be Copy. Note that we prove that T: Copy,
520-
// rather than using the `is_copy_modulo_regions`
521-
// test. This is important because
522-
// `is_copy_modulo_regions` ignores the resulting region
523-
// obligations and assumes they pass. This can result in
524-
// bounds from Copy impls being unsoundly ignored (e.g.,
525-
// #29149). Note that we decide to use Copy before knowing
526-
// whether the bounds fully apply: in effect, the rule is
527-
// that if a value of some type could implement Copy, then
528-
// it must.
529-
self.cx.prove_trait_ref(
530-
trait_ref,
531-
location.to_locations(),
532-
ConstraintCategory::CopyBound,
533-
);
534-
}
535-
place_ty
537+
place_ty
538+
})
536539
}
537540

538541
fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location) {

0 commit comments

Comments
 (0)