@@ -376,10 +376,13 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements(
376
376
377
377
static bool checkDistributedTargetResultType (
378
378
ModuleDecl *module , ValueDecl *valueDecl,
379
- const llvm::SmallPtrSetImpl<ProtocolDecl *> &serializationRequirements ,
379
+ Type serializationRequirement ,
380
380
bool diagnose) {
381
381
auto &C = valueDecl->getASTContext ();
382
382
383
+ if (!serializationRequirement || serializationRequirement->hasError ())
384
+ return false ; // error of the type would be diagnosed elsewhere
385
+
383
386
Type resultType;
384
387
if (auto func = dyn_cast<FuncDecl>(valueDecl)) {
385
388
resultType = func->mapTypeIntoContext (func->getResultInterfaceType ());
@@ -394,36 +397,39 @@ static bool checkDistributedTargetResultType(
394
397
395
398
auto isCodableRequirement =
396
399
checkDistributedSerializationRequirementIsExactlyCodable (
397
- C, serializationRequirements);
398
-
399
- for (auto serializationReq : serializationRequirements) {
400
- auto conformance =
401
- TypeChecker::conformsToProtocol (resultType, serializationReq, module );
402
- if (conformance.isInvalid ()) {
403
- if (diagnose) {
404
- llvm::StringRef conformanceToSuggest = isCodableRequirement ?
405
- " Codable" : // Codable is a typealias, easier to diagnose like that
406
- serializationReq->getNameStr ();
407
-
408
- auto diag = valueDecl->diagnose (
409
- diag::distributed_actor_target_result_not_codable,
410
- resultType,
411
- valueDecl,
412
- conformanceToSuggest
413
- );
414
-
415
- if (isCodableRequirement) {
416
- if (auto resultNominalType = resultType->getAnyNominal ()) {
417
- addCodableFixIt (resultNominalType, diag);
400
+ C, serializationRequirement);
401
+
402
+ if (serializationRequirement && !serializationRequirement->hasError ()) {
403
+ auto srl = serializationRequirement->getExistentialLayout ();
404
+ for (auto serializationReq: srl.getProtocols ()) {
405
+ auto conformance =
406
+ TypeChecker::conformsToProtocol (resultType, serializationReq, module );
407
+ if (conformance.isInvalid ()) {
408
+ if (diagnose) {
409
+ llvm::StringRef conformanceToSuggest = isCodableRequirement ?
410
+ " Codable" : // Codable is a typealias, easier to diagnose like that
411
+ serializationReq->getNameStr ();
412
+
413
+ auto diag = valueDecl->diagnose (
414
+ diag::distributed_actor_target_result_not_codable,
415
+ resultType,
416
+ valueDecl,
417
+ conformanceToSuggest
418
+ );
419
+
420
+ if (isCodableRequirement) {
421
+ if (auto resultNominalType = resultType->getAnyNominal ()) {
422
+ addCodableFixIt (resultNominalType, diag);
423
+ }
418
424
}
419
- }
420
- } // end if: diagnose
421
-
422
- return true ;
425
+ } // end if: diagnose
426
+
427
+ return true ;
428
+ }
423
429
}
424
430
}
425
431
426
- return false ;
432
+ return false ;
427
433
}
428
434
429
435
bool swift::checkDistributedActorSystem (const NominalTypeDecl *system) {
@@ -494,74 +500,35 @@ bool CheckDistributedFunctionRequest::evaluate(
494
500
if (!C.getLoadedModule (C.Id_Distributed ))
495
501
return true ;
496
502
497
- // === All parameters and the result type must conform
498
- // SerializationRequirement
499
- llvm::SmallPtrSet<ProtocolDecl *, 2 > serializationRequirements;
500
- if (auto extension = dyn_cast<ExtensionDecl>(DC)) {
501
- auto actorOrProtocol = extension->getExtendedNominal ();
502
- if (auto actor = dyn_cast<ClassDecl>(actorOrProtocol)) {
503
- assert (actor->isAnyActor ());
504
- serializationRequirements = getDistributedSerializationRequirementProtocols (
505
- getDistributedActorSystemType (actor)->getAnyNominal (),
506
- C.getProtocol (KnownProtocolKind::DistributedActorSystem));
507
- } else if (auto protocol = dyn_cast<ProtocolDecl>(actorOrProtocol)) {
508
- extractDistributedSerializationRequirements (
509
- C, protocol->getGenericRequirements (),
510
- /* into=*/ serializationRequirements);
511
- extractDistributedSerializationRequirements (
512
- C, extension->getGenericRequirements (),
513
- /* into=*/ serializationRequirements);
514
- } else {
515
- // ignore
516
- }
517
- } else if (auto actor = dyn_cast<ClassDecl>(DC)) {
518
- serializationRequirements = getDistributedSerializationRequirementProtocols (
519
- getDistributedActorSystemType (actor)->getAnyNominal (),
520
- C.getProtocol (KnownProtocolKind::DistributedActorSystem));
521
- } else if (isa<ProtocolDecl>(DC)) {
522
- if (auto seqReqTy =
523
- getConcreteReplacementForMemberSerializationRequirement (func)) {
524
- auto layout = seqReqTy->getExistentialLayout ();
525
- for (auto req : layout.getProtocols ()) {
526
- serializationRequirements.insert (req);
527
- }
528
- }
529
-
530
- // The distributed actor constrained protocol has no serialization requirements
531
- // or actor system defined, so these will only be enforced, by implementations
532
- // of DAs conforming to it, skip checks here.
533
- if (serializationRequirements.empty ()) {
534
- return false ;
535
- }
536
- } else {
537
- llvm_unreachable (" Distributed function detected in type other than extension, "
538
- " distributed actor, or protocol! This should not be possible "
539
- " , please file a bug." );
540
- }
541
-
542
- // If the requirement is exactly `Codable` we diagnose it ia bit nicer.
543
- auto serializationRequirementIsCodable =
544
- checkDistributedSerializationRequirementIsExactlyCodable (
545
- C, serializationRequirements);
546
-
547
- for (auto param : *func->getParameters ()) {
548
- // --- Check parameters for 'Codable' conformance
549
- auto paramTy = func->mapTypeIntoContext (param->getInterfaceType ());
550
-
551
- for (auto req : serializationRequirements) {
552
- if (TypeChecker::conformsToProtocol (paramTy, req, module ).isInvalid ()) {
553
- auto diag = func->diagnose (
554
- diag::distributed_actor_func_param_not_codable,
555
- param->getArgumentName ().str (), param->getInterfaceType (),
556
- func->getDescriptiveKind (),
557
- serializationRequirementIsCodable ? " Codable"
558
- : req->getNameStr ());
559
-
560
- if (auto paramNominalTy = paramTy->getAnyNominal ()) {
561
- addCodableFixIt (paramNominalTy, diag);
562
- } // else, no nominal type to suggest the fixit for, e.g. a closure
563
-
564
- return true ;
503
+ Type serializationReqType = getConcreteReplacementForMemberSerializationRequirement (func);
504
+ for (auto param: *func->getParameters ()) {
505
+
506
+ // --- Check the parameter conforming to serialization requirements
507
+ if (serializationReqType && !serializationReqType->hasError ()) {
508
+ // If the requirement is exactly `Codable` we diagnose it ia bit nicer.
509
+ auto serializationRequirementIsCodable =
510
+ checkDistributedSerializationRequirementIsExactlyCodable (
511
+ C, serializationReqType);
512
+
513
+ // --- Check parameters for 'SerializationRequirement' conformance
514
+ auto paramTy = func->mapTypeIntoContext (param->getInterfaceType ());
515
+
516
+ auto srl = serializationReqType->getExistentialLayout ();
517
+ for (auto req: srl.getProtocols ()) {
518
+ if (TypeChecker::conformsToProtocol (paramTy, req, module ).isInvalid ()) {
519
+ auto diag = func->diagnose (
520
+ diag::distributed_actor_func_param_not_codable,
521
+ param->getArgumentName ().str (), param->getInterfaceType (),
522
+ func->getDescriptiveKind (),
523
+ serializationRequirementIsCodable ? " Codable"
524
+ : req->getNameStr ());
525
+
526
+ if (auto paramNominalTy = paramTy->getAnyNominal ()) {
527
+ addCodableFixIt (paramNominalTy, diag);
528
+ } // else, no nominal type to suggest the fixit for, e.g. a closure
529
+
530
+ return true ;
531
+ }
565
532
}
566
533
}
567
534
@@ -598,10 +565,12 @@ bool CheckDistributedFunctionRequest::evaluate(
598
565
}
599
566
}
600
567
601
- // --- Result type must be either void or a codable type
602
- if (checkDistributedTargetResultType (module , func, serializationRequirements,
603
- /* diagnose=*/ true )) {
604
- return true ;
568
+ if (serializationReqType && !serializationReqType->hasError ()) {
569
+ // --- Result type must be either void or a codable type
570
+ if (checkDistributedTargetResultType (module , func, serializationReqType,
571
+ /* diagnose=*/ true )) {
572
+ return true ;
573
+ }
605
574
}
606
575
607
576
return false ;
@@ -649,13 +618,15 @@ bool swift::checkDistributedActorProperty(VarDecl *var, bool diagnose) {
649
618
DC->getSelfNominalTypeDecl ()->getDistributedActorSystemProperty ();
650
619
auto systemDecl = systemVar->getInterfaceType ()->getAnyNominal ();
651
620
652
- auto serializationRequirements =
653
- getDistributedSerializationRequirementProtocols (
654
- systemDecl,
655
- C.getProtocol (KnownProtocolKind::DistributedActorSystem));
621
+ // auto serializationRequirements =
622
+ // getDistributedSerializationRequirementProtocols(
623
+ // systemDecl,
624
+ // C.getProtocol(KnownProtocolKind::DistributedActorSystem));
625
+ auto serializationRequirement =
626
+ getConcreteReplacementForMemberSerializationRequirement (systemVar);
656
627
657
628
auto module = var->getModuleContext ();
658
- if (checkDistributedTargetResultType (module , var, serializationRequirements , diagnose)) {
629
+ if (checkDistributedTargetResultType (module , var, serializationRequirement , diagnose)) {
659
630
return true ;
660
631
}
661
632
@@ -762,6 +733,7 @@ bool TypeChecker::checkDistributedFunc(FuncDecl *func) {
762
733
return swift::checkDistributedFunction (func);
763
734
}
764
735
736
+ // TODO(distributed): Remove this entirely and rely on generic signature and getConcrete to implement checks
765
737
llvm::SmallPtrSet<ProtocolDecl *, 2 >
766
738
swift::getDistributedSerializationRequirementProtocols (
767
739
NominalTypeDecl *nominal, ProtocolDecl *protocol) {
0 commit comments