Commit Graph

844 Commits

Author SHA1 Message Date
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
Ben Langmuir
e9e1666ab0 Update for upstream LLVM changes
* removal of StringMap's GetOrCreateValue
* SmallSet::insert now returns a pair like std::set

Swift SVN r23435
2014-11-19 16:49:30 +00:00
Chris Willmore
bd1d9f3d8f Use llvm_unreachable(...) instead of assert(false && ...).
Swift SVN r23142
2014-11-06 23:41:24 +00:00
Chris Willmore
c021b7ac1f If $T1 <a @autoclosure () -> T, try binding $T1 to T.
rdar://problem/18447543

Swift SVN r23141
2014-11-06 23:17:08 +00:00
Jordan Rose
042569a3be Optional: Replace uses of Nothing with None.
llvm::Optional (like Swift.Optional!) uses None as its placeholder value,
not Nothing.

Swift SVN r22476
2014-10-02 18:51:42 +00:00
Doug Gregor
8cca0ae85d Solver: eliminate construction constraints. We never need to retain them.
Swift SVN r22432
2014-10-01 18:25:49 +00:00
Doug Gregor
45953c5b96 Solver: try binding collection literals before non-collection literals.
Trying a collection literal early often means that we can determine
the element type from context, which saves us the work of trying to
guess at the element type firsthand.

Doing this seems to help some cases significantly: 
  - test/stdlib/ArrayNew.swift got about 20% faster in a release build
  - I had to drop the threshold for the "expression too complex" test
    case by 20x to still trigger the issue.






Swift SVN r22097
2014-09-18 20:40:20 +00:00
Doug Gregor
e002261865 Diagnose free type variables that correspond to generic parameters.
t2.swift:3:1: error: argument for generic parameter 'U' could not be
inferred
f(i)
^
t2.swift:2:6: note: in call to function 'f'
func f<T, U>(t: T) -> U? { return nil }
     ^

Our lack of decent locator information means that we don't get notes
in all of the cases we want them. I'll look at that separately.

Swift SVN r21921
2014-09-12 20:27:21 +00:00
Doug Gregor
43b6ed364a Thread constraint locators through opening of generic types.
Locators that refer to opened type parameters now carry information
about the source location where we needed to open the type, so that
(for example) we can trace an opened type parameter back to the
location it was opened. As part of this, eliminate the "rootExpr"
fallback, because we're threading constraint locators everywhere.

This is infrastructural, and should be NFC.

Swift SVN r21919
2014-09-12 20:27:19 +00:00
Doug Gregor
f27c8d1b31 Solver: use literal constraints to eagerly look through optional types.
When we have a literal constraint on an optional type, and the
optional does not itself conform to the literal protocol, look through
the optional to determine whether its underlying type conforms to the
protocol. This essentially helps filter out dumb solutions that try
optional types where we should just be relying on the
value-to-optional conversion.

Should be NFC, since we would find the same solutions anyway.

Swift SVN r21918
2014-09-12 20:27:15 +00:00
Doug Gregor
c3ca1475e1 Solver: don't try a default literal type binding when we have contextual type information.
When computing the set of potential bindings for a type variable with
a literal constraint, we suggest the default literal type as a
fallback. Suppress this suggestion in the cases where another
constraint provides a type that already has some kind of contextual
type information (that does conform to the protocol), making the
default literal type more of a fallback. When type-checking the given
declaration:

  var dict: NSDictionary = [
    "status": 200,
    "people": [ [ "id": 255,
                  "name": [ "first": "John", "last": "Appleseed" ] ] ] ]

it reduces the number of solution states explored by 2/3, the number
of attempted type variable bindings by 3/4, and the number of
disjunctions explored by 1/3. This optimization is useful in general,
and lets type annotations guide the type checker to a much greater
extent. It also helps with rdar://problem/18269449.

Swift SVN r21878
2014-09-11 17:11:59 +00:00
Doug Gregor
16d8294814 Don't allow bridging conversions when we're processing favored constraints.
This is another instance where we choose a favored constraint that
only type checks because we're bridging through NSNumber, causing
awful problems. Fixes rdar://problem/17962491.


Swift SVN r21445
2014-08-25 22:16:58 +00:00
Doug Gregor
916e9a7eb5 Fix computation of “favored” constraints for binary expressions <rdar://problem/17943223>.
The determination of “favored” constraints for binary expressions was comparing the second argument to the first parameter to decide if the constraint is favored. Coupled with implicit bridging conversions through NSNumber, this meant that “1.0/10” would become Int when Foundation was imported, and hilarity ensued.

Fix the heuristic for favored constraints, tidy up this code a bit, and add ==(NSString, NSString) to cope with the ambiguity this creates.

Swift SVN r21154
2014-08-12 21:16:59 +00:00
Doug Gregor
6cac2062c9 Solver: if we fail to type-check with an implicitly unwrapped optional type, unwrap it.
Fixes <rdar://problem/17220209>, so we properly implicitly unwrap in
more cases.

Swift SVN r21022
2014-08-04 18:45:31 +00:00
Joe Pamer
71cf758055 Mitigate exponential solver behavior (rdar://problem/17162690)
While we work out the remaining performance improvements in the type checker, we can improve the user experience for some "runaway solver" bugs by setting a limit on the amount of temporary memory allocated for type variables when solving over a single expression.

Exponential behavior usually manifests itself while recursively attempting bindings over opened type variables in an expression. Each one of these bindings may result in one or more fresh type variables being created. On average, memory consumption by type variables is fairly light, but in some exponential cases it can quickly grow to many hundreds of megabytes or even gigabytes. (This memory is managed by a distinct arena in the AST context, so it's easy to track.) This problem is the source of many of the "freezing" compiler and SourceKit bugs we've been seeing.

These changes set a limit on the amount of memory that can be allocated for type variables while solving for a single expression. If the memory threshold is exceeded, we can surface a type error and suggest that the user decompose the expression into distinct, less-complex sub-expressions.

I've set the current threshold to 15MB which, experimentally, avoids false positives but doesn't let things carry on so long that the user feels compelled to kill the process before they can see an error message. (As a point of comparison, the largest allocation of type variable data while solving for a single expression in the standard library is 592,472 bytes.) I've also added a new hidden front-end flag, "solver-memory-threshold", that will allow users to set their own limit, in bytes.

Swift SVN r20986
2014-08-03 23:10:42 +00:00
Joe Groff
cd799f6797 Sema: Coerce structural lvalues when binding to non-lvalue type variables.
Modify TypeBase::getRValueType to structurally convert lvalues embedded in tuple and paren types. Inside the constraint solver, coerce types to rvalues based on the structural 'isLValueType' test rather than shallow 'is<LValueType>' checking. Fixes <rdar://problem/17507421>, but exposes an issue with call argument matching and lvalues <rdar://problem/17786730>.

Swift SVN r20442
2014-07-23 23:07:21 +00:00
Chris Lattner
bc481f0fe1 implement <rdar://problem/16859927> remove the underscore in "auto_closure"
autoclosure is one work, not two.



Swift SVN r20253
2014-07-21 15:23:50 +00:00
Joe Groff
ed88875794 Sema: Propagate lvalue-ness through the postfix ! operator.
Create a new "OptionalObject" constraint kind in the solver that relates an optional type to its payload type, preserving lvalue-ness, and use it to model ForceValueExpr under the optional-lvalues regime.

Swift SVN r20140
2014-07-18 04:37:00 +00:00
Joe Pamer
6a75d3d675 Now that the most problematic user conversions have been removed from the runtime (thanks, Doug!), we can remove the operator-specific user conversion handling code matchCallArguments. Doing so cleans things up a bit, and addresses rdar://problem/17540796, rdar://problem/17012694 and rdar://problem/16958107.
Swift SVN r19871
2014-07-12 00:41:27 +00:00
Joe Pamer
da59d305c9 Greatly improve type checker performance when inferring types for certain binary
expression applications

(rdar://problem/15933674, rdar://problem/17365394 and many, many dupes.)

When solving for the type of a binOp expression, factor the operand expression
types into account when collating overloads for the operator being applied.
This allows the type checker to now infer types for some binary operations with
hundreds of nested components, whereas previously we could only handle a handful.
(E.g., "1+2+3+4+5+6" previously sent the compiler into a tailspin.)

Specifically, if one of the operands is a literal, favor operator overloads
whose operand, result or contextual types are the default type of the literal
convertible conformance of the the argument literal type.

By doing so we can prevent exponential behavior in the solver and massively
reduce the complexity of many commonly found constraint systems. At the same
time, we'll still defer to "better" overloads if the default one cannot be
applied. (When adding an Int8 to an Int, for example.)

This obviously doesn't solve all of our performance problems (there are more
changes coming), but there are couple of nice side-effects:
- By tracking literal/convertible protocol conformance info within type
variables, I can potentially eliminate many instances of "$T0" and the
like from our diagnostics.
- Favored constraints are placed at the front of the overload resolution
disjunction, so if a system fails to produce a solution they'll be the
first to be mined for a cause. This helps preserve user intent, and leads
to better diagnostics being produced in some cases.

Swift SVN r19848
2014-07-11 16:24:42 +00:00
Joe Groff
3c539b7f24 Sema: Look through optional types for .member lookup.
When we see a '.member' expression in optional context, look for the member in the optional's object type if it isn't found in Optional itself. <rdar://problem/16125392>

Swift SVN r19469
2014-07-02 16:33:45 +00:00
Joe Groff
fb7ef8c2a1 Sema: Allow inout-to-pointer conversions for pointers to arrays.
We need to admit a potential inout-to-pointer conversion even if the inout references an array, because we can have pointers to arrays. Add a short-circuit so that array-to-pointer conversions always beat inout-to-pointer conversions; both solutions could otherwise be considered valid for an UnsafePointer<Void>, and passing a pointer to the array reference rather than to the array data would be very bad.

Swift SVN r19270
2014-06-26 22:37:27 +00:00
Doug Gregor
39bcf3bd85 Re-sugar the types we deduce for type variables.
This makes us deduce types like "[Int]" and "[String : Int]" from
array/dictionary literals, giving a nicer REPL experience.


Swift SVN r19258
2014-06-26 22:04:47 +00:00
Joe Groff
08a48565fb Sema: Introduce intrinsic pointer argument conversions.
Add primitive type-checker rules for pointer arguments. An UnsafePointer argument accepts:

- an UnsafePointer value of matching element type, or of any type if the argument is UnsafePointer<Void>,
- an inout parameter of matching element type, or of any type if the argument is UnsafePointer<Void>, or
- an inout Array parameter of matching element type, or of any type if the argument is UnsafePointer<Void>.

A ConstUnsafePointer argument accepts:

- an UnsafePointer, ConstUnsafePointer, or AutoreleasingUnsafePointer value of matching element type, or of any type if the argument is ConstUnsafePointer<Void>,
- an inout parameter of matching element type, or of any type if the argument is ConstUnsafePointer<Void>, or
- an inout or non-inout Array parameter of matching element type, or of any type if the argument is ConstUnsafePointer<Void>.

An AutoreleasingUnsafePointer argument accepts:

- an AutoreleasingUnsafePointer value of matching element type, or
- an inout parameter of matching element type.

This disrupts some error messages in unrelated tests, which is tracked by <rdar://problem/17380520>.

Swift SVN r19008
2014-06-19 18:03:10 +00:00