Skip to content

Commit 3f8e4e7

Browse files
committed
AST: Fix mistake with generic signature in findExistentialSelfReferences()
We used to concatenate the DeclContext's generic signature with the protocol requirement's signature, then look for occurrences of the first generic parameter from the DeclContext's signature in the requirement's type. This almost worked, except when the first generic parameter from the DeclContext's signature didn't conform to a protocol referenced by an associated type. In that case, we would falsely report that there are no 'Self' references. Note that the CHECK lines in test/SILGen/witnesses_class.swift change to what they were before 01d9d61.
1 parent bc6a38c commit 3f8e4e7

File tree

6 files changed

+17
-15
lines changed

6 files changed

+17
-15
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2693,8 +2693,7 @@ class ValueDecl : public Decl {
26932693
/// property, or the uncurried result type of a method/subscript, e.g.
26942694
/// '() -> () -> Self'.
26952695
GenericParameterReferenceInfo findExistentialSelfReferences(
2696-
Type baseTy, const DeclContext *useDC,
2697-
bool treatNonResultCovariantSelfAsInvariant) const;
2696+
Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const;
26982697
};
26992698

27002699
/// This is a common base class for declarations which declare a type.

lib/AST/Decl.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4085,9 +4085,9 @@ GenericParameterReferenceInfo swift::findGenericParameterReferences(
40854085
}
40864086

40874087
GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences(
4088-
Type baseTy, const DeclContext *useDC,
4089-
bool treatNonResultCovariantSelfAsInvariant) const {
4088+
Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const {
40904089
assert(baseTy->isExistentialType());
4090+
assert(!baseTy->hasTypeParameter());
40914091

40924092
// Types never refer to 'Self'.
40934093
if (isa<TypeDecl>(this))
@@ -4099,9 +4099,12 @@ GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences(
40994099
if (type->hasError())
41004100
return GenericParameterReferenceInfo();
41014101

4102-
const auto sig =
4103-
getASTContext().getOpenedArchetypeSignature(baseTy,
4104-
useDC->getGenericSignatureOfContext());
4102+
// Note: a non-null GenericSignature would violate the invariant that
4103+
// the protocol 'Self' type referenced from the requirement's interface
4104+
// type is the same as the existential 'Self' type.
4105+
auto sig = getASTContext().getOpenedArchetypeSignature(baseTy,
4106+
GenericSignature());
4107+
41054108
auto genericParam = sig.getGenericParams().front();
41064109
return findGenericParameterReferences(
41074110
this, sig, genericParam, treatNonResultCovariantSelfAsInvariant, None);

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6107,7 +6107,7 @@ bool ConstraintSystem::isMemberAvailableOnExistential(
61076107
// the actual signature of the opened archetype in context, rather it cares
61086108
// about whether you can "hold" `baseTy.member` properly in the abstract.
61096109
const auto info = member->findExistentialSelfReferences(
6110-
baseTy, DC->getModuleScopeContext(),
6110+
baseTy,
61116111
/*treatNonResultCovariantSelfAsInvariant=*/false);
61126112
if (info.selfRef > TypePosition::Covariant ||
61136113
info.assocTypeRef > TypePosition::Covariant) {

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ ExistentialRequiresAnyRequest::evaluate(Evaluator &evaluator,
681681
// For value members, look at their type signatures.
682682
if (auto valueMember = dyn_cast<ValueDecl>(member)) {
683683
const auto info = valueMember->findExistentialSelfReferences(
684-
decl->getDeclaredInterfaceType(), decl,
684+
decl->getDeclaredInterfaceType(),
685685
/*treatNonResultCovariantSelfAsInvariant=*/false);
686686
if (info.selfRef > TypePosition::Covariant || info.assocTypeRef) {
687687
return true;

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
10431043
// the default witness for 'Collection.Iterator', which is defined
10441044
// as 'IndexingIterator<Self>'.
10451045
const auto selfRefInfo = req->findExistentialSelfReferences(
1046-
proto->getDeclaredInterfaceType(), dc,
1046+
proto->getDeclaredInterfaceType(),
10471047
/*treatNonResultCovariantSelfAsInvariant=*/true);
10481048
if (!selfRefInfo.assocTypeRef) {
10491049
covariantSelf = classDecl;
@@ -4065,7 +4065,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
40654065
// Check whether this requirement uses Self in a way that might
40664066
// prevent conformance from succeeding.
40674067
const auto selfRefInfo = requirement->findExistentialSelfReferences(
4068-
Proto->getDeclaredInterfaceType(), DC,
4068+
Proto->getDeclaredInterfaceType(),
40694069
/*treatNonResultCovariantSelfAsInvariant=*/true);
40704070

40714071
if (selfRefInfo.selfRef == TypePosition::Invariant) {

test/SILGen/witnesses_class.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ class UsesDefaults<X : Barable> : HasDefaults {}
8484

8585
// Invariant Self, since type signature contains an associated type:
8686

87-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyqd__GAA03HasD0A2aEP16hasDefaultTakesTyy1TQzFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable> (@in_guaranteed UsesDefaults<τ_1_0>, @in_guaranteed τ_0_0) -> ()
87+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyxGAA03HasD0A2aEP16hasDefaultTakesTyy1TQzFTW : $@convention(witness_method: HasDefaults) <τ_0_0 where τ_0_0 : Barable> (@in_guaranteed UsesDefaults<τ_0_0>, @in_guaranteed UsesDefaults<τ_0_0>) -> ()
8888
// CHECK: [[FN:%.*]] = function_ref @$s15witnesses_class11HasDefaultsPAAE16hasDefaultTakesTyy1TQzF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults> (@in_guaranteed τ_0_0.T, @in_guaranteed τ_0_0) -> ()
89-
// CHECK: apply [[FN]]<τ_0_0>(
89+
// CHECK: apply [[FN]]<UsesDefaults<τ_0_0>>(
9090
// CHECK: return
9191

9292
// Covariant Self:
@@ -98,9 +98,9 @@ class UsesDefaults<X : Barable> : HasDefaults {}
9898

9999
// Invariant Self, since type signature contains an associated type:
100100

101-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyqd__GAA03HasD0A2aEP23hasDefaultGenericTakesTyy1TQz_qd__tAA7FooableRd__lFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable><τ_2_0 where τ_2_0 : Fooable> (@in_guaranteed UsesDefaults<τ_1_0>, @guaranteed τ_2_0, @in_guaranteed τ_0_0) -> ()
101+
// // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyxGAA03HasD0A2aEP23hasDefaultGenericTakesTyy1TQz_qd__tAA7FooableRd__lFTW : $@convention(witness_method: HasDefaults) <τ_0_0 where τ_0_0 : Barable><τ_1_0 where τ_1_0 : Fooable> (@in_guaranteed UsesDefaults<τ_0_0>, @guaranteed τ_1_0, @in_guaranteed UsesDefaults<τ_0_0>) -> ()
102102
// CHECK: [[FN:%.*]] = function_ref @$s15witnesses_class11HasDefaultsPAAE23hasDefaultGenericTakesTyy1TQz_qd__tAA7FooableRd__lF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults><τ_1_0 where τ_1_0 : Fooable> (@in_guaranteed τ_0_0.T, @guaranteed τ_1_0, @in_guaranteed τ_0_0) -> ()
103-
// CHECK: apply [[FN]]<τ_0_0, τ_2_0>(
103+
// CHECK: apply [[FN]]<UsesDefaults<τ_0_0>, τ_1_0>(
104104
// CHECK: return
105105

106106
protocol ReturnsCovariantSelf {

0 commit comments

Comments
 (0)