One can have arbitrary types defined in a constrained extension, not just
typealiases, e.g.
struct Foo<T> {}
extension Foo where T == Int {
struct X {}
}
A mention of `Foo<String>.X` should be flagged, since String != Int. Previously
this worked (in expressions) only if `X` was a typealias, and with this patch
the above example is flagged too.
Part of https://bugs.swift.org/browse/SR-5440 and
https://bugs.swift.org/browse/SR-7976 and rdar://problem/41063870.
We were failing to bind the alternatives for an IUO @optional
requirement because we forgot to set the appropriate type variable option.
Fixes: rdar://problem/40868990
This fixes a subtle issue where, during single-expression closure type inference, we would ask for the settability of local variables from the outer function's context, leading us to mistakenly consider them mutable inside single-expression closure contexts. DI would catch some but not all violations of the expected semantics here.
I think there is something far more narrow we could do here, but I'm
not sure if there is real code that such a hack would benefit from. We
can leave that to consider another day.
Fixes rdar://problem/40819547 (aka https://bugs.swift.org/browse/SR-7884).
If solver encounters a typealias inside of constrainted extension
make sure to add its requirements to the constraint system, otherwise
it might produce invalid solutions.
8271c1a removed the last hacky usage of ArrayElementType,
leaving behind just the @lvalue-to-inout conversions. Rename
the locator path element to reflect this and do a bit of cleanup on the
unrelated-but-near-enough other hack RValueAdjustment.
Most callers were using TypeLoc::withoutLoc() to wrap a Type,
and the one place that still had TypeReprs can resolve the
TypeReprs right there instead.
Otherwise, when the horrible ExprCleanser comes along, it will set
the interface type of the ParamDecl to nullptr. However there is
no way to clear the 'validation started' bit, so the next time
validateDecl() is called on this ParamDecl we will just return,
causing crashes downstream when callers expect it to already have
an interface type set.
Fixes <rdar://problem/38189778> and possibly some instances of
<rdar://problem/36434823>.
Given something like `max(1, 2)` inside a type that conforms to Sequence, this
allows the compiler to consider Swift.max as well as the two methods with that
name on Sequence.
This function (and getTypeOfMemberReference) deserve a deeper cleanup,
but for the moment lets unblock a compatibility test.
Fixes SR-7098 / rdar://problem/38394645
When we perform AnyObject lookup, we can find multiple declarations with
the same signature. When we do so, we pick fairly arbitrarily among them.
However, make sure that we don’t pick an unavailable declaration when
an available declaration is… available.
Fixes rdar://problem/39115471.
Attempt to avoid trying to optimize binary generic disjunctions
when one of the choices has `Any` or `Any?` since it's risky to
assume which one is better without solving.
Resolves: rdar://problem/38625824
Many (perhaps most?) calls to createTypeVariable explicitly pass 0 for
options. This change just defaults the parameter to 0 and removes all
the explicit 0's in the code.
Existential types don't support nested types so let's not
allow the lookup to make such access, with only exception
for typealias or associated types without type parameters,
they are currently allowed.
Resolves: rdar://problem/38505436
Any time we had a favored choice for a disjunction, we attempted to
not add it twice, but that little optimization was faulty.
This should speed up some expression type checking a tiny bit in cases
where the favored choice did not result in a solution.
Noticed by observation.
We were inserting function conversion expressions that were then
turned into forces of values in cases where we merely referenced
functions, but did not actually call them.
Fixes rdar://problem/37241550.
We were not handling IUO results of @optional protocol methods
properly, sometimes forcing the @optional requirement rather than the
result of the call.
Fixes rdar://problem/37240984.
* Implement the recently accepted SE-0195 proposal, which introduces "Dynamic
Member Lookup" Types. This is a dusted off and updated version of PR13361,
which switches from DynamicMemberLookupProtocol to @dynamicMemberLookup as
was requested by the final review decision. This also rebases it,
updates it for other changes in the compiler, fixes a bunch of bugs, and adds support for keypaths.
Thank you to @rudx and @DougGregor in particular for the helpful review comments and test cases!
Before matching witnesses, ensure that we have a valid signature, and be
more tolerant of null generic environments by using the
mapTypeIntoContext entry point meant to handle null.
We haven't managed to get a decent reproducer for this, but it's
happening often enough, and this change hardens the affected code
paths.
Should fix rdar://problem/37255982.
When we form an overload set containing two generic functions, where
one is more specialized than the other, "favor" the more-specialized
function in the constraint system so we won't explore any paths
involving the less-specialized function when the more-specialized
version applies. This should be a strict improvement, because
previously we would have always gone down both paths.
Fixes rdar://problem/37371815, taking this exponential example linear.
Also remove the decl from the known decls and remove a
bunch of code referencing that decl as well as a bunch of other
random things including deserialization support.
This includes removing some specialized diagnostics code that
matched the identifier ImplicitlyUnwrappedOptional, and tweaking
diagnostics for various modes and various issues.
Fixes most of rdar://problem/37121121, among other things.
Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it
from the type system.
Enable the code that generates disjunctions for Optional<T> and
rewrites expressions based on the original declared type being 'T!'.
Most of the changes supporting this were previously merged to master,
but some things were difficult to merge to master without actually
removing IUOs from the type system:
- Dynamic member lookup and dynamic subscripting
- Changes to ensure the bridging peephole still works
Past commits have attempted to retain as much fidelity with how we
were printing things as possible. There are some cases where we still
are not printing things the same way:
- In diagnostics we will print '?' rather than '!'
- Some SourceKit and Code Completion output where we print a Type
rather than Decl.
Things like module printing via swift-ide-test attempt to print '!'
any place that we now have Optional types that were declared as IUOs.
There are some diagnostics regressions related to the fact that we can
no longer "look through" IUOs. For the same reason some output and
functionality changes in Code Completion. I have an idea of how we can
restore these, and have opened a bug to investigate doing so.
There are some small source compatibility breaks that result from
this change:
- Results of dynamic lookup that are themselves declared IUO can in
rare circumstances be inferred differently. This shows up in
test/ClangImporter/objc_parse.swift, where we have
var optStr = obj.nsstringProperty
Rather than inferring optStr to be 'String!?', we now infer this to
be 'String??', which is in line with the expectations of SE-0054.
The fact that we were only inferring the outermost IUO to be an
Optional in Swift 4 was a result of the incomplete implementation of
SE-0054 as opposed to a particular design. This should rarely cause
problems since in the common-case of actually using the property rather
than just assigning it to a value with inferred type, we will behave
the same way.
- Overloading functions with inout parameters strictly by a difference
in optionality (i.e. Optional<T> vs. ImplicitlyUnwrappedOptional<T>)
will result in an error rather than the diagnostic that was added
in Swift 4.1.
- Any place where '!' was being used where it wasn't supposed to be
allowed by SE-0054 will now treat the '!' as if it were '?'.
Swift 4.1 generates warnings for these saying that putting '!'
in that location is deprecated. These locations include for example
typealiases or any place where '!' is nested in another type like
`Int!?` or `[Int!]`.
This commit effectively means ImplicitlyUnwrappedOptional<T> is no
longer part of the type system, although I haven't actually removed
all of the code dealing with it yet.
ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly
unwrapped Optional<T>!
Resolves rdar://problem/33272674.
If something that we are trying to contextually bind is a nested type inside
protocol or protocol extension, let's try to find the innermost conforming type
from the current declaration context and map Self parameter of the protocol
to that nominal type. Since nested types in protocols aren't yet implemented this
is going to result in failure, but that's better than crashing.
Resolves: rdar://problem/36449760
When binding an optional value, or function that returns an optional
value, if that value was produced from a decl that was declared an
IUO, create a disjunction.
After solving, make use of the disjunction choices in rewriting
expressions to force optionals where needed.
This is disabled for now, as it results in a source compatibility
issue without associated changes that actually start generating
Optional<T> in place of ImplicitlyUnwrappedOptional<T>. It's
complicated, but basically having two '??' (one returning T, one
returning T?) and creating a disjunction where the first (favored)
choice is ImplicitlyUnwrappedOptional<T> and second is T results in
our selecting the wrong '??' in some cases.
Use this in places where we have a decl that is marked with the
ImplicitlyUnwrappedOptionalAttr so that we can distinguish in the
solver which decls need to be potentially unwrapped in order to type
check successfully.
Add a new OverloadChoiceKind for decls that are either IUO-typed, or
function-typed meaning that the function result type is IUO-typed.
Not currently used, so NFC.
Instead of binding collection types directly let's try to
bind using temporary type variables substituted for element
types, that's going to ensure that subtype relationship is
always preserved.
Resolves: rdar://problem/35541153