Performance optimization to help rule out generic overload choices sooner.
This is based on an observation of the constraint solver behavior,
consider following example:
```swift
func test<U: ExpressibleByStringLiteral>(_: U) {}
test(42)
```
Constraint System for call to `test` is going to look like this:
```
$T_test := ($T_U) -> $T_U
$T_U <conforms to> ExpressibleByStringLiteral
$T_42 <argument conversion> $T_U
$T_42 <literal conforms to> ExpressibleByIntegerLiteral
```
Currently to find out that `test` doesn't match, solver would have
to first find a binding for `$T_42`, then find a binding for `$T_U`
(through `<argument conversion>` constraint) and only later fail
while checking conformance of `Int` to `ExpressibleByStringLiteral`.
Instead of waiting for parameter to be bound, let's transfer conformance
requirements through a conversion constraint directly to an argument type,
since it has to conform to the same set of protocols as parameter to
be convertible (restrictions apply i.e. protocol composition types).
With that change it's possible to verify conformances early and reject
`test<U: ExpressibleByStringLiteral>` overload as soon as type of an
argument has been determined. This especially powerful for chained calls
because solver would only have to check as deep as first invald argument
binding.
Introduce a new parameter `--skip-llbuild-clean` to prevent this from
happening.
This mimicks similar logic in place for `swiftpm`, `swift-driver`
(#33563) and `xctest` (#19512)
Addresses rdar://75057069
A protocol can constrain an associated type to Self:
protocol P {
associatedtype A : Q where A.B == Self
}
protocol Q {
associatedtype B
}
And a class might conform to this protocol:
class C : P {
typealias A = D
}
class D : Q {
typealias B = C
}
The generic signature <Self where Self : P, Self : C> is built during
conformance checking. Since Self : C, we must have that Self.A == D;
since D.B == C, the requierement 'A.B == Self' in protocol P implies
that 'Self == C'. So the correct minimized signature here is
<Self where Self == C>.
This wasn't handled properly before, because of assumptions in
removeSelfDerived() and a couple of other places.
Fixes rdar://71677712, rdar://76155506, https://bugs.swift.org/browse/SR-10033,
https://bugs.swift.org/browse/SR-13884.
Performance optimization.
If there is a concrete contextual type we could use, let's bind
it to the external type right away because internal type has to
be equal to that type anyway (through `BindParam` on external type
i.e. <internal> bind param <external> conv <concrete contextual>).
```swift
func test(_: ([String]) -> Void) {}
test { $0 == ["a", "b"] }
```
Without this optimization for almost all overloads of `==`
expect for one on `Equatable` and one on `Array` solver would
have to repeatedly try the same `[String]` type for `$0` and
fail, which does nothing expect hurts performance.
Resolves: rdar://19836070
Resolves: rdar://19357292
Resolves: rdar://75476311
When completing within an InOutExpr like `&foo.<complete>`, we were forming a
CodeCompletionExpr with a base when parsing the content of the InOutExpr and
storing it in CodeCompletionCallbacksImpl::CodeCompleteTokenExpr. When the
result of that parse contained a code completion though, we were dropping the
sub-expression completely and forming an empty code completion result in place
of the inout expression, which resulted in later code inserting a code
completion expression with no base into the AST. The solver based completion
was later asking for the type of the code completion and its base using the
expression stored in CodeCompletionCallbacksImpl::CodeCompleteTokenExpr, but
that never ended up in the AST so we hit an assertion about the expression not
have a type in the formed solutions.
Resolves rdar://75366814
This should correspond to the definition of memcmp in
usr/include/string.h and keep it from being a source of confusion for
the compiler.
rdar://69876253
When an extension is nested inside of an invalid decl context, it is
going to pull the signature of its nearest enclosing context instead of
its extended type. This leads to a null signature since the nearest
enclosing context for an extension should always be its parent source
file.
rdar://76049852
IsBindableVisitor is part of TypeBase::substituteBindingsTo(), which
is used for two things:
- Checking if one contextual type is a proper substitution of another
contextual type, used in the solver
- To compute the substituted generic signature when lowering a SIL
function type
In the first case, we're interested in knowing if the substitution
succeeds or fails. In the second case, we know the substitution is
correct by construction, and we're trying to recover the generic
requirements.
In the second case though, the substituted type might be an
interface type, and if the interface type is constrained to a
concrete type in the original type's generic signature, we would
conclude that the substitution should fail.
This is incorrect, and we should just skip the check if the
substituted type is an interface type -- we do not have enough
information to know if it succeeds, and instead we must assume it
does because otherwise the substituted type passed in to type
lowering must be incorrect.
Fixes https://bugs.swift.org/browse/SR-13849.
Prints a regular error instead of crashing.
The check is done in SILGen, because it's simple. We could also do it earlier, but I don't see a strong reason for this.
rdar://75950093
We rebuild a signature after dropping redundant conformance requirements,
since conformance requirements change the canonical type and conformance
access path computation.
When doing this, instead of using the canonical requirements from the
signature, use the original as-written requirements.
This fixes some weirdness around concrete same-type requirements.
There's a philosophical benefit here too -- since we rebuild the
signature without ever having built the old signature, we never create
an invalid GenericSignature in the ASTContext.
Fixes rdar://problem/75690903.
Type inside of an editor placeholder is more of a hint than anything else,
so if it's incorrect let's diagnose that and use type variable instead to
allow solver to make forward progress.
Resolves: SR-14213
Resolves: rdar://74356736
When requestifying the synthesis of the main function for the type
annotated @main via SynthesizeMainFunctionRequest, what were previously
were bailouts from AttributeChecker::visitMainTypeAttr had to become
returns of nullptr from SynthesizeMainFunctionRequest::evaluate.
Consequently, AttributeChecker::visitMainTypeAttr must check whether
synthesis actually succeeded before proceeding to to register the main
decl for a file.
In simple cases, this happened to work because
SourceFile::registerMainDecl would return early if the decl being
registered was the same as the already registered main decl and in
particular if the decl being registered was nullptr and the previously
registered one was nullptr as well. When, however, there are multiple
types annotated @main, if a function is successfully synthesized for one
type but synthesis fails for the second, an attempt will be made to
register nullptr as the main decl and will move past the check at the
beginning of SourceFile::registerMainDecl, resulting in a crash.
Here, we bail from AttributeChecker::visitMainTypeAttr if function
synthesis fails and add an assert to SourceFile::registerMainDecl that
the provided decl is non-null.
rdar://75547146
If completing the initialization of a variable that’s wrapped in a generic, unbound property wrapper, the expression's type is an `UnboundGenericType`. AFAICT that’s expected and the correct type to assign.
We hit the first assertion failure by trying to retrieve that type's substitution map. `UnboundGenericType`s were not handled here, so we crashed. AFAICT we can't get any substitutions out of an unbound generic type, so we should just continue looking into the parent type.
We hit the second assertion when trying to retrieve the property wrapper’s backing type, which is null (becuase it couldn't be resolved). However, we haven’t emitted a diagnostic because the variable declaration is perfectly valid. Hence I’m removing the assertion.
Fixes rdar://64141399
- Prefer CGFloat -> Double over the other way around to avoid
ambiguities;
- Every new conversion impacts the score by factor of number of
previously applied conversions to make it possible to select
solutions that require the least such conversions.
- Prefer concrete overloads with Double <-> CGFloat conversion
over generic ones.
A lot of operators (and most likely regular functions a well) have
overloads that accept i.e. a generic parameter that conforms to
`StringProtocol`, so the best fix in situations when argument is
a raw representable type would be to check whether `.rawValue`
conforms to the expected protocol and use it if so.
Resolves rdar://problem/75367157