[Module-scope lookup] Only inject macro-introduced operators at module scope

Well, this is fun. Due to the use of the module-scope lookup table to
find operators, we need to carefully filter out any macro-introduced
declarations that *aren't* operators when forming the module-scope
lookup table. Otherwise, we can find macro-introduced static entities
within types... from completely unrelated scopes.

Fixes rdar://109219036.
This commit is contained in:
Doug Gregor
2023-06-02 23:46:26 -07:00
parent 19ca63ac3a
commit ebe0b63c5e
3 changed files with 69 additions and 0 deletions

View File

@@ -403,6 +403,13 @@ void SourceLookupCache::populateAuxiliaryDeclCache() {
for (auto macroNames : introducedNames) {
auto macroRef = macroNames.getFirst();
for (auto name : macroNames.getSecond()) {
// If this macro isn't in a module-scope context, and the introduced
// name isn't an operator, we shouldn't be able to see it.
if (!decl->getDeclContext()->isModuleScopeContext() &&
!name.getBaseName().isOperator())
continue;
auto *placeholder = MissingDecl::forUnexpandedMacro(macroRef, decl);
name.addToLookupTable(TopLevelAuxiliaryDecls, placeholder);
}
@@ -485,6 +492,12 @@ void SourceLookupCache::lookupValue(DeclName Name, NLKind LookupKind,
for (auto *unexpandedDecl : unexpandedDecls) {
unexpandedDecl->forEachMacroExpandedDecl(
[&](ValueDecl *decl) {
// If the declaration is not a module-scope declaration, and
// isn't an operator, ignore it.
if (!decl->getDeclContext()->isModuleScopeContext() &&
!decl->getName().getBaseName().isOperator())
return;
if (decl->getName().matchesRef(Name)) {
if (macroExpandedDecls.insert(decl).second)
Result.push_back(decl);