@@ -3049,29 +3049,53 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3049
3049
}
3050
3050
3051
3051
void visitExtensionDecl (ExtensionDecl *ED) {
3052
+ // Produce any diagnostics for the extended type.
3053
+ auto extType = ED->getExtendedType ();
3054
+
3055
+ auto nominal = ED->getExtendedNominal ();
3056
+ if (nominal == nullptr ) {
3057
+ const bool wasAlreadyInvalid = ED->isInvalid ();
3058
+ ED->setInvalid ();
3059
+ if (extType && !extType->hasError () && extType->getAnyNominal ()) {
3060
+ // If we've got here, then we have some kind of extension of a prima
3061
+ // fascie non-nominal type. This can come up when we're projecting
3062
+ // typealiases out of bound generic types.
3063
+ //
3064
+ // struct Array<T> { typealias Indices = Range<Int> }
3065
+ // extension Array.Indices.Bound {}
3066
+ //
3067
+ // Offer to rewrite it to the underlying nominal type.
3068
+ auto canExtType = extType->getCanonicalType ();
3069
+ ED->diagnose (diag::invalid_nominal_extension, extType, canExtType)
3070
+ .highlight (ED->getExtendedTypeRepr ()->getSourceRange ());
3071
+ ED->diagnose (diag::invalid_nominal_extension_rewrite, canExtType)
3072
+ .fixItReplace (ED->getExtendedTypeRepr ()->getSourceRange (),
3073
+ canExtType->getString ());
3074
+ } else if (!wasAlreadyInvalid) {
3075
+ // If nothing else applies, fall back to a generic diagnostic.
3076
+ ED->diagnose (diag::non_nominal_extension, extType);
3077
+ }
3078
+ return ;
3079
+ }
3080
+
3052
3081
TC.validateExtension (ED);
3053
3082
3054
3083
checkInheritanceClause (ED);
3055
3084
3056
- if (auto nominal = ED->getExtendedNominal ()) {
3057
- TC.validateDecl (nominal);
3058
-
3059
- // Check the raw values of an enum, since we might synthesize
3060
- // RawRepresentable while checking conformances on this extension.
3061
- if (auto enumDecl = dyn_cast<EnumDecl>(nominal)) {
3062
- if (enumDecl->hasRawType ())
3063
- checkEnumRawValues (TC, enumDecl);
3064
- }
3085
+ // Check the raw values of an enum, since we might synthesize
3086
+ // RawRepresentable while checking conformances on this extension.
3087
+ if (auto enumDecl = dyn_cast<EnumDecl>(nominal)) {
3088
+ if (enumDecl->hasRawType ())
3089
+ checkEnumRawValues (TC, enumDecl);
3090
+ }
3065
3091
3066
- // Only generic and protocol types are permitted to have
3067
- // trailing where clauses.
3068
- if (auto trailingWhereClause = ED->getTrailingWhereClause ()) {
3069
- if (!ED->getGenericParams () &&
3070
- !ED->isInvalid ()) {
3071
- ED->diagnose (diag::extension_nongeneric_trailing_where,
3072
- nominal->getFullName ())
3092
+ // Only generic and protocol types are permitted to have
3093
+ // trailing where clauses.
3094
+ if (auto trailingWhereClause = ED->getTrailingWhereClause ()) {
3095
+ if (!ED->getGenericParams () && !ED->isInvalid ()) {
3096
+ ED->diagnose (diag::extension_nongeneric_trailing_where,
3097
+ nominal->getFullName ())
3073
3098
.highlight (trailingWhereClause->getSourceRange ());
3074
- }
3075
3099
}
3076
3100
}
3077
3101
@@ -4371,13 +4395,14 @@ static Type formExtensionInterfaceType(
4371
4395
// / Check the generic parameters of an extension, recursively handling all of
4372
4396
// / the parameter lists within the extension.
4373
4397
static GenericEnvironment *
4374
- checkExtensionGenericParams (TypeChecker &tc, ExtensionDecl *ext, Type type,
4398
+ checkExtensionGenericParams (TypeChecker &tc, ExtensionDecl *ext,
4375
4399
GenericParamList *genericParams) {
4376
4400
assert (!ext->getGenericEnvironment ());
4377
4401
4378
4402
// Form the interface type of the extension.
4379
4403
bool mustInferRequirements = false ;
4380
4404
SmallVector<std::pair<Type, Type>, 4 > sameTypeReqs;
4405
+ auto type = ext->getExtendedType ();
4381
4406
Type extInterfaceType =
4382
4407
formExtensionInterfaceType (tc, ext, type, genericParams, sameTypeReqs,
4383
4408
mustInferRequirements);
@@ -4488,10 +4513,6 @@ void TypeChecker::validateExtension(ExtensionDecl *ext) {
4488
4513
4489
4514
DeclValidationRAII IBV (ext);
4490
4515
4491
- auto extendedType = evaluateOrDefault (Context.evaluator ,
4492
- ExtendedTypeRequest{ext},
4493
- ErrorType::get (ext->getASTContext ()));
4494
-
4495
4516
if (auto *nominal = ext->getExtendedNominal ()) {
4496
4517
// If this extension was not already bound, it means it is either in an
4497
4518
// inactive conditional compilation block, or otherwise (incorrectly)
@@ -4504,8 +4525,7 @@ void TypeChecker::validateExtension(ExtensionDecl *ext) {
4504
4525
validateDecl (nominal);
4505
4526
4506
4527
if (auto *genericParams = ext->getGenericParams ()) {
4507
- GenericEnvironment *env =
4508
- checkExtensionGenericParams (*this , ext, extendedType, genericParams);
4528
+ auto *env = checkExtensionGenericParams (*this , ext, genericParams);
4509
4529
ext->setGenericEnvironment (env);
4510
4530
}
4511
4531
}
0 commit comments