diff --git a/base/deprecated.jl b/base/deprecated.jl index 9c96902ba1a55..caf8b4ef953fd 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -506,7 +506,11 @@ export float32_isvalid, float64_isvalid @deprecate utf32(c::Integer...) UTF32String(UInt32[c...,0]) # 12087 -#@deprecate call(P::Base.DFT.Plan, A) P * A +@deprecate call(P::Base.DFT.ScaledPlan, A) P * A +@deprecate call(P::Base.FFTW.DCTPlan, A) P * A +@deprecate call(P::Base.FFTW.cFFTWPlan, A) P * A +@deprecate call(P::Base.FFTW.rFFTWPlan, A) P * A +@deprecate call(P::Base.FFTW.r2rFFTWPlan, A) P * A for f in (:plan_fft, :plan_ifft, :plan_bfft, :plan_fft!, :plan_ifft!, :plan_bfft!, :plan_rfft) @eval @deprecate $f(A, dims, flags) $f(A, dims; flags=flags) @eval @deprecate $f(A, dims, flags, tlim) $f(A, dims; flags=flags, timelimit=tlim) @@ -975,3 +979,11 @@ export fieldoffsets @deprecate write(io::IO, p::Ptr, nb::Integer) unsafe_write(io, p, nb) @deprecate isgeneric(f) true + +# need to do this manually since the front end deprecates method defs of `call` +const call = @eval function(f,args...) + $(Expr(:meta, :noinline)) + depwarn("call(f,args...) is deprecated, use f(args...) instead.", :call) + f(args...) +end +export call diff --git a/base/essentials.jl b/base/essentials.jl index c76080f813e89..79f2a3c81cd1b 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -22,9 +22,6 @@ macro _propagate_inbounds_meta() Expr(:meta, :inline, :propagate_inbounds) end -# TODO jb/functions make this a deprecation -const call = (f,args...)->f(args...) - # The specialization for 1 arg is important when running with --inline=no, see #11158 call{T}(::Type{T}, arg) = convert(T, arg)::T call{T}(::Type{T}, args...) = convert(T, args...)::T diff --git a/base/exports.jl b/base/exports.jl index a72f67f52b769..cb31ce2376357 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -284,7 +284,6 @@ export At_mul_Bt!, At_rdiv_B, At_rdiv_Bt, - call, # scalar math @evalpoly, diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 3b191f93a89bd..2502dc06ac6eb 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -20,13 +20,13 @@ immutable CartesianIndex{N} end CartesianIndex{N}(index::NTuple{N,Integer}) = CartesianIndex{N}(index) -@generated function Base.call{N}(::Type{CartesianIndex{N}},index::Integer...) +@generated function (::Type{CartesianIndex{N}}){N}(index::Integer...) length(index) == N && return :(CartesianIndex(index)) length(index) > N && throw(DimensionMismatch("Cannot create CartesianIndex{$N} from $(length(index)) indexes")) args = [i <= length(index) ? :(index[$i]) : 1 for i = 1:N] :(CartesianIndex(tuple($(args...)))) end -Base.call{M,N}(::Type{CartesianIndex{N}},index::NTuple{M,Integer}) = CartesianIndex{N}(index...) +(::Type{CartesianIndex{N}}){M,N}(index::NTuple{M,Integer}) = CartesianIndex{N}(index...) # length length{N}(::CartesianIndex{N})=N diff --git a/base/operators.jl b/base/operators.jl index d8d982cedf503..da3e70e3e6918 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -533,13 +533,12 @@ export getindex, setindex!, transpose, - ctranspose, - call + ctranspose import ..this_module: !, !=, $, %, .%, ÷, .÷, &, *, +, -, .!=, .+, .-, .*, ./, .<, .<=, .==, .>, .>=, .\, .^, /, //, <, <:, <<, <=, ==, >, >=, >>, .>>, .<<, >>>, <|, |>, \, ^, |, ~, !==, ===, >:, colon, hcat, vcat, hvcat, getindex, setindex!, - transpose, ctranspose, call, + transpose, ctranspose, ≥, ≤, ≠, .≥, .≤, .≠, ⋅, ×, ∈, ∉, ∋, ∌, ⊆, ⊈, ⊊, ∩, ∪, √, ∛ end diff --git a/base/serialize.jl b/base/serialize.jl index dbfda5aa4976d..5364609d2d2e5 100644 --- a/base/serialize.jl +++ b/base/serialize.jl @@ -367,6 +367,8 @@ function should_send_whole_type(s, t::ANY) return t.name.module === Main end +# `type_itself` means we are serializing a type object. when it's false, we are +# sending the type tag part of some other object's representation. function serialize_type_data(s, t::ANY, type_itself::Bool) whole = should_send_whole_type(s, t) form = type_itself ? UInt8(0) : UInt8(1) diff --git a/base/sparse.jl b/base/sparse.jl index ae94d809eedb5..e8ae4bf35b61b 100644 --- a/base/sparse.jl +++ b/base/sparse.jl @@ -17,7 +17,7 @@ import Base: @get!, acos, acosd, acot, acotd, acsch, asech, asin, asind, asinh, log2, lu, maxabs, minabs, next, sec, secd, sech, show, showarray, sin, sinc, sind, sinh, sinpi, squeeze, start, sum, sumabs, sumabs2, summary, tan, tand, tanh, trace, transpose!, tril!, triu!, trunc, vecnorm, writemime, abs, abs2, - broadcast, call, ceil, complex, cond, conj, convert, copy, ctranspose, diagm, + broadcast, ceil, complex, cond, conj, convert, copy, ctranspose, diagm, exp, expm1, factorize, find, findmax, findmin, findnz, float, full, getindex, hcat, hvcat, imag, indmax, ishermitian, kron, length, log, log1p, max, min, maximum, minimum, norm, one, promote_eltype, real, reinterpret, reshape, rot180, diff --git a/doc/devdocs/ast.rst b/doc/devdocs/ast.rst index 8808713c9a8ae..28ba1428434be 100644 --- a/doc/devdocs/ast.rst +++ b/doc/devdocs/ast.rst @@ -88,18 +88,24 @@ These symbols appear in the ``head`` field of ``Expr``\s in lowered form. ``method`` adds a method to a generic function and assigns the result if necessary. - Has a 1-argument form and a 4-argument form. In the 1-argument form, the + Has a 1-argument form and a 4-argument form. The 1-argument form arises + from the syntax ``function foo end``. In the 1-argument form, the argument is a symbol. If this symbol already names a function in the current scope, nothing happens. If the symbol is undefined, a new function is created and assigned to the identifier specified by the symbol. - This form arises from the syntax ``function foo end``. + If the symbol is defined but names a non-function, an error is raised. + The definition of "names a function" is that the binding is constant, and + refers to an object of singleton type. The rationale for this is that an + instance of a singleton type uniquely identifies the type to add the method + to. When the type has fields, it wouldn't be clear whether the method was + being added to the instance or its type. The 4-argument form has the following arguments: - ``args[1]`` - A function name, or ``false`` if unknown. This is purely - informative and sometimes gives the "display name" of the function - (i.e. how it should be printed). The reason this can be ``false`` is that - functions can be added strictly by type, ``(::T)(x) = x``, in which case - there is no "name". + ``args[1]`` - A function name, or ``false`` if unknown. If a symbol, + then the expression first behaves like the 1-argument form above. + This argument is ignored from then on. + When this is ``false``, it means a method is being added strictly by type, + ``(::T)(x) = x``. ``args[2]`` - a ``SimpleVector`` of argument type data. ``args[2][1]`` is a ``Tuple`` type of the argument types, and ``args[2][2]`` is a diff --git a/src/gf.c b/src/gf.c index ab7a233a59dcd..fb023a32585bd 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1049,7 +1049,7 @@ static jl_lambda_info_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_datatype_t * // equal the run time type. in this case ti would be {Type{Type{Int}}, Type{Int}} // but tt would be {Type{Type{Int}}, DataType}. JL_GC_POP(); - return jl_bottom_func; + return NULL; } if (m->isstaged) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 0621d47824fd4..13c5fe4cbd5c4 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -298,6 +298,10 @@ (and (symbol? s) (eqv? (string.char (string s) 0) #\#))) +(define (is-call-name? name) + (or (eq? name 'call) (and (pair? name) (sym-ref? name) + (equal? (caddr name) '(inert call))))) + (define (method-def-expr- name sparams argl body isstaged) (receive (names bounds) (sparam-name-bounds sparams '() '()) @@ -311,15 +315,8 @@ (error "function argument and static parameter names must be distinct"))) (if (and name (not (sym-ref? name))) (error (string "invalid method name \"" (deparse name) "\""))) - (if (and (not (null? argl)) (or (eq? name 'call) (and (pair? name) (sym-ref? name) - (equal? (caddr name) '(inert call))))) - (let* ((n (arg-name (car argl))) - (n (if (hidden-name? n) "" n)) - (t (deparse (arg-type (car argl))))) - (syntax-deprecation #f - (string "call(" n "::" t ", ...)") - (string "(" n "::" t ")(...)")))) - (let* ((name (if (eq? name 'call) #f name)) + (let* ((iscall (is-call-name? name)) + (name (if iscall #f name)) (types (llist-types argl)) (body (method-lambda-expr argl body)) (mdef @@ -336,6 +333,13 @@ types))) (call (top svec) ,@gss))) ,body ,isstaged))))) + (if (and iscall (not (null? argl))) + (let* ((n (arg-name (car argl))) + (n (if (hidden-name? n) "" n)) + (t (deparse (arg-type (car argl))))) + (syntax-deprecation #f + (string "call(" n "::" t ", ...)") + (string "(" n "::" t ")(...)")))) (if (symbol? name) `(block ,mdef ,name) ;; return the function mdef))))) @@ -503,7 +507,8 @@ (list `(... ,(arg-name (car vararg)))))))) #f) ;; return primary function - ,name)))) + ,(if (or (not (symbol? name)) (is-call-name? name)) + '(null) name))))) (define (optional-positional-defs name sparams req opt dfl body isstaged overall-argl . kw) ;; prologue includes line number node and eventual meta nodes