mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[RequirementMachine] Only skip Sendable requirements inferred from preconcurrency
decls if the decl we're inferring the generic signature for is not itself preconcurrency.
This commit is contained in:
@@ -467,10 +467,12 @@ namespace {
|
||||
/// AST walker that infers requirements from type representations.
|
||||
struct InferRequirementsWalker : public TypeWalker {
|
||||
ModuleDecl *module;
|
||||
DeclContext *dc;
|
||||
SmallVector<Requirement, 2> reqs;
|
||||
SmallVector<RequirementError, 2> errors;
|
||||
|
||||
explicit InferRequirementsWalker(ModuleDecl *module) : module(module) {}
|
||||
explicit InferRequirementsWalker(ModuleDecl *module, DeclContext *dc)
|
||||
: module(module), dc(dc) {}
|
||||
|
||||
Action walkToTypePre(Type ty) override {
|
||||
// Unbound generic types are the result of recovered-but-invalid code, and
|
||||
@@ -484,10 +486,17 @@ struct InferRequirementsWalker : public TypeWalker {
|
||||
Action walkToTypePost(Type ty) override {
|
||||
// Skip `Sendable` conformance requirements that are inferred from
|
||||
// `@preconcurrency` declarations.
|
||||
auto skipRequirement = [](Requirement req, Decl *fromDecl) {
|
||||
auto skipRequirement = [&](Requirement req, Decl *fromDecl) {
|
||||
if (!fromDecl->preconcurrency())
|
||||
return false;
|
||||
|
||||
// If this decl is `@preconcurrency`, include concurrency
|
||||
// requirements. The explicit annotation directly on the decl
|
||||
// will still exclude `Sendable` requirements from ABI.
|
||||
auto *decl = dc->getAsDecl();
|
||||
if (!decl || decl->preconcurrency())
|
||||
return false;
|
||||
|
||||
return (req.getKind() == RequirementKind::Conformance &&
|
||||
req.getSecondType()->castTo<ProtocolType>()->getDecl()
|
||||
->isSpecificProtocol(KnownProtocolKind::Sendable));
|
||||
@@ -602,12 +611,13 @@ struct InferRequirementsWalker : public TypeWalker {
|
||||
/// We automatically infer 'T : Hashable' from the fact that 'struct Set'
|
||||
/// declares a Hashable requirement on its generic parameter.
|
||||
void swift::rewriting::inferRequirements(
|
||||
Type type, SourceLoc loc, ModuleDecl *module,
|
||||
Type type, SourceLoc loc,
|
||||
ModuleDecl *module, DeclContext *dc,
|
||||
SmallVectorImpl<StructuralRequirement> &result) {
|
||||
if (!type)
|
||||
return;
|
||||
|
||||
InferRequirementsWalker walker(module);
|
||||
InferRequirementsWalker walker(module, dc);
|
||||
type.walk(walker);
|
||||
|
||||
for (const auto &req : walker.reqs)
|
||||
@@ -636,11 +646,11 @@ void swift::rewriting::realizeRequirement(
|
||||
if (shouldInferRequirements) {
|
||||
auto firstLoc = (reqRepr ? reqRepr->getSubjectRepr()->getStartLoc()
|
||||
: SourceLoc());
|
||||
inferRequirements(firstType, firstLoc, moduleForInference, result);
|
||||
inferRequirements(firstType, firstLoc, moduleForInference, dc, result);
|
||||
|
||||
auto secondLoc = (reqRepr ? reqRepr->getConstraintRepr()->getStartLoc()
|
||||
: SourceLoc());
|
||||
inferRequirements(secondType, secondLoc, moduleForInference, result);
|
||||
inferRequirements(secondType, secondLoc, moduleForInference, dc, result);
|
||||
}
|
||||
|
||||
realizeTypeRequirement(dc, firstType, secondType, loc, result, errors);
|
||||
@@ -651,7 +661,7 @@ void swift::rewriting::realizeRequirement(
|
||||
if (shouldInferRequirements) {
|
||||
auto firstLoc = (reqRepr ? reqRepr->getSubjectRepr()->getStartLoc()
|
||||
: SourceLoc());
|
||||
inferRequirements(firstType, firstLoc, moduleForInference, result);
|
||||
inferRequirements(firstType, firstLoc, moduleForInference, dc, result);
|
||||
}
|
||||
|
||||
SmallVector<Requirement, 2> reqs;
|
||||
@@ -669,11 +679,11 @@ void swift::rewriting::realizeRequirement(
|
||||
if (shouldInferRequirements) {
|
||||
auto firstLoc = (reqRepr ? reqRepr->getFirstTypeRepr()->getStartLoc()
|
||||
: SourceLoc());
|
||||
inferRequirements(firstType, firstLoc, moduleForInference, result);
|
||||
inferRequirements(firstType, firstLoc, moduleForInference, dc, result);
|
||||
|
||||
auto secondLoc = (reqRepr ? reqRepr->getSecondTypeRepr()->getStartLoc()
|
||||
: SourceLoc());
|
||||
inferRequirements(secondType, secondLoc, moduleForInference, result);
|
||||
inferRequirements(secondType, secondLoc, moduleForInference, dc, result);
|
||||
}
|
||||
|
||||
SmallVector<Requirement, 2> reqs;
|
||||
@@ -717,7 +727,8 @@ void swift::rewriting::realizeInheritedRequirements(
|
||||
auto *typeRepr = inheritedTypes[index].getTypeRepr();
|
||||
SourceLoc loc = (typeRepr ? typeRepr->getStartLoc() : SourceLoc());
|
||||
if (shouldInferRequirements) {
|
||||
inferRequirements(inheritedType, loc, moduleForInference, result);
|
||||
inferRequirements(inheritedType, loc, moduleForInference,
|
||||
decl->getInnermostDeclContext(), result);
|
||||
}
|
||||
|
||||
realizeTypeRequirement(dc, type, inheritedType, loc, result, errors);
|
||||
|
||||
@@ -42,7 +42,8 @@ void desugarRequirement(Requirement req, SourceLoc loc,
|
||||
SmallVectorImpl<Requirement> &result,
|
||||
SmallVectorImpl<RequirementError> &errors);
|
||||
|
||||
void inferRequirements(Type type, SourceLoc loc, ModuleDecl *module,
|
||||
void inferRequirements(Type type, SourceLoc loc,
|
||||
ModuleDecl *module, DeclContext *dc,
|
||||
SmallVectorImpl<StructuralRequirement> &result);
|
||||
|
||||
void realizeRequirement(DeclContext *dc,
|
||||
|
||||
@@ -829,7 +829,7 @@ InferredGenericSignatureRequest::evaluate(
|
||||
loc = typeLoc;
|
||||
|
||||
inferRequirements(sourcePair.getType(), typeLoc, moduleForInference,
|
||||
requirements);
|
||||
lookupDC, requirements);
|
||||
}
|
||||
|
||||
// Finish by adding any remaining requirements. This is used to introduce
|
||||
|
||||
@@ -14,3 +14,8 @@ public typealias Alias = ExistingType
|
||||
// CHECK-LABEL: existingClient2(arg:)
|
||||
// CHECK: Canonical generic signature: <τ_0_0>
|
||||
public func existingClient2<T>(arg: T.Type) -> Alias<T>? { nil }
|
||||
|
||||
// CHECK-LABEL: preconcurrencyClient(arg:)
|
||||
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Sendable>
|
||||
@preconcurrency
|
||||
public func preconcurrencyClient<T>(arg: T.Type) -> ExistingType<T>? { nil }
|
||||
|
||||
Reference in New Issue
Block a user