-
Notifications
You must be signed in to change notification settings - Fork 235
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
'Modul(term)' -> 'Modul.(term)' ; 'Dcon.prm' -> 'Dcon?.prm', 'is_Dcon' -> 'Dcon?' ; improved name resolution #772
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The goal of this syntax change is to ensure that, for any name of the form Namespace.ident or Namespace.Name, the Namespace part is always a valid module name (except if Namespace.Name is itself the name of a module.) So far, this property was not holding for the following two cases: - many occurrences of Some.v to project the formal parameter v of an option value that is known to be Some; Formally, whenever an inductive type t is defined: type t = | Datacon : param: u -> t | ... then, for any value vt : t {is_Datacon v} , it is valid to use (Datacon.param vt), of type u, to extract the value of the formal parameter. This introduces a spurious dependency on a hypothetical module called Some (and a clash if any Some module is reachable from open namespaces.) - STATE.pre, STATE.post, and other effect members, similarly introducing spurious dependencies on a hypothetical STATE module. As mentioned, the main consequence of those data constructor and effect namespaces not being true modules are spurious dependency generation and potential clashes with modules. I claim that this current situation also gets in the way of any improvement on name resolution, e.g. potential support for `include', currently being discussed as `export' at: #691 Thus, we need to introduce new syntax to change these data constructor projector and effect member notations. While I arbitrarily chose .. for testing purposes, discussions about the final concrete syntax are still ongoing at: http://doodle.com/poll/enadrtwqb6vhu2tr However, independently of the actual choice for concrete syntax, this syntax change implies the following deeper changes: 1. The projector for a formal parameter of a data constructor has been renamed, both internally and on the extracted code. Previously, Datacon.param was added as a fully qualified name for the corresponding projector. To avoid clashes with name resolution in open namespaces, it is now renamed as __proj__Datacon__item__param We could have used the reserved prefix uu___ (defined as reserved_prefix in src/basic/ident.fs), but using such prefix actually makes the verification of examples/preorders/MRefHeap.fst fail when replaying hints, for an unknown reason so far. 2. The fields of a record have been renamed similarly in extracted code. This is for two reasons. First, a record field is treated in the same way as a formal parameter of a data constructor, for internal purposes. In particular, given the following record type: type reco = { field: unit; ... } the elaborator actually turned any field access of the form expr.field intro (Mk_reco.field expr) where Mk_reco is the name of the data constructor created by transforming the record type into an inductive type, and so Mk_reco.field was exactly the data constructor projector for the 'field' formal parameter of the Mk_reco (unique) data constructor. We preserve this elaboration as a projector, but now using the new projector name instead. However, the second reason is that, since such projector calls are turned back to field accesses in extracted ML code, we do not want to rely on the extracted language's shadowing mechanism (for two different record types in the same module, each of which having a field with the same name in both), and so we use our field renaming as a way to resolve any such shadowing in advance. 3. The fields (pre, post, reflect, return, bind, and actions) of an effect have been renamed similarly, both internally and in extracted code. In this process, we took extra care to preserve the monad scope while defining the members and actions of an effect, in such a way that those names need not be qualified by the effect name while being defined. However, once defined, such a member is now required to be qualified with its MonadName.. instead of MonadName. In particular, this new mechanism now forbids `open Monad' ---opening the namespace of a monad to access its members through unqualified names outside of the monad definition. Fortunately, this happens nowhere in any examples. The main purpose of these renamings is to guarantee that, for any global definition whose fully qualified name is of the shape Namespace.ident, Namespace is now always a valid module, which was not the case until now for data constructor projectors and effect fields.
Needed by 'make -C src test', namely 'make -C examples/unit-tests sall', more exactly examples/unit-tests/Unit1.Basic.fst
…te"" This reverts commit 5e2138d.
…na_projectors Remaining conflicts on compiler files were solved by automatically regenerating them.
Now, scopes are handled more intuitively, very much like OCaml: local opens really shadow previous local definitions, etc. The elaborator now relies on a cleaner implementation for name resolution in src/parser/env.fs, based on keeping one single list with all declarations interleaved, instead of keeping separate lists for local definitions, recursive definitions, open namespaces and module abbrevs. Thus, this commit also fixes some spurious shadowings, which were missed in some examples. This commit heavily relies on the fact that, whenever a name of the form Namespace.ident shows up, Namespace is always the name of a valid module (not an effect or a data constructor). So, now, Namespace is first separately resolved as a module, then the definition is looked up into the given module. This commit currently allows module name resolution at open, let open, and module abbrevs, but I claim that this can be easily changed and reverted to the previous behavior of requiring fully qualified module names.
Reported by failing builds 2411 to 2413
…mana_local_open Conflicts: src/parser/parse.fsi src/parser/parse.fsy Resolved as "take theirs" (discard conflicting changes coming from taramana_local_open).
…na_projectors Conflicts: src/ocaml-output/FStar_Parser_AST.ml src/parser/parse.fsi src/parser/parse.fsy Resolved as "take theirs" (discard taramana_projectors) ***NO_CI***
…mana_local_open
…mana_local_open Conflicts resolved by regenerating the parser using: make -C src/ocaml-output parser
***CI***
…mana_local_open
into taramana_projectors Conflicts: doc/tutorial/code/solutions/Ex11a.fst.hints examples/low-level/crypto/Buffer.Utils.fst.hints examples/low-level/crypto/Crypto.AEAD.AES256GCM.fst.hints examples/low-level/crypto/Crypto.AEAD.Encoding.fst.hints examples/low-level/crypto/Crypto.AEAD.Invariant.fst.hints examples/low-level/crypto/Crypto.AEAD.Lemmas.fst.hints examples/low-level/crypto/Crypto.AEAD.fst.hints examples/low-level/crypto/Crypto.Symmetric.AES.fst.hints examples/low-level/crypto/Crypto.Symmetric.Bytes.fst.hints examples/low-level/crypto/Crypto.Symmetric.GCM.fst.hints examples/low-level/crypto/Crypto.Symmetric.GF128.fst.hints examples/low-level/crypto/Crypto.Symmetric.PRF.fst.hints examples/low-level/crypto/Crypto.Symmetric.Poly1305.Bignum.Lemmas.Part3.fst.hints examples/low-level/crypto/Crypto.Symmetric.Poly1305.Bignum.fst.hints examples/low-level/crypto/Crypto.Symmetric.Poly1305.Spec.fst.hints examples/low-level/crypto/Crypto.Symmetric.Poly1305.fst.hints ulib/FStar.Math.Lib.fst.hints Resolved by discarding taramana_projectors in favor of master (git checkout --theirs) ***CI***
At this point, Crypto.AEAD.Lemmas succeeds, but Ex07c still fails. In fact, Ex07c succeeds if hints are disabled altogether, but even if hints are produced when disabled (yielding the .hints file as reflected in this commit), rechecking Ex07c with them ultimately fails, for an unknown reason so far.
…StarLang/FStar into taramana_discriminators
This reverts commit 3826b71.
…g/FStar into taramana_name_resolution Conflicts: - *.hints: --theirs - *.ml: make -C src ocaml - *.fst: manual edits
Now, 'open M' for module M again requires that M be fully qualified, or a module abbrev, and 'module A = M' requires that M be fully qualified.
49 tasks
***CI***
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This long-awaited pull request introduces invasive, non-backwards-compatible syntax changes, as announced in #770.
Namespace (term)
becomesNamespace.(term)
(similarly to OCaml, restores pull request Syntax change: 'Modul term' -> 'Modul.(term)', parsed as 'let open Modul in term' #757 that was reverted because of the PLDI deadline)Datacon.param
becomesDatacon?.param
Effect.action
becomesEffect?.action
(and similarly forreflect
, etc.)is_Datacon
becomesDatacon?
The goal of these syntax changes is to introduce an invariant in name resolution: for any identifier (except module names) of the form
Namespace.ident
,Namespace
shall always be a valid module name (in particular, it can no longer be a data constructor or effect name). This pull request introduces an improved name resolution with this invariant.The improved name resolution mechanism brought by this pull request now honors shadowing in a more intuitive way, similarly to OCaml. Thus, in the following example:
In the above example,
y
will have value 18, sincex
now takes the value ofA.x
as expected, instead of the local variablex
, as was the case previously.NOTE: This may break existing code with
let open FStar.UInt32
and the like, which will shadown
, sincen
is defined in such integer library modules.These improvements are necessary to implement long-awaited enhancements (upcoming, not yet included in this pull request):
include
for libraries, to "merge" several libraries into one single namespace #691)