aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-10-30 16:17:49 +0000
committerGitHub <[email protected]>2019-10-30 16:17:49 +0000
commitd929f9c49bceb3b7c32ea45c5e55c42f168bbf34 (patch)
tree3f0f71a7b9406738b1d15d53970e76302ac624c4
parent5806195bc1cdb1ca3fa257e99fd6e0dd897713a9 (diff)
parentcf4f7eb56660cfff355cb6bd41d5c17f7d19571b (diff)
Merge #2130
2130: improve compile time a bit r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ra_hir/src/adt.rs3
-rw-r--r--crates/ra_hir/src/code_model.rs8
-rw-r--r--crates/ra_hir/src/expr/lower.rs9
-rw-r--r--crates/ra_hir/src/from_source.rs2
-rw-r--r--crates/ra_hir/src/generics.rs2
-rw-r--r--crates/ra_hir/src/impl_block.rs11
-rw-r--r--crates/ra_hir/src/lib.rs18
-rw-r--r--crates/ra_hir/src/nameres/collector.rs3
-rw-r--r--crates/ra_hir/src/resolve.rs2
-rw-r--r--crates/ra_hir/src/source_binder.rs3
-rw-r--r--crates/ra_hir/src/traits.rs3
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs2
-rw-r--r--crates/ra_hir/src/ty/infer.rs2
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs6
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs3
-rw-r--r--crates/ra_hir/src/type_alias.rs7
-rw-r--r--crates/ra_hir_def/src/attr.rs19
-rw-r--r--crates/ra_hir_def/src/lib.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs55
-rw-r--r--crates/ra_hir_def/src/path.rs115
-rw-r--r--crates/ra_hir_expand/src/either.rs (renamed from crates/ra_hir_def/src/either.rs)0
-rw-r--r--crates/ra_hir_expand/src/hygiene.rs46
-rw-r--r--crates/ra_hir_expand/src/lib.rs14
-rw-r--r--crates/ra_hir_expand/src/name.rs (renamed from crates/ra_hir_def/src/name.rs)0
24 files changed, 178 insertions, 157 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index d16b3a1cc..97424b39e 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -3,7 +3,8 @@
3 3
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use hir_def::{name::AsName, type_ref::TypeRef}; 6use hir_def::type_ref::TypeRef;
7use hir_expand::name::AsName;
7use ra_arena::{impl_arena_id, Arena, RawId}; 8use ra_arena::{impl_arena_id, Arena, RawId};
8use ra_syntax::ast::{self, NameOwner, StructKind, TypeAscriptionOwner}; 9use ra_syntax::ast::{self, NameOwner, StructKind, TypeAscriptionOwner};
9 10
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index d865c972e..a6ce23dd1 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -6,13 +6,13 @@ pub(crate) mod docs;
6use std::sync::Arc; 6use std::sync::Arc;
7 7
8use hir_def::{ 8use hir_def::{
9 name::{
10 self, AsName, BOOL, CHAR, F32, F64, I128, I16, I32, I64, I8, ISIZE, SELF_TYPE, STR, U128,
11 U16, U32, U64, U8, USIZE,
12 },
13 type_ref::{Mutability, TypeRef}, 9 type_ref::{Mutability, TypeRef},
14 CrateModuleId, ModuleId, 10 CrateModuleId, ModuleId,
15}; 11};
12use hir_expand::name::{
13 self, AsName, BOOL, CHAR, F32, F64, I128, I16, I32, I64, I8, ISIZE, SELF_TYPE, STR, U128, U16,
14 U32, U64, U8, USIZE,
15};
16use ra_db::{CrateId, Edition}; 16use ra_db::{CrateId, Edition};
17use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 17use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
18 18
diff --git a/crates/ra_hir/src/expr/lower.rs b/crates/ra_hir/src/expr/lower.rs
index ad029b868..6463dd65e 100644
--- a/crates/ra_hir/src/expr/lower.rs
+++ b/crates/ra_hir/src/expr/lower.rs
@@ -1,9 +1,9 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{ 3use hir_def::{path::GenericArgs, type_ref::TypeRef};
4use hir_expand::{
5 hygiene::Hygiene,
4 name::{self, AsName, Name}, 6 name::{self, AsName, Name},
5 path::GenericArgs,
6 type_ref::TypeRef,
7}; 7};
8use ra_arena::Arena; 8use ra_arena::Arena;
9use ra_syntax::{ 9use ra_syntax::{
@@ -597,7 +597,8 @@ where
597 } 597 }
598 598
599 fn parse_path(&mut self, path: ast::Path) -> Option<Path> { 599 fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
600 Path::from_src(Source { ast: path, file_id: self.current_file_id }, self.db) 600 let hygiene = Hygiene::new(self.db, self.current_file_id);
601 Path::from_src(path, &hygiene)
601 } 602 }
602} 603}
603 604
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index b9fbaa367..a9de01455 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::name::AsName; 3use hir_expand::name::AsName;
4use ra_syntax::ast::{self, AstNode, NameOwner}; 4use ra_syntax::ast::{self, AstNode, NameOwner};
5 5
6use crate::{ 6use crate::{
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index 9d5d18564..52e1fbf29 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -6,10 +6,10 @@
6use std::sync::Arc; 6use std::sync::Arc;
7 7
8use hir_def::{ 8use hir_def::{
9 name::{self, AsName},
10 path::Path, 9 path::Path,
11 type_ref::{TypeBound, TypeRef}, 10 type_ref::{TypeBound, TypeRef},
12}; 11};
12use hir_expand::name::{self, AsName};
13use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner}; 13use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner};
14 14
15use crate::{ 15use crate::{
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 518330713..b1a014074 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -4,6 +4,7 @@ use rustc_hash::FxHashMap;
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use hir_def::{attr::Attr, type_ref::TypeRef}; 6use hir_def::{attr::Attr, type_ref::TypeRef};
7use hir_expand::hygiene::Hygiene;
7use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 8use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
8use ra_cfg::CfgOptions; 9use ra_cfg::CfgOptions;
9use ra_syntax::{ 10use ra_syntax::{
@@ -227,10 +228,11 @@ impl ModuleImplBlocks {
227 owner: &dyn ast::ModuleItemOwner, 228 owner: &dyn ast::ModuleItemOwner,
228 file_id: HirFileId, 229 file_id: HirFileId,
229 ) { 230 ) {
231 let hygiene = Hygiene::new(db, file_id);
230 for item in owner.items_with_macros() { 232 for item in owner.items_with_macros() {
231 match item { 233 match item {
232 ast::ItemOrMacro::Item(ast::ModuleItem::ImplBlock(impl_block_ast)) => { 234 ast::ItemOrMacro::Item(ast::ModuleItem::ImplBlock(impl_block_ast)) => {
233 let attrs = Attr::from_attrs_owner(file_id, &impl_block_ast, db); 235 let attrs = Attr::from_attrs_owner(&impl_block_ast, &hygiene);
234 if attrs.map_or(false, |attrs| { 236 if attrs.map_or(false, |attrs| {
235 attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) 237 attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false))
236 }) { 238 }) {
@@ -247,7 +249,7 @@ impl ModuleImplBlocks {
247 } 249 }
248 ast::ItemOrMacro::Item(_) => (), 250 ast::ItemOrMacro::Item(_) => (),
249 ast::ItemOrMacro::Macro(macro_call) => { 251 ast::ItemOrMacro::Macro(macro_call) => {
250 let attrs = Attr::from_attrs_owner(file_id, &macro_call, db); 252 let attrs = Attr::from_attrs_owner(&macro_call, &hygiene);
251 if attrs.map_or(false, |attrs| { 253 if attrs.map_or(false, |attrs| {
252 attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) 254 attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false))
253 }) { 255 }) {
@@ -256,9 +258,8 @@ impl ModuleImplBlocks {
256 258
257 //FIXME: we should really cut down on the boilerplate required to process a macro 259 //FIXME: we should really cut down on the boilerplate required to process a macro
258 let ast_id = AstId::new(file_id, db.ast_id_map(file_id).ast_id(&macro_call)); 260 let ast_id = AstId::new(file_id, db.ast_id_map(file_id).ast_id(&macro_call));
259 if let Some(path) = macro_call 261 if let Some(path) =
260 .path() 262 macro_call.path().and_then(|path| Path::from_src(path, &hygiene))
261 .and_then(|path| Path::from_src(Source { ast: path, file_id }, db))
262 { 263 {
263 if let Some(def) = self.module.resolver(db).resolve_path_as_macro(db, &path) 264 if let Some(def) = self.module.resolver(db).resolve_path_as_macro(db, &path)
264 { 265 {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index f765490b0..603b0c3dc 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -60,6 +60,13 @@ use crate::{ids::MacroFileKind, resolve::Resolver};
60 60
61pub use crate::{ 61pub use crate::{
62 adt::VariantDef, 62 adt::VariantDef,
63 code_model::{
64 docs::{DocDef, Docs, Documentation},
65 src::{HasBodySource, HasSource, Source},
66 Adt, AssocItem, BuiltinType, Const, ConstData, Container, Crate, CrateDependency,
67 DefWithBody, Enum, EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module,
68 ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
69 },
63 expr::ExprScopes, 70 expr::ExprScopes,
64 from_source::FromSource, 71 from_source::FromSource,
65 generics::{GenericDef, GenericParam, GenericParams, HasGenericParams}, 72 generics::{GenericDef, GenericParam, GenericParams, HasGenericParams},
@@ -73,17 +80,8 @@ pub use crate::{
73 }, 80 },
74}; 81};
75 82
76pub use self::code_model::{
77 docs::{DocDef, Docs, Documentation},
78 src::{HasBodySource, HasSource, Source},
79 Adt, AssocItem, BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody,
80 Enum, EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef,
81 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
82};
83
84pub use hir_def::{ 83pub use hir_def::{
85 either::Either,
86 name::Name,
87 path::{Path, PathKind}, 84 path::{Path, PathKind},
88 type_ref::Mutability, 85 type_ref::Mutability,
89}; 86};
87pub use hir_expand::{either::Either, name::Name};
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 2f342870b..e2e13805a 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -1,6 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{attr::Attr, name, nameres::raw}; 3use hir_def::{attr::Attr, nameres::raw};
4use hir_expand::name;
4use ra_cfg::CfgOptions; 5use ra_cfg::CfgOptions;
5use ra_db::FileId; 6use ra_db::FileId;
6use ra_syntax::{ast, SmolStr}; 7use ra_syntax::{ast, SmolStr};
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 2a783b61e..f77c9df9f 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -2,10 +2,10 @@
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use hir_def::{ 4use hir_def::{
5 name::{self, Name},
6 path::{Path, PathKind}, 5 path::{Path, PathKind},
7 CrateModuleId, 6 CrateModuleId,
8}; 7};
8use hir_expand::name::{self, Name};
9use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
10 10
11use crate::{ 11use crate::{
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 544433a0a..01f51ba5d 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -7,7 +7,8 @@
7//! purely for "IDE needs". 7//! purely for "IDE needs".
8use std::sync::Arc; 8use std::sync::Arc;
9 9
10use hir_def::{name::AsName, path::known}; 10use hir_def::path::known;
11use hir_expand::name::AsName;
11use ra_db::FileId; 12use ra_db::FileId;
12use ra_syntax::{ 13use ra_syntax::{
13 ast::{self, AstNode}, 14 ast::{self, AstNode},
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs
index 514c813ab..1a45dacba 100644
--- a/crates/ra_hir/src/traits.rs
+++ b/crates/ra_hir/src/traits.rs
@@ -2,7 +2,8 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::name::AsName; 5use hir_expand::name::AsName;
6
6use ra_syntax::ast::{self, NameOwner}; 7use ra_syntax::ast::{self, NameOwner};
7use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
8 9
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 03c45546d..3645ee831 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -5,7 +5,7 @@
5 5
6use std::iter::successors; 6use std::iter::successors;
7 7
8use hir_def::name; 8use hir_expand::name;
9use log::{info, warn}; 9use log::{info, warn};
10 10
11use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; 11use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk};
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 7466ee341..6694467a3 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -22,10 +22,10 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
22use rustc_hash::FxHashMap; 22use rustc_hash::FxHashMap;
23 23
24use hir_def::{ 24use hir_def::{
25 name,
26 path::known, 25 path::known,
27 type_ref::{Mutability, TypeRef}, 26 type_ref::{Mutability, TypeRef},
28}; 27};
28use hir_expand::name;
29use ra_arena::map::ArenaMap; 29use ra_arena::map::ArenaMap;
30use ra_prof::profile; 30use ra_prof::profile;
31use test_utils::tested_by; 31use test_utils::tested_by;
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index bc6437b44..fed52df39 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -3,10 +3,8 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use hir_def::{ 6use hir_def::path::{GenericArg, GenericArgs};
7 name, 7use hir_expand::name;
8 path::{GenericArg, GenericArgs},
9};
10 8
11use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 9use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
12use crate::{ 10use crate::{
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 2dd4c2fae..39ef92182 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -9,7 +9,8 @@ use chalk_ir::{
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum};
11 11
12use hir_def::name; 12use hir_expand::name;
13
13use ra_db::salsa::{InternId, InternKey}; 14use ra_db::salsa::{InternId, InternKey};
14 15
15use super::{Canonical, ChalkContext, Impl, Obligation}; 16use super::{Canonical, ChalkContext, Impl, Obligation};
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs
index 87126ee7f..078e6295e 100644
--- a/crates/ra_hir/src/type_alias.rs
+++ b/crates/ra_hir/src/type_alias.rs
@@ -2,10 +2,9 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{ 5use hir_def::type_ref::TypeRef;
6 name::{AsName, Name}, 6use hir_expand::name::{AsName, Name};
7 type_ref::TypeRef, 7
8};
9use ra_syntax::ast::NameOwner; 8use ra_syntax::ast::NameOwner;
10 9
11use crate::{ 10use crate::{
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 248f03cdf..0e961ca12 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -2,7 +2,7 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_expand::db::AstDatabase; 5use hir_expand::hygiene::Hygiene;
6use mbe::ast_to_token_tree; 6use mbe::ast_to_token_tree;
7use ra_cfg::CfgOptions; 7use ra_cfg::CfgOptions;
8use ra_syntax::{ 8use ra_syntax::{
@@ -11,7 +11,7 @@ use ra_syntax::{
11}; 11};
12use tt::Subtree; 12use tt::Subtree;
13 13
14use crate::{path::Path, HirFileId, Source}; 14use crate::path::Path;
15 15
16#[derive(Debug, Clone, PartialEq, Eq)] 16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct Attr { 17pub struct Attr {
@@ -26,11 +26,8 @@ pub enum AttrInput {
26} 26}
27 27
28impl Attr { 28impl Attr {
29 pub(crate) fn from_src( 29 pub(crate) fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> {
30 Source { file_id, ast }: Source<ast::Attr>, 30 let path = Path::from_src(ast.path()?, hygiene)?;
31 db: &impl AstDatabase,
32 ) -> Option<Attr> {
33 let path = Path::from_src(Source { file_id, ast: ast.path()? }, db)?;
34 let input = match ast.input() { 31 let input = match ast.input() {
35 None => None, 32 None => None,
36 Some(ast::AttrInput::Literal(lit)) => { 33 Some(ast::AttrInput::Literal(lit)) => {
@@ -46,17 +43,13 @@ impl Attr {
46 Some(Attr { path, input }) 43 Some(Attr { path, input })
47 } 44 }
48 45
49 pub fn from_attrs_owner( 46 pub fn from_attrs_owner(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Option<Arc<[Attr]>> {
50 file_id: HirFileId,
51 owner: &dyn AttrsOwner,
52 db: &impl AstDatabase,
53 ) -> Option<Arc<[Attr]>> {
54 let mut attrs = owner.attrs().peekable(); 47 let mut attrs = owner.attrs().peekable();
55 if attrs.peek().is_none() { 48 if attrs.peek().is_none() {
56 // Avoid heap allocation 49 // Avoid heap allocation
57 return None; 50 return None;
58 } 51 }
59 Some(attrs.flat_map(|ast| Attr::from_src(Source { file_id, ast }, db)).collect()) 52 Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect())
60 } 53 }
61 54
62 pub fn is_simple_atom(&self, name: &str) -> bool { 55 pub fn is_simple_atom(&self, name: &str) -> bool {
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 95d503325..7a6c7b301 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -8,9 +8,7 @@
8//! actually true. 8//! actually true.
9 9
10pub mod db; 10pub mod db;
11pub mod either;
12pub mod attr; 11pub mod attr;
13pub mod name;
14pub mod path; 12pub mod path;
15pub mod type_ref; 13pub mod type_ref;
16 14
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 86b4fef96..86c05d602 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -2,21 +2,20 @@
2 2
3use std::{ops::Index, sync::Arc}; 3use std::{ops::Index, sync::Arc};
4 4
5use hir_expand::{ast_id_map::AstIdMap, db::AstDatabase}; 5use hir_expand::{
6 ast_id_map::AstIdMap,
7 db::AstDatabase,
8 either::Either,
9 hygiene::Hygiene,
10 name::{AsName, Name},
11};
6use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 12use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
7use ra_syntax::{ 13use ra_syntax::{
8 ast::{self, AttrsOwner, NameOwner}, 14 ast::{self, AttrsOwner, NameOwner},
9 AstNode, AstPtr, SourceFile, 15 AstNode, AstPtr, SourceFile,
10}; 16};
11 17
12use crate::{ 18use crate::{attr::Attr, db::DefDatabase2, path::Path, FileAstId, HirFileId, ModuleSource, Source};
13 attr::Attr,
14 db::DefDatabase2,
15 either::Either,
16 name::{AsName, Name},
17 path::Path,
18 FileAstId, HirFileId, ModuleSource, Source,
19};
20 19
21/// `RawItems` is a set of top-level items in a file (except for impls). 20/// `RawItems` is a set of top-level items in a file (except for impls).
22/// 21///
@@ -40,10 +39,8 @@ pub struct ImportSourceMap {
40type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; 39type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
41type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>; 40type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>;
42 41
43impl ImportSourcePtr { 42fn to_node(ptr: ImportSourcePtr, file: &SourceFile) -> ImportSource {
44 fn to_node(self, file: &SourceFile) -> ImportSource { 43 ptr.map(|ptr| ptr.to_node(file.syntax()), |ptr| ptr.to_node(file.syntax()))
45 self.map(|ptr| ptr.to_node(file.syntax()), |ptr| ptr.to_node(file.syntax()))
46 }
47} 44}
48 45
49impl ImportSourceMap { 46impl ImportSourceMap {
@@ -57,7 +54,7 @@ impl ImportSourceMap {
57 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), 54 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
58 }; 55 };
59 56
60 self.map[import].to_node(&file) 57 to_node(self.map[import], &file)
61 } 58 }
62} 59}
63 60
@@ -78,7 +75,7 @@ impl RawItems {
78 source_ast_id_map: db.ast_id_map(file_id), 75 source_ast_id_map: db.ast_id_map(file_id),
79 source_map: ImportSourceMap::default(), 76 source_map: ImportSourceMap::default(),
80 file_id, 77 file_id,
81 db, 78 hygiene: Hygiene::new(db, file_id),
82 }; 79 };
83 if let Some(node) = db.parse_or_expand(file_id) { 80 if let Some(node) = db.parse_or_expand(file_id) {
84 if let Some(source_file) = ast::SourceFile::cast(node.clone()) { 81 if let Some(source_file) = ast::SourceFile::cast(node.clone()) {
@@ -204,15 +201,15 @@ pub struct MacroData {
204 pub export: bool, 201 pub export: bool,
205} 202}
206 203
207struct RawItemsCollector<DB> { 204struct RawItemsCollector {
208 raw_items: RawItems, 205 raw_items: RawItems,
209 source_ast_id_map: Arc<AstIdMap>, 206 source_ast_id_map: Arc<AstIdMap>,
210 source_map: ImportSourceMap, 207 source_map: ImportSourceMap,
211 file_id: HirFileId, 208 file_id: HirFileId,
212 db: DB, 209 hygiene: Hygiene,
213} 210}
214 211
215impl<DB: AstDatabase> RawItemsCollector<&DB> { 212impl RawItemsCollector {
216 fn process_module(&mut self, current_module: Option<Module>, body: impl ast::ModuleItemOwner) { 213 fn process_module(&mut self, current_module: Option<Module>, body: impl ast::ModuleItemOwner) {
217 for item_or_macro in body.items_with_macros() { 214 for item_or_macro in body.items_with_macros() {
218 match item_or_macro { 215 match item_or_macro {
@@ -309,9 +306,10 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
309 let is_prelude = use_item.has_atom_attr("prelude_import"); 306 let is_prelude = use_item.has_atom_attr("prelude_import");
310 let attrs = self.parse_attrs(&use_item); 307 let attrs = self.parse_attrs(&use_item);
311 308
309 let mut buf = Vec::new();
312 Path::expand_use_item( 310 Path::expand_use_item(
313 Source { ast: use_item, file_id: self.file_id }, 311 Source { ast: use_item, file_id: self.file_id },
314 self.db, 312 &self.hygiene,
315 |path, use_tree, is_glob, alias| { 313 |path, use_tree, is_glob, alias| {
316 let import_data = ImportData { 314 let import_data = ImportData {
317 path, 315 path,
@@ -321,14 +319,12 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
321 is_extern_crate: false, 319 is_extern_crate: false,
322 is_macro_use: false, 320 is_macro_use: false,
323 }; 321 };
324 self.push_import( 322 buf.push((import_data, Either::A(AstPtr::new(use_tree))));
325 current_module,
326 attrs.clone(),
327 import_data,
328 Either::A(AstPtr::new(use_tree)),
329 );
330 }, 323 },
331 ) 324 );
325 for (import_data, ptr) in buf {
326 self.push_import(current_module, attrs.clone(), import_data, ptr);
327 }
332 } 328 }
333 329
334 fn add_extern_crate_item( 330 fn add_extern_crate_item(
@@ -361,10 +357,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
361 357
362 fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) { 358 fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) {
363 let attrs = self.parse_attrs(&m); 359 let attrs = self.parse_attrs(&m);
364 let path = match m 360 let path = match m.path().and_then(|path| Path::from_src(path, &self.hygiene)) {
365 .path()
366 .and_then(|path| Path::from_src(Source { ast: path, file_id: self.file_id }, self.db))
367 {
368 Some(it) => it, 361 Some(it) => it,
369 _ => return, 362 _ => return,
370 }; 363 };
@@ -402,6 +395,6 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
402 } 395 }
403 396
404 fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { 397 fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
405 Attr::from_attrs_owner(self.file_id, item, self.db) 398 Attr::from_attrs_owner(item, &self.hygiene)
406 } 399 }
407} 400}
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index fe060437d..04039376f 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -2,18 +2,18 @@
2 2
3use std::{iter, sync::Arc}; 3use std::{iter, sync::Arc};
4 4
5use hir_expand::db::AstDatabase; 5use hir_expand::{
6 either::Either,
7 hygiene::Hygiene,
8 name::{self, AsName, Name},
9};
6use ra_db::CrateId; 10use ra_db::CrateId;
7use ra_syntax::{ 11use ra_syntax::{
8 ast::{self, NameOwner, TypeAscriptionOwner}, 12 ast::{self, NameOwner, TypeAscriptionOwner},
9 AstNode, 13 AstNode,
10}; 14};
11 15
12use crate::{ 16use crate::{type_ref::TypeRef, Source};
13 name::{self, AsName, Name},
14 type_ref::TypeRef,
15 Source,
16};
17 17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)] 18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
19pub struct Path { 19pub struct Path {
@@ -68,11 +68,11 @@ impl Path {
68 /// Calls `cb` with all paths, represented by this use item. 68 /// Calls `cb` with all paths, represented by this use item.
69 pub fn expand_use_item( 69 pub fn expand_use_item(
70 item_src: Source<ast::UseItem>, 70 item_src: Source<ast::UseItem>,
71 db: &impl AstDatabase, 71 hygiene: &Hygiene,
72 mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), 72 mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>),
73 ) { 73 ) {
74 if let Some(tree) = item_src.ast.use_tree() { 74 if let Some(tree) = item_src.ast.use_tree() {
75 expand_use_tree(None, tree, &|| item_src.file_id.macro_crate(db), &mut cb); 75 expand_use_tree(None, tree, hygiene, &mut cb);
76 } 76 }
77 } 77 }
78 78
@@ -89,17 +89,12 @@ impl Path {
89 /// Converts an `ast::Path` to `Path`. Works with use trees. 89 /// Converts an `ast::Path` to `Path`. Works with use trees.
90 /// DEPRECATED: It does not handle `$crate` from macro call. 90 /// DEPRECATED: It does not handle `$crate` from macro call.
91 pub fn from_ast(path: ast::Path) -> Option<Path> { 91 pub fn from_ast(path: ast::Path) -> Option<Path> {
92 Path::parse(path, &|| None) 92 Path::from_src(path, &Hygiene::new_unhygienic())
93 } 93 }
94 94
95 /// Converts an `ast::Path` to `Path`. Works with use trees. 95 /// Converts an `ast::Path` to `Path`. Works with use trees.
96 /// It correctly handles `$crate` based path from macro call. 96 /// It correctly handles `$crate` based path from macro call.
97 pub fn from_src(source: Source<ast::Path>, db: &impl AstDatabase) -> Option<Path> { 97 pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
98 let file_id = source.file_id;
99 Path::parse(source.ast, &|| file_id.macro_crate(db))
100 }
101
102 fn parse(mut path: ast::Path, macro_crate: &impl Fn() -> Option<CrateId>) -> Option<Path> {
103 let mut kind = PathKind::Plain; 98 let mut kind = PathKind::Plain;
104 let mut segments = Vec::new(); 99 let mut segments = Vec::new();
105 loop { 100 loop {
@@ -110,26 +105,28 @@ impl Path {
110 } 105 }
111 106
112 match segment.kind()? { 107 match segment.kind()? {
113 ast::PathSegmentKind::Name(name) => { 108 ast::PathSegmentKind::Name(name_ref) => {
114 if name.text() == "$crate" { 109 // FIXME: this should just return name
115 if let Some(macro_crate) = macro_crate() { 110 match hygiene.name_ref_to_name(name_ref) {
116 kind = PathKind::DollarCrate(macro_crate); 111 Either::A(name) => {
112 let args = segment
113 .type_arg_list()
114 .and_then(GenericArgs::from_ast)
115 .or_else(|| {
116 GenericArgs::from_fn_like_path_ast(
117 segment.param_list(),
118 segment.ret_type(),
119 )
120 })
121 .map(Arc::new);
122 let segment = PathSegment { name, args_and_bindings: args };
123 segments.push(segment);
124 }
125 Either::B(crate_id) => {
126 kind = PathKind::DollarCrate(crate_id);
117 break; 127 break;
118 } 128 }
119 } 129 }
120
121 let args = segment
122 .type_arg_list()
123 .and_then(GenericArgs::from_ast)
124 .or_else(|| {
125 GenericArgs::from_fn_like_path_ast(
126 segment.param_list(),
127 segment.ret_type(),
128 )
129 })
130 .map(Arc::new);
131 let segment = PathSegment { name: name.as_name(), args_and_bindings: args };
132 segments.push(segment);
133 } 130 }
134 ast::PathSegmentKind::Type { type_ref, trait_ref } => { 131 ast::PathSegmentKind::Type { type_ref, trait_ref } => {
135 assert!(path.qualifier().is_none()); // this can only occur at the first segment 132 assert!(path.qualifier().is_none()); // this can only occur at the first segment
@@ -143,7 +140,7 @@ impl Path {
143 } 140 }
144 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo 141 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
145 Some(trait_ref) => { 142 Some(trait_ref) => {
146 let path = Path::parse(trait_ref.path()?, macro_crate)?; 143 let path = Path::from_src(trait_ref.path()?, hygiene)?;
147 kind = path.kind; 144 kind = path.kind;
148 let mut prefix_segments = path.segments; 145 let mut prefix_segments = path.segments;
149 prefix_segments.reverse(); 146 prefix_segments.reverse();
@@ -294,8 +291,8 @@ impl From<Name> for Path {
294fn expand_use_tree( 291fn expand_use_tree(
295 prefix: Option<Path>, 292 prefix: Option<Path>,
296 tree: ast::UseTree, 293 tree: ast::UseTree,
297 macro_crate: &impl Fn() -> Option<CrateId>, 294 hygiene: &Hygiene,
298 cb: &mut impl FnMut(Path, &ast::UseTree, bool, Option<Name>), 295 cb: &mut dyn FnMut(Path, &ast::UseTree, bool, Option<Name>),
299) { 296) {
300 if let Some(use_tree_list) = tree.use_tree_list() { 297 if let Some(use_tree_list) = tree.use_tree_list() {
301 let prefix = match tree.path() { 298 let prefix = match tree.path() {
@@ -303,13 +300,13 @@ fn expand_use_tree(
303 None => prefix, 300 None => prefix,
304 // E.g. `use something::{inner}` (prefix is `None`, path is `something`) 301 // E.g. `use something::{inner}` (prefix is `None`, path is `something`)
305 // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) 302 // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
306 Some(path) => match convert_path(prefix, path, macro_crate) { 303 Some(path) => match convert_path(prefix, path, hygiene) {
307 Some(it) => Some(it), 304 Some(it) => Some(it),
308 None => return, // FIXME: report errors somewhere 305 None => return, // FIXME: report errors somewhere
309 }, 306 },
310 }; 307 };
311 for child_tree in use_tree_list.use_trees() { 308 for child_tree in use_tree_list.use_trees() {
312 expand_use_tree(prefix.clone(), child_tree, macro_crate, cb); 309 expand_use_tree(prefix.clone(), child_tree, hygiene, cb);
313 } 310 }
314 } else { 311 } else {
315 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); 312 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name());
@@ -326,7 +323,7 @@ fn expand_use_tree(
326 } 323 }
327 } 324 }
328 } 325 }
329 if let Some(path) = convert_path(prefix, ast_path, macro_crate) { 326 if let Some(path) = convert_path(prefix, ast_path, hygiene) {
330 let is_glob = tree.has_star(); 327 let is_glob = tree.has_star();
331 cb(path, &tree, is_glob, alias) 328 cb(path, &tree, is_glob, alias)
332 } 329 }
@@ -336,37 +333,36 @@ fn expand_use_tree(
336 } 333 }
337} 334}
338 335
339fn convert_path( 336fn convert_path(prefix: Option<Path>, path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
340 prefix: Option<Path>,
341 path: ast::Path,
342 macro_crate: &impl Fn() -> Option<CrateId>,
343) -> Option<Path> {
344 let prefix = if let Some(qual) = path.qualifier() { 337 let prefix = if let Some(qual) = path.qualifier() {
345 Some(convert_path(prefix, qual, macro_crate)?) 338 Some(convert_path(prefix, qual, hygiene)?)
346 } else { 339 } else {
347 prefix 340 prefix
348 }; 341 };
349 342
350 let segment = path.segment()?; 343 let segment = path.segment()?;
351 let res = match segment.kind()? { 344 let res = match segment.kind()? {
352 ast::PathSegmentKind::Name(name) => { 345 ast::PathSegmentKind::Name(name_ref) => {
353 if name.text() == "$crate" { 346 match hygiene.name_ref_to_name(name_ref) {
354 if let Some(krate) = macro_crate() { 347 Either::A(name) => {
348 // no type args in use
349 let mut res = prefix.unwrap_or_else(|| Path {
350 kind: PathKind::Plain,
351 segments: Vec::with_capacity(1),
352 });
353 res.segments.push(PathSegment {
354 name,
355 args_and_bindings: None, // no type args in use
356 });
357 res
358 }
359 Either::B(crate_id) => {
355 return Some(Path::from_simple_segments( 360 return Some(Path::from_simple_segments(
356 PathKind::DollarCrate(krate), 361 PathKind::DollarCrate(crate_id),
357 iter::empty(), 362 iter::empty(),
358 )); 363 ))
359 } 364 }
360 } 365 }
361
362 // no type args in use
363 let mut res = prefix
364 .unwrap_or_else(|| Path { kind: PathKind::Plain, segments: Vec::with_capacity(1) });
365 res.segments.push(PathSegment {
366 name: name.as_name(),
367 args_and_bindings: None, // no type args in use
368 });
369 res
370 } 366 }
371 ast::PathSegmentKind::CrateKw => { 367 ast::PathSegmentKind::CrateKw => {
372 if prefix.is_some() { 368 if prefix.is_some() {
@@ -395,8 +391,9 @@ fn convert_path(
395} 391}
396 392
397pub mod known { 393pub mod known {
394 use hir_expand::name;
395
398 use super::{Path, PathKind}; 396 use super::{Path, PathKind};
399 use crate::name;
400 397
401 pub fn std_iter_into_iterator() -> Path { 398 pub fn std_iter_into_iterator() -> Path {
402 Path::from_simple_segments( 399 Path::from_simple_segments(
diff --git a/crates/ra_hir_def/src/either.rs b/crates/ra_hir_expand/src/either.rs
index 83583ef8b..83583ef8b 100644
--- a/crates/ra_hir_def/src/either.rs
+++ b/crates/ra_hir_expand/src/either.rs
diff --git a/crates/ra_hir_expand/src/hygiene.rs b/crates/ra_hir_expand/src/hygiene.rs
new file mode 100644
index 000000000..77428ec99
--- /dev/null
+++ b/crates/ra_hir_expand/src/hygiene.rs
@@ -0,0 +1,46 @@
1//! This modules handles hygiene information.
2//!
3//! Specifically, `ast` + `Hygiene` allows you to create a `Name`. Note that, at
4//! this moment, this is horribly incomplete and handles only `$crate`.
5use ra_db::CrateId;
6use ra_syntax::ast;
7
8use crate::{
9 db::AstDatabase,
10 either::Either,
11 name::{AsName, Name},
12 HirFileId, HirFileIdRepr,
13};
14
15#[derive(Debug)]
16pub struct Hygiene {
17 // This is what `$crate` expands to
18 def_crate: Option<CrateId>,
19}
20
21impl Hygiene {
22 pub fn new(db: &impl AstDatabase, file_id: HirFileId) -> Hygiene {
23 let def_crate = match file_id.0 {
24 HirFileIdRepr::FileId(_) => None,
25 HirFileIdRepr::MacroFile(macro_file) => {
26 let loc = db.lookup_intern_macro(macro_file.macro_call_id);
27 Some(loc.def.krate)
28 }
29 };
30 Hygiene { def_crate }
31 }
32
33 pub fn new_unhygienic() -> Hygiene {
34 Hygiene { def_crate: None }
35 }
36
37 // FIXME: this should just return name
38 pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either<Name, CrateId> {
39 if let Some(def_crate) = self.def_crate {
40 if name_ref.text() == "$crate" {
41 return Either::B(def_crate);
42 }
43 }
44 Either::A(name_ref.as_name())
45 }
46}
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 3c0ef8f1c..5a0e5a19c 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -6,6 +6,9 @@
6 6
7pub mod db; 7pub mod db;
8pub mod ast_id_map; 8pub mod ast_id_map;
9pub mod either;
10pub mod name;
11pub mod hygiene;
9 12
10use std::hash::{Hash, Hasher}; 13use std::hash::{Hash, Hasher};
11 14
@@ -59,17 +62,6 @@ impl HirFileId {
59 } 62 }
60 } 63 }
61 } 64 }
62
63 /// Get the crate which the macro lives in, if it is a macro file.
64 pub fn macro_crate(self, db: &dyn db::AstDatabase) -> Option<CrateId> {
65 match self.0 {
66 HirFileIdRepr::FileId(_) => None,
67 HirFileIdRepr::MacroFile(macro_file) => {
68 let loc = db.lookup_intern_macro(macro_file.macro_call_id);
69 Some(loc.def.krate)
70 }
71 }
72 }
73} 65}
74 66
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 67#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/crates/ra_hir_def/src/name.rs b/crates/ra_hir_expand/src/name.rs
index 720896ee8..720896ee8 100644
--- a/crates/ra_hir_def/src/name.rs
+++ b/crates/ra_hir_expand/src/name.rs