@@ -490,47 +490,64 @@ static void checkNestedTypeConstraints(ConstraintSystem &cs, Type type,
490490 // info than that, unlike a typealias
491491 }
492492
493+ if (!parentTy)
494+ return ;
495+
493496 // If this decl is generic, the constraints are handled when the generic
494497 // parameters are applied, so we don't have to handle them here (which makes
495498 // getting the right substitution maps easier).
496- if (decl && !decl->isGeneric ()) {
497- auto extension = dyn_cast<ExtensionDecl>(decl->getDeclContext ());
498- if (parentTy && extension && extension->isConstrainedExtension ()) {
499- auto contextSubMap = parentTy->getContextSubstitutionMap (
500- extension->getParentModule (),
501- extension->getSelfNominalTypeDecl ());
502- if (!subMap) {
503- // The substitution map wasn't set above, meaning we should grab the map
504- // for the extension itself.
505- subMap = parentTy->getContextSubstitutionMap (
506- extension->getParentModule (), extension);
507- }
499+ if (!decl || decl->isGeneric ())
500+ return ;
508501
509- if (auto *signature = decl->getGenericSignature ()) {
510- cs.openGenericRequirements (
511- extension, signature, /* skipProtocolSelfConstraint*/ true , locator,
512- [&](Type type) {
513- // Why do we look in two substitution maps? We have to use the
514- // context substitution map to find types, because we need to
515- // avoid thinking about them when handling the constraints, or all
516- // the requirements in the signature become tautologies (if the
517- // extension has 'T == Int', subMap will map T -> Int, so the
518- // requirement becomes Int == Int no matter what the actual types
519- // are here). However, we need the conformances for the extension
520- // because the requirements might look like `T: P, T.U: Q`, where
521- // U is an associated type of protocol P.
522- return type.subst (QuerySubstitutionMap{contextSubMap},
523- LookUpConformanceInSubstitutionMap (subMap),
524- SubstFlags::UseErrorType);
525- });
526- }
502+ // struct A<T> {
503+ // let foo: [T]
504+ // }
505+ //
506+ // extension A : Codable where T: Codable {
507+ // enum CodingKeys: String, CodingKey {
508+ // case foo = "foo"
509+ // }
510+ // }
511+ //
512+ // Reference to `A.CodingKeys.foo` would point to `A` as an
513+ // unbound generic type. Conditional requirements would be
514+ // added when `A` is "opened". Les delay this check until then.
515+ if (parentTy->hasUnboundGenericType ())
516+ return ;
517+
518+ auto extension = dyn_cast<ExtensionDecl>(decl->getDeclContext ());
519+ if (extension && extension->isConstrainedExtension ()) {
520+ auto contextSubMap = parentTy->getContextSubstitutionMap (
521+ extension->getParentModule (), extension->getSelfNominalTypeDecl ());
522+ if (!subMap) {
523+ // The substitution map wasn't set above, meaning we should grab the map
524+ // for the extension itself.
525+ subMap = parentTy->getContextSubstitutionMap (extension->getParentModule (),
526+ extension);
527527 }
528528
529- // And now make sure sure the parent is okay, for things like X<T>.Y.Z.
530- if (parentTy) {
531- checkNestedTypeConstraints (cs, parentTy, locator);
529+ if (auto *signature = decl->getGenericSignature ()) {
530+ cs.openGenericRequirements (
531+ extension, signature, /* skipProtocolSelfConstraint*/ true , locator,
532+ [&](Type type) {
533+ // Why do we look in two substitution maps? We have to use the
534+ // context substitution map to find types, because we need to
535+ // avoid thinking about them when handling the constraints, or all
536+ // the requirements in the signature become tautologies (if the
537+ // extension has 'T == Int', subMap will map T -> Int, so the
538+ // requirement becomes Int == Int no matter what the actual types
539+ // are here). However, we need the conformances for the extension
540+ // because the requirements might look like `T: P, T.U: Q`, where
541+ // U is an associated type of protocol P.
542+ return type.subst (QuerySubstitutionMap{contextSubMap},
543+ LookUpConformanceInSubstitutionMap (subMap),
544+ SubstFlags::UseErrorType);
545+ });
532546 }
533547 }
548+
549+ // And now make sure sure the parent is okay, for things like X<T>.Y.Z.
550+ checkNestedTypeConstraints (cs, parentTy, locator);
534551}
535552
536553Type ConstraintSystem::openUnboundGenericType (
0 commit comments