Skip to content

Commit fd7ac18

Browse files
committed
EXPERIMENT: closer to what Carl suggested
1 parent c4c95ef commit fd7ac18

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

crates/ty_python_semantic/src/types/builder.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,11 +463,10 @@ impl<'db> UnionBuilder<'db> {
463463
None
464464
};
465465

466-
// If an alias gets here, it means we aren't unpacking aliases, and we also shouldn't try
467-
// to simplify aliases out of the union, because that will require unpacking them.
468-
// `TypedDict`s also run into trouble here when their fields refer to a recursive union, so
469-
// and we need to skip simplification to break cycles.
470-
let should_simplify_full = !matches!(ty, Type::TypeAlias(_) | Type::TypedDict(_));
466+
// If an alias gets here, it means we aren't unpacking aliases, and we also
467+
// shouldn't try to simplify aliases out of the union, because that will require
468+
// unpacking them.
469+
let should_simplify_full = !matches!(ty, Type::TypeAlias(_));
471470

472471
let mut to_remove = SmallVec::<[usize; 2]>::new();
473472
let ty_negated = if should_simplify_full {
@@ -503,6 +502,18 @@ impl<'db> UnionBuilder<'db> {
503502
return;
504503
}
505504

505+
// Comparing `TypedDict`s for redundancy requires iterating over their fields, which is
506+
// problematic if some of those fields point to recursive `Union`s. To avoid cycles,
507+
// compare `TypedDict`s by name/identity instead of using the `has_relation_to`
508+
// machinery.
509+
if let (Type::TypedDict(element_td), Type::TypedDict(ty_td)) = (element_type, ty) {
510+
if element_td == ty_td {
511+
return;
512+
} else {
513+
continue;
514+
}
515+
}
516+
506517
if should_simplify_full && !matches!(element_type, Type::TypeAlias(_)) {
507518
if ty.is_redundant_with(self.db, element_type) {
508519
return;

0 commit comments

Comments
 (0)