Various parts of the type checker (related to enum == synthesis) rely
on == for Ints being a module-scope function, which is silly. Remove
the restriction. Fixes rdar://problem/29029561.
Rather than computing the requirement environment as a tuple of
(generic signature, generic environment, substitution map),
encapsulate the result in a new RequirementEnvironment
class. Moreover, create a RequirementEnvironment once and re-use it
when matching each of the witnesses, because the environment itself
doesn't change---only the substitutions do. This saves us some work
when there are multiple potential witnesses (which is common).
My recent refactoring of witnesses in Sema and the AST disabled a
test for property behaviors, because they were no longer handling
substitutions correctly. Introduce a type checker entrypoint to record
information about a known witness, using the normal witness-matching
logic rather than trying to synthesize the correct answer (and getting
it wrong).
Note that I had to manually introduce some type witnesses to get the
property behavior tests passing, because the property-behavior code is
(intentionally) not introducing implicit typealiases for the type
witnesses it synthesized. The old witness-synthesizing code worked
around this issue, but the new code does not. A different fix is in
the works (i.e., better handling of type witnesses in the constraint
solver), so we'll take this temporary regression in an experimental
feature.
[CodeCompletion] Using the default constraints generator for TupleExpr
when inferring the type of unresolved members. rdar://28991372
When code completing, we used to create a type variable to represent the type
of an entire tuple expression. However, recent improvements on parser make this
step unnecessary and crash-prone. Thus, we use the default constraint
generator to interpret tuple expressions.
At one point this was added in order to inhibit some bridging
conversions while we are handling favored constraints, but that code has
been removed now, making this dead.
Noticed by inspection.
When we process a constraint, the first step is generally to call
getFixedTypeRecursive() to look through type variables. When this
operation actually does non-trivial work, we could save
that result by considering the current constraint "solved" and
generating a new constraint (if needed!) with the simplified types.
This commit adds the infrastructure to do that, because it's important
when getFixedTypeRecursive() starts performing more interesting
substitutions (e.g., handling member types of type
variables). However, enabling for the common case of looking through a
type variable isn't profitable (it's ~2% slower to type-check the
standard library). Stage in this infrastructure change now.
Reimplement the witness matching logic used for generic requirements
so that it properly models the expectations required of the witness,
then captures the results in the AST. The new approach has a number of
advantages over the existing hacks:
* The constraint solver no longer requires hacks to try to tangle
together the innermost archetypes from the requirement with the
outer archetypes of the context of the protocol
conformance. Instead, we create a synthetic set of archetypes that
describes the requirement as it should be matched against
witnesses. This eliminates the infamous 'SelfTypeVar' hack.
* The type checker no longer records substitutions involving a weird
mix of archetypes from different contexts (see above), so it's
actually plausible to reason about the substitutions of a witness. A
new `Witness` class contains the declaration, substitutions, and all
other information required to interpret the witness.
* SILGen now uses the substitution information for witnesses when
building witness thunks, rather than computing all of it from
scratch. ``substSelfTypeIntoProtocolRequirementType()` is now gone
(absorbed into the type checker, and improved from there), and the
witness-thunk emission code is simpler. A few other bits of SILGen
got simpler because the substitutions can now be trusted.
* Witness matching and thunk generation involving generic requirements
and nested generics now works, based on some work @slavapestov was
already doing in this area.
* The AST verifier can now verify the archetypes that occur in witness substitutions.
* Although it's not in this commit, the `Witness` structure is
suitable for complete (de-)serialization, unlike the weird mix of
archetypes previously present.
Fixes rdar://problem/24079818 and cleans up an area that's been messy
and poorly understood for a very, very long time.
As an extension of SR-2208 apply contextual conversion failure checking
to all of the expressions diagnosed via FailureDiagnosis::visitApplyExpr.
Resolves <rdar://problem/28909024>.
When a constraint fails, we retire it... but we also need to remove it
from the constraint graph. Otherwise, we break invariants when
diagnostic generation attempts to continue simplification.
Fixes rdar://rdar28145033.
When performing the occurs check, look for the *representative* of the
type variable we're about to bind, rather than the type variable
itself. Fixes rdar://problem/26845038, SR-1512, SR-1902, SR2635,
SR-2852, and SR-2766.
We've been performing the "occurs" check when computing potential
bindings for type variables, but we weren't actually performing the
check for bindings that *must* occur. Perform the occurs check before
binding type variables, which fixes a few crashers and is far more principled.
Note that this obviates the need for tracking the type variables we've
substituted in simplifyType(), so simplify that as well.
Fixes rdar://problem/27879334 / SR-2351.
This generalizes some code in Sema to fix the problem where
generic method overrides don't work if the base class is
more or less generic than the derived class.
The problem here was that we were checking types for equality
when matching overrides, which failed if generic parameters
had different depths. Now, map the generic parameters of the
base class member to the generic signature of the derived
member, so that the equality check can succeed.
Since SIL type lowering needs to perform a similar check,
move this from Sema to a method on TypeBase to complement
the existing getTypeOfMember().
Note that getTypeOfMember() still does a superclass walk, but
ideally this will go away soon.
Our existential metatype conversion/conformance handling in the type
checker was tripped up the refactoring to lazily introduce
constraints, because it dependended on the otherwise-unused
TypeMatchKind::ConformsTo. Eliminate TypeMatchKind::ConformsTo and
simplify the code here.
Start migrating the main ConstraintSolver::addConstraint() entrypoint
for relational constraints over to the model where it simplifies
first, then only creates a new constraint if the constraint it built
cannot be solved. This covers only the main relational
constraints--there are a number of other relational constraint kinds
to handle this way.
When adding a new member constraint, try to immediately simplify it,
generating a constraint when it cannot be resolved. Note that we also
generate constraints in top-level failure cases, so that the
diagnostics machinery can find it after-the-fact.
When adding a 'restricted' constraint, go straight into the 'simplify'
operation. A new constraint will only be allocated and recorded if it
cannot be immediately simplified. To get here, be more rigorous about passing TMF_GenerateConstraints through simplifyRestrictedConstraint().
When we're creating a new constraint because we couldn't solve it (and
need to record the result), do so without trying to simplify it yet
again. It's just wasted work.
ConstraintSystem::addConstraint() is no longer used to simplify
existing constraints, nor does it have to deal with "externally
solved" constraints. Remove those parameters and simplify the code. NFC
When adding constraints into the constraint system, don't immediately
allocate a Constraint and add it via the most-general
addConstraint(). Instead, go through a more specific entrypoint (e.g.,
addValueMemberConstraint, addRestrictedConstraint, etc.), so we can
start phasing out the general "add an already-formed constraint"
function. NFC