@@ -47,22 +47,8 @@ bool ArgumentTypeCheckCompletionCallback::addPossibleParams(
47
47
break ;
48
48
}
49
49
50
- // We work with the parameter from the function type and the declaration
51
- // because they contain different information that we need.
52
- //
53
- // Since not all function types are backed by declarations (e.g. closure
54
- // paramters), `DeclParam` might be `nullptr`.
55
50
const AnyFunctionType::Param *TypeParam = &ParamsToPass[Idx];
56
- const ParamDecl *DeclParam = getParameterAt (Res.FuncDeclRef , Idx);
57
-
58
- bool Required = true ;
59
- if (DeclParam && DeclParam->isDefaultArgument ()) {
60
- Required = false ;
61
- } else if (DeclParam && DeclParam->getType ()->is <PackExpansionType>()) {
62
- Required = false ;
63
- } else if (TypeParam->isVariadic ()) {
64
- Required = false ;
65
- }
51
+ bool Required = !Res.DeclParamIsOptional [Idx];
66
52
67
53
if (TypeParam->hasLabel () && !(IsCompletion && Res.IsNoninitialVariadic )) {
68
54
// Suggest parameter label if parameter has label, we are completing in it
@@ -222,7 +208,7 @@ void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
222
208
223
209
// If this is a duplicate of any other result, ignore this solution.
224
210
if (llvm::any_of (Results, [&](const Result &R) {
225
- return R.FuncDeclRef == Info.ValueRef &&
211
+ return R.FuncD == Info.getValue () &&
226
212
nullableTypesEqual (R.FuncTy , Info.ValueTy ) &&
227
213
nullableTypesEqual (R.BaseType , Info.BaseTy ) &&
228
214
R.ParamIdx == ParamIdx &&
@@ -238,11 +224,34 @@ void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
238
224
if (Info.ValueTy ) {
239
225
FuncTy = Info.ValueTy ->lookThroughAllOptionalTypes ()->getAs <AnyFunctionType>();
240
226
}
227
+
228
+ // Determine which parameters is optional. We need to do this in
229
+ // `sawSolutionImpl` because it accesses the substitution map in
230
+ // `Info.ValueRef`. This substitution map might contain tyep variables that
231
+ // are allocated in the constraint system's arena and are freed once we reach
232
+ // `deliverResults`.
233
+ std::vector<bool > DeclParamIsOptional;
234
+ if (FuncTy) {
235
+ ArrayRef<AnyFunctionType::Param> ParamsToPass = FuncTy->getParams ();
236
+ for (auto Idx : range (0 , ParamsToPass.size ())) {
237
+ bool Optional = false ;
238
+ if (Info.ValueRef ) {
239
+ if (const ParamDecl *DeclParam = getParameterAt (Info.ValueRef , Idx)) {
240
+ Optional |= DeclParam->isDefaultArgument ();
241
+ Optional |= DeclParam->getType ()->is <PackExpansionType>();
242
+ }
243
+ }
244
+ const AnyFunctionType::Param *TypeParam = &ParamsToPass[Idx];
245
+ Optional |= TypeParam->isVariadic ();
246
+ DeclParamIsOptional.push_back (Optional);
247
+ }
248
+ }
249
+
241
250
Results.push_back ({ExpectedTy, ExpectedCallType,
242
- isa<SubscriptExpr>(ParentCall), Info.ValueRef , FuncTy,
251
+ isa<SubscriptExpr>(ParentCall), Info.getValue () , FuncTy,
243
252
ArgIdx, ParamIdx, std::move (ClaimedParams),
244
253
IsNoninitialVariadic, Info.BaseTy , HasLabel, IsAsync,
245
- SolutionSpecificVarTypes});
254
+ DeclParamIsOptional, SolutionSpecificVarTypes});
246
255
}
247
256
248
257
void ArgumentTypeCheckCompletionCallback::computeShadowedDecls (
@@ -251,25 +260,25 @@ void ArgumentTypeCheckCompletionCallback::computeShadowedDecls(
251
260
auto &ResultA = Results[i];
252
261
for (size_t j = i + 1 ; j < Results.size (); ++j) {
253
262
auto &ResultB = Results[j];
254
- if (!ResultA.getFuncD () || !ResultB.getFuncD () || !ResultA.FuncTy ||
263
+ if (!ResultA.FuncD || !ResultB.FuncD || !ResultA.FuncTy ||
255
264
!ResultB.FuncTy ) {
256
265
continue ;
257
266
}
258
- if (ResultA.getFuncD () ->getName () != ResultB.getFuncD () ->getName ()) {
267
+ if (ResultA.FuncD ->getName () != ResultB.FuncD ->getName ()) {
259
268
continue ;
260
269
}
261
270
if (!ResultA.FuncTy ->isEqual (ResultB.FuncTy )) {
262
271
continue ;
263
272
}
264
273
ProtocolDecl *inProtocolExtensionA =
265
- ResultA.getFuncD () ->getDeclContext ()->getExtendedProtocolDecl ();
274
+ ResultA.FuncD ->getDeclContext ()->getExtendedProtocolDecl ();
266
275
ProtocolDecl *inProtocolExtensionB =
267
- ResultB.getFuncD () ->getDeclContext ()->getExtendedProtocolDecl ();
276
+ ResultB.FuncD ->getDeclContext ()->getExtendedProtocolDecl ();
268
277
269
278
if (inProtocolExtensionA && !inProtocolExtensionB) {
270
- ShadowedDecls.insert (ResultA.getFuncD () );
279
+ ShadowedDecls.insert (ResultA.FuncD );
271
280
} else if (!inProtocolExtensionA && inProtocolExtensionB) {
272
- ShadowedDecls.insert (ResultB.getFuncD () );
281
+ ShadowedDecls.insert (ResultB.FuncD );
273
282
}
274
283
}
275
284
}
@@ -310,37 +319,35 @@ void ArgumentTypeCheckCompletionCallback::deliverResults(
310
319
}
311
320
if ((BaseNominal = BaseTy->getAnyNominal ())) {
312
321
SemanticContext = SemanticContextKind::CurrentNominal;
313
- if (Result.getFuncD () &&
314
- Result.getFuncD () ->getDeclContext ()->getSelfNominalTypeDecl () !=
322
+ if (Result.FuncD &&
323
+ Result.FuncD ->getDeclContext ()->getSelfNominalTypeDecl () !=
315
324
BaseNominal) {
316
325
SemanticContext = SemanticContextKind::Super;
317
326
}
318
327
} else if (BaseTy->is <TupleType>() || BaseTy->is <SubstitutableType>()) {
319
328
SemanticContext = SemanticContextKind::CurrentNominal;
320
329
}
321
330
}
322
- if (SemanticContext == SemanticContextKind::None && Result.getFuncD () ) {
323
- if (Result.getFuncD () ->getDeclContext ()->isTypeContext ()) {
331
+ if (SemanticContext == SemanticContextKind::None && Result.FuncD ) {
332
+ if (Result.FuncD ->getDeclContext ()->isTypeContext ()) {
324
333
SemanticContext = SemanticContextKind::CurrentNominal;
325
- } else if (Result.getFuncD () ->getDeclContext ()->isLocalContext ()) {
334
+ } else if (Result.FuncD ->getDeclContext ()->isLocalContext ()) {
326
335
SemanticContext = SemanticContextKind::Local;
327
- } else if (Result.getFuncD ()->getModuleContext () ==
328
- DC->getParentModule ()) {
336
+ } else if (Result.FuncD ->getModuleContext () == DC->getParentModule ()) {
329
337
SemanticContext = SemanticContextKind::CurrentModule;
330
338
}
331
339
}
332
340
if (Result.FuncTy ) {
333
341
if (auto FuncTy = Result.FuncTy ) {
334
- if (ShadowedDecls.count (Result.getFuncD () ) == 0 ) {
342
+ if (ShadowedDecls.count (Result.FuncD ) == 0 ) {
335
343
// Don't show call pattern completions if the function is
336
344
// overridden.
337
345
if (Result.IsSubscript ) {
338
346
assert (SemanticContext != SemanticContextKind::None);
339
- auto *SD = dyn_cast_or_null<SubscriptDecl>(Result.getFuncD () );
347
+ auto *SD = dyn_cast_or_null<SubscriptDecl>(Result.FuncD );
340
348
Lookup.addSubscriptCallPattern (FuncTy, SD, SemanticContext);
341
349
} else {
342
- auto *FD =
343
- dyn_cast_or_null<AbstractFunctionDecl>(Result.getFuncD ());
350
+ auto *FD = dyn_cast_or_null<AbstractFunctionDecl>(Result.FuncD );
344
351
Lookup.addFunctionCallPattern (FuncTy, FD, SemanticContext);
345
352
}
346
353
}
0 commit comments