diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 56a90d9a0e..6bf201a43a 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -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) { diff --git a/vlib/v/checker/postfix.v b/vlib/v/checker/postfix.v index c59372229c..d043461f47 100644 --- a/vlib/v/checker/postfix.v +++ b/vlib/v/checker/postfix.v @@ -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)) { diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 9d97cb5301..20b142d8c5 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -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') } diff --git a/vlib/v/tests/comptime_is_interface_check_test.v b/vlib/v/tests/comptime_is_interface_check_test.v new file mode 100644 index 0000000000..a47842a057 --- /dev/null +++ b/vlib/v/tests/comptime_is_interface_check_test.v @@ -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 +}