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;
@@ -1187,15 +1212,15 @@ class ApplyClassifier {
1187
1212
return ;
1188
1213
}
1189
1214
1190
- auto params = fnSubstType->getParams ();
1191
- if (params.size () != args->size ()) {
1215
+ if (fnSubstType->getParams ().size () != args->size ()) {
1192
1216
result.merge (Classification::forInvalidCode ());
1193
1217
return ;
1194
1218
}
1195
1219
1196
- for (unsigned i = 0 , e = params.size (); i < e; ++i) {
1220
+ for (unsigned i = 0 , e = args->size (); i < e; ++i) {
1221
+ Type origParamType = fnRef.getOrigParamInterfaceType (i);
1197
1222
auto argClassification = classifyArgument (
1198
- args->getExpr (i), params[i]. getParameterType (), kind);
1223
+ args->getExpr (i), origParamType, fnRef. getSubstitutions (), kind);
1199
1224
1200
1225
// Rethrows is untyped, so adjust the thrown error type.
1201
1226
if (kind == EffectKind::Throws &&
@@ -1291,7 +1316,7 @@ class ApplyClassifier {
1291
1316
EffectKind kind) {
1292
1317
switch (fn.getKind ()) {
1293
1318
case AbstractFunction::Opaque: {
1294
- return classifyArgumentByType (fn.getType (),
1319
+ return classifyArgumentByType (fn.getType (), fn. getSubstitutions (),
1295
1320
ConditionalEffectKind::Always, reason,
1296
1321
kind);
1297
1322
}
@@ -1330,8 +1355,8 @@ class ApplyClassifier {
1330
1355
else // otherwise, it throws unconditionally.
1331
1356
conditional = ConditionalEffectKind::Always;
1332
1357
1333
- return classifyArgumentByType (param-> getTypeInContext (),
1334
- conditional, reason, kind);
1358
+ return classifyArgumentByType (
1359
+ param-> getInterfaceType (), subs, conditional, reason, kind);
1335
1360
}
1336
1361
1337
1362
bool isLocallyDefinedInPolymorphicEffectDeclContext (DeclContext *DC,
@@ -1660,7 +1685,8 @@ class ApplyClassifier {
1660
1685
}
1661
1686
1662
1687
// / Classify an argument being passed to a rethrows/reasync function.
1663
- Classification classifyArgument (Expr *arg, Type paramType, EffectKind kind) {
1688
+ Classification classifyArgument (
1689
+ Expr *arg, Type paramType, SubstitutionMap subs, EffectKind kind) {
1664
1690
arg = arg->getValueProvidingExpr ();
1665
1691
1666
1692
if (auto *defaultArg = dyn_cast<DefaultArgumentExpr>(arg)) {
@@ -1673,7 +1699,7 @@ class ApplyClassifier {
1673
1699
}
1674
1700
}
1675
1701
1676
- return classifyArgumentByType (arg->getType (),
1702
+ return classifyArgumentByType (arg->getType (), subs,
1677
1703
ConditionalEffectKind::Always,
1678
1704
PotentialEffectReason::forDefaultClosure (),
1679
1705
kind);
@@ -1698,7 +1724,7 @@ class ApplyClassifier {
1698
1724
// various tuple operations.
1699
1725
if (auto paramTupleType = dyn_cast<TupleType>(paramType.getPointer ())) {
1700
1726
if (auto tuple = dyn_cast<TupleExpr>(arg)) {
1701
- return classifyTupleArgument (tuple, paramTupleType, kind);
1727
+ return classifyTupleArgument (tuple, paramTupleType, subs, kind);
1702
1728
}
1703
1729
1704
1730
if (paramTupleType->getNumElements () != 1 ) {
@@ -1707,6 +1733,7 @@ class ApplyClassifier {
1707
1733
// parameter type included a throwing function type.
1708
1734
return classifyArgumentByType (
1709
1735
paramType,
1736
+ subs,
1710
1737
ConditionalEffectKind::Always,
1711
1738
PotentialEffectReason::forClosure (arg),
1712
1739
kind);
@@ -1751,6 +1778,7 @@ class ApplyClassifier {
1751
1778
// / Classify an argument to a rethrows/reasync function that's a tuple literal.
1752
1779
Classification classifyTupleArgument (TupleExpr *tuple,
1753
1780
TupleType *paramTupleType,
1781
+ SubstitutionMap subs,
1754
1782
EffectKind kind) {
1755
1783
if (paramTupleType->getNumElements () != tuple->getNumElements ())
1756
1784
return Classification::forInvalidCode ();
@@ -1759,7 +1787,7 @@ class ApplyClassifier {
1759
1787
for (unsigned i : indices (tuple->getElements ())) {
1760
1788
result.merge (classifyArgument (tuple->getElement (i),
1761
1789
paramTupleType->getElementType (i),
1762
- kind));
1790
+ subs, kind));
1763
1791
}
1764
1792
return result;
1765
1793
}
@@ -1768,7 +1796,8 @@ class ApplyClassifier {
1768
1796
// / a throws/async function in a way that is permitted to cause a
1769
1797
// / rethrows/reasync function to throw/async.
1770
1798
static Classification
1771
- classifyArgumentByType (Type paramType, ConditionalEffectKind conditional,
1799
+ classifyArgumentByType (Type paramType, SubstitutionMap subs,
1800
+ ConditionalEffectKind conditional,
1772
1801
PotentialEffectReason reason, EffectKind kind) {
1773
1802
if (!paramType || paramType->hasError ())
1774
1803
return Classification::forInvalidCode ();
@@ -1786,8 +1815,10 @@ class ApplyClassifier {
1786
1815
return Classification ();
1787
1816
1788
1817
case EffectKind::Throws:
1789
- if (auto thrownError = fnType->getEffectiveThrownErrorType ())
1790
- return Classification::forThrows (*thrownError, conditional, reason);
1818
+ if (auto thrownError = fnType->getEffectiveThrownErrorType ()) {
1819
+ return Classification::forThrows (
1820
+ thrownError->subst (subs), conditional, reason);
1821
+ }
1791
1822
1792
1823
return Classification ();
1793
1824
}
@@ -1799,7 +1830,7 @@ class ApplyClassifier {
1799
1830
1800
1831
for (auto eltType : tuple->getElementTypes ()) {
1801
1832
result.merge (
1802
- classifyArgumentByType (eltType, conditional, reason, kind));
1833
+ classifyArgumentByType (eltType, subs, conditional, reason, kind));
1803
1834
}
1804
1835
1805
1836
return result;
0 commit comments