@@ -2168,6 +2168,9 @@ static bool hasAdditionalSemanticChecks(ProtocolDecl *proto) {
21682168 return proto->isSpecificProtocol (KnownProtocolKind::Sendable);
21692169}
21702170
2171+ static void ensureRequirementsAreSatisfied (ASTContext &ctx,
2172+ NormalProtocolConformance *conformance);
2173+
21712174// / Determine whether the type \c T conforms to the protocol \c Proto,
21722175// / recording the complete witness table if it does.
21732176void MultiConformanceChecker::
@@ -2191,7 +2194,6 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
21912194 auto Proto = conformance->getProtocol ();
21922195 auto ProtoType = Proto->getDeclaredInterfaceType ();
21932196 SourceLoc ComplainLoc = conformance->getLoc ();
2194- auto &C = ProtoType->getASTContext ();
21952197
21962198 // Note that we are checking this conformance now.
21972199 conformance->setState (ProtocolConformanceState::Checking);
@@ -2205,27 +2207,27 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
22052207
22062208 // If the protocol requires a class, non-classes are a non-starter.
22072209 if (Proto->requiresClass () && !DC->getSelfClassDecl ()) {
2208- C .Diags .diagnose (ComplainLoc,
2209- diag::non_class_cannot_conform_to_class_protocol, T,
2210- ProtoType);
2210+ Context .Diags .diagnose (ComplainLoc,
2211+ diag::non_class_cannot_conform_to_class_protocol, T,
2212+ ProtoType);
22112213 conformance->setInvalid ();
22122214 return ;
22132215 }
22142216
22152217 if (T->isActorType ()) {
22162218 if (auto globalActor = Proto->getGlobalActorAttr ()) {
2217- C .Diags .diagnose (ComplainLoc,
2218- diag::actor_cannot_conform_to_global_actor_protocol, T,
2219- ProtoType);
2219+ Context .Diags .diagnose (ComplainLoc,
2220+ diag::actor_cannot_conform_to_global_actor_protocol, T,
2221+ ProtoType);
22202222
22212223 CustomAttr *attr;
22222224 NominalTypeDecl *actor;
22232225
22242226 std::tie (attr, actor) = *globalActor;
22252227
2226- C .Diags .diagnose (attr->getLocation (),
2227- diag::protocol_isolated_to_global_actor_here, ProtoType,
2228- actor->getDeclaredInterfaceType ());
2228+ Context .Diags .diagnose (attr->getLocation (),
2229+ diag::protocol_isolated_to_global_actor_here, ProtoType,
2230+ actor->getDeclaredInterfaceType ());
22292231
22302232 conformance->setInvalid ();
22312233 return ;
@@ -2248,7 +2250,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
22482250 break ;
22492251 }
22502252 if (diagKind) {
2251- C .Diags .diagnose (ComplainLoc, diagKind.value (), T, ProtoType);
2253+ Context .Diags .diagnose (ComplainLoc, diagKind.value (), T, ProtoType);
22522254 conformance->setInvalid ();
22532255 return ;
22542256 }
@@ -2260,9 +2262,9 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
22602262 // with the Obj-C runtime when they're satisfied, but we'd still have solve
22612263 // the problem with extensions that we check for below.
22622264 if (!conformance->getConditionalRequirements ().empty ()) {
2263- C .Diags .diagnose (ComplainLoc,
2264- diag::objc_protocol_cannot_have_conditional_conformance,
2265- T, ProtoType);
2265+ Context .Diags .diagnose (ComplainLoc,
2266+ diag::objc_protocol_cannot_have_conditional_conformance,
2267+ T, ProtoType);
22662268 conformance->setInvalid ();
22672269 return ;
22682270 }
@@ -2274,9 +2276,9 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
22742276 if (auto classDecl = ext->getSelfClassDecl ()) {
22752277 if (classDecl->isGenericContext ()) {
22762278 if (!classDecl->isTypeErasedGenericClass ()) {
2277- C .Diags .diagnose (ComplainLoc,
2278- diag::objc_protocol_in_generic_extension,
2279- classDecl->isGeneric (), T, ProtoType);
2279+ Context .Diags .diagnose (ComplainLoc,
2280+ diag::objc_protocol_in_generic_extension,
2281+ classDecl->isGeneric (), T, ProtoType);
22802282 conformance->setInvalid ();
22812283 return ;
22822284 }
@@ -2288,22 +2290,24 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
22882290 // Not every protocol/type is compatible with conditional conformances.
22892291 auto conditionalReqs = conformance->getConditionalRequirements ();
22902292 if (!conditionalReqs.empty ()) {
2291- auto nestedType = DC->getSelfNominalTypeDecl ()->getDeclaredInterfaceType ();
2292- // Obj-C generics cannot be looked up at runtime, so we don't support
2293- // conditional conformances involving them. Check the full stack of nested
2294- // types for any obj-c ones.
2295- while (nestedType) {
2296- if (auto clazz = nestedType->getClassOrBoundGenericClass ()) {
2297- if (clazz->isTypeErasedGenericClass ()) {
2298- C.Diags .diagnose (ComplainLoc,
2299- diag::objc_generics_cannot_conditionally_conform, T,
2300- ProtoType);
2301- conformance->setInvalid ();
2302- return ;
2293+ auto nestedType = DC->getSelfInterfaceType ();
2294+ if (nestedType->getAnyNominal ()) {
2295+ // Obj-C generics cannot be looked up at runtime, so we don't support
2296+ // conditional conformances involving them. Check the full stack of nested
2297+ // types for any obj-c ones.
2298+ while (nestedType) {
2299+ if (auto clazz = nestedType->getClassOrBoundGenericClass ()) {
2300+ if (clazz->isTypeErasedGenericClass ()) {
2301+ Context.Diags .diagnose (ComplainLoc,
2302+ diag::objc_generics_cannot_conditionally_conform,
2303+ T, ProtoType);
2304+ conformance->setInvalid ();
2305+ return ;
2306+ }
23032307 }
2304- }
23052308
2306- nestedType = nestedType->getNominalParent ();
2309+ nestedType = nestedType->getNominalParent ();
2310+ }
23072311 }
23082312
23092313 // If the protocol to which we are conditionally conforming is not a marker
@@ -2313,7 +2317,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
23132317 for (const auto &req : conditionalReqs) {
23142318 if (req.getKind () == RequirementKind::Conformance &&
23152319 req.getProtocolDecl ()->isMarkerProtocol ()) {
2316- C .Diags .diagnose (
2320+ Context .Diags .diagnose (
23172321 ComplainLoc, diag::marker_protocol_conditional_conformance,
23182322 Proto->getName (), req.getFirstType (),
23192323 req.getProtocolDecl ()->getName ());
@@ -2332,16 +2336,16 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
23322336 const auto effectiveVers =
23332337 getASTContext ().LangOpts .EffectiveLanguageVersion ;
23342338 if (serialized->getLanguageVersionBuiltWith () != effectiveVers) {
2335- C .Diags .diagnose (ComplainLoc,
2336- diag::protocol_has_missing_requirements_versioned, T ,
2337- ProtoType, serialized->getLanguageVersionBuiltWith (),
2338- effectiveVers);
2339+ Context .Diags .diagnose (ComplainLoc,
2340+ diag::protocol_has_missing_requirements_versioned,
2341+ T, ProtoType, serialized->getLanguageVersionBuiltWith (),
2342+ effectiveVers);
23392343 hasDiagnosed = true ;
23402344 }
23412345 }
23422346 if (!hasDiagnosed) {
2343- C .Diags .diagnose (ComplainLoc, diag::protocol_has_missing_requirements, T ,
2344- ProtoType);
2347+ Context .Diags .diagnose (ComplainLoc, diag::protocol_has_missing_requirements,
2348+ T, ProtoType);
23452349 }
23462350 conformance->setInvalid ();
23472351 return ;
@@ -2350,7 +2354,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
23502354 // Complain about the use of @unchecked for protocols that don't have
23512355 // additional semantic checks.
23522356 if (conformance->isUnchecked () && !hasAdditionalSemanticChecks (Proto)) {
2353- C .Diags .diagnose (
2357+ Context .Diags .diagnose (
23542358 ComplainLoc, diag::unchecked_conformance_not_special, ProtoType);
23552359 }
23562360
@@ -2379,12 +2383,35 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
23792383 // should go into the new extension we (might) suggest here.
23802384
23812385 diagnoseConformanceImpliedByConditionalConformance (
2382- C .Diags , conformance, implyingConf);
2386+ Context .Diags , conformance, implyingConf);
23832387
23842388 conformance->setInvalid ();
23852389 }
23862390 }
23872391
2392+ // Except in specific hardcoded cases for Foundation/Swift
2393+ // standard library compatibility, an _ObjectiveCBridgeable
2394+ // conformance must appear in the same module as the definition of
2395+ // the conforming type.
2396+ //
2397+ // Note that we check the module name to smooth over the difference
2398+ // between an imported Objective-C module and its overlay.
2399+ if (Proto->isSpecificProtocol (KnownProtocolKind::ObjectiveCBridgeable)) {
2400+ auto nominal = DC->getSelfNominalTypeDecl ();
2401+ if (!Context.isTypeBridgedInExternalModule (nominal)) {
2402+ auto clangLoader = Context.getClangModuleLoader ();
2403+ if (nominal->getParentModule () != DC->getParentModule () &&
2404+ !(clangLoader &&
2405+ clangLoader->isInOverlayModuleForImportedModule (DC, nominal))) {
2406+ auto nominalModule = nominal->getParentModule ();
2407+ Context.Diags .diagnose (conformance->getLoc (),
2408+ diag::nonlocal_bridged_to_objc,
2409+ nominal->getName (), Proto->getName (),
2410+ nominalModule->getName ());
2411+ }
2412+ }
2413+ }
2414+
23882415 // Check that T conforms to all inherited protocols.
23892416 for (auto InheritedProto : Proto->getInheritedProtocols ()) {
23902417 auto InheritedConformance =
@@ -2396,8 +2423,8 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
23962423 // Recursive call already diagnosed this problem, but tack on a note
23972424 // to establish the relationship.
23982425 if (ComplainLoc.isValid ()) {
2399- C .Diags .diagnose (Proto, diag::inherited_protocol_does_not_conform, T ,
2400- InheritedProto->getDeclaredInterfaceType ());
2426+ Context .Diags .diagnose (Proto, diag::inherited_protocol_does_not_conform,
2427+ T, InheritedProto->getDeclaredInterfaceType ());
24012428 }
24022429
24032430 conformance->setInvalid ();
@@ -2408,8 +2435,18 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
24082435 if (conformance->isComplete ())
24092436 return ;
24102437
2411- ConformanceChecker checker (getASTContext (), conformance);
2412- checker.checkConformance ();
2438+ // Resolve all of the type witnesses.
2439+ evaluateOrDefault (Context.evaluator ,
2440+ ResolveTypeWitnessesRequest{conformance},
2441+ evaluator::SideEffect ());
2442+
2443+ // Check the requirements from the requirement signature.
2444+ ensureRequirementsAreSatisfied (Context, conformance);
2445+
2446+ // Check non-type requirements.
2447+ evaluateOrDefault (Context.evaluator ,
2448+ ResolveValueWitnessesRequest{conformance},
2449+ evaluator::SideEffect ());
24132450}
24142451
24152452// / Add the next associated type deduction to the string representation
@@ -5034,45 +5071,13 @@ void ConformanceChecker::resolveValueWitnesses() {
50345071 }
50355072}
50365073
5037- void ConformanceChecker::checkConformance () {
5038- assert (!Conformance->isComplete () && " Conformance is already complete" );
5039-
5040- FrontendStatsTracer statsTracer (getASTContext ().Stats ,
5041- " check-conformance" , Conformance);
5042-
5043- // Resolve all of the type witnesses.
5044- evaluateOrDefault (getASTContext ().evaluator ,
5045- ResolveTypeWitnessesRequest{Conformance},
5046- evaluator::SideEffect ());
5047-
5048- // Check the requirements from the requirement signature.
5049- ensureRequirementsAreSatisfied (getASTContext (), Conformance);
5050-
5051- // Check non-type requirements.
5052- resolveValueWitnesses ();
5053-
5054- // Except in specific hardcoded cases for Foundation/Swift
5055- // standard library compatibility, an _ObjectiveCBridgeable
5056- // conformance must appear in the same module as the definition of
5057- // the conforming type.
5058- //
5059- // Note that we check the module name to smooth over the difference
5060- // between an imported Objective-C module and its overlay.
5061- if (Proto->isSpecificProtocol (KnownProtocolKind::ObjectiveCBridgeable)) {
5062- auto nominal = DC->getSelfNominalTypeDecl ();
5063- if (!getASTContext ().isTypeBridgedInExternalModule (nominal)) {
5064- auto clangLoader = getASTContext ().getClangModuleLoader ();
5065- if (nominal->getParentModule () != DC->getParentModule () &&
5066- !(clangLoader &&
5067- clangLoader->isInOverlayModuleForImportedModule (DC, nominal))) {
5068- auto nominalModule = nominal->getParentModule ();
5069- auto &C = nominal->getASTContext ();
5070- C.Diags .diagnose (Loc, diag::nonlocal_bridged_to_objc,
5071- nominal->getName (), Proto->getName (),
5072- nominalModule->getName ());
5073- }
5074- }
5075- }
5074+ evaluator::SideEffect
5075+ ResolveValueWitnessesRequest::evaluate (Evaluator &evaluator,
5076+ NormalProtocolConformance *conformance) const {
5077+ auto &ctx = conformance->getDeclContext ()->getASTContext ();
5078+ ConformanceChecker checker (ctx, conformance);
5079+ checker.resolveValueWitnesses ();
5080+ return evaluator::SideEffect ();
50765081}
50775082
50785083void swift::diagnoseConformanceFailure (Type T,
@@ -5133,16 +5138,23 @@ void swift::diagnoseConformanceFailure(Type T,
51335138 return ;
51345139 }
51355140
5136- // If it is missing the ActorSystem type, suggest adding it:
5137- auto systemTy = getDistributedActorSystemType (/* actor=*/ nominal);
5138- if (!systemTy || systemTy->hasError ()) {
5139- diags.diagnose (ComplainLoc,
5140- diag::distributed_actor_conformance_missing_system_type,
5141- nominal->getName ());
5142- diags.diagnose (nominal->getStartLoc (),
5143- diag::note_distributed_actor_system_can_be_defined_using_defaultdistributedactorsystem);
5144- return ;
5141+ if (nominal->isDistributedActor ()) {
5142+ // If it is missing the ActorSystem type, suggest adding it:
5143+ auto systemTy = getDistributedActorSystemType (/* actor=*/ nominal);
5144+ if (!systemTy || systemTy->hasError ()) {
5145+ diags.diagnose (ComplainLoc,
5146+ diag::distributed_actor_conformance_missing_system_type,
5147+ nominal->getName ());
5148+ diags.diagnose (nominal->getStartLoc (),
5149+ diag::note_distributed_actor_system_can_be_defined_using_defaultdistributedactorsystem);
5150+ }
51455151 }
5152+
5153+ // For a non-class nominal type, we already diagnose the failure in
5154+ // ensureRequirementsAreSatisfied() when the 'Self: AnyObject' requirement
5155+ // fails.
5156+ if (!isa<ClassDecl>(nominal))
5157+ return ;
51465158 }
51475159
51485160 // Special case: for enums with a raw type, explain that the failing
0 commit comments