{"record":{"id":"71bf16573b4039e3","repo":"astral-sh/ruff","slug":"typevar-should-be-interned-before-ordering","errorCode":null,"errorMessage":"typevar should be interned before ordering","messagePattern":"typevar should be interned before ordering","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_python_semantic/src/types/constraints.rs","lineNumber":1358,"sourceCode":"                    support.insert(typevar);\n                }\n                walk_type_with_recursion_guard(db, ty, self, &self.recursion_guard);\n            }\n        }\n\n        InternMentionedTypevars {\n            env,\n            storage: RefCell::new(self),\n            support: RefCell::new(support),\n            recursion_guard: TypeCollector::default(),\n        }\n        .visit_type(db, ty);\n    }\n\n    /// Interns all of the typevars mentioned in a constraint in a stable order.\n    fn intern_constraint_typevars(\n        &mut self,\n        db: &'db dyn Db,\n        env: &ProgramEnvironment<'db>,\n        constraint: Constraint<'db>,\n    ) -> Support {\n        let mut support = Support::default();\n        match constraint {\n            Constraint::ConcreteLower(constraint) => {\n                support.insert(self.intern_typevar(db, constraint.typevar));\n                self.intern_mentioned_typevars_in_type(db, env, constraint.bound, &mut support);\n            }\n            Constraint::ConcreteUpper(constraint) => {\n                support.insert(self.intern_typevar(db, constraint.typevar));\n                self.intern_mentioned_typevars_in_type(db, env, constraint.bound, &mut support);\n            }\n            Constraint::ConcreteEquivalence(constraint) => {\n                support.insert(self.intern_typevar(db, constraint.typevar));\n                self.intern_mentioned_typevars_in_type(db, env, constraint.bound, &mut support);\n            }\n            Constraint::TypeVarRange(constraint) => {","sourceCodeStart":1340,"sourceCodeEnd":1376,"githubUrl":"https://github.com/astral-sh/ruff/blob/5bb508f59481c1a02d5c7ff8568b9ffd8a763eef/crates/ty_python_semantic/src/types/constraints.rs#L1340-L1376","documentation":"Constraint-set storage interns every typevar through `intern_typevar` before it can be ordered; `typevar_id` only performs a lookup in `typevar_cache` keyed by typevar identity. The expect fires when ordering is requested for a `BoundTypeVarInstance` that was never interned in this builder - a typevar from another storage/overlay, or one added without going through the interning path.","triggerScenarios":"Calling ordering logic on a typevar whose constraints were never loaded into this builder: mixing storages, using a typevar after compaction split the storage, or a new code path that creates constraints without interning the typevar first.","commonSituations":"Contributions adding constraint-producing operations that bypass `intern_typevar`; overlay/borrow issues where the cache is ensured (`ensure_overlay_identity_caches`) but never populated; ordering-sensitive mdtests failing after a solver refactor.","solutions":["Ensure every code path that can later order a typevar calls `intern_typevar` (constraints.rs:1261) when adding its constraints.","If ordering foreign typevars is legitimate, make `typevar_id` intern on miss instead of expecting.","Add a regression test that orders a typevar immediately after adding constraints and one after compaction.","Report upstream with the reproducer if stock ty panics."],"exampleFix":"// before\nlet id = self.typevar_id(db, typevar);\n\n// after: intern first, ordering stays a pure lookup\nlet id = {\n    self.storage.borrow_mut().intern_typevar(db, typevar);\n    self.typevar_id(db, typevar)\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let id = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    builder.typevar_id(db, typevar)\n}))\n.ok(); // callers must treat None as 'not yet known to this builder'","preventionTips":["Contributors: every constraint-adding path must intern the typevar first; ordering is lookup-only by design.","Never reuse typevars across builders/storages in tests.","Reduce repros to the smallest typevar set that still panics before reporting."],"tags":["rust","panic","expect","ty","constraints","typevar","interning","ordering"],"backgroundTag":"constraint-solver-invariant-panic","analyzedSha":"5bb508f59481c1a02d5c7ff8568b9ffd8a763eef","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}