Lifetime indices are never necessary in Swift, they unnecessarily expose
implementation details, and they make lifetime annotations more error-prone,
since they may need to be updated if a function's parameter list changes.
The Swift Syntax parser also cannot handle lifetime annotations where the target
is an index. The main reason the C++ parser supports them is because it is also
used for SIL.
This optimizes for the case where we have a disjunction that contains an
operator defined in a protocol, and a protocol defined in a protocol
extension, and furthermore, the protocol extension operator's type is a
refinement of the protocol requirement operator's type.
In this case, there are three possibilities:
- Either the operator requirement is witnessed by a concrete operator
in the conforming type, in which case the solution involving the
protocol extension operator is going to be worse, so we can skip this
choice.
- Otherwise, the protocol requirement operator is witnessed by the same
protocol extension operator that we skipped, in which case we will find
the same solution if we just pick the protocol requirement operator
anyway.
- The only other possibility is that the protocol requirement operator
is witnessed by a protocol extension operator, but also, a more
refined protocol extension operator exists. However, it appears that in
this case, solution ranking _also_ picks the solution involving the
protocol requirement operator, as the new test case demonstrates.
Thus, we gain nothing by considering these protocol extension operators.
Skip them when forming the disjunction.
For now, we write `read`/`modify` to .swiftinterface files
so they can be read by the draft implementation in current
compilers. Here are some of the issues:
* We _cannot_ support `read`/`modify` in Swift sources without
the user specifying a flag. That's because the idiom below occurs
in real code, and would be broken by such support. So when
we enable the `CoroutineAccessors` flag by default, we _must_
not support `read`/`modify` as accessor notations in source.
```
struct XYZ {
// `read` method that takes a closure
func read(_ closure: () -> ()) { ... }
// getter that uses the above closure
var foo: Type {
read { ... closure ... }
}
}
```
* .swiftinterface files don't have the above problem.
Accessor bodies aren't stored at all by default, and
when inlineable, we always write explicit `get`.
So we can continue to accept `read`/`modify` notation
in interface files.
So our strategy here is:
* We'll accept both `read`/`modify` and `yielding borrow`/`yielding mutate`
in interface files for a lengthy transition period.
* We'll write `read`/`modify` to swiftinterface files for
a little longer, then switch to `yielding borrow`/`yielding mutate`.
* We'll disable `read`/`modify` support in source files
when we enable `CoroutineAccessors` by default.
(We can't even diagnose, due to the above idiom.)
This means that early adopters will have to update their sources
to use the new terminology. However, swiftinterface files
will be exchangeable between the new and old compilers for a little
while.
This does not rename all the internal variables, functions, and types
whose names were based on the old syntax.
I think it adds new syntax support everywhere it's needed while
retaining enough of the old syntax support that early adopters will
see nice deprecation messages guiding them to the new syntax.
We don't have support for borrowing switch on Copyable types.
It is supported for ~Copyable types, but the return expression emission for borrow accessors is not yet implemented.
Diagnose instead of crashing the compiler.
Lexer should always set `Token.CommentLength` correctly because it
necessary for restoring to the token position with comments.
Otherwise, 'Token::isAtStartOfLine()' might not correctly set.
We know this is where the issue is so we can immediately bind to a hole,
ensuring we don't produce unnecessary downstream diagnostics from
things we can't infer.