mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[IDE] Simplify isImplicitSingleExpressionReturn
Use the generalized implied result logic, and rename to `isImpliedResult` since that's really what we're querying here, and it needs to handle implicit-last-exprs if enabled.
This commit is contained in:
@@ -26,7 +26,7 @@ namespace ide {
|
||||
class AfterPoundExprCompletion : public TypeCheckCompletionCallback {
|
||||
struct Result {
|
||||
Type ExpectedTy;
|
||||
bool IsImplicitSingleExpressionReturn;
|
||||
bool IsImpliedResult;
|
||||
|
||||
/// Whether the surrounding context is async and thus calling async
|
||||
/// functions is supported.
|
||||
|
||||
@@ -39,10 +39,10 @@ public:
|
||||
/// There is no known contextual type. All types are equally good.
|
||||
None,
|
||||
|
||||
/// There is a contextual type from a single-expression closure/function
|
||||
/// body. The context is a hint, and enables unresolved member completion,
|
||||
/// but should not hide any results.
|
||||
SingleExpressionBody,
|
||||
/// There is a contextual type from e.g a single-expression closure/function
|
||||
/// body, where the return is implied. The context is a hint, and enables
|
||||
/// unresolved member completion, but should not hide any results.
|
||||
Implied,
|
||||
|
||||
/// There are known contextual types, or there aren't but a nonvoid type is
|
||||
/// expected.
|
||||
|
||||
@@ -44,12 +44,12 @@ class ExpectedTypeContext {
|
||||
/// Pre typechecked type of the expression at the completion position.
|
||||
Type IdealType;
|
||||
|
||||
/// Whether the `ExpectedTypes` comes from a single-expression body, e.g.
|
||||
/// Whether the `ExpectedTypes` comes from an implied result, e.g.
|
||||
/// `foo({ here })`.
|
||||
///
|
||||
/// Since the input may be incomplete, we take into account that the types are
|
||||
/// only a hint.
|
||||
bool IsImplicitSingleExpressionReturn = false;
|
||||
bool IsImpliedResult = false;
|
||||
bool PreferNonVoid = false;
|
||||
|
||||
/// If not empty, \c PossibleTypes are ignored and types that have an
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
if (!IdealType || !Other.IdealType || !IdealType->isEqual(Other.IdealType)) {
|
||||
IdealType = Type();
|
||||
}
|
||||
IsImplicitSingleExpressionReturn |= Other.IsImplicitSingleExpressionReturn;
|
||||
IsImpliedResult |= Other.IsImpliedResult;
|
||||
PreferNonVoid &= Other.PreferNonVoid;
|
||||
ExpectedCustomAttributeKinds |= Other.ExpectedCustomAttributeKinds;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
void setIdealType(Type IdealType) { this->IdealType = IdealType; }
|
||||
|
||||
bool requiresNonVoid() const {
|
||||
if (IsImplicitSingleExpressionReturn)
|
||||
if (IsImpliedResult)
|
||||
return false;
|
||||
if (PreferNonVoid)
|
||||
return true;
|
||||
@@ -105,13 +105,12 @@ public:
|
||||
return llvm::all_of(PossibleTypes, [](Type Ty) { return !Ty->isVoid(); });
|
||||
}
|
||||
|
||||
bool isImplicitSingleExpressionReturn() const {
|
||||
return IsImplicitSingleExpressionReturn;
|
||||
bool isImpliedResult() const {
|
||||
return IsImpliedResult;
|
||||
}
|
||||
|
||||
void
|
||||
setIsImplicitSingleExpressionReturn(bool IsImplicitSingleExpressionReturn) {
|
||||
this->IsImplicitSingleExpressionReturn = IsImplicitSingleExpressionReturn;
|
||||
void setIsImpliedResult(bool IsImpliedResult) {
|
||||
this->IsImpliedResult = IsImpliedResult;
|
||||
}
|
||||
|
||||
bool getPreferNonVoid() const { return PreferNonVoid; }
|
||||
|
||||
@@ -234,11 +234,9 @@ public:
|
||||
void setIsStaticMetatype(bool value) { IsStaticMetatype = value; }
|
||||
|
||||
void setExpectedTypes(
|
||||
ArrayRef<Type> Types, bool isImplicitSingleExpressionReturn,
|
||||
bool preferNonVoid = false,
|
||||
ArrayRef<Type> Types, bool isImpliedResult, bool preferNonVoid = false,
|
||||
OptionSet<CustomAttributeKind> expectedCustomAttributeKinds = {}) {
|
||||
expectedTypeContext.setIsImplicitSingleExpressionReturn(
|
||||
isImplicitSingleExpressionReturn);
|
||||
expectedTypeContext.setIsImpliedResult(isImpliedResult);
|
||||
expectedTypeContext.setPreferNonVoid(preferNonVoid);
|
||||
expectedTypeContext.setPossibleTypes(Types);
|
||||
expectedTypeContext.setExpectedCustomAttributeKinds(
|
||||
@@ -269,8 +267,8 @@ public:
|
||||
if (expectedTypeContext.empty() &&
|
||||
!expectedTypeContext.getPreferNonVoid()) {
|
||||
return CodeCompletionContext::TypeContextKind::None;
|
||||
} else if (expectedTypeContext.isImplicitSingleExpressionReturn()) {
|
||||
return CodeCompletionContext::TypeContextKind::SingleExpressionBody;
|
||||
} else if (expectedTypeContext.isImpliedResult()) {
|
||||
return CodeCompletionContext::TypeContextKind::Implied;
|
||||
} else {
|
||||
return CodeCompletionContext::TypeContextKind::Required;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace ide {
|
||||
class ExprTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
|
||||
public:
|
||||
struct Result {
|
||||
/// If the code completion expression is an implicit return in a
|
||||
/// If the code completion expression is an implied result, e.g in a
|
||||
/// single-expression closure.
|
||||
bool IsImplicitSingleExpressionReturn;
|
||||
bool IsImpliedResult;
|
||||
|
||||
/// Whether the surrounding context is async and thus calling async
|
||||
/// functions is supported.
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
/// If \c AddUnresolvedMemberCompletions is false, the
|
||||
/// \p UnresolvedMemberBaseType is ignored.
|
||||
void addResult(
|
||||
bool IsImplicitSingleExpressionReturn, bool IsInAsyncContext,
|
||||
bool IsImpliedResult, bool IsInAsyncContext,
|
||||
Type UnresolvedMemberBaseType,
|
||||
llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes);
|
||||
|
||||
|
||||
@@ -50,12 +50,12 @@ class PostfixCompletionCallback : public TypeCheckCompletionCallback {
|
||||
/// we know that we can't retrieve a value from it anymore.
|
||||
bool ExpectsNonVoid;
|
||||
|
||||
/// If the code completion expression occurs as a single statement in a
|
||||
/// single-expression closure. In such cases we don't want to disfavor
|
||||
/// results that produce 'Void' because the user might intend to make the
|
||||
/// closure a multi-statment closure, in which case this expression is no
|
||||
/// longer implicitly returned.
|
||||
bool IsImplicitSingleExpressionReturn;
|
||||
/// If the code completion expression occurs as e.g a single statement in a
|
||||
/// single-expression closure, where the return is implied. In such cases
|
||||
/// we don't want to disfavor results that produce 'Void' because the user
|
||||
/// might intend to make the closure a multi-statment closure, in which case
|
||||
/// this expression is no longer implicitly returned.
|
||||
bool IsImpliedResult;
|
||||
|
||||
/// Whether the surrounding context is async and thus calling async
|
||||
/// functions is supported.
|
||||
|
||||
@@ -119,8 +119,9 @@ private:
|
||||
static void setInterfaceType(VarDecl *VD, Type Ty);
|
||||
};
|
||||
|
||||
/// Whether the given completion expression is the only expression in its
|
||||
/// containing closure or function body and its value is implicitly returned.
|
||||
/// Whether the given completion expression is an implied result of a closure
|
||||
/// or function (e.g in a single-expression closure where the return is
|
||||
/// implicit).
|
||||
///
|
||||
/// If these conditions are met, code completion needs to avoid penalizing
|
||||
/// completion results that don't match the expected return type when
|
||||
@@ -128,8 +129,7 @@ private:
|
||||
/// written by the user, it's possible they intend the single expression not
|
||||
/// as the return value but merely the first entry in a multi-statement body
|
||||
/// they just haven't finished writing yet.
|
||||
bool isImplicitSingleExpressionReturn(constraints::ConstraintSystem &CS,
|
||||
Expr *CompletionExpr);
|
||||
bool isImpliedResult(const constraints::Solution &S, Expr *CompletionExpr);
|
||||
|
||||
/// Returns \c true iff the decl context \p DC allows calling async functions.
|
||||
bool isContextAsync(const constraints::Solution &S, DeclContext *DC);
|
||||
|
||||
@@ -27,7 +27,7 @@ class UnresolvedMemberTypeCheckCompletionCallback
|
||||
: public TypeCheckCompletionCallback {
|
||||
struct Result {
|
||||
Type ExpectedTy;
|
||||
bool IsImplicitSingleExpressionReturn;
|
||||
bool IsImpliedResult;
|
||||
|
||||
/// Whether the surrounding context is async and thus calling async
|
||||
/// functions is supported.
|
||||
|
||||
@@ -22,7 +22,6 @@ using namespace swift::constraints;
|
||||
using namespace swift::ide;
|
||||
|
||||
void AfterPoundExprCompletion::sawSolutionImpl(const constraints::Solution &S) {
|
||||
auto &CS = S.getConstraintSystem();
|
||||
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
|
||||
|
||||
bool IsAsync = isContextAsync(S, DC);
|
||||
@@ -32,8 +31,8 @@ void AfterPoundExprCompletion::sawSolutionImpl(const constraints::Solution &S) {
|
||||
return R.ExpectedTy->isEqual(ExpectedTy);
|
||||
};
|
||||
if (!llvm::any_of(Results, IsEqual)) {
|
||||
bool SingleExprBody = isImplicitSingleExpressionReturn(CS, CompletionExpr);
|
||||
Results.push_back({ExpectedTy, SingleExprBody, IsAsync});
|
||||
bool IsImpliedResult = isImpliedResult(S, CompletionExpr);
|
||||
Results.push_back({ExpectedTy, IsImpliedResult, IsAsync});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +49,7 @@ void AfterPoundExprCompletion::collectResults(
|
||||
UnifiedTypeContext.setPreferNonVoid(true);
|
||||
|
||||
for (auto &Result : Results) {
|
||||
Lookup.setExpectedTypes({Result.ExpectedTy},
|
||||
Result.IsImplicitSingleExpressionReturn,
|
||||
Lookup.setExpectedTypes({Result.ExpectedTy}, Result.IsImpliedResult,
|
||||
/*expectsNonVoid=*/true);
|
||||
Lookup.addPoundAvailable(ParentStmtKind);
|
||||
Lookup.addObjCPoundKeywordCompletions(/*needPound=*/false);
|
||||
|
||||
@@ -346,8 +346,7 @@ void ArgumentTypeCheckCompletionCallback::collectResults(
|
||||
for (auto &Result : Results) {
|
||||
if (Result.IncludeSignature) {
|
||||
Lookup.setHaveLParen(true);
|
||||
Lookup.setExpectedTypes(ExpectedCallTypes,
|
||||
/*isImplicitSingleExpressionReturn=*/false);
|
||||
Lookup.setExpectedTypes(ExpectedCallTypes, /*isImpliedResult=*/false);
|
||||
|
||||
auto SemanticContext = SemanticContextKind::None;
|
||||
NominalTypeDecl *BaseNominal = nullptr;
|
||||
|
||||
@@ -1834,8 +1834,7 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
|
||||
ExpectedCustomAttributeKinds |= CustomAttributeKind::DeclMacro;
|
||||
}
|
||||
|
||||
Lookup.setExpectedTypes(/*Types=*/{},
|
||||
/*isImplicitSingleExpressionReturn=*/false,
|
||||
Lookup.setExpectedTypes(/*Types=*/{}, /*isImpliedResult=*/false,
|
||||
/*preferNonVoid=*/false,
|
||||
ExpectedCustomAttributeKinds);
|
||||
|
||||
|
||||
@@ -428,8 +428,9 @@ calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
|
||||
|
||||
auto Result = TypeRelation::Unrelated;
|
||||
for (auto expectedTy : typeContext.getPossibleTypes()) {
|
||||
// Do not use Void type context for a single-expression body, since the
|
||||
// implicit return does not constrain the expression.
|
||||
// Do not use Void type context for an implied result such as a
|
||||
// single-expression closure body, since the implicit return does not
|
||||
// constrain the expression.
|
||||
//
|
||||
// { ... -> () in x } // x can be anything
|
||||
//
|
||||
@@ -437,16 +438,15 @@ calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
|
||||
//
|
||||
// { ... -> Int in x } // x must be Int
|
||||
// { ... -> () in return x } // x must be Void
|
||||
if (typeContext.isImplicitSingleExpressionReturn() && expectedTy->isVoid())
|
||||
if (typeContext.isImpliedResult() && expectedTy->isVoid())
|
||||
continue;
|
||||
|
||||
Result = std::max(Result, calculateTypeRelation(Ty, expectedTy, DC));
|
||||
}
|
||||
|
||||
// Map invalid -> unrelated when in a single-expression body, since the
|
||||
// input may be incomplete.
|
||||
if (typeContext.isImplicitSingleExpressionReturn() &&
|
||||
Result == TypeRelation::Invalid)
|
||||
// Map invalid -> unrelated for an implied result, since the input may be
|
||||
// incomplete.
|
||||
if (typeContext.isImpliedResult() && Result == TypeRelation::Invalid)
|
||||
Result = TypeRelation::Unrelated;
|
||||
|
||||
return Result;
|
||||
|
||||
@@ -39,8 +39,7 @@ static bool solutionSpecificVarTypesEqual(
|
||||
|
||||
bool ExprTypeCheckCompletionCallback::Result::operator==(
|
||||
const Result &Other) const {
|
||||
return IsImplicitSingleExpressionReturn ==
|
||||
Other.IsImplicitSingleExpressionReturn &&
|
||||
return IsImpliedResult == Other.IsImpliedResult &&
|
||||
IsInAsyncContext == Other.IsInAsyncContext &&
|
||||
nullableTypesEqual(UnresolvedMemberBaseType,
|
||||
Other.UnresolvedMemberBaseType) &&
|
||||
@@ -59,13 +58,12 @@ void ExprTypeCheckCompletionCallback::addExpectedType(Type ExpectedType) {
|
||||
}
|
||||
|
||||
void ExprTypeCheckCompletionCallback::addResult(
|
||||
bool IsImplicitSingleExpressionReturn, bool IsInAsyncContext,
|
||||
Type UnresolvedMemberBaseType,
|
||||
bool IsImpliedResult, bool IsInAsyncContext, Type UnresolvedMemberBaseType,
|
||||
llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes) {
|
||||
if (!AddUnresolvedMemberCompletions) {
|
||||
UnresolvedMemberBaseType = Type();
|
||||
}
|
||||
Result NewResult = {IsImplicitSingleExpressionReturn, IsInAsyncContext,
|
||||
Result NewResult = {IsImpliedResult, IsInAsyncContext,
|
||||
UnresolvedMemberBaseType, SolutionSpecificVarTypes};
|
||||
if (llvm::is_contained(Results, NewResult)) {
|
||||
return;
|
||||
@@ -75,22 +73,18 @@ void ExprTypeCheckCompletionCallback::addResult(
|
||||
|
||||
void ExprTypeCheckCompletionCallback::sawSolutionImpl(
|
||||
const constraints::Solution &S) {
|
||||
auto &CS = S.getConstraintSystem();
|
||||
|
||||
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
|
||||
|
||||
bool ImplicitReturn = isImplicitSingleExpressionReturn(CS, CompletionExpr);
|
||||
|
||||
bool IsImpliedResult = isImpliedResult(S, CompletionExpr);
|
||||
bool IsAsync = isContextAsync(S, DC);
|
||||
|
||||
llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes;
|
||||
getSolutionSpecificVarTypes(S, SolutionSpecificVarTypes);
|
||||
|
||||
addResult(ImplicitReturn, IsAsync, ExpectedTy, SolutionSpecificVarTypes);
|
||||
addResult(IsImpliedResult, IsAsync, ExpectedTy, SolutionSpecificVarTypes);
|
||||
addExpectedType(ExpectedTy);
|
||||
|
||||
if (auto PatternMatchType = getPatternMatchType(S, CompletionExpr)) {
|
||||
addResult(ImplicitReturn, IsAsync, PatternMatchType,
|
||||
addResult(IsImpliedResult, IsAsync, PatternMatchType,
|
||||
SolutionSpecificVarTypes);
|
||||
addExpectedType(PatternMatchType);
|
||||
}
|
||||
@@ -111,8 +105,7 @@ void ExprTypeCheckCompletionCallback::collectResults(
|
||||
for (auto &Result : Results) {
|
||||
WithSolutionSpecificVarTypesRAII VarTypes(Result.SolutionSpecificVarTypes);
|
||||
|
||||
Lookup.setExpectedTypes(ExpectedTypes,
|
||||
Result.IsImplicitSingleExpressionReturn);
|
||||
Lookup.setExpectedTypes(ExpectedTypes, Result.IsImpliedResult);
|
||||
Lookup.setCanCurrDeclContextHandleAsync(Result.IsInAsyncContext);
|
||||
Lookup.setSolutionSpecificVarTypes(Result.SolutionSpecificVarTypes);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ void PostfixCompletionCallback::Result::merge(const Result &Other,
|
||||
ExpectedTypes.push_back(OtherExpectedTy);
|
||||
}
|
||||
ExpectsNonVoid &= Other.ExpectsNonVoid;
|
||||
IsImplicitSingleExpressionReturn |= Other.IsImplicitSingleExpressionReturn;
|
||||
IsImpliedResult |= Other.IsImpliedResult;
|
||||
IsInAsyncContext |= Other.IsInAsyncContext;
|
||||
}
|
||||
|
||||
@@ -213,8 +213,7 @@ void PostfixCompletionCallback::sawSolutionImpl(
|
||||
}
|
||||
}
|
||||
|
||||
bool IsImplicitSingleExpressionReturn =
|
||||
isImplicitSingleExpressionReturn(CS, CompletionExpr);
|
||||
bool IsImpliedResult = isImpliedResult(S, CompletionExpr);
|
||||
|
||||
bool IsInAsyncContext = isContextAsync(S, DC);
|
||||
llvm::DenseMap<AbstractClosureExpr *, ActorIsolation>
|
||||
@@ -232,7 +231,7 @@ void PostfixCompletionCallback::sawSolutionImpl(
|
||||
BaseIsStaticMetaType,
|
||||
ExpectedTypes,
|
||||
ExpectsNonVoid,
|
||||
IsImplicitSingleExpressionReturn,
|
||||
IsImpliedResult,
|
||||
IsInAsyncContext,
|
||||
ClosureActorIsolations
|
||||
};
|
||||
@@ -448,8 +447,7 @@ void PostfixCompletionCallback::collectResults(
|
||||
if (!ProcessedBaseTypes.contains(Result.BaseTy)) {
|
||||
Lookup.getPostfixKeywordCompletions(Result.BaseTy, BaseExpr);
|
||||
}
|
||||
Lookup.setExpectedTypes(Result.ExpectedTypes,
|
||||
Result.IsImplicitSingleExpressionReturn,
|
||||
Lookup.setExpectedTypes(Result.ExpectedTypes, Result.IsImpliedResult,
|
||||
Result.ExpectsNonVoid);
|
||||
if (isDynamicLookup(Result.BaseTy))
|
||||
Lookup.setIsDynamicLookup();
|
||||
|
||||
@@ -155,20 +155,12 @@ void WithSolutionSpecificVarTypesRAII::setInterfaceType(VarDecl *VD, Type Ty) {
|
||||
std::move(Ty));
|
||||
}
|
||||
|
||||
bool swift::ide::isImplicitSingleExpressionReturn(ConstraintSystem &CS,
|
||||
Expr *CompletionExpr) {
|
||||
Expr *ParentExpr = CS.getParentExpr(CompletionExpr);
|
||||
if (!ParentExpr)
|
||||
return CS.getContextualTypePurpose(CompletionExpr) == CTP_ImpliedReturnStmt;
|
||||
bool swift::ide::isImpliedResult(const Solution &S, Expr *CompletionExpr) {
|
||||
auto &CS = S.getConstraintSystem();
|
||||
if (CS.getContextualTypePurpose(CompletionExpr) == CTP_ImpliedReturnStmt)
|
||||
return true;
|
||||
|
||||
if (auto *ParentCE = dyn_cast<ClosureExpr>(ParentExpr)) {
|
||||
if (ParentCE->hasSingleExpressionBody() &&
|
||||
ParentCE->getSingleExpressionBody() == CompletionExpr) {
|
||||
ASTNode Last = ParentCE->getBody()->getLastElement();
|
||||
return !Last.isStmt(StmtKind::Return) || Last.isImplicit();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return S.isImpliedResult(CompletionExpr).has_value();
|
||||
}
|
||||
|
||||
bool swift::ide::isContextAsync(const constraints::Solution &S,
|
||||
|
||||
@@ -43,7 +43,7 @@ void UnresolvedMemberTypeCheckCompletionCallback::Result::merge(
|
||||
ExpectedTy = Other.ExpectedTy;
|
||||
}
|
||||
|
||||
IsImplicitSingleExpressionReturn |= Other.IsImplicitSingleExpressionReturn;
|
||||
IsImpliedResult |= Other.IsImpliedResult;
|
||||
IsInAsyncContext |= Other.IsInAsyncContext;
|
||||
}
|
||||
|
||||
@@ -62,17 +62,15 @@ void UnresolvedMemberTypeCheckCompletionCallback::addExprResult(
|
||||
|
||||
void UnresolvedMemberTypeCheckCompletionCallback::sawSolutionImpl(
|
||||
const constraints::Solution &S) {
|
||||
auto &CS = S.getConstraintSystem();
|
||||
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
|
||||
|
||||
bool IsAsync = isContextAsync(S, DC);
|
||||
|
||||
// If the type couldn't be determined (e.g. because there isn't any context
|
||||
// to derive it from), let's not attempt to do a lookup since it wouldn't
|
||||
// produce any useful results anyway.
|
||||
if (ExpectedTy) {
|
||||
bool SingleExprBody = isImplicitSingleExpressionReturn(CS, CompletionExpr);
|
||||
Result Res = {ExpectedTy, SingleExprBody, IsAsync};
|
||||
bool IsImpliedResult = isImpliedResult(S, CompletionExpr);
|
||||
Result Res = {ExpectedTy, IsImpliedResult, IsAsync};
|
||||
addExprResult(Res);
|
||||
}
|
||||
|
||||
@@ -81,9 +79,8 @@ void UnresolvedMemberTypeCheckCompletionCallback::sawSolutionImpl(
|
||||
return R.ExpectedTy->isEqual(PatternType);
|
||||
};
|
||||
if (!llvm::any_of(EnumPatternTypes, IsEqual)) {
|
||||
EnumPatternTypes.push_back({PatternType,
|
||||
/*IsImplicitSingleExpressionReturn=*/false,
|
||||
IsAsync});
|
||||
EnumPatternTypes.push_back(
|
||||
{PatternType, /*isImpliedResult=*/false, IsAsync});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,8 +103,7 @@ void UnresolvedMemberTypeCheckCompletionCallback::collectResults(
|
||||
originalTypes.insert(Result.ExpectedTy->getCanonicalType());
|
||||
|
||||
for (auto &Result : ExprResults) {
|
||||
Lookup.setExpectedTypes({Result.ExpectedTy},
|
||||
Result.IsImplicitSingleExpressionReturn,
|
||||
Lookup.setExpectedTypes({Result.ExpectedTy}, Result.IsImpliedResult,
|
||||
/*expectsNonVoid*/ true);
|
||||
Lookup.setIdealExpectedType(Result.ExpectedTy);
|
||||
Lookup.setCanCurrDeclContextHandleAsync(Result.IsInAsyncContext);
|
||||
@@ -133,7 +129,7 @@ void UnresolvedMemberTypeCheckCompletionCallback::collectResults(
|
||||
// EnumElementPattern.
|
||||
for (auto &Result : EnumPatternTypes) {
|
||||
Type Ty = Result.ExpectedTy;
|
||||
Lookup.setExpectedTypes({Ty}, /*IsImplicitSingleExpressionReturn=*/false,
|
||||
Lookup.setExpectedTypes({Ty}, /*isImpliedResult=*/false,
|
||||
/*expectsNonVoid=*/true);
|
||||
Lookup.setIdealExpectedType(Ty);
|
||||
Lookup.setCanCurrDeclContextHandleAsync(Result.IsInAsyncContext);
|
||||
|
||||
Reference in New Issue
Block a user