diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 83edab195e..cf88401336 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2698,8 +2698,11 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to } continue } - c.error("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`", - pos) + // voidptr is an escape hatch, it should be allowed to be passed + if utyp != ast.voidptr_type { + c.error("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`", + pos) + } } // Verify fields if mut inter_sym.info is ast.Interface { diff --git a/vlib/v/tests/interface_edge_cases/pass_voidptr_as_interface_reference_test.v b/vlib/v/tests/interface_edge_cases/pass_voidptr_as_interface_reference_test.v new file mode 100644 index 0000000000..0e332e2c74 --- /dev/null +++ b/vlib/v/tests/interface_edge_cases/pass_voidptr_as_interface_reference_test.v @@ -0,0 +1,19 @@ +interface IAbc { + xyz() +} + +struct Abc {} + +fn (a Abc) xyz() {} + +fn f(i &IAbc) string { + return '$i' +} + +fn test_passing_voidptr_as_an_interface_reference() { + i := IAbc(Abc{}) + assert f(&i) == '&IAbc(Abc{})' + // a voidptr() cast is an escape hatch, that should be allowed + // but perhaps it should be forced by the compiler to be in unsafe{} + assert f(unsafe { voidptr(0) }) == '&IAbc(0)' +}