spicy icon indicating copy to clipboard operation
spicy copied to clipboard

Consider changing `import` semantics to not inherit the `public` interface

Open bbannier opened this issue 3 years ago • 0 comments

If one imports another module we always emit code for all public units in the imported module, even if none of them were used. This makes it hard to move common code to a dedicated module for reuse.

Example

# bar.spicy
module bar;

import foo; # No symbols used from `foo`.

print 1;
# foo.spicy
module foo;

public type X = unit {};
type Y = unit {}; 

Compiling bar.spicy causes emitting of both foo::X and foo::Y. The current optimizer then removes foo::Y, but does not remove foo::X since it is declared public in foo and implicitly becomes part of the external interface of bar. The current behavior is that importing a module extends the public interface of the importing module. This can be useful, but makes importing by default potentially expensive (very expensive for large libraries with C++ compile times of up to 1h reported by users).

I wonder whether we shouldn't change the semantics of import so that by default it does not add the public interface of the imported module; we could add a new import statement which triggers inheriting the public interface, e.g., public import foo;. Currently the only way users have to emulate that behavior is to manually make sure that a commonly imported module does not declare or import public types or functions. This can be impossible, e.g., when declaring non-public helper functions which work on public types.

EDIT

We already do not emit public functions from imported modules if they are unused.

bbannier avatar Dec 20 '22 11:12 bbannier