Certain type circularities weren't being checked until this point. Such as
```
struct X<T> { let a: X<X> }
struct Y<T> { let a: (Int, Y<Y>) }
enum Z<T> { case A(Optional<Z<Z>>) }
```
We introduce a more comprehensive approach to detect these in type checker.
After name lookup, exam each value field in declared structs and enums for
self-reference types that creates inifinite sizes.
When comparing two functions for overload resolution, break apart the
parameter lists to compare individual parameters rather than comparing
the tuples. This allows us to prefer functions with fewer arguments to
ones with more, defaulted or variadic arguments. That preference was
already encoded in the constraint optimizer, which led to some strange
behavior where the preference was expressed for function calls but not
for calls to initializers. Fixes rdar://problem/24128153.
The standard library change tweaks the anachronistic, unavailable
"print" variants somewhat. The only behavior change here is a slight
regression for cases like:
print(a: 1, b: 2)
where we used to produce a diagnostic:
Please wrap your tuple argument in parentheses: 'print((...))'
but we now get:
argument labels '(a:, b:)' do not match any available overloads
However, this regression will happen at some point *anyway*, if
SE-0029 (or anything else that removes the implicit tuple splat
operation) goes through.
This is a quick follow-up to
<https://github.com/apple/swift/pull/1160>, to replace the becoming
deprecated getArchetype() with doing the same thing via calling through
to ArchetypeBuilder with a declContext.
Uses findGenericSubstitutions() to do so. So this site could take
advantage of destructuring of more complex params containing generics.
Right now, though, that never happens. For complex params the
(unfortunately, worse) diagnosis happens in diagnoseFailureForExpr() on
the argument expression before reaching here. I’d like to improve that
in future work.
Correctly determine callee closeness for func/ops that include generics
as part of more complicated parameters, i.e. tuple or closure args
containing generics as elements or args/results. Still only handling
single archetypes.
Also added code to check generic substitutions already made in the callee
parameters, which further helps diagnosis.
Previously we treated the * platform as checking for the minimum
deployment target, but that's definitely unnecessary.
There is a bit of a hack here to avoid diagnosing the 'else' branch as
unreachable: if a constant true/false came from #available, ignore it.
This is the beginning of the extension of the availability model
introduced in Swift 2.0 to support two interesting things: inlineable
code and binary frameworks not tied to an OS. The former is critical
to having a stable standard library that isn't shipped with a client app.
(For more information on both of these, see docs/LibraryEvolution.rst.)
The existing availability model enforces that API is not used unless
the developer has already guaranteed its existence. We want to reuse
this logic for these new purposes. Additionally, certain queries about
the AST are dependent on this type of information as well, e.g. "can I
assume this enum will not grow any additional cases?" If the enum comes
from the module being compiled, the answer is usually "yes", but not if
the code asking the question may be inlined into another binary!
(This latter purpose is currently served by ResilienceExpansion down at
the SIL level; my goal is to replace ResilienceExpansion with
AvailabilityContext. It's a bit heavier but would also allow additional
optimization in the future.)
This commit does not change any logic; it only wraps existing uses of
VersionRange in AvailabilityContext if they're not strictly referring to
the OS version.
For a concrete type, members from its conforming protocols' extensions can be hard
to manually surface. In this commit, when printing Swift modules, we start to replicate these
extensions and synthesize them as if they are the concrete type's native extensions.
Credit to Doug for suggesting this practice.
This exposes some wierdness with while_parsing_as_left_angle_bracket where
one case the note is being is when resolveType returns a failure. However,
resolveType can produce a failure without emitting a diagnostic, and this
can lead to us generating a note unattached to an error. Just remove this
case.
The SIL parser used PolymorphicFunctionType in two places:
- Internals of SILFunctionType parsing
- Overload selection for class_method / super_method / dynamic_method
instructions
It is better to have Sema construct GenericFunctionType directly
in SIL mode. In particular, the overload selection logic is simpler
now, since it does not have to deal with the fact that
PolymorphicFunctionTypes do not canonicalize.
Mostly NFC, except the SIL printer output is a bit different; for a
generic method on a generic type, the type parameters all come first,
like ``<T><U> G<T> -> (U) -> ()'' -vs- ``<T> G<T> -> <U> (U) -> ()''.
Also, generic constraints look different, instead of ``<`Self` : P>``
we now have ``<Self where Self : P>''.
This patch has two consequences that will become important later:
- While code that constructs PolymorphicFunctionType still exists in
Sema, the SIL parser was the last major component that *consumed*
PolymorphicFunctionType.
- Everywhere we set SILFunction::ContextGenericParams, we now have
a well-formed context GenericSignature available, allowing
ContextGenericParams to be replaced by a GenericSignature
eventually.
When we have a contextual type of Optional<SomeNominal>, we get overload
lookup results indicating that the found member needs to look through the
optional. Do so!
Not all types are l-valuable, notably InoutType's. This seems like a
weird restriction to put in the type checker, but it is the cleanest
solution to this. The better solution would be to change how
inoutexpr/inouttype are represented completely... maybe someday.
Formerly we stopped type checking a PatternBindingDecl when it was marked
as invalid. This prevented semantic analysis from doing things like expanding
"stored" properties in protocols into computed properties with getters and setter,
causing downstream problems.
Stop doing this, and instead do a bit of work to silence the downstream errors in
a more narrow way.
When checking for permitted uses of Self in the input type of a
protocol requirement's function type, if the parameter itself was
a function we would recurse into its input, and reject all uses
of Self in the parameter type's result. This was the wrong way
around, and in fact we should recurse into the result.
Here is a test case that used to compile successfully and crash;
now it is rejected by the type checker:
protocol P {
func f(a: Self -> ())
}
protocol Q : P {
func g()
}
class C : P {
func f(a: C -> ()) { // should not be allowed to witness P.f
a(C())
}
}
class B : C, Q {
var x: Int = 17
func g() {
print(x)
}
}
func f<T : Q>(t: T) {
// T == B here
// t.f has type <T : Q> (T -> ()) -> ()
t.f({ $0.g() }) // but at runtime, $0 is a C not a B
}
f(B())
SelfInResultType::DynamicSelf was unnecessary because we already
returned SelfUse::Result and handled it correctly if the witness
had a dynamic Self return type.
SelfInResultType::Ignore was only used for constructors, but it
is better to handle them just like FuncDecls with dynamic Self
returns.
Also, the additional VarDecl case was unnecessary.
In SR-628 in particular, the problem was an assert that an AccessKind
was being set on a non-lvalue, but there were lots of asserts here in
various scenarios, the most common other ones being an AccessKind not
being set assertion by the ASTVerifier or lvalue-ness not matching
between tuple expr and tuple element expr.
This checks for lvalues in the tuple when a tuple indexing expr is built,
and if there are any, inserts load exprs into the lvalue elements to make all rvalues.
This reverts commit b1a7ceaf4b.
Accounting for these operators can add complexity in some cases, so I'm
backing out this change pending a more holistic approach.
Introduce Fix-Its to aid migration from selectors spelled as string
literals ("foo:bar:", which is deprecated), as well as from
construction of Selector instances from string literals
(Selector("foo:bar"), which is still acceptable but not recommended),
to the #selector syntax. Jump through some hoops to disambiguate
method references if there are overloads:
fixits.swift:51:7: warning: use of string literal for Objective-C
selectors is deprecated; use '#selector' instead
_ = "overloadedWithInt:" as Selector
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#selector(Bar.overloaded(_:) as (Bar) -> (Int) -> ())
In the cases where we cannot provide a Fix-It to a #selector
expression, we wrap the string literal in a Selector(...) construction
to suppress the deprecation warning. These are also easily searchable
in the code base.
This also means we're doing more validation of the string literals
that go into Selector, i.e., that they are well-formed selectors and
that we know about some method that is @objc and has that
selector. We'll warn if either is untrue.
In both figuring out candidate closeness and in diagnosing generic
parameter errors, if the parameter is a GenericTypeParamType, get its
decl’s archetype to perform archetype substitutability checking upon.
Set type repr's as invalid after diagnosing an unsupported protocol
to stop duplicate diagnoses.
There were two causes here. First, top-level variable
declarations were being checked once by the Decl checker, and then
again by the Stmt checker. (This caused SR-38.)
Second, the Stmt checker is called by an AST visitor itself, which
already calls it once per statement. Using the
UnsupportedProtocolVisitor here meant that each interior sub statement
would get visited multiple times. Added a setRecurseIntoSubstatements()
on the visitor, and set it to false for the Stmt checker. This keeps
from revisiting statements multiple times.