Skip to content

Commit 68efffd

Browse files
committed
[GSB] Separate out the "unresolved" and "direct" layout constraint entrypoints.
More staging for delayed resolution of constraints.
1 parent 6991a8c commit 68efffd

File tree

2 files changed

+107
-29
lines changed

2 files changed

+107
-29
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,23 @@ class GenericSignatureBuilder {
295295
Type T1, Type T2, FloatingRequirementSource Source,
296296
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
297297

298+
/// \brief Add a new layout requirement directly on the potential archetype.
299+
///
300+
/// \returns true if this requirement makes the set of requirements
301+
/// inconsistent, in which case a diagnostic will have been issued.
302+
bool addLayoutRequirementDirect(PotentialArchetype *PAT,
303+
LayoutConstraint Layout,
304+
const RequirementSource *Source);
305+
306+
/// Add a new layout requirement to the subject.
307+
///
308+
/// FIXME: The "dependent type" is the subject type pre-substitution. We
309+
/// should be able to compute this!
310+
bool addLayoutRequirement(UnresolvedType subject,
311+
LayoutConstraint layout,
312+
FloatingRequirementSource source,
313+
Type dependentType);
314+
298315
/// Add the requirements placed on the given type parameter
299316
/// to the given potential archetype.
300317
///
@@ -389,15 +406,6 @@ class GenericSignatureBuilder {
389406
const SubstitutionMap *subMap,
390407
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
391408

392-
/// \brief Add a new requirement.
393-
///
394-
/// \returns true if this requirement makes the set of requirements
395-
/// inconsistent, in which case a diagnostic will have been issued.
396-
397-
bool addLayoutRequirement(PotentialArchetype *PAT,
398-
LayoutConstraint Layout,
399-
const RequirementSource *Source);
400-
401409
/// \brief Add all of a generic signature's parameters and requirements.
402410
void addGenericSignature(GenericSignature *sig);
403411

@@ -1060,6 +1068,9 @@ class GenericSignatureBuilder::FloatingRequirementSource {
10601068

10611069
/// Retrieve the source location for this requirement.
10621070
SourceLoc getLoc() const;
1071+
1072+
/// Whether this is an explicitly-stated requirement.
1073+
bool isExplicit() const;
10631074
};
10641075

10651076
class GenericSignatureBuilder::PotentialArchetype {

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,47 @@ SourceLoc FloatingRequirementSource::getLoc() const {
829829
return SourceLoc();
830830
}
831831

832+
bool FloatingRequirementSource::isExplicit() const {
833+
switch (kind) {
834+
case Explicit:
835+
case Inferred:
836+
return true;
837+
838+
case AbstractProtocol:
839+
switch (storage.get<const RequirementSource *>()->kind) {
840+
case RequirementSource::RequirementSignatureSelf:
841+
return true;
842+
843+
case RequirementSource::Concrete:
844+
case RequirementSource::Explicit:
845+
case RequirementSource::Inferred:
846+
case RequirementSource::NestedTypeNameMatch:
847+
case RequirementSource::Parent:
848+
case RequirementSource::ProtocolRequirement:
849+
case RequirementSource::Superclass:
850+
return false;
851+
}
852+
853+
case Resolved:
854+
switch (storage.get<const RequirementSource *>()->kind) {
855+
case RequirementSource::Explicit:
856+
case RequirementSource::Inferred:
857+
return true;
858+
859+
case RequirementSource::ProtocolRequirement:
860+
return storage.get<const RequirementSource *>()->parent->kind
861+
== RequirementSource::RequirementSignatureSelf;
862+
863+
case RequirementSource::RequirementSignatureSelf:
864+
case RequirementSource::Concrete:
865+
case RequirementSource::NestedTypeNameMatch:
866+
case RequirementSource::Parent:
867+
case RequirementSource::Superclass:
868+
return false;
869+
}
870+
}
871+
}
872+
832873
GenericSignatureBuilder::PotentialArchetype::~PotentialArchetype() {
833874
for (const auto &nested : NestedTypes) {
834875
for (auto pa : nested.second) {
@@ -1027,6 +1068,8 @@ struct GenericSignatureBuilder::ResolvedType {
10271068
PotentialArchetype *getPotentialArchetype() const {
10281069
return paOrT.dyn_cast<PotentialArchetype *>();
10291070
}
1071+
1072+
bool isType() const { return paOrT.is<Type>(); }
10301073
};
10311074

10321075
/// If there is a same-type requirement to be added for the given nested type
@@ -2220,7 +2263,7 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
22202263
return false;
22212264
}
22222265

2223-
bool GenericSignatureBuilder::addLayoutRequirement(
2266+
bool GenericSignatureBuilder::addLayoutRequirementDirect(
22242267
PotentialArchetype *PAT,
22252268
LayoutConstraint Layout,
22262269
const RequirementSource *Source) {
@@ -2242,6 +2285,41 @@ bool GenericSignatureBuilder::addLayoutRequirement(
22422285
return false;
22432286
}
22442287

2288+
bool GenericSignatureBuilder::addLayoutRequirement(
2289+
UnresolvedType subject,
2290+
LayoutConstraint layout,
2291+
FloatingRequirementSource source,
2292+
Type dependentType) {
2293+
// Resolve the subject.
2294+
auto resolvedSubject = resolve(subject, source);
2295+
if (!resolvedSubject) {
2296+
return recordUnresolvedRequirement(RequirementKind::Layout, subject,
2297+
layout, source);
2298+
}
2299+
2300+
// If this layout constraint applies to a concrete type, we can fully
2301+
// resolve it now.
2302+
if (resolvedSubject->isType()) {
2303+
// If a layout requirement was explicitly written on a concrete type,
2304+
// complain.
2305+
if (source.isExplicit() && source.getLoc().isValid()) {
2306+
// FIXME: TypeLoc() is unfortunate here.
2307+
Diags.diagnose(source.getLoc(), diag::requires_not_suitable_archetype,
2308+
0, TypeLoc(), 0);
2309+
return true;
2310+
}
2311+
2312+
// FIXME: Check whether the layout constraint makes sense for this
2313+
// concrete type!
2314+
2315+
return false;
2316+
}
2317+
2318+
auto pa = resolvedSubject->getPotentialArchetype();
2319+
return addLayoutRequirementDirect(pa, layout,
2320+
source.getSource(pa, dependentType));
2321+
}
2322+
22452323
bool GenericSignatureBuilder::updateSuperclass(
22462324
PotentialArchetype *T,
22472325
Type superclass,
@@ -2279,7 +2357,7 @@ bool GenericSignatureBuilder::updateSuperclass(
22792357
// Presence of a superclass constraint implies a _Class layout
22802358
// constraint.
22812359
auto layoutReqSource = source->viaSuperclass(*this, nullptr);
2282-
addLayoutRequirement(T,
2360+
addLayoutRequirementDirect(T,
22832361
LayoutConstraint::getLayoutConstraint(
22842362
superclass->getClassOrBoundGenericClass()->isObjC()
22852363
? LayoutConstraintKind::Class
@@ -2744,18 +2822,9 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
27442822

27452823
switch (Req->getKind()) {
27462824
case RequirementReprKind::LayoutConstraint: {
2747-
// FIXME: Need to do something here.
2748-
PotentialArchetype *PA = resolveArchetype(subst(Req->getSubject()));
2749-
if (!PA) {
2750-
// FIXME: Poor location information.
2751-
// FIXME: Delay diagnostic until after type validation?
2752-
Diags.diagnose(Req->getColonLoc(), diag::requires_not_suitable_archetype,
2753-
0, Req->getSubjectLoc(), 0);
2754-
return true;
2755-
}
2756-
2757-
if (addLayoutRequirement(PA, Req->getLayoutConstraint(),
2758-
source.getSource(PA, Req->getSubject())))
2825+
if (addLayoutRequirement(subst(Req->getSubject()),
2826+
Req->getLayoutConstraint(),
2827+
source, Req->getSubject()))
27592828
return true;
27602829

27612830
return false;
@@ -2850,12 +2919,10 @@ bool GenericSignatureBuilder::addRequirement(
28502919
}
28512920

28522921
case RequirementKind::Layout: {
2853-
// FIXME: Diagnose this.
2854-
PotentialArchetype *pa = resolveArchetype(subst(req.getFirstType()));
2855-
if (!pa) return false;
2856-
2857-
return addLayoutRequirement(pa, req.getLayoutConstraint(),
2858-
source.getSource(pa, req.getFirstType()));
2922+
return addLayoutRequirement(subst(req.getFirstType()),
2923+
req.getLayoutConstraint(),
2924+
source,
2925+
req.getFirstType());
28592926
}
28602927

28612928
case RequirementKind::Conformance: {

0 commit comments

Comments
 (0)