diff options
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 177 | ||||
-rw-r--r-- | crates/hir_def/src/body/scope.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/body/tests.rs | 3 | ||||
-rw-r--r-- | crates/hir_def/src/body/tests/block.rs | 37 |
4 files changed, 54 insertions, 167 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index c18001e15..8c8eb8007 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -1,17 +1,16 @@ | |||
1 | //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` | 1 | //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` |
2 | //! representation. | 2 | //! representation. |
3 | 3 | ||
4 | use std::{any::type_name, mem, sync::Arc}; | 4 | use std::mem; |
5 | 5 | ||
6 | use either::Either; | 6 | use either::Either; |
7 | use hir_expand::{ | 7 | use hir_expand::{ |
8 | hygiene::Hygiene, | 8 | hygiene::Hygiene, |
9 | name::{name, AsName, Name}, | 9 | name::{name, AsName, Name}, |
10 | ExpandError, HirFileId, MacroDefId, MacroDefKind, | 10 | ExpandError, HirFileId, |
11 | }; | 11 | }; |
12 | use la_arena::Arena; | 12 | use la_arena::Arena; |
13 | use profile::Count; | 13 | use profile::Count; |
14 | use rustc_hash::FxHashMap; | ||
15 | use syntax::{ | 14 | use syntax::{ |
16 | ast::{ | 15 | ast::{ |
17 | self, ArgListOwner, ArrayExprKind, AstChildren, LiteralKind, LoopBodyOwner, NameOwner, | 16 | self, ArgListOwner, ArrayExprKind, AstChildren, LiteralKind, LoopBodyOwner, NameOwner, |
@@ -19,12 +18,11 @@ use syntax::{ | |||
19 | }, | 18 | }, |
20 | AstNode, AstPtr, SyntaxNodePtr, | 19 | AstNode, AstPtr, SyntaxNodePtr, |
21 | }; | 20 | }; |
22 | use test_utils::mark; | ||
23 | 21 | ||
24 | use crate::{ | 22 | use crate::{ |
25 | adt::StructKind, | 23 | adt::StructKind, |
26 | body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, | 24 | body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, |
27 | builtin_type::{BuiltinFloat, BuiltinInt}, | 25 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, |
28 | db::DefDatabase, | 26 | db::DefDatabase, |
29 | diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, | 27 | diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, |
30 | expr::{ | 28 | expr::{ |
@@ -33,11 +31,9 @@ use crate::{ | |||
33 | Statement, | 31 | Statement, |
34 | }, | 32 | }, |
35 | item_scope::BuiltinShadowMode, | 33 | item_scope::BuiltinShadowMode, |
36 | item_tree::{ItemTree, ItemTreeId, ItemTreeNode}, | ||
37 | path::{GenericArgs, Path}, | 34 | path::{GenericArgs, Path}, |
38 | type_ref::{Mutability, Rawness, TypeRef}, | 35 | type_ref::{Mutability, Rawness, TypeRef}, |
39 | AdtId, BlockLoc, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, | 36 | AdtId, BlockLoc, ModuleDefId, |
40 | ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, | ||
41 | }; | 37 | }; |
42 | 38 | ||
43 | use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; | 39 | use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; |
@@ -61,15 +57,12 @@ impl LowerCtx { | |||
61 | 57 | ||
62 | pub(super) fn lower( | 58 | pub(super) fn lower( |
63 | db: &dyn DefDatabase, | 59 | db: &dyn DefDatabase, |
64 | def: DefWithBodyId, | ||
65 | expander: Expander, | 60 | expander: Expander, |
66 | params: Option<ast::ParamList>, | 61 | params: Option<ast::ParamList>, |
67 | body: Option<ast::Expr>, | 62 | body: Option<ast::Expr>, |
68 | ) -> (Body, BodySourceMap) { | 63 | ) -> (Body, BodySourceMap) { |
69 | let item_tree = db.item_tree(expander.current_file_id); | ||
70 | ExprCollector { | 64 | ExprCollector { |
71 | db, | 65 | db, |
72 | def, | ||
73 | source_map: BodySourceMap::default(), | 66 | source_map: BodySourceMap::default(), |
74 | body: Body { | 67 | body: Body { |
75 | exprs: Arena::default(), | 68 | exprs: Arena::default(), |
@@ -77,14 +70,9 @@ pub(super) fn lower( | |||
77 | labels: Arena::default(), | 70 | labels: Arena::default(), |
78 | params: Vec::new(), | 71 | params: Vec::new(), |
79 | body_expr: dummy_expr_id(), | 72 | body_expr: dummy_expr_id(), |
80 | item_scope: Default::default(), | 73 | block_scopes: Vec::new(), |
81 | _c: Count::new(), | 74 | _c: Count::new(), |
82 | }, | 75 | }, |
83 | item_trees: { | ||
84 | let mut map = FxHashMap::default(); | ||
85 | map.insert(expander.current_file_id, item_tree); | ||
86 | map | ||
87 | }, | ||
88 | expander, | 76 | expander, |
89 | } | 77 | } |
90 | .collect(params, body) | 78 | .collect(params, body) |
@@ -92,12 +80,9 @@ pub(super) fn lower( | |||
92 | 80 | ||
93 | struct ExprCollector<'a> { | 81 | struct ExprCollector<'a> { |
94 | db: &'a dyn DefDatabase, | 82 | db: &'a dyn DefDatabase, |
95 | def: DefWithBodyId, | ||
96 | expander: Expander, | 83 | expander: Expander, |
97 | body: Body, | 84 | body: Body, |
98 | source_map: BodySourceMap, | 85 | source_map: BodySourceMap, |
99 | |||
100 | item_trees: FxHashMap<HirFileId, Arc<ItemTree>>, | ||
101 | } | 86 | } |
102 | 87 | ||
103 | impl ExprCollector<'_> { | 88 | impl ExprCollector<'_> { |
@@ -286,7 +271,7 @@ impl ExprCollector<'_> { | |||
286 | None => self.collect_expr_opt(condition.expr()), | 271 | None => self.collect_expr_opt(condition.expr()), |
287 | // if let -- desugar to match | 272 | // if let -- desugar to match |
288 | Some(pat) => { | 273 | Some(pat) => { |
289 | mark::hit!(infer_resolve_while_let); | 274 | cov_mark::hit!(infer_resolve_while_let); |
290 | let pat = self.collect_pat(pat); | 275 | let pat = self.collect_pat(pat); |
291 | let match_expr = self.collect_expr_opt(condition.expr()); | 276 | let match_expr = self.collect_expr_opt(condition.expr()); |
292 | let placeholder_pat = self.missing_pat(); | 277 | let placeholder_pat = self.missing_pat(); |
@@ -594,9 +579,6 @@ impl ExprCollector<'_> { | |||
594 | } else { | 579 | } else { |
595 | self.source_map.expansions.insert(macro_call, self.expander.current_file_id); | 580 | self.source_map.expansions.insert(macro_call, self.expander.current_file_id); |
596 | 581 | ||
597 | let item_tree = self.db.item_tree(self.expander.current_file_id); | ||
598 | self.item_trees.insert(self.expander.current_file_id, item_tree); | ||
599 | |||
600 | let id = collector(self, Some(expansion)); | 582 | let id = collector(self, Some(expansion)); |
601 | self.expander.exit(self.db, mark); | 583 | self.expander.exit(self.db, mark); |
602 | id | 584 | id |
@@ -606,32 +588,6 @@ impl ExprCollector<'_> { | |||
606 | } | 588 | } |
607 | } | 589 | } |
608 | 590 | ||
609 | fn find_inner_item<N: ItemTreeNode>(&self, ast: &N::Source) -> Option<ItemTreeId<N>> { | ||
610 | let id = self.expander.ast_id(ast); | ||
611 | let tree = &self.item_trees[&id.file_id]; | ||
612 | |||
613 | // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes | ||
614 | |||
615 | // Root file (non-macro). | ||
616 | let item_tree_id = tree | ||
617 | .all_inner_items() | ||
618 | .chain(tree.top_level_items().iter().copied()) | ||
619 | .filter_map(|mod_item| mod_item.downcast::<N>()) | ||
620 | .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value.upcast()) | ||
621 | .or_else(|| { | ||
622 | log::debug!( | ||
623 | "couldn't find inner {} item for {:?} (AST: `{}` - {:?})", | ||
624 | type_name::<N>(), | ||
625 | id, | ||
626 | ast.syntax(), | ||
627 | ast.syntax(), | ||
628 | ); | ||
629 | None | ||
630 | })?; | ||
631 | |||
632 | Some(ItemTreeId::new(id.file_id, item_tree_id)) | ||
633 | } | ||
634 | |||
635 | fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { | 591 | fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { |
636 | if let Some(expr) = expr { | 592 | if let Some(expr) = expr { |
637 | self.collect_expr(expr) | 593 | self.collect_expr(expr) |
@@ -663,7 +619,6 @@ impl ExprCollector<'_> { | |||
663 | match expansion { | 619 | match expansion { |
664 | Some(expansion) => { | 620 | Some(expansion) => { |
665 | let statements: ast::MacroStmts = expansion; | 621 | let statements: ast::MacroStmts = expansion; |
666 | this.collect_stmts_items(statements.statements()); | ||
667 | 622 | ||
668 | statements.statements().for_each(|stmt| { | 623 | statements.statements().for_each(|stmt| { |
669 | if let Some(mut r) = this.collect_stmt(stmt) { | 624 | if let Some(mut r) = this.collect_stmt(stmt) { |
@@ -701,6 +656,8 @@ impl ExprCollector<'_> { | |||
701 | let block_loc = | 656 | let block_loc = |
702 | BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) }; | 657 | BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) }; |
703 | let block_id = self.db.intern_block(block_loc); | 658 | let block_id = self.db.intern_block(block_loc); |
659 | self.body.block_scopes.push(block_id); | ||
660 | |||
704 | let opt_def_map = self.db.block_def_map(block_id); | 661 | let opt_def_map = self.db.block_def_map(block_id); |
705 | let has_def_map = opt_def_map.is_some(); | 662 | let has_def_map = opt_def_map.is_some(); |
706 | let def_map = opt_def_map.unwrap_or_else(|| self.expander.def_map.clone()); | 663 | let def_map = opt_def_map.unwrap_or_else(|| self.expander.def_map.clone()); |
@@ -708,7 +665,6 @@ impl ExprCollector<'_> { | |||
708 | let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); | 665 | let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); |
709 | let prev_local_module = mem::replace(&mut self.expander.module, module); | 666 | let prev_local_module = mem::replace(&mut self.expander.module, module); |
710 | 667 | ||
711 | self.collect_stmts_items(block.statements()); | ||
712 | let statements = | 668 | let statements = |
713 | block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); | 669 | block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); |
714 | let tail = block.tail_expr().map(|e| self.collect_expr(e)); | 670 | let tail = block.tail_expr().map(|e| self.collect_expr(e)); |
@@ -723,108 +679,6 @@ impl ExprCollector<'_> { | |||
723 | expr_id | 679 | expr_id |
724 | } | 680 | } |
725 | 681 | ||
726 | fn collect_stmts_items(&mut self, stmts: ast::AstChildren<ast::Stmt>) { | ||
727 | let container = ContainerId::DefWithBodyId(self.def); | ||
728 | |||
729 | let items = stmts | ||
730 | .filter_map(|stmt| match stmt { | ||
731 | ast::Stmt::Item(it) => Some(it), | ||
732 | ast::Stmt::LetStmt(_) | ast::Stmt::ExprStmt(_) => None, | ||
733 | }) | ||
734 | .filter_map(|item| { | ||
735 | let (def, name): (ModuleDefId, Option<ast::Name>) = match item { | ||
736 | ast::Item::Fn(def) => { | ||
737 | let id = self.find_inner_item(&def)?; | ||
738 | ( | ||
739 | FunctionLoc { container: container.into(), id }.intern(self.db).into(), | ||
740 | def.name(), | ||
741 | ) | ||
742 | } | ||
743 | ast::Item::TypeAlias(def) => { | ||
744 | let id = self.find_inner_item(&def)?; | ||
745 | ( | ||
746 | TypeAliasLoc { container: container.into(), id }.intern(self.db).into(), | ||
747 | def.name(), | ||
748 | ) | ||
749 | } | ||
750 | ast::Item::Const(def) => { | ||
751 | let id = self.find_inner_item(&def)?; | ||
752 | ( | ||
753 | ConstLoc { container: container.into(), id }.intern(self.db).into(), | ||
754 | def.name(), | ||
755 | ) | ||
756 | } | ||
757 | ast::Item::Static(def) => { | ||
758 | let id = self.find_inner_item(&def)?; | ||
759 | (StaticLoc { container, id }.intern(self.db).into(), def.name()) | ||
760 | } | ||
761 | ast::Item::Struct(def) => { | ||
762 | let id = self.find_inner_item(&def)?; | ||
763 | (StructLoc { container, id }.intern(self.db).into(), def.name()) | ||
764 | } | ||
765 | ast::Item::Enum(def) => { | ||
766 | let id = self.find_inner_item(&def)?; | ||
767 | (EnumLoc { container, id }.intern(self.db).into(), def.name()) | ||
768 | } | ||
769 | ast::Item::Union(def) => { | ||
770 | let id = self.find_inner_item(&def)?; | ||
771 | (UnionLoc { container, id }.intern(self.db).into(), def.name()) | ||
772 | } | ||
773 | ast::Item::Trait(def) => { | ||
774 | let id = self.find_inner_item(&def)?; | ||
775 | (TraitLoc { container, id }.intern(self.db).into(), def.name()) | ||
776 | } | ||
777 | ast::Item::ExternBlock(_) => return None, // FIXME: collect from extern blocks | ||
778 | ast::Item::Impl(_) | ||
779 | | ast::Item::Use(_) | ||
780 | | ast::Item::ExternCrate(_) | ||
781 | | ast::Item::Module(_) | ||
782 | | ast::Item::MacroCall(_) => return None, | ||
783 | ast::Item::MacroRules(def) => { | ||
784 | return Some(Either::Right(ast::Macro::from(def))); | ||
785 | } | ||
786 | ast::Item::MacroDef(def) => { | ||
787 | return Some(Either::Right(ast::Macro::from(def))); | ||
788 | } | ||
789 | }; | ||
790 | |||
791 | Some(Either::Left((def, name))) | ||
792 | }) | ||
793 | .collect::<Vec<_>>(); | ||
794 | |||
795 | for either in items { | ||
796 | match either { | ||
797 | Either::Left((def, name)) => { | ||
798 | self.body.item_scope.define_def(def); | ||
799 | if let Some(name) = name { | ||
800 | let vis = crate::visibility::Visibility::Public; // FIXME determine correctly | ||
801 | let has_constructor = match def { | ||
802 | ModuleDefId::AdtId(AdtId::StructId(s)) => { | ||
803 | self.db.struct_data(s).variant_data.kind() != StructKind::Record | ||
804 | } | ||
805 | _ => true, | ||
806 | }; | ||
807 | self.body.item_scope.push_res( | ||
808 | name.as_name(), | ||
809 | crate::per_ns::PerNs::from_def(def, vis, has_constructor), | ||
810 | ); | ||
811 | } | ||
812 | } | ||
813 | Either::Right(e) => { | ||
814 | let mac = MacroDefId { | ||
815 | krate: self.expander.def_map.krate(), | ||
816 | ast_id: Some(self.expander.ast_id(&e)), | ||
817 | kind: MacroDefKind::Declarative, | ||
818 | local_inner: false, | ||
819 | }; | ||
820 | if let Some(name) = e.name() { | ||
821 | self.body.item_scope.define_legacy_macro(name.as_name(), mac); | ||
822 | } | ||
823 | } | ||
824 | } | ||
825 | } | ||
826 | } | ||
827 | |||
828 | fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { | 682 | fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { |
829 | if let Some(block) = expr { | 683 | if let Some(block) = expr { |
830 | self.collect_block(block) | 684 | self.collect_block(block) |
@@ -1065,11 +919,16 @@ impl From<ast::LiteralKind> for Literal { | |||
1065 | fn from(ast_lit_kind: ast::LiteralKind) -> Self { | 919 | fn from(ast_lit_kind: ast::LiteralKind) -> Self { |
1066 | match ast_lit_kind { | 920 | match ast_lit_kind { |
1067 | LiteralKind::IntNumber(lit) => { | 921 | LiteralKind::IntNumber(lit) => { |
1068 | if let Some(float_suffix) = lit.suffix().and_then(BuiltinFloat::from_suffix) { | 922 | if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { |
1069 | return Literal::Float(Default::default(), Some(float_suffix)); | 923 | return Literal::Float(Default::default(), builtin); |
924 | } else if let builtin @ Some(_) = | ||
925 | lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it)) | ||
926 | { | ||
927 | Literal::Int(Default::default(), builtin) | ||
928 | } else { | ||
929 | let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it)); | ||
930 | Literal::Uint(Default::default(), builtin) | ||
1070 | } | 931 | } |
1071 | let ty = lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it)); | ||
1072 | Literal::Int(Default::default(), ty) | ||
1073 | } | 932 | } |
1074 | LiteralKind::FloatNumber(lit) => { | 933 | LiteralKind::FloatNumber(lit) => { |
1075 | let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it)); | 934 | let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it)); |
@@ -1077,7 +936,7 @@ impl From<ast::LiteralKind> for Literal { | |||
1077 | } | 936 | } |
1078 | LiteralKind::ByteString(_) => Literal::ByteString(Default::default()), | 937 | LiteralKind::ByteString(_) => Literal::ByteString(Default::default()), |
1079 | LiteralKind::String(_) => Literal::String(Default::default()), | 938 | LiteralKind::String(_) => Literal::String(Default::default()), |
1080 | LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), | 939 | LiteralKind::Byte => Literal::Uint(Default::default(), Some(BuiltinUint::U8)), |
1081 | LiteralKind::Bool(val) => Literal::Bool(val), | 940 | LiteralKind::Bool(val) => Literal::Bool(val), |
1082 | LiteralKind::Char => Literal::Char(Default::default()), | 941 | LiteralKind::Char => Literal::Char(Default::default()), |
1083 | } | 942 | } |
diff --git a/crates/hir_def/src/body/scope.rs b/crates/hir_def/src/body/scope.rs index 210b4a617..1bbb54fc6 100644 --- a/crates/hir_def/src/body/scope.rs +++ b/crates/hir_def/src/body/scope.rs | |||
@@ -186,7 +186,7 @@ mod tests { | |||
186 | use base_db::{fixture::WithFixture, FileId, SourceDatabase}; | 186 | use base_db::{fixture::WithFixture, FileId, SourceDatabase}; |
187 | use hir_expand::{name::AsName, InFile}; | 187 | use hir_expand::{name::AsName, InFile}; |
188 | use syntax::{algo::find_node_at_offset, ast, AstNode}; | 188 | use syntax::{algo::find_node_at_offset, ast, AstNode}; |
189 | use test_utils::{assert_eq_text, extract_offset, mark}; | 189 | use test_utils::{assert_eq_text, extract_offset}; |
190 | 190 | ||
191 | use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId}; | 191 | use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId}; |
192 | 192 | ||
@@ -454,7 +454,7 @@ fn foo() { | |||
454 | 454 | ||
455 | #[test] | 455 | #[test] |
456 | fn while_let_desugaring() { | 456 | fn while_let_desugaring() { |
457 | mark::check!(infer_resolve_while_let); | 457 | cov_mark::check!(infer_resolve_while_let); |
458 | do_check_local_name( | 458 | do_check_local_name( |
459 | r#" | 459 | r#" |
460 | fn test() { | 460 | fn test() { |
diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs index bb43569d7..991a32b15 100644 --- a/crates/hir_def/src/body/tests.rs +++ b/crates/hir_def/src/body/tests.rs | |||
@@ -2,7 +2,6 @@ mod block; | |||
2 | 2 | ||
3 | use base_db::{fixture::WithFixture, SourceDatabase}; | 3 | use base_db::{fixture::WithFixture, SourceDatabase}; |
4 | use expect_test::Expect; | 4 | use expect_test::Expect; |
5 | use test_utils::mark; | ||
6 | 5 | ||
7 | use crate::{test_db::TestDB, ModuleDefId}; | 6 | use crate::{test_db::TestDB, ModuleDefId}; |
8 | 7 | ||
@@ -48,7 +47,7 @@ fn check_at(ra_fixture: &str, expect: Expect) { | |||
48 | 47 | ||
49 | #[test] | 48 | #[test] |
50 | fn your_stack_belongs_to_me() { | 49 | fn your_stack_belongs_to_me() { |
51 | mark::check!(your_stack_belongs_to_me); | 50 | cov_mark::check!(your_stack_belongs_to_me); |
52 | lower( | 51 | lower( |
53 | " | 52 | " |
54 | macro_rules! n_nuple { | 53 | macro_rules! n_nuple { |
diff --git a/crates/hir_def/src/body/tests/block.rs b/crates/hir_def/src/body/tests/block.rs index a5ec0883f..3b6ba4cde 100644 --- a/crates/hir_def/src/body/tests/block.rs +++ b/crates/hir_def/src/body/tests/block.rs | |||
@@ -165,16 +165,16 @@ fn macro_resolve() { | |||
165 | check_at( | 165 | check_at( |
166 | r#" | 166 | r#" |
167 | //- /lib.rs crate:lib deps:core | 167 | //- /lib.rs crate:lib deps:core |
168 | use core::mark; | 168 | use core::cov_mark; |
169 | 169 | ||
170 | fn f() { | 170 | fn f() { |
171 | fn nested() { | 171 | fn nested() { |
172 | mark::hit!(Hit); | 172 | cov_mark::hit!(Hit); |
173 | $0 | 173 | $0 |
174 | } | 174 | } |
175 | } | 175 | } |
176 | //- /core.rs crate:core | 176 | //- /core.rs crate:core |
177 | pub mod mark { | 177 | pub mod cov_mark { |
178 | #[macro_export] | 178 | #[macro_export] |
179 | macro_rules! _hit { | 179 | macro_rules! _hit { |
180 | ($name:ident) => { | 180 | ($name:ident) => { |
@@ -193,8 +193,8 @@ pub mod mark { | |||
193 | nested: v | 193 | nested: v |
194 | 194 | ||
195 | crate | 195 | crate |
196 | cov_mark: t | ||
196 | f: v | 197 | f: v |
197 | mark: t | ||
198 | "#]], | 198 | "#]], |
199 | ); | 199 | ); |
200 | } | 200 | } |
@@ -259,3 +259,32 @@ fn main() { | |||
259 | "#]], | 259 | "#]], |
260 | ); | 260 | ); |
261 | } | 261 | } |
262 | |||
263 | #[test] | ||
264 | fn underscore_import() { | ||
265 | // This used to panic, because the default (private) visibility inside block expressions would | ||
266 | // point into the containing `DefMap`, which visibilities should never be able to do. | ||
267 | cov_mark::check!(adjust_vis_in_block_def_map); | ||
268 | check_at( | ||
269 | r#" | ||
270 | mod m { | ||
271 | fn main() { | ||
272 | use Tr as _; | ||
273 | trait Tr {} | ||
274 | $0 | ||
275 | } | ||
276 | } | ||
277 | "#, | ||
278 | expect![[r#" | ||
279 | block scope | ||
280 | _: t | ||
281 | Tr: t | ||
282 | |||
283 | crate | ||
284 | m: t | ||
285 | |||
286 | crate::m | ||
287 | main: v | ||
288 | "#]], | ||
289 | ); | ||
290 | } | ||