Fix missing indexing data with overloaded type (#65729)

When you have a type that's ambiguous because it's defined in 2 imported
modules, but you don't have to disambiguate by using the module name,
previously no index references were produced. Now most are for the
common case, but notably nested type constructors and generics still
aren't emitted, partially because of https://github.com/apple/swift/issues/65726

Fixes: https://github.com/apple/swift/issues/64598
This commit is contained in:
Keith Smiley
2023-06-23 09:58:17 -07:00
committed by GitHub
parent 6607f05f53
commit e9ff334778
12 changed files with 153 additions and 11 deletions

View File

@@ -1176,6 +1176,33 @@ private:
friend class TypeRepr;
};
/// A TypeRepr for uses of 'Self' in the type of a declaration.
class SelfTypeRepr : public TypeRepr {
Type Ty;
SourceLoc Loc;
public:
SelfTypeRepr(Type Ty, SourceLoc Loc)
: TypeRepr(TypeReprKind::Self), Ty(Ty), Loc(Loc) {}
/// Retrieve the location.
SourceLoc getLoc() const { return Loc; }
/// Retrieve the fixed type.
Type getType() const { return Ty; }
static bool classof(const TypeRepr *T) {
return T->getKind() == TypeReprKind::Self;
}
static bool classof(const SelfTypeRepr *T) { return true; }
private:
SourceLoc getStartLocImpl() const { return Loc; }
SourceLoc getEndLocImpl() const { return Loc; }
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
friend class TypeRepr;
};
class SILBoxTypeReprField {
SourceLoc VarOrLetLoc;
llvm::PointerIntPair<TypeRepr*, 1, bool> FieldTypeAndMutable;
@@ -1436,6 +1463,7 @@ inline bool TypeRepr::isSimple() const {
case TypeReprKind::Pack:
case TypeReprKind::Tuple:
case TypeReprKind::Fixed:
case TypeReprKind::Self:
case TypeReprKind::Array:
case TypeReprKind::SILBox:
case TypeReprKind::Isolated:

View File

@@ -74,7 +74,8 @@ ABSTRACT_TYPEREPR(Specifier, TypeRepr)
SPECIFIER_TYPEREPR(CompileTimeConst, SpecifierTypeRepr)
TYPEREPR(Fixed, TypeRepr)
TYPEREPR(SILBox, TypeRepr)
LAST_TYPEREPR(SILBox)
TYPEREPR(Self, TypeRepr)
LAST_TYPEREPR(Self)
#undef SPECIFIER_TYPEREPR
#undef ABSTRACT_TYPEREPR

View File

@@ -3352,6 +3352,22 @@ public:
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitSelfTypeRepr(SelfTypeRepr *T) {
printCommon("type_self");
auto Ty = T->getType();
if (Ty) {
auto &srcMgr = Ty->getASTContext().SourceMgr;
if (T->getLoc().isValid()) {
OS << " location=@";
T->getLoc().print(OS, srcMgr);
} else {
OS << " location=<<invalid>>";
}
}
OS << " type="; Ty.dump(OS);
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitSILBoxTypeRepr(SILBoxTypeRepr *T) {
printCommon("sil_box");
Indent += 2;

View File

@@ -2182,6 +2182,10 @@ bool Traversal::visitFixedTypeRepr(FixedTypeRepr *T) {
return false;
}
bool Traversal::visitSelfTypeRepr(SelfTypeRepr *T) {
return false;
}
bool Traversal::visitSILBoxTypeRepr(SILBoxTypeRepr *T) {
for (auto &field : T->getFields()) {
if (doIt(field.getFieldType()))

View File

@@ -2931,6 +2931,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
case TypeReprKind::Fixed:
llvm_unreachable("Cannot get fixed TypeReprs in name lookup");
case TypeReprKind::Self:
llvm_unreachable("Cannot get fixed SelfTypeRepr in name lookup");
case TypeReprKind::Optional:
case TypeReprKind::ImplicitlyUnwrappedOptional:

View File

@@ -629,6 +629,11 @@ void FixedTypeRepr::printImpl(ASTPrinter &Printer,
getType().print(Printer, Opts);
}
void SelfTypeRepr::printImpl(ASTPrinter &Printer,
const PrintOptions &Opts) const {
getType().print(Printer, Opts);
}
void SILBoxTypeRepr::printImpl(ASTPrinter &Printer,
const PrintOptions &Opts) const {
// TODO

View File

@@ -650,15 +650,23 @@ ASTWalker::PreWalkAction SemaAnnotator::walkToTypeReprPre(TypeRepr *T) {
return Action::StopIf(!Continue);
}
} else if (auto FT = dyn_cast<FixedTypeRepr>(T)) {
ValueDecl *VD = FT->getType()->getAnyGeneric();
if (auto DT = FT->getType()->getAs<DynamicSelfType>())
if (ValueDecl *VD = FT->getType()->getAnyGeneric()) {
auto Data = ReferenceMetaData(SemaReferenceKind::TypeRef, None);
Data.isImplicitCtorType = true;
auto Continue = passReference(VD, FT->getType(), FT->getLoc(),
FT->getSourceRange(), Data);
return Action::StopIf(!Continue);
}
} else if (auto ST = dyn_cast<SelfTypeRepr>(T)) {
ValueDecl *VD = ST->getType()->getAnyGeneric();
if (auto DT = ST->getType()->getAs<DynamicSelfType>())
VD = DT->getSelfType()->getAnyGeneric();
if (VD) {
auto Data = ReferenceMetaData(SemaReferenceKind::TypeRef, None);
Data.isImplicitCtorType = true;
auto Continue = passReference(VD, FT->getType(), FT->getLoc(),
FT->getSourceRange(), Data);
auto Continue = passReference(VD, ST->getType(), ST->getLoc(),
ST->getSourceRange(), Data);
return Action::StopIf(!Continue);
}
}

View File

@@ -220,6 +220,10 @@ public:
FoundResult visitFixedTypeRepr(FixedTypeRepr *T) {
return handleParent(T, ArrayRef<TypeRepr*>());
}
FoundResult visitSelfTypeRepr(SelfTypeRepr *T) {
return handleParent(T, ArrayRef<TypeRepr*>());
}
};
struct ConversionFunctionInfo {

View File

@@ -624,11 +624,19 @@ namespace {
locator, implicit, semantics);
}
if (isa<TypeDecl>(decl) && !isa<ModuleDecl>(decl)) {
auto typeExpr = TypeExpr::createImplicitHack(
loc.getBaseNameLoc(), adjustedFullType->getMetatypeInstanceType(), ctx);
cs.cacheType(typeExpr);
return typeExpr;
if (auto *typeDecl = dyn_cast<TypeDecl>(decl)) {
if (!isa<ModuleDecl>(decl)) {
TypeExpr *typeExpr = nullptr;
if (implicit) {
typeExpr = TypeExpr::createImplicitHack(
loc.getBaseNameLoc(), adjustedFullType->getMetatypeInstanceType(), ctx);
} else {
typeExpr = TypeExpr::createForDecl(loc, typeDecl, dc);
typeExpr->setType(adjustedFullType);
}
cs.cacheType(typeExpr);
return typeExpr;
}
}
auto ref = resolveConcreteDeclRef(decl, locator);

View File

@@ -597,7 +597,7 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
if (typeContext->getSelfClassDecl())
SelfType = DynamicSelfType::get(SelfType, Context);
return new (Context)
TypeExpr(new (Context) FixedTypeRepr(SelfType, Loc));
TypeExpr(new (Context) SelfTypeRepr(SelfType, Loc));
}
}

View File

@@ -2564,6 +2564,9 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
case TypeReprKind::Fixed:
return cast<FixedTypeRepr>(repr)->getType();
case TypeReprKind::Self:
return cast<SelfTypeRepr>(repr)->getType();
}
llvm_unreachable("all cases should be handled");
}
@@ -5200,6 +5203,7 @@ public:
case TypeReprKind::ImplicitlyUnwrappedOptional:
case TypeReprKind::Tuple:
case TypeReprKind::Fixed:
case TypeReprKind::Self:
case TypeReprKind::Array:
case TypeReprKind::SILBox:
case TypeReprKind::Isolated:

View File

@@ -0,0 +1,62 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// Validate that we get index references for almost ambiguous types
// RUN: %target-swift-frontend -emit-module -o %t %t/file1.swift
// RUN: %target-swift-frontend -emit-module -o %t %t/file2.swift
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %t/file3.swift -I %t > %t/output.txt
// RUN: %FileCheck %s < %t/output.txt
//--- file1.swift
public struct Thing {
public init(string: String) {}
public struct Nested {
public init(string: String) {}
}
public struct Nested2<T> {
public init(value: T) {}
}
}
//--- file2.swift
public struct Thing {}
//--- file3.swift
import file1
import file2
func foo() {
// CHECK: 7:7 | struct/Swift | Thing | s:5file15ThingV | Ref,RelCont | rel: 1
// CHECK: 7:7 | constructor/Swift | init(string:) | s:5file15ThingV6stringACSS_tcfc | Ref,Call,RelCall,RelCont | rel: 1
_ = Thing(string: "lol")
// CHECK: 10:7 | struct/Swift | Thing | s:5file15ThingV | Ref,RelCont | rel: 1
// CHECK: 10:13 | constructor/Swift | init(string:) | s:5file15ThingV6stringACSS_tcfc | Ref,Call,RelCall,RelCont | rel: 1
_ = Thing.init(string: "lol")
// CHECK: 14:7 | struct/Swift | Thing | s:5file15ThingV | Ref,RelCont | rel: 1
// CHECK: 14:13 | struct/Swift | Nested | s:5file15ThingV6NestedV | Ref,RelCont | rel: 1
// TODO: 14:13 | constructor/Swift | init(string:)
_ = Thing.Nested(string: "lol")
// CHECK: 18:7 | struct/Swift | Thing | s:5file15ThingV | Ref,RelCont | rel: 1
// CHECK: 18:13 | struct/Swift | Nested | s:5file15ThingV6NestedV | Ref,RelCont | rel: 1
// CHECK: 18:20 | constructor/Swift | init(string:) | s:5file15ThingV6NestedV6stringAESS_tcfc | Ref,Call,RelCall,RelCont | rel: 1
_ = Thing.Nested.init(string: "lol")
// CHECK: 23:7 | struct/Swift | Thing | s:5file15ThingV | Ref,RelCont | rel: 1
// CHECK: 23:13 | struct/Swift | Nested2 | s:5file15ThingV7Nested2V | Ref,RelCont | rel: 1
// TODO: 23:13 | constructor/Swift | init(value:)
// TODO: 23:21 | struct/Swift | Int | s:Si | Ref,RelCont | rel: 1
_ = Thing.Nested2<Int>(value: 0)
// CHECK: 28:7 | struct/Swift | Thing | s:5file15ThingV | Ref,RelCont | rel: 1
// CHECK: 28:13 | struct/Swift | Nested2 | s:5file15ThingV7Nested2V | Ref,RelCont | rel: 1
// TODO: 28:21 | struct/Swift | Int | s:Si | Ref,RelCont | rel: 1
// CHECK: 28:26 | constructor/Swift | init(value:) | s:5file15ThingV7Nested2V5valueAEy_xGx_tcfc | Ref,Call,RelCall,RelCont | rel: 1
_ = Thing.Nested2<Int>.init(value: 0)
// CHECK: 34:7 | module/Swift | file1 | c:@M@file1 | Ref,RelCont | rel: 1
// CHECK: 34:13 | struct/Swift | Thing | s:5file15ThingV | Ref,RelCont | rel: 1
// CHECK: 34:19 | struct/Swift | Nested2 | s:5file15ThingV7Nested2V | Ref,RelCont | rel: 1
// CHECK: 34:19 | constructor/Swift | init(value:) | s:5file15ThingV7Nested2V5valueAEy_xGx_tcfc | Ref,Call,RelCall,RelCont | rel: 1
// CHECK: 34:27 | struct/Swift | Int | s:Si | Ref,RelCont | rel: 1
_ = file1.Thing.Nested2<Int>(value: 0)
}