Skip to content

AttrTarget demo #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

AttrTarget demo #1

wants to merge 2 commits into from

Conversation

mejrs
Copy link
Owner

@mejrs mejrs commented Jun 22, 2025

The first commit creates AttrTarget. This passes down an enum to the attribute parsers so that they can tell what item they're on. This will allow us to move a lot of validation code from various passes directly into the parsers.

The second commit adds an associated const, so that we can do position checking similar to how duplicate attributes are handled with a const of AttributeOrder. You just declare it, it does the rest. We can do more than the allowed! macro; possibilities are unstable!, future_error! etc.

For more complicated relationships between the attribute and its item, like the #[naked] attribute and function abi, or diagnostic::on_unimplemented and the item's generic parameters, you cannot use that associated const; you still need to look at cx.target. The vast majority of attributes won't need to do that.

Random thoughts:

  • rustc_hir::Target is a similar but fieldless enum. However it is quite overloaded, it is used for lang items a lot for example, so reusing it would be quite a painful refactor. It's also sort of lacking, having no distinction between a trait method and an impl method for example.
  • What kind of data do we want to put there? rustc_ast types is the easiest, rustc_hir types would be more useful but complicated
    • we'd need to commit to parsing hir items before hir attributes but some lowering steps like lower_maybe_coroutine_body need to have the attributes parsed, and switching lowering order here might be ugly, impractical or impossible.
    • giving people access to some hir while lowering other hir might be confusing and error prone? It just feels like a bad idea to me.
  • What data should be in the enum? Do we want a "Nothing initially, just add it when you need it" approach.
  • Where do we put AttrTarget? Putting it outside rustc_ast and rustc_hir has the advantage that it's obviously not some kind of syntax, element or data type etc.
  • We can't do
pub enum AttrTarget<'ast> {
   Struct {
       struct_: &'ast ast::Struct,
   },
   ..
 }

Because ast::Struct doesn't exist - it's just a bunch of fields in ItemKind. Do we want to refactor that into a proper ast type, just keep passing fields, or something else?

@jdonszelmann
Copy link

jdonszelmann commented Jun 22, 2025

fyi I worked on this a bit and did go with using Target (in a way lang items are also attributes so it's not too weird that that uses the same struct). It makes the problem of different lowering orders disappear (I think this is quite hard to solve otherwise). Both our approaches work on the face of it, but I'm quite afraid that they will never do enough. So many attrs need more involved target checking that also involves tcx access so a late pass over them might always be necessary. In which case I'm not 100% convinced either of our approaches are correct

@mejrs
Copy link
Owner Author

mejrs commented Jun 22, 2025

I'm quite afraid that they will never do enough.

If we can make it so the vast majority of attributes don't need validation during a pass then that's good enough for me.

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.

2 participants