@@ -1048,35 +1048,6 @@ static std::string getDeclNameFromContext(DeclContext *dc,
1048
1048
}
1049
1049
}
1050
1050
1051
- //
1052
- // SE-0068 is "Expanding Swift Self to class members and value types"
1053
- // Returns a Type if 'Self' is available in the current implementation.
1054
- // Errs on the side of returning `Self` in most circumstances which is
1055
- // subsequently validated in the various vistors in TypeCheckDecl.cpp.
1056
- //
1057
- // https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md
1058
- //
1059
- static Type SelfAllowedBySE0068 (TypeResolution resolution,
1060
- TypeResolutionOptions options) {
1061
- auto dc = resolution.getDeclContext ();
1062
- ASTContext &ctx = dc->getASTContext ();
1063
- DeclContext *nominalDC = nullptr ;
1064
- NominalTypeDecl *nominal = nullptr ;
1065
- if ((nominalDC = dc->getInnermostTypeContext ()) &&
1066
- (nominal = nominalDC->getSelfNominalTypeDecl ())) {
1067
- assert (!isa<ProtocolDecl>(nominal) && " Cannot be a protocol" );
1068
-
1069
- if (!options.is (TypeResolverContext::GenericRequirement)) {
1070
- Type SelfType = nominal->getSelfInterfaceType ();
1071
- if (nominalDC->getSelfClassDecl () != nullptr )
1072
- SelfType = DynamicSelfType::get (SelfType, ctx);
1073
- return resolution.mapTypeIntoContext (SelfType);
1074
- }
1075
- }
1076
-
1077
- return Type ();
1078
- }
1079
-
1080
1051
// / Diagnose a reference to an unknown type.
1081
1052
// /
1082
1053
// / This routine diagnoses a reference to an unknown type, and
@@ -1104,19 +1075,13 @@ static Type diagnoseUnknownType(TypeResolution resolution,
1104
1075
(nominal = nominalDC->getSelfNominalTypeDecl ())) {
1105
1076
// Attempt to refer to 'Self' within a non-protocol nominal
1106
1077
// type. Fix this by replacing 'Self' with the nominal type name.
1107
- assert (! isa<ProtocolDecl >(nominal) && " Cannot be a protocol " );
1078
+ assert (isa<ClassDecl >(nominal) && " Must be a class " );
1108
1079
1109
1080
// Produce a Fix-It replacing 'Self' with the nominal type name.
1110
1081
auto name = getDeclNameFromContext (dc, nominal);
1111
1082
diags.diagnose (comp->getIdLoc (), diag::self_in_nominal, name)
1112
1083
.fixItReplace (comp->getIdLoc (), name);
1113
1084
1114
- // If this is a requirement, replacing 'Self' with a valid type will
1115
- // result in additional unnecessary diagnostics (does not refer to a
1116
- // generic parameter or associated type). Simply return an error type.
1117
- if (options.is (TypeResolverContext::GenericRequirement))
1118
- return ErrorType::get (ctx);
1119
-
1120
1085
auto type = resolution.mapTypeIntoContext (
1121
1086
dc->getInnermostTypeContext ()->getSelfInterfaceType ());
1122
1087
@@ -1256,6 +1221,41 @@ static Type diagnoseUnknownType(TypeResolution resolution,
1256
1221
return ErrorType::get (ctx);
1257
1222
}
1258
1223
1224
+ enum class SelfTypeKind {
1225
+ StaticSelf,
1226
+ DynamicSelf,
1227
+ InvalidSelf
1228
+ };
1229
+
1230
+ static SelfTypeKind getSelfTypeKind (DeclContext *dc,
1231
+ TypeResolutionOptions options) {
1232
+ auto *typeDC = dc->getInnermostTypeContext ();
1233
+
1234
+ // For protocols, skip this code path and find the 'Self' generic parameter.
1235
+ if (typeDC->getSelfProtocolDecl ())
1236
+ return SelfTypeKind::InvalidSelf;
1237
+
1238
+ // In enums and structs, 'Self' is just a shorthand for the nominal type,
1239
+ // and can be used anywhere.
1240
+ if (!typeDC->getSelfClassDecl ())
1241
+ return SelfTypeKind::StaticSelf;
1242
+
1243
+ // In local functions inside classes, 'Self' is the DynamicSelfType and can
1244
+ // be used anywhere.
1245
+ if (dc->isLocalContext ())
1246
+ return SelfTypeKind::DynamicSelf;
1247
+
1248
+ // In class methods, 'Self' is the DynamicSelfType and can only appear in
1249
+ // the return type.
1250
+ switch (options.getBaseContext ()) {
1251
+ case TypeResolverContext::FunctionResult:
1252
+ case TypeResolverContext::PatternBindingDecl:
1253
+ return SelfTypeKind::DynamicSelf;
1254
+ default :
1255
+ return SelfTypeKind::InvalidSelf;
1256
+ }
1257
+ }
1258
+
1259
1259
// / Resolve the given identifier type representation as an unqualified type,
1260
1260
// / returning the type it references.
1261
1261
// /
@@ -1282,31 +1282,29 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution,
1282
1282
// Resolve the first component, which is the only one that requires
1283
1283
// unqualified name lookup.
1284
1284
auto DC = resolution.getDeclContext ();
1285
+ auto id = comp->getIdentifier ();
1285
1286
1286
1287
// Dynamic 'Self' in the result type of a function body.
1287
- if (comp->getIdentifier () == ctx.Id_Self ) {
1288
- switch (options.getBaseContext ()) {
1289
- case TypeResolverContext::FunctionResult: {
1290
- if (auto *typeDC = DC->getInnermostTypeContext ()) {
1291
- // FIXME: The passed-in TypeRepr should get 'typechecked' as well.
1292
- // The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
1293
- // while the 'Self' type is more than just a reference to a TypeDecl.
1294
- auto selfType = resolution.mapTypeIntoContext (
1295
- typeDC->getSelfInterfaceType ());
1296
- if (!typeDC->getSelfClassDecl ())
1297
- return selfType;
1288
+ if (id == ctx.Id_Self ) {
1289
+ if (auto *typeDC = DC->getInnermostTypeContext ()) {
1290
+ // FIXME: The passed-in TypeRepr should get 'typechecked' as well.
1291
+ // The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
1292
+ // while the 'Self' type is more than just a reference to a TypeDecl.
1293
+ auto selfType = resolution.mapTypeIntoContext (
1294
+ typeDC->getSelfInterfaceType ());
1295
+
1296
+ // Check if we can reference Self here, and if so, what kind of Self it is.
1297
+ switch (getSelfTypeKind (DC, options)) {
1298
+ case SelfTypeKind::StaticSelf:
1299
+ return selfType;
1300
+ case SelfTypeKind::DynamicSelf:
1298
1301
return DynamicSelfType::get (selfType, ctx);
1302
+ case SelfTypeKind::InvalidSelf:
1303
+ break ;
1299
1304
}
1300
-
1301
- break ;
1302
- }
1303
- default :
1304
- break ;
1305
1305
}
1306
1306
}
1307
1307
1308
- auto id = comp->getIdentifier ();
1309
-
1310
1308
NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
1311
1309
if (options.contains (TypeResolutionFlags::KnownNonCascadingDependency))
1312
1310
lookupOptions |= NameLookupFlags::KnownPrivate;
@@ -1375,10 +1373,6 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution,
1375
1373
if (options.contains (TypeResolutionFlags::SilenceErrors))
1376
1374
return ErrorType::get (ctx);
1377
1375
1378
- if (id == ctx.Id_Self )
1379
- if (auto SelfType = SelfAllowedBySE0068 (resolution, options))
1380
- return SelfType;
1381
-
1382
1376
return diagnoseUnknownType (resolution, nullptr , SourceRange (), comp,
1383
1377
options, lookupOptions);
1384
1378
}
0 commit comments