Skip to content

Commit 8a05c6b

Browse files
committed
Stop expanding type aliases during name resolution
Type aliases now persist as TK_TYPEALIASREF nodes throughout the compiler pipeline instead of being expanded inline during name resolution. The type system, reach subsystem, and codegen unfold aliases on demand at each dispatch point. This preserves alias identity in the AST, enabling LSP features like go-to-definition on alias names and laying the groundwork for finite recursive type aliases. Closes #745 Design: #5007
1 parent ecf59a1 commit 8a05c6b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1495
-176
lines changed

src/libponyc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ add_library(libponyc STATIC
8989
type/safeto.c
9090
type/sanitise.c
9191
type/subtype.c
92+
type/typealias.c
9293
type/typeparam.c
9394
type/viewpoint.c
9495
verify/call.c

src/libponyc/ast/ast.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,31 @@ static void print_type(printbuf_t* buffer, ast_t* type, bool print_cap)
18441844
break;
18451845
}
18461846

1847+
case TK_TYPEALIASREF:
1848+
{
1849+
AST_GET_CHILDREN(type, id, typeargs, cap, ephemeral);
1850+
1851+
ast_t* def = (ast_t*)ast_data(type);
1852+
if(def != NULL)
1853+
id = ast_child(def);
1854+
1855+
printbuf(buffer, "%s", ast_nice_name(id));
1856+
1857+
if(ast_id(typeargs) != TK_NONE)
1858+
print_typeexpr(buffer, typeargs, ", ", true, true);
1859+
1860+
if(print_cap)
1861+
{
1862+
if(ast_id(cap) != TK_NONE)
1863+
printbuf(buffer, " %s", token_print(cap->t));
1864+
1865+
if(ast_id(ephemeral) != TK_NONE)
1866+
printbuf(buffer, "%s", token_print(ephemeral->t));
1867+
}
1868+
1869+
break;
1870+
}
1871+
18471872
case TK_ARROW:
18481873
{
18491874
AST_GET_CHILDREN(type, left, right);
@@ -2230,6 +2255,7 @@ static void ast_serialise_trace_data(pony_ctx_t* ctx, ast_t* ast)
22302255
case TK_FUN:
22312256
case TK_TYPEPARAM:
22322257
case TK_TYPEPARAMREF:
2258+
case TK_TYPEALIASREF:
22332259
case TK_REFERENCE:
22342260
case TK_PACKAGEREF:
22352261
case TK_TYPEREF:
@@ -2286,6 +2312,7 @@ static void ast_serialise_data(pony_ctx_t* ctx, ast_t* ast, ast_t* dst)
22862312
case TK_FUN:
22872313
case TK_TYPEPARAM:
22882314
case TK_TYPEPARAMREF:
2315+
case TK_TYPEALIASREF:
22892316
case TK_REFERENCE:
22902317
case TK_PACKAGEREF:
22912318
case TK_TYPEREF:
@@ -2336,6 +2363,7 @@ static void ast_deserialise_data(pony_ctx_t* ctx, ast_t* ast)
23362363
case TK_FUN:
23372364
case TK_TYPEPARAM:
23382365
case TK_TYPEPARAMREF:
2366+
case TK_TYPEALIASREF:
23392367
case TK_REFERENCE:
23402368
case TK_PACKAGEREF:
23412369
case TK_TYPEREF:

src/libponyc/ast/lexer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ static const lextoken_t abstract[] =
288288
{ "packageref", TK_PACKAGEREF },
289289
{ "typeref", TK_TYPEREF },
290290
{ "typeparamref", TK_TYPEPARAMREF },
291+
{ "typealiasref", TK_TYPEALIASREF },
291292
{ "newref", TK_NEWREF },
292293
{ "newberef", TK_NEWBEREF },
293294
{ "beref", TK_BEREF },

src/libponyc/ast/token.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ typedef enum token_id
238238
TK_PACKAGEREF,
239239
TK_TYPEREF,
240240
TK_TYPEPARAMREF,
241+
TK_TYPEALIASREF,
241242
TK_NEWREF,
242243
TK_NEWBEREF,
243244
TK_BEREF,

src/libponyc/ast/treecheckdef.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,9 @@ RULE(param_ref,
488488

489489
GROUP(type,
490490
type_infix, type_tuple, type_arrow, type_this, cap, nominal,
491-
type_param_ref, dontcare_type, fun_type, error_type, infer_type, lambda_type,
492-
barelambda_type, literal_type, opliteral_type, control_type);
491+
type_param_ref, type_alias_ref, dontcare_type, fun_type, error_type,
492+
infer_type, lambda_type, barelambda_type, literal_type, opliteral_type,
493+
control_type);
493494

494495
RULE(type_infix, ONE_OR_MORE(type), TK_UNIONTYPE, TK_ISECTTYPE);
495496

@@ -548,6 +549,14 @@ RULE(type_param_ref,
548549
CHILD(aliased, ephemeral, none),
549550
TK_TYPEPARAMREF);
550551

552+
RULE(type_alias_ref,
553+
HAS_DATA // Definition of referred type alias (TK_TYPE)
554+
CHILD(id)
555+
CHILD(type_args, none)
556+
CHILD(cap, gencap, none)
557+
CHILD(aliased, ephemeral, none),
558+
TK_TYPEALIASREF);
559+
551560
RULE(at, LEAF, TK_AT);
552561
RULE(bool_literal, HAS_TYPE(type), TK_TRUE, TK_FALSE);
553562
RULE(aliased, LEAF, TK_ALIASED);

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

0 commit comments

Comments
 (0)