Skip to content

Commit 038c4f3

Browse files
authored
Merge pull request #25872 from rintaro/ide-complete-contextype-openarchetypes-rdar51723460
[CodeCompletion] Enable 'openArchetypes' when checking if convertible
2 parents a0052c9 + 4d076e8 commit 038c4f3

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
@@ -353,14 +353,19 @@ static bool collectPossibleCalleesForApply(
353353
auto *fnExpr = callExpr->getFn();
354354

355355
if (auto type = fnExpr->getType()) {
356-
if (auto *funcType = type->getAs<AnyFunctionType>()) {
357-
auto refDecl = fnExpr->getReferencedDecl();
358-
if (!refDecl)
359-
if (auto apply = dyn_cast<ApplyExpr>(fnExpr))
360-
refDecl = apply->getFn()->getReferencedDecl();
361-
candidates.emplace_back(funcType, refDecl.getDecl());
362-
}
363-
} else if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
356+
if (!type->hasUnresolvedType() && !type->hasError()) {
357+
if (auto *funcType = type->getAs<AnyFunctionType>()) {
358+
auto refDecl = fnExpr->getReferencedDecl();
359+
if (!refDecl)
360+
if (auto apply = dyn_cast<ApplyExpr>(fnExpr))
361+
refDecl = apply->getFn()->getReferencedDecl();
362+
candidates.emplace_back(funcType, refDecl.getDecl());
363+
return true;
364+
}
365+
}
366+
}
367+
368+
if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
364369
if (auto *decl = DRE->getDecl()) {
365370
auto declType = decl->getInterfaceType();
366371
if (auto *funcType = declType->getAs<AnyFunctionType>())
@@ -918,7 +923,13 @@ bool swift::ide::isReferenceableByImplicitMemberExpr(
918923
// because we are emitting all `.init()`s.
919924
if (declTy->isEqual(T))
920925
return false;
921-
return swift::isConvertibleTo(declTy, T, *DC);
926+
927+
// Only non-protocol nominal type can be instantiated.
928+
auto nominal = declTy->getAnyNominal();
929+
if (!nominal || isa<ProtocolDecl>(nominal))
930+
return false;
931+
932+
return swift::isConvertibleTo(declTy, T, /*openArchetypes=*/true, *DC);
922933
}
923934

924935
// Only static member can be referenced.
@@ -935,5 +946,6 @@ bool swift::ide::isReferenceableByImplicitMemberExpr(
935946
// FIXME: This emits just 'factory'. We should emit 'factory()' instead.
936947
declTy = FT->getResult();
937948
}
938-
return declTy->isEqual(T) || swift::isConvertibleTo(declTy, T, *DC);
949+
return declTy->isEqual(T) ||
950+
swift::isConvertibleTo(declTy, T, /*openArchetypes=*/true, *DC);
939951
}

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
@@ -3829,8 +3829,9 @@ bool swift::isEqual(Type T1, Type T2, DeclContext &DC) {
38293829
return T1->isEqual(T2);
38303830
}
38313831

3832-
bool swift::isConvertibleTo(Type T1, Type T2, DeclContext &DC) {
3833-
return canSatisfy(T1, T2, false, ConstraintKind::Conversion, &DC);
3832+
bool swift::isConvertibleTo(Type T1, Type T2, bool openArchetypes,
3833+
DeclContext &DC) {
3834+
return canSatisfy(T1, T2, openArchetypes, ConstraintKind::Conversion, &DC);
38343835
}
38353836

38363837
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)