When @objc inference was extended to look at the conformances of
superclasses, the code that diagnosed near misses was not similarly
updated, so we could end up producing a near-miss diagnostic on a
declaration that was already a witness to another protocol. Use the
same witness-finding logic that we use for @objc inference so this
doesn't happen again.
Fixes the rest of rdar://problem/27348369
In most places where we were checking "is<ErrorType>()", we now mean
"any error occurred". The few exceptions are in associated type
inference, code completion, and expression diagnostics, where we might
still work with partial errors.
This was causing us to emit diagnostics talking about τ_m_n, which is
not helpful.
Now that generic function types print sanely, print them in a few
places where we were previously printing PolymorphicFunctionTypes.
When checking a conformance of a concrete type to a protocol, we
effectively checked the associated types twice -- once when
deriving them, and another time at the end, where we performed
a substitution of the protocol 'Self' type to the concrete type.
The latter checked superclass constraints, while the former did not.
However, this trick no longer works with minimized generic
signatures, because <P : Self> no longer has redundant requirements
for the associated types of 'P'.
Instead, check superclass constraints at the same time as checking
conformances.
* If current context is extension of non-final class, don't suggest stub
* If current context is extension of final class, insert 'convenience'
* If current context is direct definition of non-final class, insert 'required'
This fixes several issues:
- By default parent types of alias types are not printed which results in
- Erroneous fixits, for example when casting to 'Notification.Name' from a string, which ends up adding erroneous cast
as "Name(rawValue: ...)"
- Hard to understand types in code-completion results and diagnostics
- When printing with 'fully-qualified' option typealias types are printed erroneously like this "<PARENT>.Type.<TYPEALIAS>"
The change make typealias printing same as nominal types and addresses the above.
One minor revision: this lifts the proposed restriction against
overriding a non-open method with an open one. On reflection,
that was inconsistent with the existing rule permitting non-public
methods to be overridden with public ones. The restriction on
subclassing a non-open class with an open class remains, and is
in fact consistent with the existing access rule.
To each note with a protocol requirement that is not met, a fixit is
added that inserts a stub for the requirement at the start of the
adoptee's declaration.
Allow 'static' (or, in classes, final 'class') operators to be
declared within types and extensions thereof. Within protocols,
require operators to be marked 'static'. Use a warning with a Fix-It
to stage this in, so we don't break the world's code.
Protocol conformance checking already seems to work, so add some tests
for that. Update a pile of tests and the standard library to include
the required 'static' keywords.
There is an amusing name-mangling change here. Global operators were
getting marked as 'static' (for silly reasons), so their mangled names
had the 'Z' modifier for static methods, even though this doesn't make
sense. Now, operators within types and extensions need to be 'static'
as written.
This is a follow-up to the change that allowed one to omit @objc (or
the name in an @objc) when it can be inferred by matching a
requirement. There is no point in suggesting that one add @objc if it
will be inferred anyway, since it's just syntactic noise.
Use the diagnostics machinery of the protocol conformance checker to
say why each near-miss actually missed, e.g., a type conflict. This
gives better information regarding how to fix the actual problem. Yet
more QoI for rdar://problem/25159872.
The differences between Swift 2 and Swift 3 names can be very
significant, when the Swift 2 names have a lot of restated type
information. These differences end up disabling the near-miss
heuristics because the magnitude of the change is so high. Therefore,
apply the omit-needless-words heuristics to the potential witness and
the requirement before scoring them.
Should finish up rdar://problem/25159872 for real.
The Grand API Renaming tends to split long base names into a shorter
base name + first argument label. To account for this in near-miss
checking, consider the base name + first argument label as a unit.
It's a common mistake to mistype a declaration that is intended to
satisfy an optional requirement. In such "near misses", we want to
warn about the mistake and give the user options to either fix the
declaration or suppress the warning. Approach this problem be walking
over all of the members of each nominal type declaration or extension
therefore and looking to see if there are any members remaining that
(1) are similarly-named to an unfilfilled optional requirement of a
protocol whose conformance is attributed to that nominal type
declaration or extension,
(2) are not witnesses to another optional requirement,
(3) haven't explicitly suppressed the warning (e.g., by adding
explicit "private" or explicit "@nonobjc"), and
(4) have a useful suppression mechanism.
In addition to the suppression mechanisms described in (3), one can
suppress this warning by moving the declaration to an(other)
extension. This encourages a programming style where one breaks an
interface into extensions each implement conformance to one
protocol. Note that we encode the various cases where one cannot move
the declaration to another extension (e.g., one cannot move a
designated initializer or stored property out of a class declaration)
and suppress the warning when there's no way for the user to cope with
it.
Each warning produced by this diagnostic can have a bunch of notes on
it for various courses of action. For example:
t2.swift:7:14: warning: instance method 'doSomething(z:)' nearly
matches optional requirement 'doSomething(x:)' of protocol 'P1'
@objc func doSomething(z: Double) { }
^
t2.swift:7:14: note: rename to 'doSomething(x:)' to satisfy this
requirement
@objc func doSomething(z: Double) { }
^
x
t2.swift:7:14: note: move 'doSomething(z:)' to an extension to silence
this warning
@objc func doSomething(z: Double) { }
^
t2.swift:7:14: note: make 'doSomething(z:)' private to silence this
warning
@objc func doSomething(z: Double) { }
^
private
t2.swift:2:17: note: requirement 'doSomething(x:)' declared here
optional func doSomething(x: Int)
^
It's a *lot* of detail, but is intended to cover the various choices
available to the user: Fix-It to the names of the requirement (for
naming-related mistakes) or suppress via various mechanisms. Combining
notes means losing Fix-Its, while dropping notes can lead users to
non-optimal solutions.
This is more of rdar://problem/25159872.
When checking for permitted uses of Self in the input type of a
protocol requirement's function type, if the parameter itself was
a function we would recurse into its input, and reject all uses
of Self in the parameter type's result. This was the wrong way
around, and in fact we should recurse into the result.
Here is a test case that used to compile successfully and crash;
now it is rejected by the type checker:
protocol P {
func f(a: Self -> ())
}
protocol Q : P {
func g()
}
class C : P {
func f(a: C -> ()) { // should not be allowed to witness P.f
a(C())
}
}
class B : C, Q {
var x: Int = 17
func g() {
print(x)
}
}
func f<T : Q>(t: T) {
// T == B here
// t.f has type <T : Q> (T -> ()) -> ()
t.f({ $0.g() }) // but at runtime, $0 is a C not a B
}
f(B())
Adds an associatedtype keyword to the parser tokens, and accepts either
typealias or associatedtype to create an AssociatedTypeDecl, warning
that the former is deprecated. The ASTPrinter now emits associatedtype
for AssociatedTypeDecls.
Separated AssociatedType from TypeAlias as two different kinds of
CodeCompletionDeclKinds. This part probably doesn’t turn out to be
absolutely necessary currently, but it is nice cleanup from formerly
specifically glomming the two together.
And then many, many changes to tests. The actual new tests for the fixits
is at the end of Generics/associated_types.swift.
As of r31224, we tried to suppress redundant protocol-conformance
diagnostics for witnesses that look like they could have matched
something in an unconstrained protocol extension. However, this was
allowing ill-formed conformances to be accepted, causing a crash in
the AST verifier. Fixes rdar://problem/23033862.
Swift SVN r32671
Cleans up AST printing somewhat as well as providing slightly better
type-to-declaration mappings for annotated AST printing and indexing.
Swift SVN r32420
(Specifically, unconstrained extensions.)
This removes the problem where trying to conform to a protocol spits out
a dozen errors about missing requirements in a base protocol, but eleven
of them have a sensible default implementation with no constraints. This
is "P6" in the test cases; the others all passed before.
There's still plenty more work in this space. In particular, if an
associated type is missing we just give up rather than encouraging people
to provide the members it would be inferred from.
Swift SVN r31224
- Have DiagnosticEngine produce "aka" annotations for sugared types.
- Fix the "optional type '@lvalue C?' cannot be used as a boolean; test for '!= nil' instead"
diagnostic to stop printing @lvalue noise.
This addresses:
<rdar://problem/19036351> QoI: Print minimally-desugared 'aka' types like Clang does
Swift SVN r30587
Instead of requiring the user to disambiguate where an implied
protocol conformance goes---which they really, really don't care
about---just pick an arbitrary-but-deterministic location for the
conformance, which corresponds to the file unit in which the witness
table will be emitted. Fixes rdar://problem/21538899.
Swift SVN r30168
We were doing piecemeal checking of the requirements of specific
associated type bindings, but such checking is incomplete: superclass
constraints and, although currently inexpressible, same-type
constraints are not validated by these early checks, so this is more
correct and more robust.
Swift SVN r29808
This means that we prefer conformances implied by explicit
conformances (ones that the user wrote) over conformances implied by
synthesized conformances (those that the compiler would
generate). This resolves the ambiguity causing rdar://problem/21007417.
Swift SVN r28880
This may not be the right solution. Even if it is, there are SourceKit tests
that need updating.
This reverts commit r28849 / rdar://problem/21007417.
Swift SVN r28852
Previously, we'd warn on this code:
enum Suit { case Spades, Hearts, Clubs, Diamonds }
extension Suit : Comparable {}
func <(...) {...}
because both Comparable and the synthesized conformance to Hashable imply
a conformance to Equatable. However, that's silly: Suit already has a
synthesized conformance to Equatable associated with the main 'enum'
declaration, not the extension. These compiler-provided conformances are
part of the language and something people rely on, so rank them higher than
conformances implied by conforming to a refined protocol.
rdar://problem/21007417
Swift SVN r28849
var/let bindings to _ when they are never used, and use some values that
are only written. This is a testsuite cleanup, NFC. More to come.
Swift SVN r28406
Inference of type witnesses for associated types was previously
implemented as part of value witness matching in the constraint
solver. This led to a number of serious problems, including:
- Recursion problems with the solver hunting for a type witness,
which triggers more attemts to match value witnesses...
- Arbitrarily crummy attempts to break the recursion causing
type-check failures in fun places.
- Ordering dependencies abound: different results depending on which
value witnesses were satisfied first, failures because of the order
in which we attempted to infer type witnesses, etc.
This new implementation of type witness inference uses a separate pass
that occurs whenever we're looking for any type witness, and solves
all of the type witnesses within a given conformance
simultaneously. We still look at potential value witnesses to infer
type witnesses, but we match them structurally, without invoking the
constraint solver.
There are a few caveats to this implementation:
* We're not currently able to infer type witnesses from value
witnesses that are global operators, so some tricks involving global
operators (*cough* ~> *cough*) might require some manually-specified
type witnesses. Note that the standard library doesn't include any
such cases.
* Yes, it's another kind of solver. At simple one, fortunately.
On the other hand, this implementation should be a big step forward:
* It's far more predictable, order-invariant, and non-recursive.
* The diagnostics for failures to infer type witnesses have
improved.
Fixes rdar://problem/20598513.
Swift SVN r27616
(Note that this registry isn't fully enabled yet; it's built so that
we can test it, but has not yet taken over the primary task of
managing conformances from the existing system).
The conformance registry tracks all of the protocols to which a
particular nominal type conforms, including those for which
conformance was explicitly specified, implied by other explicit
conformances, inherited from a superclass, or synthesized by the
implementation.
The conformance registry is a lazily-built data structure designed for
multi-file support (which has been a problematic area for protocol
conformances). It allows one to query for the conformances of a type
to a particular protocol, enumerate all protocols to which a type
conforms, and enumerate all of the conformances that are associated
with a particular declaration context (important to eliminate
duplicated witness tables).
The conformance registry diagnoses conflicts and ambiguities among
different conformances of the same type to the same protocol. There
are three common cases where we'll see a diagnostic:
1) Redundant explicit conformance of a type to a protocol:
protocol P { }
struct X : P { }
extension X : P { } // error: redundant explicit conformance
2) Explicit conformance to a protocol that collides with an inherited
conformance:
protocol P { }
class Super : P { }
class Sub : Super, P { } // error: redundant explicit conformance
3) Ambiguous placement of an implied conformance:
protocol P1 { }
protocol P2 : P1 { }
protocol P3 : P1 { }
struct Y { }
extension Y : P2 { }
extension Y : P3 { } // error: ambiguous implied conformance to 'P1'
This happens when two different explicit conformances (here, P2 and
P3) placed on different declarations (e.g., two extensions, or the
original definition and other extension) both imply the same
conformance (P1), and neither of the explicit conformances imply
each other. We require the user to explicitly specify the ambiguous
conformance to break the ambiguity and associate the witness table
with a specific context.
Swift SVN r26067