Commit Graph

588 Commits

Author SHA1 Message Date
Doug Gregor
80d0e03f61 Don't path-compress the fixed type for a type variable binding.
We still perform path compression for the representative of a type
variable, but the fixed type of a type variable is no longer
compressed: it either doesn't exist or is stored in the
representative. This preserves the equivalence-class structure of type
variables even after they've been bound to fixed types.


Swift SVN r10921
2013-12-06 15:04:37 +00:00
Doug Gregor
adb4fb0da4 Separately rank the partial solutions for each connected component.
This per-component ranking selects the best partial solution (or at
least minimizes the set of partial solutions) before composing the
results of the partial solutions into set of solutions. This way, we
don't end up creating a huge number of solutions (i.e., all
permutations of the partial solutions) that we'll then have to compare. 

27% improvement in type-checking time for the standard library.



Swift SVN r10865
2013-12-05 18:00:57 +00:00
Doug Gregor
0bbf7c92bc Give ConstraintSystem::findBestSolution() a more reasonable return type.
Swift SVN r10861
2013-12-05 17:22:02 +00:00
Jordan Rose
417b5d3982 Merge TranslationUnit into Module, and eliminate the term "translation unit".
This completes the FileUnit refactoring. A module consists of multiple
FileUnits, which provide decls from various file-like sources. I say
"file-like" because the Builtin module is implemented with a single
BuiltinUnit, and imported Clang modules are just a single FileUnit source
within a module.

Most modules, therefore, contain a single file unit; only the main module
will contain multiple source files (and eventually partial AST files).

The term "translation unit" has been scrubbed from the project. To refer
to the context of declarations outside of any other declarations, use
"top-level" or "module scope". To refer to a .swift file or its DeclContext,
use "source file". To refer to a single unit of compilation, use "module",
since the model is that an entire module will be compiled with a single
driver call. (It will still be possible to compile a single source file
through the direct-to-frontend interface, but only in the context of the
whole module.)

Swift SVN r10837
2013-12-05 01:51:15 +00:00
Doug Gregor
3d4da69b08 In "x as T", type-check the subexpression "x" using "T" as the context type.
Using "T" as the contextual type, either for an implicit conversion
(in the coercion case) or as a downcast (for the checked-cast case),
opens up more type-inference opportunities. Most importantly, it
allows coercions such as "1 as UInt32" (important for
<rdar://problem/15283100>). Additionally, it allows one to omit
generic arguments within the type we're casting to.

Some additional cleanup to follow.


Swift SVN r10799
2013-12-04 22:32:28 +00:00
Doug Gregor
dac8624bc0 Don't merge the TVO_PrefersSubtypeBinding bit; it doesn't affect solving.
Swift SVN r10717
2013-12-01 17:53:48 +00:00
Doug Gregor
3e290f4471 Use a intrusive doubly-linked lists for active/retired constraints.
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
2013-12-01 16:31:49 +00:00
Doug Gregor
06ec5fff8f Remove debugging-only vector of solved constraints. It doesn't help.
Swift SVN r10677
2013-11-26 19:29:26 +00:00
Doug Gregor
3a71c8538b Remove the notion of a cutpoint from the solver; we no longer need it
Swift SVN r10675
2013-11-24 02:00:46 +00:00
Doug Gregor
cc75981ac6 Solve different connected components in isolation, then combine the results.
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
2013-11-24 01:57:47 +00:00
Doug Gregor
c8523f32ec Solver step: separate "what constraints to solve" from "how to solve it".
No functionality change.


Swift SVN r10673
2013-11-23 21:35:54 +00:00
Doug Gregor
8cd63c9b8d Use the constraint graph to isolate and solve the smallest connected component.
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
2013-11-23 03:44:40 +00:00
Doug Gregor
0428eeaebf Introduce --debug-constraints-attempt=N to debug a specific constraint system.
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
2013-11-21 18:53:00 +00:00
Doug Gregor
516fc3a9ac Track constraint solver statistics for the largest system.
Swift SVN r10633
2013-11-21 18:05:32 +00:00
Doug Gregor
cf074011b1 Stop creating type variables for archetypes.
Swift SVN r9918
2013-11-04 16:14:26 +00:00
Doug Gregor
b1a8e30b16 Teach witness matching to use interface types appropriately.
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
2013-11-01 17:09:51 +00:00
Doug Gregor
5555e6043d Kill off the member-reference path that opens based on archetypes.
This eliminates another pile of mostly-duplicated code that was
dependent on archetypes.


Swift SVN r9823
2013-10-30 23:15:15 +00:00
Doug Gregor
1a9545f5c0 Open references to types within generic contexts via the "new" path.
Swift SVN r9782
2013-10-30 04:56:40 +00:00
Doug Gregor
3b63fac07e Handle dynamic lookup through the "new" generic type path.
No functionality change; just another step in subsuming the
archetype-based path.


Swift SVN r9772
2013-10-30 00:08:35 +00:00
Doug Gregor
769ed07a6d Use the opened type of a subscript reference to compute substitutions.
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
2013-10-29 23:49:39 +00:00
Doug Gregor
45d840edfe Factor out the opening of generic function types.
No functionality change.


Swift SVN r9763
2013-10-29 21:11:09 +00:00
Doug Gregor
eecac1fd9c Eliminate the last few sources of SpecializeExprs.
All of these are dead code anyway, made redundant by ConcreteDeclRef's
elsewhere.


Swift SVN r9715
2013-10-28 18:42:24 +00:00
Doug Gregor
a000a25776 Open EnumElementDecl references via their generic function types.
Eliminates another use of SpecializeExpr.


Swift SVN r9711
2013-10-28 17:45:01 +00:00
Doug Gregor
37a803a314 For type checking, open constructor references based on their interface types.
Eliminates another use of SpecializeExpr.


Swift SVN r9690
2013-10-26 03:46:24 +00:00
Doug Gregor
a8aef7a10f Open references to protocol methods via their interface type.
Swift SVN r9641
2013-10-24 17:56:53 +00:00
Doug Gregor
e45254857a Tighten the constraint on the base of a '.' expression for protocol members.
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
2013-10-23 21:25:00 +00:00
Doug Gregor
8681e0abf9 Open operators in protocols with their interface types.
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
2013-10-23 17:36:15 +00:00
Doug Gregor
905078a278 Open method references via the interface type rather than the polymorphic type.
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
2013-10-23 05:35:16 +00:00
Doug Gregor
1eebdc9025 Replace the free type variables in a solution with generic type parameters.
This is a cleaner approach to handling solutions with free type
variables than in r9513.


Swift SVN r9613
2013-10-23 05:21:53 +00:00
Doug Gregor
9def310d89 Give a real struct name SelectedOverload to (OverloadChoice, Type) pairs.
Swift SVN r9566
2013-10-21 23:06:37 +00:00
Doug Gregor
61a0958616 Open method references to methods using their interface type.
Rely on opening the GenericFunctionType of a method, rather than its
PolymorphicFunctionType. Alas, constraint application still falls back to
the PolymorphicFunctionType.


Swift SVN r9564
2013-10-21 22:28:46 +00:00
Dmitri Hrybenko
acdd5b120a Make type checker debug output redirectable
Introduce a replaceable TypeCheckerDebugConsumer for this.


Swift SVN r9555
2013-10-21 20:26:32 +00:00
Doug Gregor
5269d99d0c Store substitutions within a DeclRefExpr.
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
2013-10-21 14:36:23 +00:00
Doug Gregor
50cfd44b37 Separate the computation of substitutions from the creation of SpecializeExpr.
No functionality change.


Swift SVN r9534
2013-10-21 14:08:26 +00:00
Doug Gregor
26c6659298 Introduce a Solution::specialize() for generic function types.
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
2013-10-20 02:52:00 +00:00
Dmitri Hrybenko
4d03f74a9a Code completion / type checker: while type checking a base expression for code
completion, don't fail if we have unsolved type variables.  Type variables are
replaced with GenericTypeParamType types.


Swift SVN r9515
2013-10-19 02:06:51 +00:00
Doug Gregor
e3ebb03c28 Start opening GenericFunctionTypes for references to non-member functions.
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
2013-10-18 23:04:16 +00:00
Doug Gregor
dea5d156d1 Eliminate the useless distinction between "solve" and "trivially solved".
Swift SVN r9493
2013-10-18 21:06:25 +00:00
Doug Gregor
307d2c28ff Remove the "trivial" flag from ConstraintSystem::matchTypes() et al.
It's a bogus notion that we aren't using.


Swift SVN r9489
2013-10-18 20:57:27 +00:00
Doug Gregor
e980d87f1a Explicitly model the single-element-tuple-to-scalar conversion.
Cleaner modeling of this conversion from (a : T) to T helps simplify
some of the type matching.


Swift SVN r9410
2013-10-16 15:56:45 +00:00
Doug Gregor
cf146ecaac Use disjunctions for "deep" equality match vs. user-defined conversions.
This should fix <rdar://problem/13140447> completely.


Swift SVN r9388
2013-10-15 23:36:40 +00:00
Doug Gregor
de416e2f4a Eliminate ConstraintSystem::isSubtypeOf().
Fix TypeChecker::isSubtypeOf() to actually solve the created system,
and introduce TypeChecker::isTrivialSubtypeOf() to handle the check
for trivial subtyping.


Swift SVN r9385
2013-10-15 22:58:17 +00:00
Doug Gregor
610fc5f2b6 Kill ConstraintSystem::isConvertibleTo().
Nobody should be using this ugly hack. Make
TypeChecker::isConvertibleTo() actually answer the "is convertible to"
query correctly.


Swift SVN r9384
2013-10-15 22:49:34 +00:00
Doug Gregor
f57e20edd1 Use disjunctions for subclass-to-superclass vs. user-defined conversions.
This fixes the superclass conversion issue in <rdar://problem/13140447>.


Swift SVN r9337
2013-10-14 23:42:42 +00:00
Doug Gregor
8a896ef59a Use disjunction conversions to handle T -> U? conversion ambiguity.
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
2013-10-14 18:08:12 +00:00
Doug Gregor
e3a664cf90 Factor out the scalar-to-tuple type matching.
Swift SVN r9229
2013-10-11 22:30:50 +00:00
Doug Gregor
d0822c5f18 Start factoring the solver's type matching to support multiple matches.
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
2013-10-11 22:19:17 +00:00
Doug Gregor
9f0ba722da Isolate the tuple-to-tuple or scalar-to-tuple conversion decision somewhat.
Swift SVN r9220
2013-10-11 21:33:51 +00:00
Doug Gregor
120ab19042 Zap anther vestige of overload sets
Swift SVN r9216
2013-10-11 19:55:04 +00:00
Doug Gregor
249ad9e095 Remove overload sets from the contraint system.
Swift SVN r9215
2013-10-11 19:04:57 +00:00