Skip to content

Commit 082f091

Browse files
authored
Merge pull request #36029 from slavapestov/reasync-part-2
Sema: Start abstracting out the 'effect' in rethrows-checking logic
2 parents 1efcd3f + 04da08a commit 082f091

15 files changed

+259
-176
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ SWIFT_TYPEID(PropertyWrapperTypeInfo)
3131
SWIFT_TYPEID(Requirement)
3232
SWIFT_TYPEID(ResilienceExpansion)
3333
SWIFT_TYPEID(FragileFunctionKind)
34-
SWIFT_TYPEID(FunctionRethrowingKind)
35-
SWIFT_TYPEID(ProtocolRethrowsRequirementList)
34+
SWIFT_TYPEID(PolymorphicEffectKind)
35+
SWIFT_TYPEID(PolymorphicEffectRequirementList)
3636
SWIFT_TYPEID(TangentPropertyInfo)
3737
SWIFT_TYPEID(SymbolSourceMap)
3838
SWIFT_TYPEID(Type)

include/swift/AST/ASTTypeIDs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ class ProtocolDecl;
6464
class Requirement;
6565
enum class ResilienceExpansion : unsigned;
6666
struct FragileFunctionKind;
67-
enum class FunctionRethrowingKind : uint8_t;
68-
class ProtocolRethrowsRequirementList;
67+
enum class PolymorphicEffectKind : uint8_t;
68+
class PolymorphicEffectRequirementList;
6969
class SourceFile;
7070
class SymbolSourceMap;
7171
struct TangentPropertyInfo;

include/swift/AST/Decl.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ namespace swift {
8686
struct PropertyWrapperTypeInfo;
8787
struct PropertyWrapperMutability;
8888
class ProtocolDecl;
89-
class ProtocolRethrowsRequirementList;
89+
class PolymorphicEffectRequirementList;
9090
class ProtocolType;
9191
struct RawComment;
9292
enum class ResilienceExpansion : unsigned;
93-
enum class FunctionRethrowingKind : uint8_t;
93+
enum class EffectKind : uint8_t;
94+
enum class PolymorphicEffectKind : uint8_t;
9495
class TrailingWhereClause;
9596
class TypeAliasDecl;
9697
class Stmt;
@@ -4117,8 +4118,11 @@ class ProtocolDecl final : public NominalTypeDecl {
41174118
/// contain 'Self' in 'parameter' or 'other' position.
41184119
bool existentialTypeSupported() const;
41194120

4120-
ProtocolRethrowsRequirementList getRethrowingRequirements() const;
4121-
bool isRethrowingProtocol() const;
4121+
/// Returns a list of protocol requirements that must be assessed to
4122+
/// determine a concrete's conformance effect polymorphism kind.
4123+
PolymorphicEffectRequirementList getPolymorphicEffectRequirements(
4124+
EffectKind kind) const;
4125+
bool hasPolymorphicEffect(EffectKind kind) const;
41224126

41234127
/// Determine whether this is a "marker" protocol, meaning that is indicates
41244128
/// semantics but has no corresponding witness table.
@@ -5740,7 +5744,13 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
57405744
/// Returns true if the function body throws.
57415745
bool hasThrows() const { return Bits.AbstractFunctionDecl.Throws; }
57425746

5743-
FunctionRethrowingKind getRethrowingKind() const;
5747+
/// Returns if the function throws or is async.
5748+
bool hasEffect(EffectKind kind) const;
5749+
5750+
/// Returns if the function is 'rethrows' or 'reasync'.
5751+
bool hasPolymorphicEffect(EffectKind kind) const;
5752+
5753+
PolymorphicEffectKind getPolymorphicEffectKind(EffectKind kind) const;
57445754

57455755
// FIXME: Hack that provides names with keyword arguments for accessors.
57465756
DeclName getEffectiveFullName() const;

include/swift/AST/Effects.h

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// This file defines some data types for rethrows and reasync effects.
13+
// This file defines some data types used for 'rethrows' and `reasync` checking.
14+
//
15+
// We refer to 'throws' and 'async' as "effects". A function might have either or
16+
// both effects.
17+
//
18+
// A function is _effect polymorphic_ if its effect depends on the call site.
19+
// This can either be unconditional (the usual 'throws' or 'async' case), or it
20+
// can depend on either its arguments or conformances (these are 'rethrows' and
21+
// 'reasync' functions).
1422
//
1523
//===----------------------------------------------------------------------===//
1624

@@ -27,50 +35,64 @@ class raw_ostream;
2735

2836
namespace swift {
2937

38+
enum class EffectKind : uint8_t {
39+
Throws,
40+
Async
41+
};
42+
43+
void simple_display(llvm::raw_ostream &out, const EffectKind kind);
44+
3045
class ValueDecl;
3146

32-
class ProtocolRethrowsRequirementList {
33-
using ThrowingRequirements = ArrayRef<AbstractFunctionDecl *>;
34-
using ThrowingConformances = ArrayRef<std::pair<Type, ProtocolDecl *>>;
47+
class PolymorphicEffectRequirementList {
48+
using Requirements = ArrayRef<AbstractFunctionDecl *>;
49+
using Conformances = ArrayRef<std::pair<Type, ProtocolDecl *>>;
3550
private:
36-
ThrowingRequirements requirements;
37-
ThrowingConformances conformances;
51+
Requirements requirements;
52+
Conformances conformances;
3853

3954
public:
40-
ProtocolRethrowsRequirementList(ThrowingRequirements requirements,
41-
ThrowingConformances conformances)
55+
PolymorphicEffectRequirementList(Requirements requirements,
56+
Conformances conformances)
4257
: requirements(requirements), conformances(conformances) {}
43-
ProtocolRethrowsRequirementList() {}
58+
PolymorphicEffectRequirementList() {}
4459

45-
ThrowingRequirements getRequirements() const {
60+
Requirements getRequirements() const {
4661
return requirements;
4762
}
4863

49-
ThrowingConformances getConformances() const {
64+
Conformances getConformances() const {
5065
return conformances;
5166
}
5267
};
5368

54-
void simple_display(llvm::raw_ostream &out, const ProtocolRethrowsRequirementList reqs);
69+
void simple_display(llvm::raw_ostream &out,
70+
const PolymorphicEffectRequirementList reqs);
5571

56-
enum class FunctionRethrowingKind : uint8_t {
57-
/// The function is not throwing
72+
enum class PolymorphicEffectKind : uint8_t {
73+
/// The function does not have this effect at all.
5874
None,
5975

60-
/// The function rethrows by closure
61-
ByClosure,
76+
/// The function has this effect if at least one closure argument has it.
77+
///
78+
/// This is the ordinary 'rethrows' /'reasync' case.
79+
ByClosure,
6280

63-
/// The function rethrows by conformance
64-
ByConformance,
81+
/// The function has this effect if at least one of its conformances has it.
82+
///
83+
/// This is the conformance-based 'rethrows' /'reasync' case.
84+
ByConformance,
6585

66-
/// The function throws
67-
Throws,
86+
/// The function has this effect unconditionally.
87+
///
88+
/// This is a plain old 'throws' / 'async' function.
89+
Always,
6890

69-
/// The function throwing determinate is invalid
91+
/// The function declaration was invalid.
7092
Invalid
7193
};
7294

73-
void simple_display(llvm::raw_ostream &out, FunctionRethrowingKind value);
95+
void simple_display(llvm::raw_ostream &out, PolymorphicEffectKind value);
7496

7597
} // end namespace swift
7698

include/swift/AST/ProtocolConformanceRef.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace swift {
3131

3232
class ConcreteDeclRef;
3333
class ProtocolConformance;
34+
enum class EffectKind : uint8_t;
3435

3536
/// A ProtocolConformanceRef is a handle to a protocol conformance which
3637
/// may be either concrete or abstract.
@@ -171,7 +172,7 @@ class ProtocolConformanceRef {
171172
/// be satisfied.
172173
ArrayRef<Requirement> getConditionalRequirements() const;
173174

174-
bool classifyAsThrows() const;
175+
bool hasEffect(EffectKind kind) const;
175176
};
176177

177178
void simple_display(llvm::raw_ostream &out, ProtocolConformanceRef conformanceRef);

include/swift/AST/TypeCheckRequests.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ class ExistentialTypeSupportedRequest :
313313
void cacheResult(bool value) const;
314314
};
315315

316-
class ProtocolRethrowsRequirementsRequest :
317-
public SimpleRequest<ProtocolRethrowsRequirementsRequest,
318-
ProtocolRethrowsRequirementList(ProtocolDecl *),
316+
class PolymorphicEffectRequirementsRequest :
317+
public SimpleRequest<PolymorphicEffectRequirementsRequest,
318+
PolymorphicEffectRequirementList(EffectKind, ProtocolDecl *),
319319
RequestFlags::Cached> {
320320
public:
321321
using SimpleRequest::SimpleRequest;
@@ -324,17 +324,17 @@ class ProtocolRethrowsRequirementsRequest :
324324
friend SimpleRequest;
325325

326326
// Evaluation.
327-
ProtocolRethrowsRequirementList
328-
evaluate(Evaluator &evaluator, ProtocolDecl *decl) const;
327+
PolymorphicEffectRequirementList
328+
evaluate(Evaluator &evaluator, EffectKind kind, ProtocolDecl *decl) const;
329329

330330
public:
331331
// Caching.
332332
bool isCached() const { return true; }
333333
};
334334

335-
class ProtocolConformanceClassifyAsThrowsRequest :
336-
public SimpleRequest<ProtocolConformanceClassifyAsThrowsRequest,
337-
bool(ProtocolConformance *),
335+
class ConformanceHasEffectRequest :
336+
public SimpleRequest<ConformanceHasEffectRequest,
337+
bool(EffectKind, ProtocolConformance *),
338338
RequestFlags::Cached> {
339339
public:
340340
using SimpleRequest::SimpleRequest;
@@ -344,7 +344,8 @@ class ProtocolConformanceClassifyAsThrowsRequest :
344344

345345
// Evaluation.
346346
bool
347-
evaluate(Evaluator &evaluator, ProtocolConformance *conformance) const;
347+
evaluate(Evaluator &evaluator, EffectKind kind,
348+
ProtocolConformance *conformance) const;
348349

349350
public:
350351
// Caching.
@@ -774,9 +775,9 @@ void simple_display(llvm::raw_ostream &out, FragileFunctionKind value);
774775

775776
void simple_display(llvm::raw_ostream &out, ResilienceExpansion value);
776777

777-
class FunctionRethrowingKindRequest :
778-
public SimpleRequest<FunctionRethrowingKindRequest,
779-
FunctionRethrowingKind(AbstractFunctionDecl*),
778+
class PolymorphicEffectKindRequest :
779+
public SimpleRequest<PolymorphicEffectKindRequest,
780+
PolymorphicEffectKind(EffectKind, AbstractFunctionDecl*),
780781
RequestFlags::Cached> {
781782
public:
782783
using SimpleRequest::SimpleRequest;
@@ -785,7 +786,9 @@ class FunctionRethrowingKindRequest :
785786
friend SimpleRequest;
786787

787788
// Evaluation.
788-
FunctionRethrowingKind evaluate(Evaluator &evaluator, AbstractFunctionDecl *decl) const;
789+
PolymorphicEffectKind evaluate(Evaluator &evaluator,
790+
EffectKind kind,
791+
AbstractFunctionDecl *decl) const;
789792

790793
public:
791794
// Caching.

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ SWIFT_REQUEST(TypeChecker, RequiresOpaqueModifyCoroutineRequest,
213213
bool(AbstractStorageDecl *), SeparatelyCached, NoLocationInfo)
214214
SWIFT_REQUEST(TypeChecker, FragileFunctionKindRequest,
215215
FragileFunctionKind(DeclContext *), Cached, NoLocationInfo)
216-
SWIFT_REQUEST(TypeChecker, FunctionRethrowingKindRequest,
217-
FunctionRethrowingKind(AbstractFunctionDecl *), Cached, NoLocationInfo)
216+
SWIFT_REQUEST(TypeChecker, PolymorphicEffectKindRequest,
217+
PolymorphicEffectKind(EffectKind, AbstractFunctionDecl *),
218+
Cached, NoLocationInfo)
218219
SWIFT_REQUEST(TypeChecker, SelfAccessKindRequest, SelfAccessKind(FuncDecl *),
219220
SeparatelyCached, NoLocationInfo)
220221
SWIFT_REQUEST(TypeChecker, StorageImplInfoRequest,
@@ -269,11 +270,11 @@ SWIFT_REQUEST(TypeChecker, ResolveImplicitMemberRequest,
269270
SWIFT_REQUEST(TypeChecker, ResolveTypeEraserTypeRequest,
270271
Type(ProtocolDecl *, TypeEraserAttr *),
271272
SeparatelyCached, NoLocationInfo)
272-
SWIFT_REQUEST(TypeChecker, ProtocolRethrowsRequirementsRequest,
273-
ProtocolRethrowsRequirementList(ProtocolDecl *),
273+
SWIFT_REQUEST(TypeChecker, PolymorphicEffectRequirementsRequest,
274+
PolymorphicEffectRequirementList(EffectKind, ProtocolDecl *),
274275
Cached, NoLocationInfo)
275-
SWIFT_REQUEST(TypeChecker, ProtocolConformanceClassifyAsThrowsRequest,
276-
bool(ProtocolConformanceRef),
276+
SWIFT_REQUEST(TypeChecker, ConformanceHasEffectRequest,
277+
bool(EffectKind, ProtocolConformanceRef),
277278
Cached, NoLocationInfo)
278279
SWIFT_REQUEST(TypeChecker, ResolveTypeRequest,
279280
Type (const TypeResolution *, TypeRepr *, GenericParamList *),

lib/AST/ASTVerifier.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,19 +1804,19 @@ class Verifier : public ASTWalker {
18041804
Out << "\n";
18051805
abort();
18061806
} else if (E->throws() && !FT->isThrowing()) {
1807-
FunctionRethrowingKind rethrowingKind = FunctionRethrowingKind::Invalid;
1807+
PolymorphicEffectKind rethrowingKind = PolymorphicEffectKind::Invalid;
18081808
if (auto DRE = dyn_cast<DeclRefExpr>(E->getFn())) {
18091809
if (auto fnDecl = dyn_cast<AbstractFunctionDecl>(DRE->getDecl())) {
1810-
rethrowingKind = fnDecl->getRethrowingKind();
1810+
rethrowingKind = fnDecl->getPolymorphicEffectKind(EffectKind::Throws);
18111811
}
18121812
} else if (auto OCDRE = dyn_cast<OtherConstructorDeclRefExpr>(E->getFn())) {
18131813
if (auto fnDecl = dyn_cast<AbstractFunctionDecl>(OCDRE->getDecl())) {
1814-
rethrowingKind = fnDecl->getRethrowingKind();
1814+
rethrowingKind = fnDecl->getPolymorphicEffectKind(EffectKind::Throws);
18151815
}
18161816
}
18171817

1818-
if (rethrowingKind != FunctionRethrowingKind::ByConformance &&
1819-
rethrowingKind != FunctionRethrowingKind::Throws) {
1818+
if (rethrowingKind != PolymorphicEffectKind::ByConformance &&
1819+
rethrowingKind != PolymorphicEffectKind::Always) {
18201820
Out << "apply expression is marked as throwing, but function operand"
18211821
"does not have a throwing function type\n";
18221822
E->dump(Out);

0 commit comments

Comments
 (0)