Skip to content

Commit 7061a20

Browse files
committed
[CS] Remove ConstraintSystem::getVarType
The logic here for completion wasn't actually helping things since it would result in adding the var overload to the system, which would result in an ErrorType binding. We could turn the ErrorType into a placeholder when resolving the overload, but the simpler solution is to just allow CSGen to turn the reference into a PlaceholderType. This matches what we do for regular solving, and fixes a crash with an IUO completion. rdar://89369091
1 parent 43839ac commit 7061a20

File tree

6 files changed

+37
-27
lines changed

6 files changed

+37
-27
lines changed

lib/IDE/TypeCheckCompletionCallback.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,10 @@ Type swift::ide::getPatternMatchType(const constraints::Solution &S, Expr *E) {
134134
// not part of the solution.
135135
// TODO: This can be removed once ExprPattern type-checking is fully part
136136
// of the constraint system.
137-
if (auto T = S.getConstraintSystem().getVarType(MatchVar))
138-
return T;
139-
140-
return getTypeForCompletion(S, MatchVar);
137+
auto Ty = MatchVar->getTypeInContext();
138+
if (Ty->hasError())
139+
return Type();
140+
return Ty;
141141
}
142142

143143
void swift::ide::getSolutionSpecificVarTypes(

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,7 @@ namespace {
15301530
if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
15311531
knownType = CS.getTypeIfAvailable(VD);
15321532
if (!knownType)
1533-
knownType = CS.getVarType(VD);
1533+
knownType = VD->getTypeInContext();
15341534

15351535
if (knownType) {
15361536
// An out-of-scope type variable(s) could appear the type of
@@ -2420,7 +2420,7 @@ namespace {
24202420

24212421
Type externalType;
24222422
if (param->getTypeRepr()) {
2423-
auto declaredTy = CS.getVarType(param);
2423+
auto declaredTy = param->getTypeInContext();
24242424

24252425
// If closure parameter couldn't be resolved, let's record
24262426
// a fix to make sure that type resolution diagnosed the
@@ -4899,7 +4899,7 @@ bool ConstraintSystem::generateConstraints(
48994899

49004900
case SyntacticElementTarget::Kind::uninitializedVar: {
49014901
if (auto *wrappedVar = target.getAsUninitializedWrappedVar()) {
4902-
auto propertyType = getVarType(wrappedVar);
4902+
auto propertyType = wrappedVar->getTypeInContext();
49034903
if (propertyType->hasError())
49044904
return true;
49054905

lib/Sema/ConstraintSystem.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4853,24 +4853,6 @@ void ConstraintSystem::removeFixedRequirement(GenericTypeParamType *GP,
48534853
ASSERT(erased);
48544854
}
48554855

4856-
// Replace any error types encountered with placeholders.
4857-
Type ConstraintSystem::getVarType(const VarDecl *var) {
4858-
auto type = var->getTypeInContext();
4859-
4860-
// If this declaration is used as part of a code completion
4861-
// expression, solver needs to glance over the fact that
4862-
// it might be invalid to avoid failing constraint generation
4863-
// and produce completion results.
4864-
if (!isForCodeCompletion())
4865-
return type;
4866-
4867-
return type.transformRec([&](Type type) -> std::optional<Type> {
4868-
if (!type->is<ErrorType>())
4869-
return std::nullopt;
4870-
return Type(PlaceholderType::get(Context, const_cast<VarDecl *>(var)));
4871-
});
4872-
}
4873-
48744856
bool ConstraintSystem::isReadOnlyKeyPathComponent(
48754857
const AbstractStorageDecl *storage, SourceLoc referenceLoc) {
48764858
// See whether key paths can store to this component. (Key paths don't

test/IDE/complete_enum_elements.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ enum FooEnum: CaseIterable {
3434
// FOO_ENUM_DOT-DAG: Decl[TypeAlias]/CurrNominal: AllCases[#[FooEnum]#]{{; name=.+$}}
3535
// FOO_ENUM_DOT-DAG: Decl[StaticVar]/CurrNominal: allCases[#[FooEnum]#]{{; name=.+$}}
3636

37+
// FOO_ENUM_DOT_INVALID-DAG: Keyword[self]/CurrNominal: self[#FooEnum.Type#]; name=self
38+
// FOO_ENUM_DOT_INVALID-DAG: Keyword/CurrNominal: Type[#FooEnum.Type#]; name=Type
39+
// FOO_ENUM_DOT_INVALID-DAG: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
40+
// FOO_ENUM_DOT_INVALID-DAG: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
41+
// FOO_ENUM_DOT_INVALID-DAG: Decl[StaticVar]/CurrNominal: alias1[#FooEnum#]{{; name=.+$}}
42+
// FOO_ENUM_DOT_INVALID-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: hash({#(self): FooEnum#})[#(into: inout Hasher) -> Void#]{{; name=.+$}}
43+
// FOO_ENUM_DOT_INVALID-DAG: Decl[TypeAlias]/CurrNominal: AllCases[#[FooEnum]#]{{; name=.+$}}
44+
// FOO_ENUM_DOT_INVALID-DAG: Decl[StaticVar]/CurrNominal: allCases[#[FooEnum]#]{{; name=.+$}}
45+
3746
// FOO_ENUM_DOT_CONTEXT-DAG: Keyword[self]/CurrNominal: self[#FooEnum.Type#]; name=self
3847
// FOO_ENUM_DOT_CONTEXT-DAG: Keyword/CurrNominal: Type[#FooEnum.Type#]; name=Type
3948
// FOO_ENUM_DOT_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/TypeRelation[Convertible]: Foo1[#FooEnum#]{{; name=.+$}}
@@ -256,7 +265,7 @@ func testSwitchWithQualification1(e: FooEnum) {
256265

257266
func testSwitchExprError1() {
258267
switch unknown_var {
259-
case FooEnum.#^ENUM_SW_EXPR_ERROR_1?check=FOO_ENUM_DOT^#
268+
case FooEnum.#^ENUM_SW_EXPR_ERROR_1?check=FOO_ENUM_DOT_INVALID^#
260269
}
261270
}
262271

test/SourceKit/CodeComplete/complete_literals.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,20 @@ func foo(_ x: Int) {
4343
}
4444

4545
// RUN: %complete-test -tok=EXPR1 %s -raw | %FileCheck %s -check-prefix=LITERALS
46-
// RUN: %complete-test -tok=EXPR2 %s -raw | %FileCheck %s -check-prefix=LITERALS
46+
// RUN: %complete-test -tok=EXPR2 %s -raw | %FileCheck %s -check-prefix=LITERALS_PLUS
47+
// RUN: %complete-test -tok=EXPR2 %s -raw | %FileCheck %s -check-prefix=LITERALS_PLUS_NOT
4748
let x1 = #^EXPR1^#
4849
x1 + #^EXPR2^#
50+
// LITERALS_PLUS: key.kind: source.lang.swift.literal.integer
51+
// LITERALS_PLUS: key.kind: source.lang.swift.literal.string
52+
// LITERALS_PLUS: key.sourcetext: "\"<#{{.*}}#>\""
53+
// LITERALS_PLUS: key.kind: source.lang.swift.literal.array
54+
// LITERALS_PLUS: key.sourcetext: "[<#{{.*}}#>]"
55+
56+
// LITERALS_PLUS_NOT-NOT: key.kind: source.lang.swift.literal.boolean
57+
// LITERALS_PLUS_NOT-NOT: key.kind: source.lang.swift.literal.dictionary
58+
// LITERALS_PLUS_NOT-NOT: key.kind: source.lang.swift.literal.tuple
59+
// LITERALS_PLUS_NOT-NOT: key.kind: source.lang.swift.literal.nil
4960

5061
// RUN: %complete-test -tok=EXPR3 %s -raw | %FileCheck %s -check-prefix=LITERAL_BOOL
5162
if #^EXPR3^# { }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %swift-ide-test -code-completion -code-completion-token COMPLETE -source-filename %s
2+
3+
// https://github.com/swiftlang/swift/issues/77335
4+
// Make sure we don't crash
5+
6+
func foo(_ x: X!) {
7+
x.#^COMPLETE^#
8+
}

0 commit comments

Comments
 (0)