@@ -110,6 +110,159 @@ Optional<SelectedOverload> FailureDiagnostic::getChoiceFor(Expr *expr) const {
110
110
return getOverloadChoiceIfAvailable (cs.getCalleeLocator (expr));
111
111
}
112
112
113
+ Type FailureDiagnostic::resolveInterfaceType (Type type,
114
+ bool reconstituteSugar) const {
115
+ auto &cs = getConstraintSystem ();
116
+ auto resolvedType = type.transform ([&](Type type) -> Type {
117
+ if (auto *tvt = type->getAs <TypeVariableType>()) {
118
+ // If this type variable is for a generic parameter, return that.
119
+ if (auto *gp = tvt->getImpl ().getGenericParameter ())
120
+ return gp;
121
+
122
+ // Otherwise resolve its fixed type, mapped out of context.
123
+ if (auto fixed = cs.getFixedType (tvt))
124
+ return resolveInterfaceType (fixed->mapTypeOutOfContext ());
125
+
126
+ return cs.getRepresentative (tvt);
127
+ }
128
+ if (auto *dmt = type->getAs <DependentMemberType>()) {
129
+ // For a dependent member, first resolve the base.
130
+ auto newBase = resolveInterfaceType (dmt->getBase ());
131
+
132
+ // Then reconstruct using its associated type.
133
+ assert (dmt->getAssocType ());
134
+ return DependentMemberType::get (newBase, dmt->getAssocType ());
135
+ }
136
+ return type;
137
+ });
138
+
139
+ assert (!resolvedType->hasArchetype ());
140
+ return reconstituteSugar ? resolvedType->reconstituteSugar (/* recursive*/ true )
141
+ : resolvedType;
142
+ }
143
+
144
+ // / Given an apply expr, returns true if it is expected to have a direct callee
145
+ // / overload, resolvable using `getChoiceFor`. Otherwise, returns false.
146
+ static bool shouldHaveDirectCalleeOverload (const ApplyExpr *apply) {
147
+ auto *fnExpr = apply->getFn ()->getValueProvidingExpr ();
148
+
149
+ // An apply of an apply/subscript doesn't have a direct callee.
150
+ if (isa<ApplyExpr>(fnExpr) || isa<SubscriptExpr>(fnExpr))
151
+ return false ;
152
+
153
+ // Applies of closures don't have callee overloads.
154
+ if (isa<ClosureExpr>(fnExpr))
155
+ return false ;
156
+
157
+ // If the optionality changes, there's no direct callee.
158
+ if (isa<BindOptionalExpr>(fnExpr) || isa<ForceValueExpr>(fnExpr) ||
159
+ isa<OptionalTryExpr>(fnExpr)) {
160
+ return false ;
161
+ }
162
+
163
+ // If we have an intermediate cast, there's no direct callee.
164
+ if (isa<ExplicitCastExpr>(fnExpr))
165
+ return false ;
166
+
167
+ // No direct callee for an if expr.
168
+ if (isa<IfExpr>(fnExpr))
169
+ return false ;
170
+
171
+ // Assume that anything else would have a direct callee.
172
+ return true ;
173
+ }
174
+
175
+ Optional<FunctionArgApplyInfo>
176
+ FailureDiagnostic::getFunctionArgApplyInfo (ConstraintLocator *locator) const {
177
+ auto &cs = getConstraintSystem ();
178
+ auto *anchor = locator->getAnchor ();
179
+ auto path = locator->getPath ();
180
+
181
+ // Look for the apply-arg-to-param element in the locator's path. We may
182
+ // have to look through other elements that are generated from an argument
183
+ // conversion such as GenericArgument for an optional-to-optional conversion,
184
+ // and OptionalPayload for a value-to-optional conversion.
185
+ auto applyArgElt =
186
+ std::find_if (path.rbegin (), path.rend (), [](LocatorPathElt elt) {
187
+ return elt.getKind () == ConstraintLocator::ApplyArgToParam;
188
+ });
189
+
190
+ if (applyArgElt == path.rend ())
191
+ return None;
192
+
193
+ assert (std::find_if (applyArgElt + 1 , path.rend (), [](LocatorPathElt elt) {
194
+ return elt.getKind () == ConstraintLocator::ApplyArgToParam;
195
+ }) == path.rend () && " Multiple ApplyArgToParam components?" );
196
+
197
+ // Form a new locator that ends at the apply-arg-to-param element, and
198
+ // simplify it to get the full argument expression.
199
+ auto argPath = path.drop_back (applyArgElt - path.rbegin ());
200
+ auto *argLocator = cs.getConstraintLocator (
201
+ anchor, argPath, ConstraintLocator::getSummaryFlagsForPath (argPath));
202
+
203
+ auto *argExpr = simplifyLocatorToAnchor (cs, argLocator);
204
+
205
+ // If we were unable to simplify down to the argument expression, we don't
206
+ // know what this is.
207
+ if (!argExpr)
208
+ return None;
209
+
210
+ ValueDecl *callee = nullptr ;
211
+ Type rawFnType;
212
+ if (auto overload = getChoiceFor (anchor)) {
213
+ // If we have resolved an overload for the callee, then use that to get the
214
+ // function type and callee.
215
+ if (auto *decl = overload->choice .getDeclOrNull ())
216
+ callee = decl;
217
+
218
+ rawFnType = overload->openedType ;
219
+ } else {
220
+ // If we didn't resolve an overload for the callee, we must be dealing with
221
+ // a call of an arbitrary function expr.
222
+ auto *call = cast<CallExpr>(anchor);
223
+ assert (!shouldHaveDirectCalleeOverload (call) &&
224
+ " Should we have resolved a callee for this?" );
225
+ rawFnType = cs.getType (call->getFn ())->getRValueType ();
226
+ }
227
+
228
+ auto *fnType = resolveType (rawFnType)->getAs <FunctionType>();
229
+ if (!fnType)
230
+ return None;
231
+
232
+ // Resolve the interface type for the function. Note that this may not be a
233
+ // function type, for example it could be a generic parameter.
234
+ Type fnInterfaceType;
235
+ if (callee && callee->hasInterfaceType ()) {
236
+ // If we have a callee with an interface type, we can use it. This is
237
+ // preferable to resolveInterfaceType, as this will allow us to get a
238
+ // GenericFunctionType for generic decls.
239
+ //
240
+ // Note that it's possible to find a callee without an interface type. This
241
+ // can happen for example with closure parameters, where the interface type
242
+ // isn't set until the solution is applied. In that case, use
243
+ // resolveInterfaceType.
244
+ fnInterfaceType = callee->getInterfaceType ();
245
+
246
+ // Strip off the curried self parameter if necessary.
247
+ if (callee->hasCurriedSelf ())
248
+ fnInterfaceType = fnInterfaceType->castTo <AnyFunctionType>()->getResult ();
249
+
250
+ if (auto *fn = fnInterfaceType->getAs <AnyFunctionType>()) {
251
+ assert (fn->getNumParams () == fnType->getNumParams () &&
252
+ " Parameter mismatch?" );
253
+ (void )fn;
254
+ }
255
+ } else {
256
+ fnInterfaceType = resolveInterfaceType (rawFnType);
257
+ }
258
+
259
+ auto argIdx = applyArgElt->getValue ();
260
+ auto paramIdx = applyArgElt->getValue2 ();
261
+
262
+ return FunctionArgApplyInfo (argExpr, argIdx, getType (argExpr), paramIdx,
263
+ fnInterfaceType, fnType, callee);
264
+ }
265
+
113
266
Type RequirementFailure::getOwnerType () const {
114
267
auto *anchor = getRawAnchor ();
115
268
@@ -544,19 +697,8 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseParameterUse() const {
544
697
return false ;
545
698
546
699
auto *anchor = getAnchor ();
547
- auto *locator = getLocator ();
548
700
auto diagnostic = diag::general_noescape_to_escaping;
549
701
550
- auto getGenericParamType =
551
- [](TypeVariableType *typeVar) -> GenericTypeParamType * {
552
- auto *locator = typeVar->getImpl ().getLocator ();
553
- if (locator->isForGenericParameter ()) {
554
- const auto &GP = locator->getPath ().back ();
555
- return GP.getGenericParameter ();
556
- }
557
- return nullptr ;
558
- };
559
-
560
702
ParamDecl *PD = nullptr ;
561
703
if (auto *DRE = dyn_cast<DeclRefExpr>(anchor)) {
562
704
PD = dyn_cast<ParamDecl>(DRE->getDecl ());
@@ -569,37 +711,29 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseParameterUse() const {
569
711
// Let's check whether this is a function parameter passed
570
712
// as an argument to another function which accepts @escaping
571
713
// function at that position.
572
- auto path = locator->getPath ();
573
- if (!path.empty () &&
574
- (path.back ().getKind () == ConstraintLocator::ApplyArgToParam)) {
575
- if (auto paramType =
576
- getParameterTypeFor (getRawAnchor (), path.back ().getValue2 ())) {
577
- if (paramType->isTypeVariableOrMember ()) {
578
- auto diagnoseGenericParamFailure = [&](Type genericParam,
579
- GenericTypeParamDecl *decl) {
580
- emitDiagnostic (anchor->getLoc (),
581
- diag::converting_noespace_param_to_generic_type,
582
- PD->getName (), genericParam);
583
-
584
- emitDiagnostic (decl, diag::generic_parameters_always_escaping);
585
- };
586
-
587
- // If this is a situation when non-escaping parameter is passed
588
- // to the argument which represents generic parameter, there is
589
- // a tailored diagnostic for that.
590
-
591
- if (auto *DMT = paramType->getAs <DependentMemberType>()) {
592
- auto baseTy = DMT->getBase ()->castTo <TypeVariableType>();
593
- diagnoseGenericParamFailure (resolveType (DMT),
594
- getGenericParamType (baseTy)->getDecl ());
595
- return true ;
596
- }
714
+ if (auto argApplyInfo = getFunctionArgApplyInfo (getLocator ())) {
715
+ auto paramInterfaceTy = argApplyInfo->getParamInterfaceType ();
716
+ if (paramInterfaceTy->isTypeParameter ()) {
717
+ auto diagnoseGenericParamFailure = [&](GenericTypeParamDecl *decl) {
718
+ emitDiagnostic (anchor->getLoc (),
719
+ diag::converting_noespace_param_to_generic_type,
720
+ PD->getName (), paramInterfaceTy);
721
+
722
+ emitDiagnostic (decl, diag::generic_parameters_always_escaping);
723
+ };
724
+
725
+ // If this is a situation when non-escaping parameter is passed
726
+ // to the argument which represents generic parameter, there is
727
+ // a tailored diagnostic for that.
728
+
729
+ if (auto *DMT = paramInterfaceTy->getAs <DependentMemberType>()) {
730
+ diagnoseGenericParamFailure (DMT->getRootGenericParam ()->getDecl ());
731
+ return true ;
732
+ }
597
733
598
- auto *typeVar = paramType->getAs <TypeVariableType>();
599
- if (auto *GP = getGenericParamType (typeVar)) {
600
- diagnoseGenericParamFailure (GP, GP->getDecl ());
601
- return true ;
602
- }
734
+ if (auto *GP = paramInterfaceTy->getAs <GenericTypeParamType>()) {
735
+ diagnoseGenericParamFailure (GP->getDecl ());
736
+ return true ;
603
737
}
604
738
}
605
739
@@ -630,20 +764,6 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseParameterUse() const {
630
764
return true ;
631
765
}
632
766
633
- Type NoEscapeFuncToTypeConversionFailure::getParameterTypeFor (
634
- Expr *expr, unsigned paramIdx) const {
635
- auto choice = getChoiceFor (expr);
636
- if (!choice)
637
- return Type ();
638
-
639
- if (auto *fnType = choice->openedType ->getAs <FunctionType>()) {
640
- const auto ¶m = fnType->getParams ()[paramIdx];
641
- return param.getPlainType ();
642
- }
643
-
644
- return Type ();
645
- }
646
-
647
767
bool MissingForcedDowncastFailure::diagnoseAsError () {
648
768
if (hasComplexLocator ())
649
769
return false ;
@@ -779,44 +899,6 @@ bool MemberAccessOnOptionalBaseFailure::diagnoseAsError() {
779
899
resultIsOptional, SourceRange ());
780
900
}
781
901
782
- Optional<AnyFunctionType::Param>
783
- MissingOptionalUnwrapFailure::getOperatorParameterFor (Expr *expr) const {
784
- auto *parentExpr = findParentExpr (expr);
785
- if (!parentExpr)
786
- return None;
787
-
788
- auto getArgIdx = [](TupleExpr *tuple, Expr *argExpr) -> unsigned {
789
- for (unsigned i = 0 , n = tuple->getNumElements (); i != n; ++i) {
790
- if (tuple->getElement (i) == argExpr)
791
- return i;
792
- }
793
- llvm_unreachable (" argument is not in enclosing tuple?!" );
794
- };
795
-
796
- auto *tupleExpr = dyn_cast<TupleExpr>(parentExpr);
797
- if (!(tupleExpr && tupleExpr->isImplicit ()))
798
- return None;
799
-
800
- parentExpr = findParentExpr (tupleExpr);
801
- if (!(parentExpr && isa<ApplyExpr>(parentExpr)))
802
- return None;
803
-
804
- auto &cs = getConstraintSystem ();
805
- auto *fnExpr = cast<ApplyExpr>(parentExpr)->getFn ();
806
- if (auto overload =
807
- getOverloadChoiceIfAvailable (cs.getConstraintLocator (fnExpr))) {
808
- if (auto *decl = overload->choice .getDecl ()) {
809
- if (!decl->isOperator ())
810
- return None;
811
-
812
- auto *fnType = overload->openedType ->castTo <FunctionType>();
813
- return fnType->getParams ()[getArgIdx (tupleExpr, expr)];
814
- }
815
- }
816
-
817
- return None;
818
- }
819
-
820
902
void MissingOptionalUnwrapFailure::offerDefaultValueUnwrapFixIt (
821
903
DeclContext *DC, Expr *expr) const {
822
904
auto *anchor = getAnchor ();
@@ -827,10 +909,9 @@ void MissingOptionalUnwrapFailure::offerDefaultValueUnwrapFixIt(
827
909
if (isa<InOutExpr>(anchor))
828
910
return ;
829
911
830
- if (auto param = getOperatorParameterFor (anchor)) {
831
- if (param-> isInOut ())
912
+ if (auto argApplyInfo = getFunctionArgApplyInfo ( getLocator ()))
913
+ if (argApplyInfo-> getParameterFlags (). isInOut ())
832
914
return ;
833
- }
834
915
835
916
auto diag = emitDiagnostic (expr->getLoc (), diag::unwrap_with_default_value);
836
917
0 commit comments