Auto merge of #98588 - b-naber:valtrees-cleanup, r=lcnr
Use only ty::Unevaluated<'tcx, ()> in type system r? `@lcnr`
This commit is contained in:
commit
c524c7dd25
59 changed files with 383 additions and 323 deletions
|
@ -2,6 +2,7 @@ use rustc_index::vec::IndexVec;
|
||||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
||||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||||
use rustc_middle::mir::{Body, Location, Promoted};
|
use rustc_middle::mir::{Body, Location, Promoted};
|
||||||
|
use rustc_middle::mir::{Constant, ConstantKind};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
|
|
||||||
|
@ -37,6 +38,21 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(valtrees): This function is necessary because `fold_regions`
|
||||||
|
// panics for mir constants in the visitor.
|
||||||
|
//
|
||||||
|
// Once `visit_mir_constant` is removed we can also remove this function
|
||||||
|
// and just use `renumber_regions`.
|
||||||
|
fn renumber_regions_in_mir_constant<'tcx>(
|
||||||
|
infcx: &InferCtxt<'_, 'tcx>,
|
||||||
|
value: ConstantKind<'tcx>,
|
||||||
|
) -> ConstantKind<'tcx> {
|
||||||
|
infcx.tcx.super_fold_regions(value, |_region, _depth| {
|
||||||
|
let origin = NllRegionVariableOrigin::Existential { from_forall: false };
|
||||||
|
infcx.next_nll_region_var(origin)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
struct NllVisitor<'a, 'tcx> {
|
struct NllVisitor<'a, 'tcx> {
|
||||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
|
@ -48,6 +64,13 @@ impl<'a, 'tcx> NllVisitor<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
renumber_regions(self.infcx, value)
|
renumber_regions(self.infcx, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn renumber_regions_in_mir_constant(
|
||||||
|
&mut self,
|
||||||
|
value: ConstantKind<'tcx>,
|
||||||
|
) -> ConstantKind<'tcx> {
|
||||||
|
renumber_regions_in_mir_constant(self.infcx, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
|
||||||
|
@ -77,7 +100,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
|
||||||
debug!(?region);
|
debug!(?region);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, constant: &mut ty::Const<'tcx>, _location: Location) {
|
#[instrument(skip(self), level = "debug")]
|
||||||
*constant = self.renumber_regions(*constant);
|
fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) {
|
||||||
|
let literal = constant.literal;
|
||||||
|
constant.literal = self.renumber_regions_in_mir_constant(literal);
|
||||||
|
debug!("constant: {:#?}", constant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,11 +355,15 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let maybe_uneval = match constant.literal {
|
let maybe_uneval = match constant.literal {
|
||||||
ConstantKind::Ty(ct) => match ct.kind() {
|
ConstantKind::Ty(ct) => match ct.kind() {
|
||||||
ty::ConstKind::Unevaluated(uv) => Some(uv),
|
ty::ConstKind::Unevaluated(_) => {
|
||||||
|
bug!("should not encounter unevaluated ConstantKind::Ty here, got {:?}", ct)
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
|
ConstantKind::Unevaluated(uv, _) => Some(uv),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(uv) = maybe_uneval {
|
if let Some(uv) = maybe_uneval {
|
||||||
if let Some(promoted) = uv.promoted {
|
if let Some(promoted) = uv.promoted {
|
||||||
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
|
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
|
||||||
|
@ -1813,12 +1817,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
|
fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
|
||||||
if let Operand::Constant(constant) = op {
|
if let Operand::Constant(constant) = op {
|
||||||
let maybe_uneval = match constant.literal {
|
let maybe_uneval = match constant.literal {
|
||||||
ConstantKind::Ty(ct) => match ct.kind() {
|
ConstantKind::Val(..) | ConstantKind::Ty(_) => None,
|
||||||
ty::ConstKind::Unevaluated(uv) => Some(uv),
|
ConstantKind::Unevaluated(uv, _) => Some(uv),
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(uv) = maybe_uneval {
|
if let Some(uv) = maybe_uneval {
|
||||||
if uv.promoted.is_none() {
|
if uv.promoted.is_none() {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
|
@ -41,36 +41,30 @@ impl ConstantCx {
|
||||||
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
|
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
|
||||||
let mut all_constants_ok = true;
|
let mut all_constants_ok = true;
|
||||||
for constant in &fx.mir.required_consts {
|
for constant in &fx.mir.required_consts {
|
||||||
let const_ = match fx.monomorphize(constant.literal) {
|
let unevaluated = match fx.monomorphize(constant.literal) {
|
||||||
ConstantKind::Ty(ct) => ct,
|
ConstantKind::Ty(ct) => match ct.kind() {
|
||||||
|
ConstKind::Unevaluated(uv) => uv.expand(),
|
||||||
|
ConstKind::Value(_) => continue,
|
||||||
|
ConstKind::Param(_)
|
||||||
|
| ConstKind::Infer(_)
|
||||||
|
| ConstKind::Bound(_, _)
|
||||||
|
| ConstKind::Placeholder(_)
|
||||||
|
| ConstKind::Error(_) => unreachable!("{:?}", ct),
|
||||||
|
},
|
||||||
|
ConstantKind::Unevaluated(uv, _) => uv,
|
||||||
ConstantKind::Val(..) => continue,
|
ConstantKind::Val(..) => continue,
|
||||||
};
|
};
|
||||||
match const_.kind() {
|
|
||||||
ConstKind::Value(_) => {}
|
if let Err(err) = fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
|
||||||
ConstKind::Unevaluated(unevaluated) => {
|
all_constants_ok = false;
|
||||||
if let Err(err) =
|
match err {
|
||||||
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None)
|
ErrorHandled::Reported(_) | ErrorHandled::Linted => {
|
||||||
{
|
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
|
||||||
all_constants_ok = false;
|
}
|
||||||
match err {
|
ErrorHandled::TooGeneric => {
|
||||||
ErrorHandled::Reported(_) | ErrorHandled::Linted => {
|
span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
|
||||||
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
|
|
||||||
}
|
|
||||||
ErrorHandled::TooGeneric => {
|
|
||||||
span_bug!(
|
|
||||||
constant.span,
|
|
||||||
"codegen encountered polymorphic constant: {:?}",
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstKind::Param(_)
|
|
||||||
| ConstKind::Infer(_)
|
|
||||||
| ConstKind::Bound(_, _)
|
|
||||||
| ConstKind::Placeholder(_)
|
|
||||||
| ConstKind::Error(_) => unreachable!("{:?}", const_),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
all_constants_ok
|
all_constants_ok
|
||||||
|
@ -122,36 +116,28 @@ pub(crate) fn codegen_constant<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
constant: &Constant<'tcx>,
|
constant: &Constant<'tcx>,
|
||||||
) -> CValue<'tcx> {
|
) -> CValue<'tcx> {
|
||||||
let const_ = match fx.monomorphize(constant.literal) {
|
let (const_val, ty) = match fx.monomorphize(constant.literal) {
|
||||||
ConstantKind::Ty(ct) => ct,
|
ConstantKind::Ty(const_) => unreachable!("{:?}", const_),
|
||||||
ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty),
|
ConstantKind::Unevaluated(ty::Unevaluated { def, substs, promoted }, ty)
|
||||||
};
|
|
||||||
let const_val = match const_.kind() {
|
|
||||||
ConstKind::Value(valtree) => fx.tcx.valtree_to_const_val((const_.ty(), valtree)),
|
|
||||||
ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
|
|
||||||
if fx.tcx.is_static(def.did) =>
|
if fx.tcx.is_static(def.did) =>
|
||||||
{
|
{
|
||||||
assert!(substs.is_empty());
|
assert!(substs.is_empty());
|
||||||
assert!(promoted.is_none());
|
assert!(promoted.is_none());
|
||||||
|
|
||||||
return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty())).to_cvalue(fx);
|
return codegen_static_ref(fx, def.did, fx.layout_of(ty)).to_cvalue(fx);
|
||||||
}
|
}
|
||||||
ConstKind::Unevaluated(unevaluated) => {
|
ConstantKind::Unevaluated(unevaluated, ty) => {
|
||||||
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
|
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
|
||||||
Ok(const_val) => const_val,
|
Ok(const_val) => (const_val, ty),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
span_bug!(constant.span, "erroneous constant not captured by required_consts");
|
span_bug!(constant.span, "erroneous constant not captured by required_consts");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstKind::Param(_)
|
ConstantKind::Val(val, ty) => (val, ty),
|
||||||
| ConstKind::Infer(_)
|
|
||||||
| ConstKind::Bound(_, _)
|
|
||||||
| ConstKind::Placeholder(_)
|
|
||||||
| ConstKind::Error(_) => unreachable!("{:?}", const_),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
codegen_const_value(fx, const_val, const_.ty())
|
codegen_const_value(fx, const_val, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn codegen_const_value<'tcx>(
|
pub(crate) fn codegen_const_value<'tcx>(
|
||||||
|
@ -496,6 +482,9 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
|
||||||
.eval_for_mir(fx.tcx, ParamEnv::reveal_all())
|
.eval_for_mir(fx.tcx, ParamEnv::reveal_all())
|
||||||
.try_to_value(fx.tcx),
|
.try_to_value(fx.tcx),
|
||||||
ConstantKind::Val(val, _) => Some(val),
|
ConstantKind::Val(val, _) => Some(val),
|
||||||
|
ConstantKind::Unevaluated(uv, _) => {
|
||||||
|
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), uv, None).ok()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
|
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
|
||||||
// inside a temporary before being passed to the intrinsic requiring the const argument.
|
// inside a temporary before being passed to the intrinsic requiring the const argument.
|
||||||
|
|
|
@ -25,26 +25,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
constant: &mir::Constant<'tcx>,
|
constant: &mir::Constant<'tcx>,
|
||||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||||
let ct = self.monomorphize(constant.literal);
|
let ct = self.monomorphize(constant.literal);
|
||||||
let ct = match ct {
|
let uv = match ct {
|
||||||
mir::ConstantKind::Ty(ct) => ct,
|
mir::ConstantKind::Ty(ct) => match ct.kind() {
|
||||||
|
ty::ConstKind::Unevaluated(uv) => uv.expand(),
|
||||||
|
ty::ConstKind::Value(val) => {
|
||||||
|
return Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val)));
|
||||||
|
}
|
||||||
|
err => span_bug!(
|
||||||
|
constant.span,
|
||||||
|
"encountered bad ConstKind after monomorphizing: {:?}",
|
||||||
|
err
|
||||||
|
),
|
||||||
|
},
|
||||||
|
mir::ConstantKind::Unevaluated(uv, _) => uv,
|
||||||
mir::ConstantKind::Val(val, _) => return Ok(val),
|
mir::ConstantKind::Val(val, _) => return Ok(val),
|
||||||
};
|
};
|
||||||
match ct.kind() {
|
|
||||||
ty::ConstKind::Unevaluated(ct) => self
|
self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| {
|
||||||
.cx
|
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
|
||||||
.tcx()
|
err
|
||||||
.const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None)
|
})
|
||||||
.map_err(|err| {
|
|
||||||
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
|
|
||||||
err
|
|
||||||
}),
|
|
||||||
ty::ConstKind::Value(val) => Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val))),
|
|
||||||
err => span_bug!(
|
|
||||||
constant.span,
|
|
||||||
"encountered bad ConstKind after monomorphizing: {:?}",
|
|
||||||
err
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// process constant containing SIMD shuffle indices
|
/// process constant containing SIMD shuffle indices
|
||||||
|
|
|
@ -564,8 +564,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
throw_inval!(AlreadyReported(reported))
|
throw_inval!(AlreadyReported(reported))
|
||||||
}
|
}
|
||||||
ty::ConstKind::Unevaluated(uv) => {
|
ty::ConstKind::Unevaluated(uv) => {
|
||||||
|
// NOTE: We evaluate to a `ValTree` here as a check to ensure
|
||||||
|
// we're working with valid constants, even though we never need it.
|
||||||
let instance = self.resolve(uv.def, uv.substs)?;
|
let instance = self.resolve(uv.def, uv.substs)?;
|
||||||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
|
let cid = GlobalId { instance, promoted: None };
|
||||||
|
let _valtree = self
|
||||||
|
.tcx
|
||||||
|
.eval_to_valtree(self.param_env.and(cid))?
|
||||||
|
.unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv));
|
||||||
|
|
||||||
|
Ok(self.eval_to_allocation(cid)?.into())
|
||||||
}
|
}
|
||||||
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
|
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
|
||||||
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c)
|
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c)
|
||||||
|
@ -586,6 +594,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
match val {
|
match val {
|
||||||
mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
|
mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
|
||||||
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
|
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
|
||||||
|
mir::ConstantKind::Unevaluated(uv, _) => {
|
||||||
|
let instance = self.resolve(uv.def, uv.substs)?;
|
||||||
|
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -346,31 +346,43 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check the qualifs of the value of `const` items.
|
// Check the qualifs of the value of `const` items.
|
||||||
if let Some(ct) = constant.literal.const_for_ty() {
|
// FIXME(valtrees): check whether const qualifs should behave the same
|
||||||
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.kind()
|
// way for type and mir constants.
|
||||||
{
|
let uneval = match constant.literal {
|
||||||
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
|
ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Unevaluated(_)) => {
|
||||||
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
|
let ty::ConstKind::Unevaluated(uv) = ct.kind() else { unreachable!() };
|
||||||
// check performed after the promotion. Verify that with an assertion.
|
|
||||||
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
|
|
||||||
// Don't peek inside trait associated constants.
|
|
||||||
if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
|
|
||||||
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
|
|
||||||
cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
|
|
||||||
} else {
|
|
||||||
cx.tcx.at(constant.span).mir_const_qualif(def.did)
|
|
||||||
};
|
|
||||||
|
|
||||||
if !Q::in_qualifs(&qualifs) {
|
Some(uv.expand())
|
||||||
return false;
|
}
|
||||||
}
|
ConstantKind::Ty(_) => None,
|
||||||
|
ConstantKind::Unevaluated(uv, _) => Some(uv),
|
||||||
|
ConstantKind::Val(..) => None,
|
||||||
|
};
|
||||||
|
|
||||||
// Just in case the type is more specific than
|
if let Some(ty::Unevaluated { def, substs: _, promoted }) = uneval {
|
||||||
// the definition, e.g., impl associated const
|
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
|
||||||
// with type parameters, take it into account.
|
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
|
||||||
|
// check performed after the promotion. Verify that with an assertion.
|
||||||
|
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
|
||||||
|
|
||||||
|
// Don't peek inside trait associated constants.
|
||||||
|
if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
|
||||||
|
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
|
||||||
|
cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
|
||||||
|
} else {
|
||||||
|
cx.tcx.at(constant.span).mir_const_qualif(def.did)
|
||||||
|
};
|
||||||
|
|
||||||
|
if !Q::in_qualifs(&qualifs) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Just in case the type is more specific than
|
||||||
|
// the definition, e.g., impl associated const
|
||||||
|
// with type parameters, take it into account.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise use the qualifs of the type.
|
// Otherwise use the qualifs of the type.
|
||||||
Q::in_any_value_of_ty(cx, constant.literal.ty())
|
Q::in_any_value_of_ty(cx, constant.literal.ty())
|
||||||
}
|
}
|
||||||
|
|
|
@ -840,21 +840,15 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||||
promoted.span = span;
|
promoted.span = span;
|
||||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
||||||
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
|
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
|
||||||
let _const = tcx.mk_const(ty::ConstS {
|
let uneval = ty::Unevaluated { def, substs, promoted: Some(promoted_id) };
|
||||||
ty,
|
|
||||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
|
||||||
def,
|
|
||||||
substs,
|
|
||||||
promoted: Some(promoted_id),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
Operand::Constant(Box::new(Constant {
|
Operand::Constant(Box::new(Constant {
|
||||||
span,
|
span,
|
||||||
user_ty: None,
|
user_ty: None,
|
||||||
literal: ConstantKind::from_const(_const, tcx),
|
literal: ConstantKind::Unevaluated(uneval, ty),
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
|
||||||
let blocks = self.source.basic_blocks.as_mut();
|
let blocks = self.source.basic_blocks.as_mut();
|
||||||
let local_decls = &mut self.source.local_decls;
|
let local_decls = &mut self.source.local_decls;
|
||||||
let loc = candidate.location;
|
let loc = candidate.location;
|
||||||
|
|
|
@ -743,7 +743,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
|
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
|
||||||
assert_eq!(promoted, None);
|
assert_eq!(promoted, ());
|
||||||
|
|
||||||
let substs = self.relate_with_variance(
|
let substs = self.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Variance::Invariant,
|
||||||
ty::VarianceDiagInfo::default(),
|
ty::VarianceDiagInfo::default(),
|
||||||
|
@ -964,13 +965,15 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
|
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
|
||||||
assert_eq!(promoted, None);
|
assert_eq!(promoted, ());
|
||||||
|
|
||||||
let substs = self.relate_with_variance(
|
let substs = self.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Variance::Invariant,
|
||||||
ty::VarianceDiagInfo::default(),
|
ty::VarianceDiagInfo::default(),
|
||||||
substs,
|
substs,
|
||||||
substs,
|
substs,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(self.tcx().mk_const(ty::ConstS {
|
Ok(self.tcx().mk_const(ty::ConstS {
|
||||||
ty: c.ty(),
|
ty: c.ty(),
|
||||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
|
kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
|
||||||
|
|
|
@ -1673,7 +1673,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
pub fn try_const_eval_resolve(
|
pub fn try_const_eval_resolve(
|
||||||
&self,
|
&self,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
unevaluated: ty::Unevaluated<'tcx>,
|
unevaluated: ty::Unevaluated<'tcx, ()>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> Result<ty::Const<'tcx>, ErrorHandled> {
|
) -> Result<ty::Const<'tcx>, ErrorHandled> {
|
||||||
|
@ -1708,7 +1708,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
pub fn const_eval_resolve(
|
pub fn const_eval_resolve(
|
||||||
&self,
|
&self,
|
||||||
mut param_env: ty::ParamEnv<'tcx>,
|
mut param_env: ty::ParamEnv<'tcx>,
|
||||||
unevaluated: ty::Unevaluated<'tcx>,
|
unevaluated: ty::Unevaluated<'tcx, ()>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> EvalToValTreeResult<'tcx> {
|
) -> EvalToValTreeResult<'tcx> {
|
||||||
let mut substs = self.resolve_vars_if_possible(unevaluated.substs);
|
let mut substs = self.resolve_vars_if_possible(unevaluated.substs);
|
||||||
|
@ -1717,7 +1717,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
// Postpone the evaluation of constants whose substs depend on inference
|
// Postpone the evaluation of constants whose substs depend on inference
|
||||||
// variables
|
// variables
|
||||||
if substs.has_infer_types_or_consts() {
|
if substs.has_infer_types_or_consts() {
|
||||||
let ac = AbstractConst::new(self.tcx, unevaluated.shrink());
|
let ac = AbstractConst::new(self.tcx, unevaluated);
|
||||||
match ac {
|
match ac {
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
|
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
|
||||||
|
@ -1739,11 +1739,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
debug!(?param_env_erased);
|
debug!(?param_env_erased);
|
||||||
debug!(?substs_erased);
|
debug!(?substs_erased);
|
||||||
|
|
||||||
let unevaluated = ty::Unevaluated {
|
let unevaluated =
|
||||||
def: unevaluated.def,
|
ty::Unevaluated { def: unevaluated.def, substs: substs_erased, promoted: () };
|
||||||
substs: substs_erased,
|
|
||||||
promoted: unevaluated.promoted,
|
|
||||||
};
|
|
||||||
|
|
||||||
// The return value is the evaluated value which doesn't contain any reference to inference
|
// The return value is the evaluated value which doesn't contain any reference to inference
|
||||||
// variables, thus we don't need to substitute back the original values.
|
// variables, thus we don't need to substitute back the original values.
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn const_eval_resolve_for_typeck(
|
pub fn const_eval_resolve_for_typeck(
|
||||||
self,
|
self,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
ct: ty::Unevaluated<'tcx>,
|
ct: ty::Unevaluated<'tcx, ()>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> EvalToValTreeResult<'tcx> {
|
) -> EvalToValTreeResult<'tcx> {
|
||||||
// Cannot resolve `Unevaluated` constants that contain inference
|
// Cannot resolve `Unevaluated` constants that contain inference
|
||||||
|
@ -78,7 +78,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
|
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
|
||||||
Ok(Some(instance)) => {
|
Ok(Some(instance)) => {
|
||||||
let cid = GlobalId { instance, promoted: ct.promoted };
|
let cid = GlobalId { instance, promoted: None };
|
||||||
self.const_eval_global_id_for_typeck(param_env, cid, span)
|
self.const_eval_global_id_for_typeck(param_env, cid, span)
|
||||||
}
|
}
|
||||||
Ok(None) => Err(ErrorHandled::TooGeneric),
|
Ok(None) => Err(ErrorHandled::TooGeneric),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
|
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
|
||||||
|
|
||||||
use crate::mir::interpret::{
|
use crate::mir::interpret::{
|
||||||
AllocRange, ConstAllocation, ConstValue, GlobalAlloc, LitToConstInput, Scalar,
|
AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, LitToConstInput, Scalar,
|
||||||
};
|
};
|
||||||
use crate::mir::visit::MirVisitable;
|
use crate::mir::visit::MirVisitable;
|
||||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||||
|
@ -2047,6 +2047,10 @@ pub struct Constant<'tcx> {
|
||||||
pub enum ConstantKind<'tcx> {
|
pub enum ConstantKind<'tcx> {
|
||||||
/// This constant came from the type system
|
/// This constant came from the type system
|
||||||
Ty(ty::Const<'tcx>),
|
Ty(ty::Const<'tcx>),
|
||||||
|
|
||||||
|
/// An unevaluated mir constant which is not part of the type system.
|
||||||
|
Unevaluated(ty::Unevaluated<'tcx, Option<Promoted>>, Ty<'tcx>),
|
||||||
|
|
||||||
/// This constant cannot go back into the type system, as it represents
|
/// This constant cannot go back into the type system, as it represents
|
||||||
/// something the type system cannot handle (e.g. pointers).
|
/// something the type system cannot handle (e.g. pointers).
|
||||||
Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
|
Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
|
||||||
|
@ -2072,20 +2076,11 @@ impl<'tcx> Constant<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ConstantKind<'tcx> {
|
impl<'tcx> ConstantKind<'tcx> {
|
||||||
/// Returns `None` if the constant is not trivially safe for use in the type system.
|
|
||||||
#[inline]
|
|
||||||
pub fn const_for_ty(&self) -> Option<ty::Const<'tcx>> {
|
|
||||||
match self {
|
|
||||||
ConstantKind::Ty(c) => Some(*c),
|
|
||||||
ConstantKind::Val(..) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn ty(&self) -> Ty<'tcx> {
|
pub fn ty(&self) -> Ty<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
ConstantKind::Ty(c) => c.ty(),
|
ConstantKind::Ty(c) => c.ty(),
|
||||||
ConstantKind::Val(_, ty) => *ty,
|
ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => *ty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2097,6 +2092,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
ConstantKind::Val(val, _) => Some(val),
|
ConstantKind::Val(val, _) => Some(val),
|
||||||
|
ConstantKind::Unevaluated(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2111,6 +2107,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
ConstantKind::Val(val, _) => val.try_to_scalar(),
|
ConstantKind::Val(val, _) => val.try_to_scalar(),
|
||||||
|
ConstantKind::Unevaluated(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2143,6 +2140,14 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Val(_, _) => self,
|
Self::Val(_, _) => self,
|
||||||
|
Self::Unevaluated(uneval, ty) => {
|
||||||
|
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
|
||||||
|
match tcx.const_eval_resolve(param_env, uneval, None) {
|
||||||
|
Ok(val) => Self::Val(val, ty),
|
||||||
|
Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self,
|
||||||
|
Err(_) => Self::Ty(tcx.const_error(ty)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2168,6 +2173,18 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||||
val.try_to_bits(size)
|
val.try_to_bits(size)
|
||||||
}
|
}
|
||||||
|
Self::Unevaluated(uneval, ty) => {
|
||||||
|
match tcx.const_eval_resolve(param_env, *uneval, None) {
|
||||||
|
Ok(val) => {
|
||||||
|
let size = tcx
|
||||||
|
.layout_of(param_env.with_reveal_all_normalized(tcx).and(*ty))
|
||||||
|
.ok()?
|
||||||
|
.size;
|
||||||
|
val.try_to_bits(size)
|
||||||
|
}
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2176,6 +2193,12 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
Self::Ty(ct) => ct.try_eval_bool(tcx, param_env),
|
Self::Ty(ct) => ct.try_eval_bool(tcx, param_env),
|
||||||
Self::Val(val, _) => val.try_to_bool(),
|
Self::Val(val, _) => val.try_to_bool(),
|
||||||
|
Self::Unevaluated(uneval, _) => {
|
||||||
|
match tcx.const_eval_resolve(param_env, *uneval, None) {
|
||||||
|
Ok(val) => val.try_to_bool(),
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2184,6 +2207,12 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
Self::Ty(ct) => ct.try_eval_usize(tcx, param_env),
|
Self::Ty(ct) => ct.try_eval_usize(tcx, param_env),
|
||||||
Self::Val(val, _) => val.try_to_machine_usize(tcx),
|
Self::Val(val, _) => val.try_to_machine_usize(tcx),
|
||||||
|
Self::Unevaluated(uneval, _) => {
|
||||||
|
match tcx.const_eval_resolve(param_env, *uneval, None) {
|
||||||
|
Ok(val) => val.try_to_machine_usize(tcx),
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2279,15 +2308,16 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
let substs =
|
let substs =
|
||||||
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
|
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
|
||||||
.substs;
|
.substs;
|
||||||
debug_assert!(!substs.has_free_regions());
|
|
||||||
Self::Ty(tcx.mk_const(ty::ConstS {
|
let uneval = ty::Unevaluated {
|
||||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
def: ty::WithOptConstParam::unknown(def_id).to_global(),
|
||||||
def: ty::WithOptConstParam::unknown(def_id).to_global(),
|
substs,
|
||||||
substs,
|
promoted: None,
|
||||||
promoted: None,
|
};
|
||||||
}),
|
|
||||||
ty,
|
debug_assert!(!uneval.has_free_regions());
|
||||||
}))
|
|
||||||
|
Self::Unevaluated(uneval, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(tcx), level = "debug", ret)]
|
#[instrument(skip(tcx), level = "debug", ret)]
|
||||||
|
@ -2380,14 +2410,14 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
debug!("error encountered during evaluation");
|
debug!("error encountered during evaluation");
|
||||||
// Error was handled in `const_eval_resolve`. Here we just create a
|
// Error was handled in `const_eval_resolve`. Here we just create a
|
||||||
// new unevaluated const and error hard later in codegen
|
// new unevaluated const and error hard later in codegen
|
||||||
Self::Ty(tcx.mk_const(ty::ConstS {
|
Self::Unevaluated(
|
||||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
ty::Unevaluated {
|
||||||
def: def.to_global(),
|
def: def.to_global(),
|
||||||
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||||
promoted: None,
|
promoted: None,
|
||||||
}),
|
},
|
||||||
ty,
|
ty,
|
||||||
}))
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2398,6 +2428,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
let const_val = tcx.valtree_to_const_val((c.ty(), valtree));
|
let const_val = tcx.valtree_to_const_val((c.ty(), valtree));
|
||||||
Self::Val(const_val, c.ty())
|
Self::Val(const_val, c.ty())
|
||||||
}
|
}
|
||||||
|
ty::ConstKind::Unevaluated(uv) => Self::Unevaluated(uv.expand(), c.ty()),
|
||||||
_ => Self::Ty(c),
|
_ => Self::Ty(c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2596,6 +2627,11 @@ impl<'tcx> Display for ConstantKind<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
ConstantKind::Ty(c) => pretty_print_const(c, fmt, true),
|
ConstantKind::Ty(c) => pretty_print_const(c, fmt, true),
|
||||||
ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true),
|
ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true),
|
||||||
|
// FIXME(valtrees): Correctly print mir constants.
|
||||||
|
ConstantKind::Unevaluated(..) => {
|
||||||
|
fmt.write_str("_")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -464,12 +464,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
||||||
let val = match literal {
|
let val = match literal {
|
||||||
ConstantKind::Ty(ct) => match ct.kind() {
|
ConstantKind::Ty(ct) => match ct.kind() {
|
||||||
ty::ConstKind::Param(p) => format!("Param({})", p),
|
ty::ConstKind::Param(p) => format!("Param({})", p),
|
||||||
ty::ConstKind::Unevaluated(uv) => format!(
|
ty::ConstKind::Unevaluated(uv) => {
|
||||||
"Unevaluated({}, {:?}, {:?})",
|
format!(
|
||||||
self.tcx.def_path_str(uv.def.did),
|
"Unevaluated({}, {:?}, {:?})",
|
||||||
uv.substs,
|
self.tcx.def_path_str(uv.def.did),
|
||||||
uv.promoted,
|
uv.substs,
|
||||||
),
|
uv.promoted,
|
||||||
|
)
|
||||||
|
}
|
||||||
ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)),
|
ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)),
|
||||||
ty::ConstKind::Error(_) => "Error".to_string(),
|
ty::ConstKind::Error(_) => "Error".to_string(),
|
||||||
// These variants shouldn't exist in the MIR.
|
// These variants shouldn't exist in the MIR.
|
||||||
|
@ -477,6 +479,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
||||||
| ty::ConstKind::Infer(_)
|
| ty::ConstKind::Infer(_)
|
||||||
| ty::ConstKind::Bound(..) => bug!("unexpected MIR constant: {:?}", literal),
|
| ty::ConstKind::Bound(..) => bug!("unexpected MIR constant: {:?}", literal),
|
||||||
},
|
},
|
||||||
|
ConstantKind::Unevaluated(uv, _) => {
|
||||||
|
format!(
|
||||||
|
"Unevaluated({}, {:?}, {:?})",
|
||||||
|
self.tcx.def_path_str(uv.def.did),
|
||||||
|
uv.substs,
|
||||||
|
uv.promoted,
|
||||||
|
)
|
||||||
|
}
|
||||||
// To keep the diffs small, we render this like we render `ty::Const::Value`.
|
// To keep the diffs small, we render this like we render `ty::Const::Value`.
|
||||||
//
|
//
|
||||||
// This changes once `ty::Const::Value` is represented using valtrees.
|
// This changes once `ty::Const::Value` is represented using valtrees.
|
||||||
|
@ -696,9 +706,9 @@ pub fn write_allocations<'tcx>(
|
||||||
struct CollectAllocIds(BTreeSet<AllocId>);
|
struct CollectAllocIds(BTreeSet<AllocId>);
|
||||||
|
|
||||||
impl<'tcx> Visitor<'tcx> for CollectAllocIds {
|
impl<'tcx> Visitor<'tcx> for CollectAllocIds {
|
||||||
fn visit_constant(&mut self, c: &Constant<'tcx>, loc: Location) {
|
fn visit_constant(&mut self, c: &Constant<'tcx>, _: Location) {
|
||||||
match c.literal {
|
match c.literal {
|
||||||
ConstantKind::Ty(c) => self.visit_const(c, loc),
|
ConstantKind::Ty(_) | ConstantKind::Unevaluated(..) => {}
|
||||||
ConstantKind::Val(val, _) => {
|
ConstantKind::Val(val, _) => {
|
||||||
self.0.extend(alloc_ids_from_const_val(val));
|
self.0.extend(alloc_ids_from_const_val(val));
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,9 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)),
|
ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)),
|
||||||
ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)),
|
ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)),
|
||||||
|
ConstantKind::Unevaluated(uv, t) => {
|
||||||
|
Ok(ConstantKind::Unevaluated(uv.try_fold_with(folder)?, t.try_fold_with(folder)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
ConstantKind::Ty(c) => c.visit_with(visitor),
|
ConstantKind::Ty(c) => c.visit_with(visitor),
|
||||||
ConstantKind::Val(_, t) => t.visit_with(visitor),
|
ConstantKind::Val(_, t) => t.visit_with(visitor),
|
||||||
|
ConstantKind::Unevaluated(uv, t) => {
|
||||||
|
uv.visit_with(visitor)?;
|
||||||
|
t.visit_with(visitor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,14 +237,6 @@ macro_rules! make_mir_visitor {
|
||||||
self.super_region(region);
|
self.super_region(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(
|
|
||||||
&mut self,
|
|
||||||
constant: $(& $mutability)? ty::Const<'tcx>,
|
|
||||||
_: Location,
|
|
||||||
) {
|
|
||||||
self.super_const(constant);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_substs(
|
fn visit_substs(
|
||||||
&mut self,
|
&mut self,
|
||||||
substs: & $($mutability)? SubstsRef<'tcx>,
|
substs: & $($mutability)? SubstsRef<'tcx>,
|
||||||
|
@ -877,8 +869,9 @@ macro_rules! make_mir_visitor {
|
||||||
self.visit_span($(& $mutability)? *span);
|
self.visit_span($(& $mutability)? *span);
|
||||||
drop(user_ty); // no visit method for this
|
drop(user_ty); // no visit method for this
|
||||||
match literal {
|
match literal {
|
||||||
ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location),
|
ConstantKind::Ty(_) => {}
|
||||||
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
||||||
|
ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,9 +909,6 @@ macro_rules! make_mir_visitor {
|
||||||
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
|
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_const(&mut self, _const: $(& $mutability)? ty::Const<'tcx>) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
|
fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -853,9 +853,9 @@ mod size_asserts {
|
||||||
static_assert_size!(Expr<'_>, 64);
|
static_assert_size!(Expr<'_>, 64);
|
||||||
static_assert_size!(ExprKind<'_>, 40);
|
static_assert_size!(ExprKind<'_>, 40);
|
||||||
#[cfg(not(bootstrap))]
|
#[cfg(not(bootstrap))]
|
||||||
static_assert_size!(Pat<'_>, 64);
|
static_assert_size!(Pat<'_>, 72);
|
||||||
#[cfg(not(bootstrap))]
|
#[cfg(not(bootstrap))]
|
||||||
static_assert_size!(PatKind<'_>, 48);
|
static_assert_size!(PatKind<'_>, 56);
|
||||||
#[cfg(not(bootstrap))]
|
#[cfg(not(bootstrap))]
|
||||||
static_assert_size!(Stmt<'_>, 48);
|
static_assert_size!(Stmt<'_>, 48);
|
||||||
#[cfg(not(bootstrap))]
|
#[cfg(not(bootstrap))]
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<'tcx> AbstractConst<'tcx> {
|
||||||
ct: ty::Const<'tcx>,
|
ct: ty::Const<'tcx>,
|
||||||
) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> {
|
) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> {
|
||||||
match ct.kind() {
|
match ct.kind() {
|
||||||
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()),
|
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv),
|
||||||
ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported),
|
ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported),
|
||||||
_ => Ok(None),
|
_ => Ok(None),
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub struct ConstS<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||||
static_assert_size!(ConstS<'_>, 48);
|
static_assert_size!(ConstS<'_>, 40);
|
||||||
|
|
||||||
impl<'tcx> Const<'tcx> {
|
impl<'tcx> Const<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -84,7 +84,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
||||||
def: def.to_global(),
|
def: def.to_global(),
|
||||||
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||||
promoted: None,
|
promoted: (),
|
||||||
}),
|
}),
|
||||||
ty,
|
ty,
|
||||||
}),
|
}),
|
||||||
|
@ -181,7 +181,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
||||||
def: ty::WithOptConstParam::unknown(def_id).to_global(),
|
def: ty::WithOptConstParam::unknown(def_id).to_global(),
|
||||||
substs,
|
substs,
|
||||||
promoted: None,
|
promoted: (),
|
||||||
}),
|
}),
|
||||||
ty,
|
ty,
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,6 +11,7 @@ use rustc_macros::HashStable;
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
|
|
||||||
use super::ScalarInt;
|
use super::ScalarInt;
|
||||||
|
|
||||||
/// An unevaluated, potentially generic, constant.
|
/// An unevaluated, potentially generic, constant.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
|
||||||
#[derive(Hash, HashStable)]
|
#[derive(Hash, HashStable)]
|
||||||
|
@ -66,7 +67,7 @@ pub enum ConstKind<'tcx> {
|
||||||
|
|
||||||
/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
|
/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
|
||||||
/// variants when the code is monomorphic enough for that.
|
/// variants when the code is monomorphic enough for that.
|
||||||
Unevaluated(Unevaluated<'tcx>),
|
Unevaluated(Unevaluated<'tcx, ()>),
|
||||||
|
|
||||||
/// Used to hold computed value.
|
/// Used to hold computed value.
|
||||||
Value(ty::ValTree<'tcx>),
|
Value(ty::ValTree<'tcx>),
|
||||||
|
@ -77,7 +78,7 @@ pub enum ConstKind<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||||
static_assert_size!(ConstKind<'_>, 40);
|
static_assert_size!(ConstKind<'_>, 32);
|
||||||
|
|
||||||
impl<'tcx> ConstKind<'tcx> {
|
impl<'tcx> ConstKind<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -184,6 +185,8 @@ impl<'tcx> ConstKind<'tcx> {
|
||||||
if let ConstKind::Unevaluated(unevaluated) = self {
|
if let ConstKind::Unevaluated(unevaluated) = self {
|
||||||
use crate::mir::interpret::ErrorHandled;
|
use crate::mir::interpret::ErrorHandled;
|
||||||
|
|
||||||
|
assert_eq!(unevaluated.promoted, ());
|
||||||
|
|
||||||
// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
|
// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
|
||||||
// also does later, but we want to do it before checking for
|
// also does later, but we want to do it before checking for
|
||||||
// inference variables.
|
// inference variables.
|
||||||
|
@ -204,7 +207,7 @@ impl<'tcx> ConstKind<'tcx> {
|
||||||
tcx.param_env(unevaluated.def.did).and(ty::Unevaluated {
|
tcx.param_env(unevaluated.def.did).and(ty::Unevaluated {
|
||||||
def: unevaluated.def,
|
def: unevaluated.def,
|
||||||
substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did),
|
substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did),
|
||||||
promoted: unevaluated.promoted,
|
promoted: (),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
param_env_and
|
param_env_and
|
||||||
|
@ -228,7 +231,7 @@ impl<'tcx> ConstKind<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EvalMode::Mir => {
|
EvalMode::Mir => {
|
||||||
match tcx.const_eval_resolve(param_env, unevaluated, None) {
|
match tcx.const_eval_resolve(param_env, unevaluated.expand(), None) {
|
||||||
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
|
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
|
||||||
// and we use the original type, so nothing from `substs`
|
// and we use the original type, so nothing from `substs`
|
||||||
// (which may be identity substs, see above),
|
// (which may be identity substs, see above),
|
||||||
|
|
|
@ -302,6 +302,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
{
|
{
|
||||||
value.fold_with(&mut RegionFolder::new(self, &mut f))
|
value.fold_with(&mut RegionFolder::new(self, &mut f))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn super_fold_regions<T>(
|
||||||
|
self,
|
||||||
|
value: T,
|
||||||
|
mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
|
||||||
|
) -> T
|
||||||
|
where
|
||||||
|
T: TypeSuperFoldable<'tcx>,
|
||||||
|
{
|
||||||
|
value.super_fold_with(&mut RegionFolder::new(self, &mut f))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Folds over the substructure of a type, visiting its component
|
/// Folds over the substructure of a type, visiting its component
|
||||||
|
|
|
@ -1201,15 +1201,9 @@ pub trait PrettyPrinter<'tcx>:
|
||||||
}
|
}
|
||||||
|
|
||||||
match ct.kind() {
|
match ct.kind() {
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated {
|
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
|
||||||
def,
|
assert_eq!(promoted, ());
|
||||||
substs,
|
|
||||||
promoted: Some(promoted),
|
|
||||||
}) => {
|
|
||||||
p!(print_value_path(def.did, substs));
|
|
||||||
p!(write("::{:?}", promoted));
|
|
||||||
}
|
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => {
|
|
||||||
match self.tcx().def_kind(def.did) {
|
match self.tcx().def_kind(def.did) {
|
||||||
DefKind::Static(..) | DefKind::Const | DefKind::AssocConst => {
|
DefKind::Static(..) | DefKind::Const | DefKind::AssocConst => {
|
||||||
p!(print_value_path(def.did, substs))
|
p!(print_value_path(def.did, substs))
|
||||||
|
|
|
@ -615,7 +615,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
|
||||||
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
|
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
|
||||||
if tcx.features().generic_const_exprs =>
|
if tcx.features().generic_const_exprs =>
|
||||||
{
|
{
|
||||||
tcx.try_unify_abstract_consts(relation.param_env().and((au.shrink(), bu.shrink())))
|
tcx.try_unify_abstract_consts(relation.param_env().and((au, bu)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
|
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
|
||||||
|
@ -624,6 +624,8 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
|
||||||
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
|
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
|
||||||
if au.def == bu.def && au.promoted == bu.promoted =>
|
if au.def == bu.def && au.promoted == bu.promoted =>
|
||||||
{
|
{
|
||||||
|
assert_eq!(au.promoted, ());
|
||||||
|
|
||||||
let substs = relation.relate_with_variance(
|
let substs = relation.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Variance::Invariant,
|
||||||
ty::VarianceDiagInfo::default(),
|
ty::VarianceDiagInfo::default(),
|
||||||
|
@ -634,7 +636,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
|
||||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
||||||
def: au.def,
|
def: au.def,
|
||||||
substs,
|
substs,
|
||||||
promoted: au.promoted,
|
promoted: (),
|
||||||
}),
|
}),
|
||||||
ty: a.ty(),
|
ty: a.ty(),
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -2,26 +2,18 @@
|
||||||
|
|
||||||
use crate::build::{parse_float_into_constval, Builder};
|
use crate::build::{parse_float_into_constval, Builder};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_middle::mir::interpret::{
|
use rustc_middle::mir::interpret::{
|
||||||
Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
|
Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
|
||||||
};
|
};
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::thir::*;
|
use rustc_middle::thir::*;
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, TyCtxt};
|
||||||
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt};
|
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
|
|
||||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
/// Compile `expr`, yielding a compile-time constant. Assumes that
|
/// Compile `expr`, yielding a compile-time constant. Assumes that
|
||||||
/// `expr` is a valid compile-time constant!
|
/// `expr` is a valid compile-time constant!
|
||||||
pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
|
pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
|
||||||
let create_uneval_from_def_id =
|
|
||||||
|tcx: TyCtxt<'tcx>, def_id: DefId, ty: Ty<'tcx>, substs: SubstsRef<'tcx>| {
|
|
||||||
let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
|
|
||||||
tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty })
|
|
||||||
};
|
|
||||||
|
|
||||||
let this = self;
|
let this = self;
|
||||||
let tcx = this.tcx;
|
let tcx = this.tcx;
|
||||||
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
|
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
|
||||||
|
@ -73,7 +65,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
inferred_ty: ty,
|
inferred_ty: ty,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs));
|
|
||||||
|
let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
|
||||||
|
let literal = ConstantKind::Unevaluated(uneval, ty);
|
||||||
|
|
||||||
Constant { user_ty, span, literal }
|
Constant { user_ty, span, literal }
|
||||||
}
|
}
|
||||||
|
@ -85,7 +79,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
Constant { user_ty: None, span, literal }
|
Constant { user_ty: None, span, literal }
|
||||||
}
|
}
|
||||||
ExprKind::ConstBlock { did: def_id, substs } => {
|
ExprKind::ConstBlock { did: def_id, substs } => {
|
||||||
let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs));
|
let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
|
||||||
|
let literal = ConstantKind::Unevaluated(uneval, ty);
|
||||||
|
|
||||||
Constant { user_ty: None, span, literal }
|
Constant { user_ty: None, span, literal }
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,23 +565,19 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
let value = value.eval(self.tcx, self.param_env);
|
let value = value.eval(self.tcx, self.param_env);
|
||||||
|
|
||||||
match value {
|
match value {
|
||||||
mir::ConstantKind::Ty(c) => {
|
mir::ConstantKind::Ty(c) => match c.kind() {
|
||||||
match c.kind() {
|
ConstKind::Param(_) => {
|
||||||
ConstKind::Param(_) => {
|
self.errors.push(PatternError::ConstParamInPattern(span));
|
||||||
self.errors.push(PatternError::ConstParamInPattern(span));
|
return PatKind::Wild;
|
||||||
return PatKind::Wild;
|
|
||||||
}
|
|
||||||
ConstKind::Unevaluated(_) => {
|
|
||||||
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
|
|
||||||
self.tcx
|
|
||||||
.sess
|
|
||||||
.span_err(span, "constant pattern depends on a generic parameter");
|
|
||||||
return PatKind::Wild;
|
|
||||||
}
|
|
||||||
_ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"),
|
|
||||||
}
|
}
|
||||||
}
|
_ => bug!("Expected ConstKind::Param"),
|
||||||
|
},
|
||||||
mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
|
mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
|
||||||
|
mir::ConstantKind::Unevaluated(..) => {
|
||||||
|
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
|
||||||
|
self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter");
|
||||||
|
return PatKind::Wild;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,7 @@ use rustc_middle::mir::{
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
|
||||||
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable};
|
||||||
self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable,
|
|
||||||
};
|
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
|
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
|
||||||
|
@ -301,18 +299,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
let err = ConstEvalErr::new(&self.ecx, error, Some(c.span));
|
let err = ConstEvalErr::new(&self.ecx, error, Some(c.span));
|
||||||
if let Some(lint_root) = self.lint_root(source_info) {
|
if let Some(lint_root) = self.lint_root(source_info) {
|
||||||
let lint_only = match c.literal {
|
let lint_only = match c.literal {
|
||||||
ConstantKind::Ty(ct) => match ct.kind() {
|
ConstantKind::Ty(ct) => ct.needs_subst(),
|
||||||
|
ConstantKind::Unevaluated(
|
||||||
|
ty::Unevaluated { def: _, substs: _, promoted: Some(_) },
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
// Promoteds must lint and not error as the user didn't ask for them
|
// Promoteds must lint and not error as the user didn't ask for them
|
||||||
ConstKind::Unevaluated(ty::Unevaluated {
|
true
|
||||||
def: _,
|
}
|
||||||
substs: _,
|
ConstantKind::Unevaluated(..) | ConstantKind::Val(..) => c.needs_subst(),
|
||||||
promoted: Some(_),
|
|
||||||
}) => true,
|
|
||||||
// Out of backwards compatibility we cannot report hard errors in unused
|
|
||||||
// generic functions using associated constants of the generic parameters.
|
|
||||||
_ => c.literal.needs_subst(),
|
|
||||||
},
|
|
||||||
ConstantKind::Val(_, ty) => ty.needs_subst(),
|
|
||||||
};
|
};
|
||||||
if lint_only {
|
if lint_only {
|
||||||
// Out of backwards compatibility we cannot report hard errors in unused
|
// Out of backwards compatibility we cannot report hard errors in unused
|
||||||
|
|
|
@ -8,7 +8,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}
|
||||||
use rustc_middle::mir::visit::*;
|
use rustc_middle::mir::visit::*;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::subst::Subst;
|
use rustc_middle::ty::subst::Subst;
|
||||||
use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
|
||||||
use rustc_session::config::OptLevel;
|
use rustc_session::config::OptLevel;
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
|
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
|
||||||
|
@ -604,11 +604,11 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
|
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
|
||||||
// because we are calling `subst_and_normalize_erasing_regions`.
|
// because we are calling `subst_and_normalize_erasing_regions`.
|
||||||
caller_body.required_consts.extend(
|
caller_body.required_consts.extend(
|
||||||
callee_body.required_consts.iter().copied().filter(|&ct| {
|
callee_body.required_consts.iter().copied().filter(|&ct| match ct.literal {
|
||||||
match ct.literal.const_for_ty() {
|
ConstantKind::Ty(_) => {
|
||||||
Some(ct) => matches!(ct.kind(), ConstKind::Unevaluated(_)),
|
bug!("should never encounter ty::Unevaluated in `required_consts`")
|
||||||
None => true,
|
|
||||||
}
|
}
|
||||||
|
ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rustc_middle::mir::visit::Visitor;
|
use rustc_middle::mir::visit::Visitor;
|
||||||
use rustc_middle::mir::{Constant, Location};
|
use rustc_middle::mir::{Constant, ConstantKind, Location};
|
||||||
use rustc_middle::ty::ConstKind;
|
use rustc_middle::ty::ConstKind;
|
||||||
|
|
||||||
pub struct RequiredConstsVisitor<'a, 'tcx> {
|
pub struct RequiredConstsVisitor<'a, 'tcx> {
|
||||||
|
@ -15,8 +15,13 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
|
||||||
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
|
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
|
||||||
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
|
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
|
||||||
let literal = constant.literal;
|
let literal = constant.literal;
|
||||||
if let Some(ct) = literal.const_for_ty() && let ConstKind::Unevaluated(_) = ct.kind() {
|
match literal {
|
||||||
self.required_consts.push(*constant);
|
ConstantKind::Ty(c) => match c.kind() {
|
||||||
|
ConstKind::Param(_) => {}
|
||||||
|
_ => bug!("only ConstKind::Param should be encountered here, got {:#?}", c),
|
||||||
|
},
|
||||||
|
ConstantKind::Unevaluated(..) => self.required_consts.push(*constant),
|
||||||
|
ConstantKind::Val(..) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -770,7 +770,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||||
ty::ConstKind::Unevaluated(ct) => {
|
ty::ConstKind::Unevaluated(ct) => {
|
||||||
debug!(?ct);
|
debug!(?ct);
|
||||||
let param_env = ty::ParamEnv::reveal_all();
|
let param_env = ty::ParamEnv::reveal_all();
|
||||||
match self.tcx.const_eval_resolve(param_env, ct, None) {
|
match self.tcx.const_eval_resolve(param_env, ct.expand(), None) {
|
||||||
// The `monomorphize` call should have evaluated that constant already.
|
// The `monomorphize` call should have evaluated that constant already.
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return,
|
Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return,
|
||||||
|
@ -783,44 +783,22 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
},
|
},
|
||||||
};
|
mir::ConstantKind::Unevaluated(uv, _) => {
|
||||||
collect_const_value(self.tcx, val, self.output);
|
let param_env = ty::ParamEnv::reveal_all();
|
||||||
self.visit_ty(literal.ty(), TyContext::Location(location));
|
match self.tcx.const_eval_resolve(param_env, uv, None) {
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
fn visit_const(&mut self, constant: ty::Const<'tcx>, location: Location) {
|
|
||||||
debug!("visiting const {:?} @ {:?}", constant, location);
|
|
||||||
|
|
||||||
let substituted_constant = self.monomorphize(constant);
|
|
||||||
let param_env = ty::ParamEnv::reveal_all();
|
|
||||||
|
|
||||||
match substituted_constant.kind() {
|
|
||||||
ty::ConstKind::Value(val) => {
|
|
||||||
let const_val = self.tcx.valtree_to_const_val((constant.ty(), val));
|
|
||||||
collect_const_value(self.tcx, const_val, self.output)
|
|
||||||
}
|
|
||||||
ty::ConstKind::Unevaluated(unevaluated) => {
|
|
||||||
match self.tcx.const_eval_resolve(param_env, unevaluated, None) {
|
|
||||||
// The `monomorphize` call should have evaluated that constant already.
|
// The `monomorphize` call should have evaluated that constant already.
|
||||||
Ok(val) => span_bug!(
|
Ok(val) => val,
|
||||||
self.body.source_info(location).span,
|
Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return,
|
||||||
"collection encountered the unevaluated constant {} which evaluated to {:?}",
|
|
||||||
substituted_constant,
|
|
||||||
val
|
|
||||||
),
|
|
||||||
Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => {}
|
|
||||||
Err(ErrorHandled::TooGeneric) => span_bug!(
|
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||||
self.body.source_info(location).span,
|
self.body.source_info(location).span,
|
||||||
"collection encountered polymorphic constant: {}",
|
"collection encountered polymorphic constant: {:?}",
|
||||||
substituted_constant
|
literal
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
};
|
||||||
}
|
collect_const_value(self.tcx, val, self.output);
|
||||||
|
MirVisitor::visit_ty(self, literal.ty(), TyContext::Location(location));
|
||||||
self.super_const(constant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
|
fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_hir::{def::DefKind, def_id::DefId, ConstContext};
|
||||||
use rustc_index::bit_set::FiniteBitSet;
|
use rustc_index::bit_set::FiniteBitSet;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
visit::{TyContext, Visitor},
|
visit::{TyContext, Visitor},
|
||||||
Local, LocalDecl, Location,
|
Constant, ConstantKind, Local, LocalDecl, Location,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self,
|
self,
|
||||||
|
@ -270,8 +270,15 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
|
||||||
self.super_local_decl(local, local_decl);
|
self.super_local_decl(local, local_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: Const<'tcx>, _: Location) {
|
fn visit_constant(&mut self, ct: &Constant<'tcx>, location: Location) {
|
||||||
c.visit_with(self);
|
match ct.literal {
|
||||||
|
ConstantKind::Ty(c) => {
|
||||||
|
c.visit_with(self);
|
||||||
|
}
|
||||||
|
ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => {
|
||||||
|
Visitor::visit_ty(self, ty, TyContext::Location(location))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>, _: TyContext) {
|
fn visit_ty(&mut self, ty: Ty<'tcx>, _: TyContext) {
|
||||||
|
@ -292,7 +299,26 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
|
||||||
self.unused_parameters.clear(param.index);
|
self.unused_parameters.clear(param.index);
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
}
|
}
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)})
|
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
|
||||||
|
if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) =>
|
||||||
|
{
|
||||||
|
assert_eq!(promoted, ());
|
||||||
|
|
||||||
|
self.visit_child_body(def.did, substs);
|
||||||
|
ControlFlow::CONTINUE
|
||||||
|
}
|
||||||
|
_ => c.super_visit_with(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
|
if !constant.has_param_types_or_consts() {
|
||||||
|
return ControlFlow::CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
match constant {
|
||||||
|
ConstantKind::Ty(ct) => ct.visit_with(self),
|
||||||
|
ConstantKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p) }, _)
|
||||||
// Avoid considering `T` unused when constants are of the form:
|
// Avoid considering `T` unused when constants are of the form:
|
||||||
// `<Self as Foo<T>>::foo::promoted[p]`
|
// `<Self as Foo<T>>::foo::promoted[p]`
|
||||||
if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self =>
|
if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self =>
|
||||||
|
@ -303,13 +329,9 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
|
||||||
self.visit_body(&promoted[p]);
|
self.visit_body(&promoted[p]);
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
}
|
}
|
||||||
ty::ConstKind::Unevaluated(uv)
|
ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => {
|
||||||
if matches!(self.tcx.def_kind(uv.def.did), DefKind::AnonConst | DefKind::InlineConst) =>
|
constant.super_visit_with(self)
|
||||||
{
|
|
||||||
self.visit_child_body(uv.def.did, uv.substs);
|
|
||||||
ControlFlow::CONTINUE
|
|
||||||
}
|
}
|
||||||
_ => c.super_visit_with(self),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -834,7 +834,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
let reported =
|
let reported =
|
||||||
tcx.sess.emit_err(UnableToConstructConstantValue {
|
tcx.sess.emit_err(UnableToConstructConstantValue {
|
||||||
span: tcx.def_span(def_id),
|
span: tcx.def_span(def_id),
|
||||||
unevaluated,
|
unevaluated: unevaluated.expand(),
|
||||||
});
|
});
|
||||||
Err(ErrorHandled::Reported(reported))
|
Err(ErrorHandled::Reported(reported))
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
FailureKind::Concrete => {}
|
FailureKind::Concrete => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
|
||||||
match concrete {
|
match concrete {
|
||||||
Err(ErrorHandled::TooGeneric) => {
|
Err(ErrorHandled::TooGeneric) => {
|
||||||
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
|
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
|
||||||
|
@ -210,7 +210,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
// and hopefully soon change this to an error.
|
// and hopefully soon change this to an error.
|
||||||
//
|
//
|
||||||
// See #74595 for more details about this.
|
// See #74595 for more details about this.
|
||||||
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
|
||||||
|
|
||||||
match concrete {
|
match concrete {
|
||||||
// If we're evaluating a foreign constant, under a nightly compiler without generic
|
// If we're evaluating a foreign constant, under a nightly compiler without generic
|
||||||
|
|
|
@ -505,11 +505,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
||||||
(c1.kind(), c2.kind())
|
(c1.kind(), c2.kind())
|
||||||
{
|
{
|
||||||
if infcx.try_unify_abstract_consts(
|
if infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
|
||||||
a.shrink(),
|
|
||||||
b.shrink(),
|
|
||||||
obligation.param_env,
|
|
||||||
) {
|
|
||||||
return ProcessResult::Changed(vec![]);
|
return ProcessResult::Changed(vec![]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,7 +366,9 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
_ => mir::ConstantKind::Ty(const_folded),
|
_ => mir::ConstantKind::Ty(const_folded),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?,
|
mir::ConstantKind::Val(_, _) | mir::ConstantKind::Unevaluated(..) => {
|
||||||
|
constant.try_super_fold_with(self)?
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -699,11 +699,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
||||||
(c1.kind(), c2.kind())
|
(c1.kind(), c2.kind())
|
||||||
{
|
{
|
||||||
if self.infcx.try_unify_abstract_consts(
|
if self.infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
|
||||||
a.shrink(),
|
|
||||||
b.shrink(),
|
|
||||||
obligation.param_env,
|
|
||||||
) {
|
|
||||||
return Ok(EvaluatedToOk);
|
return Ok(EvaluatedToOk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,7 +456,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||||
self.out.extend(obligations);
|
self.out.extend(obligations);
|
||||||
|
|
||||||
let predicate =
|
let predicate =
|
||||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
|
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
|
||||||
.to_predicate(self.tcx());
|
.to_predicate(self.tcx());
|
||||||
let cause = self.cause(traits::WellFormed(None));
|
let cause = self.cause(traits::WellFormed(None));
|
||||||
self.out.push(traits::Obligation::with_depth(
|
self.out.push(traits::Obligation::with_depth(
|
||||||
|
|
|
@ -222,17 +222,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
debug!("AbstractConstBuilder::build: body={:?}", &*self.body);
|
debug!("AbstractConstBuilder::build: body={:?}", &*self.body);
|
||||||
self.recurse_build(self.body_id)?;
|
self.recurse_build(self.body_id)?;
|
||||||
|
|
||||||
for n in self.nodes.iter() {
|
|
||||||
if let Node::Leaf(ct) = n {
|
|
||||||
if let ty::ConstKind::Unevaluated(ct) = ct.kind() {
|
|
||||||
// `AbstractConst`s should not contain any promoteds as they require references which
|
|
||||||
// are not allowed.
|
|
||||||
assert_eq!(ct.promoted, None);
|
|
||||||
assert_eq!(ct, self.tcx.erase_regions(ct));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter()))
|
Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2368,10 +2368,10 @@ fn const_evaluatable_predicates_of<'tcx>(
|
||||||
let def_id = self.tcx.hir().local_def_id(c.hir_id);
|
let def_id = self.tcx.hir().local_def_id(c.hir_id);
|
||||||
let ct = ty::Const::from_anon_const(self.tcx, def_id);
|
let ct = ty::Const::from_anon_const(self.tcx, def_id);
|
||||||
if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
|
if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
|
||||||
assert_eq!(uv.promoted, None);
|
assert_eq!(uv.promoted, ());
|
||||||
let span = self.tcx.hir().span(c.hir_id);
|
let span = self.tcx.hir().span(c.hir_id);
|
||||||
self.preds.insert((
|
self.preds.insert((
|
||||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
|
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
|
||||||
.to_predicate(self.tcx),
|
.to_predicate(self.tcx),
|
||||||
span,
|
span,
|
||||||
));
|
));
|
||||||
|
|
|
@ -235,14 +235,13 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
|
||||||
pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
|
pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
|
||||||
match n.kind() {
|
match n.kind() {
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => {
|
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => {
|
||||||
let mut s = if let Some(def) = def.as_local() {
|
assert_eq!(promoted, ());
|
||||||
|
let s = if let Some(def) = def.as_local() {
|
||||||
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did))
|
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did))
|
||||||
} else {
|
} else {
|
||||||
inline::print_inlined_const(cx.tcx, def.did)
|
inline::print_inlined_const(cx.tcx, def.did)
|
||||||
};
|
};
|
||||||
if let Some(promoted) = promoted {
|
|
||||||
s.push_str(&format!("::{:?}", promoted))
|
|
||||||
}
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
|
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
|
||||||
- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
|
- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
|
||||||
- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
|
- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
|
||||||
+ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
|
+ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
|
- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
|
||||||
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
|
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
|
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
|
||||||
- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
|
- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
|
||||||
- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
|
- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
|
||||||
+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
|
+ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
|
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
|
||||||
- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
|
- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
|
StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
|
||||||
StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
||||||
StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
||||||
_9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
_9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||||
// + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
|
StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
|
||||||
StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
||||||
StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
||||||
_9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
_9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||||
// + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
|
StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
|
||||||
StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30
|
StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30
|
||||||
StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
|
StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
|
||||||
_3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
|
_3 = const _; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/const_prop_fails_gracefully.rs:8:13: 8:16
|
// + span: $DIR/const_prop_fails_gracefully.rs:8:13: 8:16
|
||||||
// + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
|
// + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
|
||||||
|
|
|
@ -8,9 +8,8 @@
|
||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
||||||
- _1 = const <bool as NeedsDrop>::NEEDS; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
_1 = const _; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
||||||
- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
||||||
+ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
|
||||||
+ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
+ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
bb0: {
|
bb0: {
|
||||||
StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
|
StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
|
||||||
StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
||||||
_4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
_4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/ref_deref.rs:5:6: 5:10
|
// + span: $DIR/ref_deref.rs:5:6: 5:10
|
||||||
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
- StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
|
- StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
|
||||||
- _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
|
- _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
|
||||||
- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
||||||
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
+ _4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
|
||||||
+ // mir::Constant
|
+ // mir::Constant
|
||||||
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
|
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
|
||||||
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
bb0: {
|
bb0: {
|
||||||
StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
|
StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
|
||||||
StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
||||||
_4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
_4 = const _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/ref_deref_project.rs:6:6: 6:17
|
// + span: $DIR/ref_deref_project.rs:6:6: 6:17
|
||||||
// + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
- StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
|
- StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
|
||||||
- _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
|
- _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
|
||||||
- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
||||||
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
+ _4 = const _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
|
||||||
+ // mir::Constant
|
+ // mir::Constant
|
||||||
+ // + span: $DIR/ref_deref_project.rs:6:6: 6:17
|
+ // + span: $DIR/ref_deref_project.rs:6:6: 6:17
|
||||||
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
|
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
|
StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
|
||||||
StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
||||||
StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
||||||
_9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
_9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/slice_len.rs:5:6: 5:19
|
// + span: $DIR/slice_len.rs:5:6: 5:19
|
||||||
// + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
|
StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
|
||||||
StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
||||||
StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
||||||
_9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
_9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/slice_len.rs:5:6: 5:19
|
// + span: $DIR/slice_len.rs:5:6: 5:19
|
||||||
// + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
bb0: {
|
bb0: {
|
||||||
StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
|
StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
|
||||||
StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
|
StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
|
||||||
_14 = const main::promoted[0]; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
|
_14 = const _; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/derefer_complex_case.rs:6:17: 6:26
|
// + span: $DIR/derefer_complex_case.rs:6:17: 6:26
|
||||||
// + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
+ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
|
+ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
|
||||||
+ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
|
+ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
|
||||||
+ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
+ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
+ _9 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
+ _9 = const _; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
|
- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
|
||||||
- // + user_ty: UserType(1)
|
- // + user_ty: UserType(1)
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn bar() -> bool {
|
||||||
_2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6
|
_2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6
|
||||||
StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
||||||
StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
||||||
_10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
_10 = const _; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/inline-retag.rs:12:7: 12:9
|
// + span: $DIR/inline-retag.rs:12:7: 12:9
|
||||||
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) }
|
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) }
|
||||||
|
@ -43,7 +43,7 @@ fn bar() -> bool {
|
||||||
Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
|
||||||
StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
|
StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
|
||||||
StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
|
StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
|
||||||
_9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
|
_9 = const _; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/inline-retag.rs:12:11: 12:14
|
// + span: $DIR/inline-retag.rs:12:11: 12:14
|
||||||
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) }
|
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -87,7 +87,7 @@
|
||||||
StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
_10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
_28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_28 = const _; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
| User Type Annotations
|
| User Type Annotations
|
||||||
| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||||
| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: None }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: () }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||||
|
|
|
|
||||||
fn main() -> () {
|
fn main() -> () {
|
||||||
let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15
|
let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
|
StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
|
||||||
StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
|
StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
|
||||||
StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
|
StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
|
||||||
_19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
|
_19 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/lower_intrinsics.rs:50:42: 50:44
|
// + span: $DIR/lower_intrinsics.rs:50:42: 50:44
|
||||||
// + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) }
|
// + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) }
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
|
StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
|
||||||
StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
|
StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
|
||||||
StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
|
StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
|
||||||
_18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
|
_18 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/lower_intrinsics.rs:51:42: 51:45
|
// + span: $DIR/lower_intrinsics.rs:51:42: 51:45
|
||||||
// + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) }
|
// + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) }
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
|
StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
|
||||||
StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
|
StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
|
||||||
StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
|
StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
|
||||||
_17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
|
_17 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/lower_intrinsics.rs:52:42: 52:47
|
// + span: $DIR/lower_intrinsics.rs:52:42: 52:47
|
||||||
// + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) }
|
// + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) }
|
||||||
|
|
|
@ -51,7 +51,7 @@ fn full_tested_match() -> () {
|
||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
|
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
|
||||||
_11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
|
_11 = const _; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/match_false_edges.rs:14:14: 14:15
|
// + span: $DIR/match_false_edges.rs:14:14: 14:15
|
||||||
// + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) }
|
// + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -121,7 +121,7 @@ fn array_casts() -> () {
|
||||||
_14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
_35 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
// + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) }
|
// + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) }
|
||||||
|
|
|
@ -142,7 +142,7 @@ fn main() -> () {
|
||||||
Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
|
Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
|
||||||
StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||||
StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||||
_28 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
_28 = const _; // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/retag.rs:48:21: 48:23
|
// + span: $DIR/retag.rs:48:21: 48:23
|
||||||
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue