diff options
Diffstat (limited to 'crates')
77 files changed, 853 insertions, 608 deletions
diff --git a/crates/assists/src/handlers/introduce_named_lifetime.rs b/crates/assists/src/handlers/introduce_named_lifetime.rs index 3f5f44d69..02782eb6d 100644 --- a/crates/assists/src/handlers/introduce_named_lifetime.rs +++ b/crates/assists/src/handlers/introduce_named_lifetime.rs | |||
@@ -61,7 +61,7 @@ fn generate_fn_def_assist( | |||
61 | // compute the location which implicitly has the same lifetime as the anonymous lifetime | 61 | // compute the location which implicitly has the same lifetime as the anonymous lifetime |
62 | let loc_needing_lifetime = if let Some(self_param) = self_param { | 62 | let loc_needing_lifetime = if let Some(self_param) = self_param { |
63 | // if we have a self reference, use that | 63 | // if we have a self reference, use that |
64 | Some(self_param.self_token()?.text_range().start()) | 64 | Some(self_param.name()?.syntax().text_range().start()) |
65 | } else { | 65 | } else { |
66 | // otherwise, if there's a single reference parameter without a named liftime, use that | 66 | // otherwise, if there's a single reference parameter without a named liftime, use that |
67 | let fn_params_without_lifetime: Vec<_> = param_list | 67 | let fn_params_without_lifetime: Vec<_> = param_list |
diff --git a/crates/completion/src/completions/keyword.rs b/crates/completion/src/completions/keyword.rs index c1af348dc..47e146128 100644 --- a/crates/completion/src/completions/keyword.rs +++ b/crates/completion/src/completions/keyword.rs | |||
@@ -99,7 +99,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
99 | add_keyword(ctx, acc, "else if", "else if $0 {}"); | 99 | add_keyword(ctx, acc, "else if", "else if $0 {}"); |
100 | } | 100 | } |
101 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { | 101 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { |
102 | add_keyword(ctx, acc, "mod", "mod $0 {}"); | 102 | add_keyword(ctx, acc, "mod", "mod $0"); |
103 | } | 103 | } |
104 | if ctx.bind_pat_parent || ctx.ref_pat_parent { | 104 | if ctx.bind_pat_parent || ctx.ref_pat_parent { |
105 | add_keyword(ctx, acc, "mut", "mut "); | 105 | add_keyword(ctx, acc, "mut", "mut "); |
diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index 378bd2c70..4147853e7 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs | |||
@@ -401,7 +401,9 @@ impl Builder { | |||
401 | pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder { | 401 | pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder { |
402 | self.detail = detail.map(Into::into); | 402 | self.detail = detail.map(Into::into); |
403 | if let Some(detail) = &self.detail { | 403 | if let Some(detail) = &self.detail { |
404 | assert_never!(detail.contains('\n'), "multiline detail: {}", detail); | 404 | if assert_never!(detail.contains('\n'), "multiline detail: {}", detail) { |
405 | self.detail = Some(detail.splitn(2, '\n').next().unwrap().to_string()); | ||
406 | } | ||
405 | } | 407 | } |
406 | self | 408 | self |
407 | } | 409 | } |
diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml index 5d21283f7..535221294 100644 --- a/crates/hir_def/Cargo.toml +++ b/crates/hir_def/Cargo.toml | |||
@@ -20,7 +20,7 @@ fst = { version = "0.4", default-features = false } | |||
20 | itertools = "0.10.0" | 20 | itertools = "0.10.0" |
21 | indexmap = "1.4.0" | 21 | indexmap = "1.4.0" |
22 | smallvec = "1.4.0" | 22 | smallvec = "1.4.0" |
23 | la-arena = "0.1.0" | 23 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
24 | 24 | ||
25 | stdx = { path = "../stdx", version = "0.0.0" } | 25 | stdx = { path = "../stdx", version = "0.0.0" } |
26 | base_db = { path = "../base_db", version = "0.0.0" } | 26 | base_db = { path = "../base_db", version = "0.0.0" } |
diff --git a/crates/hir_def/src/adt.rs b/crates/hir_def/src/adt.rs index 237c3d3f9..06f0b9b18 100644 --- a/crates/hir_def/src/adt.rs +++ b/crates/hir_def/src/adt.rs | |||
@@ -8,7 +8,7 @@ use hir_expand::{ | |||
8 | name::{AsName, Name}, | 8 | name::{AsName, Name}, |
9 | InFile, | 9 | InFile, |
10 | }; | 10 | }; |
11 | use la_arena::{map::ArenaMap, Arena}; | 11 | use la_arena::{Arena, ArenaMap}; |
12 | use syntax::ast::{self, NameOwner, VisibilityOwner}; | 12 | use syntax::ast::{self, NameOwner, VisibilityOwner}; |
13 | use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree}; | 13 | use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree}; |
14 | 14 | ||
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 5a86823c2..1b09ff816 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -7,7 +7,7 @@ use cfg::{CfgExpr, CfgOptions}; | |||
7 | use either::Either; | 7 | use either::Either; |
8 | use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile}; | 8 | use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile}; |
9 | use itertools::Itertools; | 9 | use itertools::Itertools; |
10 | use la_arena::map::ArenaMap; | 10 | use la_arena::ArenaMap; |
11 | use mbe::ast_to_token_tree; | 11 | use mbe::ast_to_token_tree; |
12 | use syntax::{ | 12 | use syntax::{ |
13 | ast::{self, AstNode, AttrsOwner}, | 13 | ast::{self, AstNode, AttrsOwner}, |
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 43ee57277..344f0b6c0 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -16,7 +16,7 @@ use hir_expand::{ | |||
16 | ast_id_map::AstIdMap, diagnostics::DiagnosticSink, hygiene::Hygiene, AstId, ExpandResult, | 16 | ast_id_map::AstIdMap, diagnostics::DiagnosticSink, hygiene::Hygiene, AstId, ExpandResult, |
17 | HirFileId, InFile, MacroDefId, | 17 | HirFileId, InFile, MacroDefId, |
18 | }; | 18 | }; |
19 | use la_arena::{map::ArenaMap, Arena}; | 19 | use la_arena::{Arena, ArenaMap}; |
20 | use rustc_hash::FxHashMap; | 20 | use rustc_hash::FxHashMap; |
21 | use syntax::{ast, AstNode, AstPtr}; | 21 | use syntax::{ast, AstNode, AstPtr}; |
22 | use test_utils::mark; | 22 | use test_utils::mark; |
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs index 0506a7274..6ef9fe790 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | 3 | ||
4 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; | 4 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; |
5 | use hir_expand::{db::AstDatabase, HirFileId}; | 5 | use hir_expand::{db::AstDatabase, HirFileId}; |
6 | use la_arena::map::ArenaMap; | 6 | use la_arena::ArenaMap; |
7 | use syntax::SmolStr; | 7 | use syntax::SmolStr; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs index a293df9f1..5be838f4a 100644 --- a/crates/hir_def/src/expr.rs +++ b/crates/hir_def/src/expr.rs | |||
@@ -13,7 +13,7 @@ | |||
13 | //! See also a neighboring `body` module. | 13 | //! See also a neighboring `body` module. |
14 | 14 | ||
15 | use hir_expand::name::Name; | 15 | use hir_expand::name::Name; |
16 | use la_arena::{Idx, RawId}; | 16 | use la_arena::{Idx, RawIdx}; |
17 | use syntax::ast::RangeOp; | 17 | use syntax::ast::RangeOp; |
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
@@ -24,7 +24,7 @@ use crate::{ | |||
24 | 24 | ||
25 | pub type ExprId = Idx<Expr>; | 25 | pub type ExprId = Idx<Expr>; |
26 | pub(crate) fn dummy_expr_id() -> ExprId { | 26 | pub(crate) fn dummy_expr_id() -> ExprId { |
27 | ExprId::from_raw(RawId::from(!0)) | 27 | ExprId::from_raw(RawIdx::from(!0)) |
28 | } | 28 | } |
29 | 29 | ||
30 | pub type PatId = Idx<Pat>; | 30 | pub type PatId = Idx<Pat>; |
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 75eab791a..3ace3be1f 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs | |||
@@ -10,7 +10,7 @@ use hir_expand::{ | |||
10 | name::{name, AsName, Name}, | 10 | name::{name, AsName, Name}, |
11 | InFile, | 11 | InFile, |
12 | }; | 12 | }; |
13 | use la_arena::{map::ArenaMap, Arena}; | 13 | use la_arena::{Arena, ArenaMap}; |
14 | use syntax::ast::{self, GenericParamsOwner, NameOwner, TypeBoundsOwner}; | 14 | use syntax::ast::{self, GenericParamsOwner, NameOwner, TypeBoundsOwner}; |
15 | 15 | ||
16 | use crate::{ | 16 | use crate::{ |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 91e42aa0d..ff62928df 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -20,7 +20,7 @@ use hir_expand::{ | |||
20 | name::{name, AsName, Name}, | 20 | name::{name, AsName, Name}, |
21 | HirFileId, InFile, | 21 | HirFileId, InFile, |
22 | }; | 22 | }; |
23 | use la_arena::{Arena, Idx, RawId}; | 23 | use la_arena::{Arena, Idx, RawIdx}; |
24 | use rustc_hash::FxHashMap; | 24 | use rustc_hash::FxHashMap; |
25 | use smallvec::SmallVec; | 25 | use smallvec::SmallVec; |
26 | use syntax::{ast, match_ast}; | 26 | use syntax::{ast, match_ast}; |
@@ -145,7 +145,6 @@ impl ItemTree { | |||
145 | macro_calls, | 145 | macro_calls, |
146 | macro_rules, | 146 | macro_rules, |
147 | macro_defs, | 147 | macro_defs, |
148 | exprs, | ||
149 | vis, | 148 | vis, |
150 | generics, | 149 | generics, |
151 | } = &mut **data; | 150 | } = &mut **data; |
@@ -167,7 +166,6 @@ impl ItemTree { | |||
167 | macro_calls.shrink_to_fit(); | 166 | macro_calls.shrink_to_fit(); |
168 | macro_rules.shrink_to_fit(); | 167 | macro_rules.shrink_to_fit(); |
169 | macro_defs.shrink_to_fit(); | 168 | macro_defs.shrink_to_fit(); |
170 | exprs.shrink_to_fit(); | ||
171 | 169 | ||
172 | vis.arena.shrink_to_fit(); | 170 | vis.arena.shrink_to_fit(); |
173 | generics.arena.shrink_to_fit(); | 171 | generics.arena.shrink_to_fit(); |
@@ -296,7 +294,6 @@ struct ItemTreeData { | |||
296 | macro_calls: Arena<MacroCall>, | 294 | macro_calls: Arena<MacroCall>, |
297 | macro_rules: Arena<MacroRules>, | 295 | macro_rules: Arena<MacroRules>, |
298 | macro_defs: Arena<MacroDef>, | 296 | macro_defs: Arena<MacroDef>, |
299 | exprs: Arena<Expr>, | ||
300 | 297 | ||
301 | vis: ItemVisibilities, | 298 | vis: ItemVisibilities, |
302 | generics: GenericParamsStorage, | 299 | generics: GenericParamsStorage, |
@@ -461,7 +458,7 @@ macro_rules! impl_index { | |||
461 | }; | 458 | }; |
462 | } | 459 | } |
463 | 460 | ||
464 | impl_index!(fields: Field, variants: Variant, exprs: Expr); | 461 | impl_index!(fields: Field, variants: Variant); |
465 | 462 | ||
466 | impl Index<RawVisibilityId> for ItemTree { | 463 | impl Index<RawVisibilityId> for ItemTree { |
467 | type Output = RawVisibility; | 464 | type Output = RawVisibility; |
@@ -664,11 +661,6 @@ pub struct MacroDef { | |||
664 | pub ast_id: FileAstId<ast::MacroDef>, | 661 | pub ast_id: FileAstId<ast::MacroDef>, |
665 | } | 662 | } |
666 | 663 | ||
667 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array | ||
668 | // lengths, but we don't do much with them yet. | ||
669 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
670 | pub struct Expr; | ||
671 | |||
672 | macro_rules! impl_froms { | 664 | macro_rules! impl_froms { |
673 | ($e:ident { $($v:ident ($t:ty)),* $(,)? }) => { | 665 | ($e:ident { $($v:ident ($t:ty)),* $(,)? }) => { |
674 | $( | 666 | $( |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 3b206ef85..5e71ca42c 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -683,12 +683,12 @@ impl Ctx { | |||
683 | } | 683 | } |
684 | 684 | ||
685 | fn next_field_idx(&self) -> Idx<Field> { | 685 | fn next_field_idx(&self) -> Idx<Field> { |
686 | Idx::from_raw(RawId::from( | 686 | Idx::from_raw(RawIdx::from( |
687 | self.tree.data.as_ref().map_or(0, |data| data.fields.len() as u32), | 687 | self.tree.data.as_ref().map_or(0, |data| data.fields.len() as u32), |
688 | )) | 688 | )) |
689 | } | 689 | } |
690 | fn next_variant_idx(&self) -> Idx<Variant> { | 690 | fn next_variant_idx(&self) -> Idx<Variant> { |
691 | Idx::from_raw(RawId::from( | 691 | Idx::from_raw(RawIdx::from( |
692 | self.tree.data.as_ref().map_or(0, |data| data.variants.len() as u32), | 692 | self.tree.data.as_ref().map_or(0, |data| data.variants.len() as u32), |
693 | )) | 693 | )) |
694 | } | 694 | } |
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 3dd7c3cbb..e34cd7f2f 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs | |||
@@ -87,7 +87,7 @@ impl ModPath { | |||
87 | 87 | ||
88 | /// If this path is a single identifier, like `foo`, return its name. | 88 | /// If this path is a single identifier, like `foo`, return its name. |
89 | pub fn as_ident(&self) -> Option<&Name> { | 89 | pub fn as_ident(&self) -> Option<&Name> { |
90 | if self.kind != PathKind::Plain || self.segments.len() > 1 { | 90 | if !self.is_ident() { |
91 | return None; | 91 | return None; |
92 | } | 92 | } |
93 | self.segments.first() | 93 | self.segments.first() |
diff --git a/crates/hir_def/src/src.rs b/crates/hir_def/src/src.rs index eb29265d9..751d4c052 100644 --- a/crates/hir_def/src/src.rs +++ b/crates/hir_def/src/src.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Utilities for mapping between hir IDs and the surface syntax. | 1 | //! Utilities for mapping between hir IDs and the surface syntax. |
2 | 2 | ||
3 | use hir_expand::InFile; | 3 | use hir_expand::InFile; |
4 | use la_arena::map::ArenaMap; | 4 | use la_arena::ArenaMap; |
5 | 5 | ||
6 | use crate::{db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc}; | 6 | use crate::{db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc}; |
7 | 7 | ||
diff --git a/crates/hir_def/src/trace.rs b/crates/hir_def/src/trace.rs index 0a9beae8e..6e6ceb8e4 100644 --- a/crates/hir_def/src/trace.rs +++ b/crates/hir_def/src/trace.rs | |||
@@ -9,7 +9,7 @@ | |||
9 | //! absolute offsets. The `Trace` structure (inspired, at least in name, by | 9 | //! absolute offsets. The `Trace` structure (inspired, at least in name, by |
10 | //! Kotlin's `BindingTrace`) allows use the same code to compute both | 10 | //! Kotlin's `BindingTrace`) allows use the same code to compute both |
11 | //! projections. | 11 | //! projections. |
12 | use la_arena::{map::ArenaMap, Arena, Idx, RawId}; | 12 | use la_arena::{Arena, ArenaMap, Idx, RawIdx}; |
13 | 13 | ||
14 | pub(crate) struct Trace<T, V> { | 14 | pub(crate) struct Trace<T, V> { |
15 | arena: Option<Arena<T>>, | 15 | arena: Option<Arena<T>>, |
@@ -30,7 +30,7 @@ impl<T, V> Trace<T, V> { | |||
30 | let id = if let Some(arena) = &mut self.arena { | 30 | let id = if let Some(arena) = &mut self.arena { |
31 | arena.alloc(data()) | 31 | arena.alloc(data()) |
32 | } else { | 32 | } else { |
33 | let id = Idx::<T>::from_raw(RawId::from(self.len)); | 33 | let id = Idx::<T>::from_raw(RawIdx::from(self.len)); |
34 | self.len += 1; | 34 | self.len += 1; |
35 | id | 35 | id |
36 | }; | 36 | }; |
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index ae93d0d10..049b2e462 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs | |||
@@ -159,6 +159,8 @@ impl TypeRef { | |||
159 | ast::Type::DynTraitType(inner) => { | 159 | ast::Type::DynTraitType(inner) => { |
160 | TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list())) | 160 | TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list())) |
161 | } | 161 | } |
162 | // FIXME: Macros in type position are not yet supported. | ||
163 | ast::Type::MacroType(_) => TypeRef::Error, | ||
162 | } | 164 | } |
163 | } | 165 | } |
164 | 166 | ||
diff --git a/crates/hir_expand/Cargo.toml b/crates/hir_expand/Cargo.toml index b535a3d4f..5271110d2 100644 --- a/crates/hir_expand/Cargo.toml +++ b/crates/hir_expand/Cargo.toml | |||
@@ -13,7 +13,7 @@ doctest = false | |||
13 | log = "0.4.8" | 13 | log = "0.4.8" |
14 | either = "1.5.3" | 14 | either = "1.5.3" |
15 | rustc-hash = "1.0.0" | 15 | rustc-hash = "1.0.0" |
16 | la-arena = "0.1.0" | 16 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
17 | 17 | ||
18 | base_db = { path = "../base_db", version = "0.0.0" } | 18 | base_db = { path = "../base_db", version = "0.0.0" } |
19 | syntax = { path = "../syntax", version = "0.0.0" } | 19 | syntax = { path = "../syntax", version = "0.0.0" } |
diff --git a/crates/hir_expand/src/ast_id_map.rs b/crates/hir_expand/src/ast_id_map.rs index f4f6e11fd..2401b0cc5 100644 --- a/crates/hir_expand/src/ast_id_map.rs +++ b/crates/hir_expand/src/ast_id_map.rs | |||
@@ -72,10 +72,12 @@ impl AstIdMap { | |||
72 | // get lower ids then children. That is, adding a new child does not | 72 | // get lower ids then children. That is, adding a new child does not |
73 | // change parent's id. This means that, say, adding a new function to a | 73 | // change parent's id. This means that, say, adding a new function to a |
74 | // trait does not change ids of top-level items, which helps caching. | 74 | // trait does not change ids of top-level items, which helps caching. |
75 | bfs(node, |it| { | 75 | bdfs(node, |it| match ast::Item::cast(it) { |
76 | if let Some(module_item) = ast::Item::cast(it) { | 76 | Some(module_item) => { |
77 | res.alloc(module_item.syntax()); | 77 | res.alloc(module_item.syntax()); |
78 | true | ||
78 | } | 79 | } |
80 | None => false, | ||
79 | }); | 81 | }); |
80 | res | 82 | res |
81 | } | 83 | } |
@@ -105,14 +107,30 @@ impl AstIdMap { | |||
105 | } | 107 | } |
106 | } | 108 | } |
107 | 109 | ||
108 | /// Walks the subtree in bfs order, calling `f` for each node. | 110 | /// Walks the subtree in bdfs order, calling `f` for each node. What is bdfs |
109 | fn bfs(node: &SyntaxNode, mut f: impl FnMut(SyntaxNode)) { | 111 | /// order? It is a mix of breadth-first and depth first orders. Nodes for which |
112 | /// `f` returns true are visited breadth-first, all the other nodes are explored | ||
113 | /// depth-first. | ||
114 | /// | ||
115 | /// In other words, the size of the bfs queue is bound by the number of "true" | ||
116 | /// nodes. | ||
117 | fn bdfs(node: &SyntaxNode, mut f: impl FnMut(SyntaxNode) -> bool) { | ||
110 | let mut curr_layer = vec![node.clone()]; | 118 | let mut curr_layer = vec![node.clone()]; |
111 | let mut next_layer = vec![]; | 119 | let mut next_layer = vec![]; |
112 | while !curr_layer.is_empty() { | 120 | while !curr_layer.is_empty() { |
113 | curr_layer.drain(..).for_each(|node| { | 121 | curr_layer.drain(..).for_each(|node| { |
114 | next_layer.extend(node.children()); | 122 | let mut preorder = node.preorder(); |
115 | f(node); | 123 | while let Some(event) = preorder.next() { |
124 | match event { | ||
125 | syntax::WalkEvent::Enter(node) => { | ||
126 | if f(node.clone()) { | ||
127 | next_layer.extend(node.children()); | ||
128 | preorder.skip_subtree(); | ||
129 | } | ||
130 | } | ||
131 | syntax::WalkEvent::Leave(_) => {} | ||
132 | } | ||
133 | } | ||
116 | }); | 134 | }); |
117 | std::mem::swap(&mut curr_layer, &mut next_layer); | 135 | std::mem::swap(&mut curr_layer, &mut next_layer); |
118 | } | 136 | } |
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index 8db581b77..c8ea81210 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs | |||
@@ -76,6 +76,8 @@ pub struct HygieneFrame { | |||
76 | 76 | ||
77 | impl HygieneFrames { | 77 | impl HygieneFrames { |
78 | fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self { | 78 | fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self { |
79 | // Note that this intentionally avoids the `hygiene_frame` query to avoid blowing up memory | ||
80 | // usage. The query is only helpful for nested `HygieneFrame`s as it avoids redundant work. | ||
79 | HygieneFrames(Arc::new(HygieneFrame::new(db, file_id))) | 81 | HygieneFrames(Arc::new(HygieneFrame::new(db, file_id))) |
80 | } | 82 | } |
81 | 83 | ||
diff --git a/crates/hir_expand/src/proc_macro.rs b/crates/hir_expand/src/proc_macro.rs index 1923daca5..75e950816 100644 --- a/crates/hir_expand/src/proc_macro.rs +++ b/crates/hir_expand/src/proc_macro.rs | |||
@@ -135,7 +135,6 @@ mod tests { | |||
135 | let result = format!("{:#?}", remove_derive_attrs(&tt).unwrap()); | 135 | let result = format!("{:#?}", remove_derive_attrs(&tt).unwrap()); |
136 | 136 | ||
137 | assert_eq_text!( | 137 | assert_eq_text!( |
138 | &result, | ||
139 | r#" | 138 | r#" |
140 | SUBTREE $ | 139 | SUBTREE $ |
141 | PUNCH # [alone] 0 | 140 | PUNCH # [alone] 0 |
@@ -150,7 +149,8 @@ SUBTREE $ | |||
150 | PUNCH : [alone] 19 | 149 | PUNCH : [alone] 19 |
151 | IDENT u32 20 | 150 | IDENT u32 20 |
152 | "# | 151 | "# |
153 | .trim() | 152 | .trim(), |
153 | &result | ||
154 | ); | 154 | ); |
155 | } | 155 | } |
156 | } | 156 | } |
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index 436c1405b..98434b741 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -20,7 +20,7 @@ scoped-tls = "1" | |||
20 | chalk-solve = { version = "0.47", default-features = false } | 20 | chalk-solve = { version = "0.47", default-features = false } |
21 | chalk-ir = "0.47" | 21 | chalk-ir = "0.47" |
22 | chalk-recursive = "0.47" | 22 | chalk-recursive = "0.47" |
23 | la-arena = "0.1.0" | 23 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
24 | 24 | ||
25 | stdx = { path = "../stdx", version = "0.0.0" } | 25 | stdx = { path = "../stdx", version = "0.0.0" } |
26 | hir_def = { path = "../hir_def", version = "0.0.0" } | 26 | hir_def = { path = "../hir_def", version = "0.0.0" } |
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index b0e2a3b7d..b3af82444 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -7,7 +7,7 @@ use hir_def::{ | |||
7 | db::DefDatabase, expr::ExprId, ConstParamId, DefWithBodyId, FunctionId, GenericDefId, ImplId, | 7 | db::DefDatabase, expr::ExprId, ConstParamId, DefWithBodyId, FunctionId, GenericDefId, ImplId, |
8 | LocalFieldId, TypeParamId, VariantId, | 8 | LocalFieldId, TypeParamId, VariantId, |
9 | }; | 9 | }; |
10 | use la_arena::map::ArenaMap; | 10 | use la_arena::ArenaMap; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | method_resolution::{InherentImpls, TraitImpls}, | 13 | method_resolution::{InherentImpls, TraitImpls}, |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 46a806b9a..d08867c70 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -30,7 +30,7 @@ use hir_def::{ | |||
30 | TypeAliasId, VariantId, | 30 | TypeAliasId, VariantId, |
31 | }; | 31 | }; |
32 | use hir_expand::{diagnostics::DiagnosticSink, name::name}; | 32 | use hir_expand::{diagnostics::DiagnosticSink, name::name}; |
33 | use la_arena::map::ArenaMap; | 33 | use la_arena::ArenaMap; |
34 | use rustc_hash::FxHashMap; | 34 | use rustc_hash::FxHashMap; |
35 | use stdx::impl_from; | 35 | use stdx::impl_from; |
36 | use syntax::SmolStr; | 36 | use syntax::SmolStr; |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 68d16f89a..7a734c8b9 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -20,7 +20,7 @@ use hir_def::{ | |||
20 | TypeAliasId, TypeParamId, UnionId, VariantId, | 20 | TypeAliasId, TypeParamId, UnionId, VariantId, |
21 | }; | 21 | }; |
22 | use hir_expand::name::Name; | 22 | use hir_expand::name::Name; |
23 | use la_arena::map::ArenaMap; | 23 | use la_arena::ArenaMap; |
24 | use smallvec::SmallVec; | 24 | use smallvec::SmallVec; |
25 | use stdx::impl_from; | 25 | use stdx::impl_from; |
26 | use test_utils::mark; | 26 | use test_utils::mark; |
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 3b1675f0b..5ff755321 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs | |||
@@ -26,7 +26,7 @@ use once_cell::race::OnceBool; | |||
26 | use stdx::format_to; | 26 | use stdx::format_to; |
27 | use syntax::{ | 27 | use syntax::{ |
28 | algo, | 28 | algo, |
29 | ast::{self, AstNode}, | 29 | ast::{self, AstNode, NameOwner}, |
30 | SyntaxNode, | 30 | SyntaxNode, |
31 | }; | 31 | }; |
32 | use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; | 32 | use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; |
@@ -153,7 +153,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { | |||
153 | }); | 153 | }); |
154 | for (node, ty) in &types { | 154 | for (node, ty) in &types { |
155 | let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.value.clone()) { | 155 | let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.value.clone()) { |
156 | (self_param.self_token().unwrap().text_range(), "self".to_string()) | 156 | (self_param.name().unwrap().syntax().text_range(), "self".to_string()) |
157 | } else { | 157 | } else { |
158 | (node.value.text_range(), node.value.text().to_string().replace("\n", " ")) | 158 | (node.value.text_range(), node.value.text().to_string().replace("\n", " ")) |
159 | }; | 159 | }; |
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index e4335119b..579d5a308 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -140,7 +140,7 @@ impl DiagnosticWithFix for IncorrectCase { | |||
140 | rename_with_semantics(sema, file_position, &self.suggested_text).ok()?; | 140 | rename_with_semantics(sema, file_position, &self.suggested_text).ok()?; |
141 | 141 | ||
142 | let label = format!("Rename to {}", self.suggested_text); | 142 | let label = format!("Rename to {}", self.suggested_text); |
143 | Some(Fix::new(&label, rename_changes.info, rename_changes.range)) | 143 | Some(Fix::new(&label, rename_changes, frange.range)) |
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 685052e7f..00e601244 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -400,15 +400,13 @@ impl TryToNav for hir::GenericParam { | |||
400 | impl ToNav for hir::Local { | 400 | impl ToNav for hir::Local { |
401 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 401 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
402 | let src = self.source(db); | 402 | let src = self.source(db); |
403 | let (node, focus_range) = match &src.value { | 403 | let (node, name) = match &src.value { |
404 | Either::Left(bind_pat) => ( | 404 | Either::Left(bind_pat) => (bind_pat.syntax().clone(), bind_pat.name()), |
405 | bind_pat.syntax().clone(), | 405 | Either::Right(it) => (it.syntax().clone(), it.name()), |
406 | bind_pat | ||
407 | .name() | ||
408 | .map(|it| src.with_value(&it.syntax().clone()).original_file_range(db).range), | ||
409 | ), | ||
410 | Either::Right(it) => (it.syntax().clone(), it.self_token().map(|it| it.text_range())), | ||
411 | }; | 406 | }; |
407 | let focus_range = | ||
408 | name.map(|it| src.with_value(&it.syntax().clone()).original_file_range(db).range); | ||
409 | |||
412 | let full_range = src.with_value(&node).original_file_range(db); | 410 | let full_range = src.with_value(&node).original_file_range(db); |
413 | let name = match self.name(db) { | 411 | let name = match self.name(db) { |
414 | Some(it) => it.to_string().into(), | 412 | Some(it) => it.to_string().into(), |
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 988a5668f..a1d2bce1d 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -55,11 +55,6 @@ pub(crate) fn goto_definition( | |||
55 | } else { | 55 | } else { |
56 | reference_definition(&sema, Either::Left(<)).to_vec() | 56 | reference_definition(&sema, Either::Left(<)).to_vec() |
57 | }, | 57 | }, |
58 | ast::SelfParam(self_param) => { | ||
59 | let def = NameClass::classify_self_param(&sema, &self_param)?.referenced_or_defined(sema.db); | ||
60 | let nav = def.try_to_nav(sema.db)?; | ||
61 | vec![nav] | ||
62 | }, | ||
63 | _ => return None, | 58 | _ => return None, |
64 | } | 59 | } |
65 | }; | 60 | }; |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 6022bd275..2024acd94 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -98,7 +98,6 @@ pub(crate) fn hover( | |||
98 | ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)), | 98 | ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)), |
99 | ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime) | 99 | ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime) |
100 | .map_or_else(|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced(sema.db)), |d| d.defined(sema.db)), | 100 | .map_or_else(|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced(sema.db)), |d| d.defined(sema.db)), |
101 | ast::SelfParam(self_param) => NameClass::classify_self_param(&sema, &self_param).and_then(|d| d.defined(sema.db)), | ||
102 | _ => None, | 101 | _ => None, |
103 | } | 102 | } |
104 | }; | 103 | }; |
@@ -3223,7 +3222,7 @@ impl Foo { | |||
3223 | } | 3222 | } |
3224 | "#, | 3223 | "#, |
3225 | expect![[r#" | 3224 | expect![[r#" |
3226 | *&self* | 3225 | *self* |
3227 | 3226 | ||
3228 | ```rust | 3227 | ```rust |
3229 | &Foo | 3228 | &Foo |
@@ -3243,7 +3242,7 @@ impl Foo { | |||
3243 | } | 3242 | } |
3244 | "#, | 3243 | "#, |
3245 | expect![[r#" | 3244 | expect![[r#" |
3246 | *self: Arc<Foo>* | 3245 | *self* |
3247 | 3246 | ||
3248 | ```rust | 3247 | ```rust |
3249 | Arc<Foo> | 3248 | Arc<Foo> |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 07f52613f..3abbb14c6 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -86,18 +86,15 @@ pub use completion::{ | |||
86 | InsertTextFormat, | 86 | InsertTextFormat, |
87 | }; | 87 | }; |
88 | pub use hir::{Documentation, Semantics}; | 88 | pub use hir::{Documentation, Semantics}; |
89 | pub use ide_db::base_db::{ | ||
90 | Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, | ||
91 | SourceRootId, | ||
92 | }; | ||
93 | pub use ide_db::{ | 89 | pub use ide_db::{ |
90 | base_db::{ | ||
91 | Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, | ||
92 | SourceRoot, SourceRootId, | ||
93 | }, | ||
94 | call_info::CallInfo, | 94 | call_info::CallInfo, |
95 | search::{FileReference, ReferenceAccess, ReferenceKind}, | ||
96 | }; | ||
97 | pub use ide_db::{ | ||
98 | label::Label, | 95 | label::Label, |
99 | line_index::{LineCol, LineIndex}, | 96 | line_index::{LineCol, LineIndex}, |
100 | search::SearchScope, | 97 | search::{FileReference, ReferenceAccess, ReferenceKind, SearchScope}, |
101 | source_change::{FileSystemEdit, SourceChange}, | 98 | source_change::{FileSystemEdit, SourceChange}, |
102 | symbol_index::Query, | 99 | symbol_index::Query, |
103 | RootDatabase, | 100 | RootDatabase, |
@@ -525,7 +522,7 @@ impl Analysis { | |||
525 | &self, | 522 | &self, |
526 | position: FilePosition, | 523 | position: FilePosition, |
527 | new_name: &str, | 524 | new_name: &str, |
528 | ) -> Cancelable<Result<RangeInfo<SourceChange>, RenameError>> { | 525 | ) -> Cancelable<Result<SourceChange, RenameError>> { |
529 | self.with_db(|db| references::rename::rename(db, position, new_name)) | 526 | self.with_db(|db| references::rename::rename(db, position, new_name)) |
530 | } | 527 | } |
531 | 528 | ||
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 51a2f4327..df9c31aef 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -930,6 +930,26 @@ impl Foo { | |||
930 | ); | 930 | ); |
931 | } | 931 | } |
932 | 932 | ||
933 | #[test] | ||
934 | fn test_find_self_refs_decl() { | ||
935 | check( | ||
936 | r#" | ||
937 | struct Foo { bar: i32 } | ||
938 | |||
939 | impl Foo { | ||
940 | fn foo(self$0) { | ||
941 | self; | ||
942 | } | ||
943 | } | ||
944 | "#, | ||
945 | expect![[r#" | ||
946 | self SelfParam FileId(0) 47..51 47..51 SelfParam | ||
947 | |||
948 | FileId(0) 63..67 Other Read | ||
949 | "#]], | ||
950 | ); | ||
951 | } | ||
952 | |||
933 | fn check(ra_fixture: &str, expect: Expect) { | 953 | fn check(ra_fixture: &str, expect: Expect) { |
934 | check_with_scope(ra_fixture, None, expect) | 954 | check_with_scope(ra_fixture, None, expect) |
935 | } | 955 | } |
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 9ac4af026..c25bcce50 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -1,27 +1,25 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | use std::{ | 2 | use std::fmt::{self, Display}; |
3 | convert::TryInto, | ||
4 | fmt::{self, Display}, | ||
5 | }; | ||
6 | 3 | ||
7 | use hir::{Module, ModuleDef, ModuleSource, Semantics}; | 4 | use either::Either; |
5 | use hir::{HasSource, InFile, Module, ModuleDef, ModuleSource, Semantics}; | ||
8 | use ide_db::{ | 6 | use ide_db::{ |
9 | base_db::{AnchoredPathBuf, FileId, FileRange, SourceDatabaseExt}, | 7 | base_db::{AnchoredPathBuf, FileId, FileRange}, |
10 | defs::{Definition, NameClass, NameRefClass}, | 8 | defs::{Definition, NameClass, NameRefClass}, |
11 | search::FileReference, | 9 | search::FileReference, |
12 | RootDatabase, | 10 | RootDatabase, |
13 | }; | 11 | }; |
12 | use stdx::assert_never; | ||
14 | use syntax::{ | 13 | use syntax::{ |
15 | algo::find_node_at_offset, | ||
16 | ast::{self, NameOwner}, | 14 | ast::{self, NameOwner}, |
17 | lex_single_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, SyntaxToken, T, | 15 | lex_single_syntax_kind, AstNode, SyntaxKind, SyntaxNode, T, |
18 | }; | 16 | }; |
19 | use test_utils::mark; | 17 | use test_utils::mark; |
20 | use text_edit::TextEdit; | 18 | use text_edit::TextEdit; |
21 | 19 | ||
22 | use crate::{ | 20 | use crate::{ |
23 | FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange, | 21 | display::TryToNav, FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, SourceChange, |
24 | TextRange, TextSize, | 22 | TextRange, |
25 | }; | 23 | }; |
26 | 24 | ||
27 | type RenameResult<T> = Result<T, RenameError>; | 25 | type RenameResult<T> = Result<T, RenameError>; |
@@ -50,24 +48,22 @@ pub(crate) fn prepare_rename( | |||
50 | let sema = Semantics::new(db); | 48 | let sema = Semantics::new(db); |
51 | let source_file = sema.parse(position.file_id); | 49 | let source_file = sema.parse(position.file_id); |
52 | let syntax = source_file.syntax(); | 50 | let syntax = source_file.syntax(); |
53 | if let Some(module) = find_module_at_offset(&sema, position, syntax) { | 51 | let range = match &find_name_like(&sema, &syntax, position) |
54 | rename_mod(&sema, position, module, "dummy") | 52 | .ok_or_else(|| format_err!("No references found at position"))? |
55 | } else if let Some(self_token) = | ||
56 | syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self]) | ||
57 | { | 53 | { |
58 | rename_self_to_param(&sema, position, self_token, "dummy") | 54 | NameLike::Name(it) => it.syntax(), |
59 | } else { | 55 | NameLike::NameRef(it) => it.syntax(), |
60 | let RangeInfo { range, .. } = find_all_refs(&sema, position)?; | 56 | NameLike::Lifetime(it) => it.syntax(), |
61 | Ok(RangeInfo::new(range, SourceChange::default())) | ||
62 | } | 57 | } |
63 | .map(|info| RangeInfo::new(info.range, ())) | 58 | .text_range(); |
59 | Ok(RangeInfo::new(range, ())) | ||
64 | } | 60 | } |
65 | 61 | ||
66 | pub(crate) fn rename( | 62 | pub(crate) fn rename( |
67 | db: &RootDatabase, | 63 | db: &RootDatabase, |
68 | position: FilePosition, | 64 | position: FilePosition, |
69 | new_name: &str, | 65 | new_name: &str, |
70 | ) -> RenameResult<RangeInfo<SourceChange>> { | 66 | ) -> RenameResult<SourceChange> { |
71 | let sema = Semantics::new(db); | 67 | let sema = Semantics::new(db); |
72 | rename_with_semantics(&sema, position, new_name) | 68 | rename_with_semantics(&sema, position, new_name) |
73 | } | 69 | } |
@@ -76,18 +72,15 @@ pub(crate) fn rename_with_semantics( | |||
76 | sema: &Semantics<RootDatabase>, | 72 | sema: &Semantics<RootDatabase>, |
77 | position: FilePosition, | 73 | position: FilePosition, |
78 | new_name: &str, | 74 | new_name: &str, |
79 | ) -> RenameResult<RangeInfo<SourceChange>> { | 75 | ) -> RenameResult<SourceChange> { |
80 | let source_file = sema.parse(position.file_id); | 76 | let source_file = sema.parse(position.file_id); |
81 | let syntax = source_file.syntax(); | 77 | let syntax = source_file.syntax(); |
82 | 78 | ||
83 | if let Some(module) = find_module_at_offset(&sema, position, syntax) { | 79 | let def = find_definition(sema, syntax, position) |
84 | rename_mod(&sema, position, module, new_name) | 80 | .ok_or_else(|| format_err!("No references found at position"))?; |
85 | } else if let Some(self_token) = | 81 | match def { |
86 | syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self]) | 82 | Definition::ModuleDef(ModuleDef::Module(module)) => rename_mod(&sema, module, new_name), |
87 | { | 83 | def => rename_reference(sema, def, new_name), |
88 | rename_self_to_param(&sema, position, self_token, new_name) | ||
89 | } else { | ||
90 | rename_reference(&sema, position, new_name) | ||
91 | } | 84 | } |
92 | } | 85 | } |
93 | 86 | ||
@@ -98,17 +91,12 @@ pub(crate) fn will_rename_file( | |||
98 | ) -> Option<SourceChange> { | 91 | ) -> Option<SourceChange> { |
99 | let sema = Semantics::new(db); | 92 | let sema = Semantics::new(db); |
100 | let module = sema.to_module_def(file_id)?; | 93 | let module = sema.to_module_def(file_id)?; |
101 | 94 | let mut change = rename_mod(&sema, module, new_name_stem).ok()?; | |
102 | let decl = module.declaration_source(db)?; | ||
103 | let range = decl.value.name()?.syntax().text_range(); | ||
104 | |||
105 | let position = FilePosition { file_id: decl.file_id.original_file(db), offset: range.start() }; | ||
106 | let mut change = rename_mod(&sema, position, module, new_name_stem).ok()?.info; | ||
107 | change.file_system_edits.clear(); | 95 | change.file_system_edits.clear(); |
108 | Some(change) | 96 | Some(change) |
109 | } | 97 | } |
110 | 98 | ||
111 | #[derive(Debug, PartialEq)] | 99 | #[derive(Copy, Clone, Debug, PartialEq)] |
112 | enum IdentifierKind { | 100 | enum IdentifierKind { |
113 | Ident, | 101 | Ident, |
114 | Lifetime, | 102 | Lifetime, |
@@ -135,40 +123,51 @@ fn check_identifier(new_name: &str) -> RenameResult<IdentifierKind> { | |||
135 | } | 123 | } |
136 | } | 124 | } |
137 | 125 | ||
138 | fn find_module_at_offset( | 126 | enum NameLike { |
127 | Name(ast::Name), | ||
128 | NameRef(ast::NameRef), | ||
129 | Lifetime(ast::Lifetime), | ||
130 | } | ||
131 | |||
132 | fn find_name_like( | ||
139 | sema: &Semantics<RootDatabase>, | 133 | sema: &Semantics<RootDatabase>, |
140 | position: FilePosition, | ||
141 | syntax: &SyntaxNode, | 134 | syntax: &SyntaxNode, |
142 | ) -> Option<Module> { | 135 | position: FilePosition, |
143 | let ident = syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::IDENT)?; | 136 | ) -> Option<NameLike> { |
144 | 137 | let namelike = if let Some(name_ref) = | |
145 | let module = match_ast! { | 138 | sema.find_node_at_offset_with_descend::<ast::NameRef>(syntax, position.offset) |
146 | match (ident.parent()) { | 139 | { |
147 | ast::NameRef(name_ref) => { | 140 | NameLike::NameRef(name_ref) |
148 | match NameRefClass::classify(sema, &name_ref)? { | 141 | } else if let Some(name) = |
149 | NameRefClass::Definition(Definition::ModuleDef(ModuleDef::Module(module))) => module, | 142 | sema.find_node_at_offset_with_descend::<ast::Name>(syntax, position.offset) |
150 | _ => return None, | 143 | { |
151 | } | 144 | NameLike::Name(name) |
152 | }, | 145 | } else if let Some(lifetime) = |
153 | ast::Name(name) => { | 146 | sema.find_node_at_offset_with_descend::<ast::Lifetime>(syntax, position.offset) |
154 | match NameClass::classify(&sema, &name)? { | 147 | { |
155 | NameClass::Definition(Definition::ModuleDef(ModuleDef::Module(module))) => module, | 148 | NameLike::Lifetime(lifetime) |
156 | _ => return None, | 149 | } else { |
157 | } | 150 | return None; |
158 | }, | ||
159 | _ => return None, | ||
160 | } | ||
161 | }; | 151 | }; |
162 | 152 | Some(namelike) | |
163 | Some(module) | ||
164 | } | 153 | } |
165 | 154 | ||
166 | fn find_all_refs( | 155 | fn find_definition( |
167 | sema: &Semantics<RootDatabase>, | 156 | sema: &Semantics<RootDatabase>, |
157 | syntax: &SyntaxNode, | ||
168 | position: FilePosition, | 158 | position: FilePosition, |
169 | ) -> RenameResult<RangeInfo<ReferenceSearchResult>> { | 159 | ) -> Option<Definition> { |
170 | crate::references::find_all_refs(sema, position, None) | 160 | let def = match find_name_like(sema, syntax, position)? { |
171 | .ok_or_else(|| format_err!("No references found at position")) | 161 | NameLike::Name(name) => NameClass::classify(sema, &name)?.referenced_or_defined(sema.db), |
162 | NameLike::NameRef(name_ref) => NameRefClass::classify(sema, &name_ref)?.referenced(sema.db), | ||
163 | NameLike::Lifetime(lifetime) => NameRefClass::classify_lifetime(sema, &lifetime) | ||
164 | .map(|class| NameRefClass::referenced(class, sema.db)) | ||
165 | .or_else(|| { | ||
166 | NameClass::classify_lifetime(sema, &lifetime) | ||
167 | .map(|it| it.referenced_or_defined(sema.db)) | ||
168 | })?, | ||
169 | }; | ||
170 | Some(def) | ||
172 | } | 171 | } |
173 | 172 | ||
174 | fn source_edit_from_references( | 173 | fn source_edit_from_references( |
@@ -242,72 +241,84 @@ fn edit_text_range_for_record_field_expr_or_pat( | |||
242 | 241 | ||
243 | fn rename_mod( | 242 | fn rename_mod( |
244 | sema: &Semantics<RootDatabase>, | 243 | sema: &Semantics<RootDatabase>, |
245 | position: FilePosition, | ||
246 | module: Module, | 244 | module: Module, |
247 | new_name: &str, | 245 | new_name: &str, |
248 | ) -> RenameResult<RangeInfo<SourceChange>> { | 246 | ) -> RenameResult<SourceChange> { |
249 | if IdentifierKind::Ident != check_identifier(new_name)? { | 247 | if IdentifierKind::Ident != check_identifier(new_name)? { |
250 | bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); | 248 | bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); |
251 | } | 249 | } |
252 | 250 | ||
253 | let mut source_change = SourceChange::default(); | 251 | let mut source_change = SourceChange::default(); |
254 | 252 | ||
255 | let src = module.definition_source(sema.db); | 253 | let InFile { file_id, value: def_source } = module.definition_source(sema.db); |
256 | let file_id = src.file_id.original_file(sema.db); | 254 | let file_id = file_id.original_file(sema.db); |
257 | match src.value { | 255 | if let ModuleSource::SourceFile(..) = def_source { |
258 | ModuleSource::SourceFile(..) => { | 256 | // mod is defined in path/to/dir/mod.rs |
259 | // mod is defined in path/to/dir/mod.rs | 257 | let path = if module.is_mod_rs(sema.db) { |
260 | let path = if module.is_mod_rs(sema.db) { | 258 | format!("../{}/mod.rs", new_name) |
261 | format!("../{}/mod.rs", new_name) | 259 | } else { |
262 | } else { | 260 | format!("{}.rs", new_name) |
263 | format!("{}.rs", new_name) | 261 | }; |
264 | }; | 262 | let dst = AnchoredPathBuf { anchor: file_id, path }; |
265 | let dst = AnchoredPathBuf { anchor: file_id, path }; | 263 | let move_file = FileSystemEdit::MoveFile { src: file_id, dst }; |
266 | let move_file = FileSystemEdit::MoveFile { src: file_id, dst }; | 264 | source_change.push_file_system_edit(move_file); |
267 | source_change.push_file_system_edit(move_file); | 265 | } |
268 | } | 266 | |
269 | ModuleSource::Module(..) => {} | 267 | if let Some(InFile { file_id, value: decl_source }) = module.declaration_source(sema.db) { |
270 | } | 268 | let file_id = file_id.original_file(sema.db); |
271 | 269 | match decl_source.name() { | |
272 | if let Some(src) = module.declaration_source(sema.db) { | 270 | Some(name) => source_change.insert_source_edit( |
273 | let file_id = src.file_id.original_file(sema.db); | 271 | file_id, |
274 | let name = src.value.name().unwrap(); | 272 | TextEdit::replace(name.syntax().text_range(), new_name.to_string()), |
275 | source_change.insert_source_edit( | 273 | ), |
276 | file_id, | 274 | _ => unreachable!(), |
277 | TextEdit::replace(name.syntax().text_range(), new_name.into()), | 275 | }; |
278 | ); | ||
279 | } | 276 | } |
280 | 277 | let def = Definition::ModuleDef(ModuleDef::Module(module)); | |
281 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; | 278 | let usages = def.usages(sema).all(); |
282 | let ref_edits = refs.references().iter().map(|(&file_id, references)| { | 279 | let ref_edits = usages.iter().map(|(&file_id, references)| { |
283 | source_edit_from_references(sema, file_id, references, new_name) | 280 | source_edit_from_references(sema, file_id, references, new_name) |
284 | }); | 281 | }); |
285 | source_change.extend(ref_edits); | 282 | source_change.extend(ref_edits); |
286 | 283 | ||
287 | Ok(RangeInfo::new(range, source_change)) | 284 | Ok(source_change) |
288 | } | 285 | } |
289 | 286 | ||
290 | fn rename_to_self( | 287 | fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameResult<SourceChange> { |
291 | sema: &Semantics<RootDatabase>, | 288 | if assert_never!(local.is_self(sema.db)) { |
292 | position: FilePosition, | 289 | bail!("rename_to_self invoked on self"); |
293 | ) -> Result<RangeInfo<SourceChange>, RenameError> { | 290 | } |
294 | let source_file = sema.parse(position.file_id); | 291 | |
295 | let syn = source_file.syntax(); | 292 | let fn_def = match local.parent(sema.db) { |
293 | hir::DefWithBody::Function(func) => func, | ||
294 | _ => bail!("Cannot rename non-param local to self"), | ||
295 | }; | ||
296 | |||
297 | // FIXME: reimplement this on the hir instead | ||
298 | // as of the time of this writing params in hir don't keep their names | ||
299 | let fn_ast = | ||
300 | fn_def.source(sema.db).ok_or(format_err!("Cannot rename non-param local to self"))?.value; | ||
296 | 301 | ||
297 | let (fn_def, fn_ast) = find_node_at_offset::<ast::Fn>(syn, position.offset) | 302 | let first_param_range = fn_ast |
298 | .and_then(|fn_ast| sema.to_def(&fn_ast).zip(Some(fn_ast))) | ||
299 | .ok_or_else(|| format_err!("No surrounding method declaration found"))?; | ||
300 | let param_range = fn_ast | ||
301 | .param_list() | 303 | .param_list() |
302 | .and_then(|p| p.params().next()) | 304 | .and_then(|p| p.params().next()) |
303 | .ok_or_else(|| format_err!("Method has no parameters"))? | 305 | .ok_or_else(|| format_err!("Method has no parameters"))? |
304 | .syntax() | 306 | .syntax() |
305 | .text_range(); | 307 | .text_range(); |
306 | if !param_range.contains(position.offset) { | 308 | let InFile { file_id, value: local_source } = local.source(sema.db); |
307 | bail!("Only the first parameter can be self"); | 309 | match local_source { |
310 | either::Either::Left(pat) | ||
311 | if !first_param_range.contains_range(pat.syntax().text_range()) => | ||
312 | { | ||
313 | bail!("Only the first parameter can be self"); | ||
314 | } | ||
315 | _ => (), | ||
308 | } | 316 | } |
309 | 317 | ||
310 | let impl_block = find_node_at_offset::<ast::Impl>(syn, position.offset) | 318 | let impl_block = fn_ast |
319 | .syntax() | ||
320 | .ancestors() | ||
321 | .find_map(|node| ast::Impl::cast(node)) | ||
311 | .and_then(|def| sema.to_def(&def)) | 322 | .and_then(|def| sema.to_def(&def)) |
312 | .ok_or_else(|| format_err!("No impl block found for function"))?; | 323 | .ok_or_else(|| format_err!("No impl block found for function"))?; |
313 | if fn_def.self_param(sema.db).is_some() { | 324 | if fn_def.self_param(sema.db).is_some() { |
@@ -331,25 +342,21 @@ fn rename_to_self( | |||
331 | bail!("Parameter type differs from impl block type"); | 342 | bail!("Parameter type differs from impl block type"); |
332 | } | 343 | } |
333 | 344 | ||
334 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; | 345 | let def = Definition::Local(local); |
335 | 346 | let usages = def.usages(sema).all(); | |
336 | let mut source_change = SourceChange::default(); | 347 | let mut source_change = SourceChange::default(); |
337 | source_change.extend(refs.references().iter().map(|(&file_id, references)| { | 348 | source_change.extend(usages.iter().map(|(&file_id, references)| { |
338 | source_edit_from_references(sema, file_id, references, "self") | 349 | source_edit_from_references(sema, file_id, references, "self") |
339 | })); | 350 | })); |
340 | source_change.insert_source_edit( | 351 | source_change.insert_source_edit( |
341 | position.file_id, | 352 | file_id.original_file(sema.db), |
342 | TextEdit::replace(param_range, String::from(self_param)), | 353 | TextEdit::replace(first_param_range, String::from(self_param)), |
343 | ); | 354 | ); |
344 | 355 | ||
345 | Ok(RangeInfo::new(range, source_change)) | 356 | Ok(source_change) |
346 | } | 357 | } |
347 | 358 | ||
348 | fn text_edit_from_self_param( | 359 | fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Option<TextEdit> { |
349 | syn: &SyntaxNode, | ||
350 | self_param: &ast::SelfParam, | ||
351 | new_name: &str, | ||
352 | ) -> Option<TextEdit> { | ||
353 | fn target_type_name(impl_def: &ast::Impl) -> Option<String> { | 360 | fn target_type_name(impl_def: &ast::Impl) -> Option<String> { |
354 | if let Some(ast::Type::PathType(p)) = impl_def.self_ty() { | 361 | if let Some(ast::Type::PathType(p)) = impl_def.self_ty() { |
355 | return Some(p.path()?.segment()?.name_ref()?.text().to_string()); | 362 | return Some(p.path()?.segment()?.name_ref()?.text().to_string()); |
@@ -357,7 +364,7 @@ fn text_edit_from_self_param( | |||
357 | None | 364 | None |
358 | } | 365 | } |
359 | 366 | ||
360 | let impl_def = find_node_at_offset::<ast::Impl>(syn, self_param.syntax().text_range().start())?; | 367 | let impl_def = self_param.syntax().ancestors().find_map(|it| ast::Impl::cast(it))?; |
361 | let type_name = target_type_name(&impl_def)?; | 368 | let type_name = target_type_name(&impl_def)?; |
362 | 369 | ||
363 | let mut replacement_text = String::from(new_name); | 370 | let mut replacement_text = String::from(new_name); |
@@ -374,96 +381,119 @@ fn text_edit_from_self_param( | |||
374 | 381 | ||
375 | fn rename_self_to_param( | 382 | fn rename_self_to_param( |
376 | sema: &Semantics<RootDatabase>, | 383 | sema: &Semantics<RootDatabase>, |
377 | position: FilePosition, | 384 | local: hir::Local, |
378 | self_token: SyntaxToken, | ||
379 | new_name: &str, | 385 | new_name: &str, |
380 | ) -> Result<RangeInfo<SourceChange>, RenameError> { | 386 | identifier_kind: IdentifierKind, |
381 | let ident_kind = check_identifier(new_name)?; | 387 | ) -> RenameResult<SourceChange> { |
382 | match ident_kind { | 388 | let (file_id, self_param) = match local.source(sema.db) { |
383 | IdentifierKind::Lifetime => bail!("Invalid name `{}`: not an identifier", new_name), | 389 | InFile { file_id, value: Either::Right(self_param) } => (file_id, self_param), |
384 | IdentifierKind::ToSelf => { | 390 | _ => { |
385 | // no-op | 391 | assert_never!(true, "rename_self_to_param invoked on a non-self local"); |
386 | mark::hit!(rename_self_to_self); | 392 | bail!("rename_self_to_param invoked on a non-self local"); |
387 | return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default())); | ||
388 | } | ||
389 | _ => (), | ||
390 | } | ||
391 | let source_file = sema.parse(position.file_id); | ||
392 | let syn = source_file.syntax(); | ||
393 | |||
394 | let text = sema.db.file_text(position.file_id); | ||
395 | let fn_def = find_node_at_offset::<ast::Fn>(syn, position.offset) | ||
396 | .ok_or_else(|| format_err!("No surrounding method declaration found"))?; | ||
397 | let search_range = fn_def.syntax().text_range(); | ||
398 | |||
399 | let mut source_change = SourceChange::default(); | ||
400 | |||
401 | for (idx, _) in text.match_indices("self") { | ||
402 | let offset: TextSize = idx.try_into().unwrap(); | ||
403 | if !search_range.contains_inclusive(offset) { | ||
404 | continue; | ||
405 | } | 393 | } |
406 | if let Some(ref usage) = syn.token_at_offset(offset).find(|t| t.kind() == T![self]) { | 394 | }; |
407 | let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) { | ||
408 | text_edit_from_self_param(syn, self_param, new_name) | ||
409 | .ok_or_else(|| format_err!("No target type found"))? | ||
410 | } else { | ||
411 | TextEdit::replace(usage.text_range(), String::from(new_name)) | ||
412 | }; | ||
413 | source_change.insert_source_edit(position.file_id, edit); | ||
414 | } | ||
415 | } | ||
416 | 395 | ||
417 | if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore { | 396 | let def = Definition::Local(local); |
397 | let usages = def.usages(sema).all(); | ||
398 | let edit = text_edit_from_self_param(&self_param, new_name) | ||
399 | .ok_or_else(|| format_err!("No target type found"))?; | ||
400 | if usages.len() > 1 && identifier_kind == IdentifierKind::Underscore { | ||
418 | bail!("Cannot rename reference to `_` as it is being referenced multiple times"); | 401 | bail!("Cannot rename reference to `_` as it is being referenced multiple times"); |
419 | } | 402 | } |
420 | 403 | let mut source_change = SourceChange::default(); | |
421 | let range = ast::SelfParam::cast(self_token.parent()) | 404 | source_change.insert_source_edit(file_id.original_file(sema.db), edit); |
422 | .map_or(self_token.text_range(), |p| p.syntax().text_range()); | 405 | source_change.extend(usages.iter().map(|(&file_id, references)| { |
423 | 406 | source_edit_from_references(sema, file_id, &references, new_name) | |
424 | Ok(RangeInfo::new(range, source_change)) | 407 | })); |
408 | Ok(source_change) | ||
425 | } | 409 | } |
426 | 410 | ||
427 | fn rename_reference( | 411 | fn rename_reference( |
428 | sema: &Semantics<RootDatabase>, | 412 | sema: &Semantics<RootDatabase>, |
429 | position: FilePosition, | 413 | def: Definition, |
430 | new_name: &str, | 414 | new_name: &str, |
431 | ) -> Result<RangeInfo<SourceChange>, RenameError> { | 415 | ) -> RenameResult<SourceChange> { |
432 | let ident_kind = check_identifier(new_name)?; | 416 | let ident_kind = check_identifier(new_name)?; |
433 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; | ||
434 | 417 | ||
435 | match (ident_kind, &refs.declaration.kind) { | 418 | let def_is_lbl_or_lt = matches!(def, |
436 | (IdentifierKind::ToSelf, ReferenceKind::Lifetime) | 419 | Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) |
437 | | (IdentifierKind::Underscore, ReferenceKind::Lifetime) | 420 | | Definition::Label(_) |
438 | | (IdentifierKind::Ident, ReferenceKind::Lifetime) => { | 421 | ); |
422 | match (ident_kind, def) { | ||
423 | (IdentifierKind::ToSelf, _) | ||
424 | | (IdentifierKind::Underscore, _) | ||
425 | | (IdentifierKind::Ident, _) | ||
426 | if def_is_lbl_or_lt => | ||
427 | { | ||
439 | mark::hit!(rename_not_a_lifetime_ident_ref); | 428 | mark::hit!(rename_not_a_lifetime_ident_ref); |
440 | bail!("Invalid name `{}`: not a lifetime identifier", new_name) | 429 | bail!("Invalid name `{}`: not a lifetime identifier", new_name) |
441 | } | 430 | } |
442 | (IdentifierKind::Lifetime, ReferenceKind::Lifetime) => mark::hit!(rename_lifetime), | 431 | (IdentifierKind::Lifetime, _) if def_is_lbl_or_lt => mark::hit!(rename_lifetime), |
443 | (IdentifierKind::Lifetime, _) => { | 432 | (IdentifierKind::Lifetime, _) => { |
444 | mark::hit!(rename_not_an_ident_ref); | 433 | mark::hit!(rename_not_an_ident_ref); |
445 | bail!("Invalid name `{}`: not an identifier", new_name) | 434 | bail!("Invalid name `{}`: not an identifier", new_name) |
446 | } | 435 | } |
447 | (IdentifierKind::ToSelf, ReferenceKind::SelfParam) => { | 436 | (IdentifierKind::ToSelf, Definition::Local(local)) if local.is_self(sema.db) => { |
448 | unreachable!("rename_self_to_param should've been called instead") | 437 | // no-op |
438 | mark::hit!(rename_self_to_self); | ||
439 | return Ok(SourceChange::default()); | ||
449 | } | 440 | } |
450 | (IdentifierKind::ToSelf, _) => { | 441 | (ident_kind, Definition::Local(local)) if local.is_self(sema.db) => { |
451 | mark::hit!(rename_to_self); | 442 | mark::hit!(rename_self_to_param); |
452 | return rename_to_self(sema, position); | 443 | return rename_self_to_param(sema, local, new_name, ident_kind); |
453 | } | 444 | } |
454 | (IdentifierKind::Underscore, _) if !refs.references.is_empty() => { | 445 | (IdentifierKind::ToSelf, Definition::Local(local)) => { |
455 | mark::hit!(rename_underscore_multiple); | 446 | mark::hit!(rename_to_self); |
456 | bail!("Cannot rename reference to `_` as it is being referenced multiple times") | 447 | return rename_to_self(sema, local); |
457 | } | 448 | } |
449 | (IdentifierKind::ToSelf, _) => bail!("Invalid name `{}`: not an identifier", new_name), | ||
458 | (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident), | 450 | (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident), |
459 | } | 451 | } |
460 | 452 | ||
453 | let usages = def.usages(sema).all(); | ||
454 | if !usages.is_empty() && ident_kind == IdentifierKind::Underscore { | ||
455 | mark::hit!(rename_underscore_multiple); | ||
456 | bail!("Cannot rename reference to `_` as it is being referenced multiple times"); | ||
457 | } | ||
461 | let mut source_change = SourceChange::default(); | 458 | let mut source_change = SourceChange::default(); |
462 | source_change.extend(refs.into_iter().map(|(file_id, references)| { | 459 | source_change.extend(usages.iter().map(|(&file_id, references)| { |
463 | source_edit_from_references(sema, file_id, &references, new_name) | 460 | source_edit_from_references(sema, file_id, &references, new_name) |
464 | })); | 461 | })); |
465 | 462 | ||
466 | Ok(RangeInfo::new(range, source_change)) | 463 | let (file_id, edit) = source_edit_from_def(sema, def, new_name)?; |
464 | source_change.insert_source_edit(file_id, edit); | ||
465 | Ok(source_change) | ||
466 | } | ||
467 | |||
468 | fn source_edit_from_def( | ||
469 | sema: &Semantics<RootDatabase>, | ||
470 | def: Definition, | ||
471 | new_name: &str, | ||
472 | ) -> RenameResult<(FileId, TextEdit)> { | ||
473 | let nav = def.try_to_nav(sema.db).unwrap(); | ||
474 | |||
475 | let mut replacement_text = String::new(); | ||
476 | let mut repl_range = nav.focus_or_full_range(); | ||
477 | if let Definition::Local(local) = def { | ||
478 | if let Either::Left(pat) = local.source(sema.db).value { | ||
479 | if matches!( | ||
480 | pat.syntax().parent().and_then(ast::RecordPatField::cast), | ||
481 | Some(pat_field) if pat_field.name_ref().is_none() | ||
482 | ) { | ||
483 | replacement_text.push_str(": "); | ||
484 | replacement_text.push_str(new_name); | ||
485 | repl_range = TextRange::new( | ||
486 | pat.syntax().text_range().end(), | ||
487 | pat.syntax().text_range().end(), | ||
488 | ); | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | if replacement_text.is_empty() { | ||
493 | replacement_text.push_str(new_name); | ||
494 | } | ||
495 | let edit = TextEdit::replace(repl_range, replacement_text); | ||
496 | Ok((nav.file_id, edit)) | ||
467 | } | 497 | } |
468 | 498 | ||
469 | #[cfg(test)] | 499 | #[cfg(test)] |
@@ -485,7 +515,7 @@ mod tests { | |||
485 | Ok(source_change) => { | 515 | Ok(source_change) => { |
486 | let mut text_edit_builder = TextEdit::builder(); | 516 | let mut text_edit_builder = TextEdit::builder(); |
487 | let mut file_id: Option<FileId> = None; | 517 | let mut file_id: Option<FileId> = None; |
488 | for edit in source_change.info.source_file_edits { | 518 | for edit in source_change.source_file_edits { |
489 | file_id = Some(edit.0); | 519 | file_id = Some(edit.0); |
490 | for indel in edit.1.into_iter() { | 520 | for indel in edit.1.into_iter() { |
491 | text_edit_builder.replace(indel.delete, indel.insert); | 521 | text_edit_builder.replace(indel.delete, indel.insert); |
@@ -884,36 +914,33 @@ mod foo$0; | |||
884 | // empty | 914 | // empty |
885 | "#, | 915 | "#, |
886 | expect![[r#" | 916 | expect![[r#" |
887 | RangeInfo { | 917 | SourceChange { |
888 | range: 4..7, | 918 | source_file_edits: { |
889 | info: SourceChange { | 919 | FileId( |
890 | source_file_edits: { | 920 | 1, |
891 | FileId( | 921 | ): TextEdit { |
892 | 1, | 922 | indels: [ |
893 | ): TextEdit { | 923 | Indel { |
894 | indels: [ | 924 | insert: "foo2", |
895 | Indel { | 925 | delete: 4..7, |
896 | insert: "foo2", | 926 | }, |
897 | delete: 4..7, | 927 | ], |
898 | }, | ||
899 | ], | ||
900 | }, | ||
901 | }, | 928 | }, |
902 | file_system_edits: [ | 929 | }, |
903 | MoveFile { | 930 | file_system_edits: [ |
904 | src: FileId( | 931 | MoveFile { |
932 | src: FileId( | ||
933 | 2, | ||
934 | ), | ||
935 | dst: AnchoredPathBuf { | ||
936 | anchor: FileId( | ||
905 | 2, | 937 | 2, |
906 | ), | 938 | ), |
907 | dst: AnchoredPathBuf { | 939 | path: "foo2.rs", |
908 | anchor: FileId( | ||
909 | 2, | ||
910 | ), | ||
911 | path: "foo2.rs", | ||
912 | }, | ||
913 | }, | 940 | }, |
914 | ], | 941 | }, |
915 | is_snippet: false, | 942 | ], |
916 | }, | 943 | is_snippet: false, |
917 | } | 944 | } |
918 | "#]], | 945 | "#]], |
919 | ); | 946 | ); |
@@ -936,46 +963,43 @@ pub struct FooContent; | |||
936 | use crate::foo$0::FooContent; | 963 | use crate::foo$0::FooContent; |
937 | "#, | 964 | "#, |
938 | expect![[r#" | 965 | expect![[r#" |
939 | RangeInfo { | 966 | SourceChange { |
940 | range: 11..14, | 967 | source_file_edits: { |
941 | info: SourceChange { | 968 | FileId( |
942 | source_file_edits: { | 969 | 0, |
943 | FileId( | 970 | ): TextEdit { |
944 | 0, | 971 | indels: [ |
945 | ): TextEdit { | 972 | Indel { |
946 | indels: [ | 973 | insert: "quux", |
947 | Indel { | 974 | delete: 8..11, |
948 | insert: "quux", | 975 | }, |
949 | delete: 8..11, | 976 | ], |
950 | }, | 977 | }, |
951 | ], | 978 | FileId( |
952 | }, | 979 | 2, |
953 | FileId( | 980 | ): TextEdit { |
954 | 2, | 981 | indels: [ |
955 | ): TextEdit { | 982 | Indel { |
956 | indels: [ | 983 | insert: "quux", |
957 | Indel { | 984 | delete: 11..14, |
958 | insert: "quux", | 985 | }, |
959 | delete: 11..14, | 986 | ], |
960 | }, | ||
961 | ], | ||
962 | }, | ||
963 | }, | 987 | }, |
964 | file_system_edits: [ | 988 | }, |
965 | MoveFile { | 989 | file_system_edits: [ |
966 | src: FileId( | 990 | MoveFile { |
991 | src: FileId( | ||
992 | 1, | ||
993 | ), | ||
994 | dst: AnchoredPathBuf { | ||
995 | anchor: FileId( | ||
967 | 1, | 996 | 1, |
968 | ), | 997 | ), |
969 | dst: AnchoredPathBuf { | 998 | path: "quux.rs", |
970 | anchor: FileId( | ||
971 | 1, | ||
972 | ), | ||
973 | path: "quux.rs", | ||
974 | }, | ||
975 | }, | 999 | }, |
976 | ], | 1000 | }, |
977 | is_snippet: false, | 1001 | ], |
978 | }, | 1002 | is_snippet: false, |
979 | } | 1003 | } |
980 | "#]], | 1004 | "#]], |
981 | ); | 1005 | ); |
@@ -992,36 +1016,33 @@ mod fo$0o; | |||
992 | // empty | 1016 | // empty |
993 | "#, | 1017 | "#, |
994 | expect![[r#" | 1018 | expect![[r#" |
995 | RangeInfo { | 1019 | SourceChange { |
996 | range: 4..7, | 1020 | source_file_edits: { |
997 | info: SourceChange { | 1021 | FileId( |
998 | source_file_edits: { | 1022 | 0, |
999 | FileId( | 1023 | ): TextEdit { |
1000 | 0, | 1024 | indels: [ |
1001 | ): TextEdit { | 1025 | Indel { |
1002 | indels: [ | 1026 | insert: "foo2", |
1003 | Indel { | 1027 | delete: 4..7, |
1004 | insert: "foo2", | 1028 | }, |
1005 | delete: 4..7, | 1029 | ], |
1006 | }, | ||
1007 | ], | ||
1008 | }, | ||
1009 | }, | 1030 | }, |
1010 | file_system_edits: [ | 1031 | }, |
1011 | MoveFile { | 1032 | file_system_edits: [ |
1012 | src: FileId( | 1033 | MoveFile { |
1034 | src: FileId( | ||
1035 | 1, | ||
1036 | ), | ||
1037 | dst: AnchoredPathBuf { | ||
1038 | anchor: FileId( | ||
1013 | 1, | 1039 | 1, |
1014 | ), | 1040 | ), |
1015 | dst: AnchoredPathBuf { | 1041 | path: "../foo2/mod.rs", |
1016 | anchor: FileId( | ||
1017 | 1, | ||
1018 | ), | ||
1019 | path: "../foo2/mod.rs", | ||
1020 | }, | ||
1021 | }, | 1042 | }, |
1022 | ], | 1043 | }, |
1023 | is_snippet: false, | 1044 | ], |
1024 | }, | 1045 | is_snippet: false, |
1025 | } | 1046 | } |
1026 | "#]], | 1047 | "#]], |
1027 | ); | 1048 | ); |
@@ -1039,36 +1060,33 @@ mod outer { mod fo$0o; } | |||
1039 | // empty | 1060 | // empty |
1040 | "#, | 1061 | "#, |
1041 | expect![[r#" | 1062 | expect![[r#" |
1042 | RangeInfo { | 1063 | SourceChange { |
1043 | range: 16..19, | 1064 | source_file_edits: { |
1044 | info: SourceChange { | 1065 | FileId( |
1045 | source_file_edits: { | 1066 | 0, |
1046 | FileId( | 1067 | ): TextEdit { |
1047 | 0, | 1068 | indels: [ |
1048 | ): TextEdit { | 1069 | Indel { |
1049 | indels: [ | 1070 | insert: "bar", |
1050 | Indel { | 1071 | delete: 16..19, |
1051 | insert: "bar", | 1072 | }, |
1052 | delete: 16..19, | 1073 | ], |
1053 | }, | ||
1054 | ], | ||
1055 | }, | ||
1056 | }, | 1074 | }, |
1057 | file_system_edits: [ | 1075 | }, |
1058 | MoveFile { | 1076 | file_system_edits: [ |
1059 | src: FileId( | 1077 | MoveFile { |
1078 | src: FileId( | ||
1079 | 1, | ||
1080 | ), | ||
1081 | dst: AnchoredPathBuf { | ||
1082 | anchor: FileId( | ||
1060 | 1, | 1083 | 1, |
1061 | ), | 1084 | ), |
1062 | dst: AnchoredPathBuf { | 1085 | path: "bar.rs", |
1063 | anchor: FileId( | ||
1064 | 1, | ||
1065 | ), | ||
1066 | path: "bar.rs", | ||
1067 | }, | ||
1068 | }, | 1086 | }, |
1069 | ], | 1087 | }, |
1070 | is_snippet: false, | 1088 | ], |
1071 | }, | 1089 | is_snippet: false, |
1072 | } | 1090 | } |
1073 | "#]], | 1091 | "#]], |
1074 | ); | 1092 | ); |
@@ -1109,46 +1127,43 @@ pub mod foo$0; | |||
1109 | // pub fn fun() {} | 1127 | // pub fn fun() {} |
1110 | "#, | 1128 | "#, |
1111 | expect![[r#" | 1129 | expect![[r#" |
1112 | RangeInfo { | 1130 | SourceChange { |
1113 | range: 8..11, | 1131 | source_file_edits: { |
1114 | info: SourceChange { | 1132 | FileId( |
1115 | source_file_edits: { | 1133 | 0, |
1116 | FileId( | 1134 | ): TextEdit { |
1117 | 0, | 1135 | indels: [ |
1118 | ): TextEdit { | 1136 | Indel { |
1119 | indels: [ | 1137 | insert: "foo2", |
1120 | Indel { | 1138 | delete: 27..30, |
1121 | insert: "foo2", | 1139 | }, |
1122 | delete: 27..30, | 1140 | ], |
1123 | }, | ||
1124 | ], | ||
1125 | }, | ||
1126 | FileId( | ||
1127 | 1, | ||
1128 | ): TextEdit { | ||
1129 | indels: [ | ||
1130 | Indel { | ||
1131 | insert: "foo2", | ||
1132 | delete: 8..11, | ||
1133 | }, | ||
1134 | ], | ||
1135 | }, | ||
1136 | }, | 1141 | }, |
1137 | file_system_edits: [ | 1142 | FileId( |
1138 | MoveFile { | 1143 | 1, |
1139 | src: FileId( | 1144 | ): TextEdit { |
1145 | indels: [ | ||
1146 | Indel { | ||
1147 | insert: "foo2", | ||
1148 | delete: 8..11, | ||
1149 | }, | ||
1150 | ], | ||
1151 | }, | ||
1152 | }, | ||
1153 | file_system_edits: [ | ||
1154 | MoveFile { | ||
1155 | src: FileId( | ||
1156 | 2, | ||
1157 | ), | ||
1158 | dst: AnchoredPathBuf { | ||
1159 | anchor: FileId( | ||
1140 | 2, | 1160 | 2, |
1141 | ), | 1161 | ), |
1142 | dst: AnchoredPathBuf { | 1162 | path: "foo2.rs", |
1143 | anchor: FileId( | ||
1144 | 2, | ||
1145 | ), | ||
1146 | path: "foo2.rs", | ||
1147 | }, | ||
1148 | }, | 1163 | }, |
1149 | ], | 1164 | }, |
1150 | is_snippet: false, | 1165 | ], |
1151 | }, | 1166 | is_snippet: false, |
1152 | } | 1167 | } |
1153 | "#]], | 1168 | "#]], |
1154 | ); | 1169 | ); |
@@ -1350,6 +1365,7 @@ impl Foo { | |||
1350 | 1365 | ||
1351 | #[test] | 1366 | #[test] |
1352 | fn test_owned_self_to_parameter() { | 1367 | fn test_owned_self_to_parameter() { |
1368 | mark::check!(rename_self_to_param); | ||
1353 | check( | 1369 | check( |
1354 | "foo", | 1370 | "foo", |
1355 | r#" | 1371 | r#" |
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 87578e70a..8625ef5df 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs | |||
@@ -68,7 +68,8 @@ pub(super) fn element( | |||
68 | NAME_REF => { | 68 | NAME_REF => { |
69 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 69 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
70 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { | 70 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { |
71 | match NameRefClass::classify(sema, &name_ref) { | 71 | let is_self = name_ref.self_token().is_some(); |
72 | let h = match NameRefClass::classify(sema, &name_ref) { | ||
72 | Some(name_kind) => match name_kind { | 73 | Some(name_kind) => match name_kind { |
73 | NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(), | 74 | NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(), |
74 | NameRefClass::Definition(def) => { | 75 | NameRefClass::Definition(def) => { |
@@ -108,6 +109,11 @@ pub(super) fn element( | |||
108 | highlight_name_ref_by_syntax(name_ref, sema) | 109 | highlight_name_ref_by_syntax(name_ref, sema) |
109 | } | 110 | } |
110 | None => HlTag::UnresolvedReference.into(), | 111 | None => HlTag::UnresolvedReference.into(), |
112 | }; | ||
113 | if h.tag == HlTag::Symbol(SymbolKind::Module) && is_self { | ||
114 | HlTag::Symbol(SymbolKind::SelfParam).into() | ||
115 | } else { | ||
116 | h | ||
111 | } | 117 | } |
112 | }) | 118 | }) |
113 | } | 119 | } |
@@ -225,18 +231,8 @@ pub(super) fn element( | |||
225 | T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow, | 231 | T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow, |
226 | T![unsafe] => h | HlMod::Unsafe, | 232 | T![unsafe] => h | HlMod::Unsafe, |
227 | T![true] | T![false] => HlTag::BoolLiteral.into(), | 233 | T![true] | T![false] => HlTag::BoolLiteral.into(), |
228 | T![self] => { | 234 | // self is handled as either a Name or NameRef already |
229 | let self_param = element.parent().and_then(ast::SelfParam::cast); | 235 | T![self] => return None, |
230 | if let Some(NameClass::Definition(def)) = self_param | ||
231 | .and_then(|self_param| NameClass::classify_self_param(sema, &self_param)) | ||
232 | { | ||
233 | highlight_def(db, def) | HlMod::Definition | ||
234 | } else if element.ancestors().any(|it| it.kind() == USE_TREE) { | ||
235 | HlTag::Symbol(SymbolKind::SelfParam).into() | ||
236 | } else { | ||
237 | return None; | ||
238 | } | ||
239 | } | ||
240 | T![ref] => element | 236 | T![ref] => element |
241 | .parent() | 237 | .parent() |
242 | .and_then(ast::IdentPat::cast) | 238 | .and_then(ast::IdentPat::cast) |
diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs index 1d4bac7ad..4c63d3023 100644 --- a/crates/ide/src/syntax_tree.rs +++ b/crates/ide/src/syntax_tree.rs | |||
@@ -111,7 +111,6 @@ mod tests { | |||
111 | let syn = analysis.syntax_tree(file_id, None).unwrap(); | 111 | let syn = analysis.syntax_tree(file_id, None).unwrap(); |
112 | 112 | ||
113 | assert_eq_text!( | 113 | assert_eq_text!( |
114 | syn.trim(), | ||
115 | r#" | 114 | r#" |
116 | [email protected] | 115 | [email protected] |
117 | [email protected] | 116 | [email protected] |
@@ -127,7 +126,8 @@ [email protected] | |||
127 | [email protected] "{" | 126 | [email protected] "{" |
128 | [email protected] "}" | 127 | [email protected] "}" |
129 | "# | 128 | "# |
130 | .trim() | 129 | .trim(), |
130 | syn.trim() | ||
131 | ); | 131 | ); |
132 | 132 | ||
133 | let (analysis, file_id) = fixture::file( | 133 | let (analysis, file_id) = fixture::file( |
@@ -143,7 +143,6 @@ fn test() { | |||
143 | let syn = analysis.syntax_tree(file_id, None).unwrap(); | 143 | let syn = analysis.syntax_tree(file_id, None).unwrap(); |
144 | 144 | ||
145 | assert_eq_text!( | 145 | assert_eq_text!( |
146 | syn.trim(), | ||
147 | r#" | 146 | r#" |
148 | [email protected] | 147 | [email protected] |
149 | [email protected] | 148 | [email protected] |
@@ -176,7 +175,8 @@ [email protected] | |||
176 | [email protected] "\n" | 175 | [email protected] "\n" |
177 | [email protected] "}" | 176 | [email protected] "}" |
178 | "# | 177 | "# |
179 | .trim() | 178 | .trim(), |
179 | syn.trim() | ||
180 | ); | 180 | ); |
181 | } | 181 | } |
182 | 182 | ||
@@ -186,7 +186,6 @@ [email protected] | |||
186 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); | 186 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); |
187 | 187 | ||
188 | assert_eq_text!( | 188 | assert_eq_text!( |
189 | syn.trim(), | ||
190 | r#" | 189 | r#" |
191 | [email protected] | 190 | [email protected] |
192 | [email protected] "fn" | 191 | [email protected] "fn" |
@@ -201,7 +200,8 @@ [email protected] | |||
201 | [email protected] "{" | 200 | [email protected] "{" |
202 | [email protected] "}" | 201 | [email protected] "}" |
203 | "# | 202 | "# |
204 | .trim() | 203 | .trim(), |
204 | syn.trim() | ||
205 | ); | 205 | ); |
206 | 206 | ||
207 | let (analysis, range) = fixture::range( | 207 | let (analysis, range) = fixture::range( |
@@ -216,7 +216,6 @@ [email protected] | |||
216 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); | 216 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); |
217 | 217 | ||
218 | assert_eq_text!( | 218 | assert_eq_text!( |
219 | syn.trim(), | ||
220 | r#" | 219 | r#" |
221 | [email protected] | 220 | [email protected] |
222 | [email protected] | 221 | [email protected] |
@@ -234,7 +233,8 @@ [email protected] | |||
234 | [email protected] ")" | 233 | [email protected] ")" |
235 | [email protected] ";" | 234 | [email protected] ";" |
236 | "# | 235 | "# |
237 | .trim() | 236 | .trim(), |
237 | syn.trim() | ||
238 | ); | 238 | ); |
239 | } | 239 | } |
240 | 240 | ||
@@ -253,7 +253,6 @@ fn bar() { | |||
253 | ); | 253 | ); |
254 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); | 254 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); |
255 | assert_eq_text!( | 255 | assert_eq_text!( |
256 | syn.trim(), | ||
257 | r#" | 256 | r#" |
258 | [email protected] | 257 | [email protected] |
259 | [email protected] | 258 | [email protected] |
@@ -270,7 +269,8 @@ [email protected] | |||
270 | [email protected] "\n" | 269 | [email protected] "\n" |
271 | [email protected] "}" | 270 | [email protected] "}" |
272 | "# | 271 | "# |
273 | .trim() | 272 | .trim(), |
273 | syn.trim() | ||
274 | ); | 274 | ); |
275 | 275 | ||
276 | // With a raw string | 276 | // With a raw string |
@@ -287,7 +287,6 @@ fn bar() { | |||
287 | ); | 287 | ); |
288 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); | 288 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); |
289 | assert_eq_text!( | 289 | assert_eq_text!( |
290 | syn.trim(), | ||
291 | r#" | 290 | r#" |
292 | [email protected] | 291 | [email protected] |
293 | [email protected] | 292 | [email protected] |
@@ -304,7 +303,8 @@ [email protected] | |||
304 | [email protected] "\n" | 303 | [email protected] "\n" |
305 | [email protected] "}" | 304 | [email protected] "}" |
306 | "# | 305 | "# |
307 | .trim() | 306 | .trim(), |
307 | syn.trim() | ||
308 | ); | 308 | ); |
309 | 309 | ||
310 | // With a raw string | 310 | // With a raw string |
@@ -320,7 +320,6 @@ fn bar() { | |||
320 | ); | 320 | ); |
321 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); | 321 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); |
322 | assert_eq_text!( | 322 | assert_eq_text!( |
323 | syn.trim(), | ||
324 | r#" | 323 | r#" |
325 | [email protected] | 324 | [email protected] |
326 | [email protected] | 325 | [email protected] |
@@ -351,7 +350,8 @@ [email protected] | |||
351 | [email protected] "\n" | 350 | [email protected] "\n" |
352 | [email protected] "}" | 351 | [email protected] "}" |
353 | "# | 352 | "# |
354 | .trim() | 353 | .trim(), |
354 | syn.trim() | ||
355 | ); | 355 | ); |
356 | } | 356 | } |
357 | } | 357 | } |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index 231e886a9..d9875ffef 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -117,13 +117,6 @@ impl NameClass { | |||
117 | } | 117 | } |
118 | } | 118 | } |
119 | 119 | ||
120 | pub fn classify_self_param( | ||
121 | sema: &Semantics<RootDatabase>, | ||
122 | self_param: &ast::SelfParam, | ||
123 | ) -> Option<NameClass> { | ||
124 | sema.to_def(self_param).map(Definition::Local).map(NameClass::Definition) | ||
125 | } | ||
126 | |||
127 | pub fn classify(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { | 120 | pub fn classify(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { |
128 | let _p = profile::span("classify_name"); | 121 | let _p = profile::span("classify_name"); |
129 | 122 | ||
@@ -186,6 +179,10 @@ impl NameClass { | |||
186 | 179 | ||
187 | Some(NameClass::Definition(Definition::Local(local))) | 180 | Some(NameClass::Definition(Definition::Local(local))) |
188 | }, | 181 | }, |
182 | ast::SelfParam(it) => { | ||
183 | let def = sema.to_def(&it)?; | ||
184 | Some(NameClass::Definition(Definition::Local(def.into()))) | ||
185 | }, | ||
189 | ast::RecordField(it) => { | 186 | ast::RecordField(it) => { |
190 | let field: hir::Field = sema.to_def(&it)?; | 187 | let field: hir::Field = sema.to_def(&it)?; |
191 | Some(NameClass::Definition(Definition::Field(field))) | 188 | Some(NameClass::Definition(Definition::Field(field))) |
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index a603fe87f..4bbe66f1f 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs | |||
@@ -599,7 +599,7 @@ fn check( | |||
599 | 599 | ||
600 | let rewriter = insert_use(&file, path, mb); | 600 | let rewriter = insert_use(&file, path, mb); |
601 | let result = rewriter.rewrite(file.as_syntax_node()).to_string(); | 601 | let result = rewriter.rewrite(file.as_syntax_node()).to_string(); |
602 | assert_eq_text!(&result, ra_fixture_after); | 602 | assert_eq_text!(ra_fixture_after, &result); |
603 | } | 603 | } |
604 | 604 | ||
605 | fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 605 | fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { |
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index e648519f9..2a41d8167 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs | |||
@@ -51,6 +51,7 @@ pub fn syntax_node_to_token_tree(node: &SyntaxNode) -> Option<(tt::Subtree, Toke | |||
51 | let global_offset = node.text_range().start(); | 51 | let global_offset = node.text_range().start(); |
52 | let mut c = Convertor::new(node, global_offset); | 52 | let mut c = Convertor::new(node, global_offset); |
53 | let subtree = c.go()?; | 53 | let subtree = c.go()?; |
54 | c.id_alloc.map.entries.shrink_to_fit(); | ||
54 | Some((subtree, c.id_alloc.map)) | 55 | Some((subtree, c.id_alloc.map)) |
55 | } | 56 | } |
56 | 57 | ||
@@ -593,7 +594,8 @@ impl<'a> TtTreeSink<'a> { | |||
593 | } | 594 | } |
594 | } | 595 | } |
595 | 596 | ||
596 | fn finish(self) -> (Parse<SyntaxNode>, TokenMap) { | 597 | fn finish(mut self) -> (Parse<SyntaxNode>, TokenMap) { |
598 | self.token_map.entries.shrink_to_fit(); | ||
597 | (self.inner.finish(), self.token_map) | 599 | (self.inner.finish(), self.token_map) |
598 | } | 600 | } |
599 | } | 601 | } |
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs index 9ff901e97..bd2977ebd 100644 --- a/crates/mbe/src/tests.rs +++ b/crates/mbe/src/tests.rs | |||
@@ -261,7 +261,6 @@ fn test_expr_order() { | |||
261 | 261 | ||
262 | let dump = format!("{:#?}", expanded); | 262 | let dump = format!("{:#?}", expanded); |
263 | assert_eq_text!( | 263 | assert_eq_text!( |
264 | dump.trim(), | ||
265 | r#"[email protected] | 264 | r#"[email protected] |
266 | [email protected] | 265 | [email protected] |
267 | [email protected] "fn" | 266 | [email protected] "fn" |
@@ -285,6 +284,7 @@ fn test_expr_order() { | |||
285 | [email protected] "2" | 284 | [email protected] "2" |
286 | [email protected] ";" | 285 | [email protected] ";" |
287 | [email protected] "}""#, | 286 | [email protected] "}""#, |
287 | dump.trim() | ||
288 | ); | 288 | ); |
289 | } | 289 | } |
290 | 290 | ||
@@ -989,7 +989,6 @@ fn test_tt_composite2() { | |||
989 | 989 | ||
990 | let res = format!("{:#?}", &node); | 990 | let res = format!("{:#?}", &node); |
991 | assert_eq_text!( | 991 | assert_eq_text!( |
992 | res.trim(), | ||
993 | r###"[email protected] | 992 | r###"[email protected] |
994 | [email protected] | 993 | [email protected] |
995 | [email protected] | 994 | [email protected] |
@@ -1003,7 +1002,8 @@ fn test_tt_composite2() { | |||
1003 | [email protected] ">" | 1002 | [email protected] ">" |
1004 | [email protected] " " | 1003 | [email protected] " " |
1005 | [email protected] "#" | 1004 | [email protected] "#" |
1006 | [email protected] ")""### | 1005 | [email protected] ")""###, |
1006 | res.trim() | ||
1007 | ); | 1007 | ); |
1008 | } | 1008 | } |
1009 | 1009 | ||
@@ -1742,7 +1742,7 @@ impl MacroFixture { | |||
1742 | fn assert_expand(&self, invocation: &str, expected: &str) { | 1742 | fn assert_expand(&self, invocation: &str, expected: &str) { |
1743 | let expansion = self.expand_tt(invocation); | 1743 | let expansion = self.expand_tt(invocation); |
1744 | let actual = format!("{:?}", expansion); | 1744 | let actual = format!("{:?}", expansion); |
1745 | test_utils::assert_eq_text!(&actual.trim(), &expected.trim()); | 1745 | test_utils::assert_eq_text!(&expected.trim(), &actual.trim()); |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture { | 1748 | fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture { |
@@ -1941,7 +1941,6 @@ fn test_no_space_after_semi_colon() { | |||
1941 | 1941 | ||
1942 | let dump = format!("{:#?}", expanded); | 1942 | let dump = format!("{:#?}", expanded); |
1943 | assert_eq_text!( | 1943 | assert_eq_text!( |
1944 | dump.trim(), | ||
1945 | r###"[email protected] | 1944 | r###"[email protected] |
1946 | [email protected] | 1945 | [email protected] |
1947 | [email protected] | 1946 | [email protected] |
@@ -1981,6 +1980,7 @@ fn test_no_space_after_semi_colon() { | |||
1981 | [email protected] | 1980 | [email protected] |
1982 | [email protected] "f" | 1981 | [email protected] "f" |
1983 | [email protected] ";""###, | 1982 | [email protected] ";""###, |
1983 | dump.trim() | ||
1984 | ); | 1984 | ); |
1985 | } | 1985 | } |
1986 | 1986 | ||
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index bb9ffea8b..6913e9ec2 100644 --- a/crates/parser/src/grammar.rs +++ b/crates/parser/src/grammar.rs | |||
@@ -190,17 +190,25 @@ fn opt_visibility(p: &mut Parser) -> bool { | |||
190 | // test crate_visibility | 190 | // test crate_visibility |
191 | // pub(crate) struct S; | 191 | // pub(crate) struct S; |
192 | // pub(self) struct S; | 192 | // pub(self) struct S; |
193 | // pub(self) struct S; | 193 | // pub(super) struct S; |
194 | // pub(self) struct S; | ||
195 | 194 | ||
196 | // test pub_parens_typepath | 195 | // test pub_parens_typepath |
197 | // struct B(pub (super::A)); | 196 | // struct B(pub (super::A)); |
198 | // struct B(pub (crate::A,)); | 197 | // struct B(pub (crate::A,)); |
199 | T![crate] | T![self] | T![super] if p.nth(2) != T![:] => { | 198 | T![crate] | T![self] | T![super] if p.nth(2) != T![:] => { |
200 | p.bump_any(); | 199 | p.bump_any(); |
200 | let path_m = p.start(); | ||
201 | let path_segment_m = p.start(); | ||
202 | let name_ref_m = p.start(); | ||
201 | p.bump_any(); | 203 | p.bump_any(); |
204 | name_ref_m.complete(p, NAME_REF); | ||
205 | path_segment_m.complete(p, PATH_SEGMENT); | ||
206 | path_m.complete(p, PATH); | ||
202 | p.expect(T![')']); | 207 | p.expect(T![')']); |
203 | } | 208 | } |
209 | // test crate_visibility_in | ||
210 | // pub(in super::A) struct S; | ||
211 | // pub(in crate) struct S; | ||
204 | T![in] => { | 212 | T![in] => { |
205 | p.bump_any(); | 213 | p.bump_any(); |
206 | p.bump_any(); | 214 | p.bump_any(); |
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index 2070ce163..1d894e907 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs | |||
@@ -270,7 +270,9 @@ fn extern_crate(p: &mut Parser, m: Marker) { | |||
270 | p.bump(T![crate]); | 270 | p.bump(T![crate]); |
271 | 271 | ||
272 | if p.at(T![self]) { | 272 | if p.at(T![self]) { |
273 | let m = p.start(); | ||
273 | p.bump(T![self]); | 274 | p.bump(T![self]); |
275 | m.complete(p, NAME_REF); | ||
274 | } else { | 276 | } else { |
275 | name_ref(p); | 277 | name_ref(p); |
276 | } | 278 | } |
diff --git a/crates/parser/src/grammar/items/traits.rs b/crates/parser/src/grammar/items/traits.rs index d076974ed..d3327271c 100644 --- a/crates/parser/src/grammar/items/traits.rs +++ b/crates/parser/src/grammar/items/traits.rs | |||
@@ -40,6 +40,10 @@ pub(super) fn impl_(p: &mut Parser) { | |||
40 | type_params::opt_generic_param_list(p); | 40 | type_params::opt_generic_param_list(p); |
41 | } | 41 | } |
42 | 42 | ||
43 | // test impl_def_const | ||
44 | // impl const Send for X {} | ||
45 | p.eat(T![const]); | ||
46 | |||
43 | // FIXME: never type | 47 | // FIXME: never type |
44 | // impl ! {} | 48 | // impl ! {} |
45 | 49 | ||
diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs index 2d006a1d5..6a98d7368 100644 --- a/crates/parser/src/grammar/params.rs +++ b/crates/parser/src/grammar/params.rs | |||
@@ -156,7 +156,7 @@ fn variadic_param(p: &mut Parser) -> bool { | |||
156 | fn opt_self_param(p: &mut Parser, m: Marker) { | 156 | fn opt_self_param(p: &mut Parser, m: Marker) { |
157 | if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] { | 157 | if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] { |
158 | p.eat(T![mut]); | 158 | p.eat(T![mut]); |
159 | p.eat(T![self]); | 159 | self_as_name(p); |
160 | // test arb_self_types | 160 | // test arb_self_types |
161 | // impl S { | 161 | // impl S { |
162 | // fn a(self: &Self) {} | 162 | // fn a(self: &Self) {} |
@@ -169,24 +169,29 @@ fn opt_self_param(p: &mut Parser, m: Marker) { | |||
169 | let la1 = p.nth(1); | 169 | let la1 = p.nth(1); |
170 | let la2 = p.nth(2); | 170 | let la2 = p.nth(2); |
171 | let la3 = p.nth(3); | 171 | let la3 = p.nth(3); |
172 | let mut n_toks = match (p.current(), la1, la2, la3) { | 172 | if !matches!((p.current(), la1, la2, la3), |
173 | (T![&], T![self], _, _) => 2, | 173 | (T![&], T![self], _, _) |
174 | (T![&], T![mut], T![self], _) => 3, | 174 | | (T![&], T![mut], T![self], _) |
175 | (T![&], LIFETIME_IDENT, T![self], _) => 3, | 175 | | (T![&], LIFETIME_IDENT, T![self], _) |
176 | (T![&], LIFETIME_IDENT, T![mut], T![self]) => 4, | 176 | | (T![&], LIFETIME_IDENT, T![mut], T![self]) |
177 | _ => return m.abandon(p), | 177 | ) { |
178 | }; | 178 | return m.abandon(p); |
179 | p.bump_any(); | 179 | } |
180 | p.bump(T![&]); | ||
180 | if p.at(LIFETIME_IDENT) { | 181 | if p.at(LIFETIME_IDENT) { |
181 | lifetime(p); | 182 | lifetime(p); |
182 | n_toks -= 1; | ||
183 | } | ||
184 | for _ in 1..n_toks { | ||
185 | p.bump_any(); | ||
186 | } | 183 | } |
184 | p.eat(T![mut]); | ||
185 | self_as_name(p); | ||
187 | } | 186 | } |
188 | m.complete(p, SELF_PARAM); | 187 | m.complete(p, SELF_PARAM); |
189 | if !p.at(T![')']) { | 188 | if !p.at(T![')']) { |
190 | p.expect(T![,]); | 189 | p.expect(T![,]); |
191 | } | 190 | } |
192 | } | 191 | } |
192 | |||
193 | fn self_as_name(p: &mut Parser) { | ||
194 | let m = p.start(); | ||
195 | p.bump(T![self]); | ||
196 | m.complete(p, NAME); | ||
197 | } | ||
diff --git a/crates/parser/src/syntax_kind.rs b/crates/parser/src/syntax_kind.rs index 63204436c..9ea0e4f9b 100644 --- a/crates/parser/src/syntax_kind.rs +++ b/crates/parser/src/syntax_kind.rs | |||
@@ -6,6 +6,7 @@ mod generated; | |||
6 | pub use self::generated::SyntaxKind; | 6 | pub use self::generated::SyntaxKind; |
7 | 7 | ||
8 | impl From<u16> for SyntaxKind { | 8 | impl From<u16> for SyntaxKind { |
9 | #[inline] | ||
9 | fn from(d: u16) -> SyntaxKind { | 10 | fn from(d: u16) -> SyntaxKind { |
10 | assert!(d <= (SyntaxKind::__LAST as u16)); | 11 | assert!(d <= (SyntaxKind::__LAST as u16)); |
11 | unsafe { std::mem::transmute::<u16, SyntaxKind>(d) } | 12 | unsafe { std::mem::transmute::<u16, SyntaxKind>(d) } |
@@ -13,12 +14,14 @@ impl From<u16> for SyntaxKind { | |||
13 | } | 14 | } |
14 | 15 | ||
15 | impl From<SyntaxKind> for u16 { | 16 | impl From<SyntaxKind> for u16 { |
17 | #[inline] | ||
16 | fn from(k: SyntaxKind) -> u16 { | 18 | fn from(k: SyntaxKind) -> u16 { |
17 | k as u16 | 19 | k as u16 |
18 | } | 20 | } |
19 | } | 21 | } |
20 | 22 | ||
21 | impl SyntaxKind { | 23 | impl SyntaxKind { |
24 | #[inline] | ||
22 | pub fn is_trivia(self) -> bool { | 25 | pub fn is_trivia(self) -> bool { |
23 | matches!(self, SyntaxKind::WHITESPACE | SyntaxKind::COMMENT) | 26 | matches!(self, SyntaxKind::WHITESPACE | SyntaxKind::COMMENT) |
24 | } | 27 | } |
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index 7d53cc4cd..bcefd183a 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs | |||
@@ -143,6 +143,7 @@ pub enum SyntaxKind { | |||
143 | MACRO_DEF, | 143 | MACRO_DEF, |
144 | PAREN_TYPE, | 144 | PAREN_TYPE, |
145 | TUPLE_TYPE, | 145 | TUPLE_TYPE, |
146 | MACRO_TYPE, | ||
146 | NEVER_TYPE, | 147 | NEVER_TYPE, |
147 | PATH_TYPE, | 148 | PATH_TYPE, |
148 | PTR_TYPE, | 149 | PTR_TYPE, |
diff --git a/crates/proc_macro_api/Cargo.toml b/crates/proc_macro_api/Cargo.toml index 1af2bbca7..078568cb2 100644 --- a/crates/proc_macro_api/Cargo.toml +++ b/crates/proc_macro_api/Cargo.toml | |||
@@ -11,7 +11,7 @@ doctest = false | |||
11 | 11 | ||
12 | [dependencies] | 12 | [dependencies] |
13 | serde = { version = "1.0", features = ["derive"] } | 13 | serde = { version = "1.0", features = ["derive"] } |
14 | serde_json = "1.0" | 14 | serde_json = { version = "1.0", features = ["unbounded_depth"] } |
15 | log = "0.4.8" | 15 | log = "0.4.8" |
16 | crossbeam-channel = "0.5.0" | 16 | crossbeam-channel = "0.5.0" |
17 | jod-thread = "0.1.1" | 17 | jod-thread = "0.1.1" |
diff --git a/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt b/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt index e6fd21610..ea34e688f 100644 --- a/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt +++ b/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt | |||
@@ -59,7 +59,7 @@ SUBTREE $ | |||
59 | IDENT _serde 4294967295 | 59 | IDENT _serde 4294967295 |
60 | PUNCH : [joint] 4294967295 | 60 | PUNCH : [joint] 4294967295 |
61 | PUNCH : [alone] 4294967295 | 61 | PUNCH : [alone] 4294967295 |
62 | IDENT export 4294967295 | 62 | IDENT __private 4294967295 |
63 | PUNCH : [joint] 4294967295 | 63 | PUNCH : [joint] 4294967295 |
64 | PUNCH : [alone] 4294967295 | 64 | PUNCH : [alone] 4294967295 |
65 | IDENT Ok 4294967295 | 65 | IDENT Ok 4294967295 |
@@ -72,7 +72,7 @@ SUBTREE $ | |||
72 | IDENT _serde 4294967295 | 72 | IDENT _serde 4294967295 |
73 | PUNCH : [joint] 4294967295 | 73 | PUNCH : [joint] 4294967295 |
74 | PUNCH : [alone] 4294967295 | 74 | PUNCH : [alone] 4294967295 |
75 | IDENT export 4294967295 | 75 | IDENT __private 4294967295 |
76 | PUNCH : [joint] 4294967295 | 76 | PUNCH : [joint] 4294967295 |
77 | PUNCH : [alone] 4294967295 | 77 | PUNCH : [alone] 4294967295 |
78 | IDENT Err 4294967295 | 78 | IDENT Err 4294967295 |
@@ -85,7 +85,7 @@ SUBTREE $ | |||
85 | IDENT _serde 4294967295 | 85 | IDENT _serde 4294967295 |
86 | PUNCH : [joint] 4294967295 | 86 | PUNCH : [joint] 4294967295 |
87 | PUNCH : [alone] 4294967295 | 87 | PUNCH : [alone] 4294967295 |
88 | IDENT export 4294967295 | 88 | IDENT __private 4294967295 |
89 | PUNCH : [joint] 4294967295 | 89 | PUNCH : [joint] 4294967295 |
90 | PUNCH : [alone] 4294967295 | 90 | PUNCH : [alone] 4294967295 |
91 | IDENT Err 4294967295 | 91 | IDENT Err 4294967295 |
@@ -120,7 +120,7 @@ SUBTREE $ | |||
120 | IDENT _serde 4294967295 | 120 | IDENT _serde 4294967295 |
121 | PUNCH : [joint] 4294967295 | 121 | PUNCH : [joint] 4294967295 |
122 | PUNCH : [alone] 4294967295 | 122 | PUNCH : [alone] 4294967295 |
123 | IDENT export 4294967295 | 123 | IDENT __private 4294967295 |
124 | PUNCH : [joint] 4294967295 | 124 | PUNCH : [joint] 4294967295 |
125 | PUNCH : [alone] 4294967295 | 125 | PUNCH : [alone] 4294967295 |
126 | IDENT Result 4294967295 | 126 | IDENT Result 4294967295 |
diff --git a/crates/proc_macro_srv/src/tests/mod.rs b/crates/proc_macro_srv/src/tests/mod.rs index 1a827cbd7..fd54f8dfd 100644 --- a/crates/proc_macro_srv/src/tests/mod.rs +++ b/crates/proc_macro_srv/src/tests/mod.rs | |||
@@ -38,9 +38,9 @@ fn test_derive_proc_macro_list() { | |||
38 | let res = list("serde_derive", "1").join("\n"); | 38 | let res = list("serde_derive", "1").join("\n"); |
39 | 39 | ||
40 | assert_eq_text!( | 40 | assert_eq_text!( |
41 | &res, | ||
42 | r#"Serialize [CustomDerive] | 41 | r#"Serialize [CustomDerive] |
43 | Deserialize [CustomDerive]"# | 42 | Deserialize [CustomDerive]"#, |
43 | &res | ||
44 | ); | 44 | ); |
45 | } | 45 | } |
46 | 46 | ||
@@ -50,9 +50,9 @@ fn list_test_macros() { | |||
50 | let res = list("proc_macro_test", "0.0.0").join("\n"); | 50 | let res = list("proc_macro_test", "0.0.0").join("\n"); |
51 | 51 | ||
52 | assert_eq_text!( | 52 | assert_eq_text!( |
53 | &res, | ||
54 | r#"function_like_macro [FuncLike] | 53 | r#"function_like_macro [FuncLike] |
55 | attribute_macro [Attr] | 54 | attribute_macro [Attr] |
56 | DummyTrait [CustomDerive]"# | 55 | DummyTrait [CustomDerive]"#, |
56 | &res | ||
57 | ); | 57 | ); |
58 | } | 58 | } |
diff --git a/crates/proc_macro_srv/src/tests/utils.rs b/crates/proc_macro_srv/src/tests/utils.rs index 36942147d..196abb8fc 100644 --- a/crates/proc_macro_srv/src/tests/utils.rs +++ b/crates/proc_macro_srv/src/tests/utils.rs | |||
@@ -52,7 +52,7 @@ pub fn assert_expand( | |||
52 | let fixture = parse_string(ra_fixture).unwrap(); | 52 | let fixture = parse_string(ra_fixture).unwrap(); |
53 | 53 | ||
54 | let res = expander.expand(macro_name, &fixture.subtree, None).unwrap(); | 54 | let res = expander.expand(macro_name, &fixture.subtree, None).unwrap(); |
55 | assert_eq_text!(&format!("{:?}", res), &expect.trim()); | 55 | assert_eq_text!(&expect.trim(), &format!("{:?}", res)); |
56 | } | 56 | } |
57 | 57 | ||
58 | pub fn list(crate_name: &str, version: &str) -> Vec<String> { | 58 | pub fn list(crate_name: &str, version: &str) -> Vec<String> { |
diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml index 096233a09..f7231c2b8 100644 --- a/crates/profile/Cargo.toml +++ b/crates/profile/Cargo.toml | |||
@@ -13,13 +13,15 @@ doctest = false | |||
13 | once_cell = "1.3.1" | 13 | once_cell = "1.3.1" |
14 | cfg-if = "1" | 14 | cfg-if = "1" |
15 | libc = "0.2.73" | 15 | libc = "0.2.73" |
16 | la-arena = "0.1.0" | 16 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
17 | jemalloc-ctl = { version = "0.3.3", optional = true } | ||
17 | 18 | ||
18 | [target.'cfg(target_os = "linux")'.dependencies] | 19 | [target.'cfg(target_os = "linux")'.dependencies] |
19 | perf-event = "0.4" | 20 | perf-event = "0.4" |
20 | 21 | ||
21 | [features] | 22 | [features] |
22 | cpu_profiler = [] | 23 | cpu_profiler = [] |
24 | jemalloc = ["jemalloc-ctl"] | ||
23 | 25 | ||
24 | # Uncomment to enable for the whole crate graph | 26 | # Uncomment to enable for the whole crate graph |
25 | # default = [ "cpu_profiler" ] | 27 | # default = [ "cpu_profiler" ] |
diff --git a/crates/profile/src/memory_usage.rs b/crates/profile/src/memory_usage.rs index 83390212a..cb4e54447 100644 --- a/crates/profile/src/memory_usage.rs +++ b/crates/profile/src/memory_usage.rs | |||
@@ -24,7 +24,12 @@ impl std::ops::Sub for MemoryUsage { | |||
24 | impl MemoryUsage { | 24 | impl MemoryUsage { |
25 | pub fn current() -> MemoryUsage { | 25 | pub fn current() -> MemoryUsage { |
26 | cfg_if! { | 26 | cfg_if! { |
27 | if #[cfg(all(target_os = "linux", target_env = "gnu"))] { | 27 | if #[cfg(all(feature = "jemalloc", not(target_env = "msvc")))] { |
28 | jemalloc_ctl::epoch::advance().unwrap(); | ||
29 | MemoryUsage { | ||
30 | allocated: Bytes(jemalloc_ctl::stats::allocated::read().unwrap() as isize), | ||
31 | } | ||
32 | } else if #[cfg(all(target_os = "linux", target_env = "gnu"))] { | ||
28 | // Note: This is incredibly slow. | 33 | // Note: This is incredibly slow. |
29 | let alloc = unsafe { libc::mallinfo() }.uordblks as isize; | 34 | let alloc = unsafe { libc::mallinfo() }.uordblks as isize; |
30 | MemoryUsage { allocated: Bytes(alloc) } | 35 | MemoryUsage { allocated: Bytes(alloc) } |
diff --git a/crates/project_model/Cargo.toml b/crates/project_model/Cargo.toml index 51e7a7070..293cb5bfe 100644 --- a/crates/project_model/Cargo.toml +++ b/crates/project_model/Cargo.toml | |||
@@ -17,7 +17,7 @@ serde = { version = "1.0.106", features = ["derive"] } | |||
17 | serde_json = "1.0.48" | 17 | serde_json = "1.0.48" |
18 | anyhow = "1.0.26" | 18 | anyhow = "1.0.26" |
19 | itertools = "0.10.0" | 19 | itertools = "0.10.0" |
20 | la-arena = "0.1.0" | 20 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
21 | 21 | ||
22 | cfg = { path = "../cfg", version = "0.0.0" } | 22 | cfg = { path = "../cfg", version = "0.0.0" } |
23 | base_db = { path = "../base_db", version = "0.0.0" } | 23 | base_db = { path = "../base_db", version = "0.0.0" } |
@@ -25,3 +25,4 @@ toolchain = { path = "../toolchain", version = "0.0.0" } | |||
25 | proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } | 25 | proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } |
26 | paths = { path = "../paths", version = "0.0.0" } | 26 | paths = { path = "../paths", version = "0.0.0" } |
27 | stdx = { path = "../stdx", version = "0.0.0" } | 27 | stdx = { path = "../stdx", version = "0.0.0" } |
28 | profile = { path = "../profile", version = "0.0.0" } | ||
diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index aabb7a47d..970a7e140 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs | |||
@@ -5,6 +5,7 @@ mod cfg_flag; | |||
5 | mod project_json; | 5 | mod project_json; |
6 | mod sysroot; | 6 | mod sysroot; |
7 | mod workspace; | 7 | mod workspace; |
8 | mod rustc_cfg; | ||
8 | 9 | ||
9 | use std::{ | 10 | use std::{ |
10 | fs::{read_dir, ReadDir}, | 11 | fs::{read_dir, ReadDir}, |
diff --git a/crates/project_model/src/rustc_cfg.rs b/crates/project_model/src/rustc_cfg.rs new file mode 100644 index 000000000..4a7bd8ae3 --- /dev/null +++ b/crates/project_model/src/rustc_cfg.rs | |||
@@ -0,0 +1,34 @@ | |||
1 | //! Runs `rustc --print cfg` to get built-in cfg flags. | ||
2 | |||
3 | use std::process::Command; | ||
4 | |||
5 | use crate::{cfg_flag::CfgFlag, utf8_stdout}; | ||
6 | |||
7 | pub(crate) fn get(target: Option<&str>) -> Vec<CfgFlag> { | ||
8 | let _p = profile::span("rustc_cfg::get"); | ||
9 | let mut res = Vec::new(); | ||
10 | |||
11 | // Some nightly-only cfgs, which are required for stdlib | ||
12 | res.push(CfgFlag::Atom("target_thread_local".into())); | ||
13 | for &ty in ["8", "16", "32", "64", "cas", "ptr"].iter() { | ||
14 | for &key in ["target_has_atomic", "target_has_atomic_load_store"].iter() { | ||
15 | res.push(CfgFlag::KeyValue { key: key.to_string(), value: ty.into() }); | ||
16 | } | ||
17 | } | ||
18 | |||
19 | let rustc_cfgs = { | ||
20 | let mut cmd = Command::new(toolchain::rustc()); | ||
21 | cmd.args(&["--print", "cfg", "-O"]); | ||
22 | if let Some(target) = target { | ||
23 | cmd.args(&["--target", target]); | ||
24 | } | ||
25 | utf8_stdout(cmd) | ||
26 | }; | ||
27 | |||
28 | match rustc_cfgs { | ||
29 | Ok(rustc_cfgs) => res.extend(rustc_cfgs.lines().map(|it| it.parse().unwrap())), | ||
30 | Err(e) => log::error!("failed to get rustc cfgs: {:#}", e), | ||
31 | } | ||
32 | |||
33 | res | ||
34 | } | ||
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 06a0be284..8e0481ae9 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs | |||
@@ -16,7 +16,7 @@ use proc_macro_api::ProcMacroClient; | |||
16 | use rustc_hash::{FxHashMap, FxHashSet}; | 16 | use rustc_hash::{FxHashMap, FxHashSet}; |
17 | 17 | ||
18 | use crate::{ | 18 | use crate::{ |
19 | cargo_workspace, cfg_flag::CfgFlag, sysroot::SysrootCrate, utf8_stdout, CargoConfig, | 19 | cargo_workspace, cfg_flag::CfgFlag, rustc_cfg, sysroot::SysrootCrate, utf8_stdout, CargoConfig, |
20 | CargoWorkspace, ProjectJson, ProjectManifest, Sysroot, TargetKind, | 20 | CargoWorkspace, ProjectJson, ProjectManifest, Sysroot, TargetKind, |
21 | }; | 21 | }; |
22 | 22 | ||
@@ -34,15 +34,25 @@ pub struct PackageRoot { | |||
34 | #[derive(Clone, Eq, PartialEq)] | 34 | #[derive(Clone, Eq, PartialEq)] |
35 | pub enum ProjectWorkspace { | 35 | pub enum ProjectWorkspace { |
36 | /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. | 36 | /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. |
37 | Cargo { cargo: CargoWorkspace, sysroot: Sysroot, rustc: Option<CargoWorkspace> }, | 37 | Cargo { |
38 | cargo: CargoWorkspace, | ||
39 | sysroot: Sysroot, | ||
40 | rustc: Option<CargoWorkspace>, | ||
41 | /// Holds cfg flags for the current target. We get those by running | ||
42 | /// `rustc --print cfg`. | ||
43 | /// | ||
44 | /// FIXME: make this a per-crate map, as, eg, build.rs might have a | ||
45 | /// different target. | ||
46 | rustc_cfg: Vec<CfgFlag>, | ||
47 | }, | ||
38 | /// Project workspace was manually specified using a `rust-project.json` file. | 48 | /// Project workspace was manually specified using a `rust-project.json` file. |
39 | Json { project: ProjectJson, sysroot: Option<Sysroot> }, | 49 | Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> }, |
40 | } | 50 | } |
41 | 51 | ||
42 | impl fmt::Debug for ProjectWorkspace { | 52 | impl fmt::Debug for ProjectWorkspace { |
43 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 53 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
44 | match self { | 54 | match self { |
45 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => f | 55 | ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } => f |
46 | .debug_struct("Cargo") | 56 | .debug_struct("Cargo") |
47 | .field("n_packages", &cargo.packages().len()) | 57 | .field("n_packages", &cargo.packages().len()) |
48 | .field("n_sysroot_crates", &sysroot.crates().len()) | 58 | .field("n_sysroot_crates", &sysroot.crates().len()) |
@@ -50,13 +60,15 @@ impl fmt::Debug for ProjectWorkspace { | |||
50 | "n_rustc_compiler_crates", | 60 | "n_rustc_compiler_crates", |
51 | &rustc.as_ref().map_or(0, |rc| rc.packages().len()), | 61 | &rustc.as_ref().map_or(0, |rc| rc.packages().len()), |
52 | ) | 62 | ) |
63 | .field("rustc_cfg", rustc_cfg) | ||
53 | .finish(), | 64 | .finish(), |
54 | ProjectWorkspace::Json { project, sysroot } => { | 65 | ProjectWorkspace::Json { project, sysroot, rustc_cfg } => { |
55 | let mut debug_struct = f.debug_struct("Json"); | 66 | let mut debug_struct = f.debug_struct("Json"); |
56 | debug_struct.field("n_crates", &project.n_crates()); | 67 | debug_struct.field("n_crates", &project.n_crates()); |
57 | if let Some(sysroot) = sysroot { | 68 | if let Some(sysroot) = sysroot { |
58 | debug_struct.field("n_sysroot_crates", &sysroot.crates().len()); | 69 | debug_struct.field("n_sysroot_crates", &sysroot.crates().len()); |
59 | } | 70 | } |
71 | debug_struct.field("rustc_cfg", rustc_cfg); | ||
60 | debug_struct.finish() | 72 | debug_struct.finish() |
61 | } | 73 | } |
62 | } | 74 | } |
@@ -79,7 +91,7 @@ impl ProjectWorkspace { | |||
79 | })?; | 91 | })?; |
80 | let project_location = project_json.parent().unwrap().to_path_buf(); | 92 | let project_location = project_json.parent().unwrap().to_path_buf(); |
81 | let project_json = ProjectJson::new(&project_location, data); | 93 | let project_json = ProjectJson::new(&project_location, data); |
82 | ProjectWorkspace::load_inline(project_json)? | 94 | ProjectWorkspace::load_inline(project_json, config.target.as_deref())? |
83 | } | 95 | } |
84 | ProjectManifest::CargoToml(cargo_toml) => { | 96 | ProjectManifest::CargoToml(cargo_toml) => { |
85 | let cargo_version = utf8_stdout({ | 97 | let cargo_version = utf8_stdout({ |
@@ -117,21 +129,24 @@ impl ProjectWorkspace { | |||
117 | } else { | 129 | } else { |
118 | None | 130 | None |
119 | }; | 131 | }; |
120 | 132 | let rustc_cfg = rustc_cfg::get(config.target.as_deref()); | |
121 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } | 133 | ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } |
122 | } | 134 | } |
123 | }; | 135 | }; |
124 | 136 | ||
125 | Ok(res) | 137 | Ok(res) |
126 | } | 138 | } |
127 | 139 | ||
128 | pub fn load_inline(project_json: ProjectJson) -> Result<ProjectWorkspace> { | 140 | pub fn load_inline( |
141 | project_json: ProjectJson, | ||
142 | target: Option<&str>, | ||
143 | ) -> Result<ProjectWorkspace> { | ||
129 | let sysroot = match &project_json.sysroot_src { | 144 | let sysroot = match &project_json.sysroot_src { |
130 | Some(path) => Some(Sysroot::load(path)?), | 145 | Some(path) => Some(Sysroot::load(path)?), |
131 | None => None, | 146 | None => None, |
132 | }; | 147 | }; |
133 | 148 | let rustc_cfg = rustc_cfg::get(target); | |
134 | Ok(ProjectWorkspace::Json { project: project_json, sysroot }) | 149 | Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg }) |
135 | } | 150 | } |
136 | 151 | ||
137 | /// Returns the roots for the current `ProjectWorkspace` | 152 | /// Returns the roots for the current `ProjectWorkspace` |
@@ -139,7 +154,7 @@ impl ProjectWorkspace { | |||
139 | /// the root is a member of the current workspace | 154 | /// the root is a member of the current workspace |
140 | pub fn to_roots(&self) -> Vec<PackageRoot> { | 155 | pub fn to_roots(&self) -> Vec<PackageRoot> { |
141 | match self { | 156 | match self { |
142 | ProjectWorkspace::Json { project, sysroot } => project | 157 | ProjectWorkspace::Json { project, sysroot, rustc_cfg: _ } => project |
143 | .crates() | 158 | .crates() |
144 | .map(|(_, krate)| PackageRoot { | 159 | .map(|(_, krate)| PackageRoot { |
145 | is_member: krate.is_workspace_member, | 160 | is_member: krate.is_workspace_member, |
@@ -156,7 +171,7 @@ impl ProjectWorkspace { | |||
156 | }) | 171 | }) |
157 | })) | 172 | })) |
158 | .collect::<Vec<_>>(), | 173 | .collect::<Vec<_>>(), |
159 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => cargo | 174 | ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg: _ } => cargo |
160 | .packages() | 175 | .packages() |
161 | .map(|pkg| { | 176 | .map(|pkg| { |
162 | let is_member = cargo[pkg].is_member; | 177 | let is_member = cargo[pkg].is_member; |
@@ -194,7 +209,7 @@ impl ProjectWorkspace { | |||
194 | pub fn n_packages(&self) -> usize { | 209 | pub fn n_packages(&self) -> usize { |
195 | match self { | 210 | match self { |
196 | ProjectWorkspace::Json { project, .. } => project.n_crates(), | 211 | ProjectWorkspace::Json { project, .. } => project.n_crates(), |
197 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { | 212 | ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => { |
198 | let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len()); | 213 | let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len()); |
199 | cargo.packages().len() + sysroot.crates().len() + rustc_package_len | 214 | cargo.packages().len() + sysroot.crates().len() + rustc_package_len |
200 | } | 215 | } |
@@ -203,22 +218,31 @@ impl ProjectWorkspace { | |||
203 | 218 | ||
204 | pub fn to_crate_graph( | 219 | pub fn to_crate_graph( |
205 | &self, | 220 | &self, |
206 | target: Option<&str>, | ||
207 | proc_macro_client: Option<&ProcMacroClient>, | 221 | proc_macro_client: Option<&ProcMacroClient>, |
208 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | 222 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, |
209 | ) -> CrateGraph { | 223 | ) -> CrateGraph { |
224 | let _p = profile::span("ProjectWorkspace::to_crate_graph"); | ||
210 | let proc_macro_loader = |path: &Path| match proc_macro_client { | 225 | let proc_macro_loader = |path: &Path| match proc_macro_client { |
211 | Some(client) => client.by_dylib_path(path), | 226 | Some(client) => client.by_dylib_path(path), |
212 | None => Vec::new(), | 227 | None => Vec::new(), |
213 | }; | 228 | }; |
214 | 229 | ||
215 | let mut crate_graph = match self { | 230 | let mut crate_graph = match self { |
216 | ProjectWorkspace::Json { project, sysroot } => { | 231 | ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph( |
217 | project_json_to_crate_graph(target, &proc_macro_loader, load, project, sysroot) | 232 | rustc_cfg.clone(), |
218 | } | 233 | &proc_macro_loader, |
219 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { | 234 | load, |
220 | cargo_to_crate_graph(target, &proc_macro_loader, load, cargo, sysroot, rustc) | 235 | project, |
221 | } | 236 | sysroot, |
237 | ), | ||
238 | ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } => cargo_to_crate_graph( | ||
239 | rustc_cfg.clone(), | ||
240 | &proc_macro_loader, | ||
241 | load, | ||
242 | cargo, | ||
243 | sysroot, | ||
244 | rustc, | ||
245 | ), | ||
222 | }; | 246 | }; |
223 | if crate_graph.patch_cfg_if() { | 247 | if crate_graph.patch_cfg_if() { |
224 | log::debug!("Patched std to depend on cfg-if") | 248 | log::debug!("Patched std to depend on cfg-if") |
@@ -230,7 +254,7 @@ impl ProjectWorkspace { | |||
230 | } | 254 | } |
231 | 255 | ||
232 | fn project_json_to_crate_graph( | 256 | fn project_json_to_crate_graph( |
233 | target: Option<&str>, | 257 | rustc_cfg: Vec<CfgFlag>, |
234 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, | 258 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, |
235 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | 259 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, |
236 | project: &ProjectJson, | 260 | project: &ProjectJson, |
@@ -239,9 +263,9 @@ fn project_json_to_crate_graph( | |||
239 | let mut crate_graph = CrateGraph::default(); | 263 | let mut crate_graph = CrateGraph::default(); |
240 | let sysroot_deps = sysroot | 264 | let sysroot_deps = sysroot |
241 | .as_ref() | 265 | .as_ref() |
242 | .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load)); | 266 | .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load)); |
243 | 267 | ||
244 | let mut cfg_cache: FxHashMap<Option<&str>, Vec<CfgFlag>> = FxHashMap::default(); | 268 | let mut cfg_cache: FxHashMap<&str, Vec<CfgFlag>> = FxHashMap::default(); |
245 | let crates: FxHashMap<CrateId, CrateId> = project | 269 | let crates: FxHashMap<CrateId, CrateId> = project |
246 | .crates() | 270 | .crates() |
247 | .filter_map(|(crate_id, krate)| { | 271 | .filter_map(|(crate_id, krate)| { |
@@ -253,9 +277,12 @@ fn project_json_to_crate_graph( | |||
253 | let env = krate.env.clone().into_iter().collect(); | 277 | let env = krate.env.clone().into_iter().collect(); |
254 | let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| proc_macro_loader(&it)); | 278 | let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| proc_macro_loader(&it)); |
255 | 279 | ||
256 | let target = krate.target.as_deref().or(target); | 280 | let target_cfgs = match krate.target.as_deref() { |
257 | let target_cfgs = | 281 | Some(target) => { |
258 | cfg_cache.entry(target).or_insert_with(|| get_rustc_cfg_options(target)); | 282 | cfg_cache.entry(target).or_insert_with(|| rustc_cfg::get(Some(target))) |
283 | } | ||
284 | None => &rustc_cfg, | ||
285 | }; | ||
259 | 286 | ||
260 | let mut cfg_options = CfgOptions::default(); | 287 | let mut cfg_options = CfgOptions::default(); |
261 | cfg_options.extend(target_cfgs.iter().chain(krate.cfg.iter()).cloned()); | 288 | cfg_options.extend(target_cfgs.iter().chain(krate.cfg.iter()).cloned()); |
@@ -292,19 +319,20 @@ fn project_json_to_crate_graph( | |||
292 | } | 319 | } |
293 | 320 | ||
294 | fn cargo_to_crate_graph( | 321 | fn cargo_to_crate_graph( |
295 | target: Option<&str>, | 322 | rustc_cfg: Vec<CfgFlag>, |
296 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, | 323 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, |
297 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | 324 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, |
298 | cargo: &CargoWorkspace, | 325 | cargo: &CargoWorkspace, |
299 | sysroot: &Sysroot, | 326 | sysroot: &Sysroot, |
300 | rustc: &Option<CargoWorkspace>, | 327 | rustc: &Option<CargoWorkspace>, |
301 | ) -> CrateGraph { | 328 | ) -> CrateGraph { |
329 | let _p = profile::span("cargo_to_crate_graph"); | ||
302 | let mut crate_graph = CrateGraph::default(); | 330 | let mut crate_graph = CrateGraph::default(); |
303 | let (public_deps, libproc_macro) = | 331 | let (public_deps, libproc_macro) = |
304 | sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load); | 332 | sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); |
305 | 333 | ||
306 | let mut cfg_options = CfgOptions::default(); | 334 | let mut cfg_options = CfgOptions::default(); |
307 | cfg_options.extend(get_rustc_cfg_options(target)); | 335 | cfg_options.extend(rustc_cfg); |
308 | 336 | ||
309 | let mut pkg_to_lib_crate = FxHashMap::default(); | 337 | let mut pkg_to_lib_crate = FxHashMap::default(); |
310 | 338 | ||
@@ -490,11 +518,12 @@ fn add_target_crate_root( | |||
490 | fn sysroot_to_crate_graph( | 518 | fn sysroot_to_crate_graph( |
491 | crate_graph: &mut CrateGraph, | 519 | crate_graph: &mut CrateGraph, |
492 | sysroot: &Sysroot, | 520 | sysroot: &Sysroot, |
493 | target: Option<&str>, | 521 | rustc_cfg: Vec<CfgFlag>, |
494 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | 522 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, |
495 | ) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) { | 523 | ) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) { |
524 | let _p = profile::span("sysroot_to_crate_graph"); | ||
496 | let mut cfg_options = CfgOptions::default(); | 525 | let mut cfg_options = CfgOptions::default(); |
497 | cfg_options.extend(get_rustc_cfg_options(target)); | 526 | cfg_options.extend(rustc_cfg); |
498 | let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = sysroot | 527 | let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = sysroot |
499 | .crates() | 528 | .crates() |
500 | .filter_map(|krate| { | 529 | .filter_map(|krate| { |
@@ -533,34 +562,6 @@ fn sysroot_to_crate_graph( | |||
533 | (public_deps, libproc_macro) | 562 | (public_deps, libproc_macro) |
534 | } | 563 | } |
535 | 564 | ||
536 | fn get_rustc_cfg_options(target: Option<&str>) -> Vec<CfgFlag> { | ||
537 | let mut res = Vec::new(); | ||
538 | |||
539 | // Some nightly-only cfgs, which are required for stdlib | ||
540 | res.push(CfgFlag::Atom("target_thread_local".into())); | ||
541 | for &ty in ["8", "16", "32", "64", "cas", "ptr"].iter() { | ||
542 | for &key in ["target_has_atomic", "target_has_atomic_load_store"].iter() { | ||
543 | res.push(CfgFlag::KeyValue { key: key.to_string(), value: ty.into() }); | ||
544 | } | ||
545 | } | ||
546 | |||
547 | let rustc_cfgs = { | ||
548 | let mut cmd = Command::new(toolchain::rustc()); | ||
549 | cmd.args(&["--print", "cfg", "-O"]); | ||
550 | if let Some(target) = target { | ||
551 | cmd.args(&["--target", target]); | ||
552 | } | ||
553 | utf8_stdout(cmd) | ||
554 | }; | ||
555 | |||
556 | match rustc_cfgs { | ||
557 | Ok(rustc_cfgs) => res.extend(rustc_cfgs.lines().map(|it| it.parse().unwrap())), | ||
558 | Err(e) => log::error!("failed to get rustc cfgs: {:#}", e), | ||
559 | } | ||
560 | |||
561 | res | ||
562 | } | ||
563 | |||
564 | fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) { | 565 | fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) { |
565 | if let Err(err) = graph.add_dep(from, name, to) { | 566 | if let Err(err) = graph.add_dep(from, name, to) { |
566 | log::error!("{}", err) | 567 | log::error!("{}", err) |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index af7b86ead..3cb45b030 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -61,8 +61,14 @@ proc_macro_srv = { path = "../proc_macro_srv", version = "0.0.0" } | |||
61 | [target.'cfg(windows)'.dependencies] | 61 | [target.'cfg(windows)'.dependencies] |
62 | winapi = "0.3.8" | 62 | winapi = "0.3.8" |
63 | 63 | ||
64 | [target.'cfg(not(target_env = "msvc"))'.dependencies] | ||
65 | jemallocator = { version = "0.3.2", optional = true } | ||
66 | |||
64 | [dev-dependencies] | 67 | [dev-dependencies] |
65 | expect-test = "1.1" | 68 | expect-test = "1.1" |
66 | test_utils = { path = "../test_utils" } | 69 | test_utils = { path = "../test_utils" } |
67 | mbe = { path = "../mbe" } | 70 | mbe = { path = "../mbe" } |
68 | tt = { path = "../tt" } | 71 | tt = { path = "../tt" } |
72 | |||
73 | [features] | ||
74 | jemalloc = ["jemallocator", "profile/jemalloc"] | ||
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index bf42654a8..2f7f94a39 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs | |||
@@ -15,6 +15,10 @@ use vfs::AbsPathBuf; | |||
15 | #[global_allocator] | 15 | #[global_allocator] |
16 | static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; | 16 | static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; |
17 | 17 | ||
18 | #[cfg(all(feature = "jemalloc", not(target_env = "msvc")))] | ||
19 | #[global_allocator] | ||
20 | static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; | ||
21 | |||
18 | fn main() { | 22 | fn main() { |
19 | if let Err(err) = try_main() { | 23 | if let Err(err) = try_main() { |
20 | eprintln!("{}", err); | 24 | eprintln!("{}", err); |
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 31a16ca46..16ccab781 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs | |||
@@ -39,7 +39,7 @@ pub fn load_cargo( | |||
39 | None | 39 | None |
40 | }; | 40 | }; |
41 | 41 | ||
42 | let crate_graph = ws.to_crate_graph(None, proc_macro_client.as_ref(), &mut |path: &AbsPath| { | 42 | let crate_graph = ws.to_crate_graph(proc_macro_client.as_ref(), &mut |path: &AbsPath| { |
43 | let contents = loader.load_sync(path); | 43 | let contents = loader.load_sync(path); |
44 | let path = vfs::VfsPath::from(path.to_path_buf()); | 44 | let path = vfs::VfsPath::from(path.to_path_buf()); |
45 | vfs.set_file_contents(path.clone(), contents); | 45 | vfs.set_file_contents(path.clone(), contents); |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index a19e9e7dc..001f3a37d 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -810,7 +810,7 @@ pub(crate) fn handle_rename( | |||
810 | 810 | ||
811 | let change = | 811 | let change = |
812 | snap.analysis.rename(position, &*params.new_name)?.map_err(to_proto::rename_error)?; | 812 | snap.analysis.rename(position, &*params.new_name)?.map_err(to_proto::rename_error)?; |
813 | let workspace_edit = to_proto::workspace_edit(&snap, change.info)?; | 813 | let workspace_edit = to_proto::workspace_edit(&snap, change)?; |
814 | Ok(Some(workspace_edit)) | 814 | Ok(Some(workspace_edit)) |
815 | } | 815 | } |
816 | 816 | ||
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 97e20362f..dabfb4241 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -135,7 +135,10 @@ impl GlobalState { | |||
135 | ) | 135 | ) |
136 | } | 136 | } |
137 | LinkedProject::InlineJsonProject(it) => { | 137 | LinkedProject::InlineJsonProject(it) => { |
138 | project_model::ProjectWorkspace::load_inline(it.clone()) | 138 | project_model::ProjectWorkspace::load_inline( |
139 | it.clone(), | ||
140 | cargo_config.target.as_deref(), | ||
141 | ) | ||
139 | } | 142 | } |
140 | }) | 143 | }) |
141 | .collect::<Vec<_>>(); | 144 | .collect::<Vec<_>>(); |
@@ -253,11 +256,7 @@ impl GlobalState { | |||
253 | res | 256 | res |
254 | }; | 257 | }; |
255 | for ws in workspaces.iter() { | 258 | for ws in workspaces.iter() { |
256 | crate_graph.extend(ws.to_crate_graph( | 259 | crate_graph.extend(ws.to_crate_graph(self.proc_macro_client.as_ref(), &mut load)); |
257 | self.config.cargo().target.as_deref(), | ||
258 | self.proc_macro_client.as_ref(), | ||
259 | &mut load, | ||
260 | )); | ||
261 | } | 260 | } |
262 | 261 | ||
263 | crate_graph | 262 | crate_graph |
@@ -274,6 +273,7 @@ impl GlobalState { | |||
274 | } | 273 | } |
275 | 274 | ||
276 | fn reload_flycheck(&mut self) { | 275 | fn reload_flycheck(&mut self) { |
276 | let _p = profile::span("GlobalState::reload_flycheck"); | ||
277 | let config = match self.config.flycheck() { | 277 | let config = match self.config.flycheck() { |
278 | Some(it) => it, | 278 | Some(it) => it, |
279 | None => { | 279 | None => { |
@@ -288,9 +288,7 @@ impl GlobalState { | |||
288 | .iter() | 288 | .iter() |
289 | .enumerate() | 289 | .enumerate() |
290 | .filter_map(|(id, w)| match w { | 290 | .filter_map(|(id, w)| match w { |
291 | ProjectWorkspace::Cargo { cargo, sysroot: _, rustc: _ } => { | 291 | ProjectWorkspace::Cargo { cargo, .. } => Some((id, cargo.workspace_root())), |
292 | Some((id, cargo.workspace_root())) | ||
293 | } | ||
294 | ProjectWorkspace::Json { project, .. } => { | 292 | ProjectWorkspace::Json { project, .. } => { |
295 | // Enable flychecks for json projects if a custom flycheck command was supplied | 293 | // Enable flychecks for json projects if a custom flycheck command was supplied |
296 | // in the workspace configuration. | 294 | // in the workspace configuration. |
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index ad8b797fe..52394b337 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml | |||
@@ -12,7 +12,7 @@ doctest = false | |||
12 | 12 | ||
13 | [dependencies] | 13 | [dependencies] |
14 | itertools = "0.10.0" | 14 | itertools = "0.10.0" |
15 | rowan = "0.10.1" | 15 | rowan = "0.10.3" |
16 | rustc_lexer = { version = "697.0.0", package = "rustc-ap-rustc_lexer" } | 16 | rustc_lexer = { version = "697.0.0", package = "rustc-ap-rustc_lexer" } |
17 | rustc-hash = "1.1.0" | 17 | rustc-hash = "1.1.0" |
18 | arrayvec = "0.5.1" | 18 | arrayvec = "0.5.1" |
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 1d722db3c..5baa54a3f 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs | |||
@@ -11,6 +11,7 @@ pub struct Name { | |||
11 | } | 11 | } |
12 | impl Name { | 12 | impl Name { |
13 | pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } | 13 | pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } |
14 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
14 | } | 15 | } |
15 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 16 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
16 | pub struct NameRef { | 17 | pub struct NameRef { |
@@ -238,7 +239,6 @@ impl ExternCrate { | |||
238 | pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) } | 239 | pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) } |
239 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } | 240 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } |
240 | pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) } | 241 | pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) } |
241 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
242 | pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) } | 242 | pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) } |
243 | pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) } | 243 | pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) } |
244 | } | 244 | } |
@@ -406,9 +406,6 @@ pub struct Visibility { | |||
406 | impl Visibility { | 406 | impl Visibility { |
407 | pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) } | 407 | pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) } |
408 | pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } | 408 | pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } |
409 | pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) } | ||
410 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
411 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } | ||
412 | pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) } | 409 | pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) } |
413 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } | 410 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } |
414 | pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } | 411 | pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } |
@@ -492,11 +489,11 @@ pub struct SelfParam { | |||
492 | pub(crate) syntax: SyntaxNode, | 489 | pub(crate) syntax: SyntaxNode, |
493 | } | 490 | } |
494 | impl ast::AttrsOwner for SelfParam {} | 491 | impl ast::AttrsOwner for SelfParam {} |
492 | impl ast::NameOwner for SelfParam {} | ||
495 | impl SelfParam { | 493 | impl SelfParam { |
496 | pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } | 494 | pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } |
497 | pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) } | 495 | pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) } |
498 | pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } | 496 | pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } |
499 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
500 | pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) } | 497 | pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) } |
501 | pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } | 498 | pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } |
502 | } | 499 | } |
@@ -1075,6 +1072,13 @@ impl InferType { | |||
1075 | pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) } | 1072 | pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) } |
1076 | } | 1073 | } |
1077 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1074 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1075 | pub struct MacroType { | ||
1076 | pub(crate) syntax: SyntaxNode, | ||
1077 | } | ||
1078 | impl MacroType { | ||
1079 | pub fn macro_call(&self) -> Option<MacroCall> { support::child(&self.syntax) } | ||
1080 | } | ||
1081 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1078 | pub struct NeverType { | 1082 | pub struct NeverType { |
1079 | pub(crate) syntax: SyntaxNode, | 1083 | pub(crate) syntax: SyntaxNode, |
1080 | } | 1084 | } |
@@ -1303,6 +1307,7 @@ pub enum Type { | |||
1303 | ForType(ForType), | 1307 | ForType(ForType), |
1304 | ImplTraitType(ImplTraitType), | 1308 | ImplTraitType(ImplTraitType), |
1305 | InferType(InferType), | 1309 | InferType(InferType), |
1310 | MacroType(MacroType), | ||
1306 | NeverType(NeverType), | 1311 | NeverType(NeverType), |
1307 | ParenType(ParenType), | 1312 | ParenType(ParenType), |
1308 | PathType(PathType), | 1313 | PathType(PathType), |
@@ -2561,6 +2566,17 @@ impl AstNode for InferType { | |||
2561 | } | 2566 | } |
2562 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 2567 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
2563 | } | 2568 | } |
2569 | impl AstNode for MacroType { | ||
2570 | fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_TYPE } | ||
2571 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
2572 | if Self::can_cast(syntax.kind()) { | ||
2573 | Some(Self { syntax }) | ||
2574 | } else { | ||
2575 | None | ||
2576 | } | ||
2577 | } | ||
2578 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2579 | } | ||
2564 | impl AstNode for NeverType { | 2580 | impl AstNode for NeverType { |
2565 | fn can_cast(kind: SyntaxKind) -> bool { kind == NEVER_TYPE } | 2581 | fn can_cast(kind: SyntaxKind) -> bool { kind == NEVER_TYPE } |
2566 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 2582 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -2892,6 +2908,9 @@ impl From<ImplTraitType> for Type { | |||
2892 | impl From<InferType> for Type { | 2908 | impl From<InferType> for Type { |
2893 | fn from(node: InferType) -> Type { Type::InferType(node) } | 2909 | fn from(node: InferType) -> Type { Type::InferType(node) } |
2894 | } | 2910 | } |
2911 | impl From<MacroType> for Type { | ||
2912 | fn from(node: MacroType) -> Type { Type::MacroType(node) } | ||
2913 | } | ||
2895 | impl From<NeverType> for Type { | 2914 | impl From<NeverType> for Type { |
2896 | fn from(node: NeverType) -> Type { Type::NeverType(node) } | 2915 | fn from(node: NeverType) -> Type { Type::NeverType(node) } |
2897 | } | 2916 | } |
@@ -2917,8 +2936,8 @@ impl AstNode for Type { | |||
2917 | fn can_cast(kind: SyntaxKind) -> bool { | 2936 | fn can_cast(kind: SyntaxKind) -> bool { |
2918 | match kind { | 2937 | match kind { |
2919 | ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE | 2938 | ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE |
2920 | | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE | SLICE_TYPE | 2939 | | MACRO_TYPE | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE |
2921 | | TUPLE_TYPE => true, | 2940 | | SLICE_TYPE | TUPLE_TYPE => true, |
2922 | _ => false, | 2941 | _ => false, |
2923 | } | 2942 | } |
2924 | } | 2943 | } |
@@ -2930,6 +2949,7 @@ impl AstNode for Type { | |||
2930 | FOR_TYPE => Type::ForType(ForType { syntax }), | 2949 | FOR_TYPE => Type::ForType(ForType { syntax }), |
2931 | IMPL_TRAIT_TYPE => Type::ImplTraitType(ImplTraitType { syntax }), | 2950 | IMPL_TRAIT_TYPE => Type::ImplTraitType(ImplTraitType { syntax }), |
2932 | INFER_TYPE => Type::InferType(InferType { syntax }), | 2951 | INFER_TYPE => Type::InferType(InferType { syntax }), |
2952 | MACRO_TYPE => Type::MacroType(MacroType { syntax }), | ||
2933 | NEVER_TYPE => Type::NeverType(NeverType { syntax }), | 2953 | NEVER_TYPE => Type::NeverType(NeverType { syntax }), |
2934 | PAREN_TYPE => Type::ParenType(ParenType { syntax }), | 2954 | PAREN_TYPE => Type::ParenType(ParenType { syntax }), |
2935 | PATH_TYPE => Type::PathType(PathType { syntax }), | 2955 | PATH_TYPE => Type::PathType(PathType { syntax }), |
@@ -2949,6 +2969,7 @@ impl AstNode for Type { | |||
2949 | Type::ForType(it) => &it.syntax, | 2969 | Type::ForType(it) => &it.syntax, |
2950 | Type::ImplTraitType(it) => &it.syntax, | 2970 | Type::ImplTraitType(it) => &it.syntax, |
2951 | Type::InferType(it) => &it.syntax, | 2971 | Type::InferType(it) => &it.syntax, |
2972 | Type::MacroType(it) => &it.syntax, | ||
2952 | Type::NeverType(it) => &it.syntax, | 2973 | Type::NeverType(it) => &it.syntax, |
2953 | Type::ParenType(it) => &it.syntax, | 2974 | Type::ParenType(it) => &it.syntax, |
2954 | Type::PathType(it) => &it.syntax, | 2975 | Type::PathType(it) => &it.syntax, |
@@ -4085,6 +4106,11 @@ impl std::fmt::Display for InferType { | |||
4085 | std::fmt::Display::fmt(self.syntax(), f) | 4106 | std::fmt::Display::fmt(self.syntax(), f) |
4086 | } | 4107 | } |
4087 | } | 4108 | } |
4109 | impl std::fmt::Display for MacroType { | ||
4110 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
4111 | std::fmt::Display::fmt(self.syntax(), f) | ||
4112 | } | ||
4113 | } | ||
4088 | impl std::fmt::Display for NeverType { | 4114 | impl std::fmt::Display for NeverType { |
4089 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 4115 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
4090 | std::fmt::Display::fmt(self.syntax(), f) | 4116 | std::fmt::Display::fmt(self.syntax(), f) |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index b8ce71d27..738c92a5b 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -198,6 +198,13 @@ impl ast::Path { | |||
198 | pub fn parent_path(&self) -> Option<ast::Path> { | 198 | pub fn parent_path(&self) -> Option<ast::Path> { |
199 | self.syntax().parent().and_then(ast::Path::cast) | 199 | self.syntax().parent().and_then(ast::Path::cast) |
200 | } | 200 | } |
201 | |||
202 | pub fn as_single_segment(&self) -> Option<ast::PathSegment> { | ||
203 | match self.qualifier() { | ||
204 | Some(_) => None, | ||
205 | None => self.segment(), | ||
206 | } | ||
207 | } | ||
201 | } | 208 | } |
202 | 209 | ||
203 | impl ast::UseTreeList { | 210 | impl ast::UseTreeList { |
@@ -448,16 +455,22 @@ pub enum VisibilityKind { | |||
448 | 455 | ||
449 | impl ast::Visibility { | 456 | impl ast::Visibility { |
450 | pub fn kind(&self) -> VisibilityKind { | 457 | pub fn kind(&self) -> VisibilityKind { |
451 | if let Some(path) = support::children(self.syntax()).next() { | 458 | match self.path() { |
452 | VisibilityKind::In(path) | 459 | Some(path) => { |
453 | } else if self.crate_token().is_some() { | 460 | if let Some(segment) = |
454 | VisibilityKind::PubCrate | 461 | path.as_single_segment().filter(|it| it.coloncolon_token().is_none()) |
455 | } else if self.super_token().is_some() { | 462 | { |
456 | VisibilityKind::PubSuper | 463 | if segment.crate_token().is_some() { |
457 | } else if self.self_token().is_some() { | 464 | return VisibilityKind::PubCrate; |
458 | VisibilityKind::PubSelf | 465 | } else if segment.super_token().is_some() { |
459 | } else { | 466 | return VisibilityKind::PubSuper; |
460 | VisibilityKind::Pub | 467 | } else if segment.self_token().is_some() { |
468 | return VisibilityKind::PubSelf; | ||
469 | } | ||
470 | } | ||
471 | VisibilityKind::In(path) | ||
472 | } | ||
473 | None => VisibilityKind::Pub, | ||
461 | } | 474 | } |
462 | } | 475 | } |
463 | } | 476 | } |
diff --git a/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rast b/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rast index faf87d6e5..ae4dd2f3b 100644 --- a/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rast +++ b/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rast | |||
@@ -50,7 +50,10 @@ [email protected] | |||
50 | [email protected] | 50 | [email protected] |
51 | [email protected] "pub" | 51 | [email protected] "pub" |
52 | [email protected] "(" | 52 | [email protected] "(" |
53 | [email protected] "crate" | 53 | [email protected] |
54 | [email protected] | ||
55 | [email protected] | ||
56 | [email protected] "crate" | ||
54 | [email protected] ")" | 57 | [email protected] ")" |
55 | [email protected] " " | 58 | [email protected] " " |
56 | [email protected] "type" | 59 | [email protected] "type" |
@@ -69,7 +72,10 @@ [email protected] | |||
69 | [email protected] | 72 | [email protected] |
70 | [email protected] "pub" | 73 | [email protected] "pub" |
71 | [email protected] "(" | 74 | [email protected] "(" |
72 | [email protected] "crate" | 75 | [email protected] |
76 | [email protected] | ||
77 | [email protected] | ||
78 | [email protected] "crate" | ||
73 | [email protected] ")" | 79 | [email protected] ")" |
74 | [email protected] " " | 80 | [email protected] " " |
75 | [email protected] "const" | 81 | [email protected] "const" |
diff --git a/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast b/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast index 8048f5fad..f0d152d33 100644 --- a/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast +++ b/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast | |||
@@ -19,7 +19,8 @@ [email protected] | |||
19 | [email protected] | 19 | [email protected] |
20 | [email protected] "(" | 20 | [email protected] "(" |
21 | [email protected] | 21 | [email protected] |
22 | [email protected] "self" | 22 | [email protected] |
23 | [email protected] "self" | ||
23 | [email protected] ")" | 24 | [email protected] ")" |
24 | [email protected] " " | 25 | [email protected] " " |
25 | [email protected] | 26 | [email protected] |
@@ -35,7 +36,8 @@ [email protected] | |||
35 | [email protected] "(" | 36 | [email protected] "(" |
36 | [email protected] | 37 | [email protected] |
37 | [email protected] "&" | 38 | [email protected] "&" |
38 | [email protected] "self" | 39 | [email protected] |
40 | [email protected] "self" | ||
39 | [email protected] "," | 41 | [email protected] "," |
40 | [email protected] ")" | 42 | [email protected] ")" |
41 | [email protected] " " | 43 | [email protected] " " |
@@ -55,7 +57,8 @@ [email protected] | |||
55 | [email protected] | 57 | [email protected] |
56 | [email protected] "\'a" | 58 | [email protected] "\'a" |
57 | [email protected] " " | 59 | [email protected] " " |
58 | [email protected] "self" | 60 | [email protected] |
61 | [email protected] "self" | ||
59 | [email protected] "," | 62 | [email protected] "," |
60 | [email protected] ")" | 63 | [email protected] ")" |
61 | [email protected] " " | 64 | [email protected] " " |
@@ -77,7 +80,8 @@ [email protected] | |||
77 | [email protected] " " | 80 | [email protected] " " |
78 | [email protected] "mut" | 81 | [email protected] "mut" |
79 | [email protected] " " | 82 | [email protected] " " |
80 | [email protected] "self" | 83 | [email protected] |
84 | [email protected] "self" | ||
81 | [email protected] "," | 85 | [email protected] "," |
82 | [email protected] " " | 86 | [email protected] " " |
83 | [email protected] | 87 | [email protected] |
@@ -107,7 +111,8 @@ [email protected] | |||
107 | [email protected] | 111 | [email protected] |
108 | [email protected] "mut" | 112 | [email protected] "mut" |
109 | [email protected] " " | 113 | [email protected] " " |
110 | [email protected] "self" | 114 | [email protected] |
115 | [email protected] "self" | ||
111 | [email protected] ")" | 116 | [email protected] ")" |
112 | [email protected] " " | 117 | [email protected] " " |
113 | [email protected] | 118 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0018_arb_self_types.rast b/crates/syntax/test_data/parser/inline/ok/0018_arb_self_types.rast index ddbd66588..df59f37a2 100644 --- a/crates/syntax/test_data/parser/inline/ok/0018_arb_self_types.rast +++ b/crates/syntax/test_data/parser/inline/ok/0018_arb_self_types.rast | |||
@@ -19,7 +19,8 @@ [email protected] | |||
19 | [email protected] | 19 | [email protected] |
20 | [email protected] "(" | 20 | [email protected] "(" |
21 | [email protected] | 21 | [email protected] |
22 | [email protected] "self" | 22 | [email protected] |
23 | [email protected] "self" | ||
23 | [email protected] ":" | 24 | [email protected] ":" |
24 | [email protected] " " | 25 | [email protected] " " |
25 | [email protected] | 26 | [email protected] |
@@ -45,7 +46,8 @@ [email protected] | |||
45 | [email protected] | 46 | [email protected] |
46 | [email protected] "mut" | 47 | [email protected] "mut" |
47 | [email protected] " " | 48 | [email protected] " " |
48 | [email protected] "self" | 49 | [email protected] |
50 | [email protected] "self" | ||
49 | [email protected] ":" | 51 | [email protected] ":" |
50 | [email protected] " " | 52 | [email protected] " " |
51 | [email protected] | 53 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0021_impl_item_list.rast b/crates/syntax/test_data/parser/inline/ok/0021_impl_item_list.rast index ca0702aba..dc7f6295b 100644 --- a/crates/syntax/test_data/parser/inline/ok/0021_impl_item_list.rast +++ b/crates/syntax/test_data/parser/inline/ok/0021_impl_item_list.rast | |||
@@ -67,7 +67,8 @@ [email protected] | |||
67 | [email protected] "(" | 67 | [email protected] "(" |
68 | [email protected] | 68 | [email protected] |
69 | [email protected] "&" | 69 | [email protected] "&" |
70 | [email protected] "self" | 70 | [email protected] |
71 | [email protected] "self" | ||
71 | [email protected] ")" | 72 | [email protected] ")" |
72 | [email protected] " " | 73 | [email protected] " " |
73 | [email protected] | 74 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rast b/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rast index 50742cbcf..f2ead8a62 100644 --- a/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rast +++ b/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rast | |||
@@ -1,9 +1,12 @@ | |||
1 | SOURCE_FILE@0..81 | 1 | SOURCE_FILE@0..62 |
2 | [email protected] | 2 | [email protected] |
3 | [email protected] | 3 | [email protected] |
4 | [email protected] "pub" | 4 | [email protected] "pub" |
5 | [email protected] "(" | 5 | [email protected] "(" |
6 | [email protected] "crate" | 6 | [email protected] |
7 | [email protected] | ||
8 | [email protected] | ||
9 | [email protected] "crate" | ||
7 | [email protected] ")" | 10 | [email protected] ")" |
8 | [email protected] " " | 11 | [email protected] " " |
9 | [email protected] "struct" | 12 | [email protected] "struct" |
@@ -16,7 +19,10 @@ [email protected] | |||
16 | [email protected] | 19 | [email protected] |
17 | [email protected] "pub" | 20 | [email protected] "pub" |
18 | [email protected] "(" | 21 | [email protected] "(" |
19 | [email protected] "self" | 22 | [email protected] |
23 | [email protected] | ||
24 | [email protected] | ||
25 | [email protected] "self" | ||
20 | [email protected] ")" | 26 | [email protected] ")" |
21 | [email protected] " " | 27 | [email protected] " " |
22 | [email protected] "struct" | 28 | [email protected] "struct" |
@@ -25,29 +31,19 @@ [email protected] | |||
25 | [email protected] "S" | 31 | [email protected] "S" |
26 | [email protected] ";" | 32 | [email protected] ";" |
27 | [email protected] "\n" | 33 | [email protected] "\n" |
28 | [email protected]0 | 34 | [email protected]1 |
29 | [email protected]0 | 35 | [email protected]1 |
30 | [email protected] "pub" | 36 | [email protected] "pub" |
31 | [email protected] "(" | 37 | [email protected] "(" |
32 | [email protected] "self" | 38 | [email protected] |
33 | [email protected] ")" | 39 | [email protected] |
34 | [email protected] " " | 40 | [email protected] |
35 | [email protected] "struct" | 41 | [email protected] "super" |
36 | [email protected] " " | 42 | [email protected] ")" |
37 | [email protected] | 43 | [email protected] " " |
38 | [email protected] "S" | 44 | [email protected] "struct" |
39 | [email protected] ";" | 45 | [email protected] " " |
40 | [email protected] "\n" | 46 | [email protected] |
41 | [email protected] | 47 | [email protected] "S" |
42 | [email protected] | 48 | [email protected] ";" |
43 | [email protected] "pub" | 49 | [email protected] "\n" |
44 | [email protected] "(" | ||
45 | [email protected] "self" | ||
46 | [email protected] ")" | ||
47 | [email protected] " " | ||
48 | [email protected] "struct" | ||
49 | [email protected] " " | ||
50 | [email protected] | ||
51 | [email protected] "S" | ||
52 | [email protected] ";" | ||
53 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rs b/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rs index faeefde94..a790a485f 100644 --- a/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rs +++ b/crates/syntax/test_data/parser/inline/ok/0022_crate_visibility.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | pub(crate) struct S; | 1 | pub(crate) struct S; |
2 | pub(self) struct S; | 2 | pub(self) struct S; |
3 | pub(self) struct S; | 3 | pub(super) struct S; |
4 | pub(self) struct S; | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast b/crates/syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast index d3219f0b2..c54e64e3f 100644 --- a/crates/syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast +++ b/crates/syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast | |||
@@ -16,7 +16,8 @@ [email protected] | |||
16 | [email protected] "must_use" | 16 | [email protected] "must_use" |
17 | [email protected] "]" | 17 | [email protected] "]" |
18 | [email protected] " " | 18 | [email protected] " " |
19 | [email protected] "self" | 19 | [email protected] |
20 | [email protected] "self" | ||
20 | [email protected] ")" | 21 | [email protected] ")" |
21 | [email protected] " " | 22 | [email protected] " " |
22 | [email protected] | 23 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0160_crate_visibility_in.rast b/crates/syntax/test_data/parser/inline/ok/0160_crate_visibility_in.rast new file mode 100644 index 000000000..3d855fc6b --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0160_crate_visibility_in.rast | |||
@@ -0,0 +1,42 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] | ||
4 | [email protected] "pub" | ||
5 | [email protected] "(" | ||
6 | [email protected] "in" | ||
7 | [email protected] " " | ||
8 | [email protected] | ||
9 | [email protected] | ||
10 | [email protected] | ||
11 | [email protected] | ||
12 | [email protected] "super" | ||
13 | [email protected] "::" | ||
14 | [email protected] | ||
15 | [email protected] | ||
16 | [email protected] "A" | ||
17 | [email protected] ")" | ||
18 | [email protected] " " | ||
19 | [email protected] "struct" | ||
20 | [email protected] " " | ||
21 | [email protected] | ||
22 | [email protected] "S" | ||
23 | [email protected] ";" | ||
24 | [email protected] "\n" | ||
25 | [email protected] | ||
26 | [email protected] | ||
27 | [email protected] "pub" | ||
28 | [email protected] "(" | ||
29 | [email protected] "in" | ||
30 | [email protected] " " | ||
31 | [email protected] | ||
32 | [email protected] | ||
33 | [email protected] | ||
34 | [email protected] "crate" | ||
35 | [email protected] ")" | ||
36 | [email protected] " " | ||
37 | [email protected] "struct" | ||
38 | [email protected] " " | ||
39 | [email protected] | ||
40 | [email protected] "S" | ||
41 | [email protected] ";" | ||
42 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0160_crate_visibility_in.rs b/crates/syntax/test_data/parser/inline/ok/0160_crate_visibility_in.rs new file mode 100644 index 000000000..2856dbd84 --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0160_crate_visibility_in.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | pub(in super::A) struct S; | ||
2 | pub(in crate) struct S; | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rast b/crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rast new file mode 100644 index 000000000..dcd39535b --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rast | |||
@@ -0,0 +1,24 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] "impl" | ||
4 | [email protected] " " | ||
5 | [email protected] "const" | ||
6 | [email protected] " " | ||
7 | [email protected] | ||
8 | [email protected] | ||
9 | [email protected] | ||
10 | [email protected] | ||
11 | [email protected] "Send" | ||
12 | [email protected] " " | ||
13 | [email protected] "for" | ||
14 | [email protected] " " | ||
15 | [email protected] | ||
16 | [email protected] | ||
17 | [email protected] | ||
18 | [email protected] | ||
19 | [email protected] "X" | ||
20 | [email protected] " " | ||
21 | [email protected] | ||
22 | [email protected] "{" | ||
23 | [email protected] "}" | ||
24 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rs b/crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rs new file mode 100644 index 000000000..8d6886469 --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rs | |||
@@ -0,0 +1 @@ | |||
impl const Send for X {} | |||
diff --git a/crates/syntax/test_data/parser/ok/0007_extern_crate.rast b/crates/syntax/test_data/parser/ok/0007_extern_crate.rast index 594c2f8f2..4babdba92 100644 --- a/crates/syntax/test_data/parser/ok/0007_extern_crate.rast +++ b/crates/syntax/test_data/parser/ok/0007_extern_crate.rast | |||
@@ -28,7 +28,8 @@ [email protected] | |||
28 | [email protected] " " | 28 | [email protected] " " |
29 | [email protected] "crate" | 29 | [email protected] "crate" |
30 | [email protected] " " | 30 | [email protected] " " |
31 | [email protected] "self" | 31 | [email protected] |
32 | [email protected] "self" | ||
32 | [email protected] " " | 33 | [email protected] " " |
33 | [email protected] | 34 | [email protected] |
34 | [email protected] "as" | 35 | [email protected] "as" |
diff --git a/crates/syntax/test_data/parser/ok/0012_visibility.rast b/crates/syntax/test_data/parser/ok/0012_visibility.rast index 83a93b5a9..c5dbfb702 100644 --- a/crates/syntax/test_data/parser/ok/0012_visibility.rast +++ b/crates/syntax/test_data/parser/ok/0012_visibility.rast | |||
@@ -32,7 +32,10 @@ [email protected] | |||
32 | [email protected] | 32 | [email protected] |
33 | [email protected] "pub" | 33 | [email protected] "pub" |
34 | [email protected] "(" | 34 | [email protected] "(" |
35 | [email protected] "crate" | 35 | [email protected] |
36 | [email protected] | ||
37 | [email protected] | ||
38 | [email protected] "crate" | ||
36 | [email protected] ")" | 39 | [email protected] ")" |
37 | [email protected] " " | 40 | [email protected] " " |
38 | [email protected] "fn" | 41 | [email protected] "fn" |
@@ -51,7 +54,10 @@ [email protected] | |||
51 | [email protected] | 54 | [email protected] |
52 | [email protected] "pub" | 55 | [email protected] "pub" |
53 | [email protected] "(" | 56 | [email protected] "(" |
54 | [email protected] "super" | 57 | [email protected] |
58 | [email protected] | ||
59 | [email protected] | ||
60 | [email protected] "super" | ||
55 | [email protected] ")" | 61 | [email protected] ")" |
56 | [email protected] " " | 62 | [email protected] " " |
57 | [email protected] "fn" | 63 | [email protected] "fn" |
diff --git a/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast b/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast index 0ac56df6d..6afed5f05 100644 --- a/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast +++ b/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast | |||
@@ -110,7 +110,8 @@ [email protected] | |||
110 | [email protected] "(" | 110 | [email protected] "(" |
111 | [email protected] | 111 | [email protected] |
112 | [email protected] "&" | 112 | [email protected] "&" |
113 | [email protected] "self" | 113 | [email protected] |
114 | [email protected] "self" | ||
114 | [email protected] "," | 115 | [email protected] "," |
115 | [email protected] " " | 116 | [email protected] " " |
116 | [email protected] | 117 | [email protected] |
diff --git a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast index 3fed11838..e10521d85 100644 --- a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast +++ b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast | |||
@@ -281,7 +281,8 @@ [email protected] | |||
281 | [email protected] "must_use" | 281 | [email protected] "must_use" |
282 | [email protected] "]" | 282 | [email protected] "]" |
283 | [email protected] " " | 283 | [email protected] " " |
284 | [email protected] "self" | 284 | [email protected] |
285 | [email protected] "self" | ||
285 | [email protected] ")" | 286 | [email protected] ")" |
286 | [email protected] " " | 287 | [email protected] " " |
287 | [email protected] | 288 | [email protected] |
@@ -305,7 +306,8 @@ [email protected] | |||
305 | [email protected] "attr" | 306 | [email protected] "attr" |
306 | [email protected] "]" | 307 | [email protected] "]" |
307 | [email protected] " " | 308 | [email protected] " " |
308 | [email protected] "self" | 309 | [email protected] |
310 | [email protected] "self" | ||
309 | [email protected] ")" | 311 | [email protected] ")" |
310 | [email protected] " " | 312 | [email protected] " " |
311 | [email protected] | 313 | [email protected] |
@@ -330,7 +332,8 @@ [email protected] | |||
330 | [email protected] "]" | 332 | [email protected] "]" |
331 | [email protected] " " | 333 | [email protected] " " |
332 | [email protected] "&" | 334 | [email protected] "&" |
333 | [email protected] "self" | 335 | [email protected] |
336 | [email protected] "self" | ||
334 | [email protected] ")" | 337 | [email protected] ")" |
335 | [email protected] " " | 338 | [email protected] " " |
336 | [email protected] | 339 | [email protected] |
@@ -363,7 +366,8 @@ [email protected] | |||
363 | [email protected] "&" | 366 | [email protected] "&" |
364 | [email protected] "mut" | 367 | [email protected] "mut" |
365 | [email protected] " " | 368 | [email protected] " " |
366 | [email protected] "self" | 369 | [email protected] |
370 | [email protected] "self" | ||
367 | [email protected] ")" | 371 | [email protected] ")" |
368 | [email protected] " " | 372 | [email protected] " " |
369 | [email protected] | 373 | [email protected] |
@@ -397,7 +401,8 @@ [email protected] | |||
397 | [email protected] | 401 | [email protected] |
398 | [email protected] "\'a" | 402 | [email protected] "\'a" |
399 | [email protected] " " | 403 | [email protected] " " |
400 | [email protected] "self" | 404 | [email protected] |
405 | [email protected] "self" | ||
401 | [email protected] ")" | 406 | [email protected] ")" |
402 | [email protected] " " | 407 | [email protected] " " |
403 | [email protected] | 408 | [email protected] |
@@ -433,7 +438,8 @@ [email protected] | |||
433 | [email protected] " " | 438 | [email protected] " " |
434 | [email protected] "mut" | 439 | [email protected] "mut" |
435 | [email protected] " " | 440 | [email protected] " " |
436 | [email protected] "self" | 441 | [email protected] |
442 | [email protected] "self" | ||
437 | [email protected] ")" | 443 | [email protected] ")" |
438 | [email protected] " " | 444 | [email protected] " " |
439 | [email protected] | 445 | [email protected] |
@@ -457,7 +463,8 @@ [email protected] | |||
457 | [email protected] "attr" | 463 | [email protected] "attr" |
458 | [email protected] "]" | 464 | [email protected] "]" |
459 | [email protected] " " | 465 | [email protected] " " |
460 | [email protected] "self" | 466 | [email protected] |
467 | [email protected] "self" | ||
461 | [email protected] ":" | 468 | [email protected] ":" |
462 | [email protected] " " | 469 | [email protected] " " |
463 | [email protected] | 470 | [email protected] |
@@ -488,7 +495,8 @@ [email protected] | |||
488 | [email protected] "attr" | 495 | [email protected] "attr" |
489 | [email protected] "]" | 496 | [email protected] "]" |
490 | [email protected] " " | 497 | [email protected] " " |
491 | [email protected] "self" | 498 | [email protected] |
499 | [email protected] "self" | ||
492 | [email protected] ":" | 500 | [email protected] ":" |
493 | [email protected] " " | 501 | [email protected] " " |
494 | [email protected] | 502 | [email protected] |