about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-06-03 15:32:13 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-06-05 15:40:11 +0000
commita0358f44b33301e28070327eae7804a88a912b15 (patch)
treee6b419df119addee5222ce0d0fbeb65c313d63fb
parent22d0073d47e7f82b0943db94babe40420205eb6a (diff)
downloadrust-a0358f44b33301e28070327eae7804a88a912b15.tar.gz
rust-a0358f44b33301e28070327eae7804a88a912b15.zip
Also support generic constants
-rw-r--r--compiler/rustc_passes/src/reachable.rs18
-rw-r--r--tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs11
2 files changed, 20 insertions, 9 deletions
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index ee632ea5df3..74b89546e6f 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -29,12 +29,12 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::Node;
+use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::middle::privacy::{self, Level};
 use rustc_middle::mir::interpret::{ConstAllocation, ErrorHandled, GlobalAlloc};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, ExistentialTraitRef, TyCtxt};
-use rustc_middle::{bug, span_bug};
 use rustc_privacy::DefIdVisitor;
 use rustc_session::config::CrateType;
 use tracing::debug;
@@ -206,19 +206,19 @@ 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(..) => {
+                    hir::ItemKind::Const(_, _, init) => {
+                        // Only things actually ending up in the final constant need to be reachable.
+                        // Everything else is either already available as `mir_for_ctfe`, or can't be used
+                        // by codegen anyway.
                         match self.tcx.const_eval_poly_to_alloc(item.owner_id.def_id.into()) {
                             Ok(alloc) => {
                                 let alloc = self.tcx.global_alloc(alloc.alloc_id).unwrap_memory();
                                 self.propagate_from_alloc(alloc);
                             }
-                            Err(ErrorHandled::TooGeneric(span)) => span_bug!(
-                                span,
-                                "generic constants aren't implemented in reachability"
-                            ),
+                            // Reachable generic constants will be inlined into other crates
+                            // unconditionally, so we need to make sure that their
+                            // contents are also reachable.
+                            Err(ErrorHandled::TooGeneric(_)) => self.visit_nested_body(init),
                             Err(ErrorHandled::Reported(..)) => {}
                         }
                     }
diff --git a/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs b/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs
index 35071e238f3..df50b4af809 100644
--- a/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs
+++ b/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs
@@ -3,6 +3,8 @@
 
 //@compile-flags: --crate-type=lib -Copt-level=0
 
+#![feature(generic_const_items)]
+
 const fn foo() {}
 
 pub static FOO: () = foo();
@@ -14,3 +16,12 @@ const fn bar() {}
 pub const BAR: () = bar();
 
 // CHECK-NOT: define{{.*}}bar{{.*}}
+
+const fn baz() {}
+
+#[rustfmt::skip]
+pub const BAZ<const C: bool>: () = if C {
+    baz()
+};
+
+// CHECK: define{{.*}}baz{{.*}}