We had four duplicated implementations of checking how a protocol
requirement uses 'Self', all slightly wrong or incomplete:
- When deciding if the protocol type can be used as an existential.
This one would just ignore 'Self' in the return type of a method
completely, which was incorrect for cases where 'Self' is
contravariant but part of the return value, for example:
func foo() -> (Self -> ())
- When deciding if a member access can be performed on an existential
value. This is distinct from the former, because the member may
have been defined in a protocol extension, in which case it cannot
be used even if the protocol type can be used as an existential.
Unfortunately, this implementation was overly conservative, and
would reject uses of 'Self' where Sema could in fact erase the
existential type, for example:
func foo() -> Self??
func foo() -> Self.Type
func foo() -> (Self, Self)
This function handled function return types correctly, effectively
plugging the leak in the previous code. It did lead to inconsistent
behavior with protocols that had contravariant Self in requirements
though; sometimes we would diagnose uses of the existential type,
other times we would only complain about specific members.
- When deciding if a method in a non-final class can model a protocol
requirement. This one was the most elaborate one, but here
contravariance and uses of associated types are actually okay, so
it was written to pick up covariant 'Self' only. However, it also
did not handle metatypes and tuples.
- When opening the type of member of an existential, we would check
if the return value was 'Self' or an optional of 'Self', but again
this check was too conservative, so after the previous three were
fixed, we could reference members on existentials that did not
have a correct opened type.
Now, these have been combined into one check. To fix some crashes,
Sema's implementation of erasing existentials now relies on
coerceToType() instead of hand-rolling a few coercions of its own,
and wrapping the rest in CovariantFunctionConversionExpr, which
didn't make much sense if the result was not a function type.
SILGen still does not support function type conversions where an
existential return value is being erased; these would silently
miscompile before, but crash with an assertion now, because they
are correctly modeled as a FunctionConversionExpr, and not
CovariantFunctionConversionExpr.
This removes the totally lame diagnostic telling the user to wrap
their function in a closure.
Some exotic Objective-C metatype to AnyObject conversions are still
missing, and there aren't any executable tests yet. Both will be
addressed soon.
Swift SVN r31527
we process contextual constraints when producing diagnostic. Formerly,
we would aggressively drop contextual type information on the floor under
the idea that it would reduce constraints on the system and make it more
likely to be solvable. However, this also has the downside of introducing
ambiguity into the system, and some expr nodes (notably closures) cannot
usually be solved without that contextual information.
In the new model, expr diagnostics are expected to handle the fact that
contextual information may be present, and bail out without diagnosing an
error if that is the case. This gets us more information into closures,
allowing more specific return type information, e.g. in the case in
test/expr/closure/closures.swift.
This approach also produces more correct diagnostics in a bunch of other
cases as well, e.g.:
- var c = [:] // expected-error {{type '[_ : _]' does not conform to protocol 'DictionaryLiteralConvertible'}}
+ var c = [:] // expected-error {{expression type '[_ : _]' is ambiguous without more context}}
and the examples in test/stmt/foreach.swift, test/expr/cast/as_coerce.swift,
test/expr/cast/array_iteration.swift, etc.
That said, this another two steps forward, one back thing. Because we
don't handle propagating sametype constraints from results of calls to their
arguments, we regress a couple of (admittedly weird) cases. This is now
tracked by:
<rdar://problem/22333090> QoI: Propagate contextual information in a call to operands
There is also the one-off narrow case tracked by:
<rdar://problem/22333281> QoI: improve diagnostic when contextual type of closure disagrees with arguments
Swift SVN r31319
argument. For now we start with some of the most simple cases: single argument
calls. This dramatically improves the QoI for error messages in argument lists,
typically turning a error+note combo into a single specific error message.
Some minor improvements coming (and also generalizing this to n-ary calls), but it
is nice that all the infrastructure is starting to come together...
Swift SVN r30905
fixing <rdar://problem/22020088> QoI: missing member diagnostic on optional gives worse error message than existential/bound generic/etc
Swift SVN r30844
This covers:
- Lifetime-extending wrappers, like withExtendedLifetime, withCString, and withUnsafe*Pointer
- 'map' and friends on Optional
- 'indexOf'
A few APIs I haven't gotten to yet in this first pass:
- Autoclosure APIs, like assert, &&, etc.
- the 'isOrderedBefore' predicate for sorting APIs. The sorting implementation does some microoptimizations with 'inout' closures that violate rethrows checking.
- Strict 'map', 'filter', and friends on CollectionType. These need some plumbing in Lazy to be able to thread a Result-forming transformation through.
This version of the patch updates some protocol customization implementations that I missed the first time around, and includes the tests I forgot to add in the previous iteration.
Swift SVN r30790
"unavoidable failure" path, along with Failure::DoesNotHaveNonMutatingMember and
just doing some basic disambiguation in CSDiags.
This provides some benefits:
- Allows us to plug in much more specific diagnostics for the existing "only has
mutating members" diagnostic, including producing notes for why the base expr
isn't mutable (see e.g. test/Sema/immutability.swift diffs).
- Corrects issues where we'd drop full decl name info for selector references.
- Wordsmiths diagnostics to not complain about "values of type Foo.Type" instead
complaining about "type Foo"
- Where before we would diagnose all failures with "has no member named", we now
distinguish between when there is no member, and when you can't use it. When you
can't use it, you get a vauge "cannot use it" diagnostic, but...
- This provides an infrastructure for diagnosing other kinds of problems (e.g.
trying to use a private member or a static member from an instance).
- Improves a number of cases where failed type member constraints would produce uglier
diagnostics than a different constraint failure would.
- Resolves a number of rdars, e.g. (and probably others):
<rdar://problem/20294245> QoI: Error message mentions value rather than key for subscript
Swift SVN r30715
get the same wording, fixing <rdar://problem/21964599> Different diagnostics for the same issue
While I'm in the area, remove some dead code.
Swift SVN r30713
which we have a contextual type that was the failure reason. These are a bit
longer but also more explicit than the previous diagnostics.
Swift SVN r30669
conversion failures, making a bunch of diagnostics more specific and useful.
UnavoidableFailures can be very helpful, but they can also be the first constraint
failure that the system happened to come across... which is not always the most
meaningful one. CSDiag's expr processing machinery has a generally better way of
narrowing down which ones make the most sense.
Swift SVN r30647
This covers:
- Lifetime-extending wrappers, like withExtendedLifetime, withCString, and withUnsafe*Pointer
- 'map' and friends on Optional
- 'indexOf'
A few APIs I haven't gotten to yet in this first pass:
- Autoclosure APIs, like assert, &&, etc.
- the 'isOrderedBefore' predicate for sorting APIs. The sorting implementation does some microoptimizations with 'inout' closures that violate rethrows checking.
- Strict 'map', 'filter', and friends on CollectionType. These need some plumbing in Lazy to be able to thread a Result-forming transformation through.
Swift SVN r30597
lvalues when compiling list of partial-match overloads in diagnosis.
(This is a reapplication of commits r29462 and r29469.)
Also, fix the following tests:
stdlib/FixedPointDiagnostics.swift.gyb
stdlib/NumericDiagnostics.swift.gyb
<rdar://problem/17875634> can't append to array of tuples
Swift SVN r29493
This reverts commit r29462 because it looks like it breaks the following
tests:
Swift :: stdlib/FixedPointDiagnostics.swift.gyb
Swift :: stdlib/NumericDiagnostics.swift.gyb
Swift SVN r29484
This post-hoc diagnostic replaces r24915, r25045, and r25054 by doing a
very basic check for representation incompatibility between two types.
More cases can be added as necessary.
rdar://problem/19600325, again.
Swift SVN r25117
This re-applies r24987, reverted in r24990, with a fix for a spuriously-
introduced error: don't use a favored constraint in a disjunction to avoid
applying a fix. (Why not? Because favoring bubbles up, i.e. the
/disjunction/ becomes favored even if the particular branch is eventually
rejected.) This doesn't seem to affect the outcome, though: the other
branch of the disjunction doesn't seem to be tried anyway.
Finishes rdar://problem/19600325
Swift SVN r25054
And even if we don't suggest wrapping in a closure (say, because there's
already a closure involved), emit a more relevant diagnostic anyway.
(Wordsmithing welcome.)
Wrapping a function value in a closure essentially explicitly inserts a
conversion thunk that we should eventually be able to implicitly insert;
that's rdar://problem/19517003.
Part of rdar://problem/19600325
Swift SVN r24987
These haven't ever been safe in Swift's development because they require
generating thunks, and we currently don't do that. However, we were letting
existential conversions slip through the cracks because we consider them
subtypes, so that /metatype/ conversions work correctly. To be concrete:
"let _: Any.Type = Int.self" is okay.
"let _: (Int) -> Void = { (_: Any) -> Void in return }" is not.
We should implement this some day; that's rdar://problem/19517003.
This produces some lousy error messages, which I intend to fix soon.
Part of rdar://problem/19600325
Swift SVN r24915
Most tests were using %swift or similar substitutions, which did not
include the target triple and SDK. The driver was defaulting to the
host OS. Thus, we could not run the tests when the standard library was
not built for OS X.
Swift SVN r24504
These changes make the following improvements to how we generate diagnostics for expression typecheck failure:
- Customizing a diagnostic for a specific expression kind is as easy as adding a new method to the FailureDiagnosis class,
and does not require intimate knowledge of the constraint solver’s inner workings.
- As part of this patch, I’ve introduced specialized diagnostics for call, binop, unop, subscript, assignment and inout
expressions, but we can go pretty far with this.
- This also opens up the possibility to customize diagnostics not just for the expression kind, but for the specific types
involved as well.
- For the purpose of presenting accurate type info, partially-specialized subexpressions are individually re-typechecked
free of any contextual types. This allows us to:
- Properly surface subexpression errors.
- Almost completely avoid any type variables in our diagnostics. In cases where they could not be eliminated, we now
substitute in "_".
- More accurately indicate the sources of errors.
- We do a much better job of diagnosing disjunction failures. (So no more nonsensical ‘UInt8’ error messages.)
- We now present reasonable error messages for overload resolution failures, informing the user of partially-matching
parameter lists when possible.
At the very least, these changes address the following bugs:
<rdar://problem/15863738> More information needed in type-checking error messages
<rdar://problem/16306600> QoI: passing a 'let' value as an inout results in an unfriendly diagnostic
<rdar://problem/16449805> Wrong error for struct-to-protocol downcast
<rdar://problem/16699932> improve type checker diagnostic when passing Double to function taking a Float
<rdar://problem/16707914> fatal error: Can't unwrap Optional.None…Optional.swift, line 75 running Master-Detail Swift app built from template
<rdar://problem/16785829> Inout parameter fixit
<rdar://problem/16900438> We shouldn't leak the internal type placeholder
<rdar://problem/16909379> confusing type check diagnostics
<rdar://problem/16951521> Extra arguments to functions result in an unhelpful error
<rdar://problem/16971025> Two Terrible Diagnostics
<rdar://problem/17007804> $T2 in compiler error string
<rdar://problem/17027483> Terrible diagnostic
<rdar://problem/17083239> Mysterious error using find() with Foundation types
<rdar://problem/17149771> Diagnostic for closure with no inferred return value leaks type variables
<rdar://problem/17212371> Swift poorly-worded error message when overload resolution fails on return type
<rdar://problem/17236976> QoI: Swift error for incorrectly typed parameter is confusing/misleading
<rdar://problem/17304200> Wrong error for non-self-conforming protocols
<rdar://problem/17321369> better error message for inout protocols
<rdar://problem/17539380> Swift error seems wrong
<rdar://problem/17559593> Bogus locationless "treating a forced downcast to 'NSData' as optional will never produce 'nil'" warning
<rdar://problem/17567973> 32-bit error message is really far from the mark: error: missing argument for parameter 'withFont' in call
<rdar://problem/17671058> Wrong error message: "Missing argument for parameter 'completion' in call"
<rdar://problem/17704609> Float is not convertible to UInt8
<rdar://problem/17705424> Poor error reporting for passing Doubles to NSColor: extra argument 'red' in call
<rdar://problem/17743603> Swift compiler gives misleading error message in "NSLayoutConstraint.constraintsWithVisualFormat("x", options: 123, metrics: nil, views: views)"
<rdar://problem/17784167> application of operator to generic type results in odd diagnostic
<rdar://problem/17801696> Awful diagnostic trying to construct an Int when .Int is around
<rdar://problem/17863882> cannot convert the expression's type '()' to type 'Seq'
<rdar://problem/17865869> "has different argument names" diagnostic when parameter defaulted-ness differs
<rdar://problem/17937593> Unclear error message for empty array literal without type context
<rdar://problem/17943023> QoI: compiler displays wrong error when a float is provided to a Int16 parameter in init method
<rdar://problem/17951148> Improve error messages for expressions inside if statements by pre-evaluating outside the 'if'
<rdar://problem/18057815> Unhelpful Swift error message
<rdar://problem/18077468> Incorrect argument label for insertSubview(...)
<rdar://problem/18079213> 'T1' is not identical to 'T2' lacks directionality
<rdar://problem/18086470> Confusing Swift error message: error: 'T' is not convertible to 'MirrorDisposition'
<rdar://problem/18098995> QoI: Unhelpful compiler error when leaving off an & on an inout parameter
<rdar://problem/18104379> Terrible error message
<rdar://problem/18121897> unexpected low-level error on assignment to immutable value through array writeback
<rdar://problem/18123596> unexpected error on self. capture inside class method
<rdar://problem/18152074> QoI: Improve diagnostic for type mismatch in dictionary subscripting
<rdar://problem/18242160> There could be a better error message when using [] instead of [:]
<rdar://problem/18242812> 6A1021a : Type variable leaked
<rdar://problem/18331819> Unclear error message when trying to set an element of an array constant (Swift)
<rdar://problem/18414834> Bad diagnostics example
<rdar://problem/18422468> Calculation of constant value yields unexplainable error
<rdar://problem/18427217> Misleading error message makes debugging difficult
<rdar://problem/18439742> Misleading error: "cannot invoke" mentions completely unrelated types as arguments
<rdar://problem/18535804> Wrong compiler error from swift compiler
<rdar://problem/18567914> Xcode 6.1. GM, Swift, assignment from Int64 to NSNumber. Warning shown as problem with UInt8
<rdar://problem/18784027> Negating Int? Yields Float
<rdar://problem/17691565> attempt to modify a 'let' variable with ++ results in typecheck error about @lvalue Float
<rdar://problem/17164001> "++" on let value could give a better error message
Swift SVN r23782
The old ones were:
- print/println
- printAny
- printf
- Console
The new printing story is just print/println. Every object can be printed.
You can customize the way it is printed by adopting Printable protocol. Full
details in comments inside stdlib/core/OutputStream.swift.
Printing is not completely finished yet. We still have ReplPrintable, which
should be removed, string interpolation still uses String constructors, and
printing objects that don't conform to Printable will result in printing
mangled names.
Swift SVN r18001
difference is that a concrete type's conformance to an existential
type is considered a conversion (but not a subtyping). Relationships
between two existential types are (non-trivial) subtyping relationships.
Swift SVN r2718