@@ -1371,13 +1371,187 @@ fn collect_type_variables(printer: &mut Printer<'_>, function: &ast::TypedFuncti
13711371}
13721372
13731373impl < ' ast , ' a , ' b > ast:: visit:: Visit < ' ast > for TypeVariableCollector < ' a , ' b > {
1374+ fn visit_typed_function ( & mut self , fun : & ' ast ast:: TypedFunction ) {
1375+ for argument in fun. arguments . iter ( ) {
1376+ if let Some ( annotation) = & argument. annotation {
1377+ register_type_variables_from_annotation (
1378+ self . printer ,
1379+ annotation,
1380+ argument. type_ . as_ref ( ) ,
1381+ ) ;
1382+ }
1383+ }
1384+
1385+ if let Some ( annotation) = & fun. return_annotation {
1386+ register_type_variables_from_annotation (
1387+ self . printer ,
1388+ annotation,
1389+ fun. return_type . as_ref ( ) ,
1390+ ) ;
1391+ }
1392+
1393+ ast:: visit:: visit_typed_function ( self , fun) ;
1394+ }
1395+
1396+ fn visit_typed_expr_fn (
1397+ & mut self ,
1398+ location : & ' ast SrcSpan ,
1399+ type_ : & ' ast Arc < Type > ,
1400+ kind : & ' ast FunctionLiteralKind ,
1401+ arguments : & ' ast [ TypedArg ] ,
1402+ body : & ' ast Vec1 < TypedStatement > ,
1403+ return_annotation : & ' ast Option < ast:: TypeAst > ,
1404+ ) {
1405+ if let Type :: Fn {
1406+ arguments : argument_types,
1407+ return_ : return_type,
1408+ ..
1409+ } = type_. as_ref ( )
1410+ {
1411+ for ( argument, argument_type) in arguments. iter ( ) . zip ( argument_types) {
1412+ if let Some ( annotation) = & argument. annotation {
1413+ register_type_variables_from_annotation (
1414+ self . printer ,
1415+ annotation,
1416+ argument_type. as_ref ( ) ,
1417+ ) ;
1418+ }
1419+ }
1420+
1421+ if let Some ( annotation) = return_annotation {
1422+ register_type_variables_from_annotation (
1423+ self . printer ,
1424+ annotation,
1425+ return_type. as_ref ( ) ,
1426+ ) ;
1427+ }
1428+ }
1429+
1430+ ast:: visit:: visit_typed_expr_fn (
1431+ self ,
1432+ location,
1433+ type_,
1434+ kind,
1435+ arguments,
1436+ body,
1437+ return_annotation,
1438+ ) ;
1439+ }
1440+
13741441 fn visit_type_ast_var ( & mut self , _location : & ' ast SrcSpan , name : & ' ast EcoString ) {
13751442 // Register this type variable so that we don't duplicate names when
13761443 // adding annotations.
13771444 self . printer . register_type_variable ( name. clone ( ) ) ;
13781445 }
13791446}
13801447
1448+ fn register_type_variables_from_annotation (
1449+ printer : & mut Printer < ' _ > ,
1450+ annotation : & ast:: TypeAst ,
1451+ type_ : & Type ,
1452+ ) {
1453+ // fn wibble(a, b, c) {
1454+ // fn(a: b, b: c) -> d { ... }
1455+ // ^
1456+ // Without this tracking the printer could rename `d` to a fresh `h`.
1457+ match ( annotation, type_) {
1458+ ( ast:: TypeAst :: Var ( ast:: TypeAstVar { name, .. } ) , Type :: Var { type_ } ) => {
1459+ match & * type_. borrow ( ) {
1460+ TypeVar :: Generic { id } | TypeVar :: Unbound { id } => {
1461+ let id = * id;
1462+ printer. register_type_variable ( name. clone ( ) ) ;
1463+ printer. register_type_variable_with_id ( id, name. clone ( ) ) ;
1464+ }
1465+ TypeVar :: Link { type_ } => {
1466+ register_type_variables_from_annotation ( printer, annotation, type_. as_ref ( ) ) ;
1467+ }
1468+ }
1469+ }
1470+
1471+ (
1472+ ast:: TypeAst :: Fn ( ast:: TypeAstFn {
1473+ arguments : annotation_arguments,
1474+ return_ : annotation_return,
1475+ ..
1476+ } ) ,
1477+ Type :: Fn {
1478+ arguments : type_arguments,
1479+ return_ : type_return,
1480+ ..
1481+ } ,
1482+ ) => {
1483+ for ( argument_annotation, argument_type) in
1484+ annotation_arguments. iter ( ) . zip ( type_arguments)
1485+ {
1486+ // Maintain the names from each `fn(arg: name, ...)` position.
1487+ register_type_variables_from_annotation (
1488+ printer,
1489+ argument_annotation,
1490+ argument_type. as_ref ( ) ,
1491+ ) ;
1492+ }
1493+
1494+ // And likewise propagate the annotated return variable.
1495+ register_type_variables_from_annotation (
1496+ printer,
1497+ annotation_return. as_ref ( ) ,
1498+ type_return. as_ref ( ) ,
1499+ ) ;
1500+ }
1501+
1502+ (
1503+ ast:: TypeAst :: Constructor ( ast:: TypeAstConstructor {
1504+ arguments : annotation_arguments,
1505+ ..
1506+ } ) ,
1507+ Type :: Named {
1508+ arguments : type_arguments,
1509+ ..
1510+ } ,
1511+ ) => {
1512+ for ( argument_annotation, argument_type) in
1513+ annotation_arguments. iter ( ) . zip ( type_arguments)
1514+ {
1515+ // Track aliases introduced inside named type arguments.
1516+ register_type_variables_from_annotation (
1517+ printer,
1518+ argument_annotation,
1519+ argument_type. as_ref ( ) ,
1520+ ) ;
1521+ }
1522+ }
1523+
1524+ (
1525+ ast:: TypeAst :: Tuple ( ast:: TypeAstTuple {
1526+ elements : annotation_elements,
1527+ ..
1528+ } ) ,
1529+ Type :: Tuple {
1530+ elements : type_elements,
1531+ ..
1532+ } ,
1533+ ) => {
1534+ for ( element_annotation, element_type) in annotation_elements. iter ( ) . zip ( type_elements)
1535+ {
1536+ // Tuples can hide extra annotations; ensure each slot retains its label.
1537+ register_type_variables_from_annotation (
1538+ printer,
1539+ element_annotation,
1540+ element_type. as_ref ( ) ,
1541+ ) ;
1542+ }
1543+ }
1544+
1545+ ( _, Type :: Var { type_ } ) => {
1546+ if let TypeVar :: Link { type_ } = & * type_. borrow ( ) {
1547+ register_type_variables_from_annotation ( printer, annotation, type_. as_ref ( ) ) ;
1548+ }
1549+ }
1550+
1551+ _ => { }
1552+ }
1553+ }
1554+
13811555pub struct QualifiedConstructor < ' a > {
13821556 import : & ' a Import < EcoString > ,
13831557 used_name : EcoString ,
0 commit comments