Skip to content

Commit 586600f

Browse files
committed
Use ConstArg for assoc item constraints
1 parent 98df547 commit 586600f

File tree

10 files changed

+96
-53
lines changed

10 files changed

+96
-53
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10461046
AssocItemConstraintKind::Equality { term } => {
10471047
let term = match term {
10481048
Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1049-
Term::Const(c) => self.lower_anon_const(c).into(),
1049+
Term::Const(c) => self.lower_anon_const_as_const_arg(c).into(),
10501050
};
10511051
hir::AssocItemConstraintKind::Equality { term }
10521052
}
@@ -1160,11 +1160,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11601160
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
11611161
None,
11621162
);
1163-
return GenericArg::Const(ConstArg {
1163+
let const_arg = ConstArg {
11641164
hir_id: self.next_id(),
11651165
kind: ConstArgKind::Path(qpath),
11661166
is_desugared_from_effects: false,
1167-
});
1167+
};
1168+
return GenericArg::Const(self.arena.alloc(const_arg));
11681169
}
11691170
}
11701171
}
@@ -1176,7 +1177,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11761177
}
11771178
}
11781179

1179-
fn lower_anon_const_as_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
1180+
fn lower_anon_const_as_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
1181+
self.arena.alloc(self.lower_anon_const_as_const_arg_direct(anon))
1182+
}
1183+
1184+
fn lower_anon_const_as_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
11801185
if let ExprKind::Path(qself, path) = &anon.value.kind
11811186
&& let Some(res) = self
11821187
.resolver
@@ -2659,11 +2664,11 @@ impl<'hir> GenericArgsCtor<'hir> {
26592664
}
26602665
};
26612666

2662-
self.args.push(hir::GenericArg::Const(hir::ConstArg {
2667+
self.args.push(hir::GenericArg::Const(lcx.arena.alloc(hir::ConstArg {
26632668
hir_id: lcx.next_id(),
26642669
kind: const_arg_kind,
26652670
is_desugared_from_effects: true,
2666-
}))
2671+
})))
26672672
}
26682673

26692674
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

@@ -2433,7 +2433,7 @@ impl<'hir> AssocItemConstraint<'hir> {
24332433
}
24342434

24352435
/// Obtain the const on the RHS of an assoc const equality constraint if applicable.
2436-
pub fn ct(self) -> Option<&'hir AnonConst> {
2436+
pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
24372437
match self.kind {
24382438
AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
24392439
_ => None,
@@ -2444,7 +2444,7 @@ impl<'hir> AssocItemConstraint<'hir> {
24442444
#[derive(Debug, Clone, Copy, HashStable_Generic)]
24452445
pub enum Term<'hir> {
24462446
Ty(&'hir Ty<'hir>),
2447-
Const(&'hir AnonConst),
2447+
Const(&'hir ConstArg<'hir>),
24482448
}
24492449

24502450
impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
@@ -2453,8 +2453,8 @@ impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
24532453
}
24542454
}
24552455

2456-
impl<'hir> From<&'hir AnonConst> for Term<'hir> {
2457-
fn from(c: &'hir AnonConst) -> Self {
2456+
impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
2457+
fn from(c: &'hir ConstArg<'hir>) -> Self {
24582458
Term::Const(c)
24592459
}
24602460
}
@@ -3922,7 +3922,7 @@ mod size_asserts {
39223922
static_assert_size!(FnDecl<'_>, 40);
39233923
static_assert_size!(ForeignItem<'_>, 72);
39243924
static_assert_size!(ForeignItemKind<'_>, 40);
3925-
static_assert_size!(GenericArg<'_>, 40);
3925+
static_assert_size!(GenericArg<'_>, 16);
39263926
static_assert_size!(GenericBound<'_>, 48);
39273927
static_assert_size!(Generics<'_>, 56);
39283928
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
@@ -1279,7 +1279,7 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
12791279
match constraint.kind {
12801280
AssocItemConstraintKind::Equality { ref term } => match term {
12811281
Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)),
1282-
Term::Const(ref c) => try_visit!(visitor.visit_anon_const(c)),
1282+
Term::Const(ref c) => try_visit!(visitor.visit_const_arg(c)),
12831283
},
12841284
AssocItemConstraintKind::Bound { bounds } => {
12851285
walk_list!(visitor, visit_param_bound, bounds)

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
428428
});
429429

430430
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
431-
if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(anon_const) } =
431+
if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(const_arg) } =
432432
constraint.kind
433433
{
434-
let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
435-
let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, constraint.hir_id);
436-
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
434+
if let hir::ConstArgKind::Anon(anon_const) = const_arg.kind {
435+
let ty =
436+
alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
437+
let ty =
438+
check_assoc_const_binding_type(tcx, assoc_ident, ty, constraint.hir_id);
439+
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
440+
}
437441
}
438442

439443
alias_ty
@@ -450,7 +454,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
450454
hir::AssocItemConstraintKind::Equality { term } => {
451455
let term = match term {
452456
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
453-
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
457+
hir::Term::Const(ct) => {
458+
ty::Const::from_const_arg(tcx, ct, assoc_item.def_id).into()
459+
}
454460
};
455461

456462
// 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
@@ -34,7 +34,7 @@ use rustc_errors::{
3434
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
3535
use rustc_hir::def_id::{DefId, LocalDefId};
3636
use rustc_hir::intravisit::{walk_generics, Visitor as _};
37-
use rustc_hir::{self as hir, ConstArgKind};
37+
use rustc_hir::{self as hir};
3838
use rustc_hir::{GenericArg, GenericArgs, HirId};
3939
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
4040
use rustc_infer::traits::ObligationCause;
@@ -479,17 +479,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
479479
(&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
480480
handle_ty_args(has_default, &inf.to_ty())
481481
}
482-
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => match ct.kind {
483-
ConstArgKind::Path(qpath) => {
484-
// FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
485-
ty::Const::from_param(tcx, qpath, ct.hir_id).into()
486-
}
487-
ConstArgKind::Anon(anon) => {
488-
let did = anon.def_id;
489-
tcx.feed_anon_const_type(did, tcx.type_of(param.def_id));
490-
ty::Const::from_anon_const(tcx, did).into()
491-
}
492-
},
482+
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
483+
ty::Const::from_const_arg(tcx, ct, param.def_id).into()
484+
}
493485
(&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
494486
let ty = tcx
495487
.at(self.span)
@@ -922,12 +914,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
922914
let mut where_bounds = vec![];
923915
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
924916
let bound_id = bound.def_id();
925-
let bound_span = tcx
917+
let assoc_item = tcx
926918
.associated_items(bound_id)
927-
.find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
928-
.and_then(|item| tcx.hir().span_if_local(item.def_id));
919+
.find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id);
920+
let bound_span = assoc_item.and_then(|item| tcx.hir().span_if_local(item.def_id));
929921

930-
if let Some(bound_span) = bound_span {
922+
if let Some(assoc_item) = assoc_item
923+
&& let Some(bound_span) = bound_span
924+
{
931925
err.span_label(
932926
bound_span,
933927
format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
@@ -938,7 +932,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
938932
let term: ty::Term<'_> = match term {
939933
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
940934
hir::Term::Const(ct) => {
941-
ty::Const::from_anon_const(tcx, ct.def_id).into()
935+
ty::Const::from_const_arg(tcx, ct, assoc_item.def_id).into()
942936
}
943937
};
944938
// 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
@@ -1719,7 +1719,7 @@ impl<'a> State<'a> {
17191719
self.word_space("=");
17201720
match term {
17211721
Term::Ty(ty) => self.print_type(ty),
1722-
Term::Const(ref c) => self.print_anon_const(c),
1722+
Term::Const(ref c) => self.print_const_arg(c),
17231723
}
17241724
}
17251725
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::{
@@ -448,20 +448,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
448448

449449
pub fn lower_const_arg(
450450
&self,
451-
const_arg: &ConstArg<'tcx>,
451+
const_arg: &'tcx hir::ConstArg<'tcx>,
452452
param_def_id: DefId,
453453
) -> ty::Const<'tcx> {
454-
let ct = match const_arg.kind {
455-
ConstArgKind::Path(qpath) => {
456-
// FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
457-
ty::Const::from_param(self.tcx, qpath, const_arg.hir_id)
458-
}
459-
ConstArgKind::Anon(anon) => {
460-
let did = anon.def_id;
461-
self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id));
462-
ty::Const::from_anon_const(self.tcx, did)
463-
}
464-
};
454+
let ct = ty::Const::from_const_arg(self.tcx, const_arg, param_def_id);
465455
self.register_wf_obligation(
466456
ct.into(),
467457
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, TyDecodable, TyEncodable};
1010
use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
@@ -216,6 +216,39 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
216216
}
217217

218218
impl<'tcx> Const<'tcx> {
219+
/// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self).
220+
///
221+
/// `param_def_id` is the [`DefId`] of the declared param that this [`ConstArg`] is being
222+
/// supplied to. We need this in case this `ConstArg` is a [`ConstArgKind::Anon`]
223+
/// so we can tell the [`AnonConst`] what type it should be.
224+
pub fn from_const_arg(
225+
tcx: TyCtxt<'tcx>,
226+
const_arg: &'tcx hir::ConstArg<'tcx>,
227+
param_def_id: DefId,
228+
) -> Self {
229+
if let hir::ConstArgKind::Anon(anon) = &const_arg.kind {
230+
tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id));
231+
}
232+
Self::from_const_arg_without_feeding(tcx, const_arg)
233+
}
234+
235+
/// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self), without feeding it its expected type.
236+
///
237+
/// This distinction is only relevant for [`hir::ConstArgKind::Anon`];
238+
/// see [`Self::from_const_arg_without_feeding`].
239+
pub fn from_const_arg_without_feeding(
240+
tcx: TyCtxt<'tcx>,
241+
const_arg: &'tcx hir::ConstArg<'tcx>,
242+
) -> Self {
243+
match const_arg.kind {
244+
hir::ConstArgKind::Path(qpath) => {
245+
// FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
246+
Self::from_param(tcx, qpath, const_arg.hir_id)
247+
}
248+
hir::ConstArgKind::Anon(anon) => Self::from_anon_const(tcx, anon.def_id),
249+
}
250+
}
251+
219252
/// Literals and const generic parameters are eagerly converted to a constant, everything else
220253
/// becomes `Unevaluated`.
221254
#[instrument(skip(tcx), level = "debug")]
@@ -250,7 +283,7 @@ impl<'tcx> Const<'tcx> {
250283
/// Lower a const param to a [`Const`].
251284
///
252285
/// IMPORTANT: `qpath` must be a const param, otherwise this will panic
253-
pub fn from_param(tcx: TyCtxt<'tcx>, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Self {
286+
fn from_param(tcx: TyCtxt<'tcx>, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Self {
254287
// FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
255288
// does not provide the parents generics to anonymous constants. We still allow generic const
256289
// parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
@@ -315,6 +348,21 @@ impl<'tcx> Const<'tcx> {
315348
}
316349
}
317350
}
351+
352+
// FIXME: this shouldn't panic, it's just temporary code
353+
match expr.kind {
354+
hir::ExprKind::Path(hir::QPath::Resolved(
355+
_,
356+
&hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
357+
)) => {
358+
span_bug!(
359+
expr.span,
360+
"try_from_lit: received const param which shouldn't be possible"
361+
)
362+
}
363+
_ => {}
364+
}
365+
318366
None
319367
}
320368

src/librustdoc/clean/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Te
467467
match term {
468468
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
469469
hir::Term::Const(c) => Term::Constant(clean_middle_const(
470-
ty::Binder::dummy(ty::Const::from_anon_const(cx.tcx, c.def_id)),
470+
ty::Binder::dummy(ty::Const::from_const_arg_without_feeding(cx.tcx, c)),
471471
cx,
472472
)),
473473
}

0 commit comments

Comments
 (0)