diff options
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | crates/hir/src/attrs.rs | 2 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/attr.rs | 21 | ||||
-rw-r--r-- | crates/hir_def/src/body.rs | 6 | ||||
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 28 | ||||
-rw-r--r-- | crates/hir_def/src/find_path.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 34 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 1 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/incremental.rs | 52 | ||||
-rw-r--r-- | crates/hir_def/src/path.rs | 9 | ||||
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/path/lower/lower_use.rs | 23 | ||||
-rw-r--r-- | crates/hir_def/src/visibility.rs | 8 | ||||
-rw-r--r-- | crates/hir_expand/src/hygiene.rs | 57 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 2 |
19 files changed, 180 insertions, 81 deletions
diff --git a/Cargo.toml b/Cargo.toml index 46c64d35c..d34251fc0 100644 --- a/Cargo.toml +++ b/Cargo.toml | |||
@@ -27,3 +27,5 @@ debug = 0 # Set this to 1 or 2 to get more useful backtraces in debugger. | |||
27 | # chalk-recursive = { path = "../chalk/chalk-recursive" } | 27 | # chalk-recursive = { path = "../chalk/chalk-recursive" } |
28 | 28 | ||
29 | # ungrammar = { path = "../ungrammar" } | 29 | # ungrammar = { path = "../ungrammar" } |
30 | |||
31 | # salsa = { path = "../salsa" } | ||
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 4a11622fc..e8fa3c56e 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs | |||
@@ -112,7 +112,7 @@ fn resolve_doc_path( | |||
112 | AttrDefId::MacroDefId(_) => return None, | 112 | AttrDefId::MacroDefId(_) => return None, |
113 | }; | 113 | }; |
114 | let path = ast::Path::parse(link).ok()?; | 114 | let path = ast::Path::parse(link).ok()?; |
115 | let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap(); | 115 | let modpath = ModPath::from_src(db.upcast(), path, &Hygiene::new_unhygienic()).unwrap(); |
116 | let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath); | 116 | let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath); |
117 | if resolved == PerNs::none() { | 117 | if resolved == PerNs::none() { |
118 | if let Some(trait_id) = resolver.resolve_module_path_in_trait_items(db.upcast(), &modpath) { | 118 | if let Some(trait_id) = resolver.resolve_module_path_in_trait_items(db.upcast(), &modpath) { |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 6fcc58f61..f876339de 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -1666,7 +1666,7 @@ impl Impl { | |||
1666 | .value | 1666 | .value |
1667 | .attrs() | 1667 | .attrs() |
1668 | .filter_map(|it| { | 1668 | .filter_map(|it| { |
1669 | let path = ModPath::from_src(it.path()?, &hygenic)?; | 1669 | let path = ModPath::from_src(db.upcast(), it.path()?, &hygenic)?; |
1670 | if path.as_ident()?.to_string() == "derive" { | 1670 | if path.as_ident()?.to_string() == "derive" { |
1671 | Some(it) | 1671 | Some(it) |
1672 | } else { | 1672 | } else { |
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 0895bd6f1..b5c65808e 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -283,7 +283,7 @@ impl SourceAnalyzer { | |||
283 | 283 | ||
284 | // This must be a normal source file rather than macro file. | 284 | // This must be a normal source file rather than macro file. |
285 | let hygiene = Hygiene::new(db.upcast(), self.file_id); | 285 | let hygiene = Hygiene::new(db.upcast(), self.file_id); |
286 | let ctx = body::LowerCtx::with_hygiene(&hygiene); | 286 | let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene); |
287 | let hir_path = Path::from_src(path.clone(), &ctx)?; | 287 | let hir_path = Path::from_src(path.clone(), &ctx)?; |
288 | 288 | ||
289 | // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we | 289 | // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 0171d8a92..a2479016e 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -95,13 +95,17 @@ impl ops::Deref for AttrsWithOwner { | |||
95 | impl RawAttrs { | 95 | impl RawAttrs { |
96 | pub(crate) const EMPTY: Self = Self { entries: None }; | 96 | pub(crate) const EMPTY: Self = Self { entries: None }; |
97 | 97 | ||
98 | pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self { | 98 | pub(crate) fn new( |
99 | db: &dyn DefDatabase, | ||
100 | owner: &dyn ast::AttrsOwner, | ||
101 | hygiene: &Hygiene, | ||
102 | ) -> Self { | ||
99 | let entries = collect_attrs(owner) | 103 | let entries = collect_attrs(owner) |
100 | .enumerate() | 104 | .enumerate() |
101 | .flat_map(|(i, attr)| { | 105 | .flat_map(|(i, attr)| { |
102 | let index = AttrId(i as u32); | 106 | let index = AttrId(i as u32); |
103 | match attr { | 107 | match attr { |
104 | Either::Left(attr) => Attr::from_src(attr, hygiene, index), | 108 | Either::Left(attr) => Attr::from_src(db, attr, hygiene, index), |
105 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { | 109 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { |
106 | id: index, | 110 | id: index, |
107 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | 111 | input: Some(AttrInput::Literal(SmolStr::new(doc))), |
@@ -116,7 +120,7 @@ impl RawAttrs { | |||
116 | 120 | ||
117 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self { | 121 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self { |
118 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | 122 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); |
119 | Self::new(owner.value, &hygiene) | 123 | Self::new(db, owner.value, &hygiene) |
120 | } | 124 | } |
121 | 125 | ||
122 | pub(crate) fn merge(&self, other: Self) -> Self { | 126 | pub(crate) fn merge(&self, other: Self) -> Self { |
@@ -170,7 +174,7 @@ impl RawAttrs { | |||
170 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; | 174 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; |
171 | // FIXME hygiene | 175 | // FIXME hygiene |
172 | let hygiene = Hygiene::new_unhygienic(); | 176 | let hygiene = Hygiene::new_unhygienic(); |
173 | Attr::from_src(attr, &hygiene, index) | 177 | Attr::from_src(db, attr, &hygiene, index) |
174 | }); | 178 | }); |
175 | 179 | ||
176 | let cfg_options = &crate_graph[krate].cfg_options; | 180 | let cfg_options = &crate_graph[krate].cfg_options; |
@@ -627,8 +631,13 @@ pub enum AttrInput { | |||
627 | } | 631 | } |
628 | 632 | ||
629 | impl Attr { | 633 | impl Attr { |
630 | fn from_src(ast: ast::Attr, hygiene: &Hygiene, id: AttrId) -> Option<Attr> { | 634 | fn from_src( |
631 | let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?); | 635 | db: &dyn DefDatabase, |
636 | ast: ast::Attr, | ||
637 | hygiene: &Hygiene, | ||
638 | id: AttrId, | ||
639 | ) -> Option<Attr> { | ||
640 | let path = Interned::new(ModPath::from_src(db, ast.path()?, hygiene)?); | ||
632 | let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { | 641 | let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { |
633 | let value = match lit.kind() { | 642 | let value = match lit.kind() { |
634 | ast::LiteralKind::String(string) => string.value()?.into(), | 643 | ast::LiteralKind::String(string) => string.value()?.into(), |
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 131f424cc..8360426f1 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -72,7 +72,7 @@ impl CfgExpander { | |||
72 | } | 72 | } |
73 | 73 | ||
74 | pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs { | 74 | pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs { |
75 | RawAttrs::new(owner, &self.hygiene).filter(db, self.krate) | 75 | RawAttrs::new(db, owner, &self.hygiene).filter(db, self.krate) |
76 | } | 76 | } |
77 | 77 | ||
78 | pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool { | 78 | pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool { |
@@ -192,8 +192,8 @@ impl Expander { | |||
192 | self.current_file_id | 192 | self.current_file_id |
193 | } | 193 | } |
194 | 194 | ||
195 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 195 | fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option<Path> { |
196 | let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene); | 196 | let ctx = LowerCtx::with_hygiene(db, &self.cfg_expander.hygiene); |
197 | Path::from_src(path, &ctx) | 197 | Path::from_src(path, &ctx) |
198 | } | 198 | } |
199 | 199 | ||
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index c11da30d2..75dc19c11 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -40,23 +40,25 @@ use crate::{ | |||
40 | 40 | ||
41 | use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; | 41 | use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; |
42 | 42 | ||
43 | pub struct LowerCtx { | 43 | pub struct LowerCtx<'a> { |
44 | pub db: &'a dyn DefDatabase, | ||
44 | hygiene: Hygiene, | 45 | hygiene: Hygiene, |
45 | file_id: Option<HirFileId>, | 46 | file_id: Option<HirFileId>, |
46 | source_ast_id_map: Option<Arc<AstIdMap>>, | 47 | source_ast_id_map: Option<Arc<AstIdMap>>, |
47 | } | 48 | } |
48 | 49 | ||
49 | impl LowerCtx { | 50 | impl<'a> LowerCtx<'a> { |
50 | pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { | 51 | pub fn new(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self { |
51 | LowerCtx { | 52 | LowerCtx { |
53 | db, | ||
52 | hygiene: Hygiene::new(db.upcast(), file_id), | 54 | hygiene: Hygiene::new(db.upcast(), file_id), |
53 | file_id: Some(file_id), | 55 | file_id: Some(file_id), |
54 | source_ast_id_map: Some(db.ast_id_map(file_id)), | 56 | source_ast_id_map: Some(db.ast_id_map(file_id)), |
55 | } | 57 | } |
56 | } | 58 | } |
57 | 59 | ||
58 | pub fn with_hygiene(hygiene: &Hygiene) -> Self { | 60 | pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self { |
59 | LowerCtx { hygiene: hygiene.clone(), file_id: None, source_ast_id_map: None } | 61 | LowerCtx { db, hygiene: hygiene.clone(), file_id: None, source_ast_id_map: None } |
60 | } | 62 | } |
61 | 63 | ||
62 | pub(crate) fn hygiene(&self) -> &Hygiene { | 64 | pub(crate) fn hygiene(&self) -> &Hygiene { |
@@ -145,7 +147,7 @@ impl ExprCollector<'_> { | |||
145 | (self.body, self.source_map) | 147 | (self.body, self.source_map) |
146 | } | 148 | } |
147 | 149 | ||
148 | fn ctx(&self) -> LowerCtx { | 150 | fn ctx(&self) -> LowerCtx<'_> { |
149 | LowerCtx::new(self.db, self.expander.current_file_id) | 151 | LowerCtx::new(self.db, self.expander.current_file_id) |
150 | } | 152 | } |
151 | 153 | ||
@@ -376,7 +378,7 @@ impl ExprCollector<'_> { | |||
376 | ast::Expr::PathExpr(e) => { | 378 | ast::Expr::PathExpr(e) => { |
377 | let path = e | 379 | let path = e |
378 | .path() | 380 | .path() |
379 | .and_then(|path| self.expander.parse_path(path)) | 381 | .and_then(|path| self.expander.parse_path(self.db, path)) |
380 | .map(Expr::Path) | 382 | .map(Expr::Path) |
381 | .unwrap_or(Expr::Missing); | 383 | .unwrap_or(Expr::Missing); |
382 | self.alloc_expr(path, syntax_ptr) | 384 | self.alloc_expr(path, syntax_ptr) |
@@ -408,7 +410,8 @@ impl ExprCollector<'_> { | |||
408 | self.alloc_expr(Expr::Yield { expr }, syntax_ptr) | 410 | self.alloc_expr(Expr::Yield { expr }, syntax_ptr) |
409 | } | 411 | } |
410 | ast::Expr::RecordExpr(e) => { | 412 | ast::Expr::RecordExpr(e) => { |
411 | let path = e.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); | 413 | let path = |
414 | e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); | ||
412 | let record_lit = if let Some(nfl) = e.record_expr_field_list() { | 415 | let record_lit = if let Some(nfl) = e.record_expr_field_list() { |
413 | let fields = nfl | 416 | let fields = nfl |
414 | .fields() | 417 | .fields() |
@@ -791,7 +794,8 @@ impl ExprCollector<'_> { | |||
791 | } | 794 | } |
792 | } | 795 | } |
793 | ast::Pat::TupleStructPat(p) => { | 796 | ast::Pat::TupleStructPat(p) => { |
794 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); | 797 | let path = |
798 | p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); | ||
795 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); | 799 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); |
796 | Pat::TupleStruct { path, args, ellipsis } | 800 | Pat::TupleStruct { path, args, ellipsis } |
797 | } | 801 | } |
@@ -801,7 +805,8 @@ impl ExprCollector<'_> { | |||
801 | Pat::Ref { pat, mutability } | 805 | Pat::Ref { pat, mutability } |
802 | } | 806 | } |
803 | ast::Pat::PathPat(p) => { | 807 | ast::Pat::PathPat(p) => { |
804 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); | 808 | let path = |
809 | p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); | ||
805 | path.map(Pat::Path).unwrap_or(Pat::Missing) | 810 | path.map(Pat::Path).unwrap_or(Pat::Missing) |
806 | } | 811 | } |
807 | ast::Pat::OrPat(p) => { | 812 | ast::Pat::OrPat(p) => { |
@@ -815,7 +820,8 @@ impl ExprCollector<'_> { | |||
815 | } | 820 | } |
816 | ast::Pat::WildcardPat(_) => Pat::Wild, | 821 | ast::Pat::WildcardPat(_) => Pat::Wild, |
817 | ast::Pat::RecordPat(p) => { | 822 | ast::Pat::RecordPat(p) => { |
818 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); | 823 | let path = |
824 | p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); | ||
819 | let args: Vec<_> = p | 825 | let args: Vec<_> = p |
820 | .record_pat_field_list() | 826 | .record_pat_field_list() |
821 | .expect("every struct should have a field list") | 827 | .expect("every struct should have a field list") |
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index c06a37294..858e88038 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs | |||
@@ -386,7 +386,7 @@ mod tests { | |||
386 | let parsed_path_file = syntax::SourceFile::parse(&format!("use {};", path)); | 386 | let parsed_path_file = syntax::SourceFile::parse(&format!("use {};", path)); |
387 | let ast_path = | 387 | let ast_path = |
388 | parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap(); | 388 | parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap(); |
389 | let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap(); | 389 | let mod_path = ModPath::from_src(&db, ast_path, &Hygiene::new_unhygienic()).unwrap(); |
390 | 390 | ||
391 | let def_map = module.def_map(&db); | 391 | let def_map = module.def_map(&db); |
392 | let resolved = def_map | 392 | let resolved = def_map |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index eaeca01bd..8d13c7e04 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -88,7 +88,7 @@ impl ItemTree { | |||
88 | let mut item_tree = match_ast! { | 88 | let mut item_tree = match_ast! { |
89 | match syntax { | 89 | match syntax { |
90 | ast::SourceFile(file) => { | 90 | ast::SourceFile(file) => { |
91 | top_attrs = Some(RawAttrs::new(&file, &hygiene)); | 91 | top_attrs = Some(RawAttrs::new(db, &file, &hygiene)); |
92 | ctx.lower_module_items(&file) | 92 | ctx.lower_module_items(&file) |
93 | }, | 93 | }, |
94 | ast::MacroItems(items) => { | 94 | ast::MacroItems(items) => { |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 45b099cf3..5743b3386 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -31,18 +31,20 @@ where | |||
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | pub(super) struct Ctx { | 34 | pub(super) struct Ctx<'a> { |
35 | db: &'a dyn DefDatabase, | ||
35 | tree: ItemTree, | 36 | tree: ItemTree, |
36 | hygiene: Hygiene, | 37 | hygiene: Hygiene, |
37 | file: HirFileId, | 38 | file: HirFileId, |
38 | source_ast_id_map: Arc<AstIdMap>, | 39 | source_ast_id_map: Arc<AstIdMap>, |
39 | body_ctx: crate::body::LowerCtx, | 40 | body_ctx: crate::body::LowerCtx<'a>, |
40 | forced_visibility: Option<RawVisibilityId>, | 41 | forced_visibility: Option<RawVisibilityId>, |
41 | } | 42 | } |
42 | 43 | ||
43 | impl Ctx { | 44 | impl<'a> Ctx<'a> { |
44 | pub(super) fn new(db: &dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self { | 45 | pub(super) fn new(db: &'a dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self { |
45 | Self { | 46 | Self { |
47 | db, | ||
46 | tree: ItemTree::default(), | 48 | tree: ItemTree::default(), |
47 | hygiene, | 49 | hygiene, |
48 | file, | 50 | file, |
@@ -126,7 +128,7 @@ impl Ctx { | |||
126 | | ast::Item::MacroDef(_) => {} | 128 | | ast::Item::MacroDef(_) => {} |
127 | }; | 129 | }; |
128 | 130 | ||
129 | let attrs = RawAttrs::new(item, &self.hygiene); | 131 | let attrs = RawAttrs::new(self.db, item, &self.hygiene); |
130 | let items = match item { | 132 | let items = match item { |
131 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), | 133 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), |
132 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), | 134 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), |
@@ -256,7 +258,7 @@ impl Ctx { | |||
256 | for field in fields.fields() { | 258 | for field in fields.fields() { |
257 | if let Some(data) = self.lower_record_field(&field) { | 259 | if let Some(data) = self.lower_record_field(&field) { |
258 | let idx = self.data().fields.alloc(data); | 260 | let idx = self.data().fields.alloc(data); |
259 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); | 261 | self.add_attrs(idx.into(), RawAttrs::new(self.db, &field, &self.hygiene)); |
260 | } | 262 | } |
261 | } | 263 | } |
262 | let end = self.next_field_idx(); | 264 | let end = self.next_field_idx(); |
@@ -276,7 +278,7 @@ impl Ctx { | |||
276 | for (i, field) in fields.fields().enumerate() { | 278 | for (i, field) in fields.fields().enumerate() { |
277 | let data = self.lower_tuple_field(i, &field); | 279 | let data = self.lower_tuple_field(i, &field); |
278 | let idx = self.data().fields.alloc(data); | 280 | let idx = self.data().fields.alloc(data); |
279 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); | 281 | self.add_attrs(idx.into(), RawAttrs::new(self.db, &field, &self.hygiene)); |
280 | } | 282 | } |
281 | let end = self.next_field_idx(); | 283 | let end = self.next_field_idx(); |
282 | IdRange::new(start..end) | 284 | IdRange::new(start..end) |
@@ -321,7 +323,7 @@ impl Ctx { | |||
321 | for variant in variants.variants() { | 323 | for variant in variants.variants() { |
322 | if let Some(data) = self.lower_variant(&variant) { | 324 | if let Some(data) = self.lower_variant(&variant) { |
323 | let idx = self.data().variants.alloc(data); | 325 | let idx = self.data().variants.alloc(data); |
324 | self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene)); | 326 | self.add_attrs(idx.into(), RawAttrs::new(self.db, &variant, &self.hygiene)); |
325 | } | 327 | } |
326 | } | 328 | } |
327 | let end = self.next_variant_idx(); | 329 | let end = self.next_variant_idx(); |
@@ -364,7 +366,7 @@ impl Ctx { | |||
364 | }; | 366 | }; |
365 | let ty = Interned::new(self_type); | 367 | let ty = Interned::new(self_type); |
366 | let idx = self.data().params.alloc(Param::Normal(ty)); | 368 | let idx = self.data().params.alloc(Param::Normal(ty)); |
367 | self.add_attrs(idx.into(), RawAttrs::new(&self_param, &self.hygiene)); | 369 | self.add_attrs(idx.into(), RawAttrs::new(self.db, &self_param, &self.hygiene)); |
368 | has_self_param = true; | 370 | has_self_param = true; |
369 | } | 371 | } |
370 | for param in param_list.params() { | 372 | for param in param_list.params() { |
@@ -376,7 +378,7 @@ impl Ctx { | |||
376 | self.data().params.alloc(Param::Normal(ty)) | 378 | self.data().params.alloc(Param::Normal(ty)) |
377 | } | 379 | } |
378 | }; | 380 | }; |
379 | self.add_attrs(idx.into(), RawAttrs::new(¶m, &self.hygiene)); | 381 | self.add_attrs(idx.into(), RawAttrs::new(self.db, ¶m, &self.hygiene)); |
380 | } | 382 | } |
381 | } | 383 | } |
382 | let end_param = self.next_param_idx(); | 384 | let end_param = self.next_param_idx(); |
@@ -522,10 +524,11 @@ impl Ctx { | |||
522 | let is_unsafe = trait_def.unsafe_token().is_some(); | 524 | let is_unsafe = trait_def.unsafe_token().is_some(); |
523 | let bounds = self.lower_type_bounds(trait_def); | 525 | let bounds = self.lower_type_bounds(trait_def); |
524 | let items = trait_def.assoc_item_list().map(|list| { | 526 | let items = trait_def.assoc_item_list().map(|list| { |
527 | let db = self.db; | ||
525 | self.with_inherited_visibility(visibility, |this| { | 528 | self.with_inherited_visibility(visibility, |this| { |
526 | list.assoc_items() | 529 | list.assoc_items() |
527 | .filter_map(|item| { | 530 | .filter_map(|item| { |
528 | let attrs = RawAttrs::new(&item, &this.hygiene); | 531 | let attrs = RawAttrs::new(db, &item, &this.hygiene); |
529 | this.collect_inner_items(item.syntax()); | 532 | this.collect_inner_items(item.syntax()); |
530 | this.lower_assoc_item(&item).map(|item| { | 533 | this.lower_assoc_item(&item).map(|item| { |
531 | this.add_attrs(ModItem::from(item).into(), attrs); | 534 | this.add_attrs(ModItem::from(item).into(), attrs); |
@@ -567,7 +570,7 @@ impl Ctx { | |||
567 | .filter_map(|item| { | 570 | .filter_map(|item| { |
568 | self.collect_inner_items(item.syntax()); | 571 | self.collect_inner_items(item.syntax()); |
569 | let assoc = self.lower_assoc_item(&item)?; | 572 | let assoc = self.lower_assoc_item(&item)?; |
570 | let attrs = RawAttrs::new(&item, &self.hygiene); | 573 | let attrs = RawAttrs::new(self.db, &item, &self.hygiene); |
571 | self.add_attrs(ModItem::from(assoc).into(), attrs); | 574 | self.add_attrs(ModItem::from(assoc).into(), attrs); |
572 | Some(assoc) | 575 | Some(assoc) |
573 | }) | 576 | }) |
@@ -585,6 +588,7 @@ impl Ctx { | |||
585 | let mut imports = Vec::new(); | 588 | let mut imports = Vec::new(); |
586 | let tree = self.tree.data_mut(); | 589 | let tree = self.tree.data_mut(); |
587 | ModPath::expand_use_item( | 590 | ModPath::expand_use_item( |
591 | self.db, | ||
588 | InFile::new(self.file, use_item.clone()), | 592 | InFile::new(self.file, use_item.clone()), |
589 | &self.hygiene, | 593 | &self.hygiene, |
590 | |path, _use_tree, is_glob, alias| { | 594 | |path, _use_tree, is_glob, alias| { |
@@ -618,7 +622,7 @@ impl Ctx { | |||
618 | } | 622 | } |
619 | 623 | ||
620 | fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> { | 624 | fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> { |
621 | let path = Interned::new(ModPath::from_src(m.path()?, &self.hygiene)?); | 625 | let path = Interned::new(ModPath::from_src(self.db, m.path()?, &self.hygiene)?); |
622 | let ast_id = self.source_ast_id_map.ast_id(m); | 626 | let ast_id = self.source_ast_id_map.ast_id(m); |
623 | let res = MacroCall { path, ast_id }; | 627 | let res = MacroCall { path, ast_id }; |
624 | Some(id(self.data().macro_calls.alloc(res))) | 628 | Some(id(self.data().macro_calls.alloc(res))) |
@@ -647,7 +651,7 @@ impl Ctx { | |||
647 | list.extern_items() | 651 | list.extern_items() |
648 | .filter_map(|item| { | 652 | .filter_map(|item| { |
649 | self.collect_inner_items(item.syntax()); | 653 | self.collect_inner_items(item.syntax()); |
650 | let attrs = RawAttrs::new(&item, &self.hygiene); | 654 | let attrs = RawAttrs::new(self.db, &item, &self.hygiene); |
651 | let id: ModItem = match item { | 655 | let id: ModItem = match item { |
652 | ast::ExternItem::Fn(ast) => { | 656 | ast::ExternItem::Fn(ast) => { |
653 | let func_id = self.lower_function(&ast)?; | 657 | let func_id = self.lower_function(&ast)?; |
@@ -755,7 +759,7 @@ impl Ctx { | |||
755 | fn lower_visibility(&mut self, item: &impl ast::VisibilityOwner) -> RawVisibilityId { | 759 | fn lower_visibility(&mut self, item: &impl ast::VisibilityOwner) -> RawVisibilityId { |
756 | let vis = match self.forced_visibility { | 760 | let vis = match self.forced_visibility { |
757 | Some(vis) => return vis, | 761 | Some(vis) => return vis, |
758 | None => RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene), | 762 | None => RawVisibility::from_ast_with_hygiene(self.db, item.visibility(), &self.hygiene), |
759 | }; | 763 | }; |
760 | 764 | ||
761 | self.data().vis.alloc(vis) | 765 | self.data().vis.alloc(vis) |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 25694f037..da46f16f7 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -654,7 +654,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> { | |||
654 | ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { | 654 | ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { |
655 | let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); | 655 | let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); |
656 | let h = Hygiene::new(db.upcast(), self.file_id); | 656 | let h = Hygiene::new(db.upcast(), self.file_id); |
657 | let path = self.value.path().and_then(|path| path::ModPath::from_src(path, &h)); | 657 | let path = self.value.path().and_then(|path| path::ModPath::from_src(db, path, &h)); |
658 | 658 | ||
659 | let path = match error_sink | 659 | let path = match error_sink |
660 | .option(path, || mbe::ExpandError::Other("malformed macro invocation".into())) | 660 | .option(path, || mbe::ExpandError::Other("malformed macro invocation".into())) |
@@ -712,7 +712,7 @@ fn macro_call_as_call_id( | |||
712 | krate, | 712 | krate, |
713 | macro_call, | 713 | macro_call, |
714 | def, | 714 | def, |
715 | &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?), | 715 | &|path: ast::Path| resolver(path::ModPath::from_src(db, path, &hygiene)?), |
716 | error_sink, | 716 | error_sink, |
717 | ) | 717 | ) |
718 | .map(MacroCallId::from) | 718 | .map(MacroCallId::from) |
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index ba027c44a..1bc72ec1f 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs | |||
@@ -599,6 +599,7 @@ mod diagnostics { | |||
599 | let mut cur = 0; | 599 | let mut cur = 0; |
600 | let mut tree = None; | 600 | let mut tree = None; |
601 | ModPath::expand_use_item( | 601 | ModPath::expand_use_item( |
602 | db, | ||
602 | InFile::new(ast.file_id, use_item), | 603 | InFile::new(ast.file_id, use_item), |
603 | &hygiene, | 604 | &hygiene, |
604 | |_mod_path, use_tree, _is_glob, _alias| { | 605 | |_mod_path, use_tree, _is_glob, _alias| { |
diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs index 509e1bbbc..227ecd162 100644 --- a/crates/hir_def/src/nameres/tests/incremental.rs +++ b/crates/hir_def/src/nameres/tests/incremental.rs | |||
@@ -105,3 +105,55 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() { | |||
105 | assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) | 105 | assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) |
106 | } | 106 | } |
107 | } | 107 | } |
108 | |||
109 | #[test] | ||
110 | fn typing_inside_a_function_should_not_invalidate_expansions() { | ||
111 | let (mut db, pos) = TestDB::with_position( | ||
112 | r#" | ||
113 | //- /lib.rs | ||
114 | macro_rules! m { | ||
115 | ($ident:ident) => { | ||
116 | fn $ident() { }; | ||
117 | } | ||
118 | } | ||
119 | mod foo; | ||
120 | |||
121 | //- /foo/mod.rs | ||
122 | pub mod bar; | ||
123 | |||
124 | //- /foo/bar.rs | ||
125 | m!(X); | ||
126 | fn quux() { 1$0 } | ||
127 | m!(Y); | ||
128 | m!(Z); | ||
129 | "#, | ||
130 | ); | ||
131 | let krate = db.test_crate(); | ||
132 | { | ||
133 | let events = db.log_executed(|| { | ||
134 | let crate_def_map = db.crate_def_map(krate); | ||
135 | let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); | ||
136 | assert_eq!(module_data.scope.resolutions().count(), 4); | ||
137 | }); | ||
138 | let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count(); | ||
139 | assert_eq!(n_recalculated_item_trees, 6); | ||
140 | } | ||
141 | |||
142 | let new_text = r#" | ||
143 | m!(X); | ||
144 | fn quux() { 92 } | ||
145 | m!(Y); | ||
146 | m!(Z); | ||
147 | "#; | ||
148 | db.set_file_text(pos.file_id, Arc::new(new_text.to_string())); | ||
149 | |||
150 | { | ||
151 | let events = db.log_executed(|| { | ||
152 | let crate_def_map = db.crate_def_map(krate); | ||
153 | let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); | ||
154 | assert_eq!(module_data.scope.resolutions().count(), 4); | ||
155 | }); | ||
156 | let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count(); | ||
157 | assert_eq!(n_recalculated_item_trees, 1); | ||
158 | } | ||
159 | } | ||
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 509f77850..a43441b1c 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs | |||
@@ -7,7 +7,7 @@ use std::{ | |||
7 | sync::Arc, | 7 | sync::Arc, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | use crate::{body::LowerCtx, intern::Interned, type_ref::LifetimeRef}; | 10 | use crate::{body::LowerCtx, db::DefDatabase, intern::Interned, type_ref::LifetimeRef}; |
11 | use base_db::CrateId; | 11 | use base_db::CrateId; |
12 | use hir_expand::{ | 12 | use hir_expand::{ |
13 | hygiene::Hygiene, | 13 | hygiene::Hygiene, |
@@ -47,8 +47,8 @@ pub enum ImportAlias { | |||
47 | } | 47 | } |
48 | 48 | ||
49 | impl ModPath { | 49 | impl ModPath { |
50 | pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> { | 50 | pub fn from_src(db: &dyn DefDatabase, path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> { |
51 | let ctx = LowerCtx::with_hygiene(hygiene); | 51 | let ctx = LowerCtx::with_hygiene(db, hygiene); |
52 | lower::lower_path(path, &ctx).map(|it| (*it.mod_path).clone()) | 52 | lower::lower_path(path, &ctx).map(|it| (*it.mod_path).clone()) |
53 | } | 53 | } |
54 | 54 | ||
@@ -64,12 +64,13 @@ impl ModPath { | |||
64 | 64 | ||
65 | /// Calls `cb` with all paths, represented by this use item. | 65 | /// Calls `cb` with all paths, represented by this use item. |
66 | pub(crate) fn expand_use_item( | 66 | pub(crate) fn expand_use_item( |
67 | db: &dyn DefDatabase, | ||
67 | item_src: InFile<ast::Use>, | 68 | item_src: InFile<ast::Use>, |
68 | hygiene: &Hygiene, | 69 | hygiene: &Hygiene, |
69 | mut cb: impl FnMut(ModPath, &ast::UseTree, /* is_glob */ bool, Option<ImportAlias>), | 70 | mut cb: impl FnMut(ModPath, &ast::UseTree, /* is_glob */ bool, Option<ImportAlias>), |
70 | ) { | 71 | ) { |
71 | if let Some(tree) = item_src.value.use_tree() { | 72 | if let Some(tree) = item_src.value.use_tree() { |
72 | lower::lower_use_tree(None, tree, hygiene, &mut cb); | 73 | lower::lower_use_tree(db, None, tree, hygiene, &mut cb); |
73 | } | 74 | } |
74 | } | 75 | } |
75 | 76 | ||
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 1df6db525..a873325b2 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs | |||
@@ -36,7 +36,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> { | |||
36 | match segment.kind()? { | 36 | match segment.kind()? { |
37 | ast::PathSegmentKind::Name(name_ref) => { | 37 | ast::PathSegmentKind::Name(name_ref) => { |
38 | // FIXME: this should just return name | 38 | // FIXME: this should just return name |
39 | match hygiene.name_ref_to_name(name_ref) { | 39 | match hygiene.name_ref_to_name(ctx.db.upcast(), name_ref) { |
40 | Either::Left(name) => { | 40 | Either::Left(name) => { |
41 | let args = segment | 41 | let args = segment |
42 | .generic_arg_list() | 42 | .generic_arg_list() |
@@ -133,7 +133,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> { | |||
133 | // We follow what it did anyway :) | 133 | // We follow what it did anyway :) |
134 | if segments.len() == 1 && kind == PathKind::Plain { | 134 | if segments.len() == 1 && kind == PathKind::Plain { |
135 | if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { | 135 | if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { |
136 | if let Some(crate_id) = hygiene.local_inner_macros(path) { | 136 | if let Some(crate_id) = hygiene.local_inner_macros(ctx.db.upcast(), path) { |
137 | kind = PathKind::DollarCrate(crate_id); | 137 | kind = PathKind::DollarCrate(crate_id); |
138 | } | 138 | } |
139 | } | 139 | } |
diff --git a/crates/hir_def/src/path/lower/lower_use.rs b/crates/hir_def/src/path/lower/lower_use.rs index e2965b033..ee80e3df3 100644 --- a/crates/hir_def/src/path/lower/lower_use.rs +++ b/crates/hir_def/src/path/lower/lower_use.rs | |||
@@ -7,9 +7,13 @@ use either::Either; | |||
7 | use hir_expand::{hygiene::Hygiene, name::AsName}; | 7 | use hir_expand::{hygiene::Hygiene, name::AsName}; |
8 | use syntax::ast::{self, NameOwner}; | 8 | use syntax::ast::{self, NameOwner}; |
9 | 9 | ||
10 | use crate::path::{ImportAlias, ModPath, PathKind}; | 10 | use crate::{ |
11 | db::DefDatabase, | ||
12 | path::{ImportAlias, ModPath, PathKind}, | ||
13 | }; | ||
11 | 14 | ||
12 | pub(crate) fn lower_use_tree( | 15 | pub(crate) fn lower_use_tree( |
16 | db: &dyn DefDatabase, | ||
13 | prefix: Option<ModPath>, | 17 | prefix: Option<ModPath>, |
14 | tree: ast::UseTree, | 18 | tree: ast::UseTree, |
15 | hygiene: &Hygiene, | 19 | hygiene: &Hygiene, |
@@ -21,13 +25,13 @@ pub(crate) fn lower_use_tree( | |||
21 | None => prefix, | 25 | None => prefix, |
22 | // E.g. `use something::{inner}` (prefix is `None`, path is `something`) | 26 | // E.g. `use something::{inner}` (prefix is `None`, path is `something`) |
23 | // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) | 27 | // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) |
24 | Some(path) => match convert_path(prefix, path, hygiene) { | 28 | Some(path) => match convert_path(db, prefix, path, hygiene) { |
25 | Some(it) => Some(it), | 29 | Some(it) => Some(it), |
26 | None => return, // FIXME: report errors somewhere | 30 | None => return, // FIXME: report errors somewhere |
27 | }, | 31 | }, |
28 | }; | 32 | }; |
29 | for child_tree in use_tree_list.use_trees() { | 33 | for child_tree in use_tree_list.use_trees() { |
30 | lower_use_tree(prefix.clone(), child_tree, hygiene, cb); | 34 | lower_use_tree(db, prefix.clone(), child_tree, hygiene, cb); |
31 | } | 35 | } |
32 | } else { | 36 | } else { |
33 | let alias = tree.rename().map(|a| { | 37 | let alias = tree.rename().map(|a| { |
@@ -47,7 +51,7 @@ pub(crate) fn lower_use_tree( | |||
47 | } | 51 | } |
48 | } | 52 | } |
49 | } | 53 | } |
50 | if let Some(path) = convert_path(prefix, ast_path, hygiene) { | 54 | if let Some(path) = convert_path(db, prefix, ast_path, hygiene) { |
51 | cb(path, &tree, is_glob, alias) | 55 | cb(path, &tree, is_glob, alias) |
52 | } | 56 | } |
53 | // FIXME: report errors somewhere | 57 | // FIXME: report errors somewhere |
@@ -61,9 +65,14 @@ pub(crate) fn lower_use_tree( | |||
61 | } | 65 | } |
62 | } | 66 | } |
63 | 67 | ||
64 | fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> { | 68 | fn convert_path( |
69 | db: &dyn DefDatabase, | ||
70 | prefix: Option<ModPath>, | ||
71 | path: ast::Path, | ||
72 | hygiene: &Hygiene, | ||
73 | ) -> Option<ModPath> { | ||
65 | let prefix = if let Some(qual) = path.qualifier() { | 74 | let prefix = if let Some(qual) = path.qualifier() { |
66 | Some(convert_path(prefix, qual, hygiene)?) | 75 | Some(convert_path(db, prefix, qual, hygiene)?) |
67 | } else { | 76 | } else { |
68 | prefix | 77 | prefix |
69 | }; | 78 | }; |
@@ -71,7 +80,7 @@ fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) -> | |||
71 | let segment = path.segment()?; | 80 | let segment = path.segment()?; |
72 | let res = match segment.kind()? { | 81 | let res = match segment.kind()? { |
73 | ast::PathSegmentKind::Name(name_ref) => { | 82 | ast::PathSegmentKind::Name(name_ref) => { |
74 | match hygiene.name_ref_to_name(name_ref) { | 83 | match hygiene.name_ref_to_name(db.upcast(), name_ref) { |
75 | Either::Left(name) => { | 84 | Either::Left(name) => { |
76 | // no type args in use | 85 | // no type args in use |
77 | let mut res = prefix.unwrap_or_else(|| { | 86 | let mut res = prefix.unwrap_or_else(|| { |
diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs index d4b7c9970..83500f54e 100644 --- a/crates/hir_def/src/visibility.rs +++ b/crates/hir_def/src/visibility.rs | |||
@@ -33,17 +33,19 @@ impl RawVisibility { | |||
33 | db: &dyn DefDatabase, | 33 | db: &dyn DefDatabase, |
34 | node: InFile<Option<ast::Visibility>>, | 34 | node: InFile<Option<ast::Visibility>>, |
35 | ) -> RawVisibility { | 35 | ) -> RawVisibility { |
36 | Self::from_ast_with_hygiene(node.value, &Hygiene::new(db.upcast(), node.file_id)) | 36 | Self::from_ast_with_hygiene(db, node.value, &Hygiene::new(db.upcast(), node.file_id)) |
37 | } | 37 | } |
38 | 38 | ||
39 | pub(crate) fn from_ast_with_hygiene( | 39 | pub(crate) fn from_ast_with_hygiene( |
40 | db: &dyn DefDatabase, | ||
40 | node: Option<ast::Visibility>, | 41 | node: Option<ast::Visibility>, |
41 | hygiene: &Hygiene, | 42 | hygiene: &Hygiene, |
42 | ) -> RawVisibility { | 43 | ) -> RawVisibility { |
43 | Self::from_ast_with_hygiene_and_default(node, RawVisibility::private(), hygiene) | 44 | Self::from_ast_with_hygiene_and_default(db, node, RawVisibility::private(), hygiene) |
44 | } | 45 | } |
45 | 46 | ||
46 | pub(crate) fn from_ast_with_hygiene_and_default( | 47 | pub(crate) fn from_ast_with_hygiene_and_default( |
48 | db: &dyn DefDatabase, | ||
47 | node: Option<ast::Visibility>, | 49 | node: Option<ast::Visibility>, |
48 | default: RawVisibility, | 50 | default: RawVisibility, |
49 | hygiene: &Hygiene, | 51 | hygiene: &Hygiene, |
@@ -54,7 +56,7 @@ impl RawVisibility { | |||
54 | }; | 56 | }; |
55 | match node.kind() { | 57 | match node.kind() { |
56 | ast::VisibilityKind::In(path) => { | 58 | ast::VisibilityKind::In(path) => { |
57 | let path = ModPath::from_src(path, hygiene); | 59 | let path = ModPath::from_src(db, path, hygiene); |
58 | let path = match path { | 60 | let path = match path { |
59 | None => return RawVisibility::private(), | 61 | None => return RawVisibility::private(), |
60 | Some(path) => path, | 62 | Some(path) => path, |
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index ed61ebca3..aca69e35a 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs | |||
@@ -32,10 +32,14 @@ impl Hygiene { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | // FIXME: this should just return name | 34 | // FIXME: this should just return name |
35 | pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either<Name, CrateId> { | 35 | pub fn name_ref_to_name( |
36 | &self, | ||
37 | db: &dyn AstDatabase, | ||
38 | name_ref: ast::NameRef, | ||
39 | ) -> Either<Name, CrateId> { | ||
36 | if let Some(frames) = &self.frames { | 40 | if let Some(frames) = &self.frames { |
37 | if name_ref.text() == "$crate" { | 41 | if name_ref.text() == "$crate" { |
38 | if let Some(krate) = frames.root_crate(name_ref.syntax()) { | 42 | if let Some(krate) = frames.root_crate(db, name_ref.syntax()) { |
39 | return Either::Right(krate); | 43 | return Either::Right(krate); |
40 | } | 44 | } |
41 | } | 45 | } |
@@ -44,15 +48,19 @@ impl Hygiene { | |||
44 | Either::Left(name_ref.as_name()) | 48 | Either::Left(name_ref.as_name()) |
45 | } | 49 | } |
46 | 50 | ||
47 | pub fn local_inner_macros(&self, path: ast::Path) -> Option<CrateId> { | 51 | pub fn local_inner_macros(&self, db: &dyn AstDatabase, path: ast::Path) -> Option<CrateId> { |
48 | let mut token = path.syntax().first_token()?.text_range(); | 52 | let mut token = path.syntax().first_token()?.text_range(); |
49 | let frames = self.frames.as_ref()?; | 53 | let frames = self.frames.as_ref()?; |
50 | let mut current = frames.0.clone(); | 54 | let mut current = frames.0.clone(); |
51 | 55 | ||
52 | loop { | 56 | loop { |
53 | let (mapped, origin) = current.expansion.as_ref()?.map_ident_up(token)?; | 57 | let (mapped, origin) = current.expansion.as_ref()?.map_ident_up(db, token)?; |
54 | if origin == Origin::Def { | 58 | if origin == Origin::Def { |
55 | return if current.local_inner { frames.root_crate(path.syntax()) } else { None }; | 59 | return if current.local_inner { |
60 | frames.root_crate(db, path.syntax()) | ||
61 | } else { | ||
62 | None | ||
63 | }; | ||
56 | } | 64 | } |
57 | current = current.call_site.as_ref()?.clone(); | 65 | current = current.call_site.as_ref()?.clone(); |
58 | token = mapped.value; | 66 | token = mapped.value; |
@@ -82,13 +90,13 @@ impl HygieneFrames { | |||
82 | HygieneFrames(Arc::new(HygieneFrame::new(db, file_id))) | 90 | HygieneFrames(Arc::new(HygieneFrame::new(db, file_id))) |
83 | } | 91 | } |
84 | 92 | ||
85 | fn root_crate(&self, node: &SyntaxNode) -> Option<CrateId> { | 93 | fn root_crate(&self, db: &dyn AstDatabase, node: &SyntaxNode) -> Option<CrateId> { |
86 | let mut token = node.first_token()?.text_range(); | 94 | let mut token = node.first_token()?.text_range(); |
87 | let mut result = self.0.krate; | 95 | let mut result = self.0.krate; |
88 | let mut current = self.0.clone(); | 96 | let mut current = self.0.clone(); |
89 | 97 | ||
90 | while let Some((mapped, origin)) = | 98 | while let Some((mapped, origin)) = |
91 | current.expansion.as_ref().and_then(|it| it.map_ident_up(token)) | 99 | current.expansion.as_ref().and_then(|it| it.map_ident_up(db, token)) |
92 | { | 100 | { |
93 | result = current.krate; | 101 | result = current.krate; |
94 | 102 | ||
@@ -112,7 +120,7 @@ impl HygieneFrames { | |||
112 | 120 | ||
113 | #[derive(Debug, Clone, PartialEq, Eq)] | 121 | #[derive(Debug, Clone, PartialEq, Eq)] |
114 | struct HygieneInfo { | 122 | struct HygieneInfo { |
115 | arg_start: InFile<TextSize>, | 123 | file: MacroFile, |
116 | /// The `macro_rules!` arguments. | 124 | /// The `macro_rules!` arguments. |
117 | def_start: Option<InFile<TextSize>>, | 125 | def_start: Option<InFile<TextSize>>, |
118 | 126 | ||
@@ -122,12 +130,24 @@ struct HygieneInfo { | |||
122 | } | 130 | } |
123 | 131 | ||
124 | impl HygieneInfo { | 132 | impl HygieneInfo { |
125 | fn map_ident_up(&self, token: TextRange) -> Option<(InFile<TextRange>, Origin)> { | 133 | fn map_ident_up( |
134 | &self, | ||
135 | db: &dyn AstDatabase, | ||
136 | token: TextRange, | ||
137 | ) -> Option<(InFile<TextRange>, Origin)> { | ||
126 | let token_id = self.exp_map.token_by_range(token)?; | 138 | let token_id = self.exp_map.token_by_range(token)?; |
127 | 139 | ||
128 | let (token_id, origin) = self.macro_def.map_id_up(token_id); | 140 | let (token_id, origin) = self.macro_def.map_id_up(token_id); |
129 | let (token_map, tt) = match origin { | 141 | let (token_map, tt) = match origin { |
130 | mbe::Origin::Call => (&self.macro_arg.1, self.arg_start), | 142 | mbe::Origin::Call => { |
143 | let call_id = match self.file.macro_call_id { | ||
144 | MacroCallId::LazyMacro(lazy) => lazy, | ||
145 | MacroCallId::EagerMacro(_) => unreachable!(), | ||
146 | }; | ||
147 | let loc: MacroCallLoc = db.lookup_intern_macro(call_id); | ||
148 | let arg_start = loc.kind.arg(db)?.text_range().start(); | ||
149 | (&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start)) | ||
150 | } | ||
131 | mbe::Origin::Def => match (&*self.macro_def, self.def_start) { | 151 | mbe::Origin::Def => match (&*self.macro_def, self.def_start) { |
132 | (TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt)) | 152 | (TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt)) |
133 | | (TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt)) => { | 153 | | (TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt)) => { |
@@ -147,8 +167,6 @@ fn make_hygiene_info( | |||
147 | macro_file: MacroFile, | 167 | macro_file: MacroFile, |
148 | loc: &MacroCallLoc, | 168 | loc: &MacroCallLoc, |
149 | ) -> Option<HygieneInfo> { | 169 | ) -> Option<HygieneInfo> { |
150 | let arg_tt = loc.kind.arg(db)?; | ||
151 | |||
152 | let def_offset = loc.def.ast_id().left().and_then(|id| { | 170 | let def_offset = loc.def.ast_id().left().and_then(|id| { |
153 | let def_tt = match id.to_node(db) { | 171 | let def_tt = match id.to_node(db) { |
154 | ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(), | 172 | ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(), |
@@ -161,13 +179,7 @@ fn make_hygiene_info( | |||
161 | let (_, exp_map) = db.parse_macro_expansion(macro_file).value?; | 179 | let (_, exp_map) = db.parse_macro_expansion(macro_file).value?; |
162 | let macro_arg = db.macro_arg(macro_file.macro_call_id)?; | 180 | let macro_arg = db.macro_arg(macro_file.macro_call_id)?; |
163 | 181 | ||
164 | Some(HygieneInfo { | 182 | Some(HygieneInfo { file: macro_file, def_start: def_offset, macro_arg, macro_def, exp_map }) |
165 | arg_start: InFile::new(loc.kind.file_id(), arg_tt.text_range().start()), | ||
166 | def_start: def_offset, | ||
167 | macro_arg, | ||
168 | macro_def, | ||
169 | exp_map, | ||
170 | }) | ||
171 | } | 183 | } |
172 | 184 | ||
173 | impl HygieneFrame { | 185 | impl HygieneFrame { |
@@ -178,7 +190,8 @@ impl HygieneFrame { | |||
178 | MacroCallId::EagerMacro(_id) => (None, None, false), | 190 | MacroCallId::EagerMacro(_id) => (None, None, false), |
179 | MacroCallId::LazyMacro(id) => { | 191 | MacroCallId::LazyMacro(id) => { |
180 | let loc = db.lookup_intern_macro(id); | 192 | let loc = db.lookup_intern_macro(id); |
181 | let info = make_hygiene_info(db, macro_file, &loc); | 193 | let info = make_hygiene_info(db, macro_file, &loc) |
194 | .map(|info| (loc.kind.file_id(), info)); | ||
182 | match loc.def.kind { | 195 | match loc.def.kind { |
183 | MacroDefKind::Declarative(_) => { | 196 | MacroDefKind::Declarative(_) => { |
184 | (info, Some(loc.def.krate), loc.def.local_inner) | 197 | (info, Some(loc.def.krate), loc.def.local_inner) |
@@ -192,7 +205,7 @@ impl HygieneFrame { | |||
192 | }, | 205 | }, |
193 | }; | 206 | }; |
194 | 207 | ||
195 | let info = match info { | 208 | let (calling_file, info) = match info { |
196 | None => { | 209 | None => { |
197 | return HygieneFrame { | 210 | return HygieneFrame { |
198 | expansion: None, | 211 | expansion: None, |
@@ -206,7 +219,7 @@ impl HygieneFrame { | |||
206 | }; | 219 | }; |
207 | 220 | ||
208 | let def_site = info.def_start.map(|it| db.hygiene_frame(it.file_id)); | 221 | let def_site = info.def_start.map(|it| db.hygiene_frame(it.file_id)); |
209 | let call_site = Some(db.hygiene_frame(info.arg_start.file_id)); | 222 | let call_site = Some(db.hygiene_frame(calling_file)); |
210 | 223 | ||
211 | HygieneFrame { expansion: Some(info), local_inner, krate, call_site, def_site } | 224 | HygieneFrame { expansion: Some(info), local_inner, krate, call_site, def_site } |
212 | } | 225 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 4fb7d9cf2..1f6edf7a2 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -1000,7 +1000,7 @@ impl HirDisplay for TypeRef { | |||
1000 | } | 1000 | } |
1001 | TypeRef::Macro(macro_call) => { | 1001 | TypeRef::Macro(macro_call) => { |
1002 | let macro_call = macro_call.to_node(f.db.upcast()); | 1002 | let macro_call = macro_call.to_node(f.db.upcast()); |
1003 | let ctx = body::LowerCtx::with_hygiene(&Hygiene::new_unhygienic()); | 1003 | let ctx = body::LowerCtx::with_hygiene(f.db.upcast(), &Hygiene::new_unhygienic()); |
1004 | match macro_call.path() { | 1004 | match macro_call.path() { |
1005 | Some(path) => match Path::from_src(path, &ctx) { | 1005 | Some(path) => match Path::from_src(path, &ctx) { |
1006 | Some(path) => path.hir_fmt(f)?, | 1006 | Some(path) => path.hir_fmt(f)?, |