From acd3ad9e260f81f29904071186a1fc99b2e8cfc5 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 7 Apr 2025 17:26:21 -0400 Subject: [PATCH 1/5] Add optional ConstArg field to ItemKind::Const Currently always None, but will be Some if the const item value is a const path. --- compiler/rustc_ast_lowering/src/item.rs | 3 ++- compiler/rustc_hir/src/hir.rs | 14 +++++++------- compiler/rustc_hir/src/intravisit.rs | 3 ++- .../src/collect/resolve_bound_vars.rs | 2 +- compiler/rustc_hir_analysis/src/collect/type_of.rs | 2 +- compiler/rustc_hir_analysis/src/hir_wf_check.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_lint/src/context.rs | 2 +- compiler/rustc_lint/src/non_local_def.rs | 2 +- compiler/rustc_mir_build/src/builder/mod.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 2 +- .../src/error_reporting/infer/mod.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 4 ++-- src/librustdoc/clean/mod.rs | 2 +- .../clippy/clippy_lints/src/large_const_arrays.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- src/tools/clippy/clippy_lints/src/types/mod.rs | 2 +- .../clippy_lints/src/undocumented_unsafe_blocks.rs | 2 +- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- 21 files changed, 30 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 28f596ac092..31c3fa221de 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -212,7 +212,8 @@ impl<'hir> LoweringContext<'_, 'hir> { }, ); self.lower_define_opaque(hir_id, &define_opaque); - hir::ItemKind::Const(ident, ty, generics, body_id) + // TODO: make const arg instead of always using None + hir::ItemKind::Const(ident, ty, generics, body_id, None) } ItemKind::Fn(box Fn { sig: FnSig { decl, header, span: fn_sig_span }, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f8af1b81ca9..da53302d7e8 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3986,8 +3986,8 @@ impl<'hir> Item<'hir> { expect_static, (Ident, &'hir Ty<'hir>, Mutability, BodyId), ItemKind::Static(ident, ty, mutbl, body), (*ident, ty, *mutbl, *body); - expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), - ItemKind::Const(ident, ty, generics, body), (*ident, ty, generics, *body); + expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId, Option<&'hir ConstArg<'hir>>), + ItemKind::Const(ident, ty, generics, body, ct), (*ident, ty, generics, *body, *ct); expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId), ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body); @@ -4157,7 +4157,7 @@ pub enum ItemKind<'hir> { /// A `static` item. Static(Ident, &'hir Ty<'hir>, Mutability, BodyId), /// A `const` item. - Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), + Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId, Option<&'hir ConstArg<'hir>>), /// A function declaration. Fn { ident: Ident, @@ -4252,7 +4252,7 @@ impl ItemKind<'_> { Some(match self { ItemKind::Fn { generics, .. } | ItemKind::TyAlias(_, _, generics) - | ItemKind::Const(_, _, generics, _) + | ItemKind::Const(_, _, generics, _, _) | ItemKind::Enum(_, _, generics) | ItemKind::Struct(_, _, generics) | ItemKind::Union(_, _, generics) @@ -4455,7 +4455,7 @@ impl<'hir> OwnerNode<'hir> { OwnerNode::Item(Item { kind: ItemKind::Static(_, _, _, body) - | ItemKind::Const(_, _, _, body) + | ItemKind::Const(_, _, _, body, _) | ItemKind::Fn { body, .. }, .. }) @@ -4681,7 +4681,7 @@ impl<'hir> Node<'hir> { Node::Item(it) => match it.kind { ItemKind::TyAlias(_, ty, _) | ItemKind::Static(_, ty, _, _) - | ItemKind::Const(_, ty, _, _) => Some(ty), + | ItemKind::Const(_, ty, _, _, _) => Some(ty), ItemKind::Impl(impl_item) => Some(&impl_item.self_ty), _ => None, }, @@ -4712,7 +4712,7 @@ impl<'hir> Node<'hir> { Node::Item(Item { owner_id, kind: - ItemKind::Const(_, _, _, body) + ItemKind::Const(_, _, _, body, _) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. }, .. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 506358341b5..ccdc1157270 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -550,11 +550,12 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_nested_body(body)); } - ItemKind::Const(ident, ref typ, ref generics, body) => { + ItemKind::Const(ident, ref typ, ref generics, body, ct) => { try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_nested_body(body)); + visit_opt!(visitor, visit_const_arg_unambig, ct); } ItemKind::Fn { ident, sig, generics, body: body_id, .. } => { try_visit!(visitor.visit_ident(ident)); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 404753875ee..08ef84bd37d 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -628,7 +628,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { intravisit::walk_item(self, item); } hir::ItemKind::TyAlias(_, _, generics) - | hir::ItemKind::Const(_, _, generics, _) + | hir::ItemKind::Const(_, _, generics,_, _) | hir::ItemKind::Enum(_, _, generics) | hir::ItemKind::Struct(_, _, generics) | hir::ItemKind::Union(_, _, generics) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index afda2c142e2..f9ae37cea27 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -216,7 +216,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ icx.lower_ty(ty) } } - ItemKind::Const(ident, ty, _, body_id) => { + ItemKind::Const(ident, ty, _, body_id,_) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index c01b81563dc..e4d7346da2d 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -138,7 +138,7 @@ fn diagnostic_hir_wf_check<'tcx>( hir::Node::Item(item) => match item.kind { hir::ItemKind::TyAlias(_, ty, _) | hir::ItemKind::Static(_, ty, _, _) - | hir::ItemKind::Const(_, ty, _, _) => vec![ty], + | hir::ItemKind::Const(_, ty, _, _,_) => vec![ty], hir::ItemKind::Impl(impl_) => match &impl_.of_trait { Some(t) => t .path diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1c23761b2e5..7e83ca6eb76 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -608,7 +608,7 @@ impl<'a> State<'a> { self.word(";"); self.end(); // end the outer cbox } - hir::ItemKind::Const(ident, ty, generics, expr) => { + hir::ItemKind::Const(ident, ty, generics, expr, _ct) => { self.head("const"); self.print_ident(ident); self.print_generic_params(generics.params); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 9766ceda569..140b989b253 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1245,7 +1245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match opt_def_id { Some(def_id) => match self.tcx.hir_get_if_local(def_id) { Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Const(_, _, _, body_id), + kind: hir::ItemKind::Const(_, _, _, body_id, _), .. })) => match self.tcx.hir_node(body_id.hir_id) { hir::Node::Expr(expr) => { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 017ae943e91..e02100de6fa 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -949,7 +949,7 @@ impl<'tcx> LateContext<'tcx> { .. }) => *init, hir::Node::Item(item) => match item.kind { - hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => { + hir::ItemKind::Const(.., body_id,_) | hir::ItemKind::Static(.., body_id) => { Some(self.tcx.hir_body(body_id).value) } _ => None, diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 9ed11d9cc82..006e26a622b 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -183,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { && parent_opt_item_name != Some(kw::Underscore) && let Some(parent) = parent.as_local() && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent) - && let ItemKind::Const(ident, ty, _, _) = item.kind + && let ItemKind::Const(ident, ty, _, _, _) = item.kind && let TyKind::Tup(&[]) = ty.kind { Some(ident.span) diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index bcc2a4674ea..bf9e11a4503 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -563,7 +563,7 @@ fn construct_const<'a, 'tcx>( // Figure out what primary body this item has. let (span, const_ty_span) = match tcx.hir_node(hir_id) { Node::Item(hir::Item { - kind: hir::ItemKind::Static(_, ty, _, _) | hir::ItemKind::Const(_, ty, _, _), + kind: hir::ItemKind::Static(_, ty, _, _) | hir::ItemKind::Const(_, ty, _, _, _), span, .. }) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 321e5729b72..c90af0f7687 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -204,7 +204,7 @@ impl<'tcx> ReachableContext<'tcx> { } } - hir::ItemKind::Const(_, _, _, init) => { + hir::ItemKind::Const(_, _, _, init, _) => { // Only things actually ending up in the final constant value are reachable // for codegen. Everything else is only needed during const-eval, so even if // const-eval happens in a downstream crate, all they need is diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 40f8af1f691..7c00690870f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2026,7 +2026,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } LetVisitor { span }.visit_body(body).break_value() } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(_, ty, _, _), .. }) => { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(_, ty, _, _, _), .. }) => { Some(&ty.peel_refs().kind) } _ => None, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 38fcba4ea62..1f3ec5b8a60 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -358,7 +358,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | hir::ItemKind::Impl(hir::Impl { generics, .. }) | hir::ItemKind::Fn { generics, .. } | hir::ItemKind::TyAlias(_, _, generics) - | hir::ItemKind::Const(_, _, generics, _) + | hir::ItemKind::Const(_, _, generics, _, _) | hir::ItemKind::TraitAlias(_, generics, _), .. }) @@ -418,7 +418,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | hir::ItemKind::Impl(hir::Impl { generics, .. }) | hir::ItemKind::Fn { generics, .. } | hir::ItemKind::TyAlias(_, _, generics) - | hir::ItemKind::Const(_, _, generics, _) + | hir::ItemKind::Const(_, _, generics, _, _) | hir::ItemKind::TraitAlias(_, generics, _), .. }) if !param_ty => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c08ae168d69..92b01693dbd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2804,7 +2804,7 @@ fn clean_maybe_renamed_item<'tcx>( mutability, expr: Some(body_id), }), - ItemKind::Const(_, ty, generics, body_id) => ConstantItem(Box::new(Constant { + ItemKind::Const(_, ty, generics, body_id, _) => ConstantItem(Box::new(Constant { generics: clean_generics(generics, cx), type_: clean_ty(ty, cx), kind: ConstantKind::Local { body: body_id, def_id }, diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 394005e9912..d73edbc79a6 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -48,7 +48,7 @@ impl_lint_pass!(LargeConstArrays => [LARGE_CONST_ARRAYS]); impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Const(ident, _, generics, _) = &item.kind + if let ItemKind::Const(ident, _, generics, _,_) = &item.kind // Since static items may not have generics, skip generic const items. // FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it // doesn't account for empty where-clauses that only consist of keyword `where` IINM. diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 9b53608ae7f..c06cd3cff56 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -310,7 +310,7 @@ impl<'tcx> NonCopyConst<'tcx> { impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) { - if let ItemKind::Const(.., body_id) = it.kind { + if let ItemKind::Const(.., body_id,_) = it.kind { let ty = cx.tcx.type_of(it.owner_id).instantiate_identity(); if !ignored_macro(cx, it) && self.interior_mut.is_interior_mut_ty(cx, ty) diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index b6f4c4d7f0a..a0614ffdc77 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -447,7 +447,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); match item.kind { - ItemKind::Static(_, ty, _, _) | ItemKind::Const(_, ty, _, _) => self.check_ty( + ItemKind::Static(_, ty, _, _) | ItemKind::Const(_, ty, _, _, _) => self.check_ty( cx, ty, CheckTyContext { diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index a2938c86c76..e771de59486 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -243,7 +243,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { }, (ItemKind::Impl(_), _) => {}, // const and static items only need a safety comment if their body is an unsafe block, lint otherwise - (&ItemKind::Const(.., body) | &ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => { + (&ItemKind::Const(.., body, _) | &ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { let body = cx.tcx.hir_body(body); if !matches!( diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index dd149c4a29b..fb2be84d57e 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -644,7 +644,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { // which is NOT constant for our purposes. if let Some(node) = self.tcx.hir_get_if_local(def_id) && let Node::Item(Item { - kind: ItemKind::Const(.., body_id), + kind: ItemKind::Const(.., body_id, _), .. }) = node && let Node::Expr(Expr { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 8dc28fa3077..adf9a51359a 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2648,7 +2648,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym for id in tcx.hir_module_free_items(module) { if matches!(tcx.def_kind(id.owner_id), DefKind::Const) && let item = tcx.hir_item(id) - && let ItemKind::Const(ident, ty, _generics, _body) = item.kind + && let ItemKind::Const(ident, ty, _generics, _body, _ct_arg) = item.kind { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind { // We could also check for the type name `test::TestDescAndFn` From 6054bd5468c12fdce922ed77e2941d6243c32e51 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 8 Apr 2025 17:49:00 -0400 Subject: [PATCH 2/5] Add optional ConstArg field to assoc consts in HIR --- compiler/rustc_ast_lowering/src/item.rs | 7 +++--- compiler/rustc_hir/src/hir.rs | 24 ++++++++++--------- compiler/rustc_hir/src/intravisit.rs | 9 ++++--- .../src/check/compare_impl_item.rs | 4 ++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 4 ++-- .../src/collect/resolve_bound_vars.rs | 6 ++--- .../rustc_hir_analysis/src/collect/type_of.rs | 6 ++--- .../rustc_hir_analysis/src/hir_wf_check.rs | 6 ++--- compiler/rustc_hir_pretty/src/lib.rs | 4 ++-- compiler/rustc_lint/src/context.rs | 2 +- compiler/rustc_mir_build/src/builder/mod.rs | 6 +++-- compiler/rustc_passes/src/dead.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 8 +++---- src/librustdoc/clean/mod.rs | 6 ++--- .../clippy/clippy_lints/src/non_copy_const.rs | 6 ++--- .../clippy/clippy_lints/src/types/mod.rs | 4 ++-- 17 files changed, 57 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 31c3fa221de..88d461760cc 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -814,8 +814,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x))); - - hir::TraitItemKind::Const(ty, body) + // TODO: make const arg instead of always using None + hir::TraitItemKind::Const(ty, body, None) }, ); @@ -1008,7 +1008,8 @@ impl<'hir> LoweringContext<'_, 'hir> { .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); let body = this.lower_const_body(i.span, expr.as_deref()); this.lower_define_opaque(hir_id, &define_opaque); - hir::ImplItemKind::Const(ty, body) + // TODO: make const arg instead of always using None + hir::ImplItemKind::Const(ty, body, None) }, ), ), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index da53302d7e8..14997c18de6 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2973,8 +2973,8 @@ impl<'hir> TraitItem<'hir> { } expect_methods_self_kind! { - expect_const, (&'hir Ty<'hir>, Option), - TraitItemKind::Const(ty, body), (ty, *body); + expect_const, (&'hir Ty<'hir>, Option, Option<&'hir ConstArg<'hir>>), + TraitItemKind::Const(ty, body, ct), (ty, *body, *ct); expect_fn, (&FnSig<'hir>, &TraitFn<'hir>), TraitItemKind::Fn(ty, trfn), (ty, trfn); @@ -2998,7 +2998,7 @@ pub enum TraitFn<'hir> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TraitItemKind<'hir> { /// An associated constant with an optional value (otherwise `impl`s must contain a value). - Const(&'hir Ty<'hir>, Option), + Const(&'hir Ty<'hir>, Option, Option<&'hir ConstArg<'hir>>), /// An associated function with an optional body. Fn(FnSig<'hir>, TraitFn<'hir>), /// An associated type with (possibly empty) bounds and optional concrete @@ -3048,7 +3048,7 @@ impl<'hir> ImplItem<'hir> { } expect_methods_self_kind! { - expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body); + expect_const, (&'hir Ty<'hir>, BodyId, Option<&'hir ConstArg<'hir>>), ImplItemKind::Const(ty, body, ct), (ty, *body, *ct); expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body); expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty; } @@ -3059,7 +3059,7 @@ impl<'hir> ImplItem<'hir> { pub enum ImplItemKind<'hir> { /// An associated constant of the given type, set to the constant result /// of the expression. - Const(&'hir Ty<'hir>, BodyId), + Const(&'hir Ty<'hir>, BodyId, Option<&'hir ConstArg<'hir>>), /// An associated function implementation with the given signature and body. Fn(FnSig<'hir>, BodyId), /// An associated type. @@ -4461,11 +4461,12 @@ impl<'hir> OwnerNode<'hir> { }) | OwnerNode::TraitItem(TraitItem { kind: - TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)), + TraitItemKind::Fn(_, TraitFn::Provided(body)) + | TraitItemKind::Const(_, Some(body), _), .. }) | OwnerNode::ImplItem(ImplItem { - kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body), + kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body, _), .. }) => Some(*body), _ => None, @@ -4686,12 +4687,12 @@ impl<'hir> Node<'hir> { _ => None, }, Node::TraitItem(it) => match it.kind { - TraitItemKind::Const(ty, _) => Some(ty), + TraitItemKind::Const(ty, _, _) => Some(ty), TraitItemKind::Type(_, ty) => ty, _ => None, }, Node::ImplItem(it) => match it.kind { - ImplItemKind::Const(ty, _) => Some(ty), + ImplItemKind::Const(ty, _, _) => Some(ty), ImplItemKind::Type(ty) => Some(ty), _ => None, }, @@ -4720,12 +4721,13 @@ impl<'hir> Node<'hir> { | Node::TraitItem(TraitItem { owner_id, kind: - TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)), + TraitItemKind::Const(_, Some(body), _) + | TraitItemKind::Fn(_, TraitFn::Provided(body)), .. }) | Node::ImplItem(ImplItem { owner_id, - kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body), + kind: ImplItemKind::Const(_, body, _) | ImplItemKind::Fn(_, body), .. }) => Some((owner_id.def_id, *body)), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index ccdc1157270..8996f051c94 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1166,9 +1166,10 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>( try_visit!(visitor.visit_defaultness(&defaultness)); try_visit!(visitor.visit_id(hir_id)); match *kind { - TraitItemKind::Const(ref ty, default) => { + TraitItemKind::Const(ref ty, default, ct_arg) => { try_visit!(visitor.visit_ty_unambig(ty)); visit_opt!(visitor, visit_nested_body, default); + visit_opt!(visitor, visit_const_arg_unambig, ct_arg); } TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => { try_visit!(visitor.visit_fn_decl(sig.decl)); @@ -1224,9 +1225,11 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>( try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_id(impl_item.hir_id())); match *kind { - ImplItemKind::Const(ref ty, body) => { + ImplItemKind::Const(ref ty, body, ct_arg) => { try_visit!(visitor.visit_ty_unambig(ty)); - visitor.visit_nested_body(body) + try_visit!(visitor.visit_nested_body(body)); + visit_opt!(visitor, visit_const_arg_unambig, ct_arg); + V::Result::output() } ImplItemKind::Fn(ref sig, body_id) => visitor.visit_fn( FnKind::Method(impl_item.ident, sig), diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index aec9518494c..2d6048bb086 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1860,7 +1860,7 @@ fn compare_const_predicate_entailment<'tcx>( debug!(?impl_ty, ?trait_ty); // Locate the Span containing just the type of the offending impl - let (ty, _) = tcx.hir_expect_impl_item(impl_ct_def_id).expect_const(); + let (ty, ..) = tcx.hir_expect_impl_item(impl_ct_def_id).expect_const(); cause.span = ty.span; let mut diag = struct_span_code_err!( @@ -1873,7 +1873,7 @@ fn compare_const_predicate_entailment<'tcx>( let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| { // Add a label to the Span containing just the type of the const - let (ty, _) = tcx.hir_expect_trait_item(trait_ct_def_id).expect_const(); + let (ty, ..) = tcx.hir_expect_trait_item(trait_ct_def_id).expect_const(); ty.span }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 83d095ab72e..2eda0894f6e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -834,7 +834,7 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI }; let mut trait_should_be_self = vec![]; match &item.kind { - hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty)) + hir::TraitItemKind::Const(ty, ..) | hir::TraitItemKind::Type(_, Some(ty)) if could_be_self(trait_def_id.def_id, ty) => { trait_should_be_self.push(ty.span) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 075abc32594..bb2bf7bd9f4 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -799,7 +799,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { tcx.ensure_ok().fn_sig(def_id); } - hir::TraitItemKind::Const(ty, body_id) => { + hir::TraitItemKind::Const(ty, body_id, _ct) => { tcx.ensure_ok().type_of(def_id); if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType) && !(ty.is_suggestable_infer_ty() && body_id.is_some()) @@ -883,7 +883,7 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { "associated type", ); } - hir::ImplItemKind::Const(ty, _) => { + hir::ImplItemKind::Const(ty, ..) => { // Account for `const T: _ = ..;` if !ty.is_suggestable_infer_ty() { let mut visitor = HirPlaceholderCollector::default(); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 08ef84bd37d..3b0aed86216 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -628,7 +628,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { intravisit::walk_item(self, item); } hir::ItemKind::TyAlias(_, _, generics) - | hir::ItemKind::Const(_, _, generics,_, _) + | hir::ItemKind::Const(_, _, generics, _, _) | hir::ItemKind::Enum(_, _, generics) | hir::ItemKind::Struct(_, _, generics) | hir::ItemKind::Union(_, _, generics) @@ -848,7 +848,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } }) } - Const(_, _) => self.visit_early(trait_item.hir_id(), trait_item.generics, |this| { + Const(_, _, _) => self.visit_early(trait_item.hir_id(), trait_item.generics, |this| { intravisit::walk_trait_item(this, trait_item) }), } @@ -865,7 +865,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { this.visit_generics(impl_item.generics); this.visit_ty_unambig(ty); }), - Const(_, _) => self.visit_early(impl_item.hir_id(), impl_item.generics, |this| { + Const(_, _, _) => self.visit_early(impl_item.hir_id(), impl_item.generics, |this| { intravisit::walk_impl_item(this, impl_item) }), } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index f9ae37cea27..d524e2e5b41 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -153,7 +153,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - TraitItemKind::Const(ty, body_id) => body_id + TraitItemKind::Const(ty, body_id, _) => body_id .and_then(|body_id| { ty.is_suggestable_infer_ty().then(|| { infer_placeholder_type( @@ -178,7 +178,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - ImplItemKind::Const(ty, body_id) => { + ImplItemKind::Const(ty, body_id, _) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), @@ -216,7 +216,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ icx.lower_ty(ty) } } - ItemKind::Const(ident, ty, _, body_id,_) => { + ItemKind::Const(ident, ty, _, body_id, _) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index e4d7346da2d..9df810558cb 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -127,18 +127,18 @@ fn diagnostic_hir_wf_check<'tcx>( WellFormedLoc::Ty(_) => match tcx.hir_node(hir_id) { hir::Node::ImplItem(item) => match item.kind { hir::ImplItemKind::Type(ty) => vec![ty], - hir::ImplItemKind::Const(ty, _) => vec![ty], + hir::ImplItemKind::Const(ty, _, _) => vec![ty], ref item => bug!("Unexpected ImplItem {:?}", item), }, hir::Node::TraitItem(item) => match item.kind { hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(), - hir::TraitItemKind::Const(ty, _) => vec![ty], + hir::TraitItemKind::Const(ty, _, _) => vec![ty], ref item => bug!("Unexpected TraitItem {:?}", item), }, hir::Node::Item(item) => match item.kind { hir::ItemKind::TyAlias(_, ty, _) | hir::ItemKind::Static(_, ty, _, _) - | hir::ItemKind::Const(_, ty, _, _,_) => vec![ty], + | hir::ItemKind::Const(_, ty, _, _, _) => vec![ty], hir::ItemKind::Impl(impl_) => match &impl_.of_trait { Some(t) => t .path diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 7e83ca6eb76..d82360fe9fe 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -911,7 +911,7 @@ impl<'a> State<'a> { self.maybe_print_comment(ti.span.lo()); self.print_attrs_as_outer(self.attrs(ti.hir_id())); match ti.kind { - hir::TraitItemKind::Const(ty, default) => { + hir::TraitItemKind::Const(ty, default, _ct) => { self.print_associated_const(ti.ident, ti.generics, ty, default); } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_names)) => { @@ -940,7 +940,7 @@ impl<'a> State<'a> { self.print_attrs_as_outer(self.attrs(ii.hir_id())); match ii.kind { - hir::ImplItemKind::Const(ty, expr) => { + hir::ImplItemKind::Const(ty, expr, _ct) => { self.print_associated_const(ii.ident, ii.generics, ty, Some(expr)); } hir::ImplItemKind::Fn(ref sig, body) => { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index e02100de6fa..5edd2141f1b 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -949,7 +949,7 @@ impl<'tcx> LateContext<'tcx> { .. }) => *init, hir::Node::Item(item) => match item.kind { - hir::ItemKind::Const(.., body_id,_) | hir::ItemKind::Static(.., body_id) => { + hir::ItemKind::Const(.., body_id, _) | hir::ItemKind::Static(.., body_id) => { Some(self.tcx.hir_body(body_id).value) } _ => None, diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index bf9e11a4503..da79e3f0c54 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -567,9 +567,11 @@ fn construct_const<'a, 'tcx>( span, .. }) - | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(ty, _), span, .. }) + | Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Const(ty, _, _), span, .. + }) | Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Const(ty, Some(_)), + kind: hir::TraitItemKind::Const(ty, Some(_), _), span, .. }) => (*span, ty.span), diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index b62d94d65f1..9a623c972d8 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -826,7 +826,7 @@ fn check_trait_item( use hir::TraitItemKind::{Const, Fn}; if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) { let trait_item = tcx.hir_trait_item(id); - if matches!(trait_item.kind, Const(_, Some(_)) | Fn(..)) + if matches!(trait_item.kind, Const(_, Some(_), _) | Fn(..)) && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) { diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index c90af0f7687..681661891ef 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -145,7 +145,7 @@ impl<'tcx> ReachableContext<'tcx> { _ => false, }, Node::TraitItem(trait_method) => match trait_method.kind { - hir::TraitItemKind::Const(_, ref default) => default.is_some(), + hir::TraitItemKind::Const(_, ref default, _) => default.is_some(), hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => true, hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_)) | hir::TraitItemKind::Type(..) => false, @@ -249,11 +249,11 @@ impl<'tcx> ReachableContext<'tcx> { } Node::TraitItem(trait_method) => { match trait_method.kind { - hir::TraitItemKind::Const(_, None) + hir::TraitItemKind::Const(_, None, _) | hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => { // Keep going, nothing to get exported } - hir::TraitItemKind::Const(_, Some(body_id)) + hir::TraitItemKind::Const(_, Some(body_id), _) | hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)) => { self.visit_nested_body(body_id); } @@ -261,7 +261,7 @@ impl<'tcx> ReachableContext<'tcx> { } } Node::ImplItem(impl_item) => match impl_item.kind { - hir::ImplItemKind::Const(_, body) => { + hir::ImplItemKind::Const(_, body, _) => { self.visit_nested_body(body); } hir::ImplItemKind::Fn(_, body) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 92b01693dbd..f808b11d835 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1255,14 +1255,14 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext let local_did = trait_item.owner_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match trait_item.kind { - hir::TraitItemKind::Const(ty, Some(default)) => { + hir::TraitItemKind::Const(ty, Some(default), _) => { ProvidedAssocConstItem(Box::new(Constant { generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), kind: ConstantKind::Local { def_id: local_did, body: default }, type_: clean_ty(ty, cx), })) } - hir::TraitItemKind::Const(ty, None) => { + hir::TraitItemKind::Const(ty, None, _) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); RequiredAssocConstItem(generics, Box::new(clean_ty(ty, cx))) } @@ -1306,7 +1306,7 @@ pub(crate) fn clean_impl_item<'tcx>( let local_did = impl_.owner_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match impl_.kind { - hir::ImplItemKind::Const(ty, expr) => ImplAssocConstItem(Box::new(Constant { + hir::ImplItemKind::Const(ty, expr, _) => ImplAssocConstItem(Box::new(Constant { generics: clean_generics(impl_.generics, cx), kind: ConstantKind::Local { def_id: local_did, body: expr }, type_: clean_ty(ty, cx), diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index c06cd3cff56..8da46cd25ad 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -310,7 +310,7 @@ impl<'tcx> NonCopyConst<'tcx> { impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) { - if let ItemKind::Const(.., body_id,_) = it.kind { + if let ItemKind::Const(.., body_id, _) = it.kind { let ty = cx.tcx.type_of(it.owner_id).instantiate_identity(); if !ignored_macro(cx, it) && self.interior_mut.is_interior_mut_ty(cx, ty) @@ -322,7 +322,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) { - if let TraitItemKind::Const(_, body_id_opt) = &trait_item.kind { + if let TraitItemKind::Const(_, body_id_opt, _) = &trait_item.kind { let ty = cx.tcx.type_of(trait_item.owner_id).instantiate_identity(); // Normalize assoc types because ones originated from generic params @@ -349,7 +349,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { - if let ImplItemKind::Const(_, body_id) = &impl_item.kind { + if let ImplItemKind::Const(_, body_id, _) = &impl_item.kind { let item_def_id = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir_expect_item(item_def_id); diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index a0614ffdc77..3886f5b3b96 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -462,7 +462,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>) { match item.kind { - ImplItemKind::Const(ty, _) => { + ImplItemKind::Const(ty, _, _) => { let is_in_trait_impl = if let hir::Node::Item(item) = cx .tcx .hir_node_by_def_id(cx.tcx.hir_get_parent_item(item.hir_id()).def_id) @@ -514,7 +514,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { }; match item.kind { - TraitItemKind::Const(ty, _) | TraitItemKind::Type(_, Some(ty)) => { + TraitItemKind::Const(ty, _, _) | TraitItemKind::Type(_, Some(ty)) => { self.check_ty(cx, ty, context); }, TraitItemKind::Fn(ref sig, trait_method) => { From 42745dcb5a25634b3cfa0af487b70a8b77e4634c Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 10 Apr 2025 18:49:24 -0400 Subject: [PATCH 3/5] Lower to const path if possible in const item value --- compiler/rustc_ast_lowering/src/item.rs | 30 ++++++++++++++++++++----- compiler/rustc_ast_lowering/src/lib.rs | 16 +++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 88d461760cc..1a10958f5a1 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -212,8 +212,14 @@ impl<'hir> LoweringContext<'_, 'hir> { }, ); self.lower_define_opaque(hir_id, &define_opaque); - // TODO: make const arg instead of always using None - hir::ItemKind::Const(ident, ty, generics, body_id, None) + let ct_arg = if self.tcx.features().min_generic_const_args() + && let Some(expr) = expr + { + self.try_lower_as_const_path(expr) + } else { + None + }; + hir::ItemKind::Const(ident, ty, generics, body_id, ct_arg) } ItemKind::Fn(box Fn { sig: FnSig { decl, header, span: fn_sig_span }, @@ -814,8 +820,14 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x))); - // TODO: make const arg instead of always using None - hir::TraitItemKind::Const(ty, body, None) + let ct_arg = if this.tcx.features().min_generic_const_args() + && let Some(expr) = expr + { + this.try_lower_as_const_path(expr) + } else { + None + }; + hir::TraitItemKind::Const(ty, body, ct_arg) }, ); @@ -1008,8 +1020,14 @@ impl<'hir> LoweringContext<'_, 'hir> { .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); let body = this.lower_const_body(i.span, expr.as_deref()); this.lower_define_opaque(hir_id, &define_opaque); - // TODO: make const arg instead of always using None - hir::ImplItemKind::Const(ty, body, None) + let ct_arg = if this.tcx.features().min_generic_const_args() + && let Some(expr) = expr + { + this.try_lower_as_const_path(expr) + } else { + None + }; + hir::ImplItemKind::Const(ty, body, ct_arg) }, ), ), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d5d6dcd8d63..2caa6bc14a3 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2057,6 +2057,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + /// Assumes mgca feature is enabled. + fn try_lower_as_const_path(&mut self, expr: &Expr) -> Option<&'hir hir::ConstArg<'hir>> { + let ExprKind::Path(qself, path) = &expr.kind else { return None }; + let qpath = self.lower_qpath( + expr.id, + qself, + path, + ParamMode::Optional, + AllowReturnTypeNotation::No, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); + let ct_kind = hir::ConstArgKind::Path(qpath); + Some(self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })) + } + /// Used when lowering a type argument that turned out to actually be a const argument. /// /// Only use for that purpose since otherwise it will create a duplicate def. From 0cea2c1fa572a2fa6a8442bbb9c2ad91110e9dc7 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 10 Apr 2025 21:34:30 -0400 Subject: [PATCH 4/5] Centralize const item lowering logic --- compiler/rustc_ast_lowering/src/item.rs | 64 ++++++++++++------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 1a10958f5a1..219faad4001 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -182,15 +182,16 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::Static(box ast::StaticItem { ident, - ty: t, + ty, safety: _, mutability: m, expr: e, define_opaque, }) => { let ident = self.lower_ident(*ident); - let (ty, body_id) = - self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy); + let ty = + self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); + let body_id = self.lower_const_body(span, e.as_deref()); self.lower_define_opaque(hir_id, define_opaque); hir::ItemKind::Static(ident, ty, *m, body_id) } @@ -203,22 +204,17 @@ impl<'hir> LoweringContext<'_, 'hir> { .. }) => { let ident = self.lower_ident(*ident); - let (generics, (ty, body_id)) = self.lower_generics( + let (generics, (ty, (body_id, ct_arg))) = self.lower_generics( generics, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy) + let ty = this + .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); + (ty, this.lower_const_item(span, expr.as_deref())) }, ); self.lower_define_opaque(hir_id, &define_opaque); - let ct_arg = if self.tcx.features().min_generic_const_args() - && let Some(expr) = expr - { - self.try_lower_as_const_path(expr) - } else { - None - }; hir::ItemKind::Const(ident, ty, generics, body_id, ct_arg) } ItemKind::Fn(box Fn { @@ -501,13 +497,23 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_const_item( &mut self, - ty: &Ty, span: Span, body: Option<&Expr>, - impl_trait_position: ImplTraitPosition, - ) -> (&'hir hir::Ty<'hir>, hir::BodyId) { - let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position)); - (ty, self.lower_const_body(span, body)) + ) -> (hir::BodyId, Option<&'hir hir::ConstArg<'hir>>) { + let ct_arg = if self.tcx.features().min_generic_const_args() + && let Some(expr) = body + { + self.try_lower_as_const_path(expr) + } else { + None + }; + let body_id = if body.is_some() && ct_arg.is_none() { + // TODO: lower as const block instead + self.lower_const_body(span, body) + } else { + self.lower_const_body(span, body) + }; + (body_id, ct_arg) } #[instrument(level = "debug", skip(self))] @@ -819,15 +825,12 @@ impl<'hir> LoweringContext<'_, 'hir> { |this| { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); - let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x))); - let ct_arg = if this.tcx.features().min_generic_const_args() - && let Some(expr) = expr - { - this.try_lower_as_const_path(expr) - } else { - None - }; - hir::TraitItemKind::Const(ty, body, ct_arg) + match expr.as_deref().map(|e| this.lower_const_item(i.span, Some(e))) { + Some((body, ct_arg)) => { + hir::TraitItemKind::Const(ty, Some(body), ct_arg) + } + None => hir::TraitItemKind::Const(ty, None, None), + } }, ); @@ -1018,15 +1021,8 @@ impl<'hir> LoweringContext<'_, 'hir> { |this| { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); - let body = this.lower_const_body(i.span, expr.as_deref()); this.lower_define_opaque(hir_id, &define_opaque); - let ct_arg = if this.tcx.features().min_generic_const_args() - && let Some(expr) = expr - { - this.try_lower_as_const_path(expr) - } else { - None - }; + let (body, ct_arg) = this.lower_const_item(i.span, expr.as_deref()); hir::ImplItemKind::Const(ty, body, ct_arg) }, ), From 4a0cca3a388e6e9f7f0ed36784aa95f5951e1738 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 10 Apr 2025 23:07:40 -0400 Subject: [PATCH 5/5] wip on lowering as const blocks --- compiler/rustc_ast_lowering/src/item.rs | 48 ++++++++++++++++----- compiler/rustc_resolve/src/def_collector.rs | 16 ++++++- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 219faad4001..27dc4749d9c 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -500,16 +500,11 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, body: Option<&Expr>, ) -> (hir::BodyId, Option<&'hir hir::ConstArg<'hir>>) { - let ct_arg = if self.tcx.features().min_generic_const_args() - && let Some(expr) = body - { - self.try_lower_as_const_path(expr) - } else { - None - }; - let body_id = if body.is_some() && ct_arg.is_none() { - // TODO: lower as const block instead - self.lower_const_body(span, body) + let mgca = self.tcx.features().min_generic_const_args(); + let ct_arg = + if mgca && let Some(expr) = body { self.try_lower_as_const_path(expr) } else { None }; + let body_id = if mgca && ct_arg.is_none() { + self.lower_const_body_with_const_block(span, body) } else { self.lower_const_body(span, body) }; @@ -1292,6 +1287,39 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body)) } + /// HACK(mgca): lower the body of the const item as a const block + /// we need this later to be able to control generics in the body + /// separately from the const's type, etc. + pub(super) fn lower_const_body_with_const_block( + &mut self, + span: Span, + expr: Option<&Expr>, + ) -> hir::BodyId { + self.lower_body(|this| { + ( + &[], + match expr { + Some(expr) => { + let def_id = this.local_def_id(expr.id); + // TODO: somehow avoid reusing the same nodeid for the const block and the body expr + let hir_id = this.lower_node_id(expr.id); + let block = hir::ConstBlock { + def_id, + hir_id, + body: this.lower_const_body(expr.span, Some(expr)), + }; + hir::Expr { + hir_id, + span: this.lower_span(expr.span), + kind: hir::ExprKind::ConstBlock(block), + } + } + None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")), + }, + ) + }) + } + pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId { self.lower_body(|this| { ( diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 13dfb59f27f..1f8c6e3997e 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -174,6 +174,12 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { ); } } + // HACK(mgca): see lower_const_body_with_const_block in ast_lowering + ItemKind::Const(box ConstItem { expr: Some(ref expr), .. }) + if this.resolver.tcx.features().min_generic_const_args() => + { + this.create_def(expr.id, None, DefKind::InlineConst, i.span); + } _ => {} } visit::walk_item(this, i); @@ -334,7 +340,15 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }; let def = self.create_def(i.id, Some(ident.name), def_kind, i.span); - self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); + self.with_parent(def, |this| { + // HACK(mgca): see lower_const_body_with_const_block in ast_lowering + if let AssocItemKind::Const(box ConstItem { expr: Some(expr), .. }) = &i.kind + && this.resolver.tcx.features().min_generic_const_args() + { + this.create_def(expr.id, None, DefKind::InlineConst, i.span); + } + visit::walk_assoc_item(this, i, ctxt) + }); } fn visit_pat(&mut self, pat: &'a Pat) {