Skip to content

Commit 758ff39

Browse files
committed
Auto merge of rust-lang#125958 - BoxyUwU:remove_const_ty, r=lcnr,aDotInTheVoid
Remove the `ty` field from type system `Const`s 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) This is based on top of rust-lang#125967 and rust-lang#125968, and as such should not be merged until those are merged. --- 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 rust-lang#125671's description for some more information about the `ty` field --- General summary of changes in this PR: - Change how we represent `ty::Expr` from `generic_const_exprs` to not explode the size of `Const` in this PR (This doesn't really matter, I just didn't want to Completely break generic const exprs just yet) - 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`. - SMIR represents mir consts and ty consts using the same `Const` type. This... does not work at all anymore so I have split them into two different types in SMIR and it seems to make everything a lot nicer regardless of this PR. - rustdoc has its own `Const` which also has a `ty` field. It was relatively easy to remove this. --- r? `@lcnr` `@compiler-errors`
2 parents a330e49 + 50c503a commit 758ff39

File tree

149 files changed

+1159
-1228
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

+1159
-1228
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
@@ -386,16 +386,8 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
386386
Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
387387
}
388388

389-
fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
390-
let ty = self.tcx.fold_regions(ty, |r, _| match *r {
391-
rustc_type_ir::RegionKind::ReStatic => r,
392-
393-
// This is never reached in practice. If it ever is reached,
394-
// `ReErased` should be changed to `ReStatic`, and any other region
395-
// left alone.
396-
r => bug!("unexpected region: {r:?}"),
397-
});
398-
ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant")
389+
fn ct_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
390+
ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
399391
}
400392

401393
fn probe_ty_param_bounds(

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

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

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
366366
},
367367
)
368368
});
369-
let ty = tcx
370-
.type_of(param.def_id)
371-
.no_bound_vars()
372-
.expect("ct params cannot have early bound vars");
373-
ty::Const::new_error(tcx, guar, ty).into()
369+
ty::Const::new_error(tcx, guar).into()
374370
}
375371
};
376372
num_bound_vars += 1;

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+24-32
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,7 @@ pub trait HirTyLowerer<'tcx> {
103103
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
104104

105105
/// Returns the const to use when a const is omitted.
106-
fn ct_infer(
107-
&self,
108-
ty: Ty<'tcx>,
109-
param: Option<&ty::GenericParamDef>,
110-
span: Span,
111-
) -> Const<'tcx>;
106+
fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
112107

113108
/// Probe bounds in scope where the bounded type coincides with the given type parameter.
114109
///
@@ -438,15 +433,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
438433

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

447442
if let Err(incorrect) = self.incorrect_args {
448443
if incorrect.invalid_args.contains(&(param.index as usize)) {
449-
return param.to_error(tcx, preceding_args);
444+
return param.to_error(tcx);
450445
}
451446
}
452447

@@ -491,16 +486,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
491486
ty::Const::from_anon_const(tcx, did).into()
492487
}
493488
(&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
494-
let ty = tcx
495-
.at(self.span)
496-
.type_of(param.def_id)
497-
.no_bound_vars()
498-
.expect("const parameter types cannot be generic");
499489
if self.lowerer.allow_infer() {
500-
self.lowerer.ct_infer(ty, Some(param), inf.span).into()
490+
self.lowerer.ct_infer(Some(param), inf.span).into()
501491
} else {
502492
self.inferred_params.push(inf.span);
503-
ty::Const::new_misc_error(tcx, ty).into()
493+
ty::Const::new_misc_error(tcx).into()
504494
}
505495
}
506496
(kind, arg) => span_bug!(
@@ -520,7 +510,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
520510

521511
if let Err(incorrect) = self.incorrect_args {
522512
if incorrect.invalid_args.contains(&(param.index as usize)) {
523-
return param.to_error(tcx, preceding_args);
513+
return param.to_error(tcx);
524514
}
525515
}
526516
match param.kind {
@@ -568,7 +558,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
568558
.no_bound_vars()
569559
.expect("const parameter types cannot be generic");
570560
if let Err(guar) = ty.error_reported() {
571-
return ty::Const::new_error(tcx, guar, ty).into();
561+
return ty::Const::new_error(tcx, guar).into();
572562
}
573563
// FIXME(effects) see if we should special case effect params here
574564
if !infer_args && has_default {
@@ -577,10 +567,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
577567
.into()
578568
} else {
579569
if infer_args {
580-
self.lowerer.ct_infer(ty, Some(param), self.span).into()
570+
self.lowerer.ct_infer(Some(param), self.span).into()
581571
} else {
582572
// We've already errored above about the mismatch.
583-
ty::Const::new_misc_error(tcx, ty).into()
573+
ty::Const::new_misc_error(tcx).into()
584574
}
585575
}
586576
}
@@ -1930,7 +1920,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19301920
///
19311921
/// Early-bound const parameters get lowered to [`ty::ConstKind::Param`]
19321922
/// and late-bound ones to [`ty::ConstKind::Bound`].
1933-
pub(crate) fn lower_const_param(&self, hir_id: HirId, param_ty: Ty<'tcx>) -> Const<'tcx> {
1923+
pub(crate) fn lower_const_param(&self, hir_id: HirId) -> Const<'tcx> {
19341924
let tcx = self.tcx();
19351925
match tcx.named_bound_var(hir_id) {
19361926
Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
@@ -1940,12 +1930,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19401930
let generics = tcx.generics_of(item_def_id);
19411931
let index = generics.param_def_id_to_index[&def_id];
19421932
let name = tcx.item_name(def_id);
1943-
ty::Const::new_param(tcx, ty::ParamConst::new(index, name), param_ty)
1933+
ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
19441934
}
19451935
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
1946-
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index), param_ty)
1936+
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
19471937
}
1948-
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar, param_ty),
1938+
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
19491939
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id),
19501940
}
19511941
}
@@ -2161,7 +2151,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21612151
}
21622152
hir::TyKind::Array(ty, length) => {
21632153
let length = match length {
2164-
hir::ArrayLen::Infer(inf) => self.ct_infer(tcx.types.usize, None, inf.span),
2154+
hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
21652155
hir::ArrayLen::Body(constant) => {
21662156
ty::Const::from_anon_const(tcx, constant.def_id)
21672157
}
@@ -2192,17 +2182,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21922182
}
21932183
_ => (expr, None),
21942184
};
2195-
let c = match &expr.kind {
2185+
let (c, c_ty) = match &expr.kind {
21962186
hir::ExprKind::Lit(lit) => {
21972187
let lit_input =
21982188
LitToConstInput { lit: &lit.node, ty, neg: neg.is_some() };
2199-
match tcx.lit_to_const(lit_input) {
2189+
let ct = match tcx.lit_to_const(lit_input) {
22002190
Ok(c) => c,
22012191
Err(LitToConstError::Reported(err)) => {
2202-
ty::Const::new_error(tcx, err, ty)
2192+
ty::Const::new_error(tcx, err)
22032193
}
22042194
Err(LitToConstError::TypeError) => todo!(),
2205-
}
2195+
};
2196+
(ct, ty)
22062197
}
22072198

22082199
hir::ExprKind::Path(hir::QPath::Resolved(
@@ -2220,19 +2211,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22202211
.type_of(def_id)
22212212
.no_bound_vars()
22222213
.expect("const parameter types cannot be generic");
2223-
self.lower_const_param(expr.hir_id, ty)
2214+
let ct = self.lower_const_param(expr.hir_id);
2215+
(ct, ty)
22242216
}
22252217

22262218
_ => {
22272219
let err = tcx
22282220
.dcx()
22292221
.emit_err(crate::errors::NonConstRange { span: expr.span });
2230-
ty::Const::new_error(tcx, err, ty)
2222+
(ty::Const::new_error(tcx, err), Ty::new_error(tcx, err))
22312223
}
22322224
};
2233-
self.record_ty(expr.hir_id, c.ty(), expr.span);
2225+
self.record_ty(expr.hir_id, c_ty, expr.span);
22342226
if let Some((id, span)) = neg {
2235-
self.record_ty(id, c.ty(), span);
2227+
self.record_ty(id, c_ty, span);
22362228
}
22372229
c
22382230
};

compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs

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

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

0 commit comments

Comments
 (0)