Skip to content

Commit f7952ab

Browse files
committed
Sema: Move some code from TypeCheckDecl.cpp to TypeCheckEffects.cpp
1 parent 6630383 commit f7952ab

File tree

2 files changed

+161
-159
lines changed

2 files changed

+161
-159
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 0 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -696,165 +696,6 @@ ExistentialTypeSupportedRequest::evaluate(Evaluator &evaluator,
696696
return true;
697697
}
698698

699-
static bool hasThrowingFunctionClosureParameter(CanType type) {
700-
// Only consider throwing function types.
701-
if (auto fnType = dyn_cast<AnyFunctionType>(type)) {
702-
return fnType->getExtInfo().isThrowing();
703-
}
704-
705-
// Look through tuples.
706-
if (auto tuple = dyn_cast<TupleType>(type)) {
707-
for (auto eltType : tuple.getElementTypes()) {
708-
auto elt = eltType->lookThroughAllOptionalTypes()->getCanonicalType();
709-
if (hasThrowingFunctionClosureParameter(elt))
710-
return true;
711-
}
712-
return false;
713-
}
714-
715-
// Suppress diagnostics in the presence of errors.
716-
if (type->hasError()) {
717-
return true;
718-
}
719-
720-
return false;
721-
}
722-
723-
static FunctionRethrowingKind
724-
getTypeThrowingKind(Type interfaceTy, GenericSignature genericSig) {
725-
if (interfaceTy->isTypeParameter()) {
726-
for (auto proto : genericSig->getRequiredProtocols(interfaceTy)) {
727-
if (proto->isRethrowingProtocol()) {
728-
return FunctionRethrowingKind::ByConformance;
729-
}
730-
}
731-
} else if (auto NTD = interfaceTy->getNominalOrBoundGenericNominal()) {
732-
if (auto genericSig = NTD->getGenericSignature()) {
733-
for (auto req : genericSig->getRequirements()) {
734-
if (req.getKind() == RequirementKind::Conformance) {
735-
if (req.getSecondType()->castTo<ProtocolType>()
736-
->getDecl()
737-
->isRethrowingProtocol()) {
738-
return FunctionRethrowingKind::ByConformance;
739-
}
740-
}
741-
}
742-
}
743-
}
744-
return FunctionRethrowingKind::Invalid;
745-
}
746-
747-
static FunctionRethrowingKind
748-
getParameterThrowingKind(AbstractFunctionDecl *decl,
749-
GenericSignature genericSig) {
750-
FunctionRethrowingKind kind = FunctionRethrowingKind::Invalid;
751-
// check all parameters to determine if any are closures that throw
752-
bool foundThrowingClosure = false;
753-
for (auto param : *decl->getParameters()) {
754-
auto interfaceTy = param->getInterfaceType();
755-
if (hasThrowingFunctionClosureParameter(interfaceTy
756-
->lookThroughAllOptionalTypes()
757-
->getCanonicalType())) {
758-
foundThrowingClosure = true;
759-
}
760-
761-
if (kind == FunctionRethrowingKind::Invalid) {
762-
kind = getTypeThrowingKind(interfaceTy, genericSig);
763-
}
764-
}
765-
if (kind == FunctionRethrowingKind::Invalid &&
766-
foundThrowingClosure) {
767-
return FunctionRethrowingKind::ByClosure;
768-
}
769-
return kind;
770-
}
771-
772-
ProtocolRethrowsRequirementList
773-
ProtocolRethrowsRequirementsRequest::evaluate(Evaluator &evaluator,
774-
ProtocolDecl *decl) const {
775-
SmallVector<std::pair<Type, ValueDecl*>, 2> found;
776-
llvm::DenseSet<ProtocolDecl*> checkedProtocols;
777-
778-
ASTContext &ctx = decl->getASTContext();
779-
780-
// only allow rethrowing requirements to be determined from marked protocols
781-
if (!decl->getAttrs().hasAttribute<swift::AtRethrowsAttr>()) {
782-
return ProtocolRethrowsRequirementList(ctx.AllocateCopy(found));
783-
}
784-
785-
// check if immediate members of protocol are 'rethrows'
786-
for (auto member : decl->getMembers()) {
787-
auto fnDecl = dyn_cast<AbstractFunctionDecl>(member);
788-
// it must be a function
789-
// it must have a rethrows attribute
790-
// it must not have any parameters that are closures that cause rethrowing
791-
if (!fnDecl ||
792-
!fnDecl->hasThrows()) {
793-
continue;
794-
}
795-
796-
GenericSignature genericSig = fnDecl->getGenericSignature();
797-
auto kind = getParameterThrowingKind(fnDecl, genericSig);
798-
// skip closure based rethrowing cases
799-
if (kind == FunctionRethrowingKind::ByClosure) {
800-
continue;
801-
}
802-
// we now have a protocol member that has a rethrows and no closure
803-
// parameters contributing to it's rethrowing-ness
804-
found.push_back(
805-
std::pair<Type, ValueDecl*>(decl->getSelfInterfaceType(), fnDecl));
806-
}
807-
checkedProtocols.insert(decl);
808-
809-
// check associated conformances of associated types or inheritance
810-
for (auto requirement : decl->getRequirementSignature()) {
811-
if (requirement.getKind() != RequirementKind::Conformance) {
812-
continue;
813-
}
814-
auto protoTy = requirement.getSecondType()->castTo<ProtocolType>();
815-
auto proto = protoTy->getDecl();
816-
if (checkedProtocols.count(proto) != 0) {
817-
continue;
818-
}
819-
checkedProtocols.insert(proto);
820-
for (auto entry : proto->getRethrowingRequirements()) {
821-
found.emplace_back(requirement.getFirstType(), entry.second);
822-
}
823-
}
824-
825-
return ProtocolRethrowsRequirementList(ctx.AllocateCopy(found));
826-
}
827-
828-
FunctionRethrowingKind
829-
FunctionRethrowingKindRequest::evaluate(Evaluator &evaluator,
830-
AbstractFunctionDecl *decl) const {
831-
if (decl->hasThrows()) {
832-
auto proto = dyn_cast<ProtocolDecl>(decl->getDeclContext());
833-
bool fromRethrow = proto != nullptr ? proto->isRethrowingProtocol() : false;
834-
bool markedRethrows = decl->getAttrs().hasAttribute<RethrowsAttr>();
835-
if (fromRethrow && !markedRethrows) {
836-
return FunctionRethrowingKind::ByConformance;
837-
}
838-
if (markedRethrows) {
839-
GenericSignature genericSig = decl->getGenericSignature();
840-
FunctionRethrowingKind kind = getParameterThrowingKind(decl, genericSig);
841-
// since we have checked all arguments, if we still havent found anything
842-
// check the self parameter
843-
if (kind == FunctionRethrowingKind::Invalid &&
844-
decl->hasImplicitSelfDecl()) {
845-
auto selfParam = decl->getImplicitSelfDecl();
846-
if (selfParam) {
847-
auto interfaceTy = selfParam->getInterfaceType();
848-
kind = getTypeThrowingKind(interfaceTy, genericSig);
849-
}
850-
}
851-
return kind;
852-
}
853-
return FunctionRethrowingKind::Throws;
854-
}
855-
return FunctionRethrowingKind::None;
856-
}
857-
858699
bool
859700
IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
860701
if (isa<ClassDecl>(decl))

lib/Sema/TypeCheckEffects.cpp

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,173 @@
2121
#include "swift/AST/DiagnosticsSema.h"
2222
#include "swift/AST/Effects.h"
2323
#include "swift/AST/Initializer.h"
24+
#include "swift/AST/ParameterList.h"
2425
#include "swift/AST/Pattern.h"
2526
#include "swift/AST/PrettyStackTrace.h"
2627
#include "swift/AST/ProtocolConformance.h"
28+
#include "swift/AST/TypeCheckRequests.h"
2729

2830
using namespace swift;
2931

32+
static bool hasThrowingFunctionClosureParameter(CanType type) {
33+
// Only consider throwing function types.
34+
if (auto fnType = dyn_cast<AnyFunctionType>(type)) {
35+
return fnType->getExtInfo().isThrowing();
36+
}
37+
38+
// Look through tuples.
39+
if (auto tuple = dyn_cast<TupleType>(type)) {
40+
for (auto eltType : tuple.getElementTypes()) {
41+
auto elt = eltType->lookThroughAllOptionalTypes()->getCanonicalType();
42+
if (hasThrowingFunctionClosureParameter(elt))
43+
return true;
44+
}
45+
return false;
46+
}
47+
48+
// Suppress diagnostics in the presence of errors.
49+
if (type->hasError()) {
50+
return true;
51+
}
52+
53+
return false;
54+
}
55+
56+
static FunctionRethrowingKind
57+
getTypeThrowingKind(Type interfaceTy, GenericSignature genericSig) {
58+
if (interfaceTy->isTypeParameter()) {
59+
for (auto proto : genericSig->getRequiredProtocols(interfaceTy)) {
60+
if (proto->isRethrowingProtocol()) {
61+
return FunctionRethrowingKind::ByConformance;
62+
}
63+
}
64+
} else if (auto NTD = interfaceTy->getNominalOrBoundGenericNominal()) {
65+
if (auto genericSig = NTD->getGenericSignature()) {
66+
for (auto req : genericSig->getRequirements()) {
67+
if (req.getKind() == RequirementKind::Conformance) {
68+
if (req.getSecondType()->castTo<ProtocolType>()
69+
->getDecl()
70+
->isRethrowingProtocol()) {
71+
return FunctionRethrowingKind::ByConformance;
72+
}
73+
}
74+
}
75+
}
76+
}
77+
return FunctionRethrowingKind::Invalid;
78+
}
79+
80+
static FunctionRethrowingKind
81+
getParameterThrowingKind(AbstractFunctionDecl *decl,
82+
GenericSignature genericSig) {
83+
FunctionRethrowingKind kind = FunctionRethrowingKind::Invalid;
84+
// check all parameters to determine if any are closures that throw
85+
bool foundThrowingClosure = false;
86+
for (auto param : *decl->getParameters()) {
87+
auto interfaceTy = param->getInterfaceType();
88+
if (hasThrowingFunctionClosureParameter(interfaceTy
89+
->lookThroughAllOptionalTypes()
90+
->getCanonicalType())) {
91+
foundThrowingClosure = true;
92+
}
93+
94+
if (kind == FunctionRethrowingKind::Invalid) {
95+
kind = getTypeThrowingKind(interfaceTy, genericSig);
96+
}
97+
}
98+
if (kind == FunctionRethrowingKind::Invalid &&
99+
foundThrowingClosure) {
100+
return FunctionRethrowingKind::ByClosure;
101+
}
102+
return kind;
103+
}
104+
105+
ProtocolRethrowsRequirementList
106+
ProtocolRethrowsRequirementsRequest::evaluate(Evaluator &evaluator,
107+
ProtocolDecl *decl) const {
108+
SmallVector<std::pair<Type, ValueDecl*>, 2> found;
109+
llvm::DenseSet<ProtocolDecl*> checkedProtocols;
110+
111+
ASTContext &ctx = decl->getASTContext();
112+
113+
// only allow rethrowing requirements to be determined from marked protocols
114+
if (!decl->getAttrs().hasAttribute<swift::AtRethrowsAttr>()) {
115+
return ProtocolRethrowsRequirementList(ctx.AllocateCopy(found));
116+
}
117+
118+
// check if immediate members of protocol are 'rethrows'
119+
for (auto member : decl->getMembers()) {
120+
auto fnDecl = dyn_cast<AbstractFunctionDecl>(member);
121+
// it must be a function
122+
// it must have a rethrows attribute
123+
// it must not have any parameters that are closures that cause rethrowing
124+
if (!fnDecl ||
125+
!fnDecl->hasThrows()) {
126+
continue;
127+
}
128+
129+
GenericSignature genericSig = fnDecl->getGenericSignature();
130+
auto kind = getParameterThrowingKind(fnDecl, genericSig);
131+
// skip closure based rethrowing cases
132+
if (kind == FunctionRethrowingKind::ByClosure) {
133+
continue;
134+
}
135+
// we now have a protocol member that has a rethrows and no closure
136+
// parameters contributing to it's rethrowing-ness
137+
found.push_back(
138+
std::pair<Type, ValueDecl*>(decl->getSelfInterfaceType(), fnDecl));
139+
}
140+
checkedProtocols.insert(decl);
141+
142+
// check associated conformances of associated types or inheritance
143+
for (auto requirement : decl->getRequirementSignature()) {
144+
if (requirement.getKind() != RequirementKind::Conformance) {
145+
continue;
146+
}
147+
auto protoTy = requirement.getSecondType()->castTo<ProtocolType>();
148+
auto proto = protoTy->getDecl();
149+
if (checkedProtocols.count(proto) != 0) {
150+
continue;
151+
}
152+
checkedProtocols.insert(proto);
153+
for (auto entry : proto->getRethrowingRequirements()) {
154+
found.emplace_back(requirement.getFirstType(), entry.second);
155+
}
156+
}
157+
158+
return ProtocolRethrowsRequirementList(ctx.AllocateCopy(found));
159+
}
160+
161+
FunctionRethrowingKind
162+
FunctionRethrowingKindRequest::evaluate(Evaluator &evaluator,
163+
AbstractFunctionDecl *decl) const {
164+
if (decl->hasThrows()) {
165+
auto proto = dyn_cast<ProtocolDecl>(decl->getDeclContext());
166+
bool fromRethrow = proto != nullptr ? proto->isRethrowingProtocol() : false;
167+
bool markedRethrows = decl->getAttrs().hasAttribute<RethrowsAttr>();
168+
if (fromRethrow && !markedRethrows) {
169+
return FunctionRethrowingKind::ByConformance;
170+
}
171+
if (markedRethrows) {
172+
GenericSignature genericSig = decl->getGenericSignature();
173+
FunctionRethrowingKind kind = getParameterThrowingKind(decl, genericSig);
174+
// since we have checked all arguments, if we still havent found anything
175+
// check the self parameter
176+
if (kind == FunctionRethrowingKind::Invalid &&
177+
decl->hasImplicitSelfDecl()) {
178+
auto selfParam = decl->getImplicitSelfDecl();
179+
if (selfParam) {
180+
auto interfaceTy = selfParam->getInterfaceType();
181+
kind = getTypeThrowingKind(interfaceTy, genericSig);
182+
}
183+
}
184+
return kind;
185+
}
186+
return FunctionRethrowingKind::Throws;
187+
}
188+
return FunctionRethrowingKind::None;
189+
}
190+
30191
namespace {
31192

32193
/// A function reference.

0 commit comments

Comments
 (0)