-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Labels
bugIndicates an unexpected problem or unintended behaviorIndicates an unexpected problem or unintended behaviorcompiler:inferenceType inferenceType inference
Milestone
Description
On 1.6.3
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.6.3 (2021-09-23)
_/ |\__'_|_|_|\__'_| |
|__/ |
julia> function fluffs(a::Tuple{Int,Int,Int}, b::Tuple)::Bool
return Base.isequal(a, Base.inferencebarrier(b)::Tuple)
end
fluffs (generic function with 1 method)
julia> fluffs((1, 1, 1), (1, 1, 1))
true
julia> @code_typed optimize=false fluffs((1, 1, 1), (1, 1, 1))
CodeInfo(
1 ─ %1 = Main.Bool::Core.Const(Bool)
│ %2 = Base.isequal::Core.Const(isequal)
│ %3 = Base.inferencebarrier::Core.Const(Base.inferencebarrier)
│ %4 = (%3)(b)::Any
│ %5 = Core.typeassert(%4, Main.Tuple)::Tuple
│ %6 = (%2)(a, %5)::Any
│ %7 = Base.convert(%1, %6)::Any
│ %8 = Core.typeassert(%7, %1)::Bool
└── return %8
) => Bool
whereas on 1.7-RC1 and master
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.8.0-DEV.632 (2021-10-01)
_/ |\__'_|_|_|\__'_| | Commit df52b9409b (0 days old master)
|__/ |
julia> function fluffs(a::Tuple{Int,Int,Int}, b::Tuple)::Bool
return Base.isequal(a, Base.inferencebarrier(b)::Tuple)
end
fluffs (generic function with 1 method)
julia> fluffs((1, 1, 1), (1, 1, 1))
false
julia> @code_typed optimize=false fluffs((1, 1, 1), (1, 1, 1))
CodeInfo(
1 ─ %1 = Main.Bool::Core.Const(Bool)
│ %2 = Base.isequal::Core.Const(isequal)
│ %3 = Base.inferencebarrier::Core.Const(Base.inferencebarrier)
│ %4 = (%3)(b)::Any
│ %5 = Core.typeassert(%4, Main.Tuple)::Tuple
│ %6 = (%2)(a, %5)::Core.Const(false)
│ %7 = Base.convert(%1, %6)::Core.Const(false)
│ %8 = Core.typeassert(%7, %1)::Core.Const(false)
└── return %8
) => Bool
Notice that the isequal call has ::Core.Const(false) in the latter, which seems to be incorrect.
Interestingly, that still holds after dropping the ::Bool from the method signature, but
julia> function fluffs(a::Tuple{Int,Int,Int}, b::Tuple)
return Base.isequal(a, Base.inferencebarrier(b)::Tuple)
end
fluffs (generic function with 1 method)
julia> fluffs((1, 1, 1), (1, 1, 1))
true
julia> @code_typed optimize=false fluffs((1, 1, 1), (1, 1, 1))
CodeInfo(
1 ─ %1 = Base.isequal::Core.Const(isequal)
│ %2 = Base.inferencebarrier::Core.Const(Base.inferencebarrier)
│ %3 = (%2)(b)::Any
│ %4 = Core.typeassert(%3, Main.Tuple)::Tuple
│ %5 = (%1)(a, %4)::Core.Const(false)
└── return %5
) => Bool
Note that using the new definition for Base.isequal from 1.7-RC1/master on 1.6.3 yields the same issue:
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.6.3 (2021-09-23)
_/ |\__'_|_|_|\__'_| |
|__/ |
julia> begin
new_isequal(t1::Tuple, t2::Tuple) = length(t1) == length(t2) && _new_isequal(t1, t2)
_new_isequal(::Tuple{}, ::Tuple{}) = true
function _new_isequal(t1::Tuple{Any,Vararg{Any,N}}, t2::Tuple{Any,Vararg{Any,N}}) where {N}
isequal(t1[1], t2[1]) || return false
t1, t2 = Base.tail(t1), Base.tail(t2)
# avoid dynamic dispatch by telling the compiler relational invariants
return isa(t1, Tuple{}) ? true : _new_isequal(t1, t2::Tuple{Any,Vararg{Any}})
end
end
_new_isequal (generic function with 2 methods)
julia> function fluffs(a::Tuple{Int,Int,Int}, b::Tuple)::Bool
return new_isequal(a, Base.inferencebarrier(b)::Tuple)
end
fluffs (generic function with 1 method)
julia> fluffs((1, 1, 1), (1, 1, 1))
false
julia> @code_typed optimize=false fluffs((1, 1, 1), (1, 1, 1))
CodeInfo(
1 ─ %1 = Main.Bool::Core.Const(Bool)
│ %2 = Base.inferencebarrier::Core.Const(Base.inferencebarrier)
│ %3 = (%2)(b)::Any
│ %4 = Core.typeassert(%3, Main.Tuple)::Tuple
│ %5 = Main.new_isequal(a, %4)::Core.Const(false)
│ %6 = Base.convert(%1, %5)::Core.Const(false)
│ %7 = Core.typeassert(%6, %1)::Core.Const(false)
└── return %7
) => Bool
The new definition seems ok though, which suggests to me that the issue is in inference on 1.6.3, 1.7-RC1, and master. Best! :)
Metadata
Metadata
Assignees
Labels
bugIndicates an unexpected problem or unintended behaviorIndicates an unexpected problem or unintended behaviorcompiler:inferenceType inferenceType inference