Skip to content

deprecate using _ as an rvalue #20328

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

Merged
merged 1 commit into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
26 changes: 16 additions & 10 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,8 @@
(if (any (lambda (v) (contains (lambda (e) (eq? e v)) field-types))
field-names)
(map (lambda (x) (gensy)) field-names)
field-names))
;; use a different name for a field called `_`
(map (lambda (x) (if (eq? x '_) (gensy) x)) field-names)))

(define (with-wheres call wheres)
(if (pair? wheres)
Expand Down Expand Up @@ -3314,15 +3315,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
4 changes: 2 additions & 2 deletions 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 Expand Up @@ -4121,7 +4121,7 @@ end

# issue #12096
let a = Val{Val{TypeVar(:_, Int)}},
b = Val{Val{_} where _<:Int}
b = Val{Val{x} where x<:Int}

@test !isdefined(a, :instance)
@test isdefined(b, :instance)
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