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
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
Do this by only warning on self-referential uses of a variable when there's
not another binding found in the local scope. This probably still restricts
some reasonable edge cases, but it at least allows shadowing the variable
with a local name.
<rdar://problem/17087232>
Swift SVN r18771
There's a lot more work to do here, but start to categorize tests
along the lines of what a specification might look like, with
directories (chapters) for basic concepts, declarations, expressions,
statements, etc.
Swift SVN r9958
In this syntax, the closure signature (when present) is placed within
the braces and the 'in' keyword separates it from the body of the
closure, e.g.,
magic(42, { (x : Int, y : Int) -> Bool in
print("Comparing \(x) to \(y).\n")
return y < x
})
When types are omitted from the parameter list, one can also drop the
parentheses, e.g.,
magic(42, { x, y -> Bool in
print("Comparing \(x) to \(y).\n")
return y < x
})
The parsing is inefficient and recovers poorly (in part because 'in'
is a contextual keyword rather than a real keyword), but it should
handle the full grammar. A number of tests, along with the whitepaper
and related rational documents, still need to be updated. Still, this
is the core of <rdar://problem/14004323>.
Swift SVN r6105
'|' is part of the character set for operators, but within the
signature of a closure we need to treat the first non-nested '|' as
the closing delimiter for the closure parameter list. For example,
{ |x = 1| 2 + x}
parses with the default value of '1' for x, with the body 2 + x. If
the '|' operator is needed in the default value, it can be wrapped in
parentheses:
{ |x = (1|2)| x }
Note that we have problems with both name binding and type checking
for default values in closures (<rdar://problem/13372694>), so they
aren't actually enabled. However, this allows us to parse them and
recover better in their presence.
Swift SVN r5202
This commit implements closure syntax that places the (optional)
parameter list in pipes within the curly braces of a closure. This
syntax "slides" well from very simple closures with anonymous
arguments, e.g.,
sort(array, {$1 > $0})
to naming the arguments
sort(array, {|x, y| x > y})
to adding a return type and/or parameter types
sort(array, {|x : String, y : String| -> Bool x > y})
and with multiple statements in the body:
sort(array, {|x, y|
print("Comparing \(x) and \(y)\n")
return x > y
})
When the body contains only a single expression, that expression
participates in type inference with its enclosing expression, which
allows one to type-check, e.g.,
map(strings, {|x| x.toUpper()})
without context. If one has multiple statements, however, one will
need to provide additional type information either with context
strings = map(strings, {
return $0.toUpper()
})
or via annotations
map(strings, {|x| -> String
return x.toUpper()
}
because we don't perform inter-statement type inference.
The new closure expressions are only available with the new type
checker, where they completely displace the existing { $0 + $1 }
anonymous closures. 'func' expressions remain unchanged.
The tiny test changes (in SIL output and the constraint-checker test)
are due to the PipeClosureExpr AST storing anonymous closure arguments
($0, $1, etc.) within a pattern in the AST. It's far cleaner to
implement this way.
The testing here is still fairly light. In particular, we need better
testing of parser recovery, name lookup for closures with local types,
more deduction scenarios, and multi-statement closures (which don't
get exercised beyond the unit tests).
Swift SVN r5169