From 697cfa701fd8788ea202ceaaa3c6c0e7120e7807 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Thu, 14 Aug 2025 17:11:53 +0300 Subject: [PATCH] ast: allow using aliased types in interface method implementations (provide backwards compatibility to `ui`, during the migration of code from `gx` to `gg`) (#25106) --- vlib/v/ast/table.v | 3 +- vlib/v/pref/pref.v | 2 +- ...mplemented_with_type_aliased_params_test.v | 52 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/interfaces/interface_method_with_params_implemented_with_type_aliased_params_test.v diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 9ec37ca58..05bf379a6 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -218,7 +218,8 @@ pub fn (t &Table) is_same_method(f &Fn, func &Fn) string { for i in 0 .. f.params.len { // don't check receiver for `.typ` - has_unexpected_type := i > 0 && f.params[i].typ != func.params[i].typ + has_unexpected_type := i > 0 + && t.unaliased_type(f.params[i].typ) != t.unaliased_type(func.params[i].typ) // temporary hack for JS ifaces lsym := t.sym(f.params[i].typ) rsym := t.sym(func.params[i].typ) diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 1d2dbd938..83320e4a4 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -239,7 +239,7 @@ pub mut: cache_manager vcache.CacheManager gc_mode GarbageCollectionMode = .unknown // .no_gc, .boehm, .boehm_leak, ... assert_failure_mode AssertFailureMode // whether to call abort() or print_backtrace() after an assertion failure - message_limit int = 150 // the maximum amount of warnings/errors/notices that will be accumulated + message_limit int = 200 // the maximum amount of warnings/errors/notices that will be accumulated nofloat bool // for low level code, like kernels: replaces f32 with u32 and f64 with u64 use_coroutines bool // experimental coroutines fast_math bool // -fast-math will pass either -ffast-math or /fp:fast (for msvc) to the C backend diff --git a/vlib/v/tests/interfaces/interface_method_with_params_implemented_with_type_aliased_params_test.v b/vlib/v/tests/interfaces/interface_method_with_params_implemented_with_type_aliased_params_test.v new file mode 100644 index 000000000..8cca66307 --- /dev/null +++ b/vlib/v/tests/interfaces/interface_method_with_params_implemented_with_type_aliased_params_test.v @@ -0,0 +1,52 @@ +// This tests, whether type aliased values, can be used in place of their non aliased versions, +// when implementing interfaces. This is important for allowing type aliases in one module, +// to be used as substitutes to keep backwards compatibility, when migrating functionality +// from one module to another, which was the case, when deprecating `gx` in favor of moving +// its functionality into `gg`, while still keeping old code using `gx` compilable for a while, +// by making `gx` import `gg` and declare a few shallow type aliases to the new `gg` types, +// so that older `gx` importers and their CIs (like the `ui` module), can continue to work +// (with just deprecation notices), without forcing an immediate change. +struct Param1 { + x int +} + +struct Param2 { + y f32 +} + +type AliasParam1 = Param1 +type AliasParam2 = Param2 + +interface MyInterface { + method1(p1 Param1, p2 Param2) f32 +} + +struct ImplDirect { + v int +} + +fn (i ImplDirect) method1(p1 Param1, p2 Param2) f32 { + println(i) + println(p1) + println(p2) + return i.v + p1.x + p2.y +} + +struct ImplWithAliasedParams { + v int +} + +fn (i ImplWithAliasedParams) method1(p1 AliasParam1, p2 AliasParam2) f32 { + println(i) + println(p1) + println(p2) + return i.v + p1.x + p2.y +} + +fn test_interface_method_can_be_called_with_aliased_type_values() { + isdirect := MyInterface(ImplDirect{1000}) + isalias := MyInterface(ImplWithAliasedParams{2000}) + + assert isdirect.method1(AliasParam1{123}, AliasParam2{1.1}) == 1124.1 + assert isalias.method1(AliasParam1{456}, AliasParam2{2.2}) == 2458.2 +} -- 2.39.5