Skip to content

Commit

Permalink
replace current_module() with @__MODULE__
Browse files Browse the repository at this point in the history
passes macros a __module__ argument, like the __source__ argument,
allowing them to inspect and configure themselves based on their evaluation context

remove current_module dependence from `include`:
instead, we use the same trick as for `eval` (they are basically the same function after all)
to create a module-relative function in each non-bare module

now puts Module in MethodInstance.def for toplevel thunks to make it convenient to pass around this contextual information
  • Loading branch information
vtjnash committed Jun 1, 2017
1 parent ef9ab60 commit d16a141
Show file tree
Hide file tree
Showing 75 changed files with 1,102 additions and 919 deletions.
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ Deprecated or removed

* The method `srand(rng, filename, n=4)` has been deprecated ([#21359]).

* The function `current_module` is deprecated and replaced with `@__MODULE__` ([#22064]).
This caused the deprecation of some reflection methods (such as `macroexpand` and `isconst`),
which now require a module argument.
And it caused the bugfix of other default arguments to use the Main module (including `whos`, `which`).


Julia v0.6.0 Release Notes
==========================
Expand Down
18 changes: 9 additions & 9 deletions base/Enums.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,34 +49,34 @@ julia> f(apple)
Member values can be converted between the enum type and `BaseType`. `read` and `write`
perform these conversions automatically.
"""
macro enum(T,syms...)
macro enum(T, syms...)
if isempty(syms)
throw(ArgumentError("no arguments given for Enum $T"))
end
basetype = Int32
typename = T
if isa(T,Expr) && T.head == :(::) && length(T.args) == 2 && isa(T.args[1], Symbol)
if isa(T, Expr) && T.head == :(::) && length(T.args) == 2 && isa(T.args[1], Symbol)
typename = T.args[1]
basetype = eval(current_module(),T.args[2])
basetype = eval(__module__, T.args[2])
if !isa(basetype, DataType) || !(basetype <: Integer) || !isbits(basetype)
throw(ArgumentError("invalid base type for Enum $typename, $T=::$basetype; base type must be an integer primitive type"))
end
elseif !isa(T,Symbol)
elseif !isa(T, Symbol)
throw(ArgumentError("invalid type expression for enum $T"))
end
vals = Vector{Tuple{Symbol,Integer}}(0)
lo = hi = 0
i = zero(basetype)
hasexpr = false
for s in syms
if isa(s,Symbol)
if isa(s, Symbol)
if i == typemin(basetype) && !isempty(vals)
throw(ArgumentError("overflow in value \"$s\" of Enum $typename"))
end
elseif isa(s,Expr) &&
elseif isa(s, Expr) &&
(s.head == :(=) || s.head == :kw) &&
length(s.args) == 2 && isa(s.args[1],Symbol)
i = eval(current_module(),s.args[2]) # allow exprs, e.g. uint128"1"
length(s.args) == 2 && isa(s.args[1], Symbol)
i = eval(__module__, s.args[2]) # allow exprs, e.g. uint128"1"
if !isa(i, Integer)
throw(ArgumentError("invalid value for Enum $typename, $s=$i; values must be integers"))
end
Expand Down Expand Up @@ -144,7 +144,7 @@ macro enum(T,syms...)
end
end
end
if isa(typename,Symbol)
if isa(typename, Symbol)
for (sym,i) in vals
push!(blk.args, :(const $(esc(sym)) = $(esc(typename))($i)))
end
Expand Down
10 changes: 6 additions & 4 deletions base/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,10 @@ function get_type_call(expr::Expr)
return_type === nothing && return (Any, false)
return (return_type, true)
end
# Returns the return type. example: get_type(:(Base.strip("",' ')),Main) returns (String,true)
function get_type(sym::Expr, fn)
sym=expand(sym)

# Returns the return type. example: get_type(:(Base.strip("", ' ')), Main) returns (String, true)
function get_type(sym::Expr, fn::Module)
sym = expand(fn, sym)
val, found = get_value(sym, fn)
found && return Base.typesof(val).parameters[1], found
if sym.head === :call
Expand All @@ -310,10 +311,11 @@ function get_type(sym::Expr, fn)
end
return (Any, false)
end
function get_type(sym, fn)
function get_type(sym, fn::Module)
val, found = get_value(sym, fn)
return found ? Base.typesof(val).parameters[1] : Any, found
end

# Method completion on function call expression that look like :(max(1))
function complete_methods(ex_org::Expr)
args_ex = Any[]
Expand Down
8 changes: 4 additions & 4 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ String(s::String) = s # no constructor yet
# This should always be inlined
getptls() = ccall(:jl_get_ptls_states, Ptr{Void}, ())

include(fname::String) = ccall(:jl_load_, Any, (Any,), fname)
include(m::Module, fname::String) = ccall(:jl_load_, Any, (Any, Any), m, fname)

eval(e::ANY) = eval(Main, e)
eval(m::Module, e::ANY) = ccall(:jl_toplevel_eval_in, Any, (Any, Any), m, e)
Expand Down Expand Up @@ -337,15 +337,15 @@ end

# docsystem basics
macro doc(x...)
atdoc(__source__, x...)
atdoc(__source__, __module__, x...)
end
macro __doc__(x)
Expr(:escape, Expr(:block, Expr(:meta, :doc), x))
end
macro doc_str(s)
Expr(:escape, s)
end
atdoc = (source, str, expr) -> Expr(:escape, expr)
atdoc = (source, mod, str, expr) -> Expr(:escape, expr)
atdoc!(λ) = global atdoc = λ


Expand Down Expand Up @@ -382,4 +382,4 @@ show(a::ANY) = show(STDOUT, a)
print(a::ANY...) = print(STDOUT, a...)
println(a::ANY...) = println(STDOUT, a...)

ccall(:jl_set_istopmod, Void, (Bool,), true)
ccall(:jl_set_istopmod, Void, (Any, Bool), Core, true)
22 changes: 12 additions & 10 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ function eval_user_input(ast::ANY, show_value)
display_error(lasterr,bt)
errcount, lasterr = 0, ()
else
ast = expand(ast)
ast = expand(Main, ast)
value = eval(Main, ast)
eval(Main, Expr(:body, Expr(:(=), :ans, QuoteNode(value)), Expr(:return, nothing)))
if !(value === nothing) && show_value
Expand Down Expand Up @@ -210,7 +210,7 @@ function parse_input_line(s::String; filename::String="none")
s, sizeof(s), filename, sizeof(filename))
if ex === :_
# remove with 0.6 deprecation
expand(ex) # to get possible warning about using _ as an rvalue
expand(Main, ex) # to get possible warning about using _ as an rvalue
end
return ex
end
Expand Down Expand Up @@ -243,7 +243,7 @@ function incomplete_tag(ex::Expr)
end

# try to include() a file, ignoring if not found
try_include(path::AbstractString) = isfile(path) && include(path)
try_include(mod::Module, path::AbstractString) = isfile(path) && include(mod, path)

function process_options(opts::JLOptions)
if !isempty(ARGS)
Expand Down Expand Up @@ -279,7 +279,7 @@ function process_options(opts::JLOptions)
# load file immediately on all processors
if opts.load != C_NULL
@sync for p in procs()
@async remotecall_fetch(include, p, unsafe_string(opts.load))
@async remotecall_fetch(include, p, Main, unsafe_string(opts.load))
end
end
# eval expression
Expand All @@ -304,7 +304,7 @@ function process_options(opts::JLOptions)
if !is_interactive
ccall(:jl_exit_on_sigint, Void, (Cint,), 1)
end
include(PROGRAM_FILE)
include(Main, PROGRAM_FILE)
end
break
end
Expand All @@ -315,12 +315,13 @@ end
function load_juliarc()
# If the user built us with a specific Base.SYSCONFDIR, check that location first for a juliarc.jl file
# If it is not found, then continue on to the relative path based on JULIA_HOME
if !isempty(Base.SYSCONFDIR) && isfile(joinpath(JULIA_HOME,Base.SYSCONFDIR,"julia","juliarc.jl"))
include(abspath(JULIA_HOME,Base.SYSCONFDIR,"julia","juliarc.jl"))
if !isempty(Base.SYSCONFDIR) && isfile(joinpath(JULIA_HOME, Base.SYSCONFDIR, "julia", "juliarc.jl"))
include(Main, abspath(JULIA_HOME, Base.SYSCONFDIR, "julia", "juliarc.jl"))
else
try_include(abspath(JULIA_HOME,"..","etc","julia","juliarc.jl"))
try_include(Main, abspath(JULIA_HOME, "..", "etc", "julia", "juliarc.jl"))
end
try_include(abspath(homedir(),".juliarc.jl"))
try_include(Main, abspath(homedir(), ".juliarc.jl"))
nothing
end

function load_machine_file(path::AbstractString)
Expand Down Expand Up @@ -363,12 +364,13 @@ function __atreplinit(repl)
end
end
end
_atreplinit(repl) = @eval Main $__atreplinit($repl)
_atreplinit(repl) = invokelatest(__atreplinit, repl)

function _start()
empty!(ARGS)
append!(ARGS, Core.ARGS)
opts = JLOptions()
@eval Main include(x) = $include(Main, x)
try
(quiet,repl,startup,color_set,history_file) = process_options(opts)

Expand Down
6 changes: 4 additions & 2 deletions base/coreimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ Main.Core.eval(Main.Core, :(baremodule Inference
using Core.Intrinsics
import Core: print, println, show, write, unsafe_write, STDOUT, STDERR

ccall(:jl_set_istopmod, Void, (Bool,), false)
ccall(:jl_set_istopmod, Void, (Any, Bool), Inference, false)

eval(x) = Core.eval(Inference, x)
eval(m, x) = Core.eval(m, x)

const include = Core.include
include(x) = Core.include(Inference, x)
include(mod, x) = Core.include(mod, x)

# conditional to allow redefining Core.Inference after base exists
isdefined(Main, :Base) || ((::Type{T})(arg) where {T} = convert(T, arg)::T)

Expand Down
46 changes: 42 additions & 4 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,13 @@ function firstcaller(bt::Array{Ptr{Void},1}, funcsyms)
return lkup
end

deprecate(s::Symbol) = deprecate(current_module(), s)
deprecate(m::Module, s::Symbol) = ccall(:jl_deprecate_binding, Void, (Any, Any), m, s)

macro deprecate_binding(old, new, export_old=true)
Expr(:toplevel,
return Expr(:toplevel,
export_old ? Expr(:export, esc(old)) : nothing,
Expr(:const, Expr(:(=), esc(old), esc(new))),
Expr(:call, :deprecate, Expr(:quote, old)))
Expr(:call, :deprecate, __module__, Expr(:quote, old)))
end

# BEGIN 0.6-alpha deprecations (delete when 0.6 is released)
Expand Down Expand Up @@ -630,7 +629,7 @@ for (Bsig, A1sig, A2sig, gbb, funcname) in
func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC)
# need eval because func was just created by gen_broadcast_function_sparse
# TODO: convert this to a generated function
eval(current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2)))))
eval(_current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2)))))
return B
end
end # let broadcast_cache
Expand Down Expand Up @@ -1350,6 +1349,45 @@ end
@deprecate srand(filename::AbstractString, n::Integer=4) srand(read!(filename, Array{UInt32}(Int(n))))
@deprecate MersenneTwister(filename::AbstractString) srand(MersenneTwister(0), read!(filename, Array{UInt32}(Int(4))))

# also remove all support machinery in src for current_module when removing this deprecation
# and make Base.include an error
_current_module() = ccall(:jl_get_current_module, Ref{Module}, ())
@noinline function binding_module(s::Symbol)
depwarn("binding_module(symbol) is deprecated, use `binding_module(module, symbol)` instead.", :binding_module)
return binding_module(_current_module(), s)
end
@noinline function expand(x::ANY)
depwarn("expand(x) is deprecated, use `expand(module, x)` instead.", :expand)
return expand(_current_module(), x)
end
@noinline function macroexpand(x::ANY)
depwarn("macroexpand(x) is deprecated, use `macroexpand(module, x)` instead.", :macroexpand)
return macroexpand(_current_module(), x)
end
@noinline function isconst(s::Symbol)
depwarn("isconst(symbol) is deprecated, use `isconst(module, symbol)` instead.", :isconst)
return isconst(_current_module(), s)
end
@noinline function include_string(txt::AbstractString, fname::AbstractString="string")
depwarn("include_string(string, fname) is deprecated, use `include_string(module, string, fname)` instead.", :include_string)
return include_string(_current_module(), txt, fname)
end

"""
current_module() -> Module
Get the *dynamically* current `Module`, which is the `Module` code is currently being read
from. In general, this is not the same as the module containing the call to this function.
DEPRECATED: use @__MODULE__ instead
"""
@noinline function current_module()
depwarn("current_module() is deprecated, use `@__MODULE__` instead.", :current_module)
return _current_module()
end
export current_module


# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
Loading

0 comments on commit d16a141

Please sign in to comment.