rustc_ast_lowering/delegation/
attributes.rs1use rustc_hir::attrs::{AttributeKind, InlineAttr};
2use rustc_hir::{self as hir};
3use rustc_span::Span;
4use rustc_span::def_id::DefId;
5
6use crate::LoweringContext;
7use crate::delegation::DelegationResolution;
8
9struct AdditionInfo {
10 pub equals: fn(&hir::Attribute) -> bool,
11 pub kind: AdditionKind,
12}
13
14enum AdditionKind {
15 Default { factory: fn(Span) -> hir::Attribute },
16 Inherit { factory: fn(Span, &hir::Attribute) -> hir::Attribute },
17}
18
19static ADDITIONS: &[AdditionInfo] = &[
20 AdditionInfo {
21 equals: |a| #[allow(non_exhaustive_omitted_patterns)] match a {
hir::Attribute::Parsed(AttributeKind::MustUse { .. }) => true,
_ => false,
}matches!(a, hir::Attribute::Parsed(AttributeKind::MustUse { .. })),
22 kind: AdditionKind::Inherit {
23 factory: |span, original_attr| {
24 let reason = match original_attr {
25 hir::Attribute::Parsed(AttributeKind::MustUse { reason, .. }) => *reason,
26 _ => None,
27 };
28
29 hir::Attribute::Parsed(AttributeKind::MustUse { span, reason })
30 },
31 },
32 },
33 AdditionInfo {
34 equals: |a| #[allow(non_exhaustive_omitted_patterns)] match a {
hir::Attribute::Parsed(AttributeKind::Inline(..)) => true,
_ => false,
}matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))),
35 kind: AdditionKind::Default {
36 factory: |span| hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span)),
37 },
38 },
39];
40
41impl<'hir> LoweringContext<'_, 'hir> {
42 pub(super) fn add_attrs_if_needed(&mut self, resolution: &DelegationResolution) {
43 let &DelegationResolution { span, sig_id, .. } = resolution;
44
45 const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
46 let new_attrs = self.create_new_attrs(span, sig_id, self.attrs.get(&PARENT_ID));
47
48 if !new_attrs.is_empty() {
49 let new_attrs = match self.attrs.get(&PARENT_ID) {
50 Some(existing_attrs) => self.arena.alloc_from_iter(
51 existing_attrs.iter().map(|a| a.clone()).chain(new_attrs.into_iter()),
52 ),
53 None => self.arena.alloc_from_iter(new_attrs.into_iter()),
54 };
55
56 self.attrs.insert(PARENT_ID, new_attrs);
57 }
58 }
59
60 fn create_new_attrs(
61 &self,
62 span: Span,
63 sig_id: DefId,
64 existing: Option<&&[hir::Attribute]>,
65 ) -> Vec<hir::Attribute> {
66 ADDITIONS
67 .iter()
68 .filter_map(|addition| {
69 existing
70 .is_none_or(|attrs| !attrs.iter().any(|a| (addition.equals)(a)))
71 .then(|| match addition.kind {
72 AdditionKind::Default { factory } => Some(factory(span)),
73 AdditionKind::Inherit { factory, .. } =>
74 {
75 #[allow(deprecated)]
76 self.tcx
77 .get_all_attrs(sig_id)
78 .iter()
79 .find_map(|a| (addition.equals)(a).then(|| factory(span, a)))
80 }
81 })
82 .flatten()
83 })
84 .collect::<Vec<_>>()
85 }
86}