mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Try to bind extensions without expanding macros
Macro expansion can call typeCheckExpr(), which performs qualified lookups. So if we expand macros while binding extensions, these qualified lookups can fail because they cannot find members of extensions that have not been bound yet. To fix this, try binding extensions without performing macro expansion first. If any extensions remain at the end, we fall back to the old behavior, and try to bind them again, this time performing macro expansion. Fixes rdar://149798059.
This commit is contained in:
@@ -191,12 +191,14 @@ ModuleDecl *TypeChecker::getStdlibModule(const DeclContext *dc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void swift::bindExtensions(ModuleDecl &mod) {
|
void swift::bindExtensions(ModuleDecl &mod) {
|
||||||
|
bool excludeMacroExpansions = true;
|
||||||
|
|
||||||
// Utility function to try and resolve the extended type without diagnosing.
|
// Utility function to try and resolve the extended type without diagnosing.
|
||||||
// If we succeed, we go ahead and bind the extension. Otherwise, return false.
|
// If we succeed, we go ahead and bind the extension. Otherwise, return false.
|
||||||
auto tryBindExtension = [&](ExtensionDecl *ext) -> bool {
|
auto tryBindExtension = [&](ExtensionDecl *ext) -> bool {
|
||||||
assert(!ext->canNeverBeBound() &&
|
assert(!ext->canNeverBeBound() &&
|
||||||
"Only extensions that can ever be bound get here.");
|
"Only extensions that can ever be bound get here.");
|
||||||
if (auto nominal = ext->computeExtendedNominal()) {
|
if (auto nominal = ext->computeExtendedNominal(excludeMacroExpansions)) {
|
||||||
nominal->addExtension(ext);
|
nominal->addExtension(ext);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -228,6 +230,7 @@ void swift::bindExtensions(ModuleDecl &mod) {
|
|||||||
visitTopLevelDecl(D);
|
visitTopLevelDecl(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto tryBindExtensions = [&]() {
|
||||||
// Phase 2 - repeatedly go through the worklist and attempt to bind each
|
// Phase 2 - repeatedly go through the worklist and attempt to bind each
|
||||||
// extension there, removing it from the worklist if we succeed.
|
// extension there, removing it from the worklist if we succeed.
|
||||||
bool changed;
|
bool changed;
|
||||||
@@ -241,6 +244,13 @@ void swift::bindExtensions(ModuleDecl &mod) {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
} while(changed);
|
} while(changed);
|
||||||
|
};
|
||||||
|
|
||||||
|
tryBindExtensions();
|
||||||
|
|
||||||
|
// If that fails, try again, but this time expand macros.
|
||||||
|
excludeMacroExpansions = false;
|
||||||
|
tryBindExtensions();
|
||||||
|
|
||||||
// Any remaining extensions are invalid. They will be diagnosed later by
|
// Any remaining extensions are invalid. They will be diagnosed later by
|
||||||
// typeCheckDecl().
|
// typeCheckDecl().
|
||||||
|
|||||||
Reference in New Issue
Block a user