diff --git a/src/gf.c b/src/gf.c index ae4a1413b7849..4c8ae077192c1 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2421,6 +2421,12 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio closure->max_valid = ml->max_world; } } + // In some corner cases type intersection is conservative and returns something + // for intersect(A, B) even though A is a dispatch tuple and !(A <: B). + // For dispatch purposes in such a case we know there's no match. This check + // fixes issue #30394. + if (jl_is_dispatch_tupletype(closure->match.type) && !closure->match.issubty) + return 1; // a method is shadowed if type <: S <: m->sig where S is the // signature of another applicable method /* diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index a3066f99b939d..c6e59dc51412e 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2151,3 +2151,24 @@ g30098() = (h30098(:f30098); 4) h30098(f) = getfield(@__MODULE__, f)() @test @inferred(g30098()) == 4 # make sure that this @test @inferred(f30098()) == 3 # doesn't pollute the inference cache of this + +# issue #30394 +mutable struct Base30394 + a::Int +end + +mutable struct Foo30394 + foo_inner::Base30394 + Foo30394() = new(Base30394(1)) +end + +mutable struct Foo30394_2 + foo_inner::Foo30394 + Foo30394_2() = new(Foo30394()) +end + +f30394(foo::T1, ::Type{T2}) where {T2, T1 <: T2} = foo + +f30394(foo, T2) = f30394(foo.foo_inner, T2) + +@test Base.return_types(f30394, (Foo30394_2, Type{Base30394})) == Any[Base30394]