Skip to content
Open
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
3a4f5ac
Add `align_attr` RFC
Jules-Bertholet Jun 12, 2024
4badbc9
Add more mixing packed and aligned to future possibilities
Jules-Bertholet May 2, 2025
2b647a8
Avoid making commitments for interaction with `extern static`
Jules-Bertholet May 5, 2025
13cc4f2
Expand comparison with C and C++
Jules-Bertholet May 8, 2025
bbe09ee
Minor clarifications
Jules-Bertholet May 9, 2025
81748b6
Delete double spaces
Jules-Bertholet May 9, 2025
51b8069
Thumb weirdness, expand discussion of `repr`
Jules-Bertholet May 9, 2025
855a766
Rephrase
Jules-Bertholet May 9, 2025
1c7a402
Typo
Jules-Bertholet May 9, 2025
dee1e70
Address `async` and closures
Jules-Bertholet May 16, 2025
4701919
Elaborate on function parameters prohibition
Jules-Bertholet May 16, 2025
59b1230
Fix typo
Jules-Bertholet May 17, 2025
16f3bee
Justify `async fn` behavior
Jules-Bertholet May 17, 2025
5229770
Elaborate on `ref`/`ref mut`
Jules-Bertholet May 17, 2025
96350ee
Fix tpo
Jules-Bertholet May 18, 2025
0c21fb3
Fix example
Jules-Bertholet May 18, 2025
959a94c
Cache line clarifications
Jules-Bertholet May 18, 2025
75f615a
Minor rephrase
Jules-Bertholet May 18, 2025
8b1fa67
Fix typos
Jules-Bertholet May 19, 2025
95f3972
Link to WGSL alignment rules
Jules-Bertholet May 19, 2025
fefe945
Function parameter prohibition is semantic
Jules-Bertholet May 19, 2025
a478717
Justify not allowing attribute on `_`
Jules-Bertholet May 19, 2025
32b2a93
More cache clarifications
Jules-Bertholet May 19, 2025
f140b23
Rename a heading
Jules-Bertholet May 19, 2025
60f23d2
Fix typo
Jules-Bertholet May 28, 2025
3351aa9
Fix typo
Jules-Bertholet Jun 14, 2025
e10fe79
Make sentence less ambiguous
Jules-Bertholet Jun 14, 2025
441e05b
Minor rephrase
Jules-Bertholet Jun 20, 2025
8693706
Address target-specific limitations
Jules-Bertholet Jun 20, 2025
42fb9e2
`align` on trait declarations, semver
Jules-Bertholet Jun 20, 2025
9f5fb37
Overaligned fn ptrs future possibility
Jules-Bertholet Jun 20, 2025
553b5ef
Fix typo
Jules-Bertholet Jun 20, 2025
73973de
Fix typo
Jules-Bertholet Jun 20, 2025
4688f11
Fix typo
Jules-Bertholet Jun 20, 2025
9efcb25
Don’t require repeating `align` in impls
Jules-Bertholet Jun 20, 2025
7c155c8
Clarify "function's code" as "entry symbol"
Jules-Bertholet Jun 20, 2025
45a9d3d
Link to definition of "inert"
Jules-Bertholet Jun 25, 2025
893fd65
Clarify rustdoc
Jules-Bertholet Jun 25, 2025
5827b39
Rationale for 1-ZST `#[align(…)]` function item types
Jules-Bertholet Jun 25, 2025
5da3dcb
Function pointer tagging future possibility
Jules-Bertholet Jun 26, 2025
42f111b
`#[align(…)]` is compatible with `#[naked]`
Jules-Bertholet Jun 28, 2025
e79807a
`#[align(…)]` on functions in `extern` blocks
Jules-Bertholet Jun 28, 2025
d66a5cd
Address `track_caller` and WASM
Jules-Bertholet Aug 2, 2025
f16a88e
Note `align` on function subtleties
Jules-Bertholet Aug 22, 2025
0b02d6d
Address derive helper conflict
Jules-Bertholet Aug 22, 2025
2ec537f
Use `is_multiple_of` in example
Jules-Bertholet Aug 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions text/3806-align-attr.md
Copy link
Member

@workingjubilee workingjubilee Jun 14, 2025

Choose a reason for hiding this comment

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

I have no objection per se to the introduction of #[align] syntactically but I feel this will have a number of surprising complexities that will equate to the breaking change of size != stride. It feels like this tries to persuade the reader that hiding this break of assumptions in an attribute that doesn't start with #[repr will render it harmless. If you point at something with repr(align(N)), you are guaranteed padding that you can freely clobber, for instance, but pointers to things with this attribute have no such guarantee. This feels very likely to make unsafe code more confusing to write, in a similar way to what has driven us to say that we will not break size == stride.

Copy link
Contributor Author

@Jules-Bertholet Jules-Bertholet Jun 14, 2025

Choose a reason for hiding this comment

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

but pointers to things with this attribute have no such guarantee.

Yes, that is the point. If you need the guarantee, use a #[repr(align)] wrapper type. References to #[align] things have the same type as any other reference, because they provide the same guarantees as any other reference.

Copy link
Member

Choose a reason for hiding this comment

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

I must also note that I have voiced, repeatedly, that attributes do not compose very well in Rust compared to things more deeply embedded in the type, and the idea that this will compose as well as it does in C seems doubtful. I have made a separate note in one case of such. Nonetheless it is obviously the case that there are many positions where this attribute is desirable to have but there is no real way to introduce it to the type, or such is not reasonable. I wish this had been more incremental, in starting with such cases first.

Copy link
Contributor

Choose a reason for hiding this comment

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

This does, actually, seem like it's part of the unnameable type of the function itself, and that really this should be carried into the type of function pointers derived from it. The interaction of this with traits and refinement makes this more apparent.

One could imagine, e.g., the function type implementing a trait like Align16 where Align32: Align16, etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's notable as well, in light of other recent discussions, that inverse marker effects -- i.e., constraining properties of functions -- can in theory be modeled with traits.

Probably alignment isn't what we'd think of as an (inverse) effect -- it's not (the absence of) a side effect of the function that exceeds its signature -- but if we squint, it does maybe have some modeling similarities.

Copy link
Member

Choose a reason for hiding this comment

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

I have hoped for some time to be able to implement instead a trait like Aligned<const N>, specifically.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

carried into the type of function pointers derived from it.

Added to the future possibilities.

Copy link

@hanna-kruppe hanna-kruppe Jun 20, 2025

Choose a reason for hiding this comment

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

Exposing the chosen alignment as a property of the fn item type seems like a sensible extension to me (though it pokes a small hole in the arguments against #[repr(align(N))] fn). It doesn't seem obvious to me what would be the best way to expose the information (a hierarchy of AlignN traits looks weird, but const parameter on trait, associated const, just plain align_of, etc. have their own drawbacks) but since this is a backwards compatible extension, these details can be figured out later without blocking this RFC and the feature waiting on it.

I'm more worried about putting this information into fn pointer types. Those already have a lot of dimensions (safe vs unsafe, calling convention, lifetimes, and probably const-ness at some point) and most of those dimensions aren't covered by subtyping, so you can easily run into hard-to-resolve type mismatches with them once you actually use all of that flexibility. Adding alignment to the mix amplifies this problem further, only mitigated by how niche fn pointers with increased alignment would be. I'm not sure what the use cases are but I suspect most of them could be addressed just fine with being able to express "can be turned into a function pointer" and "has alignment at least N" in where clauses. Then libraries can define function pointer wrappers that can be constructed from fn item types that have sufficient alignment, without adding more dimensions to the built-in fn pointer type.

I'm also not sure if changing the "canonical" fn pointer type for a fn item type would be a breaking change (beyond new possibilities for inference failure). If it is, then figuring out the details about "aligned fn pointer types" might be a blocker for stabilizing #[align(N)] fn.

Copy link
Member

@workingjubilee workingjubilee Jun 20, 2025

Choose a reason for hiding this comment

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

It's true, we usually prefer to lean on coercions instead of subtyping for things like function pointers but that can have problems due to having coercions select different implementations for the same item according to fairly subtle rules.

Copy link

@hanna-kruppe hanna-kruppe Jun 20, 2025

Choose a reason for hiding this comment

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

Not just due to which coercion is chosen, but also because coercions don't help when the type that needs coercion is behind any sort of type constructor (including very basic ones like &T or [T; N]).

Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ fn main() {
}
```

### `derive` macro helper ambiguity

Some existing `derive` macros in the ecosystem currently declare `align` as a
helper attribute. To avoid breakage, we specify that `derive` helper attributes
shadow built-in attributes of the same name (so the built-in attribute does not
take effect). A warn-by-default lint is triggered when this occurs.
Comment on lines +272 to +277

Choose a reason for hiding this comment

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

you might want to link to

I don't understand it fully, but I believe that what @petrochenkov points out is that it's not so simple to have a builtin attribute shadow a user-defined procedural macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don’t fully understand it either, but I think we avoid the problems mentioned?

  • We only deal with derive helper attributes, which is where the Crater run said the breakage was AAUI, not conflicts with used macros. I think that avoids having to deal with the name resolution issues, because the helpers are also inert.
  • In any case, #[align(…)] doesn’t make sense to apply to macros, modules, or as an inner attribute.

Copy link
Member

@jieyouxu jieyouxu Aug 23, 2025

Choose a reason for hiding this comment

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

Is #[align] supposed to be a built-in attribute? If so, then currently introducing that breaks both the derive helper case and the use align case. (Yes, even if feature-gated, unfortunately.)

See rust-lang/rust#143834 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I am aware, there will need to be some implementation work

Choose a reason for hiding this comment

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

Do you have concrete steps in mind? Presumably that work is not really blocked on the rfc, we could already implement it for the current #[rustc_align]?

Copy link
Member

Choose a reason for hiding this comment

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

Also FWIW, a possible option is to intentionally accept this kind of breakage. The mitigation (rename to #[rustc_align]) was to not introduce such breakage unintentionally, and to alleviate time pressure so that we do not need to rush an FCP (which is usually a recipe for painful mistakes down the line).

Choose a reason for hiding this comment

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

Sure, do you feel that we have a good picture of the scope of this breakage? Based on the links at rust-lang/rust#143834, and looking at crates.io stats, these crates have low thousands number of recent downloads.

On the other hand, this problem will just pop up again elsewhere. I'm just not that familiar with the name resolution details. It seems reasonable to, like the prelude, have user code override automatically imported names, but then again name resolution is infamously complex and subtle.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure re. the degree of breakage as I didn't have the bandwidth to look into how much breakage there was specifically.


## On function items

On function items, `#[align(…)]` sets the alignment of the function’s entry
Expand Down