Generate unique symbols for shadowing identifiers

This code has a shadowing error:

```
b = False
f = \b -> b
f b
```

but prior to this commit, the compiler would hit an internal error
during monomorphization and not even get to report the error. The reason
was that when we entered the closure `\b -> b`, we would try to
introduce the identifier `b` to the scope, see that it shadows an
existing identifier, and not insert the identifier. But this meant that
when checking the body of `\b -> b`, we would think that we captured the
value `b` in the outer scope, but that's incorrect!

The present patch fixes the issue by generating new symbols for
shadowing identifiers, so deeper scopes pick up the correct reference.
This also means in the future we may be able to compile and execute code
with shadows, even though it will still be an error.

Closes #2343
This commit is contained in:
ayazhafiz 2022-01-22 20:29:17 -05:00
parent 632d809f2a
commit 0eede1cd86
8 changed files with 67 additions and 30 deletions

View file

@ -48,12 +48,11 @@ fn headers_from_annotation_help(
headers: &mut SendMap<Symbol, Loc<Type>>,
) -> bool {
match pattern {
Identifier(symbol) => {
Identifier(symbol) | Shadowed(_, _, symbol) => {
headers.insert(*symbol, annotation.clone());
true
}
Underscore
| Shadowed(_, _)
| MalformedPattern(_, _)
| UnsupportedPattern(_)
| NumLiteral(_, _, _)
@ -159,11 +158,11 @@ pub fn constrain_pattern(
PresenceConstraint::IsOpen,
));
}
Underscore | UnsupportedPattern(_) | MalformedPattern(_, _) | Shadowed(_, _) => {
Underscore | UnsupportedPattern(_) | MalformedPattern(_, _) => {
// Neither the _ pattern nor erroneous ones add any constraints.
}
Identifier(symbol) => {
Identifier(symbol) | Shadowed(_, _, symbol) => {
if destruct_position {
state.constraints.push(Constraint::Present(
expected.get_type_ref().clone(),