diff options
Diffstat (limited to 'crates/ra_hir_def/src/item_tree.rs')
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 517 |
1 files changed, 12 insertions, 505 deletions
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index 245ee5e62..a13a989dd 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs | |||
@@ -1,13 +1,23 @@ | |||
1 | //! A simplified AST that only contains items. | 1 | //! A simplified AST that only contains items. |
2 | 2 | ||
3 | mod lower; | ||
4 | |||
5 | use std::{ | ||
6 | ops::{Index, Range}, | ||
7 | sync::Arc, | ||
8 | }; | ||
9 | |||
10 | use ast::{AstNode, AttrsOwner, ModuleItemOwner, NameOwner, StructKind, TypeAscriptionOwner}; | ||
11 | use either::Either; | ||
3 | use hir_expand::{ | 12 | use hir_expand::{ |
4 | ast_id_map::{AstIdMap, FileAstId}, | 13 | ast_id_map::FileAstId, |
5 | hygiene::Hygiene, | 14 | hygiene::Hygiene, |
6 | name::{name, AsName, Name}, | 15 | name::{name, AsName, Name}, |
7 | HirFileId, InFile, | 16 | HirFileId, InFile, |
8 | }; | 17 | }; |
9 | use ra_arena::{Arena, Idx, RawId}; | 18 | use ra_arena::{Arena, Idx, RawId}; |
10 | use ra_syntax::{ast, match_ast}; | 19 | use ra_syntax::{ast, match_ast}; |
20 | use rustc_hash::FxHashMap; | ||
11 | use test_utils::mark; | 21 | use test_utils::mark; |
12 | 22 | ||
13 | use crate::{ | 23 | use crate::{ |
@@ -18,14 +28,6 @@ use crate::{ | |||
18 | type_ref::{Mutability, TypeBound, TypeRef}, | 28 | type_ref::{Mutability, TypeBound, TypeRef}, |
19 | visibility::RawVisibility, | 29 | visibility::RawVisibility, |
20 | }; | 30 | }; |
21 | use ast::{AstNode, AttrsOwner, ModuleItemOwner, NameOwner, StructKind, TypeAscriptionOwner}; | ||
22 | use either::Either; | ||
23 | use rustc_hash::FxHashMap; | ||
24 | use smallvec::SmallVec; | ||
25 | use std::{ | ||
26 | ops::{Index, Range}, | ||
27 | sync::Arc, | ||
28 | }; | ||
29 | 31 | ||
30 | /// The item tree of a source file. | 32 | /// The item tree of a source file. |
31 | #[derive(Debug, Default, Eq, PartialEq)] | 33 | #[derive(Debug, Default, Eq, PartialEq)] |
@@ -80,7 +82,7 @@ impl ItemTree { | |||
80 | }; | 82 | }; |
81 | 83 | ||
82 | let map = db.ast_id_map(file_id); | 84 | let map = db.ast_id_map(file_id); |
83 | let mut ctx = Ctx { | 85 | let mut ctx = lower::Ctx { |
84 | tree: ItemTree::default(), | 86 | tree: ItemTree::default(), |
85 | hygiene, | 87 | hygiene, |
86 | file: file_id, | 88 | file: file_id, |
@@ -366,498 +368,3 @@ pub struct Field { | |||
366 | pub type_ref: TypeRef, | 368 | pub type_ref: TypeRef, |
367 | pub visibility: RawVisibility, | 369 | pub visibility: RawVisibility, |
368 | } | 370 | } |
369 | |||
370 | struct ModItems(SmallVec<[ModItem; 1]>); | ||
371 | |||
372 | impl<T> From<T> for ModItems | ||
373 | where | ||
374 | T: Into<ModItem>, | ||
375 | { | ||
376 | fn from(t: T) -> Self { | ||
377 | ModItems(SmallVec::from_buf([t.into(); 1])) | ||
378 | } | ||
379 | } | ||
380 | |||
381 | struct Ctx { | ||
382 | tree: ItemTree, | ||
383 | hygiene: Hygiene, | ||
384 | file: HirFileId, | ||
385 | source_ast_id_map: Arc<AstIdMap>, | ||
386 | body_ctx: crate::body::LowerCtx, | ||
387 | } | ||
388 | |||
389 | impl Ctx { | ||
390 | fn lower(mut self, item_owner: &dyn ModuleItemOwner) -> ItemTree { | ||
391 | self.tree.top_level = item_owner | ||
392 | .items() | ||
393 | .flat_map(|item| self.lower_mod_item(&item)) | ||
394 | .flat_map(|items| items.0) | ||
395 | .collect(); | ||
396 | self.tree | ||
397 | } | ||
398 | |||
399 | fn lower_mod_item(&mut self, item: &ast::ModuleItem) -> Option<ModItems> { | ||
400 | let attrs = Attrs::new(item, &self.hygiene); | ||
401 | let items = match item { | ||
402 | ast::ModuleItem::StructDef(ast) => { | ||
403 | self.lower_struct(ast).map(|data| self.tree.structs.alloc(data).into()) | ||
404 | } | ||
405 | ast::ModuleItem::UnionDef(ast) => { | ||
406 | self.lower_union(ast).map(|data| self.tree.unions.alloc(data).into()) | ||
407 | } | ||
408 | ast::ModuleItem::EnumDef(ast) => { | ||
409 | self.lower_enum(ast).map(|data| self.tree.enums.alloc(data).into()) | ||
410 | } | ||
411 | ast::ModuleItem::FnDef(ast) => { | ||
412 | self.lower_function(ast).map(|data| self.tree.functions.alloc(data).into()) | ||
413 | } | ||
414 | ast::ModuleItem::TypeAliasDef(ast) => { | ||
415 | self.lower_type_alias(ast).map(|data| self.tree.type_aliases.alloc(data).into()) | ||
416 | } | ||
417 | ast::ModuleItem::StaticDef(ast) => { | ||
418 | self.lower_static(ast).map(|data| self.tree.statics.alloc(data).into()) | ||
419 | } | ||
420 | ast::ModuleItem::ConstDef(ast) => { | ||
421 | let data = self.lower_const(ast); | ||
422 | Some(self.tree.consts.alloc(data).into()) | ||
423 | } | ||
424 | ast::ModuleItem::Module(ast) => { | ||
425 | self.lower_module(ast).map(|data| self.tree.mods.alloc(data).into()) | ||
426 | } | ||
427 | ast::ModuleItem::TraitDef(ast) => { | ||
428 | self.lower_trait(ast).map(|data| self.tree.traits.alloc(data).into()) | ||
429 | } | ||
430 | ast::ModuleItem::ImplDef(ast) => { | ||
431 | self.lower_impl(ast).map(|data| self.tree.impls.alloc(data).into()) | ||
432 | } | ||
433 | ast::ModuleItem::UseItem(ast) => Some(ModItems( | ||
434 | self.lower_use(ast) | ||
435 | .into_iter() | ||
436 | .map(|data| self.tree.imports.alloc(data).into()) | ||
437 | .collect::<SmallVec<_>>(), | ||
438 | )), | ||
439 | ast::ModuleItem::ExternCrateItem(ast) => { | ||
440 | self.lower_extern_crate(ast).map(|data| self.tree.imports.alloc(data).into()) | ||
441 | } | ||
442 | ast::ModuleItem::MacroCall(ast) => { | ||
443 | self.lower_macro_call(ast).map(|data| self.tree.macro_calls.alloc(data).into()) | ||
444 | } | ||
445 | ast::ModuleItem::ExternBlock(ast) => Some(ModItems( | ||
446 | self.lower_extern_block(ast) | ||
447 | .into_iter() | ||
448 | .map(|item| match item { | ||
449 | Either::Left(func) => self.tree.functions.alloc(func).into(), | ||
450 | Either::Right(statik) => self.tree.statics.alloc(statik).into(), | ||
451 | }) | ||
452 | .collect::<SmallVec<_>>(), | ||
453 | )), | ||
454 | }; | ||
455 | |||
456 | if !attrs.is_empty() { | ||
457 | for item in items.iter().flat_map(|items| &items.0) { | ||
458 | self.tree.attrs.insert(*item, attrs.clone()); | ||
459 | } | ||
460 | } | ||
461 | |||
462 | items | ||
463 | } | ||
464 | |||
465 | fn lower_assoc_item(&mut self, item: &ast::AssocItem) -> Option<AssocItem> { | ||
466 | match item { | ||
467 | ast::AssocItem::FnDef(ast) => { | ||
468 | self.lower_function(ast).map(|data| self.tree.functions.alloc(data).into()) | ||
469 | } | ||
470 | ast::AssocItem::TypeAliasDef(ast) => { | ||
471 | self.lower_type_alias(ast).map(|data| self.tree.type_aliases.alloc(data).into()) | ||
472 | } | ||
473 | ast::AssocItem::ConstDef(ast) => { | ||
474 | let data = self.lower_const(ast); | ||
475 | Some(self.tree.consts.alloc(data).into()) | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | |||
480 | fn lower_struct(&mut self, strukt: &ast::StructDef) -> Option<Struct> { | ||
481 | let attrs = self.lower_attrs(strukt); | ||
482 | let visibility = self.lower_visibility(strukt); | ||
483 | let name = strukt.name()?.as_name(); | ||
484 | let generic_params = self.lower_generic_params(strukt); | ||
485 | let fields = self.lower_fields(&strukt.kind()); | ||
486 | let ast_id = self.source_ast_id_map.ast_id(strukt); | ||
487 | let kind = match strukt.kind() { | ||
488 | ast::StructKind::Record(_) => StructDefKind::Record, | ||
489 | ast::StructKind::Tuple(_) => StructDefKind::Tuple, | ||
490 | ast::StructKind::Unit => StructDefKind::Unit, | ||
491 | }; | ||
492 | let res = Struct { name, attrs, visibility, generic_params, fields, ast_id, kind }; | ||
493 | Some(res) | ||
494 | } | ||
495 | |||
496 | fn lower_fields(&mut self, strukt_kind: &ast::StructKind) -> Fields { | ||
497 | match strukt_kind { | ||
498 | ast::StructKind::Record(it) => { | ||
499 | let range = self.lower_record_fields(it); | ||
500 | Fields::Record(range) | ||
501 | } | ||
502 | ast::StructKind::Tuple(it) => { | ||
503 | let range = self.lower_tuple_fields(it); | ||
504 | Fields::Tuple(range) | ||
505 | } | ||
506 | ast::StructKind::Unit => Fields::Unit, | ||
507 | } | ||
508 | } | ||
509 | |||
510 | fn lower_record_fields(&mut self, fields: &ast::RecordFieldDefList) -> Range<Idx<Field>> { | ||
511 | let start = self.next_field_idx(); | ||
512 | for field in fields.fields() { | ||
513 | if let Some(data) = self.lower_record_field(&field) { | ||
514 | self.tree.fields.alloc(data); | ||
515 | } | ||
516 | } | ||
517 | let end = self.next_field_idx(); | ||
518 | start..end | ||
519 | } | ||
520 | |||
521 | fn lower_record_field(&self, field: &ast::RecordFieldDef) -> Option<Field> { | ||
522 | let name = field.name()?.as_name(); | ||
523 | let visibility = self.lower_visibility(field); | ||
524 | let type_ref = self.lower_type_ref(&field.ascribed_type()?); | ||
525 | let res = Field { name, type_ref, visibility }; | ||
526 | Some(res) | ||
527 | } | ||
528 | |||
529 | fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldDefList) -> Range<Idx<Field>> { | ||
530 | let start = self.next_field_idx(); | ||
531 | for (i, field) in fields.fields().enumerate() { | ||
532 | if let Some(data) = self.lower_tuple_field(i, &field) { | ||
533 | self.tree.fields.alloc(data); | ||
534 | } | ||
535 | } | ||
536 | let end = self.next_field_idx(); | ||
537 | start..end | ||
538 | } | ||
539 | |||
540 | fn lower_tuple_field(&self, idx: usize, field: &ast::TupleFieldDef) -> Option<Field> { | ||
541 | let name = Name::new_tuple_field(idx); | ||
542 | let visibility = self.lower_visibility(field); | ||
543 | let type_ref = self.lower_type_ref(&field.type_ref()?); | ||
544 | let res = Field { name, type_ref, visibility }; | ||
545 | Some(res) | ||
546 | } | ||
547 | |||
548 | fn lower_union(&mut self, union: &ast::UnionDef) -> Option<Union> { | ||
549 | let attrs = self.lower_attrs(union); | ||
550 | let visibility = self.lower_visibility(union); | ||
551 | let name = union.name()?.as_name(); | ||
552 | let generic_params = self.lower_generic_params(union); | ||
553 | let fields = match union.record_field_def_list() { | ||
554 | Some(record_field_def_list) => { | ||
555 | self.lower_fields(&StructKind::Record(record_field_def_list)) | ||
556 | } | ||
557 | None => Fields::Record(self.next_field_idx()..self.next_field_idx()), | ||
558 | }; | ||
559 | let ast_id = self.source_ast_id_map.ast_id(union); | ||
560 | let res = Union { name, attrs, visibility, generic_params, fields, ast_id }; | ||
561 | Some(res) | ||
562 | } | ||
563 | |||
564 | fn lower_enum(&mut self, enum_: &ast::EnumDef) -> Option<Enum> { | ||
565 | let attrs = self.lower_attrs(enum_); | ||
566 | let visibility = self.lower_visibility(enum_); | ||
567 | let name = enum_.name()?.as_name(); | ||
568 | let generic_params = self.lower_generic_params(enum_); | ||
569 | let variants = match &enum_.variant_list() { | ||
570 | Some(variant_list) => self.lower_variants(variant_list), | ||
571 | None => self.next_variant_idx()..self.next_variant_idx(), | ||
572 | }; | ||
573 | let ast_id = self.source_ast_id_map.ast_id(enum_); | ||
574 | let res = Enum { name, attrs, visibility, generic_params, variants, ast_id }; | ||
575 | Some(res) | ||
576 | } | ||
577 | |||
578 | fn lower_variants(&mut self, variants: &ast::EnumVariantList) -> Range<Idx<Variant>> { | ||
579 | let start = self.next_variant_idx(); | ||
580 | for variant in variants.variants() { | ||
581 | if let Some(data) = self.lower_variant(&variant) { | ||
582 | self.tree.variants.alloc(data); | ||
583 | } | ||
584 | } | ||
585 | let end = self.next_variant_idx(); | ||
586 | start..end | ||
587 | } | ||
588 | |||
589 | fn lower_variant(&mut self, variant: &ast::EnumVariant) -> Option<Variant> { | ||
590 | let name = variant.name()?.as_name(); | ||
591 | let fields = self.lower_fields(&variant.kind()); | ||
592 | let res = Variant { name, fields }; | ||
593 | Some(res) | ||
594 | } | ||
595 | |||
596 | fn lower_function(&mut self, func: &ast::FnDef) -> Option<Function> { | ||
597 | let attrs = self.lower_attrs(func); | ||
598 | let visibility = self.lower_visibility(func); | ||
599 | let name = func.name()?.as_name(); | ||
600 | let generic_params = self.lower_generic_params(func); | ||
601 | |||
602 | let mut params = Vec::new(); | ||
603 | let mut has_self_param = false; | ||
604 | if let Some(param_list) = func.param_list() { | ||
605 | if let Some(self_param) = param_list.self_param() { | ||
606 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { | ||
607 | TypeRef::from_ast(&self.body_ctx, type_ref) | ||
608 | } else { | ||
609 | let self_type = TypeRef::Path(name![Self].into()); | ||
610 | match self_param.kind() { | ||
611 | ast::SelfParamKind::Owned => self_type, | ||
612 | ast::SelfParamKind::Ref => { | ||
613 | TypeRef::Reference(Box::new(self_type), Mutability::Shared) | ||
614 | } | ||
615 | ast::SelfParamKind::MutRef => { | ||
616 | TypeRef::Reference(Box::new(self_type), Mutability::Mut) | ||
617 | } | ||
618 | } | ||
619 | }; | ||
620 | params.push(self_type); | ||
621 | has_self_param = true; | ||
622 | } | ||
623 | for param in param_list.params() { | ||
624 | let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ascribed_type()); | ||
625 | params.push(type_ref); | ||
626 | } | ||
627 | } | ||
628 | let ret_type = match func.ret_type().and_then(|rt| rt.type_ref()) { | ||
629 | Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref), | ||
630 | _ => TypeRef::unit(), | ||
631 | }; | ||
632 | |||
633 | let ret_type = if func.async_token().is_some() { | ||
634 | let future_impl = desugar_future_path(ret_type); | ||
635 | let ty_bound = TypeBound::Path(future_impl); | ||
636 | TypeRef::ImplTrait(vec![ty_bound]) | ||
637 | } else { | ||
638 | ret_type | ||
639 | }; | ||
640 | |||
641 | let ast_id = self.source_ast_id_map.ast_id(func); | ||
642 | let res = Function { | ||
643 | name, | ||
644 | attrs, | ||
645 | visibility, | ||
646 | generic_params, | ||
647 | has_self_param, | ||
648 | params, | ||
649 | ret_type, | ||
650 | ast_id, | ||
651 | }; | ||
652 | Some(res) | ||
653 | } | ||
654 | |||
655 | fn lower_type_alias(&mut self, type_alias: &ast::TypeAliasDef) -> Option<TypeAlias> { | ||
656 | let name = type_alias.name()?.as_name(); | ||
657 | let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it)); | ||
658 | let visibility = self.lower_visibility(type_alias); | ||
659 | let generic_params = self.lower_generic_params(type_alias); | ||
660 | let ast_id = self.source_ast_id_map.ast_id(type_alias); | ||
661 | let res = TypeAlias { name, visibility, generic_params, type_ref, ast_id }; | ||
662 | Some(res) | ||
663 | } | ||
664 | |||
665 | fn lower_static(&mut self, static_: &ast::StaticDef) -> Option<Static> { | ||
666 | let name = static_.name()?.as_name(); | ||
667 | let type_ref = self.lower_type_ref_opt(static_.ascribed_type()); | ||
668 | let visibility = self.lower_visibility(static_); | ||
669 | let ast_id = self.source_ast_id_map.ast_id(static_); | ||
670 | let res = Static { name, visibility, type_ref, ast_id }; | ||
671 | Some(res) | ||
672 | } | ||
673 | |||
674 | fn lower_const(&mut self, konst: &ast::ConstDef) -> Const { | ||
675 | let name = konst.name().map(|it| it.as_name()); | ||
676 | let type_ref = self.lower_type_ref_opt(konst.ascribed_type()); | ||
677 | let visibility = self.lower_visibility(konst); | ||
678 | let ast_id = self.source_ast_id_map.ast_id(konst); | ||
679 | Const { name, visibility, type_ref, ast_id } | ||
680 | } | ||
681 | |||
682 | fn lower_module(&mut self, module: &ast::Module) -> Option<Mod> { | ||
683 | let name = module.name()?.as_name(); | ||
684 | let visibility = self.lower_visibility(module); | ||
685 | let kind = if module.semicolon_token().is_some() { | ||
686 | ModKind::Outline {} | ||
687 | } else { | ||
688 | ModKind::Inline { | ||
689 | items: module | ||
690 | .item_list() | ||
691 | .map(|list| { | ||
692 | list.items() | ||
693 | .flat_map(|item| self.lower_mod_item(&item)) | ||
694 | .flat_map(|items| items.0) | ||
695 | .collect() | ||
696 | }) | ||
697 | .unwrap_or_else(|| { | ||
698 | mark::hit!(name_res_works_for_broken_modules); | ||
699 | Vec::new() | ||
700 | }), | ||
701 | } | ||
702 | }; | ||
703 | let ast_id = self.source_ast_id_map.ast_id(module); | ||
704 | Some(Mod { name, visibility, kind, ast_id }) | ||
705 | } | ||
706 | |||
707 | fn lower_trait(&mut self, trait_def: &ast::TraitDef) -> Option<Trait> { | ||
708 | let name = trait_def.name()?.as_name(); | ||
709 | let visibility = self.lower_visibility(trait_def); | ||
710 | let generic_params = self.lower_generic_params(trait_def); | ||
711 | let auto = trait_def.auto_token().is_some(); | ||
712 | let items = trait_def.item_list().map(|list| { | ||
713 | // FIXME: Does not handle macros | ||
714 | list.assoc_items().flat_map(|item| self.lower_assoc_item(&item)).collect() | ||
715 | }); | ||
716 | let ast_id = self.source_ast_id_map.ast_id(trait_def); | ||
717 | Some(Trait { | ||
718 | name, | ||
719 | visibility, | ||
720 | generic_params, | ||
721 | auto, | ||
722 | items: items.unwrap_or_default(), | ||
723 | ast_id, | ||
724 | }) | ||
725 | } | ||
726 | |||
727 | fn lower_impl(&mut self, impl_def: &ast::ImplDef) -> Option<Impl> { | ||
728 | let generic_params = self.lower_generic_params(impl_def); | ||
729 | let target_trait = impl_def.target_trait().map(|tr| self.lower_type_ref(&tr)); | ||
730 | let target_type = self.lower_type_ref(&impl_def.target_type()?); | ||
731 | let is_negative = impl_def.excl_token().is_some(); | ||
732 | let items = impl_def | ||
733 | .item_list()? | ||
734 | .assoc_items() | ||
735 | .filter_map(|item| self.lower_assoc_item(&item)) | ||
736 | .collect(); | ||
737 | let ast_id = self.source_ast_id_map.ast_id(impl_def); | ||
738 | Some(Impl { generic_params, target_trait, target_type, is_negative, items, ast_id }) | ||
739 | } | ||
740 | |||
741 | fn lower_use(&mut self, use_item: &ast::UseItem) -> Vec<Import> { | ||
742 | // FIXME: cfg_attr | ||
743 | let is_prelude = use_item.has_atom_attr("prelude_import"); | ||
744 | let visibility = self.lower_visibility(use_item); | ||
745 | |||
746 | // Every use item can expand to many `Import`s. | ||
747 | let mut imports = Vec::new(); | ||
748 | ModPath::expand_use_item( | ||
749 | InFile::new(self.file, use_item.clone()), | ||
750 | &self.hygiene, | ||
751 | |path, _tree, is_glob, alias| { | ||
752 | imports.push(Import { | ||
753 | path, | ||
754 | alias, | ||
755 | visibility: visibility.clone(), | ||
756 | is_glob, | ||
757 | is_prelude, | ||
758 | is_extern_crate: false, | ||
759 | is_macro_use: false, | ||
760 | }); | ||
761 | }, | ||
762 | ); | ||
763 | |||
764 | imports | ||
765 | } | ||
766 | |||
767 | fn lower_extern_crate(&mut self, extern_crate: &ast::ExternCrateItem) -> Option<Import> { | ||
768 | let path = ModPath::from_name_ref(&extern_crate.name_ref()?); | ||
769 | let alias = extern_crate.alias().map(|a| { | ||
770 | a.name().map(|it| it.as_name()).map_or(ImportAlias::Underscore, ImportAlias::Alias) | ||
771 | }); | ||
772 | let visibility = self.lower_visibility(extern_crate); | ||
773 | // FIXME: cfg_attr | ||
774 | let is_macro_use = extern_crate.has_atom_attr("macro_use"); | ||
775 | |||
776 | Some(Import { | ||
777 | path, | ||
778 | alias, | ||
779 | visibility, | ||
780 | is_glob: false, | ||
781 | is_prelude: false, | ||
782 | is_extern_crate: true, | ||
783 | is_macro_use, | ||
784 | }) | ||
785 | } | ||
786 | |||
787 | fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<MacroCall> { | ||
788 | let name = m.name().map(|it| it.as_name()); | ||
789 | let attrs = Attrs::new(m, &self.hygiene); | ||
790 | let path = ModPath::from_src(m.path()?, &self.hygiene)?; | ||
791 | |||
792 | let ast_id = self.source_ast_id_map.ast_id(m); | ||
793 | |||
794 | // FIXME: cfg_attr | ||
795 | let export_attr = attrs.by_key("macro_export"); | ||
796 | |||
797 | let is_export = export_attr.exists(); | ||
798 | let is_local_inner = if is_export { | ||
799 | export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it { | ||
800 | tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { | ||
801 | ident.text.contains("local_inner_macros") | ||
802 | } | ||
803 | _ => false, | ||
804 | }) | ||
805 | } else { | ||
806 | false | ||
807 | }; | ||
808 | |||
809 | let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); | ||
810 | Some(MacroCall { name, path, is_export, is_builtin, is_local_inner, ast_id }) | ||
811 | } | ||
812 | |||
813 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<Either<Function, Static>> { | ||
814 | block.extern_item_list().map_or(Vec::new(), |list| { | ||
815 | list.extern_items() | ||
816 | .filter_map(|item| match item { | ||
817 | ast::ExternItem::FnDef(ast) => self.lower_function(&ast).map(Either::Left), | ||
818 | ast::ExternItem::StaticDef(ast) => self.lower_static(&ast).map(Either::Right), | ||
819 | }) | ||
820 | .collect() | ||
821 | }) | ||
822 | } | ||
823 | |||
824 | fn lower_generic_params( | ||
825 | &mut self, | ||
826 | _item: &impl ast::TypeParamsOwner, | ||
827 | ) -> generics::GenericParams { | ||
828 | // TODO | ||
829 | generics::GenericParams { types: Arena::new(), where_predicates: Vec::new() } | ||
830 | } | ||
831 | |||
832 | fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { | ||
833 | Attrs::new(item, &self.hygiene) | ||
834 | } | ||
835 | fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility { | ||
836 | RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene) | ||
837 | } | ||
838 | fn lower_type_ref(&self, type_ref: &ast::TypeRef) -> TypeRef { | ||
839 | TypeRef::from_ast(&self.body_ctx, type_ref.clone()) | ||
840 | } | ||
841 | fn lower_type_ref_opt(&self, type_ref: Option<ast::TypeRef>) -> TypeRef { | ||
842 | TypeRef::from_ast_opt(&self.body_ctx, type_ref) | ||
843 | } | ||
844 | |||
845 | fn next_field_idx(&self) -> Idx<Field> { | ||
846 | Idx::from_raw(RawId::from(self.tree.fields.len() as u32)) | ||
847 | } | ||
848 | fn next_variant_idx(&self) -> Idx<Variant> { | ||
849 | Idx::from_raw(RawId::from(self.tree.variants.len() as u32)) | ||
850 | } | ||
851 | } | ||
852 | |||
853 | fn desugar_future_path(orig: TypeRef) -> Path { | ||
854 | let path = path![core::future::Future]; | ||
855 | let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments.len() - 1).collect(); | ||
856 | let mut last = GenericArgs::empty(); | ||
857 | let binding = | ||
858 | AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() }; | ||
859 | last.bindings.push(binding); | ||
860 | generic_args.push(Some(Arc::new(last))); | ||
861 | |||
862 | Path::from_known_path(path, generic_args) | ||
863 | } | ||