We have a systemic class of issues where noescape types end up bound to
type variables in places that should not. The existing diagnostic for
this is ad-hoc and duplicated in several places but it doesn't actually
address the root cause of the problem.
For now, I've changed all call sites of createTypeVariable() to set the
new flag. I plan on removing enough occurrences of the flag to replicate
the old diagnostics. Then we can continue to refine this over time.
In a few corner cases we built DeclRefExpr and MemberRefExpr
for references to types. These should just be TypeExpr so that
SILGen doesn't have to deal with it.
This also fixes a bug where a protocol typealias with an
unbound generic type could not be accessed properly from
expression context, but that is just so incredibly obscure.
Move checking for index Hashable conformance from CSApply (post-factum)
to the solver and use recorded conformance records complete subscript
components.
We currently assume that, if a subscript is declared within a value type’s decl, it must need `self` to be passed inout. This isn’t true for static subscripts, because even though the DeclContext is a value type, the metatype is actually a reference type. Skip this check for non-instance members.
NFC until static subscripts are added.
Implicit argument expression was necessary to generate keypath
constraint which is used to validate a choice picked for the member.
But since read-only check has been factored out it's now possible
to validate choice directly in combination with new 'keypath dynamic lookup'
locator associated with member type variable which represents result
of the dynamic lookup.
`openUnboundGenericType` eagerly tries to add conditional requirements
associated with chain of parents of the given type if type has been
declared inside of constrained extension. But one of the parent types
might be unbound e.g. `A.B` which means it has to be opened, which
by itself, would add such requirements.
Resolves: rdar://problem/49371608
Instead of waiting until the overload is attempted, let's figure out
if there is anything wrong with it beforehand and attach a fix to the
"bind overload" constraint representing it.
Further simplify `addOverloadSet` and move "outer" candidate handling
to the only place where it comes up - `simplifyMemberConstraint`.
Also move constraint generation for choices into a separate method.
This is a stepping stone on the path to enable attaching fixes to
the overload choices.
This is a follow-up to https://github.com/apple/swift/pull/23194,
which broke a case were single local overload choice was preferred
over any number of outer alternatives.
- Remove whole disjunction favoring which has no effect;
- Avoid creating separate disjunction for "inner" choices,
which is going to be flattened later anyway.
This narrow favoring rule makes more sense as part of disjunction
partitioning, because it is not dependent on the use site at all and
should only kick in when other options fail.
The "common type" optimization isn't really buying us anything at this
point, because we're not able to make much use of the common structure
often enough. Revert the "common type" optimization for now... I'll
bring it back when there's enough optimization infrastructure around
it to make it compelling.
Implement support for querying the effective overload type for constructors
and fix a semi-related bug for methods returning dynamic Self, which I
had not accounted for.
A declaration with an implicitly-unwrapped optional essentially has two
effective overload types, because the result might be optional or it might
have been forced. Disable computation of the effective overload type in this
case.
When simplifying a function application constraint, check the argument
labels for that application against the disjunction containing the overload
set, disabling any overloads with mis-matching labels. This is staging for
several different directions:
* Eliminating the argument label matching from performMemberLookup, where it
does not belong
* More aggressively filtering the overload set when we have some concrete
information about argument types
* Identifying favored constraints when we have some concrete information
about argument types
At present, the only easily-visible effect of this change is that
we now properly handle argument label matching for non-member functions.
Extend the computation of effective overload types, used in common result
type and common type computations, to also handle subscripts and variables.
This allows the optimization to also apply to subscripts, which did not
previously have a peephole in constraint generation.
Constraint generation for function application expressions contains a simple
hack to try to find the common result type for an overload set containing
callable things. Instead, perform this “common result type” computation
when simplifying an applicable function constraint, so it is more
widely applicable.
Type declarations are handled somewhat specially by the constraint
solver when applied, so temporarily exclude them from the "common
type" computation.
Given an overload set, attempt to compute a "common type" that
abstracts over all entries in the overload set, providing more
structure for the constraint solver.
This PR migrates instance member on type and type member on instance diagnostics handling to use the new diagnostics framework (fixes) and create more reliable and accurate diagnostics in such scenarios.
Situations like:
```swift
struct S {}
func foo(_ s: S.Type) {
_ = s()
}
```
Used to be diagnosed in solution application phase, which means that
solver was allowed to formed an incorrect solution.
Currently invalid initializer references are detected and
diagnosed in solution application phase, but that's too
late because solver wouldn't have required information while
attempting to determine the best solution, which might result
in viable solutions being ignored in favour of incorrect ones e.g.
```swift
protocol P {
init(value: Int)
}
class C {
init(value: Int, _: String = "") {}
}
func make<T: P & C>(type: T.Type) -> T {
return T.init(value: 0)
}
```
In this example `init` on `C` would be preferred since it
comes from the concrete type, but reference itself is invalid
because it's an attempt to construct class object using
metatype value via non-required initalizer.
Situations like these should be recognized early and invalid
use like in case of `C.init` should be ranked lower or diagnosed
if that is the only possible solution.
Resolves: rdar://problem/47787705
Instead of storing information about expression depths in the
solver state (which gets recomputed for salvage) let's track
it directly in constraint system, which also gives solver
access to it when needed e.g. for fixes.
Solving Bind is a little easier than Equal. The only remaining uses of Equal
are in the .member syntax and keypaths; if we can refactor those, we might be
able to simplify LValue handling in the type checker in general.