@@ -54,19 +54,33 @@ of the expression.
5454"""
5555declare_operator_alias (op:: F , _) where {F<: Function } = op
5656
57+ allow_chaining (@nospecialize (op)) = false
58+ allow_chaining (:: typeof (+ )) = true
59+ allow_chaining (:: typeof (* )) = true
60+
5761function apply_operator (op:: F , args:: Vararg{Any,D} ) where {F<: Function ,D}
5862 idx = findfirst (e -> e isa AbstractExpression, args):: Int
5963 example_expr = args[idx]
6064 E = typeof (example_expr)
6165 @assert all (e -> ! (e isa AbstractExpression) || typeof (e) === E, args)
6266 operators = get_operators (example_expr, nothing )
6367
64- op_idx = findfirst (== (op), map (Base. Fix2 (declare_operator_alias, Val (D)), operators[D]))
68+ op_idx = if length (operators) >= D
69+ findfirst (== (op), map (Base. Fix2 (declare_operator_alias, Val (D)), operators[D]))
70+ else
71+ nothing
72+ end
6573 if isnothing (op_idx)
74+ if allow_chaining (op) && D > 2
75+ # These operators might get chained by Julia, so we check
76+ # downward for any matching arity.
77+ inner = apply_operator (op, args[1 : (end - 1 )]. .. )
78+ return apply_operator (op, inner, args[end ])
79+ end
6680 throw (
6781 MissingOperatorError (
6882 " Operator $op not found in operators for expression type " *
69- " $(typeof (l) ) with $(D) -degree operators $(operators[D]) " ,
83+ " $(E ) with $(D) -degree operators $(operators[D]) " ,
7084 ),
7185 )
7286 end
@@ -116,7 +130,6 @@ macro declare_expression_operator(op, arity)
116130 continue
117131 end
118132
119-
120133 arglist = [Expr (:(:: ), syms[i], types[i]) for i in 1 : arity]
121134 signature = Expr (:call , op, arglist... )
122135 if any (t -> t == :T || (t isa Expr && t. head == :curly && :T in t. args), types)
0 commit comments