From e7cc93a1209c74f1940f3b8be86926236237fc76 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 16 Jun 2021 09:20:01 +0300 Subject: [PATCH] v.checker: allow for a `f(unsafe{voidptr(0)})` call of `fn f(x &Interface){}` --- vlib/v/checker/checker.v | 7 +++++-- ...pass_voidptr_as_interface_reference_test.v | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/interface_edge_cases/pass_voidptr_as_interface_reference_test.v 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)' +}