Skip to content

Commit e2adda0

Browse files
committed
Stop expanding type aliases during name resolution (Phase 2)
names_typealias() now creates TK_TYPEALIASREF nodes instead of expanding aliases inline. The alias identity is preserved throughout the compiler pipeline — type system, reach, and codegen unfold on demand at each dispatch point. All 1423 C++ compiler tests pass. All tools (pony-lsp, pony-lint, pony-doc) and the full-program test runner build successfully. Key changes across 24 files: Names pass: - names_typealias() creates TK_TYPEALIASREF via REPLACE instead of reify+applycap+replace (names_applycap removed as dead code) Expression pass: - pass_expr handles TK_TYPEALIASREF constraint checking - expr_nominal keeps TK_TYPEALIASREF in place (no unfold) - find_infer_type unfolds aliases for tuple destructuring inference - entity_access unfolds aliases for tuple element access (._1, ._2) - check_auto_recover_newref unfolds aliases for auto-recovery eligibility Refer pass: - is_constructed_from unfolds aliases for "let x: Alias = x.create()" Type system: - subtype.c: is_literal unfolds TK_TYPEALIASREF so is_machine_word, is_pointer, etc. correctly identify aliased builtin types - viewpoint.c: unfold-and-redispatch in viewpoint_type/upper/lower - cap.c: unfold in cap_dispatch and modified_cap - safeto.c: unfold in safe_field_move, safe_to_autorecover, safe_to_move - typeparam.c: unfold in cap_from_constraint, apply_cap, constraint_cap; TK_TUPLETYPE fallback for invalid tuple constraints exposed by unfolding - reify.c: unfold in check_constraints for struct-as-typearg detection - alias.c: unfold in sendable() only (other alias.c functions keep Phase 1 behavior — compound alias cap handling deferred to follow-up) Flatten pass: - constraint_contains_tuple passes unfolded type as both constraint and scan to fix union member iteration Lambda/object: - find_possible_fun_defs: don't free unfolded AST (caller stores pointers) - catch_up_provides: unfold TK_TYPE alias definitions for ast_passes_type Array: - find_possible_element_types and iterator variant: don't free unfolded AST (caller stores element type pointers) Reach: - add_type: unfold-and-redispatch - trace_kind_append: unfold-and-redispatch - set_method_types: unfold for param cap extraction Codegen: - genname.c, gentrace.c, genmatch.c, gencall.c, genexpr.c: unfold at all TK_TYPEALIASREF dispatch points - gentrace.c: unfold in TRACE_MACHINE_WORD case for correct boxed/unboxed decision on aliased primitive types Design: #5007
1 parent d6f3873 commit e2adda0

File tree

26 files changed

+759
-147
lines changed

26 files changed

+759
-147
lines changed

src/libponyc/codegen/gencall.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "../pkg/platformfuns.h"
1111
#include "../type/cap.h"
1212
#include "../type/subtype.h"
13+
#include "../type/typealias.h"
1314
#include "../ast/stringtab.h"
1415
#include "../pass/expr.h"
1516
#include "../../libponyrt/mem/pool.h"
@@ -651,6 +652,16 @@ static bool contains_boxable(ast_t* type)
651652
return false;
652653
}
653654

655+
case TK_TYPEALIASREF:
656+
{
657+
ast_t* unfolded = typealias_unfold(type);
658+
pony_assert(unfolded != NULL);
659+
660+
bool ok = contains_boxable(unfolded);
661+
ast_free_unattached(unfolded);
662+
return ok;
663+
}
664+
654665
default:
655666
pony_assert(0);
656667
return false;

src/libponyc/codegen/genexpr.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "genoperator.h"
1010
#include "genreference.h"
1111
#include "../type/subtype.h"
12+
#include "../type/typealias.h"
1213
#include "../../libponyrt/mem/pool.h"
1314
#include "ponyassert.h"
1415

@@ -313,6 +314,19 @@ LLVMValueRef gen_assign_cast(compile_t* c, LLVMTypeRef l_type,
313314

314315
pony_assert(r_value != GEN_NOTNEEDED);
315316

317+
// Unfold type aliases so downstream dispatch sees concrete types.
318+
if(ast_id(type) == TK_TYPEALIASREF)
319+
{
320+
ast_t* unfolded = typealias_unfold(type);
321+
322+
if(unfolded != NULL)
323+
{
324+
LLVMValueRef result = gen_assign_cast(c, l_type, r_value, unfolded);
325+
ast_free_unattached(unfolded);
326+
return result;
327+
}
328+
}
329+
316330
LLVMTypeRef r_type = LLVMTypeOf(r_value);
317331

318332
if(r_type == l_type)

src/libponyc/codegen/genident.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "genopt.h"
88
#include "../reach/subtype.h"
99
#include "../type/subtype.h"
10+
#include "../type/typealias.h"
1011
#include "../../libponyrt/mem/pool.h"
1112
#include "ponyassert.h"
1213
#include <string.h>
@@ -21,6 +22,22 @@ static LLVMValueRef gen_is_value(compile_t* c, ast_t* left_type,
2122
static LLVMValueRef tuple_is(compile_t* c, ast_t* left_type, ast_t* right_type,
2223
LLVMValueRef l_value, LLVMValueRef r_value)
2324
{
25+
// Unfold type aliases to get the actual tuple types.
26+
ast_t* unfolded_l = NULL;
27+
ast_t* unfolded_r = NULL;
28+
29+
if(ast_id(left_type) == TK_TYPEALIASREF)
30+
{
31+
unfolded_l = typealias_unfold(left_type);
32+
if(unfolded_l != NULL) left_type = unfolded_l;
33+
}
34+
35+
if(ast_id(right_type) == TK_TYPEALIASREF)
36+
{
37+
unfolded_r = typealias_unfold(right_type);
38+
if(unfolded_r != NULL) right_type = unfolded_r;
39+
}
40+
2441
pony_assert(ast_id(left_type) == TK_TUPLETYPE);
2542
pony_assert(ast_id(right_type) == TK_TUPLETYPE);
2643
pony_assert(ast_childcount(left_type) == ast_childcount(right_type));
@@ -229,13 +246,28 @@ static LLVMValueRef tuple_is_box_element(compile_t* c, ast_t* l_field_type,
229246
LLVMValueRef l_field, LLVMValueRef r_fields, LLVMValueRef r_desc,
230247
unsigned int field_index)
231248
{
249+
// Unfold type alias to determine field kind.
250+
ast_t* check_field = l_field_type;
251+
ast_t* field_unfolded = NULL;
252+
253+
if(ast_id(check_field) == TK_TYPEALIASREF)
254+
{
255+
field_unfolded = typealias_unfold(check_field);
256+
257+
if(field_unfolded != NULL)
258+
check_field = field_unfolded;
259+
}
260+
232261
int field_kind = SUBTYPE_KIND_UNBOXED;
233262

234-
if((ast_id(l_field_type) == TK_TUPLETYPE))
263+
if((ast_id(check_field) == TK_TUPLETYPE))
235264
field_kind = SUBTYPE_KIND_TUPLE;
236-
else if(is_machine_word(l_field_type))
265+
else if(is_machine_word(check_field))
237266
field_kind = SUBTYPE_KIND_NUMERIC;
238267

268+
if(field_unfolded != NULL)
269+
ast_free_unattached(field_unfolded);
270+
239271
LLVMValueRef r_field_info = gendesc_fieldinfo(c, r_desc, field_index);
240272
LLVMValueRef r_field_ptr = gendesc_fieldptr(c, r_fields, r_field_info);
241273
LLVMValueRef r_field_desc = gendesc_fielddesc(c, r_field_info);
@@ -297,6 +329,17 @@ static LLVMValueRef tuple_is_box(compile_t* c, ast_t* left_type,
297329
pony_assert(LLVMGetTypeKind(LLVMTypeOf(l_value)) == LLVMStructTypeKind);
298330
pony_assert(LLVMGetTypeKind(LLVMTypeOf(r_value)) == LLVMPointerTypeKind);
299331

332+
// Unfold type aliases to get the actual tuple type.
333+
ast_t* unfolded_left = NULL;
334+
335+
if(ast_id(left_type) == TK_TYPEALIASREF)
336+
{
337+
unfolded_left = typealias_unfold(left_type);
338+
339+
if(unfolded_left != NULL)
340+
left_type = unfolded_left;
341+
}
342+
300343
size_t cardinality = ast_childcount(left_type);
301344

302345
// If check_cardinality is false, trust the caller and don't do the check.

src/libponyc/codegen/genmatch.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "../type/subtype.h"
1111
#include "../type/matchtype.h"
1212
#include "../type/alias.h"
13+
#include "../type/typealias.h"
1314
#include "../type/viewpoint.h"
1415
#include "../type/lookup.h"
1516
#include "ponyassert.h"
@@ -214,6 +215,16 @@ static bool check_type(compile_t* c, LLVMValueRef ptr, LLVMValueRef desc,
214215
return check_type(c, ptr, desc, ast_childidx(pattern_type, 1),
215216
next_block, weight);
216217

218+
case TK_TYPEALIASREF:
219+
{
220+
ast_t* unfolded = typealias_unfold(pattern_type);
221+
pony_assert(unfolded != NULL);
222+
223+
bool ok = check_type(c, ptr, desc, unfolded, next_block, weight);
224+
ast_free_unattached(unfolded);
225+
return ok;
226+
}
227+
217228
default: {}
218229
}
219230

@@ -593,6 +604,16 @@ static bool static_tuple(compile_t* c, LLVMValueRef value, ast_t* type,
593604
return static_tuple(c, value, ast_childidx(type, 1), pattern,
594605
next_block);
595606

607+
case TK_TYPEALIASREF:
608+
{
609+
ast_t* unfolded = typealias_unfold(type);
610+
pony_assert(unfolded != NULL);
611+
612+
bool ok = static_tuple(c, value, unfolded, pattern, next_block);
613+
ast_free_unattached(unfolded);
614+
return ok;
615+
}
616+
596617
default: {}
597618
}
598619

src/libponyc/codegen/genname.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "genname.h"
22
#include "../pkg/package.h"
3+
#include "../type/typealias.h"
34
#include "../ast/stringtab.h"
45
#include "../ast/lexer.h"
56
#include "../../libponyrt/mem/pool.h"
@@ -57,6 +58,16 @@ static void type_append(printbuf_t* buf, ast_t* type, bool first)
5758
return;
5859
}
5960

61+
case TK_TYPEALIASREF:
62+
{
63+
ast_t* unfolded = typealias_unfold(type);
64+
pony_assert(unfolded != NULL);
65+
66+
type_append(buf, unfolded, first);
67+
ast_free_unattached(unfolded);
68+
return;
69+
}
70+
6071
default: {}
6172
}
6273

src/libponyc/codegen/genoperator.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "gentype.h"
77
#include "../pkg/platformfuns.h"
88
#include "../type/subtype.h"
9+
#include "../type/typealias.h"
910
#include "ponyassert.h"
1011

1112
typedef LLVMValueRef (*build_binop)(LLVMBuilderRef builder, LLVMValueRef left,
@@ -348,9 +349,21 @@ static LLVMValueRef assign_field(compile_t* c, LLVMValueRef l_value,
348349
static bool assign_tuple(compile_t* c, ast_t* left, ast_t* r_type,
349350
LLVMValueRef r_value)
350351
{
352+
// Unfold type aliases to get the actual tuple element types.
353+
ast_t* iter_type = r_type;
354+
ast_t* unfolded = NULL;
355+
356+
if(ast_id(r_type) == TK_TYPEALIASREF)
357+
{
358+
unfolded = typealias_unfold(r_type);
359+
360+
if(unfolded != NULL)
361+
iter_type = unfolded;
362+
}
363+
351364
// Handle assignment for each component.
352365
ast_t* child = ast_child(left);
353-
ast_t* rtype_child = ast_child(r_type);
366+
ast_t* rtype_child = ast_child(iter_type);
354367
int i = 0;
355368

356369
while(child != NULL)
@@ -395,6 +408,10 @@ static bool assign_tuple(compile_t* c, ast_t* left, ast_t* r_type,
395408
}
396409

397410
pony_assert(rtype_child == NULL);
411+
412+
if(unfolded != NULL)
413+
ast_free_unattached(unfolded);
414+
398415
return true;
399416
}
400417

src/libponyc/codegen/genreference.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "../reach/subtype.h"
1212
#include "../type/cap.h"
1313
#include "../type/subtype.h"
14+
#include "../type/typealias.h"
1415
#include "../type/viewpoint.h"
1516
#include "../../libponyrt/mem/pool.h"
1617
#include "ponyassert.h"
@@ -435,9 +436,21 @@ static LLVMValueRef gen_digestof_value(compile_t* c, ast_t* type,
435436

436437
case LLVMStructTypeKind:
437438
{
439+
// Unfold type aliases to get the actual tuple element types.
440+
ast_t* iter_type = type;
441+
ast_t* unfolded = NULL;
442+
443+
if(ast_id(type) == TK_TYPEALIASREF)
444+
{
445+
unfolded = typealias_unfold(type);
446+
447+
if(unfolded != NULL)
448+
iter_type = unfolded;
449+
}
450+
438451
uint32_t count = LLVMCountStructElementTypes(impl_type);
439452
LLVMValueRef result = LLVMConstInt(c->intptr, 0, false);
440-
ast_t* child = ast_child(type);
453+
ast_t* child = ast_child(iter_type);
441454

442455
for(uint32_t i = 0; i < count; i++)
443456
{
@@ -449,6 +462,9 @@ static LLVMValueRef gen_digestof_value(compile_t* c, ast_t* type,
449462

450463
pony_assert(child == NULL);
451464

465+
if(unfolded != NULL)
466+
ast_free_unattached(unfolded);
467+
452468
return result;
453469
}
454470

0 commit comments

Comments
 (0)