Skip to content

Commit ee1adb3

Browse files
committed
Move Const::from_const_arg to HIR ty lowering
This makes more sense and will allow us to start lowering all paths to `ConstArgKind::Path`, rather than just bare params.
1 parent ccc417b commit ee1adb3

File tree

8 files changed

+128
-114
lines changed

8 files changed

+128
-114
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use tracing::{debug, instrument};
4646

4747
use crate::check::intrinsic::intrinsic_operation_unsafety;
4848
use crate::errors;
49-
use crate::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
49+
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
5050

5151
pub(crate) mod dump;
5252
mod generics_of;
@@ -88,6 +88,7 @@ pub fn provide(providers: &mut Providers) {
8888
coroutine_for_closure,
8989
opaque_ty_origin,
9090
rendered_precise_capturing_args,
91+
const_param_default,
9192
..*providers
9293
};
9394
}
@@ -1790,3 +1791,22 @@ fn rendered_precise_capturing_args<'tcx>(
17901791
_ => None,
17911792
})
17921793
}
1794+
1795+
fn const_param_default<'tcx>(
1796+
tcx: TyCtxt<'tcx>,
1797+
def_id: LocalDefId,
1798+
) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
1799+
let default_ct = match tcx.hir_node_by_def_id(def_id) {
1800+
hir::Node::GenericParam(hir::GenericParam {
1801+
kind: hir::GenericParamKind::Const { default: Some(ct), .. },
1802+
..
1803+
}) => ct,
1804+
_ => span_bug!(
1805+
tcx.def_span(def_id),
1806+
"`const_param_default` expected a generic parameter with a constant"
1807+
),
1808+
};
1809+
let icx = ItemCtxt::new(tcx, def_id);
1810+
let ct = icx.lowerer().lower_const_arg(default_ct, FeedConstTy::No);
1811+
ty::EarlyBinder::bind(ct)
1812+
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use tracing::{debug, instrument};
1919
use super::errors::GenericsArgsErrExtend;
2020
use crate::bounds::Bounds;
2121
use crate::errors;
22-
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer, PredicateFilter, RegionInferReason};
22+
use crate::hir_ty_lowering::{
23+
AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason,
24+
};
2325

2426
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2527
/// Add a `Sized` bound to the `bounds` if appropriate.
@@ -352,9 +354,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
352354
hir::AssocItemConstraintKind::Equality { term } => {
353355
let term = match term {
354356
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
355-
hir::Term::Const(ct) => {
356-
ty::Const::from_const_arg(tcx, ct, ty::FeedConstTy::No).into()
357-
}
357+
hir::Term::Const(ct) => self.lower_const_arg(ct, FeedConstTy::No).into(),
358358
};
359359

360360
// Find any late-bound regions declared in `ty` that are not

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,23 @@ impl AssocItemQSelf {
218218
}
219219
}
220220

221+
/// In some cases, [`hir::ConstArg`]s that are being used in the type system
222+
/// through const generics need to have their type "fed" to them
223+
/// using the query system.
224+
///
225+
/// Use this enum with [`Const::from_const_arg`] to instruct it with the
226+
/// desired behavior.
227+
#[derive(Debug, Clone, Copy)]
228+
pub enum FeedConstTy {
229+
/// Feed the type.
230+
///
231+
/// The `DefId` belongs to the const param that we are supplying
232+
/// this (anon) const arg to.
233+
Param(DefId),
234+
/// Don't feed the type.
235+
No,
236+
}
237+
221238
/// New-typed boolean indicating whether explicit late-bound lifetimes
222239
/// are present in a set of generic arguments.
223240
///
@@ -501,8 +518,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
501518
handle_ty_args(has_default, &inf.to_ty())
502519
}
503520
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
504-
ty::Const::from_const_arg(tcx, ct, ty::FeedConstTy::Param(param.def_id))
505-
.into()
521+
self.lowerer.lower_const_arg(ct, FeedConstTy::Param(param.def_id)).into()
506522
}
507523
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
508524
self.lowerer.ct_infer(Some(param), inf.span).into()
@@ -957,8 +973,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
957973
let term: ty::Term<'_> = match term {
958974
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
959975
hir::Term::Const(ct) => {
960-
ty::Const::from_const_arg(tcx, ct, ty::FeedConstTy::No)
961-
.into()
976+
self.lower_const_arg(ct, FeedConstTy::No).into()
962977
}
963978
};
964979
// FIXME(#97583): This isn't syntactically well-formed!
@@ -2023,6 +2038,60 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20232038
}
20242039
}
20252040

2041+
/// Convert a [`hir::ConstArg`] to a [`ty::Const`](Const).
2042+
#[instrument(skip(self), level = "debug")]
2043+
pub fn lower_const_arg(
2044+
&self,
2045+
const_arg: &hir::ConstArg<'tcx>,
2046+
feed: FeedConstTy,
2047+
) -> Const<'tcx> {
2048+
let tcx = self.tcx();
2049+
2050+
if let FeedConstTy::Param(param_def_id) = feed
2051+
&& let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2052+
{
2053+
tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id));
2054+
}
2055+
2056+
match const_arg.kind {
2057+
hir::ConstArgKind::Path(qpath) => {
2058+
// FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path
2059+
self.lower_const_arg_param(qpath, const_arg.hir_id)
2060+
}
2061+
hir::ConstArgKind::Anon(anon) => Const::from_anon_const(tcx, anon.def_id),
2062+
}
2063+
}
2064+
2065+
/// Lower a use of a const param to a [`Const`].
2066+
///
2067+
/// IMPORTANT: `qpath` must be a const param, otherwise this will panic
2068+
fn lower_const_arg_param(&self, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Const<'tcx> {
2069+
let tcx = self.tcx();
2070+
2071+
let hir::QPath::Resolved(_, &hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. }) =
2072+
qpath
2073+
else {
2074+
span_bug!(qpath.span(), "non-param {qpath:?} passed to Const::from_param")
2075+
};
2076+
2077+
match tcx.named_bound_var(hir_id) {
2078+
Some(rbv::ResolvedArg::EarlyBound(_)) => {
2079+
// Find the name and index of the const parameter by indexing the generics of
2080+
// the parent item and construct a `ParamConst`.
2081+
let item_def_id = tcx.parent(def_id);
2082+
let generics = tcx.generics_of(item_def_id);
2083+
let index = generics.param_def_id_to_index[&def_id];
2084+
let name = tcx.item_name(def_id);
2085+
ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2086+
}
2087+
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2088+
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
2089+
}
2090+
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2091+
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id),
2092+
}
2093+
}
2094+
20262095
fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
20272096
let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
20282097
match idx {
@@ -2160,7 +2229,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21602229
let length = match length {
21612230
hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
21622231
hir::ArrayLen::Body(constant) => {
2163-
ty::Const::from_const_arg(tcx, constant, ty::FeedConstTy::No)
2232+
self.lower_const_arg(constant, FeedConstTy::No)
21642233
}
21652234
};
21662235

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,15 @@ use rustc_hir::def::DefKind;
9696
use rustc_middle::middle;
9797
use rustc_middle::mir::interpret::GlobalId;
9898
use rustc_middle::query::Providers;
99-
use rustc_middle::ty::{self, Ty, TyCtxt};
99+
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
100100
use rustc_session::parse::feature_err;
101101
use rustc_span::Span;
102102
use rustc_span::symbol::sym;
103103
use rustc_target::spec::abi::Abi;
104104
use rustc_trait_selection::traits;
105105

106+
use self::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
107+
106108
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
107109

108110
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
@@ -221,3 +223,13 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
221223
let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
222224
collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty)
223225
}
226+
227+
/// This is for rustdoc and clippy.
228+
pub fn lower_const_arg<'tcx>(
229+
tcx: TyCtxt<'tcx>,
230+
hir_ct: &hir::ConstArg<'tcx>,
231+
feed: FeedConstTy,
232+
) -> Const<'tcx> {
233+
let env_def_id = tcx.hir().get_parent_item(hir_ct.hir_id);
234+
collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)
235+
}

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{
1313
check_generic_arg_count_for_call, lower_generic_args,
1414
};
1515
use rustc_hir_analysis::hir_ty_lowering::{
16-
ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
17-
GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
16+
ExplicitLateBound, FeedConstTy, GenericArgCountMismatch, GenericArgCountResult,
17+
GenericArgsLowerer, GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
1818
};
1919
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
2020
use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
@@ -469,7 +469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
469469
hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
470470
hir::ArrayLen::Body(const_arg) => {
471471
let span = const_arg.span();
472-
let c = ty::Const::from_const_arg(self.tcx, const_arg, ty::FeedConstTy::No);
472+
let c = self.lowerer().lower_const_arg(const_arg, FeedConstTy::No);
473473
self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None));
474474
self.normalize(span, c)
475475
}
@@ -481,8 +481,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
481481
const_arg: &'tcx hir::ConstArg<'tcx>,
482482
param_def_id: DefId,
483483
) -> ty::Const<'tcx> {
484-
let ct =
485-
ty::Const::from_const_arg(self.tcx, const_arg, ty::FeedConstTy::Param(param_def_id));
484+
let ct = self.lowerer().lower_const_arg(const_arg, FeedConstTy::Param(param_def_id));
486485
self.register_wf_obligation(
487486
ct.into(),
488487
self.tcx.hir().span(const_arg.hir_id),

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 2 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ use either::Either;
22
use rustc_data_structures::intern::Interned;
33
use rustc_error_messages::MultiSpan;
44
use rustc_hir::def::{DefKind, Res};
5-
use rustc_hir::def_id::{DefId, LocalDefId};
6-
use rustc_hir::{self as hir, HirId};
5+
use rustc_hir::def_id::LocalDefId;
6+
use rustc_hir::{self as hir};
77
use rustc_macros::HashStable;
88
use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
99
use tracing::{debug, instrument};
1010

11-
use crate::middle::resolve_bound_vars as rbv;
1211
use crate::mir::interpret::{ErrorHandled, LitToConstInput, Scalar};
1312
use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
1413

@@ -184,46 +183,7 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
184183
}
185184
}
186185

187-
/// In some cases, [`hir::ConstArg`]s that are being used in the type system
188-
/// through const generics need to have their type "fed" to them
189-
/// using the query system.
190-
///
191-
/// Use this enum with [`Const::from_const_arg`] to instruct it with the
192-
/// desired behavior.
193-
#[derive(Debug, Clone, Copy)]
194-
pub enum FeedConstTy {
195-
/// Feed the type.
196-
///
197-
/// The `DefId` belongs to the const param that we are supplying
198-
/// this (anon) const arg to.
199-
Param(DefId),
200-
/// Don't feed the type.
201-
No,
202-
}
203-
204186
impl<'tcx> Const<'tcx> {
205-
/// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self).
206-
#[instrument(skip(tcx), level = "debug")]
207-
pub fn from_const_arg(
208-
tcx: TyCtxt<'tcx>,
209-
const_arg: &'tcx hir::ConstArg<'tcx>,
210-
feed: FeedConstTy,
211-
) -> Self {
212-
if let FeedConstTy::Param(param_def_id) = feed
213-
&& let hir::ConstArgKind::Anon(anon) = &const_arg.kind
214-
{
215-
tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id));
216-
}
217-
218-
match const_arg.kind {
219-
hir::ConstArgKind::Path(qpath) => {
220-
// FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path
221-
Self::from_param(tcx, qpath, const_arg.hir_id)
222-
}
223-
hir::ConstArgKind::Anon(anon) => Self::from_anon_const(tcx, anon.def_id),
224-
}
225-
}
226-
227187
/// Literals and const generic parameters are eagerly converted to a constant, everything else
228188
/// becomes `Unevaluated`.
229189
#[instrument(skip(tcx), level = "debug")]
@@ -250,34 +210,6 @@ impl<'tcx> Const<'tcx> {
250210
}
251211
}
252212

253-
/// Lower a const param to a [`Const`].
254-
///
255-
/// IMPORTANT: `qpath` must be a const param, otherwise this will panic
256-
fn from_param(tcx: TyCtxt<'tcx>, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Self {
257-
let hir::QPath::Resolved(_, &hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. }) =
258-
qpath
259-
else {
260-
span_bug!(qpath.span(), "non-param {qpath:?} passed to Const::from_param")
261-
};
262-
263-
match tcx.named_bound_var(hir_id) {
264-
Some(rbv::ResolvedArg::EarlyBound(_)) => {
265-
// Find the name and index of the const parameter by indexing the generics of
266-
// the parent item and construct a `ParamConst`.
267-
let item_def_id = tcx.parent(def_id);
268-
let generics = tcx.generics_of(item_def_id);
269-
let index = generics.param_def_id_to_index[&def_id];
270-
let name = tcx.item_name(def_id);
271-
ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
272-
}
273-
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
274-
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
275-
}
276-
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
277-
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id),
278-
}
279-
}
280-
281213
#[instrument(skip(tcx), level = "debug")]
282214
fn try_from_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option<Self> {
283215
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
@@ -460,20 +392,3 @@ impl<'tcx> Const<'tcx> {
460392
matches!(self.kind(), ty::ConstKind::Infer(_))
461393
}
462394
}
463-
464-
pub fn const_param_default<'tcx>(
465-
tcx: TyCtxt<'tcx>,
466-
def_id: LocalDefId,
467-
) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
468-
let default_ct = match tcx.hir_node_by_def_id(def_id) {
469-
hir::Node::GenericParam(hir::GenericParam {
470-
kind: hir::GenericParamKind::Const { default: Some(ct), .. },
471-
..
472-
}) => ct,
473-
_ => span_bug!(
474-
tcx.def_span(def_id),
475-
"`const_param_default` expected a generic parameter with a constant"
476-
),
477-
};
478-
ty::EarlyBinder::bind(Const::from_const_arg(tcx, default_ct, FeedConstTy::No))
479-
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub use self::closure::{
7070
place_to_string_for_capture,
7171
};
7272
pub use self::consts::{
73-
Const, ConstInt, ConstKind, Expr, ExprKind, FeedConstTy, ScalarInt, UnevaluatedConst, ValTree,
73+
Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree,
7474
};
7575
pub use self::context::{
7676
CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt,
@@ -2160,7 +2160,6 @@ pub fn provide(providers: &mut Providers) {
21602160
incoherent_impls: trait_def::incoherent_impls_provider,
21612161
trait_impls_in_crate: trait_def::trait_impls_in_crate_provider,
21622162
traits: trait_def::traits_provider,
2163-
const_param_default: consts::const_param_default,
21642163
vtable_allocation: vtable::vtable_allocation_provider,
21652164
..*providers
21662165
};

0 commit comments

Comments
 (0)