Weird Error: implicit module introduced

I get an error compiling some ancient code with 1.33.0:

m.chpl:1: warning: an implicit module named 'm' is being introduced to contain file-scope code

I cannot remember it being there the last time I compiled it. But that was probably something like 1.20.0. Well, back 3 years ago.

Any suggestions what I am doing wrong? Thanks.

Hi Damian,

This warning typically means you've written some code without having an
explicit module declaration around the full contents of the file. We
added this because in cases where a file has evolved to the point where
its contents are ready for being used in other files, users were having
trouble figuring out how to actually use the code in the file.

For instance, say you have a file like this:

foo.chpl

module One { ... }

module Two { ... }

proc someFunc() { ... }

The function someFunc may have been added at the beginning of the
file's existence. Maybe the user had most recently been working on the
contents of module One and forgotten what else was in the file. But
its presence means there is something defined in the file that otherwise
would not be in a module at all, and all non-module definitions need to
be inside a module (whether one created by the compiler or one defined
by the user). So the compiler creates a module to hold someFunc in
the meanwhile, and doesn't worry too much about it.

It starts to matter if the user becomes ready to write code like this in
another file:

bar.chpl

import One;

One.someOtherFunc();

Here, they're going to get a compilation error, because an implicit
module has been inserted around the entire contents of foo to hold
someFunc, so One isn't visible like it would be if it was defined in
a file by itself. One is actually inside a module named foo, so
what they'd need to write is:

bar.chpl

import foo.One;

One.someOtherFunc();

Since we don't know when a user reaches the point where they want a
file's contents to be accessible to other files, we generate this
warning when we make that wrapper module, so that they know that this
outer wrapping module exists and that they need to take some action if
they don't like that (such as defining their own module around the whole
contents of the file, or moving someFunc into module Two, or its own
file, or even a new module Three).

If your code is intended to be more "script-like" for its entire
existence instead of having its contents referenced in other files, it
is safe to ignore this warning.

Thanks,
Lydia

1 Like

Tagging onto Lydia's response, I wanted to visually show that the module structure of her source file:

would be:

  • top-level module foo
    • sub-module One
    • sub-module Two

(which is why, as she explains, that One isn't visible to other modules, since it's a sub-module of foo).

The original historical reason for this warning is that we had users writing code like the following:

testit.chpl:

use LibModule;

module M {
  ...
}

where they were thinking of use as being a fairly passive/innocuous statement like #include in C/C++. But given the interpretation in Chapel, its use above would actually result in the module structure:

  • top-level module testit
    • sub-module M

and then users would be confused about why M wasn't visible from other scopes.

In practice, we typically suggest users put all file-scope code into an explicit module if the intent is for that file to provide library capabilities; and to only use file-scope code in scripting-like settings as Lydia says.

Hope this helps determine why you're getting this warning. If not, let us know,
-Brad

Thanks for the reply. The explatation about modules is clear.

My test programs are always like

proc tom() { ...... }

proc dick() { ...... }

proc harry() { ...... }

config const .....

proc main
{
    exit(0);
}

Most do not generate this message.

Only one has so far and I cannot quite understand why only this particular one triggers the message and the others do not. That said, this one, unlike most of my single purpose test programs, does have an internal module so maybe that is why.

Hi Damian —

That's as expected—when a file only contains file-scope code with no module declarations, the compiler assumes you know what you're doing and are not confused (or maybe don't even care what the module name is). It's only when there's a mix of file-scope code and module declarations that it gives the warning to make sure that you are aware that the explicit module will be a nested module.

The easy way to quiet the warning is to explicitly declare a module to contain the file-scope code. That is, change:

testit.chpl

use LibModule;

module M {
  ...
}

into:

testit.chpl

module testit {
  use LibModule;

  module M {
    ...
  }
}

This also tells the compiler you understand what's happening.

-Brad