From 711d7c49496a39333fdceaa30264c6e255a02708 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 1 Jun 2025 01:15:22 +0300 Subject: [PATCH] type_resolver: support `$if T is $pointer {` and `$if T is $voidptr {`, to make it easier to implement a pure V dump(), without cgen specific code (#24628) --- vlib/v/ast/ast.v | 4 ++ vlib/v/fmt/fmt.v | 2 + vlib/v/gen/golang/golang.v | 2 + vlib/v/parser/comptime.v | 8 +++- .../comptime/comptime_if_is_pointer_test.v | 37 +++++++++++++++++++ vlib/v/type_resolver/comptime_resolver.v | 6 +++ 6 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/comptime/comptime_if_is_pointer_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 06b7aef7a..c95b49e2e 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -162,6 +162,8 @@ pub enum ComptimeTypeKind { function option string + pointer + voidptr } pub struct ComptimeType { @@ -187,6 +189,8 @@ pub fn (cty ComptimeType) str() string { .function { '\$function' } .option { '\$option' } .string { '\$string' } + .pointer { '\$pointer' } + .voidptr { '\$voidptr' } } } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 9e7f1aba2..789e68187 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -800,6 +800,8 @@ pub fn (mut f Fmt) expr(node_ ast.Expr) { .function { f.write('\$function') } .option { f.write('\$option') } .string { f.write('\$string') } + .pointer { f.write('\$pointer') } + .voidptr { f.write('\$voidptr') } } } } diff --git a/vlib/v/gen/golang/golang.v b/vlib/v/gen/golang/golang.v index a452f0659..aba2c7e15 100644 --- a/vlib/v/gen/golang/golang.v +++ b/vlib/v/gen/golang/golang.v @@ -677,6 +677,8 @@ pub fn (mut f Gen) expr(node_ ast.Expr) { .function { f.write('\$function') } .option { f.write('\$option') } .string { f.write('\$string') } + .pointer { f.write('\$pointer') } + .voidptr { f.write('\$voidptr') } } } } diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index ee3c54d33..6024700be 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -10,7 +10,7 @@ import v.token const supported_comptime_calls = ['html', 'tmpl', 'env', 'embed_file', 'pkgconfig', 'compile_error', 'compile_warn', 'd', 'res'] const comptime_types = ['map', 'array', 'array_dynamic', 'array_fixed', 'int', 'float', 'struct', - 'interface', 'enum', 'sumtype', 'alias', 'function', 'option', 'string'] + 'interface', 'enum', 'sumtype', 'alias', 'function', 'option', 'string', 'pointer', 'voidptr'] fn (mut p Parser) parse_comptime_type() ast.ComptimeType { pos := p.tok.pos() @@ -63,6 +63,12 @@ fn (mut p Parser) parse_comptime_type() ast.ComptimeType { 'string' { .string } + 'pointer' { + .pointer + } + 'voidptr' { + .voidptr + } else { .unknown } diff --git a/vlib/v/tests/comptime/comptime_if_is_pointer_test.v b/vlib/v/tests/comptime/comptime_if_is_pointer_test.v new file mode 100644 index 000000000..33790394a --- /dev/null +++ b/vlib/v/tests/comptime/comptime_if_is_pointer_test.v @@ -0,0 +1,37 @@ +fn g[T](x T, is_pointer bool, is_voidptr bool) { + println('type: ${typeof[T]().name}, isreftype(T): ${isreftype(T)}') + $if T is $pointer { + println('T is \$pointer') + assert is_pointer + } $else { + println('T is NOT a \$pointer') + assert !is_pointer + } + $if T is $voidptr { + println('T is \$voidptr') + assert is_voidptr + } $else { + println('T is NOT a \$voidptr') + assert !is_voidptr + } + println('--------------------------') +} + +struct Abc {} + +fn test_is_pointer_and_is_voidptr() { + unsafe { + g(voidptr(123), true, true) + g(&char(456), true, false) + // + g(int(1000), false, false) + g(&int(1001), true, false) + g(&&int(1002), true, false) + g(&&&int(1003), true, false) + // + g(Abc{}, false, false) + g(&Abc(10001), true, false) + g(&&Abc(10002), true, false) + g(&&&Abc(10003), true, false) + } +} diff --git a/vlib/v/type_resolver/comptime_resolver.v b/vlib/v/type_resolver/comptime_resolver.v index 6d3376ed6..de3c1ca68 100644 --- a/vlib/v/type_resolver/comptime_resolver.v +++ b/vlib/v/type_resolver/comptime_resolver.v @@ -249,6 +249,12 @@ pub fn (t &TypeResolver) is_comptime_type(x ast.Type, y ast.ComptimeType) bool { .string { return x_kind == .string } + .voidptr { + return x.is_voidptr() + } + .pointer { + return x.is_any_kind_of_pointer() + } .int { return x_kind in [.i8, .i16, .i32, .int, .i64, .u8, .u16, .u32, .u64, .usize, .isize, .int_literal] -- 2.39.5