diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 74db247e472b6..aea657404b249 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -487,7 +487,17 @@ function sptypes_from_meth_instance(linfo::MethodInstance) ty = UnionAll(tv, Type{tv}) end @label ty_computed - undef = !constrains_param(v, linfo.specTypes, #=covariant=#true) + undef = !(let sig=sig + # if the specialized signature `linfo.specTypes` doesn't contain any free + # type variables, we can use it for a more accurate analysis of whether `v` + # is constrained or not, otherwise we should use `def.sig` which always + # doesn't contain any free type variables + if !has_free_typevars(linfo.specTypes) + sig = linfo.specTypes + end + @assert !has_free_typevars(sig) + constrains_param(v, sig, #=covariant=#true) + end) elseif isvarargtype(v) ty = Int undef = false diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 85509ebf57199..e3d66c7531021 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -4684,6 +4684,26 @@ unknown_sparam_nothrow2(x::Ref{Ref{T}}) where T = @isdefined(T) ? T::Type : noth @test only(Base.return_types(unknown_sparam_nothrow1, (Ref,))) === Type @test only(Base.return_types(unknown_sparam_nothrow2, (Ref{Ref{T}} where T,))) === Type +struct Issue49027{Ty<:Number} + x::Ty +end +function issue49027(::Type{<:Issue49027{Ty}}) where Ty + if @isdefined Ty # should be false when `Ty` is given as a free type var. + return Ty::DataType + end + return nothing +end +@test only(Base.return_types(issue49027, (Type{Issue49027{TypeVar(:Ty)}},))) >: Nothing +@test isnothing(issue49027(Issue49027{TypeVar(:Ty)})) +function issue49027_integer(::Type{<:Issue49027{Ty}}) where Ty<:Integer + if @isdefined Ty # should be false when `Ty` is given as a free type var. + return Ty::DataType + end + nothing +end +@test only(Base.return_types(issue49027_integer, (Type{Issue49027{TypeVar(:Ty,Int)}},))) >: Nothing +@test isnothing(issue49027_integer(Issue49027{TypeVar(:Ty,Int)})) + function fapplicable end gapplicable() = Val(applicable(fapplicable)) gapplicable(x) = Val(applicable(fapplicable; x))