@@ -626,17 +626,107 @@ static bool isPointerToVoid(ASTContext &Ctx, Type Ty, bool &IsMutable) {
626
626
return BGT->getGenericArgs ().front ()->isVoid ();
627
627
}
628
628
629
- Type TypeChecker::applyGenericArguments (Type type,
630
- SourceLoc loc,
631
- TypeResolution resolution,
632
- GenericIdentTypeRepr *generic,
633
- TypeResolutionOptions options) {
629
+ static Type checkConstrainedExtensionRequirements (Type type,
630
+ SourceLoc loc,
631
+ DeclContext *dc) {
632
+ // Even if the type is not generic, it might be inside of a generic
633
+ // context, so we need to check requirements.
634
+ GenericTypeDecl *decl;
635
+ Type parentTy;
636
+ if (auto *aliasTy = dyn_cast<TypeAliasType>(type.getPointer ())) {
637
+ decl = aliasTy->getDecl ();
638
+ parentTy = aliasTy->getParent ();
639
+ } else if (auto *nominalTy = type->getAs <NominalType>()) {
640
+ decl = nominalTy->getDecl ();
641
+ parentTy = nominalTy->getParent ();
642
+ } else {
643
+ return type;
644
+ }
645
+
646
+ // FIXME: Some day the type might also have its own 'where' clause, even
647
+ // if its not generic.
648
+
649
+ auto *ext = dyn_cast<ExtensionDecl>(decl->getDeclContext ());
650
+ if (!ext || !ext->isConstrainedExtension ())
651
+ return type;
652
+
653
+ if (parentTy->hasUnboundGenericType () ||
654
+ parentTy->hasTypeVariable ()) {
655
+ return type;
656
+ }
657
+
658
+ auto subMap = parentTy->getContextSubstitutions (ext);
659
+
660
+ SourceLoc noteLoc = ext->getLoc ();
661
+ if (noteLoc.isInvalid ())
662
+ noteLoc = loc;
663
+
664
+ auto genericSig = ext->getGenericSignature ();
665
+ auto result =
666
+ TypeChecker::checkGenericArguments (
667
+ dc, loc, noteLoc, type,
668
+ genericSig->getGenericParams (),
669
+ genericSig->getRequirements (),
670
+ QueryTypeSubstitutionMap{subMap},
671
+ TypeChecker::LookUpConformance (dc),
672
+ None);
673
+
674
+ switch (result) {
675
+ case RequirementCheckResult::Failure:
676
+ case RequirementCheckResult::SubstitutionFailure:
677
+ return ErrorType::get (dc->getASTContext ());
678
+ case RequirementCheckResult::Success:
679
+ return type;
680
+ }
681
+ }
682
+
683
+ static void diagnoseUnboundGenericType (Type ty, SourceLoc loc);
684
+
685
+ // / Apply generic arguments to the given type.
686
+ // /
687
+ // / If the type is itself not generic, this does nothing.
688
+ // /
689
+ // / This function emits diagnostics about an invalid type or the wrong number
690
+ // / of generic arguments, whereas applyUnboundGenericArguments requires this
691
+ // / to be in a correct and valid form.
692
+ // /
693
+ // / \param type The generic type to which to apply arguments.
694
+ // / \param resolution The type resolution to perform.
695
+ // / \param comp The arguments to apply with the angle bracket range for
696
+ // / diagnostics.
697
+ // / \param options The type resolution context.
698
+ // /
699
+ // / \returns A BoundGenericType bound to the given arguments, or null on
700
+ // / error.
701
+ // /
702
+ // / \see applyUnboundGenericArguments
703
+ static Type applyGenericArguments (Type type,
704
+ TypeResolution resolution,
705
+ ComponentIdentTypeRepr *comp,
706
+ TypeResolutionOptions options) {
707
+ auto dc = resolution.getDeclContext ();
708
+ auto loc = comp->getIdLoc ();
709
+
710
+ auto *generic = dyn_cast<GenericIdentTypeRepr>(comp);
711
+ if (!generic) {
712
+ if (type->is <UnboundGenericType>() &&
713
+ !options.is (TypeResolverContext::TypeAliasDecl) &&
714
+ !options.contains (TypeResolutionFlags::AllowUnboundGenerics)) {
715
+ diagnoseUnboundGenericType (type, loc);
716
+ return ErrorType::get (type->getASTContext ());
717
+ }
718
+
719
+ if (resolution.getStage () == TypeResolutionStage::Structural)
720
+ return type;
721
+
722
+ return checkConstrainedExtensionRequirements (type, loc, dc);
723
+ }
724
+
634
725
if (type->hasError ()) {
635
726
generic->setInvalid ();
636
727
return type;
637
728
}
638
729
639
- auto dc = resolution.getDeclContext ();
640
730
auto &ctx = dc->getASTContext ();
641
731
auto &diags = ctx.Diags ;
642
732
@@ -716,15 +806,14 @@ Type TypeChecker::applyGenericArguments(Type type,
716
806
args.push_back (substTy);
717
807
}
718
808
719
- auto result = applyUnboundGenericArguments (unboundType, genericDecl, loc,
720
- resolution, args);
721
- if (!result)
722
- return result;
809
+ auto result = TypeChecker::applyUnboundGenericArguments (
810
+ unboundType, genericDecl, loc,
811
+ resolution, args);
723
812
724
813
if (!options.contains (TypeResolutionFlags::AllowUnavailable)) {
725
814
if (options.isAnyExpr () || dc->getParent ()->isLocalContext ())
726
815
if (dc->getResilienceExpansion () == ResilienceExpansion::Minimal)
727
- diagnoseGenericTypeExportability (loc, result, dc);
816
+ TypeChecker:: diagnoseGenericTypeExportability (loc, result, dc);
728
817
}
729
818
730
819
// Migration hack.
@@ -908,41 +997,25 @@ static void maybeDiagnoseBadConformanceRef(DeclContext *dc,
908
997
}
909
998
910
999
// / Returns a valid type or ErrorType in case of an error.
911
- static Type resolveTypeDecl (TypeDecl *typeDecl, SourceLoc loc,
1000
+ static Type resolveTypeDecl (TypeDecl *typeDecl,
912
1001
DeclContext *foundDC, TypeResolution resolution,
913
- GenericIdentTypeRepr *generic ,
1002
+ ComponentIdentTypeRepr *comp ,
914
1003
TypeResolutionOptions options) {
915
-
916
1004
// Resolve the type declaration to a specific type. How this occurs
917
1005
// depends on the current context and where the type was found.
918
- Type type = TypeChecker::resolveTypeInContext (typeDecl, foundDC, resolution,
919
- options, generic);
920
-
921
- if (type->is <UnboundGenericType>() && !generic &&
922
- !options.is (TypeResolverContext::TypeAliasDecl) &&
923
- !options.contains (TypeResolutionFlags::AllowUnboundGenerics)) {
924
- diagnoseUnboundGenericType (type, loc);
925
- return ErrorType::get (typeDecl->getASTContext ());
926
- }
1006
+ Type type = TypeChecker::resolveTypeInContext (
1007
+ typeDecl, foundDC, resolution, options,
1008
+ isa<GenericIdentTypeRepr>(comp));
927
1009
928
1010
if (type->hasError () && foundDC &&
929
1011
(isa<AssociatedTypeDecl>(typeDecl) || isa<TypeAliasDecl>(typeDecl))) {
930
1012
auto fromDC = resolution.getDeclContext ();
931
1013
assert (fromDC && " No declaration context for type resolution?" );
932
1014
maybeDiagnoseBadConformanceRef (fromDC, foundDC->getDeclaredInterfaceType (),
933
- loc, typeDecl);
934
- }
935
-
936
- if (generic) {
937
- // Apply the generic arguments to the type.
938
- type = TypeChecker::applyGenericArguments (type, loc, resolution, generic,
939
- options);
940
- if (!type)
941
- return nullptr ;
1015
+ comp->getIdLoc (), typeDecl);
942
1016
}
943
1017
944
- assert (type);
945
- return type;
1018
+ return applyGenericArguments (type, resolution, comp, options);
946
1019
}
947
1020
948
1021
static std::string getDeclNameFromContext (DeclContext *dc,
@@ -1217,9 +1290,8 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution,
1217
1290
// that now.
1218
1291
if (auto *typeDecl = comp->getBoundDecl ()) {
1219
1292
// Resolve the type declaration within this context.
1220
- return resolveTypeDecl (typeDecl, comp->getIdLoc (),
1221
- comp->getDeclContext (), resolution,
1222
- dyn_cast<GenericIdentTypeRepr>(comp), options);
1293
+ return resolveTypeDecl (typeDecl, comp->getDeclContext (), resolution,
1294
+ comp, options);
1223
1295
}
1224
1296
1225
1297
// Resolve the first component, which is the only one that requires
@@ -1265,13 +1337,8 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution,
1265
1337
auto *foundDC = entry.getDeclContext ();
1266
1338
auto *typeDecl = cast<TypeDecl>(entry.getValueDecl ());
1267
1339
1268
- Type type = resolveTypeDecl (typeDecl, comp->getIdLoc (),
1269
- foundDC, resolution,
1270
- dyn_cast<GenericIdentTypeRepr>(comp), options);
1271
-
1272
- if (!type)
1273
- return type;
1274
-
1340
+ Type type = resolveTypeDecl (typeDecl, foundDC, resolution,
1341
+ comp, options);
1275
1342
if (type->is <ErrorType>())
1276
1343
return type;
1277
1344
@@ -1355,23 +1422,6 @@ static Type resolveNestedIdentTypeComponent(
1355
1422
auto &ctx = DC->getASTContext ();
1356
1423
auto &diags = ctx.Diags ;
1357
1424
1358
- auto maybeApplyGenericArgs = [&](Type memberType) {
1359
- // If there are generic arguments, apply them now.
1360
- if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp)) {
1361
- return TypeChecker::applyGenericArguments (memberType, comp->getIdLoc (),
1362
- resolution, genComp, options);
1363
- }
1364
-
1365
- if (memberType->is <UnboundGenericType>() &&
1366
- !options.is (TypeResolverContext::TypeAliasDecl) &&
1367
- !options.contains (TypeResolutionFlags::AllowUnboundGenerics)) {
1368
- diagnoseUnboundGenericType (memberType, comp->getLoc ());
1369
- return ErrorType::get (ctx);
1370
- }
1371
-
1372
- return memberType;
1373
- };
1374
-
1375
1425
auto maybeDiagnoseBadMemberType = [&](TypeDecl *member, Type memberType,
1376
1426
AssociatedTypeDecl *inferredAssocType) {
1377
1427
// Diagnose invalid cases.
@@ -1416,7 +1466,7 @@ static Type resolveNestedIdentTypeComponent(
1416
1466
return memberType;
1417
1467
1418
1468
// If there are generic arguments, apply them now.
1419
- return maybeApplyGenericArgs (memberType);
1469
+ return applyGenericArguments (memberType, resolution, comp, options );
1420
1470
};
1421
1471
1422
1472
// Short-circuiting.
@@ -1433,7 +1483,7 @@ static Type resolveNestedIdentTypeComponent(
1433
1483
// type later on.
1434
1484
if (!memberType->is <DependentMemberType>() ||
1435
1485
memberType->castTo <DependentMemberType>()->getAssocType ()) {
1436
- return maybeApplyGenericArgs (memberType);
1486
+ return applyGenericArguments (memberType, resolution, comp, options );
1437
1487
}
1438
1488
1439
1489
return memberType;
0 commit comments