]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/item_tree.rs
Fix recursive macro statement expansion
[rust.git] / crates / hir_def / src / item_tree.rs
1 //! A simplified AST that only contains items.
2
3 mod lower;
4
5 use std::{
6     any::type_name,
7     fmt::{self, Debug},
8     hash::{Hash, Hasher},
9     marker::PhantomData,
10     ops::{Index, Range},
11     sync::Arc,
12 };
13
14 use ast::{AstNode, NameOwner, StructKind};
15 use base_db::CrateId;
16 use either::Either;
17 use hir_expand::{
18     ast_id_map::FileAstId,
19     hygiene::Hygiene,
20     name::{name, AsName, Name},
21     HirFileId, InFile,
22 };
23 use la_arena::{Arena, Idx, RawIdx};
24 use profile::Count;
25 use rustc_hash::FxHashMap;
26 use smallvec::SmallVec;
27 use syntax::{ast, match_ast, SmolStr, SyntaxKind};
28
29 use crate::{
30     attr::{Attrs, RawAttrs},
31     db::DefDatabase,
32     generics::GenericParams,
33     path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
34     type_ref::{Mutability, TypeBound, TypeRef},
35     visibility::RawVisibility,
36 };
37
38 #[derive(Copy, Clone, Eq, PartialEq)]
39 pub struct RawVisibilityId(u32);
40
41 impl RawVisibilityId {
42     pub const PUB: Self = RawVisibilityId(u32::max_value());
43     pub const PRIV: Self = RawVisibilityId(u32::max_value() - 1);
44     pub const PUB_CRATE: Self = RawVisibilityId(u32::max_value() - 2);
45 }
46
47 impl fmt::Debug for RawVisibilityId {
48     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49         let mut f = f.debug_tuple("RawVisibilityId");
50         match *self {
51             Self::PUB => f.field(&"pub"),
52             Self::PRIV => f.field(&"pub(self)"),
53             Self::PUB_CRATE => f.field(&"pub(crate)"),
54             _ => f.field(&self.0),
55         };
56         f.finish()
57     }
58 }
59
60 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
61 pub struct GenericParamsId(u32);
62
63 impl GenericParamsId {
64     pub const EMPTY: Self = GenericParamsId(u32::max_value());
65 }
66
67 /// The item tree of a source file.
68 #[derive(Debug, Default, Eq, PartialEq)]
69 pub struct ItemTree {
70     _c: Count<Self>,
71
72     top_level: SmallVec<[ModItem; 1]>,
73     attrs: FxHashMap<AttrOwner, RawAttrs>,
74
75     data: Option<Box<ItemTreeData>>,
76 }
77
78 impl ItemTree {
79     pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
80         let _p = profile::span("item_tree_query").detail(|| format!("{:?}", file_id));
81         let syntax = if let Some(node) = db.parse_or_expand(file_id) {
82             if node.kind() == SyntaxKind::ERROR {
83                 // FIXME: not 100% sure why these crop up, but return an empty tree to avoid a panic
84                 return Default::default();
85             }
86             node
87         } else {
88             return Default::default();
89         };
90
91         let hygiene = Hygiene::new(db.upcast(), file_id);
92         let ctx = lower::Ctx::new(db, hygiene.clone(), file_id);
93         let mut top_attrs = None;
94         let mut item_tree = match_ast! {
95             match syntax {
96                 ast::SourceFile(file) => {
97                     top_attrs = Some(RawAttrs::new(&file, &hygiene));
98                     ctx.lower_module_items(&file)
99                 },
100                 ast::MacroItems(items) => {
101                     ctx.lower_module_items(&items)
102                 },
103                 ast::MacroStmts(stmts) => {
104                     // The produced statements can include items, which should be added as top-level
105                     // items.
106                     ctx.lower_macro_stmts(stmts)
107                 },
108                 ast::Expr(e) => {
109                     // Macros can expand to expressions. We return an empty item tree in this case, but
110                     // still need to collect inner items.
111                     ctx.lower_inner_items(e.syntax())
112                 },
113                 _ => {
114                     panic!("cannot create item tree from {:?} {}", syntax, syntax);
115                 },
116             }
117         };
118
119         if let Some(attrs) = top_attrs {
120             item_tree.attrs.insert(AttrOwner::TopLevel, attrs);
121         }
122         item_tree.shrink_to_fit();
123         Arc::new(item_tree)
124     }
125
126     fn shrink_to_fit(&mut self) {
127         if let Some(data) = &mut self.data {
128             let ItemTreeData {
129                 imports,
130                 extern_crates,
131                 functions,
132                 params,
133                 structs,
134                 fields,
135                 unions,
136                 enums,
137                 variants,
138                 consts,
139                 statics,
140                 traits,
141                 impls,
142                 type_aliases,
143                 mods,
144                 macro_calls,
145                 macro_rules,
146                 macro_defs,
147                 vis,
148                 generics,
149                 type_refs,
150                 inner_items,
151             } = &mut **data;
152
153             imports.shrink_to_fit();
154             extern_crates.shrink_to_fit();
155             functions.shrink_to_fit();
156             params.shrink_to_fit();
157             structs.shrink_to_fit();
158             fields.shrink_to_fit();
159             unions.shrink_to_fit();
160             enums.shrink_to_fit();
161             variants.shrink_to_fit();
162             consts.shrink_to_fit();
163             statics.shrink_to_fit();
164             traits.shrink_to_fit();
165             impls.shrink_to_fit();
166             type_aliases.shrink_to_fit();
167             mods.shrink_to_fit();
168             macro_calls.shrink_to_fit();
169             macro_rules.shrink_to_fit();
170             macro_defs.shrink_to_fit();
171
172             vis.arena.shrink_to_fit();
173             generics.arena.shrink_to_fit();
174             type_refs.arena.shrink_to_fit();
175             type_refs.map.shrink_to_fit();
176
177             inner_items.shrink_to_fit();
178         }
179     }
180
181     /// Returns an iterator over all items located at the top level of the `HirFileId` this
182     /// `ItemTree` was created from.
183     pub fn top_level_items(&self) -> &[ModItem] {
184         &self.top_level
185     }
186
187     /// Returns the inner attributes of the source file.
188     pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
189         self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone().filter(db, krate)
190     }
191
192     pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs {
193         self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY)
194     }
195
196     pub fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs {
197         self.raw_attrs(of).clone().filter(db, krate)
198     }
199
200     pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ {
201         match &self.data {
202             Some(data) => Some(data.inner_items.values().flatten().copied()).into_iter().flatten(),
203             None => None.into_iter().flatten(),
204         }
205     }
206
207     pub fn inner_items_of_block(&self, block: FileAstId<ast::BlockExpr>) -> &[ModItem] {
208         match &self.data {
209             Some(data) => data.inner_items.get(&block).map(|it| &**it).unwrap_or(&[]),
210             None => &[],
211         }
212     }
213
214     fn data(&self) -> &ItemTreeData {
215         self.data.as_ref().expect("attempted to access data of empty ItemTree")
216     }
217
218     fn data_mut(&mut self) -> &mut ItemTreeData {
219         self.data.get_or_insert_with(Box::default)
220     }
221 }
222
223 #[derive(Default, Debug, Eq, PartialEq)]
224 struct ItemVisibilities {
225     arena: Arena<RawVisibility>,
226 }
227
228 impl ItemVisibilities {
229     fn alloc(&mut self, vis: RawVisibility) -> RawVisibilityId {
230         match &vis {
231             RawVisibility::Public => RawVisibilityId::PUB,
232             RawVisibility::Module(path) if path.segments().is_empty() => match &path.kind {
233                 PathKind::Super(0) => RawVisibilityId::PRIV,
234                 PathKind::Crate => RawVisibilityId::PUB_CRATE,
235                 _ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()),
236             },
237             _ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()),
238         }
239     }
240 }
241
242 static VIS_PUB: RawVisibility = RawVisibility::Public;
243 static VIS_PRIV: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)));
244 static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate));
245
246 #[derive(Default, Debug, Eq, PartialEq)]
247 struct GenericParamsStorage {
248     arena: Arena<GenericParams>,
249 }
250
251 impl GenericParamsStorage {
252     fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
253         if params.types.is_empty()
254             && params.lifetimes.is_empty()
255             && params.consts.is_empty()
256             && params.where_predicates.is_empty()
257         {
258             return GenericParamsId::EMPTY;
259         }
260
261         GenericParamsId(self.arena.alloc(params).into_raw().into())
262     }
263 }
264
265 static EMPTY_GENERICS: GenericParams = GenericParams {
266     types: Arena::new(),
267     lifetimes: Arena::new(),
268     consts: Arena::new(),
269     where_predicates: Vec::new(),
270 };
271
272 /// `TypeRef` interner.
273 #[derive(Default, Debug, Eq, PartialEq)]
274 struct TypeRefStorage {
275     arena: Arena<Arc<TypeRef>>,
276     map: FxHashMap<Arc<TypeRef>, Idx<Arc<TypeRef>>>,
277 }
278
279 impl TypeRefStorage {
280     // Note: We lie about the `Idx<TypeRef>` to hide the interner details.
281
282     fn intern(&mut self, ty: TypeRef) -> Idx<TypeRef> {
283         if let Some(id) = self.map.get(&ty) {
284             return Idx::from_raw(id.into_raw());
285         }
286
287         let ty = Arc::new(ty);
288         let idx = self.arena.alloc(ty.clone());
289         self.map.insert(ty, idx);
290         Idx::from_raw(idx.into_raw())
291     }
292
293     fn lookup(&self, id: Idx<TypeRef>) -> &TypeRef {
294         &self.arena[Idx::from_raw(id.into_raw())]
295     }
296 }
297
298 #[derive(Default, Debug, Eq, PartialEq)]
299 struct ItemTreeData {
300     imports: Arena<Import>,
301     extern_crates: Arena<ExternCrate>,
302     functions: Arena<Function>,
303     params: Arena<Param>,
304     structs: Arena<Struct>,
305     fields: Arena<Field>,
306     unions: Arena<Union>,
307     enums: Arena<Enum>,
308     variants: Arena<Variant>,
309     consts: Arena<Const>,
310     statics: Arena<Static>,
311     traits: Arena<Trait>,
312     impls: Arena<Impl>,
313     type_aliases: Arena<TypeAlias>,
314     mods: Arena<Mod>,
315     macro_calls: Arena<MacroCall>,
316     macro_rules: Arena<MacroRules>,
317     macro_defs: Arena<MacroDef>,
318
319     vis: ItemVisibilities,
320     generics: GenericParamsStorage,
321     type_refs: TypeRefStorage,
322
323     inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
324 }
325
326 #[derive(Debug, Eq, PartialEq, Hash)]
327 pub enum AttrOwner {
328     /// Attributes on an item.
329     ModItem(ModItem),
330     /// Inner attributes of the source file.
331     TopLevel,
332
333     Variant(Idx<Variant>),
334     Field(Idx<Field>),
335     Param(Idx<Param>),
336 }
337
338 macro_rules! from_attrs {
339     ( $( $var:ident($t:ty) ),+ ) => {
340         $(
341             impl From<$t> for AttrOwner {
342                 fn from(t: $t) -> AttrOwner {
343                     AttrOwner::$var(t)
344                 }
345             }
346         )+
347     };
348 }
349
350 from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>), Param(Idx<Param>));
351
352 /// Trait implemented by all item nodes in the item tree.
353 pub trait ItemTreeNode: Clone {
354     type Source: AstNode + Into<ast::Item>;
355
356     fn ast_id(&self) -> FileAstId<Self::Source>;
357
358     /// Looks up an instance of `Self` in an item tree.
359     fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self;
360
361     /// Downcasts a `ModItem` to a `FileItemTreeId` specific to this type.
362     fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>>;
363
364     /// Upcasts a `FileItemTreeId` to a generic `ModItem`.
365     fn id_to_mod_item(id: FileItemTreeId<Self>) -> ModItem;
366 }
367
368 pub struct FileItemTreeId<N: ItemTreeNode> {
369     index: Idx<N>,
370     _p: PhantomData<N>,
371 }
372
373 impl<N: ItemTreeNode> Clone for FileItemTreeId<N> {
374     fn clone(&self) -> Self {
375         Self { index: self.index, _p: PhantomData }
376     }
377 }
378 impl<N: ItemTreeNode> Copy for FileItemTreeId<N> {}
379
380 impl<N: ItemTreeNode> PartialEq for FileItemTreeId<N> {
381     fn eq(&self, other: &FileItemTreeId<N>) -> bool {
382         self.index == other.index
383     }
384 }
385 impl<N: ItemTreeNode> Eq for FileItemTreeId<N> {}
386
387 impl<N: ItemTreeNode> Hash for FileItemTreeId<N> {
388     fn hash<H: Hasher>(&self, state: &mut H) {
389         self.index.hash(state)
390     }
391 }
392
393 impl<N: ItemTreeNode> fmt::Debug for FileItemTreeId<N> {
394     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395         self.index.fmt(f)
396     }
397 }
398
399 #[derive(Debug)]
400 pub struct ItemTreeId<N: ItemTreeNode> {
401     file: HirFileId,
402     pub value: FileItemTreeId<N>,
403 }
404
405 impl<N: ItemTreeNode> ItemTreeId<N> {
406     pub fn new(file: HirFileId, idx: FileItemTreeId<N>) -> Self {
407         Self { file, value: idx }
408     }
409
410     pub fn file_id(self) -> HirFileId {
411         self.file
412     }
413
414     pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
415         db.file_item_tree(self.file)
416     }
417 }
418
419 impl<N: ItemTreeNode> Copy for ItemTreeId<N> {}
420 impl<N: ItemTreeNode> Clone for ItemTreeId<N> {
421     fn clone(&self) -> Self {
422         *self
423     }
424 }
425
426 impl<N: ItemTreeNode> PartialEq for ItemTreeId<N> {
427     fn eq(&self, other: &Self) -> bool {
428         self.file == other.file && self.value == other.value
429     }
430 }
431
432 impl<N: ItemTreeNode> Eq for ItemTreeId<N> {}
433
434 impl<N: ItemTreeNode> Hash for ItemTreeId<N> {
435     fn hash<H: Hasher>(&self, state: &mut H) {
436         self.file.hash(state);
437         self.value.hash(state);
438     }
439 }
440
441 macro_rules! mod_items {
442     ( $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => {
443         #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
444         pub enum ModItem {
445             $(
446                 $typ(FileItemTreeId<$typ>),
447             )+
448         }
449
450         $(
451             impl From<FileItemTreeId<$typ>> for ModItem {
452                 fn from(id: FileItemTreeId<$typ>) -> ModItem {
453                     ModItem::$typ(id)
454                 }
455             }
456         )+
457
458         $(
459             impl ItemTreeNode for $typ {
460                 type Source = $ast;
461
462                 fn ast_id(&self) -> FileAstId<Self::Source> {
463                     self.ast_id
464                 }
465
466                 fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
467                     &tree.data().$fld[index]
468                 }
469
470                 fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>> {
471                     if let ModItem::$typ(id) = mod_item {
472                         Some(id)
473                     } else {
474                         None
475                     }
476                 }
477
478                 fn id_to_mod_item(id: FileItemTreeId<Self>) -> ModItem {
479                     ModItem::$typ(id)
480                 }
481             }
482
483             impl Index<Idx<$typ>> for ItemTree {
484                 type Output = $typ;
485
486                 fn index(&self, index: Idx<$typ>) -> &Self::Output {
487                     &self.data().$fld[index]
488                 }
489             }
490         )+
491     };
492 }
493
494 mod_items! {
495     Import in imports -> ast::Use,
496     ExternCrate in extern_crates -> ast::ExternCrate,
497     Function in functions -> ast::Fn,
498     Struct in structs -> ast::Struct,
499     Union in unions -> ast::Union,
500     Enum in enums -> ast::Enum,
501     Const in consts -> ast::Const,
502     Static in statics -> ast::Static,
503     Trait in traits -> ast::Trait,
504     Impl in impls -> ast::Impl,
505     TypeAlias in type_aliases -> ast::TypeAlias,
506     Mod in mods -> ast::Module,
507     MacroCall in macro_calls -> ast::MacroCall,
508     MacroRules in macro_rules -> ast::MacroRules,
509     MacroDef in macro_defs -> ast::MacroDef,
510 }
511
512 macro_rules! impl_index {
513     ( $($fld:ident: $t:ty),+ $(,)? ) => {
514         $(
515             impl Index<Idx<$t>> for ItemTree {
516                 type Output = $t;
517
518                 fn index(&self, index: Idx<$t>) -> &Self::Output {
519                     &self.data().$fld[index]
520                 }
521             }
522         )+
523     };
524 }
525
526 impl_index!(fields: Field, variants: Variant, params: Param);
527
528 impl Index<RawVisibilityId> for ItemTree {
529     type Output = RawVisibility;
530     fn index(&self, index: RawVisibilityId) -> &Self::Output {
531         match index {
532             RawVisibilityId::PRIV => &VIS_PRIV,
533             RawVisibilityId::PUB => &VIS_PUB,
534             RawVisibilityId::PUB_CRATE => &VIS_PUB_CRATE,
535             _ => &self.data().vis.arena[Idx::from_raw(index.0.into())],
536         }
537     }
538 }
539
540 impl Index<GenericParamsId> for ItemTree {
541     type Output = GenericParams;
542
543     fn index(&self, index: GenericParamsId) -> &Self::Output {
544         match index {
545             GenericParamsId::EMPTY => &EMPTY_GENERICS,
546             _ => &self.data().generics.arena[Idx::from_raw(index.0.into())],
547         }
548     }
549 }
550
551 impl Index<Idx<TypeRef>> for ItemTree {
552     type Output = TypeRef;
553
554     fn index(&self, id: Idx<TypeRef>) -> &Self::Output {
555         self.data().type_refs.lookup(id)
556     }
557 }
558
559 impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
560     type Output = N;
561     fn index(&self, id: FileItemTreeId<N>) -> &N {
562         N::lookup(self, id.index)
563     }
564 }
565
566 /// A desugared `use` import.
567 #[derive(Debug, Clone, Eq, PartialEq)]
568 pub struct Import {
569     pub path: ModPath,
570     pub alias: Option<ImportAlias>,
571     pub visibility: RawVisibilityId,
572     pub is_glob: bool,
573     /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many
574     /// `Import`s can map to the same `use` item.
575     pub ast_id: FileAstId<ast::Use>,
576     /// Index of this `Import` when the containing `Use` is visited via `ModPath::expand_use_item`.
577     ///
578     /// This can be used to get the `UseTree` this `Import` corresponds to and allows emitting
579     /// precise diagnostics.
580     pub index: usize,
581 }
582
583 #[derive(Debug, Clone, Eq, PartialEq)]
584 pub struct ExternCrate {
585     pub name: Name,
586     pub alias: Option<ImportAlias>,
587     pub visibility: RawVisibilityId,
588     pub ast_id: FileAstId<ast::ExternCrate>,
589 }
590
591 #[derive(Debug, Clone, Eq, PartialEq)]
592 pub struct Function {
593     pub name: Name,
594     pub visibility: RawVisibilityId,
595     pub generic_params: GenericParamsId,
596     pub has_self_param: bool,
597     pub has_body: bool,
598     pub qualifier: FunctionQualifier,
599     /// Whether the function is located in an `extern` block (*not* whether it is an
600     /// `extern "abi" fn`).
601     pub is_in_extern_block: bool,
602     pub params: IdRange<Param>,
603     pub ret_type: Idx<TypeRef>,
604     pub ast_id: FileAstId<ast::Fn>,
605 }
606
607 #[derive(Debug, Clone, Eq, PartialEq)]
608 pub enum Param {
609     Normal(Idx<TypeRef>),
610     Varargs,
611 }
612
613 #[derive(Debug, Clone, PartialEq, Eq)]
614 pub struct FunctionQualifier {
615     pub is_default: bool,
616     pub is_const: bool,
617     pub is_async: bool,
618     pub is_unsafe: bool,
619     pub abi: Option<SmolStr>,
620 }
621
622 #[derive(Debug, Clone, Eq, PartialEq)]
623 pub struct Struct {
624     pub name: Name,
625     pub visibility: RawVisibilityId,
626     pub generic_params: GenericParamsId,
627     pub fields: Fields,
628     pub ast_id: FileAstId<ast::Struct>,
629     pub kind: StructDefKind,
630 }
631
632 #[derive(Debug, Clone, Eq, PartialEq)]
633 pub enum StructDefKind {
634     /// `struct S { ... }` - type namespace only.
635     Record,
636     /// `struct S(...);`
637     Tuple,
638     /// `struct S;`
639     Unit,
640 }
641
642 #[derive(Debug, Clone, Eq, PartialEq)]
643 pub struct Union {
644     pub name: Name,
645     pub visibility: RawVisibilityId,
646     pub generic_params: GenericParamsId,
647     pub fields: Fields,
648     pub ast_id: FileAstId<ast::Union>,
649 }
650
651 #[derive(Debug, Clone, Eq, PartialEq)]
652 pub struct Enum {
653     pub name: Name,
654     pub visibility: RawVisibilityId,
655     pub generic_params: GenericParamsId,
656     pub variants: IdRange<Variant>,
657     pub ast_id: FileAstId<ast::Enum>,
658 }
659
660 #[derive(Debug, Clone, Eq, PartialEq)]
661 pub struct Const {
662     /// const _: () = ();
663     pub name: Option<Name>,
664     pub visibility: RawVisibilityId,
665     pub type_ref: Idx<TypeRef>,
666     pub ast_id: FileAstId<ast::Const>,
667 }
668
669 #[derive(Debug, Clone, Eq, PartialEq)]
670 pub struct Static {
671     pub name: Name,
672     pub visibility: RawVisibilityId,
673     pub mutable: bool,
674     /// Whether the static is in an `extern` block.
675     pub is_extern: bool,
676     pub type_ref: Idx<TypeRef>,
677     pub ast_id: FileAstId<ast::Static>,
678 }
679
680 #[derive(Debug, Clone, Eq, PartialEq)]
681 pub struct Trait {
682     pub name: Name,
683     pub visibility: RawVisibilityId,
684     pub generic_params: GenericParamsId,
685     pub is_auto: bool,
686     pub is_unsafe: bool,
687     pub bounds: Box<[TypeBound]>,
688     pub items: Box<[AssocItem]>,
689     pub ast_id: FileAstId<ast::Trait>,
690 }
691
692 #[derive(Debug, Clone, Eq, PartialEq)]
693 pub struct Impl {
694     pub generic_params: GenericParamsId,
695     pub target_trait: Option<Idx<TypeRef>>,
696     pub target_type: Idx<TypeRef>,
697     pub is_negative: bool,
698     pub items: Box<[AssocItem]>,
699     pub ast_id: FileAstId<ast::Impl>,
700 }
701
702 #[derive(Debug, Clone, PartialEq, Eq)]
703 pub struct TypeAlias {
704     pub name: Name,
705     pub visibility: RawVisibilityId,
706     /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
707     pub bounds: Box<[TypeBound]>,
708     pub generic_params: GenericParamsId,
709     pub type_ref: Option<Idx<TypeRef>>,
710     pub is_extern: bool,
711     pub ast_id: FileAstId<ast::TypeAlias>,
712 }
713
714 #[derive(Debug, Clone, Eq, PartialEq)]
715 pub struct Mod {
716     pub name: Name,
717     pub visibility: RawVisibilityId,
718     pub kind: ModKind,
719     pub ast_id: FileAstId<ast::Module>,
720 }
721
722 #[derive(Debug, Clone, Eq, PartialEq)]
723 pub enum ModKind {
724     /// `mod m { ... }`
725     Inline { items: Box<[ModItem]> },
726
727     /// `mod m;`
728     Outline {},
729 }
730
731 #[derive(Debug, Clone, Eq, PartialEq)]
732 pub struct MacroCall {
733     /// Path to the called macro.
734     pub path: ModPath,
735     pub ast_id: FileAstId<ast::MacroCall>,
736 }
737
738 #[derive(Debug, Clone, Eq, PartialEq)]
739 pub struct MacroRules {
740     /// The name of the declared macro.
741     pub name: Name,
742     pub ast_id: FileAstId<ast::MacroRules>,
743 }
744
745 /// "Macros 2.0" macro definition.
746 #[derive(Debug, Clone, Eq, PartialEq)]
747 pub struct MacroDef {
748     pub name: Name,
749     pub visibility: RawVisibilityId,
750     pub ast_id: FileAstId<ast::MacroDef>,
751 }
752
753 macro_rules! impl_froms {
754     ($e:ident { $($v:ident ($t:ty)),* $(,)? }) => {
755         $(
756             impl From<$t> for $e {
757                 fn from(it: $t) -> $e {
758                     $e::$v(it)
759                 }
760             }
761         )*
762     }
763 }
764
765 impl ModItem {
766     pub fn as_assoc_item(&self) -> Option<AssocItem> {
767         match self {
768             ModItem::Import(_)
769             | ModItem::ExternCrate(_)
770             | ModItem::Struct(_)
771             | ModItem::Union(_)
772             | ModItem::Enum(_)
773             | ModItem::Static(_)
774             | ModItem::Trait(_)
775             | ModItem::Impl(_)
776             | ModItem::Mod(_)
777             | ModItem::MacroRules(_)
778             | ModItem::MacroDef(_) => None,
779             ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)),
780             ModItem::Const(konst) => Some(AssocItem::Const(*konst)),
781             ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)),
782             ModItem::Function(func) => Some(AssocItem::Function(*func)),
783         }
784     }
785
786     pub fn downcast<N: ItemTreeNode>(self) -> Option<FileItemTreeId<N>> {
787         N::id_from_mod_item(self)
788     }
789
790     pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
791         match self {
792             ModItem::Import(it) => tree[it.index].ast_id().upcast(),
793             ModItem::ExternCrate(it) => tree[it.index].ast_id().upcast(),
794             ModItem::Function(it) => tree[it.index].ast_id().upcast(),
795             ModItem::Struct(it) => tree[it.index].ast_id().upcast(),
796             ModItem::Union(it) => tree[it.index].ast_id().upcast(),
797             ModItem::Enum(it) => tree[it.index].ast_id().upcast(),
798             ModItem::Const(it) => tree[it.index].ast_id().upcast(),
799             ModItem::Static(it) => tree[it.index].ast_id().upcast(),
800             ModItem::Trait(it) => tree[it.index].ast_id().upcast(),
801             ModItem::Impl(it) => tree[it.index].ast_id().upcast(),
802             ModItem::TypeAlias(it) => tree[it.index].ast_id().upcast(),
803             ModItem::Mod(it) => tree[it.index].ast_id().upcast(),
804             ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(),
805             ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(),
806             ModItem::MacroDef(it) => tree[it.index].ast_id().upcast(),
807         }
808     }
809 }
810
811 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
812 pub enum AssocItem {
813     Function(FileItemTreeId<Function>),
814     TypeAlias(FileItemTreeId<TypeAlias>),
815     Const(FileItemTreeId<Const>),
816     MacroCall(FileItemTreeId<MacroCall>),
817 }
818
819 impl_froms!(AssocItem {
820     Function(FileItemTreeId<Function>),
821     TypeAlias(FileItemTreeId<TypeAlias>),
822     Const(FileItemTreeId<Const>),
823     MacroCall(FileItemTreeId<MacroCall>),
824 });
825
826 impl From<AssocItem> for ModItem {
827     fn from(item: AssocItem) -> Self {
828         match item {
829             AssocItem::Function(it) => it.into(),
830             AssocItem::TypeAlias(it) => it.into(),
831             AssocItem::Const(it) => it.into(),
832             AssocItem::MacroCall(it) => it.into(),
833         }
834     }
835 }
836
837 #[derive(Debug, Eq, PartialEq)]
838 pub struct Variant {
839     pub name: Name,
840     pub fields: Fields,
841 }
842
843 /// A range of densely allocated ItemTree IDs.
844 pub struct IdRange<T> {
845     range: Range<u32>,
846     _p: PhantomData<T>,
847 }
848
849 impl<T> IdRange<T> {
850     fn new(range: Range<Idx<T>>) -> Self {
851         Self { range: range.start.into_raw().into()..range.end.into_raw().into(), _p: PhantomData }
852     }
853 }
854
855 impl<T> Iterator for IdRange<T> {
856     type Item = Idx<T>;
857     fn next(&mut self) -> Option<Self::Item> {
858         self.range.next().map(|raw| Idx::from_raw(raw.into()))
859     }
860 }
861
862 impl<T> DoubleEndedIterator for IdRange<T> {
863     fn next_back(&mut self) -> Option<Self::Item> {
864         self.range.next_back().map(|raw| Idx::from_raw(raw.into()))
865     }
866 }
867
868 impl<T> fmt::Debug for IdRange<T> {
869     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
870         f.debug_tuple(&format!("IdRange::<{}>", type_name::<T>())).field(&self.range).finish()
871     }
872 }
873
874 impl<T> Clone for IdRange<T> {
875     fn clone(&self) -> Self {
876         Self { range: self.range.clone(), _p: PhantomData }
877     }
878 }
879
880 impl<T> PartialEq for IdRange<T> {
881     fn eq(&self, other: &Self) -> bool {
882         self.range == other.range
883     }
884 }
885
886 impl<T> Eq for IdRange<T> {}
887
888 #[derive(Debug, Clone, PartialEq, Eq)]
889 pub enum Fields {
890     Record(IdRange<Field>),
891     Tuple(IdRange<Field>),
892     Unit,
893 }
894
895 /// A single field of an enum variant or struct
896 #[derive(Debug, Clone, PartialEq, Eq)]
897 pub struct Field {
898     pub name: Name,
899     pub type_ref: Idx<TypeRef>,
900     pub visibility: RawVisibilityId,
901 }