This commit exposes all extension constructors when looking up for
a construction with a given type in the environment.
This makes constructor disambiguation work for extension constructors.
Going one step further, when the name of an extension constructors
is misspelled, we cannot rely on the type to find all possible
names. However, since we are in an error path, we have some
path at hand.
Thus, this commit alters the "lookup_from_type" function in the
Constructor module to make it scan the whole environment for
extension constructors with the right type.
This commit should not change anything for labels and standard constructors.
Persistent_env is a new module that handles the relation between the
type-checking state and the "persistent" typing information laying in
.cmi files on the filesystem. In particular, it handles the collection
and production of CRC information for the .cmi files being read and
written to the filesystem; the using modules (in our case, only Env)
are in charge of turning the cmi files into higher-level information
(components and signatures).
Persistent_env exposes a type `'a t` of a persistent environment,
which acts as a mutable store of `'a` values. There is no global state
in the module itself: while Env (and thus the OCaml type-checker) uses
a single global persistent environment, it should be possible to
create several independent environments to represent, for example,
several independent type-checking sessions.
This small change of behavior simplifies the internal plumbing of env
by avoiding the need to passes the 'current_unit_name' state to
cmi-checking exceptions -- it allows to separate the cmi/crc logic to
a separate module in a future commit.
We believe that the change does not actually reduce error message
clarity, as the name of the offending unit appears in the location
filename anyway (see how these exceptions are handled by
Location.error_of_printer_file in the error printer).
Before:
File "a.mli", line 1:
Error: Unit A imports from B, which uses recursive types.
The compilation flag -rectypes is required
After:
File "a.mli", line 1:
Error: Invalid import of B, which uses recursive types.
The compilation flag -rectypes is required
There is a small change of behavior in this patch due to a different
handling of weak dependencies (those with crco=None); in
Env.check_consistency, only non-weak dependencies would get
[Env.add_import] called, while the `toplevel/` implementations would
also call [Env.add_import] on weak dependencies. After this patch, we
systematically call [add_import] only on non-weak dependencies, even
in `toplevel/`.
([Gabriel:] As far as I can see, the use of [add_import] in the
toplevel never leads to a use of [Env.imports()] for producing
a dependency list, as the toplevel does not produce cmi/cmo files; are
they just no-ops?)
- Add a Load_path module which caches files lookup
- Instead of falling back to the external environment, allow to
declare in the environment that a module comes from the external
world. This allows persistent structures to shadows non-persistent
ones
Previously, not having a scope meant the type was used in every context,
now we set the scope to "Btype.lowest_level" to mean the same thing.
The equivalence was made obvious by the recent changes to identifiers
scoping.
- Ident.create now takes a scope as argument
- added Ident.create_var to use when the scope doesn't matter
- the current_time and the current_level are unrelated as of this
commit. But one has to remember to bump the level when creating new
scopes.
* Fix MPR#7726 by re-checking recursive modules in signatures after substitution
* Check module applications when translating types in Typetexp
* Check all results of functor applications lazily
* Reduce the overhead of checking module types by building the environment lazily
Deprecation warning (3) is currently only reported when directly
accessing a component marked with the deprecated attribute; but it is
missed when we coerce the signature contaning the deprecated component
to a signature without the attribute.
This commit adds the required machinery to detect such cases
and report the same warning. (An alternative design could be
to introduce a new warning for that purpose.)
Some of the new machinery could be used for other purposes:
- During the inclusion check, keep the location that would used in
the error message if the check fails.
- Warnings can now hold extra "sub-locations" (and associated
messages).
Instead of rebuilding cmi_info in Cmt_format.save_cmt, the record
created in Env.save_signature is kept and passed to that function. In
addition to simplifying the code, this avoids possible mismatch between
the two records, including:
- Duplicated entry in cmi_crcs for the current unit as noted in #744.
- Missing flags (Unsafe_string/Deprecated were not properly set in
Cmt_format).
The interface is also stronger, since the signature passed to save_cmt
was supposed to be already mapped by Subst.for_saving but this was not
reflected in the API.
This is used to prevent depending on a unit compiled with -unsafe-string
when the compiler has been *configured* with -safe-string. This is not
100% bullet-proof, since the unsafe_string marker is not propagated
transitively, so it is possible to "hide" it by going through an
intermediate compilation unit compiled with -safe-string (with a
compiled configure without -safe-string). But this should catch most
cases of old files staying around produced by a compiler not configured
with -safe-string.