@@ -1075,12 +1075,12 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
10751075 (void )decl->getDefaultInitializer ();
10761076}
10771077
1078- void TypeChecker::synthesizeMemberForLookup (NominalTypeDecl *target,
1079- DeclName member) {
1080- auto baseName = member. getBaseName ();
1081-
1082- if (baseName == DeclBaseName::createConstructor ())
1083- addImplicitConstructors (target);
1078+ llvm::Expected< bool >
1079+ ResolveImplicitMemberRequest::evaluate (Evaluator &evaluator,
1080+ NominalTypeDecl *target,
1081+ ImplicitMemberAction action) const {
1082+ // FIXME: This entire request is a layering violation made of smaller,
1083+ // finickier layering violations. See rdar://56844567
10841084
10851085 // Checks whether the target conforms to the given protocol. If the
10861086 // conformance is incomplete, force the conformance.
@@ -1091,9 +1091,9 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
10911091 return false ;
10921092
10931093 auto targetType = target->getDeclaredInterfaceType ();
1094- auto ref =
1095- conformsToProtocol ( targetType, protocol, target,
1096- ConformanceCheckFlags::SkipConditionalRequirements);
1094+ auto ref = TypeChecker::conformsToProtocol (
1095+ targetType, protocol, target,
1096+ ConformanceCheckFlags::SkipConditionalRequirements);
10971097
10981098 if (ref.isInvalid ()) {
10991099 return false ;
@@ -1109,67 +1109,50 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
11091109 return true ;
11101110 };
11111111
1112- if (member.isSimpleName () && !baseName.isSpecial ()) {
1113- if (baseName.getIdentifier () == Context.Id_CodingKeys ) {
1114- // CodingKeys is a special type which may be synthesized as part of
1115- // Encodable/Decodable conformance. If the target conforms to either
1116- // protocol and would derive conformance to either, the type may be
1117- // synthesized.
1118- // If the target conforms to either and the conformance has not yet been
1119- // evaluated, then we should do that here.
1120- //
1121- // Try to synthesize Decodable first. If that fails, try to synthesize
1122- // Encodable. If either succeeds and CodingKeys should have been
1123- // synthesized, it will be synthesized.
1124- auto *decodableProto = Context.getProtocol (KnownProtocolKind::Decodable);
1125- auto *encodableProto = Context.getProtocol (KnownProtocolKind::Encodable);
1126- if (!evaluateTargetConformanceTo (decodableProto))
1127- (void )evaluateTargetConformanceTo (encodableProto);
1128- }
1129-
1130- if ((baseName.getIdentifier ().str ().startswith (" $" ) ||
1131- baseName.getIdentifier ().str ().startswith (" _" )) &&
1132- baseName.getIdentifier ().str ().size () > 1 ) {
1133- // $- and _-prefixed variables can be generated by properties that have
1134- // attached property wrappers.
1135- auto originalPropertyName =
1136- Context.getIdentifier (baseName.getIdentifier ().str ().substr (1 ));
1137- for (auto member : target->lookupDirect (originalPropertyName)) {
1138- if (auto var = dyn_cast<VarDecl>(member)) {
1139- if (var->hasAttachedPropertyWrapper ()) {
1140- auto sourceFile = var->getDeclContext ()->getParentSourceFile ();
1141- if (sourceFile && sourceFile->Kind != SourceFileKind::Interface)
1142- (void )var->getPropertyWrapperBackingPropertyInfo ();
1143- }
1144- }
1145- }
1146- }
1147-
1148- } else {
1149- auto argumentNames = member.getArgumentNames ();
1150- if (member.isCompoundName () && argumentNames.size () != 1 )
1151- return ;
1152-
1153- if (baseName == DeclBaseName::createConstructor () &&
1154- (member.isSimpleName () || argumentNames.front () == Context.Id_from )) {
1155- // init(from:) may be synthesized as part of derived conformance to the
1156- // Decodable protocol.
1157- // If the target should conform to the Decodable protocol, check the
1158- // conformance here to attempt synthesis.
1159- auto *decodableProto = Context.getProtocol (KnownProtocolKind::Decodable);
1160- (void )evaluateTargetConformanceTo (decodableProto);
1161- } else if (!baseName.isSpecial () &&
1162- baseName.getIdentifier () == Context.Id_encode &&
1163- (member.isSimpleName () ||
1164- argumentNames.front () == Context.Id_to )) {
1165- // encode(to:) may be synthesized as part of derived conformance to the
1166- // Encodable protocol.
1167- // If the target should conform to the Encodable protocol, check the
1168- // conformance here to attempt synthesis.
1169- auto *encodableProto = Context.getProtocol (KnownProtocolKind::Encodable);
1112+ auto &Context = target->getASTContext ();
1113+ switch (action) {
1114+ case ImplicitMemberAction::ResolveImplicitInit:
1115+ TypeChecker::addImplicitConstructors (target);
1116+ break ;
1117+ case ImplicitMemberAction::ResolveCodingKeys: {
1118+ // CodingKeys is a special type which may be synthesized as part of
1119+ // Encodable/Decodable conformance. If the target conforms to either
1120+ // protocol and would derive conformance to either, the type may be
1121+ // synthesized.
1122+ // If the target conforms to either and the conformance has not yet been
1123+ // evaluated, then we should do that here.
1124+ //
1125+ // Try to synthesize Decodable first. If that fails, try to synthesize
1126+ // Encodable. If either succeeds and CodingKeys should have been
1127+ // synthesized, it will be synthesized.
1128+ auto *decodableProto = Context.getProtocol (KnownProtocolKind::Decodable);
1129+ auto *encodableProto = Context.getProtocol (KnownProtocolKind::Encodable);
1130+ if (!evaluateTargetConformanceTo (decodableProto)) {
11701131 (void )evaluateTargetConformanceTo (encodableProto);
11711132 }
11721133 }
1134+ break ;
1135+ case ImplicitMemberAction::ResolveEncodable: {
1136+ // encode(to:) may be synthesized as part of derived conformance to the
1137+ // Encodable protocol.
1138+ // If the target should conform to the Encodable protocol, check the
1139+ // conformance here to attempt synthesis.
1140+ auto *encodableProto = Context.getProtocol (KnownProtocolKind::Encodable);
1141+ (void )evaluateTargetConformanceTo (encodableProto);
1142+ }
1143+ break ;
1144+ case ImplicitMemberAction::ResolveDecodable: {
1145+ // init(from:) may be synthesized as part of derived conformance to the
1146+ // Decodable protocol.
1147+ // If the target should conform to the Decodable protocol, check the
1148+ // conformance here to attempt synthesis.
1149+ TypeChecker::addImplicitConstructors (target);
1150+ auto *decodableProto = Context.getProtocol (KnownProtocolKind::Decodable);
1151+ (void )evaluateTargetConformanceTo (decodableProto);
1152+ }
1153+ break ;
1154+ }
1155+ return true ;
11731156}
11741157
11751158llvm::Expected<bool >
0 commit comments