Kicking the interface type request of the base decl here is wrong
if the decl is e.g a `self` capture in a closure, since we'll be in
the middle of type-checking the closure. I'm planning on properly
fixing this by folding the lookup into the constraint system, but for
now let's at least avoid kicking the request if we don't have an enum
case or enum var. That at least prevents it from affecting cases where
e.g you're pattern matching against a property in a class.
We could potentially tighten up the checking here even further, but
that could potentially impact source compatibility for ambiguous
cases. I'd like to keep this patch low risk, and then deal with any
fallout as part of the pattern type-checking work.
rdar://146952007
Selectively revert 36683a804c to resolve
a source compatibility regression. See inline comment for use case. We
are going to consider acknowledging this use case in the rules in a
future release.
Complete support is behind a flag, because it can result in a non-convergent
rewrite system if the opaque result type has a recursive conformance of its
own (eg, `some View` for SwiftUI's View protocol).
Without the flag, it's good enough for simple examples; you just can't have
a requirement that mentions a nested type of a type parameter equated to
the concrete type.
Fixes rdar://problem/88135291, https://bugs.swift.org/browse/SR-15983.
The problem is that we currenly cannot represent the generic signature of
values of type `any P<some P>`. This is because we wind up producing
<Self where Self : P, Self.T == (some P)>
What we'd like to do in the future is erase the errant (some P) with
a fresh generic parameter and keep a substitution map on the side that
records the opaque type constraint. Something like
<Self, Opaque1 where Self : P, Opaque1 : P, Self.T == Opaque1> where Opaque1 == (some P)
A protocol can constrain an associated type to Self:
protocol P {
associatedtype A : Q where A.B == Self
}
protocol Q {
associatedtype B
}
And a class might conform to this protocol:
class C : P {
typealias A = D
}
class D : Q {
typealias B = C
}
The generic signature <Self where Self : P, Self : C> is built during
conformance checking. Since Self : C, we must have that Self.A == D;
since D.B == C, the requierement 'A.B == Self' in protocol P implies
that 'Self == C'. So the correct minimized signature here is
<Self where Self == C>.
This wasn't handled properly before, because of assumptions in
removeSelfDerived() and a couple of other places.
Fixes rdar://71677712, rdar://76155506, https://bugs.swift.org/browse/SR-10033,
https://bugs.swift.org/browse/SR-13884.
IsBindableVisitor is part of TypeBase::substituteBindingsTo(), which
is used for two things:
- Checking if one contextual type is a proper substitution of another
contextual type, used in the solver
- To compute the substituted generic signature when lowering a SIL
function type
In the first case, we're interested in knowing if the substitution
succeeds or fails. In the second case, we know the substitution is
correct by construction, and we're trying to recover the generic
requirements.
In the second case though, the substituted type might be an
interface type, and if the interface type is constrained to a
concrete type in the original type's generic signature, we would
conclude that the substitution should fail.
This is incorrect, and we should just skip the check if the
substituted type is an interface type -- we do not have enough
information to know if it succeeds, and instead we must assume it
does because otherwise the substituted type passed in to type
lowering must be incorrect.
Fixes https://bugs.swift.org/browse/SR-13849.
Doing this when computing a canonical signature didn't really
make sense because canonical signatures are not canonicalized
any more strongly _with respect to the builder_; they just
canonicalize their requirement types.
Instead, let's do these checks after creating the signature in
computeGenericSignature().
The old behavior had another undesirable property; since the
canonicalization was done by registerGenericSignatureBuilder(),
we would always build a new GSB from scratch for every
signature we compute.
The new location also means we do these checks for protocol
requirement signatures as well. This flags an existing fixed
crasher where we still emit bogus same-type requirements in
the requirement signature, so I moved this test back into
an unfixed state.
A new implementation from "first principles". The idea is that
for a given conformance, we either have an explicit source
which forms the root of the requirement path, or a derived
source, which we 'factor' into a parent type/parent protocol
pair, and a requirement signature requirement.
We recursively compute the conformance access path of the
parent type and parent protocol, and append the path element
for the requirement.
This fixes a long-standing crasher, and eliminates two hacks,
the 'usesRequirementSource' flag in RequirementSource, and
the 'HadAnyRedundantConstraints' flag in GenericSignatureBuilder.
Fixes https://bugs.swift.org/browse/SR-7371 / rdar://problem/39239511
A DependentMemberType can either have a bound AssociatedTypeDecl,
or it might be 'unresolved' and only store an identifier.
In maybeResolveEquivalenceClass(), we did not handle the unresolved
case when the base type of the DependentMemberType had itself been
resolved to a concrete type.
Fixes <rdar://problem/71162777>.
Under certain circumstances, introducing a concrete same-type or
superclass constraint can re-introduce conformance constraints
which were previously redundant.
For example, consider this code, which we correctly support today:
protocol P {
associatedtype T : Q
}
protocol Q {}
class SomeClass<U : Q> {}
struct Outer<T> where T : P {
func inner<U>(_: U) where T == SomeClass<U>, U : Q {}
}
The constraint 'T == SomeClass<U>' makes the outer constraint
`T : P' redundant, because SomeClass already conforms to P.
It also introduces an implied same-type constraint 'U == T.T'.
However, whereas 'T : P' together with 'U == T.T' make 'U : Q'
redundant, the introduction of the constraint 'T == SomeClass<U>'
removes 'T : P', so we re-introduce an explicit constraint 'U : Q'
in order to get a valid generic signature.
This code path did the right thing for constraints derived via
concrete same-type constraints, but it did not handle superclass
constraints.
As a result, this case was broken:
struct Outer<T> where T : P {
func inner<U>(_: U) where T : SomeClass<U>, U : Q {}
}
This is the same example as above, except T is related via a
superclass constraint to SomeClass<U>, instead of via a concrete
same-type constraint.
The subtlety here is that we must check if the superclass type
actually conforms to the requirement source's protocol, because it
is possible to have a superclass-constrained generic parameter
where some conformances are abstract. Eg, if SomeClass did not
conform to another protocol P2, we could write
func foo<T, U>(_: T, _: U) where T : SomeClass<U>, T : P2 {}
In this case, 'T : P2' is an abstract conformance on the type 'T'.
The common case where this would come up in real code is when you
have a class that conforms to a protocol with an associated type,
and one of the protocol requirements was fulfilled by a default in
a protocol extension, eg:
protocol P {
associatedtype T : Q
func foo()
}
extension P {
func foo() {}
}
class ConformsWithDefault<T : Q> : P {}
The above used to crash; now it will type-check correctly.
Fixes <rdar://problem/44736411>, <https://bugs.swift.org/browse/SR-8814>..
When adding a superclass constraint, we need to find any nested
types belonging to protocols that the superclass conforms to,
and introduce implicit same-type constraints between each nested
type and the corresponding type witness in the superclass's
conformance to that protocol.
Fixes <rdar://problem/39481178>, <https://bugs.swift.org/browse/SR-11232>.
This commit changes how we represent caller-side
default arguments within the AST. Instead of
directly inserting them into the call-site, use
a DefaultArgumentExpr to refer to them indirectly.
The main goal of this change is to make it such
that the expression type-checker no longer cares
about the difference between caller-side and
callee-side default arguments. In particular, it
no longer cares about whether a caller-side
default argument is well-formed when type-checking
an apply. This is important because any
conversions introduced by the default argument
shouldn't affect the score of the resulting
solution.
Instead, caller-side defaults are now lazily
type-checked when we want to emit them in SILGen.
This is done through introducing a request, and
adjusting the logic in SILGen to be more lenient
with ErrorExprs. Caller-side defaults in primary
files are still also currently checked as a part
of the declaration by `checkDefaultArguments`.
Resolves SR-11085.
Resolves rdar://problem/56144412.
The name-lookup behavior that avoids looking for members of a nominal type
or extension therefore when resolving the inheritance clause is now
handled by UnqualifiedLookup, so remove it from the type checker itself.
Fixes rdar://problem/39130543.
Wire up the request-evaluator with an instance in ASTContext, and
introduce two request kinds: one to retrieve the superclass of a class
declaration, and one to compute the type of an entry in the
inheritance clause.
Teach ClassDecl::getSuperclass() to go through the request-evaluator,
centralizing the logic to compute and extract the superclass
type.
Fixes the crasher from rdar://problem/26498438.
* Reject bad string interpolations
String interpolations with multiple comma-separate expressions or argument labels were being incorrectly accepted.
* Tweak error name to match message
* Diagnose empty interpolations more clearly
* Don’t double-diagnose parse errors
Fixes a test at Parse/recovery.swift:799 which the previous commit broke.
* Fix incorrect test RUN: line
A previous version of this test used FileCheck instead of -verify, and the run line wasn’t properly corrected to use -verify.
* Update comment
* Add more argument label tests
Ensures that we don’t get different results from an initializer that doesn’t exist or doesn’t take a String.
* Resolve the SR-7958 crasher test
We now diagnose the error and remove the label before it has an opportunity to crash.
Trying to use an argument label in an interpolation can cause various crashes. In swiftlang-1000.0.16.7, these are usually in SILGen; in master at 8f6028d, they’re in CSApply.
Since member lookup doesn't check requirements
it might sometimes return types which are not
visible in the current context e.g. typealias
defined in constrained extension, substitution
of which might produce error type for base, so
assignement should thead lightly and just fail
if it encounters such types.
Resolves: rdar://problem/39931339
Resolves: SR-5013
If there was any requirements in the @objc protocol, the user got an error in
some form (a complaint about those requirements), but giving the direct error is
better, and handles @objc protocol with no requirements.
Also, fix a hole in that existing @objc method check: in `class Outer<T> { class
Inner {} }`, Inner should be considered generic, but the loop that was checking
for this didn't consider it.
Fixes https://bugs.swift.org/browse/SR-7370 and rdar://problem/39239512.