{"record":{"id":"85469f50f6419ad7","repo":"astral-sh/ruff","slug":"there-must-be-a-first-type-if-there-are-conflictin","errorCode":null,"errorMessage":"there must be a first type if there are conflicting types","messagePattern":"there must be a first type if there are conflicting types","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_python_semantic/src/place.rs","lineNumber":2145,"sourceCode":"                    false\n                } else {\n                    // An unconditional implementation shadows preceding overload definitions. A\n                    // conditional definition, however, can be only one public possibility among\n                    // several, so keep any unrelated queued overloaded function in the union.\n                    if reachability.is_always_true()\n                        || self.queue.is_some_and(|queued| {\n                            let Type::FunctionLiteral(queued_function) = queued else {\n                                return false;\n                            };\n                            let queued_definition = queued_function.last_definition(db);\n                            function.contains_definition(db, queued_definition)\n                        })\n                    {\n                        self.queue = None;\n                    } else {\n                        self.drain_queue();\n                    }\n                    self.add_to_union(element);\n                    true\n                }\n            }\n            _ => {\n                self.drain_queue();\n                self.add_to_union(element);\n                true\n            }\n        }\n    }\n\n    fn build(mut self) -> Type<'db> {\n        self.drain_queue();\n        self.builder.build()\n    }\n}\n\n/// Accumulates multiple (potentially conflicting) declared types and type qualifiers,","sourceCodeStart":2127,"sourceCodeEnd":2163,"githubUrl":"https://github.com/astral-sh/ruff/blob/5bb508f59481c1a02d5c7ff8568b9ffd8a763eef/crates/ty_python_semantic/src/place.rs#L2127-L2163","documentation":"DeclaredTypeAndConflictingTypesBuilder assembles a symbol's declared type plus the list of conflicting declared types recorded across multiple declarations. Its invariant is that whenever a conflicting type is recorded, the original first declared type is stashed in first_type; build() panics if conflicting_types is non-empty while first_type was never set.","triggerScenarios":"A symbol that receives two or more different declared types (for example `x: int` in one branch and `x: str]` in another, or repeated annotations) where the code path that pushed the conflicting type never recorded the first type first - a builder misuse or a missed update when a new conflict-recording path was added.","commonSituations":"Modules with multiple differently-annotated declarations of the same name (conditional imports, branch-local annotations); contributor changes to place_from_declarations conflict collection.","solutions":["Minimize the module to the two conflicting annotations that trigger the panic and file a ty issue with it","As a contributor: ensure every path that pushes onto conflicting_types sets first_type beforehand (record the original type before treating later types as conflicts)","Workaround until fixed: unify or remove one of the conflicting declarations for that name"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| check_file(&db, file)));\nmatch result {\n    Ok(diags) => diags,\n    Err(payload) => { log::warn!(\"ty panicked while declaring {}: {:?}\", file, payload); vec![] }\n}","preventionTips":["Avoid mixing multiple different annotations for one name across branches in a single module while a triggering bug is unfixed","When touching conflict collection in place.rs, set first_type on every path that appends to conflicting_types","Add builder unit tests covering the one-conflict and many-conflicts sequences"],"tags":["rust","ty","places","declared-types","panic","builder-invariant"],"backgroundTag":"builder-state-invariant","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"}