From b5f1a1965931cfe92ebd27d3f1f32985a04ab42c Mon Sep 17 00:00:00 2001
From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com>
Date: Tue, 15 Feb 2022 05:43:43 +0900
Subject: [PATCH] add type annotations for non-constant Base globals (#44166)

* add type annotations for non-constant Base globals
* remove no-longer needed callsite annotations
---
 base/Base.jl                                  |  1 +
 base/client.jl                                |  4 +--
 base/compiler/compiler.jl                     |  1 +
 base/coreio.jl                                | 10 +++---
 base/essentials.jl                            |  1 -
 base/initdefs.jl                              |  6 ++--
 base/libuv.jl                                 |  6 ++--
 base/loading.jl                               |  4 +--
 base/methodshow.jl                            | 10 ++++--
 base/reflection.jl                            |  2 +-
 base/show.jl                                  |  4 +--
 base/sysinfo.jl                               | 31 ++++++++++---------
 base/util.jl                                  |  8 ++---
 contrib/generate_precompile.jl                |  4 +--
 stdlib/Distributed/src/cluster.jl             |  2 +-
 .../src/MozillaCACerts_jll.jl                 |  6 ++--
 stdlib/Profile/src/Profile.jl                 |  2 +-
 stdlib/REPL/src/REPLCompletions.jl            | 10 +++---
 test/precompile.jl                            |  2 +-
 19 files changed, 60 insertions(+), 54 deletions(-)

diff --git a/base/Base.jl b/base/Base.jl
index ece7cbe96df53..f39b227d6f663 100644
--- a/base/Base.jl
+++ b/base/Base.jl
@@ -58,6 +58,7 @@ replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:notatom
     (@inline; Core.replacefield!(x, f, expected, convert(fieldtype(typeof(x), f), desired), success_order, fail_order))
 
 convert(::Type{Any}, Core.@nospecialize x) = x
+convert(::Type{T}, x::T) where {T} = x
 include("coreio.jl")
 
 eval(x) = Core.eval(Base, x)
diff --git a/base/client.jl b/base/client.jl
index 3b85ee2b1cb5f..124bfd281c6a1 100644
--- a/base/client.jl
+++ b/base/client.jl
@@ -323,8 +323,8 @@ end
 function _global_julia_startup_file()
     # If the user built us with a specific Base.SYSCONFDIR, check that location first for a startup.jl file
     # If it is not found, then continue on to the relative path based on Sys.BINDIR
-    BINDIR = Sys.BINDIR::String
-    SYSCONFDIR = Base.SYSCONFDIR::String
+    BINDIR = Sys.BINDIR
+    SYSCONFDIR = Base.SYSCONFDIR
     if !isempty(SYSCONFDIR)
         p1 = abspath(BINDIR, SYSCONFDIR, "julia", "startup.jl")
         isfile(p1) && return p1
diff --git a/base/compiler/compiler.jl b/base/compiler/compiler.jl
index 41e045773fb06..9547bae6851e1 100644
--- a/base/compiler/compiler.jl
+++ b/base/compiler/compiler.jl
@@ -29,6 +29,7 @@ macro inline()   Expr(:meta, :inline)   end
 macro noinline() Expr(:meta, :noinline) end
 
 convert(::Type{Any}, Core.@nospecialize x) = x
+convert(::Type{T}, x::T) where {T} = x
 
 # essential files and libraries
 include("essentials.jl")
diff --git a/base/coreio.jl b/base/coreio.jl
index d0f8df290b41b..3e508c64a0a64 100644
--- a/base/coreio.jl
+++ b/base/coreio.jl
@@ -1,7 +1,7 @@
 # This file is a part of Julia. License is MIT: https://julialang.org/license
 
-print(xs...)   = print(stdout::IO, xs...)
-println(xs...) = println(stdout::IO, xs...)
+print(xs...)   = print(stdout, xs...)
+println(xs...) = println(stdout, xs...)
 println(io::IO) = print(io, '\n')
 
 function show end
@@ -29,6 +29,6 @@ let CoreIO = Union{Core.CoreSTDOUT, Core.CoreSTDERR}
     global wait_readnb(::CoreIO, nb::Int) = nothing
 end
 
-stdin = devnull
-stdout = Core.stdout
-stderr = Core.stderr
+stdin::IO = devnull
+stdout::IO = Core.stdout
+stderr::IO = Core.stderr
diff --git a/base/essentials.jl b/base/essentials.jl
index c23294cb2c218..04df906628e36 100644
--- a/base/essentials.jl
+++ b/base/essentials.jl
@@ -211,7 +211,6 @@ See also: [`round`](@ref), [`trunc`](@ref), [`oftype`](@ref), [`reinterpret`](@r
 function convert end
 
 convert(::Type{Union{}}, @nospecialize x) = throw(MethodError(convert, (Union{}, x)))
-convert(::Type{T}, x::T) where {T} = x
 convert(::Type{Type}, x::Type) = x # the ssair optimizer is strongly dependent on this method existing to avoid over-specialization
                                    # in the absence of inlining-enabled
                                    # (due to fields typed as `Type`, which is generally a bad idea)
diff --git a/base/initdefs.jl b/base/initdefs.jl
index 231f57454e3cd..4106ef4eb7777 100644
--- a/base/initdefs.jl
+++ b/base/initdefs.jl
@@ -89,9 +89,9 @@ const DEPOT_PATH = String[]
 function append_default_depot_path!(DEPOT_PATH)
     path = joinpath(homedir(), ".julia")
     path in DEPOT_PATH || push!(DEPOT_PATH, path)
-    path = abspath(Sys.BINDIR::String, "..", "local", "share", "julia")
+    path = abspath(Sys.BINDIR, "..", "local", "share", "julia")
     path in DEPOT_PATH || push!(DEPOT_PATH, path)
-    path = abspath(Sys.BINDIR::String, "..", "share", "julia")
+    path = abspath(Sys.BINDIR, "..", "share", "julia")
     path in DEPOT_PATH || push!(DEPOT_PATH, path)
 end
 
@@ -251,7 +251,7 @@ function load_path_expand(env::AbstractString)::Union{String, Nothing}
         # if you put a `@` in LOAD_PATH manually, it's expanded late
         env == "@" && return active_project(false)
         env == "@." && return current_project()
-        env == "@stdlib" && return Sys.STDLIB::String
+        env == "@stdlib" && return Sys.STDLIB
         env = replace(env, '#' => VERSION.major, count=1)
         env = replace(env, '#' => VERSION.minor, count=1)
         env = replace(env, '#' => VERSION.patch, count=1)
diff --git a/base/libuv.jl b/base/libuv.jl
index c64cbff564b66..53870188e75d9 100644
--- a/base/libuv.jl
+++ b/base/libuv.jl
@@ -130,21 +130,21 @@ function reinit_stdio()
 end
 
 """
-    stdin
+    stdin::IO
 
 Global variable referring to the standard input stream.
 """
 :stdin
 
 """
-    stdout
+    stdout::IO
 
 Global variable referring to the standard out stream.
 """
 :stdout
 
 """
-    stderr
+    stderr::IO
 
 Global variable referring to the standard error stream.
 """
diff --git a/base/loading.jl b/base/loading.jl
index 640e019f3245e..7dce4532c1571 100644
--- a/base/loading.jl
+++ b/base/loading.jl
@@ -352,7 +352,7 @@ function locate_package(pkg::PkgId)::Union{Nothing,String}
         end
         # Allow loading of stdlibs if the name/uuid are given
         # e.g. if they have been explicitly added to the project/manifest
-        path = manifest_uuid_path(Sys.STDLIB::String, pkg)
+        path = manifest_uuid_path(Sys.STDLIB, pkg)
         path === nothing || return entry_path(path, pkg.name)
     end
     return nothing
@@ -748,7 +748,7 @@ end
 
 function find_source_file(path::AbstractString)
     (isabspath(path) || isfile(path)) && return path
-    base_path = joinpath(Sys.BINDIR::String, DATAROOTDIR, "julia", "base", path)
+    base_path = joinpath(Sys.BINDIR, DATAROOTDIR, "julia", "base", path)
     return isfile(base_path) ? normpath(base_path) : nothing
 end
 
diff --git a/base/methodshow.jl b/base/methodshow.jl
index 18bfdaa6164d0..ba9911179fd19 100644
--- a/base/methodshow.jl
+++ b/base/methodshow.jl
@@ -131,9 +131,13 @@ const methodloc_callback = Ref{Union{Function, Nothing}}(nothing)
 function fixup_stdlib_path(path::String)
     # The file defining Base.Sys gets included after this file is included so make sure
     # this function is valid even in this intermediary state
-    if isdefined(@__MODULE__, :Sys) && Sys.BUILD_STDLIB_PATH != Sys.STDLIB::String
-        # BUILD_STDLIB_PATH gets defined in sysinfo.jl
-        path = replace(path, normpath(Sys.BUILD_STDLIB_PATH) => normpath(Sys.STDLIB::String))
+    if isdefined(@__MODULE__, :Sys)
+        BUILD_STDLIB_PATH = Sys.BUILD_STDLIB_PATH::String
+        STDLIB = Sys.STDLIB::String
+        if BUILD_STDLIB_PATH != STDLIB
+            # BUILD_STDLIB_PATH gets defined in sysinfo.jl
+            path = replace(path, normpath(BUILD_STDLIB_PATH) => normpath(STDLIB))
+        end
     end
     return path
 end
diff --git a/base/reflection.jl b/base/reflection.jl
index 50125e8e446c9..bf8ceabe1f39b 100644
--- a/base/reflection.jl
+++ b/base/reflection.jl
@@ -1329,7 +1329,7 @@ function print_statement_costs(io::IO, @nospecialize(tt::Type);
     end
 end
 
-print_statement_costs(args...; kwargs...) = print_statement_costs(stdout::IO, args...; kwargs...)
+print_statement_costs(args...; kwargs...) = print_statement_costs(stdout, args...; kwargs...)
 
 function _which(@nospecialize(tt::Type), world=get_world_counter())
     min_valid = RefValue{UInt}(typemin(UInt))
diff --git a/base/show.jl b/base/show.jl
index f52023912b786..8359690034c23 100644
--- a/base/show.jl
+++ b/base/show.jl
@@ -390,7 +390,7 @@ Hello World!
 """
 show(io::IO, @nospecialize(x)) = show_default(io, x)
 
-show(x) = show(stdout::IO, x)
+show(x) = show(stdout, x)
 
 # avoid inferring show_default on the type of `x`
 show_default(io::IO, @nospecialize(x)) = _show_default(io, inferencebarrier(x))
@@ -2710,7 +2710,7 @@ MyStruct
 function dump(arg; maxdepth=DUMP_DEFAULT_MAXDEPTH)
     # this is typically used interactively, so default to being in Main
     mod = get(stdout, :module, Main)
-    dump(IOContext(stdout::IO, :limit => true, :module => mod), arg; maxdepth=maxdepth)
+    dump(IOContext(stdout, :limit => true, :module => mod), arg; maxdepth=maxdepth)
 end
 
 
diff --git a/base/sysinfo.jl b/base/sysinfo.jl
index 6df8cdc56d20a..f0852f32fc17d 100644
--- a/base/sysinfo.jl
+++ b/base/sysinfo.jl
@@ -35,20 +35,19 @@ export BINDIR,
 
 import ..Base: show
 
-global BINDIR = ccall(:jl_get_julia_bindir, Any, ())::String
 """
-    Sys.BINDIR
+    Sys.BINDIR::String
 
 A string containing the full path to the directory containing the `julia` executable.
 """
-:BINDIR
+global BINDIR::String = ccall(:jl_get_julia_bindir, Any, ())::String
 
 """
-    Sys.STDLIB
+    Sys.STDLIB::String
 
 A string containing the full path to the directory containing the `stdlib` packages.
 """
-STDLIB = "$BINDIR/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)" # for bootstrap
+global STDLIB::String = "$BINDIR/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)" # for bootstrap
 # In case STDLIB change after julia is built, the variable below can be used
 # to update cached method locations to updated ones.
 const BUILD_STDLIB_PATH = STDLIB
@@ -56,7 +55,7 @@ const BUILD_STDLIB_PATH = STDLIB
 # helper to avoid triggering precompile warnings
 
 """
-    Sys.CPU_THREADS
+    Sys.CPU_THREADS::Int
 
 The number of logical CPU cores available in the system, i.e. the number of threads
 that the CPU can run concurrently. Note that this is not necessarily the number of
@@ -65,37 +64,39 @@ CPU cores, for example, in the presence of
 
 See Hwloc.jl or CpuId.jl for extended information, including number of physical cores.
 """
-CPU_THREADS = 1 # for bootstrap, changed on startup
+global CPU_THREADS::Int = 1 # for bootstrap, changed on startup
 
 """
-    Sys.ARCH
+    Sys.ARCH::Symbol
 
 A symbol representing the architecture of the build configuration.
 """
-const ARCH = ccall(:jl_get_ARCH, Any, ())
+const ARCH = ccall(:jl_get_ARCH, Any, ())::Symbol
 
 
 """
-    Sys.KERNEL
+    Sys.KERNEL::Symbol
 
 A symbol representing the name of the operating system, as returned by `uname` of the build configuration.
 """
-const KERNEL = ccall(:jl_get_UNAME, Any, ())
+const KERNEL = ccall(:jl_get_UNAME, Any, ())::Symbol
 
 """
-    Sys.MACHINE
+    Sys.MACHINE::String
 
 A string containing the build triple.
 """
-const MACHINE = Base.MACHINE
+const MACHINE = Base.MACHINE::String
 
 """
-    Sys.WORD_SIZE
+    Sys.WORD_SIZE::Int
 
 Standard word size on the current machine, in bits.
 """
 const WORD_SIZE = Core.sizeof(Int) * 8
 
+global SC_CLK_TCK::Clong, CPU_NAME::String, JIT::String
+
 function __init__()
     env_threads = nothing
     if haskey(ENV, "JULIA_CPU_THREADS")
@@ -122,7 +123,7 @@ end
 function __init_build()
     global BINDIR = ccall(:jl_get_julia_bindir, Any, ())::String
     vers = "v$(VERSION.major).$(VERSION.minor)"
-    global STDLIB = abspath(BINDIR::String, "..", "share", "julia", "stdlib", vers)
+    global STDLIB = abspath(BINDIR, "..", "share", "julia", "stdlib", vers)
     nothing
 end
 
diff --git a/base/util.jl b/base/util.jl
index cab5669282613..935f357367a8e 100644
--- a/base/util.jl
+++ b/base/util.jl
@@ -133,7 +133,7 @@ See also [`print`](@ref), [`println`](@ref), [`show`](@ref).
     printstyled(stdout, msg...; bold=bold, underline=underline, blink=blink, reverse=reverse, hidden=hidden, color=color)
 
 """
-    Base.julia_cmd(juliapath=joinpath(Sys.BINDIR::String, julia_exename()))
+    Base.julia_cmd(juliapath=joinpath(Sys.BINDIR, julia_exename()))
 
 Return a julia command similar to the one of the running process.
 Propagates any of the `--cpu-target`, `--sysimage`, `--compile`, `--sysimage-native-code`,
@@ -149,7 +149,7 @@ Among others, `--math-mode`, `--warn-overwrite`, and `--trace-compile` are notab
 !!! compat "Julia 1.5"
     The flags `--color` and `--startup-file` were added in Julia 1.5.
 """
-function julia_cmd(julia=joinpath(Sys.BINDIR::String, julia_exename()))
+function julia_cmd(julia=joinpath(Sys.BINDIR, julia_exename()))
     opts = JLOptions()
     cpu_target = unsafe_string(opts.cpu_target)
     image_file = unsafe_string(opts.image_file)
@@ -569,7 +569,7 @@ to the standard libraries before running the tests.
 If a seed is provided via the keyword argument, it is used to seed the
 global RNG in the context where the tests are run; otherwise the seed is chosen randomly.
 """
-function runtests(tests = ["all"]; ncores::Int = ceil(Int, Sys.CPU_THREADS::Int / 2),
+function runtests(tests = ["all"]; ncores::Int = ceil(Int, Sys.CPU_THREADS / 2),
                   exit_on_error::Bool=false,
                   revise::Bool=false,
                   seed::Union{BitInteger,Nothing}=nothing)
@@ -585,7 +585,7 @@ function runtests(tests = ["all"]; ncores::Int = ceil(Int, Sys.CPU_THREADS::Int
     delete!(ENV2, "JULIA_LOAD_PATH")
     delete!(ENV2, "JULIA_PROJECT")
     try
-        run(setenv(`$(julia_cmd()) $(joinpath(Sys.BINDIR::String,
+        run(setenv(`$(julia_cmd()) $(joinpath(Sys.BINDIR,
             Base.DATAROOTDIR, "julia", "test", "runtests.jl")) $tests`, ENV2))
         nothing
     catch
diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl
index 1a880ad996bd7..983f5c3c8ef36 100644
--- a/contrib/generate_precompile.jl
+++ b/contrib/generate_precompile.jl
@@ -7,7 +7,7 @@ Sys.__init_build()
 if !isdefined(Base, :uv_eventloop)
     Base.reinit_stdio()
 end
-Base.include(@__MODULE__, joinpath(Sys.BINDIR::String, "..", "share", "julia", "test", "testhelpers", "FakePTYs.jl"))
+Base.include(@__MODULE__, joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testhelpers", "FakePTYs.jl"))
 import .FakePTYs: open_fake_pty
 using Base.Meta
 
@@ -102,7 +102,7 @@ precompile_script = """
 # end
 """
 
-julia_exepath() = joinpath(Sys.BINDIR::String, Base.julia_exename())
+julia_exepath() = joinpath(Sys.BINDIR, Base.julia_exename())
 
 have_repl =  haskey(Base.loaded_modules,
                     Base.PkgId(Base.UUID("3fa0cd96-eef1-5676-8a61-b3b8758bbffb"), "REPL"))
diff --git a/stdlib/Distributed/src/cluster.jl b/stdlib/Distributed/src/cluster.jl
index cea8258f36939..5e90f231f59b1 100644
--- a/stdlib/Distributed/src/cluster.jl
+++ b/stdlib/Distributed/src/cluster.jl
@@ -531,7 +531,7 @@ default_addprocs_params(::ClusterManager) = default_addprocs_params()
 default_addprocs_params() = Dict{Symbol,Any}(
     :topology => :all_to_all,
     :dir      => pwd(),
-    :exename  => joinpath(Sys.BINDIR::String, julia_exename()),
+    :exename  => joinpath(Sys.BINDIR, julia_exename()),
     :exeflags => ``,
     :enable_threaded_blas => false,
     :lazy => true)
diff --git a/stdlib/MozillaCACerts_jll/src/MozillaCACerts_jll.jl b/stdlib/MozillaCACerts_jll/src/MozillaCACerts_jll.jl
index e9ecdf8f85729..244c1204563d5 100644
--- a/stdlib/MozillaCACerts_jll/src/MozillaCACerts_jll.jl
+++ b/stdlib/MozillaCACerts_jll/src/MozillaCACerts_jll.jl
@@ -12,12 +12,12 @@ const LIBPATH_list = String[]
 # These get calculated in __init__()
 const PATH = Ref("")
 const LIBPATH = Ref("")
-artifact_dir = ""
-cacert = ""
+global artifact_dir::String = ""
+global cacert::String = ""
 
 function __init__()
     global artifact_dir = dirname(Sys.BINDIR)
-    global cacert = normpath(Sys.BINDIR::String, Base.DATAROOTDIR, "julia", "cert.pem")
+    global cacert = normpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "cert.pem")
 end
 
 # JLLWrappers API compatibility shims.  Note that not all of these will really make sense.
diff --git a/stdlib/Profile/src/Profile.jl b/stdlib/Profile/src/Profile.jl
index 3d550f85db9d8..6916f400e16da 100644
--- a/stdlib/Profile/src/Profile.jl
+++ b/stdlib/Profile/src/Profile.jl
@@ -448,7 +448,7 @@ function short_path(spath::Symbol, filenamecache::Dict{Symbol, String})
                 end
             end
             return path
-        elseif isfile(joinpath(Sys.BINDIR::String, Base.DATAROOTDIR, "julia", "base", path))
+        elseif isfile(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "base", path))
             # do the same mechanic for Base (or Core/Compiler) files as above,
             # but they start from a relative path
             return joinpath("@Base", normpath(path))
diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl
index 894403910c188..162d1184d18c3 100644
--- a/stdlib/REPL/src/REPLCompletions.jl
+++ b/stdlib/REPL/src/REPLCompletions.jl
@@ -517,7 +517,7 @@ function get_type(T, found::Bool, default_any::Bool)
 end
 
 # Method completion on function call expression that look like :(max(1))
-MAX_METHOD_COMPLETIONS = 40
+MAX_METHOD_COMPLETIONS::Int = 40
 function complete_methods(ex_org::Expr, context_module::Module=Main)
     out = Completion[]
     funct, found = get_type(ex_org.args[1], context_module)::Tuple{Any,Bool}
@@ -525,12 +525,12 @@ function complete_methods(ex_org::Expr, context_module::Module=Main)
 
     args_ex, kwargs_ex = complete_methods_args(ex_org.args[2:end], ex_org, context_module, true, true)
     push!(args_ex, Vararg{Any})
-    complete_methods!(out, funct, args_ex, kwargs_ex, MAX_METHOD_COMPLETIONS::Int)
+    complete_methods!(out, funct, args_ex, kwargs_ex, MAX_METHOD_COMPLETIONS)
 
     return out
 end
 
-MAX_ANY_METHOD_COMPLETIONS = 10
+MAX_ANY_METHOD_COMPLETIONS::Int = 10
 function complete_any_methods(ex_org::Expr, callee_module::Module, context_module::Module, moreargs::Bool, shift::Bool)
     out = Completion[]
     args_ex, kwargs_ex = try
@@ -550,7 +550,7 @@ function complete_any_methods(ex_org::Expr, callee_module::Module, context_modul
                 funct = Core.Typeof(func)
                 if !in(funct, seen)
                     push!(seen, funct)
-                    complete_methods!(out, funct, args_ex, kwargs_ex, MAX_ANY_METHOD_COMPLETIONS::Int)
+                    complete_methods!(out, funct, args_ex, kwargs_ex, MAX_ANY_METHOD_COMPLETIONS)
                 end
             elseif callee_module === Main && isa(func, Module)
                 callee_module2 = func
@@ -561,7 +561,7 @@ function complete_any_methods(ex_org::Expr, callee_module::Module, context_modul
                             funct = Core.Typeof(func)
                             if !in(funct, seen)
                                 push!(seen, funct)
-                                complete_methods!(out, funct, args_ex, kwargs_ex, MAX_ANY_METHOD_COMPLETIONS::Int)
+                                complete_methods!(out, funct, args_ex, kwargs_ex, MAX_ANY_METHOD_COMPLETIONS)
                             end
                         end
                     end
diff --git a/test/precompile.jl b/test/precompile.jl
index 1e731c38890ad..411267705622d 100644
--- a/test/precompile.jl
+++ b/test/precompile.jl
@@ -241,7 +241,7 @@ precompile_test_harness(false) do dir
               const layout3 = collect(x.match for x in eachmatch(r"..", "abcdefghijk"))::Vector{SubString{String}}
 
               # create a backedge that includes Type{Union{}}, to ensure lookup can handle that
-              call_bottom() = show(stdout::IO, Union{})
+              call_bottom() = show(stdout, Union{})
               Core.Compiler.return_type(call_bottom, Tuple{})
 
               # check that @ccallable works from precompiled modules