pub struct FnEntry {
pub decl: Arc<FnDecl>,
pub exported: bool,
pub is_test: bool,
pub doc: Option<String>,
pub receiver_type: Option<String>,
pub from_trait_default: Option<String>,
pub direct_capabilities: BTreeSet<Capability>,
pub required_capabilities: BTreeSet<Capability>,
pub direct_open_calls: BTreeSet<OpenCall>,
pub open_calls: BTreeSet<OpenCall>,
}Expand description
A declaration that belongs to a module, with the facts derived from it.
Fields§
§decl: Arc<FnDecl>§exported: bool§is_test: booltest fn: a declaration only the test runner calls.
A test is module-private by construction — export and test cannot
both apply — so it sees its module’s private declarations, and its
required capabilities are derived from its call graph exactly as any
other function’s are.
doc: Option<String>§receiver_type: Option<String>The type this function is a method of, when it came from an impl.
from_trait_default: Option<String>The trait whose default body this method runs, when the conformance did not supply one of its own.
Such a method’s body belongs to the trait, not to this type, so it is checked once where the trait declares it rather than once per conformance.
direct_capabilities: BTreeSet<Capability>Capabilities used directly in this function’s body.
required_capabilities: BTreeSet<Capability>Capabilities this function requires, including those reached through calls to other declarations of the package — its own module’s, and any module it imports from.
A call through a field access (receiver.method(...)) whose receiver
is not a bare reference to a struct or enum visible where the call is
written is resolved to every method sharing that name in this
module and in every module it imports from. There is no static type
checker yet to narrow the receiver’s actual type, so this is a
deliberate over-approximation: it can report a capability a function
does not really need, but never omits one it does. Static type
checking would let this be exact.
Module imports made no part of that precise. They widened it: an unknown receiver used to be able to reach only the module’s own methods, and can now reach the methods of every module reachable through its imports, because that is where a value it did not declare can come from. What they did narrow is the other direction — a call that leaves the module is now followed rather than lost, so a capability reached through an imported helper is reported instead of missed.
This set is a lower bound when FnEntry::open_calls is not empty;
see ADR 0015.
direct_open_calls: BTreeSet<OpenCall>The indirect calls written in this function’s own body: calls the
call graph cannot follow, so whatever they reach is not in
direct_capabilities.
open_calls: BTreeSet<OpenCall>Why required_capabilities is a lower bound rather than the whole of
what calling this function can reach — empty when it is the whole of
it.
This is direct_open_calls propagated over the same call graph the
capabilities travel: a caller of a capability-open declaration is
capability-open too, because the requirement it cannot see is one its
own callers cannot see either.
Implementations§
Source§impl FnEntry
impl FnEntry
Sourcepub fn is_capability_open(&self) -> bool
pub fn is_capability_open(&self) -> bool
Whether FnEntry::required_capabilities is a lower bound: this
function, or something it calls, makes a call the call graph cannot
follow.
Every report that shows a derived capability set asks this, so that an incomplete set is never shown as though it were complete.