Skip to content

Commit

Permalink
fix what we say about const fn
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Mar 24, 2024
1 parent b7a9816 commit fb0af69
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
14 changes: 11 additions & 3 deletions compiler/rustc_passes/src/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
//! An item is "externally reachable" if it is relevant for other crates. This obviously includes
//! all public items. However, some of these items cannot be compiled to machine code (because they
//! are generic), and for some the machine code is not sufficient (because we want to cross-crate
//! inline them, or run them in the compile-time MIR interpreter). These items "need cross-crate
//! MIR". When a reachable function `f` needs cross-crate MIR, then all the functions it calls also
//! become reachable, as they will be necessary to use the MIR of `f` from another crate.
//! inline them). These items "need cross-crate MIR". When a reachable function `f` needs
//! cross-crate MIR, then all the functions it calls also become reachable, as they will be
//! necessary to use the MIR of `f` from another crate.
use hir::def_id::LocalDefIdSet;
use rustc_data_structures::stack::ensure_sufficient_stack;
Expand All @@ -26,6 +26,12 @@ use rustc_target::spec::abi::Abi;

/// Determines whether this (assumed to be reachable) item "needs cross-crate MIR", i.e. whether
/// another crate needs to be able to access this items' MIR.
///
/// On top of what was explained above, `const fn` also "need cross-crate MIR". This is *not*
/// because we need the MIR to interpret them (MIR for const-eval and MIR for codegen is separate,
/// and MIR for const-eval is always encoded). Instead, it is because `const fn` can create `fn()`
/// pointers to other items which end up in the evaluated result of the constant and can then be
/// called from other crates. Those items must be considered reachable.
fn needs_cross_crate_mir(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
tcx.generics_of(def_id).requires_monomorphization(tcx)
|| tcx.cross_crate_inlinable(def_id)
Expand Down Expand Up @@ -449,6 +455,8 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
// items of non-exported traits (or maybe all local traits?) unless their respective
// trait items are used from inlinable code through method call syntax or UFCS, or their
// trait is a lang item.
// (But if you implement this, don't forget to take into account that vtables and also
// make trait methods reachable!)
let crate_items = tcx.hir_crate_items(());

for id in crate_items.items() {
Expand Down
8 changes: 7 additions & 1 deletion tests/ui/consts/auxiliary/issue-63226.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ pub struct VTable{
state:extern "C" fn(),
}

impl VTable{
impl VTable {
pub const fn vtable()->&'static VTable{
Self::VTABLE
}

const VTABLE: &'static VTable =
&VTable{state};

pub const VTABLE2: &'static VTable =
&VTable{state: state2};
}

// Only referenced via a `pub const fn`, and yet reachable.
extern "C" fn state() {}
// Only referenced via a `pub const`, and yet reachable.
extern "C" fn state2() {}
1 change: 1 addition & 0 deletions tests/ui/consts/issue-63226.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
use issue_63226::VTable;

static ICE_ICE:&'static VTable=VTable::vtable();
static MORE_ICE:&'static VTable=VTable::VTABLE2;

fn main() {}

0 comments on commit fb0af69

Please sign in to comment.