Skip to content

Commit c5c8bbd

Browse files
committed
Addressing review comments
1 parent 407b3f3 commit c5c8bbd

File tree

6 files changed

+92
-22
lines changed

6 files changed

+92
-22
lines changed

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ use hir::def::{DefKind, PartialRes, Res};
4343
use hir::{BodyId, HirId};
4444
use rustc_abi::ExternAbi;
4545
use rustc_ast::*;
46+
use rustc_attr_parsing::{AttributeParser, ShouldEmit};
4647
use rustc_errors::ErrorGuaranteed;
48+
use rustc_hir::Target;
4749
use rustc_hir::attrs::{AttributeKind, InlineAttr};
4850
use rustc_hir::def_id::DefId;
4951
use rustc_middle::span_bug;
5052
use rustc_middle::ty::{Asyncness, DelegationFnSigAttrs, ResolverAstLowering};
5153
use rustc_span::symbol::kw;
52-
use rustc_span::{Ident, Span, Symbol};
54+
use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
5355
use {rustc_ast as ast, rustc_hir as hir};
5456

5557
use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
@@ -69,7 +71,7 @@ struct AttributeAdditionInfo {
6971

7072
enum AttributeAdditionKind {
7173
Default { factory: fn(Span) -> hir::Attribute },
72-
Inherit { flag: DelegationFnSigAttrs, factory: fn(Span) -> hir::Attribute },
74+
Inherit { flag: DelegationFnSigAttrs, factory: fn(Span, &hir::Attribute) -> hir::Attribute },
7375
}
7476

7577
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
@@ -78,7 +80,17 @@ static ATTRIBUTES_ADDITIONS: &[AttributeAdditionInfo] = &[
7880
AttributeAdditionInfo {
7981
equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::MustUse { .. })),
8082
kind: AttributeAdditionKind::Inherit {
81-
factory: |span| hir::Attribute::Parsed(AttributeKind::MustUse { span, reason: None }),
83+
factory: |span, original_attribute| {
84+
let reason = match original_attribute {
85+
hir::Attribute::Parsed(AttributeKind::MustUse {
86+
span: _,
87+
reason: Some(reason),
88+
}) => Some(reason.clone()),
89+
_ => None,
90+
};
91+
92+
hir::Attribute::Parsed(AttributeKind::MustUse { span, reason })
93+
},
8294
flag: DelegationFnSigAttrs::MUST_USE,
8395
},
8496
},
@@ -160,6 +172,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
160172
sig_id: DefId,
161173
existing_attrs: Option<&&[hir::Attribute]>,
162174
) -> Vec<hir::Attribute> {
175+
let local_original_attributes = self.parse_local_original_attributes(sig_id);
176+
163177
candidate_additions
164178
.iter()
165179
.filter_map(|addition_info| {
@@ -174,33 +188,57 @@ impl<'hir> LoweringContext<'_, 'hir> {
174188
match addition_info.kind {
175189
AttributeAdditionKind::Default { factory } => Some(factory(span)),
176190
AttributeAdditionKind::Inherit { flag, factory } => {
177-
// Check if an attribute present on the target of delegation,
178-
// either in this crate or other
179-
let should_inherit = match sig_id.as_local() {
191+
let original_attribute = match sig_id.as_local() {
180192
Some(local_id) => self
181193
.resolver
182194
.delegation_fn_sigs
183195
.get(&local_id)
184-
.is_some_and(|sig| sig.attrs_flags.contains(flag)),
185-
// We can not use `tcx.has_attr` and symbol here as attributes
186-
// from other crates have None in their identifiers
196+
.is_some_and(|sig| sig.attrs_flags.contains(flag))
197+
.then(|| {
198+
local_original_attributes
199+
.as_ref()
200+
.map(|attrs| {
201+
attrs
202+
.iter()
203+
.find(|base_attr| (addition_info.equals)(base_attr))
204+
})
205+
.flatten()
206+
})
207+
.flatten(),
187208
None => self
188209
.tcx
189210
.get_all_attrs(sig_id)
190211
.iter()
191-
.any(|base_attr| (addition_info.equals)(base_attr)),
212+
.find(|base_attr| (addition_info.equals)(base_attr)),
192213
};
193214

194-
match should_inherit {
195-
true => Some(factory(span)),
196-
false => None,
197-
}
215+
original_attribute.map(|a| factory(span, a))
198216
}
199217
}
200218
})
201219
.collect::<Vec<_>>()
202220
}
203221

222+
fn parse_local_original_attributes(&self, sig_id: DefId) -> Option<Vec<hir::Attribute>> {
223+
if let Some(local_id) = sig_id.as_local()
224+
&& let Some(info) = self.resolver.delegation_fn_sigs.get(&local_id)
225+
&& !info.to_inherit_attrs.is_empty()
226+
{
227+
Some(AttributeParser::parse_limited_all(
228+
self.tcx.sess,
229+
info.to_inherit_attrs.as_slice(),
230+
None,
231+
Target::Fn,
232+
DUMMY_SP,
233+
DUMMY_NODE_ID,
234+
Some(self.tcx.features()),
235+
ShouldEmit::Nothing,
236+
))
237+
} else {
238+
None
239+
}
240+
}
241+
204242
fn get_delegation_sig_id(
205243
&self,
206244
item_id: NodeId,

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub use generic_args::{GenericArgKind, TermKind, *};
2525
pub use generics::*;
2626
pub use intrinsic::IntrinsicDef;
2727
use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx};
28+
use rustc_ast::AttrVec;
2829
use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree};
2930
use rustc_ast::node_id::NodeMap;
3031
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
@@ -229,13 +230,16 @@ bitflags::bitflags! {
229230
}
230231
}
231232

233+
pub const DELEGATION_INHERIT_ATTRS_START: DelegationFnSigAttrs = DelegationFnSigAttrs::MUST_USE;
234+
232235
#[derive(Debug)]
233236
pub struct DelegationFnSig {
234237
pub header: ast::FnHeader,
235238
pub param_count: usize,
236239
pub has_self: bool,
237240
pub c_variadic: bool,
238241
pub attrs_flags: DelegationFnSigAttrs,
242+
pub to_inherit_attrs: AttrVec,
239243
}
240244

241245
#[derive(Clone, Copy, Debug, HashStable)]

compiler/rustc_resolve/src/late.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, Par
2828
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId};
2929
use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate};
3030
use rustc_middle::middle::resolve_bound_vars::Set1;
31-
use rustc_middle::ty::{AssocTag, DelegationFnSig, DelegationFnSigAttrs, Visibility};
31+
use rustc_middle::ty::{
32+
AssocTag, DELEGATION_INHERIT_ATTRS_START, DelegationFnSig, DelegationFnSigAttrs, Visibility,
33+
};
3234
use rustc_middle::{bug, span_bug};
3335
use rustc_session::config::{CrateType, ResolveDocLinks};
3436
use rustc_session::lint;
@@ -5299,12 +5301,19 @@ impl ItemInfoCollector<'_, '_, '_> {
52995301
(sym::must_use, DelegationFnSigAttrs::MUST_USE),
53005302
];
53015303

5304+
let mut to_inherit_attrs = AttrVec::new();
53025305
let mut attrs_flags = DelegationFnSigAttrs::empty();
5303-
for attr in attrs {
5306+
5307+
'attrs_loop: for attr in attrs {
53045308
for &(name, flag) in NAMES_TO_FLAGS {
53055309
if attr.has_name(name) {
53065310
attrs_flags.set(flag, true);
5307-
continue;
5311+
5312+
if flag.bits() >= DELEGATION_INHERIT_ATTRS_START.bits() {
5313+
to_inherit_attrs.push(attr.clone());
5314+
}
5315+
5316+
continue 'attrs_loop;
53085317
}
53095318
}
53105319
}
@@ -5315,6 +5324,7 @@ impl ItemInfoCollector<'_, '_, '_> {
53155324
has_self: decl.has_self(),
53165325
c_variadic: decl.c_variadic(),
53175326
attrs_flags,
5327+
to_inherit_attrs,
53185328
};
53195329

53205330
self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig);

tests/pretty/auxiliary/to-reuse-functions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#[cold]
55
pub unsafe fn unsafe_fn_extern() -> usize { 1 }
66

7-
#[must_use]
7+
#[must_use = "extern_fn_extern: some reason"]
88
#[deprecated]
99
pub extern "C" fn extern_fn_extern() -> usize { 1 }
1010

tests/pretty/delegation-inherit-attributes.pp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,28 @@
1414
extern crate to_reuse_functions;
1515

1616
mod to_reuse {
17-
#[attr = MustUse]
17+
#[attr = MustUse {reason: "foo: some reason"}]
1818
#[attr = Cold]
1919
fn foo(x: usize) -> usize { x }
2020

21+
#[attr = MustUse]
22+
#[attr = Cold]
23+
fn foo_no_reason(x: usize) -> usize { x }
24+
2125
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
2226
#[attr = Cold]
2327
fn bar(x: usize) -> usize { x }
2428
}
2529

2630
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
27-
#[attr = MustUse]
31+
#[attr = MustUse {reason: "foo: some reason"}]
2832
#[attr = Inline(Hint)]
2933
fn foo1(arg0: _) -> _ { to_reuse::foo(self + 1) }
3034

35+
#[attr = MustUse]
36+
#[attr = Inline(Hint)]
37+
fn foo_no_reason(arg0: _) -> _ { to_reuse::foo_no_reason(self + 1) }
38+
3139
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
3240
#[attr = MustUse {reason: "some reason"}]
3341
#[attr = Inline(Hint)]
@@ -39,7 +47,7 @@
3947
#[attr = MustUse]
4048
#[attr = Inline(Hint)]
4149
unsafe fn unsafe_fn_extern() -> _ { to_reuse_functions::unsafe_fn_extern() }
42-
#[attr = MustUse]
50+
#[attr = MustUse {reason: "extern_fn_extern: some reason"}]
4351
#[attr = Inline(Hint)]
4452
extern "C" fn extern_fn_extern()
4553
-> _ { to_reuse_functions::extern_fn_extern() }

tests/pretty/delegation-inherit-attributes.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@
1010
extern crate to_reuse_functions;
1111

1212
mod to_reuse {
13-
#[must_use]
13+
#[must_use = "foo: some reason"]
1414
#[cold]
1515
pub fn foo(x: usize) -> usize {
1616
x
1717
}
1818

19+
#[must_use]
20+
#[cold]
21+
pub fn foo_no_reason(x: usize) -> usize {
22+
x
23+
}
24+
1925
#[cold]
2026
#[deprecated]
2127
pub fn bar(x: usize) -> usize {
@@ -28,6 +34,10 @@ reuse to_reuse::foo as foo1 {
2834
self + 1
2935
}
3036

37+
reuse to_reuse::foo_no_reason {
38+
self + 1
39+
}
40+
3141
#[deprecated]
3242
#[must_use = "some reason"]
3343
reuse to_reuse::foo as foo2 {

0 commit comments

Comments
 (0)