@@ -1398,7 +1398,8 @@ class ApplyClassifier {
13981398 if (isa<SubscriptDecl>(cdr.getDecl ()))
13991399 return PotentialEffectReason::forSubscriptAccess ();
14001400
1401- assert (isa<VarDecl>(cdr.getDecl ()));
1401+ // Note that declarations other than properties end up with
1402+ // "property access" effect reasons for historical... reasons.
14021403 return PotentialEffectReason::forPropertyAccess ();
14031404 }
14041405
@@ -1537,18 +1538,18 @@ class ApplyClassifier {
15371538 if (!member)
15381539 return Classification::forInvalidCode ();
15391540
1540- PotentialEffectReason reason =
1541- PotentialEffectReason::forPropertyAccess ();
1542- Classification classification;
1541+ ConcreteDeclRef declToClassify;
15431542 if (auto getter = getEffectfulGetOnlyAccessor (member)) {
1544- reason = getKindOfEffectfulProp (member);
1545- classification = Classification::forDeclRef (
1546- getter, ConditionalEffectKind::Always, reason, E->getLoc (),
1547- assumedSafeArguments && assumedSafeArguments->contains (E));
1548- } else if (isa<SubscriptExpr>(E) || isa<DynamicSubscriptExpr>(E)) {
1549- reason = PotentialEffectReason::forSubscriptAccess ();
1543+ declToClassify = getter;
1544+ } else {
1545+ declToClassify = member;
15501546 }
15511547
1548+ PotentialEffectReason reason = getKindOfEffectfulProp (member);
1549+ Classification classification = Classification::forDeclRef (
1550+ declToClassify, ConditionalEffectKind::Always, reason, E->getLoc (),
1551+ assumedSafeArguments && assumedSafeArguments->contains (E));
1552+
15521553 classification.setDowngradeToWarning (
15531554 downgradeAsyncAccessToWarning (member.getDecl ()));
15541555
@@ -1557,14 +1558,6 @@ class ApplyClassifier {
15571558 E->isImplicitlyAsync ().has_value (), E->isImplicitlyThrows (),
15581559 reason);
15591560
1560- if (!classification.hasUnsafe ()) {
1561- classification.merge (
1562- Classification::forDeclRef (
1563- member, ConditionalEffectKind::Always, reason, E->getLoc (),
1564- assumedSafeArguments && assumedSafeArguments->contains (E),
1565- EffectKind::Unsafe));
1566- }
1567-
15681561 if (assumedSafeArguments) {
15691562 // If the declaration we're referencing is explicitly @safe, mark arguments
15701563 // as potentially being safe.
@@ -1646,9 +1639,10 @@ class ApplyClassifier {
16461639 PotentialEffectReason::forApply ());
16471640 }
16481641
1649- // / 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.
16501644 Classification classifyApply (
1651- ApplyExpr *E,
1645+ ApplyExpr *E,
16521646 llvm::DenseSet<const Expr *> *assumedSafeArguments
16531647 ) {
16541648 // An apply expression is a potential throw site if the function throws.
@@ -1664,9 +1658,28 @@ class ApplyClassifier {
16641658 if (!type) return Classification::forInvalidCode ();
16651659 auto fnType = type->getAs <AnyFunctionType>();
16661660 if (!fnType) return Classification::forInvalidCode ();
1667-
16681661 Expr *calleeFn = nullptr ;
16691662 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+ ) {
16701683 auto substitutions = fnRef.getSubstitutions ();
16711684 const bool hasAnyConformances =
16721685 llvm::any_of (substitutions.getConformances (),
@@ -1692,26 +1705,23 @@ class ApplyClassifier {
16921705 // If this is calling a @safe function, treat local variables as being
16931706 // safe.
16941707 if (fnRef.getExplicitSafety () == ExplicitSafety::Safe) {
1695- markArgumentsSafe (E-> getArgs () , *assumedSafeArguments);
1708+ markArgumentsSafe (args , *assumedSafeArguments);
16961709 }
16971710 }
16981711
1699- ASTContext &ctx = type ->getASTContext ();
1712+ ASTContext &ctx = fnType ->getASTContext ();
17001713
17011714 // If the function doesn't have any effects or conformances, we're done
17021715 // here.
17031716 if (!fnType->isThrowing () &&
1704- !E-> implicitlyThrows () &&
1717+ !implicitlyThrows &&
17051718 !fnType->isAsync () &&
1706- !E-> isImplicitlyAsync () &&
1719+ !implicitlyAsync &&
17071720 !hasAnyConformances &&
17081721 fnRef.getExplicitSafety () == ExplicitSafety::Safe) {
17091722 return Classification ();
17101723 }
17111724
1712- // Decompose the application.
1713- auto *args = E->getArgs ();
1714-
17151725 // If any of the arguments didn't type check, fail.
17161726 for (auto arg : *args) {
17171727 auto *argExpr = arg.getExpr ();
@@ -1721,7 +1731,7 @@ class ApplyClassifier {
17211731
17221732 Classification result;
17231733 result.mergeImplicitEffects (
1724- ctx, E-> isImplicitlyAsync (). has_value (), E-> implicitlyThrows () ,
1734+ ctx, implicitlyAsync, implicitlyThrows,
17251735 PotentialEffectReason::forApply ());
17261736
17271737 // Downgrade missing 'await' errors for preconcurrency references.
@@ -1732,8 +1742,8 @@ class ApplyClassifier {
17321742 auto classifyApplyEffect = [&](EffectKind kind) {
17331743 if (kind != EffectKind::Unsafe &&
17341744 !fnType->hasEffect (kind) &&
1735- !(kind == EffectKind::Async && E-> isImplicitlyAsync () ) &&
1736- !(kind == EffectKind::Throws && E-> implicitlyThrows () )) {
1745+ !(kind == EffectKind::Async && implicitlyAsync ) &&
1746+ !(kind == EffectKind::Throws && implicitlyThrows)) {
17371747 return ;
17381748 }
17391749
@@ -1767,7 +1777,7 @@ class ApplyClassifier {
17671777 } else if (kind == EffectKind::Unsafe) {
17681778 // For explicitly @unsafe functions, the entire call is considered
17691779 // unsafe.
1770- AbstractFunctionDecl *calleeFn =
1780+ AbstractFunctionDecl *calleeDecl =
17711781 fnRef.getKind () == AbstractFunction::Function
17721782 ? fnRef.getFunction ()
17731783 : nullptr ;
@@ -1776,7 +1786,7 @@ class ApplyClassifier {
17761786 Classification::forUnsafe (
17771787 {
17781788 UnsafeUse::forReferenceToUnsafe (
1779- calleeFn , true , fnRef.getType (), E ->getLoc ())
1789+ calleeDecl , true , fnRef.getType (), call ->getLoc ())
17801790 }
17811791 ));
17821792 return ;
@@ -1807,7 +1817,7 @@ class ApplyClassifier {
18071817 // to fix their code.
18081818 if (kind == EffectKind::Async &&
18091819 fnRef.getKind () == AbstractFunction::Function) {
1810- if (auto *ctor = dyn_cast<ConstructorRefCallExpr>(E-> getFn () )) {
1820+ if (auto *ctor = dyn_cast<ConstructorRefCallExpr>(calleeFn )) {
18111821 if (ctor->getFn ()->isImplicit () && args->isUnlabeledUnary ())
18121822 result.setDowngradeToWarning (true );
18131823 }
@@ -1848,15 +1858,15 @@ class ApplyClassifier {
18481858 return ;
18491859 }
18501860
1851- AbstractFunctionDecl *calleeFn =
1861+ AbstractFunctionDecl *calleeDecl =
18521862 fnRef.getKind () == AbstractFunction::Function
18531863 ? fnRef.getFunction ()
18541864 : nullptr ;
18551865
18561866 for (unsigned i = 0 , e = args->size (); i < e; ++i) {
18571867 Type origParamType = fnRef.getOrigParamInterfaceType (i);
18581868 auto argClassification = classifyArgument (
1859- E, calleeFn , args->getLabel (i), i,
1869+ call, calleeDecl , args->getLabel (i), i,
18601870 args->getExpr (i), origParamType, fnRef.getSubstitutions (),
18611871 kind);
18621872
@@ -1874,7 +1884,7 @@ class ApplyClassifier {
18741884 if (auto appliedSelf = fnRef.getAppliedSelf ()) {
18751885 Type origParamType = fnRef.getOrigParamSelfType ();
18761886 auto selfClassification = classifyArgument (
1877- E, calleeFn , ctx.Id_self , 0 , appliedSelf->getBase (),
1887+ call, calleeDecl , ctx.Id_self , 0 , appliedSelf->getBase (),
18781888 origParamType, fnRef.getSubstitutions (), kind);
18791889 result.merge (selfClassification);
18801890 }
@@ -1924,7 +1934,7 @@ class ApplyClassifier {
19241934 // If the safety of the callee is unspecified, check the safety of the
19251935 // arguments specifically.
19261936 if (hasUnspecifiedSafety &&
1927- !(assumedSafeArguments && assumedSafeArguments->contains (E ))) {
1937+ !(assumedSafeArguments && assumedSafeArguments->contains (call ))) {
19281938 classifyApplyEffect (EffectKind::Unsafe);
19291939 }
19301940
@@ -2611,7 +2621,7 @@ class ApplyClassifier {
26112621
26122622 // / Classify an argument being passed to a rethrows/reasync function.
26132623 Classification classifyArgument (
2614- ApplyExpr *call, const Decl* calleeDecl, Identifier argName,
2624+ Expr *call, const Decl* calleeDecl, Identifier argName,
26152625 unsigned argIndex, Expr *arg, Type paramType, SubstitutionMap subs,
26162626 EffectKind kind) {
26172627 // Check for an unsafe argument.
@@ -2718,7 +2728,7 @@ class ApplyClassifier {
27182728 }
27192729
27202730 // / Classify an argument to a rethrows/reasync function that's a tuple literal.
2721- Classification classifyTupleArgument (ApplyExpr *call,
2731+ Classification classifyTupleArgument (Expr *call,
27222732 const Decl* calleeDecl,
27232733 Identifier argName,
27242734 unsigned argIndex,
0 commit comments