[Macros] Always parse macro expansions, diagnose later

Always parse macro expansions, regardless of language mode, and
eliminate the fallback path for very, very, very old object literals
like `#Color`. Instead, check for the feature flag for macro
declaration and at macro expansion time, since this is a semantic
restriction.

While here, refactor things so the vast majority of the macro-handling
logic still applies even if the Swift Swift parser is disabled. Only
attempts to expand the macro will fail. This allows us to enable the
macro-diagnostics test everywhere.
This commit is contained in:
Doug Gregor
2022-12-23 23:22:21 -08:00
parent 71ca9c86e6
commit 6bb9cb8b5d
20 changed files with 105 additions and 217 deletions

View File

@@ -3779,67 +3779,62 @@ namespace {
}
Type visitMacroExpansionExpr(MacroExpansionExpr *expr) {
#if SWIFT_SWIFT_PARSER
auto &ctx = CS.getASTContext();
if (ctx.LangOpts.hasFeature(Feature::Macros)) {
auto locator = CS.getConstraintLocator(expr);
auto locator = CS.getConstraintLocator(expr);
// For calls, set up the argument list.
bool isCall = expr->getArgs() != nullptr;
if (isCall) {
CS.associateArgumentList(locator, expr->getArgs());
}
// Look up the macros with this name.
auto macroIdent = expr->getMacroName().getBaseIdentifier();
FunctionRefKind functionRefKind = isCall ? FunctionRefKind::SingleApply
: FunctionRefKind::Unapplied;
auto macros = lookupMacros(
macroIdent, expr->getMacroNameLoc().getBaseNameLoc(),
functionRefKind);
if (macros.empty()) {
ctx.Diags.diagnose(expr->getMacroNameLoc(), diag::macro_undefined,
macroIdent)
.highlight(expr->getMacroNameLoc().getSourceRange());
return Type();
}
// Introduce an overload set for the macro reference.
auto macroRefType = Type(CS.createTypeVariable(locator, 0));
CS.addOverloadSet(macroRefType, macros, CurDC, locator);
// Add explicit generic arguments, if there were any.
if (expr->getGenericArgsRange().isValid()) {
if (addSpecializationConstraint(
CS.getConstraintLocator(expr), macroRefType,
expr->getGenericArgs()))
return Type();
}
// For non-calls, the type variable is the result.
if (!isCall)
return macroRefType;
// For calls, form the applicable-function constraint. The result type
// is the result of that call.
SmallVector<AnyFunctionType::Param, 8> params;
getMatchingParams(expr->getArgs(), params);
Type resultType = CS.createTypeVariable(
CS.getConstraintLocator(expr, ConstraintLocator::FunctionResult),
TVO_CanBindToNoEscape);
CS.addConstraint(
ConstraintKind::ApplicableFunction,
FunctionType::get(params, resultType),
macroRefType,
CS.getConstraintLocator(
expr, ConstraintLocator::ApplyFunction));
return resultType;
// For calls, set up the argument list.
bool isCall = expr->getArgs() != nullptr;
if (isCall) {
CS.associateArgumentList(locator, expr->getArgs());
}
#endif
return Type();
// Look up the macros with this name.
auto macroIdent = expr->getMacroName().getBaseIdentifier();
FunctionRefKind functionRefKind = isCall ? FunctionRefKind::SingleApply
: FunctionRefKind::Unapplied;
auto macros = lookupMacros(
macroIdent, expr->getMacroNameLoc().getBaseNameLoc(),
functionRefKind);
if (macros.empty()) {
ctx.Diags.diagnose(expr->getMacroNameLoc(), diag::macro_undefined,
macroIdent)
.highlight(expr->getMacroNameLoc().getSourceRange());
return Type();
}
// Introduce an overload set for the macro reference.
auto macroRefType = Type(CS.createTypeVariable(locator, 0));
CS.addOverloadSet(macroRefType, macros, CurDC, locator);
// Add explicit generic arguments, if there were any.
if (expr->getGenericArgsRange().isValid()) {
if (addSpecializationConstraint(
CS.getConstraintLocator(expr), macroRefType,
expr->getGenericArgs()))
return Type();
}
// For non-calls, the type variable is the result.
if (!isCall)
return macroRefType;
// For calls, form the applicable-function constraint. The result type
// is the result of that call.
SmallVector<AnyFunctionType::Param, 8> params;
getMatchingParams(expr->getArgs(), params);
Type resultType = CS.createTypeVariable(
CS.getConstraintLocator(expr, ConstraintLocator::FunctionResult),
TVO_CanBindToNoEscape);
CS.addConstraint(
ConstraintKind::ApplicableFunction,
FunctionType::get(params, resultType),
macroRefType,
CS.getConstraintLocator(
expr, ConstraintLocator::ApplyFunction));
return resultType;
}
static bool isTriggerFallbackDiagnosticBuiltin(UnresolvedDotExpr *UDE,