Recursive concrete and superclass constraints are detected
per-equivalence-class; record them that way.
Use that information to drop recursive concrete and superclass
constraints from the resulting signature, which frees the canonical
generic signature builder from having to worry about such recursive
constraints. This eliminates the invalid-code crashes introduced in
the prior commit that disabled finalization for the canonical GSBs, as
well as fixing one other random crash-on-invalid.
Now that SILGen can correctly lower lvalue accesses of
class existential payloads, remove a hack in Sema that
was simply doing the wrong thing.
Fixes <rdar://problem/31858378>.
Properly diagnose cases of function/subscript argument tuple
structuring/destructuring related by not limited to SE-0110.
Resolves: rdar://problem/31973368
This is pretty awkward. If an lvalue has an open existential
as its RValue type, we would emit an alloc_stack instruction
holding the materialized temporary before we emitted the
value itself. This introduced a def-after-use violation
because the open existential type in the stack allocation
was not dominated by its definition.
To get around this, don't use an SGFContext to emit the 'get'
in-place. There's no performance degradation, because the only
time we will attempt materializing an lvalue with an open
existential type is when performing an lvalue access of a
class existential payload, and here we in-place initialization
makes no difference since the value is a single reference.
This is an LValue component whose value is the class
reference inside of a class existential.
Unlike OpenOpaqueExistentialComponent, this is a logical
component, with a "writeback" consisting of wrapping the
new class reference in a class existential having the
same conformances as the original.
This is slightly awkward, but adding "by-address" operations
on class existentials, and projecting the payload out is
a big change and might not make sense for other reasons.
A `GenericSignatureBuilder` only needs to be finalized when we need to
compute a generic signature from it or otherwise require diagnostics.
Canonical generic signature builders don’t need either of those, so unless we
are performing the expensive idempotency checking, only do the minimal work
to “process delayed requirements”.
This gives a 3x speedup in type-checking time for the “trivial” example
let x = [1, 2]
because we do a lot less work on deserialization of generic environments.
Part of rdar://problem/32116933.
Rather than having `ASTContext:: getOrCreateCanonicalGenericEnvironment()`
ask its `GenericSignatureBuilder` parameter recompute the generic signature
at nontrivial cost, just pass the known signature through.
The GenericSignatureBuilder requires `finalize()` to be called before a
generic signature can be retrieved with `getGenericSignature()`. Most of the former isn’t strictly needed unless you want a generic signature, and the
latter is potentially expensive. `computeGenericSignature()` combines the two
operations together, since they are conceptually related. Update most of the
callers to the former two functions to use `computeGenericSignature()`.
Archetype anchors are (re-)computed often, but shouldn't change all
that much. Cache them in the equivalence class for a ~15% speedup
type-checking the standard library.
I added a test case from one of the failures that were exposed by the
change that I was reverting in
a1ed4e6174,
but I was unable to make this test not dependent on CGFloat. We don't
have that available everywhere, and the mock SDK doesn't support
everything we need here, so I'm just going to remove the test since
adding it isn't absolutely necessary at this time.
This is a bit more robust and user-friendly than hoping more brittle recovery in SILGen or IRGen for unsupported components kicks in. rdar://problem/32200714
When lowering a LoadExpr, SILGen constructs an LValue
and loads from it to produce an RValue.
If a LoadExpr contains another LoadExpr, the innermost
LoadExpr builds its own LValue, which is then loaded
to an RValue, and turned back into an LValue by creating
a single ValueComponent.
When evaluating an OpenExistentialExpr inside an LValue,
we record the base expression and evaluate it as an LValue
later when we encounter the corresponding OpaqueValueExpr.
The problem is when this is combined with a nested
LoadExpr, we might be inside of a different LValue than
the original LValue that contained the OpenExistentialExpr.
This would trigger an assertion, because the mapping from
OpaqueValueExprs to their base expressions was per-LValue;
instead, it needs to be per-SILGenFunction.
Add `FailureDiagnostics::visitKeyPathExpr` to try and diagnose contextual
value type problems related to Smart KeyPath feature. If problems with
contextual value type can't be diagnosed let's walk components and see
if there are any structural problems with expression itself e.g. unknown
members and incorrect types in the path.
Resolves: rdar://problem/32101765
A function is pure if it has no side-effects.
If there is a call of a pure function with constant arguments, it always makes sense to inline it, because we know that the whole computation will be constant folded.