Skip to content

Commit

Permalink
fix incorrect static parameter definedness check (#49097)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
aviatesk committed Mar 23, 2023
1 parent 0469154 commit 489d076
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
12 changes: 11 additions & 1 deletion base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

2 comments on commit 489d076

@vtjnash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nanosoldier runbenchmarks(ALL, isdaily = true)

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here.

Please sign in to comment.