|  | 
| 7 | 7 | use rustc_abi::ExternAbi; | 
| 8 | 8 | use rustc_ast::ast; | 
| 9 | 9 | use rustc_attr_data_structures::{self as attrs, DeprecatedSince}; | 
|  | 10 | +use rustc_hir as hir; | 
| 10 | 11 | use rustc_hir::def::CtorKind; | 
| 11 | 12 | use rustc_hir::def_id::DefId; | 
| 12 | 13 | use rustc_metadata::rendered_const; | 
|  | 14 | +use rustc_middle::ty::TyCtxt; | 
| 13 | 15 | use rustc_middle::{bug, ty}; | 
| 14 | 16 | use rustc_span::{Pos, kw, sym}; | 
| 15 | 17 | use rustdoc_json_types::*; | 
| @@ -40,7 +42,12 @@ impl JsonRenderer<'_> { | 
| 40 | 42 |             }) | 
| 41 | 43 |             .collect(); | 
| 42 | 44 |         let docs = item.opt_doc_value(); | 
| 43 |  | -        let attrs = item.attributes(self.tcx, &self.cache, true); | 
|  | 45 | +        let attrs = item | 
|  | 46 | +            .attrs | 
|  | 47 | +            .other_attrs | 
|  | 48 | +            .iter() | 
|  | 49 | +            .filter_map(|a| maybe_from_hir_attr(a, item.item_id, self.tcx)) | 
|  | 50 | +            .collect(); | 
| 44 | 51 |         let span = item.span(self.tcx); | 
| 45 | 52 |         let visibility = item.visibility(self.tcx); | 
| 46 | 53 |         let clean::ItemInner { name, item_id, .. } = *item.inner; | 
| @@ -875,3 +882,104 @@ impl FromClean<ItemType> for ItemKind { | 
| 875 | 882 |         } | 
| 876 | 883 |     } | 
| 877 | 884 | } | 
|  | 885 | + | 
|  | 886 | +/// Maybe convert a attribue from hir to json. | 
|  | 887 | +/// | 
|  | 888 | +/// Returns `None` if the attribute shouldn't be in the output. | 
|  | 889 | +fn maybe_from_hir_attr( | 
|  | 890 | +    attr: &hir::Attribute, | 
|  | 891 | +    item_id: ItemId, | 
|  | 892 | +    tcx: TyCtxt<'_>, | 
|  | 893 | +) -> Option<Attribute> { | 
|  | 894 | +    use attrs::AttributeKind as AK; | 
|  | 895 | + | 
|  | 896 | +    let kind = match attr { | 
|  | 897 | +        hir::Attribute::Parsed(kind) => kind, | 
|  | 898 | + | 
|  | 899 | +        // There are some currently unstrucured attrs that we *do* care about. | 
|  | 900 | +        // As the attribute migration progresses (#131229), this is expected to shrink | 
|  | 901 | +        // and eventually be removed as all attributes gain a strutured representation in | 
|  | 902 | +        // HIR. | 
|  | 903 | +        hir::Attribute::Unparsed(_) => { | 
|  | 904 | +            return Some(if attr.has_name(sym::non_exhaustive) { | 
|  | 905 | +                Attribute::NonExhaustive | 
|  | 906 | +            } else if attr.has_name(sym::automatically_derived) { | 
|  | 907 | +                Attribute::AutomaticallyDerived | 
|  | 908 | +            } else if attr.has_name(sym::export_name) { | 
|  | 909 | +                Attribute::ExportName( | 
|  | 910 | +                    attr.value_str().expect("checked by attr validation").to_string(), | 
|  | 911 | +                ) | 
|  | 912 | +            } else if attr.has_name(sym::doc) | 
|  | 913 | +                && attr | 
|  | 914 | +                    .meta_item_list() | 
|  | 915 | +                    .is_some_and(|metas| metas.iter().any(|item| item.has_name(sym::hidden))) | 
|  | 916 | +            { | 
|  | 917 | +                Attribute::DocHidden | 
|  | 918 | +            } else { | 
|  | 919 | +                other_attr(tcx, attr) | 
|  | 920 | +            }); | 
|  | 921 | +        } | 
|  | 922 | +    }; | 
|  | 923 | + | 
|  | 924 | +    Some(match kind { | 
|  | 925 | +        AK::Deprecation { .. } => return None, // Handled seperatly into Item::deprecation. | 
|  | 926 | +        AK::DocComment { .. } => unreachable!("doc comments stripped out earlier"), | 
|  | 927 | + | 
|  | 928 | +        AK::MustUse { reason, span: _ } => { | 
|  | 929 | +            Attribute::MustUse { reason: reason.map(|s| s.to_string()) } | 
|  | 930 | +        } | 
|  | 931 | +        AK::Repr { .. } => repr_attr( | 
|  | 932 | +            tcx, | 
|  | 933 | +            item_id.as_def_id().expect("all items that could have #[repr] have a DefId"), | 
|  | 934 | +        ), | 
|  | 935 | +        AK::NoMangle(_) => Attribute::NoMangle, | 
|  | 936 | + | 
|  | 937 | +        _ => other_attr(tcx, attr), | 
|  | 938 | +    }) | 
|  | 939 | +} | 
|  | 940 | + | 
|  | 941 | +fn other_attr(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Attribute { | 
|  | 942 | +    let mut s = rustc_hir_pretty::attribute_to_string(&tcx, attr); | 
|  | 943 | +    assert_eq!(s.pop(), Some('\n')); | 
|  | 944 | +    Attribute::Other(s) | 
|  | 945 | +} | 
|  | 946 | + | 
|  | 947 | +fn repr_attr(tcx: TyCtxt<'_>, def_id: DefId) -> Attribute { | 
|  | 948 | +    let repr = tcx.adt_def(def_id).repr(); | 
|  | 949 | + | 
|  | 950 | +    let kind = if repr.c() { | 
|  | 951 | +        ReprKind::C | 
|  | 952 | +    } else if repr.transparent() { | 
|  | 953 | +        ReprKind::Transparent | 
|  | 954 | +    } else if repr.simd() { | 
|  | 955 | +        ReprKind::Simd | 
|  | 956 | +    } else { | 
|  | 957 | +        ReprKind::Rust | 
|  | 958 | +    }; | 
|  | 959 | + | 
|  | 960 | +    let align = repr.align.map(|a| a.bytes()); | 
|  | 961 | +    let packed = repr.pack.map(|p| p.bytes()); | 
|  | 962 | +    let int = repr.int.map(format_integer_type); | 
|  | 963 | + | 
|  | 964 | +    Attribute::Repr(AttributeRepr { kind, align, packed, int }) | 
|  | 965 | +} | 
|  | 966 | + | 
|  | 967 | +fn format_integer_type(it: rustc_abi::IntegerType) -> String { | 
|  | 968 | +    use rustc_abi::Integer::*; | 
|  | 969 | +    use rustc_abi::IntegerType::*; | 
|  | 970 | +    match it { | 
|  | 971 | +        Pointer(true) => "isize", | 
|  | 972 | +        Pointer(false) => "usize", | 
|  | 973 | +        Fixed(I8, true) => "i8", | 
|  | 974 | +        Fixed(I8, false) => "u8", | 
|  | 975 | +        Fixed(I16, true) => "i16", | 
|  | 976 | +        Fixed(I16, false) => "u16", | 
|  | 977 | +        Fixed(I32, true) => "i32", | 
|  | 978 | +        Fixed(I32, false) => "u32", | 
|  | 979 | +        Fixed(I64, true) => "i64", | 
|  | 980 | +        Fixed(I64, false) => "u64", | 
|  | 981 | +        Fixed(I128, true) => "i128", | 
|  | 982 | +        Fixed(I128, false) => "u128", | 
|  | 983 | +    } | 
|  | 984 | +    .to_owned() | 
|  | 985 | +} | 
0 commit comments