[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:
Holly Borla
2023-01-19 20:23:03 -08:00
parent d526e4c0e7
commit 679825063a
4 changed files with 29 additions and 12 deletions

View File

@@ -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);

View File

@@ -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,

View File

@@ -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

View File

@@ -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 }