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