Skip to content

Commit 489d076

Browse files
authored
fix incorrect static parameter definedness check (#49097)
We use the specialized signature of a method for accurate analysis of whether a static parameter is constrained or not. However, it turns out that we can only use it when it doesn't contain any free type variables (which it sometimes does, e.g., when the inference entry is given a signature with a free type variable). In such cases, we should use the method signature, which, by design, never contains any free type variables.
1 parent 0469154 commit 489d076

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

base/compiler/inferencestate.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,17 @@ function sptypes_from_meth_instance(linfo::MethodInstance)
487487
ty = UnionAll(tv, Type{tv})
488488
end
489489
@label ty_computed
490-
undef = !constrains_param(v, linfo.specTypes, #=covariant=#true)
490+
undef = !(let sig=sig
491+
# if the specialized signature `linfo.specTypes` doesn't contain any free
492+
# type variables, we can use it for a more accurate analysis of whether `v`
493+
# is constrained or not, otherwise we should use `def.sig` which always
494+
# doesn't contain any free type variables
495+
if !has_free_typevars(linfo.specTypes)
496+
sig = linfo.specTypes
497+
end
498+
@assert !has_free_typevars(sig)
499+
constrains_param(v, sig, #=covariant=#true)
500+
end)
491501
elseif isvarargtype(v)
492502
ty = Int
493503
undef = false

test/compiler/inference.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4684,6 +4684,26 @@ unknown_sparam_nothrow2(x::Ref{Ref{T}}) where T = @isdefined(T) ? T::Type : noth
46844684
@test only(Base.return_types(unknown_sparam_nothrow1, (Ref,))) === Type
46854685
@test only(Base.return_types(unknown_sparam_nothrow2, (Ref{Ref{T}} where T,))) === Type
46864686

4687+
struct Issue49027{Ty<:Number}
4688+
x::Ty
4689+
end
4690+
function issue49027(::Type{<:Issue49027{Ty}}) where Ty
4691+
if @isdefined Ty # should be false when `Ty` is given as a free type var.
4692+
return Ty::DataType
4693+
end
4694+
return nothing
4695+
end
4696+
@test only(Base.return_types(issue49027, (Type{Issue49027{TypeVar(:Ty)}},))) >: Nothing
4697+
@test isnothing(issue49027(Issue49027{TypeVar(:Ty)}))
4698+
function issue49027_integer(::Type{<:Issue49027{Ty}}) where Ty<:Integer
4699+
if @isdefined Ty # should be false when `Ty` is given as a free type var.
4700+
return Ty::DataType
4701+
end
4702+
nothing
4703+
end
4704+
@test only(Base.return_types(issue49027_integer, (Type{Issue49027{TypeVar(:Ty,Int)}},))) >: Nothing
4705+
@test isnothing(issue49027_integer(Issue49027{TypeVar(:Ty,Int)}))
4706+
46874707
function fapplicable end
46884708
gapplicable() = Val(applicable(fapplicable))
46894709
gapplicable(x) = Val(applicable(fapplicable; x))

0 commit comments

Comments
 (0)