mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Auto merge of #61151 - Centril:rollup-5rpyhfo, r=Centril
Rollup of 6 pull requests Successful merges: - #61092 (Make sanitize_place iterate instead of recurse) - #61093 (Make borrow_of_local_data iterate instead of recurse) - #61094 (Make find_local iterate instead of recurse) - #61099 (Make ignore_borrow iterate instead of recurse) - #61103 (Make find iterate instead of recurse) - #61104 (Make eval_place_to_op iterate instead of recurse) Failed merges: r? @ghost
This commit is contained in:
commit
02f5786a32
@ -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,92 +447,95 @@ 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)) =>
|
|
||||||
PlaceTy::from_ty(self.mir.local_decls[*index].ty),
|
|
||||||
Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => {
|
|
||||||
let sty = self.sanitize_type(place, sty);
|
|
||||||
let check_err =
|
|
||||||
|verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
|
|
||||||
place: &Place<'tcx>,
|
|
||||||
ty,
|
|
||||||
sty| {
|
|
||||||
if let Err(terr) = verifier.cx.eq_types(
|
|
||||||
sty,
|
|
||||||
ty,
|
|
||||||
location.to_locations(),
|
|
||||||
ConstraintCategory::Boring,
|
|
||||||
) {
|
|
||||||
span_mirbug!(
|
|
||||||
verifier,
|
|
||||||
place,
|
|
||||||
"bad promoted type ({:?}: {:?}): {:?}",
|
|
||||||
ty,
|
|
||||||
sty,
|
|
||||||
terr
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
match kind {
|
|
||||||
StaticKind::Promoted(promoted) => {
|
|
||||||
if !self.errors_reported {
|
|
||||||
let promoted_mir = &self.mir.promoted[*promoted];
|
|
||||||
self.sanitize_promoted(promoted_mir, location);
|
|
||||||
|
|
||||||
let promoted_ty = promoted_mir.return_ty();
|
place.iterate(|place_base, place_projection| {
|
||||||
check_err(self, place, promoted_ty, sty);
|
let mut place_ty = match place_base {
|
||||||
|
PlaceBase::Local(index) =>
|
||||||
|
PlaceTy::from_ty(self.mir.local_decls[*index].ty),
|
||||||
|
PlaceBase::Static(box Static { kind, ty: sty }) => {
|
||||||
|
let sty = self.sanitize_type(place, sty);
|
||||||
|
let check_err =
|
||||||
|
|verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
|
||||||
|
place: &Place<'tcx>,
|
||||||
|
ty,
|
||||||
|
sty| {
|
||||||
|
if let Err(terr) = verifier.cx.eq_types(
|
||||||
|
sty,
|
||||||
|
ty,
|
||||||
|
location.to_locations(),
|
||||||
|
ConstraintCategory::Boring,
|
||||||
|
) {
|
||||||
|
span_mirbug!(
|
||||||
|
verifier,
|
||||||
|
place,
|
||||||
|
"bad promoted type ({:?}: {:?}): {:?}",
|
||||||
|
ty,
|
||||||
|
sty,
|
||||||
|
terr
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
match kind {
|
||||||
|
StaticKind::Promoted(promoted) => {
|
||||||
|
if !self.errors_reported {
|
||||||
|
let promoted_mir = &self.mir.promoted[*promoted];
|
||||||
|
self.sanitize_promoted(promoted_mir, location);
|
||||||
|
|
||||||
|
let promoted_ty = promoted_mir.return_ty();
|
||||||
|
check_err(self, place, promoted_ty, sty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StaticKind::Static(def_id) => {
|
||||||
|
let ty = self.tcx().type_of(*def_id);
|
||||||
|
let ty = self.cx.normalize(ty, location);
|
||||||
|
|
||||||
|
check_err(self, place, ty, sty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StaticKind::Static(def_id) => {
|
PlaceTy::from_ty(sty)
|
||||||
let ty = self.tcx().type_of(*def_id);
|
}
|
||||||
let ty = self.cx.normalize(ty, location);
|
};
|
||||||
|
|
||||||
check_err(self, place, ty, sty);
|
// FIXME use place_projection.is_empty() when is available
|
||||||
}
|
if let Place::Base(_) = place {
|
||||||
|
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
||||||
|
let tcx = self.tcx();
|
||||||
|
let trait_ref = ty::TraitRef {
|
||||||
|
def_id: tcx.lang_items().copy_trait().unwrap(),
|
||||||
|
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
|
||||||
|
};
|
||||||
|
|
||||||
|
// In order to have a Copy operand, the type T of the
|
||||||
|
// value must be Copy. Note that we prove that T: Copy,
|
||||||
|
// rather than using the `is_copy_modulo_regions`
|
||||||
|
// test. This is important because
|
||||||
|
// `is_copy_modulo_regions` ignores the resulting region
|
||||||
|
// obligations and assumes they pass. This can result in
|
||||||
|
// bounds from Copy impls being unsoundly ignored (e.g.,
|
||||||
|
// #29149). Note that we decide to use Copy before knowing
|
||||||
|
// whether the bounds fully apply: in effect, the rule is
|
||||||
|
// that if a value of some type could implement Copy, then
|
||||||
|
// it must.
|
||||||
|
self.cx.prove_trait_ref(
|
||||||
|
trait_ref,
|
||||||
|
location.to_locations(),
|
||||||
|
ConstraintCategory::CopyBound,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
PlaceTy::from_ty(sty)
|
|
||||||
}
|
}
|
||||||
Place::Projection(ref proj) => {
|
|
||||||
let base_context = if context.is_mutating_use() {
|
for proj in place_projection {
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Projection)
|
if place_ty.variant_index.is_none() {
|
||||||
} else {
|
if place_ty.ty.references_error() {
|
||||||
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);
|
assert!(self.errors_reported);
|
||||||
return PlaceTy::from_ty(self.tcx().types.err);
|
return PlaceTy::from_ty(self.tcx().types.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.sanitize_projection(base_ty, &proj.elem, place, location)
|
place_ty = self.sanitize_projection(place_ty, &proj.elem, place, location)
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
|
||||||
let tcx = self.tcx();
|
|
||||||
let trait_ref = ty::TraitRef {
|
|
||||||
def_id: tcx.lang_items().copy_trait().unwrap(),
|
|
||||||
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
|
|
||||||
};
|
|
||||||
|
|
||||||
// In order to have a Copy operand, the type T of the
|
place_ty
|
||||||
// value must be Copy. Note that we prove that T: Copy,
|
})
|
||||||
// rather than using the `is_copy_modulo_regions`
|
|
||||||
// test. This is important because
|
|
||||||
// `is_copy_modulo_regions` ignores the resulting region
|
|
||||||
// obligations and assumes they pass. This can result in
|
|
||||||
// bounds from Copy impls being unsoundly ignored (e.g.,
|
|
||||||
// #29149). Note that we decide to use Copy before knowing
|
|
||||||
// whether the bounds fully apply: in effect, the rule is
|
|
||||||
// that if a value of some type could implement Copy, then
|
|
||||||
// it must.
|
|
||||||
self.cx.prove_trait_ref(
|
|
||||||
trait_ref,
|
|
||||||
location.to_locations(),
|
|
||||||
ConstraintCategory::CopyBound,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
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) {
|
||||||
|
@ -131,22 +131,20 @@ pub(super) fn is_active<'tcx>(
|
|||||||
/// Determines if a given borrow is borrowing local data
|
/// Determines if a given borrow is borrowing local data
|
||||||
/// This is called for all Yield statements on movable generators
|
/// This is called for all Yield statements on movable generators
|
||||||
pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool {
|
pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool {
|
||||||
match place {
|
place.iterate(|place_base, place_projection| {
|
||||||
Place::Base(PlaceBase::Static(..)) => false,
|
match place_base {
|
||||||
Place::Base(PlaceBase::Local(..)) => true,
|
PlaceBase::Static(..) => return false,
|
||||||
Place::Projection(box proj) => {
|
PlaceBase::Local(..) => {},
|
||||||
match proj.elem {
|
}
|
||||||
// Reborrow of already borrowed data is ignored
|
|
||||||
// Any errors will be caught on the initial borrow
|
|
||||||
ProjectionElem::Deref => false,
|
|
||||||
|
|
||||||
// For interior references and downcasts, find out if the base is local
|
for proj in place_projection {
|
||||||
ProjectionElem::Field(..)
|
// Reborrow of already borrowed data is ignored
|
||||||
| ProjectionElem::Index(..)
|
// Any errors will be caught on the initial borrow
|
||||||
| ProjectionElem::ConstantIndex { .. }
|
if proj.elem == ProjectionElem::Deref {
|
||||||
| ProjectionElem::Subslice { .. }
|
return false;
|
||||||
| ProjectionElem::Downcast(..) => borrow_of_local_data(&proj.base),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -25,40 +25,36 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
|||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
locals_state_at_exit: &LocalsStateAtExit,
|
locals_state_at_exit: &LocalsStateAtExit,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match self {
|
self.iterate(|place_base, place_projection| {
|
||||||
// If a local variable is immutable, then we only need to track borrows to guard
|
let ignore = match place_base {
|
||||||
// against two kinds of errors:
|
// If a local variable is immutable, then we only need to track borrows to guard
|
||||||
// * The variable being dropped while still borrowed (e.g., because the fn returns
|
// against two kinds of errors:
|
||||||
// a reference to a local variable)
|
// * The variable being dropped while still borrowed (e.g., because the fn returns
|
||||||
// * The variable being moved while still borrowed
|
// a reference to a local variable)
|
||||||
//
|
// * The variable being moved while still borrowed
|
||||||
// In particular, the variable cannot be mutated -- the "access checks" will fail --
|
//
|
||||||
// so we don't have to worry about mutation while borrowed.
|
// In particular, the variable cannot be mutated -- the "access checks" will fail --
|
||||||
Place::Base(PlaceBase::Local(index)) => {
|
// so we don't have to worry about mutation while borrowed.
|
||||||
match locals_state_at_exit {
|
PlaceBase::Local(index) => {
|
||||||
LocalsStateAtExit::AllAreInvalidated => false,
|
match locals_state_at_exit {
|
||||||
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
|
LocalsStateAtExit::AllAreInvalidated => false,
|
||||||
let ignore = !has_storage_dead_or_moved.contains(*index) &&
|
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
|
||||||
mir.local_decls[*index].mutability == Mutability::Not;
|
let ignore = !has_storage_dead_or_moved.contains(*index) &&
|
||||||
debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
|
mir.local_decls[*index].mutability == Mutability::Not;
|
||||||
ignore
|
debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
|
||||||
|
ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) =>
|
||||||
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
|
false,
|
||||||
false,
|
PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => {
|
||||||
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
|
tcx.is_mutable_static(*def_id)
|
||||||
tcx.is_mutable_static(*def_id)
|
}
|
||||||
}
|
};
|
||||||
Place::Projection(proj) => match proj.elem {
|
|
||||||
ProjectionElem::Field(..)
|
|
||||||
| ProjectionElem::Downcast(..)
|
|
||||||
| ProjectionElem::Subslice { .. }
|
|
||||||
| ProjectionElem::ConstantIndex { .. }
|
|
||||||
| ProjectionElem::Index(_) => proj.base.ignore_borrow(
|
|
||||||
tcx, mir, locals_state_at_exit),
|
|
||||||
|
|
||||||
ProjectionElem::Deref => {
|
for proj in place_projection {
|
||||||
|
if proj.elem == ProjectionElem::Deref {
|
||||||
let ty = proj.base.ty(mir, tcx).ty;
|
let ty = proj.base.ty(mir, tcx).ty;
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
// For both derefs of raw pointers and `&T`
|
// For both derefs of raw pointers and `&T`
|
||||||
@ -71,11 +67,13 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
|||||||
// original path into a new variable and
|
// original path into a new variable and
|
||||||
// borrowed *that* one, leaving the original
|
// borrowed *that* one, leaving the original
|
||||||
// path unborrowed.
|
// path unborrowed.
|
||||||
ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => true,
|
ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
|
||||||
_ => proj.base.ignore_borrow(tcx, mir, locals_state_at_exit),
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
|
||||||
|
ignore
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,16 +91,19 @@ struct BorrowedLocalsVisitor<'b, 'c: 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
|
fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
|
||||||
match *place {
|
place.iterate(|place_base, place_projection| {
|
||||||
Place::Base(PlaceBase::Local(l)) => Some(l),
|
for proj in place_projection {
|
||||||
Place::Base(PlaceBase::Static(..)) => None,
|
if proj.elem == ProjectionElem::Deref {
|
||||||
Place::Projection(ref proj) => {
|
return None;
|
||||||
match proj.elem {
|
|
||||||
ProjectionElem::Deref => None,
|
|
||||||
_ => find_local(&proj.base)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if let PlaceBase::Local(local) = place_base {
|
||||||
|
Some(*local)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, 'b, 'c> Visitor<'tcx> for BorrowedLocalsVisitor<'b, 'c> {
|
impl<'tcx, 'b, 'c> Visitor<'tcx> for BorrowedLocalsVisitor<'b, 'c> {
|
||||||
|
@ -241,21 +241,22 @@ impl MovePathLookup {
|
|||||||
// unknown place, but will rather return the nearest available
|
// unknown place, but will rather return the nearest available
|
||||||
// parent.
|
// parent.
|
||||||
pub fn find(&self, place: &Place<'tcx>) -> LookupResult {
|
pub fn find(&self, place: &Place<'tcx>) -> LookupResult {
|
||||||
match *place {
|
place.iterate(|place_base, place_projection| {
|
||||||
Place::Base(PlaceBase::Local(local)) => LookupResult::Exact(self.locals[local]),
|
let mut result = match place_base {
|
||||||
Place::Base(PlaceBase::Static(..)) => LookupResult::Parent(None),
|
PlaceBase::Local(local) => self.locals[*local],
|
||||||
Place::Projection(ref proj) => {
|
PlaceBase::Static(..) => return LookupResult::Parent(None),
|
||||||
match self.find(&proj.base) {
|
};
|
||||||
LookupResult::Exact(base_path) => {
|
|
||||||
match self.projections.get(&(base_path, proj.elem.lift())) {
|
for proj in place_projection {
|
||||||
Some(&subpath) => LookupResult::Exact(subpath),
|
if let Some(&subpath) = self.projections.get(&(result, proj.elem.lift())) {
|
||||||
None => LookupResult::Parent(Some(base_path))
|
result = subpath;
|
||||||
}
|
} else {
|
||||||
}
|
return LookupResult::Parent(Some(result));
|
||||||
inexact => inexact
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
LookupResult::Exact(result)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_local(&self, local: Local) -> MovePathIndex {
|
pub fn find_local(&self, local: Local) -> MovePathIndex {
|
||||||
|
@ -467,22 +467,34 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
|
|||||||
mir_place: &mir::Place<'tcx>,
|
mir_place: &mir::Place<'tcx>,
|
||||||
layout: Option<TyLayout<'tcx>>,
|
layout: Option<TyLayout<'tcx>>,
|
||||||
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||||
use rustc::mir::Place::*;
|
use rustc::mir::Place;
|
||||||
use rustc::mir::PlaceBase;
|
use rustc::mir::PlaceBase;
|
||||||
let op = match *mir_place {
|
|
||||||
Base(PlaceBase::Local(mir::RETURN_PLACE)) => return err!(ReadFromReturnPointer),
|
|
||||||
Base(PlaceBase::Local(local)) => self.access_local(self.frame(), local, layout)?,
|
|
||||||
|
|
||||||
Projection(ref proj) => {
|
mir_place.iterate(|place_base, place_projection| {
|
||||||
let op = self.eval_place_to_op(&proj.base, None)?;
|
let mut op = match place_base {
|
||||||
self.operand_projection(op, &proj.elem)?
|
PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
|
||||||
|
PlaceBase::Local(local) => {
|
||||||
|
// FIXME use place_projection.is_empty() when is available
|
||||||
|
let layout = if let Place::Base(_) = mir_place {
|
||||||
|
layout
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
self.access_local(self.frame(), *local, layout)?
|
||||||
|
}
|
||||||
|
PlaceBase::Static(place_static) => {
|
||||||
|
self.eval_static_to_mplace(place_static)?.into()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for proj in place_projection {
|
||||||
|
op = self.operand_projection(op, &proj.elem)?
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => self.eval_place_to_mplace(mir_place)?.into(),
|
trace!("eval_place_to_op: got {:?}", *op);
|
||||||
};
|
Ok(op)
|
||||||
|
})
|
||||||
trace!("eval_place_to_op: got {:?}", *op);
|
|
||||||
Ok(op)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate the operand, returning a place where you can then find the data.
|
/// Evaluate the operand, returning a place where you can then find the data.
|
||||||
|
@ -562,15 +562,14 @@ where
|
|||||||
|
|
||||||
/// Evaluate statics and promoteds to an `MPlace`. Used to share some code between
|
/// Evaluate statics and promoteds to an `MPlace`. Used to share some code between
|
||||||
/// `eval_place` and `eval_place_to_op`.
|
/// `eval_place` and `eval_place_to_op`.
|
||||||
pub(super) fn eval_place_to_mplace(
|
pub(super) fn eval_static_to_mplace(
|
||||||
&self,
|
&self,
|
||||||
mir_place: &mir::Place<'tcx>
|
place_static: &mir::Static<'tcx>
|
||||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||||
use rustc::mir::Place::*;
|
use rustc::mir::StaticKind;
|
||||||
use rustc::mir::PlaceBase;
|
|
||||||
use rustc::mir::{Static, StaticKind};
|
Ok(match place_static.kind {
|
||||||
Ok(match *mir_place {
|
StaticKind::Promoted(promoted) => {
|
||||||
Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })) => {
|
|
||||||
let instance = self.frame().instance;
|
let instance = self.frame().instance;
|
||||||
self.const_eval_raw(GlobalId {
|
self.const_eval_raw(GlobalId {
|
||||||
instance,
|
instance,
|
||||||
@ -578,7 +577,8 @@ where
|
|||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
|
|
||||||
Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty })) => {
|
StaticKind::Static(def_id) => {
|
||||||
|
let ty = place_static.ty;
|
||||||
assert!(!ty.needs_subst());
|
assert!(!ty.needs_subst());
|
||||||
let layout = self.layout_of(ty)?;
|
let layout = self.layout_of(ty)?;
|
||||||
let instance = ty::Instance::mono(*self.tcx, def_id);
|
let instance = ty::Instance::mono(*self.tcx, def_id);
|
||||||
@ -600,8 +600,6 @@ where
|
|||||||
let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id());
|
let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id());
|
||||||
MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout)
|
MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => bug!("eval_place_to_mplace called on {:?}", mir_place),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +611,7 @@ where
|
|||||||
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||||
use rustc::mir::Place::*;
|
use rustc::mir::Place::*;
|
||||||
use rustc::mir::PlaceBase;
|
use rustc::mir::PlaceBase;
|
||||||
let place = match *mir_place {
|
let place = match mir_place {
|
||||||
Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place {
|
Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place {
|
||||||
Some(return_place) =>
|
Some(return_place) =>
|
||||||
// We use our layout to verify our assumption; caller will validate
|
// We use our layout to verify our assumption; caller will validate
|
||||||
@ -628,17 +626,19 @@ where
|
|||||||
// This works even for dead/uninitialized locals; we check further when writing
|
// This works even for dead/uninitialized locals; we check further when writing
|
||||||
place: Place::Local {
|
place: Place::Local {
|
||||||
frame: self.cur_frame(),
|
frame: self.cur_frame(),
|
||||||
local,
|
local: *local,
|
||||||
},
|
},
|
||||||
layout: self.layout_of_local(self.frame(), local, None)?,
|
layout: self.layout_of_local(self.frame(), *local, None)?,
|
||||||
},
|
},
|
||||||
|
|
||||||
Projection(ref proj) => {
|
Projection(proj) => {
|
||||||
let place = self.eval_place(&proj.base)?;
|
let place = self.eval_place(&proj.base)?;
|
||||||
self.place_projection(place, &proj.elem)?
|
self.place_projection(place, &proj.elem)?
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => self.eval_place_to_mplace(mir_place)?.into(),
|
Base(PlaceBase::Static(place_static)) => {
|
||||||
|
self.eval_static_to_mplace(place_static)?.into()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.dump_place(place.place);
|
self.dump_place(place.place);
|
||||||
|
Loading…
Reference in New Issue
Block a user