For example @objc lookup could find multiple instance members
on `AnyObject`. It should be allowed to diagnose issues with
that as non-ambiguous if all fixes have the same kind/base type.
Resolves: rdar://102412006
Previous implementation blindly took the first solution
and tried to diagnose, but that's not a safe assumption.
It's possible that among the solution-fix pairs, one
of `noncopyableTy`'s within the fix differs from the
others. Things probably can go wrong because the solution
doesn't correspond to that type.
Also, in that case we'd be emitting a diagnostic that
may not make any sense. In such cases, now we decline
to emit a diagnostic.
Thanks Pavel for catching this.
Since values of generic type are currently assumed to always
support copying, we need to prevent move-only types from
being substituted for generic type parameters.
This approach leans on a `_Copyable` marker protocol to which
all generic type parameters implicitly must conform.
A few other changes in this initial implementation:
- Now every concrete type that can conform to Copyable will do so. This fixes issues with conforming to a protocol that requires Copyable.
- Narrowly ban writing a concrete type `[T]` when `T` is move-only.
associated failure diagnostic.
This constraint fix is unused now that MacroExpansionExpr always has an
argument list, and goes through the AddMissingArguments constraint fix for
this error.
Instead of failing constraint generation by returning `nullptr` for an `ErrorExpr` or returning a null type when a type fails to be resolved, return a fresh type variable. This allows the constraint solver to continue further and produce more meaningful diagnostics.
Most importantly, it allows us to produce a solution where previously constraint generation for a syntactic element had failed, which is required to type check multi-statement closures in result builders inside the constraint system.
Rather than re-using `DiagnosticBehavior` to describe how a fix should
act, introduce `FixBehavior` to cover the differences between (e.g.)
always-as-awarning and downgrade-to-warning. While here, split the
`isWarning` predicate into two different predicates:
* `canApplySolution`: Whether we can still apply a solution when it
contains this particular fix.
* `affectsSolutionScore`: Whether
These two predicates are currently tied together, because that's the
existing behavior, but we don't necessarily want them to stay that way.
Instead of the `warning` Boolean threaded through the solver's
diagnostics, thread `DiagnosticBehavior` to be used as the behavior
limit. Use this for concurrency checking (specifically dropped
`@Sendable` and dropped global actors) so the solver gets more control
over these diagnostics.
This change restores the diagnostics to a usable state after the prior
change, which introduced extra noise. The only change from existing
beavior is that dropping a global actor from a function type is now
always a warning in Swift < 6. This is partly intentional, because
there are some places where dropping the global actor is well-formed.
Diagnose situations where pattern variables with the same name
have conflicting types:
```swift
enum E {
case a(Int)
case b(String)
}
func test(e: E) {
switch e {
case .a(let x), .b(let x): ...
}
}
```
In this example `x` is bound to `Int` and `String` at the same
time which is incorrect.
Instead of checking for presence of `where` clause, let's use
requirement signature and check whether any of the requires are
anchored on a particular associated type.
Accessing members on the protocol could result in existential opening and subsequence
result erasure, which requires explicit coercion if there is any loss of generic requirements.