Constraints move between the active and retired lists fairly often, so
use a doubly-linked list to eliminate memory traffic and O(n) copies
of constraint pointers between the lists by using splicing instead.
Swift SVN r10715
Reduces type checking time for the standard library by ~13%, the
number of solver states visited by ~25%, and the number of pointlessly
visited constraints by ~30%. There are only 2175 separable
connected components in the standard library, likely because our
heuristics for picking type variables/constraints to solve bias
against connected components.
Swift SVN r10674
At each solution phase, construct a constraint graph and identify the
smallest connected component. Only solve for the variables in that
connected component, and restrict simplification to the constraints
within that connected component. This reduces the number of
visited-but-not-simplified constraints by ~2x when type-checking the
standard library.
Performance-wise, this is actually a regression (0.25s/8% when parsing
the standard library), because the time spent building the constraint
graph exceeds the time saved by the optimization above.
The hackaround in the standard library is due to
<rdar://problem/15168483>. Essentially, this commit changes the order
in which we visit type variables, causing the type checker to make
some very poor deduction choices.
The point of actually committing this is that it validates the
constraint graph construction and sets the stage for an actual
optimization based on isolating the solving work for the different
components.
Swift SVN r10672
The constraint solver statistics now tell us which of the constraint
systems we are solving were the largest. This lets us look at what the
solver does with that constraint system without piling on the
debugging spew.
Swift SVN r10638
This is one of the last few type checker clients of
PolymorphicFunctionType, where we were relying on opening archetypes
rather than generic parameters.
Swift SVN r9870
This eliminates the need to separately reconstruct all of the
substitutions for the base type of the subscript; our solution already
has all of that information.
Swift SVN r9771
The "conversion" constraint was far too loose, because we don't want
to permit arbitrary conversions on the left-hand side of the
'.'. Conformance constraints aren't correct either, because an
existential that does not conform to itself can still be used on the
left-hand side of a '.', so we introduce a new kind of constraint for
this.
Swift SVN r9630
Rather than jumping through special hoops to deal with operators in
protocols, just open those methods via their interface types (which
are generic function types). This eliminates a number of special cases
for protocol methods.
Swift SVN r9626
Once we've opened method references via the interface type, we then
fold all levels of generic argument specialization into the
DeclRefExpr, rather than using SpecializeExpr. For reference, the call
to x.f in this example:
struct X<T> {
func f<U>(u : U) { }
}
func honk(x: X<Int>) {
x.f("hello")
}
goes from this double-specialized AST:
(specialize_expr implicit type='(u: String) -> ()'
(with U = String)
(dot_syntax_call_expr type='<U> (u: U) -> ()'
(specialize_expr implicit
type='(@inout X<Int>) -> <U> (u: U) -> ()'
(with T = Int)
(declref_expr type='<T> @inout X<T> -> <U> (u: U) -> ()'
decl=t.X.f@t.swift:2:8 specialized=no))
to the cleaner, SpecalizeExpr-free:
(dot_syntax_call_expr type='(u: String) -> ()'
(declref_expr type='(@inout X<Int>) -> (u: String) -> ()'
decl=t.X.f@t.swift:2:8 [with T=Int, U=String]
specialized=no)
which handles substitutions at both levels together. The minor SILGen
tweak
Note that there are numerous other places where we are still generated
SpecializeExprs.
Swift SVN r9614
Rely on opening the GenericFunctionType of a method, rather than its
PolymorphicFunctionType. Alas, constraint application still falls back to
the PolymorphicFunctionType.
Swift SVN r9564
Replace DeclRefExpr's stored ValueDecl* with a ConcreteDeclRef,
allowing it to store the complete set of substitutions applied to
the declaration. Start storing those substitutions (without using them
yet).
Swift SVN r9535
This variant of specialize() uses the requirements list of the generic
function type to form the substitution list, rather than relying on
the polymorphic function type and all-archetypes lists.
Swift SVN r9518
When the type checker sees a reference to a generic non-member
function, open its interface type, which is expressed as a
GenericFunctionType, rather than its PolymorphicFunctionType. This is
a tiny step toward weaning the type checker off archetypes within the
interface.
Swift SVN r9504
Fix TypeChecker::isSubtypeOf() to actually solve the created system,
and introduce TypeChecker::isTrivialSubtypeOf() to handle the check
for trivial subtyping.
Swift SVN r9385
The constraint solver was eagerly applying the T -> U? conversion
rule, which only succeeds when T is convertible to U. Thus, we would
reject valid code where T has a user-defined conversion to
U?. Instead, introduce a disjunction conversion to try either T -> U?
by converting T to U or via a user-defined conversion.
Most of this is infrastructure for the introduction of constraint
restrictions, which specify that a particular constraint (say, a
conversion constraint) should only try a single direct path:
scalar-to-tuple, value-to-optional, user-defined, etc. Each term in the
disjunction created for the T -> U? case is restricted to a particular
conversion rule, so that checking it does not create another
disjunction.
Keep track of the constraint restrictions we used within a given
solution, so that we can replay those steps during the application
phase. There is a bunch of inactive code here at the moment, which
will become useful as we start creating disjunctions for other
ambiguous conversions.
Swift SVN r9318
ConstraintSystem::matchTypes() currently believes that there is only
one way in which two types might match each other. That being patently
untrue, start capturing the set of conversions that could potentially
work, so that we can turn them into disjunctions if when.
No functionality change yet; this is just refactoring.
Swift SVN r9227
Overload bindings constraints bind a given type to a specific overload
choice. This is a step toward moving overload sets into normal
disjunction constraints.
Part of the work here is to eliminate the constraint system's
dependence on OverloadSet, which will be going away in favor of a
disjunction constraint.
Swift SVN r9209
This introduces "class" constraints into the type checker, so that we
can specify that a particular type must be a class (or an archetype
that is required to be a class). Finishes <rdar://problem/15139128>.
Swift SVN r9176