@@ -1033,6 +1033,44 @@ static std::string getDeclNameFromContext(DeclContext *dc,
1033
1033
}
1034
1034
}
1035
1035
1036
+ //
1037
+ // SE-0068 is "Expanding Swift Self to class members and value types"
1038
+ // https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md
1039
+ //
1040
+ static Type SelfAllowedBySE0068 (TypeResolution resolution,
1041
+ TypeResolutionOptions options) {
1042
+ auto dc = resolution.getDeclContext ();
1043
+ ASTContext &ctx = dc->getASTContext ();
1044
+ DeclContext *nominalDC = nullptr ;
1045
+ NominalTypeDecl *nominal = nullptr ;
1046
+ if ((nominalDC = dc->getInnermostTypeContext ()) &&
1047
+ (nominal = nominalDC->getSelfNominalTypeDecl ())) {
1048
+ assert (!isa<ProtocolDecl>(nominal) && " Cannot be a protocol" );
1049
+
1050
+ bool insideClass = nominalDC->getSelfClassDecl () != nullptr ;
1051
+ AbstractFunctionDecl *methodDecl = dc->getInnermostMethodContext ();
1052
+ bool declaringMethod = methodDecl &&
1053
+ methodDecl->getDeclContext () == dc->getParentForLookup ();
1054
+ bool isMutablePropertyOrSubscriptOfClass = insideClass &&
1055
+ (options.is (TypeResolverContext::PatternBindingDecl) ||
1056
+ options.is (TypeResolverContext::FunctionResult));
1057
+ bool isTypeAliasInClass = insideClass &&
1058
+ options.is (TypeResolverContext::TypeAliasDecl);
1059
+
1060
+ if (((!insideClass || !declaringMethod) &&
1061
+ !isMutablePropertyOrSubscriptOfClass && !isTypeAliasInClass &&
1062
+ !options.is (TypeResolverContext::GenericRequirement)) ||
1063
+ options.is (TypeResolverContext::ExplicitCastExpr)) {
1064
+ Type SelfType = nominal->getSelfInterfaceType ();
1065
+ if (insideClass)
1066
+ SelfType = DynamicSelfType::get (SelfType, ctx);
1067
+ return resolution.mapTypeIntoContext (SelfType);
1068
+ }
1069
+ }
1070
+
1071
+ return Type ();
1072
+ }
1073
+
1036
1074
// / Diagnose a reference to an unknown type.
1037
1075
// /
1038
1076
// / This routine diagnoses a reference to an unknown type, and
@@ -1058,25 +1096,10 @@ static Type diagnoseUnknownType(TypeResolution resolution,
1058
1096
NominalTypeDecl *nominal = nullptr ;
1059
1097
if ((nominalDC = dc->getInnermostTypeContext ()) &&
1060
1098
(nominal = nominalDC->getSelfNominalTypeDecl ())) {
1099
+ // Attempt to refer to 'Self' within a non-protocol nominal
1100
+ // type. Fix this by replacing 'Self' with the nominal type name.
1061
1101
assert (!isa<ProtocolDecl>(nominal) && " Cannot be a protocol" );
1062
1102
1063
- bool insideClass = nominalDC->getSelfClassDecl () != nullptr ;
1064
- AbstractFunctionDecl *methodDecl = dc->getInnermostMethodContext ();
1065
- bool declaringMethod = methodDecl &&
1066
- methodDecl->getDeclContext () == dc->getParentForLookup ();
1067
- bool isPropertyOfClass = insideClass &&
1068
- options.is (TypeResolverContext::PatternBindingDecl);
1069
-
1070
- if (((!insideClass || !declaringMethod) && !isPropertyOfClass &&
1071
- !options.is (TypeResolverContext::GenericRequirement)) ||
1072
- options.is (TypeResolverContext::ExplicitCastExpr)) {
1073
- Type SelfType = nominal->getSelfInterfaceType ();
1074
- if (insideClass)
1075
- SelfType = DynamicSelfType::get (SelfType, ctx);
1076
- return resolution.mapTypeIntoContext (SelfType);
1077
- }
1078
-
1079
- // Attempt to refer to 'Self' within a non-protocol nominal type.
1080
1103
// Produce a Fix-It replacing 'Self' with the nominal type name.
1081
1104
auto name = getDeclNameFromContext (dc, nominal);
1082
1105
diags.diagnose (comp->getIdLoc (), diag::self_in_nominal, name)
@@ -1341,6 +1364,10 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution,
1341
1364
if (options.contains (TypeResolutionFlags::SilenceErrors))
1342
1365
return ErrorType::get (ctx);
1343
1366
1367
+ if (id == ctx.Id_Self )
1368
+ if (auto SelfType = SelfAllowedBySE0068 (resolution, options))
1369
+ return SelfType;
1370
+
1344
1371
return diagnoseUnknownType (resolution, nullptr , SourceRange (), comp,
1345
1372
options, lookupOptions);
1346
1373
}
0 commit comments