@@ -832,9 +832,11 @@ SourceLoc FloatingRequirementSource::getLoc() const {
832
832
bool FloatingRequirementSource::isExplicit () const {
833
833
switch (kind) {
834
834
case Explicit:
835
- case Inferred:
836
835
return true ;
837
836
837
+ case Inferred:
838
+ return false ;
839
+
838
840
case AbstractProtocol:
839
841
switch (storage.get <const RequirementSource *>()->kind ) {
840
842
case RequirementSource::RequirementSignatureSelf:
@@ -853,13 +855,13 @@ bool FloatingRequirementSource::isExplicit() const {
853
855
case Resolved:
854
856
switch (storage.get <const RequirementSource *>()->kind ) {
855
857
case RequirementSource::Explicit:
856
- case RequirementSource::Inferred:
857
858
return true ;
858
859
859
860
case RequirementSource::ProtocolRequirement:
860
861
return storage.get <const RequirementSource *>()->parent ->kind
861
862
== RequirementSource::RequirementSignatureSelf;
862
863
864
+ case RequirementSource::Inferred:
863
865
case RequirementSource::RequirementSignatureSelf:
864
866
case RequirementSource::Concrete:
865
867
case RequirementSource::NestedTypeNameMatch:
@@ -1070,6 +1072,7 @@ struct GenericSignatureBuilder::ResolvedType {
1070
1072
}
1071
1073
1072
1074
bool isType () const { return paOrT.is <Type>(); }
1075
+ bool isPotentialArchetype () const { return paOrT.is <PotentialArchetype *>(); }
1073
1076
};
1074
1077
1075
1078
// / If there is a same-type requirement to be added for the given nested type
@@ -2182,6 +2185,13 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
2182
2185
if (!PAT->addConformance (Proto, Source, *this ))
2183
2186
return false ;
2184
2187
2188
+ // FIXME: Ad hoc recursion breaking.
2189
+ if (Visited.count (Proto)) {
2190
+ markPotentialArchetypeRecursive (PAT, Proto, Source);
2191
+ return true ;
2192
+ }
2193
+
2194
+
2185
2195
// Add the requirement to the representative.
2186
2196
auto T = PAT->getRepresentative ();
2187
2197
@@ -2303,9 +2313,8 @@ bool GenericSignatureBuilder::addLayoutRequirement(
2303
2313
// If a layout requirement was explicitly written on a concrete type,
2304
2314
// complain.
2305
2315
if (source.isExplicit () && source.getLoc ().isValid ()) {
2306
- // FIXME: TypeLoc() is unfortunate here.
2307
2316
Diags.diagnose (source.getLoc (), diag::requires_not_suitable_archetype,
2308
- 0 , TypeLoc ( ), 0 );
2317
+ 0 , TypeLoc::withoutLoc (resolvedSubject-> getType () ), 0 );
2309
2318
return true ;
2310
2319
}
2311
2320
@@ -2390,7 +2399,7 @@ bool GenericSignatureBuilder::updateSuperclass(
2390
2399
return false ;
2391
2400
}
2392
2401
2393
- bool GenericSignatureBuilder::addSuperclassRequirement (
2402
+ bool GenericSignatureBuilder::addSuperclassRequirementDirect (
2394
2403
PotentialArchetype *T,
2395
2404
Type superclass,
2396
2405
const RequirementSource *source) {
@@ -2402,6 +2411,120 @@ bool GenericSignatureBuilder::addSuperclassRequirement(
2402
2411
return updateSuperclass (T, superclass, source);
2403
2412
}
2404
2413
2414
+ // / Map an unresolved type to a requirement right-hand-side.
2415
+ static GenericSignatureBuilder::RequirementRHS
2416
+ toRequirementRHS (GenericSignatureBuilder::UnresolvedType unresolved) {
2417
+ if (auto pa = unresolved.dyn_cast <PotentialArchetype *>())
2418
+ return pa;
2419
+
2420
+ return unresolved.dyn_cast <Type>();
2421
+ }
2422
+
2423
+ bool GenericSignatureBuilder::addTypeRequirement (
2424
+ UnresolvedType subject,
2425
+ UnresolvedType constraint,
2426
+ FloatingRequirementSource source,
2427
+ Type dependentType,
2428
+ llvm::SmallPtrSetImpl<ProtocolDecl *> *visited) {
2429
+ // Make sure we always have a "visited" set to pass down.
2430
+ SmallPtrSet<ProtocolDecl *, 4 > visitedSet;
2431
+ if (!visited)
2432
+ visited = &visitedSet;
2433
+
2434
+ // Resolve the constraint.
2435
+ auto resolvedConstraint = resolve (constraint, source);
2436
+ if (!resolvedConstraint) {
2437
+ return recordUnresolvedRequirement (RequirementKind::Conformance, subject,
2438
+ toRequirementRHS (constraint), source);
2439
+ }
2440
+
2441
+ // The right-hand side needs to be concrete.
2442
+ if (auto constraintPA = resolvedConstraint->getPotentialArchetype ()) {
2443
+ // The constraint type isn't a statically-known constraint.
2444
+ if (source.getLoc ().isValid ()) {
2445
+ auto constraintType =
2446
+ constraintPA->getDependentType (Impl->GenericParams ,
2447
+ /* allowUnresolved=*/ true );
2448
+ Diags.diagnose (source.getLoc (), diag::requires_not_suitable_archetype,
2449
+ 1 , TypeLoc::withoutLoc (constraintType), 0 );
2450
+ }
2451
+
2452
+ return true ;
2453
+ }
2454
+
2455
+ // Check whether we have a reasonable constraint type at all.
2456
+ auto constraintType = resolvedConstraint->getType ();
2457
+ assert (constraintType && " Missing constraint type?" );
2458
+ if (!constraintType->isExistentialType () &&
2459
+ !constraintType->getClassOrBoundGenericClass ()) {
2460
+ if (source.getLoc ().isValid () && !constraintType->hasError ()) {
2461
+ Type subjectType = subject.dyn_cast <Type>();
2462
+ if (!subjectType)
2463
+ subjectType = subject.get <PotentialArchetype *>()
2464
+ ->getDependentType (Impl->GenericParams ,
2465
+ /* allowUnresolved=*/ true );
2466
+
2467
+ Diags.diagnose (source.getLoc (), diag::requires_conformance_nonprotocol,
2468
+ TypeLoc::withoutLoc (subjectType),
2469
+ TypeLoc::withoutLoc (constraintType));
2470
+ }
2471
+
2472
+ return true ;
2473
+ }
2474
+
2475
+ // Resolve the subject. If we can't, delay the constraint.
2476
+ auto resolvedSubject = resolve (subject, source);
2477
+ if (!resolvedSubject) {
2478
+ auto recordedKind =
2479
+ constraintType->isExistentialType ()
2480
+ ? RequirementKind::Conformance
2481
+ : RequirementKind::Superclass;
2482
+ return recordUnresolvedRequirement (recordedKind, subject, constraintType,
2483
+ source);
2484
+ }
2485
+
2486
+ // If the resolved subject is a type, we can probably perform diagnostics
2487
+ // here.
2488
+ if (resolvedSubject->isType ()) {
2489
+ // One cannot explicitly write a constraint on a concrete type.
2490
+ if (source.isExplicit ()) {
2491
+ if (source.getLoc ().isValid ()) {
2492
+ Diags.diagnose (source.getLoc (), diag::requires_not_suitable_archetype,
2493
+ 0 , TypeLoc::withoutLoc (resolvedSubject->getType ()), 0 );
2494
+ }
2495
+
2496
+ return true ;
2497
+ }
2498
+
2499
+ // FIXME: Check the constraint now.
2500
+ return false ;
2501
+ }
2502
+
2503
+ auto subjectPA = resolvedSubject->getPotentialArchetype ();
2504
+ assert (subjectPA && " No potential archetype?" );
2505
+
2506
+ auto resolvedSource = source.getSource (subjectPA, dependentType);
2507
+
2508
+ // Protocol requirements.
2509
+ if (constraintType->isExistentialType ()) {
2510
+ // FIXME: "Class" or arbitrary layout requirements.
2511
+ SmallVector<ProtocolDecl *, 4 > protocols;
2512
+ (void )constraintType->getExistentialTypeProtocols (protocols);
2513
+ bool anyErrors = false ;
2514
+ for (auto proto : protocols) {
2515
+ if (addConformanceRequirement (subjectPA, proto, resolvedSource,
2516
+ *visited))
2517
+ anyErrors = true ;
2518
+ }
2519
+
2520
+ return anyErrors;
2521
+ }
2522
+
2523
+ // Superclass constraint.
2524
+ return addSuperclassRequirementDirect (subjectPA, constraintType,
2525
+ resolvedSource);
2526
+ }
2527
+
2405
2528
void GenericSignatureBuilder::PotentialArchetype::addSameTypeConstraint (
2406
2529
PotentialArchetype *otherPA,
2407
2530
const RequirementSource *source) {
@@ -2636,15 +2759,6 @@ bool GenericSignatureBuilder::addSameTypeRequirementBetweenConcrete(
2636
2759
return !matcher.match(type1, type2);
2637
2760
}
2638
2761
2639
- // / Map an unresolved type to a requirement right-hand-side.
2640
- static GenericSignatureBuilder::RequirementRHS
2641
- toRequirementRHS (GenericSignatureBuilder::UnresolvedType unresolved) {
2642
- if (auto pa = unresolved.dyn_cast <PotentialArchetype *>())
2643
- return pa;
2644
-
2645
- return unresolved.dyn_cast <Type>();
2646
- }
2647
-
2648
2762
bool GenericSignatureBuilder::addSameTypeRequirement (
2649
2763
UnresolvedType paOrT1,
2650
2764
UnresolvedType paOrT2,
@@ -2776,30 +2890,8 @@ bool GenericSignatureBuilder::addInheritedRequirements(
2776
2890
};
2777
2891
2778
2892
// Protocol requirement.
2779
- if (auto protocolType = inheritedType->getAs <ProtocolType>()) {
2780
- if (visited.count (protocolType->getDecl ())) {
2781
- markPotentialArchetypeRecursive (
2782
- pa, protocolType->getDecl (),
2783
- getFloatingSource ().getSource (pa, dependentType));
2784
-
2785
- return true ;
2786
- }
2787
-
2788
- return addConformanceRequirement (
2789
- pa, protocolType->getDecl (),
2790
- getFloatingSource ().getSource (pa, dependentType),
2791
- visited);
2792
- }
2793
-
2794
- // Superclass requirement.
2795
- if (inheritedType->getClassOrBoundGenericClass ()) {
2796
- return addSuperclassRequirement (
2797
- pa, inheritedType,
2798
- getFloatingSource ().getSource (pa, dependentType));
2799
- }
2800
-
2801
- // Note: anything else is an error, to be diagnosed later.
2802
- return false ;
2893
+ return addTypeRequirement (pa, inheritedType, getFloatingSource (),
2894
+ dependentType, &visited);
2803
2895
});
2804
2896
}
2805
2897
@@ -2819,48 +2911,16 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
2819
2911
return t;
2820
2912
};
2821
2913
2822
-
2823
2914
switch (Req->getKind ()) {
2824
- case RequirementReprKind::LayoutConstraint: {
2825
- if (addLayoutRequirement (subst (Req->getSubject ()),
2826
- Req->getLayoutConstraint (),
2827
- source, Req->getSubject ()))
2828
- return true ;
2829
-
2830
- return false ;
2831
- }
2832
-
2833
- case RequirementReprKind::TypeConstraint: {
2834
- PotentialArchetype *PA = resolveArchetype (subst (Req->getSubject ()));
2835
- if (!PA) {
2836
- // FIXME: Poor location information.
2837
- // FIXME: Delay diagnostic until after type validation?
2838
- Diags.diagnose (Req->getColonLoc (), diag::requires_not_suitable_archetype,
2839
- 0 , Req->getSubjectLoc (), 0 );
2840
- return true ;
2841
- }
2915
+ case RequirementReprKind::LayoutConstraint:
2916
+ return addLayoutRequirement (subst (Req->getSubject ()),
2917
+ Req->getLayoutConstraint (),
2918
+ source, Req->getSubject ());
2842
2919
2843
- // Check whether this is a supertype requirement.
2844
- if (Req->getConstraint ()->getClassOrBoundGenericClass ()) {
2845
- return addSuperclassRequirement (PA, subst (Req->getConstraint ()),
2846
- source.getSource (PA, Req->getSubject ()));
2847
- }
2848
-
2849
- if (!Req->getConstraint ()->isExistentialType ()) {
2850
- // FIXME: Diagnose this failure here, rather than over in type-checking.
2851
- return true ;
2852
- }
2853
-
2854
- // Add each of the protocols.
2855
- SmallVector<ProtocolDecl *, 4 > ConformsTo;
2856
- Req->getConstraint ()->getExistentialTypeProtocols (ConformsTo);
2857
- for (auto Proto : ConformsTo)
2858
- if (addConformanceRequirement (PA, Proto,
2859
- source.getSource (PA, Req->getSubject ())))
2860
- return true ;
2861
-
2862
- return false ;
2863
- }
2920
+ case RequirementReprKind::TypeConstraint:
2921
+ return addTypeRequirement (subst (Req->getSubject ()),
2922
+ subst (Req->getConstraint ()),
2923
+ source, Req->getSubject ());
2864
2924
2865
2925
case RequirementReprKind::SameType:
2866
2926
// Require that at least one side of the requirement contain a type
@@ -2908,47 +2968,18 @@ bool GenericSignatureBuilder::addRequirement(
2908
2968
2909
2969
2910
2970
switch (req.getKind ()) {
2911
- case RequirementKind::Superclass: {
2912
- // FIXME: Diagnose this.
2913
- PotentialArchetype *pa = resolveArchetype (subst (req.getFirstType ()));
2914
- if (!pa) return false ;
2915
-
2916
- assert (req.getSecondType ()->getClassOrBoundGenericClass ());
2917
- return addSuperclassRequirement (pa, req.getSecondType (),
2918
- source.getSource (pa, req.getFirstType ()));
2919
- }
2920
-
2921
- case RequirementKind::Layout: {
2971
+ case RequirementKind::Superclass:
2972
+ case RequirementKind::Conformance:
2973
+ return addTypeRequirement (subst (req.getFirstType ()),
2974
+ subst (req.getSecondType ()),
2975
+ source, req.getFirstType (),
2976
+ &Visited);
2977
+
2978
+ case RequirementKind::Layout:
2922
2979
return addLayoutRequirement (subst (req.getFirstType ()),
2923
2980
req.getLayoutConstraint (),
2924
2981
source,
2925
2982
req.getFirstType ());
2926
- }
2927
-
2928
- case RequirementKind::Conformance: {
2929
- // FIXME: Diagnose this.
2930
- PotentialArchetype *pa = resolveArchetype (subst (req.getFirstType ()));
2931
- if (!pa) return false ;
2932
-
2933
- SmallVector<ProtocolDecl *, 4 > conformsTo;
2934
- req.getSecondType ()->getExistentialTypeProtocols (conformsTo);
2935
-
2936
- // Add each of the protocols.
2937
- for (auto proto : conformsTo) {
2938
- if (Visited.count (proto)) {
2939
- markPotentialArchetypeRecursive (
2940
- pa, proto,
2941
- source.getSource (pa, req.getFirstType ()));
2942
- continue ;
2943
- }
2944
- if (addConformanceRequirement (pa, proto,
2945
- source.getSource (pa, req.getFirstType ()),
2946
- Visited))
2947
- return true ;
2948
- }
2949
-
2950
- return false ;
2951
- }
2952
2983
2953
2984
case RequirementKind::SameType:
2954
2985
return addSameTypeRequirement (
0 commit comments