-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested modules #1048
Nested modules #1048
Conversation
544cdee
to
27c2339
Compare
* Limitations: Does not work in combination parameterized modules, as I am about to redo how that works. * General refeactorings: * Namespaces: - We have an explicit type for namespaces, see `Cryptol.Util.Ident` - Display environments should now be aware of the namespace of the name being displayed. * Renamer: - Factor out the renamer monad and error type into separate modules - All name resultion is done through a single function `resolveName` - The renamer now computes the dependencies between declarations, orders things in dependency order, and checks for bad recursion. * Typechecker: Redo checking of declarations (both top-level and local). Previously we used a sort of CPS to add things in scope. Now we use a state monad and add things to the state. We assume that the renamer has been run, which means that declarations are ordered in dependency order, and things have unique name, so we don't need to worry about scoping too much. * Change specific to nested modules: - We have a new namespace for module names - The interface file of a module contains the interfaces for nested modules - Most of the changes related to nested modules in the renamer are in `ModuleSystem.NamingEnv` and `ModuleSystem.Rename` - There is some trickiness when resolving module names when importing submodules (seed `processOpen` and `openLoop`) - There are some changes to the representation of modules in the typechecked syntax, in particular: - During type-checking we "flatten" nested module declarations into a single big declaration. Hopefully, this means that passes after the type checker don't need to worry about nested modules - There is a new field containing the interfaces of the nested modules, this is needed so that when we import the module we know we have the nested structure - Declarations in functor/parameterzied modules do not appear in the flattened list of declarations. Instead thouse modules are collected in a separate field, and the plan is that they would be used from there when we implmenet functor instantiation.
Playing around with private submodules, I discovered that the following doesn't parse.
Basically, layout rules require the declarations in |
This generates a panic:
|
It might be nice if we could treat all submodules as being in scope "qualified". Then, the following would work without the
|
Right now, as I understand it, we have the following rules that control scoping with modules:
I think point 1a is related to the panic above. I think perhaps we should weaken point 2 so that submodules are automatically considered to be in scope qualified by their name, and Finally, I think we should allow a mechanism to explicitly weaken point 4 via an
This would export the symbol This makes it so the basic rule is that: declarations appearing in a module are exported unless they are explicitly made private. Declarations |
@robdockins thanks for the comments! The layout issue is interesting, it totally makes sense that this is rejected with the current rules (there are 2 nested layout blocks and the inner one is closing the outer one), but I agree that it might be nice to make it work somehow... On the issue about nested modules being in scope---my thinking is that this PR only implements the bare minimum "core" functionality (although clearly there is a bug, as the renamer should have caught that For re-exporting things, I think we should deal with those as a separate feature. They might be nice, but also add some complexity, both to the implementation and the specification. In particular, a nice property of the current system is that you can tell what a module exports just by looking at the declarations in it (i.e., you don't need to know what's in scope). With re-exports that's not the case anymore, so some tricky dependencies can arise. I suspect it's doable, but we'd have to think carefully about it. |
Regarding the panic: I think |
@robdockins yep, I added the example as a test, and realized that what I said above is wrong, I am investigating what's happening. I suspect the declarations are not correctly ordered after the renamer. |
See the example on the PR thread, which is captured in test T11
…cies We only show the file location as these will always be in the same file, I think.
This also fixes the extra space in the "invlid dependency" error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree the export
issue can wait. I think you've addressed all the things I've found so far.
When this is merged, I suggest we make issues to track 1) exports and 2) documentation of nested modules (I imagine it makes sense to wait until we rework parameterized modules to write the new documentation).
This fixes a bug where the scoping on the command line was incorrect for nested modules. It also changes the semantics of `:browse` (whose implementation is now in a separate module), to be more reasonable. See #689
…rent parameterzied modules. Some of this is a bit of a hack, but that code would change with the new parameterized modules, so the hack is temporary.
Limitations:
Does not work in combination parameterized modules, as I am
about to redo how that works.
General refeactorings:
Namespaces:
Cryptol.Util.Ident
name being displayed.
Renamer:
resolveName
orders things in dependency order, and checks for bad recursion.
Typechecker: Redo checking of declarations (both top-level and local).
Previously we used a sort of CPS to add things in scope. Now we use
a state monad and add things to the state. We assume that the renamer
has been run, which means that declarations are ordered in dependency
order, and things have unique name, so we don't need to worry about
scoping too much.
Change specific to nested modules:
in
ModuleSystem.NamingEnv
andModuleSystem.Rename
submodules (seed
processOpen
andopenLoop
)syntax, in particular:
a single big declaration. Hopefully, this means that passes after
the type checker don't need to worry about nested modules
this is needed so that when we import the module we know we have the
nested structure
flattened list of declarations. Instead thouse modules are collected
in a separate field, and the plan is that they would be used from
there when we implmenet functor instantiation.