Skip to content

Commit

Permalink
squash! remove tuple Type manipulations from convert
Browse files Browse the repository at this point in the history
We use an inference barrier here where we know type-intersection will
give an incorrect result to avoid the problem case of #32392.
  • Loading branch information
vtjnash committed Jul 14, 2020
1 parent 53ec8c8 commit f3b5e56
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 26 deletions.
35 changes: 34 additions & 1 deletion base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,31 @@ macro specialize(vars...)
return Expr(:meta, :specialize, vars...)
end

"""
@isdefined s -> Bool
Tests whether variable `s` is defined in the current scope.
See also [`isdefined`](@ref).
# Examples
```jldoctest
julia> function f()
println(@isdefined x)
x = 3
println(@isdefined x)
end
f (generic function with 1 method)
julia> f()
false
true
```
"""
macro isdefined(s::Symbol)
return Expr(:escape, Expr(:isdefined, s))
end

macro _pure_meta()
return Expr(:meta, :pure)
end
Expand Down Expand Up @@ -280,7 +305,15 @@ _tuple_error(T::Type, x) = (@_noinline_meta; throw(MethodError(convert, (T, x)))

convert(::Type{T}, x::T) where {T<:Tuple} = x
function convert(::Type{T}, x::NTuple{N,Any}) where {N, T<:Tuple}
NTuple{N,Union{}} <: T || _tuple_error(T, x)
# First see if there could be any conversion of the input type that'd be a subtype of the output.
# If not, we'll throw an explicit MethodError (otherwise, it might throw a typeassert).
S = NTuple{N,Union{}}
# this test is a work-around for #32392: inference doesn't currently
# realize this can't be true, so it successfully prevents it from dropping
# the subtyping test on the next line (assuming it's definitely false)
# whenever `N` wasn't known at compile time
@isdefined(N) || (S = inferencebarrier(:unreachable))
S <: T || _tuple_error(T, x)
cvt1(n) = (@_inline_meta; convert(fieldtype(T, n), getfield(x, n, #=boundscheck=#false)))
return ntuple(cvt1, Val(N))::NTuple{N,Any}
end
Expand Down
25 changes: 0 additions & 25 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -240,31 +240,6 @@ Determine whether a global is declared `const` in a given `Module`.
isconst(m::Module, s::Symbol) =
ccall(:jl_is_const, Cint, (Any, Any), m, s) != 0

"""
@isdefined s -> Bool
Tests whether variable `s` is defined in the current scope.
See also [`isdefined`](@ref).
# Examples
```jldoctest
julia> function f()
println(@isdefined x)
x = 3
println(@isdefined x)
end
f (generic function with 1 method)
julia> f()
false
true
```
"""
macro isdefined(s::Symbol)
return Expr(:isdefined, esc(s))
end

"""
@locals()
Expand Down

0 comments on commit f3b5e56

Please sign in to comment.