Now, when we have two aliases like
```
T a : [ A, B (U a) ]
U a : [ C, D (T a) ]
```
during the first pass, we simply canonicalize them but add neither to
the scope. This means that `T` will not be instantiated in the
definition of `U`. Only in the second pass, during correction, do we
instantiate both aliases **independently**:
```
T a : [ A, B [ C, D (T a) ] ]
U a : [ C, D [ A, B (U a) ] ]
```
and now we can mark each recursive, individually:
```
T a : [ A, B [ C, D <rec1> ] ] as <rec1>
U a : [ C, D [ A, B <rec2> ] ] as <rec2>
```
This means that the surface types shown to users might be a bit larger,
but it has the benefit that everything needed to understand a layout of
a type in later passes is stored on the type directly, and we don't need
to keep alias mappings.
Since we sort by connected components, this should be complete.
Closes#2458
I was hoping to add nested datatypes into the language, but it turns out
doing so is quite tricky and not all that useful with Roc's current
compilation model. Basically every implementation strategy I could think
of ended up requiring a uniform representation for the data layout
(or some ugly workaround). Furhermore it increased the complexity of the
checker/mono IR generator a little bit - basically, we must always pass
around the alias definitions of nested datatypes and instantiate them
at usage sites, rather than being able to unroll aliases as we currently
do during canonicalization.
So, especially because we don't support polymorphic recursion anyway, I
think it may be better to simply disallow any kind of nested datatypes
in the language. In any case, Stephanie Weirich [seems to think nested
datatypes are not needed](https://www.cis.upenn.edu/~plclub/blog/2020-12-04-nested-datatypes/).
Closes#2293
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