1
Fork 0

Overhaul Const.

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

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2181,7 +2181,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &hir::Expr<'_>,
base: &hir::Expr<'_>,
field: Ident,
len: &ty::Const<'tcx>,
len: ty::Const<'tcx>,
) {
if let (Some(len), Ok(user_index)) =
(len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())

View file

@ -498,14 +498,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
}
pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> &'tcx ty::Const<'tcx> {
pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> {
match length {
&hir::ArrayLen::Infer(_, span) => self.ct_infer(self.tcx.types.usize, None, span),
hir::ArrayLen::Body(anon_const) => self.to_const(anon_const),
}
}
pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
pub fn to_const(&self, ast_c: &hir::AnonConst) -> ty::Const<'tcx> {
let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
let c = ty::Const::from_anon_const(self.tcx, const_def_id);
self.register_wf_obligation(
@ -520,7 +520,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
ast_c: &hir::AnonConst,
param_def_id: DefId,
) -> &'tcx ty::Const<'tcx> {
) -> ty::Const<'tcx> {
let const_def = ty::WithOptConstParam {
did: self.tcx.hir().local_def_id(ast_c.hir_id),
const_param_did: Some(param_def_id),

View file

@ -239,7 +239,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
param: Option<&ty::GenericParamDef>,
span: Span,
) -> &'tcx Const<'tcx> {
) -> Const<'tcx> {
if let Some(param) = param {
if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
return ct;

View file

@ -1935,7 +1935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
element_ty: Ty<'tcx>,
arr_ty: Ty<'tcx>,
slice: Option<&'tcx Pat<'tcx>>,
len: &ty::Const<'tcx>,
len: ty::Const<'tcx>,
min_len: u64,
) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) {

View file

@ -1295,8 +1295,8 @@ fn check_where_clauses<'tcx, 'fcx>(
ControlFlow::BREAK
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Param(param) = c.val {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Param(param) = c.val() {
self.params.insert(param.index);
}
c.super_visit_with(self)

View file

@ -720,7 +720,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
}
}
fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) {
fn report_const_error(&self, c: ty::Const<'tcx>) {
if !self.tcx.sess.has_errors() {
self.infcx
.emit_inference_failure_err(
@ -783,14 +783,14 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
self.tcx.lifetimes.re_erased
}
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> {
match self.infcx.fully_resolve(ct) {
Ok(ct) => self.infcx.tcx.erase_regions(ct),
Err(_) => {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
self.report_const_error(ct);
self.replaced_with_error = true;
self.tcx().const_error(ct.ty)
self.tcx().const_error(ct.ty())
}
}
}

View file

@ -312,8 +312,8 @@ impl<'tcx> TypeVisitor<'tcx> for AreUniqueParamsVisitor {
_ => ControlFlow::Break(NotUniqueParam::NotParam(r.into())),
}
}
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(p) => {
if self.seen.insert(p.index) {
ControlFlow::CONTINUE

View file

@ -389,12 +389,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
self.tcx().ty_error_with_message(span, "bad placeholder type")
}
fn ct_infer(
&self,
ty: Ty<'tcx>,
_: Option<&ty::GenericParamDef>,
span: Span,
) -> &'tcx Const<'tcx> {
fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match *r {
ty::ReErased => self.tcx.lifetimes.re_static,
_ => r,
@ -2394,7 +2389,7 @@ fn const_evaluatable_predicates_of<'tcx>(
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
let def_id = self.tcx.hir().local_def_id(c.hir_id);
let ct = ty::Const::from_anon_const(self.tcx, def_id);
if let ty::ConstKind::Unevaluated(uv) = ct.val {
if let ty::ConstKind::Unevaluated(uv) = ct.val() {
assert_eq!(uv.promoted, None);
let span = self.tcx.hir().span(c.hir_id);
self.preds.insert((

View file

@ -79,11 +79,11 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
ControlFlow::CONTINUE
}
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::Unevaluated(..) if !self.include_nonconstraining => {
// Constant expressions are not injective
return c.ty.visit_with(self);
return c.ty().visit_with(self);
}
ty::ConstKind::Param(data) => {
self.parameters.push(Parameter::from(data));

View file

@ -401,12 +401,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
fn add_constraints_from_const(
&mut self,
current: &CurrentItem,
val: &ty::Const<'tcx>,
val: ty::Const<'tcx>,
variance: VarianceTermPtr<'a>,
) {
debug!("add_constraints_from_const(val={:?}, variance={:?})", val, variance);
match &val.val {
match &val.val() {
ty::ConstKind::Unevaluated(uv) => {
self.add_constraints_from_invariant_substs(current, uv.substs, variance);
}