Skip to content

Commit

Permalink
Rollup merge of rust-lang#65056 - spastorino:place-mut-visitor-adjust…
Browse files Browse the repository at this point in the history
…s, r=oli-obk

Make visit projection iterative

r? @oli-obk

/cc @nikomatsakis
  • Loading branch information
tmandry authored Oct 3, 2019
2 parents c086b9f + b9ed642 commit a9244f7
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 87 deletions.
58 changes: 38 additions & 20 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,15 @@ macro_rules! make_mir_visitor {
self.super_projection(base, projection, context, location);
}

fn visit_projection_elem(&mut self,
base: & $($mutability)? PlaceBase<'tcx>,
proj_base: & $($mutability)? [PlaceElem<'tcx>],
elem: & $($mutability)? PlaceElem<'tcx>,
context: PlaceContext,
location: Location) {
self.super_projection_elem(base, proj_base, elem, context, location);
}

fn visit_constant(&mut self,
constant: & $($mutability)? Constant<'tcx>,
location: Location) {
Expand Down Expand Up @@ -725,27 +734,36 @@ 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);
let mut cursor = projection;
while let [proj_base @ .., elem] = cursor {
cursor = proj_base;
self.visit_projection_elem(base, cursor, elem, context, location);
}
}

match elem {
ProjectionElem::Field(_field, ty) => {
self.visit_ty(ty, TyContext::Location(location));
}
ProjectionElem::Index(local) => {
self.visit_local(
local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
ProjectionElem::Deref |
ProjectionElem::Subslice { from: _, to: _ } |
ProjectionElem::ConstantIndex { offset: _,
min_length: _,
from_end: _ } |
ProjectionElem::Downcast(_, _) => {
}
fn super_projection_elem(&mut self,
_base: & $($mutability)? PlaceBase<'tcx>,
_proj_base: & $($mutability)? [PlaceElem<'tcx>],
elem: & $($mutability)? PlaceElem<'tcx>,
_context: PlaceContext,
location: Location) {
match elem {
ProjectionElem::Field(_field, ty) => {
self.visit_ty(ty, TyContext::Location(location));
}
ProjectionElem::Index(local) => {
self.visit_local(
local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
ProjectionElem::Deref |
ProjectionElem::Subslice { from: _, to: _ } |
ProjectionElem::ConstantIndex { offset: _,
min_length: _,
from_end: _ } |
ProjectionElem::Downcast(_, _) => {
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/librustc_mir/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
121 changes: 63 additions & 58 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand Down

0 comments on commit a9244f7

Please sign in to comment.