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.
Revert "Make function parameters and refutable patterns always
immutable"
This reverts commit 8f2fbdc93a.
Once we have finally merged master into the Swift 2.2 branch to be, we
should revert this commit to turn the errors back on for Swift 3.0.
All refutable patterns and function parameters marked with 'var'
is now an error.
- Using explicit 'let' keyword on function parameters causes a warning.
- Don't suggest making function parameters mutable
- Remove uses in the standard library
- Update tests
rdar://problem/23378003
- Produce more specific diagnostics relating to different kinds of invalid
- add a testcase, nfc
- Reimplement FailureDiagnosis::diagnoseGeneralMemberFailure in terms of
Not including r30787 means that we still generate bogus diagnostics like:
[1, 2, 3].doesntExist(0) // expected-error {{type 'Int2048' does not conform to protocol 'IntegerLiteralConvertible'}}
But it is an existing and separable problem from the issues addressed here.
Swift SVN r30819
r30787 causes our tests to time out; the other commits depend on r30787.
Revert "revert part of my previous patch."
Revert "Produce more specific diagnostics relating to different kinds of invalid"
Revert "add a testcase, nfc"
Revert "- Reimplement FailureDiagnosis::diagnoseGeneralMemberFailure in terms of"
Revert "Fix places in the constraint solver where it would give up once a single "
Swift SVN r30805
member references:
- Use of instance members from types
- Use of type members from instances
- Use of mutating getters.
This surely resolves some radars, but I'll have to dig them out later.
Swift SVN r30796
"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
return statements, or a return statement with no operand.
Also, fix a special-case diagnostic about converting a return
expression to (1) only apply to converting the actual return
expression, not an arbitrary sub-expression, and (2) use the
actual operand and return types, not the drilled-down types
that caused the failure.
Swift SVN r30420