This helps to diagnose contextual mismatches like `Int? vs. Bool`
instead of suggesting to unwrap the optional which would still
produce an incorrect type.
Delay "fixing" contextual conversion failures until restriction is applied
this helps to tidy up logic for superclass and existential conversions.
Too bad we have to "fix" in `simplifyRestrictedConstraintImpl` now but
we can't really do much about that because diagnostics need both top-level
types to be useful.
In Swift 5 mode, CSGen generates a conversion constraint from
the type of OptionalTryExpr's subexpression, call it T, and
Optional<$tv> for a new type variable $tv.
When applying the solution, we would coerce the sub-expression
to T? if T was not optional, or T otherwise. This was wrong
because there's no reason that $tv is actually equal to T.
Instead, we must coerce the sub-expression to Optional<$tv>,
which is the type of the overall OptionalTryExpr.
Fixes <rdar://problem/46742002>.
Since 'try?' no longer unconditionally adds a layer of optional, converting it
to 'try!' will no longer unconditionally remove a layer of optional. So let's not
suggest it. This leads to better diagnostics anyway.
Some of these are currently failing. For example:
```swift
// expected-error {{cannot convert value of type 'Int??' to specified type 'Int'}}
let _: Int = try? producer.produceDoubleOptionalInt()
```
This actually produces this warning:
```
value of optional type 'Int?' not unwrapped; did you mean to use 'try!' or chain with '?'?
```
Note that the value in question is not an `Int?`, so a suggestion of `try!` here is inappropriate.
(And, due to the change in semantics of 'try?', wouldn't change anything anyway.)
If the sub-expression of the 'try?' is optional, the result will be the same level of optional-ness.
If the sub-expression is non-optional, the result is optional.
Thus, the following lines all end up with the same type of 'Int?'
- let x = try? 3 as Int
- let x = try? 3 as? Int
- let x = try? 3 as Int?
When calling a throwing function without 'try', let's suggest multiple
possibilities of note + fix-it for user to choose from.
Resolves: rdar://problem/33040113
What I've implemented here deviates from the current proposal text
in the following ways:
- I had to introduce a FunctionArrowPrecedence to capture the parsing
of -> in expression contexts.
- I found it convenient to continue to model the assignment property
explicitly.
- The comparison and casting operators have historically been
non-associative; I have chosen to preserve that, since I don't
think this proposal intended to change it.
- This uses the precedence group names and higherThan/lowerThan
as agreed in discussion.
along with recent policy changes:
- For expression types that are not specifically handled, make sure to
produce a general "unused value" warning, catching a bunch of unused
values in the testsuite.
- For unused operator results, diagnose them as uses of the operator
instead of "calls".
- For calls, mutter the type of the result for greater specificity.
- For initializers, mutter the type of the initialized value.
- Look through OpenExistentialExpr's so we can handle protocol member
references propertly.
- Look through several other expressions so we handle @discardableResult
better.
It's not /really/ an infix operator, but it behaves like a very low
precedence prefix operator. On the other hand, 'try' and 'try!' can
freely move in and out of all the operations we add in fix-its, so
don't bother.
rdar://problem/22259867
Swift SVN r31200
<rdar://problem/21414023> Assertion failure when compiling function that takes throwing functions and rethrows
<rdar://problem/21432429> Calling rethrows from rethrows crashes Swift compiler
<rdar://problem/21427855> Swift 2: Omitting try from call to throwing closure in rethrowing function crashes compiler
Swift SVN r29580
And for "try return", "try throw", and "try let", get even more specific,
with a fix-it to suggest moving the "try" onto the expression.
rdar://problem/21043120
Swift SVN r28862
We parse 'try' as if it were a unary operator allowed on an
arbitrary element of an expr-sequence, but sequence-folding
constrains it to never appear on the RHS of most operators.
We do allow it on the RHS of an assignment or conditional
operator, but not if there's anything to the right which
was not parsed within the RHS.
We do this for assignments so that
var x = try whatever
and
x = try whatever
both work as you might expect.
We do this for conditionals because it feels natural to
allow 'try' in the center operand, and then disallowing it
in the right operand feels very strange.
In both case, this works largely because these operators are
assumed to be very low-precedence; there are no standard
operators which would parse outside the RHS. But if you
create one and use 'try' before it, we'll diagnose it.
Swift SVN r26052