diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 2fd4ccb109..962d5a8c15 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use hir_def::{ adt::VariantData, + body::scope::ExprScopes, builtin_type::BuiltinType, type_ref::{Mutability, TypeRef}, CrateModuleId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, @@ -539,6 +540,7 @@ pub trait HasBody: Copy { fn infer(self, db: &impl HirDatabase) -> Arc; fn body(self, db: &impl HirDatabase) -> Arc; fn body_source_map(self, db: &impl HirDatabase) -> Arc; + fn expr_scopes(self, db: &impl HirDatabase) -> Arc; } impl HasBody for T @@ -550,11 +552,15 @@ where } fn body(self, db: &impl HirDatabase) -> Arc { - db.body(self.into()) + self.into().body(db) } fn body_source_map(self, db: &impl HirDatabase) -> Arc { - db.body_with_source_map(self.into()).1 + self.into().body_source_map(db) + } + + fn expr_scopes(self, db: &impl HirDatabase) -> Arc { + self.into().expr_scopes(db) } } @@ -564,11 +570,15 @@ impl HasBody for DefWithBody { } fn body(self, db: &impl HirDatabase) -> Arc { - db.body(self) + db.body(self.into()) } fn body_source_map(self, db: &impl HirDatabase) -> Arc { - db.body_with_source_map(self).1 + db.body_with_source_map(self.into()).1 + } + + fn expr_scopes(self, db: &impl HirDatabase) -> Arc { + db.expr_scopes(self.into()) } } @@ -662,11 +672,11 @@ impl Function { } pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc { - db.body_with_source_map(self.into()).1 + db.body_with_source_map(self.id.into()).1 } pub fn body(self, db: &impl HirDatabase) -> Arc { - db.body(self.into()) + db.body(self.id.into()) } pub fn ty(self, db: &impl HirDatabase) -> Ty { @@ -1079,7 +1089,7 @@ pub struct Local { impl Local { pub fn name(self, db: &impl HirDatabase) -> Option { - let body = db.body(self.parent); + let body = self.parent.body(db); match &body[self.pat_id] { Pat::Bind { name, .. } => Some(name.clone()), _ => None, @@ -1091,7 +1101,7 @@ impl Local { } pub fn is_mut(self, db: &impl HirDatabase) -> bool { - let body = db.body(self.parent); + let body = self.parent.body(db); match &body[self.pat_id] { Pat::Bind { mode, .. } => match mode { BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, @@ -1115,7 +1125,7 @@ impl Local { } pub fn source(self, db: &impl HirDatabase) -> Source> { - let (_body, source_map) = db.body_with_source_map(self.parent); + let source_map = self.parent.body_source_map(db); let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... let root = src.file_syntax(db); src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 14f6b5df41..c60029c018 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -8,7 +8,6 @@ use ra_syntax::SmolStr; use crate::{ debug::HirDebugDatabase, - expr::{Body, BodySourceMap}, generics::{GenericDef, GenericParams}, ids, impl_block::{ImplBlock, ImplSourceMap, ModuleImplBlocks}, @@ -19,13 +18,14 @@ use crate::{ InferenceResult, Namespace, Substs, Ty, TypableDef, TypeCtor, }, type_alias::TypeAliasData, - Const, ConstData, Crate, DefWithBody, ExprScopes, FnData, Function, Module, Static, - StructField, Trait, TypeAlias, + Const, ConstData, Crate, DefWithBody, FnData, Function, Module, Static, StructField, Trait, + TypeAlias, }; pub use hir_def::db::{ - CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, EnumDataQuery, InternDatabase, - InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, + BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, + EnumDataQuery, ExprScopesQuery, InternDatabase, InternDatabaseStorage, RawItemsQuery, + RawItemsWithSourceMapQuery, StructDataQuery, }; pub use hir_expand::db::{ AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, @@ -85,9 +85,6 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { #[salsa::query_group(HirDatabaseStorage)] #[salsa::requires(salsa::Database)] pub trait HirDatabase: DefDatabase + AstDatabase { - #[salsa::invoke(crate::expr::expr_scopes_query)] - fn expr_scopes(&self, def: DefWithBody) -> Arc; - #[salsa::invoke(crate::ty::infer_query)] fn infer(&self, def: DefWithBody) -> Arc; @@ -113,12 +110,6 @@ pub trait HirDatabase: DefDatabase + AstDatabase { #[salsa::invoke(crate::ty::generic_defaults_query)] fn generic_defaults(&self, def: GenericDef) -> Substs; - #[salsa::invoke(crate::expr::body_with_source_map_query)] - fn body_with_source_map(&self, def: DefWithBody) -> (Arc, Arc); - - #[salsa::invoke(crate::expr::body_query)] - fn body(&self, def: DefWithBody) -> Arc; - #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] fn impls_in_crate(&self, krate: Crate) -> Arc; diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index f02104b2d7..9262325f23 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -4,9 +4,9 @@ pub(crate) mod validation; use std::sync::Arc; -use ra_syntax::{ast, AstPtr}; +use ra_syntax::AstPtr; -use crate::{db::HirDatabase, DefWithBody, HasSource, Resolver}; +use crate::{db::HirDatabase, DefWithBody, HasBody, Resolver}; pub use hir_def::{ body::{ @@ -19,48 +19,13 @@ pub use hir_def::{ }, }; -pub(crate) fn body_with_source_map_query( - db: &impl HirDatabase, - def: DefWithBody, -) -> (Arc, Arc) { - let mut params = None; - - let (file_id, body) = match def { - DefWithBody::Function(f) => { - let src = f.source(db); - params = src.ast.param_list(); - (src.file_id, src.ast.body().map(ast::Expr::from)) - } - DefWithBody::Const(c) => { - let src = c.source(db); - (src.file_id, src.ast.body()) - } - DefWithBody::Static(s) => { - let src = s.source(db); - (src.file_id, src.ast.body()) - } - }; - let expander = hir_def::body::Expander::new(db, file_id, def.module(db).id); - let (body, source_map) = Body::new(db, expander, params, body); - (Arc::new(body), Arc::new(source_map)) -} - -pub(crate) fn body_query(db: &impl HirDatabase, def: DefWithBody) -> Arc { - db.body_with_source_map(def).0 -} - -pub(crate) fn expr_scopes_query(db: &impl HirDatabase, def: DefWithBody) -> Arc { - let body = db.body(def); - Arc::new(ExprScopes::new(&*body)) -} - // needs arbitrary_self_types to be a method... or maybe move to the def? pub(crate) fn resolver_for_expr( db: &impl HirDatabase, owner: DefWithBody, expr_id: ExprId, ) -> Resolver { - let scopes = db.expr_scopes(owner); + let scopes = owner.expr_scopes(db); resolver_for_scope(db, owner, scopes.scope_for(expr_id)) } @@ -70,7 +35,7 @@ pub(crate) fn resolver_for_scope( scope_id: Option, ) -> Resolver { let mut r = owner.resolver(db); - let scopes = db.expr_scopes(owner); + let scopes = owner.expr_scopes(db); let scope_chain = scopes.scope_chain(scope_id).collect::>(); for scope in scope_chain.into_iter().rev() { r = r.push_expr_scope(Arc::clone(&scopes), scope); diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 089dbc9084..9633ef5861 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -3,9 +3,9 @@ //! It's unclear if we need this long-term, but it's definitelly useful while we //! are splitting the hir. -use hir_def::{AdtId, EnumVariantId, ModuleDefId}; +use hir_def::{AdtId, DefWithBodyId, EnumVariantId, ModuleDefId}; -use crate::{Adt, EnumVariant, ModuleDef}; +use crate::{Adt, DefWithBody, EnumVariant, ModuleDef}; macro_rules! from_id { ($(($id:path, $ty:path)),*) => {$( @@ -61,3 +61,13 @@ impl From for ModuleDef { } } } + +impl From for DefWithBodyId { + fn from(def: DefWithBody) -> Self { + match def { + DefWithBody::Function(it) => DefWithBodyId::FunctionId(it.id), + DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id), + DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id), + } + } +} diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 4b561c63de..9793af8587 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -10,7 +10,7 @@ use ra_syntax::{ use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, ids::{AstItemDef, LocationCtx}, - AstId, Const, Crate, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, + AstId, Const, Crate, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock, Local, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, }; @@ -144,7 +144,7 @@ impl Local { }; Some(res) })?; - let (_body, source_map) = db.body_with_source_map(parent); + let source_map = parent.body_source_map(db); let src = src.map(ast::Pat::from); let pat_id = source_map.node_pat(src.as_ref())?; Some(Local { parent, pat_id }) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index e337a3d4a5..ca40e3b544 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -146,7 +146,7 @@ impl SourceAnalyzer { let def_with_body = def_with_body_from_child_node(db, file_id, node); if let Some(def) = def_with_body { let source_map = def.body_source_map(db); - let scopes = db.expr_scopes(def); + let scopes = def.expr_scopes(db); let scope = match offset { None => scope_for(&scopes, &source_map, file_id.into(), &node), Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset), diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c092608642..c35378cc41 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -43,7 +43,8 @@ use crate::{ expr::{BindingAnnotation, Body, ExprId, PatId}, resolve::{Resolver, TypeNs}, ty::infer::diagnostics::InferenceDiagnostic, - Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, IntTy, Path, StructField, + Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, + StructField, }; macro_rules! ty_app { @@ -214,7 +215,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), db, owner, - body: db.body(owner), + body: owner.body(db), resolver, } } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index de322dd523..75351c17d5 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -22,7 +22,7 @@ use crate::{ ApplicationTy, GenericPredicate, Namespace, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, }, - AssocItem, Crate, ImplBlock, Trait, TypeAlias, + AssocItem, Crate, HasBody, ImplBlock, Trait, TypeAlias, }; /// This represents a trait whose name we could not resolve. @@ -714,7 +714,7 @@ fn closure_fn_trait_impl_datum( let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; let trait_ = get_fn_trait(db, krate, data.fn_trait)?; // get corresponding fn trait - let num_args: u16 = match &db.body(data.def)[data.expr] { + let num_args: u16 = match &data.def.body(db)[data.expr] { crate::expr::Expr::Lambda { args, .. } => args.len() as u16, _ => { log::warn!("closure for closure type {:?} not found", data); diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index c3e9d0c235..85dc4feb0a 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -17,7 +17,7 @@ use crate::{ expr::{Expr, ExprId, Pat, PatId}, nameres::CrateDefMap, path::Path, - ModuleId, + AstItemDef, DefWithBodyId, ModuleId, }; pub struct Expander { @@ -141,7 +141,37 @@ pub struct BodySourceMap { } impl Body { - pub fn new( + pub(crate) fn body_with_source_map_query( + db: &impl DefDatabase2, + def: DefWithBodyId, + ) -> (Arc, Arc) { + let mut params = None; + + let (file_id, module, body) = match def { + DefWithBodyId::FunctionId(f) => { + let src = f.source(db); + params = src.ast.param_list(); + (src.file_id, f.module(db), src.ast.body().map(ast::Expr::from)) + } + DefWithBodyId::ConstId(c) => { + let src = c.source(db); + (src.file_id, c.module(db), src.ast.body()) + } + DefWithBodyId::StaticId(s) => { + let src = s.source(db); + (src.file_id, s.module(db), src.ast.body()) + } + }; + let expander = Expander::new(db, file_id, module); + let (body, source_map) = Body::new(db, expander, params, body); + (Arc::new(body), Arc::new(source_map)) + } + + pub(crate) fn body_query(db: &impl DefDatabase2, def: DefWithBodyId) -> Arc { + db.body_with_source_map(def).0 + } + + fn new( db: &impl DefDatabase2, expander: Expander, params: Option, diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index dd8d06d112..09a39e721e 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs @@ -1,4 +1,5 @@ //! FIXME: write short doc here +use std::sync::Arc; use hir_expand::name::Name; use ra_arena::{impl_arena_id, Arena, RawId}; @@ -6,7 +7,9 @@ use rustc_hash::FxHashMap; use crate::{ body::Body, + db::DefDatabase2, expr::{Expr, ExprId, Pat, PatId, Statement}, + DefWithBodyId, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -42,7 +45,12 @@ pub struct ScopeData { } impl ExprScopes { - pub fn new(body: &Body) -> ExprScopes { + pub(crate) fn expr_scopes_query(db: &impl DefDatabase2, def: DefWithBodyId) -> Arc { + let body = db.body(def); + Arc::new(ExprScopes::new(&*body)) + } + + fn new(body: &Body) -> ExprScopes { let mut scopes = ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() }; let root = scopes.root_scope(); diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 29cf71a594..40b5920d9b 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -7,11 +7,12 @@ use ra_syntax::ast; use crate::{ adt::{EnumData, StructData}, + body::{scope::ExprScopes, Body, BodySourceMap}, nameres::{ raw::{ImportSourceMap, RawItems}, CrateDefMap, }, - EnumId, StructOrUnionId, + DefWithBodyId, EnumId, StructOrUnionId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -52,4 +53,13 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { #[salsa::invoke(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; + + #[salsa::invoke(Body::body_with_source_map_query)] + fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc, Arc); + + #[salsa::invoke(Body::body_query)] + fn body(&self, def: DefWithBodyId) -> Arc; + + #[salsa::invoke(ExprScopes::expr_scopes_query)] + fn expr_scopes(&self, def: DefWithBodyId) -> Arc; } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 4a758bb835..3fab7965ca 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -374,3 +374,13 @@ impl_froms!( TypeAliasId, BuiltinType ); + +/// The defs which have a body. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum DefWithBodyId { + FunctionId(FunctionId), + StaticId(StaticId), + ConstId(ConstId), +} + +impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 4952bd1891..f06191963f 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs @@ -40,24 +40,24 @@ pub(crate) fn literal(p: &mut Parser) -> Option { // E.g. for after the break in `if break {}`, this should not match pub(super) const ATOM_EXPR_FIRST: TokenSet = LITERAL_FIRST.union(paths::PATH_FIRST).union(token_set![ - L_PAREN, - L_CURLY, - L_BRACK, - PIPE, - MOVE_KW, - BOX_KW, - IF_KW, - WHILE_KW, - MATCH_KW, - UNSAFE_KW, - RETURN_KW, - BREAK_KW, - CONTINUE_KW, + T!['('], + T!['{'], + T!['['], + T![|], + T![move], + T![box], + T![if], + T![while], + T![match], + T![unsafe], + T![return], + T![break], + T![continue], + T![async], + T![try], + T![loop], + T![for], LIFETIME, - ASYNC_KW, - TRY_KW, - LOOP_KW, - FOR_KW, ]); const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; diff --git a/crates/ra_parser/src/token_set.rs b/crates/ra_parser/src/token_set.rs index 6dc061889f..2a6952c013 100644 --- a/crates/ra_parser/src/token_set.rs +++ b/crates/ra_parser/src/token_set.rs @@ -30,8 +30,8 @@ const fn mask(kind: SyntaxKind) -> u128 { #[macro_export] macro_rules! token_set { - ($($t:ident),*) => { TokenSet::empty()$(.union(TokenSet::singleton($t)))* }; - ($($t:ident),* ,) => { token_set!($($t),*) }; + ($($t:expr),*) => { TokenSet::empty()$(.union(TokenSet::singleton($t)))* }; + ($($t:expr),* ,) => { token_set!($($t),*) }; } #[test]