From 1582db1a0a54e104fb43f19ad121ad9a8d4e1032 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 10 Jan 2023 08:49:04 +0200 Subject: [PATCH] comptime: add support for `T is $Alias` and `T is $Function` (#16929) --- vlib/v/ast/ast.v | 4 ++ vlib/v/ast/table.v | 6 +++ vlib/v/fmt/fmt.v | 2 + vlib/v/gen/golang/golang.v | 2 + vlib/v/parser/comptime.v | 8 +++- vlib/v/tests/comptime_kinds_test.v | 59 ++++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+), 1 deletion(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index da2e30519f..924b584278 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -126,6 +126,8 @@ pub enum ComptimeTypeKind { array sum_type enum_ + alias + function } pub struct ComptimeType { @@ -144,6 +146,8 @@ pub fn (cty ComptimeType) str() string { .array { '\$Array' } .sum_type { '\$Sumtype' } .enum_ { '\$Enum' } + .alias { '\$Alias' } + .function { '\$Function' } } } diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 9c1a372d7e..8c97e9cc47 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -2262,6 +2262,12 @@ pub fn (t &Table) is_comptime_type(x Type, y ComptimeType) bool { .enum_ { return x_kind == .enum_ } + .alias { + return x_kind == .alias + } + .function { + return x_kind == .function + } } } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index fbf839efd6..57e234fba7 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -731,6 +731,8 @@ pub fn (mut f Fmt) expr(node_ ast.Expr) { .float { f.write('\$Float') } .sum_type { f.write('\$Sumtype') } .enum_ { f.write('\$Enum') } + .alias { f.write('\$Alias') } + .function { f.write('\$Function') } } } } diff --git a/vlib/v/gen/golang/golang.v b/vlib/v/gen/golang/golang.v index 87b085d4bb..f902dbbf7d 100644 --- a/vlib/v/gen/golang/golang.v +++ b/vlib/v/gen/golang/golang.v @@ -659,6 +659,8 @@ pub fn (mut f Gen) expr(node_ ast.Expr) { .float { f.write('\$Float') } .sum_type { f.write('\$Sumtype') } .enum_ { f.write('\$Enum') } + .alias { f.write('\$Alias') } + .function { f.write('\$Function') } } } } diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index 0e2784eff7..cc109811a6 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -12,7 +12,7 @@ const ( supported_comptime_calls = ['html', 'tmpl', 'env', 'embed_file', 'pkgconfig', 'compile_error', 'compile_warn'] comptime_types = ['Map', 'Array', 'Int', 'Float', 'Struct', 'Interface', 'Enum', - 'Sumtype'] + 'Sumtype', 'Alias', 'Function'] ) pub fn (mut p Parser) parse_comptime_type() ast.ComptimeType { @@ -40,6 +40,12 @@ pub fn (mut p Parser) parse_comptime_type() ast.ComptimeType { 'Float' { cty = .float } + 'Alias' { + cty = .alias + } + 'Function' { + cty = .function + } 'Array' { cty = .array } diff --git a/vlib/v/tests/comptime_kinds_test.v b/vlib/v/tests/comptime_kinds_test.v index f54ad3df12..66956ec90c 100644 --- a/vlib/v/tests/comptime_kinds_test.v +++ b/vlib/v/tests/comptime_kinds_test.v @@ -82,3 +82,62 @@ fn test_kind_struct() { assert_not_struct[[]int]() assert_not_struct[map[int]int]() } + +// + +type AliasOfAbc = Abc +type AliasOfint = int +type AliasOfstring = string + +fn assert_alias[T]() { + $if T is $Alias { + assert true + } $else { + assert false + } +} + +fn assert_not_alias[T]() { + $if T is $Alias { + assert false + } $else { + assert true + } +} + +fn test_kind_alias() { + assert_alias[AliasOfAbc]() + assert_alias[AliasOfint]() + assert_alias[AliasOfstring]() + // + assert_not_alias[int]() + assert_not_alias[f32]() + assert_not_alias[[]int]() + assert_not_alias[map[int]int]() + assert_not_alias[Abc]() +} + +// +fn assert_function[T](f T) { + $if T is $Function { + assert true + } $else { + assert false + } +} + +fn assert_not_function[T](f T) { + $if T is $Function { + assert false + } $else { + assert true + } +} + +fn test_kind_function() { + assert_function(test_kind_function) + assert_not_function(123) + assert_function('abc'.contains) + i := 5 + assert_function(i.str) // TODO: 5.str currently leads to a cgen error +}