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:
parent
7eb15509ce
commit
a95fb8b150
116 changed files with 654 additions and 619 deletions
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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`"
|
||||
|
|
|
@ -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 }),
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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(), ¶m.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
|
||||
|
|
|
@ -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)) => {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) => {
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>) {
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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]),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) },
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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(_)
|
||||
|
|
|
@ -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, .. } => {
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }) {
|
||||
|
|
|
@ -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) })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue