21
21
#include " swift/AST/ASTWalker.h"
22
22
#include " swift/AST/DiagnosticsSema.h"
23
23
#include " swift/AST/Effects.h"
24
+ #include " swift/AST/GenericEnvironment.h"
24
25
#include " swift/AST/Initializer.h"
25
26
#include " swift/AST/ParameterList.h"
26
27
#include " swift/AST/Pattern.h"
@@ -279,9 +280,10 @@ class AbstractFunction {
279
280
TheClosure = closure;
280
281
}
281
282
282
- explicit AbstractFunction (ParamDecl *parameter)
283
- : TheKind(Kind::Parameter) {
283
+ explicit AbstractFunction (ParamDecl *parameter, SubstitutionMap subs )
284
+ : TheKind(Kind::Parameter), Substitutions(subs) {
284
285
TheParameter = parameter;
286
+
285
287
}
286
288
287
289
Kind getKind () const { return TheKind; }
@@ -309,6 +311,24 @@ class AbstractFunction {
309
311
llvm_unreachable (" bad kind" );
310
312
}
311
313
314
+ // / Retrieve the interface type for a parameter based on an index into the
315
+ // / substituted parameter type. This
316
+ Type getOrigParamInterfaceType (unsigned substIndex) const {
317
+ switch (getKind ()) {
318
+ case Kind::Opaque:
319
+ case Kind::Closure:
320
+ case Kind::Parameter:
321
+ return getType ()->castTo <AnyFunctionType>()->getParams ()[substIndex]
322
+ .getParameterType ();
323
+
324
+ case Kind::Function: {
325
+ auto params = getParameterList (static_cast <ValueDecl *>(getFunction ()));
326
+ auto origIndex = params->getOrigParamIndex (getSubstitutions (), substIndex);
327
+ return params->get (origIndex)->getInterfaceType ();
328
+ }
329
+ }
330
+ }
331
+
312
332
bool isAutoClosure () const {
313
333
if (getKind () == Kind::Closure)
314
334
return isa<AutoClosureExpr>(getClosure ());
@@ -386,7 +406,10 @@ class AbstractFunction {
386
406
if (auto fn = dyn_cast<AbstractFunctionDecl>(decl)) {
387
407
return AbstractFunction (fn, DRE->getDeclRef ().getSubstitutions ());
388
408
} else if (auto param = dyn_cast<ParamDecl>(decl)) {
389
- return AbstractFunction (param);
409
+ SubstitutionMap subs;
410
+ if (auto genericEnv = param->getDeclContext ()->getGenericEnvironmentOfContext ())
411
+ subs = genericEnv->getForwardingSubstitutionMap ();
412
+ return AbstractFunction (param, subs);
390
413
}
391
414
392
415
// Closures.
@@ -813,6 +836,8 @@ class Classification {
813
836
if (!thrownError || isNeverThrownError (thrownError))
814
837
return result;
815
838
839
+ assert (!thrownError->hasError ());
840
+
816
841
result.ThrowKind = conditionalKind;
817
842
result.ThrowReason = reason;
818
843
result.ThrownError = thrownError;
@@ -1173,22 +1198,29 @@ class ApplyClassifier {
1173
1198
// because it only counts for rethrows/reasync purposes if it
1174
1199
// lines up with a throws/async function parameter in the
1175
1200
// original type.
1176
- auto *origType = fnRef.getType ()-> getAs <AnyFunctionType> ();
1177
- if (!origType ) {
1201
+ Type fnInterfaceType = fnRef.getType ();
1202
+ if (!fnInterfaceType ) {
1178
1203
result.merge (Classification::forInvalidCode ());
1179
1204
return ;
1180
1205
}
1181
1206
1182
1207
// Use the most significant result from the arguments.
1183
- auto params = origType->getParams ();
1184
- if (params.size () != args->size ()) {
1208
+ auto *fnSubstType = fnInterfaceType.subst (fnRef.getSubstitutions ())
1209
+ ->getAs <AnyFunctionType>();
1210
+ if (!fnSubstType) {
1185
1211
result.merge (Classification::forInvalidCode ());
1186
1212
return ;
1187
1213
}
1188
1214
1189
- for (unsigned i = 0 , e = params.size (); i < e; ++i) {
1215
+ if (fnSubstType->getParams ().size () != args->size ()) {
1216
+ result.merge (Classification::forInvalidCode ());
1217
+ return ;
1218
+ }
1219
+
1220
+ for (unsigned i = 0 , e = args->size (); i < e; ++i) {
1221
+ Type origParamType = fnRef.getOrigParamInterfaceType (i);
1190
1222
auto argClassification = classifyArgument (
1191
- args->getExpr (i), params[i]. getParameterType (), kind);
1223
+ args->getExpr (i), origParamType, fnRef. getSubstitutions (), kind);
1192
1224
1193
1225
// Rethrows is untyped, so adjust the thrown error type.
1194
1226
if (kind == EffectKind::Throws &&
@@ -1284,7 +1316,7 @@ class ApplyClassifier {
1284
1316
EffectKind kind) {
1285
1317
switch (fn.getKind ()) {
1286
1318
case AbstractFunction::Opaque: {
1287
- return classifyArgumentByType (fn.getType (),
1319
+ return classifyArgumentByType (fn.getType (), fn. getSubstitutions (),
1288
1320
ConditionalEffectKind::Always, reason,
1289
1321
kind);
1290
1322
}
@@ -1323,8 +1355,8 @@ class ApplyClassifier {
1323
1355
else // otherwise, it throws unconditionally.
1324
1356
conditional = ConditionalEffectKind::Always;
1325
1357
1326
- return classifyArgumentByType (param-> getTypeInContext (),
1327
- conditional, reason, kind);
1358
+ return classifyArgumentByType (
1359
+ param-> getInterfaceType (), subs, conditional, reason, kind);
1328
1360
}
1329
1361
1330
1362
bool isLocallyDefinedInPolymorphicEffectDeclContext (DeclContext *DC,
@@ -1653,7 +1685,8 @@ class ApplyClassifier {
1653
1685
}
1654
1686
1655
1687
// / Classify an argument being passed to a rethrows/reasync function.
1656
- Classification classifyArgument (Expr *arg, Type paramType, EffectKind kind) {
1688
+ Classification classifyArgument (
1689
+ Expr *arg, Type paramType, SubstitutionMap subs, EffectKind kind) {
1657
1690
arg = arg->getValueProvidingExpr ();
1658
1691
1659
1692
if (auto *defaultArg = dyn_cast<DefaultArgumentExpr>(arg)) {
@@ -1666,7 +1699,7 @@ class ApplyClassifier {
1666
1699
}
1667
1700
}
1668
1701
1669
- return classifyArgumentByType (arg->getType (),
1702
+ return classifyArgumentByType (arg->getType (), subs,
1670
1703
ConditionalEffectKind::Always,
1671
1704
PotentialEffectReason::forDefaultClosure (),
1672
1705
kind);
@@ -1691,7 +1724,7 @@ class ApplyClassifier {
1691
1724
// various tuple operations.
1692
1725
if (auto paramTupleType = dyn_cast<TupleType>(paramType.getPointer ())) {
1693
1726
if (auto tuple = dyn_cast<TupleExpr>(arg)) {
1694
- return classifyTupleArgument (tuple, paramTupleType, kind);
1727
+ return classifyTupleArgument (tuple, paramTupleType, subs, kind);
1695
1728
}
1696
1729
1697
1730
if (paramTupleType->getNumElements () != 1 ) {
@@ -1700,6 +1733,7 @@ class ApplyClassifier {
1700
1733
// parameter type included a throwing function type.
1701
1734
return classifyArgumentByType (
1702
1735
paramType,
1736
+ subs,
1703
1737
ConditionalEffectKind::Always,
1704
1738
PotentialEffectReason::forClosure (arg),
1705
1739
kind);
@@ -1744,6 +1778,7 @@ class ApplyClassifier {
1744
1778
// / Classify an argument to a rethrows/reasync function that's a tuple literal.
1745
1779
Classification classifyTupleArgument (TupleExpr *tuple,
1746
1780
TupleType *paramTupleType,
1781
+ SubstitutionMap subs,
1747
1782
EffectKind kind) {
1748
1783
if (paramTupleType->getNumElements () != tuple->getNumElements ())
1749
1784
return Classification::forInvalidCode ();
@@ -1752,7 +1787,7 @@ class ApplyClassifier {
1752
1787
for (unsigned i : indices (tuple->getElements ())) {
1753
1788
result.merge (classifyArgument (tuple->getElement (i),
1754
1789
paramTupleType->getElementType (i),
1755
- kind));
1790
+ subs, kind));
1756
1791
}
1757
1792
return result;
1758
1793
}
@@ -1761,7 +1796,8 @@ class ApplyClassifier {
1761
1796
// / a throws/async function in a way that is permitted to cause a
1762
1797
// / rethrows/reasync function to throw/async.
1763
1798
static Classification
1764
- classifyArgumentByType (Type paramType, ConditionalEffectKind conditional,
1799
+ classifyArgumentByType (Type paramType, SubstitutionMap subs,
1800
+ ConditionalEffectKind conditional,
1765
1801
PotentialEffectReason reason, EffectKind kind) {
1766
1802
if (!paramType || paramType->hasError ())
1767
1803
return Classification::forInvalidCode ();
@@ -1779,8 +1815,10 @@ class ApplyClassifier {
1779
1815
return Classification ();
1780
1816
1781
1817
case EffectKind::Throws:
1782
- if (auto thrownError = fnType->getEffectiveThrownErrorType ())
1783
- return Classification::forThrows (*thrownError, conditional, reason);
1818
+ if (auto thrownError = fnType->getEffectiveThrownErrorType ()) {
1819
+ return Classification::forThrows (
1820
+ thrownError->subst (subs), conditional, reason);
1821
+ }
1784
1822
1785
1823
return Classification ();
1786
1824
}
@@ -1792,7 +1830,7 @@ class ApplyClassifier {
1792
1830
1793
1831
for (auto eltType : tuple->getElementTypes ()) {
1794
1832
result.merge (
1795
- classifyArgumentByType (eltType, conditional, reason, kind));
1833
+ classifyArgumentByType (eltType, subs, conditional, reason, kind));
1796
1834
}
1797
1835
1798
1836
return result;
@@ -2914,6 +2952,14 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2914
2952
2915
2953
auto asyncKind = classification.getConditionalKind (EffectKind::Async);
2916
2954
E->setNoAsync (asyncKind == ConditionalEffectKind::None);
2955
+ } else {
2956
+ // HACK: functions can get queued multiple times in
2957
+ // definedFunctions, so be sure to be idempotent.
2958
+ if (!E->isThrowsSet ()) {
2959
+ E->setThrows (ThrownErrorDestination ());
2960
+ }
2961
+
2962
+ E->setNoAsync (true );
2917
2963
}
2918
2964
2919
2965
// If current apply expression did not type-check, don't attempt
0 commit comments