Proposal: Add @safe_in attribute to enable compile time warnings for "private" modules.

46 views
Skip to first unread message

Booker Bense

unread,
Aug 1, 2018, 11:39:24 AM8/1/18
to elixir-lang-core
The recent thread on the Elixir forum about the use of "private" modules (i.e. @moduledoc false) being unsafe to minor upgrades has started me thinking about a general solution to this problem.

Given the dynamic nature of the BEAM it would be overly onerous to attempt to do any kind of runtime "blocking" of modules, but I think a reasonable compromise would be to have a compile time warning when you call a function from an "unsafe" module. To enable this private modules would explicitly list the modules for which the module is safe to be used from.

For example:

In ExUnit.CLIFormatter you would add this attribute

@safe_in [ ExUnit]


Note: this may not be a particularly good example, since the formatter is stored as a config variable.

The compiler would generate warnings if any functions from the module were used in any modules not listed in
the @safe_in attribute. This would work for both the core Elixir libraries and also provide a tool for 3rd party
libraries to be more explicit to their users.

- Booker C. Bense

Justin Wood

unread,
Aug 1, 2018, 12:25:35 PM8/1/18
to elixir-l...@googlegroups.com
Would this be in addition to using @moduledoc false? Or would this be replacing that? I think the main problem with trying to give warnings to people about using an internal module is that functions like apply/3 exist. I think it would be impossible to do it all at compile time.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

José Valim

unread,
Aug 1, 2018, 1:02:00 PM8/1/18
to elixir-l...@googlegroups.com
Thanks Booker,

We would like to here more complete proposals on the topic. We need to consider the completeness of the mechanism, for example, how can it bypassed? What are the peformance costs? How should Code.ensure_loaded? and function_exported? behave? What are the gotchas?

For example, the proposed syntax is not achievable because Elixir does not require modules to be available at compile time when you only invoke them at runtime. So when any code invokes ExUnit.CliFormatter inside the function definition, we don't check for it at all.And if we start checking it for all invocations, it may incur big compilation time costs.



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.

Andrea Leopardi

unread,
Aug 1, 2018, 1:03:42 PM8/1/18
to elixir-lang-core
It is impossible to do at compile-time, but we have a history of doing checks that only catch stuff at compile-time. For example, xref checks for undefined functions in modules at compile-time (so it will catch Foo.undefined_function(...)), but it won't catch apply(Foo, :undefined_function, [...]). Not saying I am in favour or opposed to this feature, but I think it would be fine to implement from a consistency standpoint.

Andrea Leopardi


José Valim

unread,
Aug 1, 2018, 1:11:23 PM8/1/18
to elixir-l...@googlegroups.com
xref is that it is good at proposing things that "could be better", it doesn't provide a guarantee, it is just a suggestion, but that's fine.

However, I would say here we need stronger guarantees, and there just too many ways to bypass xref for it to be worth it.



José Valim
Skype: jv.ptec
Founder and Director of R&D

On Wed, Aug 1, 2018 at 7:03 PM, Andrea Leopardi <an.le...@gmail.com> wrote:
It is impossible to do at compile-time, but we have a history of doing checks that only catch stuff at compile-time. For example, xref checks for undefined functions in modules at compile-time (so it will catch Foo.undefined_function(...)), but it won't catch apply(Foo, :undefined_function, [...]). Not saying I am in favour or opposed to this feature, but I think it would be fine to implement from a consistency standpoint.

Andrea Leopardi


On Wed, Aug 1, 2018 at 6:25 PM 'Justin Wood' via elixir-lang-core <elixir-lang-core@googlegroups.com> wrote:
Would this be in addition to using @moduledoc false? Or would this be replacing that? I think the main problem with trying to give warnings to people about using an internal module is that functions like apply/3 exist. I think it would be impossible to do it all at compile time.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On 1 August 2018 11:39 AM, Booker Bense <bbe...@gmail.com> wrote:

The recent thread on the Elixir forum about the use of "private" modules (i.e. @moduledoc false) being unsafe to minor upgrades has started me thinking about a general solution to this problem.

Given the dynamic nature of the BEAM it would be overly onerous to attempt to do any kind of runtime "blocking" of modules, but I think a reasonable compromise would be to have a compile time warning when you call a function from an "unsafe" module. To enable this private modules would explicitly list the modules for which the module is safe to be used from.

For example:

In ExUnit.CLIFormatter you would add this attribute

@safe_in [ ExUnit]


Note: this may not be a particularly good example, since the formatter is stored as a config variable.

The compiler would generate warnings if any functions from the module were used in any modules not listed in
the @safe_in attribute. This would work for both the core Elixir libraries and also provide a tool for 3rd party
libraries to be more explicit to their users.

- Booker C. Bense


--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAM9Rf%2B%2BM0EPN8X9BoJ27o1ZEh_9fvVfbR-7ONpB3VeitWtM6EA%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages