@@ -2879,6 +2879,55 @@ TypeVariableBinding::fixForHole(ConstraintSystem &cs) const {
28792879 return std::nullopt ;
28802880}
28812881
2882+ static bool shouldIgnoreHoleForCodeCompletion (ConstraintSystem &cs,
2883+ TypeVariableType *typeVar,
2884+ ConstraintLocator *srcLocator) {
2885+ if (!cs.isForCodeCompletion ())
2886+ return false ;
2887+
2888+ // Don't penalize solutions with unresolved generics.
2889+ if (typeVar->getImpl ().getGenericParameter ())
2890+ return true ;
2891+
2892+ // Don't penalize solutions if we couldn't determine the type of the code
2893+ // completion token. We still want to examine the surrounding types in
2894+ // that case.
2895+ if (typeVar->getImpl ().isCodeCompletionToken ())
2896+ return true ;
2897+
2898+ // When doing completion in a result builder, we avoid solving unrelated
2899+ // expressions by replacing them with unbound placeholder variables.
2900+ // As such, we need to avoid penalizing holes for references to
2901+ // placeholder variables.
2902+ if (srcLocator->isLastElement <LocatorPathElt::PlaceholderType>()) {
2903+ if (auto *DRE = getAsExpr<DeclRefExpr>(srcLocator->getAnchor ())) {
2904+ if (auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl ())) {
2905+ if (auto *PBD = VD->getParentPatternBinding ()) {
2906+ if (isPlaceholderVar (PBD))
2907+ return true ;
2908+ }
2909+ }
2910+ }
2911+ }
2912+
2913+ // Don't penalize solutions with holes due to missing arguments after the
2914+ // code completion position.
2915+ auto argLoc = srcLocator->findLast <LocatorPathElt::SynthesizedArgument>();
2916+ if (argLoc && argLoc->isAfterCodeCompletionLoc ())
2917+ return true ;
2918+
2919+ // Don't penalize solutions that have holes for ignored arguments.
2920+ if (cs.hasArgumentsIgnoredForCodeCompletion ()) {
2921+ // Avoid simplifying the locator if the constraint system didn't ignore
2922+ // any arguments.
2923+ auto argExpr = simplifyLocatorToAnchor (typeVar->getImpl ().getLocator ());
2924+ if (cs.isArgumentIgnoredForCodeCompletion (argExpr.dyn_cast <Expr *>())) {
2925+ return true ;
2926+ }
2927+ }
2928+ return false ;
2929+ }
2930+
28822931bool TypeVariableBinding::attempt (ConstraintSystem &cs) const {
28832932 auto type = Binding.BindingType ;
28842933 auto *srcLocator = Binding.getLocator ();
@@ -2934,33 +2983,9 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const {
29342983 }
29352984
29362985 auto reportHole = [&]() {
2937- if (cs.isForCodeCompletion ()) {
2938- // Don't penalize solutions with unresolved generics.
2939- if (TypeVar->getImpl ().getGenericParameter ())
2940- return false ;
2941-
2942- // Don't penalize solutions if we couldn't determine the type of the code
2943- // completion token. We still want to examine the surrounding types in
2944- // that case.
2945- if (TypeVar->getImpl ().isCodeCompletionToken ())
2946- return false ;
2947-
2948- // Don't penalize solutions with holes due to missing arguments after the
2949- // code completion position.
2950- auto argLoc = srcLocator->findLast <LocatorPathElt::SynthesizedArgument>();
2951- if (argLoc && argLoc->isAfterCodeCompletionLoc ())
2952- return false ;
2953-
2954- // Don't penalize solutions that have holes for ignored arguments.
2955- if (cs.hasArgumentsIgnoredForCodeCompletion ()) {
2956- // Avoid simplifying the locator if the constraint system didn't ignore
2957- // any arguments.
2958- auto argExpr = simplifyLocatorToAnchor (TypeVar->getImpl ().getLocator ());
2959- if (cs.isArgumentIgnoredForCodeCompletion (argExpr.dyn_cast <Expr *>())) {
2960- return false ;
2961- }
2962- }
2963- }
2986+ if (shouldIgnoreHoleForCodeCompletion (cs, TypeVar, srcLocator))
2987+ return false ;
2988+
29642989 // Reflect in the score that this type variable couldn't be
29652990 // resolved and had to be bound to a placeholder "hole" type.
29662991 cs.increaseScore (SK_Hole, srcLocator);
0 commit comments