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