1
Fork 0

Auto merge of #105012 - WaffleLapkin:into, r=oli-obk

Make `tcx.mk_const` more permissive wrt `kind` argument (`impl Into`)

r? `@oli-obk` you've asked for this >:)
This commit is contained in:
bors 2022-11-29 13:28:44 +00:00
commit e0098a5cc3
20 changed files with 86 additions and 98 deletions

View file

@ -870,6 +870,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]] [[package]]
name = "core" name = "core"
version = "0.0.0" version = "0.0.0"
@ -1060,6 +1066,19 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn",
]
[[package]] [[package]]
name = "diff" name = "diff"
version = "0.1.13" version = "0.1.13"
@ -3979,6 +3998,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"chalk-ir", "chalk-ir",
"derive_more",
"either", "either",
"gsgdt", "gsgdt",
"polonius-engine", "polonius-engine",

View file

@ -147,7 +147,7 @@ impl<'tcx> InferCtxt<'tcx> {
CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, name }, ty) => { CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, name }, ty) => {
let universe_mapped = universe_map(universe); let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name }; let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name };
self.tcx.mk_const(ty::ConstKind::Placeholder(placeholder_mapped), ty).into() self.tcx.mk_const(placeholder_mapped, ty).into()
} }
} }
} }

View file

@ -753,7 +753,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
origin: var_value.origin, origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.for_universe }, val: ConstVariableValue::Unknown { universe: self.for_universe },
}); });
Ok(self.tcx().mk_const_var(new_var_id, c.ty())) Ok(self.tcx().mk_const(new_var_id, c.ty()))
} }
} }
} }
@ -765,10 +765,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
substs, substs,
substs, substs,
)?; )?;
Ok(self.tcx().mk_const( Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty()))
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }),
c.ty(),
))
} }
_ => relate::super_relate_consts(self, c, c), _ => relate::super_relate_consts(self, c, c),
} }
@ -975,7 +972,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
}, },
}, },
); );
Ok(self.tcx().mk_const_var(new_var_id, c.ty())) Ok(self.tcx().mk_const(new_var_id, c.ty()))
} }
} }
} }
@ -988,10 +985,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
substs, substs,
)?; )?;
Ok(self.tcx().mk_const( Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty()))
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }),
c.ty(),
))
} }
_ => relate::super_relate_consts(self, c, c), _ => relate::super_relate_consts(self, c, c),
} }

View file

@ -102,7 +102,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
let index = self.const_freshen_count; let index = self.const_freshen_count;
self.const_freshen_count += 1; self.const_freshen_count += 1;
let ct = self.infcx.tcx.mk_const_infer(freshener(index), ty); let ct = self.infcx.tcx.mk_const(freshener(index), ty);
entry.insert(ct); entry.insert(ct);
ct ct
} }

View file

@ -94,13 +94,8 @@ impl<'tcx> InferCtxt<'tcx> {
})) }))
}, },
consts: &mut |bound_var: ty::BoundVar, ty| { consts: &mut |bound_var: ty::BoundVar, ty| {
self.tcx.mk_const( self.tcx
ty::ConstKind::Placeholder(ty::PlaceholderConst { .mk_const(ty::PlaceholderConst { universe: next_universe, name: bound_var }, ty)
universe: next_universe,
name: bound_var,
}),
ty,
)
}, },
}; };

View file

@ -1065,7 +1065,7 @@ impl<'tcx> InferCtxt<'tcx> {
} }
pub fn next_const_var(&self, ty: Ty<'tcx>, origin: ConstVariableOrigin) -> ty::Const<'tcx> { pub fn next_const_var(&self, ty: Ty<'tcx>, origin: ConstVariableOrigin) -> ty::Const<'tcx> {
self.tcx.mk_const_var(self.next_const_var_id(origin), ty) self.tcx.mk_const(self.next_const_var_id(origin), ty)
} }
pub fn next_const_var_in_universe( pub fn next_const_var_in_universe(
@ -1079,7 +1079,7 @@ impl<'tcx> InferCtxt<'tcx> {
.borrow_mut() .borrow_mut()
.const_unification_table() .const_unification_table()
.new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } }); .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } });
self.tcx.mk_const_var(vid, ty) self.tcx.mk_const(vid, ty)
} }
pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> { pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> {
@ -1195,7 +1195,7 @@ impl<'tcx> InferCtxt<'tcx> {
origin, origin,
val: ConstVariableValue::Unknown { universe: self.universe() }, val: ConstVariableValue::Unknown { universe: self.universe() },
}); });
self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into() self.tcx.mk_const(const_var_id, self.tcx.type_of(param.def_id)).into()
} }
} }
} }
@ -1580,7 +1580,7 @@ impl<'tcx> InferCtxt<'tcx> {
span: Option<Span>, span: Option<Span>,
) -> Result<ty::Const<'tcx>, ErrorHandled> { ) -> Result<ty::Const<'tcx>, ErrorHandled> {
match self.const_eval_resolve(param_env, unevaluated, span) { match self.const_eval_resolve(param_env, unevaluated, span) {
Ok(Some(val)) => Ok(ty::Const::from_value(self.tcx, val, ty)), Ok(Some(val)) => Ok(self.tcx.mk_const(val, ty)),
Ok(None) => { Ok(None) => {
let tcx = self.tcx; let tcx = self.tcx;
let def_id = unevaluated.def.did; let def_id = unevaluated.def.did;
@ -2049,10 +2049,10 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
bug!("const `{ct}`'s type should not reference params or types"); bug!("const `{ct}`'s type should not reference params or types");
} }
tcx.mk_const( tcx.mk_const(
ty::ConstKind::Placeholder(ty::PlaceholderConst { ty::PlaceholderConst {
universe: ty::UniverseIndex::ROOT, universe: ty::UniverseIndex::ROOT,
name: ty::BoundVar::from_usize(idx), name: ty::BoundVar::from_usize(idx),
}), },
ty, ty,
) )
.into() .into()

View file

@ -1087,7 +1087,7 @@ where
origin: var_value.origin, origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.universe }, val: ConstVariableValue::Unknown { universe: self.universe },
}); });
Ok(self.tcx().mk_const_var(new_var_id, a.ty())) Ok(self.tcx().mk_const(new_var_id, a.ty()))
} }
} }
} }

View file

@ -8,6 +8,7 @@ edition = "2021"
[dependencies] [dependencies]
bitflags = "1.2.1" bitflags = "1.2.1"
chalk-ir = "0.87.0" chalk-ir = "0.87.0"
derive_more = "0.99.17"
either = "1.5.0" either = "1.5.0"
gsgdt = "0.1.2" gsgdt = "0.1.2"
polonius-engine = "0.13.0" polonius-engine = "0.13.0"

View file

@ -2527,8 +2527,7 @@ impl<'tcx> ConstantKind<'tcx> {
let generics = tcx.generics_of(item_def_id); let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id]; let index = generics.param_def_id_to_index[&def_id];
let name = tcx.item_name(def_id); let name = tcx.item_name(def_id);
let ty_const = let ty_const = tcx.mk_const(ty::ParamConst::new(index, name), ty);
tcx.mk_const(ty::ConstKind::Param(ty::ParamConst::new(index, name)), ty);
debug!(?ty_const); debug!(?ty_const);
return Self::Ty(ty_const); return Self::Ty(ty_const);

View file

@ -76,10 +76,10 @@ impl<'tcx> Const<'tcx> {
match Self::try_eval_lit_or_param(tcx, ty, expr) { match Self::try_eval_lit_or_param(tcx, ty, expr) {
Some(v) => v, Some(v) => v,
None => tcx.mk_const( None => tcx.mk_const(
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { ty::UnevaluatedConst {
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()),
}), },
ty, ty,
), ),
} }
@ -134,18 +134,12 @@ impl<'tcx> Const<'tcx> {
let generics = tcx.generics_of(item_def_id); let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id]; let index = generics.param_def_id_to_index[&def_id];
let name = tcx.item_name(def_id); let name = tcx.item_name(def_id);
Some(tcx.mk_const(ty::ConstKind::Param(ty::ParamConst::new(index, name)), ty)) Some(tcx.mk_const(ty::ParamConst::new(index, name), ty))
} }
_ => None, _ => None,
} }
} }
/// Interns the given value as a constant.
#[inline]
pub fn from_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Self {
tcx.mk_const(ConstKind::Value(val), ty)
}
/// Panics if self.kind != ty::ConstKind::Value /// Panics if self.kind != ty::ConstKind::Value
pub fn to_valtree(self) -> ty::ValTree<'tcx> { pub fn to_valtree(self) -> ty::ValTree<'tcx> {
match self.kind() { match self.kind() {
@ -154,11 +148,6 @@ impl<'tcx> Const<'tcx> {
} }
} }
pub fn from_scalar_int(tcx: TyCtxt<'tcx>, i: ScalarInt, ty: Ty<'tcx>) -> Self {
let valtree = ty::ValTree::from_scalar_int(i);
Self::from_value(tcx, valtree, ty)
}
#[inline] #[inline]
/// Creates a constant with the given integer value and interns it. /// Creates a constant with the given integer value and interns it.
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self { pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self {
@ -166,14 +155,16 @@ impl<'tcx> Const<'tcx> {
.layout_of(ty) .layout_of(ty)
.unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e)) .unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
.size; .size;
Self::from_scalar_int(tcx, ScalarInt::try_from_uint(bits, size).unwrap(), ty.value) tcx.mk_const(
ty::ValTree::from_scalar_int(ScalarInt::try_from_uint(bits, size).unwrap()),
ty.value,
)
} }
#[inline] #[inline]
/// Creates an interned zst constant. /// Creates an interned zst constant.
pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self { pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
let valtree = ty::ValTree::zst(); tcx.mk_const(ty::ValTree::zst(), ty)
Self::from_value(tcx, valtree, ty)
} }
#[inline] #[inline]
@ -220,7 +211,7 @@ impl<'tcx> Const<'tcx> {
pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Const<'tcx> { pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Const<'tcx> {
if let Some(val) = self.kind().try_eval_for_typeck(tcx, param_env) { if let Some(val) = self.kind().try_eval_for_typeck(tcx, param_env) {
match val { match val {
Ok(val) => Const::from_value(tcx, val, self.ty()), Ok(val) => tcx.mk_const(val, self.ty()),
Err(guar) => tcx.const_error_with_guaranteed(self.ty(), guar), Err(guar) => tcx.const_error_with_guaranteed(self.ty(), guar),
} }
} else { } else {

View file

@ -49,6 +49,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
/// Represents a constant in Rust. /// Represents a constant in Rust.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
#[derive(derive_more::From)]
pub enum ConstKind<'tcx> { pub enum ConstKind<'tcx> {
/// A const generic parameter. /// A const generic parameter.
Param(ty::ParamConst), Param(ty::ParamConst),
@ -71,12 +72,19 @@ pub enum ConstKind<'tcx> {
/// A placeholder for a const which could not be computed; this is /// A placeholder for a const which could not be computed; this is
/// propagated to avoid useless error messages. /// propagated to avoid useless error messages.
#[from(ignore)]
Error(ErrorGuaranteed), Error(ErrorGuaranteed),
/// Expr which contains an expression which has partially evaluated items. /// Expr which contains an expression which has partially evaluated items.
Expr(Expr<'tcx>), Expr(Expr<'tcx>),
} }
impl<'tcx> From<ty::ConstVid<'tcx>> for ConstKind<'tcx> {
fn from(const_vid: ty::ConstVid<'tcx>) -> Self {
InferConst::Var(const_vid).into()
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
pub enum Expr<'tcx> { pub enum Expr<'tcx> {

View file

@ -17,8 +17,8 @@ use crate::traits;
use crate::ty::query::{self, TyCtxtAt}; use crate::ty::query::{self, TyCtxtAt};
use crate::ty::{ use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, FloatTy, FloatVar, FloatVid, ClosureSizeProfileData, Const, ConstS, DefIdTree, FloatTy, FloatVar, FloatVid,
GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, GenericParamDefKind, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy,
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut,
UintTy, Visibility, UintTy, Visibility,
@ -2604,13 +2604,8 @@ impl<'tcx> TyCtxt<'tcx> {
} }
#[inline] #[inline]
pub fn mk_const(self, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { pub fn mk_const(self, kind: impl Into<ty::ConstKind<'tcx>>, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const_internal(ty::ConstS { kind, ty }) self.mk_const_internal(ty::ConstS { kind: kind.into(), ty })
}
#[inline]
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstKind::Infer(InferConst::Var(v)), ty)
} }
#[inline] #[inline]
@ -2628,30 +2623,23 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(Infer(it)) self.mk_ty(Infer(it))
} }
#[inline]
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.mk_const(ty::ConstKind::Infer(ic), ty)
}
#[inline] #[inline]
pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> { pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
self.mk_ty(Param(ParamTy { index, name })) self.mk_ty(Param(ParamTy { index, name }))
} }
#[inline]
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstKind::Param(ParamConst { index, name }), ty)
}
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => { GenericParamDefKind::Lifetime => {
self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into() self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
} }
GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(), GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
GenericParamDefKind::Const { .. } => { GenericParamDefKind::Const { .. } => self
self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into() .mk_const(
} ParamConst { index: param.index, name: param.name },
self.type_of(param.def_id),
)
.into(),
} }
} }

View file

@ -1468,8 +1468,7 @@ pub trait PrettyPrinter<'tcx>:
} }
// Aggregates, printed as array/tuple/struct/variant construction syntax. // Aggregates, printed as array/tuple/struct/variant construction syntax.
(ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => { (ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => {
let contents = let contents = self.tcx().destructure_const(self.tcx().mk_const(valtree, ty));
self.tcx().destructure_const(ty::Const::from_value(self.tcx(), valtree, ty));
let fields = contents.fields.iter().copied(); let fields = contents.fields.iter().copied();
match *ty.kind() { match *ty.kind() {
ty::Array(..) => { ty::Array(..) => {

View file

@ -663,10 +663,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
au.substs, au.substs,
bu.substs, bu.substs,
)?; )?;
return Ok(tcx.mk_const( return Ok(tcx.mk_const(ty::UnevaluatedConst { def: au.def, substs }, a.ty()));
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def: au.def, substs }),
a.ty(),
));
} }
// Before calling relate on exprs, it is necessary to ensure that the nested consts // Before calling relate on exprs, it is necessary to ensure that the nested consts
// have identical types. // have identical types.

View file

@ -77,7 +77,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant { user_ty, span, literal } Constant { user_ty, span, literal }
} }
ExprKind::ConstParam { param, def_id: _ } => { ExprKind::ConstParam { param, def_id: _ } => {
let const_param = tcx.mk_const(ty::ConstKind::Param(param), expr.ty); let const_param = tcx.mk_const(param, expr.ty);
let literal = ConstantKind::Ty(const_param); let literal = ConstantKind::Ty(const_param);
Constant { user_ty: None, span, literal } Constant { user_ty: None, span, literal }

View file

@ -61,5 +61,5 @@ pub(crate) fn lit_to_const<'tcx>(
_ => return Err(LitToConstError::TypeError), _ => return Err(LitToConstError::TypeError),
}; };
Ok(ty::Const::from_value(tcx, valtree, ty)) Ok(tcx.mk_const(valtree, ty))
} }

View file

@ -799,9 +799,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
unevaluated, unevaluated,
Some(obligation.cause.span), Some(obligation.cause.span),
) { ) {
Ok(Some(valtree)) => { Ok(Some(valtree)) => Ok(selcx.tcx().mk_const(valtree, c.ty())),
Ok(ty::Const::from_value(selcx.tcx(), valtree, c.ty()))
}
Ok(None) => { Ok(None) => {
let tcx = self.tcx; let tcx = self.tcx;
let def_id = unevaluated.def.did; let def_id = unevaluated.def.did;

View file

@ -818,7 +818,7 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
let universe = self.universe_for(debruijn); let universe = self.universe_for(debruijn);
let p = ty::PlaceholderConst { universe, name: bound_const }; let p = ty::PlaceholderConst { universe, name: bound_const };
self.mapped_consts.insert(p, bound_const); self.mapped_consts.insert(p, bound_const);
self.infcx.tcx.mk_const(ty::ConstKind::Placeholder(p), ct.ty()) self.infcx.tcx.mk_const(p, ct.ty())
} }
_ => ct.super_fold_with(self), _ => ct.super_fold_with(self),
} }

View file

@ -5,7 +5,7 @@ use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
use rustc_middle::thir::visit; use rustc_middle::thir::visit;
use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::visit::Visitor;
use rustc_middle::ty::abstract_const::CastKind; use rustc_middle::ty::abstract_const::CastKind;
use rustc_middle::ty::{self, ConstKind, Expr, TyCtxt, TypeVisitable}; use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitable};
use rustc_middle::{mir, thir}; use rustc_middle::{mir, thir};
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::VariantIdx; use rustc_target::abi::VariantIdx;
@ -32,10 +32,8 @@ pub(crate) fn destructure_const<'tcx>(
let (fields, variant) = match const_.ty().kind() { let (fields, variant) = match const_.ty().kind() {
ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
// construct the consts for the elements of the array/slice // construct the consts for the elements of the array/slice
let field_consts = branches let field_consts =
.iter() branches.iter().map(|b| tcx.mk_const(*b, *inner_ty)).collect::<Vec<_>>();
.map(|b| tcx.mk_const(ty::ConstKind::Value(*b), *inner_ty))
.collect::<Vec<_>>();
debug!(?field_consts); debug!(?field_consts);
(field_consts, None) (field_consts, None)
@ -53,7 +51,7 @@ pub(crate) fn destructure_const<'tcx>(
for (field, field_valtree) in iter::zip(fields, branches) { for (field, field_valtree) in iter::zip(fields, branches) {
let field_ty = field.ty(tcx, substs); let field_ty = field.ty(tcx, substs);
let field_const = tcx.mk_const(ty::ConstKind::Value(*field_valtree), field_ty); let field_const = tcx.mk_const(*field_valtree, field_ty);
field_consts.push(field_const); field_consts.push(field_const);
} }
debug!(?field_consts); debug!(?field_consts);
@ -62,9 +60,7 @@ pub(crate) fn destructure_const<'tcx>(
} }
ty::Tuple(elem_tys) => { ty::Tuple(elem_tys) => {
let fields = iter::zip(*elem_tys, branches) let fields = iter::zip(*elem_tys, branches)
.map(|(elem_ty, elem_valtree)| { .map(|(elem_ty, elem_valtree)| tcx.mk_const(*elem_valtree, elem_ty))
tcx.mk_const(ty::ConstKind::Value(*elem_valtree), elem_ty)
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
(fields, None) (fields, None)
@ -129,17 +125,17 @@ fn recurse_build<'tcx>(
} }
&ExprKind::NonHirLiteral { lit, user_ty: _ } => { &ExprKind::NonHirLiteral { lit, user_ty: _ } => {
let val = ty::ValTree::from_scalar_int(lit); let val = ty::ValTree::from_scalar_int(lit);
ty::Const::from_value(tcx, val, node.ty) tcx.mk_const(val, node.ty)
} }
&ExprKind::ZstLiteral { user_ty: _ } => { &ExprKind::ZstLiteral { user_ty: _ } => {
let val = ty::ValTree::zst(); let val = ty::ValTree::zst();
ty::Const::from_value(tcx, val, node.ty) tcx.mk_const(val, node.ty)
} }
&ExprKind::NamedConst { def_id, substs, user_ty: _ } => { &ExprKind::NamedConst { def_id, substs, user_ty: _ } => {
let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
tcx.mk_const(ty::ConstKind::Unevaluated(uneval), node.ty) tcx.mk_const(uneval, node.ty)
} }
ExprKind::ConstParam { param, .. } => tcx.mk_const(ty::ConstKind::Param(*param), node.ty), ExprKind::ConstParam { param, .. } => tcx.mk_const(*param, node.ty),
ExprKind::Call { fun, args, .. } => { ExprKind::Call { fun, args, .. } => {
let fun = recurse_build(tcx, body, *fun, root_span)?; let fun = recurse_build(tcx, body, *fun, root_span)?;
@ -149,16 +145,16 @@ fn recurse_build<'tcx>(
new_args.push(recurse_build(tcx, body, id, root_span)?); new_args.push(recurse_build(tcx, body, id, root_span)?);
} }
let new_args = tcx.mk_const_list(new_args.iter()); let new_args = tcx.mk_const_list(new_args.iter());
tcx.mk_const(ConstKind::Expr(Expr::FunctionCall(fun, new_args)), node.ty) tcx.mk_const(Expr::FunctionCall(fun, new_args), node.ty)
} }
&ExprKind::Binary { op, lhs, rhs } if check_binop(op) => { &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => {
let lhs = recurse_build(tcx, body, lhs, root_span)?; let lhs = recurse_build(tcx, body, lhs, root_span)?;
let rhs = recurse_build(tcx, body, rhs, root_span)?; let rhs = recurse_build(tcx, body, rhs, root_span)?;
tcx.mk_const(ConstKind::Expr(Expr::Binop(op, lhs, rhs)), node.ty) tcx.mk_const(Expr::Binop(op, lhs, rhs), node.ty)
} }
&ExprKind::Unary { op, arg } if check_unop(op) => { &ExprKind::Unary { op, arg } if check_unop(op) => {
let arg = recurse_build(tcx, body, arg, root_span)?; let arg = recurse_build(tcx, body, arg, root_span)?;
tcx.mk_const(ConstKind::Expr(Expr::UnOp(op, arg)), node.ty) tcx.mk_const(Expr::UnOp(op, arg), node.ty)
} }
// This is necessary so that the following compiles: // This is necessary so that the following compiles:
// //
@ -179,11 +175,11 @@ fn recurse_build<'tcx>(
// This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested) // This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested)
&ExprKind::Use { source } => { &ExprKind::Use { source } => {
let arg = recurse_build(tcx, body, source, root_span)?; let arg = recurse_build(tcx, body, source, root_span)?;
tcx.mk_const(ConstKind::Expr(Expr::Cast(CastKind::Use, arg, node.ty)), node.ty) tcx.mk_const(Expr::Cast(CastKind::Use, arg, node.ty), node.ty)
} }
&ExprKind::Cast { source } => { &ExprKind::Cast { source } => {
let arg = recurse_build(tcx, body, source, root_span)?; let arg = recurse_build(tcx, body, source, root_span)?;
tcx.mk_const(ConstKind::Expr(Expr::Cast(CastKind::As, arg, node.ty)), node.ty) tcx.mk_const(Expr::Cast(CastKind::As, arg, node.ty), node.ty)
} }
ExprKind::Borrow { arg, .. } => { ExprKind::Borrow { arg, .. } => {
let arg_node = &body.exprs[*arg]; let arg_node = &body.exprs[*arg];

View file

@ -98,6 +98,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"chalk-ir", "chalk-ir",
"chalk-solve", "chalk-solve",
"chrono", "chrono",
"convert_case", // dependency of derive_more
"compiler_builtins", "compiler_builtins",
"cpufeatures", "cpufeatures",
"crc32fast", "crc32fast",
@ -108,6 +109,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"crypto-common", "crypto-common",
"cstr", "cstr",
"datafrog", "datafrog",
"derive_more",
"difference", "difference",
"digest", "digest",
"displaydoc", "displaydoc",