Skip to content

Commit

Permalink
Merge branch 'master' into jb/fix29781
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson authored Nov 29, 2018
2 parents abf1b08 + 15f649c commit f61d56a
Show file tree
Hide file tree
Showing 19 changed files with 182 additions and 72 deletions.
26 changes: 18 additions & 8 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@ New language features

* An *exception stack* is maintained on each task to make exception handling more robust and enable root cause analysis using `catch_stack` ([#28878]).


Language changes
----------------

* the constructor `BigFloat(::BigFloat)` now respects the global precision setting and always
returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127]). The optional
`precision` argument to override the global setting is now a keyword instead of positional
argument ([#29157]).
* Parser inputs ending with a comma are now consistently treated as incomplete.
Previously they were sometimes parsed as tuples, depending on whitespace ([#28506]).
* `Regex` and `TimeZone` now behave like scalars when used in broadcasting ([#29913], [#30159]).
* `Char` now behaves like a read-only 0-dimensional array ([#29819]).
* Spaces were accidentally allowed in broadcast call syntax, e.g. `f. (x)`. They are now
disallowed, consistent with normal function call syntax ([#29781]).
* Big integer literals and command syntax (backticks) are now parsed with the name of
the macro (`@int128_str`, `@uint128_str`, `@big_str`, `@cmd`) qualified to refer
to the `Core` module ([#29968]).

New library functions
---------------------
Expand All @@ -28,7 +24,6 @@ New library functions
* `isnothing(::Any)` function, to check whether something is a `Nothing`, returns a `Bool` ([#29679]).
* `getpid(::Process)` method ([#24064]).


Standard library changes
------------------------

Expand All @@ -40,14 +35,29 @@ Standard library changes
* `edit` can now be called on a module to edit the file that defines it ([#29636]).
* `diff` now supports arrays of arbitrary dimensionality and can operate over any dimension ([#29827]).
* `sprandn` now supports result types like `ComplexF64` or `Float32` ([#30083]).
* The constructor `BigFloat(::BigFloat)` now respects the global precision setting and always
returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127]). The optional
`precision` argument to override the global setting is now a keyword instead of positional
argument ([#29157]).
* `Regex` and `TimeZone` now behave like scalars when used in broadcasting ([#29913], [#30159]).
* `Char` now behaves like a read-only 0-dimensional array ([#29819]).
* `parse` now allows strings representing integer 0 and 1 for type `Bool` ([#29980]).
* `Base.tail` now works on named tuples ([#29595]).
* `randperm` and `randcycle` now use the type of their argument to determine the element type of
the returned array ([#29670]).

Compiler/Runtime improvements
-----------------------------


Deprecated or removed
---------------------

* `one(i::CartesianIndex)` should be replaced with `oneunit(i::CartesianIndex)` ([#29442]).
* The internal array `Base.Grisu.DIGITS` is deprecated; new code should use `Base.Grisu.getbuf()`
to get an appropriate task-local buffer and pass it to `grisu()` instead ([#29907]).
* The internal function `Base._default_type(T)` has been removed. Calls to it should be
replaced with just the argument `T` ([#29739]).

<!--- generated by NEWS-update.jl: -->
[#28156]: https://github.com/JuliaLang/julia/issues/28156
Expand Down
8 changes: 8 additions & 0 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,14 @@ end
atdoc = (source, mod, str, expr) -> Expr(:escape, expr)
atdoc!(λ) = global atdoc = λ

# macros for big integer syntax
macro int128_str end
macro uint128_str end
macro big_str end

# macro for command syntax
macro cmd end


# simple stand-alone print definitions for debugging
abstract type IO end
Expand Down
27 changes: 20 additions & 7 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,22 @@ end

# This is only for use with `Conditional`.
# In general, usage of this is wrong.
function ssa_def_expr(@nospecialize(arg), sv::InferenceState)
function ssa_def_slot(@nospecialize(arg), sv::InferenceState)
init = sv.currpc
while isa(arg, SSAValue)
arg = sv.src.code[arg.id]
init = arg.id
arg = sv.src.code[init]
end
arg isa SlotNumber || return nothing
for i = init:(sv.currpc - 1)
# conservatively make sure there isn't potentially another conflicting assignment to
# the same slot between the def and usage
# we can assume the IR is sorted, since the front-end only creates SSA values in order
e = sv.src.code[i]
e isa Expr || continue
if e.head === :(=) && e.args[1] === arg
return nothing
end
end
return arg
end
Expand Down Expand Up @@ -552,8 +565,8 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
cnd = argtypes[2]::Conditional
tx = argtypes[3]
ty = argtypes[4]
a = ssa_def_expr(fargs[3], sv)
b = ssa_def_expr(fargs[4], sv)
a = ssa_def_slot(fargs[3], sv)
b = ssa_def_slot(fargs[4], sv)
if isa(a, Slot) && slot_id(cnd.var) == slot_id(a)
tx = typeintersect(tx, cnd.vtype)
end
Expand All @@ -572,7 +585,7 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
elseif (rt === Bool || (isa(rt, Const) && isa(rt.val, Bool))) && isa(fargs, Vector{Any})
# perform very limited back-propagation of type information for `is` and `isa`
if f === isa
a = ssa_def_expr(fargs[2], sv)
a = ssa_def_slot(fargs[2], sv)
if isa(a, Slot)
aty = widenconst(argtypes[2])
if rt === Const(false)
Expand All @@ -591,8 +604,8 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
end
end
elseif f === (===)
a = ssa_def_expr(fargs[2], sv)
b = ssa_def_expr(fargs[3], sv)
a = ssa_def_slot(fargs[2], sv)
b = ssa_def_slot(fargs[3], sv)
aty = argtypes[2]
bty = argtypes[3]
# if doing a comparison to a singleton, consider returning a `Conditional` instead
Expand Down
4 changes: 3 additions & 1 deletion base/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ function showerror(io::IO, ex::TypeError)
if ex.expected === Bool
print(io, "non-boolean (", typeof(ex.got), ") used in boolean context")
else
if isa(ex.got, Type)
if isvarargtype(ex.got)
targs = (ex.got,)
elseif isa(ex.got, Type)
targs = ("Type{", ex.got, "}")
else
targs = (typeof(ex.got),)
Expand Down
23 changes: 17 additions & 6 deletions base/grisu/grisu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,26 @@ include("grisu/bignum.jl")
const DIGITS = Vector{UInt8}(undef, 309+17)
const BIGNUMS = [Bignums.Bignum(),Bignums.Bignum(),Bignums.Bignum(),Bignums.Bignum()]

# thread-safe code should use a per-thread DIGITS buffer DIGITSs[Threads.threadid()]
# NOTE: DIGITS[s] is deprecated; you should use getbuf() instead.
const DIGITSs = [DIGITS]
const BIGNUMSs = [BIGNUMS]
function __init__()
Threads.resize_nthreads!(DIGITSs)
Threads.resize_nthreads!(BIGNUMSs)
end

function getbuf()
tls = task_local_storage()
d = get(tls, :DIGITS, nothing)
if d === nothing
d = Vector{UInt8}(undef, 309+17)
tls[:DIGITS] = d
end
return d::Vector{UInt8}
end

"""
(len, point, neg) = Grisu.grisu(v::AbstractFloat, mode, requested_digits,
buffer=DIGITSs[Threads.threadid()], bignums=BIGNUMSs[Threads.threadid()])
(len, point, neg) = Grisu.grisu(v::AbstractFloat, mode, requested_digits, [buffer], [bignums])
Convert the number `v` to decimal using the Grisu algorithm.
Expand All @@ -38,7 +47,7 @@ Convert the number `v` to decimal using the Grisu algorithm.
- `Grisu.FIXED`: round to `requested_digits` digits.
- `Grisu.PRECISION`: round to `requested_digits` significant digits.
The characters are written as bytes to `buffer`, with a terminating NUL byte, and `bignums` are used internally as part of the correction step.
The characters are written as bytes to `buffer`, with a terminating NUL byte, and `bignums` are used internally as part of the correction step. You can call `Grisu.getbuf()` to obtain a suitable task-local buffer.
The returned tuple contains:
Expand Down Expand Up @@ -94,7 +103,8 @@ function _show(io::IO, x::AbstractFloat, mode, n::Int, typed, compact)
return
end
typed && isa(x,Float16) && print(io, "Float16(")
(len,pt,neg),buffer = grisu(x,mode,n),DIGITSs[Threads.threadid()]
buffer = getbuf()
len, pt, neg = grisu(x,mode,n,buffer)
pdigits = pointer(buffer)
if mode == PRECISION
while len > 1 && buffer[len] == 0x30
Expand Down Expand Up @@ -182,7 +192,8 @@ function _print_shortest(io::IO, x::AbstractFloat, dot::Bool, mode, n::Int)
isnan(x) && return print(io, "NaN")
x < 0 && print(io,'-')
isinf(x) && return print(io, "Inf")
(len,pt,neg),buffer = grisu(x,mode,n),DIGITSs[Threads.threadid()]
buffer = getbuf()
len, pt, neg = grisu(x,mode,n,buffer)
pdigits = pointer(buffer)
e = pt-len
k = -9<=e<=9 ? 1 : 2
Expand Down
11 changes: 8 additions & 3 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ rounding_raw(::Type{BigFloat}) = ROUNDING_MODE[]
setrounding_raw(::Type{BigFloat}, r::MPFRRoundingMode) = ROUNDING_MODE[]=r

rounding(::Type{BigFloat}) = convert(RoundingMode, rounding_raw(BigFloat))
setrounding(::Type{BigFloat},r::RoundingMode) = setrounding_raw(BigFloat, convert(MPFRRoundingMode, r))
setrounding(::Type{BigFloat}, r::RoundingMode) = setrounding_raw(BigFloat, convert(MPFRRoundingMode, r))


# overload the definition of unsafe_convert to ensure that `x.d` is assigned
Expand Down Expand Up @@ -224,8 +224,13 @@ BigFloat(x::Union{UInt8,UInt16,UInt32}, r::MPFRRoundingMode=ROUNDING_MODE[]; pre
BigFloat(x::Union{Float16,Float32}, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) =
BigFloat(Float64(x), r; precision=precision)

BigFloat(x::Rational, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) =
BigFloat(numerator(x), r; precision=precision) / BigFloat(denominator(x), r ;precision=precision)
function BigFloat(x::Rational, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[])
setprecision(BigFloat, precision) do
setrounding_raw(BigFloat, r) do
BigFloat(numerator(x)) / BigFloat(denominator(x))
end
end
end

function tryparse(::Type{BigFloat}, s::AbstractString; base::Integer=0, precision::Integer=DEFAULT_PRECISION[], rounding::MPFRRoundingMode=ROUNDING_MODE[])
!isempty(s) && isspace(s[end]) && return tryparse(BigFloat, rstrip(s), base = base)
Expand Down
7 changes: 7 additions & 0 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ function tryparse_internal(::Type{Bool}, sbuff::Union{String,SubString{String}},
return nothing
end

if isnumeric(sbuff[1])
intres = tryparse_internal(UInt8, sbuff, startpos, endpos, base, false)
(intres == 1) && return true
(intres == 0) && return false
raise && throw(ArgumentError("invalid Bool representation: $(repr(sbuff))"))
end

orig_start = startpos
orig_end = endpos

Expand Down
Loading

0 comments on commit f61d56a

Please sign in to comment.