From 70dd70b1fcbbbe2e60849412412ef05e7d31eb0a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 13 Nov 2019 09:56:33 +0300 Subject: Reduce duplication between uncertain floats & ints --- crates/ra_hir/src/lib.rs | 4 +--- crates/ra_hir/src/ty.rs | 6 +++--- crates/ra_hir/src/ty/infer.rs | 28 +++++++++++---------------- crates/ra_hir/src/ty/infer/expr.rs | 30 ++++++++++++++--------------- crates/ra_hir/src/ty/lower.rs | 14 +++++++------- crates/ra_hir/src/ty/method_resolution.rs | 11 +++++------ crates/ra_hir/src/ty/primitive.rs | 32 +++++++++++++------------------ 7 files changed, 55 insertions(+), 70 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 92d71b9e8..5ba847d35 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -77,9 +77,7 @@ pub use crate::{ source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, ty::{ display::HirDisplay, - primitive::{ - FloatBitness, FloatTy, IntBitness, IntTy, Signedness, UncertainFloatTy, UncertainIntTy, - }, + primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, }, }; diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 6f24cfad6..ff6030ac4 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -21,7 +21,7 @@ use crate::{ expr::ExprId, generics::{GenericParams, HasGenericParams}, util::make_mut_slice, - Adt, Crate, DefWithBody, Mutability, Name, Trait, TypeAlias, + Adt, Crate, DefWithBody, FloatTy, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -47,10 +47,10 @@ pub enum TypeCtor { Char, /// A primitive integer type. For example, `i32`. - Int(primitive::UncertainIntTy), + Int(Uncertain), /// A primitive floating-point type. For example, `f64`. - Float(primitive::UncertainFloatTy), + Float(Uncertain), /// Structures, enumerations and unions. Adt(Adt), diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index f17c6c614..c09260864 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -31,10 +31,10 @@ use ra_prof::profile; use test_utils::tested_by; use super::{ - lower, primitive, + lower, traits::{Guidance, Obligation, ProjectionPredicate, Solution}, ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, - TypeCtor, TypeWalk, + TypeCtor, TypeWalk, Uncertain, }; use crate::{ adt::VariantDef, @@ -43,7 +43,7 @@ use crate::{ expr::{BindingAnnotation, Body, ExprId, PatId}, resolve::{Resolver, TypeNs}, ty::infer::diagnostics::InferenceDiagnostic, - Adt, AssocItem, ConstData, DefWithBody, FnData, Function, Path, StructField, + Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, IntTy, Path, StructField, }; macro_rules! ty_app { @@ -358,14 +358,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { match ty { Ty::Unknown => self.new_type_var(), - Ty::Apply(ApplicationTy { - ctor: TypeCtor::Int(primitive::UncertainIntTy::Unknown), - .. - }) => self.new_integer_var(), - Ty::Apply(ApplicationTy { - ctor: TypeCtor::Float(primitive::UncertainFloatTy::Unknown), - .. - }) => self.new_float_var(), + Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(Uncertain::Unknown), .. }) => { + self.new_integer_var() + } + Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(Uncertain::Unknown), .. }) => { + self.new_float_var() + } _ => ty, } } @@ -684,12 +682,8 @@ impl InferTy { fn fallback_value(self) -> Ty { match self { InferTy::TypeVar(..) => Ty::Unknown, - InferTy::IntVar(..) => { - Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(primitive::IntTy::i32()))) - } - InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float( - primitive::UncertainFloatTy::Known(primitive::FloatTy::f64()), - )), + InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(Uncertain::Known(IntTy::i32()))), + InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(Uncertain::Known(FloatTy::f64()))), InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), } } diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index c6802487a..5e68a1678 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -3,7 +3,10 @@ use std::iter::{repeat, repeat_with}; use std::sync::Arc; -use hir_def::path::{GenericArg, GenericArgs}; +use hir_def::{ + builtin_type::Signedness, + path::{GenericArg, GenericArgs}, +}; use hir_expand::name; use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; @@ -12,8 +15,9 @@ use crate::{ expr::{self, Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, generics::{GenericParams, HasGenericParams}, ty::{ - autoderef, method_resolution, op, primitive, CallableDef, InferTy, Mutability, Namespace, + autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, + Uncertain, }, Adt, Name, }; @@ -337,13 +341,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { UnaryOp::Neg => { match &inner_ty { Ty::Apply(a_ty) => match a_ty.ctor { - TypeCtor::Int(primitive::UncertainIntTy::Unknown) - | TypeCtor::Int(primitive::UncertainIntTy::Known( - primitive::IntTy { - signedness: primitive::Signedness::Signed, - .. - }, - )) + TypeCtor::Int(Uncertain::Unknown) + | TypeCtor::Int(Uncertain::Known(IntTy { + signedness: Signedness::Signed, + .. + })) | TypeCtor::Float(..) => inner_ty, _ => Ty::Unknown, }, @@ -428,9 +430,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ); self.infer_expr( *repeat, - &Expectation::has_type(Ty::simple(TypeCtor::Int( - primitive::UncertainIntTy::Known(primitive::IntTy::usize()), - ))), + &Expectation::has_type(Ty::simple(TypeCtor::Int(Uncertain::Known( + IntTy::usize(), + )))), ); } } @@ -443,9 +445,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) } Literal::ByteString(..) => { - let byte_type = Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known( - primitive::IntTy::u8(), - ))); + let byte_type = Ty::simple(TypeCtor::Int(Uncertain::Known(IntTy::u8()))); let slice_type = Ty::apply_one(TypeCtor::Slice, byte_type); Ty::apply_one(TypeCtor::Ref(Mutability::Shared), slice_type) } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 1832fcf50..de3c56097 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -25,7 +25,7 @@ use crate::{ generics::{GenericDef, WherePredicate}, resolve::{Resolver, TypeNs}, ty::{ - primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, + primitive::{FloatTy, IntTy, Uncertain}, Adt, }, util::make_mut_slice, @@ -674,20 +674,20 @@ impl From for FloatTy { } } -impl From> for UncertainIntTy { +impl From> for Uncertain { fn from(t: Option) -> Self { match t { - None => UncertainIntTy::Unknown, - Some(t) => UncertainIntTy::Known(t.into()), + None => Uncertain::Unknown, + Some(t) => Uncertain::Known(t.into()), } } } -impl From> for UncertainFloatTy { +impl From> for Uncertain { fn from(t: Option) -> Self { match t { - None => UncertainFloatTy::Unknown, - Some(t) => UncertainFloatTy::Known(t.into()), + None => Uncertain::Unknown, + Some(t) => Uncertain::Known(t.into()), } } } diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 8c3d32d09..eb5ca6769 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -8,16 +8,17 @@ use arrayvec::ArrayVec; use hir_def::CrateModuleId; use rustc_hash::FxHashMap; -use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; use crate::{ db::HirDatabase, impl_block::{ImplBlock, ImplId}, resolve::Resolver, - ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy}, + ty::primitive::{FloatBitness, Uncertain}, ty::{Ty, TypeCtor}, AssocItem, Crate, Function, Module, Mutability, Name, Trait, }; +use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; + /// This is used as a key for indexing impls. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum TyFingerprint { @@ -140,14 +141,12 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option Some(std::iter::once(def_id.krate(db)?).collect()), TypeCtor::Bool => lang_item_crate!(db, cur_crate, "bool"), TypeCtor::Char => lang_item_crate!(db, cur_crate, "char"), - TypeCtor::Float(UncertainFloatTy::Known(f)) => match f.bitness { + TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) FloatBitness::X32 => lang_item_crate!(db, cur_crate, "f32", "f32_runtime"), FloatBitness::X64 => lang_item_crate!(db, cur_crate, "f64", "f64_runtime"), }, - TypeCtor::Int(UncertainIntTy::Known(i)) => { - lang_item_crate!(db, cur_crate, i.ty_to_string()) - } + TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(db, cur_crate, i.ty_to_string()), TypeCtor::Str => lang_item_crate!(db, cur_crate, "str_alloc", "str"), TypeCtor::Slice => lang_item_crate!(db, cur_crate, "slice_alloc", "slice"), TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!(db, cur_crate, "const_ptr"), diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 7362de4c3..47789db87 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs @@ -4,44 +4,38 @@ use std::fmt; pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness}; -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum UncertainIntTy { +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] +pub enum Uncertain { Unknown, - Known(IntTy), + Known(T), } -impl From for UncertainIntTy { +impl From for Uncertain { fn from(ty: IntTy) -> Self { - UncertainIntTy::Known(ty) + Uncertain::Known(ty) } } -impl fmt::Display for UncertainIntTy { +impl fmt::Display for Uncertain { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - UncertainIntTy::Unknown => write!(f, "{{integer}}"), - UncertainIntTy::Known(ty) => write!(f, "{}", ty), + Uncertain::Unknown => write!(f, "{{integer}}"), + Uncertain::Known(ty) => write!(f, "{}", ty), } } } -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum UncertainFloatTy { - Unknown, - Known(FloatTy), -} - -impl From for UncertainFloatTy { +impl From for Uncertain { fn from(ty: FloatTy) -> Self { - UncertainFloatTy::Known(ty) + Uncertain::Known(ty) } } -impl fmt::Display for UncertainFloatTy { +impl fmt::Display for Uncertain { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - UncertainFloatTy::Unknown => write!(f, "{{float}}"), - UncertainFloatTy::Known(ty) => write!(f, "{}", ty), + Uncertain::Unknown => write!(f, "{{float}}"), + Uncertain::Known(ty) => write!(f, "{}", ty), } } } -- cgit v1.2.3 From b8f62095d6cf07ba521cdb3f7bac147496b313c9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:09:42 +0300 Subject: Normalize data No need to store derivable info --- crates/ra_hir/src/expr/scope.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index 0e49a28d6..fe5e836f2 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs @@ -17,7 +17,6 @@ impl_arena_id!(ScopeId); #[derive(Debug, PartialEq, Eq)] pub struct ExprScopes { - pub(crate) body: Arc, scopes: Arena, scope_by_expr: FxHashMap, } @@ -47,19 +46,16 @@ pub(crate) struct ScopeData { impl ExprScopes { pub(crate) fn expr_scopes_query(db: &impl HirDatabase, def: DefWithBody) -> Arc { let body = db.body(def); - let res = ExprScopes::new(body); + let res = ExprScopes::new(&*body); Arc::new(res) } - fn new(body: Arc) -> ExprScopes { - let mut scopes = ExprScopes { - body: body.clone(), - scopes: Arena::default(), - scope_by_expr: FxHashMap::default(), - }; + fn new(body: &Body) -> ExprScopes { + let mut scopes = + ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() }; let root = scopes.root_scope(); - scopes.add_params_bindings(root, body.params()); - compute_expr_scopes(body.body_expr(), &body, &mut scopes, root); + scopes.add_params_bindings(body, root, body.params()); + compute_expr_scopes(body.body_expr(), body, &mut scopes, root); scopes } @@ -99,9 +95,8 @@ impl ExprScopes { } } - fn add_params_bindings(&mut self, scope: ScopeId, params: &[PatId]) { - let body = Arc::clone(&self.body); - params.iter().for_each(|pat| self.add_bindings(&body, scope, *pat)); + fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId]) { + params.iter().for_each(|pat| self.add_bindings(body, scope, *pat)); } fn set_scope(&mut self, node: ExprId, scope: ScopeId) { @@ -151,7 +146,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope } Expr::Lambda { args, body: body_expr, .. } => { let scope = scopes.new_scope(scope); - scopes.add_params_bindings(scope, &args); + scopes.add_params_bindings(body, scope, &args); compute_expr_scopes(*body_expr, body, scopes, scope); } Expr::Match { expr, arms } => { -- cgit v1.2.3 From b3175b7077129ca4b6c52e05f0491e65617ae423 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:37:33 +0300 Subject: Move current file to MacroResolver --- crates/ra_hir/src/expr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 82955fa55..d1af8ee39 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -40,8 +40,8 @@ pub(crate) fn body_with_source_map_query( (src.file_id, src.ast.body()) } }; - let resolver = hir_def::body::MacroResolver::new(db, def.module(db).id); - let (body, source_map) = Body::new(db, resolver, file_id, params, body); + let resolver = hir_def::body::MacroResolver::new(db, file_id, def.module(db).id); + let (body, source_map) = Body::new(db, resolver, params, body); (Arc::new(body), Arc::new(source_map)) } -- cgit v1.2.3 From 8c8ef1432e1891809f48ff691f949047d6527c07 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:38:25 +0300 Subject: Rename MacroResolver -> Expander --- crates/ra_hir/src/expr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index d1af8ee39..d19f5d14c 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -40,8 +40,8 @@ pub(crate) fn body_with_source_map_query( (src.file_id, src.ast.body()) } }; - let resolver = hir_def::body::MacroResolver::new(db, file_id, def.module(db).id); - let (body, source_map) = Body::new(db, resolver, params, 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)) } -- cgit v1.2.3 From da2ca01ebaaaaa47aa09c5848c53b145a68af8fa Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 10:30:30 +0300 Subject: Handle macro-generated expressions slightly less wrong --- crates/ra_hir/src/expr/scope.rs | 6 +++++- crates/ra_hir/src/from_source.rs | 3 ++- crates/ra_hir/src/source_binder.rs | 44 +++++++++++++++++++++++++++----------- 3 files changed, 38 insertions(+), 15 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index fe5e836f2..afba66069 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs @@ -166,6 +166,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope #[cfg(test)] mod tests { + use hir_expand::Source; use ra_db::{fixture::WithFixture, SourceDatabase}; use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; use test_utils::{assert_eq_text, extract_offset}; @@ -189,7 +190,10 @@ mod tests { let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); let scopes = analyzer.scopes(); - let expr_id = analyzer.body_source_map().node_expr(&marker.into()).unwrap(); + let expr_id = analyzer + .body_source_map() + .node_expr(Source { file_id: file_id.into(), ast: &marker.into() }) + .unwrap(); let scope = scopes.scope_for(expr_id); let actual = scopes diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 2c441b0f4..4b561c63d 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -145,7 +145,8 @@ impl Local { Some(res) })?; let (_body, source_map) = db.body_with_source_map(parent); - let pat_id = source_map.node_pat(&src.ast.into())?; + 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 f28e9c931..88eed1137 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -7,8 +7,11 @@ //! purely for "IDE needs". use std::sync::Arc; -use hir_def::path::known; -use hir_expand::name::AsName; +use hir_def::{ + expr::{ExprId, PatId}, + path::known, +}; +use hir_expand::{name::AsName, Source}; use ra_db::FileId; use ra_syntax::{ ast::{self, AstNode}, @@ -93,6 +96,8 @@ fn def_with_body_from_child_node( /// original source files. It should not be used inside the HIR itself. #[derive(Debug)] pub struct SourceAnalyzer { + // FIXME: this doesn't handle macros at all + file_id: FileId, resolver: Resolver, body_owner: Option, body_source_map: Option>, @@ -147,7 +152,7 @@ impl SourceAnalyzer { let source_map = def.body_source_map(db); let scopes = db.expr_scopes(def); let scope = match offset { - None => scope_for(&scopes, &source_map, &node), + None => scope_for(&scopes, &source_map, file_id.into(), &node), Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset), }; let resolver = expr::resolver_for_scope(db, def, scope); @@ -157,6 +162,7 @@ impl SourceAnalyzer { body_source_map: Some(source_map), infer: Some(def.infer(db)), scopes: Some(scopes), + file_id, } } else { SourceAnalyzer { @@ -168,17 +174,28 @@ impl SourceAnalyzer { body_source_map: None, infer: None, scopes: None, + file_id, } } } + fn expr_id(&self, expr: &ast::Expr) -> Option { + let src = Source { file_id: self.file_id.into(), ast: expr }; + self.body_source_map.as_ref()?.node_expr(src) + } + + fn pat_id(&self, pat: &ast::Pat) -> Option { + let src = Source { file_id: self.file_id.into(), ast: pat }; + self.body_source_map.as_ref()?.node_pat(src) + } + pub fn type_of(&self, _db: &impl HirDatabase, expr: &ast::Expr) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(expr)?; + let expr_id = self.expr_id(expr)?; Some(self.infer.as_ref()?[expr_id].clone()) } pub fn type_of_pat(&self, _db: &impl HirDatabase, pat: &ast::Pat) -> Option { - let pat_id = self.body_source_map.as_ref()?.node_pat(pat)?; + let pat_id = self.pat_id(pat)?; Some(self.infer.as_ref()?[pat_id].clone()) } @@ -191,22 +208,22 @@ impl SourceAnalyzer { } pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(&call.clone().into())?; + let expr_id = self.expr_id(&call.clone().into())?; self.infer.as_ref()?.method_resolution(expr_id) } pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(&field.clone().into())?; + let expr_id = self.expr_id(&field.clone().into())?; self.infer.as_ref()?.field_resolution(expr_id) } pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(&record_lit.clone().into())?; + let expr_id = self.expr_id(&record_lit.clone().into())?; self.infer.as_ref()?.variant_resolution_for_expr(expr_id) } pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option { - let pat_id = self.body_source_map.as_ref()?.node_pat(&record_pat.clone().into())?; + let pat_id = self.pat_id(&record_pat.clone().into())?; self.infer.as_ref()?.variant_resolution_for_pat(pat_id) } @@ -264,13 +281,13 @@ impl SourceAnalyzer { pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option { if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { - let expr_id = self.body_source_map.as_ref()?.node_expr(&path_expr.into())?; + let expr_id = self.expr_id(&path_expr.into())?; if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { return Some(PathResolution::AssocItem(assoc)); } } if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { - let pat_id = self.body_source_map.as_ref()?.node_pat(&path_pat.into())?; + let pat_id = self.pat_id(&path_pat.into())?; if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { return Some(PathResolution::AssocItem(assoc)); } @@ -285,7 +302,7 @@ impl SourceAnalyzer { let name = name_ref.as_name(); let source_map = self.body_source_map.as_ref()?; let scopes = self.scopes.as_ref()?; - let scope = scope_for(scopes, source_map, name_ref.syntax()); + let scope = scope_for(scopes, source_map, self.file_id.into(), name_ref.syntax()); let ret = scopes .scope_chain(scope) .flat_map(|scope| scopes.entries(scope).iter()) @@ -418,11 +435,12 @@ impl SourceAnalyzer { fn scope_for( scopes: &ExprScopes, source_map: &BodySourceMap, + file_id: HirFileId, node: &SyntaxNode, ) -> Option { node.ancestors() .filter_map(ast::Expr::cast) - .filter_map(|it| source_map.node_expr(&it)) + .filter_map(|it| source_map.node_expr(Source { file_id, ast: &it })) .find_map(|it| scopes.scope_for(it)) } -- cgit v1.2.3 From f924ae3b86dc5e978071b6f8308b9f357415780b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 11:56:13 +0300 Subject: Move scopes to hir_def --- crates/ra_hir/src/db.rs | 2 +- crates/ra_hir/src/expr.rs | 204 ++++++++++++++++++++- crates/ra_hir/src/expr/scope.rs | 353 ------------------------------------- crates/ra_hir/src/resolve.rs | 5 +- crates/ra_hir/src/source_binder.rs | 6 +- 5 files changed, 202 insertions(+), 368 deletions(-) delete mode 100644 crates/ra_hir/src/expr/scope.rs (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 9ac811232..14f6b5df4 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -85,7 +85,7 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { #[salsa::query_group(HirDatabaseStorage)] #[salsa::requires(salsa::Database)] pub trait HirDatabase: DefDatabase + AstDatabase { - #[salsa::invoke(ExprScopes::expr_scopes_query)] + #[salsa::invoke(crate::expr::expr_scopes_query)] fn expr_scopes(&self, def: DefWithBody) -> Arc; #[salsa::invoke(crate::ty::infer_query)] diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index d19f5d14c..f02104b2d 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -1,6 +1,5 @@ //! FIXME: write short doc here -pub(crate) mod scope; pub(crate) mod validation; use std::sync::Arc; @@ -9,10 +8,11 @@ use ra_syntax::{ast, AstPtr}; use crate::{db::HirDatabase, DefWithBody, HasSource, Resolver}; -pub use self::scope::ExprScopes; - pub use hir_def::{ - body::{Body, BodySourceMap, ExprPtr, ExprSource, PatPtr, PatSource}, + body::{ + scope::{ExprScopes, ScopeEntry, ScopeId}, + Body, BodySourceMap, ExprPtr, ExprSource, PatPtr, PatSource, + }, expr::{ ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, @@ -49,6 +49,11 @@ 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, @@ -62,7 +67,7 @@ pub(crate) fn resolver_for_expr( pub(crate) fn resolver_for_scope( db: &impl HirDatabase, owner: DefWithBody, - scope_id: Option, + scope_id: Option, ) -> Resolver { let mut r = owner.resolver(db); let scopes = db.expr_scopes(owner); @@ -72,3 +77,192 @@ pub(crate) fn resolver_for_scope( } r } + +#[cfg(test)] +mod tests { + use hir_expand::Source; + use ra_db::{fixture::WithFixture, SourceDatabase}; + use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; + use test_utils::{assert_eq_text, extract_offset}; + + use crate::{source_binder::SourceAnalyzer, test_db::TestDB}; + + fn do_check(code: &str, expected: &[&str]) { + let (off, code) = extract_offset(code); + let code = { + let mut buf = String::new(); + let off = u32::from(off) as usize; + buf.push_str(&code[..off]); + buf.push_str("marker"); + buf.push_str(&code[off..]); + buf + }; + + let (db, file_id) = TestDB::with_single_file(&code); + + let file = db.parse(file_id).ok().unwrap(); + let marker: ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); + let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); + + let scopes = analyzer.scopes(); + let expr_id = analyzer + .body_source_map() + .node_expr(Source { file_id: file_id.into(), ast: &marker.into() }) + .unwrap(); + let scope = scopes.scope_for(expr_id); + + let actual = scopes + .scope_chain(scope) + .flat_map(|scope| scopes.entries(scope)) + .map(|it| it.name().to_string()) + .collect::>() + .join("\n"); + let expected = expected.join("\n"); + assert_eq_text!(&expected, &actual); + } + + #[test] + fn test_lambda_scope() { + do_check( + r" + fn quux(foo: i32) { + let f = |bar, baz: i32| { + <|> + }; + }", + &["bar", "baz", "foo"], + ); + } + + #[test] + fn test_call_scope() { + do_check( + r" + fn quux() { + f(|x| <|> ); + }", + &["x"], + ); + } + + #[test] + fn test_method_call_scope() { + do_check( + r" + fn quux() { + z.f(|x| <|> ); + }", + &["x"], + ); + } + + #[test] + fn test_loop_scope() { + do_check( + r" + fn quux() { + loop { + let x = (); + <|> + }; + }", + &["x"], + ); + } + + #[test] + fn test_match() { + do_check( + r" + fn quux() { + match () { + Some(x) => { + <|> + } + }; + }", + &["x"], + ); + } + + #[test] + fn test_shadow_variable() { + do_check( + r" + fn foo(x: String) { + let x : &str = &x<|>; + }", + &["x"], + ); + } + + fn do_check_local_name(code: &str, expected_offset: u32) { + let (off, code) = extract_offset(code); + + let (db, file_id) = TestDB::with_single_file(&code); + let file = db.parse(file_id).ok().unwrap(); + let expected_name = find_node_at_offset::(file.syntax(), expected_offset.into()) + .expect("failed to find a name at the target offset"); + let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); + let analyzer = SourceAnalyzer::new(&db, file_id, name_ref.syntax(), None); + + let local_name_entry = analyzer.resolve_local_name(&name_ref).unwrap(); + let local_name = + local_name_entry.ptr().either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); + assert_eq!(local_name.range(), expected_name.syntax().text_range()); + } + + #[test] + fn test_resolve_local_name() { + do_check_local_name( + r#" + fn foo(x: i32, y: u32) { + { + let z = x * 2; + } + { + let t = x<|> * 3; + } + }"#, + 21, + ); + } + + #[test] + fn test_resolve_local_name_declaration() { + do_check_local_name( + r#" + fn foo(x: String) { + let x : &str = &x<|>; + }"#, + 21, + ); + } + + #[test] + fn test_resolve_local_name_shadow() { + do_check_local_name( + r" + fn foo(x: String) { + let x : &str = &x; + x<|> + } + ", + 53, + ); + } + + #[test] + fn ref_patterns_contribute_bindings() { + do_check_local_name( + r" + fn foo() { + if let Some(&from) = bar() { + from<|>; + } + } + ", + 53, + ); + } +} diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs deleted file mode 100644 index afba66069..000000000 --- a/crates/ra_hir/src/expr/scope.rs +++ /dev/null @@ -1,353 +0,0 @@ -//! FIXME: write short doc here - -use std::sync::Arc; - -use ra_arena::{impl_arena_id, Arena, RawId}; -use rustc_hash::FxHashMap; - -use crate::{ - db::HirDatabase, - expr::{Body, Expr, ExprId, Pat, PatId, Statement}, - DefWithBody, Name, -}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ScopeId(RawId); -impl_arena_id!(ScopeId); - -#[derive(Debug, PartialEq, Eq)] -pub struct ExprScopes { - scopes: Arena, - scope_by_expr: FxHashMap, -} - -#[derive(Debug, PartialEq, Eq)] -pub(crate) struct ScopeEntry { - name: Name, - pat: PatId, -} - -impl ScopeEntry { - pub(crate) fn name(&self) -> &Name { - &self.name - } - - pub(crate) fn pat(&self) -> PatId { - self.pat - } -} - -#[derive(Debug, PartialEq, Eq)] -pub(crate) struct ScopeData { - parent: Option, - entries: Vec, -} - -impl ExprScopes { - pub(crate) fn expr_scopes_query(db: &impl HirDatabase, def: DefWithBody) -> Arc { - let body = db.body(def); - let res = ExprScopes::new(&*body); - Arc::new(res) - } - - fn new(body: &Body) -> ExprScopes { - let mut scopes = - ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() }; - let root = scopes.root_scope(); - scopes.add_params_bindings(body, root, body.params()); - compute_expr_scopes(body.body_expr(), body, &mut scopes, root); - scopes - } - - pub(crate) fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { - &self.scopes[scope].entries - } - - pub(crate) fn scope_chain(&self, scope: Option) -> impl Iterator + '_ { - std::iter::successors(scope, move |&scope| self.scopes[scope].parent) - } - - pub(crate) fn scope_for(&self, expr: ExprId) -> Option { - self.scope_by_expr.get(&expr).copied() - } - - pub(crate) fn scope_by_expr(&self) -> &FxHashMap { - &self.scope_by_expr - } - - fn root_scope(&mut self) -> ScopeId { - self.scopes.alloc(ScopeData { parent: None, entries: vec![] }) - } - - fn new_scope(&mut self, parent: ScopeId) -> ScopeId { - self.scopes.alloc(ScopeData { parent: Some(parent), entries: vec![] }) - } - - fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { - match &body[pat] { - Pat::Bind { name, .. } => { - // bind can have a sub pattern, but it's actually not allowed - // to bind to things in there - let entry = ScopeEntry { name: name.clone(), pat }; - self.scopes[scope].entries.push(entry) - } - p => p.walk_child_pats(|pat| self.add_bindings(body, scope, pat)), - } - } - - fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId]) { - params.iter().for_each(|pat| self.add_bindings(body, scope, *pat)); - } - - fn set_scope(&mut self, node: ExprId, scope: ScopeId) { - self.scope_by_expr.insert(node, scope); - } -} - -fn compute_block_scopes( - statements: &[Statement], - tail: Option, - body: &Body, - scopes: &mut ExprScopes, - mut scope: ScopeId, -) { - for stmt in statements { - match stmt { - Statement::Let { pat, initializer, .. } => { - if let Some(expr) = initializer { - scopes.set_scope(*expr, scope); - compute_expr_scopes(*expr, body, scopes, scope); - } - scope = scopes.new_scope(scope); - scopes.add_bindings(body, scope, *pat); - } - Statement::Expr(expr) => { - scopes.set_scope(*expr, scope); - compute_expr_scopes(*expr, body, scopes, scope); - } - } - } - if let Some(expr) = tail { - compute_expr_scopes(expr, body, scopes, scope); - } -} - -fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) { - scopes.set_scope(expr, scope); - match &body[expr] { - Expr::Block { statements, tail } => { - compute_block_scopes(&statements, *tail, body, scopes, scope); - } - Expr::For { iterable, pat, body: body_expr } => { - compute_expr_scopes(*iterable, body, scopes, scope); - let scope = scopes.new_scope(scope); - scopes.add_bindings(body, scope, *pat); - compute_expr_scopes(*body_expr, body, scopes, scope); - } - Expr::Lambda { args, body: body_expr, .. } => { - let scope = scopes.new_scope(scope); - scopes.add_params_bindings(body, scope, &args); - compute_expr_scopes(*body_expr, body, scopes, scope); - } - Expr::Match { expr, arms } => { - compute_expr_scopes(*expr, body, scopes, scope); - for arm in arms { - let scope = scopes.new_scope(scope); - for pat in &arm.pats { - scopes.add_bindings(body, scope, *pat); - } - scopes.set_scope(arm.expr, scope); - compute_expr_scopes(arm.expr, body, scopes, scope); - } - } - e => e.walk_child_exprs(|e| compute_expr_scopes(e, body, scopes, scope)), - }; -} - -#[cfg(test)] -mod tests { - use hir_expand::Source; - use ra_db::{fixture::WithFixture, SourceDatabase}; - use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; - use test_utils::{assert_eq_text, extract_offset}; - - use crate::{source_binder::SourceAnalyzer, test_db::TestDB}; - - fn do_check(code: &str, expected: &[&str]) { - let (off, code) = extract_offset(code); - let code = { - let mut buf = String::new(); - let off = u32::from(off) as usize; - buf.push_str(&code[..off]); - buf.push_str("marker"); - buf.push_str(&code[off..]); - buf - }; - - let (db, file_id) = TestDB::with_single_file(&code); - let file = db.parse(file_id).ok().unwrap(); - let marker: ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); - let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); - - let scopes = analyzer.scopes(); - let expr_id = analyzer - .body_source_map() - .node_expr(Source { file_id: file_id.into(), ast: &marker.into() }) - .unwrap(); - let scope = scopes.scope_for(expr_id); - - let actual = scopes - .scope_chain(scope) - .flat_map(|scope| scopes.entries(scope)) - .map(|it| it.name().to_string()) - .collect::>() - .join("\n"); - let expected = expected.join("\n"); - assert_eq_text!(&expected, &actual); - } - - #[test] - fn test_lambda_scope() { - do_check( - r" - fn quux(foo: i32) { - let f = |bar, baz: i32| { - <|> - }; - }", - &["bar", "baz", "foo"], - ); - } - - #[test] - fn test_call_scope() { - do_check( - r" - fn quux() { - f(|x| <|> ); - }", - &["x"], - ); - } - - #[test] - fn test_method_call_scope() { - do_check( - r" - fn quux() { - z.f(|x| <|> ); - }", - &["x"], - ); - } - - #[test] - fn test_loop_scope() { - do_check( - r" - fn quux() { - loop { - let x = (); - <|> - }; - }", - &["x"], - ); - } - - #[test] - fn test_match() { - do_check( - r" - fn quux() { - match () { - Some(x) => { - <|> - } - }; - }", - &["x"], - ); - } - - #[test] - fn test_shadow_variable() { - do_check( - r" - fn foo(x: String) { - let x : &str = &x<|>; - }", - &["x"], - ); - } - - fn do_check_local_name(code: &str, expected_offset: u32) { - let (off, code) = extract_offset(code); - - let (db, file_id) = TestDB::with_single_file(&code); - let file = db.parse(file_id).ok().unwrap(); - let expected_name = find_node_at_offset::(file.syntax(), expected_offset.into()) - .expect("failed to find a name at the target offset"); - let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); - let analyzer = SourceAnalyzer::new(&db, file_id, name_ref.syntax(), None); - - let local_name_entry = analyzer.resolve_local_name(&name_ref).unwrap(); - let local_name = - local_name_entry.ptr().either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); - assert_eq!(local_name.range(), expected_name.syntax().text_range()); - } - - #[test] - fn test_resolve_local_name() { - do_check_local_name( - r#" - fn foo(x: i32, y: u32) { - { - let z = x * 2; - } - { - let t = x<|> * 3; - } - }"#, - 21, - ); - } - - #[test] - fn test_resolve_local_name_declaration() { - do_check_local_name( - r#" - fn foo(x: String) { - let x : &str = &x<|>; - }"#, - 21, - ); - } - - #[test] - fn test_resolve_local_name_shadow() { - do_check_local_name( - r" - fn foo(x: String) { - let x : &str = &x; - x<|> - } - ", - 53, - ); - } - - #[test] - fn ref_patterns_contribute_bindings() { - do_check_local_name( - r" - fn foo() { - if let Some(&from) = bar() { - from<|>; - } - } - ", - 53, - ); - } -} diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index b932b0c8c..2f3e12eb8 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -13,10 +13,7 @@ use rustc_hash::FxHashSet; use crate::{ code_model::Crate, db::{DefDatabase, HirDatabase}, - expr::{ - scope::{ExprScopes, ScopeId}, - PatId, - }, + expr::{ExprScopes, PatId, ScopeId}, generics::GenericParams, impl_block::ImplBlock, Adt, Const, Enum, EnumVariant, Function, MacroDef, ModuleDef, PerNs, Static, Struct, Trait, diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 88eed1137..e337a3d4a 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -23,11 +23,7 @@ use rustc_hash::FxHashSet; use crate::{ db::HirDatabase, - expr::{ - self, - scope::{ExprScopes, ScopeId}, - BodySourceMap, - }, + expr::{self, BodySourceMap, ExprScopes, ScopeId}, ids::LocationCtx, resolve::{ScopeDef, TypeNs, ValueNs}, ty::method_resolution::{self, implements_trait}, -- cgit v1.2.3 From 1583ab1558022d0fdbbc10d3a440a2d3daa4a840 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 17:37:22 +0300 Subject: Move body queries to hir_def --- crates/ra_hir/src/code_model.rs | 28 +++++++++++++++-------- crates/ra_hir/src/db.rs | 19 +++++----------- crates/ra_hir/src/expr.rs | 43 ++++-------------------------------- crates/ra_hir/src/from_id.rs | 14 ++++++++++-- crates/ra_hir/src/from_source.rs | 4 ++-- crates/ra_hir/src/source_binder.rs | 2 +- crates/ra_hir/src/ty/infer.rs | 5 +++-- crates/ra_hir/src/ty/traits/chalk.rs | 4 ++-- 8 files changed, 48 insertions(+), 71 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 2fd4ccb10..962d5a8c1 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 14f6b5df4..c60029c01 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 f02104b2d..9262325f2 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 089dbc908..9633ef586 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 4b561c63d..9793af858 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 e337a3d4a..ca40e3b54 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 c09260864..c35378cc4 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 de322dd52..75351c17d 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); -- cgit v1.2.3