@@ -239,69 +239,51 @@ class AbstractFunction {
239
239
ParamDecl *TheParameter;
240
240
Expr *TheExpr;
241
241
};
242
- unsigned TheKind : 2 ;
243
- unsigned ParamCount : 2 ;
242
+ Kind TheKind;
244
243
PolymorphicEffectKind RethrowingKind;
245
244
SubstitutionMap Substitutions;
246
245
247
246
public:
248
247
explicit AbstractFunction (Kind kind, Expr *fn)
249
248
: TheKind(kind),
250
- ParamCount(1 ),
251
249
RethrowingKind(PolymorphicEffectKind::None) {
252
250
TheExpr = fn;
253
251
}
254
252
255
253
explicit AbstractFunction (AbstractFunctionDecl *fn, SubstitutionMap subs)
256
254
: TheKind(Kind::Function),
257
- ParamCount(fn->getNumCurryLevels ()),
258
255
RethrowingKind(fn->getPolymorphicEffectKind (EffectKind::Throws)),
259
256
Substitutions(subs) {
260
257
TheFunction = fn;
261
258
}
262
259
263
260
explicit AbstractFunction (AbstractClosureExpr *closure)
264
261
: TheKind(Kind::Closure),
265
- ParamCount(1 ),
266
262
RethrowingKind(PolymorphicEffectKind::None) {
267
263
TheClosure = closure;
268
264
}
269
265
270
266
explicit AbstractFunction (ParamDecl *parameter)
271
267
: TheKind(Kind::Parameter),
272
- ParamCount(1 ),
273
268
RethrowingKind(PolymorphicEffectKind::None) {
274
269
TheParameter = parameter;
275
270
}
276
271
277
- Kind getKind () const { return Kind (TheKind); }
278
-
279
- // / Whether the function is marked 'rethrows'.
280
- bool isBodyRethrows () const {
281
- switch (RethrowingKind) {
282
- case PolymorphicEffectKind::None:
283
- case PolymorphicEffectKind::Always:
284
- return false ;
285
-
286
- case PolymorphicEffectKind::ByClosure:
287
- case PolymorphicEffectKind::ByConformance:
288
- case PolymorphicEffectKind::Invalid:
289
- return true ;
290
- }
291
- }
272
+ Kind getKind () const { return TheKind; }
292
273
293
274
PolymorphicEffectKind getRethrowingKind () const {
294
275
return RethrowingKind;
295
276
}
296
277
297
- unsigned getNumArgumentsForFullApply () const {
298
- return ParamCount;
299
- }
300
-
301
278
Type getType () const {
302
279
switch (getKind ()) {
303
280
case Kind::Opaque: return getOpaqueFunction ()->getType ();
304
- case Kind::Function: return getFunction ()->getInterfaceType ();
281
+ case Kind::Function: {
282
+ auto *AFD = getFunction ();
283
+ if (AFD->hasImplicitSelfDecl ())
284
+ return AFD->getMethodInterfaceType ();
285
+ return AFD->getInterfaceType ();
286
+ }
305
287
case Kind::Closure: return getClosure ()->getType ();
306
288
case Kind::Parameter: return getParameter ()->getType ();
307
289
}
@@ -336,23 +318,20 @@ class AbstractFunction {
336
318
}
337
319
338
320
static AbstractFunction decomposeApply (ApplyExpr *apply,
339
- SmallVectorImpl<SmallVector<Expr *, 2 >> &argLists) {
340
- Expr *fn;
341
- do {
342
- auto *argExpr = apply->getArg ();
343
- if (auto *tupleExpr = dyn_cast<TupleExpr>(argExpr)) {
344
- auto args = tupleExpr->getElements ();
345
- argLists.emplace_back (args.begin (), args.end ());
346
- } else if (auto *parenExpr = dyn_cast<ParenExpr>(argExpr)) {
347
- argLists.emplace_back ();
348
- argLists.back ().push_back (parenExpr->getSubExpr ());
349
- } else {
350
- argLists.emplace_back ();
351
- argLists.back ().push_back (argExpr);
352
- }
321
+ SmallVectorImpl<Expr *> &args) {
322
+ auto *argExpr = apply->getArg ();
323
+ if (auto *tupleExpr = dyn_cast<TupleExpr>(argExpr)) {
324
+ auto elts = tupleExpr->getElements ();
325
+ args.append (elts.begin (), elts.end ());
326
+ } else {
327
+ auto *parenExpr = cast<ParenExpr>(argExpr);
328
+ args.push_back (parenExpr->getSubExpr ());
329
+ }
330
+
331
+ Expr *fn = apply->getFn ()->getValueProvidingExpr ();
353
332
354
- fn = apply-> getFn ()-> getValueProvidingExpr ();
355
- } while ((apply = dyn_cast<ApplyExpr>(fn)) );
333
+ if ( auto *selfCall = dyn_cast<SelfApplyExpr>(fn))
334
+ fn = selfCall-> getFn ()-> getValueProvidingExpr ( );
356
335
357
336
return decomposeFunction (fn);
358
337
}
@@ -702,6 +681,9 @@ class ApplyClassifier {
702
681
703
682
// / Check to see if the given function application throws or is async.
704
683
Classification classifyApply (ApplyExpr *E) {
684
+ if (isa<SelfApplyExpr>(E))
685
+ return Classification ();
686
+
705
687
// An apply expression is a potential throw site if the function throws.
706
688
// But if the expression didn't type-check, suppress diagnostics.
707
689
if (!E->getType () || E->getType ()->hasError ())
@@ -713,88 +695,66 @@ class ApplyClassifier {
713
695
if (!fnType) return Classification::forInvalidCode ();
714
696
715
697
bool isAsync = fnType->isAsync () || E->implicitlyAsync ();
698
+
716
699
// Decompose the application.
717
- SmallVector<SmallVector< Expr *, 2 >, 2 > argLists ;
718
- auto fnRef = AbstractFunction::decomposeApply (E, argLists );
700
+ SmallVector<Expr *, 2 > args ;
701
+ auto fnRef = AbstractFunction::decomposeApply (E, args );
719
702
720
703
// If any of the arguments didn't type check, fail.
721
- for (auto argList : argLists) {
722
- for (auto *arg : argList) {
723
- if (!arg->getType () || arg->getType ()->hasError ())
724
- return Classification::forInvalidCode ();
725
- }
704
+ for (auto *arg : args) {
705
+ if (!arg->getType () || arg->getType ()->hasError ())
706
+ return Classification::forInvalidCode ();
726
707
}
727
708
728
709
// If the function doesn't throw at all, we're done here.
729
710
if (!fnType->isThrowing ()) {
730
711
return isAsync ? Classification::forAsync () : Classification ();
731
712
}
732
713
733
- // If we're applying more arguments than the natural argument
734
- // count, then this is a call to the opaque value returned from
735
- // the function.
736
- if (argLists.size () != fnRef.getNumArgumentsForFullApply ()) {
737
- // Special case: a reference to an operator within a type might be
738
- // missing 'self'.
739
- // FIXME: The issue here is that this is an ill-formed expression, but
740
- // we don't know it from the structure of the expression.
741
- if (argLists.size () == 1 && fnRef.getKind () == AbstractFunction::Function &&
742
- isa<FuncDecl>(fnRef.getFunction ()) &&
743
- cast<FuncDecl>(fnRef.getFunction ())->isOperator () &&
744
- fnRef.getNumArgumentsForFullApply () == 2 &&
745
- fnRef.getFunction ()->getDeclContext ()->isTypeContext ()) {
746
- // Can only happen with invalid code.
747
- assert (fnRef.getFunction ()->getASTContext ().Diags .hadAnyError ());
748
- return Classification::forInvalidCode ();
749
- }
750
-
751
- assert (argLists.size () > fnRef.getNumArgumentsForFullApply () &&
752
- " partial application was throwing?" );
753
- return Classification::forThrow (PotentialThrowReason::forThrowingApply (),
754
- isAsync);
755
- }
756
-
757
- if (fnRef.getRethrowingKind () == PolymorphicEffectKind::ByConformance) {
714
+ // Handle rethrowing functions.
715
+ switch (fnRef.getRethrowingKind ()) {
716
+ case PolymorphicEffectKind::ByConformance: {
758
717
auto substitutions = fnRef.getSubstitutions ();
759
718
for (auto conformanceRef : substitutions.getConformances ()) {
760
719
if (conformanceRef.hasEffect (EffectKind::Throws)) {
761
720
return Classification::forRethrowingOnly (
762
721
PotentialThrowReason::forRethrowsConformance (E), isAsync);
763
722
}
764
723
}
724
+
725
+ // 'ByConformance' is a superset of 'ByClosure', so check for
726
+ // closure arguments too.
727
+ LLVM_FALLTHROUGH;
765
728
}
766
729
767
- // If the function's body is 'rethrows' for the number of
768
- // arguments we gave it, apply the rethrows logic.
769
- if (fnRef.isBodyRethrows ()) {
730
+ case PolymorphicEffectKind::ByClosure: {
770
731
// We need to walk the original parameter types in parallel
771
732
// because it only counts for 'rethrows' purposes if it lines up
772
733
// with a throwing function parameter in the original type.
773
- Type type = fnRef.getType ();
774
- if (!type) return Classification::forInvalidCode ();
734
+ auto *origType = fnRef.getType ()->getAs <AnyFunctionType>();
735
+ if (!origType)
736
+ return Classification::forInvalidCode ();
775
737
776
738
// Use the most significant result from the arguments.
777
739
Classification result = isAsync ? Classification::forAsync ()
778
740
: Classification ();
779
- for (auto argList : llvm::reverse (argLists)) {
780
- auto fnType = type->getAs <AnyFunctionType>();
781
- if (!fnType)
782
- return Classification::forInvalidCode ();
783
-
784
- auto params = fnType->getParams ();
785
- if (params.size () != argList.size ())
786
- return Classification::forInvalidCode ();
787
-
788
- for (unsigned i = 0 , e = params.size (); i < e; ++i) {
789
- result.merge (classifyRethrowsArgument (argList[i],
790
- params[i].getParameterType ()));
791
- }
792
741
793
- type = fnType->getResult ();
742
+ auto params = origType->getParams ();
743
+ if (params.size () != args.size ())
744
+ return Classification::forInvalidCode ();
745
+
746
+ for (unsigned i = 0 , e = params.size (); i < e; ++i) {
747
+ result.merge (classifyRethrowsArgument (args[i],
748
+ params[i].getParameterType ()));
794
749
}
750
+
795
751
return result;
796
752
}
797
753
754
+ default :
755
+ break ;
756
+ }
757
+
798
758
// Try to classify the implementation of functions that we have
799
759
// local knowledge of.
800
760
Classification result =
0 commit comments