Skip to content

Commit 371c77b

Browse files
committed
make unevaluated const substs optional
1 parent 4e8e894 commit 371c77b

File tree

25 files changed

+122
-80
lines changed

25 files changed

+122
-80
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,13 @@ pub(crate) fn codegen_constant<'tcx>(
116116
let const_ = fx.monomorphize(constant.literal);
117117
let const_val = match const_.val {
118118
ConstKind::Value(const_val) => const_val,
119-
ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => {
120-
assert!(substs.is_empty());
121-
assert!(promoted.is_none());
119+
ConstKind::Unevaluated(uv) if fx.tcx.is_static(uv.def.did) => {
120+
assert!(uv.substs(fx.tcx).is_empty());
121+
assert!(uv.promoted.is_none());
122122

123123
return codegen_static_ref(
124124
fx,
125-
def.did,
125+
uv.def.did,
126126
fx.layout_of(fx.monomorphize(&constant.literal.ty)),
127127
)
128128
.to_cvalue(fx);

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,16 +1498,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14981498
pub fn const_eval_resolve(
14991499
&self,
15001500
param_env: ty::ParamEnv<'tcx>,
1501-
ty::Unevaluated { def, substs, promoted }: ty::Unevaluated<'tcx>,
1501+
unevaluated: ty::Unevaluated<'tcx>,
15021502
span: Option<Span>,
15031503
) -> EvalToConstValueResult<'tcx> {
15041504
let mut original_values = OriginalQueryValues::default();
1505-
let canonical = self.canonicalize_query((param_env, substs), &mut original_values);
1505+
let canonical = self.canonicalize_query((param_env, unevaluated), &mut original_values);
15061506

1507-
let (param_env, substs) = canonical.value;
1507+
let (param_env, unevaluated) = canonical.value;
15081508
// The return value is the evaluated value which doesn't contain any reference to inference
15091509
// variables, thus we don't need to substitute back the original values.
1510-
self.tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, span)
1510+
self.tcx.const_eval_resolve(param_env, unevaluated, span)
15111511
}
15121512

15131513
/// If `typ` is a type variable of some kind, resolve it one level

compiler/rustc_middle/src/mir/interpret/queries.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> {
3838
ct: ty::Unevaluated<'tcx>,
3939
span: Option<Span>,
4040
) -> EvalToConstValueResult<'tcx> {
41-
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
41+
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs(self)) {
4242
Ok(Some(instance)) => {
4343
let cid = GlobalId { instance, promoted: ct.promoted };
4444
self.const_eval_global_id(param_env, cid, span)

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ rustc_queries! {
9393
desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
9494
}
9595

96+
query default_anon_const_substs(key: DefId) -> SubstsRef<'tcx> {
97+
desc { |tcx| "computing the default generic arguments for `{}`", tcx.def_path_str(key) }
98+
}
99+
96100
/// Records the type of every item.
97101
query type_of(key: DefId) -> Ty<'tcx> {
98102
desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::mir::interpret::ConstValue;
22
use crate::mir::interpret::{LitToConstInput, Scalar};
3-
use crate::ty::subst::InternalSubsts;
43
use crate::ty::{self, Ty, TyCtxt};
54
use crate::ty::{ParamEnv, ParamEnvAnd};
65
use rustc_errors::ErrorReported;
@@ -98,7 +97,7 @@ impl<'tcx> Const<'tcx> {
9897
}
9998
_ => ty::ConstKind::Unevaluated(ty::Unevaluated {
10099
def: def.to_global(),
101-
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
100+
non_default_substs: None,
102101
promoted: None,
103102
}),
104103
};

compiler/rustc_middle/src/ty/consts/kind.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ use rustc_target::abi::Size;
1414
#[derive(Hash, HashStable)]
1515
pub struct Unevaluated<'tcx> {
1616
pub def: ty::WithOptConstParam<DefId>,
17-
pub substs: SubstsRef<'tcx>,
17+
pub non_default_substs: Option<SubstsRef<'tcx>>,
1818
pub promoted: Option<Promoted>,
1919
}
2020

21+
impl<'tcx> Unevaluated<'tcx> {
22+
pub fn substs(self, tcx: TyCtxt<'tcx>) -> SubstsRef<'tcx> {
23+
self.non_default_substs.unwrap_or_else(|| tcx.default_anon_const_substs(self.def.did))
24+
}
25+
}
26+
2127
/// Represents a constant in Rust.
2228
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
2329
#[derive(Hash, HashStable)]
@@ -102,7 +108,7 @@ impl<'tcx> ConstKind<'tcx> {
102108
tcx: TyCtxt<'tcx>,
103109
param_env: ParamEnv<'tcx>,
104110
) -> Option<Result<ConstValue<'tcx>, ErrorReported>> {
105-
if let ConstKind::Unevaluated(Unevaluated { def, substs, promoted }) = self {
111+
if let ConstKind::Unevaluated(unevaluated) = self {
106112
use crate::mir::interpret::ErrorHandled;
107113

108114
// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
@@ -111,29 +117,35 @@ impl<'tcx> ConstKind<'tcx> {
111117
// Note that we erase regions *before* calling `with_reveal_all_normalized`,
112118
// so that we don't try to invoke this query with
113119
// any region variables.
114-
let param_env_and_substs = tcx
120+
let param_env_and = tcx
115121
.erase_regions(param_env)
116122
.with_reveal_all_normalized(tcx)
117-
.and(tcx.erase_regions(substs));
123+
.and(tcx.erase_regions(unevaluated));
118124

119125
// HACK(eddyb) when the query key would contain inference variables,
120126
// attempt using identity substs and `ParamEnv` instead, that will succeed
121127
// when the expression doesn't depend on any parameters.
122128
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
123129
// we can call `infcx.const_eval_resolve` which handles inference variables.
124-
let param_env_and_substs = if param_env_and_substs.needs_infer() {
125-
tcx.param_env(def.did).and(InternalSubsts::identity_for_item(tcx, def.did))
130+
let param_env_and = if param_env_and.needs_infer() {
131+
tcx.param_env(unevaluated.def.did).and(ty::Unevaluated {
132+
def: unevaluated.def,
133+
non_default_substs: Some(InternalSubsts::identity_for_item(
134+
tcx,
135+
unevaluated.def.did,
136+
)),
137+
promoted: unevaluated.promoted,
138+
})
126139
} else {
127-
param_env_and_substs
140+
param_env_and
128141
};
129142

130143
// FIXME(eddyb) maybe the `const_eval_*` methods should take
131-
// `ty::ParamEnvAnd<SubstsRef>` instead of having them separate.
132-
let (param_env, substs) = param_env_and_substs.into_parts();
144+
// `ty::ParamEnvAnd` instead of having them separate.
145+
let (param_env, unevaluated) = param_env_and.into_parts();
133146
// try to resolve e.g. associated constants to their definition on an impl, and then
134147
// evaluate the const.
135-
match tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, None)
136-
{
148+
match tcx.const_eval_resolve(param_env, unevaluated, None) {
137149
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
138150
// and we use the original type, so nothing from `substs`
139151
// (which may be identity substs, see above),

compiler/rustc_middle/src/ty/flags.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ impl FlagComputation {
295295
}
296296

297297
fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'tcx>) {
298-
self.add_substs(ct.substs);
298+
// TODO
299+
self.add_substs(ct.non_default_substs.unwrap());
299300
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
300301
}
301302

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,9 @@ pub trait PrettyPrinter<'tcx>:
915915
}
916916

917917
match ct.val {
918-
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
918+
ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs, promoted }) => {
919+
// TODO
920+
let substs = non_default_substs.unwrap();
919921
if let Some(promoted) = promoted {
920922
p!(print_value_path(def.did, substs));
921923
p!(write("::{:?}", promoted));

compiler/rustc_middle/src/ty/relate.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
590590
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
591591
if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() =>
592592
{
593-
if tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) {
593+
if tcx.try_unify_abstract_consts(((au.def, au.substs(tcx)), (bu.def, bu.substs(tcx)))) {
594594
Ok(a.val)
595595
} else {
596596
Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
@@ -603,11 +603,14 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
603603
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
604604
if au.def == bu.def && au.promoted == bu.promoted =>
605605
{
606-
let substs =
607-
relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?;
606+
let substs = relation.relate_with_variance(
607+
ty::Variance::Invariant,
608+
au.substs(tcx),
609+
bu.substs(tcx),
610+
)?;
608611
Ok(ty::ConstKind::Unevaluated(ty::Unevaluated {
609612
def: au.def,
610-
substs,
613+
non_default_substs: Some(substs),
611614
promoted: au.promoted,
612615
}))
613616
}

compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,13 +1031,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
10311031
match self {
10321032
ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)),
10331033
ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)),
1034-
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
1035-
ty::ConstKind::Unevaluated(ty::Unevaluated {
1036-
def,
1037-
substs: substs.fold_with(folder),
1038-
promoted,
1039-
})
1040-
}
1034+
ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)),
10411035
ty::ConstKind::Value(_)
10421036
| ty::ConstKind::Bound(..)
10431037
| ty::ConstKind::Placeholder(..)
@@ -1049,7 +1043,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
10491043
match *self {
10501044
ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
10511045
ty::ConstKind::Param(p) => p.visit_with(visitor),
1052-
ty::ConstKind::Unevaluated(ct) => ct.substs.visit_with(visitor),
1046+
ty::ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
10531047
ty::ConstKind::Value(_)
10541048
| ty::ConstKind::Bound(..)
10551049
| ty::ConstKind::Placeholder(_)
@@ -1067,3 +1061,17 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
10671061
ControlFlow::CONTINUE
10681062
}
10691063
}
1064+
1065+
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
1066+
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
1067+
ty::Unevaluated {
1068+
def: self.def,
1069+
non_default_substs: Some(self.substs(folder.tcx()).fold_with(folder)),
1070+
promoted: self.promoted,
1071+
}
1072+
}
1073+
1074+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1075+
self.substs(visitor.tcx_for_anon_const_substs()).visit_with(visitor)
1076+
}
1077+
}

0 commit comments

Comments
 (0)