impl<'tcx> Constant<'tcx> {
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
- match self.literal.try_to_scalar() {
+ match self.literal.const_for_ty()?.val().try_to_scalar() {
Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) {
GlobalAlloc::Static(def_id) => {
assert!(!tcx.is_thread_local_static(def_id));
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::MirSource;
use rustc_middle::mir::*;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor};
use rustc_target::abi::Size;
+use std::ops::ControlFlow;
const INDENT: &str = " ";
/// Alignment for lining up comments following MIR statements
fn alloc_ids_from_alloc(alloc: &Allocation) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
alloc.relocations().values().map(|id| *id)
}
-
fn alloc_ids_from_const(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
match val {
ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _size)) => {
}
}
}
-
struct CollectAllocIds(BTreeSet<AllocId>);
-
- impl<'tcx> Visitor<'tcx> for CollectAllocIds {
- fn visit_const(&mut self, c: ty::Const<'tcx>, _loc: Location) {
+ impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds {
+ fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val() {
self.0.extend(alloc_ids_from_const(val));
}
- }
-
- fn visit_constant(&mut self, c: &Constant<'tcx>, loc: Location) {
- match c.literal {
- ConstantKind::Ty(c) => self.visit_const(c, loc),
- ConstantKind::Val(val, _) => {
- self.0.extend(alloc_ids_from_const(val));
- }
- }
+ c.super_visit_with(self)
}
}
-
let mut visitor = CollectAllocIds(Default::default());
- visitor.visit_body(body);
-
+ body.visit_with(&mut visitor);
// `seen` contains all seen allocations, including the ones we have *not* printed yet.
// The protocol is to first `insert` into `seen`, and only if that returns `true`
// then push to `todo`.
use rustc_index::vec::IndexVec;
use rustc_middle::infer::canonical::Canonical;
use rustc_middle::middle::region;
-use rustc_middle::mir::interpret::AllocId;
use rustc_middle::mir::{
BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp, UserTypeProjection,
};
/// This is only distinguished from `Literal` so that we can register some
/// info for diagnostics.
StaticRef {
- alloc_id: AllocId,
- ty: Ty<'tcx>,
+ literal: Const<'tcx>,
def_id: DefId,
},
/// Inline assembly, i.e. `asm!()`.
}
Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
- StaticRef { .. } => {}
+ StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
for op in &**operands {
use InlineAsmOperand::*;
//! See docs in build/expr/mod.rs
use crate::build::Builder;
-use rustc_middle::mir::interpret::{ConstValue, Scalar};
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::CanonicalUserTypeAnnotation;
assert_eq!(literal.ty(), ty);
Constant { span, user_ty, literal: literal.into() }
}
- ExprKind::StaticRef { alloc_id, ty, .. } => {
- let const_val =
- ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &this.tcx));
- let literal = ConstantKind::Val(const_val, ty);
-
- Constant { span, user_ty: None, literal }
+ ExprKind::StaticRef { literal, .. } => {
+ Constant { span, user_ty: None, literal: literal.into() }
}
ExprKind::ConstBlock { value } => {
Constant { span: span, user_ty: None, literal: value.into() }
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
use rustc_middle::middle::region;
+use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp};
use rustc_middle::thir::*;
use rustc_middle::ty::adjustment::{
let kind = if self.tcx.is_thread_local_static(id) {
ExprKind::ThreadLocalRef(id)
} else {
- let alloc_id = self.tcx.create_static_alloc(id);
- ExprKind::StaticRef { alloc_id, ty, def_id: id }
+ let ptr = self.tcx.create_static_alloc(id);
+ ExprKind::StaticRef {
+ literal: ty::Const::from_scalar(
+ self.tcx,
+ Scalar::from_pointer(ptr.into(), &self.tcx),
+ ty,
+ ),
+ def_id: id,
+ }
};
ExprKind::Deref {
arg: self.thir.exprs.push(Expr { ty, temp_lifetime, span: expr.span, kind }),
StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
_2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
+ // ty::Const
+ // + ty: &&[(std::option::Option<i32>, &[&str])]
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/const_allocation.rs:8:5: 8:8
- // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
+ // + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
_1 = (*_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
_2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
+ // ty::Const
+ // + ty: &&[(std::option::Option<i32>, &[&str])]
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/const_allocation.rs:8:5: 8:8
- // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
+ // + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
_1 = (*_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
_2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
+ // ty::Const
+ // + ty: &&[(std::option::Option<i32>, &[&u8])]
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/const_allocation2.rs:5:5: 5:8
- // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
+ // + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
_1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
_2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
+ // ty::Const
+ // + ty: &&[(std::option::Option<i32>, &[&u8])]
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/const_allocation2.rs:5:5: 5:8
- // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
+ // + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
_1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
_2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
+ // ty::Const
+ // + ty: &&Packed
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/const_allocation3.rs:5:5: 5:8
// + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) }
StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
_2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
+ // ty::Const
+ // + ty: &&Packed
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/const_allocation3.rs:5:5: 5:8
// + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) }
bb0: {
_3 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
+ // ty::Const
+ // + ty: &i32
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
// + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
+ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
-+ // ty::Const
+ // ty::Const
+- // + ty: &i32
+- // + val: Value(Scalar(alloc1))
+ // + ty: &[&i32; 1]
+ // + val: Unevaluated(BAR, [], Some(promoted[0]))
// mir::Constant
bb0: {
_3 = const {alloc3: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+ // ty::Const
+ // + ty: *const i32
+ // + val: Value(Scalar(alloc3))
// mir::Constant
// + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
// + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
-+ // ty::Const
+ // ty::Const
+- // + ty: *const i32
+- // + val: Value(Scalar(alloc3))
+ // + ty: &[&i32; 1]
+ // + val: Unevaluated(FOO, [], Some(promoted[0]))
// mir::Constant
StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
_4 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
+ // ty::Const
+ // + ty: *mut u32
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19
// + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) }
StorageLive(_2); // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
StorageLive(_3); // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
_3 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
+ // ty::Const
+ // + ty: &u8
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/read_immutable_static.rs:7:13: 7:16
// + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
StorageLive(_4); // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
StorageLive(_5); // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
_5 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
+ // ty::Const
+ // + ty: &u8
+ // + val: Value(Scalar(alloc1))
// mir::Constant
// + span: $DIR/read_immutable_static.rs:7:19: 7:22
// + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }