From 917c0f24167e68fe671be58fe7876490a437ad0b Mon Sep 17 00:00:00 2001 From: Colin Caine Date: Fri, 10 Sep 2021 17:49:18 +0100 Subject: [PATCH 1/2] Exclude modules own name from empty modules Follow up on #40110 --- NEWS.md | 2 +- base/boot.jl | 2 +- doc/src/manual/modules.md | 2 +- src/module.c | 12 +++++++----- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/NEWS.md b/NEWS.md index b1442f0192350..3cd65f560937b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,7 +5,7 @@ Julia v1.8 Release Notes New language features --------------------- -* `Module(:name, false, false)` can be used to create a `module` that does not import `Core`. ([#40110]) +* `Module(:name, false, false)` can be used to create a `module` that contains no names (it does not import `Base` or `Core` and does not contain a reference to itself). ([#40110, #42154]) * `@inline` and `@noinline` annotations can be used within a function body to give an extra hint about the inlining cost to the compiler. ([#41312]) * `@inline` and `@noinline` annotations can now be applied to a function callsite or block diff --git a/base/boot.jl b/base/boot.jl index ee1370bf5dff1..4679acd85d26d 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -428,7 +428,7 @@ eval(Core, :(InterConditional(slot::Int, @nospecialize(vtype), @nospecialize(els eval(Core, :(MethodMatch(@nospecialize(spec_types), sparams::SimpleVector, method::Method, fully_covers::Bool) = $(Expr(:new, :MethodMatch, :spec_types, :sparams, :method, :fully_covers)))) -Module(name::Symbol=:anonymous, std_imports::Bool=true, using_core::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, using_core) +Module(name::Symbol=:anonymous, std_imports::Bool=true, default_names::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, default_names) function _Task(@nospecialize(f), reserved_stack::Int, completion_future) return ccall(:jl_new_task, Ref{Task}, (Any, Any, Int), f, completion_future, reserved_stack) diff --git a/doc/src/manual/modules.md b/doc/src/manual/modules.md index 7d3304810a428..1135991743bb2 100644 --- a/doc/src/manual/modules.md +++ b/doc/src/manual/modules.md @@ -303,7 +303,7 @@ include(p) = Base.include(Mod, p) end ``` -If even `Core` is not wanted, a module that imports nothing at all can be defined with `Module(:YourNameHere, false, false)` and code can be evaluated into it with [`@eval`](@ref) or [`Core.eval`](@ref). +If even `Core` is not wanted, a module that imports nothing and defines no names at all can be defined with `Module(:YourNameHere, false, false)` and code can be evaluated into it with [`@eval`](@ref) or [`Core.eval`](@ref). ### Standard modules diff --git a/src/module.c b/src/module.c index 4120b6cb9225d..a7db957d2d9c3 100644 --- a/src/module.c +++ b/src/module.c @@ -11,7 +11,7 @@ extern "C" { #endif -JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, uint8_t using_core) +JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, uint8_t default_names) { jl_task_t *ct = jl_current_task; const jl_uuid_t uuid_zero = {0, 0}; @@ -36,11 +36,13 @@ JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, uint8_t using_core) htable_new(&m->bindings, 0); arraylist_new(&m->usings, 0); JL_GC_PUSH1(&m); - if (jl_core_module && using_core) { + if (jl_core_module && default_names) { jl_module_using(m, jl_core_module); } // export own name, so "using Foo" makes "Foo" itself visible - jl_set_const(m, name, (jl_value_t*)m); + if (default_names) { + jl_set_const(m, name, (jl_value_t*)m); + } jl_module_export(m, name); JL_GC_POP(); return m; @@ -56,10 +58,10 @@ uint32_t jl_module_next_counter(jl_module_t *m) return jl_atomic_fetch_add(&m->counter, 1); } -JL_DLLEXPORT jl_value_t *jl_f_new_module(jl_sym_t *name, uint8_t std_imports, uint8_t using_core) +JL_DLLEXPORT jl_value_t *jl_f_new_module(jl_sym_t *name, uint8_t std_imports, uint8_t default_names) { // TODO: should we prohibit this during incremental compilation? - jl_module_t *m = jl_new_module_(name, using_core); + jl_module_t *m = jl_new_module_(name, default_names); JL_GC_PUSH1(&m); m->parent = jl_main_module; // TODO: this is a lie jl_gc_wb(m, m->parent); From dff88cfe85546213f7cc797e050f47eca658a69d Mon Sep 17 00:00:00 2001 From: Colin Caine Date: Fri, 10 Sep 2021 18:01:41 +0100 Subject: [PATCH 2/2] Document Module constructor --- base/docs/basedocs.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index e7ae0123117b5..f436ebef82026 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -2812,6 +2812,13 @@ StridedVecOrMat Module A `Module` is a separate global variable workspace. See [`module`](@ref) and the [manual section about modules](@ref modules) for details. + + Module(name::Symbol=:anonymous, std_imports=true, default_names=true) + +Return a module with the specified name. A `baremodule` corresponds to `Module(:ModuleName, false)` + +An empty module containing no names at all can be created with `Module(:ModuleName, false, false)`. +This module will not import `Base` or `Core` and does not contain a reference to itself. """ Module