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

  1. File a rustc ICE; this is an internal phase-ordering violation.
  2. 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.
  3. Bisect with cargo bisect-rustc to locate the ordering change.
  4. 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 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


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/914542374cd3605b. Report an issue: GitHub.