diff --git a/src/core/tUnification.ml b/src/core/tUnification.ml index d9de382f217..b6454437306 100644 --- a/src/core/tUnification.ml +++ b/src/core/tUnification.ml @@ -796,6 +796,11 @@ let rec unify (uctx : unification_context) a b = | TEnum (ea,tl1) , TEnum (eb,tl2) -> if ea != eb then error [cannot_unify a b]; unify_type_params uctx a b tl1 tl2 + | TAbstract ({a_path=[],"Null"},[t1]), TAbstract ({a_path=[],"Null"},[t2]) -> + (* Unify the wrapped types directly so a monomorph on either side binds to the + unwrapped type instead of capturing the whole Null<...> - see #11077 *) + begin try unify uctx t1 t2 + with Unify_error l -> error (cannot_unify a b :: l) end | TAbstract ({a_path=[],"Null"},[t]),_ -> begin try unify uctx t b with Unify_error l -> error (cannot_unify a b :: l) end diff --git a/tests/nullsafety/src/cases/TestTypeParameters.hx b/tests/nullsafety/src/cases/TestTypeParameters.hx index f48fcf904f9..7d578e70e97 100644 --- a/tests/nullsafety/src/cases/TestTypeParameters.hx +++ b/tests/nullsafety/src/cases/TestTypeParameters.hx @@ -183,3 +183,18 @@ class TestDeepTypeParams { }); } } + +// Inlining a generic function returning Null must not bind the inline +// type-param monomorph to Null instead of Int. +@:nullSafety +class TestInlineGenericReturn { + static function main() { + final arr = [1, 2, 3]; + iter(arr, item -> true); + } + + static inline function iter(it:Array, callback:(item:T) -> Bool):Null { + for (v in it) callback(v); + return null; + } +}