A lot of files transitively include Expr.h, because it was
included from SILInstruction.h, SILLocation.h and SILDeclRef.h.
However in reality most of these files don't do anything
with Exprs, especially not anything in IRGen or the SILOptimizer.
Now we're down to 171 files in the frontend which depend on
Expr.h, which is still a lot but much better than before.
In particular, it doesn't "toll-free bridge" to the Error existential on non-ObjC-interop platforms, and we would miscompile as if it could. This should fix SR-585.
Previously we would check TMF_UnwrappingOptional flag, which does not
stick with the constraint, so it would not always persist. Now, add a
new OptionalPayload locator element, which is more correct.
Fixes <rdar://problem/30429709>.
We previously penalized bindings to Any, and that resulted in
inappropriately rejecting solutions where we bind a decl that is
explicitly typed Any. That penalty was removed in
170dc8acd7, but that has led to a variety
of source compatibility issues.
So now, we'll reintroduce a penalty for Any-typed things, but instead of
penalizing bindings (which happen both because of explicitly-typed
values in the source, and implicitly due to attempting various types for
a particular type variable), penalize casts, which are always present in
some form in the source.
Thanks go to John for the suggestion.
Fixes
SR-3817 (aka rdar://problem/30311052)
SR-3786 (aka rdar://problem/30268529)
rdar://problem/29907555
This change is needed by a separate change I have that penalizes
conversions to Any. That change exposed a problem where we ended up
doing a direct lvalue-to-Any conversion without first loading as part of
an lvalue-to-rvalue conversion.
We should really only be doing most of these other conversions/fixes on
rvalues.
Unfortunately I don't know of a way to hit this without the other
change, and thus don't have a test case.
As a side note, this also helps some (perhaps most, but definitely not
all) of the exponential type inference cases involving arrays and
dictionaries. Unfortunately again, we don't currently have a testing
mechanism in place to ensure we don't regress those cases, and I don't
want to add a test that will completely hang every bot if it does
regress, so...*sad face*...no test case for that either.
We limit Optional-to-IUO as an implicit conversion to avoid making
common expressions ambiguous. However, this runs into trouble with
function-to-function conversions, which always look for a "Subtype"
relationship for their inputs and outputs. This is a conservative way
for Sema to avoid emitting conversions that SILGen cannot handle.
The problem case here is converting a closure with type '(Any!) ->
Void' to a value of type '(Any?) -> Void':
let f: ((Any?) -> Void) = { (arg: Any!) in }
This is clearly a safe conversion, since 'Any!' and 'Any?' have the
same representation at run time, but historically we've disallowed it
because of the above rules. However, in Swift 3.0 this particular case
was permitted, with the type checker deciding that the 'Any?' argument
to 'f' could first itself be put into an 'Any', then /that/ value
could go through a value-to-optional conversion to make 'Any!'.
Fortunately the emitted code didn't follow this incorrect conversion
path.
This patch doesn't even try to emulate the old behavior. Instead, it
just weakens the restriction on Optional-to-IUO via a new type
matching flag that only applies within the context of matching
function types.
We can consider opening up function conversions in Swift 4 to anything
that supports conversion---not just subtyping---now that SILGen knows
how to automatically reabstract most such things. But whether we do or
not, Optional/IUO is a special case.
https://bugs.swift.org/browse/SR-3758
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
When I refactored the handling of bridging conversions (e.g.,
valueType as? NSClassType), I broke the path that performed a bridging
conversion followed by a conversion to an existential, e.g.,
"some-bridged-value-type as CVarArg". Reinstate such use cases.
Fixes rdar://problem/30195862.
Without this, CSGen/CSSimplify and CSApply may have differing
opinions about whether e.g. a let property is settable, which
can lead to invalid ASTs.
Arguably, a better fix would be to remove the dependency on the
exact nested DC. For example, we could treat lets as settable
in all contexts and then just complain later about invalid
attempts to set them. Or we could change CSApply to directly
use the information it already has about how an l-value is used,
rather than trying to figure out whether it *might* be getting set.
But somehow, tracking a new piece of information through the
entire constraint system seems to be the more minimal change.
Fixes rdar://29810997.
Revert 7c665c105b because it results in a
much worse source compatibility regression than the one it was intended
to fix.
The problem is that it results in force-unwrapping IUOs, which can lead
to cases where we prefer type-checking solutions that choose methods
over properties where we used to choose properties. So for example a
collection literal like [x] will result in a collection with a method
named 'x' in it rather than a property named 'x'.
I'll be looking at other solutions which fix both the original
compatibility regression as well as retain the behavior in the new test
added here.
Fixes SR-3715 and rdar://problem/30176166.
1efafbcd9b restricted our classification
of various optional-related conversions (implicit forcing of IUOs,
optional-to-optional conversions, value-to-optional conversions) to
produce a single potential classification. However, in the presence of
type variables, we cannot always determine which particular conversion
restriction might apply. Prior to 1efafb, we produced too many
options; after 1efafb, we produced too few. Here, enumerate a more
bounded (but complete) set of potential conversions, taking into
account embedded type variables.
This is a better fix for rdar://problem/29977523 than simply reverting
1efafb, because it bounds the set of optional conversions we attempt.
This reapply's Doug's change d79ba781c6,
which had previously been applied on top of
1efafbcd9b, the latter of which resulted
in a source compatibility break.
This reverts commit 1efafbcd9b because
results in a regression in source compatibility with Swift 3.
It also adds a test demonstrating what was broken by the change.
I will take another look at fixing the exponential behavior that this
was attempting to fix.
Fixes rdar://problem/29977523.
In Swift 4 mode, no longer consider e.g. 'nsNumber as Int' or 'nsValue as NSRange' to be valid coercions. This would break compatibility with Swift 3, so in Swift 3 mode, accept the coercion, but *also* accept a checked cast without a warning, and raise a migration warning about the unchecked coercion.
Commit 170dc8acd7 removed a penalty that
we used to have for conversions to Any. In some unusual circumstances
not having that penalty can result in new amiguities where we should
have nothing ambiguous about an expression according to our type rules.
This change attempts to ensure that we make that less likely or
impossible by not allowing direct conversions from IUOs to Any (instead
forcing these to first be force-unchecked, leading to more expensive
solutions). We never should have allowed these conversions anyway,
independent of removing the penalty for conversions to Any.
This change is intentionally very narrow to avoid further potential
source breakage.
Fixes rdar://problem/29907555.
This commit introduces new kind of requirements: layout requirements.
This kind of requirements allows to expose that a type should satisfy certain layout properties, e.g. it should be a trivial type, have a given size and alignment, etc.
Convert subtype constraints with inout on one side and type variable
on the other into fixed binding. Constriants like `inout T0 subtype T1`
where (T0 must be materializable) are created when closures are part
of the generic function parameters e.g. `func foo<T>(_ t: T, (inout T) -> Void) {}`
so when such function gets called e.g.
```
var x = 42
foo(x) { $0 = 0 }
```
it's going to try and map closure parameters type (inout T0) - where
is opened generic parameter T - to argument type (T1), which can
be 'inout' but it's uncertain at this stage, but since closure
'declaration' `{ $0 = 0 }` is wrapped inside of a function call,
it has to 'map' parameters to arguments instead of converting them,
see `ConstraintSystem::matchFunctionTypes`.
Resolves: SR-3520, SR-1976, SR-3073, SR-3479.
The typedef `swift::Module` was a temporary solution that allowed
`swift::Module` to be renamed to `swift::ModuleDecl` without requiring
every single callsite to be modified.
Modify all the callsites, and get rid of the typedef.
For collection literals that contained implicitly unwrapped optionals,
we were attempting three different conversions per element of the
collection, resulting in exponential type checking time.
We should only ever attempt one of these conversions for any pair of
types where one or both is optional.
We had several reports of this as it seems quite common for people to
write expressions that create a collection of IUOs from class/struct
elements, and then either return the collection or some variation that
has been filtered and mapped.
I am looking at adding the appropriate instrumentation to the type
checker so that I can add a scale-test for this and other type checker
test cases related to slow type checking so that we can avoid regressing
in the future.
Previously all of the following would strip off varying amounts of
MetatypeType, LValueType, InOutType, DynamicSelfType, etc:
- ConstraintSystem::performMemberLookup()
- ConstraintSystem::lookupMember()
- TypeChecker::lookupMember()
- DeclContext::lookupQualified()
- Type::getContextSubstitutions()
The problem is that the higher level methods that took a lookup type
would call the lower level methods, and post-process the result using
the given lookup type. Since different levels of sugar were stripped,
it made the code hard to reason about and opened up edge cases, eg
if a DynamicSelfType or InOutType appears where we didn't expect it.
Since filtering out static/instance and mutating/nonmutating members
is done at higher levels, there's no reason for these name lookup
operations to accept anything other than nominal types, existentials
and archetypes.
Make this so with assertions, and deal with the fallout.
We have an implicit conversion where a closure with a non-Void
result type can be passed as a function value with a Void
result; this makes single-expression closures more usable in
the case where you want the single expression to be a
statement -- discarding it's result.
Unfortunately we were checking if the locator contains a
ClosureResult component *anywhere* in the path. This is too
permissive. The correct check is that the *last* path component
is a ClosureResult.
Otherwise, we happily convert anything to () *anywhere*
in a closure result, which crashes immediately in SILGen.
Fixes <https://bugs.swift.org/browse/SR-403>.
Currently isAnyHashableType method validates only structs but
it doesn't account for situation when type is represented via type
variable with type already fixed to AnyHashable, that results in
infinite loop in the solver because restriction [hashable-to-
anyhashable] is going to add new type variable recursively.
withoutActuallyEscaping has a signature like `<T..., U, V, W> (@nonescaping (T...) throws<U> -> V, (@escaping (T...) throws<U> -> V) -> W) -> W, but our type system for functions unfortunately isn't quite that expressive yet, so we need to special-case it. Set up the necessary type system when resolving an overload set to reference withoutActuallyEscaping, and if a type check succeeds, build a MakeTemporarilyEscapableExpr to represent it in the type-checked AST.
The prior formulation of bridging conversions allowed conversion to
more-optional types, e.g., converting an "NSDate" to "Date?", which
was broken by my recent refactoring in this area. Allow bridging
conversions to more-optional types by introducing extra optional
injections at the end.
Fixes rdar://problem/29780527.
Specialize and improve the "downcast only unwraps optionals"
diagnostic to provide specific diagnostics + Fix-Its for the various
casts of forced cast, conditional cast, and "isa" check. Specifically:
* With a forced cast, customize the diagnostic. We still insert the
appropriate number of !'s, but now we remove the 'as! T' (if an
implicit conversion would suffice) or replace the 'as!' with 'as'
(if we still need a bridge)
* With a conditional cast, only emit a diagnostic if we're removing
just one level of optional. In such cases, we either have a no-op
(an implicit conversion would do) or we could just use 'as' to the
optional type, so emit a customized warning to do that. If we are
removing more than one level of optional, don't complain:
conditional casts can remove optionals. Add the appropriate Fix-Its
here.
* With an 'is' expression, only emit a diagnostic if we're removing
just one level of optional. In this case, the 'is' check is
equivalent to '!= nil'. Add a Fix-It for that.
Across the board, reduce the error to a warning. These are
semantically-well-formed casts, it's just that they could be written
better.
Fixes rdar://problem/28856049 and rdar://problem/22275685.
The type checker implements logic for handling checked casts in two
places: the constraint solver (for type-checking expressions
containing "as!" or "as?") and as a top-level entrypoint for
type-checking as?/as! for diagnostics and is/as patterns. Needless to
say, the two implementations were inconsistent, and in fact both were
wrong, leading to various problems---rejecting perfectly-valid "as!"
and "as?" casts outright, bogus warnings that particular as!/as? casts
always-succeed or always-fail when they wouldn't, and so on.
Start detangling the mess in two ways. First, drastically simplify the
handling of checked casts in the constraint solver, eliminating the
unprincipled "subtype" constraint checks that (among other things)
broke the handling of checked casts that involved bridging or optional
unwrapping. The simpler code is more permissive and more correct; it
essentially accepts that the user knows what she is doing with the
cast.
Second, make the type checker's checking of casts far more thorough,
which includes:
* When we're performing a collection cast, actually check that the
element types (and key types, for a dictionary) are castable, rather
than assuming all collection casts are legitimate. This means we'll
get more useful "always fails" and "always succeeds" diagnostics for
array/set/dictionary.
* Handle casts from a bridged value type to a subclass of the
corresponding bridged class type. Previously, these would be
incorrectly classified as "always fails".
While I'm here, eliminate a spurious diagnostic that occurs when using
a conditional cast ("as?") that could have been a coercion/bridging
conversion ("as"). The optional injection we synthesize to get the
resulting type correct was getting diagnosed as an implicit coercion,
but shouldn't have been.
Previously, bridging conversions were handled as a form of "explicit
conversion" that was treated along the same path as normal
conversions in matchTypes(). Historically, this made some
sense---bridging was just another form of conversion---however, Swift
now separates out bridging into a different kind of conversion that is
available only via an explicit "as". This change accomplishes a few
things:
* Improves type inference around "as" coercions. We were incorrectly
inferring type variables of the "x" in "x as T" in cases where a
bridging conversion was expected, which cause some type inference
failures (e.g., the SR-3319 regression).
* Detangles checking for bridging conversions from other conversions,
so it's easier to isolate when we're applying a bridging
conversion.
* Explicitly handle optionals when dealing with bridging conversions,
addressing a number of problems with incorrect diagnostics, e.g.,
complains about "unrelated type" cast failures that would succeed at
runtime.
Addresses rdar://problem/29496775 / SR-3319 / SR-2365.