1 //! These from impls are used to create the JSON types which get serialized. They're very close to
2 //! the `clean` types but with some fields removed or stringified to simplify the output and not
3 //! expose unstable compiler internals.
5 #![allow(rustc::default_hash_types)]
7 use std
::convert
::From
;
11 use rustc_hir
::{def::CtorKind, def_id::DefId}
;
12 use rustc_middle
::ty
::{self, TyCtxt}
;
13 use rustc_span
::{Pos, Symbol}
;
14 use rustc_target
::spec
::abi
::Abi
as RustcAbi
;
16 use rustdoc_json_types
::*;
18 use crate::clean
::utils
::print_const_expr
;
19 use crate::clean
::{self, ItemId}
;
20 use crate::formats
::item_type
::ItemType
;
21 use crate::json
::JsonRenderer
;
22 use crate::passes
::collect_intra_doc_links
::UrlFragment
;
24 impl JsonRenderer
<'_
> {
25 pub(super) fn convert_item(&self, item
: clean
::Item
) -> Option
<Item
> {
26 let deprecation
= item
.deprecation(self.tcx
);
33 .map(|clean
::ItemLink { link, page_id, fragment, .. }
| {
34 let id
= match fragment
{
35 Some(UrlFragment
::Item(frag_id
)) => *frag_id
,
36 // FIXME: Pass the `UserWritten` segment to JSON consumer.
37 Some(UrlFragment
::UserWritten(_
)) | None
=> *page_id
,
40 (link
.clone(), from_item_id(id
.into(), self.tcx
))
43 let docs
= item
.attrs
.collapsed_doc_value();
48 .map(rustc_ast_pretty
::pprust
::attribute_to_string
)
50 let span
= item
.span(self.tcx
);
51 let clean
::Item { name, attrs: _, kind: _, visibility, item_id, cfg: _ }
= item
;
52 let inner
= match *item
.kind
{
53 clean
::KeywordItem
=> return None
,
54 clean
::StrippedItem(ref inner
) => {
56 // We document stripped modules as with `Module::is_stripped` set to
57 // `true`, to prevent contained items from being orphaned for downstream users,
58 // as JSON does no inlining.
60 if self.imported_items
.contains(&item_id
.expect_def_id()) =>
62 from_clean_item(item
, self.tcx
)
67 _
=> from_clean_item(item
, self.tcx
),
70 id
: from_item_id_with_name(item_id
, self.tcx
, name
),
71 crate_id
: item_id
.krate().as_u32(),
72 name
: name
.map(|sym
| sym
.to_string()),
73 span
: span
.and_then(|span
| self.convert_span(span
)),
74 visibility
: self.convert_visibility(visibility
),
77 deprecation
: deprecation
.map(from_deprecation
),
83 fn convert_span(&self, span
: clean
::Span
) -> Option
<Span
> {
84 match span
.filename(self.sess()) {
85 rustc_span
::FileName
::Real(name
) => {
86 if let Some(local_path
) = name
.into_local_path() {
87 let hi
= span
.hi(self.sess());
88 let lo
= span
.lo(self.sess());
91 begin
: (lo
.line
, lo
.col
.to_usize()),
92 end
: (hi
.line
, hi
.col
.to_usize()),
102 fn convert_visibility(&self, v
: clean
::Visibility
) -> Visibility
{
103 use clean
::Visibility
::*;
105 Public
=> Visibility
::Public
,
106 Inherited
=> Visibility
::Default
,
107 Restricted(did
) if did
.is_crate_root() => Visibility
::Crate
,
108 Restricted(did
) => Visibility
::Restricted
{
109 parent
: from_item_id(did
.into(), self.tcx
),
110 path
: self.tcx
.def_path(did
).to_string_no_crate_verbose(),
116 pub(crate) trait FromWithTcx
<T
> {
117 fn from_tcx(f
: T
, tcx
: TyCtxt
<'_
>) -> Self;
120 pub(crate) trait IntoWithTcx
<T
> {
121 fn into_tcx(self, tcx
: TyCtxt
<'_
>) -> T
;
124 impl<T
, U
> IntoWithTcx
<U
> for T
128 fn into_tcx(self, tcx
: TyCtxt
<'_
>) -> U
{
129 U
::from_tcx(self, tcx
)
133 impl<I
, T
, U
> FromWithTcx
<I
> for Vec
<U
>
135 I
: IntoIterator
<Item
= T
>,
138 fn from_tcx(f
: I
, tcx
: TyCtxt
<'_
>) -> Vec
<U
> {
139 f
.into_iter().map(|x
| x
.into_tcx(tcx
)).collect()
143 pub(crate) fn from_deprecation(deprecation
: rustc_attr
::Deprecation
) -> Deprecation
{
145 let rustc_attr
::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ }
= deprecation
;
146 Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) }
149 impl FromWithTcx
<clean
::GenericArgs
> for GenericArgs
{
150 fn from_tcx(args
: clean
::GenericArgs
, tcx
: TyCtxt
<'_
>) -> Self {
151 use clean
::GenericArgs
::*;
153 AngleBracketed { args, bindings }
=> GenericArgs
::AngleBracketed
{
154 args
: args
.into_vec().into_tcx(tcx
),
155 bindings
: bindings
.into_tcx(tcx
),
157 Parenthesized { inputs, output }
=> GenericArgs
::Parenthesized
{
158 inputs
: inputs
.into_vec().into_tcx(tcx
),
159 output
: output
.map(|a
| (*a
).into_tcx(tcx
)),
165 impl FromWithTcx
<clean
::GenericArg
> for GenericArg
{
166 fn from_tcx(arg
: clean
::GenericArg
, tcx
: TyCtxt
<'_
>) -> Self {
167 use clean
::GenericArg
::*;
169 Lifetime(l
) => GenericArg
::Lifetime(convert_lifetime(l
)),
170 Type(t
) => GenericArg
::Type(t
.into_tcx(tcx
)),
171 Const(box c
) => GenericArg
::Const(c
.into_tcx(tcx
)),
172 Infer
=> GenericArg
::Infer
,
177 impl FromWithTcx
<clean
::Constant
> for Constant
{
178 fn from_tcx(constant
: clean
::Constant
, tcx
: TyCtxt
<'_
>) -> Self {
179 let expr
= constant
.expr(tcx
);
180 let value
= constant
.value(tcx
);
181 let is_literal
= constant
.is_literal(tcx
);
182 Constant { type_: constant.type_.into_tcx(tcx), expr, value, is_literal }
186 impl FromWithTcx
<clean
::TypeBinding
> for TypeBinding
{
187 fn from_tcx(binding
: clean
::TypeBinding
, tcx
: TyCtxt
<'_
>) -> Self {
189 name
: binding
.assoc
.name
.to_string(),
190 args
: binding
.assoc
.args
.into_tcx(tcx
),
191 binding
: binding
.kind
.into_tcx(tcx
),
196 impl FromWithTcx
<clean
::TypeBindingKind
> for TypeBindingKind
{
197 fn from_tcx(kind
: clean
::TypeBindingKind
, tcx
: TyCtxt
<'_
>) -> Self {
198 use clean
::TypeBindingKind
::*;
200 Equality { term }
=> TypeBindingKind
::Equality(term
.into_tcx(tcx
)),
201 Constraint { bounds }
=> TypeBindingKind
::Constraint(bounds
.into_tcx(tcx
)),
206 /// It generates an ID as follows:
208 /// `CRATE_ID:ITEM_ID[:NAME_ID]` (if there is no name, NAME_ID is not generated).
209 pub(crate) fn from_item_id(item_id
: ItemId
, tcx
: TyCtxt
<'_
>) -> Id
{
210 from_item_id_with_name(item_id
, tcx
, None
)
213 // FIXME: this function (and appending the name at the end of the ID) should be removed when
214 // reexports are not inlined anymore for json format. It should be done in #93518.
215 pub(crate) fn from_item_id_with_name(item_id
: ItemId
, tcx
: TyCtxt
<'_
>, name
: Option
<Symbol
>) -> Id
{
216 struct DisplayDefId
<'a
>(DefId
, TyCtxt
<'a
>, Option
<Symbol
>);
218 impl<'a
> fmt
::Display
for DisplayDefId
<'a
> {
219 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
220 let name
= match self.2 {
221 Some(name
) => format
!(":{}", name
.as_u32()),
224 .opt_item_name(self.0)
225 .map(|n
| format
!(":{}", n
.as_u32()))
226 .unwrap_or_default(),
228 write
!(f
, "{}:{}{}", self.0.krate
.as_u32(), u32::from(self.0.index
), name
)
233 ItemId
::DefId(did
) => Id(format
!("{}", DisplayDefId(did
, tcx
, name
))),
234 ItemId
::Blanket { for_, impl_id }
=> {
235 Id(format
!("b:{}-{}", DisplayDefId(impl_id
, tcx
, None
), DisplayDefId(for_
, tcx
, name
)))
237 ItemId
::Auto { for_, trait_ }
=> {
238 Id(format
!("a:{}-{}", DisplayDefId(trait_
, tcx
, None
), DisplayDefId(for_
, tcx
, name
)))
240 ItemId
::Primitive(ty
, krate
) => Id(format
!("p:{}:{}", krate
.as_u32(), ty
.as_sym())),
244 fn from_clean_item(item
: clean
::Item
, tcx
: TyCtxt
<'_
>) -> ItemEnum
{
245 use clean
::ItemKind
::*;
246 let name
= item
.name
;
247 let is_crate
= item
.is_crate();
248 let header
= item
.fn_header(tcx
);
252 ItemEnum
::Module(Module { is_crate, items: ids(m.items, tcx), is_stripped: false }
)
254 ImportItem(i
) => ItemEnum
::Import(i
.into_tcx(tcx
)),
255 StructItem(s
) => ItemEnum
::Struct(s
.into_tcx(tcx
)),
256 UnionItem(u
) => ItemEnum
::Union(u
.into_tcx(tcx
)),
257 StructFieldItem(f
) => ItemEnum
::StructField(f
.into_tcx(tcx
)),
258 EnumItem(e
) => ItemEnum
::Enum(e
.into_tcx(tcx
)),
259 VariantItem(v
) => ItemEnum
::Variant(v
.into_tcx(tcx
)),
260 FunctionItem(f
) => ItemEnum
::Function(from_function(f
, header
.unwrap(), tcx
)),
261 ForeignFunctionItem(f
) => ItemEnum
::Function(from_function(f
, header
.unwrap(), tcx
)),
262 TraitItem(t
) => ItemEnum
::Trait((*t
).into_tcx(tcx
)),
263 TraitAliasItem(t
) => ItemEnum
::TraitAlias(t
.into_tcx(tcx
)),
264 MethodItem(m
, _
) => ItemEnum
::Method(from_function_method(m
, true, header
.unwrap(), tcx
)),
265 TyMethodItem(m
) => ItemEnum
::Method(from_function_method(m
, false, header
.unwrap(), tcx
)),
266 ImplItem(i
) => ItemEnum
::Impl((*i
).into_tcx(tcx
)),
267 StaticItem(s
) => ItemEnum
::Static(s
.into_tcx(tcx
)),
268 ForeignStaticItem(s
) => ItemEnum
::Static(s
.into_tcx(tcx
)),
269 ForeignTypeItem
=> ItemEnum
::ForeignType
,
270 TypedefItem(t
) => ItemEnum
::Typedef(t
.into_tcx(tcx
)),
271 OpaqueTyItem(t
) => ItemEnum
::OpaqueTy(t
.into_tcx(tcx
)),
272 ConstantItem(c
) => ItemEnum
::Constant(c
.into_tcx(tcx
)),
273 MacroItem(m
) => ItemEnum
::Macro(m
.source
),
274 ProcMacroItem(m
) => ItemEnum
::ProcMacro(m
.into_tcx(tcx
)),
275 PrimitiveItem(p
) => ItemEnum
::PrimitiveType(p
.as_sym().to_string()),
276 TyAssocConstItem(ty
) => ItemEnum
::AssocConst { type_: ty.into_tcx(tcx), default: None }
,
277 AssocConstItem(ty
, default) => {
278 ItemEnum
::AssocConst { type_: ty.into_tcx(tcx), default: Some(default.expr(tcx)) }
280 TyAssocTypeItem(g
, b
) => ItemEnum
::AssocType
{
281 generics
: (*g
).into_tcx(tcx
),
282 bounds
: b
.into_tcx(tcx
),
285 AssocTypeItem(t
, b
) => ItemEnum
::AssocType
{
286 generics
: t
.generics
.into_tcx(tcx
),
287 bounds
: b
.into_tcx(tcx
),
288 default: Some(t
.item_type
.unwrap_or(t
.type_
).into_tcx(tcx
)),
290 // `convert_item` early returns `None` for stripped items and keywords.
291 KeywordItem
=> unreachable
!(),
292 StrippedItem(inner
) => {
294 ModuleItem(m
) => ItemEnum
::Module(Module
{
296 items
: ids(m
.items
, tcx
),
299 // `convert_item` early returns `None` for stripped items we're not including
303 ExternCrateItem { ref src }
=> ItemEnum
::ExternCrate
{
304 name
: name
.as_ref().unwrap().to_string(),
305 rename
: src
.map(|x
| x
.to_string()),
310 impl FromWithTcx
<clean
::Struct
> for Struct
{
311 fn from_tcx(struct_
: clean
::Struct
, tcx
: TyCtxt
<'_
>) -> Self {
312 let fields_stripped
= struct_
.has_stripped_entries();
313 let clean
::Struct { struct_type, generics, fields }
= struct_
;
315 let kind
= match struct_type
{
316 CtorKind
::Fn
=> StructKind
::Tuple(ids_keeping_stripped(fields
, tcx
)),
318 assert
!(fields
.is_empty());
321 CtorKind
::Fictive
=> StructKind
::Plain { fields: ids(fields, tcx), fields_stripped }
,
326 generics
: generics
.into_tcx(tcx
),
327 impls
: Vec
::new(), // Added in JsonRenderer::item
332 impl FromWithTcx
<clean
::Union
> for Union
{
333 fn from_tcx(union_
: clean
::Union
, tcx
: TyCtxt
<'_
>) -> Self {
334 let fields_stripped
= union_
.has_stripped_entries();
335 let clean
::Union { generics, fields }
= union_
;
337 generics
: generics
.into_tcx(tcx
),
339 fields
: ids(fields
, tcx
),
340 impls
: Vec
::new(), // Added in JsonRenderer::item
345 pub(crate) fn from_fn_header(header
: &rustc_hir
::FnHeader
) -> Header
{
347 async_
: header
.is_async(),
348 const_
: header
.is_const(),
349 unsafe_
: header
.is_unsafe(),
350 abi
: convert_abi(header
.abi
),
354 fn convert_abi(a
: RustcAbi
) -> Abi
{
356 RustcAbi
::Rust
=> Abi
::Rust
,
357 RustcAbi
::C { unwind }
=> Abi
::C { unwind }
,
358 RustcAbi
::Cdecl { unwind }
=> Abi
::Cdecl { unwind }
,
359 RustcAbi
::Stdcall { unwind }
=> Abi
::Stdcall { unwind }
,
360 RustcAbi
::Fastcall { unwind }
=> Abi
::Fastcall { unwind }
,
361 RustcAbi
::Aapcs { unwind }
=> Abi
::Aapcs { unwind }
,
362 RustcAbi
::Win64 { unwind }
=> Abi
::Win64 { unwind }
,
363 RustcAbi
::SysV64 { unwind }
=> Abi
::SysV64 { unwind }
,
364 RustcAbi
::System { unwind }
=> Abi
::System { unwind }
,
365 _
=> Abi
::Other(a
.to_string()),
369 fn convert_lifetime(l
: clean
::Lifetime
) -> String
{
373 impl FromWithTcx
<clean
::Generics
> for Generics
{
374 fn from_tcx(generics
: clean
::Generics
, tcx
: TyCtxt
<'_
>) -> Self {
376 params
: generics
.params
.into_tcx(tcx
),
377 where_predicates
: generics
.where_predicates
.into_tcx(tcx
),
382 impl FromWithTcx
<clean
::GenericParamDef
> for GenericParamDef
{
383 fn from_tcx(generic_param
: clean
::GenericParamDef
, tcx
: TyCtxt
<'_
>) -> Self {
385 name
: generic_param
.name
.to_string(),
386 kind
: generic_param
.kind
.into_tcx(tcx
),
391 impl FromWithTcx
<clean
::GenericParamDefKind
> for GenericParamDefKind
{
392 fn from_tcx(kind
: clean
::GenericParamDefKind
, tcx
: TyCtxt
<'_
>) -> Self {
393 use clean
::GenericParamDefKind
::*;
395 Lifetime { outlives }
=> GenericParamDefKind
::Lifetime
{
396 outlives
: outlives
.into_iter().map(convert_lifetime
).collect(),
398 Type { did: _, bounds, default, synthetic }
=> GenericParamDefKind
::Type
{
399 bounds
: bounds
.into_tcx(tcx
),
400 default: default.map(|x
| (*x
).into_tcx(tcx
)),
403 Const { did: _, ty, default }
=> GenericParamDefKind
::Const
{
404 type_
: (*ty
).into_tcx(tcx
),
405 default: default.map(|x
| *x
),
411 impl FromWithTcx
<clean
::WherePredicate
> for WherePredicate
{
412 fn from_tcx(predicate
: clean
::WherePredicate
, tcx
: TyCtxt
<'_
>) -> Self {
413 use clean
::WherePredicate
::*;
415 BoundPredicate { ty, bounds, bound_params }
=> WherePredicate
::BoundPredicate
{
416 type_
: ty
.into_tcx(tcx
),
417 bounds
: bounds
.into_tcx(tcx
),
418 generic_params
: bound_params
420 .map(|x
| GenericParamDef
{
421 name
: x
.0.to_string(),
422 kind
: GenericParamDefKind
::Lifetime { outlives: vec![] }
,
426 RegionPredicate { lifetime, bounds }
=> WherePredicate
::RegionPredicate
{
427 lifetime
: convert_lifetime(lifetime
),
428 bounds
: bounds
.into_tcx(tcx
),
430 EqPredicate { lhs, rhs }
=> {
431 WherePredicate
::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) }
437 impl FromWithTcx
<clean
::GenericBound
> for GenericBound
{
438 fn from_tcx(bound
: clean
::GenericBound
, tcx
: TyCtxt
<'_
>) -> Self {
439 use clean
::GenericBound
::*;
441 TraitBound(clean
::PolyTrait { trait_, generic_params }
, modifier
) => {
442 GenericBound
::TraitBound
{
443 trait_
: trait_
.into_tcx(tcx
),
444 generic_params
: generic_params
.into_tcx(tcx
),
445 modifier
: from_trait_bound_modifier(modifier
),
448 Outlives(lifetime
) => GenericBound
::Outlives(convert_lifetime(lifetime
)),
453 pub(crate) fn from_trait_bound_modifier(
454 modifier
: rustc_hir
::TraitBoundModifier
,
455 ) -> TraitBoundModifier
{
456 use rustc_hir
::TraitBoundModifier
::*;
458 None
=> TraitBoundModifier
::None
,
459 Maybe
=> TraitBoundModifier
::Maybe
,
460 MaybeConst
=> TraitBoundModifier
::MaybeConst
,
464 impl FromWithTcx
<clean
::Type
> for Type
{
465 fn from_tcx(ty
: clean
::Type
, tcx
: TyCtxt
<'_
>) -> Self {
467 Array
, BareFunction
, BorrowedRef
, Generic
, ImplTrait
, Infer
, Primitive
, QPath
,
468 RawPointer
, Slice
, Tuple
,
472 clean
::Type
::Path { path }
=> Type
::ResolvedPath(path
.into_tcx(tcx
)),
473 clean
::Type
::DynTrait(bounds
, lt
) => Type
::DynTrait(DynTrait
{
474 lifetime
: lt
.map(convert_lifetime
),
475 traits
: bounds
.into_tcx(tcx
),
477 Generic(s
) => Type
::Generic(s
.to_string()),
478 Primitive(p
) => Type
::Primitive(p
.as_sym().to_string()),
479 BareFunction(f
) => Type
::FunctionPointer(Box
::new((*f
).into_tcx(tcx
))),
480 Tuple(t
) => Type
::Tuple(t
.into_tcx(tcx
)),
481 Slice(t
) => Type
::Slice(Box
::new((*t
).into_tcx(tcx
))),
482 Array(t
, s
) => Type
::Array { type_: Box::new((*t).into_tcx(tcx)), len: s }
,
483 ImplTrait(g
) => Type
::ImplTrait(g
.into_tcx(tcx
)),
484 Infer
=> Type
::Infer
,
485 RawPointer(mutability
, type_
) => Type
::RawPointer
{
486 mutable
: mutability
== ast
::Mutability
::Mut
,
487 type_
: Box
::new((*type_
).into_tcx(tcx
)),
489 BorrowedRef { lifetime, mutability, type_ }
=> Type
::BorrowedRef
{
490 lifetime
: lifetime
.map(convert_lifetime
),
491 mutable
: mutability
== ast
::Mutability
::Mut
,
492 type_
: Box
::new((*type_
).into_tcx(tcx
)),
494 QPath(box clean
::QPathData { assoc, self_type, trait_, .. }
) => Type
::QualifiedPath
{
495 name
: assoc
.name
.to_string(),
496 args
: Box
::new(assoc
.args
.into_tcx(tcx
)),
497 self_type
: Box
::new(self_type
.into_tcx(tcx
)),
498 trait_
: trait_
.into_tcx(tcx
),
504 impl FromWithTcx
<clean
::Path
> for Path
{
505 fn from_tcx(path
: clean
::Path
, tcx
: TyCtxt
<'_
>) -> Path
{
507 name
: path
.whole_name(),
508 id
: from_item_id(path
.def_id().into(), tcx
),
509 args
: path
.segments
.last().map(|args
| Box
::new(args
.clone().args
.into_tcx(tcx
))),
514 impl FromWithTcx
<clean
::Term
> for Term
{
515 fn from_tcx(term
: clean
::Term
, tcx
: TyCtxt
<'_
>) -> Term
{
517 clean
::Term
::Type(ty
) => Term
::Type(FromWithTcx
::from_tcx(ty
, tcx
)),
518 clean
::Term
::Constant(c
) => Term
::Constant(FromWithTcx
::from_tcx(c
, tcx
)),
523 impl FromWithTcx
<clean
::BareFunctionDecl
> for FunctionPointer
{
524 fn from_tcx(bare_decl
: clean
::BareFunctionDecl
, tcx
: TyCtxt
<'_
>) -> Self {
525 let clean
::BareFunctionDecl { unsafety, generic_params, decl, abi }
= bare_decl
;
528 unsafe_
: matches
!(unsafety
, rustc_hir
::Unsafety
::Unsafe
),
531 abi
: convert_abi(abi
),
533 generic_params
: generic_params
.into_tcx(tcx
),
534 decl
: decl
.into_tcx(tcx
),
539 impl FromWithTcx
<clean
::FnDecl
> for FnDecl
{
540 fn from_tcx(decl
: clean
::FnDecl
, tcx
: TyCtxt
<'_
>) -> Self {
541 let clean
::FnDecl { inputs, output, c_variadic }
= decl
;
546 .map(|arg
| (arg
.name
.to_string(), arg
.type_
.into_tcx(tcx
)))
548 output
: match output
{
549 clean
::FnRetTy
::Return(t
) => Some(t
.into_tcx(tcx
)),
550 clean
::FnRetTy
::DefaultReturn
=> None
,
557 impl FromWithTcx
<clean
::Trait
> for Trait
{
558 fn from_tcx(trait_
: clean
::Trait
, tcx
: TyCtxt
<'_
>) -> Self {
559 let is_auto
= trait_
.is_auto(tcx
);
560 let is_unsafe
= trait_
.unsafety(tcx
) == rustc_hir
::Unsafety
::Unsafe
;
561 let clean
::Trait { items, generics, bounds, .. }
= trait_
;
565 items
: ids(items
, tcx
),
566 generics
: generics
.into_tcx(tcx
),
567 bounds
: bounds
.into_tcx(tcx
),
568 implementations
: Vec
::new(), // Added in JsonRenderer::item
573 impl FromWithTcx
<clean
::PolyTrait
> for PolyTrait
{
575 clean
::PolyTrait { trait_, generic_params }
: clean
::PolyTrait
,
578 PolyTrait { trait_: trait_.into_tcx(tcx), generic_params: generic_params.into_tcx(tcx) }
582 impl FromWithTcx
<clean
::Impl
> for Impl
{
583 fn from_tcx(impl_
: clean
::Impl
, tcx
: TyCtxt
<'_
>) -> Self {
584 let provided_trait_methods
= impl_
.provided_trait_methods(tcx
);
585 let clean
::Impl { unsafety, generics, trait_, for_, items, polarity, kind }
= impl_
;
586 // FIXME: use something like ImplKind in JSON?
587 let (synthetic
, blanket_impl
) = match kind
{
588 clean
::ImplKind
::Normal
| clean
::ImplKind
::FakeVaradic
=> (false, None
),
589 clean
::ImplKind
::Auto
=> (true, None
),
590 clean
::ImplKind
::Blanket(ty
) => (false, Some(*ty
)),
592 let negative_polarity
= match polarity
{
593 ty
::ImplPolarity
::Positive
| ty
::ImplPolarity
::Reservation
=> false,
594 ty
::ImplPolarity
::Negative
=> true,
597 is_unsafe
: unsafety
== rustc_hir
::Unsafety
::Unsafe
,
598 generics
: generics
.into_tcx(tcx
),
599 provided_trait_methods
: provided_trait_methods
601 .map(|x
| x
.to_string())
603 trait_
: trait_
.map(|path
| path
.into_tcx(tcx
)),
604 for_
: for_
.into_tcx(tcx
),
605 items
: ids(items
, tcx
),
606 negative
: negative_polarity
,
608 blanket_impl
: blanket_impl
.map(|x
| x
.into_tcx(tcx
)),
613 pub(crate) fn from_function(
614 function
: Box
<clean
::Function
>,
615 header
: rustc_hir
::FnHeader
,
618 let clean
::Function { decl, generics }
= *function
;
620 decl
: decl
.into_tcx(tcx
),
621 generics
: generics
.into_tcx(tcx
),
622 header
: from_fn_header(&header
),
626 pub(crate) fn from_function_method(
627 function
: Box
<clean
::Function
>,
629 header
: rustc_hir
::FnHeader
,
632 let clean
::Function { decl, generics }
= *function
;
634 decl
: decl
.into_tcx(tcx
),
635 generics
: generics
.into_tcx(tcx
),
636 header
: from_fn_header(&header
),
641 impl FromWithTcx
<clean
::Enum
> for Enum
{
642 fn from_tcx(enum_
: clean
::Enum
, tcx
: TyCtxt
<'_
>) -> Self {
643 let variants_stripped
= enum_
.has_stripped_entries();
644 let clean
::Enum { variants, generics }
= enum_
;
646 generics
: generics
.into_tcx(tcx
),
648 variants
: ids(variants
, tcx
),
649 impls
: Vec
::new(), // Added in JsonRenderer::item
654 impl FromWithTcx
<clean
::Variant
> for Variant
{
655 fn from_tcx(variant
: clean
::Variant
, tcx
: TyCtxt
<'_
>) -> Self {
656 use clean
::Variant
::*;
658 CLike(disr
) => Variant
::Plain(disr
.map(|disr
| disr
.into_tcx(tcx
))),
659 Tuple(fields
) => Variant
::Tuple(ids_keeping_stripped(fields
, tcx
)),
660 Struct(s
) => Variant
::Struct
{
661 fields_stripped
: s
.has_stripped_entries(),
662 fields
: ids(s
.fields
, tcx
),
668 impl FromWithTcx
<clean
::Discriminant
> for Discriminant
{
669 fn from_tcx(disr
: clean
::Discriminant
, tcx
: TyCtxt
<'_
>) -> Self {
671 // expr is only none if going throught the inlineing path, which gets
672 // `rustc_middle` types, not `rustc_hir`, but because JSON never inlines
673 // the expr is always some.
674 expr
: disr
.expr(tcx
).unwrap(),
675 value
: disr
.value(tcx
),
680 impl FromWithTcx
<clean
::Import
> for Import
{
681 fn from_tcx(import
: clean
::Import
, tcx
: TyCtxt
<'_
>) -> Self {
682 use clean
::ImportKind
::*;
683 let (name
, glob
) = match import
.kind
{
684 Simple(s
) => (s
.to_string(), false),
686 import
.source
.path
.last_opt().unwrap_or_else(|| Symbol
::intern("*")).to_string(),
691 source
: import
.source
.path
.whole_name(),
693 id
: import
.source
.did
.map(ItemId
::from
).map(|i
| from_item_id(i
, tcx
)),
699 impl FromWithTcx
<clean
::ProcMacro
> for ProcMacro
{
700 fn from_tcx(mac
: clean
::ProcMacro
, _tcx
: TyCtxt
<'_
>) -> Self {
702 kind
: from_macro_kind(mac
.kind
),
703 helpers
: mac
.helpers
.iter().map(|x
| x
.to_string()).collect(),
708 pub(crate) fn from_macro_kind(kind
: rustc_span
::hygiene
::MacroKind
) -> MacroKind
{
709 use rustc_span
::hygiene
::MacroKind
::*;
711 Bang
=> MacroKind
::Bang
,
712 Attr
=> MacroKind
::Attr
,
713 Derive
=> MacroKind
::Derive
,
717 impl FromWithTcx
<Box
<clean
::Typedef
>> for Typedef
{
718 fn from_tcx(typedef
: Box
<clean
::Typedef
>, tcx
: TyCtxt
<'_
>) -> Self {
719 let clean
::Typedef { type_, generics, item_type: _ }
= *typedef
;
720 Typedef { type_: type_.into_tcx(tcx), generics: generics.into_tcx(tcx) }
724 impl FromWithTcx
<clean
::OpaqueTy
> for OpaqueTy
{
725 fn from_tcx(opaque
: clean
::OpaqueTy
, tcx
: TyCtxt
<'_
>) -> Self {
726 OpaqueTy { bounds: opaque.bounds.into_tcx(tcx), generics: opaque.generics.into_tcx(tcx) }
730 impl FromWithTcx
<clean
::Static
> for Static
{
731 fn from_tcx(stat
: clean
::Static
, tcx
: TyCtxt
<'_
>) -> Self {
733 type_
: stat
.type_
.into_tcx(tcx
),
734 mutable
: stat
.mutability
== ast
::Mutability
::Mut
,
735 expr
: stat
.expr
.map(|e
| print_const_expr(tcx
, e
)).unwrap_or_default(),
740 impl FromWithTcx
<clean
::TraitAlias
> for TraitAlias
{
741 fn from_tcx(alias
: clean
::TraitAlias
, tcx
: TyCtxt
<'_
>) -> Self {
742 TraitAlias { generics: alias.generics.into_tcx(tcx), params: alias.bounds.into_tcx(tcx) }
746 impl FromWithTcx
<ItemType
> for ItemKind
{
747 fn from_tcx(kind
: ItemType
, _tcx
: TyCtxt
<'_
>) -> Self {
750 Module
=> ItemKind
::Module
,
751 ExternCrate
=> ItemKind
::ExternCrate
,
752 Import
=> ItemKind
::Import
,
753 Struct
=> ItemKind
::Struct
,
754 Union
=> ItemKind
::Union
,
755 Enum
=> ItemKind
::Enum
,
756 Function
=> ItemKind
::Function
,
757 Typedef
=> ItemKind
::Typedef
,
758 OpaqueTy
=> ItemKind
::OpaqueTy
,
759 Static
=> ItemKind
::Static
,
760 Constant
=> ItemKind
::Constant
,
761 Trait
=> ItemKind
::Trait
,
762 Impl
=> ItemKind
::Impl
,
763 TyMethod
| Method
=> ItemKind
::Method
,
764 StructField
=> ItemKind
::StructField
,
765 Variant
=> ItemKind
::Variant
,
766 Macro
=> ItemKind
::Macro
,
767 Primitive
=> ItemKind
::Primitive
,
768 AssocConst
=> ItemKind
::AssocConst
,
769 AssocType
=> ItemKind
::AssocType
,
770 ForeignType
=> ItemKind
::ForeignType
,
771 Keyword
=> ItemKind
::Keyword
,
772 TraitAlias
=> ItemKind
::TraitAlias
,
773 ProcAttribute
=> ItemKind
::ProcAttribute
,
774 ProcDerive
=> ItemKind
::ProcDerive
,
779 fn ids(items
: impl IntoIterator
<Item
= clean
::Item
>, tcx
: TyCtxt
<'_
>) -> Vec
<Id
> {
782 .filter(|x
| !x
.is_stripped() && !x
.is_keyword())
783 .map(|i
| from_item_id_with_name(i
.item_id
, tcx
, i
.name
))
787 fn ids_keeping_stripped(
788 items
: impl IntoIterator
<Item
= clean
::Item
>,
790 ) -> Vec
<Option
<Id
>> {
794 if !i
.is_stripped() && !i
.is_keyword() {
795 Some(from_item_id_with_name(i
.item_id
, tcx
, i
.name
))