Skip to content

Commit 003a902

Browse files
committed
Auto merge of #125958 - BoxyUwU:remove_const_ty, r=lcnr
Remove the `ty` field from type system `Const`s Fixes #125556 Fixes #122908 Part of the work on `adt_const_params`/`generic_const_param_types`/`min_generic_const_exprs`/generally making the compiler nicer. cc rust-lang/project-const-generics#44 Please review commit-by-commit otherwise I wasted a lot of time not just squashing this into a giant mess (and also it'll be SO much nicer because theres a lot of fluff changes mixed in with other more careful changes if looking via File Changes --- Why do this? - The `ty` field keeps causing ICEs and weird behaviour due to it either being treated as "part of the const" or it being forgotten about leading to ICEs. - As we move forward with `adt_const_params` and a potential `min_generic_const_exprs` it's going to become more complex to actually lower the correct `Ty<'tcx>` - It muddles the idea behind how we check `Const` arguments have the correct type. By having the `ty` field it may seem like we ought to be relating it when we relate two types, or that its generally important information about the `Const`. - Brings the compiler more in line with `a-mir-formality` as that also tracks the type of type system `Const`s via `ConstArgHasType` bounds in the env instead of on the `Const` itself. - A lot of stuff is a lot nicer when you dont have to pass around the type of a const lol. Everywhere we construct `Const` is now significantly nicer 😅 See #125671's description for some more information about the `ty` field --- General summary of changes in this PR: - Add `Ty` to `ConstKind::Value` as otherwise there is no way to implement `ConstArgHasType` to ensure that const arguments are correctly typed for the parameter when we stop creating anon consts for all const args. It's also just incredibly difficult/annoying to thread the correct `Ty` around to a bunch of ctfe functions otherwise. - Fully implement `ConstArgHasType` in both the old and new solver. Since it now has no reliance on the `ty` field it serves its originally intended purpose of being able to act as a double check that trait vs impls have correctly typed const parameters. It also will now be able to be responsible for checking types of const arguments to parameters under `min_generic_const_exprs`. - Add `Ty` to `mir::Const::Ty`. I dont have a great understanding of why mir constants are setup like this to be honest. Regardless they need to be able to determine the type of the const and the easiest way to make this happen was to simply store the `Ty` along side the `ty::Const`. Maybe we can do better here in the future but I'd have to spend way more time looking at everywhere we use `mir::Const`. - rustdoc has its own `Const` which also has a `ty` field. It was relatively easy to remove this. --- r? `@lcnr` `@compiler-errors`
2 parents d0ccb54 + 3a6b606 commit 003a902

File tree

149 files changed

+1160
-1229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+1160
-1229
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
346346
} else {
347347
let tcx = self.tcx();
348348
let maybe_uneval = match constant.const_ {
349-
Const::Ty(ct) => match ct.kind() {
349+
Const::Ty(_, ct) => match ct.kind() {
350350
ty::ConstKind::Unevaluated(_) => {
351351
bug!("should not encounter unevaluated Const::Ty here, got {:?}", ct)
352352
}
@@ -1856,7 +1856,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18561856

18571857
if let Operand::Constant(constant) = op {
18581858
let maybe_uneval = match constant.const_ {
1859-
Const::Val(..) | Const::Ty(_) => None,
1859+
Const::Val(..) | Const::Ty(_, _) => None,
18601860
Const::Unevaluated(uv, _) => Some(uv),
18611861
};
18621862

compiler/rustc_borrowck/src/type_check/relate_tys.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
193193
types: &mut |_bound_ty: ty::BoundTy| {
194194
unreachable!("we only replace regions in nll_relate, not types")
195195
},
196-
consts: &mut |_bound_var: ty::BoundVar, _ty| {
196+
consts: &mut |_bound_var: ty::BoundVar| {
197197
unreachable!("we only replace regions in nll_relate, not consts")
198198
},
199199
};
@@ -231,7 +231,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
231231
types: &mut |_bound_ty: ty::BoundTy| {
232232
unreachable!("we only replace regions in nll_relate, not types")
233233
},
234-
consts: &mut |_bound_var: ty::BoundVar, _ty| {
234+
consts: &mut |_bound_var: ty::BoundVar| {
235235
unreachable!("we only replace regions in nll_relate, not consts")
236236
},
237237
};

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
133133
.expect_const()
134134
.eval(fx.tcx, ty::ParamEnv::reveal_all(), span)
135135
.unwrap()
136+
.1
136137
.unwrap_branch();
137138

138139
assert_eq!(x.layout(), y.layout());

compiler/rustc_codegen_llvm/src/intrinsic.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
12011201
.expect_const()
12021202
.eval(tcx, ty::ParamEnv::reveal_all(), span)
12031203
.unwrap()
1204+
.1
12041205
.unwrap_branch();
12051206
let n = idx.len() as u64;
12061207

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+38-33
Original file line numberDiff line numberDiff line change
@@ -693,41 +693,46 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
693693
ty::ConstKind::Param(param) => {
694694
write!(output, "{}", param.name)
695695
}
696-
_ => match ct.ty().kind() {
697-
ty::Int(ity) => {
698-
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
699-
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
700-
write!(output, "{val}")
701-
}
702-
ty::Uint(_) => {
703-
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
704-
write!(output, "{val}")
705-
}
706-
ty::Bool => {
707-
let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
708-
write!(output, "{val}")
709-
}
710-
_ => {
711-
// If we cannot evaluate the constant to a known type, we fall back
712-
// to emitting a stable hash value of the constant. This isn't very pretty
713-
// but we get a deterministic, virtually unique value for the constant.
714-
//
715-
// Let's only emit 64 bits of the hash value. That should be plenty for
716-
// avoiding collisions and will make the emitted type names shorter.
717-
let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
718-
let mut hasher = StableHasher::new();
719-
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
720-
hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
721-
hasher.finish::<Hash64>()
722-
});
723-
724-
if cpp_like_debuginfo(tcx) {
725-
write!(output, "CONST${hash_short:x}")
726-
} else {
727-
write!(output, "{{CONST#{hash_short:x}}}")
696+
ty::ConstKind::Value(ty, _) => {
697+
match ty.kind() {
698+
ty::Int(ity) => {
699+
// FIXME: directly extract the bits from a valtree instead of evaluating an
700+
// alreay evaluated `Const` in order to get the bits.
701+
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
702+
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
703+
write!(output, "{val}")
704+
}
705+
ty::Uint(_) => {
706+
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
707+
write!(output, "{val}")
708+
}
709+
ty::Bool => {
710+
let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
711+
write!(output, "{val}")
712+
}
713+
_ => {
714+
// If we cannot evaluate the constant to a known type, we fall back
715+
// to emitting a stable hash value of the constant. This isn't very pretty
716+
// but we get a deterministic, virtually unique value for the constant.
717+
//
718+
// Let's only emit 64 bits of the hash value. That should be plenty for
719+
// avoiding collisions and will make the emitted type names shorter.
720+
let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
721+
let mut hasher = StableHasher::new();
722+
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
723+
hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
724+
hasher.finish::<Hash64>()
725+
});
726+
727+
if cpp_like_debuginfo(tcx) {
728+
write!(output, "CONST${hash_short:x}")
729+
} else {
730+
write!(output, "{{CONST#{hash_short:x}}}")
731+
}
728732
}
729733
}
730-
},
734+
}
735+
_ => bug!("Invalid `Const` during codegen: {:?}", ct),
731736
}
732737
.unwrap();
733738
}

compiler/rustc_codegen_ssa/src/mir/constant.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
4040
) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> {
4141
let uv = match self.monomorphize(constant.const_) {
4242
mir::Const::Unevaluated(uv, _) => uv.shrink(),
43-
mir::Const::Ty(c) => match c.kind() {
43+
mir::Const::Ty(_, c) => match c.kind() {
4444
// A constant that came from a const generic but was then used as an argument to old-style
4545
// simd_shuffle (passing as argument instead of as a generic param).
46-
rustc_type_ir::ConstKind::Value(valtree) => return Ok(Some(valtree)),
46+
rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Some(valtree)),
4747
other => span_bug!(constant.span, "{other:#?}"),
4848
},
4949
// We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate

compiler/rustc_const_eval/src/check_consts/qualifs.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -357,15 +357,15 @@ where
357357

358358
// Check the qualifs of the value of `const` items.
359359
let uneval = match constant.const_ {
360-
Const::Ty(ct)
360+
Const::Ty(_, ct)
361361
if matches!(
362362
ct.kind(),
363-
ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_)
363+
ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_, _)
364364
) =>
365365
{
366366
None
367367
}
368-
Const::Ty(c) => {
368+
Const::Ty(_, c) => {
369369
bug!("expected ConstKind::Param or ConstKind::Value here, found {:?}", c)
370370
}
371371
Const::Unevaluated(uv, _) => Some(uv),

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

-3
Original file line numberDiff line numberDiff line change
@@ -2198,9 +2198,6 @@ fn param_env_with_gat_bounds<'tcx>(
21982198
tcx,
21992199
ty::INNERMOST,
22002200
ty::BoundVar::from_usize(bound_vars.len() - 1),
2201-
tcx.type_of(param.def_id)
2202-
.no_bound_vars()
2203-
.expect("const parameter types cannot be generic"),
22042201
)
22052202
.into()
22062203
}

compiler/rustc_hir_analysis/src/collect.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -396,16 +396,8 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
396396
Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
397397
}
398398

399-
fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
400-
let ty = self.tcx.fold_regions(ty, |r, _| match *r {
401-
rustc_type_ir::RegionKind::ReStatic => r,
402-
403-
// This is never reached in practice. If it ever is reached,
404-
// `ReErased` should be changed to `ReStatic`, and any other region
405-
// left alone.
406-
r => bug!("unexpected region: {r:?}"),
407-
});
408-
ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant")
399+
fn ct_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
400+
ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
409401
}
410402

411403
fn probe_ty_param_bounds(

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
196196
.type_of(param.def_id.to_def_id())
197197
.no_bound_vars()
198198
.expect("const parameters cannot be generic");
199-
let ct = icx.lowerer().lower_const_param(param.hir_id, ct_ty);
199+
let ct = icx.lowerer().lower_const_param(param.hir_id);
200200
predicates
201201
.insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span));
202202
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
368368
},
369369
)
370370
});
371-
let ty = tcx
372-
.type_of(param.def_id)
373-
.no_bound_vars()
374-
.expect("ct params cannot have early bound vars");
375-
ty::Const::new_error(tcx, guar, ty).into()
371+
ty::Const::new_error(tcx, guar).into()
376372
}
377373
};
378374
num_bound_vars += 1;

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+23-31
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,7 @@ pub trait HirTyLowerer<'tcx> {
111111
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
112112

113113
/// Returns the const to use when a const is omitted.
114-
fn ct_infer(
115-
&self,
116-
ty: Ty<'tcx>,
117-
param: Option<&ty::GenericParamDef>,
118-
span: Span,
119-
) -> Const<'tcx>;
114+
fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
120115

121116
/// Probe bounds in scope where the bounded type coincides with the given type parameter.
122117
///
@@ -439,15 +434,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
439434

440435
fn provided_kind(
441436
&mut self,
442-
preceding_args: &[ty::GenericArg<'tcx>],
437+
_preceding_args: &[ty::GenericArg<'tcx>],
443438
param: &ty::GenericParamDef,
444439
arg: &GenericArg<'tcx>,
445440
) -> ty::GenericArg<'tcx> {
446441
let tcx = self.lowerer.tcx();
447442

448443
if let Err(incorrect) = self.incorrect_args {
449444
if incorrect.invalid_args.contains(&(param.index as usize)) {
450-
return param.to_error(tcx, preceding_args);
445+
return param.to_error(tcx);
451446
}
452447
}
453448

@@ -487,12 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
487482
ty::Const::from_anon_const(tcx, did).into()
488483
}
489484
(&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
490-
let ty = tcx
491-
.at(self.span)
492-
.type_of(param.def_id)
493-
.no_bound_vars()
494-
.expect("const parameter types cannot be generic");
495-
self.lowerer.ct_infer(ty, Some(param), inf.span).into()
485+
self.lowerer.ct_infer(Some(param), inf.span).into()
496486
}
497487
(kind, arg) => span_bug!(
498488
self.span,
@@ -511,7 +501,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
511501

512502
if let Err(incorrect) = self.incorrect_args {
513503
if incorrect.invalid_args.contains(&(param.index as usize)) {
514-
return param.to_error(tcx, preceding_args);
504+
return param.to_error(tcx);
515505
}
516506
}
517507
match param.kind {
@@ -548,7 +538,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
548538
.no_bound_vars()
549539
.expect("const parameter types cannot be generic");
550540
if let Err(guar) = ty.error_reported() {
551-
return ty::Const::new_error(tcx, guar, ty).into();
541+
return ty::Const::new_error(tcx, guar).into();
552542
}
553543
// FIXME(effects) see if we should special case effect params here
554544
if !infer_args && has_default {
@@ -557,10 +547,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
557547
.into()
558548
} else {
559549
if infer_args {
560-
self.lowerer.ct_infer(ty, Some(param), self.span).into()
550+
self.lowerer.ct_infer(Some(param), self.span).into()
561551
} else {
562552
// We've already errored above about the mismatch.
563-
ty::Const::new_misc_error(tcx, ty).into()
553+
ty::Const::new_misc_error(tcx).into()
564554
}
565555
}
566556
}
@@ -1908,7 +1898,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19081898
///
19091899
/// Early-bound const parameters get lowered to [`ty::ConstKind::Param`]
19101900
/// and late-bound ones to [`ty::ConstKind::Bound`].
1911-
pub(crate) fn lower_const_param(&self, hir_id: HirId, param_ty: Ty<'tcx>) -> Const<'tcx> {
1901+
pub(crate) fn lower_const_param(&self, hir_id: HirId) -> Const<'tcx> {
19121902
let tcx = self.tcx();
19131903
match tcx.named_bound_var(hir_id) {
19141904
Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
@@ -1918,12 +1908,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19181908
let generics = tcx.generics_of(item_def_id);
19191909
let index = generics.param_def_id_to_index[&def_id];
19201910
let name = tcx.item_name(def_id);
1921-
ty::Const::new_param(tcx, ty::ParamConst::new(index, name), param_ty)
1911+
ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
19221912
}
19231913
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
1924-
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index), param_ty)
1914+
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
19251915
}
1926-
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar, param_ty),
1916+
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
19271917
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id),
19281918
}
19291919
}
@@ -2139,7 +2129,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21392129
}
21402130
hir::TyKind::Array(ty, length) => {
21412131
let length = match length {
2142-
hir::ArrayLen::Infer(inf) => self.ct_infer(tcx.types.usize, None, inf.span),
2132+
hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
21432133
hir::ArrayLen::Body(constant) => {
21442134
ty::Const::from_anon_const(tcx, constant.def_id)
21452135
}
@@ -2170,17 +2160,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21702160
}
21712161
_ => (expr, None),
21722162
};
2173-
let c = match &expr.kind {
2163+
let (c, c_ty) = match &expr.kind {
21742164
hir::ExprKind::Lit(lit) => {
21752165
let lit_input =
21762166
LitToConstInput { lit: &lit.node, ty, neg: neg.is_some() };
2177-
match tcx.lit_to_const(lit_input) {
2167+
let ct = match tcx.lit_to_const(lit_input) {
21782168
Ok(c) => c,
21792169
Err(LitToConstError::Reported(err)) => {
2180-
ty::Const::new_error(tcx, err, ty)
2170+
ty::Const::new_error(tcx, err)
21812171
}
21822172
Err(LitToConstError::TypeError) => todo!(),
2183-
}
2173+
};
2174+
(ct, ty)
21842175
}
21852176

21862177
hir::ExprKind::Path(hir::QPath::Resolved(
@@ -2198,19 +2189,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21982189
.type_of(def_id)
21992190
.no_bound_vars()
22002191
.expect("const parameter types cannot be generic");
2201-
self.lower_const_param(expr.hir_id, ty)
2192+
let ct = self.lower_const_param(expr.hir_id);
2193+
(ct, ty)
22022194
}
22032195

22042196
_ => {
22052197
let err = tcx
22062198
.dcx()
22072199
.emit_err(crate::errors::NonConstRange { span: expr.span });
2208-
ty::Const::new_error(tcx, err, ty)
2200+
(ty::Const::new_error(tcx, err), Ty::new_error(tcx, err))
22092201
}
22102202
};
2211-
self.record_ty(expr.hir_id, c.ty(), expr.span);
2203+
self.record_ty(expr.hir_id, c_ty, expr.span);
22122204
if let Some((id, span)) = neg {
2213-
self.record_ty(id, c.ty(), span);
2205+
self.record_ty(id, c_ty, span);
22142206
}
22152207
c
22162208
};

compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
143143
// `trait_object_dummy_self`, so check for that.
144144
let references_self = match pred.skip_binder().term.unpack() {
145145
ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
146-
ty::TermKind::Const(c) => {
147-
c.ty().walk().any(|arg| arg == dummy_self.into())
148-
}
146+
// FIXME(associated_const_equality): We should walk the const instead of not doing anything
147+
ty::TermKind::Const(_) => false,
149148
};
150149

151150
// If the projection output contains `Self`, force the user to

compiler/rustc_hir_typeck/src/demand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
350350
lt_op: |_| self.tcx.lifetimes.re_erased,
351351
ct_op: |ct| {
352352
if let ty::ConstKind::Infer(_) = ct.kind() {
353-
self.next_const_var(ct.ty(), DUMMY_SP)
353+
self.next_const_var(DUMMY_SP)
354354
} else {
355355
ct
356356
}

0 commit comments

Comments
 (0)