Commit Graph

117 Commits

Author SHA1 Message Date
Mishal Shah
a84704f4b5 Revert "[Type checker] Introduce directional path consistency algorithm" 2016-08-24 17:53:12 -07:00
Pavel Yaskevich
de51b01195 [Type checker] Introduce directional path consistency algorithm
DPC algoritm tries to solve individual sub-expressions and combine
resolved types as a way to reduce pre-existing OSR domains. Solving
is done bottom-up so each consecutive sub-expression tightens
possible solution domain even further.
2016-08-24 14:38:46 -07:00
Doug Gregor
51529ae888 Eliminate the -enable-id-as-any flag; it's always on now anyway.
Simplify e.g., ASTContext::getBridgedToObjC(), which no longer needs
the optional return.

Eliminate the now-unused constraint kind for checking bridging to
Objective-C.
2016-08-19 21:17:09 -07:00
Doug Gregor
4d77a1fbf1 [Type checker] Strip unused code from enumerateDirectSupertypes.
The goal is to progressively remove everything from this function so
it can be removed entirely. It's an awful hack.
2016-08-19 13:24:13 -07:00
Doug Gregor
78b7bb4c4b [Type checker]: Implement 'join' for optional types and a special case for 'nil'.
The join operation for optional types is straightforward to define/implement:

  join(T?, U)  ::= join(T, U)?
  join(T, U?)  ::= join(T, U)?
  join(T?, U?) ::= join(T, U)?

As a special case in the constraint solver, handle the join of a 'nil'
literal with a non-ExpressibleByNilLiteral-conforming concrete type
'T' to produce 'T?'. This allows us, e.g., infer [String?] for the
expressions

  ["hello", nil]

and

   true ? "hello" nil

for example. Fixes rdar://problem/16326914.
2016-08-19 10:46:59 -07:00
Doug Gregor
1b99f7f5d5 [Type checker] s/meet/join, so we get our terminology straight. 2016-08-19 10:46:59 -07:00
Doug Gregor
22287ddb58 [Type system] Infer 'Any' for array elements and dictionary values and 'AnyHashable' for dictionary keys.
The id-as-Any work regressed cases where Swift code could specify
heterogeneous collection literals, e.g.,

    var states: [String: Any] = [
      "California": [
        "population": 37_000_000,
        "cities": ["Los Angeles", "San Diego", "San Jose"],
      ],
      "Oregon": [
        "population": 4_000_000,
        "cities": ["Portland", "Salem", "Eugene"],
      ]
    ]

Prior to this, the code worked (when Foundation was imported) because
we'd end up with literals of type [NSObject : AnyObject].

The new defaulting rule says that the element type of an array literal
and the key/value types of a dictionary literal can be defaulted if no
stronger type can be inferred. The default type is:

  Any, for the element type of an array literal or the value type of a
  dictionary literal, or

  AnyHashable, for the key type of a dictionary literal.

The latter is intended to compose with implicit conversions to
AnyHashable, so the most-general inferred dictionary type is
[AnyHashable : Any] and will work for any plausible dictionary
literal.

To prevent this inference from diluting types too greatly, we don't
allow this inference in "top-level" expressions, e.g.,

  let d = ["a" : 1, "b" : "two"]

will produce an error because it's a heterogeneous dictionary literal
at the top level. One should annotate this with, e.g.,

  let d = ["a" : 1, "b" : "two"] as [String : Any]

However, we do permit heterogeneous collections in nested positions,
to support cases like the original motivating example.

Fixes rdar://problem/27661580.
2016-08-04 20:58:13 -07:00
Doug Gregor
2bcf555896 [Constraint solver] Introduce a *trivial* 'meet' operation for types.
Stub out a simplistic 'meet' operation for types that currently only
handles finding the meet of two class types. Use it to optimize the
constraint solver ever so slightly: when we see a type variable whose
constraints state that it is a supertype of two different concrete
types, we attempt to compute their meet and, if we find it, only
produce one potential binding that is the meet itself.

Note that this is an extremely poor implementation of this concept
that is meant to address a specific regression being introduced by the
defaulting of collection literal element types. A real implementation
would, at the very least:

* Implement a proper 'meet' that covers all subtyping in the language.
* Distinguish between "I don't know if there is a meet" and "I am
  absolutely certain that there is no meet".
* Collapse the constraints themselves to reduce the number of
  constraints in the system, rather than just the number of type
  variable bindings we attempt.
2016-08-04 20:36:47 -07:00
Doug Gregor
d0733750cc [Constraint solver] Try ‘defaultable’ bindings even if there are other possibilities.
Fixes rdar://problem/17444930.
2016-08-04 13:45:07 -07:00
Doug Gregor
87a5e4d8d8 [NFC] ConstrainSystem::getComputedBindings() is dead. Kill it. 2016-08-04 11:21:35 -07:00
Robert Widmann
f97e5dcb0e [SE-0115][1/2] Rename *LiteralConvertible protocols to ExpressibleBy*Literal. This
change includes both the necessary protocol updates and the deprecation
warnings
suitable for migration.  A future patch will remove the renamings and
make this
a hard error.
2016-07-12 15:25:24 -07:00
Joe Pamer
778a4ee136 When converting potential IUO bindings to optional
ones, look through any lvalue types. Doing so can
prevent improper double-optional binds, which can
cause unexpected runtime behavior.

(rdar://problem/26360502)
2016-06-02 11:53:27 -07:00
Chris Willmore
af0c7bd620 Initial implementation of SE-0054 "Abolish IUO Type" (#2322)
This is a squash of the following commits:

* [SE-0054] Import function pointer arg, return types, typedefs as optional

IUOs are only allowed on function decl arguments and return types, so
don't import typedefs or function pointer args or return types as IUO.

* [SE-0054] Only allow IUOs in function arg and result type.

When validating a TypeRepr, raise a diagnostic if an IUO is found
anywhere other thn the top level or as a function parameter or return
tpye.

* [SE-0054] Disable inference of IUOs by default

When considering a constraint of the form '$T1 is convertible to T!',
generate potential bindings 'T' and 'T?' for $T1, but not 'T!'. This
prevents variables without explicit type information from ending up with
IUO type. It also prevents implicit instantiation of functions and types
with IUO type arguments.

* [SE-0054] Remove the -disable-infer-iuos flag.

* Add nonnull annotations to ObjectiveCTests.h in benchmark suite.
2016-05-03 14:06:19 -07:00
Chris Lattner
ab14e6706f Progress towards implementing SE-0049 - Allow autoclosure in parameter types
as well as on parameter decls.  Also, tighten up the type checker to look at
parameter types instead of decl attributes in some cases (exposing a type
checker bug).

Still TODO:
 - Reject autoclosure/noescape on non-parameter types.
 - Move stdlib and other code to use noescape and autoclosure in the right
   spot.
 - Warn about autoclosure/noescape on parameters decls, with a fixit to move it.
 - Upgrade the warning to an error.
2016-04-14 23:13:43 -07:00
Chris Willmore
4cc75187c6 [Sema] Flag -disable-infer-iuos: don't infer IUO type for untyped bindings
If this option is enabled, when generating potential bindings for a type
variable, don't propagate IUO type. Instead try the optional type and
the underlying type. This way, untyped bindings will not be given IUO
type when they are initialized with exprs of IUO type.
2016-03-21 17:33:29 -07:00
Michael Gottesman
5f72810ad3 Add a range adaptor for std::count and update various trivial usages in the compiler to use this API instead. 2016-03-08 14:58:13 -08:00
Joe Pamer
096ff9228f When trying out potential bindings for a given type variable, take greater measures not to try the same binding against a bound generic type more than once. Multiple attempts at bindings can result in massive slow downs in overload resolution, because we'll potentially post many duplicate results to the solution. (In cases such as "[0..<10, 0..<10, 0..<10, 0..<10, 0..<10]", for example.) 2016-01-28 11:02:26 -08:00
Joe Pamer
d7fb571855 When solving for type variable bindings, protect against trying the same (potentially unwrapped) binding twice. 2016-01-28 11:02:26 -08:00
Joe Pamer
de3d8a5823 More effectively simplify constraint graphs for nested binary expressions with homogeneous argument types. For example, this allows us to typecheck expressions of the form "a + b + c + d", where each variable is of an array type, without getting a "too complex" error.
Note that the typecheck perf for these kinds of expressions still isn't fantastic, but at least they're now computationally feasible. I have further improvements planned for this area which should bring performance in line with expectations.
2016-01-22 12:34:34 -08:00
Joe Pamer
37032b2a58 Take first steps towards simplifying the constraint graph by performing edge contraction. 2016-01-22 12:34:32 -08:00
Chris Lattner
b5500b8600 Generalize the conditions in which we'll accept an ambiguous solution to
a constraint system in "allowFreeTypeVariables" mode.  Previously, we
only allowed a few specific constraints, now we allow any relational and
member constraints.  The later one is a big deal because it means that we
can allow ".Foo" expressions as ambiguous solutions, which CSDiags can
handle well.

This unblocks solving 23942743 and enables some minor improvements across
the board, including diagnosing things like this better:
  Optional(.none)  // now: generic parameter 'T' could not be inferred

That said, it also just permutes some non-awesome diagnostics.
2016-01-11 17:04:46 -08:00
Jacob Bandes-Storch
ce2f5d6ba8 [Sema] Skip ErrorTypes in potential bindings during constraint solving 2016-01-08 22:45:52 -08:00
practicalswift
31ff35e1dd Use 80 column headers consistently. 2016-01-04 01:35:02 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Chris Lattner
1909e83034 fix <rdar://problem/23798944> = vs. == in Swift if string character count statement causes segmentation fault
This is a really nasty problem where we'd explode trying to unify type variables
we found in the constraint graph, that didn't exist in the constraint system.  This
happened because diagnostic generation is simplifying the system in
"ContinueAfterFailures" mode to try to get to a minimal system (to avoid
producing an error message about trivially solvable constraints that only
exist due to the solver stopping early) and in this mode we would see an
erroneous constraint, remove it from the constraint system, but not the
constraint graph.  This only mattered in ContinueAfterFailures.

As with many things, the fix is pretty simple once the onion is peeled enough
to find the stinky part lurking inside.
2015-12-22 23:12:50 -08:00
practicalswift
36d7072013 Remove immediately adjacent repeated words ("the the", "for for", "an an", etc.). 2015-12-21 22:16:04 +01:00
practicalswift
8ab8847684 Fix typos. 2015-12-16 22:09:32 +01:00
Justas Brazauskas
043c518b27 Fix typos 2015-12-09 17:54:54 +02:00
Davide Italiano
40d7a0acaf [Sema/CSSolver] Moving a local object in return prevents copy elision. 2015-12-07 20:45:49 +00:00
Chris Willmore
49e5130103 Allow inout closure param type to be inferred from context or usage.
Introduce a new constraint kind, BindParam, which relates the type of a
function parameter to the type of a reference to it from within the
function body. If the param type is an inout type, the ref type is an
lvalue type with the same underlying object type; otherwise the two
types must be the same. This prevents DeclRefExprs from being inferred
to have inout type in some cases.

<rdar://problem/15998821> Fail to infer types for closure that takes an inout argument

Swift SVN r32183
2015-09-23 18:46:12 +00:00
Chris Willmore
e274f7b04d Don't favor exploring potential bindings of type variable if those
bindings only bound the type variable from above with existential types.

<rdar://problem/22459135> error: 'print' is unavailable: Please wrap your tuple argument in parentheses: 'print((...))'

Swift SVN r31953
2015-09-15 00:28:58 +00:00
Chris Lattner
f6ce68a45a remove ConstraintKind::Conjunction, it is unused and unnecessary - after
all, the whole system is a conjunction!


Swift SVN r31284
2015-08-18 00:47:28 +00:00
Chris Lattner
a899872d91 Reapply r31105, with some fixes to invalid unconstrained generics. These fixes correct
the regressions that r31105 introduced in the validation tests, as well as fixing a number
of other validation tests as well.

Introduce a new UnresolvedType to the type system, and have CSDiags start to use it
as a way to get more type information out of incorrect subexpressions.  UnresolvedType
generally just propagates around the type system like a type variable:
 - it magically conforms to all protocols
 - it CSGens as an unconstrained type variable.
 - it ASTPrints as _, just like a type variable.

The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to 
diagnose subexpressions w.r.t. their types.

For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.

We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type 
variables as UnresolvedTypes.  This allows us to get more precise information out,
for example, diagnosing:

 func r22162441(lines: [String]) {
   lines.map { line in line.fooBar() }
 }

with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context

This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.





Swift SVN r31130
2015-08-11 06:06:05 +00:00
Chris Lattner
2204dbcbfd revert r31105, it causes some regressions on validation tests.
Swift SVN r31107
2015-08-10 15:01:22 +00:00
Chris Lattner
de79b60c89 Introduce a new UnresolvedType to the type system, and have CSDiags start to use it
as a way to get more type information out of incorrect subexpressions.  UnresolvedType
generally just propagates around the type system like a type variable:
 - it magically conforms to all protocols
 - it CSGens as an unconstrained type variable.
 - it ASTPrints as _, just like a type variable.

The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to 
diagnose subexpressions w.r.t. their types.

For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.

We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type 
variables as UnresolvedTypes.  This allows us to get more precise information out,
for example, diagnosing:

 func r22162441(lines: [String]) {
   lines.map { line in line.fooBar() }
 }

with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context

This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.



Swift SVN r31105
2015-08-10 06:18:27 +00:00
Chris Lattner
4a5be366c2 add a new ContinueAfterFailures default argument to ConstraintSystem::simplify,
and use it in the diagnostics path (only!) to revisit active constraints that
are left in the system after a failure is found.  This improves a number of 
otherwise sad diagnostics in the testsuite and resolves rdar://22083115.

The one QoI regression (in throwing_functions.swift) is now tracked by 22158167.



Swift SVN r31027
2015-08-05 20:57:39 +00:00
Chris Lattner
9e7f602198 Handle diagnosing unbound archetypes in the outer level ambiguity diagnostics
machinery, instead of in multiple places in CSSolver and CSDiags.  This leads
to more predictable behavior (e.g. by removing the UnboundGenericParameter
failure kind) and eliminates a class of "'_' is not convertible to 'FooType'"
diagnostics.



Swift SVN r30923
2015-08-01 22:16:56 +00:00
Ben Langmuir
c1a2955ef6 Revert r30787, r30789, r30795, r30796, r30797
r30787 causes our tests to time out; the other commits depend on r30787.

Revert "revert part of my previous patch."
Revert "Produce more specific diagnostics relating to different kinds of invalid"
Revert "add a testcase, nfc"
Revert "- Reimplement FailureDiagnosis::diagnoseGeneralMemberFailure in terms of"
Revert "Fix places in the constraint solver where it would give up once a single "

Swift SVN r30805
2015-07-30 17:44:22 +00:00
Chris Lattner
4fb19ada2b Fix places in the constraint solver where it would give up once a single
constraint failed, leaving a bunch of other solvable constraints laying 
around in the system as inactive.

This is a problem for diagnostics emission, because it turns around and
reaches into the constraint system for some inactive constraint, assuming
that anything left could not be solved.  The constraint system attempted to
solve this by taking the first failure and putting it into the failedConstraint
with the intention of driving diagnostics, but just because it happened to fail
first in constraint-solver-worklist-order doesn't mean it is the most pertinent
one to diagnose.



Swift SVN r30787
2015-07-30 05:08:50 +00:00
John McCall
50a667b295 Instead of assuming that the return type of a closure
with no returns *must* be (), add a defaulting constraint
so that it will be inferred as () in the absence of
other possibilities.

The chief benefit here is that it allows better QoI when
the user simply hasn't yet written the return statement.

Doing this does regress a corner case where an attempt
to recover from an uncalled function leads to the
type-checker inferring a result for a closure that
doesn't make any sense at all.

Swift SVN r30476
2015-07-22 00:13:02 +00:00
Chris Lattner
ab487a17b5 Introduce a new TypeCheckExprFlags::AllowUnresolvedTypeVariables option,
which allows solving of a constraint system to succeed without emitting
errors in the face of ambiguous solutions.  This is important for CSDiag
because it is in the business of trying to solve subexpressions of a global
expression - and it wants to know the difference between a subexpression
that is inherently impossible to solve, vs one that is simply ambiguous
because its context has been removed.

Use this in CSDiag's typeCheckChildIndependently() to provide it an
extra flag that enables this behavior.  This is currently unused, so NFC 
with this patch.


Swift SVN r30402
2015-07-20 16:16:54 +00:00
Doug Gregor
d7ccd18faa Split ConstraintSystem::solve() into a top-level and a recursive entrypoint.
NFC, but improves sanity because the two uses had different meanings
for the "bool" result :)

Swift SVN r30177
2015-07-13 23:50:04 +00:00
Chris Lattner
85be767182 introduce a new ConstraintSystem::solveSingle helper function to simplify some
clients.  NFC.



Swift SVN r30163
2015-07-13 21:22:24 +00:00
Doug Gregor
a30ca2a60d Replace bool parameter to TypeChecker::conformsToProtocol() with an option set.
NFC; we can extend this option set more readily later.

Swift SVN r27894
2015-04-29 00:08:22 +00:00
Chris Lattner
976620b513 random tidying up, rename the raw_ostream form of
ConstraintSystem::dump to ConstraintSystem::print for
consistency with other parts of the compiler.  Enhance
CS::print to print the ID # of a Type Variable, so you
don't have to count them to realize that you're looking
at typevar #13


Swift SVN r27874
2015-04-28 17:50:24 +00:00
Doug Gregor
f4d98da668 Support the use of members of protocol extensions on existential types.
To use members of protocol extensions on existential types, we
introduce an OpenExistentialExpr expression to open up the existential
type (into a local archetype) and perform the operations on that local
archetype.

Unlike with uses of initializers or dynamic-Self-producing
methods of protocols, which produce similar ASTs, we have the type
checker perform the "open" operation and then track it through
constraint application. This scheme is better (because it's more
direct), but it's still using a simplistic approach to deciding where
the actual OpenExistentialExpr goes that needs improvement.

Swift SVN r26964
2015-04-04 00:00:14 +00:00
Chris Lattner
79ed57f9f2 standardize naming of tuples and tuple patterns on "elements".
Previously some parts of the compiler referred to them as "fields",
and most referred to them as "elements".  Use the more generic 'elements'
nomenclature because that's what we refer to other things in the compiler
(e.g. the elements of a bracestmt).

At the same time, make the API better by providing "getElement" consistently
and using it, instead of getElements()[i].

NFC.



Swift SVN r26894
2015-04-02 20:23:49 +00:00
Doug Gregor
3805e18090 Explicitly track the mapping from dependent types to their opened type variables.
Previously, we were reconstructing this mapping from the "full" opened
type produced by declaration references. However, when dealing with
same-type constraints between associated types and type parameters, we
could end up with an incomplete mapping, which let archetypes slip
through. Most of the churn here is sorting out the locators we need to
use to find the opened-type information. Fixes rdar://problem/18208283
and at least 3 dupes of it that I've found so far.

Swift SVN r25375
2015-02-18 19:41:40 +00:00
Chris Willmore
68dd563fbf <rdar://problem/18311362> TLF: Eliminate implicit bridging conversions
Require 'as' when converting from Objective-C type to native type (but
continue to allow implicit conversion from native to Objective-C). This
conversion constraint is called ExplicitConversion; all implicit
conversions are covered by the existing Conversion constraint. Update
standard library and tests to match.

Swift SVN r24496
2015-01-18 00:07:45 +00:00
Jordan Rose
2b0fbcbe80 Looking up conformances for a type isn't always a public use of the type.
Specifically, it's not when
- the conformance is being used within a function body (test included)
- the conformance is being used for or within a private type (test included)
- the conformance is being used to generate a diagnostic string

We're still a bit imprecise in some places (checking ObjC bridging), but
in general this means less of an issue for checking literals.

Swift SVN r23700
2014-12-05 00:23:24 +00:00