@@ -1639,9 +1639,10 @@ class ApplyClassifier {
16391639 PotentialEffectReason::forApply ());
16401640 }
16411641
1642- // / Check to see if the given function application throws or is async.
1642+ // / Check to see if the given function application throws, is async, or
1643+ // / involves unsafe behavior.
16431644 Classification classifyApply (
1644- ApplyExpr *E,
1645+ ApplyExpr *E,
16451646 llvm::DenseSet<const Expr *> *assumedSafeArguments
16461647 ) {
16471648 // An apply expression is a potential throw site if the function throws.
@@ -1657,9 +1658,28 @@ class ApplyClassifier {
16571658 if (!type) return Classification::forInvalidCode ();
16581659 auto fnType = type->getAs <AnyFunctionType>();
16591660 if (!fnType) return Classification::forInvalidCode ();
1660-
16611661 Expr *calleeFn = nullptr ;
16621662 auto fnRef = AbstractFunction::getAppliedFn (E, &calleeFn);
1663+
1664+ auto *args = E->getArgs ();
1665+ return classifyApply (
1666+ E, fnRef, calleeFn, fnType, args,
1667+ E->isImplicitlyAsync ().has_value (), E->implicitlyThrows (),
1668+ assumedSafeArguments);
1669+ }
1670+
1671+ // / Check to see if the given function application throws, is async, or
1672+ // / involves unsafe behavior.
1673+ Classification classifyApply (
1674+ Expr *call,
1675+ const AbstractFunction &fnRef,
1676+ Expr *calleeFn,
1677+ const AnyFunctionType *fnType,
1678+ ArgumentList *args,
1679+ bool implicitlyAsync,
1680+ bool implicitlyThrows,
1681+ llvm::DenseSet<const Expr *> *assumedSafeArguments
1682+ ) {
16631683 auto substitutions = fnRef.getSubstitutions ();
16641684 const bool hasAnyConformances =
16651685 llvm::any_of (substitutions.getConformances (),
@@ -1685,26 +1705,23 @@ class ApplyClassifier {
16851705 // If this is calling a @safe function, treat local variables as being
16861706 // safe.
16871707 if (fnRef.getExplicitSafety () == ExplicitSafety::Safe) {
1688- markArgumentsSafe (E-> getArgs () , *assumedSafeArguments);
1708+ markArgumentsSafe (args , *assumedSafeArguments);
16891709 }
16901710 }
16911711
1692- ASTContext &ctx = type ->getASTContext ();
1712+ ASTContext &ctx = fnType ->getASTContext ();
16931713
16941714 // If the function doesn't have any effects or conformances, we're done
16951715 // here.
16961716 if (!fnType->isThrowing () &&
1697- !E-> implicitlyThrows () &&
1717+ !implicitlyThrows &&
16981718 !fnType->isAsync () &&
1699- !E-> isImplicitlyAsync () &&
1719+ !implicitlyAsync &&
17001720 !hasAnyConformances &&
17011721 fnRef.getExplicitSafety () == ExplicitSafety::Safe) {
17021722 return Classification ();
17031723 }
17041724
1705- // Decompose the application.
1706- auto *args = E->getArgs ();
1707-
17081725 // If any of the arguments didn't type check, fail.
17091726 for (auto arg : *args) {
17101727 auto *argExpr = arg.getExpr ();
@@ -1714,7 +1731,7 @@ class ApplyClassifier {
17141731
17151732 Classification result;
17161733 result.mergeImplicitEffects (
1717- ctx, E-> isImplicitlyAsync (). has_value (), E-> implicitlyThrows () ,
1734+ ctx, implicitlyAsync, implicitlyThrows,
17181735 PotentialEffectReason::forApply ());
17191736
17201737 // Downgrade missing 'await' errors for preconcurrency references.
@@ -1725,8 +1742,8 @@ class ApplyClassifier {
17251742 auto classifyApplyEffect = [&](EffectKind kind) {
17261743 if (kind != EffectKind::Unsafe &&
17271744 !fnType->hasEffect (kind) &&
1728- !(kind == EffectKind::Async && E-> isImplicitlyAsync () ) &&
1729- !(kind == EffectKind::Throws && E-> implicitlyThrows () )) {
1745+ !(kind == EffectKind::Async && implicitlyAsync ) &&
1746+ !(kind == EffectKind::Throws && implicitlyThrows)) {
17301747 return ;
17311748 }
17321749
@@ -1760,7 +1777,7 @@ class ApplyClassifier {
17601777 } else if (kind == EffectKind::Unsafe) {
17611778 // For explicitly @unsafe functions, the entire call is considered
17621779 // unsafe.
1763- AbstractFunctionDecl *calleeFn =
1780+ AbstractFunctionDecl *calleeDecl =
17641781 fnRef.getKind () == AbstractFunction::Function
17651782 ? fnRef.getFunction ()
17661783 : nullptr ;
@@ -1769,7 +1786,7 @@ class ApplyClassifier {
17691786 Classification::forUnsafe (
17701787 {
17711788 UnsafeUse::forReferenceToUnsafe (
1772- calleeFn , true , fnRef.getType (), E ->getLoc ())
1789+ calleeDecl , true , fnRef.getType (), call ->getLoc ())
17731790 }
17741791 ));
17751792 return ;
@@ -1800,7 +1817,7 @@ class ApplyClassifier {
18001817 // to fix their code.
18011818 if (kind == EffectKind::Async &&
18021819 fnRef.getKind () == AbstractFunction::Function) {
1803- if (auto *ctor = dyn_cast<ConstructorRefCallExpr>(E-> getFn () )) {
1820+ if (auto *ctor = dyn_cast<ConstructorRefCallExpr>(calleeFn )) {
18041821 if (ctor->getFn ()->isImplicit () && args->isUnlabeledUnary ())
18051822 result.setDowngradeToWarning (true );
18061823 }
@@ -1841,15 +1858,15 @@ class ApplyClassifier {
18411858 return ;
18421859 }
18431860
1844- AbstractFunctionDecl *calleeFn =
1861+ AbstractFunctionDecl *calleeDecl =
18451862 fnRef.getKind () == AbstractFunction::Function
18461863 ? fnRef.getFunction ()
18471864 : nullptr ;
18481865
18491866 for (unsigned i = 0 , e = args->size (); i < e; ++i) {
18501867 Type origParamType = fnRef.getOrigParamInterfaceType (i);
18511868 auto argClassification = classifyArgument (
1852- E, calleeFn , args->getLabel (i), i,
1869+ call, calleeDecl , args->getLabel (i), i,
18531870 args->getExpr (i), origParamType, fnRef.getSubstitutions (),
18541871 kind);
18551872
@@ -1867,7 +1884,7 @@ class ApplyClassifier {
18671884 if (auto appliedSelf = fnRef.getAppliedSelf ()) {
18681885 Type origParamType = fnRef.getOrigParamSelfType ();
18691886 auto selfClassification = classifyArgument (
1870- E, calleeFn , ctx.Id_self , 0 , appliedSelf->getBase (),
1887+ call, calleeDecl , ctx.Id_self , 0 , appliedSelf->getBase (),
18711888 origParamType, fnRef.getSubstitutions (), kind);
18721889 result.merge (selfClassification);
18731890 }
@@ -1917,7 +1934,7 @@ class ApplyClassifier {
19171934 // If the safety of the callee is unspecified, check the safety of the
19181935 // arguments specifically.
19191936 if (hasUnspecifiedSafety &&
1920- !(assumedSafeArguments && assumedSafeArguments->contains (E ))) {
1937+ !(assumedSafeArguments && assumedSafeArguments->contains (call ))) {
19211938 classifyApplyEffect (EffectKind::Unsafe);
19221939 }
19231940
@@ -2604,7 +2621,7 @@ class ApplyClassifier {
26042621
26052622 // / Classify an argument being passed to a rethrows/reasync function.
26062623 Classification classifyArgument (
2607- ApplyExpr *call, const Decl* calleeDecl, Identifier argName,
2624+ Expr *call, const Decl* calleeDecl, Identifier argName,
26082625 unsigned argIndex, Expr *arg, Type paramType, SubstitutionMap subs,
26092626 EffectKind kind) {
26102627 // Check for an unsafe argument.
@@ -2711,7 +2728,7 @@ class ApplyClassifier {
27112728 }
27122729
27132730 // / Classify an argument to a rethrows/reasync function that's a tuple literal.
2714- Classification classifyTupleArgument (ApplyExpr *call,
2731+ Classification classifyTupleArgument (Expr *call,
27152732 const Decl* calleeDecl,
27162733 Identifier argName,
27172734 unsigned argIndex,
0 commit comments