aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-06-26 17:12:22 +0100
committerGitHub <[email protected]>2020-06-26 17:12:22 +0100
commit89277e7a422fee67ef6c068d9430ab6bc88847ba (patch)
treeec3b8427ab991aa379ce3dfc1853e291c7b12e40 /crates/ra_hir_def
parentdf27b99f2769146f588b5b5a29072fe51be7b57b (diff)
parentefe378d2b43b90f8cf549781e870bfa2ebe90fd0 (diff)
Merge #5081
5081: Fix a panic with malformed inner items r=jonas-schievink a=jonas-schievink bors r+ Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs98
-rw-r--r--crates/ra_hir_def/src/body/scope.rs13
2 files changed, 50 insertions, 61 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 3ced648e5..a7e2e0982 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -5,7 +5,7 @@ use either::Either;
5use hir_expand::{ 5use hir_expand::{
6 hygiene::Hygiene, 6 hygiene::Hygiene,
7 name::{name, AsName, Name}, 7 name::{name, AsName, Name},
8 AstId, HirFileId, MacroDefId, MacroDefKind, 8 HirFileId, MacroDefId, MacroDefKind,
9}; 9};
10use ra_arena::Arena; 10use ra_arena::Arena;
11use ra_syntax::{ 11use ra_syntax::{
@@ -27,7 +27,7 @@ use crate::{
27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, 27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
28 }, 28 },
29 item_scope::BuiltinShadowMode, 29 item_scope::BuiltinShadowMode,
30 item_tree::{FileItemTreeId, ItemTree, ItemTreeNode}, 30 item_tree::{ItemTree, ItemTreeId, ItemTreeNode},
31 path::{GenericArgs, Path}, 31 path::{GenericArgs, Path},
32 type_ref::{Mutability, Rawness, TypeRef}, 32 type_ref::{Mutability, Rawness, TypeRef},
33 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, 33 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
@@ -37,7 +37,7 @@ use crate::{
37use super::{ExprSource, PatSource}; 37use super::{ExprSource, PatSource};
38use ast::AstChildren; 38use ast::AstChildren;
39use rustc_hash::FxHashMap; 39use rustc_hash::FxHashMap;
40use std::sync::Arc; 40use std::{any::type_name, sync::Arc};
41 41
42pub(crate) struct LowerCtx { 42pub(crate) struct LowerCtx {
43 hygiene: Hygiene, 43 hygiene: Hygiene,
@@ -561,17 +561,30 @@ impl ExprCollector<'_> {
561 } 561 }
562 } 562 }
563 563
564 fn find_inner_item<S: ItemTreeNode>(&self, id: AstId<ast::ModuleItem>) -> FileItemTreeId<S> { 564 fn find_inner_item<N: ItemTreeNode>(&self, ast: &N::Source) -> Option<ItemTreeId<N>> {
565 let id = self.expander.ast_id(ast);
565 let tree = &self.item_trees[&id.file_id]; 566 let tree = &self.item_trees[&id.file_id];
566 567
567 // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes 568 // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes
568 569
569 // Root file (non-macro). 570 // Root file (non-macro).
570 tree.all_inner_items() 571 let item_tree_id = tree
572 .all_inner_items()
571 .chain(tree.top_level_items().iter().copied()) 573 .chain(tree.top_level_items().iter().copied())
572 .filter_map(|mod_item| mod_item.downcast::<S>()) 574 .filter_map(|mod_item| mod_item.downcast::<N>())
573 .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value) 575 .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value.upcast())
574 .unwrap_or_else(|| panic!("couldn't find inner item for {:?}", id)) 576 .or_else(|| {
577 log::debug!(
578 "couldn't find inner {} item for {:?} (AST: `{}` - {:?})",
579 type_name::<N>(),
580 id,
581 ast.syntax(),
582 ast.syntax(),
583 );
584 None
585 })?;
586
587 Some(ItemTreeId::new(id.file_id, item_tree_id))
575 } 588 }
576 589
577 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { 590 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
@@ -611,82 +624,45 @@ impl ExprCollector<'_> {
611 .filter_map(|item| { 624 .filter_map(|item| {
612 let (def, name): (ModuleDefId, Option<ast::Name>) = match item { 625 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
613 ast::ModuleItem::FnDef(def) => { 626 ast::ModuleItem::FnDef(def) => {
614 let ast_id = self.expander.ast_id(&def); 627 let id = self.find_inner_item(&def)?;
615 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
616 ( 628 (
617 FunctionLoc { container: container.into(), id: ast_id.with_value(id) } 629 FunctionLoc { container: container.into(), id }.intern(self.db).into(),
618 .intern(self.db)
619 .into(),
620 def.name(), 630 def.name(),
621 ) 631 )
622 } 632 }
623 ast::ModuleItem::TypeAliasDef(def) => { 633 ast::ModuleItem::TypeAliasDef(def) => {
624 let ast_id = self.expander.ast_id(&def); 634 let id = self.find_inner_item(&def)?;
625 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
626 ( 635 (
627 TypeAliasLoc { container: container.into(), id: ast_id.with_value(id) } 636 TypeAliasLoc { container: container.into(), id }.intern(self.db).into(),
628 .intern(self.db)
629 .into(),
630 def.name(), 637 def.name(),
631 ) 638 )
632 } 639 }
633 ast::ModuleItem::ConstDef(def) => { 640 ast::ModuleItem::ConstDef(def) => {
634 let ast_id = self.expander.ast_id(&def); 641 let id = self.find_inner_item(&def)?;
635 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
636 ( 642 (
637 ConstLoc { container: container.into(), id: ast_id.with_value(id) } 643 ConstLoc { container: container.into(), id }.intern(self.db).into(),
638 .intern(self.db)
639 .into(),
640 def.name(), 644 def.name(),
641 ) 645 )
642 } 646 }
643 ast::ModuleItem::StaticDef(def) => { 647 ast::ModuleItem::StaticDef(def) => {
644 let ast_id = self.expander.ast_id(&def); 648 let id = self.find_inner_item(&def)?;
645 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 649 (StaticLoc { container, id }.intern(self.db).into(), def.name())
646 (
647 StaticLoc { container, id: ast_id.with_value(id) }
648 .intern(self.db)
649 .into(),
650 def.name(),
651 )
652 } 650 }
653 ast::ModuleItem::StructDef(def) => { 651 ast::ModuleItem::StructDef(def) => {
654 let ast_id = self.expander.ast_id(&def); 652 let id = self.find_inner_item(&def)?;
655 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 653 (StructLoc { container, id }.intern(self.db).into(), def.name())
656 (
657 StructLoc { container, id: ast_id.with_value(id) }
658 .intern(self.db)
659 .into(),
660 def.name(),
661 )
662 } 654 }
663 ast::ModuleItem::EnumDef(def) => { 655 ast::ModuleItem::EnumDef(def) => {
664 let ast_id = self.expander.ast_id(&def); 656 let id = self.find_inner_item(&def)?;
665 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 657 (EnumLoc { container, id }.intern(self.db).into(), def.name())
666 (
667 EnumLoc { container, id: ast_id.with_value(id) }.intern(self.db).into(),
668 def.name(),
669 )
670 } 658 }
671 ast::ModuleItem::UnionDef(def) => { 659 ast::ModuleItem::UnionDef(def) => {
672 let ast_id = self.expander.ast_id(&def); 660 let id = self.find_inner_item(&def)?;
673 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 661 (UnionLoc { container, id }.intern(self.db).into(), def.name())
674 (
675 UnionLoc { container, id: ast_id.with_value(id) }
676 .intern(self.db)
677 .into(),
678 def.name(),
679 )
680 } 662 }
681 ast::ModuleItem::TraitDef(def) => { 663 ast::ModuleItem::TraitDef(def) => {
682 let ast_id = self.expander.ast_id(&def); 664 let id = self.find_inner_item(&def)?;
683 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 665 (TraitLoc { container, id }.intern(self.db).into(), def.name())
684 (
685 TraitLoc { container, id: ast_id.with_value(id) }
686 .intern(self.db)
687 .into(),
688 def.name(),
689 )
690 } 666 }
691 ast::ModuleItem::ExternBlock(_) => return None, // FIXME: collect from extern blocks 667 ast::ModuleItem::ExternBlock(_) => return None, // FIXME: collect from extern blocks
692 ast::ModuleItem::ImplDef(_) 668 ast::ModuleItem::ImplDef(_)
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 81397b063..99e876683 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -337,6 +337,19 @@ fn foo() {
337 ); 337 );
338 } 338 }
339 339
340 #[test]
341 fn broken_inner_item() {
342 do_check(
343 r"
344 fn foo() {
345 trait {}
346 <|>
347 }
348 ",
349 &[],
350 );
351 }
352
340 fn do_check_local_name(ra_fixture: &str, expected_offset: u32) { 353 fn do_check_local_name(ra_fixture: &str, expected_offset: u32) {
341 let (db, position) = TestDB::with_position(ra_fixture); 354 let (db, position) = TestDB::with_position(ra_fixture);
342 let file_id = position.file_id; 355 let file_id = position.file_id;