Skip to content

Commit

Permalink
deprecate using _ as an rvalue
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Feb 3, 2017
1 parent c47412b commit 418631a
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 16 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ Language changes
* `@.` is now parsed as `@__dot__`, and can be used to add dots to
every function call, operator, and assignment in an expression ([#20321]).

* The identifier `_` can be assigned, but accessing its value is deprecated,
allowing this syntax to be used in the future for discarding values ([#9343], [#18251]).

Breaking changes
----------------

Expand Down
10 changes: 5 additions & 5 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ function typeof_tfunc(t::ANY)
elseif t === Any
return DataType
else
return Type{_} where _<:t
return Type{_T} where _T<:t
end
elseif isa(t, Union)
a = widenconst(typeof_tfunc(t.a))
Expand Down Expand Up @@ -891,7 +891,7 @@ function fieldtype_tfunc(s0::ANY, name::ANY)
if exact
return Const(ft)
end
return Type{_} where _<:ft
return Type{_T} where _T<:ft
end
add_tfunc(fieldtype, 2, 2, fieldtype_tfunc)

Expand Down Expand Up @@ -1002,17 +1002,17 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...)
catch ex
# type instantiation might fail if one of the type parameters
# doesn't match, which could happen if a type estimate is too coarse
return Type{_} where _<:headtype
return Type{_T} where _T<:headtype
end
!uncertain && canconst && return Const(appl)
if isvarargtype(headtype)
return Type
end
if uncertain && type_too_complex(appl,0)
return Type{_} where _<:headtype
return Type{_T} where _T<:headtype
end
if istuple
return Type{_} where _<:appl
return Type{_T} where _T<:appl
end
ans = Type{appl}
for i = length(outervars):-1:1
Expand Down
2 changes: 2 additions & 0 deletions src/jlfrontend.scm
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@
(or (memq (car e) '(toplevel line module import importall using export
error incomplete))
(and (eq? (car e) 'global) (every symbol? (cdr e))))))
(if (eq? e '_)
(syntax-deprecation #f "_ as an rvalue" ""))
e)
(else
(let ((last *in-expand*))
Expand Down
23 changes: 14 additions & 9 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -3314,15 +3314,20 @@ f(x) = yt(x)
(define (compile e break-labels value tail)
(if (or (not (pair? e)) (memq (car e) '(null ssavalue quote inert top core copyast the_exception $
globalref outerref cdecl stdcall fastcall thiscall llvmcall)))
(let ((e (if (and arg-map (symbol? e))
(get arg-map e e)
e)))
(cond (tail (emit-return e))
(value e)
((or (eq? e 'true) (eq? e 'false)) #f)
((symbol? e) (emit e) #f) ;; keep symbols for undefined-var checking
((and (pair? e) (eq? (car e) 'outerref)) (emit e) #f) ;; keep globals for undefined-var checking
((and (pair? e) (eq? (car e) 'globalref)) (emit e) #f) ;; keep globals for undefined-var checking
(let ((e1 (if (and arg-map (symbol? e))
(get arg-map e e)
e)))
(if (and value (or (eq? e '_)
(and (pair? e) (or (eq? (car e) 'outerref)
(eq? (car e) 'globalref))
(eq? (cadr e) '_))))
(syntax-deprecation #f "_ as an rvalue" ""))
(cond (tail (emit-return e1))
(value e1)
((or (eq? e1 'true) (eq? e1 'false)) #f)
((symbol? e1) (emit e1) #f) ;; keep symbols for undefined-var checking
((and (pair? e1) (eq? (car e1) 'outerref)) (emit e1) #f) ;; keep globals for undefined-var checking
((and (pair? e1) (eq? (car e1) 'globalref)) (emit e1) #f) ;; keep globals for undefined-var checking
(else #f)))
(case (car e)
((call new foreigncall)
Expand Down
2 changes: 1 addition & 1 deletion test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3115,7 +3115,7 @@ typealias PossiblyInvalidUnion{T} Union{T,Int}
# issue #13007
call13007{T,N}(::Type{Array{T,N}}) = 0
call13007(::Type{Array}) = 1
@test length(Base._methods(call13007, Tuple{Type{_} where _<:Array}, 4, typemax(UInt))) == 2
@test length(Base._methods(call13007, Tuple{Type{x} where x<:Array}, 4, typemax(UInt))) == 2

# detecting cycles during type intersection, e.g. #1631
cycle_in_solve_tvar_constraints{S}(::Type{Nullable{S}}, x::S) = 0
Expand Down
2 changes: 1 addition & 1 deletion test/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ code_llvm(DevNull, f14009, (Int,))
arithtype9232{T<:Real}(::Type{T},::Type{T}) = arithtype9232(T)
result_type9232{T1<:Number,T2<:Number}(::Type{T1}, ::Type{T2}) = arithtype9232(T1, T2)
# this gave a "type too large", but not reliably
@test length(code_typed(result_type9232, Tuple{(Type{_} where _<:Union{Float32,Float64}), Type{T2} where T2<:Number})) == 1
@test length(code_typed(result_type9232, Tuple{(Type{x} where x<:Union{Float32,Float64}), Type{T2} where T2<:Number})) == 1


# issue #10878
Expand Down

0 comments on commit 418631a

Please sign in to comment.