In Swift 3.0.1, argument labels are ignored when calling a function
having a single parameter of 'Any' type. That is, if we have:
func foo(_: Any) {}
Both of the following were accepted in a no-assert build (an assert
build would crash, but the GM builds of Xcode ship with asserts off):
foo(123)
foo(data: 123)
This behavior was fixed by 578e36a7e1,
but unfortunately we have to revert to the old behavior *and* defeat
the assertion when in Swift 3 mode.
Swift 4 mode still has the correct behavior, where the second call
'foo(data: 123)' produces a diagnostic.
Now, I have to pour myself a strong drink to forget this ever happened.
Fixes <rdar://problem/28952837>.
There's a general problem where a SubscriptExpr has an argument
that's a LoadExpr loading a tuple from an lvalue. For some reason
we don't construct the ParenExpr in this case, which confused
CSDiag.
Also, in Swift 3 mode, add a total hack to fudge things in
matchCallArguments() in the case where we erroneously lost
ParenType sugar.
This parameter implements getType() for the given expression, making
it possible to use this from within the constraint system, which now
has it's own side map for types of expressions.
Update CSGen/CSApply/CSSolver to primarily use getType() from
ConstraintSystem.
Currently getType() just returns the type on the expression. As with
setType(), which continues to set the type on the expression, this
will be updated once all the other changes are in place.
This change also moves coerceToRValue from TypeChecker to
CosntraintSystem so that it can access the expression type map in the
constraint system.
I've been unable to reproduce the issue that hit on the builder, and
still expect this change to be NFC, so trying it out again. If it
fails, I'll revert again and try another shot at reproducing.
Original commit message:
We create new expressions that have the type on the expression
set. Make sure we capture these types in the constraint system type
map so that we can refer to types uniformally by consulting the map.
NFC.
(cherry picked from commit 57d5d974ff)
We create new expressions that have the type on the expression
set. Make sure we capture these types in the constraint system type
map so that we can refer to types uniformally by consulting the map.
NFC.
The setType() function in ConstraintSystem still sets the types on the
expressions themselves and that will continue until everything is
moved over to using the map.
Unfortunately this exposed cases where we are currently setting the
type multiple times to different values, so I've commented out the
assert that I previously added. I will circle back and start looking
into those issues once everything is moved over.
NFC for now.
This method gets the GenericTypeDecl for a typealias, nominal type, or
extension thereof. While the result is typed as GenericTypeDecl, it's
not always generic, so rename it accordingly.
An audit of the callers illustrated that they should be using
different entrypoints anyway, so fix all of the callers and make this
function private.
Another oddly-named utility function with poorly-defined behavior.
It returned true for archetypes, generic parameters, existential
types, and metatypes of existential types.
However, it would return false for dependent member types, or
metatypes of archetypes, and so on.
All the callers were doing something bad to begin with, so
changing them over to more precise predicates improved the code.
In particular, this simplifies substitution construction in
the SIL parser, and makes it stricter, which turned up a couple
of mistakes in the SIL tests where we were doing stuff with
non-conforming types.
After recent changes, this asserts on all decls that are not VarDecls,
so we can just enforce that statically now. Interestingly, this turns
up some dead code which would have asserted immediately if called.
Also, replace AnyFunctionRef::getType() with
AnyFunctionRef::getInterfaceType(), since the old
AnyFunctionRef::getType() would just assert when called on
a Decl.
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>.
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>.
Previously, getInterfaceType() would return getType() if no
interface type was set. Instead, always set an interface type
explicitly.
Eventually we want to remove getType() altogether, and this
brings us one step closer to this goal.
Note that ParamDecls are excempt from this treatment, because
they don't have a proper interface type yet. Cleaning this up
requires more effort.
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>.
Type substitution works on a fairly narrow set of types: generic type
parameters (to, e.g., use a generic) and archetypes (to map out of a
generic context). Historically, it was also used with
DependentMemberTypes, but recent refactoring to eliminate witness
markers eliminate that code path.
Therefore, narrow TypeSubstitutionMap's keys to SubstitutableType,
which covers archetypes and generic type parameters. NFC
This function had a weird, pre-ProtocolConformanceRef interface that
returned true when the type conformed to the protocol, then had a
separate indirect return value for the concrete conformance (if there
is one). Refactor this API, and the similar
TypeChecker::containsProtocol(), to produce an optional
ProtocolConformanceRef, which is far more idiomatic and easier to
use. Push ProtocolConformanceRef into a few more places. Should be NFC
It's possible some of the asserts will eventually migrate to something
like test-and-return, but at least for now let's ensure that we know
when this is happening.
This is not comprehensive. There are other places we are creating fresh
constraint systems and then creating constraints using type variables
from a pre-existing constraint systems.
Rather than computing the requirement environment as a tuple of
(generic signature, generic environment, substitution map),
encapsulate the result in a new RequirementEnvironment
class. Moreover, create a RequirementEnvironment once and re-use it
when matching each of the witnesses, because the environment itself
doesn't change---only the substitutions do. This saves us some work
when there are multiple potential witnesses (which is common).
The warnings here are not ideal, nor are the fixits, but having a
correct source location at least helps users determine where the
conversions are happening.
I've filed https://bugs.swift.org/browse/SR-2928 to improve the warnings
and fixits.
This resolves https://bugs.swift.org/browse/SR-2921 and the warning
location portion of rdar://problem/28722908.
While, tracking defaulted constraints based on their type variable
usually works in practice, it can break if the type variable ends up
being equivalent to some other type variable that. Instead, record the
locators associated with Defaultable constraints where we used the
default, which are easier to work with during constraint application.
In most places where we were checking "is<ErrorType>()", we now mean
"any error occurred". The few exceptions are in associated type
inference, code completion, and expression diagnostics, where we might
still work with partial errors.
Type::subst()'s "IgnoreMissing" option was fairly unprincipled, dropping
unsubstituted types into the resulting AST without any indication
whatsoever that anything went wrong. Replace this notion with a new
form of ErrorType that explicitly tracks which substituted type caused
the problem. It's still an ErrorType, but it prints like the
substituted type (which is important for code completion) and allows
us to step back to the substituted type if needed (which is used by
associated type inference). Then, allow Type::subst(), when the new
UseErrorTypes flag is passed, to form partially-substituted types that
contain errors, which both code completion and associated type
inference relied on.
Over time, I hope we can use error-types-with-original-types more
often to eliminate "<<error type>>" from diagnostics and teach
Type::subst() never to return a "null" type. Clients can check
"hasError()" to deal with failure cases rather than checking null.
This fixes a usability regression with the removal of @noreturn
in Swift 3. Previously, it was legal to write this:
let callback: () -> Int = { fatalError() }
Now that the special @noreturn attribute has been replaced with
a Never type, the above fails to typecheck, because the expression
now has type 'Never', and we expect a value of type 'Int'.
Getting around this behavior requires ugly workarounds to force the
parser to treat the body as a statement rather than an expression;
for example,
let callback: () -> Int = { _ = (); fatalError() }
This patch generalized single-expression closures to allow
the 'Never to T' conversion. Note that this is rather narrow
in scope -- it only applies to closure *literals*, single-expression
ones at that, not arbitrary function *values*.
In fact, it is not really a conversion at all, but more of a
desugaring rule for single-expression closures. They can now be
summarized as follows:
- If the closure literal has contextual return type T and
the expression has Never type, the closure desugars as
{ _ = <expr> }, with no ReturnStmt.
- If the closure literal has contextual return type T for some
non-void type T, the closure desugars as { return <expr> };
the expression type must be convertible to T.
- If the closure literal has contextual return type Void, and
the expression has some non-Void type T, the closure
desugars as { _ = <expr>; return () }.
Fixes <rdar://problem/28269358> and <https://bugs.swift.org/browse/SR-2661>.