Neither of the following is supported:
func g<T>(_: T) {
_ = {
struct S {}
}
}
struct G<T> {
let fn = {
struct S {}
}
}
Even though nested generic types are supported, the second example
is more like a type inside a function than a type inside a type,
because 'S' has no parent type.
Technically this is source-breaking but since neither SILGen nor
IRGen knew how to generate code for these I doubt anything worked.
There's no need to walk up from a function or type context -- if
no generic signature (or environment) is set, the parent won't have
one, either, and if we're in the middle of validating the child
context, using the parent's signature or environment to resolve
dependent types is just wrong.
If one of the associated types is witnessed by a generic parameter
from the function's scope, make sure it maps down to an ErrorType
instead of leaving it as a type parameter, which triggers an
assertion.
Eventually we'll plumb it through properly.
We would falsely diagnose the occurrence of the protocol
_in the inheritance clause_ as a "bad" usage of an
existential type, because the UnsupportedProtocolVisitor
was too eager in walking into nested Decls and Stmts.
Note that in one case we don't emit a diagnostic where we
did before, but this doesn't matter; the VarDecl in
question becomes invalid later, and only the order in
which the decls are visited changes.
This patch contains several intertwined changes:
- Remove some unnecessary complexity and duplication.
- Adds a new TypeChecker::lookupUnqualifiedType() which bypasses most of
the logic in TypeChecker::lookupUnqualified(), such as the
LookupResultBuilder. Use this when resolving unqualified references
to types.
- Fixes for generic typealiases to better preserve the type parameters of
the parent type, and clean up the logic for applying the inner generic
arguments. Some uses of generic typealiases that used to crash now work,
and those tests have been uncommented.
- Avoid an unnecessary desugaring of TypeAliasDecls which map directly
to GenericTypeParamTypes. Once again this perturbs the source-stability
test.
- When looking up a nested type of a base class with a derived class base,
always use the base class as the parent of the nested type. This fixes
a recent regression where in some cases we were using the wrong parent.
Fixes <rdar://problem/29782186>.
and provide a fix-it to move it to the new location as referenced
in SE-0081.
Fix up a few stray places in the standard library that is still using
the old syntax.
Update any ./test files that aren't expecting the new warning/fix-it
in -verify mode.
While investigating what I thought was a new crash due to this new
diagnostic, I discovered two sources of quite a few compiler crashers
related to unterminated generic parameter lists, where the right
angle bracket source location was getting unconditionally set to
the current token, even though it wasn't actually a '>'.
trying to set the superclass on classes in such situations by setting the superclass of an invalid decl to the error type.
This fixes a bunch of compiler crashes, and also changes some errors in other tests where the main error is the invalid declaration and now the
downstream errors can be a bit different because the decl has been invalidated.
Consider this code:
struct A<T> {
struct B {}
struct C<U> {}
}
Previously:
- getDeclaredType() of 'A.B' would give 'A<T>.B'
- getDeclaredTypeInContext() of 'A.B' would give 'A<T>.B'
- getDeclaredType() of 'A.C' would give 'A<T>.C'
- getDeclaredTypeInContext() of 'A.C' would give 'A<T>.C<U>'
This was causing problems for nested generics. Now, with this change,
- getDeclaredType() of 'A.B' gives 'A.B' (*)
- getDeclaredTypeInContext() of 'A.B' gives 'A<T>.B'
- getDeclaredType() of 'A.C' gives 'A.C' (*)
- getDeclaredTypeInContext() of 'A.C' gives 'A<T>.C<U>'
(Differences marked with (*)).
Also, this change makes these accessors fully lazy. Previously,
only getDeclaredTypeInContext() and getDeclaredIterfaceType()
were lazy, whereas getDeclaredType() was built from validateDecl().
Fix a few spots where the return value wasn't being checked
properly.
These functions return ErrorType if a circularity was detected via
the generic parameter list, or if the extension did not resolve.
They return Type() if the extension cannot be resolved *yet*.
This is pretty subtle, and I'll need to do another pass over
callers of these functions at some point. Many of them should be
moved over to use getSelfInContext(), getSelfOfContext() and
getSelfInterfaceType() instead.
Finally, this patch consolidates logic for diagnosting invalid
nesting of types.
The parser had some code for protocols in bad places and bad things
inside protocols, and Sema had several different bail-outs for
bad things in protocols, nested generic types, and stuff nested
inside protocol extensions.
Combine all of these into a single set of checks in Sema. Note
that we no longer give up early if we find invalid nesting.
Leaving decls unvalidated and un-type-checked only leads to
further problems. Now that all the preliminary crap has been
fixed, we can go ahead and start validating these funny nested
decls, actually fixing some crashers in the process.