From bffa7f80e92a2c05f7ddfa5e8a45e46b8d99d063 Mon Sep 17 00:00:00 2001 From: odow Date: Tue, 2 Mar 2021 16:03:18 +1300 Subject: [PATCH] Fix inference issue in MOIU.Model --- src/Utilities/model.jl | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/Utilities/model.jl b/src/Utilities/model.jl index 20d30ed0f9..839a17bbb3 100644 --- a/src/Utilities/model.jl +++ b/src/Utilities/model.jl @@ -550,7 +550,7 @@ single_variable_flag(::Type{<:MOI.Semiinteger}) = 0x80 # If a set is added here, a line should be added in # `MOI.delete(::AbstractModel, ::MOI.VariableIndex)` -function flag_to_set_type(flag::UInt8, T::Type) +function flag_to_set_type(flag::UInt8, ::Type{T}) where {T} if flag == 0x1 return MOI.EqualTo{T} elseif flag == 0x2 @@ -565,27 +565,39 @@ function flag_to_set_type(flag::UInt8, T::Type) return MOI.ZeroOne elseif flag == 0x40 return MOI.Semicontinuous{T} - elseif flag == 0x80 - return MOI.Semiinteger{T} else - # $flag would print it in decimal - error("Invalid flag `$(sprint(show, flag))`.") + @assert flag == 0x80 + return MOI.Semiinteger{T} end end +# Julia doesn't infer `S1` correctly, so we use a function barrier to improve +# inference. +function _throw_if_lower_bound_set(variable, S2, mask, T) + S1 = flag_to_set_type(mask & LOWER_BOUND_MASK, T) + throw(MOI.LowerBoundAlreadySet{S1,S2}(variable)) + return +end + function throw_if_lower_bound_set(variable, S2, mask, T) flag = single_variable_flag(S2) if !iszero(flag & LOWER_BOUND_MASK) && !iszero(mask & LOWER_BOUND_MASK) - S1 = flag_to_set_type(mask & LOWER_BOUND_MASK, T) - throw(MOI.LowerBoundAlreadySet{S1,S2}(variable)) + _throw_if_lower_bound_set(variable, S2, mask, T) end end +# Julia doesn't infer `S1` correctly, so we use a function barrier to improve +# inference. +function _throw_if_upper_bound_set(variable, S2, mask, T) + S1 = flag_to_set_type(mask & LOWER_BOUND_MASK, T) + throw(MOI.LowerBoundAlreadySet{S1,S2}(variable)) + return +end + function throw_if_upper_bound_set(variable, S2, mask, T) flag = single_variable_flag(S2) if !iszero(flag & UPPER_BOUND_MASK) && !iszero(mask & UPPER_BOUND_MASK) - S1 = flag_to_set_type(mask & UPPER_BOUND_MASK, T) - throw(MOI.UpperBoundAlreadySet{S1,S2}(variable)) + _throw_if_upper_bound_set(variable, S2, mask, T) end end