This now fails with the infamous 'Assertion failed: ((conforms ||
replacement->is<ErrorType>() || firstArchetype->getIsRecursive() ||
isOpenedAnyObject(replacement) || replacement->is<GenericTypeParamType>())
&& "Constraint system missed a conformance?")' error.
The actual problem is something with unbound generics and inference
of generic parameters. Here's a minimal test case:
protocol A {}
struct B<f> {}
func a<T:A>() {
class AA {
var t:B=B()
}
}
I'll fix it soon.
There was a weird corner case with nested generic functions that
would fail in the SIL verifier with some nonsense about archetypes
out of context.
Fix this the "right" way, by re-working Sema function declaration
validation to assign generic signatures in a more principled way.
Previously, nested functions did not get an interface type unless
they themselves had generic parameters.
This was inconsistent with methods nested inside generic types,
which did get an interface type even if they themselves did not
have a generic parameter list.
There's some spill-over in SILGen from this change. Mostly it
makes things more consistent and fixes some corner cases.
With the previous resolveTypeInContext() patch, a few compiler
crashers regressed with this problem, presumably because we were now
performing lookups in more contexts than before.
This is a class of problems where we would attempt a recursive
validation:
1) Generic signature validation begins for type T
2) Name lookup in type context finds a non-type declaration D nested in T
3) Generic signature validation begins for D
4) The outer generic context of D is T, but T doesn't have a generic
signature yet
The right way to break such cycles is to implement the iterative
decl checker design. However when the recursion is via name lookup,
we can try to avoid the problem in the first place by not validating
non-type declarations if the client requested a type-only lookup.
Note that there is a small semantic change here, where programs that
were previously rejected as invalid because of name clashes are
now valid. It is arguable if we want to allow stuff like this or not:
class A {
func A(a: A) {}
}
or
class Case {}
enum Foo {
case Case(Case)
}
However at the very least, the new behavior is better because it
gives us an opportunity to add a diagnostic in the right place
later. The old diagnostics were not very good, for example the
second example just yields "use of undeclared type 'Case'".
In other examples, the undeclared type diagnostic would come up
multiple times, or we would generate a cryptic "type 'A' used within
its own definition".
As far as I understand, this should not change behavior of any existing
valid code.
This is a big refactoring of resolveTypeInContext() which makes
the function clearer to understand by merging various special
cases and generalizing the logic for walking parent and superclass
contexts to cover more cases.
This improves typealiases in protocols a bit:
1) Previously a typealias in a protocol either had to be concrete,
or consist of a single path of member types from Self, eg
Self.A.B. Lift this restriction, so we can now write things like
protocol Fireworks {
associatedtype Exploding
typealias Exploder = Exploding -> [Exploding]
}
2) Protocol typealiases can now be accessed via qualified lookup
on concrete types. Getting this working for unqualified lookup
requires further refactorings which will be in a subsequent
patch.
This reverts commit 586288312c. It broke
tests:
Swift :: IDE/complete_override_access_control.swift
Swift :: IDE/complete_value_expr.swift
Swift :: SourceKit/DocSupport/doc_swift_module.swift
Swift :: decl/typealias/associated_types.swift
Swift :: decl/typealias/typealias.swift
Previously a typealias in a protocol either had to be concrete,
or consist of a single path of member types from Self, eg
Self.A.B. Lift this restriction.
Fix a few other corner cases that came up in the validation
suite, and clean up the function in general.
Goes back to Swift 2.2 behavior of treating the 'typealias' keyword inside a protocol as a deprecated form of an associatedtype. To get the newer (but still partly buggy) behavior of treating it as an actual typealias, add "-Xfrontend -enable-protocol-typealiases" to the compile invocation. 'decl/typealias/typealias.swift' now uses this flag to continue testing the enabled behavior.
Since there still are some holes in this feature, and I haven't had time to
fill them lately: Go back to the 2.2 behavior of treating 'typealias' keyword
in protocols as an associated type, and emit a deprecation warning.
Commented out tests specifically for typealiases in protocols for now, and
random validation tests that crash or not based on whether keyword is interpreted as associatedtype or typealias updated.
Before, a keyword in an inheritance clause would lead to a long list of errors
not really showing what was wrong.
A special case is added to handle protocol composition; in inheritance clauses
the protocols don't have to be composed with 'protocol<>'.
Initializers are inherited by synthesizing an implicit decl which
delegates to super.init(). Previously this was only done if the
class and superclass were concrete.
The only thing missing was that we weren't computing an interface
type for the synthesized constructor. There are two steps to this:
- First, we must map the contextual types of the superclass
initializer's ParamDecls to the subclass generic context.
- Second, we must set the interface type by calling the new
configureInterfaceType() method, extracted from from
validateGenericSignature().
Note that configureInterfaceType() now uses the new
AbstractFunctionDecl::hasThrows() flag to set the 'throws' bit on
the function type. Previously, validateGenericFuncSignature()
would look at getThrowsLoc().isValid(), which is not correct for
imported, implicitly-generated or de-serialized decls that 'throw',
because none of those have source location information.
We still don't allow inheriting initializers which have their
own generic parameter list, like 'init<T>(t: T) {...}'. That
requires a little bit more refactoring.
Progress on <rdar://problem/23376955>.
BoundGenericType::getSubsitutions() would only look at the bound
generic arguments of the innermost type, ignoring parent types.
However, it would then proceed to walk the AllArchetypes list
of all outer generic parameter lists when forming the final
result.
The gatherAllSubstitutions() would also walk through parent types.
As a result, outer generic parameters would appear multiple
times.
Simplify gatherAllSubstitutions() to just skip to the innermost
BoundGenericType, and delegate to getSubsitutions() for the rest.
Most calls to gatherAllSubstitutions() are from SILGen it seems,
and fix only fixes one compiler_crasher.
However an upcoming patch adds a new call to gatherAllSubstitutions()
which caused some crashers to regress, so I'm going to fix it
properly here.
This particular crasher very rarely didn't crash, causing mayhem with
false failures on the builders.
We were keeping a reference to a vector that could be reallocated in a
recursive call back into the same function. Instead, tend towards
looking up the vector in the map each time we need it.
Don’t try to find a conformation witness for typealias declarations in
protocols.
Fixed a bug with same type constraint between an alias and a concrete
type - just a bad assumption on my part. Added test for that.
Made archetype builder more resilient in constructing PA trees: it will
work correctly now if the alias destination is a dependent member type
instead of an archetype type. It also handles the case of finding
multiple aliases with the same name along with an associatedtype with
that name, fixing up all the representative ptrs.
Extensions/Nominals that tried to use a protocol's typealias would get a
dependent type as resolved with the protocol's base instead of with the 'Self'
base type of the current extension/nominal, resulting in spurious conformance
failures. So resolve aliases to protocol assoctypes based on the 'Self'
in which they are used.
Also fixed tests to not use common stdlib names, added tests for
typealias in protocol extension and self & recursive aliases. One recent
crasher also fixed.