-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add promote_rule
methods instead of promote_type
#56779
base: master
Are you sure you want to change the base?
Conversation
promote_rule
methods instead of promote_type
promote_rule
methods instead of promote_type
That sounds like a bad idea. Why would one want to do that? And shouldn't |
In most cases, this specific example is probably a bad idea, but in certain specific cases this might be practical. The point about Notwithstanding the less-than-convincing example, the idea here is that packages should add methods to |
# avoid recursion if the types don't change under promote_rule, and throw an informative error instead | ||
function _throw_promote_type_fail(A::Type, B::Type) | ||
throw(ArgumentError(LazyString("`promote_type(", A, ", ", B, ")` failed as conflicting `promote_rule`s were ", | ||
"detected with either argument being a possible result."))) | ||
end | ||
promote_result(::Type{T},::Type{S},::Type{T},::Type{S}) where {T,S} = _throw_promote_type_fail(T, S) | ||
promote_result(::Type{T},::Type{S},::Type{S},::Type{T}) where {T,S} = _throw_promote_type_fail(T, S) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, this these lines are unrelated to the rest of the change, and improve the error message for promote_rule mistakes (explicit error instead of a stack overflow crash), so these can be merged separately from the other controversial changes?
That is a mistake to add those rules, as |
In this PR, we move some
promote_type
methods topromote_rule
, so that packages that wish to override this behavior only need to define the appropriatepromote_rule
method. E.g., currently, if one wishes to definepromote_type(T, T)
to return something other thanT
, they would need to specializepromote_type
. With this PR, they may specializepromote_rule
instead, which seems to be what the promotion documentation asks for.This is inspired by the specific example in #54138.
cc @nsajko
Note that this PR changes
to
Previously, this was being handled directly by
promote_type
.Some of the methods added to
promote_result
also lead to an informative error in conflicting cases:Currently, this leads to a stack-overflow, as
promote_result
callspromote_type
internally, creating a cycle.