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