Commit Graph

54 Commits

Author SHA1 Message Date
Mark Lacey
e4f19a10c2 [Constraint solver] Type checker perf test with mixed dictionary/closures.
This is now compiling reasonably quickly (rather than "expression was
too complex"), so ensure it does not regress.
2017-04-16 09:45:20 -07:00
Mark Lacey
e19ab8077a [Constraint solver] Enable a type checker performance test.
This now passes with constraint propagation enabled.
2017-04-16 08:50:37 -07:00
Mark Lacey
ee7bedde3f Remove -O from a couple type checker perf tests, and add another test.
We don't need -O here. The new test is another known failure.
2017-04-11 23:55:57 -07:00
Mark Lacey
81fca31ef4 Add a typecheck perf test for inferring array-of-tuples. 2017-02-23 12:39:32 -08:00
Mark Lacey
b026a07fd8 Add a scale-test counter for expression type checking.
Also add the first example of using the counter to test for
known-exponential typechecking behavior for nil-coalescing.
2017-02-23 12:08:30 -08:00
Doug Gregor
40b6764e80 [Constraint solver] Handle disjunctions as separate connected components.
The constraint graph models type variables (as the nodes) and
constraints (as the multi-edges connecting nodes). The connected
components within this (multi-)graph are independent subproblems that
are solved separately; the results from each subproblem are then
combined. The approach helps curtail exponential behavior, because
(e.g.) the disjunctions/type variables in one component won't ever be
explored while solving for another component

This approach assumes that all of the constraints that cannot be
immediately solved are associated with one or more type
variables. This is almost entirely true---constraints that don't
involve type variables are immediately simplified.

Except for disjunctions. A disjunction involving no type variables
would not appear *at all* in the constraint graph. Worse, it's
independence from other constraints could not be established, so the
constraint solver would go exponential for every one of these
constraints. This has always been an issue, but it got worse with the
separation of type checking of "as" into the "coercion" case and the
"bridging" case, which introduced more of these disjunctions. This led
to counterintuitive behavior where adding "as Foo" would cause the
type checking to take *more* time than leaving it off, if both sides
of the "as" were known to be concrete. rdar://problem/30545483
captures a case (now in the new test case) where we saw such
exponential blow-ups.

Teach the constraint graph to keep track of "orphaned" constraints
that don't reference any type variables, and treat each "orphaned"
constraint as a separate connected component. That way, they're solved
independently.

Fixes rdar://problem/30545483 and will likely curtain other
exponential behavior we're seeing in the solver.
2017-02-20 17:18:18 -08:00
Doug Gregor
fbb7dcf971 Replace concrete init(stringInterpolationSegment:)'s with generic ones
Remove 16 concrete init(stringInterpolationSegment:) overloads and
replace them with 3 generic overloads, significantly reducing the
exponential blow-up from larger string interpolations.

Fixes rdar://problem/29389887.
2017-02-08 21:01:09 -08:00
Doug Gregor
e387361194 Revert "Replace concrete init(stringInterpolationSegment:)'s with generic ones"
This reverts commit f6cac54606.
2017-02-08 13:38:11 -08:00
Jordan Rose
37774eb97e Fix the TypeChecker's omitNeedlessWords to use interface types. (#7193)
...avoiding a crash when trying to detect near misses of protocol
requirements. Unfortunately I can't come up with a test case for the
VarDecl changes; everything I try seems to already work. But using
interface types is more correct anyway.

https://bugs.swift.org/browse/SR-3812
2017-02-02 14:26:29 -08:00
Doug Gregor
f6cac54606 Replace concrete init(stringInterpolationSegment:)'s with generic ones
Remove 16 concrete init(stringInterpolationSegment:) overloads and
replace them with 3 generic overloads, significantly reducing the
exponential blow-up from larger string interpolations.

Fixes rdar://problem/29389887.
2017-01-27 21:54:59 -08:00
Jordan Rose
7c8117301a In Swift 3 mode, allow "tuple unsplatting" in certain cases. (#7077)
Swift 3.0 allowed constructing an enum or calling a function-typed
property with multiple arguments even when a single argument of tuple
type was expected. Emulate that in Swift 3 mode by wrapping in an
extra level of parentheses when the situation comes up.

Last vestiges of fallout from SE-0110. Hopefully last, anyway. A nice
follow-up to this commit might be to /warn/ in Swift 3 mode when this
happens.

rdar://problem/30171399
2017-01-27 11:19:07 -08:00
Slava Pestov
9db06ee36d Sema: Fixes for handling of 'Self'-returning methods
Protocol methods returning optionals, metatypes and functions
returning 'Self' are now handled correctly in Sema when
accessed with a base of existential type, eg:

protocol Clonable {
  func maybeClone() -> Self?
  func cloneMetatype() -> Self.Type
  func getClonerFunc() -> () -> Self
}

let c: Clonable = ...
let _: Clonable = c.maybeClone()
let _: Clonable.Type = c.cloneMetatype()

Previously, we were unable to model this properly, for
several reasons:

- When opening the function type, we replaced the return
  value in openedFullType _unconditionally_ with the
  existential type. This was broken if the return type
  was not the 'Self' parameter, but rather an optional,
  metatype or function type involving the 'Self' parameter.

- It was also broken because we lost information; if the
  return type originally contained an existential, we had
  no way to draw the distinction. The 'hasArchetypeSelf()'
  method was a hint that the original type contained a
  type parameter, but it was inaccurate in some subtle cases.

- Since we performed this replacement on both the
  'openedFullType' and 'openedType', CSApply had to "undo"
  it to replace the existential type with the opened
  existential archetype. This is because while the formal
  type of the access returns the existential type, in
  reality it returns the opened type, and CSApply has to
  insert the correct ErasureExpr.

  This was also done unconditionally, but even if it were
  done more carefully, it would do the wrong thing because
  of the 'loss of information' above.

- There was something fishy going on when we were dealing
  with a constructor that was declared on the Optional type
  itself, as seen in the fixed type_checker_crasher.

- TypeBase::eraseOpenedExistential() would transform a
  MetatypeType of an opened existential into a MetatypeType
  of an existential, rather than an ExistentialMetatypeType
  of the existential type.

The new logic has the following improvements:

- When opening a function type, we replace the 'Self' type
  parameter with the existential type in 'openedType', but
  *not* 'openedFullType'. This simplifies CSApply, since it
  doesn't have to "undo" this transformation when figuring
  out what coercions to perform.

- We now only use replaceCovariantResultType() when working
  with Self-returning methods on *classes*, which have more
  severe restrictions than protocols. For protocols, we walk
  the type using Type::transform() and handle all the cases
  properly.

- Not really related to the above, but there was a whole
  pile of dead code here concerning associated type references.

Note that SILGen still needs support for function conversions
involving an existential erasure; in the above Clonable example,
Sema now models this properly but SILGen still crashes:

let _: () -> Clonable = c.getClonerFunc()

Fixes <rdar://problem/28048391>, progress on <rdar://problem/21391055>.
2017-01-03 21:49:00 -08:00
Jordan Rose
49e6c06eef [validation-test] Remove "REQUIRES: asserts" from /fixed/ crash cases. (#6156) 2016-12-08 19:06:32 -08:00
Mark Lacey
1342223894 Merge pull request #6057 from xedin/rdar28235248
[QoI] When adding archetype requirements don't expect all of the members to be resolved
2016-12-07 19:37:58 -08:00
Slava Pestov
a1c213d4ee Update a diagnostic string in a -verify test
The old diagnostic was misleading; the closure really does take
one argument, but we're _returning_ a value that doesn't match
the contextual return type. And the suggestion to wrap the
argument in parens makes no sense either.

The new diagnostic is totally useless, but at least isn't not
misleading.
2016-12-07 14:16:43 -08:00
Pavel Yaskevich
91e8a0ccdb [QoI] When adding archetype requirements don't expect all of the members to be resolved
Some of the type members might be unresolved because they are misspelled or
do not exist (represented by DependentMemberType), so when trying to add
requirements to the nested types don't expect that all of the members have
their associated types resolved.

Resolves: <rdar://problem/28235248>.
2016-12-03 23:19:51 -08:00
Slava Pestov
4ebac86895 AST: Type::subst(): try harder to preserve sugar
If a sugared type desugars to a substitutable type, we would
return the replacement type without the sugar. I think in
practice this meant that ParenType would be lost sometimes.

Preserving this correctly is required for an upcoming CSDiag
change.

Note that there's a minor source-breaking change with enum
case constructors here. I've filed <rdar://problem/27261929>
to track sorting it out in Swift 3 mode.

Also an upcoming patch fixes another related issue and adds more
tests for case constructors.
2016-11-29 03:05:28 -07:00
xedin
2f3b5ad318 [QoI] Handle coercions involving ImplicitlyUnwrappedOptional<T> as 'from' type (#5900)
Add a case to ExprRewriter.coerceToType which tries to look through
ImplicitlyUnwrappedOptional<T> and apply 'to-value' transformation
before coercing to required 'to' type.

Resolves: <rdar://problem/28023899>.
2016-11-29 16:08:34 +09:00
Pavel Yaskevich
d111e9b4be [Diagnostics] When building a subscript don't assume that overload is always present
This handles situation when overload for the subscript hasn't been resolved
by constraint solver, such might happen, for example, if solver was allowed to
produce solutions with free or unresolved type variables (e.g. when running diagnostics).

Resolves: <rdar://problem/27329076>, <rdar://problem/28619118>, <rdar://problem/2778734>.
2016-11-28 19:18:44 -08:00
David Farler
b7d17b25ba Rename -parse flag to -typecheck
A parse-only option is needed for parse performance tracking and the
current option also includes semantic analysis.
2016-11-28 10:50:55 -08:00
Pavel Yaskevich
965d2d6d87 [QoI] Coerce tuple type elements to RValue before erasure
When trying to convert tuple type to existential look through
it's elements and convert found LValues to RValues (via load)
before applying erasure.

Resolves: <rdar://problem/27575060>.
2016-11-21 00:42:45 -08:00
Doug Gregor
dc70877465 Merge pull request #5834 from xedin/rdar27464577
[TypeChecker] Don't assume that cast expressions always have sub-expressions
2016-11-18 13:00:01 -08:00
Doug Gregor
585e065c90 Handle requirement environments with concrete same-type constraints.
It is possible to have requirement environments in which substitution
of the conforming type for Self into the requirement's signature would
result in substituted same-type requirements that no longer involve
type parameters. This triggered an assertion in the construction of
the requiremet environement; instead, just drop the requirement
because it is no longer interesting. Witness matching will simply fail
later one.

With this fix, it now because possible to add generic requirements to
a protocol that were unsatisfiable for certain models. For example,
the following protocol:

    protocol P {
      associatedtype A
      associatedtype B

      func f<T: P>(_: T) where T.A == Self.A, T.A == Self.B
    }

can only be satisfied by conforming types for which Self.A ==
Self.B. SE-0142 will introduce a proper way to add such requirements
onto associated types. This commit makes any such attempt to add
requirements onto "Self" (or its associated types) ill-formed, so we
will reject the protocol P above with a diagnostic such as:

    error: instance method requirement 'f' cannot add constraint
    'Self.A == Self.B' on 'Self'

Fixes rdar://problem/29075927.
2016-11-17 23:53:10 -08:00
Pavel Yaskevich
351ae5bde9 [TypeChecker] Don't assume that cast expressions always have sub-expressions
When cast expressions (conditional or forced downcasts) are part
of the closure expression with invalid parameters or return type,
they are not going be to folded by PreCheckExpression, which means
that they are not going to have sub-expression (from) set.

Resolves: <rdar://problem/27464577>.
2016-11-16 23:58:03 -08:00
Pavel Yaskevich
ad0b1c7383 [TypeChecker] Disallow solutions with free type variables when finalizing witness match
Disallows solutions containing free type variables on the final step of
witness matching, because that would yield incorrect results when witness
type has free type variables as well.

Resolves: <rdar://problem/27249691>.
2016-11-15 13:43:31 -08:00
Pavel Yaskevich
28777a3c7e [Diagnostics] Coerce closure arguments to contextual type only if it is valid
Modify TypeChecker::coerceParameterListToType to always validate and consider only
valid contextual types (contains: no undefined, error, or type variables etc.) for
argument type coercion, such logic prevents erasure of important explicitly specified
type information attached to parameters of the closure expressions being diagnosed.

Resolves: SR-2994.
2016-11-11 10:31:30 -08:00
Doug Gregor
f168e7270c [Type checker] Use DependentMemberType instead of type variables for nested types.
In the constraint solver, we've traditionally modeled nested type via
a "type member" constraint of the form

  $T1 = $T0.NameOfTypeMember

and treated $T1 as a type variable. While the solver did generally try
to avoid attempting bindings for $T1 (it would wait until $T0 was
bound, which solves the constraint), on occasion we would get weird
behavior because the solver did try to bind the type
variable.

With this commit, model nested types via DependentMemberType, the same
way we handle (e.g.) the nested type of a generic type parameter. This
solution maintains more information (e.g., we know specifically which
associated type we're referring to), fits in better with the type
system (we know how to deal with dependent members throughout the type
checker, AST, and so on), and is easier to reason able.

This change is a performance optimization for the type checker for a
few reasons. First, it reduces the number of type variables we need to
deal with significantly (we create half as many type variables while
type checking the standard library), and the solver scales poorly with
the number of type variables because it visits all of the
as-yet-unbound type variables at each solving step. Second, it
eliminates a number of redundant by-name lookups in cases where we
already know which associated type we want.

Overall, this change provides a 25% speedup when type-checking the
standard library.
2016-11-05 23:20:28 -07:00
Mark Lacey
c7f448f972 Do not assume Set/Dictionary are always bound generic types.
In cases where we cannot infer the types they won't be, so we don't want
to just cast to BoundGenericType when we see these.

Fixes rdar://problem/28317710 and at least one dup (and I think a few
more).
2016-11-03 00:42:03 -07:00
Doug Gregor
33ad7a8473 [Constraint solver] Remove erroneous constraints from the constraint graph.
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.
2016-10-27 21:35:14 -07:00
Doug Gregor
2ce30d32c4 Add a few more type-checker crasher addressed by the "occurs" check.
For rdar://problem/19343997, rdar://problem/19924870, and rdar://problem/20771765.
2016-10-25 23:26:07 -07:00
Doug Gregor
b295106830 [Constraint solver] Use the type representative in the "occurs" check.
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.
2016-10-25 22:37:21 -07:00
Doug Gregor
4cc41e5e64 [Constraint solver] Perform the "occurs" check properly.
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.
2016-10-25 13:32:06 -07:00
Doug Gregor
d2cb83b4c7 [Constraint solver] Make checked cast constraint generation lazy.
Fixes rdar://problem/27148148.
2016-10-22 22:57:25 -07:00
Mark Lacey
f95e5db2c6 Add a crasher for rdar://problem/27017206. 2016-10-15 10:42:24 -07:00
Mark Lacey
dda3521ba4 Add a crasher for rdar://problem/27249691. 2016-10-15 10:32:34 -07:00
Mark Lacey
b7b8245e1f Add a crasher for rdar://problem/28023899. 2016-10-15 10:14:50 -07:00
Mark Lacey
a3dff973ea Add some more known type checker crashers.
Minimized tests from:
  rdar://problem/28145033
  rdar://problem/28221883
  rdar://problem/28235248
2016-10-14 23:53:38 -07:00
Mark Lacey
bea2aabf11 Add a crasher for rdar://problem/28619118. 2016-10-12 11:32:43 -07:00
Doug Gregor
c2b9759cd3 Simplify ConstraintSystem::getFixedTypeRecursive and use it consistently.
We had a few places that were performing ad hoc variants of
ConstraintSystem::getFixedTypeRecursive(); simplify it's interface so
we can use it everywhere consistently. Fixes rdar://problem/27261929.
2016-10-11 17:08:52 -07:00
Mark Lacey
fb3470266a Add a crasher for rdar://problem/27148148. 2016-10-02 19:43:05 -07:00
Mark Lacey
9f5e9737ea Add a crasher for rdar://problem/28048391. 2016-10-02 19:43:05 -07:00
Mark Lacey
63922ea8f7 Add a crasher for rdar://problem/28317710. 2016-10-02 19:43:05 -07:00
Mark Lacey
b44a93ea84 Fix crash on typecheck failure in interpolated strings.
We were attempting to clean up stray type variables before creating a
new constraint system and moving forward with narrowing down the
typecheck failure, but we were failing to remove type variables for
interpolated strings.

Fix that, as well as removing them from TypeExpr's, and add an assert
that on exit from the pre-order visitor we don't have any type
variables (except for literals that aren't interpolated strings, which
I'm going to dig into further).

Fixes rdar://problem/27830834 and SR-2716.
2016-09-22 17:09:31 -07:00
Mark Lacey
126b9fcb2a Do not recurse infinitely when type checking constructor parameters.
Fully-qualified references to associated types in parameter lists of
constructors could result in infinite recursion and crash the compiler
when the typealias for the associated type is not defined.

Use the same approach used in normal function parameter lists of setting
IsBeingTypeChecked on the enclosing type to avoid going into an infinite
recursion here.

Resolves rdar://problem/27680407.
2016-09-19 14:55:25 -07:00
Mark Lacey
e2f7c6e23d Add known type checker crasher.
Add minimized test for rdar://problem/27830834.

In a build with asserts enabled assert with:
  (TypeVariables[impl.getGraphIndex()] == typeVar && "Type variable mismatch")
2016-08-25 11:19:49 -07:00
Mark Lacey
5d89924307 Add known type checker crashers.
Add minimized tests for:
    rdar://problem/27879334
2016-08-23 20:34:56 -07:00
Doug Gregor
65d8f03448 Merge pull request #4329 from rjmccall/collection-upcast-oves
Fix this to not die on the OVEs from collection upcasts.
2016-08-17 10:40:56 -07:00
John McCall
e360d7f2b0 Fix the open-existential remover to not die on the OVEs in collection upcasts. 2016-08-16 22:17:02 -07:00
Mark Lacey
5307a79b82 Add known type checker crashers.
Add minimized tests for:
    rdar://problem/27261929
    rdar://problem/27329076
2016-08-16 16:35:58 -07:00
Mark Lacey
2ea5486c29 Add known type checker crashers.
Add minimized tests for:
  rdar://problem/27464577
  rdar://problem/27575060
  rdar://problem/27680407
  rdar://problem/27787341
  rdar://problem/27815848

As these (and other tests added here) are fixed, we can move them into a
new type_checker_crashers_fixed directory.
2016-08-13 12:57:20 -07:00