Skip to content
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

Backports for 1.10.1 #52755

Merged
merged 42 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a2e4054
Don't access parent of triangular matrix in powm (#52583)
jishnub Dec 25, 2023
5de62a4
update --gcthreads section in command line options (#52645)
d-netto Dec 27, 2023
79684ad
update nthreads info in versioninfo (#52423)
IanButterworth Dec 28, 2023
6eb535d
inference: Guard TypeVar special case against vararg (#52721)
Keno Jan 4, 2024
6a107d0
Use `jl_types_egal` in `equiv_field_types` (#52748)
timholy Jan 6, 2024
5c0a2a6
release 1.10: backport the lattice fix for array op type checks (#527…
aviatesk Jan 7, 2024
fd13cf0
effects: fix #52843, account for mutable values directly embedded to IR
aviatesk Jan 11, 2024
0cea48e
change Downloads branch to release-1.10
IanButterworth Jan 13, 2024
df9062b
lowering: remove `QuoteNode` wrapping for captured variables (#52878)
aviatesk Jan 13, 2024
813bfac
Revert inlined method signature stacktrace lookup code (#52754)
BioTurboNick Jan 14, 2024
e5ccc44
inference: always bail out const-prop' with non-const result limited …
aviatesk Jan 16, 2024
aaaf5de
🤖 [backports-release-1.10] Bump the Downloads stdlib from f97c72f to …
DilumAluthgeBot Jan 16, 2024
788eff9
Correctly port realloc from 1.9 to 1.10 (#52929)
gbaraldi Jan 16, 2024
f9c2461
Widen diagonal var during `Type` unwrapping in `instanceof_tfunc` (#5…
N5N3 Nov 18, 2023
47999ab
Fix `widen_diagonal` bug for nested `UnionAll` (#52924)
N5N3 Jan 16, 2024
ddb9d0d
🤖 [backports-release-1.10] Bump the Pkg stdlib from 563a3387a to 11cf…
DilumAluthgeBot Jan 22, 2024
3552d36
🤖 [backports-release-1.10] Bump the Pkg stdlib from 11cf00df7 to 7052…
DilumAluthgeBot Jan 24, 2024
7d3c68e
Fix edge cases where inexact conversions to UInt don't throw (#51095)
LilithHafner Aug 30, 2023
2481fdf
loading: fix finding bundled stdlibs even if they are e.g. devved in …
KristofferC Jan 5, 2024
cc26004
staticdata: handle cycles in datatypes (#52752)
vtjnash Jan 5, 2024
69d58e0
use a Dict instead of an IdDict for caching of the `cwstring` for Win…
KristofferC Jan 8, 2024
d2fd317
Insert hardcoded backlinks to stdlib doc pages (#51375)
LilithHafner Jan 16, 2024
4f3a3ae
place work-stealing queue indices on different cache lines to avoid f…
d-netto Jan 23, 2024
8517eb3
Add type assertion in iterate for logicalindex (#53015)
jishnub Jan 23, 2024
fa85fa7
Fix a list in GC devdocs (#53032)
fingolfin Jan 24, 2024
a4cc920
make "dec" and ryu functions faster and simpler (#51273)
vtjnash Sep 13, 2023
e0e3c63
fix type-stability bugs in Ryu code (#52781)
stevengj Jan 8, 2024
f371de8
Default uplo in symmetric/hermitian (#52605)
jishnub Dec 27, 2023
8a04df0
Fix GC rooting during rehashing of iddict (#52569)
Zentrik Dec 18, 2023
cfbff10
heap snapshot: add gc roots and gc finalist roots to fix unrooted nod…
JianFangAtRai Dec 30, 2023
f06a63d
Apple silicon has 128 byte alignment so fix our defines to match (#52…
gbaraldi Jan 24, 2024
6fdf37e
Replace `⇔` by `↔` in documentation (#52078)
fingolfin Jan 24, 2024
ece8b7b
Profile: use full terminal cols to show function name (#53055)
IanButterworth Jan 25, 2024
2c8ecd3
1.10: REPL: fix intermittent REPL test failure (#53096)
aviatesk Jan 29, 2024
a215b37
1.10: inlining: fix `joint_effects` calculation (#53076)
aviatesk Jan 29, 2024
3c73873
[OpenBLAS] Ugrade to v0.3.23+4
Jan 29, 2024
b0b804e
use proper cache-line size variable in work-stealing queue (#53035)
d-netto Jan 24, 2024
a45cd5f
doc: replace harr HTML entity by unicode (#53066)
fingolfin Jan 29, 2024
c644e89
apply OpenBLAS_jll v0.3.23+4 patch (#53074)
pablosanjose Jan 29, 2024
00aa65e
bump NetworkOptions
KristofferC Jan 30, 2024
6407c33
inference: avoid adding duplicate edges as invoke targets (#53121)
vtjnash Jan 31, 2024
0627076
Put mingw32 `*.a` files in `private_libdir` (#51698)
giordano Oct 19, 2023
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
2 changes: 1 addition & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ LIBGFORTRAN_VERSION := $(subst libgfortran,,$(filter libgfortran%,$(subst -,$(SP
# shipped with CSL. Although we do not depend on any of the symbols, it is entirely
# possible that a user might choose to install a library which depends on symbols provided
# by a newer libstdc++. Without runtime detection, those libraries would break.
CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.31|GLIBCXX_3\.5\.|GLIBCXX_4\.
CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.33|GLIBCXX_3\.5\.|GLIBCXX_4\.


# This is the set of projects that BinaryBuilder dependencies are hooked up for.
Expand Down
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -281,16 +281,13 @@ else ifeq ($(JULIA_BUILD_MODE),debug)
-$(INSTALL_M) $(build_libdir)/libjulia-debug.dll.a $(DESTDIR)$(libdir)/
-$(INSTALL_M) $(build_libdir)/libjulia-internal-debug.dll.a $(DESTDIR)$(libdir)/
endif
-$(INSTALL_M) $(wildcard $(build_private_libdir)/*.a) $(DESTDIR)$(private_libdir)/

# We have a single exception; we want 7z.dll to live in private_libexecdir, not bindir, so that 7z.exe can find it.
# We have a single exception; we want 7z.dll to live in private_libexecdir,
# not bindir, so that 7z.exe can find it.
-mv $(DESTDIR)$(bindir)/7z.dll $(DESTDIR)$(private_libexecdir)/
-$(INSTALL_M) $(build_bindir)/libopenlibm.dll.a $(DESTDIR)$(libdir)/
-$(INSTALL_M) $(build_libdir)/libssp.dll.a $(DESTDIR)$(libdir)/
# The rest are compiler dependencies, as an example memcpy is exported by msvcrt
# These are files from mingw32 and required for creating shared libraries like our caches.
-$(INSTALL_M) $(build_libdir)/libgcc_s.a $(DESTDIR)$(libdir)/
-$(INSTALL_M) $(build_libdir)/libgcc.a $(DESTDIR)$(libdir)/
-$(INSTALL_M) $(build_libdir)/libmsvcrt.a $(DESTDIR)$(libdir)/
else

# Copy over .dSYM directories directly for Darwin
Expand Down
70 changes: 37 additions & 33 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -785,11 +785,7 @@ end
function abstract_call_method_with_const_args(interp::AbstractInterpreter,
result::MethodCallResult, @nospecialize(f), arginfo::ArgInfo, si::StmtInfo,
match::MethodMatch, sv::AbsIntState, invokecall::Union{Nothing,InvokeCall}=nothing)
if !const_prop_enabled(interp, sv, match)
return nothing
end
if bail_out_const_call(interp, result, si)
add_remark!(interp, sv, "[constprop] No more information to be gained")
if !const_prop_enabled(interp, match, sv) || bail_out_const_call(interp, result, si, sv)
return nothing
end
eligibility = concrete_eval_eligible(interp, f, result, arginfo, sv)
Expand Down Expand Up @@ -822,7 +818,7 @@ function abstract_call_method_with_const_args(interp::AbstractInterpreter,
return const_prop_call(interp, mi, result, arginfo, sv, concrete_eval_result)
end

function const_prop_enabled(interp::AbstractInterpreter, sv::AbsIntState, match::MethodMatch)
function const_prop_enabled(interp::AbstractInterpreter, match::MethodMatch, sv::AbsIntState)
if !InferenceParams(interp).ipo_constant_propagation
add_remark!(interp, sv, "[constprop] Disabled by parameter")
return false
Expand All @@ -834,9 +830,11 @@ function const_prop_enabled(interp::AbstractInterpreter, sv::AbsIntState, match:
return true
end

function bail_out_const_call(interp::AbstractInterpreter, result::MethodCallResult, si::StmtInfo)
function bail_out_const_call(interp::AbstractInterpreter, result::MethodCallResult,
si::StmtInfo, sv::AbsIntState)
if is_removable_if_unused(result.effects)
if isa(result.rt, Const) || call_result_unused(si)
add_remark!(interp, sv, "[constprop] No more information to be gained (const)")
return true
end
end
Expand Down Expand Up @@ -937,7 +935,10 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter,
match::MethodMatch, sv::AbsIntState)
method = match.method
force = force_const_prop(interp, f, method)
force || const_prop_entry_heuristic(interp, result, si, sv) || return nothing
if !const_prop_entry_heuristic(interp, result, si, sv, force)
# N.B. remarks are emitted within `const_prop_entry_heuristic`
return nothing
end
nargs::Int = method.nargs
method.isva && (nargs -= 1)
length(arginfo.argtypes) < nargs && return nothing
Expand All @@ -964,8 +965,17 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter,
return mi
end

function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodCallResult, si::StmtInfo, sv::AbsIntState)
if call_result_unused(si) && result.edgecycle
function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodCallResult,
si::StmtInfo, sv::AbsIntState, force::Bool)
if result.rt isa LimitedAccuracy
# optimizations like inlining are disabled for limited frames,
# thus there won't be much benefit in constant-prop' here
# N.B. don't allow forced constprop' for safety (xref #52763)
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (limited accuracy)")
return false
elseif force
return true
elseif call_result_unused(si) && result.edgecycle
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (edgecycle with unused result)")
return false
end
Expand All @@ -978,27 +988,21 @@ function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodC
if rt === Bottom
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (erroneous result)")
return false
else
return true
end
return true
elseif isa(rt, PartialStruct) || isa(rt, InterConditional) || isa(rt, InterMustAlias)
# could be improved to `Const` or a more precise wrapper
return true
elseif isa(rt, LimitedAccuracy)
# optimizations like inlining are disabled for limited frames,
# thus there won't be much benefit in constant-prop' here
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (limited accuracy)")
return false
else
if isa(rt, Const)
if !is_nothrow(result.effects)
# Could still be improved to Bottom (or at least could see the effects improved)
return true
end
elseif isa(rt, Const)
if is_nothrow(result.effects)
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (nothrow const)")
return false
end
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (unimprovable result)")
return false
# Could still be improved to Bottom (or at least could see the effects improved)
return true
end
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (unimprovable result)")
return false
end

# determines heuristically whether if constant propagation can be worthwhile
Expand Down Expand Up @@ -2021,10 +2025,10 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
elseif isa(f, Core.OpaqueClosure)
# calling an OpaqueClosure about which we have no information returns no information
return CallMeta(typeof(f).parameters[2], Effects(), NoCallInfo())
elseif f === TypeVar
elseif f === TypeVar && !isvarargtype(argtypes[end])
# Manually look through the definition of TypeVar to
# make sure to be able to get `PartialTypeVar`s out.
(la < 2 || la > 4) && return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
2 ≤ la ≤ 4 || return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
n = argtypes[2]
ub_var = Const(Any)
lb_var = Const(Union{})
Expand Down Expand Up @@ -2267,11 +2271,7 @@ function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::
end

function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(e), vtypes::Union{VarTable,Nothing}, sv::AbsIntState)
if isa(e, QuoteNode)
merge_effects!(interp, sv, Effects(EFFECTS_TOTAL;
inaccessiblememonly = is_mutation_free_argtype(typeof(e.value)) ? ALWAYS_TRUE : ALWAYS_FALSE))
return Const(e.value)
elseif isa(e, SSAValue)
if isa(e, SSAValue)
return abstract_eval_ssavalue(e, sv)
elseif isa(e, SlotNumber)
if vtypes !== nothing
Expand All @@ -2293,7 +2293,11 @@ function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(
elseif isa(e, GlobalRef)
return abstract_eval_globalref(interp, e, sv)
end

if isa(e, QuoteNode)
e = e.value
end
merge_effects!(interp, sv, Effects(EFFECTS_TOTAL;
inaccessiblememonly = is_mutation_free_argtype(typeof(e)) ? ALWAYS_TRUE : ALWAYS_FALSE))
return Const(e)
end

Expand Down
4 changes: 2 additions & 2 deletions base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1615,7 +1615,7 @@ function escape_builtin!(::typeof(arrayref), astate::AnalysisState, pc::Int, arg
argtypes = Any[argextype(args[i], astate.ir) for i in 2:length(args)]
boundcheckt = argtypes[1]
aryt = argtypes[2]
if !array_builtin_common_typecheck(boundcheckt, aryt, argtypes, 3)
if !array_builtin_common_typecheck(𝕃ₒ, boundcheckt, aryt, argtypes, 3)
add_thrown_escapes!(astate, pc, args, 2)
end
ary = args[3]
Expand Down Expand Up @@ -1679,7 +1679,7 @@ function escape_builtin!(::typeof(arrayset), astate::AnalysisState, pc::Int, arg
boundcheckt = argtypes[1]
aryt = argtypes[2]
valt = argtypes[3]
if !(array_builtin_common_typecheck(boundcheckt, aryt, argtypes, 4) &&
if !(array_builtin_common_typecheck(𝕃ₒ, boundcheckt, aryt, argtypes, 4) &&
arrayset_typecheck(aryt, valt))
add_thrown_escapes!(astate, pc, args, 2)
end
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ function compileable_specialization(mi::MethodInstance, effects::Effects,
end
end
add_inlining_backedge!(et, mi) # to the dispatch lookup
push!(et.edges, method.sig, mi_invoke) # add_inlining_backedge to the invoke call
mi_invoke !== mi && push!(et.edges, method.sig, mi_invoke) # add_inlining_backedge to the invoke call, if that is different
return InvokeCase(mi_invoke, effects, info)
end

Expand Down Expand Up @@ -1408,7 +1408,7 @@ function compute_inlining_cases(@nospecialize(info::CallInfo), flag::UInt8, sig:
fully_covered &= split_fully_covered
end

fully_covered || (joint_effects = Effects(joint_effects; nothrow=false))
(handled_all_cases & fully_covered) || (joint_effects = Effects(joint_effects; nothrow=false))

if handled_all_cases && revisit_idx !== nothing
# we handled everything except one match with unmatched sparams,
Expand Down
27 changes: 17 additions & 10 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,31 @@ add_tfunc(throw, 1, 1, @nospecs((𝕃::AbstractLattice, x)->Bottom), 0)
# if isexact is false, the actual runtime type may (will) be a subtype of t
# if isconcrete is true, the actual runtime type is definitely concrete (unreachable if not valid as a typeof)
# if istype is true, the actual runtime value will definitely be a type (e.g. this is false for Union{Type{Int}, Int})
function instanceof_tfunc(@nospecialize(t))
function instanceof_tfunc(@nospecialize(t), @nospecialize(troot) = t)
if isa(t, Const)
if isa(t.val, Type) && valid_as_lattice(t.val)
return t.val, true, isconcretetype(t.val), true
end
return Bottom, true, false, false # runtime throws on non-Type
end
t = widenconst(t)
troot = widenconst(troot)
if t === Bottom
return Bottom, true, true, false # runtime unreachable
elseif t === typeof(Bottom) || !hasintersect(t, Type)
return Bottom, true, false, false # literal Bottom or non-Type
elseif isType(t)
tp = t.parameters[1]
valid_as_lattice(tp) || return Bottom, true, false, false # runtime unreachable / throws on non-Type
if troot isa UnionAll
# Free `TypeVar`s inside `Type` has violated the "diagonal" rule.
# Widen them before `UnionAll` rewraping to relax concrete constraint.
tp = widen_diagonal(tp, troot)
end
return tp, !has_free_typevars(tp), isconcretetype(tp), true
elseif isa(t, UnionAll)
t′ = unwrap_unionall(t)
t′′, isexact, isconcrete, istype = instanceof_tfunc(t′)
t′′, isexact, isconcrete, istype = instanceof_tfunc(t′, rewrap_unionall(t, troot))
tr = rewrap_unionall(t′′, t)
if t′′ isa DataType && t′′.name !== Tuple.name && !has_free_typevars(tr)
# a real instance must be within the declared bounds of the type,
Expand All @@ -128,8 +134,8 @@ function instanceof_tfunc(@nospecialize(t))
end
return tr, isexact, isconcrete, istype
elseif isa(t, Union)
ta, isexact_a, isconcrete_a, istype_a = instanceof_tfunc(t.a)
tb, isexact_b, isconcrete_b, istype_b = instanceof_tfunc(t.b)
ta, isexact_a, isconcrete_a, istype_a = instanceof_tfunc(t.a, troot)
tb, isexact_b, isconcrete_b, istype_b = instanceof_tfunc(t.b, troot)
isconcrete = isconcrete_a && isconcrete_b
istype = istype_a && istype_b
# most users already handle the Union case, so here we assume that
Expand Down Expand Up @@ -2034,12 +2040,12 @@ function array_type_undefable(@nospecialize(arytype))
end
end

function array_builtin_common_nothrow(argtypes::Vector{Any}, isarrayref::Bool)
function array_builtin_common_nothrow(𝕃::AbstractLattice, argtypes::Vector{Any}, isarrayref::Bool)
first_idx_idx = isarrayref ? 3 : 4
length(argtypes) ≥ first_idx_idx || return false
boundscheck = argtypes[1]
arytype = argtypes[2]
array_builtin_common_typecheck(boundscheck, arytype, argtypes, first_idx_idx) || return false
array_builtin_common_typecheck(𝕃, boundscheck, arytype, argtypes, first_idx_idx) || return false
if isarrayref
# If we could potentially throw undef ref errors, bail out now.
arytype = widenconst(arytype)
Expand All @@ -2056,8 +2062,9 @@ function array_builtin_common_nothrow(argtypes::Vector{Any}, isarrayref::Bool)
return false
end

@nospecs function array_builtin_common_typecheck(boundscheck, arytype,
argtypes::Vector{Any}, first_idx_idx::Int)
@nospecs function array_builtin_common_typecheck(𝕃::AbstractLattice,
boundscheck, arytype, argtypes::Vector{Any}, first_idx_idx::Int)
⊑ = Core.Compiler.:⊑(𝕃)
(boundscheck ⊑ Bool && arytype ⊑ Array) || return false
for i = first_idx_idx:length(argtypes)
argtypes[i] ⊑ Int || return false
Expand All @@ -2080,11 +2087,11 @@ end
@nospecs function _builtin_nothrow(𝕃::AbstractLattice, f, argtypes::Vector{Any}, rt)
⊑ = Core.Compiler.:⊑(𝕃)
if f === arrayset
array_builtin_common_nothrow(argtypes, #=isarrayref=#false) || return false
array_builtin_common_nothrow(𝕃, argtypes, #=isarrayref=#false) || return false
# Additionally check element type compatibility
return arrayset_typecheck(argtypes[2], argtypes[3])
elseif f === arrayref || f === const_arrayref
return array_builtin_common_nothrow(argtypes, #=isarrayref=#true)
return array_builtin_common_nothrow(𝕃, argtypes, #=isarrayref=#true)
elseif f === Core._expr
length(argtypes) >= 1 || return false
return argtypes[1] ⊑ Symbol
Expand Down
13 changes: 7 additions & 6 deletions base/env.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
if Sys.iswindows()
const ERROR_ENVVAR_NOT_FOUND = UInt32(203)

const env_dict = IdDict{String, Vector{Cwchar_t}}()
const env_dict = Dict{String, Vector{Cwchar_t}}()
const env_lock = ReentrantLock()

function memoized_env_lookup(str::AbstractString)
# Windows environment variables have a different format from Linux / MacOS, and previously
# incurred allocations because we had to convert a String to a Vector{Cwchar_t} each time
# an environment variable was looked up. This function memoizes that lookup process, storing
# the String => Vector{Cwchar_t} pairs in env_dict
var = get(env_dict, str, nothing)
if isnothing(var)
var = @lock env_lock begin
env_dict[str] = cwstring(str)
@lock env_lock begin
var = get(env_dict, str, nothing)
if isnothing(var)
var = cwstring(str)
env_dict[str] = var
end
return var
end
var
end

_getenvlen(var::Vector{UInt16}) = ccall(:GetEnvironmentVariableW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32),var,C_NULL,0)
Expand Down
5 changes: 5 additions & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ function rename_unionall(@nospecialize(u))
return UnionAll(nv, body{nv})
end

# remove concrete constraint on diagonal TypeVar if it comes from troot
function widen_diagonal(@nospecialize(t), troot::UnionAll)
body = ccall(:jl_widen_diagonal, Any, (Any, Any), t, troot)
end

function isvarargtype(@nospecialize(t))
return isa(t, Core.TypeofVararg)
end
Expand Down
5 changes: 4 additions & 1 deletion base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,10 @@ for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UIn
end
end
function (::Type{$Ti})(x::$Tf)
if ($(Tf(typemin(Ti))) <= x <= $(Tf(typemax(Ti)))) && isinteger(x)
# When typemax(Ti) is not representable by Tf but typemax(Ti) + 1 is,
# then < Tf(typemax(Ti) + 1) is stricter than <= Tf(typemax(Ti)). Using
# the former causes us to throw on UInt64(Float64(typemax(UInt64))+1)
if ($(Tf(typemin(Ti))) <= x < $(Tf(typemax(Ti))+one(Tf))) && isinteger(x)
return unsafe_trunc($Ti,x)
else
throw(InexactError($(Expr(:quote,Ti.name.name)), $Ti, x))
Expand Down
Loading