Emit refs to collections initialized with a type shorthand expression.

Normally references to initializers of collections like Array and Dict are emitted into the index data. It was missing any initializer called using the collection's literal type resentation instead of the type name.

For example:

```
_ = Array<Int>(repeating: 0, count: 1)  // Reference is emitted.
_ = [Int](repeating: 0, count: 1) // Reference is missing.
```

This PR fixes the inconsistency by emitting references for those collection intializers.

fixes #68974
This commit is contained in:
Dylan Sturgeon
2024-10-31 11:08:20 -07:00
parent 0d16cbf5d5
commit b59eb14c25
2 changed files with 71 additions and 0 deletions

View File

@@ -678,6 +678,35 @@ private:
return true;
}
/// Indexes refs to initializers of collections when initialized from a short
/// hand version of the collection's type.
///
/// For example, emits refs for `[Int](repeating:count:)`.
void handleCollectionShortHandTypeInitRefs(Expr *E) {
auto *ctorRef = dyn_cast<ConstructorRefCallExpr>(E);
if (!ctorRef)
return;
auto TE = dyn_cast<TypeExpr>(ctorRef->getBase());
if (!TE || TE->isImplicit())
return;
auto TR = TE->getTypeRepr();
if (TR && !isa<ArrayTypeRepr>(TR) && !isa<DictionaryTypeRepr>(TR))
return;
auto DRE = dyn_cast<DeclRefExpr>(ctorRef->getFn());
if (!DRE)
return;
auto decl = DRE->getDecl();
if (!shouldIndex(decl, /*IsRef=*/true))
return;
IndexSymbol Info;
if (initIndexSymbol(decl, ctorRef->getSourceRange().Start, /*IsRef=*/true,
Info))
return;
if (startEntity(decl, Info, /*IsRef=*/true))
finishCurrentEntity();
}
void handleMemberwiseInitRefs(Expr *E) {
if (!isa<ApplyExpr>(E))
return;
@@ -744,6 +773,7 @@ private:
ExprStack.push_back(E);
Containers.activateContainersFor(E);
handleMemberwiseInitRefs(E);
handleCollectionShortHandTypeInitRefs(E);
return true;
}