mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
cgen: fix comptime is
condition when using interface (#20952)
This commit is contained in:
parent
0211a0d548
commit
a3bb422ec4
4 changed files with 46 additions and 4 deletions
|
@ -10,6 +10,10 @@ fn (mut c Checker) check_compatible_types(left_type ast.Type, right ast.TypeNode
|
|||
right_type := c.unwrap_generic(right.typ)
|
||||
sym := c.table.sym(right_type)
|
||||
|
||||
if right_type.has_flag(.option) != left_type.has_flag(.option) {
|
||||
return .skip
|
||||
}
|
||||
|
||||
if sym.kind == .interface_ {
|
||||
checked_type := c.unwrap_generic(left_type)
|
||||
return if c.table.does_type_implement_interface(checked_type, right_type) {
|
||||
|
|
|
@ -19,7 +19,8 @@ fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
|
|||
node.expr.pos())
|
||||
}
|
||||
|
||||
if !c.inside_unsafe && is_non_void_pointer && !node.expr.is_auto_deref_var() {
|
||||
if node.op != .question && !c.inside_unsafe && is_non_void_pointer
|
||||
&& !node.expr.is_auto_deref_var() {
|
||||
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos)
|
||||
}
|
||||
if !(typ_sym.is_number() || ((c.inside_unsafe || c.pref.translated) && is_non_void_pointer)) {
|
||||
|
|
|
@ -516,11 +516,11 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) (bool, bool) {
|
|||
got_sym := g.table.sym(got_type)
|
||||
|
||||
if got_sym.kind == .interface_ && got_sym.info is ast.Interface {
|
||||
is_true := g.table.does_type_implement_interface(exp_type,
|
||||
got_type)
|
||||
is_true := exp_type.has_flag(.option) == got_type.has_flag(.option)
|
||||
&& g.table.does_type_implement_interface(exp_type, got_type)
|
||||
if cond.op == .key_is {
|
||||
if is_true {
|
||||
g.write('1')
|
||||
g.write('1 && ${exp_type.has_flag(.option)} == ${got_type.has_flag(.option)}')
|
||||
} else {
|
||||
g.write('0')
|
||||
}
|
||||
|
|
37
vlib/v/tests/comptime_is_interface_check_test.v
Normal file
37
vlib/v/tests/comptime_is_interface_check_test.v
Normal file
|
@ -0,0 +1,37 @@
|
|||
module main
|
||||
|
||||
interface TestInterface {
|
||||
test_func() f64
|
||||
}
|
||||
|
||||
struct Struct1 {
|
||||
num f64
|
||||
}
|
||||
|
||||
fn (o &Struct1) test_func() f64 {
|
||||
return o.num
|
||||
}
|
||||
|
||||
struct Struct2 {
|
||||
mut:
|
||||
s1 ?&Struct1
|
||||
}
|
||||
|
||||
fn do_thing[T](s1 Struct1) T {
|
||||
mut t := T{}
|
||||
t.s1 = &s1
|
||||
$for field in T.fields {
|
||||
$if field.typ is TestInterface {
|
||||
i := TestInterface(t.$(field.name))
|
||||
assert false
|
||||
} $else $if field.typ is ?TestInterface {
|
||||
i := TestInterface(t.$(field.name) ?)
|
||||
assert true
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
assert do_thing[Struct2](Struct1{1.23}).s1?.num == 1.23
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue