Skip to content

Commit d54bb8c

Browse files
committed
Use ConstArg for assoc item constraints
1 parent 8b6a4d8 commit d54bb8c

File tree

10 files changed

+100
-55
lines changed

10 files changed

+100
-55
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10431043
AssocItemConstraintKind::Equality { term } => {
10441044
let term = match term {
10451045
Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1046-
Term::Const(c) => self.lower_anon_const(c).into(),
1046+
Term::Const(c) => self.lower_anon_const_as_const_arg(c).into(),
10471047
};
10481048
hir::AssocItemConstraintKind::Equality { term }
10491049
}
@@ -1157,11 +1157,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11571157
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
11581158
None,
11591159
);
1160-
return GenericArg::Const(ConstArg {
1160+
let const_arg = ConstArg {
11611161
hir_id: self.next_id(),
11621162
kind: ConstArgKind::Path(qpath),
11631163
is_desugared_from_effects: false,
1164-
});
1164+
};
1165+
return GenericArg::Const(self.arena.alloc(const_arg));
11651166
}
11661167
}
11671168
}
@@ -1173,7 +1174,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11731174
}
11741175
}
11751176

1176-
fn lower_anon_const_as_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
1177+
fn lower_anon_const_as_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
1178+
self.arena.alloc(self.lower_anon_const_as_const_arg_direct(anon))
1179+
}
1180+
1181+
fn lower_anon_const_as_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
11771182
if let ExprKind::Path(qself, path) = &anon.value.kind
11781183
&& let Some(res) = self
11791184
.resolver
@@ -2656,11 +2661,11 @@ impl<'hir> GenericArgsCtor<'hir> {
26562661
}
26572662
};
26582663

2659-
self.args.push(hir::GenericArg::Const(hir::ConstArg {
2664+
self.args.push(hir::GenericArg::Const(lcx.arena.alloc(hir::ConstArg {
26602665
hir_id: lcx.next_id(),
26612666
kind: const_arg_kind,
26622667
is_desugared_from_effects: true,
2663-
}))
2668+
})))
26642669
}
26652670

26662671
fn is_empty(&self) -> bool {

compiler/rustc_hir/src/hir.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl InferArg {
268268
pub enum GenericArg<'hir> {
269269
Lifetime(&'hir Lifetime),
270270
Type(&'hir Ty<'hir>),
271-
Const(ConstArg<'hir>),
271+
Const(&'hir ConstArg<'hir>),
272272
Infer(InferArg),
273273
}
274274

@@ -2448,7 +2448,7 @@ impl<'hir> AssocItemConstraint<'hir> {
24482448
}
24492449

24502450
/// Obtain the const on the RHS of an assoc const equality constraint if applicable.
2451-
pub fn ct(self) -> Option<&'hir AnonConst> {
2451+
pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
24522452
match self.kind {
24532453
AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
24542454
_ => None,
@@ -2459,7 +2459,7 @@ impl<'hir> AssocItemConstraint<'hir> {
24592459
#[derive(Debug, Clone, Copy, HashStable_Generic)]
24602460
pub enum Term<'hir> {
24612461
Ty(&'hir Ty<'hir>),
2462-
Const(&'hir AnonConst),
2462+
Const(&'hir ConstArg<'hir>),
24632463
}
24642464

24652465
impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
@@ -2468,8 +2468,8 @@ impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
24682468
}
24692469
}
24702470

2471-
impl<'hir> From<&'hir AnonConst> for Term<'hir> {
2472-
fn from(c: &'hir AnonConst) -> Self {
2471+
impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
2472+
fn from(c: &'hir ConstArg<'hir>) -> Self {
24732473
Term::Const(c)
24742474
}
24752475
}
@@ -3952,7 +3952,7 @@ mod size_asserts {
39523952
static_assert_size!(FnDecl<'_>, 40);
39533953
static_assert_size!(ForeignItem<'_>, 72);
39543954
static_assert_size!(ForeignItemKind<'_>, 40);
3955-
static_assert_size!(GenericArg<'_>, 40);
3955+
static_assert_size!(GenericArg<'_>, 16);
39563956
static_assert_size!(GenericBound<'_>, 48);
39573957
static_assert_size!(Generics<'_>, 56);
39583958
static_assert_size!(Impl<'_>, 80);

compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
12921292
match constraint.kind {
12931293
AssocItemConstraintKind::Equality { ref term } => match term {
12941294
Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)),
1295-
Term::Const(ref c) => try_visit!(visitor.visit_anon_const(c)),
1295+
Term::Const(ref c) => try_visit!(visitor.visit_const_arg(c)),
12961296
},
12971297
AssocItemConstraintKind::Bound { bounds } => {
12981298
walk_list!(visitor, visit_param_bound, bounds)

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -410,12 +410,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
410410
});
411411

412412
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
413-
if let Some(anon_const) = constraint.ct() {
414-
let ty = alias_term
415-
.map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args));
416-
let ty =
417-
check_assoc_const_binding_type(tcx, constraint.ident, ty, constraint.hir_id);
418-
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
413+
if let Some(const_arg) = constraint.ct() {
414+
if let hir::ConstArgKind::Anon(anon_const) = const_arg.kind {
415+
let ty = alias_term
416+
.map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args));
417+
let ty = check_assoc_const_binding_type(
418+
tcx,
419+
constraint.ident,
420+
ty,
421+
constraint.hir_id,
422+
);
423+
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
424+
}
419425
}
420426

421427
alias_term
@@ -432,7 +438,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
432438
hir::AssocItemConstraintKind::Equality { term } => {
433439
let term = match term {
434440
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
435-
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
441+
hir::Term::Const(ct) => {
442+
ty::Const::from_const_arg(tcx, ct, assoc_item.def_id).into()
443+
}
436444
};
437445

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

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
340340
{
341341
let span = match term {
342342
hir::Term::Ty(ty) => ty.span,
343-
hir::Term::Const(ct) => tcx.def_span(ct.def_id),
343+
hir::Term::Const(ct) => ct.span(),
344344
};
345345
(span, Some(ident.span), assoc_item.kind, assoc_kind)
346346
} else {

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -476,18 +476,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
476476
(&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
477477
handle_ty_args(has_default, &inf.to_ty())
478478
}
479-
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => match ct.kind {
480-
hir::ConstArgKind::Path(qpath) => {
481-
// FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
482-
ty::Const::from_param(tcx, qpath, ct.hir_id).into()
483-
}
484-
hir::ConstArgKind::Anon(anon) => {
485-
let did = anon.def_id;
486-
tcx.feed_anon_const_type(did, tcx.type_of(param.def_id));
487-
ty::Const::from_anon_const(tcx, did).into()
488-
}
489-
},
490-
(&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
479+
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
480+
ty::Const::from_const_arg(tcx, ct, param.def_id).into()
481+
}
482+
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
491483
self.lowerer.ct_infer(Some(param), inf.span).into()
492484
}
493485
(kind, arg) => span_bug!(
@@ -907,12 +899,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
907899
let mut where_bounds = vec![];
908900
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
909901
let bound_id = bound.def_id();
910-
let bound_span = tcx
902+
let assoc_item = tcx
911903
.associated_items(bound_id)
912-
.find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
913-
.and_then(|item| tcx.hir().span_if_local(item.def_id));
904+
.find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id);
905+
let bound_span = assoc_item.and_then(|item| tcx.hir().span_if_local(item.def_id));
914906

915-
if let Some(bound_span) = bound_span {
907+
if let Some(assoc_item) = assoc_item
908+
&& let Some(bound_span) = bound_span
909+
{
916910
err.span_label(
917911
bound_span,
918912
format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
@@ -923,7 +917,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
923917
let term: ty::Term<'_> = match term {
924918
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
925919
hir::Term::Const(ct) => {
926-
ty::Const::from_anon_const(tcx, ct.def_id).into()
920+
ty::Const::from_const_arg(tcx, ct, assoc_item.def_id).into()
927921
}
928922
};
929923
// FIXME(#97583): This isn't syntactically well-formed!

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,7 @@ impl<'a> State<'a> {
17231723
self.word_space("=");
17241724
match term {
17251725
Term::Ty(ty) => self.print_type(ty),
1726-
Term::Const(ref c) => self.print_anon_const(c),
1726+
Term::Const(ref c) => self.print_const_arg(c),
17271727
}
17281728
}
17291729
hir::AssocItemConstraintKind::Bound { bounds } => {

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey};
88
use rustc_hir::def::{CtorOf, DefKind, Res};
99
use rustc_hir::def_id::DefId;
1010
use rustc_hir::lang_items::LangItem;
11-
use rustc_hir::{self as hir, ConstArg, ConstArgKind};
11+
use rustc_hir::{self as hir};
1212
use rustc_hir::{ExprKind, GenericArg, HirId, Node, QPath};
1313
use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend;
1414
use rustc_hir_analysis::hir_ty_lowering::generics::{
@@ -468,20 +468,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
468468

469469
pub fn lower_const_arg(
470470
&self,
471-
const_arg: &ConstArg<'tcx>,
471+
const_arg: &'tcx hir::ConstArg<'tcx>,
472472
param_def_id: DefId,
473473
) -> ty::Const<'tcx> {
474-
let ct = match const_arg.kind {
475-
ConstArgKind::Path(qpath) => {
476-
// FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
477-
ty::Const::from_param(self.tcx, qpath, const_arg.hir_id)
478-
}
479-
ConstArgKind::Anon(anon) => {
480-
let did = anon.def_id;
481-
self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id));
482-
ty::Const::from_anon_const(self.tcx, did)
483-
}
484-
};
474+
let ct = ty::Const::from_const_arg(self.tcx, const_arg, param_def_id);
485475
self.register_wf_obligation(
486476
ct.into(),
487477
self.tcx.hir().span(const_arg.hir_id),

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisita
44
use rustc_data_structures::intern::Interned;
55
use rustc_error_messages::MultiSpan;
66
use rustc_hir::def::{DefKind, Res};
7-
use rustc_hir::def_id::LocalDefId;
7+
use rustc_hir::def_id::{DefId, LocalDefId};
88
use rustc_hir::{self as hir, HirId};
99
use rustc_macros::HashStable;
1010
use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
@@ -179,6 +179,39 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
179179
}
180180

181181
impl<'tcx> Const<'tcx> {
182+
/// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self).
183+
///
184+
/// `param_def_id` is the [`DefId`] of the declared param that this [`ConstArg`] is being
185+
/// supplied to. We need this in case this `ConstArg` is a [`ConstArgKind::Anon`]
186+
/// so we can tell the [`AnonConst`] what type it should be.
187+
pub fn from_const_arg(
188+
tcx: TyCtxt<'tcx>,
189+
const_arg: &'tcx hir::ConstArg<'tcx>,
190+
param_def_id: DefId,
191+
) -> Self {
192+
if let hir::ConstArgKind::Anon(anon) = &const_arg.kind {
193+
tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id));
194+
}
195+
Self::from_const_arg_without_feeding(tcx, const_arg)
196+
}
197+
198+
/// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self), without feeding it its expected type.
199+
///
200+
/// This distinction is only relevant for [`hir::ConstArgKind::Anon`];
201+
/// see [`Self::from_const_arg_without_feeding`].
202+
pub fn from_const_arg_without_feeding(
203+
tcx: TyCtxt<'tcx>,
204+
const_arg: &'tcx hir::ConstArg<'tcx>,
205+
) -> Self {
206+
match const_arg.kind {
207+
hir::ConstArgKind::Path(qpath) => {
208+
// FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
209+
Self::from_param(tcx, qpath, const_arg.hir_id)
210+
}
211+
hir::ConstArgKind::Anon(anon) => Self::from_anon_const(tcx, anon.def_id),
212+
}
213+
}
214+
182215
/// Literals and const generic parameters are eagerly converted to a constant, everything else
183216
/// becomes `Unevaluated`.
184217
#[instrument(skip(tcx), level = "debug")]
@@ -212,7 +245,7 @@ impl<'tcx> Const<'tcx> {
212245
/// Lower a const param to a [`Const`].
213246
///
214247
/// IMPORTANT: `qpath` must be a const param, otherwise this will panic
215-
pub fn from_param(tcx: TyCtxt<'tcx>, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Self {
248+
fn from_param(tcx: TyCtxt<'tcx>, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Self {
216249
// FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
217250
// does not provide the parents generics to anonymous constants. We still allow generic const
218251
// parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
@@ -274,6 +307,21 @@ impl<'tcx> Const<'tcx> {
274307
}
275308
}
276309
}
310+
311+
// FIXME: this shouldn't panic, it's just temporary code
312+
match expr.kind {
313+
hir::ExprKind::Path(hir::QPath::Resolved(
314+
_,
315+
&hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
316+
)) => {
317+
span_bug!(
318+
expr.span,
319+
"try_from_lit: received const param which shouldn't be possible"
320+
)
321+
}
322+
_ => {}
323+
}
324+
277325
None
278326
}
279327

src/librustdoc/clean/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Te
433433
match term {
434434
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
435435
hir::Term::Const(c) => Term::Constant(clean_middle_const(
436-
ty::Binder::dummy(ty::Const::from_anon_const(cx.tcx, c.def_id)),
436+
ty::Binder::dummy(ty::Const::from_const_arg_without_feeding(cx.tcx, c)),
437437
cx,
438438
)),
439439
}

0 commit comments

Comments
 (0)