Add gated const item paths support for selected builtin attributes.#154708
Add gated const item paths support for selected builtin attributes.#154708BarronKane wants to merge 5 commits intorust-lang:mainfrom
Conversation
|
Some changes occurred in compiler/rustc_attr_parsing cc @jdonszelmann, @JonathanBrouwer Some changes occurred in compiler/rustc_hir/src/attrs |
|
r? @jieyouxu rustbot has assigned @jieyouxu. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Thanks for opening the door on resolving things in attributes. I actually want this for other things so it's nice to see happening.
There are a lot of names like AttrConstResolution, attr_const_res_map, attr_const_resolution etc being used. I'm worried that if someone wants to extend this to resolve other things (not constants) they'll have to change all those names. Can you choose a more general naming scheme? (let's wait for consensus before making big changes though)
For example maybe just drop the const part everywhere and change AttrConstResolution to
enum AttrResolution {
Const(...)
}so others can add variants as needed.
I can't comment on the name resolution part - I'm not familiar with it.
compiler/rustc_resolve/src/late.rs
Outdated
| fn resolve_attr_const_paths(&mut self, attr: &'ast Attribute) { | ||
| match attr.name() { | ||
| Some(sym::repr) => { | ||
| let Some(items) = attr.meta_item_list() else { | ||
| return; | ||
| }; | ||
| for item in &items { | ||
| let Some(meta) = item.meta_item() else { | ||
| continue; | ||
| }; | ||
| let Some(name) = meta.name() else { | ||
| continue; | ||
| }; | ||
| if !matches!(name, sym::align | sym::packed) { | ||
| continue; | ||
| } | ||
| let Some([arg]) = meta.meta_item_list() else { | ||
| continue; | ||
| }; | ||
| let Some(path_meta) = arg.meta_item() else { | ||
| continue; | ||
| }; | ||
| if !path_meta.is_word() { | ||
| continue; | ||
| } | ||
| if !self.should_resolve_attr_const_path(path_meta.path.span) { | ||
| continue; | ||
| } | ||
| self.resolve_attr_const_path(attr.id, &path_meta.path); | ||
| } | ||
| } | ||
| Some(sym::rustc_align | sym::rustc_align_static) => { | ||
| let Some(items) = attr.meta_item_list() else { | ||
| return; | ||
| }; | ||
| let [arg] = items.as_slice() else { | ||
| return; | ||
| }; | ||
| let Some(path_meta) = arg.meta_item() else { | ||
| return; | ||
| }; | ||
| if !path_meta.is_word() { | ||
| return; | ||
| } | ||
| if !self.should_resolve_attr_const_path(path_meta.path.span) { | ||
| return; | ||
| } | ||
| self.resolve_attr_const_path(attr.id, &path_meta.path); | ||
| } | ||
| _ => {} | ||
| } |
There was a problem hiding this comment.
I strongly worry how this creates another place where an attribute is parsed. This is the exact thing we want to eliminate with the attribute parsing rework. Is it possible to use AttributeParser::parse_limited_should_emit here?
There was a problem hiding this comment.
I missed that! I'll investigate. Do you want me to go forward in that direction or wait until a review threshold?
There was a problem hiding this comment.
Please do go ahead. We definitely do not want this sort of duplicated parsing code.
There was a problem hiding this comment.
Addressed! I folded everything into the AttributeParser machinery.
|
Have a few more PRs that I need to investigate, don't have bandwidth to review this any time soon. |
|
Note that this still needs approval from the lang team as an experiment before going forward. |
| #[derive(PartialEq, Eq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic)] | ||
| pub enum AttrIntValue { | ||
| Lit(u128), | ||
| Const { def_id: DefId, span: Span }, | ||
| } | ||
|
|
||
| #[derive(Debug, Copy, Clone, HashStable_Generic, Encodable, Decodable, PrintAttribute)] | ||
| pub enum AttrConstResolved<Id = ast::NodeId> { | ||
| Resolved(Res<Id>), | ||
| Error, | ||
| } | ||
|
|
||
| #[derive(Debug, Copy, Clone, HashStable_Generic, Encodable, Decodable, PrintAttribute)] | ||
| pub struct AttrConstResolution<Id = ast::NodeId> { | ||
| pub path_span: Span, | ||
| pub resolved: AttrConstResolved<Id>, | ||
| } |
There was a problem hiding this comment.
Please make sure to document new types and functions you add, this isn't completely obvious. (I realize this is pretty much a draft, just something to do before merge)
There was a problem hiding this comment.
Do you mean in the PR or in another part of the rustlang solution tree?
There was a problem hiding this comment.
By "before merge“ I did mean here
Thanks! Yea as I get further and further into critical-safe aware library writing (offline I'm doing slab-allocator basaed green-thread fiber stacks, with a script that crawls the ELF for exact slab sizing for stack-based futures and async, no more pin box dyn trait), I'm finding more and more machinery that I think really should be rust-native. Being able to build per-target alignment is a BIG one, but I have a lot of others cooking. I've taken the suggestions and code reviews I've gotten, and am about to push. I generally like the direction this has ended up going rather than my initial ideas. |
This comment has been minimized.
This comment has been minimized.
This timing is diabolical. Fixing. |
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
Add gated support for const item paths in selected builtin attributes, including `repr(align)`, `repr(packed)`, `rustc_align`, and `rustc_align_static`. Resolve attribute const paths during late resolution, carry them through HIR as attr int values, and evaluate them at the layout/codegen use sites. This keeps the feature scoped to const item paths without adding general expression support in attributes. Also adds UI/codegen/incremental coverage and fixes the gated-syntax diagnostics so unresolved names do not leak before the feature gate.
11e1199 to
23982a2
Compare
This adds a new unstable feature gate,
const_attr_paths, which allowsselected builtin attributes to accept paths to
constitems instead ofonly literal integers.
Relevant: #52840
Zulip thread: #t-lang > #[repr(align(cacheline))] Support
New Types
AttrResolutionKindAttrResolvedAttrResolutionAttrResolutionRequestNew Functions
AttributeParser::parse_limited_attr_resolution_requests_should_emitAttributeParse::parse_limited_attr_resolution_requestsForward
Currently this supports:
#[repr(align(CONST))]#[repr(packed(CONST))]#[rustc_align(CONST)]#[rustc_align_static(CONST)]Example:
Design
This is intentionally scoped to const item paths, not arbitrary expressions in attributes.
The implementation resolves eligible attribute paths during late resolution, carries them through HIR as
AttrIntValue, and evaluates them only at the layout/codegen use sites. That keeps the change narrow and avoids introducing general expression parsing/evaluation inside builtin attributes.Diagnostics
This also fixes the interaction between name resolution and the feature gate so that gated syntax does not leak premature unresolved-name errors before the const_attr_paths gate is checked.
Additional diagnostics are included for:
Tests
Adds UI, codegen, incremental, cross-crate, and unpretty coverage for the new behavior, including gate coverage and invalid cases.
Non-goals
This PR does not:
This is meant as a small, explicit experiment for builtin attributes that already conceptually consume integer values. More importantly, this guards the ability to expand this semantically later to include arbitrary expressions in attributes.