rust-lang/rust · error
this deprecation is always in effect; {since:?}
Error message
this deprecation is always in effect; {since:?} What it means
This `unreachable!` fires in `deprecated_since_kind` when a deprecation's `since` field is `NonStandard`, `Unspecified`, or `Err` yet `is_in_effect` returned `false`. Those three `DeprecatedSince` variants *mean* the deprecation is always in effect, so the function should have taken the `DeprecatedSinceKind::InEffect` branch at stability.rs:171 and never reached the match on `since`. Hitting it indicates a contradictory `Deprecation` value — the `since` field and `is_in_effect()` disagree — produced upstream by stability-attribute decoding/HIR processing.
Source
Thrown at compiler/rustc_middle/src/middle/stability.rs:181
diag.subdiagnostic(sub);
}
diag
}
}
fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
if is_in_effect {
DeprecatedSinceKind::InEffect
} else {
match since {
DeprecatedSince::RustcVersion(version) => {
DeprecatedSinceKind::InVersion(version.to_string())
}
DeprecatedSince::Future => DeprecatedSinceKind::InFuture,
DeprecatedSince::NonStandard(_)
| DeprecatedSince::Unspecified
| DeprecatedSince::Err => {
unreachable!("this deprecation is always in effect; {since:?}")
}
}
}
}
pub fn early_report_macro_deprecation(
lint_buffer: &mut LintBuffer,
depr: &Deprecation,
suggestion_span: Span,
node_id: NodeId,
path: String,
) {
if suggestion_span.in_derive_expansion() {
return;
}
let is_in_effect = depr.is_in_effect();
let suggestion = depr.suggestion;View on GitHub (pinned to 22057b88b0)
Solutions
- Inspect the offending crate's `#[deprecated(since = "...")]` attribute and supply a valid SemVer/RustcVersion string or remove the attribute.
- If reproducing from metadata, force a clean rebuild (`cargo clean`) to regenerate rmeta so stale stability data does not survive a toolchain change.
- File an ICE report against rustc including the attribute text and the `since` value from the panic message; this path is meant to be unreachable.
- For rustc hackers: audit the function populating `Deprecation.since` to ensure it sets `is_in_effect=true` for NonStandard/Unspecified/Err.
Example fix
// before #[deprecated(since = "??", note = "x")] // (decodes to DeprecatedSince::Err with is_in_effect == false → unreachable!) // after #[deprecated(since = "1.65.0", note = "x")]
Defensive patterns
Strategy: validation
Validate before calling
// deprecated_since_kind is unreachable when is_in_effect == false AND since is
// NonStandard | Unspecified | Err. Reject that combination before relying on it.
fn deprecation_kind_safe(is_in_effect: bool, since: &DeprecatedSince) -> bool {
if is_in_effect {
return true; // any `since` is fine
}
matches!(
since,
DeprecatedSince::RustcVersion(_) | DeprecatedSince::Future
)
}
if !deprecation_kind_safe(is_in_effect, &since) {
// Either force is_in_effect=true, or repair `since` to a concrete version.
return Err("deprecation not in effect and `since` carries no version");
} Try / catch
let kind = std::panic::catch_unwind(|| deprecated_since_kind(is_in_effect, since.clone()));
match kind {
Ok(k) => /* use k */,
Err(_) => /* fall back to treating the item as deprecated-now */,
} Prevention
- When authoring #[deprecated] attributes, always supply a concrete `since` version instead of leaving it unspecified.
- Before querying deprecation status, confirm `is_in_effect`; the unspecified/Err/Future variants are only reachable on the not-yet-in-effect path with a real version or Future marker.
- Do not synthesize DeprecatedSince::Err or NonStandard values in tooling that later flows into this function; remap them to a real version first.
- If you consume deprecation metadata from an external source, normalize it to RustcVersion(_) or Future before passing it downstream.
When it happens
Trigger: Decoding a `#[deprecated(since = ...)]` attribute whose `since` value resolves to `NonStandard(s)`, `Unspecified`, or `Err` while `Deprecation::is_in_effect()` simultaneously returns false. Concretely: a corrupted rmeta/crate metadata block for a stability attribute, a hand-constructed `Deprecation` struct in tests/fuzzers, or a regression in `rustc_ast::decode` / the stability query that miscomputes `is_in_effect`.
Common situations: Fuzzing the compiler with malformed `#[deprecated]` attributes; cross-version rmeta incompatibilities after a stability-query refactor; crates built with mismatched std/core stability metadata; custom rustc forks that altered `DeprecatedSince` encoding.
Related errors
- invalid level/lint_id combination
- there must be provenance somewhere here
- statics should not have generic parameters
- layout decided on a larger discriminant type ({min_ity:?}) t
- encountered a non-arbitrary layout during enum layout
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/63581b6cfeac23bc.json.
Report an issue: GitHub.