@@ -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;
@@ -4340,6 +4342,16 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
43404342 if (!T->mayHaveMembers ())
43414343 return ;
43424344
4345+ if (auto objT = T->getOptionalObjectType ()) {
4346+ // Add 'nil' keyword with erasing '.' instruction.
4347+ unsigned bytesToErase = 0 ;
4348+ auto &SM = CurrDeclContext->getASTContext ().SourceMgr ;
4349+ if (DotLoc.isValid ())
4350+ bytesToErase = SM.getByteDistance (DotLoc, SM.getCodeCompletionLoc ());
4351+ addKeyword (" nil" , T, SemanticContextKind::None,
4352+ CodeCompletionKeywordKind::kw_nil, bytesToErase);
4353+ }
4354+
43434355 // We can only say .foo where foo is a static member of the contextual
43444356 // type and has the same type (or if the member is a function, then the
43454357 // same result type) as the contextual type.
@@ -4378,14 +4390,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
43784390 objT = objT->lookThroughAllOptionalTypes ();
43794391 if (seenTypes.insert (objT->getCanonicalType ()).second )
43804392 getUnresolvedMemberCompletions (objT);
4381-
4382- // Add 'nil' keyword with erasing '.' instruction.
4383- unsigned bytesToErase = 0 ;
4384- auto &SM = CurrDeclContext->getASTContext ().SourceMgr ;
4385- if (DotLoc.isValid ())
4386- bytesToErase = SM.getByteDistance (DotLoc, SM.getCodeCompletionLoc ());
4387- addKeyword (" nil" , T, SemanticContextKind::None,
4388- CodeCompletionKeywordKind::kw_nil, bytesToErase);
43894393 }
43904394 getUnresolvedMemberCompletions (T);
43914395 }
@@ -6083,6 +6087,45 @@ static void deliverCompletionResults(CodeCompletionContext &CompletionContext,
60836087 DCForModules);
60846088}
60856089
6090+ void deliverUnresolvedMemberResults (
6091+ ArrayRef<UnresolvedMemberTypeCheckCompletionCallback::Result> Results,
6092+ DeclContext *DC, SourceLoc DotLoc,
6093+ ide::CodeCompletionContext &CompletionCtx,
6094+ CodeCompletionConsumer &Consumer) {
6095+ ASTContext &Ctx = DC->getASTContext ();
6096+ CompletionLookup Lookup (CompletionCtx.getResultSink (), Ctx, DC,
6097+ &CompletionCtx);
6098+
6099+ assert (DotLoc.isValid ());
6100+ Lookup.setHaveDot (DotLoc);
6101+ Lookup.shouldCheckForDuplicates (Results.size () > 1 );
6102+
6103+ // Get the canonical versions of the top-level types
6104+ SmallPtrSet<CanType, 4 > originalTypes;
6105+ for (auto &Result: Results)
6106+ originalTypes.insert (Result.ExpectedTy ->getCanonicalType ());
6107+
6108+ for (auto &Result: Results) {
6109+ Lookup.setExpectedTypes ({Result.ExpectedTy },
6110+ Result.IsImplicitSingleExpressionReturn ,
6111+ /* expectsNonVoid*/ true );
6112+ Lookup.setIdealExpectedType (Result.ExpectedTy );
6113+
6114+ // For optional types, also get members of the unwrapped type if it's not
6115+ // already equivalent to one of the top-level types. Handling it via the top
6116+ // level type and not here ensures we give the correct type relation
6117+ // (identical, rather than convertible).
6118+ if (Result.ExpectedTy ->getOptionalObjectType ()) {
6119+ Type Unwrapped = Result.ExpectedTy ->lookThroughAllOptionalTypes ();
6120+ if (originalTypes.insert (Unwrapped->getCanonicalType ()).second )
6121+ Lookup.getUnresolvedMemberCompletions (Unwrapped);
6122+ }
6123+ Lookup.getUnresolvedMemberCompletions (Result.ExpectedTy );
6124+ }
6125+ SourceFile *SF = DC->getParentSourceFile ();
6126+ deliverCompletionResults (CompletionCtx, Lookup, *SF, Consumer);
6127+ }
6128+
60866129void deliverDotExprResults (
60876130 ArrayRef<DotExprTypeCheckCompletionCallback::Result> Results,
60886131 Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc, bool IsInSelector,
@@ -6113,7 +6156,7 @@ void deliverDotExprResults(
61136156 Lookup.setIsStaticMetatype (Result.BaseIsStaticMetaType );
61146157 Lookup.getPostfixKeywordCompletions (Result.BaseTy , BaseExpr);
61156158 Lookup.setExpectedTypes (Result.ExpectedTypes ,
6116- Result.IsSingleExpressionBody ,
6159+ Result.IsImplicitSingleExpressionReturn ,
61176160 Result.ExpectsNonVoid );
61186161 if (isDynamicLookup (Result.BaseTy ))
61196162 Lookup.setIsDynamicLookup ();
@@ -6158,6 +6201,23 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
61586201 Consumer);
61596202 return true ;
61606203 }
6204+ case CompletionKind::UnresolvedMember: {
6205+ assert (CodeCompleteTokenExpr);
6206+ assert (CurDeclContext);
6207+
6208+ UnresolvedMemberTypeCheckCompletionCallback Lookup (CodeCompleteTokenExpr);
6209+ llvm::SaveAndRestore<TypeCheckCompletionCallback*>
6210+ CompletionCollector (Context.CompletionCallback , &Lookup);
6211+ typeCheckContextAt (CurDeclContext, CompletionLoc);
6212+
6213+ if (!Lookup.gotCallback ())
6214+ Lookup.fallbackTypeCheck (CurDeclContext);
6215+
6216+ addKeywords (CompletionContext.getResultSink (), MaybeFuncBody);
6217+ deliverUnresolvedMemberResults (Lookup.getResults (), CurDeclContext, DotLoc,
6218+ CompletionContext, Consumer);
6219+ return true ;
6220+ }
61616221 default :
61626222 return false ;
61636223 }
@@ -6277,6 +6337,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
62776337 switch (Kind) {
62786338 case CompletionKind::None:
62796339 case CompletionKind::DotExpr:
6340+ case CompletionKind::UnresolvedMember:
62806341 llvm_unreachable (" should be already handled" );
62816342 return ;
62826343
@@ -6336,7 +6397,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
63366397 case CompletionKind::PostfixExprBeginning: {
63376398 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
63386399 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6339- ContextInfo.isSingleExpressionBody ());
6400+ ContextInfo.isImplicitSingleExpressionReturn ());
63406401 DoPostfixExprBeginning ();
63416402 break ;
63426403 }
@@ -6358,8 +6419,9 @@ void CodeCompletionCallbacksImpl::doneParsing() {
63586419
63596420 if (ShouldCompleteCallPatternAfterParen) {
63606421 ExprContextInfo ParentContextInfo (CurDeclContext, ParsedExpr);
6361- Lookup.setExpectedTypes (ParentContextInfo.getPossibleTypes (),
6362- ParentContextInfo.isSingleExpressionBody ());
6422+ Lookup.setExpectedTypes (
6423+ ParentContextInfo.getPossibleTypes (),
6424+ ParentContextInfo.isImplicitSingleExpressionReturn ());
63636425 if (!ContextInfo.getPossibleCallees ().empty ()) {
63646426 for (auto &typeAndDecl : ContextInfo.getPossibleCallees ())
63656427 Lookup.tryFunctionCallCompletions (typeAndDecl.Type , typeAndDecl.Decl ,
@@ -6377,7 +6439,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
63776439 (Lookup.FoundFunctionCalls &&
63786440 Lookup.FoundFunctionsWithoutFirstKeyword )) {
63796441 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6380- ContextInfo.isSingleExpressionBody ());
6442+ ContextInfo.isImplicitSingleExpressionReturn ());
63816443 Lookup.setHaveLParen (false );
63826444 DoPostfixExprBeginning ();
63836445 }
@@ -6426,7 +6488,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
64266488 case CompletionKind::CaseStmtBeginning: {
64276489 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
64286490 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6429- ContextInfo.isSingleExpressionBody ());
6491+ ContextInfo.isImplicitSingleExpressionReturn ());
64306492 Lookup.setIdealExpectedType (CodeCompleteTokenExpr->getType ());
64316493 Lookup.getUnresolvedMemberCompletions (ContextInfo.getPossibleTypes ());
64326494 DoPostfixExprBeginning ();
@@ -6445,7 +6507,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
64456507 if (isa<AccessorDecl>(ParsedDecl)) {
64466508 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
64476509 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6448- ContextInfo.isSingleExpressionBody ());
6510+ ContextInfo.isImplicitSingleExpressionReturn ());
64496511 DoPostfixExprBeginning ();
64506512 }
64516513 break ;
@@ -6478,15 +6540,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
64786540 Lookup.addImportModuleNames ();
64796541 break ;
64806542 }
6481- case CompletionKind::UnresolvedMember: {
6482- Lookup.setHaveDot (DotLoc);
6483- ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6484- Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6485- ContextInfo.isSingleExpressionBody ());
6486- Lookup.setIdealExpectedType (CodeCompleteTokenExpr->getType ());
6487- Lookup.getUnresolvedMemberCompletions (ContextInfo.getPossibleTypes ());
6488- break ;
6489- }
64906543 case CompletionKind::CallArg: {
64916544 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
64926545
@@ -6528,7 +6581,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
65286581
65296582 if (shouldPerformGlobalCompletion) {
65306583 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6531- ContextInfo.isSingleExpressionBody ());
6584+ ContextInfo.isImplicitSingleExpressionReturn ());
65326585 DoPostfixExprBeginning ();
65336586 }
65346587 break ;
@@ -6647,7 +6700,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
66476700 SmallVector<Type, 2 > possibleReturnTypes;
66486701 collectPossibleReturnTypesFromContext (CurDeclContext, possibleReturnTypes);
66496702 Lookup.setExpectedTypes (possibleReturnTypes,
6650- /* isSingleExpressionBody */ false );
6703+ /* isImplicitSingleExpressionReturn */ false );
66516704 Lookup.getValueCompletionsInDeclContext (Loc);
66526705 break ;
66536706 }
@@ -6658,7 +6711,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
66586711 if (FD->isCoroutine ()) {
66596712 // TODO: handle multi-value yields.
66606713 Lookup.setExpectedTypes (FD->getStorage ()->getValueInterfaceType (),
6661- /* isSingleExpressionBody */ false );
6714+ /* isImplicitSingleExpressionReturn */ false );
66626715 }
66636716 }
66646717 Lookup.getValueCompletionsInDeclContext (Loc);
@@ -6668,7 +6721,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
66686721 case CompletionKind::AfterPoundExpr: {
66696722 ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
66706723 Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6671- ContextInfo.isSingleExpressionBody ());
6724+ ContextInfo.isImplicitSingleExpressionReturn ());
66726725
66736726 Lookup.addPoundAvailable (ParentStmtKind);
66746727 Lookup.addPoundLiteralCompletions (/* needPound=*/ false );
0 commit comments