From b9ed64268de50378b91f3ba7488329b7bd884e7d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 2 Oct 2019 19:11:08 -0300 Subject: [PATCH] Make visit_projection iterative --- src/librustc/mir/visit.rs | 7 +- .../transform/check_consts/validation.rs | 18 +-- src/librustc_mir/transform/qualify_consts.rs | 121 +++++++++--------- 3 files changed, 76 insertions(+), 70 deletions(-) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 7236b17999948..bfbeeebd1e230 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -734,9 +734,10 @@ macro_rules! make_mir_visitor { projection: & $($mutability)? [PlaceElem<'tcx>], context: PlaceContext, location: Location) { - if let [proj_base @ .., elem] = projection { - self.visit_projection(base, proj_base, context, location); - self.visit_projection_elem(base, proj_base, elem, context, location); + let mut cursor = projection; + while let [proj_base @ .., elem] = cursor { + cursor = proj_base; + self.visit_projection_elem(base, cursor, elem, context, location); } } diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 3045239d7a770..3a2a81f11913b 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -404,25 +404,25 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { self.super_assign(dest, rvalue, location); } - fn visit_projection( + fn visit_projection_elem( &mut self, place_base: &PlaceBase<'tcx>, - proj: &[PlaceElem<'tcx>], + proj_base: &[PlaceElem<'tcx>], + elem: &PlaceElem<'tcx>, context: PlaceContext, location: Location, ) { trace!( - "visit_place_projection: proj={:?} context={:?} location={:?}", - proj, + "visit_projection_elem: place_base={:?} proj_base={:?} elem={:?} \ + context={:?} location={:?}", + place_base, + proj_base, + elem, context, location, ); - self.super_projection(place_base, proj, context, location); - let (elem, proj_base) = match proj.split_last() { - Some(x) => x, - None => return, - }; + self.super_projection_elem(place_base, proj_base, elem, context, location); match elem { ProjectionElem::Deref => { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 2fa6b9d1a2936..fbcf9c8cb5eba 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1156,82 +1156,87 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { } } - fn visit_projection( + fn visit_projection_elem( &mut self, place_base: &PlaceBase<'tcx>, - proj: &[PlaceElem<'tcx>], + proj_base: &[PlaceElem<'tcx>], + elem: &PlaceElem<'tcx>, context: PlaceContext, location: Location, ) { debug!( - "visit_place_projection: proj={:?} context={:?} location={:?}", - proj, context, location, + "visit_projection_elem: place_base={:?} proj_base={:?} elem={:?} \ + context={:?} location={:?}", + place_base, + proj_base, + elem, + context, + location, ); - self.super_projection(place_base, proj, context, location); - if let [proj_base @ .., elem] = proj { - match elem { - ProjectionElem::Deref => { - if context.is_mutating_use() { - // `not_const` errors out in const contexts - self.not_const(ops::MutDeref) - } - let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty; - match self.mode { - Mode::NonConstFn => {} - _ if self.suppress_errors => {} - _ => { - if let ty::RawPtr(_) = base_ty.kind { - if !self.tcx.features().const_raw_ptr_deref { - self.record_error(ops::RawPtrDeref); - emit_feature_err( - &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref, - self.span, GateIssue::Language, - &format!( - "dereferencing raw pointers in {}s is unstable", - self.mode, - ), - ); - } + self.super_projection_elem(place_base, proj_base, elem, context, location); + + match elem { + ProjectionElem::Deref => { + if context.is_mutating_use() { + // `not_const` errors out in const contexts + self.not_const(ops::MutDeref) + } + let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty; + match self.mode { + Mode::NonConstFn => {} + _ if self.suppress_errors => {} + _ => { + if let ty::RawPtr(_) = base_ty.kind { + if !self.tcx.features().const_raw_ptr_deref { + self.record_error(ops::RawPtrDeref); + emit_feature_err( + &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref, + self.span, GateIssue::Language, + &format!( + "dereferencing raw pointers in {}s is unstable", + self.mode, + ), + ); } } } } + } - ProjectionElem::ConstantIndex {..} | - ProjectionElem::Subslice {..} | - ProjectionElem::Field(..) | - ProjectionElem::Index(_) => { - let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty; - if let Some(def) = base_ty.ty_adt_def() { - if def.is_union() { - match self.mode { - Mode::ConstFn => { - if !self.tcx.features().const_fn_union - && !self.suppress_errors - { - self.record_error(ops::UnionAccess); - emit_feature_err( - &self.tcx.sess.parse_sess, sym::const_fn_union, - self.span, GateIssue::Language, - "unions in const fn are unstable", - ); - } - }, + ProjectionElem::ConstantIndex {..} | + ProjectionElem::Subslice {..} | + ProjectionElem::Field(..) | + ProjectionElem::Index(_) => { + let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty; + if let Some(def) = base_ty.ty_adt_def() { + if def.is_union() { + match self.mode { + Mode::ConstFn => { + if !self.tcx.features().const_fn_union + && !self.suppress_errors + { + self.record_error(ops::UnionAccess); + emit_feature_err( + &self.tcx.sess.parse_sess, sym::const_fn_union, + self.span, GateIssue::Language, + "unions in const fn are unstable", + ); + } + }, - | Mode::NonConstFn - | Mode::Static - | Mode::StaticMut - | Mode::Const - => {}, - } + | Mode::NonConstFn + | Mode::Static + | Mode::StaticMut + | Mode::Const + => {}, } } } + } - ProjectionElem::Downcast(..) => { - self.not_const(ops::Downcast) - } + ProjectionElem::Downcast(..) => { + self.not_const(ops::Downcast) } } }