rust-lang/rust · critical
Can't have a type error relating to itself
Error message
Can't have a type error relating to itself
What it means
This fires inside Polonius's `record_live_region_variance`, which extracts the variance (co/contra/invariant) of each region inside a type by relating the type with itself (`extractor.relate(value, value)`). Relating a type with itself should never produce a type error — identical types are always compatible. If it does, the compiler considers this a logic error in how the type or its regions were constructed.
Source
Thrown at compiler/rustc_borrowck/src/polonius/liveness_constraints.rs:26
use super::{ConstraintDirection, PoloniusContext};
use crate::universal_regions::UniversalRegions;
impl PoloniusContext {
/// Record the variance of each region contained within the given value.
pub(crate) fn record_live_region_variance<'tcx>(
&mut self,
tcx: TyCtxt<'tcx>,
universal_regions: &UniversalRegions<'tcx>,
value: impl TypeVisitable<TyCtxt<'tcx>> + Relate<TyCtxt<'tcx>>,
) {
let mut extractor = VarianceExtractor {
tcx,
ambient_variance: ty::Variance::Covariant,
directions: &mut self.live_region_variances,
universal_regions,
};
extractor.relate(value, value).expect("Can't have a type error relating to itself");
}
}
/// Extracts variances for regions contained within types. Follows the same structure as
/// `rustc_infer`'s `Generalizer`: we try to relate a type with itself to track and extract the
/// variances of regions.
struct VarianceExtractor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
ambient_variance: ty::Variance,
directions: &'a mut BTreeMap<RegionVid, ConstraintDirection>,
universal_regions: &'a UniversalRegions<'tcx>,
}
impl<'tcx> VarianceExtractor<'_, 'tcx> {
fn record_variance(&mut self, region: ty::Region<'tcx>, variance: ty::Variance) {
// We're only interested in the variance of vars and free regions.
//
// Note: even if we currently bail for two cases of unexpected region kinds here, missingView on GitHub (pinned to 7088e4b63a)
Solutions
- Remove `-Zpolonius=next` and use the default NLL borrow checker; this code path is exclusive to polonius.
- Minimize the reproduction and file a bug with the type that triggers the self-relation error.
- Update to the latest nightly; polonius variance extraction is under active development.
- If contributing to rustc, inspect the `VarianceExtractor` in `liveness_constraints.rs` — the `relate` call may need to handle additional region kinds that are currently unexpected.
Example fix
// before (complex GAT + opaque, triggers polonius variance ICE)
#![feature(polonius)]
trait L { type Item<T>; }
fn f<T>(x: <() as L>::Item<T>) { /* ... */ }
// after (avoid polonius for this crate; remove the flag)
// RUSTFLAGS='' cargo build (uses default NLL) Defensive patterns
Strategy: fallback
Validate before calling
// This is a compiler-internal invariant. No user-level validation possible. // The fallback is to not use -Zpolonius=next: // unset RUSTFLAGS or ensure -Zpolonius=next is not present
Prevention
- Don't use -Zpolonius=next on crates with complex GAT/opaque type interactions until polonius stabilizes.
- Maintain a known-good nightly version for polonius testing.
- Report the type that triggers self-relation failure to help fix the variance extractor.
- Use default NLL borrow checker for production builds.
When it happens
Trigger: During Polonius analysis (`-Zpolonius=next`), when the variance extractor encounters a type that cannot be related to itself. This implies a malformed or internally inconsistent type — e.g., a type with opaque/hidden regions, inference variables that escaped their scope, or a type-rewrite bug in the MIR type-check pass feeding bad data to polonius.
Common situations: Nightly Rust with `-Zpolonius=next` on code using complex generics, associated types, opaque types, or GATs where a type's internal structure is subtly inconsistent. This is a compiler soundness-adjacent invariant; the panic indicates the variance data would be wrong, so the compiler aborts rather than emit incorrect borrow-check results.
Related errors
- missing polonius context with `-Zpolonius=next`
- Polonius output is unavailable despite `-Z polonius`
- Accessing live loans requires `-Zpolonius=next`
- coroutine lowered from async gen fn should be in fn
- simd {}
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/f639becd91528a2b.
Report an issue: GitHub.