Skip to content

Commit ddfd73e

Browse files
committed
[RequirementMachine] Only skip Sendable requirements inferred from preconcurrency
decls if the decl we're inferring the generic signature for is not itself preconcurrency.
1 parent 0a2e53f commit ddfd73e

File tree

4 files changed

+29
-12
lines changed

4 files changed

+29
-12
lines changed

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -467,10 +467,12 @@ namespace {
467467
/// AST walker that infers requirements from type representations.
468468
struct InferRequirementsWalker : public TypeWalker {
469469
ModuleDecl *module;
470+
DeclContext *dc;
470471
SmallVector<Requirement, 2> reqs;
471472
SmallVector<RequirementError, 2> errors;
472473

473-
explicit InferRequirementsWalker(ModuleDecl *module) : module(module) {}
474+
explicit InferRequirementsWalker(ModuleDecl *module, DeclContext *dc)
475+
: module(module), dc(dc) {}
474476

475477
Action walkToTypePre(Type ty) override {
476478
// Unbound generic types are the result of recovered-but-invalid code, and
@@ -484,10 +486,17 @@ struct InferRequirementsWalker : public TypeWalker {
484486
Action walkToTypePost(Type ty) override {
485487
// Skip `Sendable` conformance requirements that are inferred from
486488
// `@preconcurrency` declarations.
487-
auto skipRequirement = [](Requirement req, Decl *fromDecl) {
489+
auto skipRequirement = [&](Requirement req, Decl *fromDecl) {
488490
if (!fromDecl->preconcurrency())
489491
return false;
490492

493+
// If this decl is `@preconcurrency`, include concurrency
494+
// requirements. The explicit annotation directly on the decl
495+
// will still exclude `Sendable` requirements from ABI.
496+
auto *decl = dc->getAsDecl();
497+
if (!decl || decl->preconcurrency())
498+
return false;
499+
491500
return (req.getKind() == RequirementKind::Conformance &&
492501
req.getSecondType()->castTo<ProtocolType>()->getDecl()
493502
->isSpecificProtocol(KnownProtocolKind::Sendable));
@@ -602,12 +611,13 @@ struct InferRequirementsWalker : public TypeWalker {
602611
/// We automatically infer 'T : Hashable' from the fact that 'struct Set'
603612
/// declares a Hashable requirement on its generic parameter.
604613
void swift::rewriting::inferRequirements(
605-
Type type, SourceLoc loc, ModuleDecl *module,
614+
Type type, SourceLoc loc,
615+
ModuleDecl *module, DeclContext *dc,
606616
SmallVectorImpl<StructuralRequirement> &result) {
607617
if (!type)
608618
return;
609619

610-
InferRequirementsWalker walker(module);
620+
InferRequirementsWalker walker(module, dc);
611621
type.walk(walker);
612622

613623
for (const auto &req : walker.reqs)
@@ -636,11 +646,11 @@ void swift::rewriting::realizeRequirement(
636646
if (shouldInferRequirements) {
637647
auto firstLoc = (reqRepr ? reqRepr->getSubjectRepr()->getStartLoc()
638648
: SourceLoc());
639-
inferRequirements(firstType, firstLoc, moduleForInference, result);
649+
inferRequirements(firstType, firstLoc, moduleForInference, dc, result);
640650

641651
auto secondLoc = (reqRepr ? reqRepr->getConstraintRepr()->getStartLoc()
642652
: SourceLoc());
643-
inferRequirements(secondType, secondLoc, moduleForInference, result);
653+
inferRequirements(secondType, secondLoc, moduleForInference, dc, result);
644654
}
645655

646656
realizeTypeRequirement(dc, firstType, secondType, loc, result, errors);
@@ -651,7 +661,7 @@ void swift::rewriting::realizeRequirement(
651661
if (shouldInferRequirements) {
652662
auto firstLoc = (reqRepr ? reqRepr->getSubjectRepr()->getStartLoc()
653663
: SourceLoc());
654-
inferRequirements(firstType, firstLoc, moduleForInference, result);
664+
inferRequirements(firstType, firstLoc, moduleForInference, dc, result);
655665
}
656666

657667
SmallVector<Requirement, 2> reqs;
@@ -669,11 +679,11 @@ void swift::rewriting::realizeRequirement(
669679
if (shouldInferRequirements) {
670680
auto firstLoc = (reqRepr ? reqRepr->getFirstTypeRepr()->getStartLoc()
671681
: SourceLoc());
672-
inferRequirements(firstType, firstLoc, moduleForInference, result);
682+
inferRequirements(firstType, firstLoc, moduleForInference, dc, result);
673683

674684
auto secondLoc = (reqRepr ? reqRepr->getSecondTypeRepr()->getStartLoc()
675685
: SourceLoc());
676-
inferRequirements(secondType, secondLoc, moduleForInference, result);
686+
inferRequirements(secondType, secondLoc, moduleForInference, dc, result);
677687
}
678688

679689
SmallVector<Requirement, 2> reqs;
@@ -717,7 +727,8 @@ void swift::rewriting::realizeInheritedRequirements(
717727
auto *typeRepr = inheritedTypes[index].getTypeRepr();
718728
SourceLoc loc = (typeRepr ? typeRepr->getStartLoc() : SourceLoc());
719729
if (shouldInferRequirements) {
720-
inferRequirements(inheritedType, loc, moduleForInference, result);
730+
inferRequirements(inheritedType, loc, moduleForInference,
731+
decl->getInnermostDeclContext(), result);
721732
}
722733

723734
realizeTypeRequirement(dc, type, inheritedType, loc, result, errors);

lib/AST/RequirementMachine/RequirementLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ void desugarRequirement(Requirement req, SourceLoc loc,
4242
SmallVectorImpl<Requirement> &result,
4343
SmallVectorImpl<RequirementError> &errors);
4444

45-
void inferRequirements(Type type, SourceLoc loc, ModuleDecl *module,
45+
void inferRequirements(Type type, SourceLoc loc,
46+
ModuleDecl *module, DeclContext *dc,
4647
SmallVectorImpl<StructuralRequirement> &result);
4748

4849
void realizeRequirement(DeclContext *dc,

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ InferredGenericSignatureRequest::evaluate(
829829
loc = typeLoc;
830830

831831
inferRequirements(sourcePair.getType(), typeLoc, moduleForInference,
832-
requirements);
832+
lookupDC, requirements);
833833
}
834834

835835
// Finish by adding any remaining requirements. This is used to introduce

test/Generics/requirement_inference_preconcurrency.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ public typealias Alias = ExistingType
1414
// CHECK-LABEL: existingClient2(arg:)
1515
// CHECK: Canonical generic signature: <τ_0_0>
1616
public func existingClient2<T>(arg: T.Type) -> Alias<T>? { nil }
17+
18+
// CHECK-LABEL: preconcurrencyClient(arg:)
19+
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Sendable>
20+
@preconcurrency
21+
public func preconcurrencyClient<T>(arg: T.Type) -> ExistingType<T>? { nil }

0 commit comments

Comments
 (0)