diff options
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/attr.rs | 175 | ||||
-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 | 5 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 37 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 18 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 3 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 22 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/incremental.rs | 58 | ||||
-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 |
14 files changed, 269 insertions, 129 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index d9294d93a..aadd4e44a 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -9,7 +9,7 @@ use std::{ | |||
9 | use base_db::CrateId; | 9 | use base_db::CrateId; |
10 | use cfg::{CfgExpr, CfgOptions}; | 10 | use cfg::{CfgExpr, CfgOptions}; |
11 | use either::Either; | 11 | use either::Either; |
12 | use hir_expand::{hygiene::Hygiene, name::AsName, AstId, AttrId, InFile}; | 12 | use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile}; |
13 | use itertools::Itertools; | 13 | use itertools::Itertools; |
14 | use la_arena::ArenaMap; | 14 | use la_arena::ArenaMap; |
15 | use mbe::ast_to_token_tree; | 15 | use mbe::ast_to_token_tree; |
@@ -95,19 +95,19 @@ 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 | .flat_map(|(id, attr)| match attr { |
101 | .flat_map(|(i, attr)| { | 105 | Either::Left(attr) => Attr::from_src(db, attr, hygiene, id), |
102 | let index = AttrId(i as u32); | 106 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { |
103 | match attr { | 107 | id, |
104 | Either::Left(attr) => Attr::from_src(attr, hygiene, index), | 108 | input: Some(AttrInput::Literal(SmolStr::new(doc))), |
105 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { | 109 | path: Interned::new(ModPath::from(hir_expand::name!(doc))), |
106 | id: index, | 110 | }), |
107 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | ||
108 | path: Interned::new(ModPath::from(hir_expand::name!(doc))), | ||
109 | }), | ||
110 | } | ||
111 | }) | 111 | }) |
112 | .collect::<Arc<_>>(); | 112 | .collect::<Arc<_>>(); |
113 | 113 | ||
@@ -116,10 +116,11 @@ impl RawAttrs { | |||
116 | 116 | ||
117 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self { | 117 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self { |
118 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | 118 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); |
119 | Self::new(owner.value, &hygiene) | 119 | Self::new(db, owner.value, &hygiene) |
120 | } | 120 | } |
121 | 121 | ||
122 | pub(crate) fn merge(&self, other: Self) -> Self { | 122 | pub(crate) fn merge(&self, other: Self) -> Self { |
123 | // FIXME: This needs to fixup `AttrId`s | ||
123 | match (&self.entries, &other.entries) { | 124 | match (&self.entries, &other.entries) { |
124 | (None, None) => Self::EMPTY, | 125 | (None, None) => Self::EMPTY, |
125 | (Some(entries), None) | (None, Some(entries)) => { | 126 | (Some(entries), None) | (None, Some(entries)) => { |
@@ -170,7 +171,7 @@ impl RawAttrs { | |||
170 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; | 171 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; |
171 | // FIXME hygiene | 172 | // FIXME hygiene |
172 | let hygiene = Hygiene::new_unhygienic(); | 173 | let hygiene = Hygiene::new_unhygienic(); |
173 | Attr::from_src(attr, &hygiene, index) | 174 | Attr::from_src(db, attr, &hygiene, index) |
174 | }); | 175 | }); |
175 | 176 | ||
176 | let cfg_options = &crate_graph[krate].cfg_options; | 177 | let cfg_options = &crate_graph[krate].cfg_options; |
@@ -371,39 +372,26 @@ impl AttrsWithOwner { | |||
371 | 372 | ||
372 | let def_map = module.def_map(db); | 373 | let def_map = module.def_map(db); |
373 | let mod_data = &def_map[module.local_id]; | 374 | let mod_data = &def_map[module.local_id]; |
374 | let attrs = match mod_data.declaration_source(db) { | 375 | match mod_data.declaration_source(db) { |
375 | Some(it) => { | 376 | Some(it) => { |
376 | let mut attrs: Vec<_> = collect_attrs(&it.value as &dyn ast::AttrsOwner) | 377 | let mut map = AttrSourceMap::new(InFile::new(it.file_id, &it.value)); |
377 | .map(|attr| InFile::new(it.file_id, attr)) | ||
378 | .collect(); | ||
379 | if let InFile { file_id, value: ModuleSource::SourceFile(file) } = | 378 | if let InFile { file_id, value: ModuleSource::SourceFile(file) } = |
380 | mod_data.definition_source(db) | 379 | mod_data.definition_source(db) |
381 | { | 380 | { |
382 | attrs.extend( | 381 | map.merge(AttrSourceMap::new(InFile::new(file_id, &file))); |
383 | collect_attrs(&file as &dyn ast::AttrsOwner) | ||
384 | .map(|attr| InFile::new(file_id, attr)), | ||
385 | ) | ||
386 | } | 382 | } |
387 | attrs | 383 | return map; |
388 | } | 384 | } |
389 | None => { | 385 | None => { |
390 | let InFile { file_id, value } = mod_data.definition_source(db); | 386 | let InFile { file_id, value } = mod_data.definition_source(db); |
391 | match &value { | 387 | let attrs_owner = match &value { |
392 | ModuleSource::SourceFile(file) => { | 388 | ModuleSource::SourceFile(file) => file as &dyn ast::AttrsOwner, |
393 | collect_attrs(file as &dyn ast::AttrsOwner) | 389 | ModuleSource::Module(module) => module as &dyn ast::AttrsOwner, |
394 | } | 390 | ModuleSource::BlockExpr(block) => block as &dyn ast::AttrsOwner, |
395 | ModuleSource::Module(module) => { | 391 | }; |
396 | collect_attrs(module as &dyn ast::AttrsOwner) | 392 | return AttrSourceMap::new(InFile::new(file_id, attrs_owner)); |
397 | } | ||
398 | ModuleSource::BlockExpr(block) => { | ||
399 | collect_attrs(block as &dyn ast::AttrsOwner) | ||
400 | } | ||
401 | } | ||
402 | .map(|attr| InFile::new(file_id, attr)) | ||
403 | .collect() | ||
404 | } | 393 | } |
405 | }; | 394 | } |
406 | return AttrSourceMap { attrs }; | ||
407 | } | 395 | } |
408 | AttrDefId::FieldId(id) => { | 396 | AttrDefId::FieldId(id) => { |
409 | let map = db.fields_attrs_source_map(id.parent); | 397 | let map = db.fields_attrs_source_map(id.parent); |
@@ -458,11 +446,7 @@ impl AttrsWithOwner { | |||
458 | }, | 446 | }, |
459 | }; | 447 | }; |
460 | 448 | ||
461 | AttrSourceMap { | 449 | AttrSourceMap::new(owner.as_ref().map(|node| node as &dyn AttrsOwner)) |
462 | attrs: collect_attrs(&owner.value) | ||
463 | .map(|attr| InFile::new(owner.file_id, attr)) | ||
464 | .collect(), | ||
465 | } | ||
466 | } | 450 | } |
467 | 451 | ||
468 | pub fn docs_with_rangemap( | 452 | pub fn docs_with_rangemap( |
@@ -484,10 +468,10 @@ impl AttrsWithOwner { | |||
484 | let mut buf = String::new(); | 468 | let mut buf = String::new(); |
485 | let mut mapping = Vec::new(); | 469 | let mut mapping = Vec::new(); |
486 | for (doc, idx) in docs { | 470 | for (doc, idx) in docs { |
487 | // str::lines doesn't yield anything for the empty string | ||
488 | if !doc.is_empty() { | 471 | if !doc.is_empty() { |
489 | for line in doc.split('\n') { | 472 | let mut base_offset = 0; |
490 | let line = line.trim_end(); | 473 | for raw_line in doc.split('\n') { |
474 | let line = raw_line.trim_end(); | ||
491 | let line_len = line.len(); | 475 | let line_len = line.len(); |
492 | let (offset, line) = match line.char_indices().nth(indent) { | 476 | let (offset, line) = match line.char_indices().nth(indent) { |
493 | Some((offset, _)) => (offset, &line[offset..]), | 477 | Some((offset, _)) => (offset, &line[offset..]), |
@@ -498,9 +482,13 @@ impl AttrsWithOwner { | |||
498 | mapping.push(( | 482 | mapping.push(( |
499 | TextRange::new(buf_offset.try_into().ok()?, buf.len().try_into().ok()?), | 483 | TextRange::new(buf_offset.try_into().ok()?, buf.len().try_into().ok()?), |
500 | idx, | 484 | idx, |
501 | TextRange::new(offset.try_into().ok()?, line_len.try_into().ok()?), | 485 | TextRange::at( |
486 | (base_offset + offset).try_into().ok()?, | ||
487 | line_len.try_into().ok()?, | ||
488 | ), | ||
502 | )); | 489 | )); |
503 | buf.push('\n'); | 490 | buf.push('\n'); |
491 | base_offset += raw_line.len() + 1; | ||
504 | } | 492 | } |
505 | } else { | 493 | } else { |
506 | buf.push('\n'); | 494 | buf.push('\n'); |
@@ -510,7 +498,7 @@ impl AttrsWithOwner { | |||
510 | if buf.is_empty() { | 498 | if buf.is_empty() { |
511 | None | 499 | None |
512 | } else { | 500 | } else { |
513 | Some((Documentation(buf), DocsRangeMap { mapping, source: self.source_map(db).attrs })) | 501 | Some((Documentation(buf), DocsRangeMap { mapping, source_map: self.source_map(db) })) |
514 | } | 502 | } |
515 | } | 503 | } |
516 | } | 504 | } |
@@ -551,27 +539,59 @@ fn inner_attributes( | |||
551 | } | 539 | } |
552 | 540 | ||
553 | pub struct AttrSourceMap { | 541 | pub struct AttrSourceMap { |
554 | attrs: Vec<InFile<Either<ast::Attr, ast::Comment>>>, | 542 | attrs: Vec<InFile<ast::Attr>>, |
543 | doc_comments: Vec<InFile<ast::Comment>>, | ||
555 | } | 544 | } |
556 | 545 | ||
557 | impl AttrSourceMap { | 546 | impl AttrSourceMap { |
547 | fn new(owner: InFile<&dyn ast::AttrsOwner>) -> Self { | ||
548 | let mut attrs = Vec::new(); | ||
549 | let mut doc_comments = Vec::new(); | ||
550 | for (_, attr) in collect_attrs(owner.value) { | ||
551 | match attr { | ||
552 | Either::Left(attr) => attrs.push(owner.with_value(attr)), | ||
553 | Either::Right(comment) => doc_comments.push(owner.with_value(comment)), | ||
554 | } | ||
555 | } | ||
556 | |||
557 | Self { attrs, doc_comments } | ||
558 | } | ||
559 | |||
560 | fn merge(&mut self, other: Self) { | ||
561 | self.attrs.extend(other.attrs); | ||
562 | self.doc_comments.extend(other.doc_comments); | ||
563 | } | ||
564 | |||
558 | /// Maps the lowered `Attr` back to its original syntax node. | 565 | /// Maps the lowered `Attr` back to its original syntax node. |
559 | /// | 566 | /// |
560 | /// `attr` must come from the `owner` used for AttrSourceMap | 567 | /// `attr` must come from the `owner` used for AttrSourceMap |
561 | /// | 568 | /// |
562 | /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of | 569 | /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of |
563 | /// the attribute represented by `Attr`. | 570 | /// the attribute represented by `Attr`. |
564 | pub fn source_of(&self, attr: &Attr) -> InFile<&Either<ast::Attr, ast::Comment>> { | 571 | pub fn source_of(&self, attr: &Attr) -> InFile<Either<ast::Attr, ast::Comment>> { |
565 | self.attrs | 572 | self.source_of_id(attr.id) |
566 | .get(attr.id.0 as usize) | 573 | } |
567 | .unwrap_or_else(|| panic!("cannot find `Attr` at index {:?}", attr.id)) | 574 | |
568 | .as_ref() | 575 | fn source_of_id(&self, id: AttrId) -> InFile<Either<ast::Attr, ast::Comment>> { |
576 | if id.is_doc_comment { | ||
577 | self.doc_comments | ||
578 | .get(id.ast_index as usize) | ||
579 | .unwrap_or_else(|| panic!("cannot find doc comment at index {:?}", id)) | ||
580 | .clone() | ||
581 | .map(|attr| Either::Right(attr)) | ||
582 | } else { | ||
583 | self.attrs | ||
584 | .get(id.ast_index as usize) | ||
585 | .unwrap_or_else(|| panic!("cannot find `Attr` at index {:?}", id)) | ||
586 | .clone() | ||
587 | .map(|attr| Either::Left(attr)) | ||
588 | } | ||
569 | } | 589 | } |
570 | } | 590 | } |
571 | 591 | ||
572 | /// A struct to map text ranges from [`Documentation`] back to TextRanges in the syntax tree. | 592 | /// A struct to map text ranges from [`Documentation`] back to TextRanges in the syntax tree. |
573 | pub struct DocsRangeMap { | 593 | pub struct DocsRangeMap { |
574 | source: Vec<InFile<Either<ast::Attr, ast::Comment>>>, | 594 | source_map: AttrSourceMap, |
575 | // (docstring-line-range, attr_index, attr-string-range) | 595 | // (docstring-line-range, attr_index, attr-string-range) |
576 | // a mapping from the text range of a line of the [`Documentation`] to the attribute index and | 596 | // a mapping from the text range of a line of the [`Documentation`] to the attribute index and |
577 | // the original (untrimmed) syntax doc line | 597 | // the original (untrimmed) syntax doc line |
@@ -588,7 +608,7 @@ impl DocsRangeMap { | |||
588 | 608 | ||
589 | let relative_range = range - line_docs_range.start(); | 609 | let relative_range = range - line_docs_range.start(); |
590 | 610 | ||
591 | let &InFile { file_id, value: ref source } = &self.source[idx.0 as usize]; | 611 | let &InFile { file_id, value: ref source } = &self.source_map.source_of_id(idx); |
592 | match source { | 612 | match source { |
593 | Either::Left(_) => None, // FIXME, figure out a nice way to handle doc attributes here | 613 | Either::Left(_) => None, // FIXME, figure out a nice way to handle doc attributes here |
594 | // as well as for whats done in syntax highlight doc injection | 614 | // as well as for whats done in syntax highlight doc injection |
@@ -607,6 +627,12 @@ impl DocsRangeMap { | |||
607 | } | 627 | } |
608 | } | 628 | } |
609 | 629 | ||
630 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
631 | pub(crate) struct AttrId { | ||
632 | is_doc_comment: bool, | ||
633 | pub(crate) ast_index: u32, | ||
634 | } | ||
635 | |||
610 | #[derive(Debug, Clone, PartialEq, Eq)] | 636 | #[derive(Debug, Clone, PartialEq, Eq)] |
611 | pub struct Attr { | 637 | pub struct Attr { |
612 | pub(crate) id: AttrId, | 638 | pub(crate) id: AttrId, |
@@ -623,8 +649,13 @@ pub enum AttrInput { | |||
623 | } | 649 | } |
624 | 650 | ||
625 | impl Attr { | 651 | impl Attr { |
626 | fn from_src(ast: ast::Attr, hygiene: &Hygiene, id: AttrId) -> Option<Attr> { | 652 | fn from_src( |
627 | let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?); | 653 | db: &dyn DefDatabase, |
654 | ast: ast::Attr, | ||
655 | hygiene: &Hygiene, | ||
656 | id: AttrId, | ||
657 | ) -> Option<Attr> { | ||
658 | let path = Interned::new(ModPath::from_src(db, ast.path()?, hygiene)?); | ||
628 | let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { | 659 | let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { |
629 | let value = match lit.kind() { | 660 | let value = match lit.kind() { |
630 | ast::LiteralKind::String(string) => string.value()?.into(), | 661 | ast::LiteralKind::String(string) => string.value()?.into(), |
@@ -736,22 +767,32 @@ fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase | |||
736 | 767 | ||
737 | fn collect_attrs( | 768 | fn collect_attrs( |
738 | owner: &dyn ast::AttrsOwner, | 769 | owner: &dyn ast::AttrsOwner, |
739 | ) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { | 770 | ) -> impl Iterator<Item = (AttrId, Either<ast::Attr, ast::Comment>)> { |
740 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) | 771 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) |
741 | .map_or((None, None), |(attrs, docs)| (Some(attrs), Some(docs))); | 772 | .map_or((None, None), |(attrs, docs)| (Some(attrs), Some(docs))); |
742 | 773 | ||
743 | let outer_attrs = owner.attrs().filter(|attr| attr.kind().is_outer()); | 774 | let outer_attrs = owner.attrs().filter(|attr| attr.kind().is_outer()); |
744 | let attrs = outer_attrs | 775 | let attrs = |
745 | .chain(inner_attrs.into_iter().flatten()) | 776 | outer_attrs.chain(inner_attrs.into_iter().flatten()).enumerate().map(|(idx, attr)| { |
746 | .map(|attr| (attr.syntax().text_range().start(), Either::Left(attr))); | 777 | ( |
778 | AttrId { ast_index: idx as u32, is_doc_comment: false }, | ||
779 | attr.syntax().text_range().start(), | ||
780 | Either::Left(attr), | ||
781 | ) | ||
782 | }); | ||
747 | 783 | ||
748 | let outer_docs = | 784 | let outer_docs = |
749 | ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer); | 785 | ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer); |
750 | let docs = outer_docs | 786 | let docs = |
751 | .chain(inner_docs.into_iter().flatten()) | 787 | outer_docs.chain(inner_docs.into_iter().flatten()).enumerate().map(|(idx, docs_text)| { |
752 | .map(|docs_text| (docs_text.syntax().text_range().start(), Either::Right(docs_text))); | 788 | ( |
789 | AttrId { ast_index: idx as u32, is_doc_comment: true }, | ||
790 | docs_text.syntax().text_range().start(), | ||
791 | Either::Right(docs_text), | ||
792 | ) | ||
793 | }); | ||
753 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved | 794 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved |
754 | docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).map(|(_, attr)| attr) | 795 | docs.chain(attrs).sorted_by_key(|&(_, offset, _)| offset).map(|(id, _, attr)| (id, attr)) |
755 | } | 796 | } |
756 | 797 | ||
757 | pub(crate) fn variants_attrs_source_map( | 798 | pub(crate) fn variants_attrs_source_map( |
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 820d5c17e..9f278d35b 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() |
@@ -801,7 +804,8 @@ impl ExprCollector<'_> { | |||
801 | } | 804 | } |
802 | } | 805 | } |
803 | ast::Pat::TupleStructPat(p) => { | 806 | ast::Pat::TupleStructPat(p) => { |
804 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); | 807 | let path = |
808 | p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); | ||
805 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); | 809 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); |
806 | Pat::TupleStruct { path, args, ellipsis } | 810 | Pat::TupleStruct { path, args, ellipsis } |
807 | } | 811 | } |
@@ -811,7 +815,8 @@ impl ExprCollector<'_> { | |||
811 | Pat::Ref { pat, mutability } | 815 | Pat::Ref { pat, mutability } |
812 | } | 816 | } |
813 | ast::Pat::PathPat(p) => { | 817 | ast::Pat::PathPat(p) => { |
814 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); | 818 | let path = |
819 | p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); | ||
815 | path.map(Pat::Path).unwrap_or(Pat::Missing) | 820 | path.map(Pat::Path).unwrap_or(Pat::Missing) |
816 | } | 821 | } |
817 | ast::Pat::OrPat(p) => { | 822 | ast::Pat::OrPat(p) => { |
@@ -825,7 +830,8 @@ impl ExprCollector<'_> { | |||
825 | } | 830 | } |
826 | ast::Pat::WildcardPat(_) => Pat::Wild, | 831 | ast::Pat::WildcardPat(_) => Pat::Wild, |
827 | ast::Pat::RecordPat(p) => { | 832 | ast::Pat::RecordPat(p) => { |
828 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); | 833 | let path = |
834 | p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); | ||
829 | let args: Vec<_> = p | 835 | let args: Vec<_> = p |
830 | .record_pat_field_list() | 836 | .record_pat_field_list() |
831 | .expect("every struct should have a field list") | 837 | .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..cad8a7479 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -18,7 +18,7 @@ use hir_expand::{ | |||
18 | ast_id_map::FileAstId, | 18 | ast_id_map::FileAstId, |
19 | hygiene::Hygiene, | 19 | hygiene::Hygiene, |
20 | name::{name, AsName, Name}, | 20 | name::{name, AsName, Name}, |
21 | HirFileId, InFile, | 21 | FragmentKind, HirFileId, InFile, |
22 | }; | 22 | }; |
23 | use la_arena::{Arena, Idx, RawIdx}; | 23 | use la_arena::{Arena, Idx, RawIdx}; |
24 | use profile::Count; | 24 | use profile::Count; |
@@ -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) => { |
@@ -656,6 +656,7 @@ pub struct MacroCall { | |||
656 | /// Path to the called macro. | 656 | /// Path to the called macro. |
657 | pub path: Interned<ModPath>, | 657 | pub path: Interned<ModPath>, |
658 | pub ast_id: FileAstId<ast::MacroCall>, | 658 | pub ast_id: FileAstId<ast::MacroCall>, |
659 | pub fragment: FragmentKind, | ||
659 | } | 660 | } |
660 | 661 | ||
661 | #[derive(Debug, Clone, Eq, PartialEq)] | 662 | #[derive(Debug, Clone, Eq, PartialEq)] |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 45b099cf3..fe348091d 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,9 +622,10 @@ 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 fragment = hir_expand::to_fragment_kind(m); |
628 | let res = MacroCall { path, ast_id, fragment }; | ||
624 | Some(id(self.data().macro_calls.alloc(res))) | 629 | Some(id(self.data().macro_calls.alloc(res))) |
625 | } | 630 | } |
626 | 631 | ||
@@ -647,7 +652,7 @@ impl Ctx { | |||
647 | list.extern_items() | 652 | list.extern_items() |
648 | .filter_map(|item| { | 653 | .filter_map(|item| { |
649 | self.collect_inner_items(item.syntax()); | 654 | self.collect_inner_items(item.syntax()); |
650 | let attrs = RawAttrs::new(&item, &self.hygiene); | 655 | let attrs = RawAttrs::new(self.db, &item, &self.hygiene); |
651 | let id: ModItem = match item { | 656 | let id: ModItem = match item { |
652 | ast::ExternItem::Fn(ast) => { | 657 | ast::ExternItem::Fn(ast) => { |
653 | let func_id = self.lower_function(&ast)?; | 658 | let func_id = self.lower_function(&ast)?; |
@@ -755,7 +760,7 @@ impl Ctx { | |||
755 | fn lower_visibility(&mut self, item: &impl ast::VisibilityOwner) -> RawVisibilityId { | 760 | fn lower_visibility(&mut self, item: &impl ast::VisibilityOwner) -> RawVisibilityId { |
756 | let vis = match self.forced_visibility { | 761 | let vis = match self.forced_visibility { |
757 | Some(vis) => return vis, | 762 | Some(vis) => return vis, |
758 | None => RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene), | 763 | None => RawVisibility::from_ast_with_hygiene(self.db, item.visibility(), &self.hygiene), |
759 | }; | 764 | }; |
760 | 765 | ||
761 | self.data().vis.alloc(vis) | 766 | self.data().vis.alloc(vis) |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 25694f037..a82ea5957 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -62,13 +62,14 @@ use hir_expand::{ | |||
62 | ast_id_map::FileAstId, | 62 | ast_id_map::FileAstId, |
63 | eager::{expand_eager_macro, ErrorEmitted, ErrorSink}, | 63 | eager::{expand_eager_macro, ErrorEmitted, ErrorSink}, |
64 | hygiene::Hygiene, | 64 | hygiene::Hygiene, |
65 | AstId, AttrId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, | 65 | AstId, FragmentKind, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, |
66 | }; | 66 | }; |
67 | use la_arena::Idx; | 67 | use la_arena::Idx; |
68 | use nameres::DefMap; | 68 | use nameres::DefMap; |
69 | use path::ModPath; | 69 | use path::ModPath; |
70 | use syntax::ast; | 70 | use syntax::ast; |
71 | 71 | ||
72 | use crate::attr::AttrId; | ||
72 | use crate::builtin_type::BuiltinType; | 73 | use crate::builtin_type::BuiltinType; |
73 | use item_tree::{ | 74 | use item_tree::{ |
74 | Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait, | 75 | Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait, |
@@ -652,9 +653,10 @@ impl AsMacroCall for InFile<&ast::MacroCall> { | |||
652 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, | 653 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, |
653 | mut error_sink: &mut dyn FnMut(mbe::ExpandError), | 654 | mut error_sink: &mut dyn FnMut(mbe::ExpandError), |
654 | ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { | 655 | ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { |
656 | let fragment = hir_expand::to_fragment_kind(self.value); | ||
655 | let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); | 657 | 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); | 658 | let h = Hygiene::new(db.upcast(), self.file_id); |
657 | let path = self.value.path().and_then(|path| path::ModPath::from_src(path, &h)); | 659 | let path = self.value.path().and_then(|path| path::ModPath::from_src(db, path, &h)); |
658 | 660 | ||
659 | let path = match error_sink | 661 | let path = match error_sink |
660 | .option(path, || mbe::ExpandError::Other("malformed macro invocation".into())) | 662 | .option(path, || mbe::ExpandError::Other("malformed macro invocation".into())) |
@@ -667,6 +669,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> { | |||
667 | 669 | ||
668 | macro_call_as_call_id( | 670 | macro_call_as_call_id( |
669 | &AstIdWithPath::new(ast_id.file_id, ast_id.value, path), | 671 | &AstIdWithPath::new(ast_id.file_id, ast_id.value, path), |
672 | fragment, | ||
670 | db, | 673 | db, |
671 | krate, | 674 | krate, |
672 | resolver, | 675 | resolver, |
@@ -695,6 +698,7 @@ pub struct UnresolvedMacro { | |||
695 | 698 | ||
696 | fn macro_call_as_call_id( | 699 | fn macro_call_as_call_id( |
697 | call: &AstIdWithPath<ast::MacroCall>, | 700 | call: &AstIdWithPath<ast::MacroCall>, |
701 | fragment: FragmentKind, | ||
698 | db: &dyn db::DefDatabase, | 702 | db: &dyn db::DefDatabase, |
699 | krate: CrateId, | 703 | krate: CrateId, |
700 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, | 704 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, |
@@ -712,13 +716,17 @@ fn macro_call_as_call_id( | |||
712 | krate, | 716 | krate, |
713 | macro_call, | 717 | macro_call, |
714 | def, | 718 | def, |
715 | &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?), | 719 | &|path: ast::Path| resolver(path::ModPath::from_src(db, path, &hygiene)?), |
716 | error_sink, | 720 | error_sink, |
717 | ) | 721 | ) |
718 | .map(MacroCallId::from) | 722 | .map(MacroCallId::from) |
719 | } else { | 723 | } else { |
720 | Ok(def | 724 | Ok(def |
721 | .as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike { ast_id: call.ast_id }) | 725 | .as_lazy_macro( |
726 | db.upcast(), | ||
727 | krate, | ||
728 | MacroCallKind::FnLike { ast_id: call.ast_id, fragment }, | ||
729 | ) | ||
722 | .into()) | 730 | .into()) |
723 | }; | 731 | }; |
724 | Ok(res) | 732 | Ok(res) |
@@ -745,7 +753,7 @@ fn derive_macro_as_call_id( | |||
745 | MacroCallKind::Derive { | 753 | MacroCallKind::Derive { |
746 | ast_id: item_attr.ast_id, | 754 | ast_id: item_attr.ast_id, |
747 | derive_name: last_segment.to_string(), | 755 | derive_name: last_segment.to_string(), |
748 | derive_attr, | 756 | derive_attr_index: derive_attr.ast_index, |
749 | }, | 757 | }, |
750 | ) | 758 | ) |
751 | .into(); | 759 | .into(); |
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index ba027c44a..249af6fc8 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| { |
@@ -628,7 +629,7 @@ mod diagnostics { | |||
628 | DiagnosticKind::UnresolvedProcMacro { ast } => { | 629 | DiagnosticKind::UnresolvedProcMacro { ast } => { |
629 | let mut precise_location = None; | 630 | let mut precise_location = None; |
630 | let (file, ast, name) = match ast { | 631 | let (file, ast, name) = match ast { |
631 | MacroCallKind::FnLike { ast_id } => { | 632 | MacroCallKind::FnLike { ast_id, .. } => { |
632 | let node = ast_id.to_node(db.upcast()); | 633 | let node = ast_id.to_node(db.upcast()); |
633 | (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None) | 634 | (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None) |
634 | } | 635 | } |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 05ceb1efb..adfb78c94 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -13,14 +13,14 @@ use hir_expand::{ | |||
13 | builtin_macro::find_builtin_macro, | 13 | builtin_macro::find_builtin_macro, |
14 | name::{AsName, Name}, | 14 | name::{AsName, Name}, |
15 | proc_macro::ProcMacroExpander, | 15 | proc_macro::ProcMacroExpander, |
16 | AttrId, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, | 16 | FragmentKind, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, |
17 | }; | 17 | }; |
18 | use hir_expand::{InFile, MacroCallLoc}; | 18 | use hir_expand::{InFile, MacroCallLoc}; |
19 | use rustc_hash::{FxHashMap, FxHashSet}; | 19 | use rustc_hash::{FxHashMap, FxHashSet}; |
20 | use syntax::ast; | 20 | use syntax::ast; |
21 | 21 | ||
22 | use crate::{ | 22 | use crate::{ |
23 | attr::Attrs, | 23 | attr::{AttrId, Attrs}, |
24 | db::DefDatabase, | 24 | db::DefDatabase, |
25 | derive_macro_as_call_id, | 25 | derive_macro_as_call_id, |
26 | intern::Interned, | 26 | intern::Interned, |
@@ -215,7 +215,7 @@ struct MacroDirective { | |||
215 | 215 | ||
216 | #[derive(Clone, Debug, Eq, PartialEq)] | 216 | #[derive(Clone, Debug, Eq, PartialEq)] |
217 | enum MacroDirectiveKind { | 217 | enum MacroDirectiveKind { |
218 | FnLike { ast_id: AstIdWithPath<ast::MacroCall> }, | 218 | FnLike { ast_id: AstIdWithPath<ast::MacroCall>, fragment: FragmentKind }, |
219 | Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId }, | 219 | Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId }, |
220 | } | 220 | } |
221 | 221 | ||
@@ -807,9 +807,10 @@ impl DefCollector<'_> { | |||
807 | let mut res = ReachedFixedPoint::Yes; | 807 | let mut res = ReachedFixedPoint::Yes; |
808 | macros.retain(|directive| { | 808 | macros.retain(|directive| { |
809 | match &directive.kind { | 809 | match &directive.kind { |
810 | MacroDirectiveKind::FnLike { ast_id } => { | 810 | MacroDirectiveKind::FnLike { ast_id, fragment } => { |
811 | match macro_call_as_call_id( | 811 | match macro_call_as_call_id( |
812 | ast_id, | 812 | ast_id, |
813 | *fragment, | ||
813 | self.db, | 814 | self.db, |
814 | self.def_map.krate, | 815 | self.def_map.krate, |
815 | |path| { | 816 | |path| { |
@@ -926,8 +927,9 @@ impl DefCollector<'_> { | |||
926 | 927 | ||
927 | for directive in &self.unexpanded_macros { | 928 | for directive in &self.unexpanded_macros { |
928 | match &directive.kind { | 929 | match &directive.kind { |
929 | MacroDirectiveKind::FnLike { ast_id, .. } => match macro_call_as_call_id( | 930 | MacroDirectiveKind::FnLike { ast_id, fragment } => match macro_call_as_call_id( |
930 | ast_id, | 931 | ast_id, |
932 | *fragment, | ||
931 | self.db, | 933 | self.db, |
932 | self.def_map.krate, | 934 | self.def_map.krate, |
933 | |path| { | 935 | |path| { |
@@ -1496,6 +1498,7 @@ impl ModCollector<'_, '_> { | |||
1496 | let mut error = None; | 1498 | let mut error = None; |
1497 | match macro_call_as_call_id( | 1499 | match macro_call_as_call_id( |
1498 | &ast_id, | 1500 | &ast_id, |
1501 | mac.fragment, | ||
1499 | self.def_collector.db, | 1502 | self.def_collector.db, |
1500 | self.def_collector.def_map.krate, | 1503 | self.def_collector.def_map.krate, |
1501 | |path| { | 1504 | |path| { |
@@ -1524,9 +1527,14 @@ impl ModCollector<'_, '_> { | |||
1524 | } | 1527 | } |
1525 | Ok(Err(_)) => { | 1528 | Ok(Err(_)) => { |
1526 | // Built-in macro failed eager expansion. | 1529 | // Built-in macro failed eager expansion. |
1530 | |||
1531 | // FIXME: don't parse the file here | ||
1532 | let fragment = hir_expand::to_fragment_kind( | ||
1533 | &ast_id.ast_id.to_node(self.def_collector.db.upcast()), | ||
1534 | ); | ||
1527 | self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error( | 1535 | self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error( |
1528 | self.module_id, | 1536 | self.module_id, |
1529 | MacroCallKind::FnLike { ast_id: ast_id.ast_id }, | 1537 | MacroCallKind::FnLike { ast_id: ast_id.ast_id, fragment }, |
1530 | error.unwrap().to_string(), | 1538 | error.unwrap().to_string(), |
1531 | )); | 1539 | )); |
1532 | return; | 1540 | return; |
@@ -1543,7 +1551,7 @@ impl ModCollector<'_, '_> { | |||
1543 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1551 | self.def_collector.unexpanded_macros.push(MacroDirective { |
1544 | module_id: self.module_id, | 1552 | module_id: self.module_id, |
1545 | depth: self.macro_depth + 1, | 1553 | depth: self.macro_depth + 1, |
1546 | kind: MacroDirectiveKind::FnLike { ast_id }, | 1554 | kind: MacroDirectiveKind::FnLike { ast_id, fragment: mac.fragment }, |
1547 | }); | 1555 | }); |
1548 | } | 1556 | } |
1549 | 1557 | ||
diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs index 509e1bbbc..d884a6eb4 100644 --- a/crates/hir_def/src/nameres/tests/incremental.rs +++ b/crates/hir_def/src/nameres/tests/incremental.rs | |||
@@ -105,3 +105,61 @@ 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 | let n_reparsed_macros = | ||
141 | events.iter().filter(|it| it.contains("parse_macro_expansion")).count(); | ||
142 | assert_eq!(n_reparsed_macros, 3); | ||
143 | } | ||
144 | |||
145 | let new_text = r#" | ||
146 | m!(X); | ||
147 | fn quux() { 92 } | ||
148 | m!(Y); | ||
149 | m!(Z); | ||
150 | "#; | ||
151 | db.set_file_text(pos.file_id, Arc::new(new_text.to_string())); | ||
152 | |||
153 | { | ||
154 | let events = db.log_executed(|| { | ||
155 | let crate_def_map = db.crate_def_map(krate); | ||
156 | let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); | ||
157 | assert_eq!(module_data.scope.resolutions().count(), 4); | ||
158 | }); | ||
159 | let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count(); | ||
160 | assert_eq!(n_recalculated_item_trees, 1); | ||
161 | let n_reparsed_macros = | ||
162 | events.iter().filter(|it| it.contains("parse_macro_expansion")).count(); | ||
163 | assert_eq!(n_reparsed_macros, 0); | ||
164 | } | ||
165 | } | ||
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, |