about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2023-05-04 16:40:57 +0200
committerLeón Orell Valerian Liehr <me@fmease.dev>2023-07-28 22:21:40 +0200
commit9213aec76231149a6e03252e4a26ea46962bc1f7 (patch)
tree96022ca42c7198ef72ed5404cb91099877d21289
parentafd009a8d8a8fea07cfee279817c75427b707778 (diff)
downloadrust-9213aec76231149a6e03252e4a26ea46962bc1f7.tar.gz
rust-9213aec76231149a6e03252e4a26ea46962bc1f7.zip
Lower generic const items to HIR
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs55
-rw-r--r--compiler/rustc_hir/src/hir.rs23
-rw-r--r--compiler/rustc_hir/src/intravisit.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs3
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
-rw-r--r--src/librustdoc/clean/mod.rs3
16 files changed, 84 insertions, 41 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 2f58f566c81..5a0474dbc01 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -231,9 +231,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
                 hir::ItemKind::Static(ty, *m, body_id)
             }
-            ItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
-                let (ty, body_id) = self.lower_const_item(ty, span, expr.as_deref());
-                hir::ItemKind::Const(ty, body_id)
+            ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
+                let (generics, (ty, body_id)) = self.lower_generics(
+                    generics,
+                    Const::No,
+                    id,
+                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    |this| this.lower_const_item(ty, span, expr.as_deref()),
+                );
+                hir::ItemKind::Const(ty, generics, body_id)
             }
             ItemKind::Fn(box Fn {
                 sig: FnSig { decl, header, span: fn_sig_span },
@@ -715,11 +721,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let trait_item_def_id = hir_id.expect_owner();
 
         let (generics, kind, has_default) = match &i.kind {
-            AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
-                let ty =
-                    self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
-                let body = expr.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
-                (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
+            AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => {
+                let (generics, kind) = self.lower_generics(
+                    &generics,
+                    Const::No,
+                    i.id,
+                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    |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)));
+
+                        hir::TraitItemKind::Const(ty, body)
+                    },
+                );
+                (generics, kind, expr.is_some())
             }
             AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
                 let asyncness = sig.header.asyncness;
@@ -817,14 +835,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.lower_attrs(hir_id, &i.attrs);
 
         let (generics, kind) = match &i.kind {
-            AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
-                let ty =
-                    self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
-                (
-                    hir::Generics::empty(),
-                    hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
-                )
-            }
+            AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
+                &generics,
+                Const::No,
+                i.id,
+                &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                |this| {
+                    let ty = this
+                        .lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
+                    let body = this.lower_const_body(i.span, expr.as_deref());
+
+                    hir::ImplItemKind::Const(ty, body)
+                },
+            ),
             AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
                 self.current_item = Some(i.span);
                 let asyncness = sig.header.asyncness;
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 3663c450ba6..6b76e16825f 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3130,9 +3130,9 @@ impl<'hir> Item<'hir> {
     }
     /// Expect an [`ItemKind::Const`] or panic.
     #[track_caller]
-    pub fn expect_const(&self) -> (&'hir Ty<'hir>, BodyId) {
-        let ItemKind::Const(ty, body) = self.kind else { self.expect_failed("a constant") };
-        (ty, body)
+    pub fn expect_const(&self) -> (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId) {
+        let ItemKind::Const(ty, gen, body) = self.kind else { self.expect_failed("a constant") };
+        (ty, gen, body)
     }
     /// Expect an [`ItemKind::Fn`] or panic.
     #[track_caller]
@@ -3319,7 +3319,7 @@ pub enum ItemKind<'hir> {
     /// A `static` item.
     Static(&'hir Ty<'hir>, Mutability, BodyId),
     /// A `const` item.
-    Const(&'hir Ty<'hir>, BodyId),
+    Const(&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
     /// A function declaration.
     Fn(FnSig<'hir>, &'hir Generics<'hir>, BodyId),
     /// A MBE macro definition (`macro_rules!` or `macro`).
@@ -3372,6 +3372,7 @@ impl ItemKind<'_> {
         Some(match *self {
             ItemKind::Fn(_, ref generics, _)
             | ItemKind::TyAlias(_, ref generics)
+            | ItemKind::Const(_, ref generics, _)
             | ItemKind::OpaqueTy(OpaqueTy { ref generics, .. })
             | ItemKind::Enum(_, ref generics)
             | ItemKind::Struct(_, ref generics)
@@ -3567,7 +3568,9 @@ impl<'hir> OwnerNode<'hir> {
         match self {
             OwnerNode::Item(Item {
                 kind:
-                    ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body),
+                    ItemKind::Static(_, _, body)
+                    | ItemKind::Const(_, _, body)
+                    | ItemKind::Fn(_, _, body),
                 ..
             })
             | OwnerNode::TraitItem(TraitItem {
@@ -3770,9 +3773,9 @@ impl<'hir> Node<'hir> {
     pub fn ty(self) -> Option<&'hir Ty<'hir>> {
         match self {
             Node::Item(it) => match it.kind {
-                ItemKind::TyAlias(ty, _) | ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _) => {
-                    Some(ty)
-                }
+                ItemKind::TyAlias(ty, _)
+                | ItemKind::Static(ty, _, _)
+                | ItemKind::Const(ty, _, _) => Some(ty),
                 _ => None,
             },
             Node::TraitItem(it) => match it.kind {
@@ -3800,7 +3803,9 @@ impl<'hir> Node<'hir> {
         match self {
             Node::Item(Item {
                 kind:
-                    ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body),
+                    ItemKind::Static(_, _, body)
+                    | ItemKind::Const(_, _, body)
+                    | ItemKind::Fn(_, _, body),
                 ..
             })
             | Node::TraitItem(TraitItem {
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 347c1f4637f..a8a94e6a476 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -467,11 +467,17 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
         ItemKind::Use(ref path, _) => {
             visitor.visit_use(path, item.hir_id());
         }
-        ItemKind::Static(ref typ, _, body) | ItemKind::Const(ref typ, body) => {
+        ItemKind::Static(ref typ, _, body) => {
             visitor.visit_id(item.hir_id());
             visitor.visit_ty(typ);
             visitor.visit_nested_body(body);
         }
+        ItemKind::Const(ref typ, ref generics, body) => {
+            visitor.visit_id(item.hir_id());
+            visitor.visit_ty(typ);
+            visitor.visit_generics(generics);
+            visitor.visit_nested_body(body);
+        }
         ItemKind::Fn(ref sig, ref generics, body_id) => {
             visitor.visit_id(item.hir_id());
             visitor.visit_fn(
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index a9ef791077e..2bbdbe3a1f6 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -404,7 +404,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
                         icx.to_ty(ty)
                     }
                 }
-                ItemKind::Const(ty, body_id) => {
+                ItemKind::Const(ty, _, body_id) => {
                     if is_suggestable_infer_ty(ty) {
                         infer_placeholder_type(
                             tcx, def_id, body_id, ty.span, item.ident, "constant",
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index f1765174d79..ca7679cfba0 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -130,7 +130,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 a699cd6c942..2d8b956771b 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -420,12 +420,13 @@ impl<'a> State<'a> {
     fn print_associated_const(
         &mut self,
         ident: Ident,
+        generics: &hir::Generics<'_>,
         ty: &hir::Ty<'_>,
         default: Option<hir::BodyId>,
     ) {
-        self.head("");
         self.word_space("const");
         self.print_ident(ident);
+        self.print_generic_params(generics.params);
         self.word_space(":");
         self.print_type(ty);
         if let Some(expr) = default {
@@ -433,6 +434,7 @@ impl<'a> State<'a> {
             self.word_space("=");
             self.ann.nested(self, Nested::Body(expr));
         }
+        self.print_where_clause(generics);
         self.word(";")
     }
 
@@ -532,9 +534,10 @@ impl<'a> State<'a> {
                 self.word(";");
                 self.end(); // end the outer cbox
             }
-            hir::ItemKind::Const(ty, expr) => {
+            hir::ItemKind::Const(ty, generics, expr) => {
                 self.head("const");
                 self.print_ident(item.ident);
+                self.print_generic_params(generics.params);
                 self.word_space(":");
                 self.print_type(ty);
                 self.space();
@@ -542,6 +545,7 @@ impl<'a> State<'a> {
 
                 self.word_space("=");
                 self.ann.nested(self, Nested::Body(expr));
+                self.print_where_clause(generics);
                 self.word(";");
                 self.end(); // end the outer cbox
             }
@@ -836,7 +840,7 @@ impl<'a> State<'a> {
         self.print_outer_attributes(self.attrs(ti.hir_id()));
         match ti.kind {
             hir::TraitItemKind::Const(ty, default) => {
-                self.print_associated_const(ti.ident, ty, default);
+                self.print_associated_const(ti.ident, ti.generics, ty, default);
             }
             hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_names)) => {
                 self.print_method_sig(ti.ident, sig, ti.generics, arg_names, None);
@@ -865,7 +869,7 @@ impl<'a> State<'a> {
 
         match ii.kind {
             hir::ImplItemKind::Const(ty, expr) => {
-                self.print_associated_const(ii.ident, ty, Some(expr));
+                self.print_associated_const(ii.ident, ii.generics, ty, Some(expr));
             }
             hir::ImplItemKind::Fn(ref sig, body) => {
                 self.head("");
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3f1f10f2f00..8f5737dd4ad 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1394,7 +1394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let Some((
             _,
             hir::Node::Local(hir::Local { ty: Some(ty), .. })
-            | hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. }),
+            | hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }),
         )) = parent_node
         else {
             return;
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 864308267bb..c4d3cbc9faa 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -101,7 +101,7 @@ fn primary_body_of(
 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> {
     match node {
         Node::Item(item) => match item.kind {
-            hir::ItemKind::Const(ty, body) | hir::ItemKind::Static(ty, _, body) => {
+            hir::ItemKind::Const(ty, _, body) | hir::ItemKind::Static(ty, _, body) => {
                 Some((body, Some(ty), None))
             }
             hir::ItemKind::Fn(ref sig, .., body) => Some((body, None, Some(sig))),
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 6ffa3b0a0b3..4d236a86dda 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -924,7 +924,8 @@ 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().get(body_id.hir_id) {
                     hir::Node::Expr(expr) => {
                         if hir::is_range_literal(expr) {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index d3978e242a8..c000f988aa2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2068,7 +2068,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 visitor.visit_body(body);
                 visitor.result.map(|r| &r.peel_refs().kind)
             }
-            Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. })) => {
+            Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. })) => {
                 Some(&ty.peel_refs().kind)
             }
             _ => None,
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index cf6e7f16f07..ba05622bf37 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1529,9 +1529,10 @@ declare_lint_pass!(
 impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
         match it.kind {
-            hir::ItemKind::Const(_, body_id) => {
+            hir::ItemKind::Const(_, _, body_id) => {
                 let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
                 // trigger the query once for all constants since that will already report the errors
+                // FIXME(generic_const_items): Does this work properly with generic const items?
                 cx.tcx.ensure().const_eval_poly(def_id);
             }
             hir::ItemKind::Static(_, _, body_id) => {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 1fd68dc5cb2..b167364f680 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -24,7 +24,7 @@ pub fn associated_body(node: Node<'_>) -> Option<(LocalDefId, BodyId)> {
     match node {
         Node::Item(Item {
             owner_id,
-            kind: ItemKind::Const(_, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body),
+            kind: ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body),
             ..
         })
         | Node::TraitItem(TraitItem {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 1ae8031ef3c..c66eba5520e 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -570,7 +570,7 @@ fn construct_const<'a, 'tcx>(
     // Figure out what primary body this item has.
     let (span, const_ty_span) = match tcx.hir().get(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 160528e4074..7dec5b0acc8 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -236,7 +236,7 @@ impl<'tcx> ReachableContext<'tcx> {
                     // Reachable constants will be inlined into other crates
                     // unconditionally, so we need to make sure that their
                     // contents are also reachable.
-                    hir::ItemKind::Const(_, init) | hir::ItemKind::Static(_, _, init) => {
+                    hir::ItemKind::Const(_, _, init) | hir::ItemKind::Static(_, _, init) => {
                         self.visit_nested_body(init);
                     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index ff7854d51d9..38d6f1cb23d 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -655,6 +655,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         | hir::ItemKind::Impl(hir::Impl { generics, .. })
                         | hir::ItemKind::Fn(_, generics, _)
                         | hir::ItemKind::TyAlias(_, generics)
+                        | hir::ItemKind::Const(_, generics, _)
                         | hir::ItemKind::TraitAlias(generics, _)
                         | hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
                     ..
@@ -720,6 +721,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         | hir::ItemKind::Impl(hir::Impl { generics, .. })
                         | hir::ItemKind::Fn(_, generics, _)
                         | hir::ItemKind::TyAlias(_, generics)
+                        | hir::ItemKind::Const(_, generics, _)
                         | hir::ItemKind::TraitAlias(generics, _)
                         | hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
                     ..
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index aeae1dd0570..a26eb222c18 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2603,7 +2603,8 @@ fn clean_maybe_renamed_item<'tcx>(
             ItemKind::Static(ty, mutability, body_id) => {
                 StaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: Some(body_id) })
             }
-            ItemKind::Const(ty, body_id) => ConstantItem(Constant {
+            // FIXME(fmease): rustdoc integration
+            ItemKind::Const(ty, _generics, body_id) => ConstantItem(Constant {
                 type_: clean_ty(ty, cx),
                 kind: ConstantKind::Local { body: body_id, def_id },
             }),