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
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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>())
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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((
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue