Skip to content

Conversation

hborla
Copy link
Member

@hborla hborla commented Jan 22, 2023

To type-check macro arguments, we build an overload set from all of the attached macro declarations found in findMacroForCustomAttr, and then form a CallExpr with the overload set as the callee with the custom attribute arguments (or an implicit empty argument list). The concrete DeclRefExpr written back to the type-checked AST is the resolved macro decl for the given arguments.

Note that this change prevents macros from being declared using a : Void type annotation, because we always build a CallExpr to resolve the macro reference; a call to a macro declaration with type Void would result in the error cannot call value of non-function type 'Void'.

Type wrappers were invoking CustomAttrDeclRequest with a decl context
of the attached nominal type rather than its decl context, so the request
was invoked twice for the same custom attributes with different decl
contexts.
invalid macro attributes in `findMacroForCustomAttr`.
@hborla
Copy link
Member Author

hborla commented Jan 22, 2023

@swift-ci please smoke test

type checking macro attribute arguments into two different requests.
@hborla
Copy link
Member Author

hborla commented Jan 23, 2023

@swift-ci please smoke test

@hborla hborla merged commit 336af60 into swiftlang:main Jan 23, 2023
@hborla hborla deleted the type-check-attached-macro-args branch January 23, 2023 04:27
@@ -3590,7 +3590,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
if (auto macro = dyn_cast<MacroDecl>(decl)) {
// Macro can only be used in an expansion. If we end up here, it's
// because we found a macro but are missing the leading '#'.
if (!locator->isForMacroExpansion()) {
if (!(locator->isForMacroExpansion() || locator->getAnchor().isImplicit())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this be replaced with a different locator check to cover attached macros, or... ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was going back and forth between generalizing MacroExpansionExpr to work for attached macros, or providing "this is an attached macro" through some other mechanism, e.g. a dedicated SolutionApplicationTarget::Kind. If we decide on a common approach for no-argument macros across attached and freestanding, I think generalizing MacroExpansionExpr makes the most sense.

llvm::TinyPtrVector<ValueDecl *> macros;
findMacroForCustomAttr(attr, dc, macros);
if (!macros.empty())
return nullptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so MacroOrNominalTypeDecl will go away again. Sorry for the detour.

/// Resolve a given custom attribute to an attached macro declaration.
class ResolveAttachedMacroRequest
: public SimpleRequest<ResolveAttachedMacroRequest,
MacroDecl *(CustomAttr *, DeclContext *),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return a ConcreteDeclRef that points at the MacroDecl, so we also have the inferred generic arguments? Otherwise, they won't be captured anywhere.

@@ -17,7 +17,7 @@
// REQUIRES: OS=macosx

@attached(accessor)
macro myPropertyWrapper: Void =
macro myPropertyWrapper() =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noted this offline, but we should consider this change in the context of expression macros as well. Perhaps macros should always have argument lists, but can be used without parentheses if all parameters have default arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants