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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 38 additions & 33 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 3 additions & 3 deletions
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

Lines changed: 0 additions & 3 deletions
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

Lines changed: 2 additions & 10 deletions
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

Lines changed: 1 addition & 1 deletion
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
}

0 commit comments

Comments
 (0)