@@ -38,34 +38,70 @@ __internal_oop(::JacFunctionWrapper{iip, oop}) where {iip, oop} = oop
3838(f:: JacFunctionWrapper{false, true, 2} )(u) = f. f (u, f. p)
3939(f:: JacFunctionWrapper{false, true, 3} )(u) = f. f (u)
4040
41- function JacFunctionWrapper (f:: F , fu_, u, p, t) where {F}
41+ # NOTE: `use_deprecated_ordering` is a way for external libraries to update to the correct
42+ # style. In the next release, we will drop the first check
43+ function JacFunctionWrapper (f:: F , fu_, u, p, t;
44+ use_deprecated_ordering:: Val{deporder} = Val (true )) where {F, deporder}
4245 # The warning instead of error ensures a non-breaking change for users relying on an
4346 # undefined / undocumented feature
4447 fu = fu_ === nothing ? copy (u) : copy (fu_)
48+
49+ if deporder
50+ # Check this first else we were breaking things
51+ # In the next breaking release, we will fix the ordering of the checks
52+ iip = static_hasmethod (f, typeof ((fu, u)))
53+ oop = static_hasmethod (f, typeof ((u,)))
54+ if iip || oop
55+ if p != = nothing || t != = nothing
56+ Base. depwarn (""" `p` and/or `t` provided and are not `nothing`. But we
57+ potentially detected `f(du, u)` or `f(u)`. This can be caused by:
58+
59+ 1. `f(du, u)` or `f(u)` is defined, in-which case `p` and/or `t` should not
60+ be supplied.
61+ 2. `f(args...)` is defined, in which case `hasmethod` can be spurious.
62+
63+ Currently, we perform the check for `f(du, u)` and `f(u)` first, but in
64+ future breaking releases, this check will be performed last, which means
65+ that if `t` is provided `f(du, u, p, t)`/`f(u, p, t)` will be given
66+ precedence, similarly if `p` is provided `f(du, u, p)`/`f(u, p)` will be
67+ given precedence.""" , :JacFunctionWrapper )
68+ end
69+ return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
70+ fu, p, t)
71+ end
72+ end
73+
4574 if t != = nothing
4675 iip = static_hasmethod (f, typeof ((fu, u, p, t)))
4776 oop = static_hasmethod (f, typeof ((u, p, t)))
4877 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)
78+ throw (ArgumentError (""" `p` and `t` provided but `f(u, p, t)` or `f(fu, u, p, t)`
79+ not defined for `f`!""" ))
5480 end
81+ return JacFunctionWrapper {iip, oop, 1, F, typeof(fu), typeof(p), typeof(t)} (f,
82+ fu, p, t)
5583 elseif p != = nothing
5684 iip = static_hasmethod (f, typeof ((fu, u, p)))
5785 oop = static_hasmethod (f, typeof ((u, p)))
5886 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)
87+ throw (ArgumentError (""" `p` is provided but `f(u, p)` or `f(fu, u, p)`
88+ not defined for `f`!""" ))
89+ end
90+ return JacFunctionWrapper {iip, oop, 2, F, typeof(fu), typeof(p), typeof(t)} (f,
91+ fu, p, t)
92+ end
93+
94+ if ! deporder
95+ iip = static_hasmethod (f, typeof ((fu, u)))
96+ oop = static_hasmethod (f, typeof ((u,)))
97+ if ! iip && ! oop
98+ throw (ArgumentError (""" `p` is provided but `f(u)` or `f(fu, u)` not defined for
99+ `f`!""" ))
64100 end
101+ return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
102+ fu, p, t)
103+ else
104+ throw (ArgumentError (""" Couldn't determine the function signature of `f` to
105+ construct a JacobianWrapper!""" ))
65106 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)
71107end
0 commit comments