@@ -829,6 +829,47 @@ SourceLoc FloatingRequirementSource::getLoc() const {
829
829
return SourceLoc ();
830
830
}
831
831
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
+
832
873
GenericSignatureBuilder::PotentialArchetype::~PotentialArchetype () {
833
874
for (const auto &nested : NestedTypes) {
834
875
for (auto pa : nested.second ) {
@@ -1027,6 +1068,8 @@ struct GenericSignatureBuilder::ResolvedType {
1027
1068
PotentialArchetype *getPotentialArchetype () const {
1028
1069
return paOrT.dyn_cast <PotentialArchetype *>();
1029
1070
}
1071
+
1072
+ bool isType () const { return paOrT.is <Type>(); }
1030
1073
};
1031
1074
1032
1075
// / If there is a same-type requirement to be added for the given nested type
@@ -2220,7 +2263,7 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
2220
2263
return false ;
2221
2264
}
2222
2265
2223
- bool GenericSignatureBuilder::addLayoutRequirement (
2266
+ bool GenericSignatureBuilder::addLayoutRequirementDirect (
2224
2267
PotentialArchetype *PAT,
2225
2268
LayoutConstraint Layout,
2226
2269
const RequirementSource *Source) {
@@ -2242,6 +2285,41 @@ bool GenericSignatureBuilder::addLayoutRequirement(
2242
2285
return false ;
2243
2286
}
2244
2287
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
+
2245
2323
bool GenericSignatureBuilder::updateSuperclass (
2246
2324
PotentialArchetype *T,
2247
2325
Type superclass,
@@ -2279,7 +2357,7 @@ bool GenericSignatureBuilder::updateSuperclass(
2279
2357
// Presence of a superclass constraint implies a _Class layout
2280
2358
// constraint.
2281
2359
auto layoutReqSource = source->viaSuperclass (*this , nullptr );
2282
- addLayoutRequirement (T,
2360
+ addLayoutRequirementDirect (T,
2283
2361
LayoutConstraint::getLayoutConstraint (
2284
2362
superclass->getClassOrBoundGenericClass ()->isObjC ()
2285
2363
? LayoutConstraintKind::Class
@@ -2744,18 +2822,9 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
2744
2822
2745
2823
switch (Req->getKind ()) {
2746
2824
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 ()))
2759
2828
return true ;
2760
2829
2761
2830
return false ;
@@ -2850,12 +2919,10 @@ bool GenericSignatureBuilder::addRequirement(
2850
2919
}
2851
2920
2852
2921
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 ());
2859
2926
}
2860
2927
2861
2928
case RequirementKind::Conformance: {
0 commit comments