@@ -1171,14 +1171,14 @@ calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
11711171 //
11721172 // { ... -> Int in x } // x must be Int
11731173 // { ... -> () in return x } // x must be Void
1174- if (typeContext.isSingleExpressionBody && expectedTy->isVoid ())
1174+ if (typeContext.isImplicitSingleExpressionReturn && expectedTy->isVoid ())
11751175 continue ;
11761176
11771177 Result = std::max (Result, calculateTypeRelation (Ty, expectedTy, DC));
11781178
11791179 // Map invalid -> unrelated when in a single-expression body, since the
11801180 // input may be incomplete.
1181- if (typeContext.isSingleExpressionBody &&
1181+ if (typeContext.isImplicitSingleExpressionReturn &&
11821182 Result == CodeCompletionResult::ExpectedTypeRelation::Invalid)
11831183 Result = CodeCompletionResult::ExpectedTypeRelation::Unrelated;
11841184 }
@@ -1958,9 +1958,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
19581958 IsStaticMetatype = value;
19591959 }
19601960
1961- void setExpectedTypes (ArrayRef<Type> Types, bool isSingleExpressionBody,
1961+ void setExpectedTypes (ArrayRef<Type> Types,
1962+ bool isImplicitSingleExpressionReturn,
19621963 bool preferNonVoid = false ) {
1963- expectedTypeContext.isSingleExpressionBody = isSingleExpressionBody;
1964+ expectedTypeContext.isImplicitSingleExpressionReturn =
1965+ isImplicitSingleExpressionReturn;
19641966 expectedTypeContext.preferNonVoid = preferNonVoid;
19651967 expectedTypeContext.possibleTypes .clear ();
19661968 expectedTypeContext.possibleTypes .reserve (Types.size ());
@@ -1976,7 +1978,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
19761978 CodeCompletionContext::TypeContextKind typeContextKind () const {
19771979 if (expectedTypeContext.empty () && !expectedTypeContext.preferNonVoid ) {
19781980 return CodeCompletionContext::TypeContextKind::None;
1979- } else if (expectedTypeContext.isSingleExpressionBody ) {
1981+ } else if (expectedTypeContext.isImplicitSingleExpressionReturn ) {
19801982 return CodeCompletionContext::TypeContextKind::SingleExpressionBody;
19811983 } else {
19821984 return CodeCompletionContext::TypeContextKind::Required;
@@ -4346,6 +4348,16 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
43464348 if (!T->mayHaveMembers ())
43474349 return ;
43484350
4351+ if (auto objT = T->getOptionalObjectType ()) {
4352+ // Add 'nil' keyword with erasing '.' instruction.
4353+ unsigned bytesToErase = 0 ;
4354+ auto &SM = CurrDeclContext->getASTContext ().SourceMgr ;
4355+ if (DotLoc.isValid ())
4356+ bytesToErase = SM.getByteDistance (DotLoc, SM.getCodeCompletionLoc ());
4357+ addKeyword (" nil" , T, SemanticContextKind::None,
4358+ CodeCompletionKeywordKind::kw_nil, bytesToErase);
4359+ }
4360+
43494361 // We can only say .foo where foo is a static member of the contextual
43504362 // type and has the same type (or if the member is a function, then the
43514363 // same result type) as the contextual type.
@@ -4384,14 +4396,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
43844396 objT = objT->lookThroughAllOptionalTypes ();
43854397 if (seenTypes.insert (objT->getCanonicalType ()).second )
43864398 getUnresolvedMemberCompletions (objT);
4387-
4388- // Add 'nil' keyword with erasing '.' instruction.
4389- unsigned bytesToErase = 0 ;
4390- auto &SM = CurrDeclContext->getASTContext ().SourceMgr ;
4391- if (DotLoc.isValid ())
4392- bytesToErase = SM.getByteDistance (DotLoc, SM.getCodeCompletionLoc ());
4393- addKeyword (" nil" , T, SemanticContextKind::None,
4394- CodeCompletionKeywordKind::kw_nil, bytesToErase);
43954399 }
43964400 getUnresolvedMemberCompletions (T);
43974401 }
@@ -6089,6 +6093,45 @@ static void deliverCompletionResults(CodeCompletionContext &CompletionContext,
60896093 DCForModules);
60906094}
60916095
6096+ void deliverUnresolvedMemberResults (
6097+ ArrayRef<UnresolvedMemberTypeCheckCompletionCallback::Result> Results,
6098+ DeclContext *DC, SourceLoc DotLoc,
6099+ ide::CodeCompletionContext &CompletionCtx,
6100+ CodeCompletionConsumer &Consumer) {
6101+ ASTContext &Ctx = DC->getASTContext ();
6102+ CompletionLookup Lookup (CompletionCtx.getResultSink (), Ctx, DC,
6103+ &CompletionCtx);
6104+
6105+ assert (DotLoc.isValid ());
6106+ Lookup.setHaveDot (DotLoc);
6107+ Lookup.shouldCheckForDuplicates (Results.size () > 1 );
6108+
6109+ // Get the canonical versions of the top-level types
6110+ SmallPtrSet<CanType, 4 > originalTypes;
6111+ for (auto &Result: Results)
6112+ originalTypes.insert (Result.ExpectedTy ->getCanonicalType ());
6113+
6114+ for (auto &Result: Results) {
6115+ Lookup.setExpectedTypes ({Result.ExpectedTy },
6116+ Result.IsImplicitSingleExpressionReturn ,
6117+ /* expectsNonVoid*/ true );
6118+ Lookup.setIdealExpectedType (Result.ExpectedTy );
6119+
6120+ // For optional types, also get members of the unwrapped type if it's not
6121+ // already equivalent to one of the top-level types. Handling it via the top
6122+ // level type and not here ensures we give the correct type relation
6123+ // (identical, rather than convertible).
6124+ if (Result.ExpectedTy ->getOptionalObjectType ()) {
6125+ Type Unwrapped = Result.ExpectedTy ->lookThroughAllOptionalTypes ();
6126+ if (originalTypes.insert (Unwrapped->getCanonicalType ()).second )
6127+ Lookup.getUnresolvedMemberCompletions (Unwrapped);
6128+ }
6129+ Lookup.getUnresolvedMemberCompletions (Result.ExpectedTy );
6130+ }
6131+ SourceFile *SF = DC->getParentSourceFile ();
6132+ deliverCompletionResults (CompletionCtx, Lookup, *SF, Consumer);
6133+ }
6134+
60926135void deliverDotExprResults (
60936136 ArrayRef<DotExprTypeCheckCompletionCallback::Result> Results,
60946137 Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc, bool IsInSelector,
@@ -6119,7 +6162,7 @@ void deliverDotExprResults(
61196162 Lookup.setIsStaticMetatype (Result.BaseIsStaticMetaType );
61206163 Lookup.getPostfixKeywordCompletions (Result.BaseTy , BaseExpr);
61216164 Lookup.setExpectedTypes (Result.ExpectedTypes ,
6122- Result.IsSingleExpressionBody ,
6165+ Result.IsImplicitSingleExpressionReturn ,
61236166 Result.ExpectsNonVoid );
61246167 if (isDynamicLookup (Result.BaseTy ))
61256168 Lookup.setIsDynamicLookup ();
@@ -6164,6 +6207,23 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
61646207 Consumer);
61656208 return true ;
61666209 }
6210+ case CompletionKind::UnresolvedMember: {
6211+ assert (CodeCompleteTokenExpr);
6212+ assert (CurDeclContext);
6213+
6214+ UnresolvedMemberTypeCheckCompletionCallback Lookup (CodeCompleteTokenExpr);
6215+ llvm::SaveAndRestore<TypeCheckCompletionCallback*>
6216+ CompletionCollector (Context.CompletionCallback , &Lookup);
6217+ typeCheckContextAt (CurDeclContext, CompletionLoc);
6218+
6219+ if (!Lookup.gotCallback ())
6220+ Lookup.fallbackTypeCheck (CurDeclContext);
6221+
6222+ addKeywords (CompletionContext.getResultSink (), MaybeFuncBody);
6223+ deliverUnresolvedMemberResults (Lookup.getResults (), CurDeclContext, DotLoc,
6224+ CompletionContext, Consumer);
6225+ return true ;
6226+ }
61676227 default :
61686228 return false ;
61696229 }
@@ -6283,6 +6343,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
62836343 switch (Kind) {
62846344 case CompletionKind::None:
62856345 case CompletionKind::DotExpr:
6346+ case CompletionKind::UnresolvedMember:
62866347 llvm_unreachable (" should be already handled" );
62876348 return ;
62886349
@@ -6342,7 +6403,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
63426403 case CompletionKind::PostfixExprBeginning: {
63436404 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
63446405 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6345- ContextInfo.isSingleExpressionBody ());
6406+ ContextInfo.isImplicitSingleExpressionReturn ());
63466407 DoPostfixExprBeginning ();
63476408 break ;
63486409 }
@@ -6364,8 +6425,9 @@ void CodeCompletionCallbacksImpl::doneParsing() {
63646425
63656426 if (ShouldCompleteCallPatternAfterParen) {
63666427 ExprContextInfo ParentContextInfo (CurDeclContext, ParsedExpr);
6367- Lookup.setExpectedTypes (ParentContextInfo.getPossibleTypes (),
6368- ParentContextInfo.isSingleExpressionBody ());
6428+ Lookup.setExpectedTypes (
6429+ ParentContextInfo.getPossibleTypes (),
6430+ ParentContextInfo.isImplicitSingleExpressionReturn ());
63696431 if (!ContextInfo.getPossibleCallees ().empty ()) {
63706432 for (auto &typeAndDecl : ContextInfo.getPossibleCallees ())
63716433 Lookup.tryFunctionCallCompletions (typeAndDecl.Type , typeAndDecl.Decl ,
@@ -6383,7 +6445,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
63836445 (Lookup.FoundFunctionCalls &&
63846446 Lookup.FoundFunctionsWithoutFirstKeyword )) {
63856447 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6386- ContextInfo.isSingleExpressionBody ());
6448+ ContextInfo.isImplicitSingleExpressionReturn ());
63876449 Lookup.setHaveLParen (false );
63886450 DoPostfixExprBeginning ();
63896451 }
@@ -6432,7 +6494,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
64326494 case CompletionKind::CaseStmtBeginning: {
64336495 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
64346496 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6435- ContextInfo.isSingleExpressionBody ());
6497+ ContextInfo.isImplicitSingleExpressionReturn ());
64366498 Lookup.setIdealExpectedType (CodeCompleteTokenExpr->getType ());
64376499 Lookup.getUnresolvedMemberCompletions (ContextInfo.getPossibleTypes ());
64386500 DoPostfixExprBeginning ();
@@ -6451,7 +6513,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
64516513 if (isa<AccessorDecl>(ParsedDecl)) {
64526514 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
64536515 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6454- ContextInfo.isSingleExpressionBody ());
6516+ ContextInfo.isImplicitSingleExpressionReturn ());
64556517 DoPostfixExprBeginning ();
64566518 }
64576519 break ;
@@ -6484,15 +6546,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
64846546 Lookup.addImportModuleNames ();
64856547 break ;
64866548 }
6487- case CompletionKind::UnresolvedMember: {
6488- Lookup.setHaveDot (DotLoc);
6489- ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6490- Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6491- ContextInfo.isSingleExpressionBody ());
6492- Lookup.setIdealExpectedType (CodeCompleteTokenExpr->getType ());
6493- Lookup.getUnresolvedMemberCompletions (ContextInfo.getPossibleTypes ());
6494- break ;
6495- }
64966549 case CompletionKind::CallArg: {
64976550 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
64986551
@@ -6534,7 +6587,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
65346587
65356588 if (shouldPerformGlobalCompletion) {
65366589 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6537- ContextInfo.isSingleExpressionBody ());
6590+ ContextInfo.isImplicitSingleExpressionReturn ());
65386591 DoPostfixExprBeginning ();
65396592 }
65406593 break ;
@@ -6653,7 +6706,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
66536706 SmallVector<Type, 2 > possibleReturnTypes;
66546707 collectPossibleReturnTypesFromContext (CurDeclContext, possibleReturnTypes);
66556708 Lookup.setExpectedTypes (possibleReturnTypes,
6656- /* isSingleExpressionBody */ false );
6709+ /* isImplicitSingleExpressionReturn */ false );
66576710 Lookup.getValueCompletionsInDeclContext (Loc);
66586711 break ;
66596712 }
@@ -6664,7 +6717,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
66646717 if (FD->isCoroutine ()) {
66656718 // TODO: handle multi-value yields.
66666719 Lookup.setExpectedTypes (FD->getStorage ()->getValueInterfaceType (),
6667- /* isSingleExpressionBody */ false );
6720+ /* isImplicitSingleExpressionReturn */ false );
66686721 }
66696722 }
66706723 Lookup.getValueCompletionsInDeclContext (Loc);
@@ -6674,7 +6727,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
66746727 case CompletionKind::AfterPoundExpr: {
66756728 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
66766729 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6677- ContextInfo.isSingleExpressionBody ());
6730+ ContextInfo.isImplicitSingleExpressionReturn ());
66786731
66796732 Lookup.addPoundAvailable (ParentStmtKind);
66806733 Lookup.addPoundLiteralCompletions (/* needPound=*/ false );
0 commit comments