rust-lang/rust · error
features not available at this point in the compiler
Error message
features not available at this point in the compiler
What it means
interface.rs:297: AcceptContext::features() does self.features.expect("features not available at this point in the compiler"). AcceptContext.features is Option<&Features>; an attribute parser that calls features() before the feature-gate information has been attached to the context panics. The invariant: features() must only be called during the attribute-acceptance phase after features are populated.
Source
Thrown at compiler/rustc_attr_parsing/src/interface.rs:297
attr_tools: &'sess RegisteredTools,
should_emit: ShouldEmit,
) -> Self {
Self {
features: Some(features),
attr_tools: Some(attr_tools),
parse_filter: None,
sess,
should_emit,
}
}
pub(crate) fn sess(&self) -> &'sess Session {
self.sess
}
#[track_caller]
pub(crate) fn features(&self) -> &'sess Features {
self.features.expect("features not available at this point in the compiler")
}
pub(crate) fn features_option(&self) -> Option<&'sess Features> {
self.features
}
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'sess> {
self.sess().dcx()
}
pub(crate) fn emit_err(&self, diag: impl for<'x> Diagnostic<'x>) -> ErrorGuaranteed {
self.should_emit.emit_err(self.sess.dcx().create_err(diag))
}
/// Parse a list of attributes.
///
/// `target_span` is the span of the thing this list of attributes is applied to,
/// and when `omit_doc` is set, doc attributes are filtered out.View on GitHub (pinned to 7088e4b63a)
Solutions
- File a rustc ICE; this is an internal phase-ordering violation.
- If you are writing/patching a compiler attribute parser, gate the call: use cx.features_option() (provided just above) instead of cx.features() when features may be absent.
- Bisect with cargo bisect-rustc to locate the ordering change.
- Reduce the triggering attribute set to the minimum that exercises the early parser.
Example fix
// before (compiler code)
let feats = cx.features(); // panics if features not set yet
// after
let feats = cx.features_option(); // None-safe
match feats {
Some(f) if f.enabled(sym::my_feature) => { /* ... */ }
_ => { /* feature not available; skip */ }
} Defensive patterns
Strategy: validation
Validate before calling
// Compiler-internal: prefer the None-safe accessor. let feats = cx.features_option(); let on = feats.is_some_and(|f| f.enabled(sym::my_feature));
Prevention
- When patching the compiler, call cx.features_option() (None-safe) unless you are certain features are set.
- Only call cx.features() during the attribute-acceptance phase after features are populated.
- Register attribute parsers to run in a phase that has feature information.
- File an ICE if it triggers on a stock toolchain.
When it happens
Trigger: An attribute parser invokes cx.features() outside the window where AcceptContext.features has been set (e.g. during early validation before feature computation, or in a context that intentionally has no features).
Common situations: A compiler-developer mistake calling features() too early, or an attribute registered to run in a phase that lacks feature info; an internal ordering bug.
Related errors
- cfg_attr has docs
- alt layout should always work
- alt layout should have a niche like the regular one
- `Self` generic param is not found while expected
- must be at least one segment
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/914542374cd3605b.
Report an issue: GitHub.