From dadad36bb9770f9b13ed84bc219ea0168a7a5bf1 Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Mon, 18 Nov 2019 18:02:28 +0100 Subject: Move type inlay hint truncation to language server This commit implements a general truncation framework for HirFormatter that keeps track of how much has been output so far. This information can then be used to perform truncation inside the language server, instead of relying on the client. Initial support is implemented for truncating types hints using the maxInlayHintLength server config option. The existing solution in the VSCode extension has been removed in favor of letting the server truncate type hints. --- crates/ra_hir/src/ty.rs | 20 +++++++++++++++++++ crates/ra_hir/src/ty/display.rs | 43 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index b7f50b714..776613c7c 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -800,6 +800,10 @@ impl HirDisplay for &Ty { impl HirDisplay for ApplicationTy { fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + if f.should_truncate() { + return write!(f, "…"); + } + match self.ctor { TypeCtor::Bool => write!(f, "bool")?, TypeCtor::Char => write!(f, "char")?, @@ -901,6 +905,10 @@ impl HirDisplay for ApplicationTy { impl HirDisplay for ProjectionTy { fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + if f.should_truncate() { + return write!(f, "…"); + } + let trait_name = self .associated_ty .parent_trait(f.db) @@ -919,6 +927,10 @@ impl HirDisplay for ProjectionTy { impl HirDisplay for Ty { fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + if f.should_truncate() { + return write!(f, "…"); + } + match self { Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, @@ -1001,6 +1013,10 @@ impl HirDisplay for Ty { impl TraitRef { fn hir_fmt_ext(&self, f: &mut HirFormatter, use_as: bool) -> fmt::Result { + if f.should_truncate() { + return write!(f, "…"); + } + self.substs[0].hir_fmt(f)?; if use_as { write!(f, " as ")?; @@ -1031,6 +1047,10 @@ impl HirDisplay for &GenericPredicate { impl HirDisplay for GenericPredicate { fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + if f.should_truncate() { + return write!(f, "…"); + } + match self { GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, GenericPredicate::Projection(projection_pred) => { diff --git a/crates/ra_hir/src/ty/display.rs b/crates/ra_hir/src/ty/display.rs index 7910429d7..9bb3ece6c 100644 --- a/crates/ra_hir/src/ty/display.rs +++ b/crates/ra_hir/src/ty/display.rs @@ -7,15 +7,30 @@ use crate::db::HirDatabase; pub struct HirFormatter<'a, 'b, DB> { pub db: &'a DB, fmt: &'a mut fmt::Formatter<'b>, + buf: String, + curr_size: usize, + max_size: Option, } pub trait HirDisplay { fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result; + fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self> where Self: Sized, { - HirDisplayWrapper(db, self) + HirDisplayWrapper(db, self, None) + } + + fn display_truncated<'a, DB>( + &'a self, + db: &'a DB, + max_size: Option, + ) -> HirDisplayWrapper<'a, DB, Self> + where + Self: Sized, + { + HirDisplayWrapper(db, self, max_size) } } @@ -41,11 +56,25 @@ where /// This allows using the `write!` macro directly with a `HirFormatter`. pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { - fmt::write(self.fmt, args) + // We write to a buffer first to track output size + self.buf.clear(); + fmt::write(&mut self.buf, args)?; + self.curr_size += self.buf.len(); + + // Then we write to the internal formatter from the buffer + self.fmt.write_str(&self.buf) + } + + pub fn should_truncate(&self) -> bool { + if let Some(max_size) = self.max_size { + self.curr_size >= max_size + } else { + false + } } } -pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T); +pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option); impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> where @@ -53,6 +82,12 @@ where T: HirDisplay, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.1.hir_fmt(&mut HirFormatter { db: self.0, fmt: f }) + self.1.hir_fmt(&mut HirFormatter { + db: self.0, + fmt: f, + buf: String::with_capacity(20), + curr_size: 0, + max_size: self.2, + }) } } -- cgit v1.2.3 From 36e3fc9d5413f7e6e17e82867aae1318645880a3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 09:40:36 +0300 Subject: Rename Source::ast -> Source::value --- crates/ra_hir/src/code_model.rs | 14 ++++++------- crates/ra_hir/src/code_model/attrs.rs | 6 +++--- crates/ra_hir/src/code_model/docs.rs | 24 +++++++++++----------- crates/ra_hir/src/code_model/src.rs | 24 +++++++++++----------- crates/ra_hir/src/diagnostics.rs | 10 ++++----- crates/ra_hir/src/expr.rs | 4 ++-- crates/ra_hir/src/from_source.rs | 38 +++++++++++++++++------------------ crates/ra_hir/src/generics.rs | 16 +++++++-------- crates/ra_hir/src/lang_item.rs | 4 ++-- crates/ra_hir/src/source_binder.rs | 24 +++++++++++----------- crates/ra_hir/src/traits.rs | 6 +++--- crates/ra_hir/src/ty/tests.rs | 8 +++++--- crates/ra_hir/src/type_alias.rs | 2 +- 13 files changed, 91 insertions(+), 89 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 731cc1fff..cb990f4e2 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -139,7 +139,7 @@ impl Module { ) -> Either { let src = self.definition_source(db); let (_, source_map) = db.raw_items_with_source_map(src.file_id); - source_map.get(&src.ast, import) + source_map.get(&src.value, import) } /// Returns the crate this module is part of. @@ -206,7 +206,7 @@ impl Module { crate::ModuleDef::Function(f) => f.diagnostics(db, sink), crate::ModuleDef::Module(m) => { // Only add diagnostics from inline modules - if let ModuleSource::Module(_) = m.definition_source(db).ast { + if let ModuleSource::Module(_) = m.definition_source(db).value { m.diagnostics(db, sink) } } @@ -598,10 +598,10 @@ impl FnData { func: Function, ) -> Arc { let src = func.source(db); - let name = src.ast.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); + let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); let mut params = Vec::new(); let mut has_self_param = false; - if let Some(param_list) = src.ast.param_list() { + if let Some(param_list) = src.value.param_list() { if let Some(self_param) = param_list.self_param() { let self_type = if let Some(type_ref) = self_param.ascribed_type() { TypeRef::from_ast(type_ref) @@ -625,7 +625,7 @@ impl FnData { params.push(type_ref); } } - let ret_type = if let Some(type_ref) = src.ast.ret_type().and_then(|rt| rt.type_ref()) { + let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { TypeRef::from_ast(type_ref) } else { TypeRef::unit() @@ -801,7 +801,7 @@ impl ConstData { db: &(impl DefDatabase + AstDatabase), konst: Const, ) -> Arc { - let node = konst.source(db).ast; + let node = konst.source(db).value; const_data_for(&node) } @@ -809,7 +809,7 @@ impl ConstData { db: &(impl DefDatabase + AstDatabase), konst: Static, ) -> Arc { - let node = konst.source(db).ast; + let node = konst.source(db).value; const_data_for(&node) } } diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs index f7db36b66..9e304217c 100644 --- a/crates/ra_hir/src/code_model/attrs.rs +++ b/crates/ra_hir/src/code_model/attrs.rs @@ -49,9 +49,9 @@ pub(crate) fn attributes_query( AttrDef::Module(it) => { let src = it.declaration_source(db)?; let hygiene = Hygiene::new(db, src.file_id); - Attr::from_attrs_owner(&src.ast, &hygiene) + Attr::from_attrs_owner(&src.value, &hygiene) } - AttrDef::StructField(it) => match it.source(db).ast { + AttrDef::StructField(it) => match it.source(db).value { FieldSource::Named(named) => { let src = it.source(db); let hygiene = Hygiene::new(db, src.file_id); @@ -82,7 +82,7 @@ where { let src = node.source(db); let hygiene = Hygiene::new(db, src.file_id); - Attr::from_attrs_owner(&src.ast, &hygiene) + Attr::from_attrs_owner(&src.value, &hygiene) } impl + Copy> Attrs for T { diff --git a/crates/ra_hir/src/code_model/docs.rs b/crates/ra_hir/src/code_model/docs.rs index 8533b4f5e..e40efef34 100644 --- a/crates/ra_hir/src/code_model/docs.rs +++ b/crates/ra_hir/src/code_model/docs.rs @@ -70,23 +70,23 @@ pub(crate) fn documentation_query( def: DocDef, ) -> Option { match def { - DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.ast), - DocDef::StructField(it) => match it.source(db).ast { + DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.value), + DocDef::StructField(it) => match it.source(db).value { FieldSource::Named(named) => docs_from_ast(&named), FieldSource::Pos(..) => None, }, DocDef::Adt(it) => match it { - Adt::Struct(it) => docs_from_ast(&it.source(db).ast), - Adt::Enum(it) => docs_from_ast(&it.source(db).ast), - Adt::Union(it) => docs_from_ast(&it.source(db).ast), + Adt::Struct(it) => docs_from_ast(&it.source(db).value), + Adt::Enum(it) => docs_from_ast(&it.source(db).value), + Adt::Union(it) => docs_from_ast(&it.source(db).value), }, - DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).ast), - DocDef::Static(it) => docs_from_ast(&it.source(db).ast), - DocDef::Const(it) => docs_from_ast(&it.source(db).ast), - DocDef::Function(it) => docs_from_ast(&it.source(db).ast), - DocDef::Trait(it) => docs_from_ast(&it.source(db).ast), - DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).ast), - DocDef::MacroDef(it) => docs_from_ast(&it.source(db).ast), + DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).value), + DocDef::Static(it) => docs_from_ast(&it.source(db).value), + DocDef::Const(it) => docs_from_ast(&it.source(db).value), + DocDef::Function(it) => docs_from_ast(&it.source(db).value), + DocDef::Trait(it) => docs_from_ast(&it.source(db).value), + DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).value), + DocDef::MacroDef(it) => docs_from_ast(&it.source(db).value), } } diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 247ae3e55..556417b0f 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -25,9 +25,9 @@ impl Module { let def_map = db.crate_def_map(self.id.krate); let decl_id = def_map[self.id.module_id].declaration; let file_id = def_map[self.id.module_id].definition; - let ast = ModuleSource::new(db, file_id, decl_id); + let value = ModuleSource::new(db, file_id, decl_id); let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); - Source { file_id, ast } + Source { file_id, value } } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. @@ -38,8 +38,8 @@ impl Module { ) -> Option> { let def_map = db.crate_def_map(self.id.krate); let decl = def_map[self.id.module_id].declaration?; - let ast = decl.to_node(db); - Some(Source { file_id: decl.file_id(), ast }) + let value = decl.to_node(db); + Some(Source { file_id: decl.file_id(), value }) } } @@ -53,11 +53,11 @@ impl HasSource for StructField { let (file_id, struct_kind) = match self.parent { VariantDef::Struct(s) => { ss = s.source(db); - (ss.file_id, ss.ast.kind()) + (ss.file_id, ss.value.kind()) } VariantDef::EnumVariant(e) => { es = e.source(db); - (es.file_id, es.ast.kind()) + (es.file_id, es.value.kind()) } }; @@ -66,13 +66,13 @@ impl HasSource for StructField { ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(), ast::StructKind::Unit => Vec::new(), }; - let ast = field_sources + let value = field_sources .into_iter() .zip(fields.iter()) .find(|(_syntax, (id, _))| *id == self.id) .unwrap() .0; - Source { file_id, ast } + Source { file_id, value } } } impl HasSource for Struct { @@ -98,8 +98,8 @@ impl HasSource for EnumVariant { fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source { let enum_data = db.enum_data(self.parent.id); let src = self.parent.id.source(db); - let ast = src - .ast + let value = src + .value .variant_list() .into_iter() .flat_map(|it| it.variants()) @@ -107,7 +107,7 @@ impl HasSource for EnumVariant { .find(|(_syntax, (id, _))| *id == self.id) .unwrap() .0; - Source { file_id: src.file_id, ast } + Source { file_id: src.file_id, value } } } impl HasSource for Function { @@ -143,7 +143,7 @@ impl HasSource for TypeAlias { impl HasSource for MacroDef { type Ast = ast::MacroCall; fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source { - Source { file_id: self.id.ast_id.file_id(), ast: self.id.ast_id.to_node(db) } + Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } } } diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index 1751e7be3..7d1b64858 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs @@ -21,7 +21,7 @@ impl Diagnostic for NoSuchField { } fn source(&self) -> Source { - Source { file_id: self.file, ast: self.field.into() } + Source { file_id: self.file, value: self.field.into() } } fn as_any(&self) -> &(dyn Any + Send + 'static) { @@ -41,7 +41,7 @@ impl Diagnostic for MissingFields { "fill structure fields".to_string() } fn source(&self) -> Source { - Source { file_id: self.file, ast: self.field_list.into() } + Source { file_id: self.file, value: self.field_list.into() } } fn as_any(&self) -> &(dyn Any + Send + 'static) { self @@ -53,7 +53,7 @@ impl AstDiagnostic for MissingFields { fn ast(&self, db: &impl AstDatabase) -> Self::AST { let root = db.parse_or_expand(self.source().file_id).unwrap(); - let node = self.source().ast.to_node(&root); + let node = self.source().value.to_node(&root); ast::RecordFieldList::cast(node).unwrap() } } @@ -69,7 +69,7 @@ impl Diagnostic for MissingOkInTailExpr { "wrap return expression in Ok".to_string() } fn source(&self) -> Source { - Source { file_id: self.file, ast: self.expr.into() } + Source { file_id: self.file, value: self.expr.into() } } fn as_any(&self) -> &(dyn Any + Send + 'static) { self @@ -81,7 +81,7 @@ impl AstDiagnostic for MissingOkInTailExpr { fn ast(&self, db: &impl AstDatabase) -> Self::AST { let root = db.parse_or_expand(self.file).unwrap(); - let node = self.source().ast.to_node(&root); + let node = self.source().value.to_node(&root); ast::Expr::cast(node).unwrap() } } diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index e3733779e..8bfdda45e 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -116,7 +116,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { let source_map = self.func.body_source_map(db); if let Some(source_ptr) = source_map.expr_syntax(id) { - if let Some(expr) = source_ptr.ast.a() { + if let Some(expr) = source_ptr.value.a() { let root = source_ptr.file_syntax(db); if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) { if let Some(field_list) = record_lit.record_field_list() { @@ -161,7 +161,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { let source_map = self.func.body_source_map(db); if let Some(source_ptr) = source_map.expr_syntax(id) { - if let Some(expr) = source_ptr.ast.a() { + if let Some(expr) = source_ptr.value.a() { self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr }); } } diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 1c26756c9..f4dca25cb 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -87,7 +87,7 @@ impl FromSource for MacroDef { let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; let krate = module.krate().crate_id(); - let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.ast)); + let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value)); let id: MacroDefId = MacroDefId { krate, ast_id, kind }; Some(MacroDef { id }) @@ -105,8 +105,8 @@ impl FromSource for ImplBlock { impl FromSource for EnumVariant { type Ast = ast::EnumVariant; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let parent_enum = src.ast.parent_enum(); - let src_enum = Source { file_id: src.file_id, ast: parent_enum }; + let parent_enum = src.value.parent_enum(); + let src_enum = Source { file_id: src.file_id, value: parent_enum }; let variants = Enum::from_source(db, src_enum)?.variants(db); variants.into_iter().find(|v| v.source(db) == src) } @@ -115,16 +115,16 @@ impl FromSource for EnumVariant { impl FromSource for StructField { type Ast = FieldSource; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let variant_def: VariantDef = match src.ast { + let variant_def: VariantDef = match src.value { FieldSource::Named(ref field) => { - let ast = field.syntax().ancestors().find_map(ast::StructDef::cast)?; - let src = Source { file_id: src.file_id, ast }; + let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?; + let src = Source { file_id: src.file_id, value }; let def = Struct::from_source(db, src)?; VariantDef::from(def) } FieldSource::Pos(ref field) => { - let ast = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; - let src = Source { file_id: src.file_id, ast }; + let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; + let src = Source { file_id: src.file_id, value }; let def = EnumVariant::from_source(db, src)?; VariantDef::from(def) } @@ -142,12 +142,12 @@ impl FromSource for StructField { impl Local { pub fn from_source(db: &impl HirDatabase, src: Source) -> Option { let file_id = src.file_id; - let parent: DefWithBody = src.ast.syntax().ancestors().find_map(|it| { + let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| { let res = match_ast! { match it { - ast::ConstDef(ast) => { Const::from_source(db, Source { ast, file_id})?.into() }, - ast::StaticDef(ast) => { Static::from_source(db, Source { ast, file_id})?.into() }, - ast::FnDef(ast) => { Function::from_source(db, Source { ast, file_id})?.into() }, + ast::ConstDef(value) => { Const::from_source(db, Source { value, file_id})?.into() }, + ast::StaticDef(value) => { Static::from_source(db, Source { value, file_id})?.into() }, + ast::FnDef(value) => { Function::from_source(db, Source { value, file_id})?.into() }, _ => return None, } }; @@ -162,33 +162,33 @@ impl Local { impl Module { pub fn from_declaration(db: &impl DefDatabase, src: Source) -> Option { - let parent_declaration = src.ast.syntax().ancestors().skip(1).find_map(ast::Module::cast); + let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); let parent_module = match parent_declaration { Some(parent_declaration) => { - let src_parent = Source { file_id: src.file_id, ast: parent_declaration }; + let src_parent = Source { file_id: src.file_id, value: parent_declaration }; Module::from_declaration(db, src_parent) } _ => { let src_parent = Source { file_id: src.file_id, - ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), + value: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), }; Module::from_definition(db, src_parent) } }?; - let child_name = src.ast.name()?; + let child_name = src.value.name()?; parent_module.child(db, &child_name.as_name()) } pub fn from_definition(db: &impl DefDatabase, src: Source) -> Option { - match src.ast { + match src.value { ModuleSource::Module(ref module) => { assert!(!module.has_semi()); return Module::from_declaration( db, - Source { file_id: src.file_id, ast: module.clone() }, + Source { file_id: src.file_id, value: module.clone() }, ); } ModuleSource::SourceFile(_) => (), @@ -214,5 +214,5 @@ where let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; let ctx = LocationCtx::new(db, module.id, src.file_id); - Some(DEF::from_ast(ctx, &src.ast)) + Some(DEF::from_ast(ctx, &src.value)) } diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index c35482ae8..8925ba3a9 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs @@ -91,10 +91,10 @@ impl GenericParams { let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; // FIXME: add `: Sized` bound for everything except for `Self` in traits match def { - GenericDef::Function(it) => generics.fill(&it.source(db).ast, start), - GenericDef::Adt(Adt::Struct(it)) => generics.fill(&it.source(db).ast, start), - GenericDef::Adt(Adt::Union(it)) => generics.fill(&it.source(db).ast, start), - GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).ast, start), + GenericDef::Function(it) => generics.fill(&it.source(db).value, start), + GenericDef::Adt(Adt::Struct(it)) => generics.fill(&it.source(db).value, start), + GenericDef::Adt(Adt::Union(it)) => generics.fill(&it.source(db).value, start), + GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).value, start), GenericDef::Trait(it) => { // traits get the Self type as an implicit first type parameter generics.params.push(GenericParam { @@ -102,17 +102,17 @@ impl GenericParams { name: name::SELF_TYPE, default: None, }); - generics.fill(&it.source(db).ast, start + 1); + generics.fill(&it.source(db).value, start + 1); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name::SELF_TYPE.into()); - generics.fill_bounds(&it.source(db).ast, self_param); + generics.fill_bounds(&it.source(db).value, self_param); } - GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), + GenericDef::TypeAlias(it) => generics.fill(&it.source(db).value, start), // Note that we don't add `Self` here: in `impl`s, `Self` is not a // type-parameter, but rather is a type-alias for impl's target // type, so this is handled by the resolver. - GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start), + GenericDef::ImplBlock(it) => generics.fill(&it.source(db).value, start), GenericDef::EnumVariant(_) | GenericDef::Const(_) => {} } diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs index fa2ef8a17..89fd85f59 100644 --- a/crates/ra_hir/src/lang_item.rs +++ b/crates/ra_hir/src/lang_item.rs @@ -97,7 +97,7 @@ impl LangItems { // Look for impl targets for impl_block in module.impl_blocks(db) { let src = impl_block.source(db); - if let Some(lang_item_name) = lang_item_name(&src.ast) { + if let Some(lang_item_name) = lang_item_name(&src.value) { self.items .entry(lang_item_name) .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); @@ -144,7 +144,7 @@ impl LangItems { T: Copy + HasSource, N: AttrsOwner, { - let node = item.source(db).ast; + let node = item.source(db).value; if let Some(lang_item_name) = lang_item_name(&node) { self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 5d3196c2a..471b0b089 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -31,7 +31,7 @@ use crate::{ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option { match_ast! { - match (node.ast) { + match (node.value) { ast::Module(it) => { let src = node.with_ast(it); Some(crate::Module::from_declaration(db, src)?.resolver(db)) @@ -48,7 +48,7 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - let src = node.with_ast(it); Some(Enum::from_source(db, src)?.resolver(db)) }, - _ => match node.ast.kind() { + _ => match node.value.kind() { FN_DEF | CONST_DEF | STATIC_DEF => { Some(def_with_body_from_child_node(db, node)?.resolver(db)) } @@ -67,7 +67,7 @@ fn def_with_body_from_child_node( let module = Module::from_definition(db, Source::new(child.file_id, module_source))?; let ctx = LocationCtx::new(db, module.id, child.file_id); - child.ast.ancestors().find_map(|node| { + child.value.ancestors().find_map(|node| { match_ast! { match node { ast::FnDef(def) => { Some(Function {id: ctx.to_def(&def) }.into()) }, @@ -171,7 +171,7 @@ impl SourceAnalyzer { } else { SourceAnalyzer { resolver: node - .ast + .value .ancestors() .find_map(|it| try_get_resolver_for_node(db, node.with_ast(&it))) .unwrap_or_default(), @@ -185,12 +185,12 @@ impl SourceAnalyzer { } fn expr_id(&self, expr: &ast::Expr) -> Option { - let src = Source { file_id: self.file_id, ast: expr }; + let src = Source { file_id: self.file_id, value: 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, ast: pat }; + let src = Source { file_id: self.file_id, value: pat }; self.body_source_map.as_ref()?.node_pat(src) } @@ -302,7 +302,7 @@ impl SourceAnalyzer { let entry = scopes.resolve_name_in_scope(scope, &name)?; Some(ScopeEntryWithSyntax { name: entry.name().clone(), - ptr: source_map.pat_syntax(entry.pat())?.ast, + ptr: source_map.pat_syntax(entry.pat())?.value, }) } @@ -428,7 +428,7 @@ fn scope_for( source_map: &BodySourceMap, node: Source<&SyntaxNode>, ) -> Option { - node.ast + node.value .ancestors() .filter_map(ast::Expr::cast) .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) @@ -450,18 +450,18 @@ fn scope_for_offset( return None; } let syntax_node_ptr = - source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); + source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); Some((syntax_node_ptr, scope)) }) // find containing scope .min_by_key(|(ptr, _scope)| { ( - !(ptr.range().start() <= offset.ast && offset.ast <= ptr.range().end()), + !(ptr.range().start() <= offset.value && offset.value <= ptr.range().end()), ptr.range().len(), ) }) .map(|(ptr, scope)| { - adjust(scopes, source_map, ptr, offset.file_id, offset.ast).unwrap_or(*scope) + adjust(scopes, source_map, ptr, offset.file_id, offset.value).unwrap_or(*scope) }) } @@ -485,7 +485,7 @@ fn adjust( return None; } let syntax_node_ptr = - source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); + source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); Some((syntax_node_ptr, scope)) }) .map(|(ptr, scope)| (ptr.range(), scope)) diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs index 1a45dacba..858972c6f 100644 --- a/crates/ra_hir/src/traits.rs +++ b/crates/ra_hir/src/traits.rs @@ -26,11 +26,11 @@ impl TraitData { tr: Trait, ) -> Arc { let src = tr.source(db); - let name = src.ast.name().map(|n| n.as_name()); + let name = src.value.name().map(|n| n.as_name()); let module = tr.module(db); let ctx = LocationCtx::new(db, module.id, src.file_id); - let auto = src.ast.is_auto(); - let items = if let Some(item_list) = src.ast.item_list() { + let auto = src.value.is_auto(); + let items = if let Some(item_list) = src.value.item_list() { item_list .impl_items() .map(|item_node| match item_node { diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index ca1693679..c1024d03c 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -4694,14 +4694,16 @@ fn infer(content: &str) -> String { } // sort ranges for consistency - types.sort_by_key(|(src_ptr, _)| (src_ptr.ast.range().start(), src_ptr.ast.range().end())); + types.sort_by_key(|(src_ptr, _)| { + (src_ptr.value.range().start(), src_ptr.value.range().end()) + }); for (src_ptr, ty) in &types { - let node = src_ptr.ast.to_node(&src_ptr.file_syntax(&db)); + let node = src_ptr.value.to_node(&src_ptr.file_syntax(&db)); let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { (self_param.self_kw_token().text_range(), "self".to_string()) } else { - (src_ptr.ast.range(), node.text().to_string().replace("\n", " ")) + (src_ptr.value.range(), node.text().to_string().replace("\n", " ")) }; let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; write!( diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs index 078e6295e..392f244cf 100644 --- a/crates/ra_hir/src/type_alias.rs +++ b/crates/ra_hir/src/type_alias.rs @@ -23,7 +23,7 @@ impl TypeAliasData { db: &(impl DefDatabase + AstDatabase), typ: TypeAlias, ) -> Arc { - let node = typ.source(db).ast; + let node = typ.source(db).value; let name = node.name().map_or_else(Name::missing, |n| n.as_name()); let type_ref = node.type_ref().map(TypeRef::from_ast); Arc::new(TypeAliasData { name, type_ref }) -- cgit v1.2.3 From 0e771915faf057ec4561224b75ec9b5be93d71c8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 11:42:58 +0300 Subject: Allow non-path default type parameters --- crates/ra_hir/src/generics.rs | 11 ++++------- crates/ra_hir/src/ty/lower.rs | 4 +--- crates/ra_hir/src/ty/tests.rs | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 8925ba3a9..78fab1a13 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs @@ -5,12 +5,9 @@ use std::sync::Arc; -use hir_def::{ - path::Path, - type_ref::{TypeBound, TypeRef}, -}; +use hir_def::type_ref::{TypeBound, TypeRef}; use hir_expand::name::{self, AsName}; -use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner}; +use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, @@ -24,7 +21,7 @@ pub struct GenericParam { // FIXME: give generic params proper IDs pub idx: u32, pub name: Name, - pub default: Option, + pub default: Option, } /// Data about the generic parameters of a function, struct, impl, etc. @@ -140,7 +137,7 @@ impl GenericParams { for (idx, type_param) in params.type_params().enumerate() { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` - let default = type_param.default_type().and_then(|t| t.path()).and_then(Path::from_ast); + let default = type_param.default_type().map(TypeRef::from_ast); let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; self.params.push(param); diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index de3c56097..03db38605 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -611,9 +611,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> let defaults = generic_params .params_including_parent() .into_iter() - .map(|p| { - p.default.as_ref().map_or(Ty::Unknown, |path| Ty::from_hir_path(db, &resolver, path)) - }) + .map(|p| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) .collect(); Substs(defaults) diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index c1024d03c..abfaffb5e 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -1979,6 +1979,30 @@ fn test() { ); } +#[test] +fn infer_associated_method_generics_with_default_tuple_param() { + let t = type_at( + r#" +//- /main.rs +struct Gen { + val: T +} + +impl Gen { + pub fn make() -> Gen { + loop { } + } +} + +fn test() { + let a = Gen::make(); + a.val<|>; +} +"#, + ); + assert_eq!(t, "()"); +} + #[test] fn infer_associated_method_generics_without_args() { assert_snapshot!( -- cgit v1.2.3 From e1a6e38767c1e47e5e88a97a9ef5b4547390803c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 12:25:02 +0300 Subject: Move Generics to hir_def --- crates/ra_hir/src/db.rs | 2 +- crates/ra_hir/src/from_id.rs | 44 +++++++++- crates/ra_hir/src/generics.rs | 182 ++++-------------------------------------- crates/ra_hir/src/resolve.rs | 2 +- 4 files changed, 60 insertions(+), 170 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index d75d71d66..0d35014a0 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -43,7 +43,7 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; - #[salsa::invoke(crate::generics::GenericParams::generic_params_query)] + #[salsa::invoke(crate::generics::generic_params_query)] fn generic_params(&self, def: GenericDef) -> Arc; #[salsa::invoke(FnData::fn_data_query)] diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index f2203e995..b7692d407 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, AssocItemId, DefWithBodyId, EnumVariantId, ModuleDefId}; +use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId}; -use crate::{Adt, AssocItem, DefWithBody, EnumVariant, ModuleDef}; +use crate::{Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef}; macro_rules! from_id { ($(($id:path, $ty:path)),*) => {$( @@ -41,6 +41,16 @@ impl From for Adt { } } +impl From for AdtId { + fn from(id: Adt) -> Self { + match id { + Adt::Struct(it) => AdtId::StructId(it.id), + Adt::Union(it) => AdtId::UnionId(it.id), + Adt::Enum(it) => AdtId::EnumId(it.id), + } + } +} + impl From for EnumVariant { fn from(id: EnumVariantId) -> Self { EnumVariant { parent: id.parent.into(), id: id.local_id } @@ -82,3 +92,33 @@ impl From for AssocItem { } } } + +impl From for GenericDefId { + fn from(def: GenericDef) -> Self { + match def { + GenericDef::Function(it) => GenericDefId::FunctionId(it.id), + GenericDef::Adt(it) => GenericDefId::AdtId(it.into()), + GenericDef::Trait(it) => GenericDefId::TraitId(it.id), + GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), + GenericDef::ImplBlock(it) => GenericDefId::ImplId(it.id), + GenericDef::EnumVariant(it) => { + GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) + } + GenericDef::Const(it) => GenericDefId::ConstId(it.id), + } + } +} + +impl From for GenericDef { + fn from(def: GenericDefId) -> Self { + match def { + GenericDefId::FunctionId(it) => GenericDef::Function(it.into()), + GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), + GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), + GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), + GenericDefId::ImplId(it) => GenericDef::ImplBlock(it.into()), + GenericDefId::EnumVariantId(it) => GenericDef::EnumVariant(it.into()), + GenericDefId::ConstId(it) => GenericDef::Const(it.into()), + } + } +} diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 78fab1a13..caedb90e6 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs @@ -1,47 +1,12 @@ -//! Many kinds of items or constructs can have generic parameters: functions, -//! structs, impls, traits, etc. This module provides a common HIR for these -//! generic parameters. See also the `Generics` type and the `generics_of` query -//! in rustc. - +//! Temp module to wrap hir_def::generics use std::sync::Arc; -use hir_def::type_ref::{TypeBound, TypeRef}; -use hir_expand::name::{self, AsName}; -use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; - use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, - Adt, Const, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, Trait, - TypeAlias, Union, + Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, TypeAlias, Union, }; -/// Data about a generic parameter (to a function, struct, impl, ...). -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct GenericParam { - // FIXME: give generic params proper IDs - pub idx: u32, - pub name: Name, - pub default: Option, -} - -/// Data about the generic parameters of a function, struct, impl, etc. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct GenericParams { - pub(crate) def: GenericDef, - pub(crate) parent_params: Option>, - pub(crate) params: Vec, - pub(crate) where_predicates: Vec, -} - -/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined -/// where clauses like `where T: Foo + Bar` are turned into multiple of these. -/// It might still result in multiple actual predicates though, because of -/// associated type bindings like `Iterator`. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct WherePredicate { - pub(crate) type_ref: TypeRef, - pub(crate) bound: TypeBound, -} +pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate}; #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub enum GenericDef { @@ -66,134 +31,19 @@ impl_froms!( Const ); -impl GenericParams { - pub(crate) fn generic_params_query( - db: &(impl DefDatabase + AstDatabase), - def: GenericDef, - ) -> Arc { - let parent = match def { - GenericDef::Function(it) => it.container(db).map(GenericDef::from), - GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), - GenericDef::Const(it) => it.container(db).map(GenericDef::from), - GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()), - GenericDef::Adt(_) | GenericDef::Trait(_) => None, - GenericDef::ImplBlock(_) => None, - }; - let mut generics = GenericParams { - def, - params: Vec::new(), - parent_params: parent.map(|p| db.generic_params(p)), - where_predicates: Vec::new(), - }; - let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; - // FIXME: add `: Sized` bound for everything except for `Self` in traits - match def { - GenericDef::Function(it) => generics.fill(&it.source(db).value, start), - GenericDef::Adt(Adt::Struct(it)) => generics.fill(&it.source(db).value, start), - GenericDef::Adt(Adt::Union(it)) => generics.fill(&it.source(db).value, start), - GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).value, start), - GenericDef::Trait(it) => { - // traits get the Self type as an implicit first type parameter - generics.params.push(GenericParam { - idx: start, - name: name::SELF_TYPE, - default: None, - }); - generics.fill(&it.source(db).value, start + 1); - // add super traits as bounds on Self - // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar - let self_param = TypeRef::Path(name::SELF_TYPE.into()); - generics.fill_bounds(&it.source(db).value, self_param); - } - GenericDef::TypeAlias(it) => generics.fill(&it.source(db).value, start), - // Note that we don't add `Self` here: in `impl`s, `Self` is not a - // type-parameter, but rather is a type-alias for impl's target - // type, so this is handled by the resolver. - GenericDef::ImplBlock(it) => generics.fill(&it.source(db).value, start), - GenericDef::EnumVariant(_) | GenericDef::Const(_) => {} - } - - Arc::new(generics) - } - - fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { - if let Some(params) = node.type_param_list() { - self.fill_params(params, start) - } - if let Some(where_clause) = node.where_clause() { - self.fill_where_predicates(where_clause); - } - } - - fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) { - for bound in - node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) - { - self.add_where_predicate_from_bound(bound, type_ref.clone()); - } - } - - fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { - for (idx, type_param) in params.type_params().enumerate() { - let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); - // FIXME: Use `Path::from_src` - let default = type_param.default_type().map(TypeRef::from_ast); - - let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; - self.params.push(param); - - let type_ref = TypeRef::Path(name.into()); - self.fill_bounds(&type_param, type_ref); - } - } - - fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { - for pred in where_clause.predicates() { - let type_ref = match pred.type_ref() { - Some(type_ref) => type_ref, - None => continue, - }; - let type_ref = TypeRef::from_ast(type_ref); - for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { - self.add_where_predicate_from_bound(bound, type_ref.clone()); - } - } - } - - fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { - if bound.has_question_mark() { - // FIXME: remove this bound - return; - } - let bound = TypeBound::from_ast(bound); - self.where_predicates.push(WherePredicate { type_ref, bound }); - } - - pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { - self.params.iter().find(|p| &p.name == name) - } - - pub fn count_parent_params(&self) -> usize { - self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0) - } - - pub fn count_params_including_parent(&self) -> usize { - let parent_count = self.count_parent_params(); - parent_count + self.params.len() - } - - fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) { - if let Some(parent) = &self.parent_params { - parent.for_each_param(f); - } - self.params.iter().for_each(f); - } - - pub fn params_including_parent(&self) -> Vec<&GenericParam> { - let mut vec = Vec::with_capacity(self.count_params_including_parent()); - self.for_each_param(&mut |p| vec.push(p)); - vec - } +pub(crate) fn generic_params_query( + db: &(impl DefDatabase + AstDatabase), + def: GenericDef, +) -> Arc { + let parent = match def { + GenericDef::Function(it) => it.container(db).map(GenericDef::from), + GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), + GenericDef::Const(it) => it.container(db).map(GenericDef::from), + GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()), + GenericDef::Adt(_) | GenericDef::Trait(_) => None, + GenericDef::ImplBlock(_) => None, + }; + Arc::new(GenericParams::new(db, def.into(), parent.map(|it| db.generic_params(it)))) } impl GenericDef { diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 79b92180a..a2fa0bb79 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -369,7 +369,7 @@ impl Resolver { pub(crate) fn generic_def(&self) -> Option { self.scopes.iter().find_map(|scope| match scope { - Scope::GenericParams(params) => Some(params.def), + Scope::GenericParams(params) => Some(params.def.into()), _ => None, }) } -- cgit v1.2.3 From 51baaf298d4ac56036062786bf070aeab7ab8e79 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 13:09:21 +0300 Subject: Rename with_ast -> with_value --- crates/ra_hir/src/source_binder.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 471b0b089..a1c1daacd 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -33,19 +33,19 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - match_ast! { match (node.value) { ast::Module(it) => { - let src = node.with_ast(it); + let src = node.with_value(it); Some(crate::Module::from_declaration(db, src)?.resolver(db)) }, ast::SourceFile(it) => { - let src = node.with_ast(crate::ModuleSource::SourceFile(it)); + let src = node.with_value(crate::ModuleSource::SourceFile(it)); Some(crate::Module::from_definition(db, src)?.resolver(db)) }, ast::StructDef(it) => { - let src = node.with_ast(it); + let src = node.with_value(it); Some(Struct::from_source(db, src)?.resolver(db)) }, ast::EnumDef(it) => { - let src = node.with_ast(it); + let src = node.with_value(it); Some(Enum::from_source(db, src)?.resolver(db)) }, _ => match node.value.kind() { @@ -157,7 +157,7 @@ impl SourceAnalyzer { let scopes = def.expr_scopes(db); let scope = match offset { None => scope_for(&scopes, &source_map, node), - Some(offset) => scope_for_offset(&scopes, &source_map, node.with_ast(offset)), + Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), }; let resolver = expr::resolver_for_scope(db, def, scope); SourceAnalyzer { @@ -173,7 +173,7 @@ impl SourceAnalyzer { resolver: node .value .ancestors() - .find_map(|it| try_get_resolver_for_node(db, node.with_ast(&it))) + .find_map(|it| try_get_resolver_for_node(db, node.with_value(&it))) .unwrap_or_default(), body_owner: None, body_source_map: None, -- cgit v1.2.3 From 06fa3d8389c833b01f482bf35b0f850e627612b9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 14:22:06 +0300 Subject: Move traits to hir_def --- crates/ra_hir/src/code_model.rs | 32 +++++------- crates/ra_hir/src/db.rs | 10 +--- crates/ra_hir/src/lib.rs | 1 - crates/ra_hir/src/traits.rs | 82 ------------------------------- crates/ra_hir/src/ty/method_resolution.rs | 6 +-- 5 files changed, 17 insertions(+), 114 deletions(-) delete mode 100644 crates/ra_hir/src/traits.rs (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 cb990f4e2..f436d5d5e 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -10,8 +10,9 @@ use hir_def::{ adt::VariantData, body::scope::ExprScopes, builtin_type::BuiltinType, + traits::TraitData, type_ref::{Mutability, TypeRef}, - CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, + AssocItemId, CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -30,7 +31,6 @@ use crate::{ TypeAliasId, }, resolve::{Resolver, Scope, TypeNs}, - traits::TraitData, ty::{InferenceResult, Namespace, TraitRef}, Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, }; @@ -230,15 +230,7 @@ impl Module { pub fn declarations(self, db: &impl DefDatabase) -> Vec { let def_map = db.crate_def_map(self.id.krate); - def_map[self.id.module_id] - .scope - .entries() - .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) - .flat_map(|per_ns| { - per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) - }) - .map(ModuleDef::from) - .collect() + def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() } pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec { @@ -693,7 +685,7 @@ impl Function { /// The containing trait, if this is a trait method definition. pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db)).get_parent_trait(self.into()) + db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) } pub fn container(self, db: &impl DefDatabase) -> Option { @@ -757,7 +749,7 @@ impl Const { } pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db)).get_parent_trait(self.into()) + db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) } pub fn container(self, db: &impl DefDatabase) -> Option { @@ -861,11 +853,11 @@ impl Trait { } pub fn name(self, db: &impl DefDatabase) -> Option { - self.trait_data(db).name().clone() + self.trait_data(db).name.clone() } pub fn items(self, db: &impl DefDatabase) -> Vec { - self.trait_data(db).items().to_vec() + self.trait_data(db).items.iter().map(|it| (*it).into()).collect() } fn direct_super_traits(self, db: &impl HirDatabase) -> Vec { @@ -912,10 +904,10 @@ impl Trait { pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option { let trait_data = self.trait_data(db); trait_data - .items() + .items .iter() .filter_map(|item| match item { - AssocItem::TypeAlias(t) => Some(*t), + AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)), _ => None, }) .find(|t| &t.name(db) == name) @@ -930,7 +922,7 @@ impl Trait { } pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc { - db.trait_data(self) + db.trait_data(self.id) } pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { @@ -938,7 +930,7 @@ impl Trait { } pub fn is_auto(self, db: &impl DefDatabase) -> bool { - self.trait_data(db).is_auto() + self.trait_data(db).auto } pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { @@ -971,7 +963,7 @@ impl TypeAlias { /// The containing trait, if this is a trait method definition. pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db)).get_parent_trait(self.into()) + db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) } pub fn container(self, db: &impl DefDatabase) -> Option { diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 0d35014a0..73859e1e9 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -11,7 +11,6 @@ use crate::{ generics::{GenericDef, GenericParams}, ids, lang_item::{LangItemTarget, LangItems}, - traits::TraitData, ty::{ method_resolution::CrateImplBlocks, traits::{AssocTyValue, Impl}, @@ -26,7 +25,8 @@ use crate::{ pub use hir_def::db::{ BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, - RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, + RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery, + TraitItemsIndexQuery, }; pub use hir_expand::db::{ AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, @@ -37,12 +37,6 @@ pub use hir_expand::db::{ #[salsa::query_group(DefDatabaseStorage)] #[salsa::requires(AstDatabase)] pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { - #[salsa::invoke(crate::traits::TraitData::trait_data_query)] - fn trait_data(&self, t: Trait) -> Arc; - - #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] - fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; - #[salsa::invoke(crate::generics::generic_params_query)] fn generic_params(&self, def: GenericDef) -> Arc; diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index da33c9591..7ac9a9041 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -33,7 +33,6 @@ pub mod source_binder; mod ids; mod adt; -mod traits; mod type_alias; mod ty; mod impl_block; diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs deleted file mode 100644 index 858972c6f..000000000 --- a/crates/ra_hir/src/traits.rs +++ /dev/null @@ -1,82 +0,0 @@ -//! HIR for trait definitions. - -use std::sync::Arc; - -use hir_expand::name::AsName; - -use ra_syntax::ast::{self, NameOwner}; -use rustc_hash::FxHashMap; - -use crate::{ - db::{AstDatabase, DefDatabase}, - ids::LocationCtx, - AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias, -}; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TraitData { - name: Option, - items: Vec, - auto: bool, -} - -impl TraitData { - pub(crate) fn trait_data_query( - db: &(impl DefDatabase + AstDatabase), - tr: Trait, - ) -> Arc { - let src = tr.source(db); - let name = src.value.name().map(|n| n.as_name()); - let module = tr.module(db); - let ctx = LocationCtx::new(db, module.id, src.file_id); - let auto = src.value.is_auto(); - let items = if let Some(item_list) = src.value.item_list() { - item_list - .impl_items() - .map(|item_node| match item_node { - ast::ImplItem::FnDef(it) => Function { id: ctx.to_def(&it) }.into(), - ast::ImplItem::ConstDef(it) => Const { id: ctx.to_def(&it) }.into(), - ast::ImplItem::TypeAliasDef(it) => TypeAlias { id: ctx.to_def(&it) }.into(), - }) - .collect() - } else { - Vec::new() - }; - Arc::new(TraitData { name, items, auto }) - } - - pub(crate) fn name(&self) -> &Option { - &self.name - } - - pub(crate) fn items(&self) -> &[AssocItem] { - &self.items - } - - pub(crate) fn is_auto(&self) -> bool { - self.auto - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TraitItemsIndex { - traits_by_def: FxHashMap, -} - -impl TraitItemsIndex { - pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { - let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; - for decl in module.declarations(db) { - if let crate::ModuleDef::Trait(tr) = decl { - for item in tr.trait_data(db).items() { - index.traits_by_def.insert(*item, tr); - } - } - } - index - } - - pub(crate) fn get_parent_trait(&self, item: AssocItem) -> Option { - self.traits_by_def.get(&item).cloned() - } -} diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index d20aeaacf..f377fca48 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -232,8 +232,8 @@ fn iterate_trait_method_candidates( // trait, but if we find out it doesn't, we'll skip the rest of the // iteration let mut known_implemented = false; - for &item in data.items() { - if !is_valid_candidate(db, name, mode, item) { + for &item in data.items.iter() { + if !is_valid_candidate(db, name, mode, item.into()) { continue; } if !known_implemented { @@ -243,7 +243,7 @@ fn iterate_trait_method_candidates( } } known_implemented = true; - if let Some(result) = callback(&ty.value, item) { + if let Some(result) = callback(&ty.value, item.into()) { return Some(result); } } -- cgit v1.2.3 From cebeedc66fc40097eae20bf1767a285d00269966 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 16:03:59 +0300 Subject: Next gen IDs for functions The current system with AstIds has two primaraly drawbacks: * It is possible to manufacture IDs out of thin air. For example, it's possible to create IDs for items which are not considered in CrateDefMap due to cfg. Or it is possible to mixup structs and unions, because they share ID space. * Getting the ID of a parent requires a secondary index. Instead, the plan is to pursue the more traditional approach, where each items stores the id of the parent declaration. This makes `FromSource` more awkward, but also more correct: now, to get from an AST to HIR, we first do this recursively for the parent item, and the just search the children of the parent for the matching def --- crates/ra_hir/src/code_model.rs | 25 ++++++++------ crates/ra_hir/src/code_model/src.rs | 3 +- crates/ra_hir/src/from_source.rs | 65 +++++++++++++++++++++++++++++++++---- crates/ra_hir/src/source_binder.rs | 2 +- 4 files changed, 76 insertions(+), 19 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 f436d5d5e..c49190a0f 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -12,7 +12,8 @@ use hir_def::{ builtin_type::BuiltinType, traits::TraitData, type_ref::{Mutability, TypeRef}, - AssocItemId, CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, + AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId, + LocalStructFieldId, Lookup, ModuleId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -647,7 +648,7 @@ impl FnData { impl Function { pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.module(db) } + self.id.lookup(db).module(db).into() } pub fn krate(self, db: &impl DefDatabase) -> Option { @@ -680,21 +681,25 @@ impl Function { /// The containing impl block, if this is a method. pub fn impl_block(self, db: &impl DefDatabase) -> Option { - ImplBlock::containing(db, self.into()) + match self.container(db) { + Some(Container::ImplBlock(it)) => Some(it), + _ => None, + } } /// The containing trait, if this is a trait method definition. pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) + match self.container(db) { + Some(Container::Trait(it)) => Some(it), + _ => None, + } } pub fn container(self, db: &impl DefDatabase) -> Option { - if let Some(impl_block) = self.impl_block(db) { - Some(impl_block.into()) - } else if let Some(trait_) = self.parent_trait(db) { - Some(trait_.into()) - } else { - None + match self.id.lookup(db).container { + FunctionContainerId::TraitId(it) => Some(Container::Trait(it.into())), + FunctionContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), + FunctionContainerId::ModuleId(_) => None, } } diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 556417b0f..91cab7414 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -1,5 +1,6 @@ //! FIXME: write short doc here +use hir_def::{HasSource as _, Lookup}; use ra_syntax::ast::{self, AstNode}; use crate::{ @@ -113,7 +114,7 @@ impl HasSource for EnumVariant { impl HasSource for Function { type Ast = ast::FnDef; fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source { - self.id.source(db) + self.id.lookup(db).source(db) } } impl HasSource for Const { diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index f4dca25cb..303d5f138 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -4,15 +4,15 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId}; use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; use ra_syntax::{ ast::{self, AstNode, NameOwner}, - match_ast, + match_ast, AstPtr, }; use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, ids::{AstItemDef, LocationCtx}, - Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock, - Local, MacroDef, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, - Union, VariantDef, + AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, + ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, + StructField, Trait, TypeAlias, Union, VariantDef, }; pub trait FromSource: Sized { @@ -52,10 +52,51 @@ impl FromSource for Trait { impl FromSource for Function { type Ast = ast::FnDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id = from_source(db, src)?; - Some(Function { id }) + // FIXME: this doesn't try to handle nested declarations + for container in src.value.syntax().ancestors() { + let res = match_ast! { + match container { + ast::TraitDef(it) => { + let c = Trait::from_source(db, src.with_value(it))?; + c.items(db) + .into_iter() + .filter_map(|it| match it { + AssocItem::Function(it) => Some(it), + _ => None + }) + .find(|it| same_source(&it.source(db), &src))? + }, + ast::ImplBlock(it) => { + let c = ImplBlock::from_source(db, src.with_value(it))?; + c.items(db) + .into_iter() + .filter_map(|it| match it { + AssocItem::Function(it) => Some(it), + _ => None + }) + .find(|it| same_source(&it.source(db), &src))? + + }, + _ => { continue }, + } + }; + return Some(res); + } + + let module_source = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); + let c = Module::from_definition(db, src.with_value(module_source))?; + let res = c + .declarations(db) + .into_iter() + .filter_map(|it| match it { + ModuleDef::Function(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)); + res } } + impl FromSource for Const { type Ast = ast::ConstDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { @@ -108,7 +149,7 @@ impl FromSource for EnumVariant { let parent_enum = src.value.parent_enum(); let src_enum = Source { file_id: src.file_id, value: parent_enum }; let variants = Enum::from_source(db, src_enum)?.variants(db); - variants.into_iter().find(|v| v.source(db) == src) + variants.into_iter().find(|v| same_source(&v.source(db), &src)) } } @@ -216,3 +257,13 @@ where let ctx = LocationCtx::new(db, module.id, src.file_id); Some(DEF::from_ast(ctx, &src.value)) } + +/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are +/// equal if they point to exactly the same object. +/// +/// In general, we do not guarantee that we have exactly one instance of a +/// syntax tree for each file. We probably should add such guanratree, but, for +/// the time being, we will use identity-less AstPtr comparison. +fn same_source(s1: &Source, s2: &Source) -> bool { + s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) +} diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index a1c1daacd..5d9e22ee2 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -70,7 +70,7 @@ fn def_with_body_from_child_node( child.value.ancestors().find_map(|node| { match_ast! { match node { - ast::FnDef(def) => { Some(Function {id: ctx.to_def(&def) }.into()) }, + ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) }, ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, _ => { None }, -- cgit v1.2.3 From 0a9c80053ffcd72d076ca3792bf4a9ddb94eaf95 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 20 Nov 2019 12:21:31 +0800 Subject: Fix expand macro --- crates/ra_hir/src/source_binder.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 5d9e22ee2..caa8d0082 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -405,9 +405,16 @@ impl SourceAnalyzer { implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) } - pub fn expand(&self, db: &impl HirDatabase, macro_call: &ast::MacroCall) -> Option { - let def = self.resolve_macro_call(db, macro_call)?.id; - let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(macro_call)); + pub fn expand( + &self, + db: &impl HirDatabase, + macro_call: Source<&ast::MacroCall>, + ) -> Option { + let def = self.resolve_macro_call(db, macro_call.value)?.id; + let ast_id = AstId::new( + macro_call.file_id, + db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), + ); let macro_call_loc = MacroCallLoc { def, ast_id }; Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) } -- cgit v1.2.3 From 64c21ed19594b323e72605ba8c5dd4c6eee433f6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 17:39:58 +0300 Subject: Switch type aliases to new sources --- crates/ra_hir/src/code_model.rs | 28 +++++---- crates/ra_hir/src/code_model/src.rs | 2 +- crates/ra_hir/src/from_source.rs | 112 +++++++++++++++++++++++------------- 3 files changed, 88 insertions(+), 54 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 c49190a0f..b8d48a500 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -13,7 +13,7 @@ use hir_def::{ traits::TraitData, type_ref::{Mutability, TypeRef}, AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId, - LocalStructFieldId, Lookup, ModuleId, UnionId, + LocalStructFieldId, Lookup, ModuleId, TypeAliasContainerId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -954,30 +954,34 @@ pub struct TypeAlias { impl TypeAlias { pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.module(db) } + Module { id: self.id.lookup(db).module(db) } } pub fn krate(self, db: &impl DefDatabase) -> Option { Some(self.module(db).krate()) } - /// The containing impl block, if this is a method. + /// The containing impl block, if this is a type alias. pub fn impl_block(self, db: &impl DefDatabase) -> Option { - ImplBlock::containing(db, self.into()) + match self.container(db) { + Some(Container::ImplBlock(it)) => Some(it), + _ => None, + } } - /// The containing trait, if this is a trait method definition. + /// The containing trait, if this is a trait type alias definition. pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) + match self.container(db) { + Some(Container::Trait(it)) => Some(it), + _ => None, + } } pub fn container(self, db: &impl DefDatabase) -> Option { - if let Some(impl_block) = self.impl_block(db) { - Some(impl_block.into()) - } else if let Some(trait_) = self.parent_trait(db) { - Some(trait_.into()) - } else { - None + match self.id.lookup(db).container { + TypeAliasContainerId::TraitId(it) => Some(Container::Trait(it.into())), + TypeAliasContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), + TypeAliasContainerId::ModuleId(_) => None, } } diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 91cab7414..04675e08e 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -138,7 +138,7 @@ impl HasSource for Trait { impl HasSource for TypeAlias { type Ast = ast::TypeAliasDef; fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source { - self.id.source(db) + self.id.lookup(db).source(db) } } impl HasSource for MacroDef { diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 303d5f138..f5fdaafa3 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -4,7 +4,7 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId}; use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; use ra_syntax::{ ast::{self, AstNode, NameOwner}, - match_ast, AstPtr, + match_ast, AstPtr, SyntaxNode, }; use crate::{ @@ -52,48 +52,27 @@ impl FromSource for Trait { impl FromSource for Function { type Ast = ast::FnDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - // FIXME: this doesn't try to handle nested declarations - for container in src.value.syntax().ancestors() { - let res = match_ast! { - match container { - ast::TraitDef(it) => { - let c = Trait::from_source(db, src.with_value(it))?; - c.items(db) - .into_iter() - .filter_map(|it| match it { - AssocItem::Function(it) => Some(it), - _ => None - }) - .find(|it| same_source(&it.source(db), &src))? - }, - ast::ImplBlock(it) => { - let c = ImplBlock::from_source(db, src.with_value(it))?; - c.items(db) - .into_iter() - .filter_map(|it| match it { - AssocItem::Function(it) => Some(it), - _ => None - }) - .find(|it| same_source(&it.source(db), &src))? - - }, - _ => { continue }, - } - }; - return Some(res); - } - - let module_source = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); - let c = Module::from_definition(db, src.with_value(module_source))?; - let res = c - .declarations(db) + let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { + Container::Trait(it) => it.items(db), + Container::ImplBlock(it) => it.items(db), + Container::Module(m) => { + return m + .declarations(db) + .into_iter() + .filter_map(|it| match it { + ModuleDef::Function(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) + } + }; + items .into_iter() .filter_map(|it| match it { - ModuleDef::Function(it) => Some(it), + AssocItem::Function(it) => Some(it), _ => None, }) - .find(|it| same_source(&it.source(db), &src)); - res + .find(|it| same_source(&it.source(db), &src)) } } @@ -114,8 +93,27 @@ impl FromSource for Static { impl FromSource for TypeAlias { type Ast = ast::TypeAliasDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id = from_source(db, src)?; - Some(TypeAlias { id }) + let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { + Container::Trait(it) => it.items(db), + Container::ImplBlock(it) => it.items(db), + Container::Module(m) => { + return m + .declarations(db) + .into_iter() + .filter_map(|it| match it { + ModuleDef::TypeAlias(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) + } + }; + items + .into_iter() + .filter_map(|it| match it { + AssocItem::TypeAlias(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) } } @@ -258,6 +256,38 @@ where Some(DEF::from_ast(ctx, &src.value)) } +enum Container { + Trait(Trait), + ImplBlock(ImplBlock), + Module(Module), +} + +impl Container { + fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option { + // FIXME: this doesn't try to handle nested declarations + for container in src.value.ancestors() { + let res = match_ast! { + match container { + ast::TraitDef(it) => { + let c = Trait::from_source(db, src.with_value(it))?; + Container::Trait(c) + }, + ast::ImplBlock(it) => { + let c = ImplBlock::from_source(db, src.with_value(it))?; + Container::ImplBlock(c) + }, + _ => { continue }, + } + }; + return Some(res); + } + + let module_source = ModuleSource::from_child_node(db, src); + let c = Module::from_definition(db, src.with_value(module_source))?; + Some(Container::Module(c)) + } +} + /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are /// equal if they point to exactly the same object. /// -- cgit v1.2.3 From ee95a35664e6fe9153f6324cfc57872ca365887c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 17:49:57 +0300 Subject: Don't duplicate ContainerId type --- crates/ra_hir/src/code_model.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 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 b8d48a500..669666989 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -12,8 +12,8 @@ use hir_def::{ builtin_type::BuiltinType, traits::TraitData, type_ref::{Mutability, TypeRef}, - AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId, - LocalStructFieldId, Lookup, ModuleId, TypeAliasContainerId, UnionId, + AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, + LocalStructFieldId, Lookup, ModuleId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -697,9 +697,9 @@ impl Function { pub fn container(self, db: &impl DefDatabase) -> Option { match self.id.lookup(db).container { - FunctionContainerId::TraitId(it) => Some(Container::Trait(it.into())), - FunctionContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), - FunctionContainerId::ModuleId(_) => None, + ContainerId::TraitId(it) => Some(Container::Trait(it.into())), + ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), + ContainerId::ModuleId(_) => None, } } @@ -979,9 +979,9 @@ impl TypeAlias { pub fn container(self, db: &impl DefDatabase) -> Option { match self.id.lookup(db).container { - TypeAliasContainerId::TraitId(it) => Some(Container::Trait(it.into())), - TypeAliasContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), - TypeAliasContainerId::ModuleId(_) => None, + ContainerId::TraitId(it) => Some(Container::Trait(it.into())), + ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), + ContainerId::ModuleId(_) => None, } } -- cgit v1.2.3 From 111891dc2dc1d2c7ea87144e8e3ddefe23fc7b6d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 18:00:01 +0300 Subject: Move constants to new ID This allows us to get rid of trait item index --- crates/ra_hir/src/code_model.rs | 25 +++++++++++++++---------- crates/ra_hir/src/code_model/src.rs | 2 +- crates/ra_hir/src/db.rs | 1 - crates/ra_hir/src/from_source.rs | 25 ++++++++++++++++++++++--- crates/ra_hir/src/impl_block.rs | 8 -------- crates/ra_hir/src/source_binder.rs | 7 ++++++- crates/ra_hir/src/ty.rs | 5 +++-- crates/ra_hir/src/ty/tests.rs | 7 +++++-- 8 files changed, 52 insertions(+), 28 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 669666989..920899dce 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -729,7 +729,7 @@ pub struct Const { impl Const { pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.module(db) } + Module { id: self.id.lookup(db).module(db) } } pub fn krate(self, db: &impl DefDatabase) -> Option { @@ -748,22 +748,27 @@ impl Const { db.infer(self.into()) } - /// The containing impl block, if this is a method. + /// The containing impl block, if this is a type alias. pub fn impl_block(self, db: &impl DefDatabase) -> Option { - ImplBlock::containing(db, self.into()) + match self.container(db) { + Some(Container::ImplBlock(it)) => Some(it), + _ => None, + } } + /// The containing trait, if this is a trait type alias definition. pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) + match self.container(db) { + Some(Container::Trait(it)) => Some(it), + _ => None, + } } pub fn container(self, db: &impl DefDatabase) -> Option { - if let Some(impl_block) = self.impl_block(db) { - Some(impl_block.into()) - } else if let Some(trait_) = self.parent_trait(db) { - Some(trait_.into()) - } else { - None + match self.id.lookup(db).container { + ContainerId::TraitId(it) => Some(Container::Trait(it.into())), + ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), + ContainerId::ModuleId(_) => None, } } diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 04675e08e..354d2c98f 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -120,7 +120,7 @@ impl HasSource for Function { impl HasSource for Const { type Ast = ast::ConstDef; fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source { - self.id.source(db) + self.id.lookup(db).source(db) } } impl HasSource for Static { diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 73859e1e9..5bb7961b3 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -26,7 +26,6 @@ pub use hir_def::db::{ BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery, - TraitItemsIndexQuery, }; pub use hir_expand::db::{ AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index f5fdaafa3..b86307c58 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -79,8 +79,27 @@ impl FromSource for Function { impl FromSource for Const { type Ast = ast::ConstDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id = from_source(db, src)?; - Some(Const { id }) + let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { + Container::Trait(it) => it.items(db), + Container::ImplBlock(it) => it.items(db), + Container::Module(m) => { + return m + .declarations(db) + .into_iter() + .filter_map(|it| match it { + ModuleDef::Const(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) + } + }; + items + .into_iter() + .filter_map(|it| match it { + AssocItem::Const(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) } } impl FromSource for Static { @@ -292,7 +311,7 @@ impl Container { /// equal if they point to exactly the same object. /// /// In general, we do not guarantee that we have exactly one instance of a -/// syntax tree for each file. We probably should add such guanratree, but, for +/// syntax tree for each file. We probably should add such guarantee, but, for /// the time being, we will use identity-less AstPtr comparison. fn same_source(s1: &Source, s2: &Source) -> bool { s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 0c2bb8fee..0513f28a9 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -19,14 +19,6 @@ impl HasSource for ImplBlock { } impl ImplBlock { - pub(crate) fn containing(db: &impl DefDatabase, item: AssocItem) -> Option { - let module = item.module(db); - let crate_def_map = db.crate_def_map(module.id.krate); - crate_def_map[module.id.module_id].impls.iter().copied().map(ImplBlock::from).find(|it| { - db.impl_data(it.id).items().iter().copied().map(AssocItem::from).any(|it| it == item) - }) - } - pub fn target_trait(&self, db: &impl DefDatabase) -> Option { db.impl_data(self.id).target_trait().cloned() } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index caa8d0082..fd9994098 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -71,7 +71,7 @@ fn def_with_body_from_child_node( match_ast! { match node { ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, - ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) }, + ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, _ => { None }, } @@ -428,6 +428,11 @@ impl SourceAnalyzer { pub(crate) fn inference_result(&self) -> Arc { self.infer.clone().unwrap() } + + #[cfg(test)] + pub(crate) fn analyzed_declaration(&self) -> Option { + self.body_owner + } } fn scope_for( diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 776613c7c..36ece723f 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -3,8 +3,6 @@ mod autoderef; pub(crate) mod primitive; -#[cfg(test)] -mod tests; pub(crate) mod traits; pub(crate) mod method_resolution; mod op; @@ -12,6 +10,9 @@ mod lower; mod infer; pub(crate) mod display; +#[cfg(test)] +mod tests; + use std::ops::Deref; use std::sync::Arc; use std::{fmt, iter, mem}; diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index abfaffb5e..74c12a0a2 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -11,6 +11,7 @@ use ra_syntax::{ ast::{self, AstNode}, SyntaxKind::*, }; +use rustc_hash::FxHashSet; use test_utils::covers; use crate::{ @@ -2518,7 +2519,6 @@ fn test() { [167; 179) 'GLOBAL_CONST': u32 [189; 191) 'id': u32 [194; 210) 'Foo::A..._CONST': u32 - [126; 128) '99': u32 "### ); } @@ -4742,10 +4742,13 @@ fn infer(content: &str) -> String { } }; + let mut analyzed = FxHashSet::default(); for node in source_file.syntax().descendants() { if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); - infer_def(analyzer.inference_result(), analyzer.body_source_map()); + if analyzed.insert(analyzer.analyzed_declaration()) { + infer_def(analyzer.inference_result(), analyzer.body_source_map()); + } } } -- cgit v1.2.3 From cb642fc578100c0945088accb85acb8f03d2e1fd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 20:33:18 +0300 Subject: Move generic_params query to HIR --- crates/ra_hir/src/db.rs | 10 ++++------ crates/ra_hir/src/generics.rs | 19 ++----------------- 2 files changed, 6 insertions(+), 23 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 5bb7961b3..a9982a70f 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -8,7 +8,7 @@ use ra_syntax::SmolStr; use crate::{ debug::HirDebugDatabase, - generics::{GenericDef, GenericParams}, + generics::GenericDef, ids, lang_item::{LangItemTarget, LangItems}, ty::{ @@ -24,8 +24,9 @@ use crate::{ pub use hir_def::db::{ BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, - EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, - RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery, + EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, + InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, + TraitDataQuery, }; pub use hir_expand::db::{ AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, @@ -36,9 +37,6 @@ pub use hir_expand::db::{ #[salsa::query_group(DefDatabaseStorage)] #[salsa::requires(AstDatabase)] pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { - #[salsa::invoke(crate::generics::generic_params_query)] - fn generic_params(&self, def: GenericDef) -> Arc; - #[salsa::invoke(FnData::fn_data_query)] fn fn_data(&self, func: Function) -> Arc; diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index caedb90e6..54ed03642 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use crate::{ - db::{AstDatabase, DefDatabase, HirDatabase}, + db::{DefDatabase, HirDatabase}, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, TypeAlias, Union, }; @@ -31,21 +31,6 @@ impl_froms!( Const ); -pub(crate) fn generic_params_query( - db: &(impl DefDatabase + AstDatabase), - def: GenericDef, -) -> Arc { - let parent = match def { - GenericDef::Function(it) => it.container(db).map(GenericDef::from), - GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), - GenericDef::Const(it) => it.container(db).map(GenericDef::from), - GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()), - GenericDef::Adt(_) | GenericDef::Trait(_) => None, - GenericDef::ImplBlock(_) => None, - }; - Arc::new(GenericParams::new(db, def.into(), parent.map(|it| db.generic_params(it)))) -} - impl GenericDef { pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver { match self { @@ -78,6 +63,6 @@ where T: Into + Copy, { fn generic_params(self, db: &impl DefDatabase) -> Arc { - db.generic_params(self.into()) + db.generic_params(self.into().into()) } } -- cgit v1.2.3 From 12ec946216a3637685f30ae359bc955313595a22 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 20:50:34 +0300 Subject: Simplify generic params --- crates/ra_hir/src/code_model.rs | 23 ++++++----------------- crates/ra_hir/src/impl_block.rs | 8 +++----- crates/ra_hir/src/resolve.rs | 39 ++++++++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 37 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 920899dce..e2638cf92 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -322,9 +322,7 @@ impl Struct { // take the outer scope... let r = self.module(db).resolver(db); // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r + r.push_generic_params_scope(db, self.into()) } } @@ -352,9 +350,7 @@ impl Union { // take the outer scope... let r = self.module(db).resolver(db); // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r + r.push_generic_params_scope(db, self.into()) } } @@ -402,8 +398,7 @@ impl Enum { // take the outer scope... let r = self.module(db).resolver(db); // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; + let r = r.push_generic_params_scope(db, self.into()); r.push_scope(Scope::AdtScope(self.into())) } } @@ -709,9 +704,7 @@ impl Function { // take the outer scope... let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r + r.push_generic_params_scope(db, self.into()) } pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { @@ -946,9 +939,7 @@ impl Trait { pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { let r = self.module(db).resolver(db); // add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r + r.push_generic_params_scope(db, self.into()) } } @@ -1010,9 +1001,7 @@ impl TypeAlias { .map(|ib| ib.resolver(db)) .unwrap_or_else(|| self.module(db).resolver(db)); // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r + r.push_generic_params_scope(db, self.into()) } } diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 0513f28a9..492d964a4 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -5,7 +5,6 @@ use ra_syntax::ast::{self}; use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, - generics::HasGenericParams, resolve::Resolver, ty::Ty, AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, @@ -52,12 +51,11 @@ impl ImplBlock { Crate { crate_id: self.module(db).id.krate } } - pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { let r = self.module(db).resolver(db); // add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - let r = r.push_impl_block_scope(self.clone()); + let r = r.push_generic_params_scope(db, self.into()); + let r = r.push_impl_block_scope(self); r } } diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index a2fa0bb79..e5e768be9 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -14,9 +14,9 @@ use crate::{ code_model::Crate, db::{DefDatabase, HirDatabase}, expr::{ExprScopes, PatId, ScopeId}, - generics::GenericParams, - Adt, Const, DefWithBody, Enum, EnumVariant, Function, ImplBlock, Local, MacroDef, ModuleDef, - PerNs, Static, Struct, Trait, TypeAlias, + generics::{GenericParams, HasGenericParams}, + Adt, Const, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, MacroDef, + ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, }; #[derive(Debug, Clone, Default)] @@ -43,7 +43,7 @@ pub(crate) enum Scope { /// All the items and imported names of a module ModuleScope(ModuleItemMap), /// Brings the generic parameters of an item into scope - GenericParams(Arc), + GenericParams { def: GenericDef, params: Arc }, /// Brings `Self` in `impl` block into scope ImplBlockScope(ImplBlock), /// Brings `Self` in enum, struct and union definitions into scope @@ -141,9 +141,9 @@ impl Resolver { for scope in self.scopes.iter().rev() { match scope { Scope::ExprScope(_) => continue, - Scope::GenericParams(_) | Scope::ImplBlockScope(_) if skip_to_mod => continue, + Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, - Scope::GenericParams(params) => { + Scope::GenericParams { params, .. } => { if let Some(param) = params.find_by_name(first_name) { let idx = if path.segments.len() == 1 { None } else { Some(1) }; return Some((TypeNs::GenericParam(param.idx), idx)); @@ -212,7 +212,7 @@ impl Resolver { match scope { Scope::AdtScope(_) | Scope::ExprScope(_) - | Scope::GenericParams(_) + | Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => { @@ -232,13 +232,13 @@ impl Resolver { } Scope::ExprScope(_) => continue, - Scope::GenericParams(params) if n_segments > 1 => { + Scope::GenericParams { params, .. } if n_segments > 1 => { if let Some(param) = params.find_by_name(first_name) { let ty = TypeNs::GenericParam(param.idx); return Some(ResolveValueResult::Partial(ty, 1)); } } - Scope::GenericParams(_) => continue, + Scope::GenericParams { .. } => continue, Scope::ImplBlockScope(impl_) if n_segments > 1 => { if first_name == &name::SELF_TYPE { @@ -361,7 +361,7 @@ impl Resolver { self.scopes .iter() .filter_map(|scope| match scope { - Scope::GenericParams(params) => Some(params), + Scope::GenericParams { params, .. } => Some(params), _ => None, }) .flat_map(|params| params.where_predicates.iter()) @@ -369,7 +369,7 @@ impl Resolver { pub(crate) fn generic_def(&self) -> Option { self.scopes.iter().find_map(|scope| match scope { - Scope::GenericParams(params) => Some(params.def.into()), + Scope::GenericParams { def, .. } => Some(*def), _ => None, }) } @@ -381,8 +381,17 @@ impl Resolver { self } - pub(crate) fn push_generic_params_scope(self, params: Arc) -> Resolver { - self.push_scope(Scope::GenericParams(params)) + pub(crate) fn push_generic_params_scope( + self, + db: &impl DefDatabase, + def: GenericDef, + ) -> Resolver { + let params = def.generic_params(db); + if params.params.is_empty() { + self + } else { + self.push_scope(Scope::GenericParams { def, params }) + } } pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { @@ -457,8 +466,8 @@ impl Scope { }); } } - Scope::GenericParams(gp) => { - for param in &gp.params { + Scope::GenericParams { params, .. } => { + for param in params.params.iter() { f(param.name.clone(), ScopeDef::GenericParam(param.idx)) } } -- cgit v1.2.3 From 7c275a7ed2253fc7bd8b46c685a754c4d4e9dee3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 21:08:39 +0300 Subject: Remove hir/adt.rs --- crates/ra_hir/src/adt.rs | 54 ------------------------------------- crates/ra_hir/src/code_model.rs | 42 ++++++++++++++++++++++++++++- crates/ra_hir/src/code_model/src.rs | 3 +-- crates/ra_hir/src/lib.rs | 8 +++--- crates/ra_hir/src/ty/infer.rs | 3 +-- crates/ra_hir/src/ty/lower.rs | 3 +-- 6 files changed, 47 insertions(+), 66 deletions(-) delete mode 100644 crates/ra_hir/src/adt.rs (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs deleted file mode 100644 index 945f236c2..000000000 --- a/crates/ra_hir/src/adt.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! This module contains the implementation details of the HIR for ADTs, i.e. -//! structs and enums (and unions). - -use std::sync::Arc; - -use hir_def::adt::VariantData; - -use crate::{ - db::{DefDatabase, HirDatabase}, - EnumVariant, Module, Name, Struct, StructField, -}; - -impl Struct { - pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc { - db.struct_data(self.id.into()).variant_data.clone() - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum VariantDef { - Struct(Struct), - EnumVariant(EnumVariant), -} -impl_froms!(VariantDef: Struct, EnumVariant); - -impl VariantDef { - pub fn fields(self, db: &impl HirDatabase) -> Vec { - match self { - VariantDef::Struct(it) => it.fields(db), - VariantDef::EnumVariant(it) => it.fields(db), - } - } - - pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option { - match self { - VariantDef::Struct(it) => it.field(db, name), - VariantDef::EnumVariant(it) => it.field(db, name), - } - } - - pub fn module(self, db: &impl HirDatabase) -> Module { - match self { - VariantDef::Struct(it) => it.module(db), - VariantDef::EnumVariant(it) => it.module(db), - } - } - - pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc { - match self { - VariantDef::Struct(it) => it.variant_data(db), - VariantDef::EnumVariant(it) => it.variant_data(db), - } - } -} diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index e2638cf92..9b6276b51 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -23,7 +23,6 @@ use ra_db::{CrateId, Edition}; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; use crate::{ - adt::VariantDef, db::{AstDatabase, DefDatabase, HirDatabase}, expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, generics::{GenericDef, HasGenericParams}, @@ -324,6 +323,10 @@ impl Struct { // ...and add generic params, if present r.push_generic_params_scope(db, self.into()) } + + fn variant_data(self, db: &impl DefDatabase) -> Arc { + db.struct_data(self.id.into()).variant_data.clone() + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -482,6 +485,43 @@ impl Adt { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum VariantDef { + Struct(Struct), + EnumVariant(EnumVariant), +} +impl_froms!(VariantDef: Struct, EnumVariant); + +impl VariantDef { + pub fn fields(self, db: &impl HirDatabase) -> Vec { + match self { + VariantDef::Struct(it) => it.fields(db), + VariantDef::EnumVariant(it) => it.fields(db), + } + } + + pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option { + match self { + VariantDef::Struct(it) => it.field(db, name), + VariantDef::EnumVariant(it) => it.field(db, name), + } + } + + pub fn module(self, db: &impl HirDatabase) -> Module { + match self { + VariantDef::Struct(it) => it.module(db), + VariantDef::EnumVariant(it) => it.module(db), + } + } + + pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc { + match self { + VariantDef::Struct(it) => it.variant_data(db), + VariantDef::EnumVariant(it) => it.variant_data(db), + } + } +} + /// The defs which have a body. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum DefWithBody { diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 354d2c98f..4aa427de4 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -4,11 +4,10 @@ use hir_def::{HasSource as _, Lookup}; use ra_syntax::ast::{self, AstNode}; use crate::{ - adt::VariantDef, db::{AstDatabase, DefDatabase, HirDatabase}, ids::AstItemDef, Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module, - ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, + ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, }; pub use hir_expand::Source; diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 7ac9a9041..31da74d2f 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -32,7 +32,6 @@ pub mod db; pub mod source_binder; mod ids; -mod adt; mod type_alias; mod ty; mod impl_block; @@ -56,15 +55,14 @@ mod marks; use crate::resolve::Resolver; pub use crate::{ - adt::VariantDef, - code_model::ImplBlock, code_model::{ attrs::{AttrDef, Attrs}, docs::{DocDef, Docs, Documentation}, src::{HasBodySource, HasSource}, Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, - EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, Local, MacroDef, Module, - ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, + EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, + MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, + Union, VariantDef, }, expr::ExprScopes, from_source::FromSource, diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c35378cc4..092bc3a3f 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -37,14 +37,13 @@ use super::{ TypeCtor, TypeWalk, Uncertain, }; use crate::{ - adt::VariantDef, code_model::TypeAlias, db::HirDatabase, expr::{BindingAnnotation, Body, ExprId, PatId}, resolve::{Resolver, TypeNs}, ty::infer::diagnostics::InferenceDiagnostic, Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, - StructField, + StructField, VariantDef, }; macro_rules! ty_app { diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 03db38605..91e60b5ab 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -19,7 +19,6 @@ use super::{ TypeWalk, }; use crate::{ - adt::VariantDef, db::HirDatabase, generics::HasGenericParams, generics::{GenericDef, WherePredicate}, @@ -30,7 +29,7 @@ use crate::{ }, util::make_mut_slice, Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, - TypeAlias, Union, + TypeAlias, Union, VariantDef, }; // FIXME: this is only really used in `type_for_def`, which contains a bunch of -- cgit v1.2.3 From 6241cf9a598b19cbd6c8c41c3743f8d56adafd2b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 21:55:33 +0300 Subject: Add HasResolver trait --- crates/ra_hir/src/code_model.rs | 106 +----------------------------- crates/ra_hir/src/expr.rs | 1 + crates/ra_hir/src/generics.rs | 18 +---- crates/ra_hir/src/impl_block.rs | 10 +-- crates/ra_hir/src/resolve.rs | 131 ++++++++++++++++++++++++++++++++++++- crates/ra_hir/src/source_binder.rs | 2 +- crates/ra_hir/src/ty/infer.rs | 2 +- crates/ra_hir/src/ty/lower.rs | 2 +- 8 files changed, 138 insertions(+), 134 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 9b6276b51..c5539e076 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -30,7 +30,7 @@ use crate::{ AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, TypeAliasId, }, - resolve::{Resolver, Scope, TypeNs}, + resolve::{HasResolver, TypeNs}, ty::{InferenceResult, Namespace, TraitRef}, Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, }; @@ -223,11 +223,6 @@ impl Module { } } - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - let def_map = db.crate_def_map(self.id.krate); - Resolver::default().push_module_scope(def_map, self.id.module_id) - } - pub fn declarations(self, db: &impl DefDatabase) -> Vec { let def_map = db.crate_def_map(self.id.krate); def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() @@ -315,15 +310,6 @@ impl Struct { db.type_for_def(self.into(), Namespace::Values) } - // FIXME move to a more general type - /// Builds a resolver for type references inside this struct. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } - fn variant_data(self, db: &impl DefDatabase) -> Arc { db.struct_data(self.id.into()).variant_data.clone() } @@ -339,22 +325,13 @@ impl Union { db.struct_data(self.id.into()).name.clone() } - pub fn module(self, db: &impl HirDatabase) -> Module { + pub fn module(self, db: &impl DefDatabase) -> Module { Module { id: self.id.0.module(db) } } pub fn ty(self, db: &impl HirDatabase) -> Ty { db.type_for_def(self.into(), Namespace::Types) } - - // FIXME move to a more general type - /// Builds a resolver for type references inside this union. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -394,16 +371,6 @@ impl Enum { pub fn ty(self, db: &impl HirDatabase) -> Ty { db.type_for_def(self.into(), Namespace::Types) } - - // FIXME: move to a more general type - /// Builds a resolver for type references inside this struct. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - let r = r.push_generic_params_scope(db, self.into()); - r.push_scope(Scope::AdtScope(self.into())) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -475,14 +442,6 @@ impl Adt { .krate(), ) } - - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - match self { - Adt::Struct(it) => it.resolver(db), - Adt::Union(it) => it.resolver(db), - Adt::Enum(it) => it.resolver(db), - } - } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -533,15 +492,6 @@ pub enum DefWithBody { impl_froms!(DefWithBody: Function, Const, Static); impl DefWithBody { - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - match self { - DefWithBody::Const(c) => c.resolver(db), - DefWithBody::Function(f) => f.resolver(db), - DefWithBody::Static(s) => s.resolver(db), - } - } - pub(crate) fn krate(self, db: &impl HirDatabase) -> Option { match self { DefWithBody::Const(c) => c.krate(db), @@ -738,15 +688,6 @@ impl Function { } } - // FIXME: move to a more general type for 'body-having' items - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } - pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { let infer = self.infer(db); infer.add_diagnostics(db, self, sink); @@ -804,17 +745,6 @@ impl Const { ContainerId::ModuleId(_) => None, } } - - // FIXME: move to a more general type for 'body-having' items - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self - .impl_block(db) - .map(|ib| ib.resolver(db)) - .unwrap_or_else(|| self.module(db).resolver(db)); - r - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -874,12 +804,6 @@ impl Static { db.static_data(self) } - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - self.module(db).resolver(db) - } - pub fn infer(self, db: &impl HirDatabase) -> Arc { db.infer(self.into()) } @@ -975,12 +899,6 @@ impl Trait { pub fn is_auto(self, db: &impl DefDatabase) -> bool { self.trait_data(db).auto } - - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - let r = self.module(db).resolver(db); - // add generic params, if present - r.push_generic_params_scope(db, self.into()) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -1032,17 +950,6 @@ impl TypeAlias { pub fn name(self, db: &impl DefDatabase) -> Name { db.type_alias_data(self).name.clone() } - - /// Builds a resolver for the type references in this type alias. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self - .impl_block(db) - .map(|ib| ib.resolver(db)) - .unwrap_or_else(|| self.module(db).resolver(db)); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -1058,15 +965,6 @@ pub enum Container { } impl_froms!(Container: Trait, ImplBlock); -impl Container { - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - match self { - Container::Trait(trait_) => trait_.resolver(db), - Container::ImplBlock(impl_block) => impl_block.resolver(db), - } - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum AssocItem { Function(Function), diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 8bfdda45e..869879bdf 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -11,6 +11,7 @@ use rustc_hash::FxHashSet; use crate::{ db::HirDatabase, diagnostics::{MissingFields, MissingOkInTailExpr}, + resolve::HasResolver, ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, }; diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 54ed03642..f1bf2ee9d 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs @@ -2,8 +2,8 @@ use std::sync::Arc; use crate::{ - db::{DefDatabase, HirDatabase}, - Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, TypeAlias, Union, + db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, + TypeAlias, Union, }; pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate}; @@ -31,20 +31,6 @@ impl_froms!( Const ); -impl GenericDef { - pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver { - match self { - GenericDef::Function(inner) => inner.resolver(db), - GenericDef::Adt(adt) => adt.resolver(db), - GenericDef::Trait(inner) => inner.resolver(db), - GenericDef::TypeAlias(inner) => inner.resolver(db), - GenericDef::ImplBlock(inner) => inner.resolver(db), - GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), - GenericDef::Const(inner) => inner.resolver(db), - } - } -} - impl From for GenericDef { fn from(c: Container) -> Self { match c { diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 492d964a4..964a3da8c 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -5,7 +5,7 @@ use ra_syntax::ast::{self}; use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, - resolve::Resolver, + resolve::HasResolver, ty::Ty, AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, }; @@ -50,12 +50,4 @@ impl ImplBlock { pub fn krate(&self, db: &impl DefDatabase) -> Crate { Crate { crate_id: self.module(db).id.krate } } - - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - let r = self.module(db).resolver(db); - // add generic params, if present - let r = r.push_generic_params_scope(db, self.into()); - let r = r.push_impl_block_scope(self); - r - } } diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index e5e768be9..b8e1b4dad 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -15,8 +15,8 @@ use crate::{ db::{DefDatabase, HirDatabase}, expr::{ExprScopes, PatId, ScopeId}, generics::{GenericParams, HasGenericParams}, - Adt, Const, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, MacroDef, - ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, + Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, + MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, Union, }; #[derive(Debug, Clone, Default)] @@ -486,3 +486,130 @@ impl Scope { } } } + +pub(crate) trait HasResolver { + /// Builds a resolver for type references inside this def. + fn resolver(self, db: &impl DefDatabase) -> Resolver; +} + +impl HasResolver for Module { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + let def_map = db.crate_def_map(self.id.krate); + Resolver::default().push_module_scope(def_map, self.id.module_id) + } +} + +impl HasResolver for Trait { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db).resolver(db).push_generic_params_scope(db, self.into()) + } +} + +impl HasResolver for Struct { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_scope(Scope::AdtScope(self.into())) + } +} + +impl HasResolver for Union { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_scope(Scope::AdtScope(self.into())) + } +} + +impl HasResolver for Enum { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_scope(Scope::AdtScope(self.into())) + } +} + +impl HasResolver for Adt { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + Adt::Struct(it) => it.resolver(db), + Adt::Union(it) => it.resolver(db), + Adt::Enum(it) => it.resolver(db), + } + } +} + +impl HasResolver for Function { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.container(db) + .map(|c| c.resolver(db)) + .unwrap_or_else(|| self.module(db).resolver(db)) + .push_generic_params_scope(db, self.into()) + } +} + +impl HasResolver for DefWithBody { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + DefWithBody::Const(c) => c.resolver(db), + DefWithBody::Function(f) => f.resolver(db), + DefWithBody::Static(s) => s.resolver(db), + } + } +} + +impl HasResolver for Const { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db)) + } +} + +impl HasResolver for Static { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db).resolver(db) + } +} + +impl HasResolver for TypeAlias { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.container(db) + .map(|ib| ib.resolver(db)) + .unwrap_or_else(|| self.module(db).resolver(db)) + .push_generic_params_scope(db, self.into()) + } +} + +impl HasResolver for Container { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + Container::Trait(trait_) => trait_.resolver(db), + Container::ImplBlock(impl_block) => impl_block.resolver(db), + } + } +} + +impl HasResolver for GenericDef { + fn resolver(self, db: &impl DefDatabase) -> crate::Resolver { + match self { + GenericDef::Function(inner) => inner.resolver(db), + GenericDef::Adt(adt) => adt.resolver(db), + GenericDef::Trait(inner) => inner.resolver(db), + GenericDef::TypeAlias(inner) => inner.resolver(db), + GenericDef::ImplBlock(inner) => inner.resolver(db), + GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), + GenericDef::Const(inner) => inner.resolver(db), + } + } +} + +impl HasResolver for ImplBlock { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_impl_block_scope(self) + } +} diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index fd9994098..727310f06 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -23,7 +23,7 @@ use crate::{ db::HirDatabase, expr::{self, BodySourceMap, ExprScopes, ScopeId}, ids::LocationCtx, - resolve::{ScopeDef, TypeNs, ValueNs}, + resolve::{HasResolver, ScopeDef, TypeNs, ValueNs}, ty::method_resolution::{self, implements_trait}, AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 092bc3a3f..7f9e81d64 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -40,7 +40,7 @@ use crate::{ code_model::TypeAlias, db::HirDatabase, expr::{BindingAnnotation, Body, ExprId, PatId}, - resolve::{Resolver, TypeNs}, + resolve::{HasResolver, Resolver, TypeNs}, ty::infer::diagnostics::InferenceDiagnostic, Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, StructField, VariantDef, diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 91e60b5ab..397ee7d5f 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -22,7 +22,7 @@ use crate::{ db::HirDatabase, generics::HasGenericParams, generics::{GenericDef, WherePredicate}, - resolve::{Resolver, TypeNs}, + resolve::{HasResolver, Resolver, TypeNs}, ty::{ primitive::{FloatTy, IntTy, Uncertain}, Adt, -- cgit v1.2.3 From 1cead415100c35097d5ea68cf58b9485fe306dc2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 22:00:57 +0300 Subject: Simplify --- crates/ra_hir/src/code_model.rs | 17 +++++++++-------- crates/ra_hir/src/resolve.rs | 39 ++++++--------------------------------- 2 files changed, 15 insertions(+), 41 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 c5539e076..a132d128b 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -432,15 +432,16 @@ impl Adt { } } + pub fn module(self, db: &impl DefDatabase) -> Module { + match self { + Adt::Struct(s) => s.module(db), + Adt::Union(s) => s.module(db), + Adt::Enum(e) => e.module(db), + } + } + pub fn krate(self, db: &impl HirDatabase) -> Option { - Some( - match self { - Adt::Struct(s) => s.module(db), - Adt::Union(s) => s.module(db), - Adt::Enum(e) => e.module(db), - } - .krate(), - ) + Some(self.module(db).krate()) } } diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index b8e1b4dad..eca8e0596 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -16,7 +16,7 @@ use crate::{ expr::{ExprScopes, PatId, ScopeId}, generics::{GenericParams, HasGenericParams}, Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, - MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, Union, + MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, }; #[derive(Debug, Clone, Default)] @@ -505,40 +505,13 @@ impl HasResolver for Trait { } } -impl HasResolver for Struct { +impl> HasResolver for T { fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db) - .resolver(db) - .push_generic_params_scope(db, self.into()) - .push_scope(Scope::AdtScope(self.into())) - } -} - -impl HasResolver for Union { - fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db) - .resolver(db) - .push_generic_params_scope(db, self.into()) - .push_scope(Scope::AdtScope(self.into())) - } -} - -impl HasResolver for Enum { - fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db) + let def = self.into(); + def.module(db) .resolver(db) - .push_generic_params_scope(db, self.into()) - .push_scope(Scope::AdtScope(self.into())) - } -} - -impl HasResolver for Adt { - fn resolver(self, db: &impl DefDatabase) -> Resolver { - match self { - Adt::Struct(it) => it.resolver(db), - Adt::Union(it) => it.resolver(db), - Adt::Enum(it) => it.resolver(db), - } + .push_generic_params_scope(db, def.into()) + .push_scope(Scope::AdtScope(def)) } } -- cgit v1.2.3