Skip to content

Commit 2c06daf

Browse files
authored
Merge pull request #25874 from rintaro/5.1-ide-complete-contextype-openarchetypes-rdar51723460
[5.1][CodeCompletion] Enable 'openArchetypes' when checking if convertible
2 parents 9c07772 + 22dc8dc commit 2c06daf

File tree

8 files changed

+63
-19
lines changed

8 files changed

+63
-19
lines changed

include/swift/Sema/IDETypeChecking.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace swift {
4646
/// Check if T1 is convertible to T2.
4747
///
4848
/// \returns true on convertible, false on not.
49-
bool isConvertibleTo(Type T1, Type T2, DeclContext &DC);
49+
bool isConvertibleTo(Type T1, Type T2, bool openArchetypes, DeclContext &DC);
5050

5151
bool isEqual(Type T1, Type T2, DeclContext &DC);
5252

lib/IDE/CodeCompletion.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,12 @@ static CodeCompletionResult::ExpectedTypeRelation calculateTypeRelation(
845845
if (!Ty->hasTypeParameter() && !ExpectedTy->hasTypeParameter()) {
846846
if (Ty->isEqual(ExpectedTy))
847847
return CodeCompletionResult::ExpectedTypeRelation::Identical;
848-
if (!ExpectedTy->isAny() && isConvertibleTo(Ty, ExpectedTy, *DC))
848+
bool isAny = false;
849+
isAny |= ExpectedTy->isAny();
850+
isAny |= ExpectedTy->is<ArchetypeType>() &&
851+
!ExpectedTy->castTo<ArchetypeType>()->hasRequirements();
852+
853+
if (!isAny && isConvertibleTo(Ty, ExpectedTy, /*openArchetypes=*/true, *DC))
849854
return CodeCompletionResult::ExpectedTypeRelation::Convertible;
850855
}
851856
if (auto FT = Ty->getAs<AnyFunctionType>()) {

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -400,14 +400,19 @@ bool collectPossibleCalleesForApply(
400400
auto *fnExpr = callExpr->getFn();
401401

402402
if (auto type = fnExpr->getType()) {
403-
if (auto *funcType = type->getAs<AnyFunctionType>()) {
404-
auto refDecl = fnExpr->getReferencedDecl();
405-
if (!refDecl)
406-
if (auto apply = dyn_cast<ApplyExpr>(fnExpr))
407-
refDecl = apply->getFn()->getReferencedDecl();
408-
candidates.emplace_back(funcType, refDecl.getDecl());
409-
}
410-
} else if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
403+
if (!type->hasUnresolvedType() && !type->hasError()) {
404+
if (auto *funcType = type->getAs<AnyFunctionType>()) {
405+
auto refDecl = fnExpr->getReferencedDecl();
406+
if (!refDecl)
407+
if (auto apply = dyn_cast<ApplyExpr>(fnExpr))
408+
refDecl = apply->getFn()->getReferencedDecl();
409+
candidates.emplace_back(funcType, refDecl.getDecl());
410+
return true;
411+
}
412+
}
413+
}
414+
415+
if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
411416
if (auto *decl = DRE->getDecl()) {
412417
auto declType = decl->getInterfaceType();
413418
if (auto *funcType = declType->getAs<AnyFunctionType>())
@@ -995,7 +1000,13 @@ bool swift::ide::isReferenceableByImplicitMemberExpr(
9951000
// because we are emitting all `.init()`s.
9961001
if (declTy->isEqual(T))
9971002
return false;
998-
return swift::isConvertibleTo(declTy, T, *DC);
1003+
1004+
// Only non-protocol nominal type can be instantiated.
1005+
auto nominal = declTy->getAnyNominal();
1006+
if (!nominal || isa<ProtocolDecl>(nominal))
1007+
return false;
1008+
1009+
return swift::isConvertibleTo(declTy, T, /*openArchetypes=*/true, *DC);
9991010
}
10001011

10011012
// Only static member can be referenced.
@@ -1012,5 +1023,6 @@ bool swift::ide::isReferenceableByImplicitMemberExpr(
10121023
// FIXME: This emits just 'factory'. We should emit 'factory()' instead.
10131024
declTy = FT->getResult();
10141025
}
1015-
return declTy->isEqual(T) || swift::isConvertibleTo(declTy, T, *DC);
1026+
return declTy->isEqual(T) ||
1027+
swift::isConvertibleTo(declTy, T, /*openArchetypes=*/true, *DC);
10161028
}

lib/IDE/IDETypeChecking.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ struct SynthesizedExtensionAnalyzer::Implementation {
327327
// conformance instead of subtyping
328328
if (!canPossiblyConvertTo(First, Second, *DC))
329329
return true;
330-
else if (!isConvertibleTo(First, Second, *DC))
330+
else if (!isConvertibleTo(First, Second, /*openArchetypes=*/false,
331+
*DC))
331332
MergeInfo.addRequirement(GenericSig, First, Second, Kind);
332333
break;
333334

lib/IDE/TypeContextInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ void ContextInfoCallbacks::getImplicitMembers(
153153
// Static properties which is convertible to 'Self'.
154154
if (isa<VarDecl>(VD) && VD->isStatic()) {
155155
auto declTy = T->getTypeOfMember(CurModule, VD);
156-
if (declTy->isEqual(T) || swift::isConvertibleTo(declTy, T, *DC))
156+
if (declTy->isEqual(T) ||
157+
swift::isConvertibleTo(declTy, T, /*openArchetypes=*/true, *DC))
157158
return true;
158159
}
159160

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3718,8 +3718,9 @@ bool swift::isEqual(Type T1, Type T2, DeclContext &DC) {
37183718
return T1->isEqual(T2);
37193719
}
37203720

3721-
bool swift::isConvertibleTo(Type T1, Type T2, DeclContext &DC) {
3722-
return canSatisfy(T1, T2, false, ConstraintKind::Conversion, &DC);
3721+
bool swift::isConvertibleTo(Type T1, Type T2, bool openArchetypes,
3722+
DeclContext &DC) {
3723+
return canSatisfy(T1, T2, openArchetypes, ConstraintKind::Conversion, &DC);
37233724
}
37243725

37253726
void swift::eraseOpenedExistentials(ConstraintSystem &CS, Expr *&expr) {

test/IDE/complete_call_arg.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,8 @@ struct TestBoundGeneric1 {
464464
func test2() {
465465
takeArray(#^BOUND_GENERIC_1_2^#)
466466
}
467-
// FIXME: These should be convertible to [T]. rdar://problem/24570603
468-
// BOUND_GENERIC_1: Decl[InstanceVar]/CurrNominal: x[#[Int]#];
469-
// BOUND_GENERIC_1: Decl[InstanceVar]/CurrNominal: y[#[Int]#];
467+
// BOUND_GENERIC_1: Decl[InstanceVar]/CurrNominal/TypeRelation[Convertible]: x[#[Int]#];
468+
// BOUND_GENERIC_1: Decl[InstanceVar]/CurrNominal/TypeRelation[Convertible]: y[#[Int]#];
470469
}
471470

472471
func whereConvertible<T>(lhs: T, rhs: T) where T: Collection {

test/IDE/complete_unresolved_members.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@
107107
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_2 | %FileCheck %s -check-prefix=UNRESOLVED_3
108108
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_3 | %FileCheck %s -check-prefix=UNRESOLVED_3
109109

110+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPEPARAM_IN_CONTEXTTYPE_1 | %FileCheck %s -check-prefix=TYPEPARAM_IN_CONTEXTTYPE_1
111+
110112
enum SomeEnum1 {
111113
case South
112114
case North
@@ -692,3 +694,26 @@ class TestDefalutArg {
692694
func method(arg: SomeEnum1 = .#^DEFAULT_ARG_2^#) {}
693695
init(arg: SomeEnum1 = .#^DEFAULT_ARG_3^#) {}
694696
}
697+
698+
699+
struct ConcreteMyProtocol: MyProtocol {}
700+
struct OtherProtocol {}
701+
struct ConcreteOtherProtocol: OtherProtocol {}
702+
703+
struct MyStruct<T> {}
704+
extension MyStruct where T: MyProtocol {
705+
static var myProtocolOption: MyStruct<ConcreteMyProtocol> { fatalError() }
706+
}
707+
extension MyStruct where T: OtherProtocol {
708+
static var otherProtocolOption: MyStruct<ConcreteOtherProtocol> { fatalError() }
709+
}
710+
711+
func receiveMyStructOfMyProtocol<T: MyProtocol>(value: MyStruct<T>) {}
712+
func testTypeParamInContextType() {
713+
receiveMyStructOfMyProtocol(value: .#^TYPEPARAM_IN_CONTEXTTYPE_1^#)
714+
// TYPEPARAM_IN_CONTEXTTYPE_1: Begin completions, 2 items
715+
// TYPEPARAM_IN_CONTEXTTYPE_1-NOT: otherProtocolOption
716+
// TYPEPARAM_IN_CONTEXTTYPE_1-DAG: Decl[Constructor]/CurrNominal: init()[#MyStruct<MyProtocol>#];
717+
// TYPEPARAM_IN_CONTEXTTYPE_1-DAG: Decl[StaticVar]/CurrNominal/TypeRelation[Convertible]: myProtocolOption[#MyStruct<ConcreteMyProtocol>#];
718+
// TYPEPARAM_IN_CONTEXTTYPE_1: End completions
719+
}

0 commit comments

Comments
 (0)