Skip to content

Commit ce8ad52

Browse files
authored
Merge pull request #41968 from slavapestov/fix-rdar90666408-5.6
GSB: Try to avoid calling Type::subst() from expandConformanceRequirement() [5.6]
2 parents f1224fd + 58a549f commit ce8ad52

File tree

4 files changed

+41
-25
lines changed

4 files changed

+41
-25
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3988,8 +3988,16 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
39883988
ProtocolDecl *proto,
39893989
const RequirementSource *source,
39903990
bool onlySameTypeConstraints) {
3991-
auto protocolSubMap = SubstitutionMap::getProtocolSubstitutions(
3992-
proto, selfType.getDependentType(*this), ProtocolConformanceRef(proto));
3991+
auto selfTy = selfType.getDependentType(*this);
3992+
3993+
auto subst = [&](Requirement req) -> Optional<Requirement> {
3994+
return req.subst(
3995+
[&](SubstitutableType *t) -> Type {
3996+
assert(isa<GenericTypeParamType>(t));
3997+
return selfTy;
3998+
},
3999+
MakeAbstractConformanceForGenericType());
4000+
};
39934001

39944002
// Use the requirement signature to avoid rewalking the entire protocol. This
39954003
// cannot compute the requirement signature directly, because that may be
@@ -4003,7 +4011,7 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
40034011
if (onlySameTypeConstraints && req.getKind() != RequirementKind::SameType)
40044012
continue;
40054013

4006-
auto substReq = req.subst(protocolSubMap);
4014+
auto substReq = subst(req);
40074015
auto reqResult = substReq
40084016
? addRequirement(*substReq, innerSource, nullptr)
40094017
: ConstraintResult::Conflicting;
@@ -4032,8 +4040,9 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
40324040

40334041
auto innerSource = FloatingRequirementSource::viaProtocolRequirement(
40344042
source, proto, reqRepr->getSeparatorLoc(), /*inferred=*/false);
4035-
addRequirement(req, reqRepr, innerSource,
4036-
&protocolSubMap, nullptr);
4043+
4044+
if (auto substReq = subst(req))
4045+
addRequirement(*substReq, reqRepr, innerSource, nullptr);
40374046
return false;
40384047
});
40394048

@@ -4146,7 +4155,7 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
41464155
source, proto, SourceLoc(), /*inferred=*/true);
41474156

41484157
auto rawReq = Requirement(RequirementKind::SameType, firstType, secondType);
4149-
if (auto req = rawReq.subst(protocolSubMap))
4158+
if (auto req = subst(rawReq))
41504159
addRequirement(*req, inferredSameTypeSource, proto->getParentModule());
41514160
};
41524161

@@ -4174,8 +4183,10 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
41744183

41754184
auto innerSource = FloatingRequirementSource::viaProtocolRequirement(
41764185
source, proto, reqRepr->getSeparatorLoc(), /*inferred=*/false);
4177-
addRequirement(req, reqRepr, innerSource, &protocolSubMap,
4178-
/*inferForModule=*/nullptr);
4186+
if (auto substReq = subst(req)) {
4187+
addRequirement(*substReq, reqRepr, innerSource,
4188+
/*inferForModule=*/nullptr);
4189+
}
41794190
return false;
41804191
});
41814192

@@ -5160,28 +5171,19 @@ ConstraintResult
51605171
GenericSignatureBuilder::addRequirement(const Requirement &req,
51615172
FloatingRequirementSource source,
51625173
ModuleDecl *inferForModule) {
5163-
return addRequirement(req, nullptr, source, nullptr, inferForModule);
5174+
return addRequirement(req, nullptr, source, inferForModule);
51645175
}
51655176

51665177
ConstraintResult
51675178
GenericSignatureBuilder::addRequirement(const Requirement &req,
51685179
const RequirementRepr *reqRepr,
51695180
FloatingRequirementSource source,
5170-
const SubstitutionMap *subMap,
51715181
ModuleDecl *inferForModule) {
5172-
// Local substitution for types in the requirement.
5173-
auto subst = [&](Type t) {
5174-
if (subMap)
5175-
return t.subst(*subMap);
5176-
5177-
return t;
5178-
};
5179-
5180-
auto firstType = subst(req.getFirstType());
5182+
auto firstType = req.getFirstType();
51815183
switch (req.getKind()) {
51825184
case RequirementKind::Superclass:
51835185
case RequirementKind::Conformance: {
5184-
auto secondType = subst(req.getSecondType());
5186+
auto secondType = req.getSecondType();
51855187

51865188
if (inferForModule) {
51875189
inferRequirements(*inferForModule, firstType,
@@ -5209,7 +5211,7 @@ GenericSignatureBuilder::addRequirement(const Requirement &req,
52095211
}
52105212

52115213
case RequirementKind::SameType: {
5212-
auto secondType = subst(req.getSecondType());
5214+
auto secondType = req.getSecondType();
52135215

52145216
if (inferForModule) {
52155217
inferRequirements(*inferForModule, firstType,
@@ -8697,8 +8699,8 @@ InferredGenericSignatureRequest::evaluate(
86978699
}
86988700
}
86998701

8700-
builder.addRequirement(req, reqRepr, source, nullptr,
8701-
lookupDC->getParentModule());
8702+
builder.addRequirement(req, reqRepr, source,
8703+
lookupDC->getParentModule());
87028704
return false;
87038705
};
87048706

lib/AST/GenericSignatureBuilder.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,6 @@ class GenericSignatureBuilder {
570570
ConstraintResult addRequirement(const Requirement &req,
571571
const RequirementRepr *reqRepr,
572572
FloatingRequirementSource source,
573-
const SubstitutionMap *subMap,
574573
ModuleDecl *inferForModule);
575574

576575
/// Add all of a generic signature's parameters and requirements.

test/Generics/rdar89921930.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-frontend -typecheck -verify %s
2+
3+
// This used to hit a circularity.
4+
5+
public protocol P {}
6+
7+
public struct G<T : P> {}
8+
9+
public typealias A<T : P> = G<T>
10+
11+
public protocol Circle {
12+
associatedtype X : P
13+
associatedtype Y where Y == A<X>
14+
}
15+
16+

validation-test/compiler_crashers_2_fixed/0159-rdar40009245.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
protocol P {
44
associatedtype A : P where A.X == Self
5-
// expected-error@-1{{'X' is not a member type of type 'Self.A'}}
65
associatedtype X : P where P.A == Self
76
// expected-error@-1{{associated type 'A' can only be used with a concrete type or generic parameter base}}
87
}

0 commit comments

Comments
 (0)