@@ -42,30 +42,50 @@ function JacFunctionWrapper(f::F, fu_, u, p, t) where {F}
4242 # The warning instead of error ensures a non-breaking change for users relying on an
4343 # undefined / undocumented feature
4444 fu = fu_ === nothing ? copy (u) : copy (fu_)
45+
46+ # Check this first else we were breaking things
47+ # In the next breaking release, we will fix the ordering of the checks
48+ iip = static_hasmethod (f, typeof ((fu, u)))
49+ oop = static_hasmethod (f, typeof ((u,)))
50+ if iip || oop
51+ if p != = nothing || t != = nothing
52+ Base. depwarn (""" `p` and/or `t` provided and are not `nothing`. But we
53+ potentially detected `f(du, u)` or `f(u)`. This can be caused by:
54+
55+ 1. `f(du, u)` or `f(u)` is defined, in-which case `p` and/or `t` should not be
56+ supplied.
57+ 2. `f(args...)` is defined, in which case `hasmethod` can be spurious.
58+
59+ Currently, we perform the check for `f(du, u)` and `f(u)` first, but in future
60+ breaking releases, this check will be performed last, which means that if `t`
61+ is provided `f(du, u, p, t)`/`f(u, p, t)` will be given precedence, similarly
62+ if `p` is provided `f(du, u, p)`/`f(u, p)` will be given precedence.""" ,
63+ :JacFunctionWrapper )
64+ end
65+ return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
66+ fu, p, t)
67+ end
68+
4569 if t != = nothing
4670 iip = static_hasmethod (f, typeof ((fu, u, p, t)))
4771 oop = static_hasmethod (f, typeof ((u, p, t)))
4872 if ! iip && ! oop
49- @warn """ `p` and `t` provided but `f(u, p, t)` or `f(fu, u, p, t)` not defined
50- for `f`! Will fallback to `f(u)` or `f(fu, u)`.""" maxlog= 1
51- else
52- return JacFunctionWrapper {iip, oop, 1, F, typeof(fu), typeof(p), typeof(t)} (f,
53- fu, p, t)
73+ throw (ArgumentError (""" `p` and `t` provided but `f(u, p, t)` or `f(fu, u, p, t)`
74+ not defined for `f`!""" ))
5475 end
55- elseif p != = nothing && ! (p isa SciMLBase. NullParameters)
76+ return JacFunctionWrapper {iip, oop, 1, F, typeof(fu), typeof(p), typeof(t)} (f,
77+ fu, p, t)
78+ elseif p != = nothing
5679 iip = static_hasmethod (f, typeof ((fu, u, p)))
5780 oop = static_hasmethod (f, typeof ((u, p)))
5881 if ! iip && ! oop
59- @warn """ `p` provided but `f(u, p)` or `f(fu, u, p)` not defined for `f`! Will
60- fallback to `f(u)` or `f(fu, u)`.""" maxlog= 1
61- else
62- return JacFunctionWrapper {iip, oop, 2, F, typeof(fu), typeof(p), typeof(t)} (f,
63- fu, p, t)
82+ throw (ArgumentError (""" `p` is provided but `f(u, p)` or `f(fu, u, p)`
83+ not defined for `f`!""" ))
6484 end
85+ return JacFunctionWrapper {iip, oop, 2, F, typeof(fu), typeof(p), typeof(t)} (f,
86+ fu, p, t)
6587 end
66- iip = static_hasmethod (f, typeof ((fu, u)))
67- oop = static_hasmethod (f, typeof ((u,)))
68- ! iip && ! oop && throw (ArgumentError (" `f(u)` or `f(fu, u)` not defined for `f`" ))
69- return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
70- fu, p, t)
88+
89+ throw (ArgumentError (""" Couldn't determine the function signature of `f` to construct a
90+ JacobianWrapper!""" ))
7191end
0 commit comments