diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-06 22:53:05 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-06 22:53:05 +0100 |
commit | 6fccb152b4646877e38dc29dce1b0cd826eb6908 (patch) | |
tree | 361153338ec7c32866a5477b3e7681d05a4b0b7c /crates/hir_def/src/path | |
parent | b37b709459a4ff881a91965ebf0c39e3a449c304 (diff) | |
parent | 20ae41c1a12963e938cb3bd4c7c84007412d6fa6 (diff) |
Merge #8746
8746: Don't store call-site text offsets in hygiene info r=matklad a=jonas-schievink
This threads a lot more database references around in order to avoid storing a bare `TextOffset` in the hygiene info. This `TextOffset` made hygiene info and `ItemTree`s more volatile than they should be, leading to excessive recomputation of `ItemTree`s.
The incremental test added in https://github.com/rust-analyzer/rust-analyzer/pull/8721 is now passing with these changes.
closes https://github.com/rust-analyzer/rust-analyzer/pull/8721
Co-authored-by: Jonas Schievink <[email protected]>
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/hir_def/src/path')
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/path/lower/lower_use.rs | 23 |
2 files changed, 18 insertions, 9 deletions
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(|| { |