Skip to content

Commit f40bb7e

Browse files
authored
Propagate #[target_feature] attributes on #[builder]-generated finishing functions (#284)
1 parent 5b71e5a commit f40bb7e

7 files changed

Lines changed: 82 additions & 4 deletions

File tree

bon-macros/src/builder/builder_gen/finish_fn.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,23 @@ impl super::BuilderGenCtx {
157157
let state_var = &self.state_var;
158158
let const_ = &self.const_;
159159

160+
// `#[target_feature]` is not compatible with `#[inline(always)]`,
161+
// so we need to downgrade it to `#[inline]
162+
let inline_attr = self
163+
.finish_fn
164+
.special_attrs
165+
.iter()
166+
.find_map(|attr| {
167+
attr.meta
168+
.path()
169+
.is_ident("target_feature")
170+
.then(|| quote! { #[inline] })
171+
})
172+
.unwrap_or_else(|| quote! { #[inline(always)] });
173+
160174
quote! {
161175
#(#attrs)*
162-
#[inline(always)]
176+
#inline_attr
163177
#[allow(
164178
// This is intentional. We want the builder syntax to compile away
165179
clippy::inline_always,

bon-macros/src/builder/builder_gen/input_fn/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ fn merge_generic_params(
485485
.collect()
486486
}
487487

488-
const PROPAGATED_ATTRIBUTES: &[&str] = &["must_use", "track_caller"];
488+
const PROPAGATED_ATTRIBUTES: &[&str] = &["must_use", "track_caller", "target_feature"];
489489

490490
fn get_propagated_attrs(attrs: &[syn::Attribute]) -> Result<Vec<syn::Attribute>> {
491491
PROPAGATED_ATTRIBUTES

bon/tests/integration/builder/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod orig_fn_naming;
2525
mod positional_members;
2626
mod raw_idents;
2727
mod smoke;
28+
mod target_feature;
2829
mod track_caller;
2930

3031
use crate::prelude::*;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#[cfg(target_arch = "x86_64")]
2+
#[rustversion::since(1.86.0)]
3+
mod msrv_1_86 {
4+
#![allow(dead_code)]
5+
use crate::prelude::*;
6+
7+
#[test]
8+
fn target_feature_function() {
9+
#[builder]
10+
#[target_feature(enable = "avx2")]
11+
fn building_but_wider(_x: [u8; 32], _y: [u32; 8]) {}
12+
13+
#[target_feature(enable = "avx2")]
14+
#[allow(unsafe_code)]
15+
unsafe fn wider() {
16+
building_but_wider().x([0; 32]).y([1; 8]).call();
17+
}
18+
}
19+
20+
#[test]
21+
fn target_feature_method() {
22+
#[repr(C, align(32))]
23+
struct Brick([u8; 32]);
24+
struct Senti;
25+
26+
#[bon]
27+
impl Senti {
28+
#[builder(finish_fn = yatta_but_wide)]
29+
#[target_feature(enable = "avx2")]
30+
fn new(brick: Brick) -> Self {
31+
let Brick(_) = brick;
32+
Self
33+
}
34+
#[target_feature(enable = "avx2")]
35+
#[allow(unsafe_code)]
36+
unsafe fn briiick() {
37+
Self::builder().brick(Brick([0; 32])).yatta_but_wide();
38+
}
39+
}
40+
}
41+
}

bon/tests/integration/builder/track_caller.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl From<&'_ Location<'_>> for LineCol {
1818
}
1919

2020
#[test]
21-
fn track_caller_fn() {
21+
fn track_caller_function() {
2222
#[builder]
2323
#[track_caller]
2424
fn dont_brick(_x: u32) -> LineCol {
@@ -39,7 +39,7 @@ fn track_caller_fn() {
3939
}
4040

4141
#[test]
42-
fn track_caller_impl_block() {
42+
fn track_caller_method() {
4343
struct Brick;
4444
struct Senti;
4545
#[bon]

bon/tests/integration/ui/compile_fail/attr_builder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,7 @@ fn destructuring2((_, _): (u32, u32)) {}
7272
#[track_caller]
7373
#[track_caller]
7474
fn double_track_caller() {}
75+
#[builder]
76+
#[target_feature(enable = "")]
77+
#[target_feature(enable = "")]
78+
fn double_invalid_target_feature() {}

bon/tests/integration/ui/compile_fail/attr_builder.stderr

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,21 @@ error: found multiple #[track_caller], but bon only works with exactly one or ze
8989
|
9090
73 | #[track_caller]
9191
| ^
92+
93+
error: found multiple #[target_feature], but bon only works with exactly one or zero.
94+
--> tests/integration/ui/compile_fail/attr_builder.rs:77:1
95+
|
96+
77 | #[target_feature(enable = "")]
97+
| ^
98+
99+
error: the feature named `` is not valid for this target
100+
--> tests/integration/ui/compile_fail/attr_builder.rs:76:18
101+
|
102+
76 | #[target_feature(enable = "")]
103+
| ^^^^^^^^^^^ `` is not valid for this target
104+
105+
error: the feature named `` is not valid for this target
106+
--> tests/integration/ui/compile_fail/attr_builder.rs:77:18
107+
|
108+
77 | #[target_feature(enable = "")]
109+
| ^^^^^^^^^^^ `` is not valid for this target

0 commit comments

Comments
 (0)