* Instead of consuming 'inout' unconditionally, use backtracking to
determine it's obsolete usage of 'inout' position.
* parse '...' before '= <initializer>' because '(Int... = [1])' is more
likely than '(Int = 1 ...)'. This improves diagnostics.
Instead, just emit a deprecation warning and suggest switching to Optionals.
The old behavior caused several projects to break, so before we change
the behavior here we need to investigate whether we can mitigate most
of those breaks.
For Swift 3 / 4:
Deprecate the spelling "ImplicitlyUnwrappedOptional", emitting a warning
and suggesting "!" in places where they are allowed according to
SE-0054.
In places where SE-0054 disallowed IUOs but we continued to accept them
in previous compilers, emit a warning suggesting "Optional" or "?" as
an alternative depending on context and treat the IUO as an Optional,
noting this in the diagnostic.
For Swift 5:
Treat "ImplicitlyUnwrappedOptional" as an error, suggesting
"!" in places where they are allowed by SE-0054.
In places where SE-0054 disallowed IUOs, emit an error suggestion
"Optional" or "?" as an alternative depending on context.
We can just use parseType() everywhere instead. We already check
for non-identifier types in inheritance clauses elsewhere, and indeed
we have to anyway because an identifier type might resolve to a
type alias whose underlying type is a non-nominal type.
It doesn't look like this change made any diagnostics worse, but if
we find a case where it did, we could revert it.
We allowed them for generic parameter inheritance clauses but
not anywhere else. While arguably this has stylistic benefits,
the restriction was not enforced consistently and was mostly a
result of implementation limitations.
Lift the restriction and fix things up where needed to make them
work. This brings us closer to allowing protocols to constrain
the 'Self' type to a subclass of a class by listing the class in
the protocol's inheritance clause, which was a feature from SE-0156,
but this doesn't quite work.
Fixes <https://bugs.swift.org/browse/SR-4678> and
<rdar://problem/31785092>.
A generic signature like <T : SomeClass> would create
a subtype constraint between the type variable for T and
SomeClass. This is too loose, because a subclass existential
like 'SomeClass & SomeProto' is a subtype of SomeClass, but
cannot bind to T, because it is not representationally a
single retainable pointer.
Fixes <rdar://problem/32617814>, <https://bugs.swift.org/browse/SR-5142>.
Teach preCheckExpression() about UnresolvedSpecializeExpr
where the base is a TypeExpr.
This allows us to type check expressions like
'[Outer<T>.Inner<U>]()' by folding them down to a TypeExpr
with an array type.
This folds member access on types to a TypeExpr if the member
resolves to a nested type.
This allows [Foo.Bar]() to become an ApplyExpr of a TypeExpr,
rather than an ApplyExpr of an array literal; previously,
only [Foo]() worked.
Two cases that are still unsupported:
1) If G is a generic type and T is a generic typealias, then
G.T<X> cannot be folded to a TypeExpr, because we cannot
represent a generic typealias with an unbound generic
parent type. Such lookups remain member lookups, where
Sema first opens the base type to produce a bound generic
type G<$T0>, and then resolves the generic typealias
member on that.
2) If T is a generic parameter and X is an associated type,
T.X is not folded down to a TypeExpr either.
Fixes <rdar://problem/16849958>.
Generic type specialization is ambiguous with < and > operators.
Extend the disambiguation hack to also consider parsing a generic
parameter list if the > is followed by &.
This fixes parsing types such as 'Base<Int> & P' in expression
context.
This was added at some point with the associated type where
clause work, but it appears to be unnecessary, because all
the tests passed with this removed.
It also introduced a source compatibility issue where we
stopped accepting typealiases to protocol compositions in
protocol inheritance clauses.
Add a test for this case too, since it wasn't tested before.
Fixes <https://bugs.swift.org/browse/SR-4855>.
Previously we allowed this:
protocol HasSelf {
func foo(_: Self)
}
typealias Alias = HasSelf
But not this:
struct Outer {
typealias Alias = HasSelf
}
Lift this restriction since the new String implementation
wants to make use of it.
In an extension of a nested type, the extended type must be
fully qualified.
Also clean up the diagnostic logic a little bit and centralize
it in diagnoseUnknownType().
Fixes <https://bugs.swift.org/browse/SR-4379>.
Some messages said 'typealias' and others said 'type alias'.
Change everything to use 'type alias' consistently (except
when it's talking about the keyword itself).
Normally there is very little the type checker can conclude about
casts between existentials, because new conformances can be added
retroactively. However if the existentials are class-constrained,
we can rule out certain casts as always failing by looking at
superclass bounds.
If the -enable-experimental-subclass-existentials staging flag
is on, resolveType() now allows protocol compositions to contain
class types. It also diagnoses if a composition has more than one
superclass requirement.
Also, change diagnostics that talked about 'protocol composition'
to 'protocol-constrained type'.
Since such types can now contain a superclass constraint, it's not
correct to call them protocol composition.
"Protocol-constrained type" isn't quite accurate either because
'Any' has no protocols, and 'AnyObject' will have no protocols but
a general class constraint; but those are edge cases which won't
come up in these diagnostics.
Instead of the simple "expected identifier in declaration", the error will now read "keyword '%' cannot be used as an identifier here", and will be accompanied by a note suggesting escaping the keyword with backticks, as well as a fixit.
https://bugs.swift.org/browse/SR-3167
Fixes: https://bugs.swift.org/browse/SR-3124
"If '>' had any split token" was not really a correct condition for adding
parenthesis.
For instance:
let a:protocol<P1, P2>=someThing
We don't need parenthesis for this case:
let a:P1 & P2=someThing
On the other hand:
typealias PMetaType = protocol<P1, P2>.Type
This doesn't produce a split token, but we need the parenthesis.
typealias PMetaType = (P1 & P2).Type
The new rule is: "If the token after '>' can be any postfix TypeRepr"
(i.e. '?', '!', '.Type' or '.Protocol')
Fixes: https://bugs.swift.org/browse/SR-2843
'P1 & P2.Type' is mistakingly accepted and parsed as (meatatype (composition P1, P2))
in swift3. Now, we parse it as (composition P1, (metatype P2))
For source compatibility, reconstruct it as Swift3.
Also, this solves inconsistent behavior between type and type-expression in Swift3.
typealias T1 = P1 & P2? // was accepted as '(P1 & P2)?'
let T2 = (P1 & P2?).self // was silently accepted as 'P1' in Swift3.0
A variadic parameter of function type must be @escaping -- we cannot
reason about an array of non-escaping closures, so this was a safety
hole.
Also, attempting to define an @autoclosure variadic did not produce a
diagnostic, but would fail later on if you actually tried to do
anything with it. Let's ban this completely.
Both changes are source breaking, but impact is limited to code that
was already only marginally valid.
* [Parser] Correct a fixit to preserve the trailing content after replacing Protocol<A, B>. rdar://27992964
When migrating, we found our fixit to replace the old protocol composition syntax, namely "Protocol<A, B>",
to the new syntax, "A & B", does not preserve the trailing content after '>'. For instance, we replace "Protocol<A, B>?"
with "A & B". This patch fixes the issue by inserting whatever after '>' in the old syntax to the new
replacement string. I consider this as a hack; the root-cause fix should be in the lexer to smartly separate
'>' and '?' as two tokens instead of one.
* [test] Update existing test.