Skip to content

Restrict * methods for SimplePoly to Number's - #539

Merged
devmotion merged 1 commit into
JuliaMath:masterfrom
JamesWrigley:mul
Aug 5, 2026
Merged

Restrict * methods for SimplePoly to Number's#539
devmotion merged 1 commit into
JuliaMath:masterfrom
JamesWrigley:mul

Conversation

@JamesWrigley

Copy link
Copy Markdown
Contributor

I think it should still be ok for differentiating through expint() with ForwardDiff, since Dual <: Real.

Fixes these invalidations seen when loading CurveFit.jl on 1.13:

 inserting *(p::SpecialFunctions.SimplePoly, c) @ SpecialFunctions ~/.julia/packages/SpecialFunctions/pIm7V/src/expint.jl:8 invalidated:                                                                                                       
   mt_backedges:  1: signature Tuple{typeof(*), Any, Nothing} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Nothing, ::Nothing) (0 children)                                                                                 
                  2: signature Tuple{typeof(*), Any, Compiler.ConstResult} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::T, ::T) where T<:Compiler.ConstResult (0 children)                                                  
                  3: signature Tuple{typeof(*), Any, Compiler.CallMeta} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.CallMeta, ::Compiler.CallMeta) (0 children)                                                   
                  4: signature Tuple{typeof(*), Any, Compiler.MethodMatchInfo} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.MethodMatchInfo, ::Compiler.MethodMatchInfo) (0 children)                              
                  5: signature Tuple{typeof(*), Any, Compiler.AbstractIterationInfo} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.AbstractIterationInfo, ::Compiler.AbstractIterationInfo) (0 children)            
                  6: signature Tuple{typeof(*), Any, Compiler.ApplyCallInfo} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.ApplyCallInfo, ::Compiler.ApplyCallInfo) (0 children)                                    
                  7: signature Tuple{typeof(*), Any, Compiler.NewPhiCNode2} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.NewPhiCNode2, ::Compiler.NewPhiCNode2) (0 children)                                       
                  8: signature Tuple{typeof(*), Any, Compiler.ConstResult} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::T, ::T) where T<:Compiler.ConstResult (1 children)                                                  
                  9: signature Tuple{typeof(*), Any, Compiler.AbstractIterationInfo} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.AbstractIterationInfo, ::Compiler.AbstractIterationInfo) (1 children)            
                 10: signature Tuple{typeof(*), Any, Module} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Module, ::Module) (4 children)                                                                                    
                 11: signature Tuple{typeof(*), Any, Compiler.CallMeta} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.CallMeta, ::Compiler.CallMeta) (10 children)                                                  
                 12: signature Tuple{typeof(*), Any, Compiler.MethodMatchInfo} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.MethodMatchInfo, ::Compiler.MethodMatchInfo) (10 children)                             
                 13: signature Tuple{typeof(*), Any, Compiler.ApplyCallInfo} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.ApplyCallInfo, ::Compiler.ApplyCallInfo) (10 children)                                   
                 14: signature Tuple{typeof(*), Any, Compiler.NewPhiCNode2} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Compiler.NewPhiCNode2, ::Compiler.NewPhiCNode2) (10 children)                                      
                 15: signature Tuple{typeof(*), Any, Tuple{LineNumberNode, Expr}} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Tuple{LineNumberNode, Expr}, ::Tuple{LineNumberNode, Expr}) (11 children)                    
                 16: signature Tuple{typeof(*), Any, Nothing} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::Nothing, ::Nothing) (20 children)                                                                                
                 17: signature Tuple{typeof(*), Any, String} triggered MethodInstance for Base.lerpi(::Integer, ::Integer, ::String, ::String) (644 children)                                                                                  

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.49%. Comparing base (42ec04a) to head (4b03347).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #539   +/-   ##
=======================================
  Coverage   94.49%   94.49%           
=======================================
  Files          14       14           
  Lines        3016     3016           
=======================================
  Hits         2850     2850           
  Misses        166      166           
Flag Coverage Δ
unittests 94.49% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JamesWrigley

Copy link
Copy Markdown
Contributor Author

AFAICT the test failures are unrelated.

This avoids invalidating other methods.
Comment thread src/expint.jl
Comment on lines +8 to +9
Base.:*(p::SimplePoly, c::Number) = SimplePoly(p.coeffs * c)
Base.:*(c::Number, p::SimplePoly) = p * c

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we actually need both forms? AFAICT SimplePoly is completely internal, so likely one form should be sufficient?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think that's a question for you and the other maintainers, I'm not at all familiar with the internals 😅 When it comes to invalidations I don't think it would matter.

@devmotion
devmotion merged commit 00feaac into JuliaMath:master Aug 5, 2026
15 checks passed
@JamesWrigley
JamesWrigley deleted the mul branch August 5, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants