Overhaul Const.

Specifically, rename the `Const` struct as `ConstS` and re-introduce `Const` as
this:
```
pub struct Const<'tcx>(&'tcx Interned<ConstS>);
```
This now matches `Ty` and `Predicate` more closely, including using
pointer-based `eq` and `hash`.

Notable changes:
- `mk_const` now takes a `ConstS`.
- `Const` was copy, despite being 48 bytes. Now `ConstS` is not, so need a
  we need separate arena for it, because we can't use the `Dropless` one any
  more.
- Many `&'tcx Const<'tcx>`/`&Const<'tcx>` to `Const<'tcx>` changes
- Many `ct.ty` to `ct.ty()` and `ct.val` to `ct.val()` changes.
- Lots of tedious sigil fiddling.
This commit is contained in:
Nicholas Nethercote 2022-02-02 14:24:45 +11:00
parent 7eb15509ce
commit a95fb8b150
116 changed files with 654 additions and 619 deletions

View file

@ -198,7 +198,7 @@ fn check_opaque_type_parameter_valid(
GenericArgKind::Lifetime(lt) => {
matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_))
}
GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
GenericArgKind::Const(ct) => matches!(ct.val(), ty::ConstKind::Param(_)),
};
if arg_is_param {

View file

@ -77,7 +77,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
debug!(?region);
}
fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _location: Location) {
*constant = self.renumber_regions(&*constant);
fn visit_const(&mut self, constant: &mut ty::Const<'tcx>, _location: Location) {
*constant = self.renumber_regions(*constant);
}
}

View file

@ -383,7 +383,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
} else {
let tcx = self.tcx();
let maybe_uneval = match constant.literal {
ConstantKind::Ty(ct) => match ct.val {
ConstantKind::Ty(ct) => match ct.val() {
ty::ConstKind::Unevaluated(uv) => Some(uv),
_ => None,
},
@ -1956,7 +1956,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
if let Operand::Constant(constant) = op {
let maybe_uneval = match constant.literal {
ConstantKind::Ty(ct) => match ct.val {
ConstantKind::Ty(ct) => match ct.val() {
ty::ConstKind::Unevaluated(uv) => Some(uv),
_ => None,
},

View file

@ -117,7 +117,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
// We don't have to worry about the equality of consts during borrow checking
// as consts always have a static lifetime.
fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {}
fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {}
fn normalization() -> NormalizationStrategy {
NormalizationStrategy::Eager

View file

@ -668,7 +668,7 @@ fn codegen_stmt<'tcx>(
let times = fx
.monomorphize(times)
.eval(fx.tcx, ParamEnv::reveal_all())
.val
.val()
.try_to_bits(fx.tcx.data_layout.pointer_size)
.unwrap();
if operand.layout().size.bytes() == 0 {

View file

@ -46,7 +46,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
ConstantKind::Ty(ct) => ct,
ConstantKind::Val(..) => continue,
};
match const_.val {
match const_.val() {
ConstKind::Value(_) => {}
ConstKind::Unevaluated(unevaluated) => {
if let Err(err) =
@ -127,7 +127,7 @@ pub(crate) fn codegen_constant<'tcx>(
ConstantKind::Ty(ct) => ct,
ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty),
};
let const_val = match const_.val {
let const_val = match const_.val() {
ConstKind::Value(const_val) => const_val,
ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
if fx.tcx.is_static(def.did) =>
@ -135,7 +135,7 @@ pub(crate) fn codegen_constant<'tcx>(
assert!(substs.is_empty());
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(const_.ty())).to_cvalue(fx);
}
ConstKind::Unevaluated(unevaluated) => {
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
@ -152,7 +152,7 @@ pub(crate) fn codegen_constant<'tcx>(
| ConstKind::Error(_) => unreachable!("{:?}", const_),
};
codegen_const_value(fx, const_val, const_.ty)
codegen_const_value(fx, const_val, const_.ty())
}
pub(crate) fn codegen_const_value<'tcx>(
@ -465,7 +465,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
match operand {
Operand::Constant(const_) => match const_.literal {
ConstantKind::Ty(const_) => {
fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value()
fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val().try_to_value()
}
ConstantKind::Val(val, _) => Some(val),
},

View file

@ -146,7 +146,7 @@ fn push_debuginfo_type_name<'tcx>(
if cpp_like_debuginfo {
output.push_str("array$<");
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
match len.val {
match len.val() {
ty::ConstKind::Param(param) => write!(output, ",{}>", param.name).unwrap(),
_ => write!(output, ",{}>", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
.unwrap(),
@ -154,7 +154,7 @@ fn push_debuginfo_type_name<'tcx>(
} else {
output.push('[');
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
match len.val {
match len.val() {
ty::ConstKind::Param(param) => write!(output, "; {}]", param.name).unwrap(),
_ => write!(output, "; {}]", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
.unwrap(),
@ -645,19 +645,19 @@ fn push_generic_params_internal<'tcx>(
true
}
fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output: &mut String) {
match ct.val {
fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut String) {
match ct.val() {
ty::ConstKind::Param(param) => {
write!(output, "{}", param.name)
}
_ => match ct.ty.kind() {
_ => match ct.ty().kind() {
ty::Int(ity) => {
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty);
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty());
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
write!(output, "{}", val)
}
ty::Uint(_) => {
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty);
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty());
write!(output, "{}", val)
}
ty::Bool => {
@ -672,7 +672,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output:
let mut hasher = StableHasher::new();
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
ct.val.hash_stable(hcx, &mut hasher);
ct.val().hash_stable(hcx, &mut hasher);
});
});
// Let's only emit 64 bits of the hash value. That should be plenty for

View file

@ -29,7 +29,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::ConstantKind::Ty(ct) => ct,
mir::ConstantKind::Val(val, _) => return Ok(val),
};
match ct.val {
match ct.val() {
ty::ConstKind::Unevaluated(ct) => self
.cx
.tcx()
@ -61,11 +61,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let c = ty::Const::from_value(bx.tcx(), val, ty);
let values: Vec<_> = bx
.tcx()
.destructure_const(ty::ParamEnv::reveal_all().and(&c))
.destructure_const(ty::ParamEnv::reveal_all().and(c))
.fields
.iter()
.map(|field| {
if let Some(prim) = field.val.try_to_scalar() {
if let Some(prim) = field.val().try_to_scalar() {
let layout = bx.layout_of(field_ty);
let scalar = match layout.abi {
Abi::Scalar(x) => x,
@ -78,7 +78,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
})
.collect();
let llval = bx.const_struct(&values, false);
(llval, c.ty)
(llval, c.ty())
})
.unwrap_or_else(|_| {
bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time");

View file

@ -139,14 +139,14 @@ fn const_to_valtree_inner<'tcx>(
pub(crate) fn destructure_const<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
val: &'tcx ty::Const<'tcx>,
val: ty::Const<'tcx>,
) -> mir::DestructuredConst<'tcx> {
trace!("destructure_const: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let op = ecx.const_to_op(val, None).unwrap();
// We go to `usize` as we cannot allocate anything bigger anyway.
let (field_count, variant, down) = match val.ty.kind() {
let (field_count, variant, down) = match val.ty().kind() {
ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
ty::Adt(def, _) if def.variants.is_empty() => {
return mir::DestructuredConst { variant: None, fields: &[] };
@ -173,8 +173,8 @@ pub(crate) fn destructure_const<'tcx>(
pub(crate) fn deref_const<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
val: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
val: ty::Const<'tcx>,
) -> ty::Const<'tcx> {
trace!("deref_const: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let op = ecx.const_to_op(val, None).unwrap();
@ -203,5 +203,5 @@ pub(crate) fn deref_const<'tcx>(
},
};
tcx.mk_const(ty::Const { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty })
tcx.mk_const(ty::ConstS { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty })
}

View file

@ -68,7 +68,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
}
}
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
self.pretty_print_const(ct, false)
}

View file

@ -561,10 +561,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// "universe" (param_env).
pub fn const_to_op(
&self,
val: &ty::Const<'tcx>,
val: ty::Const<'tcx>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
match val.val {
match val.val() {
ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)),
ty::ConstKind::Unevaluated(uv) => {
@ -574,7 +574,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => {
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", val)
}
ty::ConstKind::Value(val_val) => self.const_val_to_op(val_val, val.ty, layout),
ty::ConstKind::Value(val_val) => self.const_val_to_op(val_val, val.ty(), layout),
}
}
@ -584,7 +584,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
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),
}
}

View file

@ -55,7 +55,7 @@ where
assert!(matches!(ty.kind(), ty::Param(_)))
}
ty::subst::GenericArgKind::Const(ct) => {
assert!(matches!(ct.val, ty::ConstKind::Param(_)))
assert!(matches!(ct.val(), ty::ConstKind::Param(_)))
}
ty::subst::GenericArgKind::Lifetime(..) => (),
},
@ -68,8 +68,8 @@ where
}
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match c.val {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match c.val() {
ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
_ => c.super_visit_with(self),
}

View file

@ -355,7 +355,7 @@ where
// Check the qualifs of the value of `const` items.
if let Some(ct) = constant.literal.const_for_ty() {
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val {
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val() {
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
// check performed after the promotion. Verify that with an assertion.

View file

@ -839,7 +839,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
span,
user_ty: None,
literal: tcx
.mk_const(ty::Const {
.mk_const(ty::ConstS {
ty,
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def,

View file

@ -299,7 +299,7 @@ impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
}
}
impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
fn to_trace(
_: TyCtxt<'tcx>,
cause: &ObligationCause<'tcx>,

View file

@ -475,8 +475,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match ct.val {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
debug!("canonical: const var found with vid {:?}", vid);
match self.infcx.probe_const_var(vid) {
@ -493,7 +493,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
ui = ty::UniverseIndex::ROOT;
}
return self.canonicalize_const_var(
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty) },
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty()) },
ct,
);
}
@ -769,17 +769,17 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
fn canonicalize_const_var(
&mut self,
info: CanonicalVarInfo<'tcx>,
const_var: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
const_var: ty::Const<'tcx>,
) -> ty::Const<'tcx> {
let infcx = self.infcx;
let bound_to = infcx.shallow_resolve(const_var);
if bound_to != const_var {
self.fold_const(bound_to)
} else {
let var = self.canonical_var(info, const_var.into());
self.tcx().mk_const(ty::Const {
self.tcx().mk_const(ty::ConstS {
val: ty::ConstKind::Bound(self.binder_index, var),
ty: self.fold_ty(const_var.ty),
ty: self.fold_ty(const_var.ty()),
})
}
}

View file

@ -149,7 +149,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name };
self.tcx
.mk_const(ty::Const {
.mk_const(ty::ConstS {
val: ty::ConstKind::Placeholder(placeholder_mapped),
ty: name.ty,
})

View file

@ -437,12 +437,12 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
}
}
GenericArgKind::Const(result_value) => {
if let ty::Const { val: ty::ConstKind::Bound(debrujin, b), .. } = result_value {
if let ty::ConstKind::Bound(debrujin, b) = result_value.val() {
// ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(*debrujin, ty::INNERMOST);
opt_values[*b] = Some(*original_value);
assert_eq!(debrujin, ty::INNERMOST);
opt_values[b] = Some(*original_value);
}
}
}
@ -670,7 +670,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
});
}
fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {
fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {
span_bug!(
self.cause.span(self.infcx.tcx),
"generic_const_exprs: unreachable `const_equate`"

View file

@ -123,9 +123,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
pub fn super_combine_consts<R>(
&self,
relation: &mut R,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>>
where
R: ConstEquateRelation<'tcx>,
{
@ -139,7 +139,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
let a_is_expected = relation.a_is_expected();
match (a.val, b.val) {
match (a.val(), b.val()) {
(
ty::ConstKind::Infer(InferConst::Var(a_vid)),
ty::ConstKind::Infer(InferConst::Var(b_vid)),
@ -226,9 +226,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
&self,
param_env: ty::ParamEnv<'tcx>,
target_vid: ty::ConstVid<'tcx>,
ct: &'tcx ty::Const<'tcx>,
ct: ty::Const<'tcx>,
vid_is_expected: bool,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
) -> RelateResult<'tcx, ty::Const<'tcx>> {
let (for_universe, span) = {
let mut inner = self.inner.borrow_mut();
let variable_table = &mut inner.const_unification_table();
@ -451,8 +451,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
pub fn add_const_equate_obligation(
&mut self,
a_is_expected: bool,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) {
let predicate = if a_is_expected {
ty::PredicateKind::ConstEquate(a, b)
@ -716,12 +716,12 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
fn consts(
&mut self,
c: &'tcx ty::Const<'tcx>,
c2: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
c: ty::Const<'tcx>,
c2: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
match c.val {
match c.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
let mut inner = self.infcx.inner.borrow_mut();
let variable_table = &mut inner.const_unification_table();
@ -739,7 +739,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.for_universe },
});
Ok(self.tcx().mk_const_var(new_var_id, c.ty))
Ok(self.tcx().mk_const_var(new_var_id, c.ty()))
}
}
}
@ -754,8 +754,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
substs,
substs,
)?;
Ok(self.tcx().mk_const(ty::Const {
ty: c.ty,
Ok(self.tcx().mk_const(ty::ConstS {
ty: c.ty(),
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
}))
}
@ -768,7 +768,7 @@ pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> {
/// Register an obligation that both constants must be equal to each other.
///
/// If they aren't equal then the relation doesn't hold.
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
}
pub trait RelateResultCompare<'tcx, T> {
@ -788,7 +788,7 @@ impl<'tcx, T: Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'
pub fn const_unification_error<'tcx>(
a_is_expected: bool,
(a, b): (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>),
(a, b): (ty::Const<'tcx>, ty::Const<'tcx>),
) -> TypeError<'tcx> {
TypeError::ConstMismatch(ExpectedFound::new(a_is_expected, a, b))
}
@ -945,13 +945,13 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
#[tracing::instrument(level = "debug", skip(self))]
fn consts(
&mut self,
c: &'tcx ty::Const<'tcx>,
_c: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
c: ty::Const<'tcx>,
_c: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug_assert_eq!(c, _c);
debug!("ConstInferUnifier: c={:?}", c);
match c.val {
match c.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
// Check if the current unification would end up
// unifying `target_vid` with a const which contains
@ -985,7 +985,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
},
},
);
Ok(self.tcx().mk_const_var(new_var_id, c.ty))
Ok(self.tcx().mk_const_var(new_var_id, c.ty()))
}
}
}
@ -1000,8 +1000,8 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
substs,
substs,
)?;
Ok(self.tcx().mk_const(ty::Const {
ty: c.ty,
Ok(self.tcx().mk_const(ty::ConstS {
ty: c.ty(),
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
}))
}

View file

@ -117,9 +117,9 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -143,7 +143,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
}
impl<'tcx> ConstEquateRelation<'tcx> for Equate<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -515,7 +515,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Err(NonTrivialPath)
}
fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
Err(NonTrivialPath)
}

View file

@ -409,7 +409,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
GenericArgKind::Const(ct) => {
match ct.val {
match ct.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
let origin = self
.inner
@ -459,7 +459,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
_ => {}
},
GenericArgKind::Const(c) => match c.val {
GenericArgKind::Const(c) => match c.val() {
ty::ConstKind::Infer(InferConst::Var(_)) => {
return self.extract_inference_diagnostics_data(s, None);
}
@ -935,9 +935,9 @@ impl<'tcx> ResolvedTypeParamEraser<'tcx> {
}
/// Replace not yet inferred const params with their def name.
fn replace_infers(&self, c: &'tcx Const<'tcx>, index: u32, name: Symbol) -> &'tcx Const<'tcx> {
match c.val {
ty::ConstKind::Infer(..) => self.tcx().mk_const_param(index, name, c.ty),
fn replace_infers(&self, c: Const<'tcx>, index: u32, name: Symbol) -> Const<'tcx> {
match c.val() {
ty::ConstKind::Infer(..) => self.tcx().mk_const_param(index, name, c.ty()),
_ => c,
}
}
@ -962,7 +962,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
.map(|(subst, param)| match &(subst.unpack(), &param.kind) {
(_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst,
(crate::infer::GenericArgKind::Const(c), _) => {
self.replace_infers(c, param.index, param.name).into()
self.replace_infers(*c, param.index, param.name).into()
}
_ => subst.super_fold_with(self),
})
@ -1002,7 +1002,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
| ty::Projection(_)
| ty::Never => t.super_fold_with(self),
ty::Array(ty, c) => {
self.tcx().mk_ty(ty::Array(self.fold_ty(*ty), self.replace_infers(c, 0, sym::N)))
self.tcx().mk_ty(ty::Array(self.fold_ty(*ty), self.replace_infers(*c, 0, sym::N)))
}
// We don't want to hide type params that haven't been resolved yet.
// This would be the type that will be written out with the type param

View file

@ -46,7 +46,7 @@ pub struct TypeFreshener<'a, 'tcx> {
ty_freshen_count: u32,
const_freshen_count: u32,
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>,
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, ty::Const<'tcx>>,
keep_static: bool,
}
@ -89,11 +89,11 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
fn freshen_const<F>(
&mut self,
opt_ct: Option<&'tcx ty::Const<'tcx>>,
opt_ct: Option<ty::Const<'tcx>>,
key: ty::InferConst<'tcx>,
freshener: F,
ty: Ty<'tcx>,
) -> &'tcx ty::Const<'tcx>
) -> ty::Const<'tcx>
where
F: FnOnce(u32) -> ty::InferConst<'tcx>,
{
@ -221,8 +221,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match ct.val {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val() {
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
let opt_ct = self
.infcx
@ -236,7 +236,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
opt_ct,
ty::InferConst::Var(v),
ty::InferConst::Fresh,
ct.ty,
ct.ty(),
);
}
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {

View file

@ -230,14 +230,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
r
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Infer(ty::InferConst::Var(vid)), ty } = ct {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.val() {
if self.const_vars.0.contains(&vid) {
// This variable was created during the fudging.
// Recreate it with a fresh variable here.
let idx = (vid.index - self.const_vars.0.start.index) as usize;
let origin = self.const_vars.1[idx];
self.infcx.next_const_var(*ty, origin)
self.infcx.next_const_var(ct.ty(), origin)
} else {
ct
}

View file

@ -78,9 +78,9 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -120,7 +120,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
}
impl<'tcx> ConstEquateRelation<'tcx> for Glb<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -94,7 +94,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};
let fld_c = |bound_var: ty::BoundVar, ty| {
self.tcx.mk_const(ty::Const {
self.tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Placeholder(ty::PlaceholderConst {
universe: next_universe,
name: ty::BoundConst { var: bound_var, ty },

View file

@ -78,9 +78,9 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -103,7 +103,7 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
}
impl<'tcx> ConstEquateRelation<'tcx> for Lub<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -1079,11 +1079,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.mk_ty_var(vid)
}
pub fn next_const_var(
&self,
ty: Ty<'tcx>,
origin: ConstVariableOrigin,
) -> &'tcx 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)
}
@ -1092,7 +1088,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
origin: ConstVariableOrigin,
universe: ty::UniverseIndex,
) -> &'tcx ty::Const<'tcx> {
) -> ty::Const<'tcx> {
let vid = self
.inner
.borrow_mut()
@ -1435,7 +1431,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn probe_const_var(
&self,
vid: ty::ConstVid<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex> {
) -> Result<ty::Const<'tcx>, ty::UniverseIndex> {
match self.inner.borrow_mut().const_unification_table().probe_value(vid).val {
ConstVariableValue::Known { value } => Ok(value),
ConstVariableValue::Unknown { universe } => Err(universe),
@ -1501,8 +1497,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn report_mismatched_consts(
&self,
cause: &ObligationCause<'tcx>,
expected: &'tcx ty::Const<'tcx>,
actual: &'tcx ty::Const<'tcx>,
expected: ty::Const<'tcx>,
actual: ty::Const<'tcx>,
err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx> {
let trace = TypeTrace::consts(cause, true, expected, actual);
@ -1756,8 +1752,8 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
/// Tries to extract an inference variable from a constant, returns `None`
/// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
pub fn maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option<Self> {
match ct.val {
pub fn maybe_from_const(ct: ty::Const<'tcx>) -> Option<Self> {
match ct.val() {
ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
_ => None,
}
@ -1777,13 +1773,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
self.infcx.shallow_resolve_ty(ty)
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val() {
self.infcx
.inner
.borrow_mut()
.const_unification_table()
.probe_value(*vid)
.probe_value(vid)
.val
.known()
.unwrap_or(ct)
@ -1813,8 +1809,8 @@ impl<'tcx> TypeTrace<'tcx> {
pub fn consts(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),

View file

@ -87,7 +87,7 @@ pub trait TypeRelatingDelegate<'tcx> {
info: ty::VarianceDiagInfo<'tcx>,
);
fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
/// Creates a new universe index. Used when instantiating placeholders.
fn create_next_universe(&mut self) -> ty::UniverseIndex;
@ -609,16 +609,16 @@ where
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
mut b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
mut b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
let a = self.infcx.shallow_resolve(a);
if !D::forbid_inference_vars() {
b = self.infcx.shallow_resolve(b);
}
match b.val {
match b.val() {
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
// Forbid inference variables in the RHS.
bug!("unexpected inference var {:?}", b)
@ -745,7 +745,7 @@ impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D>
where
D: TypeRelatingDelegate<'tcx>,
{
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.delegate.const_equate(a, b);
}
}
@ -992,10 +992,10 @@ where
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
_: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
match a.val {
a: ty::Const<'tcx>,
_: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
match a.val() {
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
bug!("unexpected inference variable encountered in NLL generalization: {:?}", a);
}
@ -1010,7 +1010,7 @@ where
origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.universe },
});
Ok(self.tcx().mk_const_var(new_var_id, a.ty))
Ok(self.tcx().mk_const_var(new_var_id, a.ty()))
}
}
}

View file

@ -39,7 +39,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
fn fold_const(&mut self, ct: Const<'tcx>) -> Const<'tcx> {
if !ct.has_infer_types_or_consts() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
@ -98,7 +98,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if !ct.has_infer_regions() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
@ -218,15 +218,12 @@ impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
}
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
if !c.needs_infer() {
Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
let c = self.infcx.shallow_resolve(c);
match c.val {
match c.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
return Err(FixupError::UnresolvedConst(vid));
}

View file

@ -151,9 +151,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -170,7 +170,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
}
impl<'tcx> ConstEquateRelation<'tcx> for Sub<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -101,7 +101,7 @@ pub enum FulfillmentErrorCode<'tcx> {
CodeSelectionError(SelectionError<'tcx>),
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
CodeConstEquateError(ExpectedFound<&'tcx Const<'tcx>>, TypeError<'tcx>),
CodeConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>),
CodeAmbiguity,
}

View file

@ -2895,7 +2895,7 @@ impl ClashingExternDeclarations {
}
(Array(a_ty, a_const), Array(b_ty, b_const)) => {
// For arrays, we also check the constness of the type.
a_const.val == b_const.val
a_const.val() == b_const.val()
&& structurally_same_type_impl(seen_types, cx, *a_ty, *b_ty, ckind)
}
(Slice(a_ty), Slice(b_ty)) => {

View file

@ -974,7 +974,7 @@ impl<'tcx> LateContext<'tcx> {
Ok(())
}
fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
Ok(())
}

View file

@ -117,7 +117,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
thir_abstract_const => { cdata.get_thir_abstract_const(tcx, def_id.index) }
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
const_param_default => { tcx.mk_const(cdata.get_const_param_default(tcx, def_id.index)) }
const_param_default => { cdata.get_const_param_default(tcx, def_id.index) }
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }

View file

@ -89,6 +89,7 @@ macro_rules! arena_types {
// Interned types
[] tys: rustc_middle::ty::TyS<'tcx>,
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
[] consts: rustc_middle::ty::ConstS<'tcx>,
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
// since we need to allocate this type on both the `rustc_hir` arena

View file

@ -328,8 +328,8 @@ impl<'tcx> CanonicalVarValues<'tcx> {
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
}
GenericArgKind::Const(ct) => tcx
.mk_const(ty::Const {
ty: ct.ty,
.mk_const(ty::ConstS {
ty: ct.ty(),
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
})
.into(),

View file

@ -95,14 +95,14 @@ pub enum ConstVariableOriginKind {
#[derive(Copy, Clone, Debug)]
pub enum ConstVariableValue<'tcx> {
Known { value: &'tcx ty::Const<'tcx> },
Known { value: ty::Const<'tcx> },
Unknown { universe: ty::UniverseIndex },
}
impl<'tcx> ConstVariableValue<'tcx> {
/// If this value is known, returns the const it is known to be.
/// Otherwise, `None`.
pub fn known(&self) -> Option<&'tcx ty::Const<'tcx>> {
pub fn known(&self) -> Option<ty::Const<'tcx>> {
match *self {
ConstVariableValue::Unknown { .. } => None,
ConstVariableValue::Known { value } => Some(value),
@ -130,7 +130,7 @@ impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
}
impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
type Error = (ty::Const<'tcx>, ty::Const<'tcx>);
fn unify_values(&value1: &Self, &value2: &Self) -> Result<Self, Self::Error> {
Ok(match (value1.val, value2.val) {
@ -162,18 +162,18 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
}
}
impl<'tcx> EqUnifyValue for &'tcx ty::Const<'tcx> {}
impl<'tcx> EqUnifyValue for ty::Const<'tcx> {}
pub fn replace_if_possible<'tcx, V, L>(
table: &mut UnificationTable<InPlace<ty::ConstVid<'tcx>, V, L>>,
c: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx>
c: ty::Const<'tcx>,
) -> ty::Const<'tcx>
where
V: snapshot_vec::VecLike<unify::Delegate<ty::ConstVid<'tcx>>>,
L: UndoLogs<snapshot_vec::UndoLog<unify::Delegate<ty::ConstVid<'tcx>>>>,
{
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = c {
match table.probe_value(*vid).val.known() {
if let ty::ConstKind::Infer(InferConst::Var(vid)) = c.val() {
match table.probe_value(vid).val.known() {
Some(c) => c,
None => c,
}

View file

@ -2185,7 +2185,7 @@ pub enum Rvalue<'tcx> {
Use(Operand<'tcx>),
/// [x; 32]
Repeat(Operand<'tcx>, &'tcx ty::Const<'tcx>),
Repeat(Operand<'tcx>, ty::Const<'tcx>),
/// &x or &mut x
Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
@ -2335,7 +2335,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
match *self {
Use(ref place) => write!(fmt, "{:?}", place),
Repeat(ref a, ref b) => {
Repeat(ref a, b) => {
write!(fmt, "[{:?}; ", a)?;
pretty_print_const(b, fmt, false)?;
write!(fmt, "]")
@ -2514,7 +2514,7 @@ pub struct Constant<'tcx> {
#[derive(Lift)]
pub enum ConstantKind<'tcx> {
/// This constant came from the type system
Ty(&'tcx ty::Const<'tcx>),
Ty(ty::Const<'tcx>),
/// This constant cannot go back into the type system, as it represents
/// something the type system cannot handle (e.g. pointers).
Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
@ -2522,7 +2522,7 @@ pub enum ConstantKind<'tcx> {
impl<'tcx> Constant<'tcx> {
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
match self.literal.const_for_ty()?.val.try_to_scalar() {
match self.literal.const_for_ty()?.val().try_to_scalar() {
Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) {
GlobalAlloc::Static(def_id) => {
assert!(!tcx.is_thread_local_static(def_id));
@ -2539,25 +2539,25 @@ impl<'tcx> Constant<'tcx> {
}
}
impl<'tcx> From<&'tcx ty::Const<'tcx>> for ConstantKind<'tcx> {
impl<'tcx> From<ty::Const<'tcx>> for ConstantKind<'tcx> {
#[inline]
fn from(ct: &'tcx ty::Const<'tcx>) -> Self {
fn from(ct: ty::Const<'tcx>) -> Self {
Self::Ty(ct)
}
}
impl<'tcx> ConstantKind<'tcx> {
/// Returns `None` if the constant is not trivially safe for use in the type system.
pub fn const_for_ty(&self) -> Option<&'tcx ty::Const<'tcx>> {
pub fn const_for_ty(&self) -> Option<ty::Const<'tcx>> {
match self {
ConstantKind::Ty(c) => Some(c),
ConstantKind::Ty(c) => Some(*c),
ConstantKind::Val(..) => None,
}
}
pub fn ty(&self) -> Ty<'tcx> {
match self {
ConstantKind::Ty(c) => c.ty,
ConstantKind::Ty(c) => c.ty(),
ConstantKind::Val(_, ty) => *ty,
}
}
@ -2565,7 +2565,7 @@ impl<'tcx> ConstantKind<'tcx> {
#[inline]
pub fn try_to_value(self) -> Option<interpret::ConstValue<'tcx>> {
match self {
ConstantKind::Ty(c) => c.val.try_to_value(),
ConstantKind::Ty(c) => c.val().try_to_value(),
ConstantKind::Val(val, _) => Some(val),
}
}
@ -2829,7 +2829,7 @@ impl<'tcx> Display for ConstantKind<'tcx> {
}
fn pretty_print_const<'tcx>(
c: &ty::Const<'tcx>,
c: ty::Const<'tcx>,
fmt: &mut Formatter<'_>,
print_types: bool,
) -> fmt::Result {

View file

@ -462,10 +462,11 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
}
}
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
fn visit_const(&mut self, constant: ty::Const<'tcx>, _: Location) {
self.super_const(constant);
let ty::Const { ty, val, .. } = constant;
if use_verbose(*ty, false) {
let ty = constant.ty();
let val = constant.val();
if use_verbose(ty, false) {
self.push("ty::Const");
self.push(&format!("+ ty: {:?}", ty));
let val = match val {
@ -683,8 +684,8 @@ pub fn write_allocations<'tcx>(
}
struct CollectAllocIds(BTreeSet<AllocId>);
impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds {
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val() {
self.0.extend(alloc_ids_from_const(val));
}
c.super_visit_with(self)

View file

@ -387,7 +387,7 @@ pub enum ClosureOutlivesSubject<'tcx> {
#[derive(Copy, Clone, Debug, HashStable)]
pub struct DestructuredConst<'tcx> {
pub variant: Option<VariantIdx>,
pub fields: &'tcx [&'tcx ty::Const<'tcx>],
pub fields: &'tcx [ty::Const<'tcx>],
}
/// Coverage information summarized from a MIR if instrumented for source code coverage (see

View file

@ -200,7 +200,7 @@ macro_rules! make_mir_visitor {
}
fn visit_const(&mut self,
constant: & $($mutability)? &'tcx ty::Const<'tcx>,
constant: $(& $mutability)? ty::Const<'tcx>,
_: Location) {
self.super_const(constant);
}
@ -864,7 +864,7 @@ macro_rules! make_mir_visitor {
self.visit_span(span);
drop(user_ty); // no visit method for this
match literal {
ConstantKind::Ty(ct) => self.visit_const(ct, location),
ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location),
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
}
}
@ -903,7 +903,7 @@ macro_rules! make_mir_visitor {
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
}
fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) {
fn super_const(&mut self, _const: $(& $mutability)? ty::Const<'tcx>) {
}
fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {

View file

@ -113,7 +113,7 @@ rustc_queries! {
/// Given the def_id of a const-generic parameter, computes the associated default const
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> {
query const_param_default(param: DefId) -> ty::Const<'tcx> {
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
separate_provide_extern
}
@ -926,7 +926,7 @@ rustc_queries! {
/// Destructure a constant ADT or array into its variant index and its
/// field values.
query destructure_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> mir::DestructuredConst<'tcx> {
desc { "destructure constant" }
remap_env_constness
@ -935,8 +935,8 @@ rustc_queries! {
/// Dereference a constant reference or raw pointer and turn the result into a constant
/// again.
query deref_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
) -> &'tcx ty::Const<'tcx> {
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> ty::Const<'tcx> {
desc { "deref constant" }
remap_env_constness
}
@ -947,7 +947,7 @@ rustc_queries! {
query lit_to_const(
key: LitToConstInput<'tcx>
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
) -> Result<ty::Const<'tcx>, LitToConstError> {
desc { "converting literal to const" }
}

View file

@ -368,12 +368,12 @@ pub enum ExprKind<'tcx> {
},
/// An inline `const` block, e.g. `const {}`.
ConstBlock {
value: &'tcx Const<'tcx>,
value: Const<'tcx>,
},
/// An array literal constructed from one repeated element, e.g. `[1; 5]`.
Repeat {
value: ExprId,
count: &'tcx Const<'tcx>,
count: Const<'tcx>,
},
/// An array, e.g. `[a, b, c, d]`.
Array {
@ -407,7 +407,7 @@ pub enum ExprKind<'tcx> {
},
/// A literal.
Literal {
literal: &'tcx Const<'tcx>,
literal: Const<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
/// The `DefId` of the `const` item this literal
/// was produced from, if this is not a user-written
@ -419,7 +419,7 @@ pub enum ExprKind<'tcx> {
/// This is only distinguished from `Literal` so that we can register some
/// info for diagnostics.
StaticRef {
literal: &'tcx Const<'tcx>,
literal: Const<'tcx>,
def_id: DefId,
},
/// Inline assembly, i.e. `asm!()`.
@ -501,7 +501,7 @@ pub enum InlineAsmOperand<'tcx> {
out_expr: Option<ExprId>,
},
Const {
value: &'tcx Const<'tcx>,
value: Const<'tcx>,
span: Span,
},
SymFn {
@ -640,7 +640,7 @@ pub enum PatKind<'tcx> {
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
/// `PartialEq` and `Eq`.
Constant {
value: &'tcx ty::Const<'tcx>,
value: ty::Const<'tcx>,
},
Range(PatRange<'tcx>),
@ -670,8 +670,8 @@ pub enum PatKind<'tcx> {
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
pub struct PatRange<'tcx> {
pub lo: &'tcx ty::Const<'tcx>,
pub hi: &'tcx ty::Const<'tcx>,
pub lo: ty::Const<'tcx>,
pub hi: ty::Const<'tcx>,
pub end: RangeEnd,
}

View file

@ -22,7 +22,7 @@ pub enum CastKind {
/// A node of an `AbstractConst`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
pub enum Node<'tcx> {
Leaf(&'tcx ty::Const<'tcx>),
Leaf(ty::Const<'tcx>),
Binop(mir::BinOp, NodeId, NodeId),
UnaryOp(mir::UnOp, NodeId),
FunctionCall(NodeId, &'tcx [NodeId]),

View file

@ -26,7 +26,7 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized {
walk_pat(self, pat);
}
fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
fn visit_const(&mut self, _cnst: Const<'tcx>) {}
}
pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
@ -209,7 +209,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
visitor.visit_pat(&subpattern.pattern);
}
}
Constant { value } => visitor.visit_const(value),
Constant { value } => visitor.visit_const(*value),
Range(range) => {
visitor.visit_const(range.lo);
visitor.visit_const(range.hi);

View file

@ -88,21 +88,21 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b {
return Ok(a);
}
match (a.val, b.val) {
match (a.val(), b.val()) {
(_, ty::ConstKind::Infer(InferConst::Fresh(_))) => {
return Ok(a);
}
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b)));
}
_ => {}

View file

@ -144,6 +144,12 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Region<'tcx> {
}
}
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Const<'tcx> {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
self.0.0.encode(e)
}
}
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
e.encode_alloc_id(self)
@ -335,8 +341,8 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> &'tcx Self {
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> Self {
decoder.tcx().mk_const(Decodable::decode(decoder))
}
}

View file

@ -4,10 +4,12 @@ use crate::ty::{
self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty,
TyCtxt, TypeFoldable,
};
use rustc_data_structures::intern::Interned;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::HashStable;
use std::fmt;
mod int;
mod kind;
@ -17,22 +19,42 @@ pub use int::*;
pub use kind::*;
pub use valtree::*;
/// Typed constant value.
#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
#[derive(HashStable)]
pub struct Const<'tcx> {
pub ty: Ty<'tcx>,
/// Use this rather than `ConstS`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
pub struct Const<'tcx>(pub Interned<'tcx, ConstS<'tcx>>);
impl<'tcx> fmt::Debug for Const<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// This reflects what `Const` looked liked before `Interned` was
// introduced. We print it like this to avoid having to update expected
// output in a lot of tests.
write!(f, "Const {{ ty: {:?}, val: {:?} }}", self.ty(), self.val())
}
}
/// Typed constant value.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)]
pub struct ConstS<'tcx> {
pub ty: Ty<'tcx>,
pub val: ConstKind<'tcx>,
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Const<'_>, 48);
static_assert_size!(ConstS<'_>, 48);
impl<'tcx> Const<'tcx> {
pub fn ty(self) -> Ty<'tcx> {
self.0.ty
}
pub fn val(self) -> ConstKind<'tcx> {
self.0.val
}
/// Literals and const generic parameters are eagerly converted to a constant, everything else
/// becomes `Unevaluated`.
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
}
@ -40,7 +62,7 @@ impl<'tcx> Const<'tcx> {
pub fn from_opt_const_arg_anon_const(
tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<LocalDefId>,
) -> &'tcx Self {
) -> Self {
debug!("Const::from_anon_const(def={:?})", def);
let body_id = match tcx.hir().get_by_def_id(def.did) {
@ -58,7 +80,7 @@ impl<'tcx> Const<'tcx> {
match Self::try_eval_lit_or_param(tcx, ty, expr) {
Some(v) => v,
None => tcx.mk_const(ty::Const {
None => tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
@ -74,7 +96,7 @@ impl<'tcx> Const<'tcx> {
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
) -> Option<&'tcx Self> {
) -> Option<Self> {
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
let expr = match &expr.kind {
@ -120,7 +142,7 @@ impl<'tcx> Const<'tcx> {
let generics = tcx.generics_of(item_def_id.to_def_id());
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.hir().name(hir_id);
Some(tcx.mk_const(ty::Const {
Some(tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
ty,
}))
@ -129,7 +151,7 @@ impl<'tcx> Const<'tcx> {
}
}
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
debug!("Const::from_inline_const(def_id={:?})", def_id);
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
@ -155,7 +177,7 @@ impl<'tcx> Const<'tcx> {
let substs =
InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty })
.substs;
tcx.mk_const(ty::Const {
tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: ty::WithOptConstParam::unknown(def_id).to_global(),
substs,
@ -171,19 +193,19 @@ impl<'tcx> Const<'tcx> {
/// Interns the given value as a constant.
#[inline]
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
tcx.mk_const(Self { val: ConstKind::Value(val), ty })
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> Self {
tcx.mk_const(ConstS { val: ConstKind::Value(val), ty })
}
#[inline]
/// Interns the given scalar as a constant.
pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> Self {
Self::from_value(tcx, ConstValue::Scalar(val), ty)
}
#[inline]
/// 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>>) -> &'tcx Self {
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self {
let size = tcx
.layout_of(ty)
.unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
@ -193,19 +215,19 @@ impl<'tcx> Const<'tcx> {
#[inline]
/// Creates an interned zst constant.
pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
Self::from_scalar(tcx, Scalar::ZST, ty)
}
#[inline]
/// Creates an interned bool constant.
pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> &'tcx Self {
pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self {
Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
}
#[inline]
/// Creates an interned usize constant.
pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> &'tcx Self {
pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
}
@ -214,35 +236,35 @@ impl<'tcx> Const<'tcx> {
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
/// contains const generic parameters or pointers).
pub fn try_eval_bits(
&self,
self,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Option<u128> {
assert_eq!(self.ty, ty);
assert_eq!(self.ty(), ty);
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
// if `ty` does not depend on generic parameters, use an empty param_env
self.val.eval(tcx, param_env).try_to_bits(size)
self.val().eval(tcx, param_env).try_to_bits(size)
}
#[inline]
pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
self.val.eval(tcx, param_env).try_to_bool()
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
self.val().eval(tcx, param_env).try_to_bool()
}
#[inline]
pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
self.val.eval(tcx, param_env).try_to_machine_usize(tcx)
pub fn try_eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
self.val().eval(tcx, param_env).try_to_machine_usize(tcx)
}
#[inline]
/// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
/// unevaluated constant.
pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
if let Some(val) = self.val.try_eval(tcx, param_env) {
pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Const<'tcx> {
if let Some(val) = self.val().try_eval(tcx, param_env) {
match val {
Ok(val) => Const::from_value(tcx, val, self.ty),
Err(ErrorReported) => tcx.const_error(self.ty),
Ok(val) => Const::from_value(tcx, val, self.ty()),
Err(ErrorReported) => tcx.const_error(self.ty()),
}
} else {
self
@ -251,20 +273,20 @@ impl<'tcx> Const<'tcx> {
#[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
self.try_eval_bits(tcx, param_env, ty)
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
}
#[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid `usize`.
pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
pub fn eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
self.try_eval_usize(tcx, param_env)
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
}
}
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Const<'tcx> {
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Const<'tcx> {
let default_def_id = match tcx.hir().get_by_def_id(def_id.expect_local()) {
hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },

View file

@ -18,10 +18,10 @@ use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, Substs
use crate::ty::TyKind::*;
use crate::ty::{
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, RegionKind,
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
};
use rustc_ast as ast;
use rustc_attr as attr;
@ -111,7 +111,7 @@ pub struct CtxtInterners<'tcx> {
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, Const<'tcx>>,
const_: InternedSet<'tcx, ConstS<'tcx>>,
const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, Layout>,
@ -229,7 +229,7 @@ pub struct CommonLifetimes<'tcx> {
}
pub struct CommonConsts<'tcx> {
pub unit: &'tcx Const<'tcx>,
pub unit: Const<'tcx>,
}
pub struct LocalTableInContext<'a, V> {
@ -869,7 +869,7 @@ impl<'tcx> CanonicalUserType<'tcx> {
_ => false,
},
GenericArgKind::Const(ct) => match ct.val {
GenericArgKind::Const(ct) => match ct.val() {
ty::ConstKind::Bound(debruijn, b) => {
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(debruijn, ty::INNERMOST);
@ -946,11 +946,14 @@ impl<'tcx> CommonLifetimes<'tcx> {
impl<'tcx> CommonConsts<'tcx> {
fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
let mk_const =
|c| interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0;
let mk_const = |c| {
Const(Interned::new_unchecked(
interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0,
))
};
CommonConsts {
unit: mk_const(ty::Const {
unit: mk_const(ty::ConstS {
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::ZST)),
ty: types.unit,
}),
@ -1222,7 +1225,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Like [TyCtxt::ty_error] but for constants.
#[track_caller]
pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
self.const_error_with_message(
ty,
DUMMY_SP,
@ -1237,9 +1240,9 @@ impl<'tcx> TyCtxt<'tcx> {
ty: Ty<'tcx>,
span: S,
msg: &str,
) -> &'tcx Const<'tcx> {
) -> Const<'tcx> {
self.sess.delay_span_bug(span, msg);
self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
self.mk_const(ty::ConstS { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
}
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
@ -1685,7 +1688,7 @@ macro_rules! nop_list_lift {
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
nop_lift! {region; Region<'a> => Region<'tcx>}
nop_lift_old! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
nop_lift! {const_; Const<'a> => Const<'tcx>}
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
@ -2127,6 +2130,7 @@ macro_rules! direct_interners {
direct_interners! {
region: mk_region(RegionKind): Region -> Region<'tcx>,
const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
}
macro_rules! direct_interners_old {
@ -2167,7 +2171,6 @@ macro_rules! direct_interners_old {
// FIXME: eventually these should all be converted to `direct_interners`.
direct_interners_old! {
const_: mk_const(Const<'tcx>),
const_allocation: intern_const_alloc(Allocation),
layout: intern_layout(Layout),
adt_def: intern_adt_def(AdtDef),
@ -2491,8 +2494,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
}
#[inline]
@ -2511,8 +2514,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(ic), ty })
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(ic), ty })
}
#[inline]
@ -2521,8 +2524,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
}
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {

View file

@ -71,7 +71,7 @@ impl<'tcx> Ty<'tcx> {
fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool {
match arg.unpack() {
GenericArgKind::Type(ty) => ty.is_suggestable(),
GenericArgKind::Const(c) => const_is_suggestable(c.val),
GenericArgKind::Const(c) => const_is_suggestable(c.val()),
_ => true,
}
}
@ -110,7 +110,7 @@ impl<'tcx> Ty<'tcx> {
}) => {
let term_is_suggestable = match term {
Term::Ty(ty) => ty.is_suggestable(),
Term::Const(c) => const_is_suggestable(c.val),
Term::Const(c) => const_is_suggestable(c.val()),
};
term_is_suggestable && substs.iter().all(generic_arg_is_suggestible)
}
@ -120,7 +120,7 @@ impl<'tcx> Ty<'tcx> {
args.iter().all(generic_arg_is_suggestible)
}
Slice(ty) | RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => ty.is_suggestable(),
Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val),
Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val()),
_ => true,
}
}

View file

@ -60,13 +60,13 @@ pub enum TypeError<'tcx> {
/// created a cycle (because it appears somewhere within that
/// type).
CyclicTy(Ty<'tcx>),
CyclicConst(&'tcx ty::Const<'tcx>),
CyclicConst(ty::Const<'tcx>),
ProjectionMismatched(ExpectedFound<DefId>),
ExistentialMismatch(
ExpectedFound<&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>>,
),
ObjectUnsafeCoercion(DefId),
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
ConstMismatch(ExpectedFound<ty::Const<'tcx>>),
IntrinsicCast,
/// Safe `#[target_feature]` functions are not assignable to safe function pointers.
@ -255,7 +255,7 @@ impl<'tcx> Ty<'tcx> {
}
let n = tcx.lift(n).unwrap();
if let ty::ConstKind::Value(v) = n.val {
if let ty::ConstKind::Value(v) = n.val() {
if let Some(n) = v.try_to_machine_usize(tcx) {
return format!("array of {} element{}", n, pluralize!(n)).into();
}

View file

@ -28,7 +28,7 @@ impl FlagComputation {
result
}
pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
pub fn for_const(c: ty::Const<'_>) -> TypeFlags {
let mut result = FlagComputation::new();
result.add_const(c);
result.flags
@ -286,9 +286,9 @@ impl FlagComputation {
}
}
fn add_const(&mut self, c: &ty::Const<'_>) {
self.add_ty(c.ty);
match c.val {
fn add_const(&mut self, c: ty::Const<'_>) {
self.add_ty(c.ty());
match c.val() {
ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated),
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);

View file

@ -216,7 +216,7 @@ pub trait TypeFolder<'tcx>: Sized {
r.super_fold_with(self)
}
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx>
where
Self: TypeFolder<'tcx, Error = !>,
{
@ -263,10 +263,7 @@ pub trait FallibleTypeFolder<'tcx>: TypeFolder<'tcx> {
r.try_super_fold_with(self)
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
c.try_super_fold_with(self)
}
@ -306,10 +303,7 @@ where
Ok(self.fold_region(r))
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
Ok(self.fold_const(c))
}
@ -346,7 +340,7 @@ pub trait TypeVisitor<'tcx>: Sized {
r.super_visit_with(self)
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
c.super_visit_with(self)
}
@ -366,7 +360,7 @@ pub struct BottomUpFolder<'tcx, F, G, H>
where
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::Const<'tcx>) -> ty::Const<'tcx>,
{
pub tcx: TyCtxt<'tcx>,
pub ty_op: F,
@ -378,7 +372,7 @@ impl<'tcx, F, G, H> TypeFolder<'tcx> for BottomUpFolder<'tcx, F, G, H>
where
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::Const<'tcx>) -> ty::Const<'tcx>,
{
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.tcx
@ -394,7 +388,7 @@ where
(self.lt_op)(r)
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
let ct = ct.super_fold_with(self);
(self.ct_op)(ct)
}
@ -593,7 +587,7 @@ struct BoundVarReplacer<'a, 'tcx> {
fld_r: Option<&'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a)>,
fld_t: Option<&'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx> + 'a)>,
}
impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
@ -601,7 +595,7 @@ impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
fld_r: Option<&'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a)>,
fld_t: Option<&'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx> + 'a)>,
) -> Self {
BoundVarReplacer { tcx, current_index: ty::INNERMOST, fld_r, fld_t, fld_c }
}
@ -660,14 +654,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
r
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match *ct {
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
if debruijn == self.current_index =>
{
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val() {
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
if let Some(fld_c) = self.fld_c.as_mut() {
let ct = fld_c(bound_const, ty);
return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32());
let ct = fld_c(bound_const, ct.ty());
return ty::fold::shift_vars(self.tcx, ct, self.current_index.as_u32());
}
}
_ if ct.has_vars_bound_at_or_above(self.current_index) => {
@ -726,7 +718,7 @@ impl<'tcx> TyCtxt<'tcx> {
where
F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx>,
T: TypeFoldable<'tcx>,
{
if !value.has_escaping_bound_vars() {
@ -751,7 +743,7 @@ impl<'tcx> TyCtxt<'tcx> {
where
F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx>,
T: TypeFoldable<'tcx>,
{
let mut region_map = BTreeMap::new();
@ -804,7 +796,7 @@ impl<'tcx> TyCtxt<'tcx> {
))
},
|c, ty| {
self.mk_const(ty::Const {
self.mk_const(ty::ConstS {
val: ty::ConstKind::Bound(
ty::INNERMOST,
ty::BoundVar::from_usize(c.as_usize() + bound_vars),
@ -1057,13 +1049,16 @@ impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.val() {
if self.amount == 0 || debruijn < self.current_index {
ct
} else {
let debruijn = debruijn.shifted_in(self.amount);
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
self.tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Bound(debruijn, bound_ct),
ty: ct.ty(),
})
}
} else {
ct.super_fold_with(self)
@ -1165,13 +1160,13 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
}
}
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// we don't have a `visit_infer_const` callback, so we have to
// hook in here to catch this case (annoying...), but
// otherwise we do want to remember to visit the rest of the
// const, as it has types/regions embedded in a lot of other
// places.
match ct.val {
match ct.val() {
ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => {
ControlFlow::Break(FoundEscapingVars)
}
@ -1236,7 +1231,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
#[inline]
#[instrument(level = "trace")]
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = FlagComputation::for_const(c);
trace!(r.flags=?flags);
if flags.intersects(self.flags) {
@ -1325,12 +1320,12 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
t.super_visit_with(self)
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// if we are only looking for "constrained" region, we have to
// ignore the inputs of an unevaluated const, as they may not appear
// in the normalized form
if self.just_constrained {
if let ty::ConstKind::Unevaluated(..) = c.val {
if let ty::ConstKind::Unevaluated(..) = c.val() {
return ControlFlow::CONTINUE;
}
}

View file

@ -59,7 +59,9 @@ pub use self::closure::{
RootVariableMinCaptureList, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap, UpvarPath,
CAPTURE_STRUCT_LOCAL,
};
pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, Unevaluated, ValTree};
pub use self::consts::{
Const, ConstInt, ConstKind, ConstS, InferConst, ScalarInt, Unevaluated, ValTree,
};
pub use self::context::{
tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt,
@ -592,7 +594,7 @@ pub enum PredicateKind<'tcx> {
ConstEvaluatable(ty::Unevaluated<'tcx, ()>),
/// Constants must be equal. The first component is the const that is expected.
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
ConstEquate(Const<'tcx>, Const<'tcx>),
/// Represents a type found in the environment that we can use for implied bounds.
///
@ -818,7 +820,7 @@ pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
#[derive(HashStable, TypeFoldable)]
pub enum Term<'tcx> {
Ty(Ty<'tcx>),
Const(&'tcx Const<'tcx>),
Const(Const<'tcx>),
}
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
@ -827,8 +829,8 @@ impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
}
}
impl<'tcx> From<&'tcx Const<'tcx>> for Term<'tcx> {
fn from(c: &'tcx Const<'tcx>) -> Self {
impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
fn from(c: Const<'tcx>) -> Self {
Term::Const(c)
}
}
@ -837,8 +839,8 @@ impl<'tcx> Term<'tcx> {
pub fn ty(&self) -> Option<Ty<'tcx>> {
if let Term::Ty(ty) = self { Some(*ty) } else { None }
}
pub fn ct(&self) -> Option<&'tcx Const<'tcx>> {
if let Term::Const(c) = self { Some(c) } else { None }
pub fn ct(&self) -> Option<Const<'tcx>> {
if let Term::Const(c) = self { Some(*c) } else { None }
}
}

View file

@ -192,7 +192,7 @@ impl<'tcx> TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()
}
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const()
}
@ -244,13 +244,10 @@ impl<'tcx> FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'t
}
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
match self.try_normalize_generic_arg_after_erasing_regions(c.into()) {
Ok(t) => Ok(t.expect_const()),
Err(_) => Err(NormalizationError::Const(*c)),
Err(_) => Err(NormalizationError::Const(c)),
}
}

View file

@ -66,7 +66,7 @@ pub trait Printer<'tcx>: Sized {
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
) -> Result<Self::DynExistential, Self::Error>;
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error>;
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error>;
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error>;
@ -352,10 +352,10 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P>
}
}
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::Const<'tcx> {
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> {
type Output = P::Const;
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_const(self)
cx.print_const(*self)
}
}

View file

@ -754,14 +754,14 @@ pub trait PrettyPrinter<'tcx>:
p!("[", print(ty), "; ");
if self.tcx().sess.verbose() {
p!(write("{:?}", sz));
} else if let ty::ConstKind::Unevaluated(..) = sz.val {
} else if let ty::ConstKind::Unevaluated(..) = sz.val() {
// Do not try to evaluate unevaluated constants. If we are const evaluating an
// array length anon const, rustc will (with debug assertions) print the
// constant's path. Which will end up here again.
p!("_");
} else if let Some(n) = sz.val.try_to_bits(self.tcx().data_layout.pointer_size) {
} else if let Some(n) = sz.val().try_to_bits(self.tcx().data_layout.pointer_size) {
p!(write("{}", n));
} else if let ty::ConstKind::Param(param) = sz.val {
} else if let ty::ConstKind::Param(param) = sz.val() {
p!(write("{}", param));
} else {
p!("_");
@ -1148,13 +1148,13 @@ pub trait PrettyPrinter<'tcx>:
fn pretty_print_const(
mut self,
ct: &'tcx ty::Const<'tcx>,
ct: ty::Const<'tcx>,
print_ty: bool,
) -> Result<Self::Const, Self::Error> {
define_scoped_cx!(self);
if self.tcx().sess.verbose() {
p!(write("Const({:?}: {:?})", ct.val, ct.ty));
p!(write("Const({:?}: {:?})", ct.val(), ct.ty()));
return Ok(self);
}
@ -1166,7 +1166,7 @@ pub trait PrettyPrinter<'tcx>:
write!(this, "_")?;
Ok(this)
},
|this| this.print_type(ct.ty),
|this| this.print_type(ct.ty()),
": ",
)?;
} else {
@ -1175,7 +1175,7 @@ pub trait PrettyPrinter<'tcx>:
}};
}
match ct.val {
match ct.val() {
ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
substs,
@ -1206,7 +1206,7 @@ pub trait PrettyPrinter<'tcx>:
ty::ConstKind::Infer(..) => print_underscore!(),
ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
ty::ConstKind::Value(value) => {
return self.pretty_print_const_value(value, ct.ty, print_ty);
return self.pretty_print_const_value(value, ct.ty(), print_ty);
}
ty::ConstKind::Bound(debruijn, bound_var) => {
@ -1248,10 +1248,13 @@ pub trait PrettyPrinter<'tcx>:
kind:
ty::Array(
Ty(Interned(ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, _)),
ty::Const {
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
..
},
ty::Const(Interned(
ty::ConstS {
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
..
},
_,
)),
),
..
},
@ -1435,7 +1438,7 @@ pub trait PrettyPrinter<'tcx>:
Ok(self)
}
(ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => {
let n = n.val.try_to_bits(self.tcx().data_layout.pointer_size).unwrap();
let n = n.val().try_to_bits(self.tcx().data_layout.pointer_size).unwrap();
// cast is ok because we already checked for pointer size (32 or 64 bit) above
let range = AllocRange { start: offset, size: Size::from_bytes(n) };
@ -1456,10 +1459,10 @@ pub trait PrettyPrinter<'tcx>:
// FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
// correct `ty::ParamEnv` to allow printing *all* constant values.
(_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
let contents = self.tcx().destructure_const(
ty::ParamEnv::reveal_all()
.and(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(ct), ty })),
);
let contents =
self.tcx().destructure_const(ty::ParamEnv::reveal_all().and(
self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty }),
));
let fields = contents.fields.iter().copied();
match *ty.kind() {
@ -1717,7 +1720,7 @@ impl<'tcx, F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
self.pretty_print_dyn_existential(predicates)
}
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
self.pretty_print_const(ct, true)
}
@ -2454,7 +2457,7 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
forward_display_to_print! {
Ty<'tcx>,
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
&'tcx ty::Const<'tcx>,
ty::Const<'tcx>,
// HACK(eddyb) these are exhaustive instead of generic,
// because `for<'tcx>` isn't possible yet.

View file

@ -89,9 +89,9 @@ pub trait TypeRelation<'tcx>: Sized {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>;
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>>;
fn binders<T>(
&mut self,
@ -545,16 +545,16 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
/// it.
pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
let tcx = relation.tcx();
// FIXME(oli-obk): once const generics can have generic types, this assertion
// will likely get triggered. Move to `normalize_erasing_regions` at that point.
let a_ty = tcx.erase_regions(a.ty);
let b_ty = tcx.erase_regions(b.ty);
let a_ty = tcx.erase_regions(a.ty());
let b_ty = tcx.erase_regions(b.ty());
if a_ty != b_ty {
relation.tcx().sess.delay_span_bug(
DUMMY_SP,
@ -562,14 +562,14 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
);
}
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| x.eval(tcx, relation.param_env());
let eagerly_eval = |x: ty::Const<'tcx>| x.eval(tcx, relation.param_env());
let a = eagerly_eval(a);
let b = eagerly_eval(b);
// Currently, the values that can be unified are primitive types,
// and those that derive both `PartialEq` and `Eq`, corresponding
// to structural-match types.
let is_match = match (a.val, b.val) {
let is_match = match (a.val(), b.val()) {
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
// The caller should handle these cases!
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
@ -602,13 +602,13 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
au.substs,
bu.substs,
)?;
return Ok(tcx.mk_const(ty::Const {
return Ok(tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: au.def,
substs,
promoted: au.promoted,
}),
ty: a.ty,
ty: a.ty(),
}));
}
_ => false,
@ -621,8 +621,8 @@ fn check_const_value_eq<'tcx, R: TypeRelation<'tcx>>(
a_val: ConstValue<'tcx>,
b_val: ConstValue<'tcx>,
// FIXME(oli-obk): these arguments should go away with valtrees
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
// FIXME(oli-obk): this should just be `bool` with valtrees
) -> RelateResult<'tcx, bool> {
let tcx = relation.tcx();
@ -648,9 +648,9 @@ fn check_const_value_eq<'tcx, R: TypeRelation<'tcx>>(
}
(ConstValue::ByRef { alloc: alloc_a, .. }, ConstValue::ByRef { alloc: alloc_b, .. })
if a.ty.is_ref() || b.ty.is_ref() =>
if a.ty().is_ref() || b.ty().is_ref() =>
{
if a.ty.is_ref() && b.ty.is_ref() {
if a.ty().is_ref() && b.ty().is_ref() {
alloc_a == alloc_b
} else {
false
@ -663,7 +663,7 @@ fn check_const_value_eq<'tcx, R: TypeRelation<'tcx>>(
// Both the variant and each field have to be equal.
if a_destructured.variant == b_destructured.variant {
for (a_field, b_field) in iter::zip(a_destructured.fields, b_destructured.fields) {
relation.consts(a_field, b_field)?;
relation.consts(*a_field, *b_field)?;
}
true
@ -756,12 +756,12 @@ impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
}
}
impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
impl<'tcx> Relate<'tcx> for ty::Const<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
relation.consts(a, b)
}
}

View file

@ -1159,15 +1159,15 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
let ty = self.ty.try_fold_with(folder)?;
let val = self.val.try_fold_with(folder)?;
if ty != self.ty || val != self.val {
Ok(folder.tcx().mk_const(ty::Const { ty, val }))
let ty = self.ty().try_fold_with(folder)?;
let val = self.val().try_fold_with(folder)?;
if ty != self.ty() || val != self.val() {
Ok(folder.tcx().mk_const(ty::ConstS { ty, val }))
} else {
Ok(self)
}
@ -1178,12 +1178,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.ty.visit_with(visitor)?;
self.val.visit_with(visitor)
self.ty().visit_with(visitor)?;
self.val().visit_with(visitor)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_const(self)
visitor.visit_const(*self)
}
}

View file

@ -116,7 +116,7 @@ pub enum TyKind<'tcx> {
Str,
/// An array with the given length. Written as `[T; N]`.
Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),
Array(Ty<'tcx>, ty::Const<'tcx>),
/// The pointee of an array slice. Written as `[T]`.
Slice(Ty<'tcx>),

View file

@ -32,7 +32,7 @@ use std::ops::ControlFlow;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct GenericArg<'tcx> {
ptr: NonZeroUsize,
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)>,
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
}
const TAG_MASK: usize = 0b11;
@ -44,7 +44,7 @@ const CONST_TAG: usize = 0b10;
pub enum GenericArgKind<'tcx> {
Lifetime(ty::Region<'tcx>),
Type(Ty<'tcx>),
Const(&'tcx ty::Const<'tcx>),
Const(ty::Const<'tcx>),
}
impl<'tcx> GenericArgKind<'tcx> {
@ -62,8 +62,8 @@ impl<'tcx> GenericArgKind<'tcx> {
}
GenericArgKind::Const(ct) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(ct) & TAG_MASK, 0);
(CONST_TAG, ct as *const ty::Const<'tcx> as usize)
assert_eq!(mem::align_of_val(ct.0.0) & TAG_MASK, 0);
(CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize)
}
};
@ -105,8 +105,8 @@ impl<'tcx> From<Ty<'tcx>> for GenericArg<'tcx> {
}
}
impl<'tcx> From<&'tcx ty::Const<'tcx>> for GenericArg<'tcx> {
fn from(c: &'tcx ty::Const<'tcx>) -> GenericArg<'tcx> {
impl<'tcx> From<ty::Const<'tcx>> for GenericArg<'tcx> {
fn from(c: ty::Const<'tcx>) -> GenericArg<'tcx> {
GenericArgKind::Const(c).pack()
}
}
@ -126,7 +126,9 @@ impl<'tcx> GenericArg<'tcx> {
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const ty::TyS<'tcx>),
))),
CONST_TAG => GenericArgKind::Const(&*((ptr & !TAG_MASK) as *const ty::Const<'tcx>)),
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
))),
_ => intrinsics::unreachable(),
}
}
@ -143,7 +145,7 @@ impl<'tcx> GenericArg<'tcx> {
}
/// Unpack the `GenericArg` as a const when it is known certainly to be a const.
pub fn expect_const(self) -> &'tcx ty::Const<'tcx> {
pub fn expect_const(self) -> ty::Const<'tcx> {
match self.unpack() {
GenericArgKind::Const(c) => c,
_ => bug!("expected a const, but found another kind"),
@ -300,7 +302,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
}
#[inline]
pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::Const<'tcx>> + 'a {
pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'a {
self.iter().filter_map(|k| {
if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None }
})
@ -335,7 +337,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
}
#[inline]
pub fn const_at(&self, i: usize) -> &'tcx ty::Const<'tcx> {
pub fn const_at(&self, i: usize) -> ty::Const<'tcx> {
if let GenericArgKind::Const(ct) = self[i].unpack() {
ct
} else {
@ -514,8 +516,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
}
}
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::ConstKind::Param(p) = c.val {
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Param(p) = c.val() {
self.const_for_param(p, c)
} else {
c.super_fold_with(self)
@ -564,11 +566,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
self.shift_vars_through_binders(ty)
}
fn const_for_param(
&self,
p: ParamConst,
source_ct: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
fn const_for_param(&self, p: ParamConst, source_ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
// Look up the const in the substitutions. It really should be in there.
let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack());
let ct = match opt_ct {

View file

@ -6,7 +6,8 @@ use crate::ty::layout::IntegerExt;
use crate::ty::query::TyCtxtAt;
use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
use crate::ty::{
self, DebruijnIndex, DefIdTree, List, ReEarlyBound, Region, Ty, TyCtxt, TyKind::*, TypeFoldable,
self, Const, DebruijnIndex, DefIdTree, List, ReEarlyBound, Region, Ty, TyCtxt, TyKind::*,
TypeFoldable,
};
use rustc_apfloat::Float as _;
use rustc_ast as ast;
@ -398,9 +399,10 @@ impl<'tcx> TyCtxt<'tcx> {
ty::TyS { kind: ty::Param(ref pt), .. },
_,
))) => !impl_generics.type_param(pt, self).pure_wrt_drop,
GenericArgKind::Const(&ty::Const {
val: ty::ConstKind::Param(ref pc), ..
}) => !impl_generics.const_param(pc, self).pure_wrt_drop,
GenericArgKind::Const(Const(Interned(
ty::ConstS { val: ty::ConstKind::Param(ref pc), .. },
_,
))) => !impl_generics.const_param(pc, self).pure_wrt_drop,
GenericArgKind::Lifetime(_)
| GenericArgKind::Type(_)
| GenericArgKind::Const(_) => {
@ -622,7 +624,7 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
impl<'tcx> Ty<'tcx> {
/// Returns the maximum value for the given numeric type (including `char`s)
/// or returns `None` if the type is not numeric.
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<Const<'tcx>> {
let val = match self.kind() {
ty::Int(_) | ty::Uint(_) => {
let (size, signed) = int_size_and_signed(tcx, self);
@ -637,12 +639,12 @@ impl<'tcx> Ty<'tcx> {
}),
_ => None,
};
val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
}
/// Returns the minimum value for the given numeric type (including `char`s)
/// or returns `None` if the type is not numeric.
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<Const<'tcx>> {
let val = match self.kind() {
ty::Int(_) | ty::Uint(_) => {
let (size, signed) = int_size_and_signed(tcx, self);
@ -656,7 +658,7 @@ impl<'tcx> Ty<'tcx> {
}),
_ => None,
};
val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
}
/// Checks whether values of this type `T` are *moved* or *copied*
@ -996,7 +998,7 @@ pub fn needs_drop_components<'tcx>(
ty::Array(elem_ty, size) => {
match needs_drop_components(*elem_ty, target_layout) {
Ok(v) if v.is_empty() => Ok(v),
res => match size.val.try_to_bits(target_layout.pointer_size) {
res => match size.val().try_to_bits(target_layout.pointer_size) {
// Arrays of size zero don't need drop, even if their element
// type does.
Some(0) => Ok(SmallVec::new()),

View file

@ -189,8 +189,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
},
GenericArgKind::Lifetime(_) => {}
GenericArgKind::Const(parent_ct) => {
stack.push(parent_ct.ty.into());
match parent_ct.val {
stack.push(parent_ct.ty().into());
match parent_ct.val() {
ty::ConstKind::Infer(_)
| ty::ConstKind::Param(_)
| ty::ConstKind::Placeholder(_)

View file

@ -23,7 +23,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
inferred_ty: ty,
})
});
assert_eq!(literal.ty, ty);
assert_eq!(literal.ty(), ty);
Constant { span, user_ty, literal: literal.into() }
}
ExprKind::StaticRef { literal, .. } => {

View file

@ -964,13 +964,13 @@ enum TestKind<'tcx> {
///
/// For `bool` we always generate two edges, one for `true` and one for
/// `false`.
options: FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
options: FxIndexMap<ty::Const<'tcx>, u128>,
},
/// Test for equality with value, possibly after an unsizing coercion to
/// `ty`,
Eq {
value: &'tcx ty::Const<'tcx>,
value: ty::Const<'tcx>,
// Integer types are handled by `SwitchInt`, and constants with ADT
// types are converted back into patterns, so this can only be `&str`,
// `&[T]`, `f32` or `f64`.

View file

@ -210,7 +210,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
PatKind::Range(PatRange { lo, hi, end }) => {
let (range, bias) = match *lo.ty.kind() {
let (range, bias) = match *lo.ty().kind() {
ty::Char => {
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
}
@ -228,7 +228,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
_ => (None, 0),
};
if let Some((min, max, sz)) = range {
if let (Some(lo), Some(hi)) = (lo.val.try_to_bits(sz), hi.val.try_to_bits(sz)) {
if let (Some(lo), Some(hi)) =
(lo.val().try_to_bits(sz), hi.val().try_to_bits(sz))
{
// We want to compare ranges numerically, but the order of the bitwise
// representation of signed integers does not match their numeric order.
// Thus, to correct the ordering, we need to shift the range of signed

View file

@ -59,8 +59,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
},
PatKind::Range(range) => {
assert_eq!(range.lo.ty, match_pair.pattern.ty);
assert_eq!(range.hi.ty, match_pair.pattern.ty);
assert_eq!(range.lo.ty(), match_pair.pattern.ty);
assert_eq!(range.hi.ty(), match_pair.pattern.ty);
Test { span: match_pair.pattern.span, kind: TestKind::Range(range) }
}
@ -86,7 +86,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
test_place: &PlaceBuilder<'tcx>,
candidate: &Candidate<'pat, 'tcx>,
switch_ty: Ty<'tcx>,
options: &mut FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
options: &mut FxIndexMap<ty::Const<'tcx>, u128>,
) -> bool {
let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
return false;
@ -266,7 +266,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ty,
);
} else if let [success, fail] = *make_target_blocks(self) {
assert_eq!(value.ty, ty);
assert_eq!(value.ty(), ty);
let expect = self.literal_operand(test.span, value);
let val = Operand::Copy(place);
self.compare(block, success, fail, source_info, BinOp::Eq, expect, val);
@ -275,7 +275,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
TestKind::Range(PatRange { ref lo, ref hi, ref end }) => {
TestKind::Range(PatRange { lo, hi, ref end }) => {
let lower_bound_success = self.cfg.start_new_block();
let target_blocks = make_target_blocks(self);
@ -369,7 +369,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block: BasicBlock,
make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>,
source_info: SourceInfo,
value: &'tcx ty::Const<'tcx>,
value: ty::Const<'tcx>,
place: Place<'tcx>,
mut ty: Ty<'tcx>,
) {
@ -390,7 +390,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
_ => None,
};
let opt_ref_ty = unsize(ty);
let opt_ref_test_ty = unsize(value.ty);
let opt_ref_test_ty = unsize(value.ty());
match (opt_ref_ty, opt_ref_test_ty) {
// nothing to do, neither is an array
(None, None) => {}
@ -646,7 +646,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let tcx = self.tcx;
let test_ty = test.lo.ty;
let test_ty = test.lo.ty();
let lo = compare_const_vals(tcx, test.lo, pat.hi, self.param_env, test_ty)?;
let hi = compare_const_vals(tcx, test.hi, pat.lo, self.param_env, test_ty)?;
@ -764,17 +764,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
span_bug!(match_pair.pattern.span, "simplifyable pattern found: {:?}", match_pair.pattern)
}
fn const_range_contains(
&self,
range: PatRange<'tcx>,
value: &'tcx ty::Const<'tcx>,
) -> Option<bool> {
fn const_range_contains(&self, range: PatRange<'tcx>, value: ty::Const<'tcx>) -> Option<bool> {
use std::cmp::Ordering::*;
let tcx = self.tcx;
let a = compare_const_vals(tcx, range.lo, value, self.param_env, range.lo.ty)?;
let b = compare_const_vals(tcx, value, range.hi, self.param_env, range.lo.ty)?;
let a = compare_const_vals(tcx, range.lo, value, self.param_env, range.lo.ty())?;
let b = compare_const_vals(tcx, value, range.hi, self.param_env, range.lo.ty())?;
match (b, range.end) {
(Less, _) | (Equal, RangeEnd::Included) if a != Greater => Some(true),
@ -785,7 +781,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn values_not_contained_in_range(
&self,
range: PatRange<'tcx>,
options: &FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
options: &FxIndexMap<ty::Const<'tcx>, u128>,
) -> Option<bool> {
for &val in options.keys() {
if self.const_range_contains(range, val)? {
@ -831,7 +827,7 @@ fn trait_method<'tcx>(
method_name: Symbol,
self_ty: Ty<'tcx>,
params: &[GenericArg<'tcx>],
) -> &'tcx ty::Const<'tcx> {
) -> ty::Const<'tcx> {
let substs = tcx.mk_substs_trait(self_ty, params);
// The unhygienic comparison here is acceptable because this is only

View file

@ -25,11 +25,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Convenience function for creating a literal operand, one
/// without any user type annotation.
crate fn literal_operand(
&mut self,
span: Span,
literal: &'tcx ty::Const<'tcx>,
) -> Operand<'tcx> {
crate fn literal_operand(&mut self, span: Span, literal: ty::Const<'tcx>) -> Operand<'tcx> {
let literal = literal.into();
let constant = Box::new(Constant { span, user_ty: None, literal });
Operand::Constant(constant)

View file

@ -10,7 +10,7 @@ use rustc_target::abi::Size;
crate fn lit_to_const<'tcx>(
tcx: TyCtxt<'tcx>,
lit_input: LitToConstInput<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
) -> Result<ty::Const<'tcx>, LitToConstError> {
let LitToConstInput { lit, ty, neg } = lit_input;
let trunc = |n| {

View file

@ -583,7 +583,7 @@ impl<'tcx> Cx<'tcx> {
_ => span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty),
};
ExprKind::Repeat { value: self.mirror_expr(v), count }
ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
}
hir::ExprKind::Ret(ref v) => {
ExprKind::Return { value: v.as_ref().map(|v| self.mirror_expr(v)) }
@ -708,7 +708,7 @@ impl<'tcx> Cx<'tcx> {
// in case we are offsetting from a computed discriminant
// and not the beginning of discriminants (which is always `0`)
let substs = InternalSubsts::identity_for_item(self.tcx(), did);
let lhs = ty::Const {
let lhs = ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated::new(
ty::WithOptConstParam::unknown(did),
substs,
@ -890,7 +890,7 @@ impl<'tcx> Cx<'tcx> {
let name = self.tcx.hir().name(hir_id);
let val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
ExprKind::Literal {
literal: self.tcx.mk_const(ty::Const {
literal: self.tcx.mk_const(ty::ConstS {
val,
ty: self.typeck_results().node_type(expr.hir_id),
}),
@ -903,7 +903,7 @@ impl<'tcx> Cx<'tcx> {
let user_ty = self.user_substs_applied_to_res(expr.hir_id, res);
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
ExprKind::Literal {
literal: self.tcx.mk_const(ty::Const {
literal: self.tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated::new(
ty::WithOptConstParam::unknown(def_id),
substs,

View file

@ -79,7 +79,7 @@ impl<'tcx> Cx<'tcx> {
ty: Ty<'tcx>,
sp: Span,
neg: bool,
) -> &'tcx ty::Const<'tcx> {
) -> ty::Const<'tcx> {
trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
match self.tcx.at(sp).lit_to_const(LitToConstInput { lit, ty, neg }) {

View file

@ -22,7 +22,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
pub(super) fn const_to_pat(
&self,
cv: &'tcx ty::Const<'tcx>,
cv: ty::Const<'tcx>,
id: hir::HirId,
span: Span,
mir_structural_match_violation: bool,
@ -152,11 +152,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
ty.is_structural_eq_shallow(self.infcx.tcx)
}
fn to_pat(
&mut self,
cv: &'tcx ty::Const<'tcx>,
mir_structural_match_violation: bool,
) -> Pat<'tcx> {
fn to_pat(&mut self, cv: ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> {
trace!(self.treat_byte_string_as_slice);
// This method is just a wrapper handling a validity check; the heavy lifting is
// performed by the recursive `recur` method, which is not meant to be
@ -171,10 +167,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
// If we were able to successfully convert the const to some pat,
// double-check that all types in the const implement `Structural`.
let structural = self.search_for_structural_match_violation(cv.ty);
let structural = self.search_for_structural_match_violation(cv.ty());
debug!(
"search_for_structural_match_violation cv.ty: {:?} returned: {:?}",
cv.ty, structural
cv.ty(),
structural
);
// This can occur because const qualification treats all associated constants as
@ -189,7 +186,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
}
if let Some(msg) = structural {
if !self.type_may_have_partial_eq_impl(cv.ty) {
if !self.type_may_have_partial_eq_impl(cv.ty()) {
// span_fatal avoids ICE from resolution of non-existent method (rare case).
self.tcx().sess.span_fatal(self.span, &msg);
} else if mir_structural_match_violation && !self.saw_const_match_lint.get() {
@ -247,7 +244,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
fn field_pats(
&self,
vals: impl Iterator<Item = &'tcx ty::Const<'tcx>>,
vals: impl Iterator<Item = ty::Const<'tcx>>,
) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
vals.enumerate()
.map(|(idx, val)| {
@ -260,7 +257,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
fn recur(
&self,
cv: &'tcx ty::Const<'tcx>,
cv: ty::Const<'tcx>,
mir_structural_match_violation: bool,
) -> Result<Pat<'tcx>, FallbackToConstRef> {
let id = self.id;
@ -268,7 +265,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
let tcx = self.tcx();
let param_env = self.param_env;
let kind = match cv.ty.kind() {
let kind = match cv.ty().kind() {
ty::Float(_) => {
if self.include_lint_checks {
tcx.struct_span_lint_hir(
@ -292,14 +289,14 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
PatKind::Wild
}
ty::Adt(..)
if !self.type_may_have_partial_eq_impl(cv.ty)
if !self.type_may_have_partial_eq_impl(cv.ty())
// FIXME(#73448): Find a way to bring const qualification into parity with
// `search_for_structural_match_violation` and then remove this condition.
&& self.search_for_structural_match_violation(cv.ty).is_some() =>
&& self.search_for_structural_match_violation(cv.ty()).is_some() =>
{
// Obtain the actual type that isn't annotated. If we just looked at `cv.ty` we
// could get `Option<NonStructEq>`, even though `Option` is annotated with derive.
let msg = self.search_for_structural_match_violation(cv.ty).unwrap();
let msg = self.search_for_structural_match_violation(cv.ty()).unwrap();
self.saw_const_match_error.set(true);
if self.include_lint_checks {
tcx.sess.span_err(self.span, &msg);
@ -317,7 +314,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
// details.
// Backwards compatibility hack because we can't cause hard errors on these
// types, so we compare them via `PartialEq::eq` at runtime.
ty::Adt(..) if !self.type_marked_structural(cv.ty) && self.behind_reference.get() => {
ty::Adt(..) if !self.type_marked_structural(cv.ty()) && self.behind_reference.get() => {
if self.include_lint_checks
&& !self.saw_const_match_error.get()
&& !self.saw_const_match_lint.get()
@ -331,7 +328,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
let msg = format!(
"to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
cv.ty, cv.ty,
cv.ty(),
cv.ty(),
);
lint.build(&msg).emit()
},
@ -342,8 +340,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
// `PartialEq::eq` on it.
return Err(fallback_to_const_ref(self));
}
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => {
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, cv.ty);
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty()) => {
debug!(
"adt_def {:?} has !type_marked_structural for cv.ty: {:?}",
adt_def,
cv.ty()
);
let path = tcx.def_path_str(adt_def.did);
let msg = format!(
"to use a constant of type `{}` in a pattern, \
@ -378,7 +380,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.destructure_const(param_env.and(cv))
.fields
.iter()
.map(|val| self.recur(val, false))
.map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?,
slice: None,
suffix: Vec::new(),
@ -387,7 +389,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
// These are not allowed and will error elsewhere anyway.
ty::Dynamic(..) => {
self.saw_const_match_error.set(true);
let msg = format!("`{}` cannot be used in patterns", cv.ty);
let msg = format!("`{}` cannot be used in patterns", cv.ty());
if self.include_lint_checks {
tcx.sess.span_err(span, &msg);
} else {
@ -414,7 +416,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.destructure_const(param_env.and(array))
.fields
.iter()
.map(|val| self.recur(val, false))
.map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?,
slice: None,
suffix: vec![],
@ -440,7 +442,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.destructure_const(param_env.and(array))
.fields
.iter()
.map(|val| self.recur(val, false))
.map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?,
slice: None,
suffix: vec![],
@ -544,7 +546,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
}
_ => {
self.saw_const_match_error.set(true);
let msg = format!("`{}` cannot be used in patterns", cv.ty);
let msg = format!("`{}` cannot be used in patterns", cv.ty());
if self.include_lint_checks {
tcx.sess.span_err(span, &msg);
} else {
@ -560,12 +562,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
&& mir_structural_match_violation
// FIXME(#73448): Find a way to bring const qualification into parity with
// `search_for_structural_match_violation` and then remove this condition.
&& self.search_for_structural_match_violation(cv.ty).is_some()
&& self.search_for_structural_match_violation(cv.ty()).is_some()
{
self.saw_const_match_lint.set(true);
// Obtain the actual type that isn't annotated. If we just looked at `cv.ty` we
// could get `Option<NonStructEq>`, even though `Option` is annotated with derive.
let msg = self.search_for_structural_match_violation(cv.ty).unwrap().replace(
let msg = self.search_for_structural_match_violation(cv.ty()).unwrap().replace(
"in a pattern,",
"in a pattern, the constant's initializer must be trivial or",
);
@ -577,6 +579,6 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
);
}
Ok(Pat { span, ty: cv.ty, kind: Box::new(kind) })
Ok(Pat { span, ty: cv.ty(), kind: Box::new(kind) })
}
}

View file

@ -136,12 +136,12 @@ impl IntRange {
fn from_const<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: &Const<'tcx>,
value: Const<'tcx>,
) -> Option<IntRange> {
if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, value.ty) {
let ty = value.ty;
let ty = value.ty();
if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) {
let val = (|| {
if let ty::ConstKind::Value(ConstValue::Scalar(scalar)) = value.val {
if let ty::ConstKind::Value(ConstValue::Scalar(scalar)) = value.val() {
// For this specific pattern we can skip a lot of effort and go
// straight to the result, after doing a bit of checking. (We
// could remove this branch and just fall through, which
@ -630,9 +630,9 @@ pub(super) enum Constructor<'tcx> {
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
IntRange(IntRange),
/// Ranges of floating-point literal values (`2.0..=5.2`).
FloatRange(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>, RangeEnd),
FloatRange(ty::Const<'tcx>, ty::Const<'tcx>, RangeEnd),
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
Str(&'tcx ty::Const<'tcx>),
Str(ty::Const<'tcx>),
/// Array and slice patterns.
Slice(Slice),
/// Constants that must not be matched structurally. They are treated as black
@ -815,8 +815,14 @@ impl<'tcx> Constructor<'tcx> {
FloatRange(other_from, other_to, other_end),
) => {
match (
compare_const_vals(pcx.cx.tcx, self_to, other_to, pcx.cx.param_env, pcx.ty),
compare_const_vals(pcx.cx.tcx, self_from, other_from, pcx.cx.param_env, pcx.ty),
compare_const_vals(pcx.cx.tcx, *self_to, *other_to, pcx.cx.param_env, pcx.ty),
compare_const_vals(
pcx.cx.tcx,
*self_from,
*other_from,
pcx.cx.param_env,
pcx.ty,
),
) {
(Some(to), Some(from)) => {
(from == Ordering::Greater || from == Ordering::Equal)
@ -828,8 +834,13 @@ impl<'tcx> Constructor<'tcx> {
}
(Str(self_val), Str(other_val)) => {
// FIXME: there's probably a more direct way of comparing for equality
match compare_const_vals(pcx.cx.tcx, self_val, other_val, pcx.cx.param_env, pcx.ty)
{
match compare_const_vals(
pcx.cx.tcx,
*self_val,
*other_val,
pcx.cx.param_env,
pcx.ty,
) {
Some(comparison) => comparison == Ordering::Equal,
None => false,
}
@ -1368,13 +1379,13 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
}
}
PatKind::Constant { value } => {
if let Some(int_range) = IntRange::from_const(cx.tcx, cx.param_env, value) {
if let Some(int_range) = IntRange::from_const(cx.tcx, cx.param_env, *value) {
ctor = IntRange(int_range);
fields = Fields::empty();
} else {
match pat.ty.kind() {
ty::Float(_) => {
ctor = FloatRange(value, value, RangeEnd::Included);
ctor = FloatRange(*value, *value, RangeEnd::Included);
fields = Fields::empty();
}
ty::Ref(_, t, _) if t.is_str() => {
@ -1386,7 +1397,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
// fields.
// Note: `t` is `str`, not `&str`.
let subpattern =
DeconstructedPat::new(Str(value), Fields::empty(), *t, pat.span);
DeconstructedPat::new(Str(*value), Fields::empty(), *t, pat.span);
ctor = Single;
fields = Fields::singleton(cx, subpattern)
}
@ -1401,11 +1412,11 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
}
}
&PatKind::Range(PatRange { lo, hi, end }) => {
let ty = lo.ty;
let ty = lo.ty();
ctor = if let Some(int_range) = IntRange::from_range(
cx.tcx,
lo.eval_bits(cx.tcx, cx.param_env, lo.ty),
hi.eval_bits(cx.tcx, cx.param_env, hi.ty),
lo.eval_bits(cx.tcx, cx.param_env, lo.ty()),
hi.eval_bits(cx.tcx, cx.param_env, hi.ty()),
ty,
&end,
) {

View file

@ -121,13 +121,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
fn lower_pattern_range(
&mut self,
ty: Ty<'tcx>,
lo: &'tcx ty::Const<'tcx>,
hi: &'tcx ty::Const<'tcx>,
lo: ty::Const<'tcx>,
hi: ty::Const<'tcx>,
end: RangeEnd,
span: Span,
) -> PatKind<'tcx> {
assert_eq!(lo.ty, ty);
assert_eq!(hi.ty, ty);
assert_eq!(lo.ty(), ty);
assert_eq!(hi.ty(), ty);
let cmp = compare_const_vals(self.tcx, lo, hi, self.param_env, ty);
match (end, cmp) {
// `x..y` where `x < y`.
@ -177,16 +177,16 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
lo: Option<&PatKind<'tcx>>,
hi: Option<&PatKind<'tcx>>,
) -> Option<(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>)> {
) -> Option<(ty::Const<'tcx>, ty::Const<'tcx>)> {
match (lo, hi) {
(Some(PatKind::Constant { value: lo }), Some(PatKind::Constant { value: hi })) => {
Some((lo, hi))
Some((*lo, *hi))
}
(Some(PatKind::Constant { value: lo }), None) => {
Some((lo, ty.numeric_max_val(self.tcx)?))
Some((*lo, ty.numeric_max_val(self.tcx)?))
}
(None, Some(PatKind::Constant { value: hi })) => {
Some((ty.numeric_min_val(self.tcx)?, hi))
Some((ty.numeric_min_val(self.tcx)?, *hi))
}
_ => None,
}
@ -493,7 +493,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let const_ =
ty::Const::from_value(self.tcx, value, self.typeck_results.node_type(id));
let pattern = self.const_to_pat(&const_, id, span, mir_structural_match_violation);
let pattern = self.const_to_pat(const_, id, span, mir_structural_match_violation);
if !is_associated_const {
return pattern;
@ -514,7 +514,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
user_ty_span: span,
},
}),
ty: const_.ty,
ty: const_.ty(),
}
} else {
pattern
@ -546,7 +546,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// Evaluate early like we do in `lower_path`.
let value = value.eval(self.tcx, self.param_env);
match value.val {
match value.val() {
ConstKind::Param(_) => {
self.errors.push(PatternError::ConstParamInPattern(span));
return PatKind::Wild;
@ -744,8 +744,8 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
crate fn compare_const_vals<'tcx>(
tcx: TyCtxt<'tcx>,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Option<Ordering> {
@ -756,13 +756,13 @@ crate fn compare_const_vals<'tcx>(
let fallback = || from_bool(a == b);
// Use the fallback if any type differs
if a.ty != b.ty || a.ty != ty {
if a.ty() != b.ty() || a.ty() != ty {
return fallback();
}
// Early return for equal constants (so e.g. references to ZSTs can be compared, even if they
// are just integer addresses).
if a.val == b.val {
if a.val() == b.val() {
return from_bool(true);
}
@ -797,7 +797,7 @@ crate fn compare_const_vals<'tcx>(
if let (
ty::ConstKind::Value(a_val @ ConstValue::Slice { .. }),
ty::ConstKind::Value(b_val @ ConstValue::Slice { .. }),
) = (a.val, b.val)
) = (a.val(), b.val())
{
let a_bytes = get_slice_bytes(&tcx, a_val);
let b_bytes = get_slice_bytes(&tcx, b_val);

View file

@ -484,7 +484,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let err = ConstEvalErr::new(&self.ecx, error, Some(c.span));
if let Some(lint_root) = self.lint_root(source_info) {
let lint_only = match c.literal {
ConstantKind::Ty(ct) => match ct.val {
ConstantKind::Ty(ct) => match ct.val() {
// Promoteds must lint and not error as the user didn't ask for them
ConstKind::Unevaluated(ty::Unevaluated {
def: _,
@ -801,7 +801,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
) {
if let Rvalue::Use(Operand::Constant(c)) = rval {
match c.literal {
ConstantKind::Ty(c) if matches!(c.val, ConstKind::Unevaluated(..)) => {}
ConstantKind::Ty(c) if matches!(c.val(), ConstKind::Unevaluated(..)) => {}
_ => {
trace!("skipping replace of Rvalue::Use({:?} because it is already a const", c);
return;
@ -875,7 +875,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
literal: self
.ecx
.tcx
.mk_const(ty::Const {
.mk_const(ty::ConstS {
ty,
val: ty::ConstKind::Value(ConstValue::ByRef {
alloc,

View file

@ -625,7 +625,7 @@ impl<'tcx> Inliner<'tcx> {
caller_body.required_consts.extend(
callee_body.required_consts.iter().copied().filter(|&ct| {
match ct.literal.const_for_ty() {
Some(ct) => matches!(ct.val, ConstKind::Unevaluated(_)),
Some(ct) => matches!(ct.val(), ConstKind::Unevaluated(_)),
None => true,
}
}),

View file

@ -15,7 +15,7 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
if let Some(ct) = constant.literal.const_for_ty() {
if let ConstKind::Unevaluated(_) = ct.val {
if let ConstKind::Unevaluated(_) = ct.val() {
self.required_consts.push(*constant);
}
}

View file

@ -709,7 +709,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
let literal = self.monomorphize(constant.literal);
let val = match literal {
mir::ConstantKind::Val(val, _) => val,
mir::ConstantKind::Ty(ct) => match ct.val {
mir::ConstantKind::Ty(ct) => match ct.val() {
ty::ConstKind::Value(val) => val,
ty::ConstKind::Unevaluated(ct) => {
let param_env = ty::ParamEnv::reveal_all();
@ -731,13 +731,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
self.visit_ty(literal.ty(), TyContext::Location(location));
}
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) {
debug!("visiting const {:?} @ {:?}", *constant, location);
fn visit_const(&mut self, constant: ty::Const<'tcx>, location: Location) {
debug!("visiting const {:?} @ {:?}", constant, location);
let substituted_constant = self.monomorphize(*constant);
let substituted_constant = self.monomorphize(constant);
let param_env = ty::ParamEnv::reveal_all();
match substituted_constant.val {
match substituted_constant.val() {
ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output),
ty::ConstKind::Unevaluated(unevaluated) => {
match self.tcx.const_eval_resolve(param_env, unevaluated, None) {

View file

@ -267,7 +267,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
self.super_local_decl(local, local_decl);
}
fn visit_const(&mut self, c: &&'tcx Const<'tcx>, _: Location) {
fn visit_const(&mut self, c: Const<'tcx>, _: Location) {
c.visit_with(self);
}
@ -278,12 +278,12 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if !c.has_param_types_or_consts() {
return ControlFlow::CONTINUE;
}
match c.val {
match c.val() {
ty::ConstKind::Param(param) => {
debug!(?param);
self.unused_parameters.clear(param.index);
@ -348,12 +348,12 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> {
type BreakTy = ();
#[instrument(level = "debug", skip(self))]
fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if !c.has_param_types_or_consts() {
return ControlFlow::CONTINUE;
}
match c.val {
match c.val() {
ty::ConstKind::Param(param) => {
if self.unused_parameters.contains(param.index).unwrap_or(false) {
ControlFlow::CONTINUE

View file

@ -280,8 +280,8 @@ where
}
}
fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
self.visit_ty(c.ty)?;
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
self.visit_ty(c.ty())?;
let tcx = self.def_id_visitor.tcx();
if let Ok(Some(ct)) = AbstractConst::from_const(tcx, c) {
self.visit_abstract_const_expr(tcx, ct)?;

View file

@ -275,7 +275,7 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
}
}
impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) {
impl<'tcx> Key for (ty::Const<'tcx>, mir::Field) {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true
@ -345,7 +345,7 @@ impl<'tcx> Key for mir::ConstantKind<'tcx> {
}
}
impl<'tcx> Key for &'tcx ty::Const<'tcx> {
impl<'tcx> Key for ty::Const<'tcx> {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true

View file

@ -243,10 +243,10 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
Ok(self)
}
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
// only print integers
if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int { .. })) = ct.val {
if ct.ty.is_integral() {
if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int { .. })) = ct.val() {
if ct.ty().is_integral() {
return self.pretty_print_const(ct, true);
}
}

View file

@ -116,7 +116,7 @@ struct SymbolMangler<'tcx> {
/// The values are start positions in `out`, in bytes.
paths: FxHashMap<(DefId, &'tcx [GenericArg<'tcx>]), usize>,
types: FxHashMap<Ty<'tcx>, usize>,
consts: FxHashMap<&'tcx ty::Const<'tcx>, usize>,
consts: FxHashMap<ty::Const<'tcx>, usize>,
}
impl<'tcx> SymbolMangler<'tcx> {
@ -576,10 +576,10 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
Ok(self)
}
fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(mut self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
// We only mangle a typed value if the const can be evaluated.
let ct = ct.eval(self.tcx, ty::ParamEnv::reveal_all());
match ct.val {
match ct.val() {
ty::ConstKind::Value(_) => {}
// Placeholders (should be demangled as `_`).
@ -603,14 +603,14 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
}
let start = self.out.len();
match ct.ty.kind() {
match ct.ty().kind() {
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
self = ct.ty.print(self)?;
self = ct.ty().print(self)?;
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty);
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty());
// Negative integer values are mangled using `n` as a "sign prefix".
if let ty::Int(ity) = ct.ty.kind() {
if let ty::Int(ity) = ct.ty().kind() {
let val =
Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128;
if val < 0 {
@ -627,7 +627,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
// handle `&str` and include both `&` ("R") and `str` ("e") prefixes.
ty::Ref(_, ty, hir::Mutability::Not) if *ty == self.tcx.types.str_ => {
self.push("R");
match ct.val {
match ct.val() {
ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => {
// NOTE(eddyb) the following comment was kept from `ty::print::pretty`:
// The `inspect` here is okay since we checked the bounds, and there are no
@ -671,7 +671,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
Ok(this)
};
match *ct.ty.kind() {
match *ct.ty().kind() {
ty::Array(..) => {
self.push("A");
self = print_field_list(self)?;
@ -721,7 +721,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
}
_ => {
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct);
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty(), ct);
}
}

View file

@ -287,10 +287,10 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
trace!("checking const {:?}", ct);
// Find a const parameter
match ct.val {
match ct.val() {
ty::ConstKind::Param(..) => {
// Look it up in the substitution list.
match self.map.get(&ct.into()).map(|k| k.unpack()) {
@ -311,7 +311,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
)
.emit();
self.tcx().const_error(ct.ty)
self.tcx().const_error(ct.ty())
}
}
}

View file

@ -809,14 +809,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
};
}
ty::PredicateKind::ConstEquate(c1, c2) => {
let evaluate = |c: &'tcx ty::Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
let evaluate = |c: ty::Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.val() {
match select.infcx().const_eval_resolve(
obligation.param_env,
unevaluated,
Some(obligation.cause.span),
) {
Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)),
Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty())),
Err(err) => Err(err),
}
} else {

View file

@ -8,6 +8,7 @@
//! In this case we try to build an abstract representation of this constant using
//! `thir_abstract_const` which can then be checked for structural equality with other
//! generic constants mentioned in the `caller_bounds` of the current environment.
use rustc_data_structures::intern::Interned;
use rustc_errors::ErrorReported;
use rustc_hir::def::DefKind;
use rustc_index::vec::IndexVec;
@ -201,9 +202,9 @@ impl<'tcx> AbstractConst<'tcx> {
pub fn from_const(
tcx: TyCtxt<'tcx>,
ct: &ty::Const<'tcx>,
ct: ty::Const<'tcx>,
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
match ct.val {
match ct.val() {
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()),
ty::ConstKind::Error(_) => Err(ErrorReported),
_ => Ok(None),
@ -293,7 +294,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
}
}
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) {
fn visit_const(&mut self, ct: ty::Const<'tcx>) {
self.is_poly |= ct.has_param_types_or_consts();
}
}
@ -334,7 +335,11 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
self.recurse_build(self.body_id)?;
for n in self.nodes.iter() {
if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n {
if let Node::Leaf(ty::Const(Interned(
ty::ConstS { val: ty::ConstKind::Unevaluated(ct), ty: _ },
_,
))) = n
{
// `AbstractConst`s should not contain any promoteds as they require references which
// are not allowed.
assert_eq!(ct.promoted, None);
@ -602,11 +607,11 @@ pub(super) fn try_unify<'tcx>(
match (a.root(tcx), b.root(tcx)) {
(Node::Leaf(a_ct), Node::Leaf(b_ct)) => {
if a_ct.ty != b_ct.ty {
if a_ct.ty() != b_ct.ty() {
return false;
}
match (a_ct.val, b_ct.val) {
match (a_ct.val(), b_ct.val()) {
// We can just unify errors with everything to reduce the amount of
// emitted errors here.
(ty::ConstKind::Error(_), _) | (_, ty::ConstKind::Error(_)) => true,

View file

@ -211,7 +211,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let type_string = self.tcx.type_of(def.did).to_string();
flags.push((sym::_Self, Some(format!("[{}]", type_string))));
let len = len.val.try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
let len =
len.val().try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
let string = match len {
Some(n) => format!("[{}; {}]", type_string, n),
None => format!("[{}; _]", type_string),

View file

@ -562,7 +562,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
//
// Let's just see where this breaks :shrug:
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
(c1.val, c2.val)
(c1.val(), c2.val())
{
if infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) {
return ProcessResult::Changed(vec![]);
@ -572,14 +572,14 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
let stalled_on = &mut pending_obligation.stalled_on;
let mut evaluate = |c: &'tcx Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
let mut evaluate = |c: Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.val() {
match self.selcx.infcx().const_eval_resolve(
obligation.param_env,
unevaluated,
Some(obligation.cause.span),
) {
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)),
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty())),
Err(ErrorHandled::TooGeneric) => {
stalled_on.extend(
unevaluated

View file

@ -499,7 +499,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
}
}
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
if self.selcx.tcx().lazy_normalization() {
constant
} else {
@ -622,24 +622,24 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match *ct {
ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ }
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val() {
ty::ConstKind::Bound(debruijn, _)
if debruijn.as_usize() + 1
> self.current_index.as_usize() + self.universe_indices.len() =>
{
bug!("Bound vars outside of `self.universe_indices`");
}
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
if debruijn >= self.current_index =>
{
ty::ConstKind::Bound(debruijn, bound_const) if debruijn >= self.current_index => {
let universe = self.universe_for(debruijn);
let p = ty::PlaceholderConst {
universe,
name: ty::BoundConst { var: bound_const, ty },
name: ty::BoundConst { var: bound_const, ty: ct.ty() },
};
self.mapped_consts.insert(p, bound_const);
self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })
self.infcx
.tcx
.mk_const(ty::ConstS { val: ty::ConstKind::Placeholder(p), ty: ct.ty() })
}
_ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self),
_ => ct,
@ -758,8 +758,8 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Placeholder(p), ty } = *ct {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Placeholder(p) = ct.val() {
let replace_var = self.mapped_consts.get(&p);
match replace_var {
Some(replace_var) => {
@ -771,8 +771,10 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
let db = ty::DebruijnIndex::from_usize(
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
);
self.tcx()
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })
self.tcx().mk_const(ty::ConstS {
val: ty::ConstKind::Bound(db, *replace_var),
ty: ct.ty(),
})
}
None => ct,
}
@ -1862,7 +1864,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
let val = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, identity_substs));
tcx.mk_const(ty::Const { ty, val }).into()
tcx.mk_const(ty::ConstS { ty, val }).into()
} else {
ty.into()
};

View file

@ -140,8 +140,8 @@ impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor {
ControlFlow::CONTINUE
}
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match ct.val {
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match ct.val() {
ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => {
self.escaping =
self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize());
@ -324,8 +324,8 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
fn try_fold_const(
&mut self,
constant: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
constant: ty::Const<'tcx>,
) -> Result<ty::Const<'tcx>, Self::Error> {
let constant = constant.try_super_fold_with(self)?;
Ok(constant.eval(self.infcx.tcx, self.param_env))
}

View file

@ -983,7 +983,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Lifetimes aren't allowed to change during unsizing.
GenericArgKind::Lifetime(_) => None,
GenericArgKind::Const(ct) => match ct.val {
GenericArgKind::Const(ct) => match ct.val() {
ty::ConstKind::Param(p) => Some(p.index),
_ => None,
},

View file

@ -643,7 +643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
//
// Let's just see where this breaks :shrug:
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
(c1.val, c2.val)
(c1.val(), c2.val())
{
if self.infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) {
return Ok(EvaluatedToOk);
@ -651,15 +651,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
let evaluate = |c: &'tcx ty::Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
let evaluate = |c: ty::Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.val() {
self.infcx
.const_eval_resolve(
obligation.param_env,
unevaluated,
Some(obligation.cause.span),
)
.map(|val| ty::Const::from_value(self.tcx(), val, c.ty))
.map(|val| ty::Const::from_value(self.tcx(), val, c.ty()))
} else {
Ok(c)
}

View file

@ -41,7 +41,7 @@ pub fn obligations<'a, 'tcx>(
.into()
}
GenericArgKind::Const(ct) => {
match ct.val {
match ct.val() {
ty::ConstKind::Infer(infer) => {
let resolved = infcx.shallow_resolve(infer);
if resolved == infer {
@ -49,7 +49,9 @@ pub fn obligations<'a, 'tcx>(
return None;
}
infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Infer(resolved), ty: ct.ty })
infcx
.tcx
.mk_const(ty::ConstS { val: ty::ConstKind::Infer(resolved), ty: ct.ty() })
}
_ => ct,
}
@ -442,7 +444,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
GenericArgKind::Lifetime(_) => continue,
GenericArgKind::Const(constant) => {
match constant.val {
match constant.val() {
ty::ConstKind::Unevaluated(uv) => {
let obligations = self.nominal_obligations(uv.def.did, uv.substs);
self.out.extend(obligations);
@ -464,9 +466,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
if resolved != infer {
let cause = self.cause(traits::MiscObligation);
let resolved_constant = self.infcx.tcx.mk_const(ty::Const {
let resolved_constant = self.infcx.tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Infer(resolved),
..*constant
ty: constant.ty(),
});
self.out.push(traits::Obligation::with_depth(
cause,

View file

@ -715,7 +715,7 @@ fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx
}
ty::GenericParamDefKind::Const { .. } => tcx
.mk_const(ty::Const {
.mk_const(ty::ConstS {
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
ty: tcx.type_of(param.def_id),
})
@ -735,7 +735,7 @@ fn binders_for<'tcx>(
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
}
ty::subst::GenericArgKind::Const(c) => {
chalk_ir::VariableKind::Const(c.ty.lower_into(interner))
chalk_ir::VariableKind::Const(c.ty().lower_into(interner))
}
}),
)

View file

@ -389,7 +389,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
TyKind::Array(ty, c) => {
let ty = ty.lower_into(interner);
let c = c.lower_into(interner);
ty::Array(ty, interner.tcx.mk_const(c))
ty::Array(ty, c)
}
TyKind::FnDef(id, substitution) => ty::FnDef(id.0, substitution.lower_into(interner)),
TyKind::Closure(closure, substitution) => {
@ -505,8 +505,8 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
impl<'tcx> LowerInto<'tcx, chalk_ir::Const<RustInterner<'tcx>>> for ty::Const<'tcx> {
fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::Const<RustInterner<'tcx>> {
let ty = self.ty.lower_into(interner);
let value = match self.val {
let ty = self.ty().lower_into(interner);
let value = match self.val() {
ty::ConstKind::Value(val) => {
chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: val })
}
@ -532,7 +532,7 @@ impl<'tcx> LowerInto<'tcx, ty::Const<'tcx>> for &chalk_ir::Const<RustInterner<'t
chalk_ir::ConstValue::Placeholder(_p) => unimplemented!(),
chalk_ir::ConstValue::Concrete(c) => ty::ConstKind::Value(c.interned),
};
ty::Const { ty, val }
interner.tcx.mk_const(ty::ConstS { ty, val })
}
}
@ -568,7 +568,7 @@ impl<'tcx> LowerInto<'tcx, ty::subst::GenericArg<'tcx>>
}
chalk_ir::GenericArgData::Const(c) => {
let c: ty::Const<'tcx> = c.lower_into(interner);
interner.tcx.mk_const(c).into()
c.into()
}
}
}

View file

@ -83,7 +83,7 @@ pub trait AstConv<'tcx> {
ty: Ty<'tcx>,
param: Option<&ty::GenericParamDef>,
span: Span,
) -> &'tcx Const<'tcx>;
) -> Const<'tcx>;
/// Projecting an associated type from a (potentially)
/// higher-ranked trait reference is more complicated, because of
@ -1428,7 +1428,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// `trait_object_dummy_self`, so check for that.
let references_self = match pred.skip_binder().term {
ty::Term::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
ty::Term::Const(c) => c.ty.walk().any(|arg| arg == dummy_self.into()),
ty::Term::Const(c) => c.ty().walk().any(|arg| arg == dummy_self.into()),
};
// If the projection output contains `Self`, force the user to

View file

@ -480,8 +480,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
r.super_visit_with(self)
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Unevaluated(..) = c.val {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Unevaluated(..) = c.val() {
// FIXME(#72219) We currently don't detect lifetimes within substs
// which would violate this check. Even though the particular substitution is not used
// within the const, this should still be fixed.

View file

@ -1306,7 +1306,7 @@ pub fn check_type_bounds<'tcx>(
GenericParamDefKind::Const { .. } => {
let bound_var = ty::BoundVariableKind::Const;
bound_vars.push(bound_var);
tcx.mk_const(ty::Const {
tcx.mk_const(ty::ConstS {
ty: tcx.type_of(param.def_id),
val: ty::ConstKind::Bound(
ty::INNERMOST,

View file

@ -362,9 +362,9 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("SimpleEqRelation::consts(a={:?}, b={:?})", a, b);
ty::relate::super_relate_consts(self, a, b)
}

Some files were not shown because too many files have changed in this diff Show more