From e4ffc7f224f58e473045e8261f7c73f7d9fb11f1 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 17 Oct 2024 05:50:10 -0300 Subject: [PATCH] v: add support for `T.unaliased_typ` (#22546) --- vlib/v/ast/ast.v | 1 + vlib/v/checker/checker.v | 3 ++ vlib/v/gen/c/cgen.v | 4 +++ vlib/v/gen/c/comptime.v | 2 ++ vlib/v/gen/js/js.v | 8 ++++- vlib/v/parser/parser.v | 1 + .../comptime_generic_unaliased_typ_test.v | 35 +++++++++++++++++++ 7 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/comptime/comptime_generic_unaliased_typ_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index c8cd71cf56..03e94d1ca3 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -279,6 +279,7 @@ pub enum GenericKindField { unknown name typ + unaliased_typ } // `foo.bar` diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 62be8f886c..507155b630 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1513,6 +1513,9 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { .name { return ast.string_type } + .unaliased_typ { + return ast.int_type + } .typ { return ast.int_type } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index b55d570323..6f24e11518 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3880,6 +3880,10 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { g.write(int(g.unwrap_generic(node.name_type)).str()) return } + .unaliased_typ { + g.write(int(g.table.unaliased_type(g.unwrap_generic(node.name_type))).str()) + return + } .unknown { // ast.TypeOf of `typeof(string).idx` etc if node.field_name == 'name' { diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 84b54ac884..579c7cac66 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -473,6 +473,8 @@ fn (mut g Gen) get_expr_type(cond ast.Expr) ast.Type { ast.SelectorExpr { if cond.gkind_field == .typ { return g.unwrap_generic(cond.name_type) + } else if cond.gkind_field == .unaliased_typ { + return g.table.unaliased_type(g.unwrap_generic(cond.name_type)) } else { name := '${cond.expr}.${cond.field_name}' if name in g.comptime.type_map { diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 5803c9f020..4bd9e4ea26 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -3250,12 +3250,18 @@ fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) { } .typ { g.write('new int(') - g.write('${int(g.unwrap_generic(it.name_type))}') g.write(')') g.write(')') return } + .unaliased_typ { + g.write('new int(') + g.write('${int(g.table.unaliased_type(g.unwrap_generic(it.name_type)))}') + g.write(')') + g.write(')') + return + } .unknown { if node.field_name == 'name' { g.type_name(it.name_type) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 4f9880040c..0b29ffd40c 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2936,6 +2936,7 @@ fn (mut p Parser) name_expr() ast.Expr { fkind := match field { 'name' { ast.GenericKindField.name } 'typ' { ast.GenericKindField.typ } + 'unaliased_typ' { ast.GenericKindField.unaliased_typ } else { ast.GenericKindField.unknown } } pos.extend(p.tok.pos()) diff --git a/vlib/v/tests/comptime/comptime_generic_unaliased_typ_test.v b/vlib/v/tests/comptime/comptime_generic_unaliased_typ_test.v new file mode 100644 index 0000000000..c2c82a9b2b --- /dev/null +++ b/vlib/v/tests/comptime/comptime_generic_unaliased_typ_test.v @@ -0,0 +1,35 @@ +struct Struct { + a int +} + +type StructAlias = Struct + +fn test_main() { + mut a := StructAlias(Struct{}) + assert alias_first(a) == 'alias' + assert struct_first(a) == 'struct' +} + +fn alias_first[T](val T) string { + $if T is $alias { + return 'alias' + } $else $if T is $struct { + return 'struct' + } $else { + return 'else' + } +} + +fn struct_first[T](val T) string { + $if T is $struct { + return 'struct' + } $else $if T is $alias { + $if T.unaliased_typ is $struct { + return 'struct' + } $else { + return 'alias' + } + } $else { + return 'else' + } +}