|
36 | 36 | using namespace swift;
|
37 | 37 | using namespace swift::constraints;
|
38 | 38 |
|
39 |
| -/// Find the declaration directly referenced by this expression. |
40 |
| -static std::pair<ValueDecl *, FunctionRefKind> |
41 |
| -findReferencedDecl(Expr *expr, DeclNameLoc &loc) { |
42 |
| - do { |
43 |
| - expr = expr->getSemanticsProvidingExpr(); |
44 |
| - |
45 |
| - if (auto ice = dyn_cast<ImplicitConversionExpr>(expr)) { |
46 |
| - expr = ice->getSubExpr(); |
47 |
| - continue; |
48 |
| - } |
49 |
| - |
50 |
| - if (auto dre = dyn_cast<DeclRefExpr>(expr)) { |
51 |
| - loc = dre->getNameLoc(); |
52 |
| - return { dre->getDecl(), dre->getFunctionRefKind() }; |
53 |
| - } |
54 |
| - |
55 |
| - return { nullptr, FunctionRefKind::Unapplied }; |
56 |
| - } while (true); |
57 |
| -} |
58 |
| - |
59 | 39 | static bool isArithmeticOperatorDecl(ValueDecl *vd) {
|
60 | 40 | return vd &&
|
61 | 41 | (vd->getBaseName() == "+" ||
|
@@ -915,35 +895,6 @@ namespace {
|
915 | 895 | };
|
916 | 896 | } // end anonymous namespace
|
917 | 897 |
|
918 |
| -namespace { |
919 |
| -// Check if \p E is a call expression to curried thunk of "KeyPath as function". |
920 |
| -// i.e. '{ `$kp$` in { $0[keyPath: $kp$] } }(keypath)' |
921 |
| -static bool isKeyPathCurriedThunkCallExpr(Expr *E) { |
922 |
| - auto CE = dyn_cast<CallExpr>(E); |
923 |
| - if (!CE) |
924 |
| - return false; |
925 |
| - auto thunk = dyn_cast<AutoClosureExpr>(CE->getFn()); |
926 |
| - if (!thunk) |
927 |
| - return false; |
928 |
| - if (thunk->getParameters()->size() != 1 || |
929 |
| - thunk->getParameters()->get(0)->getParameterName().str() != "$kp$") |
930 |
| - return false; |
931 |
| - |
932 |
| - auto PE = dyn_cast<ParenExpr>(CE->getArg()); |
933 |
| - if (!PE) |
934 |
| - return false; |
935 |
| - return isa<KeyPathExpr>(PE->getSubExpr()); |
936 |
| -} |
937 |
| - |
938 |
| -// Extract the keypath expression from the curried thunk expression. |
939 |
| -static Expr *extractKeyPathFromCurryThunkCall(Expr *E) { |
940 |
| - assert(isKeyPathCurriedThunkCallExpr(E)); |
941 |
| - auto call = cast<CallExpr>(E); |
942 |
| - auto arg = cast<ParenExpr>(call->getArg()); |
943 |
| - return arg->getSubExpr(); |
944 |
| -} |
945 |
| -} // end anonymous namespace |
946 |
| - |
947 | 898 | namespace {
|
948 | 899 |
|
949 | 900 | class ConstraintGenerator : public ExprVisitor<ConstraintGenerator, Type> {
|
@@ -3776,272 +3727,6 @@ namespace {
|
3776 | 3727 | }
|
3777 | 3728 | };
|
3778 | 3729 |
|
3779 |
| - /// AST walker that "sanitizes" an expression for re-typechecking during |
3780 |
| - /// code completion. |
3781 |
| - /// |
3782 |
| - /// FIXME: Remove this. |
3783 |
| - class SanitizeExpr : public ASTWalker { |
3784 |
| - ASTContext &C; |
3785 |
| - bool ShouldReusePrecheckedType; |
3786 |
| - llvm::SmallDenseMap<OpaqueValueExpr *, Expr *, 4> OpenExistentials; |
3787 |
| - |
3788 |
| - public: |
3789 |
| - SanitizeExpr(ASTContext &C, |
3790 |
| - bool shouldReusePrecheckedType) |
3791 |
| - : C(C), ShouldReusePrecheckedType(shouldReusePrecheckedType) { } |
3792 |
| - |
3793 |
| - std::pair<bool, Expr *> walkToExprPre(Expr *expr) override { |
3794 |
| - while (true) { |
3795 |
| - |
3796 |
| - // If we should reuse pre-checked types, don't sanitize the expression |
3797 |
| - // if it's already type-checked. |
3798 |
| - if (ShouldReusePrecheckedType && expr->getType()) |
3799 |
| - return { false, expr }; |
3800 |
| - |
3801 |
| - // OpenExistentialExpr contains OpaqueValueExpr in its sub expression. |
3802 |
| - if (auto OOE = dyn_cast<OpenExistentialExpr>(expr)) { |
3803 |
| - auto archetypeVal = OOE->getOpaqueValue(); |
3804 |
| - auto base = OOE->getExistentialValue(); |
3805 |
| - |
3806 |
| - bool inserted = OpenExistentials.insert({archetypeVal, base}).second; |
3807 |
| - assert(inserted && "OpaqueValue appears multiple times?"); |
3808 |
| - (void)inserted; |
3809 |
| - SWIFT_DEFER { OpenExistentials.erase(archetypeVal); }; |
3810 |
| - |
3811 |
| - // Walk to and return the base expression to erase any existentials |
3812 |
| - // within it. |
3813 |
| - return { false, OOE->getSubExpr()->walk(*this) }; |
3814 |
| - } |
3815 |
| - |
3816 |
| - // Hacky, this behaves just like an OpenedExistential in that it changes |
3817 |
| - // the expr tree. |
3818 |
| - if (auto ISLE = dyn_cast<InterpolatedStringLiteralExpr>(expr)) { |
3819 |
| - if (auto subExpr = ISLE->getAppendingExpr()->getSubExpr()) { |
3820 |
| - if (auto opaqueValue = dyn_cast<OpaqueValueExpr>(subExpr)) { |
3821 |
| - ISLE->getAppendingExpr()->setSubExpr(nullptr); |
3822 |
| - } |
3823 |
| - } |
3824 |
| - } |
3825 |
| - |
3826 |
| - // Substitute OpaqueValue with its representing existental. |
3827 |
| - if (auto OVE = dyn_cast<OpaqueValueExpr>(expr)) { |
3828 |
| - auto value = OpenExistentials.find(OVE); |
3829 |
| - |
3830 |
| - if (value != OpenExistentials.end()) { |
3831 |
| - expr = value->second; |
3832 |
| - continue; |
3833 |
| - } else { |
3834 |
| - assert(OVE->isPlaceholder() && |
3835 |
| - "Didn't see this OVE in a containing OpenExistentialExpr?"); |
3836 |
| - } |
3837 |
| - } |
3838 |
| - |
3839 |
| - // Skip any implicit conversions applied to this expression. |
3840 |
| - if (auto ICE = dyn_cast<ImplicitConversionExpr>(expr)) { |
3841 |
| - expr = ICE->getSubExpr(); |
3842 |
| - continue; |
3843 |
| - } |
3844 |
| - |
3845 |
| - // MakeTemporarilyEscapableExpr is typechecked expression. |
3846 |
| - if (auto MTEE = dyn_cast<MakeTemporarilyEscapableExpr>(expr)) { |
3847 |
| - expr = MTEE->getOriginalExpr(); |
3848 |
| - continue; |
3849 |
| - } |
3850 |
| - |
3851 |
| - // Extract keypath from '{ `$kp$` in { $0[keyPath: $kp$] } }(keypath)' |
3852 |
| - if (isKeyPathCurriedThunkCallExpr(expr)) { |
3853 |
| - expr = extractKeyPathFromCurryThunkCall(expr); |
3854 |
| - continue; |
3855 |
| - } |
3856 |
| - |
3857 |
| - // Restore '@autoclosure'd value. |
3858 |
| - if (auto ACE = dyn_cast<AutoClosureExpr>(expr)) { |
3859 |
| - // This is only valid if the closure doesn't have parameters. |
3860 |
| - if (ACE->getParameters()->size() == 0) { |
3861 |
| - expr = ACE->getSingleExpressionBody(); |
3862 |
| - continue; |
3863 |
| - } |
3864 |
| - llvm_unreachable("other AutoClosureExpr must be handled specially"); |
3865 |
| - } |
3866 |
| - |
3867 |
| - // Remove any semantic expression injected by typechecking. |
3868 |
| - if (auto EPE = dyn_cast<EditorPlaceholderExpr>(expr)) { |
3869 |
| - EPE->setSemanticExpr(nullptr); |
3870 |
| - } |
3871 |
| - |
3872 |
| - // Strip default arguments and varargs from type-checked call |
3873 |
| - // argument lists. |
3874 |
| - if (isa<ParenExpr>(expr) || isa<TupleExpr>(expr)) { |
3875 |
| - if (shouldSanitizeArgumentList(expr)) |
3876 |
| - expr = sanitizeArgumentList(expr); |
3877 |
| - } |
3878 |
| - |
3879 |
| - // If this expression represents keypath based dynamic member |
3880 |
| - // lookup, let's convert it back to the original form of |
3881 |
| - // member or subscript reference. |
3882 |
| - if (auto *SE = dyn_cast<SubscriptExpr>(expr)) { |
3883 |
| - if (auto *TE = dyn_cast<TupleExpr>(SE->getIndex())) { |
3884 |
| - auto isImplicitKeyPathExpr = [](Expr *argExpr) -> bool { |
3885 |
| - if (auto *KP = dyn_cast<KeyPathExpr>(argExpr)) |
3886 |
| - return KP->isImplicit(); |
3887 |
| - return false; |
3888 |
| - }; |
3889 |
| - |
3890 |
| - if (TE->isImplicit() && TE->getNumElements() == 1 && |
3891 |
| - TE->getElementName(0) == C.Id_dynamicMember && |
3892 |
| - isImplicitKeyPathExpr(TE->getElement(0))) { |
3893 |
| - auto *keyPathExpr = cast<KeyPathExpr>(TE->getElement(0)); |
3894 |
| - auto *componentExpr = keyPathExpr->getParsedPath(); |
3895 |
| - |
3896 |
| - if (auto *UDE = dyn_cast<UnresolvedDotExpr>(componentExpr)) { |
3897 |
| - UDE->setBase(SE->getBase()); |
3898 |
| - return {true, UDE}; |
3899 |
| - } |
3900 |
| - |
3901 |
| - if (auto *subscript = dyn_cast<SubscriptExpr>(componentExpr)) { |
3902 |
| - subscript->setBase(SE->getBase()); |
3903 |
| - return {true, subscript}; |
3904 |
| - } |
3905 |
| - |
3906 |
| - llvm_unreachable("unknown keypath component type"); |
3907 |
| - } |
3908 |
| - } |
3909 |
| - } |
3910 |
| - |
3911 |
| - // If this is a closure, only walk into its children if they |
3912 |
| - // are type-checked in the context of the enclosing expression. |
3913 |
| - if (auto closure = dyn_cast<ClosureExpr>(expr)) { |
3914 |
| - if (!shouldTypeCheckInEnclosingExpression(closure)) |
3915 |
| - return { false, expr }; |
3916 |
| - } |
3917 |
| - |
3918 |
| - // Now, we're ready to walk into sub expressions. |
3919 |
| - return {true, expr}; |
3920 |
| - } |
3921 |
| - } |
3922 |
| - |
3923 |
| - bool isSyntheticArgumentExpr(const Expr *expr) { |
3924 |
| - if (isa<DefaultArgumentExpr>(expr)) |
3925 |
| - return true; |
3926 |
| - |
3927 |
| - if (auto *varargExpr = dyn_cast<VarargExpansionExpr>(expr)) |
3928 |
| - if (isa<ArrayExpr>(varargExpr->getSubExpr())) |
3929 |
| - return true; |
3930 |
| - |
3931 |
| - return false; |
3932 |
| - } |
3933 |
| - |
3934 |
| - bool shouldSanitizeArgumentList(const Expr *expr) { |
3935 |
| - if (auto *parenExpr = dyn_cast<ParenExpr>(expr)) { |
3936 |
| - return isSyntheticArgumentExpr(parenExpr->getSubExpr()); |
3937 |
| - } else if (auto *tupleExpr = dyn_cast<TupleExpr>(expr)) { |
3938 |
| - for (auto *arg : tupleExpr->getElements()) { |
3939 |
| - if (isSyntheticArgumentExpr(arg)) |
3940 |
| - return true; |
3941 |
| - } |
3942 |
| - |
3943 |
| - return false; |
3944 |
| - } else { |
3945 |
| - return isSyntheticArgumentExpr(expr); |
3946 |
| - } |
3947 |
| - } |
3948 |
| - |
3949 |
| - Expr *sanitizeArgumentList(Expr *original) { |
3950 |
| - auto argList = getOriginalArgumentList(original); |
3951 |
| - |
3952 |
| - if (argList.args.size() == 1 && |
3953 |
| - argList.labels[0].empty() && |
3954 |
| - !isa<VarargExpansionExpr>(argList.args[0])) { |
3955 |
| - auto *result = |
3956 |
| - new (C) ParenExpr(argList.lParenLoc, |
3957 |
| - argList.args[0], |
3958 |
| - argList.rParenLoc, |
3959 |
| - argList.hasTrailingClosure); |
3960 |
| - result->setImplicit(); |
3961 |
| - return result; |
3962 |
| - } |
3963 |
| - |
3964 |
| - return TupleExpr::create(C, |
3965 |
| - argList.lParenLoc, |
3966 |
| - argList.args, |
3967 |
| - argList.labels, |
3968 |
| - argList.labelLocs, |
3969 |
| - argList.rParenLoc, |
3970 |
| - argList.hasTrailingClosure, |
3971 |
| - /*implicit=*/true); |
3972 |
| - } |
3973 |
| - |
3974 |
| - Expr *walkToExprPost(Expr *expr) override { |
3975 |
| - assert(!isa<ImplicitConversionExpr>(expr) && |
3976 |
| - "ImplicitConversionExpr should be eliminated in walkToExprPre"); |
3977 |
| - |
3978 |
| - auto buildMemberRef = [&](Type memberType, Expr *base, SourceLoc dotLoc, |
3979 |
| - ConcreteDeclRef member, DeclNameLoc memberLoc, |
3980 |
| - bool implicit) -> Expr * { |
3981 |
| - auto *memberRef = new (C) |
3982 |
| - MemberRefExpr(base, dotLoc, member, memberLoc, implicit); |
3983 |
| - |
3984 |
| - if (memberType) { |
3985 |
| - memberRef->setType(memberType); |
3986 |
| - return memberRef; |
3987 |
| - } |
3988 |
| - |
3989 |
| - return memberRef; |
3990 |
| - }; |
3991 |
| - |
3992 |
| - // A DotSyntaxCallExpr is a member reference that has already been |
3993 |
| - // type-checked down to a call; turn it back into an overloaded |
3994 |
| - // member reference expression. |
3995 |
| - if (auto dotCall = dyn_cast<DotSyntaxCallExpr>(expr)) { |
3996 |
| - DeclNameLoc memberLoc; |
3997 |
| - auto memberAndFunctionRef = findReferencedDecl(dotCall->getFn(), |
3998 |
| - memberLoc); |
3999 |
| - if (memberAndFunctionRef.first) { |
4000 |
| - assert(!isa<ImplicitConversionExpr>(dotCall->getBase())); |
4001 |
| - return buildMemberRef(dotCall->getType(), |
4002 |
| - dotCall->getBase(), |
4003 |
| - dotCall->getDotLoc(), |
4004 |
| - memberAndFunctionRef.first, |
4005 |
| - memberLoc, expr->isImplicit()); |
4006 |
| - } |
4007 |
| - } |
4008 |
| - |
4009 |
| - if (auto *dynamicMember = dyn_cast<DynamicMemberRefExpr>(expr)) { |
4010 |
| - if (auto memberRef = dynamicMember->getMember()) { |
4011 |
| - assert(!isa<ImplicitConversionExpr>(dynamicMember->getBase())); |
4012 |
| - return buildMemberRef(dynamicMember->getType(), |
4013 |
| - dynamicMember->getBase(), |
4014 |
| - dynamicMember->getDotLoc(), |
4015 |
| - memberRef, |
4016 |
| - dynamicMember->getNameLoc(), |
4017 |
| - expr->isImplicit()); |
4018 |
| - } |
4019 |
| - } |
4020 |
| - |
4021 |
| - // A DotSyntaxBaseIgnoredExpr is a static member reference that has |
4022 |
| - // already been type-checked down to a call where the argument doesn't |
4023 |
| - // actually matter; turn it back into an overloaded member reference |
4024 |
| - // expression. |
4025 |
| - if (auto dotIgnored = dyn_cast<DotSyntaxBaseIgnoredExpr>(expr)) { |
4026 |
| - DeclNameLoc memberLoc; |
4027 |
| - auto memberAndFunctionRef = findReferencedDecl(dotIgnored->getRHS(), |
4028 |
| - memberLoc); |
4029 |
| - if (memberAndFunctionRef.first) { |
4030 |
| - assert(!isa<ImplicitConversionExpr>(dotIgnored->getLHS())); |
4031 |
| - return buildMemberRef(dotIgnored->getType(), |
4032 |
| - dotIgnored->getLHS(), |
4033 |
| - dotIgnored->getDotLoc(), |
4034 |
| - memberAndFunctionRef.first, |
4035 |
| - memberLoc, expr->isImplicit()); |
4036 |
| - } |
4037 |
| - } |
4038 |
| - return expr; |
4039 |
| - } |
4040 |
| - |
4041 |
| - /// Ignore declarations. |
4042 |
| - bool walkToDeclPre(Decl *decl) override { return false; } |
4043 |
| - }; |
4044 |
| - |
4045 | 3730 | class ConstraintWalker : public ASTWalker {
|
4046 | 3731 | ConstraintGenerator &CG;
|
4047 | 3732 |
|
@@ -4169,10 +3854,6 @@ namespace {
|
4169 | 3854 |
|
4170 | 3855 | static Expr *generateConstraintsFor(ConstraintSystem &cs, Expr *expr,
|
4171 | 3856 | DeclContext *DC) {
|
4172 |
| - // Remove implicit conversions from the expression. |
4173 |
| - expr = expr->walk(SanitizeExpr(cs.getASTContext(), |
4174 |
| - cs.shouldReusePrecheckedType())); |
4175 |
| - |
4176 | 3857 | // Walk the expression, generating constraints.
|
4177 | 3858 | ConstraintGenerator cg(cs, DC);
|
4178 | 3859 | ConstraintWalker cw(cg);
|
|
0 commit comments