Detect and diagnose a problem when explicitly specified closure
result type doesn't match what is expected by the context:
Example:
```swift
func foo(_: () -> Int) {}
foo { () -> String in "" } // `Int` vs. `String`
```
- When parsing a type or extension declaration, attempt to parse a function or property declaration when meeting an identifier, an operator or a paren (for tuple declarations).
- Produce the diagnostic with a fix-it suggesting to insert the needed keyword
- Recover parsing as if the declaration with the missing keyword is a function/property declaration
Resolves https://bugs.swift.org/browse/SR-10477
We still had unavailable versions of these for floating-point types
only. We shouldn't need to keep these around, and can instead just
emit a helpful diagnostic for anyone that attempts to use them.
Unfortunately I don't see any way for the diagnostic to produce an
actual fix-it, so it just suggests '+= 1' or '-= 1' without actually
producing a fix.
Allow witnesses to protocols in a copyable context to elide explicit
ownership conventions. This allows clients like the standard library to
standardize on one ownership convention without an ABI or API breaking
change in 3rd party code.
In the future, moveonly contexts must disallow this default behavior
else the witness thunks could silently transfer ownership.
rdar://40774922
protocol P {
__consuming func implicit(x: __shared String)
__consuming func explicit(x: __owned String)
__consuming func mismatch(x: __shared String)
}
class C : P {
// C.implicit(x:) takes self and x '@guaranteed' thru the witness thunk
func implicit(x: String) {}
// C.explicit(x:) takes self and x @owned with no convention changes
__consuming func explicit(x: __owned String) {}
// Would inherit __consuming, but x has been spelled __owned so the requirement match fails.
func mismatch(x: __owned String) {}
}
* [Diagnostics] SR-7445 Improve diagnostics for assignment failures
* modified messages for assignments to function calls,
modified messages for assignments to methods.
removed comment for resolved radar.
* removed extra line and braces
* added tests for assignment_lhs_is_apply_expression
eliminated redundant literal check which is always invoked before call
reverted 'cannot assign to value' for literal assignments in subexpressions
* Complemented assigning to literal tests & reverted to 'cannot asign to value' for methods (was 'cannot assign to member')
* removed extra tabs
* eliminated one more accidental spacing
* Update CSDiag.cpp
* added highlighting, fixed & rechecked tests
* added highlighting for complex expressions involving assigning to literals
Resolves: [SR-7445](https://bugs.swift.org/browse/SR-7445)
Currently edge related to the parameter bindings is contracted
without properly checking if newly created equivalence class has
the same inout & l-value requirements. This patch improves the
situation by disallowing contraction of the edges related to parameter
binding constraint where left-hand side has `inout` attribute set.
Such guarantees that parameter can get `inout` type assigned when
argument gets `l-value` type.
Resolves: rdar://problem/33429010
Pushes __consuming through the frontend and extends existing
attribute-based diagnsotics to cover it. Unlike `nonmutating`,
__consuming is allowed in class methods, though it makes little
sense to put it there.
1) Move the "both" check up and don't prematurely return because there
may be more errors.
2) Remove fix-it when both attributes exist. We simply don't know which
attribute the programmer wants to keep.
Using the attribute in this position is a relic from the Swift 2
days, and fixing it required letting invalid code fall through to
Sema instead of being diagnosed in Parse proper. Treat 'var'
in this position like 'let' by simply offering to remove it
instead of extracting it into a separate variable.
- Subscripts parameter lists may not contain inout arguments, but we
were rejecting this at the call site. Teach the type checker to reject
them during type resolution instead.
- We assumed a syntactic check for inout/var parameters would suffice
given that a parameter unified to an InoutType. However, closures
passed to function parameters with inout parameters in their parameter
lists can also cause this case to appear, and we would emit a
SourceLoc-less diagnostic. Instead, do not attempt this recovery path
if the user did not actually write ‘var’ or ‘inout’ on the parameter
type.
`1 { }` was parsed as a call expression with a trailing closure. This made the diagnostics for `var x = 1 { get { ... } }` extremely bad. Resolves SR-3671.
If we found any error in a list, in most cases, we cannot expect that the
following tokens could construct a valid element. Skip them, instead of trying
to parse them as the next element. This significally reduces bogus diagnostics.
Bailout if seeing tok::eof or token that can never start a element, after
parsing an element. This silences superfluous "expected ',' separator" error,
or misleading expected declaration error. What we should emit is
"expected ')' in expression list, or "expected '}' in struct".
Previously, we would skip validating the type (and checking var/inout)
on parameters that didn't have an explicit type. Instead, teach
validateParameterType how to handle an elided type.
We previously said:
x.method = 1 // error: cannot assign to property: 'x' is immutable
we now say:
error: cannot assign to property: 'method' is a method
Otherwise, we hit a problem because the setter is called with self passed as a
(single retainable pointer) value, but the witness expects a self value passed
indirectly.
I hit this while testing other stuff related to resilient default implementations.
Parse 'var [behavior] x: T', and when we see it, try to instantiate the property's
implementation in terms of the given behavior. To start out, behaviors are modeled
as protocols. If the protocol follows this pattern:
```
protocol behavior {
associatedtype Value
}
extension behavior {
var value: Value { ... }
}
```
then the property is instantiated by forming a conformance to `behavior` where
`Self` is bound to the enclosing type and `Value` is bound to the property's
declared type, and invoking the accessors of the `value` implementation:
```
struct Foo {
var [behavior] foo: Int
}
/* behaves like */
extension Foo: private behavior {
@implements(behavior.Value)
private typealias `[behavior].Value` = Int
var foo: Int {
get { return value }
set { value = newValue }
}
}
```
If the protocol requires a `storage` member, and provides an `initStorage` method
to provide an initial value to the storage:
```
protocol storageBehavior {
associatedtype Value
var storage: Something<Value> { ... }
}
extension storageBehavior {
var value: Value { ... }
static func initStorage() -> Something<Value> { ... }
}
```
then a stored property of the appropriate type is instantiated to witness the
requirement, using `initStorage` to initialize:
```
struct Foo {
var [storageBehavior] foo: Int
}
/* behaves like */
extension Foo: private storageBehavior {
@implements(storageBehavior.Value)
private typealias `[storageBehavior].Value` = Int
@implements(storageBehavior.storage)
private var `[storageBehavior].storage`: Something<Int> = initStorage()
var foo: Int {
get { return value }
set { value = newValue }
}
}
```
In either case, the `value` and `storage` properties should support any combination
of get-only/settable and mutating/nonmutating modifiers. The instantiated property
follows the settability and mutating-ness of the `value` implementation. The
protocol can also impose requirements on the `Self` and `Value` types.
Bells and whistles such as initializer expressions, accessors,
out-of-line initialization, etc. are not implemented. Additionally, behaviors
that instantiate storage are currently only supported on instance properties.
This also hasn't been tested past sema yet; SIL and IRGen will likely expose
additional issues.