If you’ve resolve the name conflict (and thus the warning) you can use the long form including the module in source
using NonlinearSolve: .. what you need but solve!
using VortexStepMethod: .. what you need but solve!
# later in code
NonlinearSolve.solve!(...)
VortexStepMethod.solve!(...)
I do not know about either of the packages. But what is it exactly what you want to achieve?
Do you want to end up with one function solve! and two methods defined for it?
In this case one package should make its function available (export or public) and the other package should import (not using) it or address it with its FQN like OtherPackage.solve! when defining the additional method
Or do you want to end up with two functions solve! with one method defined for each?
Then you should either use the FQNs or rename at least one of both functions when bringing them into the namespace.
I think changing the solve! function in VortexStepMethod to become NonlinearSolve’s, which originates in the lightweight dependency CommonSolve, is a breaking change. Even if those modules would define separate specificity sub-trees of methods by working on distinct types they own, it’s technically possible that someone relied on solve! being (at least) 2 distinct functions with separate method tables. It’s also likely nobody did so you could get away with it.
I’d recommend against import with names or bare using followed by extensions with unqualified method definitions because its presence changes whether the same method code extends another module’s function or tries to create a new one. Opposition to unqualified extension methods is more often mentioned for import with names, but bare using is a bit sneakier because whether the name was referenced beforehand is an additional factor:
julia> module D
export f
function f end
end;
julia> module E # first, no reference or definition
using ..D
end;
julia> D.f === E.f
true
julia> module E # no reference -> new function
using ..D
f() = 0
end;
WARNING: replacing module E.
julia> D.f === E.f
false
julia> module E # prior reference -> attempted extension
using ..D
f
f() = 0
end;
WARNING: replacing module E.
ERROR: invalid method definition in E: function D.f must be explicitly imported to be extended
I’d hazard a guess that you intended VortexStepMethod.solve! === NonlinearSolve.solve! in the first place, but bare using threw you off.
Does your VortexStepMethod.solve! follow the conventions and API of CommonSolve.jl? If so, make VortexStepMethod depend upon CommonSolve, and make your VortexStepMethod solve! definitions explicitly extend CommonSolve’s function (typically by fully-qualifying CommonSolve.solve! in all your method definitions).
Then there’s only one function shared between both libraries and both can export it without trouble.
If you can’t do that, folks can still be using both packages together without this warning or major consternation — they just need to make sure that all usages are fully qualified or explicitly renamed.
Before the currently proposed fixes, you had 2 distinct functions instead, and it is sounding more like it was unintentional. To adapt the D/E example to your case, I guessed that you expected
using NonlinearSolve
...
function solve!(...
to extend NonlinearSolve.solve!, but that instead made a new function with a separate method table in VortexStepMethod. Any of the fixes here would undo that and extend NonlinearSolve.solve! instead, but it seems like a breaking change, which isn’t as smooth for v1+ packages. I don’t expect it to break much; anyone who previously qualified or renamed the 2 distinct functions would still have working calls, just silently changed to the same function. But it’d break unusual reliance on the 2 functions being distinct, like a condition solve_func !== NonlinearSolve.solve! or try-catch-ing MethodErrors for the wrong function, and it’d break anyone’s code that extended the 2 functions separately over their own types.