We replace them with a new kind of (delayed) assignment at `metavar_context`
```
mvar := (lctx, locals, v)
```
where `lctx` is a local context, `locals` is a list of local
constants, and `v` is an expression.
When all metavariables in `v` are assigned, this assignment is replaced with
```
mvar := Fun(locals, v)
```
It was a bad idea to try to store the name_generator here.
We copy/restore metavar_context objects in a few places.
These operations would trigger the regeneration of previously generated
fresh names, and would violate the assumptions made at persistent_context_cache.
We should have a name_generator at type_context instead.
The peformance problem was affecting theorems that contain many `intro`
tactic applications.
@gebner After this optimization, the GAPT benchmark elaboration time went from
1.6 secs to 0.6 secs.
Fixes#1363
After error recovery has been implemented in the elaborator, a few
assumptions made in the type context are not valid anymore since we may
be recovering from errors, and the local and metavariable contexts may
be invalid.
I used the approach used in the class environment.
- find* methods return optional<...>
- get* methods throw exception for unknown elements
Remarks:
I preserved code patterns such as
optional<local_decl> d = lctx.find_local_decl(...)
lean_assert(d)
and did not convert them into
local_decl d = lctx.get_local_decl(...)
Reason: the intention is clear that the local must be defined there.
If it is not we should analyze the problem and decide whether we should
throw an exception or not.
However, I converted code patterns such as
local_decl d = *lctx.find_local_decl(...)
into
local_decl d = lctx.get_local_decl(...)
Disclaimer: this change fixes issue #1363, but it may obfuscate other bugs.
This commit also removes a "hack" that tried to fix this problem for
universe meta-variables only. Moreover, the hack was incomplete, since
it would not consider nested metavars.