@@ -3961,7 +3961,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
39613961 alias_node .normalized = rvalue .node .normalized
39623962 current_node = existing .node if existing else alias_node
39633963 assert isinstance (current_node , TypeAlias )
3964- self .disable_invalid_recursive_aliases (s , current_node )
3964+ self .disable_invalid_recursive_aliases (s , current_node , s . rvalue )
39653965 if self .is_class_scope ():
39663966 assert self .type is not None
39673967 if self .type .is_protocol :
@@ -4057,7 +4057,7 @@ def analyze_type_alias_type_params(
40574057 return declared_tvars , all_declared_tvar_names
40584058
40594059 def disable_invalid_recursive_aliases (
4060- self , s : AssignmentStmt , current_node : TypeAlias
4060+ self , s : AssignmentStmt | TypeAliasStmt , current_node : TypeAlias , ctx : Context
40614061 ) -> None :
40624062 """Prohibit and fix recursive type aliases that are invalid/unsupported."""
40634063 messages = []
@@ -4074,7 +4074,7 @@ def disable_invalid_recursive_aliases(
40744074 current_node .target = AnyType (TypeOfAny .from_error )
40754075 s .invalid_recursive_alias = True
40764076 for msg in messages :
4077- self .fail (msg , s . rvalue )
4077+ self .fail (msg , ctx )
40784078
40794079 def analyze_lvalue (
40804080 self ,
@@ -5304,6 +5304,8 @@ def visit_match_stmt(self, s: MatchStmt) -> None:
53045304 self .visit_block (s .bodies [i ])
53055305
53065306 def visit_type_alias_stmt (self , s : TypeAliasStmt ) -> None :
5307+ if s .invalid_recursive_alias :
5308+ return
53075309 self .statement = s
53085310 type_params = self .push_type_args (s .type_args , s )
53095311 if type_params is None :
@@ -5369,10 +5371,32 @@ def visit_type_alias_stmt(self, s: TypeAliasStmt) -> None:
53695371 and isinstance (existing .node , (PlaceholderNode , TypeAlias ))
53705372 and existing .node .line == s .line
53715373 ):
5372- existing .node = alias_node
5374+ updated = False
5375+ if isinstance (existing .node , TypeAlias ):
5376+ if existing .node .target != res :
5377+ # Copy expansion to the existing alias, this matches how we update base classes
5378+ # for a TypeInfo _in place_ if there are nested placeholders.
5379+ existing .node .target = res
5380+ existing .node .alias_tvars = alias_tvars
5381+ updated = True
5382+ else :
5383+ # Otherwise just replace existing placeholder with type alias.
5384+ existing .node = alias_node
5385+ updated = True
5386+
5387+ if updated :
5388+ if self .final_iteration :
5389+ self .cannot_resolve_name (s .name .name , "name" , s )
5390+ return
5391+ else :
5392+ # We need to defer so that this change can get propagated to base classes.
5393+ self .defer (s , force_progress = True )
53735394 else :
53745395 self .add_symbol (s .name .name , alias_node , s )
53755396
5397+ current_node = existing .node if existing else alias_node
5398+ assert isinstance (current_node , TypeAlias )
5399+ self .disable_invalid_recursive_aliases (s , current_node , s .value )
53765400 finally :
53775401 self .pop_type_args (s .type_args )
53785402
0 commit comments