Skip to content

invalid usage of @assume_effects in base/irrationals.jl #55874

Closed
@nsajko

Description

There are four methods with @assume_effects :total applied to the entire method in base/irrationals.jl:

@assume_effects :total function Rational{T}(x::AbstractIrrational) where T<:Integer

@assume_effects :total function (t::Type{T})(x::AbstractIrrational, r::RoundingMode) where T<:Union{Float32,Float64}

julia/base/irrationals.jl

Lines 113 to 120 in 6e5e87b

@assume_effects :total function rationalize(::Type{T}, x::AbstractIrrational; tol::Real=0) where T
return rationalize(T, big(x), tol=tol)
end
@assume_effects :total function lessrational(rx::Rational{<:Integer}, x::AbstractIrrational)
# an @assume_effects :total version of `<` for determining if the rationalization of
# an irrational number required rounding up or down
return rx < big(x)
end

Issues:

  • The :total effect is too powerful and not future-proof. I guess what's actually desired is just :foldable.
  • It's not valid to apply @assume_effects to the ::AbstractIrrational methods, because users may define custom subtypes of AbstractIrrational, and thus calls like BigFloat(::AbstractIrrational) or big(::AbstractIrrational) may execute arbitrary code. That said ...
  • It's not valid to apply @assume_effects even just for ::Irrational, because users may define custom subtypes of Irrational! Example:
# in a user package
struct IrrationalSymbol end
function big(::Irrational{IrrationalSymbol})
    execute_arbitrary_code()
end

This seems perfectly legal, or at least it's not type piracy.

The solution seems simple: define a Union of all known irrational constants, something like the following, then dispatch on it for methods that have @assume_effects, instead of on AbstractIrrational or on Irrational:

const _KnownIrrational = (ℯ, π, MathConstants.γ, MathConstants.catalan, MathConstants.φ)

This will ensure calls involving the known constants are foldable, and allow the unsafe @assume_effects annotations to be deleted. Will make a PR later.

Metadata

Assignees

Labels

bugIndicates an unexpected problem or unintended behavior

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions