You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When joining environments, we exclude variables that are no longer
useful in the joined environment. This causes the remaining variables to
have new (lower) binding times.
If we later join the resulting environment again with another
environment that still has those variables, we end up having the
same variable with different binding times in the joined level, and we
define the variable twice in the resulting environment.
This can allow breaking the order between two variable's binding times,
which means that different canonical elements can be chosen in different
environments for the same pair of variables.
This patch fixes the issue by keeping track of `next_binding_time`
*globally* across all related environments and keeping the binding time
during join, ensuring that the binding time of a variable is globally
unique and preventing any such re-orderings.
Longer explanation
------------------
Consider 4 environments that define variables `a`, `b`, `c`, and `d`.
```
_________________________________
/ | | \
Env 1 Env 2 Env 3 Env 4
/ | | \
define a define a define a define a
| | | |
define b define b define b define b
| | | |
define c define c define c define c
| | | |
define d define d define d define d
```
Suppose that we first join environments 3 and 4 (filtering out `a` and
`b`) and environments 1 and 2 (filtering out `d`):
```
____________
/ \
Env 1 \/ 2 Env 3 \/ 4
/ \
define a define c
| |
define b define d
|
define c
```
Once we join the two resulting environments, if we filter out `a` and
`b` but keep `c` and `d`, the current implementation creates a level
which defines `c`, then `d`, then `c` again. Since we keep the last
definition, we end up with the environment:
```
define d
|
define c
```
We have now swapped the binding times of `c` and `d` which, if they were
in the same alias set, can introduce subtle bugs.
0 commit comments