@@ -2168,6 +2168,9 @@ static bool hasAdditionalSemanticChecks(ProtocolDecl *proto) {
2168
2168
return proto->isSpecificProtocol (KnownProtocolKind::Sendable);
2169
2169
}
2170
2170
2171
+ static void ensureRequirementsAreSatisfied (ASTContext &ctx,
2172
+ NormalProtocolConformance *conformance);
2173
+
2171
2174
// / Determine whether the type \c T conforms to the protocol \c Proto,
2172
2175
// / recording the complete witness table if it does.
2173
2176
void MultiConformanceChecker::
@@ -2191,7 +2194,6 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2191
2194
auto Proto = conformance->getProtocol ();
2192
2195
auto ProtoType = Proto->getDeclaredInterfaceType ();
2193
2196
SourceLoc ComplainLoc = conformance->getLoc ();
2194
- auto &C = ProtoType->getASTContext ();
2195
2197
2196
2198
// Note that we are checking this conformance now.
2197
2199
conformance->setState (ProtocolConformanceState::Checking);
@@ -2205,27 +2207,27 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2205
2207
2206
2208
// If the protocol requires a class, non-classes are a non-starter.
2207
2209
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);
2211
2213
conformance->setInvalid ();
2212
2214
return ;
2213
2215
}
2214
2216
2215
2217
if (T->isActorType ()) {
2216
2218
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);
2220
2222
2221
2223
CustomAttr *attr;
2222
2224
NominalTypeDecl *actor;
2223
2225
2224
2226
std::tie (attr, actor) = *globalActor;
2225
2227
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 ());
2229
2231
2230
2232
conformance->setInvalid ();
2231
2233
return ;
@@ -2248,7 +2250,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2248
2250
break ;
2249
2251
}
2250
2252
if (diagKind) {
2251
- C .Diags .diagnose (ComplainLoc, diagKind.value (), T, ProtoType);
2253
+ Context .Diags .diagnose (ComplainLoc, diagKind.value (), T, ProtoType);
2252
2254
conformance->setInvalid ();
2253
2255
return ;
2254
2256
}
@@ -2260,9 +2262,9 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2260
2262
// with the Obj-C runtime when they're satisfied, but we'd still have solve
2261
2263
// the problem with extensions that we check for below.
2262
2264
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);
2266
2268
conformance->setInvalid ();
2267
2269
return ;
2268
2270
}
@@ -2274,9 +2276,9 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2274
2276
if (auto classDecl = ext->getSelfClassDecl ()) {
2275
2277
if (classDecl->isGenericContext ()) {
2276
2278
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);
2280
2282
conformance->setInvalid ();
2281
2283
return ;
2282
2284
}
@@ -2288,22 +2290,24 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2288
2290
// Not every protocol/type is compatible with conditional conformances.
2289
2291
auto conditionalReqs = conformance->getConditionalRequirements ();
2290
2292
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
+ }
2303
2307
}
2304
- }
2305
2308
2306
- nestedType = nestedType->getNominalParent ();
2309
+ nestedType = nestedType->getNominalParent ();
2310
+ }
2307
2311
}
2308
2312
2309
2313
// If the protocol to which we are conditionally conforming is not a marker
@@ -2313,7 +2317,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2313
2317
for (const auto &req : conditionalReqs) {
2314
2318
if (req.getKind () == RequirementKind::Conformance &&
2315
2319
req.getProtocolDecl ()->isMarkerProtocol ()) {
2316
- C .Diags .diagnose (
2320
+ Context .Diags .diagnose (
2317
2321
ComplainLoc, diag::marker_protocol_conditional_conformance,
2318
2322
Proto->getName (), req.getFirstType (),
2319
2323
req.getProtocolDecl ()->getName ());
@@ -2332,16 +2336,16 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2332
2336
const auto effectiveVers =
2333
2337
getASTContext ().LangOpts .EffectiveLanguageVersion ;
2334
2338
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);
2339
2343
hasDiagnosed = true ;
2340
2344
}
2341
2345
}
2342
2346
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);
2345
2349
}
2346
2350
conformance->setInvalid ();
2347
2351
return ;
@@ -2350,7 +2354,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2350
2354
// Complain about the use of @unchecked for protocols that don't have
2351
2355
// additional semantic checks.
2352
2356
if (conformance->isUnchecked () && !hasAdditionalSemanticChecks (Proto)) {
2353
- C .Diags .diagnose (
2357
+ Context .Diags .diagnose (
2354
2358
ComplainLoc, diag::unchecked_conformance_not_special, ProtoType);
2355
2359
}
2356
2360
@@ -2379,12 +2383,35 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2379
2383
// should go into the new extension we (might) suggest here.
2380
2384
2381
2385
diagnoseConformanceImpliedByConditionalConformance (
2382
- C .Diags , conformance, implyingConf);
2386
+ Context .Diags , conformance, implyingConf);
2383
2387
2384
2388
conformance->setInvalid ();
2385
2389
}
2386
2390
}
2387
2391
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
+
2388
2415
// Check that T conforms to all inherited protocols.
2389
2416
for (auto InheritedProto : Proto->getInheritedProtocols ()) {
2390
2417
auto InheritedConformance =
@@ -2396,8 +2423,8 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2396
2423
// Recursive call already diagnosed this problem, but tack on a note
2397
2424
// to establish the relationship.
2398
2425
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 ());
2401
2428
}
2402
2429
2403
2430
conformance->setInvalid ();
@@ -2408,8 +2435,18 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
2408
2435
if (conformance->isComplete ())
2409
2436
return ;
2410
2437
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 ());
2413
2450
}
2414
2451
2415
2452
// / Add the next associated type deduction to the string representation
@@ -5034,45 +5071,13 @@ void ConformanceChecker::resolveValueWitnesses() {
5034
5071
}
5035
5072
}
5036
5073
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 ();
5076
5081
}
5077
5082
5078
5083
void swift::diagnoseConformanceFailure (Type T,
@@ -5133,16 +5138,23 @@ void swift::diagnoseConformanceFailure(Type T,
5133
5138
return ;
5134
5139
}
5135
5140
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
+ }
5145
5151
}
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 ;
5146
5158
}
5147
5159
5148
5160
// Special case: for enums with a raw type, explain that the failing
0 commit comments