Skip to content

Commit a58bc8a

Browse files
committed
Sema: Use GSB to build the signature for opaque result type decls.
Our ad-hoc mechanism for building the signature did not always produce requirements in the order expected by the rest of the system; using the GSB should ensure we build a valid generic signature. Fixes rdar://problem/50309983.
1 parent d044696 commit a58bc8a

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -194,49 +194,52 @@ Type TypeChecker::getOrCreateOpaqueResultType(TypeResolution resolution,
194194
// Create a generic signature for the opaque environment. This is the outer
195195
// generic signature with an added generic parameter representing the opaque
196196
// type and its interface constraints.
197-
SmallVector<GenericTypeParamType *, 4> interfaceGenericParams;
198-
SmallVector<Requirement, 4> interfaceRequirements;
197+
GenericSignatureBuilder builder(Context);
199198

200199
auto originatingDC = originatingDecl->getInnermostDeclContext();
200+
unsigned returnTypeDepth = 0;
201201
auto outerGenericSignature = originatingDC->getGenericSignatureOfContext();
202+
202203
if (outerGenericSignature) {
203-
std::copy(outerGenericSignature->getGenericParams().begin(),
204-
outerGenericSignature->getGenericParams().end(),
205-
std::back_inserter(interfaceGenericParams));
206-
std::copy(outerGenericSignature->getRequirements().begin(),
207-
outerGenericSignature->getRequirements().end(),
208-
std::back_inserter(interfaceRequirements));
204+
builder.addGenericSignature(outerGenericSignature);
205+
returnTypeDepth =
206+
outerGenericSignature->getGenericParams().back()->getDepth() + 1;
209207
}
210-
211-
unsigned returnTypeDepth = 0;
212-
if (!interfaceGenericParams.empty())
213-
returnTypeDepth = interfaceGenericParams.back()->getDepth() + 1;
208+
214209
auto returnTypeParam = GenericTypeParamType::get(returnTypeDepth, 0,
215210
Context);
216-
interfaceGenericParams.push_back(returnTypeParam);
211+
212+
builder.addGenericParameter(returnTypeParam);
217213

218214
if (constraintType->getClassOrBoundGenericClass()) {
219-
// Use the type as a superclass constraint.
220-
interfaceRequirements.push_back(Requirement(RequirementKind::Superclass,
221-
returnTypeParam, constraintType));
215+
builder.addRequirement(Requirement(RequirementKind::Superclass,
216+
returnTypeParam, constraintType),
217+
GenericSignatureBuilder::FloatingRequirementSource::forAbstract(),
218+
originatingDC->getParentModule());
222219
} else {
223220
auto constraints = constraintType->getExistentialLayout();
224221
if (auto superclass = constraints.getSuperclass()) {
225-
interfaceRequirements.push_back(Requirement(RequirementKind::Superclass,
226-
returnTypeParam, superclass));
222+
builder.addRequirement(Requirement(RequirementKind::Superclass,
223+
returnTypeParam, superclass),
224+
GenericSignatureBuilder::FloatingRequirementSource::forAbstract(),
225+
originatingDC->getParentModule());
227226
}
228227
for (auto protocol : constraints.getProtocols()) {
229-
interfaceRequirements.push_back(Requirement(RequirementKind::Conformance,
230-
returnTypeParam, protocol));
228+
builder.addRequirement(Requirement(RequirementKind::Conformance,
229+
returnTypeParam, protocol),
230+
GenericSignatureBuilder::FloatingRequirementSource::forAbstract(),
231+
originatingDC->getParentModule());
231232
}
232233
if (auto layout = constraints.getLayoutConstraint()) {
233-
interfaceRequirements.push_back(Requirement(RequirementKind::Layout,
234-
returnTypeParam, layout));
234+
builder.addRequirement(Requirement(RequirementKind::Layout,
235+
returnTypeParam, layout),
236+
GenericSignatureBuilder::FloatingRequirementSource::forAbstract(),
237+
originatingDC->getParentModule());
235238
}
236239
}
237240

238-
auto interfaceSignature = GenericSignature::get(interfaceGenericParams,
239-
interfaceRequirements);
241+
auto interfaceSignature = std::move(builder)
242+
.computeGenericSignature(SourceLoc());
240243

241244
// Create the OpaqueTypeDecl for the result type.
242245
// It has the same parent context and generic environment as the originating
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend -emit-ir -verify %s
2+
3+
// rdar://problem/50309983, make sure that the generic signature built for
4+
// an opaque return type is correct when there are associated type constraints
5+
// on the enclosing generic context
6+
7+
protocol Bort {}
8+
9+
extension Int: Bort {}
10+
11+
struct Butt<T: RandomAccessCollection>
12+
where T.Element: Bort, T.Index: Hashable
13+
{
14+
func foo() -> some Bort {
15+
return 0
16+
}
17+
}

0 commit comments

Comments
 (0)