Detect and diagnose contextual failures originating in an attempt
to convert `nil` to some other non-optional type e.g.
```swift
let _: Int = nil // can't initialize `Int` with `nil`
func foo() -> Int {
return nil // can't return `nil` from `foo`
}
_ = 1 + nil // there is no `+` overload which accepts `Int` and optional
```
Each candidate with incorrect labels (but everything else lined up)
gets a note on its declarationm which says what is expected and what
has been given.
If a syntax sugared type like Array had an unresolved type, it used to print as `[_]` in diagnostics, which could be confusing.
Instead, desugar these unresolved types before printing, so Array, for example, prints as `Array<_>`.
Currently this only applies to Array, Dictionary, and Optional.
Extend use of "instance member on type" fix to cover potentially
invalid partial applications, references to instance members on
metatypes, and remove related and now obsolete code from `CSDiag`.
Resolves: [SR-9415](https://bugs.swift.org/browse/SR-9415)
Introduce a fix to detect and diagnose situations when omitted
generic arguments couldn't be deduced by the solver based on
the enclosing context.
Example:
```swift
struct S<T> {
}
_ = S() // There is not enough context to deduce `T`
```
Resolves: rdar://problem/51203824
Detect and diagnose a contextual mismatch between expected
collection element type and the one provided (e.g. source
of the assignment or argument to a call) e.g.:
```swift
let _: [Int] = ["hello"]
func foo(_: [Int]) {}
foo(["hello"])
```
Escapingness is a property of the type of a value, not a property of a function
parameter. Having it as a separate parameter flag just meant one more piece of
state that could get out of sync and cause weird problems.
Instead, always look at the noescape bit in a function type as the canonical
source of truth.
This does mean that '@escaping' is now printed in a few diagnostics where it was
not printed before; we can investigate these as separate issues, but it is
correct to print it there because the function types in question are, in fact,
escaping.
Fixes <https://bugs.swift.org/browse/SR-10256>, <rdar://problem/49522774>.
The diagnostics for `variable_never_mutated` always suggests
changing `var` to `let`, which is misleading in case of
for-each loops where explicitly immutable context applies.
This patch adds some variety to the message to make it appropriate.
Resolves: SR-9732
When the compiler fails to find an overload with suitable parameter or return types, it often attaches a note listing the available overloads so that users can find the one they meant to use. The overloads are currently ordered in a way that depends on the order they were declared, so swift-evolve would sometimes cause tests involving these diagnostics to fail.
This change emits the list in a textually-sorted order instead. The names were already being sorted as they were inserted into a std::set, so this shouldn’t significantly slow down the diagnostic.
Detect and fix situations when (force) unwrap is used on
a non-optional type, this helps to diagnose invalid unwraps
precisely and provide fix-its.
Resolves: [SR-8977](https://bugs.swift.org/browse/SR-8977)
Resolves: rdar://problem/45218255
When converting an initialization to a coercion like:
```swift
_ = Float(90)
```
the outer coercion is given the startLoc and endLoc of the CallExpr in
source.
However, once we unwrap it and pull the implicit CallExpr to
`init(_builtinIntegerLiteral:)`, we lose the original source range.
Instead, leave the outer CoerceExpr, as it's ignored in SILGen anyway.
This makes diagnostics more verbose and accurate, because
it's possible to distinguish how many parameters there are
based on the message itself.
Also there are multiple diagnostic messages in a format of
`<descriptive-kind> <decl-name> ...` that get printed as
e.g. `subscript 'subscript'` if empty labels are omitted.
We were building the following constraint, where $member and
$input are type variables and 'result' is a concrete type:
- Conversion($member, $input -> result)
When $member was fixed to a function type of arbitrary
arity, this would simplify to a conversion between $member's
result type and 'result'.
Instead, express this using the newly-added FunctionResult
constraint:
- FunctionResult($member, $result)
- Conversion($result, result)
I wasn't expecting this to change diagnostics, but it looks
like it did; I'm not going to bother investigating why,
because Pavel is going to rewrite contextual diagnostics soon
anyway. All but one are clear improvements.
Fixes <rdar://41416346> and <rdar://41416647>, two cases where
diagnostics regressed from -swift-version 3 to -swift-version 4.
Avoid claiming un-labeled defaulted parameters
by out-of-order un-labeled arguments or parts
of variadic argument sequence, because that might
be incorrect.
The following example is supposed to type-check
correctly but without these changes produces
`missing argument for parameter #4 in call`
error, because `3` will be claimed as '_ b:':
```swift
func foo(_ a: Int, _ b: Int = 0, c: Int = 0, _ d: Int) {}
foo(1, c: 2, 3)
```
Resolves: rdar://problem/43525641
Unresolved member calls e.g. `.foo(1, 2)` are unique in a way that
they don't form regular application expressions. So let's teach
`simplifyLocator` how to extract arguments from such calls
based on locators like:
`[UnresolvedMemberExpr -> apply argument -> comparing call argument # to parameter #]`.
This helps to diagnose more failures via diagnostics attached to
constraint system fixes.
If generic parameter associated with missing conformance comes
from different context diagnose the problem as "referencing" a
specific declaration from affected type.
Instead of simply pointing out which type had conformance failures,
let's use affected declaration instead, which makes diagnostics much
richer e.g.
```
'List<[S], S.Id>' requires that 'S.Id' conform to 'Hashable'
```
versus
```
initializer 'init(_🆔)' requires that 'E' conform to 'Hashable' [with 'E' = 'S.Id']
```
Since latter message uses information about declaration, it can also
point to it in the source. That makes is much easier to understand when
problem is related to overloaded (function) declarations.
...and collapse StaticVar/ClassVar and StaticLet/ClassLet into
StaticProperty/ClassProperty.
"var" and "let" aren't great nouns to use in diagnostics to begin with,
especially alongside semantic terms like "instance method". Focus on
the type vs. non-type aspect instead with "property", which better
matches how people talk about member vars (and lets) anyway.
* Improve label mismatch callback:
- Split "missing label" callback into 3 - missing, extraneous, incorrect (with typo(s));
- Allow label callbacks to indicate if it's a fatal error or not;
* Improve matching of the variadic parameters;
* Improve matching of the parameters with defaults;
* Try to look for an argument with matching label before fallback to
forced claming (if allowed).
Implementation is as follows: In `preCheckExpression` try to
detect if there is `T(literal)` call in the AST, replace it with
implicit `literal as T`, while trying to form type-checked AST,
after constraint solving, restore source information and drop
unnecessary coercion expression.
Resolves: rdar://problem/17088188
Resolves: rdar://problem/39120081
Resolves: rdar://problem/23672697
Resolves: rdar://problem/40379985
Introduce a new fix kind into the constraint solver to cover unwrapping the base
of a member access so we can refer to the a member of the unwrapped base.
Wire this fix kind to the just-added diagnostic that suggests either the
chaining ‘?’ or the force-unwrap ‘!’ via separate, descriptive Fix-Its.
Example:
error: value of optional type 'X?' must be unwrapped to refer to member 'f' of wrapped base type 'X'
let _: Int = x.f()
^
note: chain the optional using '?' to access member 'f' only for non-'nil' base values
let _: Int = x.f()
^
?
note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
let _: Int = x.f()
^
!
Before this, we would sometimes get a Fix-It for just ‘?’ and sometimes get a Fix-It for the
coalescing ‘??’, neither of which is likely to be right.
More work on rdar://problem/42081852.
Improve diagnostics when referencing a member of an optional base, where the
Optional type does not have the member but the wrapped type does. Specifically,
suggest both the chaining ‘?’ and the force-unwrapping ‘!’ Fix-Its via explanatory
notes, e.g.:
error: value of optional type '[Int]?' must be unwrapped to refer to member 'subscript' of wrapped base type '[Int]'
return foo.array[0]
^
note: chain the optional using '?' to access member 'subscript' only for non-'nil' base values
return foo.array[0]
^
?
note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
return foo.array[0]
^
!
More of rdar://problem/42081852.
When we determine that an optional value needs to be unwrapped to make
an expression type check, use notes to provide several different
Fix-It options (with descriptions) rather than always pushing users
toward '!'. Specifically, the errors + Fix-Its now looks like this:
error: value of optional type 'X?' must be unwrapped to a value of
type 'X'
f(x)
^
note: coalesce using '??' to provide a default when the optional
value contains 'nil'
f(x)
^
?? <#default value#>
note: force-unwrap using '!' to abort execution if the optional
value contains 'nil'
f(x)
^
!
Fixes rdar://problem/42081852.