From 66f04e6be54c47104877bff777b7042960d04393 Mon Sep 17 00:00:00 2001 From: Frizi Date: Sun, 24 Nov 2019 17:36:30 +0100 Subject: [PATCH 01/65] Show missing struct fields in the error message --- crates/ra_hir/src/diagnostics.rs | 7 ++++++- crates/ra_hir/src/ty/tests.rs | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index dafacba70c..6db499e060 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs @@ -39,7 +39,12 @@ pub struct MissingFields { impl Diagnostic for MissingFields { fn message(&self) -> String { - "fill structure fields".to_string() + use std::fmt::Write; + let mut message = String::from("Missing structure fields:\n"); + for field in &self.missed_fields { + write!(message, "- {}\n", field).unwrap(); + } + message } fn source(&self) -> Source { Source { file_id: self.file, value: self.field_list.into() } diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 3209c66bd0..98eb863cb9 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -4832,7 +4832,8 @@ fn no_such_field_diagnostics() { assert_snapshot!(diagnostics, @r###" "baz: 62": no such field - "{\n foo: 92,\n baz: 62,\n }": fill structure fields + "{\n foo: 92,\n baz: 62,\n }": Missing structure fields: + - bar "### ); } From bd53bd80bff9a1f320615a975235399b1fa4792e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 12:45:45 +0300 Subject: [PATCH 02/65] Push resolver up --- crates/ra_hir/src/ty/autoderef.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 41c99d227b..86b08ae6ff 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -8,10 +8,14 @@ use std::iter::successors; use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; use hir_expand::name; use log::{info, warn}; +use ra_db::CrateId; use crate::{db::HirDatabase, Trait}; -use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; +use super::{ + traits::{InEnvironment, Solution}, + Canonical, Substs, Ty, TypeWalk, +}; const AUTODEREF_RECURSION_LIMIT: usize = 10; @@ -31,16 +35,17 @@ pub(crate) fn deref( if let Some(derefed) = ty.value.builtin_deref() { Some(Canonical { value: derefed, num_vars: ty.num_vars }) } else { - deref_by_trait(db, resolver, ty) + let krate = resolver.krate()?; + let environment = super::lower::trait_env(db, resolver); + deref_by_trait(db, krate, InEnvironment { value: ty, environment }) } } fn deref_by_trait( db: &impl HirDatabase, - resolver: &Resolver, - ty: &Canonical, + krate: CrateId, + ty: InEnvironment<&Canonical>, ) -> Option> { - let krate = resolver.krate()?; let deref_trait = match db.lang_item(krate.into(), "deref".into())? { LangItemTarget::TraitId(t) => Trait::from(t), _ => return None, @@ -56,10 +61,8 @@ fn deref_by_trait( // FIXME make the Canonical handling nicer - let env = super::lower::trait_env(db, resolver); - let parameters = Substs::build_for_generics(&generic_params) - .push(ty.value.clone().shift_bound_vars(1)) + .push(ty.value.value.clone().shift_bound_vars(1)) .build(); let projection = super::traits::ProjectionPredicate { @@ -69,9 +72,9 @@ fn deref_by_trait( let obligation = super::Obligation::Projection(projection); - let in_env = super::traits::InEnvironment { value: obligation, environment: env }; + let in_env = InEnvironment { value: obligation, environment: ty.environment }; - let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; + let canonical = super::Canonical { num_vars: 1 + ty.value.num_vars, value: in_env }; let solution = db.trait_solve(krate.into(), canonical)?; @@ -89,14 +92,14 @@ fn deref_by_trait( // the case. for i in 1..vars.0.num_vars { if vars.0.value[i] != Ty::Bound((i - 1) as u32) { - warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution); + warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); return None; } } Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) } Solution::Ambig(_) => { - info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution); + info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); None } } From 8c3e372835243c922b0eff7ca23f79f227991e88 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 13:10:26 +0300 Subject: [PATCH 03/65] Remove Resolver from autoderef Resolver holds onto too much context, including local scopes. Let's try to pass in only what is necessary -- the trait environment. --- crates/ra_hir/src/source_binder.rs | 10 ++++-- crates/ra_hir/src/ty/autoderef.rs | 24 +++++++------- crates/ra_hir/src/ty/infer.rs | 3 +- crates/ra_hir/src/ty/infer/coerce.rs | 13 +++++--- crates/ra_hir/src/ty/infer/expr.rs | 40 +++++++++++++++-------- crates/ra_hir/src/ty/lower.rs | 21 ++++++------ crates/ra_hir/src/ty/method_resolution.rs | 11 ++++--- 7 files changed, 73 insertions(+), 49 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 31390bb7ff..b4f0e81d30 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -26,7 +26,10 @@ use ra_syntax::{ use crate::{ db::HirDatabase, expr::{BodySourceMap, ExprScopes, ScopeId}, - ty::method_resolution::{self, implements_trait}, + ty::{ + method_resolution::{self, implements_trait}, + TraitEnvironment, + }, Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias, }; @@ -408,7 +411,10 @@ impl SourceAnalyzer { // There should be no inference vars in types passed here // FIXME check that? let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; - crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) + let krate = self.resolver.krate(); + let environment = TraitEnvironment::lower(db, &self.resolver); + let ty = crate::ty::InEnvironment { value: canonical, environment }; + crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) } /// Checks that particular type `ty` implements `std::future::Future`. diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 86b08ae6ff..44547197ca 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -5,7 +5,7 @@ use std::iter::successors; -use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; +use hir_def::lang_item::LangItemTarget; use hir_expand::name; use log::{info, warn}; use ra_db::CrateId; @@ -21,23 +21,25 @@ const AUTODEREF_RECURSION_LIMIT: usize = 10; pub(crate) fn autoderef<'a>( db: &'a impl HirDatabase, - resolver: &'a Resolver, - ty: Canonical, + krate: Option, + ty: InEnvironment>, ) -> impl Iterator> + 'a { - successors(Some(ty), move |ty| deref(db, resolver, ty)).take(AUTODEREF_RECURSION_LIMIT) + let InEnvironment { value: ty, environment } = ty; + successors(Some(ty), move |ty| { + deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) + }) + .take(AUTODEREF_RECURSION_LIMIT) } pub(crate) fn deref( db: &impl HirDatabase, - resolver: &Resolver, - ty: &Canonical, + krate: CrateId, + ty: InEnvironment<&Canonical>, ) -> Option> { - if let Some(derefed) = ty.value.builtin_deref() { - Some(Canonical { value: derefed, num_vars: ty.num_vars }) + if let Some(derefed) = ty.value.value.builtin_deref() { + Some(Canonical { value: derefed, num_vars: ty.value.num_vars }) } else { - let krate = resolver.krate()?; - let environment = super::lower::trait_env(db, resolver); - deref_by_trait(db, krate, InEnvironment { value: ty, environment }) + deref_by_trait(db, krate, ty) } } diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index ddc7d262aa..6fd00d457f 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -34,7 +34,6 @@ use ra_prof::profile; use test_utils::tested_by; use super::{ - lower, traits::{Guidance, Obligation, ProjectionPredicate, Solution}, ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, TypeCtor, TypeWalk, Uncertain, @@ -216,7 +215,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { var_unification_table: InPlaceUnificationTable::new(), obligations: Vec::default(), return_ty: Ty::Unknown, // set in collect_fn_signature - trait_env: lower::trait_env(db, &resolver), + trait_env: TraitEnvironment::lower(db, &resolver), coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), db, owner, diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 54765da358..4b53bba73b 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -14,7 +14,7 @@ use crate::{ Adt, Mutability, }; -use super::{InferTy, InferenceContext, TypeVarValue}; +use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// Unify two types, but may coerce the first one to the second one @@ -320,9 +320,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); let to_ty = self.resolve_ty_shallow(&to_ty); // FIXME: Auto DerefMut - for derefed_ty in - autoderef::autoderef(self.db, &self.resolver.clone(), canonicalized.value.clone()) - { + for derefed_ty in autoderef::autoderef( + self.db, + self.resolver.krate(), + InEnvironment { + value: canonicalized.value.clone(), + environment: self.trait_env.clone(), + }, + ) { let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { // Stop when constructor matches. diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 663ff9435c..194e558191 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -15,9 +15,9 @@ use crate::{ db::HirDatabase, expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, ty::{ - autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, - Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, - Uncertain, + autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, + Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, + TypeCtor, TypeWalk, Uncertain, }, Adt, Name, }; @@ -245,8 +245,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); let ty = autoderef::autoderef( self.db, - &self.resolver.clone(), - canonicalized.value.clone(), + self.resolver.krate(), + InEnvironment { + value: canonicalized.value.clone(), + environment: self.trait_env.clone(), + }, ) .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { Ty::Apply(a_ty) => match a_ty.ctor { @@ -337,16 +340,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Expr::UnaryOp { expr, op } => { let inner_ty = self.infer_expr(*expr, &Expectation::none()); match op { - UnaryOp::Deref => { - let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); - if let Some(derefed_ty) = - autoderef::deref(self.db, &self.resolver, &canonicalized.value) - { - canonicalized.decanonicalize_ty(derefed_ty.value) - } else { - Ty::Unknown + UnaryOp::Deref => match self.resolver.krate() { + Some(krate) => { + let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); + match autoderef::deref( + self.db, + krate, + InEnvironment { + value: &canonicalized.value, + environment: self.trait_env.clone(), + }, + ) { + Some(derefed_ty) => { + canonicalized.decanonicalize_ty(derefed_ty.value) + } + None => Ty::Unknown, + } } - } + None => Ty::Unknown, + }, UnaryOp::Neg => { match &inner_ty { Ty::Apply(a_ty) => match a_ty.ctor { diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index a39beb2a08..b769295018 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -19,8 +19,8 @@ use hir_def::{ use ra_arena::map::ArenaMap; use super::{ - FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, - TypeWalk, + FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, + Ty, TypeCtor, TypeWalk, }; use crate::{ db::HirDatabase, @@ -591,16 +591,15 @@ pub(crate) fn generic_predicates_for_param_query( .collect() } -pub(crate) fn trait_env( - db: &impl HirDatabase, - resolver: &Resolver, -) -> Arc { - let predicates = resolver - .where_predicates_in_scope() - .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) - .collect::>(); +impl TraitEnvironment { + pub(crate) fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc { + let predicates = resolver + .where_predicates_in_scope() + .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) + .collect::>(); - Arc::new(super::TraitEnvironment { predicates }) + Arc::new(TraitEnvironment { predicates }) + } } /// Resolve the where clause(s) of an item with generics. diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index caa5f5f74a..f7905b5ffe 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -15,7 +15,7 @@ use crate::{ AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, }; -use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; +use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; /// This is used as a key for indexing impls. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -179,8 +179,9 @@ pub(crate) fn iterate_method_candidates( // Also note that when we've got a receiver like &S, even if the method we // find in the end takes &self, we still do the autoderef step (just as // rustc does an autoderef and then autoref again). - - for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { + let environment = TraitEnvironment::lower(db, resolver); + let ty = InEnvironment { value: ty.clone(), environment }; + for derefed_ty in autoderef::autoderef(db, resolver.krate(), ty) { if let Some(result) = iterate_inherent_methods( &derefed_ty, db, @@ -230,7 +231,7 @@ fn iterate_trait_method_candidates( ) -> Option { let krate = resolver.krate()?; // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) - let env = lower::trait_env(db, resolver); + let env = TraitEnvironment::lower(db, resolver); // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope let inherent_trait = ty.value.inherent_trait().into_iter(); // if we have `T: Trait` in the param env, the trait doesn't need to be in scope @@ -324,7 +325,7 @@ pub(crate) fn implements_trait( // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet return true; } - let env = lower::trait_env(db, resolver); + let env = TraitEnvironment::lower(db, resolver); let goal = generic_implements_goal(db, env, trait_, ty.clone()); let solution = db.trait_solve(krate, goal); From c2a16632d0773dec707acb215297ef55b5c880fe Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 15:39:12 +0300 Subject: [PATCH 04/65] Use GenericDefId more --- crates/ra_hir/src/db.rs | 4 ++-- crates/ra_hir/src/from_id.rs | 17 ++--------------- crates/ra_hir/src/ty.rs | 6 +++--- crates/ra_hir/src/ty/lower.rs | 16 ++++++++-------- crates/ra_hir/src/ty/traits/chalk.rs | 10 +++++----- 5 files changed, 20 insertions(+), 33 deletions(-) diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 5084bbacf5..7ec04ad73d 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -24,7 +24,7 @@ pub use hir_def::{ RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, }, - LocalStructFieldId, VariantId, + GenericDefId, LocalStructFieldId, VariantId, }; pub use hir_expand::db::{ AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, @@ -54,7 +54,7 @@ pub trait HirDatabase: DefDatabase { ) -> Arc<[GenericPredicate]>; #[salsa::invoke(crate::ty::generic_predicates_query)] - fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; + fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>; #[salsa::invoke(crate::ty::generic_defaults_query)] fn generic_defaults(&self, def: GenericDef) -> Substs; diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 529ac82517..3a27d6f0c3 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -9,9 +9,8 @@ use hir_def::{ }; use crate::{ - ty::{CallableDef, TypableDef}, - Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, - ModuleDef, Static, StructField, TypeAlias, VariantDef, + ty::TypableDef, Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, + GenericDef, ModuleDef, Static, StructField, TypeAlias, VariantDef, }; impl From for Crate { @@ -214,18 +213,6 @@ impl From for GenericDefId { } } -impl From for GenericDefId { - fn from(def: CallableDef) -> Self { - match def { - CallableDef::Function(it) => it.id.into(), - CallableDef::Struct(it) => it.id.into(), - CallableDef::EnumVariant(it) => { - EnumVariantId { parent: it.parent.id, local_id: it.id }.into() - } - } - } -} - impl From for VariantId { fn from(def: VariantDef) -> Self { match def { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index f62316c1fb..2473ac5745 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -17,7 +17,7 @@ use std::ops::Deref; use std::sync::Arc; use std::{fmt, iter, mem}; -use hir_def::{generics::GenericParams, AdtId}; +use hir_def::{generics::GenericParams, AdtId, GenericDefId}; use ra_db::{impl_intern_key, salsa}; use crate::{ @@ -176,7 +176,7 @@ impl TypeCtor { } } - pub fn as_generic_def(self) -> Option { + pub fn as_generic_def(self) -> Option { match self { TypeCtor::Bool | TypeCtor::Char @@ -193,7 +193,7 @@ impl TypeCtor { | TypeCtor::Closure { .. } => None, TypeCtor::Adt(adt) => Some(adt.into()), TypeCtor::FnDef(callable) => Some(callable.into()), - TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), + TypeCtor::AssociatedType(type_alias) => Some(type_alias.id.into()), } } } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index b769295018..da3c8e94af 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -14,7 +14,7 @@ use hir_def::{ path::{GenericArg, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, - AdtId, GenericDefId, LocalStructFieldId, VariantId, + AdtId, EnumVariantId, GenericDefId, LocalStructFieldId, VariantId, }; use ra_arena::map::ArenaMap; @@ -605,9 +605,9 @@ impl TraitEnvironment { /// Resolve the where clause(s) of an item with generics. pub(crate) fn generic_predicates_query( db: &impl HirDatabase, - def: GenericDef, + def: GenericDefId, ) -> Arc<[GenericPredicate]> { - let resolver = GenericDefId::from(def).resolver(db); + let resolver = def.resolver(db); resolver .where_predicates_in_scope() .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) @@ -819,12 +819,12 @@ impl CallableDef { } } -impl From for GenericDef { - fn from(def: CallableDef) -> GenericDef { +impl From for GenericDefId { + fn from(def: CallableDef) -> GenericDefId { match def { - CallableDef::Function(f) => f.into(), - CallableDef::Struct(s) => s.into(), - CallableDef::EnumVariant(e) => e.into(), + CallableDef::Function(f) => f.id.into(), + CallableDef::Struct(s) => s.id.into(), + CallableDef::EnumVariant(e) => EnumVariantId::from(e).into(), } } } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 1a93e5e506..a0dbf63052 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -9,7 +9,7 @@ use chalk_ir::{ }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; -use hir_def::lang_item::LangItemTarget; +use hir_def::{lang_item::LangItemTarget, GenericDefId}; use hir_expand::name; use ra_db::salsa::{InternId, InternKey}; @@ -19,7 +19,7 @@ use crate::{ db::HirDatabase, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - Crate, GenericDef, ImplBlock, Trait, TypeAlias, + Crate, ImplBlock, Trait, TypeAlias, }; /// This represents a trait whose name we could not resolve. @@ -402,7 +402,7 @@ fn make_binders(value: T, num_vars: usize) -> chalk_ir::Binders { fn convert_where_clauses( db: &impl HirDatabase, - def: GenericDef, + def: GenericDefId, substs: &Substs, ) -> Vec> { let generic_predicates = db.generic_predicates(def); @@ -561,7 +561,7 @@ pub(crate) fn trait_datum_query( marker: false, fundamental: false, }; - let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); + let where_clauses = convert_where_clauses(db, trait_.id.into(), &bound_vars); let associated_ty_ids = trait_ .items(db) .into_iter() @@ -643,7 +643,7 @@ fn impl_block_datum( } else { chalk_rust_ir::ImplType::External }; - let where_clauses = convert_where_clauses(db, impl_block.into(), &bound_vars); + let where_clauses = convert_where_clauses(db, impl_block.id.into(), &bound_vars); let negative = impl_block.is_negative(db); debug!( "impl {:?}: {}{} where {:?}", From 5f39c5794ec2521e9bb4c108771a1644269859ab Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 15:41:53 +0300 Subject: [PATCH 05/65] Use GenericDefIdMore --- crates/ra_hir/src/code_model.rs | 18 +++-------- crates/ra_hir/src/db.rs | 6 ++-- crates/ra_hir/src/from_id.rs | 24 ++++++-------- crates/ra_hir/src/source_binder.rs | 4 +-- crates/ra_hir/src/ty.rs | 8 ++--- crates/ra_hir/src/ty/infer/path.rs | 2 +- crates/ra_hir/src/ty/lower.rs | 32 ++++++++++--------- crates/ra_hir/src/ty/method_resolution.rs | 2 +- crates/ra_hir/src/ty/traits/chalk.rs | 2 +- .../ra_ide_api/src/completion/presentation.rs | 2 +- 10 files changed, 44 insertions(+), 56 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 3f44a50c4d..534f1f8e98 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -11,9 +11,9 @@ use hir_def::{ per_ns::PerNs, resolver::{HasResolver, TypeNs}, type_ref::TypeRef, - AstItemDef, ConstId, ContainerId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, - LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, - TraitId, TypeAliasId, UnionId, + AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, + LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, + StaticId, StructId, TraitId, TypeAliasId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -897,16 +897,6 @@ impl_froms!( Const ); -impl From for GenericDef { - fn from(item: AssocItem) -> Self { - match item { - AssocItem::Function(f) => f.into(), - AssocItem::Const(c) => c.into(), - AssocItem::TypeAlias(t) => t.into(), - } - } -} - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Local { pub(crate) parent: DefWithBody, @@ -960,7 +950,7 @@ impl Local { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct GenericParam { - pub(crate) parent: GenericDef, + pub(crate) parent: GenericDefId, pub(crate) idx: u32, } diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 7ec04ad73d..b034d4e448 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -12,7 +12,7 @@ use crate::{ CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, TypeCtor, }, - Crate, DefWithBody, GenericDef, ImplBlock, Trait, + Crate, DefWithBody, ImplBlock, Trait, }; pub use hir_def::{ @@ -49,7 +49,7 @@ pub trait HirDatabase: DefDatabase { #[salsa::invoke(crate::ty::generic_predicates_for_param_query)] fn generic_predicates_for_param( &self, - def: GenericDef, + def: GenericDefId, param_idx: u32, ) -> Arc<[GenericPredicate]>; @@ -57,7 +57,7 @@ pub trait HirDatabase: DefDatabase { fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>; #[salsa::invoke(crate::ty::generic_defaults_query)] - fn generic_defaults(&self, def: GenericDef) -> Substs; + fn generic_defaults(&self, def: GenericDefId) -> Substs; #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] fn impls_in_crate(&self, krate: Crate) -> Arc; diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 3a27d6f0c3..619f6055e1 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -137,20 +137,6 @@ impl From for GenericDefId { } } -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()), - } - } -} - impl From for TypableDef { fn from(id: AdtId) -> Self { Adt::from(id).into() @@ -244,3 +230,13 @@ impl From for AttrDefId { } } } + +impl From for GenericDefId { + fn from(item: AssocItem) -> Self { + match item { + AssocItem::Function(f) => f.id.into(), + AssocItem::Const(c) => c.id.into(), + AssocItem::TypeAlias(t) => t.id.into(), + } + } +} diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index b4f0e81d30..cbfeca3abb 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -251,7 +251,7 @@ impl SourceAnalyzer { let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { - parent: self.resolver.generic_def().unwrap().into(), + parent: self.resolver.generic_def().unwrap(), idx, }), TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { @@ -326,7 +326,7 @@ impl SourceAnalyzer { resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), resolver::ScopeDef::GenericParam(idx) => { - let parent = self.resolver.generic_def().unwrap().into(); + let parent = self.resolver.generic_def().unwrap(); ScopeDef::GenericParam(GenericParam { parent, idx }) } resolver::ScopeDef::Local(pat_id) => { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 2473ac5745..1e05ac3f23 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -21,8 +21,8 @@ use hir_def::{generics::GenericParams, AdtId, GenericDefId}; use ra_db::{impl_intern_key, salsa}; use crate::{ - db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, - GenericDef, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, + db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, IntTy, + Mutability, Name, Trait, TypeAlias, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -356,9 +356,9 @@ impl Substs { ) } - pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { + pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { let def = def.into(); - let params = db.generic_params(def.into()); + let params = db.generic_params(def); let param_count = params.count_params_including_parent(); Substs::builder(param_count) } diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index ee54d82173..6165eba4fc 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -203,7 +203,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()), Container::Trait(t) => { // we're picking this method - let trait_substs = Substs::build_for_def(self.db, t) + let trait_substs = Substs::build_for_def(self.db, t.id) .push(ty.clone()) .fill(std::iter::repeat_with(|| self.new_type_var())) .build(); diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index da3c8e94af..1ceafd9b15 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -29,8 +29,8 @@ use crate::{ Adt, }, util::make_mut_slice, - Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, - Trait, TypeAlias, Union, + Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, + TypeAlias, Union, }; // FIXME: this is only really used in `type_for_def`, which contains a bunch of @@ -261,8 +261,10 @@ impl Ty { let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); for t in traits { if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { - let substs = - Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); + let substs = Substs::build_for_def(db, t.id) + .push(self_ty.clone()) + .fill_with_unknown() + .build(); // FIXME handle type parameters on the segment return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); } @@ -287,11 +289,11 @@ impl Ty { segment: &PathSegment, resolved: TypableDef, ) -> Substs { - let def_generic: Option = match resolved { - TypableDef::Function(func) => Some(func.into()), + let def_generic: Option = match resolved { + TypableDef::Function(func) => Some(func.id.into()), TypableDef::Adt(adt) => Some(adt.into()), - TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), - TypableDef::TypeAlias(t) => Some(t.into()), + TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()), + TypableDef::TypeAlias(t) => Some(t.id.into()), TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, }; substs_from_path_segment(db, resolver, segment, def_generic, false) @@ -338,7 +340,7 @@ pub(super) fn substs_from_path_segment( db: &impl HirDatabase, resolver: &Resolver, segment: &PathSegment, - def_generic: Option, + def_generic: Option, add_self_param: bool, ) -> Substs { let mut substs = Vec::new(); @@ -376,7 +378,7 @@ pub(super) fn substs_from_path_segment( // handle defaults if let Some(def_generic) = def_generic { - let default_substs = db.generic_defaults(def_generic); + let default_substs = db.generic_defaults(def_generic.into()); assert_eq!(substs.len(), default_substs.len()); for (i, default_ty) in default_substs.iter().enumerate() { @@ -439,7 +441,7 @@ impl TraitRef { ) -> Substs { let has_self_param = segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); - substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) + substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param) } pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { @@ -579,10 +581,10 @@ pub(crate) fn field_types_query( /// these are fine: `T: Foo, U: Foo<()>`. pub(crate) fn generic_predicates_for_param_query( db: &impl HirDatabase, - def: GenericDef, + def: GenericDefId, param_idx: u32, ) -> Arc<[GenericPredicate]> { - let resolver = GenericDefId::from(def).resolver(db); + let resolver = def.resolver(db); resolver .where_predicates_in_scope() // we have to filter out all other predicates *first*, before attempting to lower them @@ -615,8 +617,8 @@ pub(crate) fn generic_predicates_query( } /// Resolve the default type params from generics -pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { - let resolver = GenericDefId::from(def).resolver(db); +pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { + let resolver = def.resolver(db); let generic_params = db.generic_params(def.into()); let defaults = generic_params diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index f7905b5ffe..c5ab690eb9 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -365,7 +365,7 @@ fn generic_implements_goal( self_ty: Canonical, ) -> Canonical> { let num_vars = self_ty.num_vars; - let substs = super::Substs::build_for_def(db, trait_) + let substs = super::Substs::build_for_def(db, trait_.id) .push(self_ty.value) .fill_with_bound_vars(num_vars as u32) .build(); diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index a0dbf63052..0272dd9aef 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -736,7 +736,7 @@ fn closure_fn_trait_impl_datum( let trait_ref = TraitRef { trait_, - substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), + substs: Substs::build_for_def(db, trait_.id).push(self_ty).push(arg_ty).build(), }; let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db); diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index bac3f7582f..85b053a6ee 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -292,7 +292,7 @@ fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { } fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { - let subst = db.generic_defaults(def); + let subst = db.generic_defaults(def.into()); subst.iter().any(|ty| ty == &Ty::Unknown) } From 711c1a3e46b008e43249edfafb5f22cc23daaced Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Mon, 25 Nov 2019 08:12:28 -0500 Subject: [PATCH 06/65] Update crates --- Cargo.lock | 118 ++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f7783deb9..8c81112869 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -105,9 +105,9 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -181,19 +181,18 @@ dependencies = [ "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "chrono" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -356,7 +355,7 @@ name = "flexi_logger" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -472,7 +471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -520,8 +519,8 @@ dependencies = [ "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -536,7 +535,7 @@ dependencies = [ [[package]] name = "itertools" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -643,8 +642,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -653,8 +652,8 @@ version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -755,12 +754,12 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -885,7 +884,7 @@ dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -923,7 +922,7 @@ name = "ra_assists" version = "0.1.0" dependencies = [ "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ra_db 0.1.0", "ra_fmt 0.1.0", @@ -990,7 +989,7 @@ dependencies = [ name = "ra_fmt" version = "0.1.0" dependencies = [ - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "ra_syntax 0.1.0", ] @@ -1061,7 +1060,7 @@ dependencies = [ "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1102,8 +1101,8 @@ dependencies = [ "ra_vfs_glob 0.1.0", "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1134,7 +1133,7 @@ name = "ra_prof" version = "0.1.0" dependencies = [ "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1150,8 +1149,8 @@ dependencies = [ "ra_cfg 0.1.0", "ra_db 0.1.0", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1159,11 +1158,11 @@ name = "ra_syntax" version = "0.1.0" dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ra_parser 0.1.0", "ra_text_edit 0.1.0", - "rowan 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rowan 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1423,17 +1422,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rowan" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thin-dst 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1516,7 +1516,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1526,15 +1526,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1544,12 +1544,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1569,7 +1569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1596,7 +1596,7 @@ name = "smol_str" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1652,7 +1652,7 @@ name = "test_utils" version = "0.1.0" dependencies = [ "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1661,6 +1661,11 @@ name = "text_unit" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "thin-dst" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "thread_local" version = "0.3.6" @@ -1705,10 +1710,10 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1734,7 +1739,7 @@ dependencies = [ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1743,7 +1748,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1816,12 +1821,12 @@ dependencies = [ name = "xtask" version = "0.1.0" dependencies = [ - "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1840,7 +1845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" -"checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968" +"checksum anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1072d8f55592084072d2d3cb23a4b680a8543c00f10d446118e85ad3718142" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" @@ -1862,7 +1867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" "checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" "checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" -"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" +"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5d540c2d34ac9dd0deb5f3b5f54c36c79efa78f6b3ad19106a554d07a7b5d9f" @@ -1903,7 +1908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" "checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -"checksum itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87fa75c9dea7b07be3138c49abbb83fd4bea199b5cdc76f9804458edc5da0d6e" +"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c502a5ff9dd2924f1ed32ba96e3b65735d837b4bfd978d3161b1702e66aca4b7" "checksum jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45" @@ -1930,7 +1935,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" -"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6" +"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" "checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" "checksum number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" "checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" @@ -1974,7 +1979,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5" -"checksum rowan 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a241900475bf2ba302061550ff50c82b45095ca95d23d1872345793fd42407" +"checksum rowan 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ca620bbf9c48c92b5cef19f96354a309ac36b7d8ef7c591e66117335c8b1988b" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5" @@ -1986,9 +1991,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" -"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" -"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" +"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" +"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" +"checksum serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "1a3351dcbc1f067e2c92ab7c3c1f288ad1a4cffc470b5aaddb4c2e0a3ae80043" "checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" @@ -2001,12 +2006,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" "checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579" +"checksum thin-dst 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c52fd98a9e4913c466d83381a59245691875d2f3e04611fca57f964bd8aa96e1" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf" +"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" From 9047a4ad4620d3b37d17a11e6dee0ea4ffbd7af1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 16:16:41 +0300 Subject: [PATCH 07/65] Use more IDs --- crates/ra_hir/src/ty/lower.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 1ceafd9b15..348c5f67d3 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -14,7 +14,7 @@ use hir_def::{ path::{GenericArg, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, - AdtId, EnumVariantId, GenericDefId, LocalStructFieldId, VariantId, + AdtId, EnumVariantId, FunctionId, GenericDefId, LocalStructFieldId, StructId, VariantId, }; use ra_arena::map::ArenaMap; @@ -546,9 +546,9 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace /// Build the signature of a callable item (function, struct or enum variant). pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { match def { - CallableDef::Function(f) => fn_sig_for_fn(db, f), - CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s), - CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e), + CallableDef::Function(f) => fn_sig_for_fn(db, f.id), + CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s.id), + CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e.into()), } } @@ -630,9 +630,9 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) - Substs(defaults) } -fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { - let data = db.function_data(def.id); - let resolver = def.id.resolver(db); +fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { + let data = db.function_data(def); + let resolver = def.resolver(db); let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::>(); let ret = Ty::from_hir(db, &resolver, &data.ret_type); FnSig::from_params_and_return(params, ret) @@ -703,15 +703,15 @@ impl From> for Uncertain { } } -fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { - let struct_data = db.struct_data(def.id.into()); +fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { + let struct_data = db.struct_data(def.into()); let fields = struct_data.variant_data.fields(); - let resolver = def.id.resolver(db); + let resolver = def.resolver(db); let params = fields .iter() .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) .collect::>(); - let ret = type_for_adt(db, def); + let ret = type_for_adt(db, Struct::from(def)); FnSig::from_params_and_return(params, ret) } @@ -726,17 +726,18 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { Ty::apply(TypeCtor::FnDef(def.into()), substs) } -fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { - let var_data = def.variant_data(db); - let fields = var_data.fields(); - let resolver = def.parent.id.resolver(db); +fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { + let enum_data = db.enum_data(def.parent); + let var_data = &enum_data.variants[def.local_id]; + let fields = var_data.variant_data.fields(); + let resolver = def.parent.resolver(db); let params = fields .iter() .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) .collect::>(); - let generics = db.generic_params(def.parent_enum(db).id.into()); + let generics = db.generic_params(def.parent.into()); let substs = Substs::identity(&generics); - let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); + let ret = type_for_adt(db, Enum::from(def.parent)).subst(&substs); FnSig::from_params_and_return(params, ret) } From 78791d6fac1ff426264e636545a07664d83d2039 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 16:26:52 +0300 Subject: [PATCH 08/65] Use ids for Callable --- crates/ra_hir/src/ty.rs | 19 ++++++++++----- crates/ra_hir/src/ty/infer/expr.rs | 14 +++++++---- crates/ra_hir/src/ty/lower.rs | 38 ++++++++++++++++-------------- crates/ra_ide_api/src/call_info.rs | 13 ++++++---- 4 files changed, 50 insertions(+), 34 deletions(-) diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 1e05ac3f23..8c045aaef2 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -171,7 +171,7 @@ impl TypeCtor { | TypeCtor::Tuple { .. } => None, TypeCtor::Closure { def, .. } => def.krate(db), TypeCtor::Adt(adt) => adt.krate(db), - TypeCtor::FnDef(callable) => callable.krate(db), + TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), TypeCtor::AssociatedType(type_alias) => type_alias.krate(db), } } @@ -856,13 +856,20 @@ impl HirDisplay for ApplicationTy { TypeCtor::FnDef(def) => { let sig = f.db.callable_item_signature(def); let name = match def { - CallableDef::Function(ff) => ff.name(f.db), - CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing), - CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing), + CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), + CallableDef::StructId(s) => { + f.db.struct_data(s.0).name.clone().unwrap_or_else(Name::missing) + } + CallableDef::EnumVariantId(e) => { + let enum_data = f.db.enum_data(e.parent); + enum_data.variants[e.local_id].name.clone().unwrap_or_else(Name::missing) + } }; match def { - CallableDef::Function(_) => write!(f, "fn {}", name)?, - CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?, + CallableDef::FunctionId(_) => write!(f, "fn {}", name)?, + CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { + write!(f, "{}", name)? + } } if self.parameters.len() > 0 { write!(f, "<")?; diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 194e558191..1d6df2b7ad 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -8,6 +8,7 @@ use hir_def::{ generics::GenericParams, path::{GenericArg, GenericArgs}, resolver::resolver_for_expr, + ContainerId, Lookup, }; use hir_expand::name; @@ -660,18 +661,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } // add obligation for trait implementation, if this is a trait method match def { - CallableDef::Function(f) => { - if let Some(trait_) = f.parent_trait(self.db) { + CallableDef::FunctionId(f) => { + if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { // construct a TraitDef let substs = a_ty.parameters.prefix( self.db - .generic_params(trait_.id.into()) + .generic_params(trait_.into()) .count_params_including_parent(), ); - self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); + self.obligations.push(Obligation::Trait(TraitRef { + trait_: trait_.into(), + substs, + })); } } - CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {} + CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {} } } } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 348c5f67d3..27cfe00c11 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -14,9 +14,11 @@ use hir_def::{ path::{GenericArg, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, - AdtId, EnumVariantId, FunctionId, GenericDefId, LocalStructFieldId, StructId, VariantId, + AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, + Lookup, StructId, VariantId, }; use ra_arena::map::ArenaMap; +use ra_db::CrateId; use super::{ FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, @@ -546,9 +548,9 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace /// Build the signature of a callable item (function, struct or enum variant). pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { match def { - CallableDef::Function(f) => fn_sig_for_fn(db, f.id), - CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s.id), - CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e.into()), + CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), + CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), + CallableDef::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e), } } @@ -643,7 +645,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { let generics = db.generic_params(def.id.into()); let substs = Substs::identity(&generics); - Ty::apply(TypeCtor::FnDef(def.into()), substs) + Ty::apply(TypeCtor::FnDef(def.id.into()), substs) } /// Build the declared type of a const. @@ -723,7 +725,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { } let generics = db.generic_params(def.id.into()); let substs = Substs::identity(&generics); - Ty::apply(TypeCtor::FnDef(def.into()), substs) + Ty::apply(TypeCtor::FnDef(def.id.into()), substs) } fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { @@ -749,7 +751,7 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> } let generics = db.generic_params(def.parent_enum(db).id.into()); let substs = Substs::identity(&generics); - Ty::apply(TypeCtor::FnDef(def.into()), substs) + Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) } fn type_for_adt(db: &impl HirDatabase, adt: impl Into) -> Ty { @@ -806,18 +808,18 @@ impl From for Option { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum CallableDef { - Function(Function), - Struct(Struct), - EnumVariant(EnumVariant), + FunctionId(FunctionId), + StructId(StructId), + EnumVariantId(EnumVariantId), } -impl_froms!(CallableDef: Function, Struct, EnumVariant); +impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId); impl CallableDef { - pub fn krate(self, db: &impl HirDatabase) -> Option { + pub fn krate(self, db: &impl HirDatabase) -> CrateId { match self { - CallableDef::Function(f) => f.krate(db), - CallableDef::Struct(s) => s.krate(db), - CallableDef::EnumVariant(e) => e.parent_enum(db).krate(db), + CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, + CallableDef::StructId(s) => s.0.module(db).krate, + CallableDef::EnumVariantId(e) => e.parent.module(db).krate, } } } @@ -825,9 +827,9 @@ impl CallableDef { impl From for GenericDefId { fn from(def: CallableDef) -> GenericDefId { match def { - CallableDef::Function(f) => f.id.into(), - CallableDef::Struct(s) => s.id.into(), - CallableDef::EnumVariant(e) => EnumVariantId::from(e).into(), + CallableDef::FunctionId(f) => f.into(), + CallableDef::StructId(s) => s.into(), + CallableDef::EnumVariantId(e) => e.into(), } } } diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 7c367230e7..9beceb29cf 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -26,14 +26,17 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { - //FIXME: apply subst + //FIXME: don't poke into Ty let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; match callable_def { - hir::CallableDef::Function(it) => { - (CallInfo::with_fn(db, it), it.has_self_param(db)) + hir::CallableDef::FunctionId(it) => { + let fn_def = it.into(); + (CallInfo::with_fn(db, fn_def), fn_def.has_self_param(db)) + } + hir::CallableDef::StructId(it) => (CallInfo::with_struct(db, it.into())?, false), + hir::CallableDef::EnumVariantId(it) => { + (CallInfo::with_enum_variant(db, it.into())?, false) } - hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it)?, false), - hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it)?, false), } } FnCallNode::MethodCallExpr(expr) => { From e1c0bdaf75f8d88a5c28b3e44def17d91d4f46b3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 16:55:09 +0300 Subject: [PATCH 09/65] Introduce dedicated AST node for union Although structs and unions have the same syntax and differ only in the keyword, re-using the single syntax node for both of them leads to confusion in practice, and propagates further down the hir in an upleasent way. Moreover, static and consts also share syntax, but we use different nodes for them. --- crates/ra_parser/src/grammar/items.rs | 10 +++---- .../src/grammar/items/{nominal.rs => adt.rs} | 23 ++++++++++----- crates/ra_parser/src/syntax_kind/generated.rs | 1 + crates/ra_syntax/src/ast/generated.rs | 28 +++++++++++++++++++ crates/ra_syntax/src/grammar.ron | 10 +++++++ .../parser/inline/ok/0068_union_items.txt | 4 +-- .../test_data/parser/ok/0035_weird_exprs.txt | 2 +- 7 files changed, 63 insertions(+), 15 deletions(-) rename crates/ra_parser/src/grammar/items/{nominal.rs => adt.rs} (88%) diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 85f7eeb002..630e6ce64f 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs @@ -1,13 +1,13 @@ //! FIXME: write short doc here mod consts; -mod nominal; +mod adt; mod traits; mod use_item; pub(crate) use self::{ expressions::{match_arm_list, record_field_list}, - nominal::{enum_variant_list, record_field_def_list}, + adt::{enum_variant_list, record_field_def_list}, traits::{impl_item_list, trait_item_list}, use_item::use_tree_list, }; @@ -247,7 +247,7 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { // a: i32, // b: f32, // } - nominal::struct_def(p, m, T![struct]); + adt::struct_def(p, m); } IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { // test union_items @@ -256,9 +256,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { // a: i32, // b: f32, // } - nominal::struct_def(p, m, T![union]); + adt::union_def(p, m); } - T![enum] => nominal::enum_def(p, m), + T![enum] => adt::enum_def(p, m), T![use] => use_item::use_item(p, m), T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m), T![static] => consts::static_def(p, m), diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/adt.rs similarity index 88% rename from crates/ra_parser/src/grammar/items/nominal.rs rename to crates/ra_parser/src/grammar/items/adt.rs index 9d8fb84869..c777bc9d00 100644 --- a/crates/ra_parser/src/grammar/items/nominal.rs +++ b/crates/ra_parser/src/grammar/items/adt.rs @@ -2,10 +2,19 @@ use super::*; -pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { - assert!(p.at(T![struct]) || p.at_contextual_kw("union")); - p.bump_remap(kind); +pub(super) fn struct_def(p: &mut Parser, m: Marker) { + assert!(p.at(T![struct])); + p.bump(T![struct]); + struct_or_union(p, m, T![struct], STRUCT_DEF); +} +pub(super) fn union_def(p: &mut Parser, m: Marker) { + assert!(p.at_contextual_kw("union")); + p.bump_remap(T![union]); + struct_or_union(p, m, T![union], UNION_DEF); +} + +fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { name_r(p, ITEM_RECOVERY_SET); type_params::opt_type_param_list(p); match p.current() { @@ -22,11 +31,11 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { } } } - T![;] if kind == T![struct] => { + T![;] if kw == T![struct] => { p.bump(T![;]); } T!['{'] => record_field_def_list(p), - T!['('] if kind == T![struct] => { + T!['('] if kw == T![struct] => { tuple_field_def_list(p); // test tuple_struct_where // struct Test(T) where T: Clone; @@ -34,14 +43,14 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { type_params::opt_where_clause(p); p.expect(T![;]); } - _ if kind == T![struct] => { + _ if kw == T![struct] => { p.error("expected `;`, `{`, or `(`"); } _ => { p.error("expected `{`"); } } - m.complete(p, STRUCT_DEF); + m.complete(p, def); } pub(super) fn enum_def(p: &mut Parser, m: Marker) { diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 96b5bce88d..fe0fcdb33f 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -122,6 +122,7 @@ pub enum SyntaxKind { R_DOLLAR, SOURCE_FILE, STRUCT_DEF, + UNION_DEF, ENUM_DEF, FN_DEF, RET_TYPE, diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index de506d7cda..1a03ae56c4 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -3789,6 +3789,34 @@ impl AstNode for TypeRef { } impl TypeRef {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct UnionDef { + pub(crate) syntax: SyntaxNode, +} +impl AstNode for UnionDef { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + UNION_DEF => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} +impl ast::VisibilityOwner for UnionDef {} +impl ast::NameOwner for UnionDef {} +impl ast::TypeParamsOwner for UnionDef {} +impl ast::AttrsOwner for UnionDef {} +impl ast::DocCommentsOwner for UnionDef {} +impl UnionDef {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UseItem { pub(crate) syntax: SyntaxNode, } diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 88d1dc109b..c16bed8915 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -126,6 +126,7 @@ Grammar( "SOURCE_FILE", "STRUCT_DEF", + "UNION_DEF", "ENUM_DEF", "FN_DEF", "RET_TYPE", @@ -285,6 +286,15 @@ Grammar( "DocCommentsOwner" ] ), + "UnionDef": ( + traits: [ + "VisibilityOwner", + "NameOwner", + "TypeParamsOwner", + "AttrsOwner", + "DocCommentsOwner" + ] + ), "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), "RecordFieldDef": ( traits: [ diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt index f9ace02ee0..9d79826846 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt @@ -1,5 +1,5 @@ SOURCE_FILE@[0; 51) - STRUCT_DEF@[0; 12) + UNION_DEF@[0; 12) UNION_KW@[0; 5) "union" WHITESPACE@[5; 6) " " NAME@[6; 9) @@ -9,7 +9,7 @@ SOURCE_FILE@[0; 51) L_CURLY@[10; 11) "{" R_CURLY@[11; 12) "}" WHITESPACE@[12; 13) "\n" - STRUCT_DEF@[13; 50) + UNION_DEF@[13; 50) UNION_KW@[13; 18) "union" WHITESPACE@[18; 19) " " NAME@[19; 22) diff --git a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt index 3260cc5896..90538b90da 100644 --- a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt +++ b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt @@ -1592,7 +1592,7 @@ SOURCE_FILE@[0; 3813) BLOCK@[2845; 2906) L_CURLY@[2845; 2846) "{" WHITESPACE@[2846; 2851) "\n " - STRUCT_DEF@[2851; 2904) + UNION_DEF@[2851; 2904) UNION_KW@[2851; 2856) "union" WHITESPACE@[2856; 2857) " " NAME@[2857; 2862) From 5fd68b592938b6a4c074146c1b22ea0f6908fe26 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 17:30:50 +0300 Subject: [PATCH 10/65] Fix hir for ast::UnionDef --- crates/ra_assists/src/assists/add_new.rs | 4 +-- crates/ra_hir/src/code_model.rs | 6 ++-- crates/ra_hir/src/code_model/src.rs | 8 ++--- crates/ra_hir/src/from_source.rs | 13 ++++---- crates/ra_hir/src/ty.rs | 2 +- crates/ra_hir/src/ty/infer/coerce.rs | 2 +- crates/ra_hir/src/ty/lower.rs | 4 +-- crates/ra_hir_def/src/adt.rs | 18 +++++++++-- crates/ra_hir_def/src/attr.rs | 4 +-- crates/ra_hir_def/src/db.rs | 12 +++++--- crates/ra_hir_def/src/docs.rs | 4 +-- crates/ra_hir_def/src/generics.rs | 6 ++-- crates/ra_hir_def/src/lib.rs | 32 +++++++++----------- crates/ra_hir_def/src/nameres/collector.rs | 12 +++----- crates/ra_hir_def/src/nameres/raw.rs | 13 ++++---- crates/ra_hir_def/src/nameres/tests.rs | 7 +++++ crates/ra_ide_api/src/display/short_label.rs | 6 ++++ crates/ra_ide_api/src/impls.rs | 4 +++ crates/ra_parser/src/grammar/items.rs | 2 +- crates/ra_syntax/src/ast/extensions.rs | 11 ------- crates/ra_syntax/src/ast/generated.rs | 28 ++++++++++++++--- crates/ra_syntax/src/grammar.ron | 9 +++--- 22 files changed, 121 insertions(+), 86 deletions(-) diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs index ee8bff3467..8f68bd5fb1 100644 --- a/crates/ra_assists/src/assists/add_new.rs +++ b/crates/ra_assists/src/assists/add_new.rs @@ -35,8 +35,8 @@ pub(crate) fn add_new(ctx: AssistCtx) -> Option { let strukt = ctx.find_node_at_offset::()?; // We want to only apply this to non-union structs with named fields - let field_list = match (strukt.kind(), strukt.is_union()) { - (StructKind::Record(named), false) => named, + let field_list = match strukt.kind() { + StructKind::Record(named) => named, _ => return None, }; diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 534f1f8e98..ae730beb51 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -320,7 +320,7 @@ pub struct Struct { impl Struct { pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.0.module(db) } + Module { id: self.id.module(db) } } pub fn krate(self, db: &impl DefDatabase) -> Option { @@ -369,11 +369,11 @@ pub struct Union { impl Union { pub fn name(self, db: &impl DefDatabase) -> Option { - db.struct_data(self.id.into()).name.clone() + db.union_data(self.id).name.clone() } pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.0.module(db) } + Module { id: self.id.module(db) } } pub fn ty(self, db: &impl HirDatabase) -> Ty { diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index a4e317c203..076d86f2b9 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -51,13 +51,13 @@ impl HasSource for StructField { impl HasSource for Struct { type Ast = ast::StructDef; fn source(self, db: &impl DefDatabase) -> Source { - self.id.0.source(db) + self.id.source(db) } } impl HasSource for Union { - type Ast = ast::StructDef; - fn source(self, db: &impl DefDatabase) -> Source { - self.id.0.source(db) + type Ast = ast::UnionDef; + fn source(self, db: &impl DefDatabase) -> Source { + self.id.source(db) } } impl HasSource for Enum { diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 1e7c22774d..95db7161bf 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use hir_def::{AstItemDef, LocationCtx, ModuleId, StructId, StructOrUnionId, UnionId}; +use hir_def::{AstItemDef, LocationCtx, ModuleId}; use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; use ra_syntax::{ ast::{self, AstNode, NameOwner}, @@ -19,19 +19,18 @@ pub trait FromSource: Sized { fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option; } -// FIXIME: these two impls are wrong, `ast::StructDef` might produce either a struct or a union impl FromSource for Struct { type Ast = ast::StructDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id: StructOrUnionId = from_source(db, src)?; - Some(Struct { id: StructId(id) }) + let id = from_source(db, src)?; + Some(Struct { id }) } } impl FromSource for Union { - type Ast = ast::StructDef; + type Ast = ast::UnionDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id: StructOrUnionId = from_source(db, src)?; - Some(Union { id: UnionId(id) }) + let id = from_source(db, src)?; + Some(Union { id }) } } impl FromSource for Enum { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 8c045aaef2..3cbcbd1d01 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -858,7 +858,7 @@ impl HirDisplay for ApplicationTy { let name = match def { CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), CallableDef::StructId(s) => { - f.db.struct_data(s.0).name.clone().unwrap_or_else(Name::missing) + f.db.struct_data(s).name.clone().unwrap_or_else(Name::missing) } CallableDef::EnumVariantId(e) => { let enum_data = f.db.enum_data(e.parent); diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 4b53bba73b..bb9a2e427e 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -246,7 +246,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), ) if struct1 == struct2 => { let field_tys = self.db.field_types(struct1.id.into()); - let struct_data = self.db.struct_data(struct1.id.0); + let struct_data = self.db.struct_data(struct1.id); let mut fields = struct_data.variant_data.fields().iter(); let (last_field_id, _data) = fields.next_back()?; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 27cfe00c11..89bc4b9aeb 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -560,7 +560,7 @@ pub(crate) fn field_types_query( variant_id: VariantId, ) -> Arc> { let (resolver, var_data) = match variant_id { - VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()), + VariantId::StructId(it) => (it.resolver(db), db.struct_data(it).variant_data.clone()), VariantId::EnumVariantId(it) => ( it.parent.resolver(db), db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), @@ -818,7 +818,7 @@ impl CallableDef { pub fn krate(self, db: &impl HirDatabase) -> CrateId { match self { CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, - CallableDef::StructId(s) => s.0.module(db).krate, + CallableDef::StructId(s) => s.module(db).krate, CallableDef::EnumVariantId(e) => e.parent.module(db).krate, } } diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index c9f30923ee..71014826ef 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -12,7 +12,7 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; use crate::{ db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, - LocalEnumVariantId, LocalStructFieldId, StructOrUnionId, VariantId, + LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, }; /// Note that we use `StructData` for unions as well! @@ -49,13 +49,25 @@ pub struct StructFieldData { } impl StructData { - pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructOrUnionId) -> Arc { + pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc { let src = id.source(db); let name = src.value.name().map(|n| n.as_name()); let variant_data = VariantData::new(src.value.kind()); let variant_data = Arc::new(variant_data); Arc::new(StructData { name, variant_data }) } + pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc { + let src = id.source(db); + let name = src.value.name().map(|n| n.as_name()); + let variant_data = VariantData::new( + src.value + .record_field_def_list() + .map(ast::StructKind::Record) + .unwrap_or(ast::StructKind::Unit), + ); + let variant_data = Arc::new(variant_data); + Arc::new(StructData { name, variant_data }) + } } impl EnumData { @@ -137,7 +149,7 @@ impl HasChildSource for VariantId { let src = it.parent.child_source(db); src.map(|map| map[it.local_id].kind()) } - VariantId::StructId(it) => it.0.source(db).map(|it| it.kind()), + VariantId::StructId(it) => it.source(db).map(|it| it.kind()), }; let mut trace = Trace::new_for_map(); lower_struct(&mut trace, &src.value); diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 53456fc085..298608e27c 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -54,9 +54,9 @@ impl Attrs { Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) } AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + AdtId::StructId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), - AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), }, AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 32adb11bdc..ef5611ffc0 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -18,8 +18,8 @@ use crate::{ CrateDefMap, }, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, - ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructOrUnionId, TraitId, TypeAliasId, - TypeAliasLoc, + ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, TypeAliasLoc, + UnionId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -27,7 +27,9 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_function(&self, loc: FunctionLoc) -> FunctionId; #[salsa::interned] - fn intern_struct_or_union(&self, loc: ItemLoc) -> StructOrUnionId; + fn intern_struct(&self, loc: ItemLoc) -> StructId; + #[salsa::interned] + fn intern_union(&self, loc: ItemLoc) -> UnionId; #[salsa::interned] fn intern_enum(&self, loc: ItemLoc) -> EnumId; #[salsa::interned] @@ -57,7 +59,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase { fn crate_def_map(&self, krate: CrateId) -> Arc; #[salsa::invoke(StructData::struct_data_query)] - fn struct_data(&self, id: StructOrUnionId) -> Arc; + fn struct_data(&self, id: StructId) -> Arc; + #[salsa::invoke(StructData::union_data_query)] + fn union_data(&self, id: UnionId) -> Arc; #[salsa::invoke(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 90a8627bc6..4749b642f0 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -47,9 +47,9 @@ impl Documentation { } } AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => docs_from_ast(&it.0.source(db).value), + AdtId::StructId(it) => docs_from_ast(&it.source(db).value), AdtId::EnumId(it) => docs_from_ast(&it.source(db).value), - AdtId::UnionId(it) => docs_from_ast(&it.0.source(db).value), + AdtId::UnionId(it) => docs_from_ast(&it.source(db).value), }, AttrDefId::EnumVariantId(it) => { let src = it.parent.child_source(db); diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 015fe772e5..3f94e40e4f 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -60,10 +60,8 @@ impl GenericParams { // FIXME: add `: Sized` bound for everything except for `Self` in traits match def { GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), - GenericDefId::AdtId(AdtId::StructId(it)) => { - generics.fill(&it.0.source(db).value, start) - } - GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.0.source(db).value, start), + GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start), + GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start), GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), GenericDefId::TraitId(it) => { // traits get the Self type as an implicit first type parameter diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 8e8c2d7490..5f11be1143 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -141,30 +141,26 @@ impl Lookup for FunctionId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct StructOrUnionId(salsa::InternId); -impl_intern_key!(StructOrUnionId); -impl AstItemDef for StructOrUnionId { +pub struct StructId(salsa::InternId); +impl_intern_key!(StructId); +impl AstItemDef for StructId { fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_struct_or_union(loc) + db.intern_struct(loc) } fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_struct_or_union(self) + db.lookup_intern_struct(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct StructId(pub StructOrUnionId); -impl From for StructOrUnionId { - fn from(id: StructId) -> StructOrUnionId { - id.0 +pub struct UnionId(salsa::InternId); +impl_intern_key!(UnionId); +impl AstItemDef for UnionId { + fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { + db.intern_union(loc) } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct UnionId(pub StructOrUnionId); -impl From for StructOrUnionId { - fn from(id: UnionId) -> StructOrUnionId { - id.0 + fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { + db.lookup_intern_union(self) } } @@ -485,8 +481,8 @@ impl HasModule for ConstLoc { impl HasModule for AdtId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match self { - AdtId::StructId(it) => it.0.module(db), - AdtId::UnionId(it) => it.0.module(db), + AdtId::StructId(it) => it.module(db), + AdtId::UnionId(it) => it.module(db), AdtId::EnumId(it) => it.module(db), } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 41becf8dff..4ff6f72cfb 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -25,7 +25,7 @@ use crate::{ per_ns::PerNs, AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, - StructOrUnionId, TraitId, TypeAliasLoc, UnionId, + TraitId, TypeAliasLoc, UnionId, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -698,14 +698,12 @@ where PerNs::values(def.into()) } raw::DefKind::Struct(ast_id) => { - let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); - let s = StructId(id).into(); - PerNs::both(s, s) + let id = StructId::from_ast_id(ctx, ast_id).into(); + PerNs::both(id, id) } raw::DefKind::Union(ast_id) => { - let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); - let u = UnionId(id).into(); - PerNs::both(u, u) + let id = UnionId::from_ast_id(ctx, ast_id).into(); + PerNs::both(id, id) } raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), raw::DefKind::Const(ast_id) => { diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 401af031cc..6eb106094c 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -176,7 +176,7 @@ pub(super) struct DefData { pub(super) enum DefKind { Function(FileAstId), Struct(FileAstId), - Union(FileAstId), + Union(FileAstId), Enum(FileAstId), Const(FileAstId), Static(FileAstId), @@ -246,11 +246,12 @@ impl RawItemsCollector { ast::ModuleItem::StructDef(it) => { let id = self.source_ast_id_map.ast_id(&it); let name = it.name(); - if it.is_union() { - (DefKind::Union(id), name) - } else { - (DefKind::Struct(id), name) - } + (DefKind::Struct(id), name) + } + ast::ModuleItem::UnionDef(it) => { + let id = self.source_ast_id_map.ast_id(&it); + let name = it.name(); + (DefKind::Union(id), name) } ast::ModuleItem::EnumDef(it) => { (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name()) diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index f502f1cb30..87fcd617c5 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -82,6 +82,12 @@ fn crate_def_map_smoke_test() { //- /foo/bar.rs pub struct Baz; + + union U { + to_be: bool, + not_to_be: u8, + } + enum E { V } ", ); @@ -99,6 +105,7 @@ fn crate_def_map_smoke_test() { ⋮crate::foo::bar ⋮Baz: t v ⋮E: t + ⋮U: t v "###) } diff --git a/crates/ra_ide_api/src/display/short_label.rs b/crates/ra_ide_api/src/display/short_label.rs index 5d2bce3d29..9ffc9b9801 100644 --- a/crates/ra_ide_api/src/display/short_label.rs +++ b/crates/ra_ide_api/src/display/short_label.rs @@ -19,6 +19,12 @@ impl ShortLabel for ast::StructDef { } } +impl ShortLabel for ast::UnionDef { + fn short_label(&self) -> Option { + short_label_from_node(self, "union ") + } +} + impl ShortLabel for ast::EnumDef { fn short_label(&self) -> Option { short_label_from_node(self, "enum ") diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index 3e3012559b..2b3100fc36 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs @@ -49,6 +49,10 @@ fn impls_for_def( let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; hir::Enum::from_source(db, src)?.ty(db) } + ast::NominalDef::UnionDef(def) => { + let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; + hir::Union::from_source(db, src)?.ty(db) + } }; let krate = module.krate(); diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 630e6ce64f..370990e21f 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs @@ -6,8 +6,8 @@ mod traits; mod use_item; pub(crate) use self::{ - expressions::{match_arm_list, record_field_list}, adt::{enum_variant_list, record_field_def_list}, + expressions::{match_arm_list, record_field_list}, traits::{impl_item_list, trait_item_list}, use_item::use_tree_list, }; diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index 513ed7920f..a8f6251762 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs @@ -196,17 +196,6 @@ impl StructKind { } impl ast::StructDef { - pub fn is_union(&self) -> bool { - for child in self.syntax().children_with_tokens() { - match child.kind() { - T![struct] => return false, - T![union] => return true, - _ => (), - } - } - false - } - pub fn kind(&self) -> StructKind { StructKind::from_node(self) } diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 1a03ae56c4..c06076e3d7 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1856,6 +1856,7 @@ impl Module { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleItem { StructDef(StructDef), + UnionDef(UnionDef), EnumDef(EnumDef), FnDef(FnDef), TraitDef(TraitDef), @@ -1872,6 +1873,11 @@ impl From for ModuleItem { ModuleItem::StructDef(node) } } +impl From for ModuleItem { + fn from(node: UnionDef) -> ModuleItem { + ModuleItem::UnionDef(node) + } +} impl From for ModuleItem { fn from(node: EnumDef) -> ModuleItem { ModuleItem::EnumDef(node) @@ -1925,14 +1931,15 @@ impl From for ModuleItem { impl AstNode for ModuleItem { fn can_cast(kind: SyntaxKind) -> bool { match kind { - STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_BLOCK | USE_ITEM - | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, + STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF + | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, _ => false, } } fn cast(syntax: SyntaxNode) -> Option { let res = match syntax.kind() { STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }), + UNION_DEF => ModuleItem::UnionDef(UnionDef { syntax }), ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }), FN_DEF => ModuleItem::FnDef(FnDef { syntax }), TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }), @@ -1950,6 +1957,7 @@ impl AstNode for ModuleItem { fn syntax(&self) -> &SyntaxNode { match self { ModuleItem::StructDef(it) => &it.syntax, + ModuleItem::UnionDef(it) => &it.syntax, ModuleItem::EnumDef(it) => &it.syntax, ModuleItem::FnDef(it) => &it.syntax, ModuleItem::TraitDef(it) => &it.syntax, @@ -2038,6 +2046,7 @@ impl NeverType {} pub enum NominalDef { StructDef(StructDef), EnumDef(EnumDef), + UnionDef(UnionDef), } impl From for NominalDef { fn from(node: StructDef) -> NominalDef { @@ -2049,10 +2058,15 @@ impl From for NominalDef { NominalDef::EnumDef(node) } } +impl From for NominalDef { + fn from(node: UnionDef) -> NominalDef { + NominalDef::UnionDef(node) + } +} impl AstNode for NominalDef { fn can_cast(kind: SyntaxKind) -> bool { match kind { - STRUCT_DEF | ENUM_DEF => true, + STRUCT_DEF | ENUM_DEF | UNION_DEF => true, _ => false, } } @@ -2060,6 +2074,7 @@ impl AstNode for NominalDef { let res = match syntax.kind() { STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }), ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }), + UNION_DEF => NominalDef::UnionDef(UnionDef { syntax }), _ => return None, }; Some(res) @@ -2068,6 +2083,7 @@ impl AstNode for NominalDef { match self { NominalDef::StructDef(it) => &it.syntax, NominalDef::EnumDef(it) => &it.syntax, + NominalDef::UnionDef(it) => &it.syntax, } } } @@ -3815,7 +3831,11 @@ impl ast::NameOwner for UnionDef {} impl ast::TypeParamsOwner for UnionDef {} impl ast::AttrsOwner for UnionDef {} impl ast::DocCommentsOwner for UnionDef {} -impl UnionDef {} +impl UnionDef { + pub fn record_field_def_list(&self) -> Option { + AstChildren::new(&self.syntax).next() + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UseItem { pub(crate) syntax: SyntaxNode, diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index c16bed8915..d1be40abeb 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -293,7 +293,8 @@ Grammar( "TypeParamsOwner", "AttrsOwner", "DocCommentsOwner" - ] + ], + options: ["RecordFieldDefList"], ), "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), "RecordFieldDef": ( @@ -398,7 +399,7 @@ Grammar( ]), "NominalDef": ( - enum: ["StructDef", "EnumDef"], + enum: ["StructDef", "EnumDef", "UnionDef"], traits: [ "NameOwner", "TypeParamsOwner", @@ -406,9 +407,9 @@ Grammar( ], ), "ModuleItem": ( - enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", + enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], - traits: ["AttrsOwner"] + traits: ["AttrsOwner"], ), "ImplItem": ( enum: ["FnDef", "TypeAliasDef", "ConstDef"], From 1455663ea15ecbfbe87b4b5be6919aa35dd0b260 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 17:34:15 +0300 Subject: [PATCH 11/65] Fixme for union fields --- crates/ra_hir/src/ty/infer/expr.rs | 2 ++ crates/ra_hir/src/ty/lower.rs | 1 + crates/ra_hir_def/src/adt.rs | 5 +++++ crates/ra_hir_def/src/lib.rs | 1 + 4 files changed, 9 insertions(+) diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 1d6df2b7ad..994a6d7e95 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -263,6 +263,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { .clone() .subst(&a_ty.parameters) }), + // FIXME: + TypeCtor::Adt(Adt::Union(_)) => None, _ => None, }, _ => None, diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 89bc4b9aeb..eb51d31bd0 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -561,6 +561,7 @@ pub(crate) fn field_types_query( ) -> Arc> { let (resolver, var_data) = match variant_id { VariantId::StructId(it) => (it.resolver(db), db.struct_data(it).variant_data.clone()), + VariantId::UnionId(it) => (it.resolver(db), db.union_data(it).variant_data.clone()), VariantId::EnumVariantId(it) => ( it.parent.resolver(db), db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 71014826ef..0091bfbc33 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -150,6 +150,11 @@ impl HasChildSource for VariantId { src.map(|map| map[it.local_id].kind()) } VariantId::StructId(it) => it.source(db).map(|it| it.kind()), + VariantId::UnionId(it) => it.source(db).map(|it| { + it.record_field_def_list() + .map(ast::StructKind::Record) + .unwrap_or(ast::StructKind::Unit) + }), }; let mut trace = Trace::new_for_map(); lower_struct(&mut trace, &src.value); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 5f11be1143..a88a78b38f 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -431,6 +431,7 @@ impl_froms!( pub enum VariantId { EnumVariantId(EnumVariantId), StructId(StructId), + UnionId(UnionId), } impl_froms!(VariantId: EnumVariantId, StructId); From 3e32ac4f866e2b9430dd1e91b2c7fa3824c646a9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 18:31:48 +0300 Subject: [PATCH 12/65] More ids in Ty --- crates/ra_hir/src/code_model.rs | 8 -------- crates/ra_hir/src/ty.rs | 11 ++++++----- crates/ra_hir/src/ty/infer/expr.rs | 6 ++++-- crates/ra_hir/src/ty/traits.rs | 5 +++-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index ae730beb51..f7fc80d4ee 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -538,14 +538,6 @@ pub enum DefWithBody { impl_froms!(DefWithBody: Function, Const, Static); impl DefWithBody { - pub(crate) fn krate(self, db: &impl HirDatabase) -> Option { - match self { - DefWithBody::Const(c) => c.krate(db), - DefWithBody::Function(f) => f.krate(db), - DefWithBody::Static(s) => s.krate(db), - } - } - pub fn module(self, db: &impl HirDatabase) -> Module { match self { DefWithBody::Const(c) => c.module(db), diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 3cbcbd1d01..bac21732ec 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -17,12 +17,12 @@ use std::ops::Deref; use std::sync::Arc; use std::{fmt, iter, mem}; -use hir_def::{generics::GenericParams, AdtId, GenericDefId}; +use hir_def::{generics::GenericParams, AdtId, DefWithBodyId, GenericDefId}; use ra_db::{impl_intern_key, salsa}; use crate::{ - db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, IntTy, - Mutability, Name, Trait, TypeAlias, Uncertain, + db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, + Name, Trait, TypeAlias, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -113,7 +113,7 @@ pub enum TypeCtor { /// /// The closure signature is stored in a `FnPtr` type in the first type /// parameter. - Closure { def: DefWithBody, expr: ExprId }, + Closure { def: DefWithBodyId, expr: ExprId }, } /// This exists just for Chalk, because Chalk just has a single `StructId` where @@ -169,7 +169,8 @@ impl TypeCtor { | TypeCtor::Ref(_) | TypeCtor::FnPtr { .. } | TypeCtor::Tuple { .. } => None, - TypeCtor::Closure { def, .. } => def.krate(db), + // Closure's krate is irrelevant for coherence I would think? + TypeCtor::Closure { .. } => None, TypeCtor::Adt(adt) => adt.krate(db), TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), TypeCtor::AssociatedType(type_alias) => type_alias.krate(db), diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 994a6d7e95..b581d192f5 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -137,8 +137,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, Substs(sig_tys.into()), ); - let closure_ty = - Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); + let closure_ty = Ty::apply_one( + TypeCtor::Closure { def: self.owner.into(), expr: tgt_expr }, + sig_ty, + ); // Eagerly try to relate the closure type with the expected // type, otherwise we often won't have enough information to diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 268fa09e4a..b9a5d651f4 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,13 +2,14 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; +use hir_def::DefWithBodyId; use log::debug; use ra_db::{impl_intern_key, salsa}; use ra_prof::profile; use rustc_hash::FxHashSet; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; -use crate::{db::HirDatabase, expr::ExprId, Crate, DefWithBody, ImplBlock, Trait, TypeAlias}; +use crate::{db::HirDatabase, expr::ExprId, Crate, ImplBlock, Trait, TypeAlias}; use self::chalk::{from_chalk, ToChalk}; @@ -290,7 +291,7 @@ impl FnTrait { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ClosureFnTraitImplData { - def: DefWithBody, + def: DefWithBodyId, expr: ExprId, fn_trait: FnTrait, } From 6d2ec8765d418b365dfaf472ab9b2b53b8eeafa9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 18:44:36 +0300 Subject: [PATCH 13/65] Use TypeAliasId in Ty, pt 1 --- crates/ra_hir/src/ty.rs | 26 ++++++++++++++++---------- crates/ra_hir/src/ty/traits/chalk.rs | 14 +++++++++++++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index bac21732ec..8a184de71d 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -17,7 +17,10 @@ use std::ops::Deref; use std::sync::Arc; use std::{fmt, iter, mem}; -use hir_def::{generics::GenericParams, AdtId, DefWithBodyId, GenericDefId}; +use hir_def::{ + generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, + TypeAliasId, +}; use ra_db::{impl_intern_key, salsa}; use crate::{ @@ -107,7 +110,7 @@ pub enum TypeCtor { /// when we have tried to normalize a projection like `T::Item` but /// couldn't find a better representation. In that case, we generate /// an **application type** like `(Iterator::Item)`. - AssociatedType(TypeAlias), + AssociatedType(TypeAliasId), /// The type of a specific closure. /// @@ -147,7 +150,7 @@ impl TypeCtor { generic_params.count_params_including_parent() } TypeCtor::AssociatedType(type_alias) => { - let generic_params = db.generic_params(type_alias.id.into()); + let generic_params = db.generic_params(type_alias.into()); generic_params.count_params_including_parent() } TypeCtor::FnPtr { num_args } => num_args as usize + 1, @@ -173,7 +176,9 @@ impl TypeCtor { TypeCtor::Closure { .. } => None, TypeCtor::Adt(adt) => adt.krate(db), TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), - TypeCtor::AssociatedType(type_alias) => type_alias.krate(db), + TypeCtor::AssociatedType(type_alias) => { + Some(type_alias.lookup(db).module(db).krate.into()) + } } } @@ -194,7 +199,7 @@ impl TypeCtor { | TypeCtor::Closure { .. } => None, TypeCtor::Adt(adt) => Some(adt.into()), TypeCtor::FnDef(callable) => Some(callable.into()), - TypeCtor::AssociatedType(type_alias) => Some(type_alias.id.into()), + TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), } } } @@ -896,11 +901,12 @@ impl HirDisplay for ApplicationTy { } } TypeCtor::AssociatedType(type_alias) => { - let trait_name = type_alias - .parent_trait(f.db) - .and_then(|t| t.name(f.db)) - .unwrap_or_else(Name::missing); - let name = type_alias.name(f.db); + let trait_ = match type_alias.lookup(f.db).container { + ContainerId::TraitId(it) => it, + _ => panic!("not an associated type"), + }; + let trait_name = f.db.trait_data(trait_).name.clone().unwrap_or_else(Name::missing); + let name = f.db.type_alias_data(type_alias).name.clone(); write!(f, "{}::{}", trait_name, name)?; if self.parameters.len() > 0 { write!(f, "<")?; diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 0272dd9aef..fd2f1b1742 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -9,7 +9,7 @@ use chalk_ir::{ }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; -use hir_def::{lang_item::LangItemTarget, GenericDefId}; +use hir_def::{lang_item::LangItemTarget, GenericDefId, TypeAliasId}; use hir_expand::name; use ra_db::salsa::{InternId, InternKey}; @@ -215,6 +215,18 @@ impl ToChalk for TypeAlias { } } +impl ToChalk for TypeAliasId { + type Chalk = chalk_ir::TypeId; + + fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { + chalk_ir::TypeId(id_to_chalk(self)) + } + + fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAliasId { + id_from_chalk(type_alias_id.0) + } +} + impl ToChalk for AssocTyValue { type Chalk = chalk_rust_ir::AssociatedTyValueId; From 1a0da6d4dad846568042f85ad7225b45b3275e49 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 18:58:17 +0300 Subject: [PATCH 14/65] Use TypeAliasId in Ty, pt 2 --- crates/ra_hir/src/ty.rs | 35 ++++++++++++++-------------- crates/ra_hir/src/ty/autoderef.rs | 2 +- crates/ra_hir/src/ty/infer/expr.rs | 6 ++--- crates/ra_hir/src/ty/lower.rs | 9 ++++--- crates/ra_hir/src/ty/traits/chalk.rs | 34 ++++++++++----------------- 5 files changed, 40 insertions(+), 46 deletions(-) diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 8a184de71d..388530f310 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -19,13 +19,13 @@ use std::{fmt, iter, mem}; use hir_def::{ generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, - TypeAliasId, + TraitId, TypeAliasId, }; use ra_db::{impl_intern_key, salsa}; use crate::{ db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, - Name, Trait, TypeAlias, Uncertain, + Name, Trait, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -218,18 +218,19 @@ pub struct ApplicationTy { /// trait and all its parameters are fully known. #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct ProjectionTy { - pub associated_ty: TypeAlias, + pub associated_ty: TypeAliasId, pub parameters: Substs, } impl ProjectionTy { pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef { - TraitRef { - trait_: self - .associated_ty - .parent_trait(db) - .expect("projection ty without parent trait"), - substs: self.parameters.clone(), + TraitRef { trait_: self.trait_(db).into(), substs: self.parameters.clone() } + } + + fn trait_(&self, db: &impl HirDatabase) -> TraitId { + match self.associated_ty.lookup(db).container { + ContainerId::TraitId(it) => it, + _ => panic!("projection ty without parent trait"), } } } @@ -933,18 +934,15 @@ impl HirDisplay for ProjectionTy { return write!(f, "…"); } - let trait_name = self - .associated_ty - .parent_trait(f.db) - .and_then(|t| t.name(f.db)) - .unwrap_or_else(Name::missing); + let trait_name = + f.db.trait_data(self.trait_(f.db)).name.clone().unwrap_or_else(Name::missing); write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; if self.parameters.len() > 1 { write!(f, "<")?; f.write_joined(&self.parameters[1..], ", ")?; write!(f, ">")?; } - write!(f, ">::{}", self.associated_ty.name(f.db))?; + write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; Ok(()) } } @@ -1007,7 +1005,10 @@ impl HirDisplay for Ty { write!(f, "<")?; angle_open = true; } - let name = projection_pred.projection_ty.associated_ty.name(f.db); + let name = + f.db.type_alias_data(projection_pred.projection_ty.associated_ty) + .name + .clone(); write!(f, "{} = ", name)?; projection_pred.ty.hir_fmt(f)?; } @@ -1083,7 +1084,7 @@ impl HirDisplay for GenericPredicate { write!( f, ">::{} = {}", - projection_pred.projection_ty.associated_ty.name(f.db), + f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, projection_pred.ty.display(f.db) )?; } diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 44547197ca..9e7593b8b0 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -69,7 +69,7 @@ fn deref_by_trait( let projection = super::traits::ProjectionPredicate { ty: Ty::Bound(0), - projection_ty: super::ProjectionTy { associated_ty: target, parameters }, + projection_ty: super::ProjectionTy { associated_ty: target.id, parameters }, }; let obligation = super::Obligation::Projection(projection); diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index b581d192f5..316cdc8800 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -101,7 +101,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: pat_ty.clone(), projection_ty: ProjectionTy { - associated_ty: into_iter_item_alias, + associated_ty: into_iter_item_alias.id, parameters: Substs::single(iterable_ty), }, }; @@ -283,7 +283,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: ty.clone(), projection_ty: ProjectionTy { - associated_ty: future_future_output_alias, + associated_ty: future_future_output_alias.id, parameters: Substs::single(inner_ty), }, }; @@ -302,7 +302,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: ty.clone(), projection_ty: ProjectionTy { - associated_ty: ops_try_ok_alias, + associated_ty: ops_try_ok_alias.id, parameters: Substs::single(inner_ty), }, }; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index eb51d31bd0..d7d4bb0d66 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -176,7 +176,7 @@ impl Ty { Some(associated_ty) => { // FIXME handle type parameters on the segment Ty::Projection(ProjectionTy { - associated_ty, + associated_ty: associated_ty.id, parameters: trait_ref.substs, }) } @@ -268,7 +268,10 @@ impl Ty { .fill_with_unknown() .build(); // FIXME handle type parameters on the segment - return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); + return Ty::Projection(ProjectionTy { + associated_ty: associated_ty.id, + parameters: substs, + }); } } Ty::Unknown @@ -508,7 +511,7 @@ fn assoc_type_bindings_from_type_bound<'a>( let associated_ty = match trait_ref.trait_.associated_type_by_name_including_super_traits(db, &name) { None => return GenericPredicate::Error, - Some(t) => t, + Some(t) => t.id, }; let projection_ty = ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index fd2f1b1742..06388a3ce2 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -9,7 +9,7 @@ use chalk_ir::{ }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; -use hir_def::{lang_item::LangItemTarget, GenericDefId, TypeAliasId}; +use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TypeAliasId}; use hir_expand::name; use ra_db::salsa::{InternId, InternKey}; @@ -203,18 +203,6 @@ impl ToChalk for Impl { } } -impl ToChalk for TypeAlias { - type Chalk = chalk_ir::TypeId; - - fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { - chalk_ir::TypeId(id_to_chalk(self.id)) - } - - fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAlias { - TypeAlias { id: id_from_chalk(type_alias_id.0) } - } -} - impl ToChalk for TypeAliasId { type Chalk = chalk_ir::TypeId; @@ -516,21 +504,21 @@ pub(crate) fn associated_ty_data_query( id: TypeId, ) -> Arc> { debug!("associated_ty_data {:?}", id); - let type_alias: TypeAlias = from_chalk(db, id); - let trait_ = match type_alias.container(db) { - Some(crate::Container::Trait(t)) => t, + let type_alias: TypeAliasId = from_chalk(db, id); + let trait_ = match type_alias.lookup(db).container { + ContainerId::TraitId(t) => t, _ => panic!("associated type not in trait"), }; - let generic_params = db.generic_params(type_alias.id.into()); + let generic_params = db.generic_params(type_alias.into()); let bound_data = chalk_rust_ir::AssociatedTyDatumBound { // FIXME add bounds and where clauses bounds: vec![], where_clauses: vec![], }; let datum = AssociatedTyDatum { - trait_id: trait_.to_chalk(db), + trait_id: Trait::from(trait_).to_chalk(db), id, - name: lalrpop_intern::intern(&type_alias.name(db).to_string()), + name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), binders: make_binders(bound_data, generic_params.count_params_including_parent()), }; Arc::new(datum) @@ -578,7 +566,7 @@ pub(crate) fn trait_datum_query( .items(db) .into_iter() .filter_map(|trait_item| match trait_item { - crate::AssocItem::TypeAlias(type_alias) => Some(type_alias), + crate::AssocItem::TypeAlias(type_alias) => Some(type_alias.id), _ => None, }) .map(|type_alias| type_alias.to_chalk(db)) @@ -797,7 +785,8 @@ fn type_alias_associated_ty_value( .trait_; let assoc_ty = trait_ .associated_type_by_name(db, &type_alias.name(db)) - .expect("assoc ty value should not exist"); // validated when building the impl data as well + .expect("assoc ty value should not exist") // validated when building the impl data as well + .id; let generic_params = db.generic_params(impl_block.id.into()); let bound_vars = Substs::bound_vars(&generic_params); let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); @@ -832,7 +821,8 @@ fn closure_fn_trait_output_assoc_ty_value( let output_ty_id = fn_once_trait .associated_type_by_name(db, &name::OUTPUT_TYPE) - .expect("assoc ty value should not exist"); + .expect("assoc ty value should not exist") + .id; let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: output_ty.to_chalk(db) }; From 245a9b165acb179c40b8c9d4a085e5ccdd4b75d3 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 26 Nov 2019 15:05:53 +0800 Subject: [PATCH 15/65] Add hygiene information to SourceAnalyzer --- crates/ra_hir/src/source_binder.rs | 13 ++++++----- crates/ra_hir_def/src/path.rs | 2 +- crates/ra_ide_api/src/call_info.rs | 9 +++----- crates/ra_ide_api/src/expand_macro.rs | 23 ++++++++++++++++++++ crates/ra_ide_api/src/references/classify.rs | 2 +- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index cbfeca3abb..287cea8808 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -14,7 +14,8 @@ use hir_def::{ DefWithBodyId, }; use hir_expand::{ - name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source, + hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, + Source, }; use ra_syntax::{ ast::{self, AstNode}, @@ -236,10 +237,10 @@ impl SourceAnalyzer { pub fn resolve_macro_call( &self, db: &impl HirDatabase, - macro_call: &ast::MacroCall, + macro_call: Source<&ast::MacroCall>, ) -> Option { - // This must be a normal source file rather than macro file. - let path = macro_call.path().and_then(Path::from_ast)?; + let hygiene = Hygiene::new(db, macro_call.file_id); + let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) } @@ -441,12 +442,14 @@ impl SourceAnalyzer { db: &impl HirDatabase, macro_call: Source<&ast::MacroCall>, ) -> Option { - let def = self.resolve_macro_call(db, macro_call.value)?.id; + let def = self.resolve_macro_call(db, macro_call)?.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 }; + let kind = to_macro_file_kind(macro_call.value); + dbg!(kind); Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc), macro_file_kind: to_macro_file_kind(macro_call.value), diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 0e606fd0e8..6810a26dbb 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -97,7 +97,7 @@ impl Path { /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. - pub(crate) fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option { + pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option { let mut kind = PathKind::Plain; let mut segments = Vec::new(); loop { diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 9beceb29cf..7ebdfc585a 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -18,12 +18,9 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { //FIXME: don't poke into Ty @@ -44,7 +41,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { - let macro_def = analyzer.resolve_macro_call(db, &expr)?; + let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?; (CallInfo::with_macro(db, macro_def)?, false) } }; diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 0b540b8cde..abc602244c 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs @@ -269,4 +269,27 @@ fn some_thing() -> u32 { assert_eq!(res.name, "foo"); assert_snapshot!(res.expansion, @r###"bar!()"###); } + + #[test] + fn macro_expand_with_dollar_crate() { + let res = check_expand_macro( + r#" + //- /lib.rs + #[macro_export] + macro_rules! bar { + () => {0}; + } + macro_rules! foo { + () => {$crate::bar!()}; + } + + fn main() { + let res = fo<|>o!(); + } + "#, + ); + + assert_eq!(res.name, "foo"); + assert_snapshot!(res.expansion, @r###"0"###); + } } diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs index cab06dea94..227737ad24 100644 --- a/crates/ra_ide_api/src/references/classify.rs +++ b/crates/ra_ide_api/src/references/classify.rs @@ -152,7 +152,7 @@ pub(crate) fn classify_name_ref( if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { tested_by!(goto_definition_works_for_macros); - if let Some(macro_def) = analyzer.resolve_macro_call(db, ¯o_call) { + if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(¯o_call)) { let kind = NameKind::Macro(macro_def); return Some(NameDefinition { kind, container, visibility }); } From 131c2da6bfd8ad6a25a55b4c85081da327ba2acb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 11:29:20 +0300 Subject: [PATCH 16/65] :arrow_up: salsa --- Cargo.lock | 52 ++++++++++++++++++----------- crates/ra_assists/src/test_db.rs | 3 ++ crates/ra_cli/src/analysis_bench.rs | 4 +-- crates/ra_db/Cargo.toml | 2 +- crates/ra_hir/src/test_db.rs | 4 +++ crates/ra_hir_def/src/test_db.rs | 4 ++- crates/ra_hir_expand/src/test_db.rs | 4 +++ crates/ra_ide_api/src/change.rs | 2 +- crates/ra_ide_api/src/db.rs | 3 ++ 9 files changed, 53 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c81112869..12d8af7e2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,16 +291,6 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "derive-new" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "difference" version = "2.0.0" @@ -799,6 +789,15 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.6.2" @@ -813,6 +812,19 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot_core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "paste" version = "0.1.6" @@ -981,7 +993,7 @@ dependencies = [ "ra_syntax 0.1.0", "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "salsa 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "salsa 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", ] @@ -1472,23 +1484,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "salsa" -version = "0.13.2" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "salsa-macros 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "salsa-macros" -version = "0.13.2" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1877,7 +1888,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" "checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" -"checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" @@ -1940,8 +1950,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" "checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" +"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" "checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" @@ -1985,8 +1997,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" -"checksum salsa 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec0865bdd9d8e614686a0cbb76979c735810131d287eb1683e91e4e64a58c387" -"checksum salsa-macros 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cac182212d3a1db75ddc42399ff1461b258a694b8318ee7e0baf6c976e39efee" +"checksum salsa 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a006c56096acaaa5e82e5974c28d05ff1e84aa70615f19c53fecf8a1afb2fd2" +"checksum salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "038a09b6271446f1123f142fe7e5bef6d4687c4cf82e6986be574c2af3745530" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" diff --git a/crates/ra_assists/src/test_db.rs b/crates/ra_assists/src/test_db.rs index 5f96c974bc..523259fd46 100644 --- a/crates/ra_assists/src/test_db.rs +++ b/crates/ra_assists/src/test_db.rs @@ -21,6 +21,9 @@ impl salsa::Database for TestDB { fn salsa_runtime(&self) -> &salsa::Runtime { &self.runtime } + fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime { + &mut self.runtime + } } impl std::panic::RefUnwindSafe for TestDB {} diff --git a/crates/ra_cli/src/analysis_bench.rs b/crates/ra_cli/src/analysis_bench.rs index 8bbe5d9e83..34105af57f 100644 --- a/crates/ra_cli/src/analysis_bench.rs +++ b/crates/ra_cli/src/analysis_bench.rs @@ -91,7 +91,7 @@ fn do_work T, T>(host: &mut AnalysisHost, file_id: FileId, w { let start = Instant::now(); eprint!("trivial change: "); - host.raw_database().salsa_runtime().synthetic_write(Durability::LOW); + host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::LOW); work(&host.analysis()); eprintln!("{:?}", start.elapsed()); } @@ -111,7 +111,7 @@ fn do_work T, T>(host: &mut AnalysisHost, file_id: FileId, w { let start = Instant::now(); eprint!("const change: "); - host.raw_database().salsa_runtime().synthetic_write(Durability::HIGH); + host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::HIGH); let res = work(&host.analysis()); eprintln!("{:?}", start.elapsed()); res diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml index 4ec09b6d91..7afa5d8fc9 100644 --- a/crates/ra_db/Cargo.toml +++ b/crates/ra_db/Cargo.toml @@ -8,7 +8,7 @@ authors = ["rust-analyzer developers"] doctest = false [dependencies] -salsa = "0.13.0" +salsa = "0.14.1" relative-path = "1.0.0" rustc-hash = "1.0" diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs index efee2f658b..a2071f71cf 100644 --- a/crates/ra_hir/src/test_db.rs +++ b/crates/ra_hir/src/test_db.rs @@ -28,6 +28,10 @@ impl salsa::Database for TestDB { &self.runtime } + fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime { + &mut self.runtime + } + fn salsa_event(&self, event: impl Fn() -> salsa::Event) { let mut events = self.events.lock(); if let Some(events) = &mut *events { diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs index 439e8a412b..54e3a84bdf 100644 --- a/crates/ra_hir_def/src/test_db.rs +++ b/crates/ra_hir_def/src/test_db.rs @@ -24,7 +24,9 @@ impl salsa::Database for TestDB { fn salsa_runtime(&self) -> &salsa::Runtime { &self.runtime } - + fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime { + &mut self.runtime + } fn salsa_event(&self, event: impl Fn() -> salsa::Event) { let mut events = self.events.lock().unwrap(); if let Some(events) = &mut *events { diff --git a/crates/ra_hir_expand/src/test_db.rs b/crates/ra_hir_expand/src/test_db.rs index d23e75d9ee..918736e2a1 100644 --- a/crates/ra_hir_expand/src/test_db.rs +++ b/crates/ra_hir_expand/src/test_db.rs @@ -23,6 +23,10 @@ impl salsa::Database for TestDB { &self.runtime } + fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime { + &mut self.runtime + } + fn salsa_event(&self, event: impl Fn() -> salsa::Event) { let mut events = self.events.lock().unwrap(); if let Some(events) = &mut *events { diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 0f692460dc..84340aff8c 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs @@ -171,7 +171,7 @@ impl RootDatabase { log::info!("apply_change {:?}", change); { let _p = profile("RootDatabase::apply_change/cancellation"); - self.salsa_runtime().synthetic_write(Durability::LOW); + self.salsa_runtime_mut().synthetic_write(Durability::LOW); } if !change.new_roots.is_empty() { let mut local_roots = Vec::clone(&self.local_roots()); diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index c2a9dcdd14..f739ebecd3 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs @@ -65,6 +65,9 @@ impl salsa::Database for RootDatabase { fn salsa_runtime(&self) -> &salsa::Runtime { &self.runtime } + fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime { + &mut self.runtime + } fn on_propagated_panic(&self) -> ! { Canceled::throw() } From 0a7ef0933130b8293b09b57382fd61e3d7c46c69 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 11:45:12 +0300 Subject: [PATCH 17/65] Use chalk fork to paper over #2052 --- Cargo.lock | 68 ++++++++++++++++++++-------------------- crates/ra_hir/Cargo.toml | 8 +++-- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12d8af7e2a..5feb78450d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,7 +123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chalk-derive" version = "0.1.0" -source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" +source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -133,9 +133,9 @@ dependencies = [ [[package]] name = "chalk-engine" version = "0.9.0" -source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" +source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30" dependencies = [ - "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", + "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "stacker 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -143,18 +143,18 @@ dependencies = [ [[package]] name = "chalk-ir" version = "0.1.0" -source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" +source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30" dependencies = [ - "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", + "chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "chalk-macros" version = "0.1.1" -source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" +source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -162,24 +162,24 @@ dependencies = [ [[package]] name = "chalk-rust-ir" version = "0.1.0" -source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" +source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30" dependencies = [ - "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", + "chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", ] [[package]] name = "chalk-solve" version = "0.1.0" -source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" +source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30" dependencies = [ - "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", + "chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -954,7 +954,7 @@ dependencies = [ "ra_hir 0.1.0", "ra_ide_api 0.1.0", "ra_project_model 0.1.0", - "ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "ra_vfs_glob 0.1.0", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1010,9 +1010,9 @@ name = "ra_hir" version = "0.1.0" dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", - "chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", + "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1109,7 +1109,7 @@ dependencies = [ "ra_project_model 0.1.0", "ra_syntax 0.1.0", "ra_text_edit 0.1.0", - "ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "ra_vfs_glob 0.1.0", "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1200,14 +1200,14 @@ dependencies = [ [[package]] name = "ra_vfs" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1218,7 +1218,7 @@ name = "ra_vfs_glob" version = "0.1.0" dependencies = [ "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1872,12 +1872,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cargo_metadata 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8d2d1617e838936c0d2323a65cc151e03ae19a7678dd24f72bccf27119b90a5d" "checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" -"checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" -"checksum chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" -"checksum chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" -"checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" -"checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "" +"checksum chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "" +"checksum chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "" +"checksum chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "" +"checksum chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "" +"checksum chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "" +"checksum chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "" "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" @@ -1966,7 +1966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum psm 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b14fc68b454f875abc8354c2555e1d56596f74833ddc0f77f87f4871ed6a30e0" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a95d3d1edc70a98d9e42f145bc92c2071dfdc532571591c9eac407c0e4feb89" +"checksum ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc898f237e4b4498959ae0100c688793a23e77624d44ef710ba70094217f98e0" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 42ddfecc9a..f725744855 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml @@ -26,9 +26,11 @@ hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } test_utils = { path = "../test_utils" } ra_prof = { path = "../ra_prof" } -chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } -chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } +# https://github.com/rust-lang/chalk/pull/294 +chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } +chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } +chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } + lalrpop-intern = "0.15.1" [dev-dependencies] From e5eadb339039e21718d382c0b3d02a4bf053b3f4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 14:02:57 +0300 Subject: [PATCH 18/65] Introduce hir::Type It should provide a convenient API over more low-level Ty --- .../src/assists/add_explicit_type.rs | 13 +- .../ra_assists/src/assists/fill_match_arms.rs | 7 +- crates/ra_hir/src/code_model.rs | 166 +++++++++++++++++- crates/ra_hir/src/lib.rs | 2 +- crates/ra_hir/src/source_binder.rs | 46 ++--- crates/ra_hir_def/src/lib.rs | 10 ++ crates/ra_ide_api/src/call_info.rs | 4 +- .../ra_ide_api/src/completion/complete_dot.rs | 36 ++-- .../src/completion/complete_postfix.rs | 16 +- .../src/completion/complete_record_literal.rs | 7 +- .../src/completion/complete_record_pattern.rs | 7 +- .../ra_ide_api/src/completion/presentation.rs | 39 ++-- crates/ra_ide_api/src/goto_type_definition.rs | 4 +- crates/ra_ide_api/src/inlay_hints.rs | 23 +-- crates/ra_ide_api/src/syntax_highlighting.rs | 9 +- 15 files changed, 253 insertions(+), 136 deletions(-) diff --git a/crates/ra_assists/src/assists/add_explicit_type.rs b/crates/ra_assists/src/assists/add_explicit_type.rs index 562a096853..eeb4ff39f4 100644 --- a/crates/ra_assists/src/assists/add_explicit_type.rs +++ b/crates/ra_assists/src/assists/add_explicit_type.rs @@ -1,4 +1,4 @@ -use hir::{db::HirDatabase, HirDisplay, Ty}; +use hir::{db::HirDatabase, HirDisplay}; use ra_syntax::{ ast::{self, AstNode, LetStmt, NameOwner}, T, @@ -43,7 +43,7 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx) -> Option) -> Option bool { - match ty { - Ty::Unknown => true, - Ty::Apply(a_ty) => a_ty.parameters.iter().any(is_unknown), - _ => false, - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/ra_assists/src/assists/fill_match_arms.rs b/crates/ra_assists/src/assists/fill_match_arms.rs index 8482897c57..b75bd44ebe 100644 --- a/crates/ra_assists/src/assists/fill_match_arms.rs +++ b/crates/ra_assists/src/assists/fill_match_arms.rs @@ -83,10 +83,11 @@ fn resolve_enum_def( ) -> Option { let expr_ty = analyzer.type_of(db, &expr)?; - analyzer.autoderef(db, expr_ty).find_map(|ty| match ty.as_adt() { - Some((Adt::Enum(e), _)) => Some(e.source(db).value), + let res = expr_ty.autoderef(db).find_map(|ty| match ty.as_adt() { + Some(Adt::Enum(e)) => Some(e.source(db).value), _ => None, - }) + }); + res } fn build_pat(var: ast::EnumVariant) -> Option { diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index f7fc80d4ee..a7bba85e14 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -10,9 +10,9 @@ use hir_def::{ docs::Documentation, per_ns::PerNs, resolver::{HasResolver, TypeNs}, - type_ref::TypeRef, - AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, - LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, + type_ref::{Mutability, TypeRef}, + AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, + ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, }; use hir_expand::{ @@ -26,8 +26,12 @@ use ra_syntax::{ast, AstNode, SyntaxNode}; use crate::{ db::{DefDatabase, HirDatabase}, expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, - ty::{InferenceResult, Namespace, TraitRef}, - Either, Name, Source, Ty, + ty::display::HirFormatter, + ty::{ + self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, + TypeWalk, + }, + CallableDef, Either, HirDisplay, Name, Source, }; /// hir::Crate describes a single crate. It's the main interface with which @@ -469,6 +473,10 @@ pub enum Adt { impl_froms!(Adt: Struct, Union, Enum); impl Adt { + pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { + let subst = db.generic_defaults(self.into()); + subst.iter().any(|ty| ty == &Ty::Unknown) + } pub fn ty(self, db: &impl HirDatabase) -> Ty { match self { Adt::Struct(it) => it.ty(db), @@ -777,6 +785,11 @@ pub struct TypeAlias { } impl TypeAlias { + pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { + let subst = db.generic_defaults(self.id.into()); + subst.iter().any(|ty| ty == &Ty::Unknown) + } + pub fn module(self, db: &impl DefDatabase) -> Module { Module { id: self.id.lookup(db).module(db) } } @@ -927,9 +940,14 @@ impl Local { self.parent.module(db) } - pub fn ty(self, db: &impl HirDatabase) -> Ty { + pub fn ty(self, db: &impl HirDatabase) -> Type { let infer = db.infer(self.parent); - infer[self.pat_id].clone() + let ty = infer[self.pat_id].clone(); + let def = DefWithBodyId::from(self.parent); + let resolver = def.resolver(db); + let krate = def.module(db).krate; + let environment = TraitEnvironment::lower(db, &resolver); + Type { krate, ty: InEnvironment { value: ty, environment } } } pub fn source(self, db: &impl HirDatabase) -> Source> { @@ -986,6 +1004,140 @@ impl ImplBlock { } } +#[derive(Clone, PartialEq, Eq)] +pub struct Type { + pub(crate) krate: CrateId, + pub(crate) ty: InEnvironment, +} + +impl Type { + pub fn is_bool(&self) -> bool { + match &self.ty.value { + Ty::Apply(a_ty) => match a_ty.ctor { + TypeCtor::Bool => true, + _ => false, + }, + _ => false, + } + } + + pub fn is_mutable_reference(&self) -> bool { + match &self.ty.value { + Ty::Apply(a_ty) => match a_ty.ctor { + TypeCtor::Ref(Mutability::Mut) => true, + _ => false, + }, + _ => false, + } + } + + pub fn is_unknown(&self) -> bool { + match &self.ty.value { + Ty::Unknown => true, + _ => false, + } + } + + // FIXME: this method is broken, as it doesn't take closures into account. + pub fn as_callable(&self) -> Option { + Some(self.ty.value.as_callable()?.0) + } + + pub fn contains_unknown(&self) -> bool { + return go(&self.ty.value); + + fn go(ty: &Ty) -> bool { + match ty { + Ty::Unknown => true, + Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), + _ => false, + } + } + } + + pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { + let mut res = Vec::new(); + if let Ty::Apply(a_ty) = &self.ty.value { + match a_ty.ctor { + ty::TypeCtor::Adt(Adt::Struct(s)) => { + for field in s.fields(db) { + let ty = field.ty(db).subst(&a_ty.parameters); + res.push((field, self.derived(ty))); + } + } + _ => {} + } + }; + res + } + + pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec { + let mut res = Vec::new(); + if let Ty::Apply(a_ty) = &self.ty.value { + match a_ty.ctor { + ty::TypeCtor::Tuple { .. } => { + for ty in a_ty.parameters.iter() { + let ty = ty.clone().subst(&a_ty.parameters); + res.push(self.derived(ty)); + } + } + _ => {} + } + }; + res + } + + pub fn variant_fields( + &self, + db: &impl HirDatabase, + def: VariantDef, + ) -> Vec<(StructField, Type)> { + // FIXME: check that ty and def match + match &self.ty.value { + Ty::Apply(a_ty) => def + .fields(db) + .into_iter() + .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) + .collect(), + _ => Vec::new(), + } + } + + pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator + 'a { + // There should be no inference vars in types passed here + // FIXME check that? + let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; + let environment = self.ty.environment.clone(); + let ty = InEnvironment { value: canonical, environment: environment.clone() }; + ty::autoderef(db, Some(self.krate), ty) + .map(|canonical| canonical.value) + .map(move |ty| self.derived(ty)) + } + + // FIXME: remove + pub fn into_ty(self) -> Ty { + self.ty.value + } + + pub fn as_adt(&self) -> Option { + let (adt, _subst) = self.ty.value.as_adt()?; + Some(adt) + } + + fn derived(&self, ty: Ty) -> Type { + Type { + krate: self.krate, + ty: InEnvironment { value: ty, environment: self.ty.environment.clone() }, + } + } +} + +impl HirDisplay for Type { + fn hir_fmt(&self, f: &mut HirFormatter) -> std::fmt::Result { + self.ty.value.hir_fmt(f) + } +} + /// For IDE only pub enum ScopeDef { ModuleDef(ModuleDef), diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 843ce6a88a..b88e4c745a 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -51,7 +51,7 @@ pub use crate::{ src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, - Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, + Static, Struct, StructField, Trait, Type, TypeAlias, Union, VariantDef, }, expr::ExprScopes, from_source::FromSource, diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index cbfeca3abb..95a94c3f02 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -28,10 +28,10 @@ use crate::{ expr::{BodySourceMap, ExprScopes, ScopeId}, ty::{ method_resolution::{self, implements_trait}, - TraitEnvironment, + InEnvironment, TraitEnvironment, Ty, }, Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, - GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias, + GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, }; fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option { @@ -198,14 +198,18 @@ impl SourceAnalyzer { self.body_source_map.as_ref()?.node_pat(src) } - pub fn type_of(&self, _db: &impl HirDatabase, expr: &ast::Expr) -> Option { + pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option { let expr_id = self.expr_id(expr)?; - Some(self.infer.as_ref()?[expr_id].clone()) + let ty = self.infer.as_ref()?[expr_id].clone(); + let environment = TraitEnvironment::lower(db, &self.resolver); + Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) } - pub fn type_of_pat(&self, _db: &impl HirDatabase, pat: &ast::Pat) -> Option { + pub fn type_of_pat(&self, db: &impl HirDatabase, pat: &ast::Pat) -> Option { let pat_id = self.pat_id(pat)?; - Some(self.infer.as_ref()?[pat_id].clone()) + let ty = self.infer.as_ref()?[pat_id].clone(); + let environment = TraitEnvironment::lower(db, &self.resolver); + Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) } pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option { @@ -361,14 +365,14 @@ impl SourceAnalyzer { pub fn iterate_method_candidates( &self, db: &impl HirDatabase, - ty: Ty, + ty: &Type, name: Option<&Name>, mut callback: impl FnMut(&Ty, Function) -> Option, ) -> Option { // There should be no inference vars in types passed here // FIXME check that? // FIXME replace Unknown by bound vars here - let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; + let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; method_resolution::iterate_method_candidates( &canonical, db, @@ -403,19 +407,19 @@ impl SourceAnalyzer { ) } - pub fn autoderef<'a>( - &'a self, - db: &'a impl HirDatabase, - ty: Ty, - ) -> impl Iterator + 'a { - // There should be no inference vars in types passed here - // FIXME check that? - let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; - let krate = self.resolver.krate(); - let environment = TraitEnvironment::lower(db, &self.resolver); - let ty = crate::ty::InEnvironment { value: canonical, environment }; - crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) - } + // pub fn autoderef<'a>( + // &'a self, + // db: &'a impl HirDatabase, + // ty: Ty, + // ) -> impl Iterator + 'a { + // // There should be no inference vars in types passed here + // // FIXME check that? + // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; + // let krate = self.resolver.krate(); + // let environment = TraitEnvironment::lower(db, &self.resolver); + // let ty = crate::ty::InEnvironment { value: canonical, environment }; + // crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) + // } /// Checks that particular type `ty` implements `std::future::Future`. /// This function is used in `.await` syntax completion. diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index a88a78b38f..274dd1467e 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -489,6 +489,16 @@ impl HasModule for AdtId { } } +impl HasModule for DefWithBodyId { + fn module(&self, db: &impl db::DefDatabase) -> ModuleId { + match self { + DefWithBodyId::FunctionId(it) => it.lookup(db).module(db), + DefWithBodyId::StaticId(it) => it.lookup(db).module(db), + DefWithBodyId::ConstId(it) => it.lookup(db).module(db), + } + } +} + impl HasModule for StaticLoc { fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { self.container diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 9beceb29cf..d0283e4103 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -26,8 +26,8 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { - //FIXME: don't poke into Ty - let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; + //FIXME: Type::as_callable is broken + let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; match callable_def { hir::CallableDef::FunctionId(it) => { let fn_def = it.into(); diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index 5a3f9b5f64..b6fe486270 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use hir::{Adt, Ty, TypeCtor}; +use hir::Type; use crate::completion::completion_item::CompletionKind; use crate::{ @@ -22,12 +22,12 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { }; if !ctx.is_call { - complete_fields(acc, ctx, receiver_ty.clone()); + complete_fields(acc, ctx, &receiver_ty); } - complete_methods(acc, ctx, receiver_ty.clone()); + complete_methods(acc, ctx, &receiver_ty); // Suggest .await syntax for types that implement Future trait - if ctx.analyzer.impls_future(ctx.db, receiver_ty) { + if ctx.analyzer.impls_future(ctx.db, receiver_ty.into_ty()) { CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await") .detail("expr.await") .insert_text("await") @@ -35,28 +35,18 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { } } -fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { - for receiver in ctx.analyzer.autoderef(ctx.db, receiver) { - if let Ty::Apply(a_ty) = receiver { - match a_ty.ctor { - TypeCtor::Adt(Adt::Struct(s)) => { - for field in s.fields(ctx.db) { - acc.add_field(ctx, field, &a_ty.parameters); - } - } - // FIXME unions - TypeCtor::Tuple { .. } => { - for (i, ty) in a_ty.parameters.iter().enumerate() { - acc.add_tuple_field(ctx, i, ty); - } - } - _ => {} - } - }; +fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { + for receiver in receiver.autoderef(ctx.db) { + for (field, ty) in receiver.fields(ctx.db) { + acc.add_field(ctx, field, &ty); + } + for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() { + acc.add_tuple_field(ctx, i, &ty); + } } } -fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { +fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { let mut seen_methods = FxHashSet::default(); ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| { if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) { diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs index 17b75cf7eb..646a30c76e 100644 --- a/crates/ra_ide_api/src/completion/complete_postfix.rs +++ b/crates/ra_ide_api/src/completion/complete_postfix.rs @@ -1,6 +1,5 @@ //! FIXME: write short doc here -use hir::{Ty, TypeCtor}; use ra_syntax::{ast::AstNode, TextRange, TextUnit}; use ra_text_edit::TextEdit; @@ -30,9 +29,12 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { dot_receiver.syntax().text().to_string() }; - let receiver_ty = ctx.analyzer.type_of(ctx.db, &dot_receiver); + let receiver_ty = match ctx.analyzer.type_of(ctx.db, &dot_receiver) { + Some(it) => it, + None => return, + }; - if is_bool_or_unknown(receiver_ty) { + if receiver_ty.is_bool() || receiver_ty.is_unknown() { postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) .add_to(acc); postfix_snippet( @@ -75,14 +77,6 @@ fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: .snippet_edit(edit) } -fn is_bool_or_unknown(ty: Option) -> bool { - match &ty { - Some(Ty::Apply(app)) if app.ctor == TypeCtor::Bool => true, - Some(Ty::Unknown) | None => true, - Some(_) => false, - } -} - #[cfg(test)] mod tests { use insta::assert_debug_snapshot; diff --git a/crates/ra_ide_api/src/completion/complete_record_literal.rs b/crates/ra_ide_api/src/completion/complete_record_literal.rs index 45a4a97382..577c394d22 100644 --- a/crates/ra_ide_api/src/completion/complete_record_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_record_literal.rs @@ -1,7 +1,5 @@ //! FIXME: write short doc here -use hir::Substs; - use crate::completion::{CompletionContext, Completions}; /// Complete fields in fields literals. @@ -15,10 +13,9 @@ pub(super) fn complete_record_literal(acc: &mut Completions, ctx: &CompletionCon Some(it) => it, _ => return, }; - let substs = &ty.substs().unwrap_or_else(Substs::empty); - for field in variant.fields(ctx.db) { - acc.add_field(ctx, field, substs); + for (field, field_ty) in ty.variant_fields(ctx.db, variant) { + acc.add_field(ctx, field, &field_ty); } } diff --git a/crates/ra_ide_api/src/completion/complete_record_pattern.rs b/crates/ra_ide_api/src/completion/complete_record_pattern.rs index aa0fd6d24f..a56c7e3a1f 100644 --- a/crates/ra_ide_api/src/completion/complete_record_pattern.rs +++ b/crates/ra_ide_api/src/completion/complete_record_pattern.rs @@ -1,7 +1,5 @@ //! FIXME: write short doc here -use hir::Substs; - use crate::completion::{CompletionContext, Completions}; pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) { @@ -14,10 +12,9 @@ pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionCon Some(it) => it, _ => return, }; - let substs = &ty.substs().unwrap_or_else(Substs::empty); - for field in variant.fields(ctx.db) { - acc.add_field(ctx, field, substs); + for (field, field_ty) in ty.variant_fields(ctx.db, variant) { + acc.add_field(ctx, field, &field_ty); } } diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 85b053a6ee..5f056730ac 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -1,12 +1,12 @@ //! This modules takes care of rendering various definitions as completion items. -use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; +use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Type}; use join_to_string::join; use ra_syntax::ast::NameOwner; use test_utils::tested_by; use crate::completion::{ - db, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, + CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, }; use crate::display::{const_label, function_label, macro_label, type_label}; @@ -16,7 +16,7 @@ impl Completions { &mut self, ctx: &CompletionContext, field: hir::StructField, - substs: &hir::Substs, + ty: &Type, ) { let is_deprecated = is_deprecated(field, ctx.db); CompletionItem::new( @@ -25,13 +25,13 @@ impl Completions { field.name(ctx.db).to_string(), ) .kind(CompletionItemKind::Field) - .detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string()) + .detail(ty.display(ctx.db).to_string()) .set_documentation(field.docs(ctx.db)) .set_deprecated(is_deprecated) .add_to(self); } - pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &hir::Ty) { + pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &Type) { CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string()) .kind(CompletionItemKind::Field) .detail(ty.display(ctx.db).to_string()) @@ -98,7 +98,7 @@ impl Completions { CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone()); if let ScopeDef::Local(local) = resolution { let ty = local.ty(ctx.db); - if ty != Ty::Unknown { + if !ty.is_unknown() { completion_item = completion_item.detail(ty.display(ctx.db).to_string()); } }; @@ -108,19 +108,17 @@ impl Completions { && !ctx.has_type_args && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") { - let generic_def: Option = match resolution { - ScopeDef::ModuleDef(Adt(it)) => Some((*it).into()), - ScopeDef::ModuleDef(TypeAlias(it)) => Some((*it).into()), - _ => None, + let has_non_default_type_params = match resolution { + ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db), + ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db), + _ => false, }; - if let Some(def) = generic_def { - if has_non_default_type_params(def, ctx.db) { - tested_by!(inserts_angle_brackets_for_generics); - completion_item = completion_item - .lookup_by(local_name.clone()) - .label(format!("{}<…>", local_name)) - .insert_snippet(format!("{}<$0>", local_name)); - } + if has_non_default_type_params { + tested_by!(inserts_angle_brackets_for_generics); + completion_item = completion_item + .lookup_by(local_name.clone()) + .label(format!("{}<…>", local_name)) + .insert_snippet(format!("{}<$0>", local_name)); } } @@ -291,11 +289,6 @@ fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { node.attrs(db).by_key("deprecated").exists() } -fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { - let subst = db.generic_defaults(def.into()); - subst.iter().any(|ty| ty == &Ty::Unknown) -} - #[cfg(test)] mod tests { use insta::assert_debug_snapshot; diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide_api/src/goto_type_definition.rs index 28a83a3e2a..992a088090 100644 --- a/crates/ra_ide_api/src/goto_type_definition.rs +++ b/crates/ra_ide_api/src/goto_type_definition.rs @@ -24,7 +24,7 @@ pub(crate) fn goto_type_definition( let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); - let ty: hir::Ty = if let Some(ty) = + let ty: hir::Type = if let Some(ty) = ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) { ty @@ -35,7 +35,7 @@ pub(crate) fn goto_type_definition( return None; }; - let adt_def = analyzer.autoderef(db, ty).find_map(|ty| ty.as_adt().map(|adt| adt.0))?; + let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?; let nav = adt_def.to_nav(db); Some(RangeInfo::new(node.text_range(), vec![nav])) diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs index 24a7ca5e71..45149bf0cc 100644 --- a/crates/ra_ide_api/src/inlay_hints.rs +++ b/crates/ra_ide_api/src/inlay_hints.rs @@ -1,7 +1,7 @@ //! FIXME: write short doc here use crate::{db::RootDatabase, FileId}; -use hir::{HirDisplay, SourceAnalyzer, Ty}; +use hir::{HirDisplay, SourceAnalyzer}; use ra_syntax::{ ast::{self, AstNode, TypeAscriptionOwner}, match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange, @@ -100,8 +100,11 @@ fn get_pat_type_hints( .into_iter() .filter(|pat| !skip_root_pat_hint || pat != original_pat) .filter_map(|pat| { - get_node_displayable_type(db, &analyzer, &pat) - .map(|pat_type| (pat.syntax().text_range(), pat_type)) + let ty = analyzer.type_of_pat(db, &pat)?; + if ty.is_unknown() { + return None; + } + Some((pat.syntax().text_range(), ty)) }) .map(|(range, pat_type)| InlayHint { range, @@ -158,20 +161,6 @@ fn get_leaf_pats(root_pat: ast::Pat) -> Vec { leaf_pats } -fn get_node_displayable_type( - db: &RootDatabase, - analyzer: &SourceAnalyzer, - node_pat: &ast::Pat, -) -> Option { - analyzer.type_of_pat(db, node_pat).and_then(|resolved_type| { - if let Ty::Apply(_) = resolved_type { - Some(resolved_type) - } else { - None - } - }) -} - #[cfg(test)] mod tests { use crate::mock_analysis::single_file; diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 2b653fe8fa..10165a9bbc 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs @@ -2,7 +2,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; -use hir::{Mutability, Name, Source}; +use hir::{Name, Source}; use ra_db::SourceDatabase; use ra_prof::profile; use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; @@ -230,11 +230,10 @@ fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { Local(local) => { if local.is_mut(db) { "variable.mut" + } else if local.ty(db).is_mutable_reference() { + "variable.mut" } else { - match local.ty(db).as_reference() { - Some((_, Mutability::Mut)) => "variable.mut", - _ => "variable", - } + "variable" } } } From a443b5033c2e95ee58bf086f7093ddc610d4f78f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 14:29:12 +0300 Subject: [PATCH 19/65] Id-ify Ty::Adt --- crates/ra_hir/src/code_model.rs | 54 +++++++++++++++---- crates/ra_hir/src/expr.rs | 4 +- crates/ra_hir/src/from_id.rs | 17 ++++++ crates/ra_hir/src/ty.rs | 12 ++--- crates/ra_hir/src/ty/infer.rs | 4 +- crates/ra_hir/src/ty/infer/coerce.rs | 12 ++--- crates/ra_hir/src/ty/infer/expr.rs | 21 ++++---- crates/ra_hir/src/ty/lower.rs | 2 +- crates/ra_hir/src/ty/method_resolution.rs | 6 ++- crates/ra_hir_def/src/adt.rs | 4 ++ .../src/references/name_definition.rs | 1 + 11 files changed, 98 insertions(+), 39 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a7bba85e14..bb1596bed0 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -11,9 +11,9 @@ use hir_def::{ per_ns::PerNs, resolver::{HasResolver, TypeNs}, type_ref::{Mutability, TypeRef}, - AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, - ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, - StaticId, StructId, TraitId, TypeAliasId, UnionId, + AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, + HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, + Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -383,6 +383,28 @@ impl Union { pub fn ty(self, db: &impl HirDatabase) -> Ty { db.type_for_def(self.into(), Namespace::Types) } + + pub fn fields(self, db: &impl HirDatabase) -> Vec { + db.union_data(self.id) + .variant_data + .fields() + .iter() + .map(|(id, _)| StructField { parent: self.into(), id }) + .collect() + } + + pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option { + db.union_data(self.id) + .variant_data + .fields() + .iter() + .find(|(_id, data)| data.name == *name) + .map(|(id, _)| StructField { parent: self.into(), id }) + } + + fn variant_data(self, db: &impl DefDatabase) -> Arc { + db.union_data(self.id).variant_data.clone() + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -501,14 +523,16 @@ impl Adt { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum VariantDef { Struct(Struct), + Union(Union), EnumVariant(EnumVariant), } -impl_froms!(VariantDef: Struct, EnumVariant); +impl_froms!(VariantDef: Struct, Union, EnumVariant); impl VariantDef { pub fn fields(self, db: &impl HirDatabase) -> Vec { match self { VariantDef::Struct(it) => it.fields(db), + VariantDef::Union(it) => it.fields(db), VariantDef::EnumVariant(it) => it.fields(db), } } @@ -516,6 +540,7 @@ impl VariantDef { pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option { match self { VariantDef::Struct(it) => it.field(db, name), + VariantDef::Union(it) => it.field(db, name), VariantDef::EnumVariant(it) => it.field(db, name), } } @@ -523,6 +548,7 @@ impl VariantDef { pub fn module(self, db: &impl HirDatabase) -> Module { match self { VariantDef::Struct(it) => it.module(db), + VariantDef::Union(it) => it.module(db), VariantDef::EnumVariant(it) => it.module(db), } } @@ -530,6 +556,7 @@ impl VariantDef { pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc { match self { VariantDef::Struct(it) => it.variant_data(db), + VariantDef::Union(it) => it.variant_data(db), VariantDef::EnumVariant(it) => it.variant_data(db), } } @@ -1056,19 +1083,24 @@ impl Type { } pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { - let mut res = Vec::new(); if let Ty::Apply(a_ty) = &self.ty.value { match a_ty.ctor { - ty::TypeCtor::Adt(Adt::Struct(s)) => { - for field in s.fields(db) { - let ty = field.ty(db).subst(&a_ty.parameters); - res.push((field, self.derived(ty))); - } + ty::TypeCtor::Adt(AdtId::StructId(s)) => { + let var_def = s.into(); + return db + .field_types(var_def) + .iter() + .map(|(local_id, ty)| { + let def = StructField { parent: var_def.into(), id: local_id }; + let ty = ty.clone().subst(&a_ty.parameters); + (def, self.derived(ty)) + }) + .collect(); } _ => {} } }; - res + Vec::new() } pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec { diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 43fedde7aa..adb9805ab8 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use hir_def::{path::known, resolver::HasResolver}; +use hir_def::{path::known, resolver::HasResolver, AdtId}; use hir_expand::diagnostics::DiagnosticSink; use ra_syntax::ast; use ra_syntax::AstPtr; @@ -127,7 +127,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { _ => return, }; - let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into())); + let std_result_ctor = TypeCtor::Adt(AdtId::EnumId(std_result_enum)); let params = match &mismatch.expected { Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, _ => return, diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 619f6055e1..38daa5e59f 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -199,11 +199,22 @@ impl From for GenericDefId { } } +impl From for VariantDef { + fn from(def: VariantId) -> Self { + match def { + VariantId::StructId(it) => VariantDef::Struct(it.into()), + VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()), + VariantId::UnionId(it) => VariantDef::Union(it.into()), + } + } +} + impl From for VariantId { fn from(def: VariantDef) -> Self { match def { VariantDef::Struct(it) => VariantId::StructId(it.id), VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), + VariantDef::Union(it) => VariantId::UnionId(it.id), } } } @@ -214,6 +225,12 @@ impl From for StructFieldId { } } +impl From for StructField { + fn from(def: StructFieldId) -> Self { + StructField { parent: def.parent.into(), id: def.local_id } + } +} + impl From for AttrDefId { fn from(def: AttrDef) -> Self { match def { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 388530f310..bd03055b93 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -58,7 +58,7 @@ pub enum TypeCtor { Float(Uncertain), /// Structures, enumerations and unions. - Adt(Adt), + Adt(AdtId), /// The pointee of a string slice. Written as `str`. Str, @@ -174,7 +174,7 @@ impl TypeCtor { | TypeCtor::Tuple { .. } => None, // Closure's krate is irrelevant for coherence I would think? TypeCtor::Closure { .. } => None, - TypeCtor::Adt(adt) => adt.krate(db), + TypeCtor::Adt(adt) => Some(adt.module(db).krate.into()), TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), TypeCtor::AssociatedType(type_alias) => { Some(type_alias.lookup(db).module(db).krate.into()) @@ -598,7 +598,7 @@ impl Ty { pub fn as_adt(&self) -> Option<(Adt, &Substs)> { match self { Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { - Some((*adt_def, parameters)) + Some(((*adt_def).into(), parameters)) } _ => None, } @@ -889,9 +889,9 @@ impl HirDisplay for ApplicationTy { } TypeCtor::Adt(def_id) => { let name = match def_id { - Adt::Struct(s) => s.name(f.db), - Adt::Union(u) => u.name(f.db), - Adt::Enum(e) => e.name(f.db), + AdtId::StructId(it) => f.db.struct_data(it).name.clone(), + AdtId::UnionId(it) => f.db.union_data(it).name.clone(), + AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), } .unwrap_or_else(Name::missing); write!(f, "{}", name)?; diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 6fd00d457f..fce45321df 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -598,10 +598,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) } - fn resolve_boxed_box(&self) -> Option { + fn resolve_boxed_box(&self) -> Option { let path = known::std_boxed_box(); let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; - Some(Adt::Struct(struct_.into())) + Some(struct_.into()) } } diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index bb9a2e427e..5ed4470afa 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -4,14 +4,14 @@ //! //! See: https://doc.rust-lang.org/nomicon/coercions.html -use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; +use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId}; use rustc_hash::FxHashMap; use test_utils::tested_by; use crate::{ db::HirDatabase, ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, - Adt, Mutability, + Mutability, }; use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; @@ -242,11 +242,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { // - T is not part of the type of any other fields // - Bar: Unsize>, if the last field of Foo has type Bar ( - ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), - ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), + ty_app!(TypeCtor::Adt(AdtId::StructId(struct1)), st1), + ty_app!(TypeCtor::Adt(AdtId::StructId(struct2)), st2), ) if struct1 == struct2 => { - let field_tys = self.db.field_types(struct1.id.into()); - let struct_data = self.db.struct_data(struct1.id); + let field_tys = self.db.field_types((*struct1).into()); + let struct_data = self.db.struct_data(*struct1); let mut fields = struct_data.variant_data.fields().iter(); let (last_field_id, _data) = fields.next_back()?; diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 316cdc8800..3d0895dc61 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -8,7 +8,7 @@ use hir_def::{ generics::GenericParams, path::{GenericArg, GenericArgs}, resolver::resolver_for_expr, - ContainerId, Lookup, + AdtId, ContainerId, Lookup, StructFieldId, }; use hir_expand::name; @@ -20,7 +20,7 @@ use crate::{ Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }, - Adt, Name, + Name, }; use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; @@ -259,14 +259,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { TypeCtor::Tuple { .. } => name .as_tuple_index() .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), - TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { - self.write_field_resolution(tgt_expr, field); - self.db.field_types(s.id.into())[field.id] - .clone() - .subst(&a_ty.parameters) - }), + TypeCtor::Adt(AdtId::StructId(s)) => { + self.db.struct_data(s).variant_data.field(name).map(|local_id| { + let field = StructFieldId { parent: s.into(), local_id }.into(); + self.write_field_resolution(tgt_expr, field); + self.db.field_types(s.into())[field.id] + .clone() + .subst(&a_ty.parameters) + }) + } // FIXME: - TypeCtor::Adt(Adt::Union(_)) => None, + TypeCtor::Adt(AdtId::UnionId(_)) => None, _ => None, }, _ => None, diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index d7d4bb0d66..485871e690 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -762,7 +762,7 @@ fn type_for_adt(db: &impl HirDatabase, adt: impl Into) -> Ty { let adt = adt.into(); let adt_id: AdtId = adt.into(); let generics = db.generic_params(adt_id.into()); - Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) + Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics)) } fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index c5ab690eb9..7f0ff2e8ca 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use arrayvec::ArrayVec; -use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef}; +use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule}; use rustc_hash::FxHashMap; use crate::{ @@ -102,7 +102,9 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option match a_ty.ctor { - TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()), + TypeCtor::Adt(def_id) => { + return Some(std::iter::once(def_id.module(db).krate.into()).collect()) + } TypeCtor::Bool => lang_item_crate!("bool"), TypeCtor::Char => lang_item_crate!("char"), TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 0091bfbc33..0cf418d301 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -129,6 +129,10 @@ impl VariantData { } } + pub fn field(&self, name: &Name) -> Option { + self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None }) + } + pub fn is_unit(&self) -> bool { match self { VariantData::Unit => true, diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs index aca23f79e2..cf12db066a 100644 --- a/crates/ra_ide_api/src/references/name_definition.rs +++ b/crates/ra_ide_api/src/references/name_definition.rs @@ -46,6 +46,7 @@ pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDe let container = parent.module(db); let visibility = match parent { VariantDef::Struct(s) => s.source(db).value.visibility(), + VariantDef::Union(e) => e.source(db).value.visibility(), VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), }; NameDefinition { kind, container, visibility } From 4c43631829d8bac8b7533c994d8cf1241a95ce70 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 14:35:23 +0300 Subject: [PATCH 20/65] Introduce hir_ty --- Cargo.lock | 23 ++++ crates/ra_hir/Cargo.toml | 1 + crates/ra_hir/src/ty/lower.rs | 34 +----- crates/ra_hir/src/ty/primitive.rs | 159 +------------------------ crates/ra_hir_ty/Cargo.toml | 32 +++++ crates/ra_hir_ty/src/lib.rs | 3 + crates/ra_hir_ty/src/primitive.rs | 190 ++++++++++++++++++++++++++++++ 7 files changed, 252 insertions(+), 190 deletions(-) create mode 100644 crates/ra_hir_ty/Cargo.toml create mode 100644 crates/ra_hir_ty/src/lib.rs create mode 100644 crates/ra_hir_ty/src/primitive.rs diff --git a/Cargo.lock b/Cargo.lock index 5feb78450d..9e5ca2fb6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1024,6 +1024,7 @@ dependencies = [ "ra_db 0.1.0", "ra_hir_def 0.1.0", "ra_hir_expand 0.1.0", + "ra_hir_ty 0.1.0", "ra_mbe 0.1.0", "ra_prof 0.1.0", "ra_syntax 0.1.0", @@ -1065,6 +1066,28 @@ dependencies = [ "ra_tt 0.1.0", ] +[[package]] +name = "ra_hir_ty" +version = "0.1.0" +dependencies = [ + "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", + "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ra_arena 0.1.0", + "ra_db 0.1.0", + "ra_hir_def 0.1.0", + "ra_hir_expand 0.1.0", + "ra_prof 0.1.0", + "ra_syntax 0.1.0", + "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "test_utils 0.1.0", +] + [[package]] name = "ra_ide_api" version = "0.1.0" diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index f725744855..23c056e90e 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml @@ -23,6 +23,7 @@ mbe = { path = "../ra_mbe", package = "ra_mbe" } tt = { path = "../ra_tt", package = "ra_tt" } hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } +hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } test_utils = { path = "../test_utils" } ra_prof = { path = "../ra_prof" } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 485871e690..2d23890a58 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -9,7 +9,7 @@ use std::iter; use std::sync::Arc; use hir_def::{ - builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, + builtin_type::BuiltinType, generics::WherePredicate, path::{GenericArg, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, @@ -27,7 +27,7 @@ use super::{ use crate::{ db::HirDatabase, ty::{ - primitive::{FloatTy, IntTy, Uncertain}, + primitive::{FloatTy, IntTy}, Adt, }, util::make_mut_slice, @@ -679,36 +679,6 @@ fn type_for_builtin(def: BuiltinType) -> Ty { }) } -impl From for IntTy { - fn from(t: BuiltinInt) -> Self { - IntTy { signedness: t.signedness, bitness: t.bitness } - } -} - -impl From for FloatTy { - fn from(t: BuiltinFloat) -> Self { - FloatTy { bitness: t.bitness } - } -} - -impl From> for Uncertain { - fn from(t: Option) -> Self { - match t { - None => Uncertain::Unknown, - Some(t) => Uncertain::Known(t.into()), - } - } -} - -impl From> for Uncertain { - fn from(t: Option) -> Self { - match t { - None => Uncertain::Unknown, - Some(t) => Uncertain::Known(t.into()), - } - } -} - fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { let struct_data = db.struct_data(def.into()); let fields = struct_data.variant_data.fields(); diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 47789db877..eb7b5c4ef9 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs @@ -1,160 +1,3 @@ //! FIXME: write short doc here -use std::fmt; - -pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness}; - -#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] -pub enum Uncertain { - Unknown, - Known(T), -} - -impl From for Uncertain { - fn from(ty: IntTy) -> Self { - Uncertain::Known(ty) - } -} - -impl fmt::Display for Uncertain { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Uncertain::Unknown => write!(f, "{{integer}}"), - Uncertain::Known(ty) => write!(f, "{}", ty), - } - } -} - -impl From for Uncertain { - fn from(ty: FloatTy) -> Self { - Uncertain::Known(ty) - } -} - -impl fmt::Display for Uncertain { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Uncertain::Unknown => write!(f, "{{float}}"), - Uncertain::Known(ty) => write!(f, "{}", ty), - } - } -} - -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct IntTy { - pub signedness: Signedness, - pub bitness: IntBitness, -} - -impl fmt::Debug for IntTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl fmt::Display for IntTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.ty_to_string()) - } -} - -impl IntTy { - pub fn isize() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } - } - - pub fn i8() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } - } - - pub fn i16() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } - } - - pub fn i32() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } - } - - pub fn i64() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } - } - - pub fn i128() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } - } - - pub fn usize() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } - } - - pub fn u8() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } - } - - pub fn u16() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } - } - - pub fn u32() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } - } - - pub fn u64() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } - } - - pub fn u128() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } - } - - pub(crate) fn ty_to_string(self) -> &'static str { - match (self.signedness, self.bitness) { - (Signedness::Signed, IntBitness::Xsize) => "isize", - (Signedness::Signed, IntBitness::X8) => "i8", - (Signedness::Signed, IntBitness::X16) => "i16", - (Signedness::Signed, IntBitness::X32) => "i32", - (Signedness::Signed, IntBitness::X64) => "i64", - (Signedness::Signed, IntBitness::X128) => "i128", - (Signedness::Unsigned, IntBitness::Xsize) => "usize", - (Signedness::Unsigned, IntBitness::X8) => "u8", - (Signedness::Unsigned, IntBitness::X16) => "u16", - (Signedness::Unsigned, IntBitness::X32) => "u32", - (Signedness::Unsigned, IntBitness::X64) => "u64", - (Signedness::Unsigned, IntBitness::X128) => "u128", - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub struct FloatTy { - pub bitness: FloatBitness, -} - -impl fmt::Debug for FloatTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl fmt::Display for FloatTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.ty_to_string()) - } -} - -impl FloatTy { - pub fn f32() -> FloatTy { - FloatTy { bitness: FloatBitness::X32 } - } - - pub fn f64() -> FloatTy { - FloatTy { bitness: FloatBitness::X64 } - } - - pub(crate) fn ty_to_string(self) -> &'static str { - match self.bitness { - FloatBitness::X32 => "f32", - FloatBitness::X64 => "f64", - } - } -} +pub use hir_ty::primitive::{FloatBitness, IntBitness, Signedness, FloatTy, IntTy, Uncertain}; diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml new file mode 100644 index 0000000000..70216ab240 --- /dev/null +++ b/crates/ra_hir_ty/Cargo.toml @@ -0,0 +1,32 @@ +[package] +edition = "2018" +name = "ra_hir_ty" +version = "0.1.0" +authors = ["rust-analyzer developers"] + +[lib] +doctest = false + +[dependencies] +log = "0.4.5" +rustc-hash = "1.0" +parking_lot = "0.9.0" +ena = "0.13" + +ra_syntax = { path = "../ra_syntax" } +ra_arena = { path = "../ra_arena" } +ra_db = { path = "../ra_db" } +hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } +hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } +test_utils = { path = "../test_utils" } +ra_prof = { path = "../ra_prof" } + +# https://github.com/rust-lang/chalk/pull/294 +chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } +chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } +chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } + +lalrpop-intern = "0.15.1" + +[dev-dependencies] +insta = "0.12.0" diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs new file mode 100644 index 0000000000..25bfc1d154 --- /dev/null +++ b/crates/ra_hir_ty/src/lib.rs @@ -0,0 +1,3 @@ +//! FIXME: write short doc here + +pub mod primitive; diff --git a/crates/ra_hir_ty/src/primitive.rs b/crates/ra_hir_ty/src/primitive.rs new file mode 100644 index 0000000000..afa22448da --- /dev/null +++ b/crates/ra_hir_ty/src/primitive.rs @@ -0,0 +1,190 @@ +//! FIXME: write short doc here + +use std::fmt; + +pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; + +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] +pub enum Uncertain { + Unknown, + Known(T), +} + +impl From for Uncertain { + fn from(ty: IntTy) -> Self { + Uncertain::Known(ty) + } +} + +impl fmt::Display for Uncertain { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Uncertain::Unknown => write!(f, "{{integer}}"), + Uncertain::Known(ty) => write!(f, "{}", ty), + } + } +} + +impl From for Uncertain { + fn from(ty: FloatTy) -> Self { + Uncertain::Known(ty) + } +} + +impl fmt::Display for Uncertain { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Uncertain::Unknown => write!(f, "{{float}}"), + Uncertain::Known(ty) => write!(f, "{}", ty), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct IntTy { + pub signedness: Signedness, + pub bitness: IntBitness, +} + +impl fmt::Debug for IntTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Display for IntTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.ty_to_string()) + } +} + +impl IntTy { + pub fn isize() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } + } + + pub fn i8() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } + } + + pub fn i16() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } + } + + pub fn i32() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } + } + + pub fn i64() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } + } + + pub fn i128() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } + } + + pub fn usize() -> IntTy { + IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } + } + + pub fn u8() -> IntTy { + IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } + } + + pub fn u16() -> IntTy { + IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } + } + + pub fn u32() -> IntTy { + IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } + } + + pub fn u64() -> IntTy { + IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } + } + + pub fn u128() -> IntTy { + IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } + } + + pub fn ty_to_string(self) -> &'static str { + match (self.signedness, self.bitness) { + (Signedness::Signed, IntBitness::Xsize) => "isize", + (Signedness::Signed, IntBitness::X8) => "i8", + (Signedness::Signed, IntBitness::X16) => "i16", + (Signedness::Signed, IntBitness::X32) => "i32", + (Signedness::Signed, IntBitness::X64) => "i64", + (Signedness::Signed, IntBitness::X128) => "i128", + (Signedness::Unsigned, IntBitness::Xsize) => "usize", + (Signedness::Unsigned, IntBitness::X8) => "u8", + (Signedness::Unsigned, IntBitness::X16) => "u16", + (Signedness::Unsigned, IntBitness::X32) => "u32", + (Signedness::Unsigned, IntBitness::X64) => "u64", + (Signedness::Unsigned, IntBitness::X128) => "u128", + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct FloatTy { + pub bitness: FloatBitness, +} + +impl fmt::Debug for FloatTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Display for FloatTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.ty_to_string()) + } +} + +impl FloatTy { + pub fn f32() -> FloatTy { + FloatTy { bitness: FloatBitness::X32 } + } + + pub fn f64() -> FloatTy { + FloatTy { bitness: FloatBitness::X64 } + } + + pub fn ty_to_string(self) -> &'static str { + match self.bitness { + FloatBitness::X32 => "f32", + FloatBitness::X64 => "f64", + } + } +} + +impl From for IntTy { + fn from(t: BuiltinInt) -> Self { + IntTy { signedness: t.signedness, bitness: t.bitness } + } +} + +impl From for FloatTy { + fn from(t: BuiltinFloat) -> Self { + FloatTy { bitness: t.bitness } + } +} + +impl From> for Uncertain { + fn from(t: Option) -> Self { + match t { + None => Uncertain::Unknown, + Some(t) => Uncertain::Known(t.into()), + } + } +} + +impl From> for Uncertain { + fn from(t: Option) -> Self { + match t { + None => Uncertain::Unknown, + Some(t) => Uncertain::Known(t.into()), + } + } +} From 8b1f2cd14eded9c2e37f6969a755541f843552b5 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Tue, 26 Nov 2019 07:29:28 -0500 Subject: [PATCH 21/65] Update parking_lot and smallvec to drop some dependencies --- Cargo.lock | 51 ++++----------------------------- crates/ra_hir/Cargo.toml | 2 +- crates/ra_lsp_server/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5feb78450d..12da410d09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,7 +611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lock_api" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -653,11 +653,6 @@ name = "matches" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "memchr" version = "2.2.1" @@ -779,39 +774,15 @@ name = "ordermap" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot_core" version = "0.7.0" @@ -1018,7 +989,7 @@ dependencies = [ "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ra_arena 0.1.0", "ra_cfg 0.1.0", "ra_db 0.1.0", @@ -1103,7 +1074,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ra_ide_api 0.1.0", "ra_prof 0.1.0", "ra_project_model 0.1.0", @@ -1589,14 +1560,6 @@ name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "smallvec" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "smallvec" version = "1.0.0" @@ -1931,12 +1894,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" -"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" +"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12" "checksum lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa3268fbe8beb2795c2fb327bf44f4f3d24f5fe9ebc18d7e2980afd444d72bcf" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" @@ -1951,8 +1913,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" -"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" "checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" @@ -2009,7 +1969,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" "checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b" "checksum stacker 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d96fc4f13a0ac088e9a3cd9af1cc8c5cc1ab5deb2145cef661267dfc9c542f8a" diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index f725744855..16bd4bafc2 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml @@ -11,7 +11,7 @@ doctest = false arrayvec = "0.5.1" log = "0.4.5" rustc-hash = "1.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" ena = "0.13" once_cell = "1.0.1" diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 72dbe06dcc..58b9cfaa00 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -17,7 +17,7 @@ flexi_logger = "0.14.0" log = "0.4.3" lsp-types = { version = "0.61.0", features = ["proposed"] } rustc-hash = "1.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" jod-thread = "0.1.0" ra_vfs = "0.5.0" ra_syntax = { path = "../ra_syntax" } From 45d05ed78384b28fbd341068f36912a2e0308292 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 15:27:33 +0300 Subject: [PATCH 22/65] id-ify impls_in_crate_query --- crates/ra_hir/src/code_model.rs | 9 ++ crates/ra_hir/src/db.rs | 4 +- crates/ra_hir/src/ty/method_resolution.rs | 105 ++++++++++++---------- crates/ra_hir/src/ty/primitive.rs | 2 +- crates/ra_hir/src/ty/traits.rs | 4 +- crates/ra_ide_api/src/impls.rs | 10 +-- 6 files changed, 76 insertions(+), 58 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index bb1596bed0..821f919d47 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -997,6 +997,15 @@ pub struct ImplBlock { } impl ImplBlock { + pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec { + let impls = db.impls_in_crate(krate.crate_id); + impls.all_impls().map(Self::from).collect() + } + pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec { + let impls = db.impls_in_crate(krate.crate_id); + impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect() + } + pub fn target_trait(&self, db: &impl DefDatabase) -> Option { db.impl_data(self.id).target_trait.clone() } diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index b034d4e448..32f05a4d8b 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use ra_arena::map::ArenaMap; -use ra_db::salsa; +use ra_db::{salsa, CrateId}; use crate::{ ty::{ @@ -60,7 +60,7 @@ pub trait HirDatabase: DefDatabase { fn generic_defaults(&self, def: GenericDefId) -> Substs; #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] - fn impls_in_crate(&self, krate: Crate) -> Arc; + fn impls_in_crate(&self, krate: CrateId) -> Arc; #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 7f0ff2e8ca..489fcd64b9 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -5,14 +5,19 @@ use std::sync::Arc; use arrayvec::ArrayVec; -use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule}; +use hir_def::{ + lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef, + HasModule, ImplId, TraitId, +}; +use ra_db::CrateId; +use ra_prof::profile; use rustc_hash::FxHashMap; use crate::{ db::HirDatabase, ty::primitive::{FloatBitness, Uncertain}, ty::{Ty, TypeCtor}, - AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, + AssocItem, Crate, Function, Mutability, Name, Trait, }; use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; @@ -37,53 +42,57 @@ impl TyFingerprint { #[derive(Debug, PartialEq, Eq)] pub struct CrateImplBlocks { - impls: FxHashMap>, - impls_by_trait: FxHashMap>, + impls: FxHashMap>, + impls_by_trait: FxHashMap>, } impl CrateImplBlocks { pub(crate) fn impls_in_crate_query( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, ) -> Arc { - let mut crate_impl_blocks = + let _p = profile("impls_in_crate_query"); + let mut res = CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; - if let Some(module) = krate.root_module(db) { - crate_impl_blocks.collect_recursive(db, module); - } - Arc::new(crate_impl_blocks) - } - pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator + '_ { - let fingerprint = TyFingerprint::for_impl(ty); - fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() - } - pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator + '_ { - self.impls_by_trait.get(&tr).into_iter().flatten().copied() - } + let crate_def_map = db.crate_def_map(krate); + for (_module_id, module_data) in crate_def_map.modules.iter() { + for &impl_id in module_data.impls.iter() { + let impl_data = db.impl_data(impl_id); + let resolver = impl_id.resolver(db); - pub fn all_impls<'a>(&'a self) -> impl Iterator + 'a { - self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() - } + let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; - fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { - for impl_block in module.impl_blocks(db) { - let target_ty = impl_block.target_ty(db); - - if impl_block.target_trait(db).is_some() { - if let Some(tr) = impl_block.target_trait_ref(db) { - self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block); - } - } else { - if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { - self.impls.entry(target_ty_fp).or_default().push(impl_block); + match &impl_data.target_trait { + Some(trait_ref) => { + if let Some(tr) = + TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) + { + res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); + } + } + None => { + if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { + res.impls.entry(target_ty_fp).or_default().push(impl_id); + } + } } } } - for child in module.children(db) { - self.collect_recursive(db, child); - } + Arc::new(res) + } + pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator + '_ { + let fingerprint = TyFingerprint::for_impl(ty); + fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() + } + + pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator + '_ { + self.impls_by_trait.get(&tr.id).into_iter().flatten().copied() + } + + pub fn all_impls<'a>(&'a self) -> impl Iterator + 'a { + self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() } } @@ -279,14 +288,14 @@ fn iterate_inherent_methods( mut callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { for krate in def_crates(db, krate, &ty.value)? { - let impls = db.impls_in_crate(krate); + let impls = db.impls_in_crate(krate.crate_id); for impl_block in impls.lookup_impl_blocks(&ty.value) { - for item in impl_block.items(db) { + for &item in db.impl_data(impl_block).items.iter() { if !is_valid_candidate(db, name, mode, item) { continue; } - if let Some(result) = callback(&ty.value, item) { + if let Some(result) = callback(&ty.value, item.into()) { return Some(result); } } @@ -299,17 +308,17 @@ fn is_valid_candidate( db: &impl HirDatabase, name: Option<&Name>, mode: LookupMode, - item: AssocItem, + item: AssocItemId, ) -> bool { match item { - AssocItem::Function(m) => { - let data = db.function_data(m.id); - name.map_or(true, |name| data.name == *name) + AssocItemId::FunctionId(m) => { + let data = db.function_data(m); + name.map_or(true, |name| &data.name == name) && (data.has_self_param || mode == LookupMode::Path) } - AssocItem::Const(c) => { - name.map_or(true, |name| Some(name) == c.name(db).as_ref()) - && (mode == LookupMode::Path) + AssocItemId::ConstId(c) => { + let data = db.const_data(c); + name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path) } _ => false, } @@ -344,11 +353,11 @@ impl Ty { mut callback: impl FnMut(AssocItem) -> Option, ) -> Option { for krate in def_crates(db, krate, &self)? { - let impls = db.impls_in_crate(krate); + let impls = db.impls_in_crate(krate.crate_id); for impl_block in impls.lookup_impl_blocks(&self) { - for item in impl_block.items(db) { - if let Some(result) = callback(item) { + for &item in db.impl_data(impl_block).items.iter() { + if let Some(result) = callback(item.into()) { return Some(result); } } diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index eb7b5c4ef9..12dc965725 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs @@ -1,3 +1,3 @@ //! FIXME: write short doc here -pub use hir_ty::primitive::{FloatBitness, IntBitness, Signedness, FloatTy, IntTy, Uncertain}; +pub use hir_ty::primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}; diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index b9a5d651f4..2eeb030999 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -88,8 +88,8 @@ pub(crate) fn impls_for_trait_query( for dep in krate.dependencies(db) { impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); } - let crate_impl_blocks = db.impls_in_crate(krate); - impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); + let crate_impl_blocks = db.impls_in_crate(krate.crate_id); + impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); impls.into_iter().collect() } diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index 2b3100fc36..b3ebd91454 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use hir::{db::HirDatabase, ApplicationTy, FromSource, Ty, TypeCtor}; +use hir::{ApplicationTy, FromSource, ImplBlock, Ty, TypeCtor}; use ra_db::SourceDatabase; use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; @@ -56,11 +56,11 @@ fn impls_for_def( }; let krate = module.krate(); - let impls = db.impls_in_crate(krate); + let impls = ImplBlock::all_in_crate(db, krate); Some( impls - .all_impls() + .into_iter() .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) .map(|imp| imp.to_nav(db)) .collect(), @@ -77,9 +77,9 @@ fn impls_for_trait( let tr = hir::Trait::from_source(db, src)?; let krate = module.krate(); - let impls = db.impls_in_crate(krate); + let impls = ImplBlock::for_trait(db, krate, tr); - Some(impls.lookup_impl_blocks_for_trait(tr).map(|imp| imp.to_nav(db)).collect()) + Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect()) } fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { From 4e17718a9aaba34533ba6a46d52b4aa959c662c7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 15:40:55 +0300 Subject: [PATCH 23/65] Doc primitives --- crates/ra_hir_ty/src/lib.rs | 3 ++- crates/ra_hir_ty/src/primitive.rs | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 25bfc1d154..28859ba636 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -1,3 +1,4 @@ -//! FIXME: write short doc here +//! Work in Progress: everything related to types, type inference and trait +//! solving. pub mod primitive; diff --git a/crates/ra_hir_ty/src/primitive.rs b/crates/ra_hir_ty/src/primitive.rs index afa22448da..02a8179d94 100644 --- a/crates/ra_hir_ty/src/primitive.rs +++ b/crates/ra_hir_ty/src/primitive.rs @@ -1,4 +1,7 @@ -//! FIXME: write short doc here +//! Defines primitive types, which have a couple of peculiarities: +//! +//! * during type inference, they can be uncertain (ie, `let x = 92;`) +//! * they don't belong to any particular crate. use std::fmt; From 0623164c1d1ec461570c7d3d330d7c90fb00cf6e Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 26 Nov 2019 21:13:36 +0800 Subject: [PATCH 24/65] Remove dbg! --- crates/ra_hir/src/source_binder.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 287cea8808..144e144bbb 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -448,8 +448,6 @@ impl SourceAnalyzer { db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), ); let macro_call_loc = MacroCallLoc { def, ast_id }; - let kind = to_macro_file_kind(macro_call.value); - dbg!(kind); Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc), macro_file_kind: to_macro_file_kind(macro_call.value), From b81548c73a134cd63aefb9ceb20edb399bd3a16c Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Tue, 26 Nov 2019 08:20:40 -0500 Subject: [PATCH 25/65] Fix stale crates that snuck in --- Cargo.lock | 2 +- crates/ra_hir_ty/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c87cf8e54..1c61615049 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1048,7 +1048,7 @@ dependencies = [ "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ra_arena 0.1.0", "ra_db 0.1.0", "ra_hir_def 0.1.0", diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index 70216ab240..027b508657 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml @@ -10,7 +10,7 @@ doctest = false [dependencies] log = "0.4.5" rustc-hash = "1.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" ena = "0.13" ra_syntax = { path = "../ra_syntax" } From 4a0792362e2c6cae2809520da454471d5a917384 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 16:59:24 +0300 Subject: [PATCH 26/65] Detangle ty from traits a bit --- crates/ra_hir/src/code_model.rs | 53 +++-------------------- crates/ra_hir/src/ty.rs | 1 + crates/ra_hir/src/ty/lower.rs | 3 +- crates/ra_hir/src/ty/method_resolution.rs | 5 ++- crates/ra_hir/src/ty/utils.rs | 50 +++++++++++++++++++++ 5 files changed, 63 insertions(+), 49 deletions(-) create mode 100644 crates/ra_hir/src/ty/utils.rs diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 821f919d47..9930cff663 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -9,7 +9,7 @@ use hir_def::{ builtin_type::BuiltinType, docs::Documentation, per_ns::PerNs, - resolver::{HasResolver, TypeNs}, + resolver::HasResolver, type_ref::{Mutability, TypeRef}, AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, @@ -28,8 +28,8 @@ use crate::{ expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, ty::display::HirFormatter, ty::{ - self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, - TypeWalk, + self, utils::all_super_traits, InEnvironment, InferenceResult, Namespace, TraitEnvironment, + TraitRef, Ty, TypeCtor, TypeWalk, }, CallableDef, Either, HirDisplay, Name, Source, }; @@ -740,48 +740,6 @@ impl Trait { db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() } - fn direct_super_traits(self, db: &impl HirDatabase) -> Vec { - let resolver = self.id.resolver(db); - // returning the iterator directly doesn't easily work because of - // lifetime problems, but since there usually shouldn't be more than a - // few direct traits this should be fine (we could even use some kind of - // SmallVec if performance is a concern) - db.generic_params(self.id.into()) - .where_predicates - .iter() - .filter_map(|pred| match &pred.type_ref { - TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(), - _ => None, - }) - .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { - Some(TypeNs::TraitId(t)) => Some(t), - _ => None, - }) - .map(Trait::from) - .collect() - } - - /// Returns an iterator over the whole super trait hierarchy (including the - /// trait itself). - pub fn all_super_traits(self, db: &impl HirDatabase) -> Vec { - // we need to take care a bit here to avoid infinite loops in case of cycles - // (i.e. if we have `trait A: B; trait B: A;`) - let mut result = vec![self]; - let mut i = 0; - while i < result.len() { - let t = result[i]; - // yeah this is quadratic, but trait hierarchies should be flat - // enough that this doesn't matter - for tt in t.direct_super_traits(db) { - if !result.contains(&tt) { - result.push(tt); - } - } - i += 1; - } - result - } - pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option { let trait_data = db.trait_data(self.id); let res = @@ -794,7 +752,10 @@ impl Trait { db: &impl HirDatabase, name: &Name, ) -> Option { - self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) + all_super_traits(db, self.id) + .into_iter() + .map(Trait::from) + .find_map(|t| t.associated_type_by_name(db, name)) } pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index bd03055b93..2a2dc26b49 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -9,6 +9,7 @@ mod op; mod lower; mod infer; pub(crate) mod display; +pub(crate) mod utils; #[cfg(test)] mod tests; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 2d23890a58..9e3afabe0d 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -28,6 +28,7 @@ use crate::{ db::HirDatabase, ty::{ primitive::{FloatTy, IntTy}, + utils::all_super_traits, Adt, }, util::make_mut_slice, @@ -260,7 +261,7 @@ impl Ty { GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), _ => None, }); - let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); + let traits = traits_from_env.flat_map(|t| all_super_traits(db, t.id)).map(Trait::from); for t in traits { if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { let substs = Substs::build_for_def(db, t.id) diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 489fcd64b9..0e18684ed7 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -16,7 +16,7 @@ use rustc_hash::FxHashMap; use crate::{ db::HirDatabase, ty::primitive::{FloatBitness, Uncertain}, - ty::{Ty, TypeCtor}, + ty::{utils::all_super_traits, Ty, TypeCtor}, AssocItem, Crate, Function, Mutability, Name, Trait, }; @@ -249,7 +249,8 @@ fn iterate_trait_method_candidates( let traits_from_env = env .trait_predicates_for_self_ty(&ty.value) .map(|tr| tr.trait_) - .flat_map(|t| t.all_super_traits(db)); + .flat_map(|t| all_super_traits(db, t.id)) + .map(Trait::from); let traits = inherent_trait .chain(traits_from_env) .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs new file mode 100644 index 0000000000..345fa94300 --- /dev/null +++ b/crates/ra_hir/src/ty/utils.rs @@ -0,0 +1,50 @@ +use hir_def::{ + db::DefDatabase, + resolver::{HasResolver, TypeNs}, + type_ref::TypeRef, + TraitId, +}; +use hir_expand::name; + +// FIXME: this is wrong, b/c it can't express `trait T: PartialEq<()>`. +// We should return a `TraitREf` here. +fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { + let resolver = trait_.resolver(db); + // returning the iterator directly doesn't easily work because of + // lifetime problems, but since there usually shouldn't be more than a + // few direct traits this should be fine (we could even use some kind of + // SmallVec if performance is a concern) + db.generic_params(trait_.into()) + .where_predicates + .iter() + .filter_map(|pred| match &pred.type_ref { + TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(), + _ => None, + }) + .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { + Some(TypeNs::TraitId(t)) => Some(t), + _ => None, + }) + .collect() +} + +/// Returns an iterator over the whole super trait hierarchy (including the +/// trait itself). +pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { + // we need to take care a bit here to avoid infinite loops in case of cycles + // (i.e. if we have `trait A: B; trait B: A;`) + let mut result = vec![trait_]; + let mut i = 0; + while i < result.len() { + let t = result[i]; + // yeah this is quadratic, but trait hierarchies should be flat + // enough that this doesn't matter + for tt in direct_super_traits(db, t) { + if !result.contains(&tt) { + result.push(tt); + } + } + i += 1; + } + result +} From 9bc8f1f4f8d7bded19517205f8522a0110204f51 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 17:12:16 +0300 Subject: [PATCH 27/65] Store names in TraitData --- crates/ra_hir/src/code_model.rs | 7 +-- crates/ra_hir/src/ty/method_resolution.rs | 6 +-- crates/ra_hir_def/src/data.rs | 55 ++++++++++++++++------- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9930cff663..9e7a1deecc 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -737,14 +737,11 @@ impl Trait { } pub fn items(self, db: &impl DefDatabase) -> Vec { - db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() + db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() } pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option { - let trait_data = db.trait_data(self.id); - let res = - trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; - Some(res) + db.trait_data(self.id).associated_type_by_name(name).map(TypeAlias::from) } pub fn associated_type_by_name_including_super_traits( diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 0e18684ed7..9988570e83 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -261,8 +261,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.iter() { - if !is_valid_candidate(db, name, mode, item.into()) { + for (_name, item) in data.items.iter() { + if !is_valid_candidate(db, name, mode, (*item).into()) { continue; } if !known_implemented { @@ -272,7 +272,7 @@ fn iterate_trait_method_candidates( } } known_implemented = true; - if let Some(result) = callback(&ty.value, item.into()) { + if let Some(result) = callback(&ty.value, (*item).into()) { return Some(result); } } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 68bea34df7..813099a058 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -87,7 +87,7 @@ impl TypeAliasData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraitData { pub name: Option, - pub items: Vec, + pub items: Vec<(Name, AssocItemId)>, pub auto: bool, } @@ -97,28 +97,42 @@ impl TraitData { let name = src.value.name().map(|n| n.as_name()); let auto = src.value.is_auto(); let ast_id_map = db.ast_id_map(src.file_id); + + let container = ContainerId::TraitId(tr); 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) => FunctionLoc { - container: ContainerId::TraitId(tr), - ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + ast::ImplItem::FnDef(it) => { + let name = it.name().map(|it| it.as_name()).unwrap_or_else(Name::missing); + let def = FunctionLoc { + container, + ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + } + .intern(db) + .into(); + (name, def) } - .intern(db) - .into(), - ast::ImplItem::ConstDef(it) => ConstLoc { - container: ContainerId::TraitId(tr), - ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + ast::ImplItem::ConstDef(it) => { + let name = it.name().map(|it| it.as_name()).unwrap_or_else(Name::missing); + let def = ConstLoc { + container, + ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + } + .intern(db) + .into(); + (name, def) } - .intern(db) - .into(), - ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { - container: ContainerId::TraitId(tr), - ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + ast::ImplItem::TypeAliasDef(it) => { + let name = it.name().map(|it| it.as_name()).unwrap_or_else(Name::missing); + let def = TypeAliasLoc { + container, + ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + } + .intern(db) + .into(); + (name, def) } - .intern(db) - .into(), }) .collect() } else { @@ -128,11 +142,18 @@ impl TraitData { } pub fn associated_types(&self) -> impl Iterator + '_ { - self.items.iter().filter_map(|item| match item { + self.items.iter().filter_map(|(_name, item)| match item { AssocItemId::TypeAliasId(t) => Some(*t), _ => None, }) } + + pub fn associated_type_by_name(&self, name: &Name) -> Option { + self.items.iter().find_map(|(item_name, item)| match item { + AssocItemId::TypeAliasId(t) if item_name == name => Some(*t), + _ => None, + }) + } } #[derive(Debug, Clone, PartialEq, Eq)] From d118997b9318b750676a7fe5b8896219f98d9e6e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 17:21:29 +0300 Subject: [PATCH 28/65] Remove assoc_type_by_name helper --- crates/ra_hir/src/code_model.rs | 8 ++----- crates/ra_hir/src/ty/autoderef.rs | 10 ++++----- crates/ra_hir/src/ty/infer.rs | 14 ++++++------ crates/ra_hir/src/ty/lower.rs | 8 +++---- crates/ra_hir/src/ty/traits/chalk.rs | 33 ++++++++++++++-------------- 5 files changed, 34 insertions(+), 39 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9e7a1deecc..50e6409b1d 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -740,10 +740,6 @@ impl Trait { db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() } - pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option { - db.trait_data(self.id).associated_type_by_name(name).map(TypeAlias::from) - } - pub fn associated_type_by_name_including_super_traits( self, db: &impl HirDatabase, @@ -751,8 +747,8 @@ impl Trait { ) -> Option { all_super_traits(db, self.id) .into_iter() - .map(Trait::from) - .find_map(|t| t.associated_type_by_name(db, name)) + .find_map(|t| db.trait_data(t).associated_type_by_name(name)) + .map(TypeAlias::from) } pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 9e7593b8b0..ae68234aca 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -10,7 +10,7 @@ use hir_expand::name; use log::{info, warn}; use ra_db::CrateId; -use crate::{db::HirDatabase, Trait}; +use crate::db::HirDatabase; use super::{ traits::{InEnvironment, Solution}, @@ -49,12 +49,12 @@ fn deref_by_trait( ty: InEnvironment<&Canonical>, ) -> Option> { let deref_trait = match db.lang_item(krate.into(), "deref".into())? { - LangItemTarget::TraitId(t) => Trait::from(t), + LangItemTarget::TraitId(it) => it, _ => return None, }; - let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; + let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?; - let generic_params = db.generic_params(target.id.into()); + let generic_params = db.generic_params(target.into()); if generic_params.count_params_including_parent() != 1 { // the Target type + Deref trait should only have one generic parameter, // namely Deref's Self type @@ -69,7 +69,7 @@ fn deref_by_trait( let projection = super::traits::ProjectionPredicate { ty: Ty::Bound(0), - projection_ty: super::ProjectionTy { associated_ty: target.id, parameters }, + projection_ty: super::ProjectionTy { associated_ty: target, parameters }, }; let obligation = super::Obligation::Projection(projection); diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index fce45321df..b023ae6901 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -43,7 +43,7 @@ use crate::{ db::HirDatabase, expr::{BindingAnnotation, Body, ExprId, PatId}, ty::infer::diagnostics::InferenceDiagnostic, - Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, Trait, VariantDef, + Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, }; macro_rules! ty_app { @@ -582,20 +582,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { fn resolve_into_iter_item(&self) -> Option { let path = known::std_iter_into_iterator(); - let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); - trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) + let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE).map(TypeAlias::from) } fn resolve_ops_try_ok(&self) -> Option { let path = known::std_ops_try(); - let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); - trait_.associated_type_by_name(self.db, &name::OK_TYPE) + let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE).map(TypeAlias::from) } fn resolve_future_future_output(&self) -> Option { let path = known::std_future_future(); - let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); - trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) + let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE).map(TypeAlias::from) } fn resolve_boxed_box(&self) -> Option { diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 9e3afabe0d..0ac7920bbd 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -263,16 +263,14 @@ impl Ty { }); let traits = traits_from_env.flat_map(|t| all_super_traits(db, t.id)).map(Trait::from); for t in traits { - if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { + if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name) + { let substs = Substs::build_for_def(db, t.id) .push(self_ty.clone()) .fill_with_unknown() .build(); // FIXME handle type parameters on the segment - return Ty::Projection(ProjectionTy { - associated_ty: associated_ty.id, - parameters: substs, - }); + return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); } } Ty::Unknown diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 06388a3ce2..78f4b3e27e 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -9,7 +9,7 @@ use chalk_ir::{ }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; -use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TypeAliasId}; +use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId}; use hir_expand::name; use ra_db::salsa::{InternId, InternKey}; @@ -459,7 +459,7 @@ where [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() { if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) { - if trait_ == actual_trait { + if trait_.id == actual_trait { let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait }; result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db)); } @@ -661,6 +661,7 @@ fn impl_block_datum( }; let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses }; + let trait_data = db.trait_data(trait_.id); let associated_ty_value_ids = impl_block .items(db) .into_iter() @@ -670,7 +671,7 @@ fn impl_block_datum( }) .filter(|type_alias| { // don't include associated types that don't exist in the trait - trait_.associated_type_by_name(db, &type_alias.name(db)).is_some() + trait_data.associated_type_by_name(&type_alias.name(db)).is_some() }) .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) .collect(); @@ -713,7 +714,7 @@ fn closure_fn_trait_impl_datum( // and don't want to return a valid value only to find out later that FnOnce // is broken let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; - fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?; + let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name::OUTPUT_TYPE)?; let num_args: u16 = match &db.body(data.def.into())[data.expr] { crate::expr::Expr::Lambda { args, .. } => args.len() as u16, @@ -735,8 +736,8 @@ fn closure_fn_trait_impl_datum( let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty); let trait_ref = TraitRef { - trait_, - substs: Substs::build_for_def(db, trait_.id).push(self_ty).push(arg_ty).build(), + trait_: trait_.into(), + substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), }; let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db); @@ -783,10 +784,10 @@ fn type_alias_associated_ty_value( .target_trait_ref(db) .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved .trait_; - let assoc_ty = trait_ - .associated_type_by_name(db, &type_alias.name(db)) - .expect("assoc ty value should not exist") // validated when building the impl data as well - .id; + let assoc_ty = db + .trait_data(trait_.id) + .associated_type_by_name(&type_alias.name(db)) + .expect("assoc ty value should not exist"); // validated when building the impl data as well let generic_params = db.generic_params(impl_block.id.into()); let bound_vars = Substs::bound_vars(&generic_params); let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); @@ -819,10 +820,10 @@ fn closure_fn_trait_output_assoc_ty_value( let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist"); - let output_ty_id = fn_once_trait - .associated_type_by_name(db, &name::OUTPUT_TYPE) - .expect("assoc ty value should not exist") - .id; + let output_ty_id = db + .trait_data(fn_once_trait) + .associated_type_by_name(&name::OUTPUT_TYPE) + .expect("assoc ty value should not exist"); let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: output_ty.to_chalk(db) }; @@ -834,10 +835,10 @@ fn closure_fn_trait_output_assoc_ty_value( Arc::new(value) } -fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option { +fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option { let target = db.lang_item(krate.crate_id, fn_trait.lang_item_name().into())?; match target { - LangItemTarget::TraitId(t) => Some(t.into()), + LangItemTarget::TraitId(t) => Some(t), _ => None, } } From 25b32f9d68e9f01f2b92801f4b35daf2b8b250f7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 17:26:08 +0300 Subject: [PATCH 29/65] Doc --- crates/ra_hir/src/ty/utils.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs index 345fa94300..6728047873 100644 --- a/crates/ra_hir/src/ty/utils.rs +++ b/crates/ra_hir/src/ty/utils.rs @@ -1,3 +1,6 @@ +//! Helper functions for working with def, which don't need to be a separate +//! query, but can't be computed directly from `*Data` (ie, which need a `db`). + use hir_def::{ db::DefDatabase, resolver::{HasResolver, TypeNs}, From 24b1e79af51f5af76047a5eee2fe90baf100afca Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 17:42:21 +0300 Subject: [PATCH 30/65] Remove another helper --- crates/ra_hir/src/code_model.rs | 15 ++------------- crates/ra_hir/src/ty/lower.rs | 23 +++++++++++++---------- crates/ra_hir/src/ty/utils.rs | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 50e6409b1d..9578c20b08 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -28,8 +28,8 @@ use crate::{ expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, ty::display::HirFormatter, ty::{ - self, utils::all_super_traits, InEnvironment, InferenceResult, Namespace, TraitEnvironment, - TraitRef, Ty, TypeCtor, TypeWalk, + self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, + TypeWalk, }, CallableDef, Either, HirDisplay, Name, Source, }; @@ -740,17 +740,6 @@ impl Trait { db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() } - pub fn associated_type_by_name_including_super_traits( - self, - db: &impl HirDatabase, - name: &Name, - ) -> Option { - all_super_traits(db, self.id) - .into_iter() - .find_map(|t| db.trait_data(t).associated_type_by_name(name)) - .map(TypeAlias::from) - } - pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { TraitRef::for_trait(db, self) } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 0ac7920bbd..805a73ff5e 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -28,7 +28,7 @@ use crate::{ db::HirDatabase, ty::{ primitive::{FloatTy, IntTy}, - utils::all_super_traits, + utils::{all_super_traits, associated_type_by_name_including_super_traits}, Adt, }, util::make_mut_slice, @@ -170,14 +170,16 @@ impl Ty { ); return if remaining_segments.len() == 1 { let segment = &remaining_segments[0]; - match trait_ref - .trait_ - .associated_type_by_name_including_super_traits(db, &segment.name) - { + let associated_ty = associated_type_by_name_including_super_traits( + db, + trait_ref.trait_.id, + &segment.name, + ); + match associated_ty { Some(associated_ty) => { // FIXME handle type parameters on the segment Ty::Projection(ProjectionTy { - associated_ty: associated_ty.id, + associated_ty, parameters: trait_ref.substs, }) } @@ -508,10 +510,11 @@ fn assoc_type_bindings_from_type_bound<'a>( .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) .map(move |(name, type_ref)| { let associated_ty = - match trait_ref.trait_.associated_type_by_name_including_super_traits(db, &name) { - None => return GenericPredicate::Error, - Some(t) => t.id, - }; + associated_type_by_name_including_super_traits(db, trait_ref.trait_.id, &name); + let associated_ty = match associated_ty { + None => return GenericPredicate::Error, + Some(t) => t, + }; let projection_ty = ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; let ty = Ty::from_hir(db, resolver, type_ref); diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs index 6728047873..52994b9e34 100644 --- a/crates/ra_hir/src/ty/utils.rs +++ b/crates/ra_hir/src/ty/utils.rs @@ -5,9 +5,9 @@ use hir_def::{ db::DefDatabase, resolver::{HasResolver, TypeNs}, type_ref::TypeRef, - TraitId, + TraitId, TypeAliasId, }; -use hir_expand::name; +use hir_expand::name::{self, Name}; // FIXME: this is wrong, b/c it can't express `trait T: PartialEq<()>`. // We should return a `TraitREf` here. @@ -51,3 +51,13 @@ pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec Option { + all_super_traits(db, trait_) + .into_iter() + .find_map(|t| db.trait_data(t).associated_type_by_name(name)) +} From 72d8e7e69abca9f27fb3ea386a6879324741e152 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 18:00:36 +0300 Subject: [PATCH 31/65] Use TraitId in TraitRef --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/ty.rs | 13 +++--- crates/ra_hir/src/ty/infer/path.rs | 39 ++++++++++-------- crates/ra_hir/src/ty/lower.rs | 14 +++---- crates/ra_hir/src/ty/method_resolution.rs | 18 ++++---- crates/ra_hir/src/ty/traits/chalk.rs | 50 +++++++++++------------ 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9578c20b08..7b5d78543a 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -741,7 +741,7 @@ impl Trait { } pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { - TraitRef::for_trait(db, self) + TraitRef::for_trait(db, self.id) } pub fn is_auto(self, db: &impl DefDatabase) -> bool { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 2a2dc26b49..3711068faf 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -26,7 +26,7 @@ use ra_db::{impl_intern_key, salsa}; use crate::{ db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, - Name, Trait, Uncertain, + Name, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -445,7 +445,7 @@ impl Deref for Substs { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct TraitRef { /// FIXME name? - pub trait_: Trait, + pub trait_: TraitId, pub substs: Substs, } @@ -676,7 +676,7 @@ impl Ty { } /// If this is an `impl Trait` or `dyn Trait`, returns that trait. - pub fn inherent_trait(&self) -> Option { + pub fn inherent_trait(&self) -> Option { match self { Ty::Dyn(predicates) | Ty::Opaque(predicates) => { predicates.iter().find_map(|pred| match pred { @@ -988,7 +988,10 @@ impl HirDisplay for Ty { write!( f, "{}", - trait_ref.trait_.name(f.db).unwrap_or_else(Name::missing) + f.db.trait_data(trait_ref.trait_) + .name + .clone() + .unwrap_or_else(Name::missing) )?; if trait_ref.substs.len() > 1 { write!(f, "<")?; @@ -1049,7 +1052,7 @@ impl TraitRef { } else { write!(f, ": ")?; } - write!(f, "{}", self.trait_.name(f.db).unwrap_or_else(Name::missing))?; + write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?; if self.substs.len() > 1 { write!(f, "<")?; f.write_joined(&self.substs[1..], ", ")?; diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 6165eba4fc..202fff4f37 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -143,24 +143,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { id: ExprOrPatId, ) -> Option<(ValueNs, Option)> { let trait_ = trait_ref.trait_; - let item = trait_.items(self.db).iter().copied().find_map(|item| match item { - AssocItem::Function(func) => { - if segment.name == func.name(self.db) { - Some(AssocItem::Function(func)) - } else { - None - } - } + let item = + self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id).into()).find_map( + |item| match item { + AssocItem::Function(func) => { + if segment.name == func.name(self.db) { + Some(AssocItem::Function(func)) + } else { + None + } + } - AssocItem::Const(konst) => { - if konst.name(self.db).map_or(false, |n| n == segment.name) { - Some(AssocItem::Const(konst)) - } else { - None - } - } - AssocItem::TypeAlias(_) => None, - })?; + AssocItem::Const(konst) => { + if konst.name(self.db).map_or(false, |n| n == segment.name) { + Some(AssocItem::Const(konst)) + } else { + None + } + } + AssocItem::TypeAlias(_) => None, + }, + )?; let def = match item { AssocItem::Function(f) => ValueNs::FunctionId(f.id), AssocItem::Const(c) => ValueNs::ConstId(c.id), @@ -212,7 +215,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { .fill_with_params() .build(); self.obligations.push(super::Obligation::Trait(TraitRef { - trait_: t, + trait_: t.id, substs: trait_substs, })); Some(substs) diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 805a73ff5e..a7149614d4 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -15,7 +15,7 @@ use hir_def::{ resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, - Lookup, StructId, VariantId, + Lookup, StructId, TraitId, VariantId, }; use ra_arena::map::ArenaMap; use ra_db::CrateId; @@ -172,7 +172,7 @@ impl Ty { let segment = &remaining_segments[0]; let associated_ty = associated_type_by_name_including_super_traits( db, - trait_ref.trait_.id, + trait_ref.trait_, &segment.name, ); match associated_ty { @@ -263,7 +263,7 @@ impl Ty { GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), _ => None, }); - let traits = traits_from_env.flat_map(|t| all_super_traits(db, t.id)).map(Trait::from); + let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)).map(Trait::from); for t in traits { if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name) { @@ -423,7 +423,7 @@ impl TraitRef { if let Some(self_ty) = explicit_self_ty { make_mut_slice(&mut substs.0)[0] = self_ty; } - TraitRef { trait_: resolved, substs } + TraitRef { trait_: resolved.id, substs } } pub(crate) fn from_hir( @@ -450,8 +450,8 @@ impl TraitRef { substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param) } - pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { - let substs = Substs::identity(&db.generic_params(trait_.id.into())); + pub(crate) fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef { + let substs = Substs::identity(&db.generic_params(trait_.into())); TraitRef { trait_, substs } } @@ -510,7 +510,7 @@ fn assoc_type_bindings_from_type_bound<'a>( .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) .map(move |(name, type_ref)| { let associated_ty = - associated_type_by_name_including_super_traits(db, trait_ref.trait_.id, &name); + associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name); let associated_ty = match associated_ty { None => return GenericPredicate::Error, Some(t) => t, diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 9988570e83..f1bc638eec 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -68,7 +68,7 @@ impl CrateImplBlocks { if let Some(tr) = TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) { - res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); + res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); } } None => { @@ -249,13 +249,11 @@ fn iterate_trait_method_candidates( let traits_from_env = env .trait_predicates_for_self_ty(&ty.value) .map(|tr| tr.trait_) - .flat_map(|t| all_super_traits(db, t.id)) - .map(Trait::from); - let traits = inherent_trait - .chain(traits_from_env) - .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); + .flat_map(|t| all_super_traits(db, t)); + let traits = + inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter()); 'traits: for t in traits { - let data = db.trait_data(t.id); + let data = db.trait_data(t); // we'll be lazy about checking whether the type implements the // trait, but if we find out it doesn't, we'll skip the rest of the @@ -330,7 +328,7 @@ pub(crate) fn implements_trait( db: &impl HirDatabase, resolver: &Resolver, krate: Crate, - trait_: Trait, + trait_: TraitId, ) -> bool { if ty.value.inherent_trait() == Some(trait_) { // FIXME this is a bit of a hack, since Chalk should say the same thing @@ -373,11 +371,11 @@ impl Ty { fn generic_implements_goal( db: &impl HirDatabase, env: Arc, - trait_: Trait, + trait_: TraitId, self_ty: Canonical, ) -> Canonical> { let num_vars = self_ty.num_vars; - let substs = super::Substs::build_for_def(db, trait_.id) + let substs = super::Substs::build_for_def(db, trait_) .push(self_ty.value) .fill_with_bound_vars(num_vars as u32) .build(); diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 78f4b3e27e..02d37deadd 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -9,7 +9,9 @@ use chalk_ir::{ }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; -use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId}; +use hir_def::{ + lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, +}; use hir_expand::name; use ra_db::salsa::{InternId, InternKey}; @@ -19,7 +21,7 @@ use crate::{ db::HirDatabase, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - Crate, ImplBlock, Trait, TypeAlias, + Crate, ImplBlock, TypeAlias, }; /// This represents a trait whose name we could not resolve. @@ -167,15 +169,15 @@ impl ToChalk for TraitRef { } } -impl ToChalk for Trait { +impl ToChalk for TraitId { type Chalk = chalk_ir::TraitId; fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { - chalk_ir::TraitId(id_to_chalk(self.id)) + chalk_ir::TraitId(id_to_chalk(self)) } - fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait { - Trait { id: id_from_chalk(trait_id.0) } + fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId { + id_from_chalk(trait_id.0) } } @@ -443,10 +445,10 @@ where if trait_id == UNKNOWN_TRAIT { return Vec::new(); } - let trait_: Trait = from_chalk(self.db, trait_id); + let trait_: TraitId = from_chalk(self.db, trait_id); let mut result: Vec<_> = self .db - .impls_for_trait(self.krate, trait_) + .impls_for_trait(self.krate, trait_.into()) .iter() .copied() .map(Impl::ImplBlock) @@ -459,7 +461,7 @@ where [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() { if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) { - if trait_.id == actual_trait { + if trait_ == actual_trait { let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait }; result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db)); } @@ -516,7 +518,7 @@ pub(crate) fn associated_ty_data_query( where_clauses: vec![], }; let datum = AssociatedTyDatum { - trait_id: Trait::from(trait_).to_chalk(db), + trait_id: trait_.to_chalk(db), id, name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), binders: make_binders(bound_data, generic_params.count_params_including_parent()), @@ -548,29 +550,23 @@ pub(crate) fn trait_datum_query( associated_ty_ids: vec![], }); } - let trait_: Trait = from_chalk(db, trait_id); - debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); - let generic_params = db.generic_params(trait_.id.into()); + let trait_: TraitId = from_chalk(db, trait_id); + let trait_data = db.trait_data(trait_); + debug!("trait {:?} = {:?}", trait_id, trait_data.name); + let generic_params = db.generic_params(trait_.into()); let bound_vars = Substs::bound_vars(&generic_params); let flags = chalk_rust_ir::TraitFlags { - auto: trait_.is_auto(db), - upstream: trait_.module(db).krate() != krate, + auto: trait_data.auto, + upstream: trait_.module(db).krate != krate.crate_id, non_enumerable: true, coinductive: false, // only relevant for Chalk testing // FIXME set these flags correctly marker: false, fundamental: false, }; - let where_clauses = convert_where_clauses(db, trait_.id.into(), &bound_vars); - let associated_ty_ids = trait_ - .items(db) - .into_iter() - .filter_map(|trait_item| match trait_item { - crate::AssocItem::TypeAlias(type_alias) => Some(type_alias.id), - _ => None, - }) - .map(|type_alias| type_alias.to_chalk(db)) - .collect(); + let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); + let associated_ty_ids = + trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses }; let trait_datum = TraitDatum { id: trait_id, @@ -661,7 +657,7 @@ fn impl_block_datum( }; let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses }; - let trait_data = db.trait_data(trait_.id); + let trait_data = db.trait_data(trait_); let associated_ty_value_ids = impl_block .items(db) .into_iter() @@ -785,7 +781,7 @@ fn type_alias_associated_ty_value( .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved .trait_; let assoc_ty = db - .trait_data(trait_.id) + .trait_data(trait_) .associated_type_by_name(&type_alias.name(db)) .expect("assoc ty value should not exist"); // validated when building the impl data as well let generic_params = db.generic_params(impl_block.id.into()); From b60b26b8abc9d2bed46278c07415b7b39752040c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 18:02:50 +0300 Subject: [PATCH 32/65] Reduce visibility --- crates/ra_hir/src/ty/traits.rs | 5 +++-- crates/ra_hir/src/ty/utils.rs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 2eeb030999..a91c2476be 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,14 +2,15 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; -use hir_def::DefWithBodyId; +use hir_def::{expr::ExprId, DefWithBodyId}; use log::debug; use ra_db::{impl_intern_key, salsa}; use ra_prof::profile; use rustc_hash::FxHashSet; +use crate::{db::HirDatabase, Crate, ImplBlock, Trait, TypeAlias}; + use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; -use crate::{db::HirDatabase, expr::ExprId, Crate, ImplBlock, Trait, TypeAlias}; use self::chalk::{from_chalk, ToChalk}; diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs index 52994b9e34..80ffceb4bc 100644 --- a/crates/ra_hir/src/ty/utils.rs +++ b/crates/ra_hir/src/ty/utils.rs @@ -33,7 +33,7 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { /// Returns an iterator over the whole super trait hierarchy (including the /// trait itself). -pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { +pub(super) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { // we need to take care a bit here to avoid infinite loops in case of cycles // (i.e. if we have `trait A: B; trait B: A;`) let mut result = vec![trait_]; @@ -52,7 +52,7 @@ pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec Date: Tue, 26 Nov 2019 18:06:12 +0300 Subject: [PATCH 33/65] Cleanup imports --- crates/ra_hir/src/ty.rs | 10 ++++++---- crates/ra_hir/src/ty/lower.rs | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 3711068faf..e420c796f2 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -19,14 +19,16 @@ use std::sync::Arc; use std::{fmt, iter, mem}; use hir_def::{ - generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, - TraitId, TypeAliasId, + expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, + GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, }; use ra_db::{impl_intern_key, salsa}; use crate::{ - db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, - Name, Uncertain, + db::HirDatabase, + ty::primitive::{FloatTy, IntTy, Uncertain}, + util::make_mut_slice, + Adt, Crate, Name, }; use display::{HirDisplay, HirFormatter}; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index a7149614d4..c3c47a5766 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -29,10 +29,9 @@ use crate::{ ty::{ primitive::{FloatTy, IntTy}, utils::{all_super_traits, associated_type_by_name_including_super_traits}, - Adt, }, util::make_mut_slice, - Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, + Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, TypeAlias, Union, }; From 6fb4871f3149ab32e50052eb6a3bb29f852e6a6b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 19:30:57 +0300 Subject: [PATCH 34/65] Add note --- crates/ra_hir_def/src/resolver.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 95b3c926dc..c40f41717b 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -61,6 +61,8 @@ pub enum TypeNs { GenericParam(u32), AdtId(AdtId), AdtSelfType(AdtId), + // Yup, enum variants are added to the types ns, but any usage of variant as + // type is an error. EnumVariantId(EnumVariantId), TypeAliasId(TypeAliasId), BuiltinType(BuiltinType), From 447268ceac497432822e8cf28525a6784f392020 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 27 Nov 2019 01:33:08 +0800 Subject: [PATCH 35/65] Hide MacroCallLoc --- crates/ra_hir/src/source_binder.rs | 6 ++---- crates/ra_hir_def/src/body.rs | 5 ++--- crates/ra_hir_def/src/nameres/collector.rs | 7 +++---- crates/ra_hir_expand/src/lib.rs | 14 ++++++++++++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 82cb665830..7c4ebd4b4f 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -14,8 +14,7 @@ use hir_def::{ DefWithBodyId, }; use hir_expand::{ - hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, - Source, + hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, }; use ra_syntax::{ ast::{self, AstNode}, @@ -451,9 +450,8 @@ impl SourceAnalyzer { 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), + macro_call_id: def.as_call_id(db, ast_id), macro_file_kind: to_macro_file_kind(macro_call.value), }) } diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index d77ccb272a..78a532bdd6 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -6,8 +6,7 @@ pub mod scope; use std::{ops::Index, sync::Arc}; use hir_expand::{ - either::Either, hygiene::Hygiene, AstId, HirFileId, MacroCallLoc, MacroDefId, MacroFileKind, - Source, + either::Either, hygiene::Hygiene, AstId, HirFileId, MacroDefId, MacroFileKind, Source, }; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstNode, AstPtr}; @@ -47,7 +46,7 @@ impl Expander { if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { if let Some(def) = self.resolve_path_as_macro(db, &path) { - let call_id = db.intern_macro(MacroCallLoc { def, ast_id }); + let call_id = def.as_call_id(db, ast_id); let file_id = call_id.as_file(MacroFileKind::Expr); if let Some(node) = db.parse_or_expand(file_id) { if let Some(expr) = ast::Expr::cast(node) { diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 4ff6f72cfb..ea3abfdae2 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -6,7 +6,7 @@ use hir_expand::{ builtin_macro::find_builtin_macro, name::{self, AsName, Name}, - HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, MacroFileKind, + HirFileId, MacroCallId, MacroDefId, MacroDefKind, MacroFileKind, }; use ra_cfg::CfgOptions; use ra_db::{CrateId, FileId}; @@ -480,7 +480,7 @@ where ); if let Some(def) = resolved_res.resolved_def.take_macros() { - let call_id = self.db.intern_macro(MacroCallLoc { def, ast_id: *ast_id }); + let call_id = def.as_call_id(self.db, *ast_id); resolved.push((*module_id, call_id, def)); res = ReachedFixedPoint::No; return false; @@ -773,8 +773,7 @@ where if let Some(macro_def) = mac.path.as_ident().and_then(|name| { self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) }) { - let macro_call_id = - self.def_collector.db.intern_macro(MacroCallLoc { def: macro_def, ast_id }); + let macro_call_id = macro_def.as_call_id(self.def_collector.db, ast_id); self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_def); return; diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 4f3ccf1d0d..b6a739cda5 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -135,6 +135,16 @@ pub struct MacroDefId { pub kind: MacroDefKind, } +impl MacroDefId { + pub fn as_call_id( + self, + db: &dyn db::AstDatabase, + ast_id: AstId, + ) -> MacroCallId { + db.intern_macro(MacroCallLoc { def: self, ast_id }) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum MacroDefKind { Declarative, @@ -143,8 +153,8 @@ pub enum MacroDefKind { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct MacroCallLoc { - pub def: MacroDefId, - pub ast_id: AstId, + pub(crate) def: MacroDefId, + pub(crate) ast_id: AstId, } impl MacroCallId { From 4e415a269e2d821f31963c05843517c6fde0132d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 21:04:24 +0300 Subject: [PATCH 36/65] Remove ns-polymorphic type_for_def --- crates/ra_hir/src/code_model.rs | 15 +-- crates/ra_hir/src/db.rs | 11 +- crates/ra_hir/src/ty.rs | 4 +- crates/ra_hir/src/ty/infer.rs | 53 +++----- crates/ra_hir/src/ty/infer/expr.rs | 10 +- crates/ra_hir/src/ty/infer/path.rs | 7 +- crates/ra_hir/src/ty/lower.rs | 189 +++++++++++++-------------- crates/ra_hir/src/ty/traits/chalk.rs | 2 +- crates/ra_ide_api/src/change.rs | 3 +- 9 files changed, 129 insertions(+), 165 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 7b5d78543a..c5cf39ee1a 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -28,8 +28,7 @@ use crate::{ expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, ty::display::HirFormatter, ty::{ - self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, - TypeWalk, + self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, }, CallableDef, Either, HirDisplay, Name, Source, }; @@ -354,11 +353,11 @@ impl Struct { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Values) + db.value_ty(self.id.into()) } fn variant_data(self, db: &impl DefDatabase) -> Arc { @@ -381,7 +380,7 @@ impl Union { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } pub fn fields(self, db: &impl HirDatabase) -> Vec { @@ -442,7 +441,7 @@ impl Enum { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } } @@ -617,7 +616,7 @@ impl Function { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Values) + db.value_ty(self.id.into()) } pub fn infer(self, db: &impl HirDatabase) -> Arc { @@ -797,7 +796,7 @@ impl TypeAlias { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } pub fn name(self, db: &impl DefDatabase) -> Name { diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 32f05a4d8b..3b5aa75161 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -9,8 +9,8 @@ use crate::{ ty::{ method_resolution::CrateImplBlocks, traits::{AssocTyValue, Impl}, - CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, - TypeCtor, + CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, + ValueTyDefId, }, Crate, DefWithBody, ImplBlock, Trait, }; @@ -37,8 +37,11 @@ pub trait HirDatabase: DefDatabase { #[salsa::invoke(crate::ty::infer_query)] fn infer(&self, def: DefWithBody) -> Arc; - #[salsa::invoke(crate::ty::type_for_def)] - fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; + #[salsa::invoke(crate::ty::ty_query)] + fn ty(&self, def: TyDefId) -> Ty; + + #[salsa::invoke(crate::ty::value_ty_query)] + fn value_ty(&self, def: ValueTyDefId) -> Ty; #[salsa::invoke(crate::ty::field_types_query)] fn field_types(&self, var: VariantId) -> Arc>; diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index e420c796f2..680ddc2f9c 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -37,8 +37,8 @@ pub(crate) use infer::{infer_query, InferTy, InferenceResult}; pub use lower::CallableDef; pub(crate) use lower::{ callable_item_sig, field_types_query, generic_defaults_query, - generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace, - TypableDef, + generic_predicates_for_param_query, generic_predicates_query, ty_query, value_ty_query, + TyDefId, TypableDef, ValueTyDefId, }; pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index b023ae6901..beb2efb7aa 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -35,15 +35,15 @@ use test_utils::tested_by; use super::{ traits::{Guidance, Obligation, ProjectionPredicate, Solution}, - ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, - TypeCtor, TypeWalk, Uncertain, + ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, + TypeWalk, Uncertain, }; use crate::{ code_model::TypeAlias, db::HirDatabase, expr::{BindingAnnotation, Body, ExprId, PatId}, ty::infer::diagnostics::InferenceDiagnostic, - Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, + AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, }; macro_rules! ty_app { @@ -520,45 +520,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { None => return (Ty::Unknown, None), }; let resolver = &self.resolver; - let def: TypableDef = - // FIXME: this should resolve assoc items as well, see this example: - // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 - match resolver.resolve_path_in_type_ns_fully(self.db, &path) { - Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), - Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), - Some(TypeNs::AdtSelfType(adt)) => adt.into(), - Some(TypeNs::EnumVariantId(it)) => it.into(), - Some(TypeNs::TypeAliasId(it)) => it.into(), - - Some(TypeNs::SelfType(_)) | - Some(TypeNs::GenericParam(_)) | - Some(TypeNs::BuiltinType(_)) | - Some(TypeNs::TraitId(_)) | - Some(TypeNs::AdtId(AdtId::EnumId(_))) | - None => { - return (Ty::Unknown, None) - } - }; - // FIXME remove the duplication between here and `Ty::from_path`? - let substs = Ty::substs_from_path(self.db, resolver, path, def); - match def { - TypableDef::Adt(Adt::Struct(s)) => { - let ty = s.ty(self.db); + // FIXME: this should resolve assoc items as well, see this example: + // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 + match resolver.resolve_path_in_type_ns_fully(self.db, &path) { + Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { + let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); + let ty = self.db.ty(strukt.into()); let ty = self.insert_type_vars(ty.apply_substs(substs)); - (ty, Some(s.into())) + (ty, Some(VariantDef::Struct(strukt.into()))) } - TypableDef::EnumVariant(var) => { - let ty = var.parent_enum(self.db).ty(self.db); + Some(TypeNs::EnumVariantId(var)) => { + let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); + let ty = self.db.ty(var.parent.into()); let ty = self.insert_type_vars(ty.apply_substs(substs)); - (ty, Some(var.into())) + (ty, Some(VariantDef::EnumVariant(var.into()))) } - TypableDef::Adt(Adt::Enum(_)) - | TypableDef::Adt(Adt::Union(_)) - | TypableDef::TypeAlias(_) - | TypableDef::Function(_) - | TypableDef::Const(_) - | TypableDef::Static(_) - | TypableDef::BuiltinType(_) => (Ty::Unknown, None), + Some(_) | None => (Ty::Unknown, None), } } diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 3d0895dc61..eb221d6bc8 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -17,8 +17,8 @@ use crate::{ expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, ty::{ autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, - Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, - TypeCtor, TypeWalk, Uncertain, + Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, + TypeWalk, Uncertain, }, Name, }; @@ -558,11 +558,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Some((ty, func)) => { let ty = canonicalized_receiver.decanonicalize_ty(ty); self.write_method_resolution(tgt_expr, func); - ( - ty, - self.db.type_for_def(func.into(), Namespace::Values), - Some(self.db.generic_params(func.id.into())), - ) + (ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into()))) } None => (receiver_ty, Ty::Unknown, None), }; diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 202fff4f37..be2067dd4d 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -7,7 +7,7 @@ use hir_def::{ use crate::{ db::HirDatabase, - ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, + ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}, AssocItem, Container, Function, Name, Path, }; @@ -56,7 +56,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } }; - let typable: TypableDef = match value { + let typable: ValueTyDefId = match value { ValueNs::LocalBinding(pat) => { let ty = self.result.type_of_pat.get(pat)?.clone(); let ty = self.resolve_ty_as_possible(&mut vec![], ty); @@ -69,11 +69,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ValueNs::EnumVariantId(it) => it.into(), }; - let mut ty = self.db.type_for_def(typable, Namespace::Values); + let mut ty = self.db.value_ty(typable); if let Some(self_subst) = self_subst { ty = ty.subst(&self_subst); } - let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); let ty = ty.subst(&substs); Some(ty) diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index c3c47a5766..709492d217 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -14,8 +14,8 @@ use hir_def::{ path::{GenericArg, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, - Lookup, StructId, TraitId, VariantId, + AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, + LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, }; use ra_arena::map::ArenaMap; use ra_db::CrateId; @@ -35,17 +35,6 @@ use crate::{ TypeAlias, Union, }; -// FIXME: this is only really used in `type_for_def`, which contains a bunch of -// impossible cases. Perhaps we should recombine `TypeableDef` and `Namespace` -// into a `AsTypeDef`, `AsValueDef` enums? -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum Namespace { - Types, - Values, - // Note that only type inference uses this enum, and it doesn't care about macros. - // Macro, -} - impl Ty { pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { match type_ref { @@ -281,27 +270,15 @@ impl Ty { db: &impl HirDatabase, resolver: &Resolver, segment: &PathSegment, - typable: TypableDef, + typable: TyDefId, ) -> Ty { - let ty = db.type_for_def(typable, Namespace::Types); - let substs = Ty::substs_from_path_segment(db, resolver, segment, typable); - ty.subst(&substs) - } - - pub(super) fn substs_from_path_segment( - db: &impl HirDatabase, - resolver: &Resolver, - segment: &PathSegment, - resolved: TypableDef, - ) -> Substs { - let def_generic: Option = match resolved { - TypableDef::Function(func) => Some(func.id.into()), - TypableDef::Adt(adt) => Some(adt.into()), - TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()), - TypableDef::TypeAlias(t) => Some(t.id.into()), - TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, + let generic_def = match typable { + TyDefId::BuiltinType(_) => None, + TyDefId::AdtId(it) => Some(it.into()), + TyDefId::TypeAliasId(it) => Some(it.into()), }; - substs_from_path_segment(db, resolver, segment, def_generic, false) + let substs = substs_from_path_segment(db, resolver, segment, generic_def, false); + db.ty(typable).subst(&substs) } /// Collect generic arguments from a path into a `Substs`. See also @@ -310,17 +287,18 @@ impl Ty { db: &impl HirDatabase, resolver: &Resolver, path: &Path, - resolved: TypableDef, + // Note that we don't call `db.value_type(resolved)` here, + // `ValueTyDefId` is just a convenient way to pass generics and + // special-case enum variants + resolved: ValueTyDefId, ) -> Substs { let last = path.segments.last().expect("path should have at least one segment"); - let segment = match resolved { - TypableDef::Function(_) - | TypableDef::Adt(_) - | TypableDef::Const(_) - | TypableDef::Static(_) - | TypableDef::TypeAlias(_) - | TypableDef::BuiltinType(_) => last, - TypableDef::EnumVariant(_) => { + let (segment, generic_def) = match resolved { + ValueTyDefId::FunctionId(it) => (last, Some(it.into())), + ValueTyDefId::StructId(it) => (last, Some(it.into())), + ValueTyDefId::ConstId(it) => (last, Some(it.into())), + ValueTyDefId::StaticId(_) => (last, None), + ValueTyDefId::EnumVariantId(var) => { // the generic args for an enum variant may be either specified // on the segment referring to the enum, or on the segment // referring to the variant. So `Option::::None` and @@ -334,10 +312,10 @@ impl Ty { // Option::None:: last }; - segment + (segment, Some(var.parent.into())) } }; - Ty::substs_from_path_segment(db, resolver, segment, resolved) + substs_from_path_segment(db, resolver, segment, generic_def, false) } } @@ -522,33 +500,6 @@ fn assoc_type_bindings_from_type_bound<'a>( }) } -/// Build the declared type of an item. This depends on the namespace; e.g. for -/// `struct Foo(usize)`, we have two types: The type of the struct itself, and -/// the constructor function `(usize) -> Foo` which lives in the values -/// namespace. -pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty { - match (def, ns) { - (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f), - (TypableDef::Adt(Adt::Struct(s)), Namespace::Values) => type_for_struct_constructor(db, s), - (TypableDef::Adt(adt), Namespace::Types) => type_for_adt(db, adt), - (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v), - (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t), - (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c), - (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c), - (TypableDef::BuiltinType(t), Namespace::Types) => type_for_builtin(t), - - // 'error' cases: - (TypableDef::Function(_), Namespace::Types) => Ty::Unknown, - (TypableDef::Adt(Adt::Union(_)), Namespace::Values) => Ty::Unknown, - (TypableDef::Adt(Adt::Enum(_)), Namespace::Values) => Ty::Unknown, - (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown, - (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown, - (TypableDef::Const(_), Namespace::Types) => Ty::Unknown, - (TypableDef::Static(_), Namespace::Types) => Ty::Unknown, - (TypableDef::BuiltinType(_), Namespace::Values) => Ty::Unknown, - } -} - /// Build the signature of a callable item (function, struct or enum variant). pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { match def { @@ -647,24 +598,24 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { /// Build the declared type of a function. This should not need to look at the /// function body. -fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { - let generics = db.generic_params(def.id.into()); +fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { + let generics = db.generic_params(def.into()); let substs = Substs::identity(&generics); - Ty::apply(TypeCtor::FnDef(def.id.into()), substs) + Ty::apply(TypeCtor::FnDef(def.into()), substs) } /// Build the declared type of a const. -fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { - let data = db.const_data(def.id); - let resolver = def.id.resolver(db); +fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { + let data = db.const_data(def); + let resolver = def.resolver(db); Ty::from_hir(db, &resolver, &data.type_ref) } /// Build the declared type of a static. -fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { - let data = db.static_data(def.id); - let resolver = def.id.resolver(db); +fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { + let data = db.static_data(def); + let resolver = def.resolver(db); Ty::from_hir(db, &resolver, &data.type_ref) } @@ -688,19 +639,19 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig .iter() .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) .collect::>(); - let ret = type_for_adt(db, Struct::from(def)); + let ret = type_for_adt(db, def.into()); FnSig::from_params_and_return(params, ret) } /// Build the type of a tuple struct constructor. -fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { - let struct_data = db.struct_data(def.id.into()); +fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { + let struct_data = db.struct_data(def.into()); if struct_data.variant_data.is_unit() { - return type_for_adt(db, def); // Unit struct + return type_for_adt(db, def.into()); // Unit struct } - let generics = db.generic_params(def.id.into()); + let generics = db.generic_params(def.into()); let substs = Substs::identity(&generics); - Ty::apply(TypeCtor::FnDef(def.id.into()), substs) + Ty::apply(TypeCtor::FnDef(def.into()), substs) } fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { @@ -714,34 +665,33 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId .collect::>(); let generics = db.generic_params(def.parent.into()); let substs = Substs::identity(&generics); - let ret = type_for_adt(db, Enum::from(def.parent)).subst(&substs); + let ret = type_for_adt(db, def.parent.into()).subst(&substs); FnSig::from_params_and_return(params, ret) } /// Build the type of a tuple enum variant constructor. -fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { - let var_data = def.variant_data(db); +fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { + let enum_data = db.enum_data(def.parent); + let var_data = &enum_data.variants[def.local_id].variant_data; if var_data.is_unit() { - return type_for_adt(db, def.parent_enum(db)); // Unit variant + return type_for_adt(db, def.parent.into()); // Unit variant } - let generics = db.generic_params(def.parent_enum(db).id.into()); + let generics = db.generic_params(def.parent.into()); let substs = Substs::identity(&generics); Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) } -fn type_for_adt(db: &impl HirDatabase, adt: impl Into) -> Ty { - let adt = adt.into(); - let adt_id: AdtId = adt.into(); - let generics = db.generic_params(adt_id.into()); - Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics)) +fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { + let generics = db.generic_params(adt.into()); + Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) } -fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { - let generics = db.generic_params(t.id.into()); - let resolver = t.id.resolver(db); - let type_ref = t.type_ref(db); +fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { + let generics = db.generic_params(t.into()); + let resolver = t.resolver(db); + let type_ref = &db.type_alias_data(t).type_ref; let substs = Substs::identity(&generics); - let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); + let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error)); inner.subst(&substs) } @@ -808,3 +758,42 @@ impl From for GenericDefId { } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum TyDefId { + BuiltinType(BuiltinType), + AdtId(AdtId), + TypeAliasId(TypeAliasId), +} +impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ValueTyDefId { + FunctionId(FunctionId), + StructId(StructId), + EnumVariantId(EnumVariantId), + ConstId(ConstId), + StaticId(StaticId), +} +impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId); + +/// Build the declared type of an item. This depends on the namespace; e.g. for +/// `struct Foo(usize)`, we have two types: The type of the struct itself, and +/// the constructor function `(usize) -> Foo` which lives in the values +/// namespace. +pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { + match def { + TyDefId::BuiltinType(it) => type_for_builtin(it), + TyDefId::AdtId(it) => type_for_adt(db, it), + TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), + } +} +pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { + match def { + ValueTyDefId::FunctionId(it) => type_for_fn(db, it), + ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), + ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), + ValueTyDefId::ConstId(it) => type_for_const(db, it), + ValueTyDefId::StaticId(it) => type_for_static(db, it), + } +} diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 02d37deadd..4b0f4f56c2 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -786,7 +786,7 @@ fn type_alias_associated_ty_value( .expect("assoc ty value should not exist"); // validated when building the impl data as well let generic_params = db.generic_params(impl_block.id.into()); let bound_vars = Substs::bound_vars(&generic_params); - let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); + let ty = db.ty(type_alias.id.into()).subst(&bound_vars); let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; let value = chalk_rust_ir::AssociatedTyValue { impl_id, diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 84340aff8c..4a76d1dd83 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs @@ -323,7 +323,8 @@ impl RootDatabase { hir::db::DocumentationQuery hir::db::ExprScopesQuery hir::db::InferQuery - hir::db::TypeForDefQuery + hir::db::TyQuery + hir::db::ValueTyQuery hir::db::FieldTypesQuery hir::db::CallableItemSignatureQuery hir::db::GenericPredicatesQuery From 882fe0a47ee6f60928395326d1f194eec521ce2e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 21:18:26 +0300 Subject: [PATCH 37/65] More precise NameKind::Self --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_ide_api/src/goto_definition.rs | 23 ++--- crates/ra_ide_api/src/hover.rs | 91 +++++++++---------- crates/ra_ide_api/src/references.rs | 5 +- crates/ra_ide_api/src/references/classify.rs | 3 +- .../src/references/name_definition.rs | 6 +- 6 files changed, 61 insertions(+), 69 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index c5cf39ee1a..0edcdb1771 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -982,7 +982,7 @@ impl ImplBlock { } } -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct Type { pub(crate) krate: CrateId, pub(crate) ty: InEnvironment, diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index b6c72efdff..c10a6c8448 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -71,10 +71,11 @@ pub(crate) fn reference_definition( Some(nav) => return Exact(nav), None => return Approximate(vec![]), }, - Some(SelfType(ty)) => { - if let Some((adt, _)) = ty.as_adt() { - return Exact(adt.to_nav(db)); - } + Some(SelfType(imp)) => { + // FIXME: ideally, this should point to the type in the impl, and + // not at the whole impl. And goto **type** definition should bring + // us to the actual type + return Exact(imp.to_nav(db)); } Some(Local(local)) => return Exact(local.to_nav(db)), Some(GenericParam(_)) => { @@ -503,7 +504,7 @@ mod tests { } } ", - "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", + "impl IMPL_BLOCK FileId(1) [12; 73)", ); check_goto( @@ -516,7 +517,7 @@ mod tests { } } ", - "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", + "impl IMPL_BLOCK FileId(1) [12; 73)", ); check_goto( @@ -529,7 +530,7 @@ mod tests { } } ", - "Foo ENUM_DEF FileId(1) [0; 14) [5; 8)", + "impl IMPL_BLOCK FileId(1) [15; 75)", ); check_goto( @@ -541,7 +542,7 @@ mod tests { } } ", - "Foo ENUM_DEF FileId(1) [0; 14) [5; 8)", + "impl IMPL_BLOCK FileId(1) [15; 62)", ); } @@ -560,7 +561,7 @@ mod tests { } } ", - "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", + "impl IMPL_BLOCK FileId(1) [49; 115)", ); check_goto( @@ -572,11 +573,11 @@ mod tests { } impl Make for Foo { fn new() -> Self<|> { - Self{} + Self {} } } ", - "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", + "impl IMPL_BLOCK FileId(1) [49; 115)", ); } diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 9839be985f..260a7b8694 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -133,20 +133,12 @@ fn hover_text_from_name_kind( hir::ModuleDef::TypeAlias(it) => from_def_source(db, it), hir::ModuleDef::BuiltinType(it) => Some(it.to_string()), }, - SelfType(ty) => match ty.as_adt() { - Some((adt_def, _)) => match adt_def { - hir::Adt::Struct(it) => from_def_source(db, it), - hir::Adt::Union(it) => from_def_source(db, it), - hir::Adt::Enum(it) => from_def_source(db, it), - }, - _ => None, - }, Local(_) => { // Hover for these shows type names *no_fallback = true; None } - GenericParam(_) => { + GenericParam(_) | SelfType(_) => { // FIXME: Hover for generic param None } @@ -622,49 +614,52 @@ fn func(foo: i32) { if true { <|>foo; }; } ", ); let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup_opt(hover.info.first()), Some("struct Thing")); + assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); assert_eq!(hover.info.is_exact(), true); - let (analysis, position) = single_file_with_position( - " - struct Thing { x: u32 } - impl Thing { - fn new() -> Self<|> { - Self { x: 0 } - } - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup_opt(hover.info.first()), Some("struct Thing")); - assert_eq!(hover.info.is_exact(), true); + /* FIXME: revive these tests + let (analysis, position) = single_file_with_position( + " + struct Thing { x: u32 } + impl Thing { + fn new() -> Self<|> { + Self { x: 0 } + } + } + ", + ); - let (analysis, position) = single_file_with_position( - " - enum Thing { A } - impl Thing { - pub fn new() -> Self<|> { - Thing::A - } - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); - assert_eq!(hover.info.is_exact(), true); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); + assert_eq!(hover.info.is_exact(), true); - let (analysis, position) = single_file_with_position( - " - enum Thing { A } - impl Thing { - pub fn thing(a: Self<|>) { - } - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); - assert_eq!(hover.info.is_exact(), true); + let (analysis, position) = single_file_with_position( + " + enum Thing { A } + impl Thing { + pub fn new() -> Self<|> { + Thing::A + } + } + ", + ); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); + assert_eq!(hover.info.is_exact(), true); + + let (analysis, position) = single_file_with_position( + " + enum Thing { A } + impl Thing { + pub fn thing(a: Self<|>) { + } + } + ", + ); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); + assert_eq!(hover.info.is_exact(), true); + */ } #[test] diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index cb343e59a0..21a1ea69eb 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs @@ -83,10 +83,7 @@ pub(crate) fn find_all_refs( NameKind::Field(field) => field.to_nav(db), NameKind::AssocItem(assoc) => assoc.to_nav(db), NameKind::Def(def) => NavigationTarget::from_def(db, def)?, - NameKind::SelfType(ref ty) => match ty.as_adt() { - Some((adt, _)) => adt.to_nav(db), - None => return None, - }, + NameKind::SelfType(imp) => imp.to_nav(db), NameKind::Local(local) => local.to_nav(db), NameKind::GenericParam(_) => return None, }; diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs index 227737ad24..5cea805ec9 100644 --- a/crates/ra_ide_api/src/references/classify.rs +++ b/crates/ra_ide_api/src/references/classify.rs @@ -178,8 +178,7 @@ pub(crate) fn classify_name_ref( Some(NameDefinition { kind, container, visibility }) } PathResolution::SelfType(impl_block) => { - let ty = impl_block.target_ty(db); - let kind = NameKind::SelfType(ty); + let kind = NameKind::SelfType(impl_block); let container = impl_block.module(db); Some(NameDefinition { kind, container, visibility }) } diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs index cf12db066a..10d3a2364c 100644 --- a/crates/ra_ide_api/src/references/name_definition.rs +++ b/crates/ra_ide_api/src/references/name_definition.rs @@ -4,8 +4,8 @@ //! Note that the reference search is possible for not all of the classified items. use hir::{ - Adt, AssocItem, GenericParam, HasSource, Local, MacroDef, Module, ModuleDef, StructField, Ty, - VariantDef, + Adt, AssocItem, GenericParam, HasSource, ImplBlock, Local, MacroDef, Module, ModuleDef, + StructField, VariantDef, }; use ra_syntax::{ast, ast::VisibilityOwner}; @@ -17,7 +17,7 @@ pub enum NameKind { Field(StructField), AssocItem(AssocItem), Def(ModuleDef), - SelfType(Ty), + SelfType(ImplBlock), Local(Local), GenericParam(GenericParam), } From 936c6950e78d073f54c9ba66795f7f6f3abb351b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 21:25:17 +0300 Subject: [PATCH 38/65] Remove last traces of adt from Ty --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/expr.rs | 4 ++-- crates/ra_hir/src/ty.rs | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 0edcdb1771..a842dfed6d 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -1104,7 +1104,7 @@ impl Type { pub fn as_adt(&self) -> Option { let (adt, _subst) = self.ty.value.as_adt()?; - Some(adt) + Some(adt.into()) } fn derived(&self, ty: Ty) -> Type { diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index adb9805ab8..5c82c23d6c 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -12,7 +12,7 @@ use crate::{ db::HirDatabase, diagnostics::{MissingFields, MissingOkInTailExpr}, ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, - Adt, Function, Name, Path, + Function, Name, Path, Struct, }; pub use hir_def::{ @@ -69,7 +69,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { } let struct_def = match self.infer[id].as_adt() { - Some((Adt::Struct(s), _)) => s, + Some((AdtId::StructId(s), _)) => Struct::from(s), _ => return, }; diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 680ddc2f9c..791b6064ac 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -22,13 +22,14 @@ use hir_def::{ expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, }; +use hir_expand::name::Name; use ra_db::{impl_intern_key, salsa}; use crate::{ db::HirDatabase, ty::primitive::{FloatTy, IntTy, Uncertain}, util::make_mut_slice, - Adt, Crate, Name, + Crate, }; use display::{HirDisplay, HirFormatter}; @@ -598,10 +599,10 @@ impl Ty { } } - pub fn as_adt(&self) -> Option<(Adt, &Substs)> { + pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { match self { Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { - Some(((*adt_def).into(), parameters)) + Some((*adt_def, parameters)) } _ => None, } From cace49e9a79a5fe44cda63964412c5bdce7ee90d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 22:26:47 +0300 Subject: [PATCH 39/65] Decouple --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/db.rs | 21 +++++------ crates/ra_hir/src/ty/method_resolution.rs | 46 +++++++++++------------ crates/ra_hir/src/ty/traits.rs | 16 ++++---- crates/ra_hir/src/ty/traits/chalk.rs | 2 +- 5 files changed, 42 insertions(+), 45 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a842dfed6d..b4b47057de 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -945,7 +945,7 @@ impl ImplBlock { } pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec { let impls = db.impls_in_crate(krate.crate_id); - impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect() + impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() } pub fn target_trait(&self, db: &impl DefDatabase) -> Option { diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 3b5aa75161..31b21ca840 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use hir_def::{GenericDefId, LocalStructFieldId, TraitId, VariantId}; use ra_arena::map::ArenaMap; use ra_db::{salsa, CrateId}; @@ -12,19 +13,15 @@ use crate::{ CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, ValueTyDefId, }, - Crate, DefWithBody, ImplBlock, Trait, + Crate, DefWithBody, ImplBlock, }; -pub use hir_def::{ - db::{ - BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, - DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, - FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, - InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, - RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery, - TypeAliasDataQuery, - }, - GenericDefId, LocalStructFieldId, VariantId, +pub use hir_def::db::{ + BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, + DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, + FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, + LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, + StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, }; pub use hir_expand::db::{ AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, @@ -66,7 +63,7 @@ pub trait HirDatabase: DefDatabase { fn impls_in_crate(&self, krate: CrateId) -> Arc; #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] - fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; + fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplBlock]>; /// This provides the Chalk trait solver instance. Because Chalk always /// works from a specific crate, this query is keyed on the crate; and diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index f1bc638eec..fdc87a28d0 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -6,9 +6,10 @@ use std::sync::Arc; use arrayvec::ArrayVec; use hir_def::{ - lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef, - HasModule, ImplId, TraitId, + lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability, + AssocItemId, AstItemDef, HasModule, ImplId, TraitId, }; +use hir_expand::name::Name; use ra_db::CrateId; use ra_prof::profile; use rustc_hash::FxHashMap; @@ -17,7 +18,7 @@ use crate::{ db::HirDatabase, ty::primitive::{FloatBitness, Uncertain}, ty::{utils::all_super_traits, Ty, TypeCtor}, - AssocItem, Crate, Function, Mutability, Name, Trait, + AssocItem, Function, }; use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; @@ -87,8 +88,8 @@ impl CrateImplBlocks { fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() } - pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator + '_ { - self.impls_by_trait.get(&tr.id).into_iter().flatten().copied() + pub fn lookup_impl_blocks_for_trait(&self, tr: TraitId) -> impl Iterator + '_ { + self.impls_by_trait.get(&tr).into_iter().flatten().copied() } pub fn all_impls<'a>(&'a self) -> impl Iterator + 'a { @@ -96,14 +97,18 @@ impl CrateImplBlocks { } } -fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option> { +fn def_crates( + db: &impl HirDatabase, + cur_crate: CrateId, + ty: &Ty, +) -> Option> { // Types like slice can have inherent impls in several crates, (core and alloc). // The corresponding impls are marked with lang items, so we can use them to find the required crates. macro_rules! lang_item_crate { ($($name:expr),+ $(,)?) => {{ let mut v = ArrayVec::<[LangItemTarget; 2]>::new(); $( - v.extend(db.lang_item(cur_crate.crate_id, $name.into())); + v.extend(db.lang_item(cur_crate, $name.into())); )+ v }}; @@ -112,7 +117,7 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option match a_ty.ctor { TypeCtor::Adt(def_id) => { - return Some(std::iter::once(def_id.module(db).krate.into()).collect()) + return Some(std::iter::once(def_id.module(db).krate).collect()) } TypeCtor::Bool => lang_item_crate!("bool"), TypeCtor::Char => lang_item_crate!("char"), @@ -136,7 +141,7 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option Some(it), _ => None, }) - .map(|it| it.module(db).krate.into()) + .map(|it| it.module(db).krate) .collect(); Some(res) } @@ -193,14 +198,9 @@ pub(crate) fn iterate_method_candidates( let environment = TraitEnvironment::lower(db, resolver); let ty = InEnvironment { value: ty.clone(), environment }; for derefed_ty in autoderef::autoderef(db, resolver.krate(), ty) { - if let Some(result) = iterate_inherent_methods( - &derefed_ty, - db, - name, - mode, - krate.into(), - &mut callback, - ) { + if let Some(result) = + iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback) + { return Some(result); } if let Some(result) = iterate_trait_method_candidates( @@ -283,11 +283,11 @@ fn iterate_inherent_methods( db: &impl HirDatabase, name: Option<&Name>, mode: LookupMode, - krate: Crate, + krate: CrateId, mut callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { for krate in def_crates(db, krate, &ty.value)? { - let impls = db.impls_in_crate(krate.crate_id); + let impls = db.impls_in_crate(krate); for impl_block in impls.lookup_impl_blocks(&ty.value) { for &item in db.impl_data(impl_block).items.iter() { @@ -327,7 +327,7 @@ pub(crate) fn implements_trait( ty: &Canonical, db: &impl HirDatabase, resolver: &Resolver, - krate: Crate, + krate: CrateId, trait_: TraitId, ) -> bool { if ty.value.inherent_trait() == Some(trait_) { @@ -337,7 +337,7 @@ pub(crate) fn implements_trait( } let env = TraitEnvironment::lower(db, resolver); let goal = generic_implements_goal(db, env, trait_, ty.clone()); - let solution = db.trait_solve(krate, goal); + let solution = db.trait_solve(krate.into(), goal); solution.is_some() } @@ -348,11 +348,11 @@ impl Ty { pub fn iterate_impl_items( self, db: &impl HirDatabase, - krate: Crate, + krate: CrateId, mut callback: impl FnMut(AssocItem) -> Option, ) -> Option { for krate in def_crates(db, krate, &self)? { - let impls = db.impls_in_crate(krate.crate_id); + let impls = db.impls_in_crate(krate); for impl_block in impls.lookup_impl_blocks(&self) { for &item in db.impl_data(impl_block).items.iter() { diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index a91c2476be..637e21e9c4 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,13 +2,13 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; -use hir_def::{expr::ExprId, DefWithBodyId}; +use hir_def::{expr::ExprId, DefWithBodyId, TraitId}; use log::debug; -use ra_db::{impl_intern_key, salsa}; +use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; use rustc_hash::FxHashSet; -use crate::{db::HirDatabase, Crate, ImplBlock, Trait, TypeAlias}; +use crate::{db::HirDatabase, Crate, ImplBlock, TypeAlias}; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; @@ -77,8 +77,8 @@ pub(crate) fn trait_solver_query( /// Collects impls for the given trait in the whole dependency tree of `krate`. pub(crate) fn impls_for_trait_query( db: &impl HirDatabase, - krate: Crate, - trait_: Trait, + krate: CrateId, + trait_: TraitId, ) -> Arc<[ImplBlock]> { let mut impls = FxHashSet::default(); // We call the query recursively here. On the one hand, this means we can @@ -86,10 +86,10 @@ pub(crate) fn impls_for_trait_query( // will only ever get called for a few crates near the root of the tree (the // ones the user is editing), so this may actually be a waste of memory. I'm // doing it like this mainly for simplicity for now. - for dep in krate.dependencies(db) { - impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); + for dep in db.crate_graph().dependencies(krate) { + impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); } - let crate_impl_blocks = db.impls_in_crate(krate.crate_id); + let crate_impl_blocks = db.impls_in_crate(krate); impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); impls.into_iter().collect() } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 4b0f4f56c2..d879382a0e 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -448,7 +448,7 @@ where let trait_: TraitId = from_chalk(self.db, trait_id); let mut result: Vec<_> = self .db - .impls_for_trait(self.krate, trait_.into()) + .impls_for_trait(self.krate.crate_id, trait_.into()) .iter() .copied() .map(Impl::ImplBlock) From bed6869865ccfc6e72be26cb2041d83ab5cdbe3c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 22:56:07 +0300 Subject: [PATCH 40/65] Cleanup --- crates/ra_hir/src/code_model.rs | 49 +++++++-- crates/ra_hir/src/source_binder.rs | 4 +- crates/ra_hir/src/ty/lower.rs | 2 +- crates/ra_hir/src/ty/method_resolution.rs | 101 +++++++----------- crates/ra_hir_def/src/resolver.rs | 4 +- .../src/completion/complete_path.rs | 2 +- 6 files changed, 85 insertions(+), 77 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index b4b47057de..54da937eaa 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -28,7 +28,8 @@ use crate::{ expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, ty::display::HirFormatter, ty::{ - self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, + self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TyDefId, TypeCtor, + TypeWalk, }, CallableDef, Either, HirDisplay, Name, Source, }; @@ -498,12 +499,9 @@ impl Adt { let subst = db.generic_defaults(self.into()); subst.iter().any(|ty| ty == &Ty::Unknown) } - pub fn ty(self, db: &impl HirDatabase) -> Ty { - match self { - Adt::Struct(it) => it.ty(db), - Adt::Union(it) => it.ty(db), - Adt::Enum(it) => it.ty(db), - } + pub fn ty(self, db: &impl HirDatabase) -> Type { + let id = AdtId::from(self); + Type::from_def(db, id.module(db).krate, id) } pub fn module(self, db: &impl DefDatabase) -> Module { @@ -795,8 +793,8 @@ impl TypeAlias { db.type_alias_data(self.id).type_ref.clone() } - pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.ty(self.id.into()) + pub fn ty(self, db: &impl HirDatabase) -> Type { + Type::from_def(db, self.id.lookup(db).module(db).krate, self.id) } pub fn name(self, db: &impl DefDatabase) -> Name { @@ -989,6 +987,17 @@ pub struct Type { } impl Type { + fn from_def( + db: &impl HirDatabase, + krate: CrateId, + def: impl HasResolver + Into, + ) -> Type { + let resolver = def.resolver(db); + let environment = TraitEnvironment::lower(db, &resolver); + let ty = db.ty(def.into()); + Type { krate, ty: InEnvironment { value: ty, environment } } + } + pub fn is_bool(&self) -> bool { match &self.ty.value { Ty::Apply(a_ty) => match a_ty.ctor { @@ -1097,6 +1106,28 @@ impl Type { .map(move |ty| self.derived(ty)) } + // This would be nicer if it just returned an iterator, but that runs into + // lifetime problems, because we need to borrow temp `CrateImplBlocks`. + pub fn iterate_impl_items( + self, + db: &impl HirDatabase, + krate: Crate, + mut callback: impl FnMut(AssocItem) -> Option, + ) -> Option { + for krate in self.ty.value.def_crates(db, krate.crate_id)? { + let impls = db.impls_in_crate(krate); + + for impl_block in impls.lookup_impl_blocks(&self.ty.value) { + for &item in db.impl_data(impl_block).items.iter() { + if let Some(result) = callback(item.into()) { + return Some(result); + } + } + } + } + None + } + // FIXME: remove pub fn into_ty(self) -> Ty { self.ty.value diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 7c4ebd4b4f..9f3e6c43f2 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -389,14 +389,14 @@ impl SourceAnalyzer { pub fn iterate_path_candidates( &self, db: &impl HirDatabase, - ty: Ty, + ty: &Type, name: Option<&Name>, callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { // There should be no inference vars in types passed here // FIXME check that? // FIXME replace Unknown by bound vars here - let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; + let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; method_resolution::iterate_method_candidates( &canonical, db, diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 709492d217..1c0f71adc2 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -189,7 +189,7 @@ impl Ty { Ty::Param { idx, name } } TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db), - TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db), + TypeNs::AdtSelfType(adt) => db.ty(adt.into()), TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), TypeNs::BuiltinType(it) => { diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index fdc87a28d0..92645e2a52 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -97,14 +97,15 @@ impl CrateImplBlocks { } } -fn def_crates( - db: &impl HirDatabase, - cur_crate: CrateId, - ty: &Ty, -) -> Option> { - // Types like slice can have inherent impls in several crates, (core and alloc). - // The corresponding impls are marked with lang items, so we can use them to find the required crates. - macro_rules! lang_item_crate { +impl Ty { + pub(crate) fn def_crates( + &self, + db: &impl HirDatabase, + cur_crate: CrateId, + ) -> Option> { + // Types like slice can have inherent impls in several crates, (core and alloc). + // The corresponding impls are marked with lang items, so we can use them to find the required crates. + macro_rules! lang_item_crate { ($($name:expr),+ $(,)?) => {{ let mut v = ArrayVec::<[LangItemTarget; 2]>::new(); $( @@ -114,38 +115,38 @@ fn def_crates( }}; } - let lang_item_targets = match ty { - Ty::Apply(a_ty) => match a_ty.ctor { - TypeCtor::Adt(def_id) => { - return Some(std::iter::once(def_id.module(db).krate).collect()) - } - TypeCtor::Bool => lang_item_crate!("bool"), - TypeCtor::Char => lang_item_crate!("char"), - TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { - // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) - FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), - FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), + let lang_item_targets = match self { + Ty::Apply(a_ty) => match a_ty.ctor { + TypeCtor::Adt(def_id) => { + return Some(std::iter::once(def_id.module(db).krate).collect()) + } + TypeCtor::Bool => lang_item_crate!("bool"), + TypeCtor::Char => lang_item_crate!("char"), + TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { + // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) + FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), + FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), + }, + TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()), + TypeCtor::Str => lang_item_crate!("str_alloc", "str"), + TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), + TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), + TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"), + _ => return None, }, - TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()), - TypeCtor::Str => lang_item_crate!("str_alloc", "str"), - TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), - TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), - TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"), _ => return None, - }, - _ => return None, - }; - let res = lang_item_targets - .into_iter() - .filter_map(|it| match it { - LangItemTarget::ImplBlockId(it) => Some(it), - _ => None, - }) - .map(|it| it.module(db).krate) - .collect(); - Some(res) + }; + let res = lang_item_targets + .into_iter() + .filter_map(|it| match it { + LangItemTarget::ImplBlockId(it) => Some(it), + _ => None, + }) + .map(|it| it.module(db).krate) + .collect(); + Some(res) + } } - /// Look up the method with the given name, returning the actual autoderefed /// receiver type (but without autoref applied yet). pub(crate) fn lookup_method( @@ -286,7 +287,7 @@ fn iterate_inherent_methods( krate: CrateId, mut callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { - for krate in def_crates(db, krate, &ty.value)? { + for krate in ty.value.def_crates(db, krate)? { let impls = db.impls_in_crate(krate); for impl_block in impls.lookup_impl_blocks(&ty.value) { @@ -342,30 +343,6 @@ pub(crate) fn implements_trait( solution.is_some() } -impl Ty { - // This would be nicer if it just returned an iterator, but that runs into - // lifetime problems, because we need to borrow temp `CrateImplBlocks`. - pub fn iterate_impl_items( - self, - db: &impl HirDatabase, - krate: CrateId, - mut callback: impl FnMut(AssocItem) -> Option, - ) -> Option { - for krate in def_crates(db, krate, &self)? { - let impls = db.impls_in_crate(krate); - - for impl_block in impls.lookup_impl_blocks(&self) { - for &item in db.impl_data(impl_block).items.iter() { - if let Some(result) = callback(item.into()) { - return Some(result); - } - } - } - } - None - } -} - /// This creates Substs for a trait with the given Self type and type variables /// for all other parameters, to query Chalk with it. fn generic_implements_goal( diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index c40f41717b..5155365ccb 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -484,7 +484,7 @@ impl Resolver { } } -pub trait HasResolver { +pub trait HasResolver: Copy { /// Builds a resolver for type references inside this def. fn resolver(self, db: &impl DefDatabase) -> Resolver; } @@ -502,7 +502,7 @@ impl HasResolver for TraitId { } } -impl> HasResolver for T { +impl + Copy> HasResolver for T { fn resolver(self, db: &impl DefDatabase) -> Resolver { let def = self.into(); def.module(db) diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 63e25e0bf1..89e0009a17 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs @@ -50,7 +50,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), _ => unreachable!(), }; - ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| { + ctx.analyzer.iterate_path_candidates(ctx.db, &ty, None, |_ty, item| { match item { hir::AssocItem::Function(func) => { if !func.has_self_param(ctx.db) { From 5b49ad5bd5d78a8425f7162b6387c2cad6e2ef10 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 27 Nov 2019 04:09:30 +0800 Subject: [PATCH 41/65] Use a simple progress bar instead of indicatif --- Cargo.lock | 26 ------ crates/ra_cli/Cargo.toml | 1 - crates/ra_cli/src/analysis_stats.rs | 17 ++-- crates/ra_cli/src/main.rs | 1 + crates/ra_cli/src/progress_bar.rs | 130 ++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 37 deletions(-) create mode 100644 crates/ra_cli/src/progress_bar.rs diff --git a/Cargo.lock b/Cargo.lock index 1c61615049..f751be2e38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,7 +226,6 @@ dependencies = [ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -472,17 +471,6 @@ dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "indicatif" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "inotify" version = "0.6.1" @@ -759,11 +747,6 @@ dependencies = [ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "number_prefix" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "once_cell" version = "1.2.0" @@ -945,7 +928,6 @@ name = "ra_cli" version = "0.1.0" dependencies = [ "flexi_logger 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)", - "indicatif 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ra_batch 0.1.0", "ra_db 0.1.0", @@ -1718,11 +1700,6 @@ name = "unicode-segmentation" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicode-width" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.2.0" @@ -1899,7 +1876,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" -"checksum indicatif 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8572bccfb0665e70b7faf44ee28841b8e0823450cd4ad562a76b5a3c4bf48487" "checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" "checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349" @@ -1932,7 +1908,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" "checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" "checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" -"checksum number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" "checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" @@ -2008,7 +1983,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" -"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index c9d3bdb776..3bb4759979 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml @@ -8,7 +8,6 @@ publish = false [dependencies] pico-args = "0.3.0" flexi_logger = "0.14.0" -indicatif = "0.13.0" ra_syntax = { path = "../ra_syntax" } ra_ide_api = { path = "../ra_ide_api" } diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index c4eb28245b..8bf3863bb0 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs @@ -6,7 +6,7 @@ use ra_db::SourceDatabaseExt; use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; use ra_syntax::AstNode; -use crate::{Result, Verbosity}; +use crate::{progress_bar::ProgressBar, Result, Verbosity}; pub fn run( verbosity: Verbosity, @@ -75,17 +75,14 @@ pub fn run( println!("Item Collection: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); let inference_time = Instant::now(); - let bar = match verbosity { - Verbosity::Verbose | Verbosity::Normal => indicatif::ProgressBar::with_draw_target( - funcs.len() as u64, - indicatif::ProgressDrawTarget::stderr_nohz(), - ), - Verbosity::Quiet => indicatif::ProgressBar::hidden(), + let mut bar = match verbosity { + Verbosity::Verbose | Verbosity::Normal => ProgressBar::new(funcs.len() as u64), + Verbosity::Quiet => ProgressBar::hidden(), }; - bar.set_style( - indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), - ); + // bar.set_style( + // indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), + // ); bar.tick(); let mut num_exprs = 0; let mut num_exprs_unknown = 0; diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index a31fd5d6ae..c23d92ec2e 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -3,6 +3,7 @@ mod analysis_stats; mod analysis_bench; mod help; +mod progress_bar; use std::{error::Error, fmt::Write, io::Read}; diff --git a/crates/ra_cli/src/progress_bar.rs b/crates/ra_cli/src/progress_bar.rs new file mode 100644 index 0000000000..95bfcf4d0a --- /dev/null +++ b/crates/ra_cli/src/progress_bar.rs @@ -0,0 +1,130 @@ +//! A simple progress bar +//! +//! A single thread non-optimized progress bar +use std::io::Write; + +/// A Simple ASCII Progress Bar +pub struct ProgressBar { + curr: f32, + text: String, + anim: usize, + hidden: bool, + + len: u64, + pos: u64, + msg: String, +} + +impl ProgressBar { + const ANIMATION: &'static str = r#"|/-\"#; + const BLOCK_COUNT: usize = 20; + + pub fn new(len: u64) -> ProgressBar { + ProgressBar { + curr: 0.0, + text: String::new(), + anim: 0, + hidden: false, + len, + pos: 0, + msg: String::new(), + } + } + + pub fn hidden() -> ProgressBar { + ProgressBar { + curr: 0.0, + text: String::new(), + anim: 0, + hidden: true, + len: 0, + pos: 0, + msg: String::new(), + } + } + + pub fn set_message(&mut self, msg: &str) { + self.msg = msg.to_string(); + self.tick(); + } + + pub fn println>(&mut self, msg: I) { + self.clear(); + println!("{}", msg.into()); + self.tick(); + } + + pub fn inc(&mut self, delta: u64) { + self.pos += delta; + if self.len == 0 { + self.set_value(0.0) + } else { + self.set_value((self.pos as f32) / (self.len as f32)) + } + self.tick(); + } + + pub fn finish_and_clear(&mut self) { + self.clear(); + } + + pub fn tick(&mut self) { + if self.hidden { + return; + } + + let progress_block: usize = (self.curr * Self::BLOCK_COUNT as f32) as usize; + let percent = (self.curr * 100.0) as u32; + let text = format!( + "[{}{}] {:3>}% {} {}", + "#".repeat(progress_block), + "-".repeat(Self::BLOCK_COUNT - progress_block), + percent, + Self::ANIMATION.chars().nth(self.anim).unwrap(), + self.msg, + ); + + self.anim = (self.anim + 1) % Self::ANIMATION.len(); + self.update_text(&text); + } + + fn update_text(&mut self, text: &str) { + // Get length of common portion + let mut common_prefix_length = 0; + let common_length = usize::min(self.text.len(), text.len()); + + while common_prefix_length < common_length + && text.chars().nth(common_prefix_length).unwrap() + == self.text.chars().nth(common_prefix_length).unwrap() + { + common_prefix_length += 1; + } + + // Backtrack to the first differing character + let mut output = String::new(); + output += &'\x08'.to_string().repeat(self.text.len() - common_prefix_length); + // Output new suffix + output += &text[common_prefix_length..text.len()]; + + // If the new text is shorter than the old one: delete overlapping characters + if let Some(overlap_count) = self.text.len().checked_sub(text.len()) { + if overlap_count > 0 { + output += &" ".repeat(overlap_count); + output += &"\x08".repeat(overlap_count); + } + } + + let _ = std::io::stdout().write(output.as_bytes()); + let _ = std::io::stdout().flush(); + self.text = text.to_string(); + } + + fn set_value(&mut self, value: f32) { + self.curr = f32::max(0.0, f32::min(1.0, value)); + } + + fn clear(&mut self) { + print!("{}", "\x08".repeat(self.text.len())); + self.text = String::new(); + } +} From 97f6f141ee06ddfb22f8c02223fa71102b670528 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 27 Nov 2019 04:16:03 +0800 Subject: [PATCH 42/65] Remove commented code --- crates/ra_cli/src/analysis_stats.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 8bf3863bb0..122aa05523 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs @@ -80,9 +80,6 @@ pub fn run( Verbosity::Quiet => ProgressBar::hidden(), }; - // bar.set_style( - // indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), - // ); bar.tick(); let mut num_exprs = 0; let mut num_exprs_unknown = 0; From 27943bead6798cd202d7398f38cecfd3f5840645 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 27 Nov 2019 04:33:40 +0800 Subject: [PATCH 43/65] Remove progress bar and add a true counter --- crates/ra_cli/src/analysis_stats.rs | 6 ++-- crates/ra_cli/src/main.rs | 2 +- .../{progress_bar.rs => progress_report.rs} | 33 +++++-------------- 3 files changed, 12 insertions(+), 29 deletions(-) rename crates/ra_cli/src/{progress_bar.rs => progress_report.rs} (77%) diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 122aa05523..9b1802a5fc 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs @@ -6,7 +6,7 @@ use ra_db::SourceDatabaseExt; use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; use ra_syntax::AstNode; -use crate::{progress_bar::ProgressBar, Result, Verbosity}; +use crate::{progress_report::ProgressReport, Result, Verbosity}; pub fn run( verbosity: Verbosity, @@ -76,8 +76,8 @@ pub fn run( let inference_time = Instant::now(); let mut bar = match verbosity { - Verbosity::Verbose | Verbosity::Normal => ProgressBar::new(funcs.len() as u64), - Verbosity::Quiet => ProgressBar::hidden(), + Verbosity::Verbose | Verbosity::Normal => ProgressReport::new(funcs.len() as u64), + Verbosity::Quiet => ProgressReport::hidden(), }; bar.tick(); diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index c23d92ec2e..08f3531477 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -3,7 +3,7 @@ mod analysis_stats; mod analysis_bench; mod help; -mod progress_bar; +mod progress_report; use std::{error::Error, fmt::Write, io::Read}; diff --git a/crates/ra_cli/src/progress_bar.rs b/crates/ra_cli/src/progress_report.rs similarity index 77% rename from crates/ra_cli/src/progress_bar.rs rename to crates/ra_cli/src/progress_report.rs index 95bfcf4d0a..6ce0d4cab7 100644 --- a/crates/ra_cli/src/progress_bar.rs +++ b/crates/ra_cli/src/progress_report.rs @@ -4,10 +4,9 @@ use std::io::Write; /// A Simple ASCII Progress Bar -pub struct ProgressBar { +pub struct ProgressReport { curr: f32, text: String, - anim: usize, hidden: bool, len: u64, @@ -15,15 +14,11 @@ pub struct ProgressBar { msg: String, } -impl ProgressBar { - const ANIMATION: &'static str = r#"|/-\"#; - const BLOCK_COUNT: usize = 20; - - pub fn new(len: u64) -> ProgressBar { - ProgressBar { +impl ProgressReport { + pub fn new(len: u64) -> ProgressReport { + ProgressReport { curr: 0.0, text: String::new(), - anim: 0, hidden: false, len, pos: 0, @@ -31,11 +26,10 @@ impl ProgressBar { } } - pub fn hidden() -> ProgressBar { - ProgressBar { + pub fn hidden() -> ProgressReport { + ProgressReport { curr: 0.0, text: String::new(), - anim: 0, hidden: true, len: 0, pos: 0, @@ -72,19 +66,8 @@ impl ProgressBar { if self.hidden { return; } - - let progress_block: usize = (self.curr * Self::BLOCK_COUNT as f32) as usize; let percent = (self.curr * 100.0) as u32; - let text = format!( - "[{}{}] {:3>}% {} {}", - "#".repeat(progress_block), - "-".repeat(Self::BLOCK_COUNT - progress_block), - percent, - Self::ANIMATION.chars().nth(self.anim).unwrap(), - self.msg, - ); - - self.anim = (self.anim + 1) % Self::ANIMATION.len(); + let text = format!("{}/{} {:3>}% {}", self.pos, self.len, percent, self.msg); self.update_text(&text); } @@ -124,7 +107,7 @@ impl ProgressBar { } fn clear(&mut self) { - print!("{}", "\x08".repeat(self.text.len())); + print!("{}{}", " ".repeat(self.text.len()), "\x08".repeat(self.text.len())); self.text = String::new(); } } From f0aaf3b2964a26a08be13dcf04f31d5bfe46b2f3 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 27 Nov 2019 05:01:13 +0800 Subject: [PATCH 44/65] Fill all last text to space and return the cursor --- crates/ra_cli/src/progress_report.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/ra_cli/src/progress_report.rs b/crates/ra_cli/src/progress_report.rs index 6ce0d4cab7..31867a1e97 100644 --- a/crates/ra_cli/src/progress_report.rs +++ b/crates/ra_cli/src/progress_report.rs @@ -107,7 +107,14 @@ impl ProgressReport { } fn clear(&mut self) { - print!("{}{}", " ".repeat(self.text.len()), "\x08".repeat(self.text.len())); + if self.hidden { + return; + } + + // Fill all last text to space and return the cursor + let spaces = " ".repeat(self.text.len()); + let backspaces = "\x08".repeat(self.text.len()); + print!("{}{}{}", backspaces, spaces, backspaces); self.text = String::new(); } } From aa45561183493f274b78ca6be6b841bbc4b29e0d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 09:42:55 +0300 Subject: [PATCH 45/65] Crate -> CrateId --- crates/ra_hir/src/db.rs | 14 +++++------ crates/ra_hir/src/ty.rs | 13 ++++------- crates/ra_hir/src/ty/traits.rs | 10 ++++---- crates/ra_hir/src/ty/traits/chalk.rs | 35 ++++++++++++++++------------ 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 31b21ca840..17cb638686 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -13,7 +13,7 @@ use crate::{ CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, ValueTyDefId, }, - Crate, DefWithBody, ImplBlock, + DefWithBody, ImplBlock, }; pub use hir_def::db::{ @@ -71,7 +71,7 @@ pub trait HirDatabase: DefDatabase { /// Mutex and the query does an untracked read internally, to make sure the /// cached state is thrown away when input facts change. #[salsa::invoke(crate::ty::traits::trait_solver_query)] - fn trait_solver(&self, krate: Crate) -> crate::ty::traits::TraitSolver; + fn trait_solver(&self, krate: CrateId) -> crate::ty::traits::TraitSolver; // Interned IDs for Chalk integration #[salsa::interned] @@ -93,35 +93,35 @@ pub trait HirDatabase: DefDatabase { #[salsa::invoke(crate::ty::traits::chalk::trait_datum_query)] fn trait_datum( &self, - krate: Crate, + krate: CrateId, trait_id: chalk_ir::TraitId, ) -> Arc>; #[salsa::invoke(crate::ty::traits::chalk::struct_datum_query)] fn struct_datum( &self, - krate: Crate, + krate: CrateId, struct_id: chalk_ir::StructId, ) -> Arc>; #[salsa::invoke(crate::ty::traits::chalk::impl_datum_query)] fn impl_datum( &self, - krate: Crate, + krate: CrateId, impl_id: chalk_ir::ImplId, ) -> Arc>; #[salsa::invoke(crate::ty::traits::chalk::associated_ty_value_query)] fn associated_ty_value( &self, - krate: Crate, + krate: CrateId, id: chalk_rust_ir::AssociatedTyValueId, ) -> Arc>; #[salsa::invoke(crate::ty::traits::trait_solve_query)] fn trait_solve( &self, - krate: Crate, + krate: CrateId, goal: crate::ty::Canonical>, ) -> Option; } diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 791b6064ac..a26776b268 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -23,13 +23,12 @@ use hir_def::{ GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, }; use hir_expand::name::Name; -use ra_db::{impl_intern_key, salsa}; +use ra_db::{impl_intern_key, salsa, CrateId}; use crate::{ db::HirDatabase, ty::primitive::{FloatTy, IntTy, Uncertain}, util::make_mut_slice, - Crate, }; use display::{HirDisplay, HirFormatter}; @@ -162,7 +161,7 @@ impl TypeCtor { } } - pub fn krate(self, db: &impl HirDatabase) -> Option { + pub fn krate(self, db: &impl HirDatabase) -> Option { match self { TypeCtor::Bool | TypeCtor::Char @@ -178,11 +177,9 @@ impl TypeCtor { | TypeCtor::Tuple { .. } => None, // Closure's krate is irrelevant for coherence I would think? TypeCtor::Closure { .. } => None, - TypeCtor::Adt(adt) => Some(adt.module(db).krate.into()), - TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), - TypeCtor::AssociatedType(type_alias) => { - Some(type_alias.lookup(db).module(db).krate.into()) - } + TypeCtor::Adt(adt) => Some(adt.module(db).krate), + TypeCtor::FnDef(callable) => Some(callable.krate(db)), + TypeCtor::AssociatedType(type_alias) => Some(type_alias.lookup(db).module(db).krate), } } diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 637e21e9c4..39b489a4c9 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -8,7 +8,7 @@ use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; use rustc_hash::FxHashSet; -use crate::{db::HirDatabase, Crate, ImplBlock, TypeAlias}; +use crate::{db::HirDatabase, ImplBlock, TypeAlias}; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; @@ -18,7 +18,7 @@ pub(crate) mod chalk; #[derive(Debug, Clone)] pub struct TraitSolver { - krate: Crate, + krate: CrateId, inner: Arc>>, } @@ -60,12 +60,12 @@ const CHALK_SOLVER_MAX_SIZE: usize = 4; #[derive(Debug, Copy, Clone)] struct ChalkContext<'a, DB> { db: &'a DB, - krate: Crate, + krate: CrateId, } pub(crate) fn trait_solver_query( db: &(impl HirDatabase + salsa::Database), - krate: Crate, + krate: CrateId, ) -> TraitSolver { db.salsa_runtime().report_untracked_read(); // krate parameter is just so we cache a unique solver per crate @@ -176,7 +176,7 @@ impl TypeWalk for ProjectionPredicate { /// Solve a trait goal using Chalk. pub(crate) fn trait_solve_query( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, goal: Canonical>, ) -> Option { let _p = profile("trait_solve_query"); diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index d879382a0e..49fa955081 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -8,6 +8,7 @@ use chalk_ir::{ TypeKindId, TypeName, UniverseIndex, }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; +use ra_db::CrateId; use hir_def::{ lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, @@ -21,7 +22,7 @@ use crate::{ db::HirDatabase, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - Crate, ImplBlock, TypeAlias, + ImplBlock, TypeAlias, }; /// This represents a trait whose name we could not resolve. @@ -448,7 +449,7 @@ where let trait_: TraitId = from_chalk(self.db, trait_id); let mut result: Vec<_> = self .db - .impls_for_trait(self.krate.crate_id, trait_.into()) + .impls_for_trait(self.krate, trait_.into()) .iter() .copied() .map(Impl::ImplBlock) @@ -487,7 +488,7 @@ where &self, id: chalk_rust_ir::AssociatedTyValueId, ) -> Arc> { - self.db.associated_ty_value(self.krate, id) + self.db.associated_ty_value(self.krate.into(), id) } fn custom_clauses(&self) -> Vec> { vec![] @@ -528,7 +529,7 @@ pub(crate) fn associated_ty_data_query( pub(crate) fn trait_datum_query( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, trait_id: chalk_ir::TraitId, ) -> Arc> { debug!("trait_datum {:?}", trait_id); @@ -557,7 +558,7 @@ pub(crate) fn trait_datum_query( let bound_vars = Substs::bound_vars(&generic_params); let flags = chalk_rust_ir::TraitFlags { auto: trait_data.auto, - upstream: trait_.module(db).krate != krate.crate_id, + upstream: trait_.module(db).krate != krate, non_enumerable: true, coinductive: false, // only relevant for Chalk testing // FIXME set these flags correctly @@ -579,7 +580,7 @@ pub(crate) fn trait_datum_query( pub(crate) fn struct_datum_query( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, struct_id: chalk_ir::StructId, ) -> Arc> { debug!("struct_datum {:?}", struct_id); @@ -611,7 +612,7 @@ pub(crate) fn struct_datum_query( pub(crate) fn impl_datum_query( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, impl_id: ImplId, ) -> Arc> { let _p = ra_prof::profile("impl_datum"); @@ -626,7 +627,7 @@ pub(crate) fn impl_datum_query( fn impl_block_datum( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, impl_id: ImplId, impl_block: ImplBlock, ) -> Option>> { @@ -634,7 +635,7 @@ fn impl_block_datum( let bound_vars = Substs::bound_vars(&generic_params); let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); let trait_ = trait_ref.trait_; - let impl_type = if impl_block.krate(db) == krate { + let impl_type = if impl_block.krate(db).crate_id == krate { chalk_rust_ir::ImplType::Local } else { chalk_rust_ir::ImplType::External @@ -698,7 +699,7 @@ fn invalid_impl_datum() -> Arc> { fn closure_fn_trait_impl_datum( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, data: super::ClosureFnTraitImplData, ) -> Option>> { // for some closure |X, Y| -> Z: @@ -755,7 +756,7 @@ fn closure_fn_trait_impl_datum( pub(crate) fn associated_ty_value_query( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, id: chalk_rust_ir::AssociatedTyValueId, ) -> Arc> { let data: AssocTyValue = from_chalk(db, id); @@ -771,7 +772,7 @@ pub(crate) fn associated_ty_value_query( fn type_alias_associated_ty_value( db: &impl HirDatabase, - _krate: Crate, + _krate: CrateId, type_alias: TypeAlias, ) -> Arc> { let impl_block = type_alias.impl_block(db).expect("assoc ty value should be in impl"); @@ -798,7 +799,7 @@ fn type_alias_associated_ty_value( fn closure_fn_trait_output_assoc_ty_value( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, data: super::ClosureFnTraitImplData, ) -> Arc> { let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db); @@ -831,8 +832,12 @@ fn closure_fn_trait_output_assoc_ty_value( Arc::new(value) } -fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option { - let target = db.lang_item(krate.crate_id, fn_trait.lang_item_name().into())?; +fn get_fn_trait( + db: &impl HirDatabase, + krate: CrateId, + fn_trait: super::FnTrait, +) -> Option { + let target = db.lang_item(krate, fn_trait.lang_item_name().into())?; match target { LangItemTarget::TraitId(t) => Some(t), _ => None, From a306531e6aa7995145dc041166f68ea950aca1a8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 11:40:10 +0300 Subject: [PATCH 46/65] Decouple --- crates/ra_hir/src/ty/method_resolution.rs | 2 +- crates/ra_hir/src/ty/traits.rs | 6 ++-- crates/ra_hir/src/ty/traits/chalk.rs | 40 ++++++++++++++--------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 92645e2a52..7df2649c90 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -62,7 +62,7 @@ impl CrateImplBlocks { let impl_data = db.impl_data(impl_id); let resolver = impl_id.resolver(db); - let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; + let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); match &impl_data.target_trait { Some(trait_ref) => { diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 39b489a4c9..99afeb35f2 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,13 +2,13 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; -use hir_def::{expr::ExprId, DefWithBodyId, TraitId}; +use hir_def::{expr::ExprId, DefWithBodyId, TraitId, TypeAliasId}; use log::debug; use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; use rustc_hash::FxHashSet; -use crate::{db::HirDatabase, ImplBlock, TypeAlias}; +use crate::{db::HirDatabase, ImplBlock}; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; @@ -317,7 +317,7 @@ impl_intern_key!(GlobalImplId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum AssocTyValue { /// A normal assoc type value from an impl block. - TypeAlias(TypeAlias), + TypeAlias(TypeAliasId), /// The output type of the Fn trait implementation. ClosureFnTraitImplOutput(ClosureFnTraitImplData), } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 49fa955081..76ff6f67ff 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -11,7 +11,8 @@ use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum use ra_db::CrateId; use hir_def::{ - lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, + lang_item::LangItemTarget, resolver::HasResolver, AstItemDef, ContainerId, GenericDefId, + Lookup, TraitId, TypeAliasId, }; use hir_expand::name; @@ -22,7 +23,7 @@ use crate::{ db::HirDatabase, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - ImplBlock, TypeAlias, + ImplBlock, }; /// This represents a trait whose name we could not resolve. @@ -670,7 +671,7 @@ fn impl_block_datum( // don't include associated types that don't exist in the trait trait_data.associated_type_by_name(&type_alias.name(db)).is_some() }) - .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) + .map(|type_alias| AssocTyValue::TypeAlias(type_alias.id).to_chalk(db)) .collect(); debug!("impl_datum: {:?}", impl_datum_bound); let impl_datum = ImplDatum { @@ -773,24 +774,33 @@ pub(crate) fn associated_ty_value_query( fn type_alias_associated_ty_value( db: &impl HirDatabase, _krate: CrateId, - type_alias: TypeAlias, + type_alias: TypeAliasId, ) -> Arc> { - let impl_block = type_alias.impl_block(db).expect("assoc ty value should be in impl"); - let impl_id = Impl::ImplBlock(impl_block).to_chalk(db); - let trait_ = impl_block - .target_trait_ref(db) - .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved - .trait_; + let type_alias_data = db.type_alias_data(type_alias); + let impl_id = match type_alias.lookup(db).container { + ContainerId::ImplId(it) => it, + _ => panic!("assoc ty value should be in impl"), + }; + + let impl_data = db.impl_data(impl_id); + let resolver = impl_id.resolver(db); + let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); + let target_trait = impl_data + .target_trait + .as_ref() + .and_then(|trait_ref| TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))) + .expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved + let assoc_ty = db - .trait_data(trait_) - .associated_type_by_name(&type_alias.name(db)) + .trait_data(target_trait.trait_) + .associated_type_by_name(&type_alias_data.name) .expect("assoc ty value should not exist"); // validated when building the impl data as well - let generic_params = db.generic_params(impl_block.id.into()); + let generic_params = db.generic_params(impl_id.into()); let bound_vars = Substs::bound_vars(&generic_params); - let ty = db.ty(type_alias.id.into()).subst(&bound_vars); + let ty = db.ty(type_alias.into()).subst(&bound_vars); let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; let value = chalk_rust_ir::AssociatedTyValue { - impl_id, + impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), associated_ty_id: assoc_ty.to_chalk(db), value: make_binders(value_bound, bound_vars.len()), }; From 3a0929fca7a52605526c6f89be4e3e86c5d0359d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 12:02:54 +0300 Subject: [PATCH 47/65] Decouple --- crates/ra_hir/src/db.rs | 6 +++--- crates/ra_hir/src/ty/infer/coerce.rs | 21 +++++++++++++++++---- crates/ra_hir/src/ty/traits.rs | 6 +++--- crates/ra_hir/src/ty/traits/chalk.rs | 2 +- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 17cb638686..a5bfef91f6 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use hir_def::{GenericDefId, LocalStructFieldId, TraitId, VariantId}; +use hir_def::{GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; use ra_arena::map::ArenaMap; use ra_db::{salsa, CrateId}; @@ -13,7 +13,7 @@ use crate::{ CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, ValueTyDefId, }, - DefWithBody, ImplBlock, + DefWithBody, }; pub use hir_def::db::{ @@ -63,7 +63,7 @@ pub trait HirDatabase: DefDatabase { fn impls_in_crate(&self, krate: CrateId) -> Arc; #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] - fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplBlock]>; + fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplId]>; /// This provides the Chalk trait solver instance. Because Chalk always /// works from a specific crate, this query is keyed on the crate; and diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 5ed4470afa..cf45ede7ce 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -4,13 +4,17 @@ //! //! See: https://doc.rust-lang.org/nomicon/coercions.html -use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId}; +use hir_def::{ + lang_item::LangItemTarget, + resolver::{HasResolver, Resolver}, + AdtId, +}; use rustc_hash::FxHashMap; use test_utils::tested_by; use crate::{ db::HirDatabase, - ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, + ty::{autoderef, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, Mutability, }; @@ -57,9 +61,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { impls .iter() - .filter_map(|impl_block| { + .filter_map(|&impl_id| { + let impl_data = db.impl_data(impl_id); + let resolver = impl_id.resolver(db); + let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); + // `CoerseUnsized` has one generic parameter for the target type. - let trait_ref = impl_block.target_trait_ref(db)?; + let trait_ref = TraitRef::from_hir( + db, + &resolver, + impl_data.target_trait.as_ref()?, + Some(target_ty), + )?; let cur_from_ty = trait_ref.substs.0.get(0)?; let cur_to_ty = trait_ref.substs.0.get(1)?; diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 99afeb35f2..93cb328697 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; -use hir_def::{expr::ExprId, DefWithBodyId, TraitId, TypeAliasId}; +use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId}; use log::debug; use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; @@ -79,7 +79,7 @@ pub(crate) fn impls_for_trait_query( db: &impl HirDatabase, krate: CrateId, trait_: TraitId, -) -> Arc<[ImplBlock]> { +) -> Arc<[ImplId]> { let mut impls = FxHashSet::default(); // We call the query recursively here. On the one hand, this means we can // reuse results from queries for different crates; on the other hand, this @@ -90,7 +90,7 @@ pub(crate) fn impls_for_trait_query( impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); } let crate_impl_blocks = db.impls_in_crate(krate); - impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); + impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); impls.into_iter().collect() } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 76ff6f67ff..7b2e530a2c 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -453,7 +453,7 @@ where .impls_for_trait(self.krate, trait_.into()) .iter() .copied() - .map(Impl::ImplBlock) + .map(|it| Impl::ImplBlock(it.into())) .map(|impl_| impl_.to_chalk(self.db)) .collect(); From e91ebfc752bdfa8fc20be6ea97a14aa6a4d897ae Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 12:13:07 +0300 Subject: [PATCH 48/65] Cleanup imports --- crates/ra_hir/src/ty/infer/coerce.rs | 2 +- crates/ra_hir/src/ty/infer/expr.rs | 5 ++--- crates/ra_hir/src/ty/infer/pat.rs | 10 +++++++--- crates/ra_hir/src/ty/infer/path.rs | 5 +++-- crates/ra_hir/src/ty/infer/unify.rs | 12 +++++++----- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index cf45ede7ce..3fb5d8a83b 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -7,6 +7,7 @@ use hir_def::{ lang_item::LangItemTarget, resolver::{HasResolver, Resolver}, + type_ref::Mutability, AdtId, }; use rustc_hash::FxHashMap; @@ -15,7 +16,6 @@ use test_utils::tested_by; use crate::{ db::HirDatabase, ty::{autoderef, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - Mutability, }; use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index eb221d6bc8..57f845dfa4 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -5,22 +5,21 @@ use std::sync::Arc; use hir_def::{ builtin_type::Signedness, + expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, generics::GenericParams, path::{GenericArg, GenericArgs}, resolver::resolver_for_expr, AdtId, ContainerId, Lookup, StructFieldId, }; -use hir_expand::name; +use hir_expand::name::{self, Name}; use crate::{ db::HirDatabase, - expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, ty::{ autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }, - Name, }; use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir/src/ty/infer/pat.rs index 641d61e87b..6dbf03eb20 100644 --- a/crates/ra_hir/src/ty/infer/pat.rs +++ b/crates/ra_hir/src/ty/infer/pat.rs @@ -3,14 +3,18 @@ use std::iter::repeat; use std::sync::Arc; +use hir_def::{ + expr::{BindingAnnotation, Pat, PatId, RecordFieldPat}, + path::Path, + type_ref::Mutability, +}; +use hir_expand::name::Name; use test_utils::tested_by; use super::{BindingMode, InferenceContext}; use crate::{ db::HirDatabase, - expr::{BindingAnnotation, Pat, PatId, RecordFieldPat}, - ty::{Mutability, Substs, Ty, TypeCtor, TypeWalk}, - Name, Path, + ty::{Substs, Ty, TypeCtor, TypeWalk}, }; impl<'a, D: HirDatabase> InferenceContext<'a, D> { diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index be2067dd4d..8d8b56d2d0 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -1,14 +1,15 @@ //! Path expression resolution. use hir_def::{ - path::PathSegment, + path::{Path, PathSegment}, resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, }; +use hir_expand::name::Name; use crate::{ db::HirDatabase, ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}, - AssocItem, Container, Function, Name, Path, + AssocItem, Container, Function, }; use super::{ExprOrPatId, InferenceContext, TraitRef}; diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir/src/ty/infer/unify.rs index 64d9394cf7..e27bb2f825 100644 --- a/crates/ra_hir/src/ty/infer/unify.rs +++ b/crates/ra_hir/src/ty/infer/unify.rs @@ -1,12 +1,14 @@ //! Unification and canonicalization logic. use super::{InferenceContext, Obligation}; -use crate::db::HirDatabase; -use crate::ty::{ - Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, - TypeWalk, +use crate::{ + db::HirDatabase, + ty::{ + Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, + TypeWalk, + }, + util::make_mut_slice, }; -use crate::util::make_mut_slice; impl<'a, D: HirDatabase> InferenceContext<'a, D> { pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b, D> From 825049bc6247f6d596910cd99f76f891d5435a86 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 12:31:40 +0300 Subject: [PATCH 49/65] Decouple --- crates/ra_hir/src/source_binder.rs | 8 +-- crates/ra_hir/src/ty/infer.rs | 6 +- crates/ra_hir/src/ty/infer/path.rs | 86 +++++++++++++---------- crates/ra_hir/src/ty/method_resolution.rs | 10 +-- crates/ra_hir_def/src/lib.rs | 10 +++ 5 files changed, 71 insertions(+), 49 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 9f3e6c43f2..b9d3a17131 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -11,7 +11,7 @@ use hir_def::{ expr::{ExprId, PatId}, path::known, resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, - DefWithBodyId, + AssocItemId, DefWithBodyId, }; use hir_expand::{ hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, @@ -380,7 +380,7 @@ impl SourceAnalyzer { name, method_resolution::LookupMode::MethodCall, |ty, it| match it { - AssocItem::Function(f) => callback(ty, f), + AssocItemId::FunctionId(f) => callback(ty, f.into()), _ => None, }, ) @@ -391,7 +391,7 @@ impl SourceAnalyzer { db: &impl HirDatabase, ty: &Type, name: Option<&Name>, - callback: impl FnMut(&Ty, AssocItem) -> Option, + mut callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { // There should be no inference vars in types passed here // FIXME check that? @@ -403,7 +403,7 @@ impl SourceAnalyzer { &self.resolver, name, method_resolution::LookupMode::Path, - callback, + |ty, it| callback(ty, it.into()), ) } diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index beb2efb7aa..db9a8c9d1e 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -26,7 +26,7 @@ use hir_def::{ path::known, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{Mutability, TypeRef}, - AdtId, DefWithBodyId, + AdtId, AssocItemId, DefWithBodyId, }; use hir_expand::{diagnostics::DiagnosticSink, name}; use ra_arena::map::ArenaMap; @@ -255,8 +255,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.result.variant_resolutions.insert(id, variant); } - fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItem) { - self.result.assoc_resolutions.insert(id, item); + fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId) { + self.result.assoc_resolutions.insert(id, item.into()); } fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 8d8b56d2d0..09ff797288 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -2,14 +2,14 @@ use hir_def::{ path::{Path, PathSegment}, - resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, + resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, + AssocItemId, ContainerId, Lookup, }; use hir_expand::name::Name; use crate::{ db::HirDatabase, ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}, - AssocItem, Container, Function, }; use super::{ExprOrPatId, InferenceContext, TraitRef}; @@ -143,31 +143,35 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { id: ExprOrPatId, ) -> Option<(ValueNs, Option)> { let trait_ = trait_ref.trait_; - let item = - self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id).into()).find_map( - |item| match item { - AssocItem::Function(func) => { - if segment.name == func.name(self.db) { - Some(AssocItem::Function(func)) - } else { - None - } + let item = self + .db + .trait_data(trait_) + .items + .iter() + .map(|(_name, id)| (*id).into()) + .find_map(|item| match item { + AssocItemId::FunctionId(func) => { + if segment.name == self.db.function_data(func).name { + Some(AssocItemId::FunctionId(func)) + } else { + None } + } - AssocItem::Const(konst) => { - if konst.name(self.db).map_or(false, |n| n == segment.name) { - Some(AssocItem::Const(konst)) - } else { - None - } + AssocItemId::ConstId(konst) => { + if self.db.const_data(konst).name.as_ref().map_or(false, |n| n == &segment.name) + { + Some(AssocItemId::ConstId(konst)) + } else { + None } - AssocItem::TypeAlias(_) => None, - }, - )?; + } + AssocItemId::TypeAliasId(_) => None, + })?; let def = match item { - AssocItem::Function(f) => ValueNs::FunctionId(f.id), - AssocItem::Const(c) => ValueNs::ConstId(c.id), - AssocItem::TypeAlias(_) => unreachable!(), + AssocItemId::FunctionId(f) => ValueNs::FunctionId(f), + AssocItemId::ConstId(c) => ValueNs::ConstId(c), + AssocItemId::TypeAliasId(_) => unreachable!(), }; let substs = Substs::build_for_def(self.db, item) .use_parent_substs(&trait_ref.substs) @@ -197,16 +201,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Some(name), method_resolution::LookupMode::Path, move |_ty, item| { - let def = match item { - AssocItem::Function(f) => ValueNs::FunctionId(f.id), - AssocItem::Const(c) => ValueNs::ConstId(c.id), - AssocItem::TypeAlias(_) => unreachable!(), + let (def, container) = match item { + AssocItemId::FunctionId(f) => { + (ValueNs::FunctionId(f), f.lookup(self.db).container) + } + AssocItemId::ConstId(c) => (ValueNs::ConstId(c), c.lookup(self.db).container), + AssocItemId::TypeAliasId(_) => unreachable!(), }; - let substs = match item.container(self.db) { - Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()), - Container::Trait(t) => { + let substs = match container { + ContainerId::ImplId(_) => self.find_self_types(&def, ty.clone()), + ContainerId::TraitId(trait_) => { // we're picking this method - let trait_substs = Substs::build_for_def(self.db, t.id) + let trait_substs = Substs::build_for_def(self.db, trait_) .push(ty.clone()) .fill(std::iter::repeat_with(|| self.new_type_var())) .build(); @@ -215,29 +221,35 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { .fill_with_params() .build(); self.obligations.push(super::Obligation::Trait(TraitRef { - trait_: t.id, + trait_, substs: trait_substs, })); Some(substs) } + ContainerId::ModuleId(_) => None, }; - self.write_assoc_resolution(id, item); + self.write_assoc_resolution(id, item.into()); Some((def, substs)) }, ) } fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option { - if let ValueNs::FunctionId(func) = def { - let func = Function::from(*func); + if let ValueNs::FunctionId(func) = *def { // We only do the infer if parent has generic params - let gen = self.db.generic_params(func.id.into()); + let gen = self.db.generic_params(func.into()); if gen.count_parent_params() == 0 { return None; } - let impl_block = func.impl_block(self.db)?.target_ty(self.db); + let impl_id = match func.lookup(self.db).container { + ContainerId::ImplId(it) => it, + _ => return None, + }; + let resolver = impl_id.resolver(self.db); + let impl_data = self.db.impl_data(impl_id); + let impl_block = Ty::from_hir(self.db, &resolver, &impl_data.target_type); let impl_block_substs = impl_block.substs()?; let actual_substs = actual_def_ty.substs()?; diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 7df2649c90..02e81fb341 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -18,7 +18,7 @@ use crate::{ db::HirDatabase, ty::primitive::{FloatBitness, Uncertain}, ty::{utils::all_super_traits, Ty, TypeCtor}, - AssocItem, Function, + Function, }; use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; @@ -157,7 +157,7 @@ pub(crate) fn lookup_method( ) -> Option<(Ty, Function)> { iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f { - AssocItem::Function(f) => Some((ty.clone(), f)), + AssocItemId::FunctionId(f) => Some((ty.clone(), f.into())), _ => None, }) } @@ -183,7 +183,7 @@ pub(crate) fn iterate_method_candidates( resolver: &Resolver, name: Option<&Name>, mode: LookupMode, - mut callback: impl FnMut(&Ty, AssocItem) -> Option, + mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { let krate = resolver.krate()?; match mode { @@ -239,7 +239,7 @@ fn iterate_trait_method_candidates( resolver: &Resolver, name: Option<&Name>, mode: LookupMode, - mut callback: impl FnMut(&Ty, AssocItem) -> Option, + mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { let krate = resolver.krate()?; // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) @@ -285,7 +285,7 @@ fn iterate_inherent_methods( name: Option<&Name>, mode: LookupMode, krate: CrateId, - mut callback: impl FnMut(&Ty, AssocItem) -> Option, + mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { for krate in ty.value.def_crates(db, krate)? { let impls = db.impls_in_crate(krate); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 274dd1467e..ea3f00bb33 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -398,6 +398,16 @@ impl_froms!( ConstId ); +impl From for GenericDefId { + fn from(item: AssocItemId) -> Self { + match item { + AssocItemId::FunctionId(f) => f.into(), + AssocItemId::ConstId(c) => c.into(), + AssocItemId::TypeAliasId(t) => t.into(), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum AttrDefId { ModuleId(ModuleId), From 1fe9656ba4fdb1369153d4f0f6a7c8bfea6bfe08 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 12:47:18 +0300 Subject: [PATCH 50/65] Decouple --- crates/ra_hir/src/ty/traits.rs | 4 +-- crates/ra_hir/src/ty/traits/chalk.rs | 52 ++++++++++++++++------------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 93cb328697..76189a60b1 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -8,7 +8,7 @@ use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; use rustc_hash::FxHashSet; -use crate::{db::HirDatabase, ImplBlock}; +use crate::db::HirDatabase; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; @@ -302,7 +302,7 @@ pub struct ClosureFnTraitImplData { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Impl { /// A normal impl from an impl block. - ImplBlock(ImplBlock), + ImplBlock(ImplId), /// Closure types implement the Fn traits synthetically. ClosureFnTraitImpl(ClosureFnTraitImplData), } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 7b2e530a2c..67ac5422cf 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -4,15 +4,15 @@ use std::sync::Arc; use log::debug; use chalk_ir::{ - cast::Cast, family::ChalkIr, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, - TypeKindId, TypeName, UniverseIndex, + cast::Cast, family::ChalkIr, Identifier, Parameter, PlaceholderIndex, TypeId, TypeKindId, + TypeName, UniverseIndex, }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; use ra_db::CrateId; use hir_def::{ - lang_item::LangItemTarget, resolver::HasResolver, AstItemDef, ContainerId, GenericDefId, - Lookup, TraitId, TypeAliasId, + lang_item::LangItemTarget, resolver::HasResolver, AssocItemId, AstItemDef, ContainerId, + GenericDefId, ImplId, Lookup, TraitId, TypeAliasId, }; use hir_expand::name; @@ -23,7 +23,6 @@ use crate::{ db::HirDatabase, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - ImplBlock, }; /// This represents a trait whose name we could not resolve. @@ -435,14 +434,14 @@ where fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc> { self.db.struct_datum(self.krate, struct_id) } - fn impl_datum(&self, impl_id: ImplId) -> Arc> { + fn impl_datum(&self, impl_id: chalk_ir::ImplId) -> Arc> { self.db.impl_datum(self.krate, impl_id) } fn impls_for_trait( &self, trait_id: chalk_ir::TraitId, parameters: &[Parameter], - ) -> Vec { + ) -> Vec { debug!("impls_for_trait {:?}", trait_id); if trait_id == UNKNOWN_TRAIT { return Vec::new(); @@ -614,7 +613,7 @@ pub(crate) fn struct_datum_query( pub(crate) fn impl_datum_query( db: &impl HirDatabase, krate: CrateId, - impl_id: ImplId, + impl_id: chalk_ir::ImplId, ) -> Arc> { let _p = ra_prof::profile("impl_datum"); debug!("impl_datum {:?}", impl_id); @@ -629,23 +628,31 @@ pub(crate) fn impl_datum_query( fn impl_block_datum( db: &impl HirDatabase, krate: CrateId, + chalk_id: chalk_ir::ImplId, impl_id: ImplId, - impl_block: ImplBlock, ) -> Option>> { - let generic_params = db.generic_params(impl_block.id.into()); + let impl_data = db.impl_data(impl_id); + let resolver = impl_id.resolver(db); + let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); + + // `CoerseUnsized` has one generic parameter for the target type. + let trait_ref = + TraitRef::from_hir(db, &resolver, impl_data.target_trait.as_ref()?, Some(target_ty))?; + + let generic_params = db.generic_params(impl_id.into()); let bound_vars = Substs::bound_vars(&generic_params); - let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); + let trait_ref = trait_ref.subst(&bound_vars); let trait_ = trait_ref.trait_; - let impl_type = if impl_block.krate(db).crate_id == krate { + let impl_type = if impl_id.module(db).krate == krate { chalk_rust_ir::ImplType::Local } else { chalk_rust_ir::ImplType::External }; - let where_clauses = convert_where_clauses(db, impl_block.id.into(), &bound_vars); - let negative = impl_block.is_negative(db); + let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars); + let negative = impl_data.is_negative; debug!( "impl {:?}: {}{} where {:?}", - impl_id, + chalk_id, if negative { "!" } else { "" }, trait_ref.display(db), where_clauses @@ -660,18 +667,19 @@ fn impl_block_datum( let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses }; let trait_data = db.trait_data(trait_); - let associated_ty_value_ids = impl_block - .items(db) - .into_iter() + let associated_ty_value_ids = impl_data + .items + .iter() .filter_map(|item| match item { - crate::AssocItem::TypeAlias(type_alias) => Some(type_alias), + AssocItemId::TypeAliasId(type_alias) => Some(*type_alias), _ => None, }) - .filter(|type_alias| { + .filter(|&type_alias| { // don't include associated types that don't exist in the trait - trait_data.associated_type_by_name(&type_alias.name(db)).is_some() + let name = &db.type_alias_data(type_alias).name; + trait_data.associated_type_by_name(name).is_some() }) - .map(|type_alias| AssocTyValue::TypeAlias(type_alias.id).to_chalk(db)) + .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) .collect(); debug!("impl_datum: {:?}", impl_datum_bound); let impl_datum = ImplDatum { From d569869f7a8c7a4c23b14fadbef63d4dbc949bcd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 15:56:20 +0300 Subject: [PATCH 51/65] Decouple more --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/source_binder.rs | 6 +-- crates/ra_hir/src/ty/infer.rs | 54 ++++++++++++----------- crates/ra_hir/src/ty/infer/expr.rs | 12 ++--- crates/ra_hir/src/ty/method_resolution.rs | 7 ++- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 54da937eaa..6d71bde921 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -647,7 +647,7 @@ impl Function { pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { let infer = self.infer(db); - infer.add_diagnostics(db, self, sink); + infer.add_diagnostics(db, self.id, sink); let mut validator = ExprValidator::new(self, infer, sink); validator.validate_body(db); } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index b9d3a17131..0de36abd16 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -214,17 +214,17 @@ impl SourceAnalyzer { pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option { let expr_id = self.expr_id(&call.clone().into())?; - self.infer.as_ref()?.method_resolution(expr_id) + self.infer.as_ref()?.method_resolution(expr_id).map(Function::from) } pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option { let expr_id = self.expr_id(&field.clone().into())?; - self.infer.as_ref()?.field_resolution(expr_id) + self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into()) } pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option { let expr_id = self.expr_id(&field.expr()?)?; - self.infer.as_ref()?.record_field_resolution(expr_id) + self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) } pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option { diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index db9a8c9d1e..7b6dfd61b9 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -22,11 +22,13 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; use rustc_hash::FxHashMap; use hir_def::{ + body::Body, data::{ConstData, FunctionData}, - path::known, + expr::{BindingAnnotation, ExprId, PatId}, + path::{known, Path}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{Mutability, TypeRef}, - AdtId, AssocItemId, DefWithBodyId, + AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, }; use hir_expand::{diagnostics::DiagnosticSink, name}; use ra_arena::map::ArenaMap; @@ -34,16 +36,14 @@ use ra_prof::profile; use test_utils::tested_by; use super::{ + primitive::{FloatTy, IntTy}, traits::{Guidance, Obligation, ProjectionPredicate, Solution}, ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }; use crate::{ - code_model::TypeAlias, - db::HirDatabase, - expr::{BindingAnnotation, Body, ExprId, PatId}, - ty::infer::diagnostics::InferenceDiagnostic, - AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, + db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic, AssocItem, DefWithBody, + VariantDef, }; macro_rules! ty_app { @@ -121,11 +121,11 @@ pub struct TypeMismatch { #[derive(Clone, PartialEq, Eq, Debug, Default)] pub struct InferenceResult { /// For each method call expr, records the function it resolves to. - method_resolutions: FxHashMap, + method_resolutions: FxHashMap, /// For each field access expr, records the field it resolves to. - field_resolutions: FxHashMap, + field_resolutions: FxHashMap, /// For each field in record literal, records the field it resolves to. - record_field_resolutions: FxHashMap, + record_field_resolutions: FxHashMap, /// For each struct literal, records the variant it resolves to. variant_resolutions: FxHashMap, /// For each associated item record what it resolves to @@ -137,13 +137,13 @@ pub struct InferenceResult { } impl InferenceResult { - pub fn method_resolution(&self, expr: ExprId) -> Option { + pub fn method_resolution(&self, expr: ExprId) -> Option { self.method_resolutions.get(&expr).copied() } - pub fn field_resolution(&self, expr: ExprId) -> Option { + pub fn field_resolution(&self, expr: ExprId) -> Option { self.field_resolutions.get(&expr).copied() } - pub fn record_field_resolution(&self, expr: ExprId) -> Option { + pub fn record_field_resolution(&self, expr: ExprId) -> Option { self.record_field_resolutions.get(&expr).copied() } pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option { @@ -164,7 +164,7 @@ impl InferenceResult { pub(crate) fn add_diagnostics( &self, db: &impl HirDatabase, - owner: Function, + owner: FunctionId, sink: &mut DiagnosticSink, ) { self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) @@ -243,11 +243,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.result.type_of_expr.insert(expr, ty); } - fn write_method_resolution(&mut self, expr: ExprId, func: Function) { + fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId) { self.result.method_resolutions.insert(expr, func); } - fn write_field_resolution(&mut self, expr: ExprId, field: StructField) { + fn write_field_resolution(&mut self, expr: ExprId, field: StructFieldId) { self.result.field_resolutions.insert(expr, field); } @@ -557,22 +557,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); } - fn resolve_into_iter_item(&self) -> Option { + fn resolve_into_iter_item(&self) -> Option { let path = known::std_iter_into_iterator(); let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; - self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE).map(TypeAlias::from) + self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE) } - fn resolve_ops_try_ok(&self) -> Option { + fn resolve_ops_try_ok(&self) -> Option { let path = known::std_ops_try(); let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; - self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE).map(TypeAlias::from) + self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE) } - fn resolve_future_future_output(&self) -> Option { + fn resolve_future_future_output(&self) -> Option { let path = known::std_future_future(); let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; - self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE).map(TypeAlias::from) + self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE) } fn resolve_boxed_box(&self) -> Option { @@ -696,9 +696,10 @@ impl Expectation { } mod diagnostics { + use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup}; use hir_expand::diagnostics::DiagnosticSink; - use crate::{db::HirDatabase, diagnostics::NoSuchField, expr::ExprId, Function, HasSource}; + use crate::{db::HirDatabase, diagnostics::NoSuchField}; #[derive(Debug, PartialEq, Eq, Clone)] pub(super) enum InferenceDiagnostic { @@ -709,13 +710,14 @@ mod diagnostics { pub(super) fn add_to( &self, db: &impl HirDatabase, - owner: Function, + owner: FunctionId, sink: &mut DiagnosticSink, ) { match self { InferenceDiagnostic::NoSuchField { expr, field } => { - let file = owner.source(db).file_id; - let field = owner.body_source_map(db).field_syntax(*expr, *field); + let file = owner.lookup(db).source(db).file_id; + let (_, source_map) = db.body_with_source_map(owner.into()); + let field = source_map.field_syntax(*expr, *field); sink.push(NoSuchField { file, field }) } } diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 57f845dfa4..d9ea6da423 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -100,7 +100,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: pat_ty.clone(), projection_ty: ProjectionTy { - associated_ty: into_iter_item_alias.id, + associated_ty: into_iter_item_alias, parameters: Substs::single(iterable_ty), }, }; @@ -230,7 +230,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } }); if let Some(field_def) = field_def { - self.result.record_field_resolutions.insert(field.expr, field_def); + self.result.record_field_resolutions.insert(field.expr, field_def.into()); } let field_ty = field_def .map_or(Ty::Unknown, |it| field_types[it.id].clone()) @@ -262,7 +262,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.db.struct_data(s).variant_data.field(name).map(|local_id| { let field = StructFieldId { parent: s.into(), local_id }.into(); self.write_field_resolution(tgt_expr, field); - self.db.field_types(s.into())[field.id] + self.db.field_types(s.into())[field.local_id] .clone() .subst(&a_ty.parameters) }) @@ -285,7 +285,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: ty.clone(), projection_ty: ProjectionTy { - associated_ty: future_future_output_alias.id, + associated_ty: future_future_output_alias, parameters: Substs::single(inner_ty), }, }; @@ -304,7 +304,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: ty.clone(), projection_ty: ProjectionTy { - associated_ty: ops_try_ok_alias.id, + associated_ty: ops_try_ok_alias, parameters: Substs::single(inner_ty), }, }; @@ -557,7 +557,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Some((ty, func)) => { let ty = canonicalized_receiver.decanonicalize_ty(ty); self.write_method_resolution(tgt_expr, func); - (ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into()))) + (ty, self.db.value_ty(func.into()), Some(self.db.generic_params(func.into()))) } None => (receiver_ty, Ty::Unknown, None), }; diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 02e81fb341..5cc2498552 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use arrayvec::ArrayVec; use hir_def::{ lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability, - AssocItemId, AstItemDef, HasModule, ImplId, TraitId, + AssocItemId, AstItemDef, FunctionId, HasModule, ImplId, TraitId, }; use hir_expand::name::Name; use ra_db::CrateId; @@ -18,7 +18,6 @@ use crate::{ db::HirDatabase, ty::primitive::{FloatBitness, Uncertain}, ty::{utils::all_super_traits, Ty, TypeCtor}, - Function, }; use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; @@ -154,10 +153,10 @@ pub(crate) fn lookup_method( db: &impl HirDatabase, name: &Name, resolver: &Resolver, -) -> Option<(Ty, Function)> { +) -> Option<(Ty, FunctionId)> { iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f { - AssocItemId::FunctionId(f) => Some((ty.clone(), f.into())), + AssocItemId::FunctionId(f) => Some((ty.clone(), f)), _ => None, }) } From 17680f6060be1abe8f021538aeff0a95e9c569da Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 16:02:33 +0300 Subject: [PATCH 52/65] More decoupling --- crates/ra_hir/src/code_model.rs | 10 +++++----- crates/ra_hir/src/db.rs | 17 +++++++---------- crates/ra_hir/src/source_binder.rs | 6 +++--- crates/ra_hir/src/ty/infer.rs | 27 ++++++++++++--------------- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 6d71bde921..0e987240a6 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -618,7 +618,7 @@ impl Function { } pub fn infer(self, db: &impl HirDatabase) -> Arc { - db.infer(self.into()) + db.infer(self.id.into()) } /// The containing impl block, if this is a method. @@ -672,7 +672,7 @@ impl Const { } pub fn infer(self, db: &impl HirDatabase) -> Arc { - db.infer(self.into()) + db.infer(self.id.into()) } /// The containing impl block, if this is a type alias. @@ -715,7 +715,7 @@ impl Static { } pub fn infer(self, db: &impl HirDatabase) -> Arc { - db.infer(self.into()) + db.infer(self.id.into()) } } @@ -908,9 +908,9 @@ impl Local { } pub fn ty(self, db: &impl HirDatabase) -> Type { - let infer = db.infer(self.parent); - let ty = infer[self.pat_id].clone(); let def = DefWithBodyId::from(self.parent); + let infer = db.infer(def); + let ty = infer[self.pat_id].clone(); let resolver = def.resolver(db); let krate = def.module(db).krate; let environment = TraitEnvironment::lower(db, &resolver); diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a5bfef91f6..e192c8f470 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -2,18 +2,15 @@ use std::sync::Arc; -use hir_def::{GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; +use hir_def::{DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; use ra_arena::map::ArenaMap; use ra_db::{salsa, CrateId}; -use crate::{ - ty::{ - method_resolution::CrateImplBlocks, - traits::{AssocTyValue, Impl}, - CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, - ValueTyDefId, - }, - DefWithBody, +use crate::ty::{ + method_resolution::CrateImplBlocks, + traits::{AssocTyValue, Impl}, + CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, + ValueTyDefId, }; pub use hir_def::db::{ @@ -32,7 +29,7 @@ pub use hir_expand::db::{ #[salsa::requires(salsa::Database)] pub trait HirDatabase: DefDatabase { #[salsa::invoke(crate::ty::infer_query)] - fn infer(&self, def: DefWithBody) -> Arc; + fn infer(&self, def: DefWithBodyId) -> Arc; #[salsa::invoke(crate::ty::ty_query)] fn ty(&self, def: TyDefId) -> Ty; diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 0de36abd16..c85e38a0da 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -168,7 +168,7 @@ impl SourceAnalyzer { resolver, body_owner: Some(def), body_source_map: Some(source_map), - infer: Some(db.infer(def)), + infer: Some(db.infer(def.into())), scopes: Some(scopes), file_id: node.file_id, } @@ -297,13 +297,13 @@ impl SourceAnalyzer { if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { let expr_id = self.expr_id(&path_expr.into())?; if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { - return Some(PathResolution::AssocItem(assoc)); + return Some(PathResolution::AssocItem(assoc.into())); } } if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { let pat_id = self.pat_id(&path_pat.into())?; if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { - return Some(PathResolution::AssocItem(assoc)); + return Some(PathResolution::AssocItem(assoc.into())); } } // This must be a normal source file rather than macro file. diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 7b6dfd61b9..1eca4883d4 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -41,10 +41,7 @@ use super::{ ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }; -use crate::{ - db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic, AssocItem, DefWithBody, - VariantDef, -}; +use crate::{db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic, VariantDef}; macro_rules! ty_app { ($ctor:pat, $param:pat) => { @@ -62,15 +59,15 @@ mod pat; mod coerce; /// The entry point of type inference. -pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc { +pub fn infer_query(db: &impl HirDatabase, def: DefWithBodyId) -> Arc { let _p = profile("infer_query"); - let resolver = DefWithBodyId::from(def).resolver(db); + let resolver = def.resolver(db); let mut ctx = InferenceContext::new(db, def, resolver); - match &def { - DefWithBody::Const(c) => ctx.collect_const(&db.const_data(c.id)), - DefWithBody::Function(f) => ctx.collect_fn(&db.function_data(f.id)), - DefWithBody::Static(s) => ctx.collect_const(&db.static_data(s.id)), + match def { + DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)), + DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)), + DefWithBodyId::StaticId(s) => ctx.collect_const(&db.static_data(s)), } ctx.infer_body(); @@ -129,7 +126,7 @@ pub struct InferenceResult { /// For each struct literal, records the variant it resolves to. variant_resolutions: FxHashMap, /// For each associated item record what it resolves to - assoc_resolutions: FxHashMap, + assoc_resolutions: FxHashMap, diagnostics: Vec, pub(super) type_of_expr: ArenaMap, pub(super) type_of_pat: ArenaMap, @@ -152,10 +149,10 @@ impl InferenceResult { pub fn variant_resolution_for_pat(&self, id: PatId) -> Option { self.variant_resolutions.get(&id.into()).copied() } - pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option { + pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option { self.assoc_resolutions.get(&id.into()).copied() } - pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option { + pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option { self.assoc_resolutions.get(&id.into()).copied() } pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { @@ -191,7 +188,7 @@ impl Index for InferenceResult { #[derive(Clone, Debug)] struct InferenceContext<'a, D: HirDatabase> { db: &'a D, - owner: DefWithBody, + owner: DefWithBodyId, body: Arc, resolver: Resolver, var_unification_table: InPlaceUnificationTable, @@ -209,7 +206,7 @@ struct InferenceContext<'a, D: HirDatabase> { } impl<'a, D: HirDatabase> InferenceContext<'a, D> { - fn new(db: &'a D, owner: DefWithBody, resolver: Resolver) -> Self { + fn new(db: &'a D, owner: DefWithBodyId, resolver: Resolver) -> Self { InferenceContext { result: InferenceResult::default(), var_unification_table: InPlaceUnificationTable::new(), From 9fa46ff5c67bd1809cc748f6fc0e93d7c9be3fdb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 16:25:01 +0300 Subject: [PATCH 53/65] Use Id for variats --- crates/ra_hir/src/code_model.rs | 8 ------- crates/ra_hir/src/source_binder.rs | 4 ++-- crates/ra_hir/src/ty/infer.rs | 18 ++++++++-------- crates/ra_hir/src/ty/infer/expr.rs | 34 +++++++++++++++++------------- crates/ra_hir/src/ty/infer/pat.rs | 20 ++++++++++-------- crates/ra_hir/src/ty/lower.rs | 14 ++++++------ crates/ra_hir/src/ty/utils.rs | 14 +++++++++++- 7 files changed, 60 insertions(+), 52 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 0e987240a6..52ad4e5d16 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -534,14 +534,6 @@ impl VariantDef { } } - pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option { - match self { - VariantDef::Struct(it) => it.field(db, name), - VariantDef::Union(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), diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index c85e38a0da..05f5bca575 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -229,12 +229,12 @@ impl SourceAnalyzer { pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option { let expr_id = self.expr_id(&record_lit.clone().into())?; - self.infer.as_ref()?.variant_resolution_for_expr(expr_id) + self.infer.as_ref()?.variant_resolution_for_expr(expr_id).map(|it| it.into()) } pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option { let pat_id = self.pat_id(&record_pat.clone().into())?; - self.infer.as_ref()?.variant_resolution_for_pat(pat_id) + self.infer.as_ref()?.variant_resolution_for_pat(pat_id).map(|it| it.into()) } pub fn resolve_macro_call( diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 1eca4883d4..59e4e5f36b 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -28,7 +28,7 @@ use hir_def::{ path::{known, Path}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{Mutability, TypeRef}, - AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, + AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId, }; use hir_expand::{diagnostics::DiagnosticSink, name}; use ra_arena::map::ArenaMap; @@ -41,7 +41,7 @@ use super::{ ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }; -use crate::{db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic, VariantDef}; +use crate::{db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic}; macro_rules! ty_app { ($ctor:pat, $param:pat) => { @@ -124,7 +124,7 @@ pub struct InferenceResult { /// For each field in record literal, records the field it resolves to. record_field_resolutions: FxHashMap, /// For each struct literal, records the variant it resolves to. - variant_resolutions: FxHashMap, + variant_resolutions: FxHashMap, /// For each associated item record what it resolves to assoc_resolutions: FxHashMap, diagnostics: Vec, @@ -143,10 +143,10 @@ impl InferenceResult { pub fn record_field_resolution(&self, expr: ExprId) -> Option { self.record_field_resolutions.get(&expr).copied() } - pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option { + pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option { self.variant_resolutions.get(&id.into()).copied() } - pub fn variant_resolution_for_pat(&self, id: PatId) -> Option { + pub fn variant_resolution_for_pat(&self, id: PatId) -> Option { self.variant_resolutions.get(&id.into()).copied() } pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option { @@ -248,7 +248,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.result.field_resolutions.insert(expr, field); } - fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantDef) { + fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) { self.result.variant_resolutions.insert(id, variant); } @@ -511,7 +511,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { }) } - fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option) { + fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option) { let path = match path { Some(path) => path, None => return (Ty::Unknown, None), @@ -524,13 +524,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); let ty = self.db.ty(strukt.into()); let ty = self.insert_type_vars(ty.apply_substs(substs)); - (ty, Some(VariantDef::Struct(strukt.into()))) + (ty, Some(strukt.into())) } Some(TypeNs::EnumVariantId(var)) => { let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); let ty = self.db.ty(var.parent.into()); let ty = self.insert_type_vars(ty.apply_substs(substs)); - (ty, Some(VariantDef::EnumVariant(var.into()))) + (ty, Some(var.into())) } Some(_) | None => (Ty::Unknown, None), } diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index d9ea6da423..f9ededa235 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -16,9 +16,9 @@ use hir_expand::name::{self, Name}; use crate::{ db::HirDatabase, ty::{ - autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, - Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, - TypeWalk, Uncertain, + autoderef, method_resolution, op, traits::InEnvironment, utils::variant_data, CallableDef, + InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, + TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }, }; @@ -218,22 +218,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let substs = ty.substs().unwrap_or_else(Substs::empty); let field_types = def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default(); + let variant_data = def_id.map(|it| variant_data(self.db, it)); for (field_idx, field) in fields.iter().enumerate() { - let field_def = def_id.and_then(|it| match it.field(self.db, &field.name) { - Some(field) => Some(field), - None => { - self.push_diagnostic(InferenceDiagnostic::NoSuchField { - expr: tgt_expr, - field: field_idx, - }); - None - } - }); + let field_def = + variant_data.as_ref().and_then(|it| match it.field(&field.name) { + Some(local_id) => { + Some(StructFieldId { parent: def_id.unwrap(), local_id }) + } + None => { + self.push_diagnostic(InferenceDiagnostic::NoSuchField { + expr: tgt_expr, + field: field_idx, + }); + None + } + }); if let Some(field_def) = field_def { - self.result.record_field_resolutions.insert(field.expr, field_def.into()); + self.result.record_field_resolutions.insert(field.expr, field_def); } let field_ty = field_def - .map_or(Ty::Unknown, |it| field_types[it.id].clone()) + .map_or(Ty::Unknown, |it| field_types[it.local_id].clone()) .subst(&substs); self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); } diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir/src/ty/infer/pat.rs index 6dbf03eb20..a147746077 100644 --- a/crates/ra_hir/src/ty/infer/pat.rs +++ b/crates/ra_hir/src/ty/infer/pat.rs @@ -14,7 +14,7 @@ use test_utils::tested_by; use super::{BindingMode, InferenceContext}; use crate::{ db::HirDatabase, - ty::{Substs, Ty, TypeCtor, TypeWalk}, + ty::{utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}, }; impl<'a, D: HirDatabase> InferenceContext<'a, D> { @@ -26,16 +26,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { default_bm: BindingMode, ) -> Ty { let (ty, def) = self.resolve_variant(path); - + let var_data = def.map(|it| variant_data(self.db, it)); self.unify(&ty, expected); let substs = ty.substs().unwrap_or_else(Substs::empty); let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); + for (i, &subpat) in subpats.iter().enumerate() { - let expected_ty = def - .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) - .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) + let expected_ty = var_data + .as_ref() + .and_then(|d| d.field(&Name::new_tuple_field(i))) + .map_or(Ty::Unknown, |field| field_tys[field].clone()) .subst(&substs); let expected_ty = self.normalize_associated_types_in(expected_ty); self.infer_pat(subpat, &expected_ty, default_bm); @@ -53,6 +55,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { id: PatId, ) -> Ty { let (ty, def) = self.resolve_variant(path); + let var_data = def.map(|it| variant_data(self.db, it)); if let Some(variant) = def { self.write_variant_resolution(id.into(), variant); } @@ -63,10 +66,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); for subpat in subpats { - let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); - let expected_ty = matching_field - .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) - .subst(&substs); + let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); + let expected_ty = + matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs); let expected_ty = self.normalize_associated_types_in(expected_ty); self.infer_pat(subpat.pat, &expected_ty, default_bm); } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 1c0f71adc2..d33b50794c 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -28,7 +28,7 @@ use crate::{ db::HirDatabase, ty::{ primitive::{FloatTy, IntTy}, - utils::{all_super_traits, associated_type_by_name_including_super_traits}, + utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, }, util::make_mut_slice, Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, @@ -514,13 +514,11 @@ pub(crate) fn field_types_query( db: &impl HirDatabase, variant_id: VariantId, ) -> Arc> { - let (resolver, var_data) = match variant_id { - VariantId::StructId(it) => (it.resolver(db), db.struct_data(it).variant_data.clone()), - VariantId::UnionId(it) => (it.resolver(db), db.union_data(it).variant_data.clone()), - VariantId::EnumVariantId(it) => ( - it.parent.resolver(db), - db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), - ), + let var_data = variant_data(db, variant_id); + let resolver = match variant_id { + VariantId::StructId(it) => it.resolver(db), + VariantId::UnionId(it) => it.resolver(db), + VariantId::EnumVariantId(it) => it.parent.resolver(db), }; let mut res = ArenaMap::default(); for (field_id, field_data) in var_data.fields().iter() { diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs index 80ffceb4bc..f82e6ac9b1 100644 --- a/crates/ra_hir/src/ty/utils.rs +++ b/crates/ra_hir/src/ty/utils.rs @@ -1,11 +1,13 @@ //! Helper functions for working with def, which don't need to be a separate //! query, but can't be computed directly from `*Data` (ie, which need a `db`). +use std::sync::Arc; use hir_def::{ + adt::VariantData, db::DefDatabase, resolver::{HasResolver, TypeNs}, type_ref::TypeRef, - TraitId, TypeAliasId, + TraitId, TypeAliasId, VariantId, }; use hir_expand::name::{self, Name}; @@ -61,3 +63,13 @@ pub(super) fn associated_type_by_name_including_super_traits( .into_iter() .find_map(|t| db.trait_data(t).associated_type_by_name(name)) } + +pub(super) fn variant_data(db: &impl DefDatabase, var: VariantId) -> Arc { + match var { + VariantId::StructId(it) => db.struct_data(it).variant_data.clone(), + VariantId::UnionId(it) => db.union_data(it).variant_data.clone(), + VariantId::EnumVariantId(it) => { + db.enum_data(it.parent).variants[it.local_id].variant_data.clone() + } + } +} From d6e8f27488f8bf4ae7024b9b7a9c4797c2b52b12 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 16:29:11 +0300 Subject: [PATCH 54/65] Cleanup imports --- crates/ra_hir/src/ty/lower.rs | 4 ++-- crates/ra_hir/src/ty/op.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index d33b50794c..d776b6cd07 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use hir_def::{ builtin_type::BuiltinType, generics::WherePredicate, - path::{GenericArg, PathSegment}, + path::{GenericArg, Path, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, @@ -31,7 +31,7 @@ use crate::{ utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, }, util::make_mut_slice, - Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, + Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Static, Struct, Trait, TypeAlias, Union, }; diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs index bcfa3a6a2a..80d4111a0d 100644 --- a/crates/ra_hir/src/ty/op.rs +++ b/crates/ra_hir/src/ty/op.rs @@ -1,8 +1,8 @@ //! FIXME: write short doc here +use hir_def::expr::{BinaryOp, CmpOp}; use super::{InferTy, Ty, TypeCtor}; use crate::{ - expr::{BinaryOp, CmpOp}, ty::ApplicationTy, }; From 12501fcdd02fec9d43dfd810d65e927ddebb1b56 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 16:39:58 +0300 Subject: [PATCH 55/65] Remove TypableDef --- crates/ra_hir/src/from_id.rs | 60 +++-------------------------------- crates/ra_hir/src/ty.rs | 2 +- crates/ra_hir/src/ty/lower.rs | 39 +---------------------- crates/ra_hir/src/ty/op.rs | 4 +-- 4 files changed, 7 insertions(+), 98 deletions(-) diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 38daa5e59f..e96a18d12a 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -4,13 +4,13 @@ //! are splitting the hir. use hir_def::{ - AdtId, AssocItemId, AttrDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, - GenericDefId, ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId, + AdtId, AssocItemId, AttrDefId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId, + StructFieldId, VariantId, }; use crate::{ - ty::TypableDef, Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, - GenericDef, ModuleDef, Static, StructField, TypeAlias, VariantDef, + Adt, AssocItem, AttrDef, Crate, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, + VariantDef, }; impl From for Crate { @@ -137,58 +137,6 @@ impl From for GenericDefId { } } -impl From for TypableDef { - fn from(id: AdtId) -> Self { - Adt::from(id).into() - } -} - -impl From for TypableDef { - fn from(id: StructId) -> Self { - AdtId::StructId(id).into() - } -} - -impl From for TypableDef { - fn from(id: UnionId) -> Self { - AdtId::UnionId(id).into() - } -} - -impl From for TypableDef { - fn from(id: EnumId) -> Self { - AdtId::EnumId(id).into() - } -} - -impl From for TypableDef { - fn from(id: EnumVariantId) -> Self { - EnumVariant::from(id).into() - } -} - -impl From for TypableDef { - fn from(id: TypeAliasId) -> Self { - TypeAlias::from(id).into() - } -} - -impl From for TypableDef { - fn from(id: FunctionId) -> Self { - Function::from(id).into() - } -} -impl From for TypableDef { - fn from(id: ConstId) -> Self { - Const::from(id).into() - } -} -impl From for TypableDef { - fn from(id: StaticId) -> Self { - Static::from(id).into() - } -} - impl From for GenericDefId { fn from(id: Adt) -> Self { match id { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index a26776b268..e4ba8afa61 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -38,7 +38,7 @@ pub use lower::CallableDef; pub(crate) use lower::{ callable_item_sig, field_types_query, generic_defaults_query, generic_predicates_for_param_query, generic_predicates_query, ty_query, value_ty_query, - TyDefId, TypableDef, ValueTyDefId, + TyDefId, ValueTyDefId, }; pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index d776b6cd07..5dce2f3423 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -31,8 +31,7 @@ use crate::{ utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, }, util::make_mut_slice, - Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Static, Struct, Trait, - TypeAlias, Union, + ImplBlock, Trait, }; impl Ty { @@ -693,42 +692,6 @@ fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { inner.subst(&substs) } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum TypableDef { - Function(Function), - Adt(Adt), - EnumVariant(EnumVariant), - TypeAlias(TypeAlias), - Const(Const), - Static(Static), - BuiltinType(BuiltinType), -} -impl_froms!( - TypableDef: Function, - Adt(Struct, Enum, Union), - EnumVariant, - TypeAlias, - Const, - Static, - BuiltinType -); - -impl From for Option { - fn from(def: ModuleDef) -> Option { - let res = match def { - ModuleDef::Function(f) => f.into(), - ModuleDef::Adt(adt) => adt.into(), - ModuleDef::EnumVariant(v) => v.into(), - ModuleDef::TypeAlias(t) => t.into(), - ModuleDef::Const(v) => v.into(), - ModuleDef::Static(v) => v.into(), - ModuleDef::BuiltinType(t) => t.into(), - ModuleDef::Module(_) | ModuleDef::Trait(_) => return None, - }; - Some(res) - } -} - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum CallableDef { FunctionId(FunctionId), diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs index 80d4111a0d..cc6e244f44 100644 --- a/crates/ra_hir/src/ty/op.rs +++ b/crates/ra_hir/src/ty/op.rs @@ -2,9 +2,7 @@ use hir_def::expr::{BinaryOp, CmpOp}; use super::{InferTy, Ty, TypeCtor}; -use crate::{ - ty::ApplicationTy, -}; +use crate::ty::ApplicationTy; pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { match op { From 368653081558ab389c6543d6b5027859e26beb3b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 16:48:48 +0300 Subject: [PATCH 56/65] Decouple --- crates/ra_hir/src/ty/lower.rs | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 5dce2f3423..2d447f1ea7 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -31,7 +31,6 @@ use crate::{ utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, }, util::make_mut_slice, - ImplBlock, Trait, }; impl Ty { @@ -148,13 +147,8 @@ impl Ty { ) -> Ty { let ty = match resolution { TypeNs::TraitId(trait_) => { - let trait_ref = TraitRef::from_resolved_path( - db, - resolver, - trait_.into(), - resolved_segment, - None, - ); + let trait_ref = + TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); return if remaining_segments.len() == 1 { let segment = &remaining_segments[0]; let associated_ty = associated_type_by_name_including_super_traits( @@ -187,7 +181,11 @@ impl Ty { let name = resolved_segment.name.clone(); Ty::Param { idx, name } } - TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db), + TypeNs::SelfType(impl_id) => { + let impl_data = db.impl_data(impl_id); + let resolver = impl_id.resolver(db); + Ty::from_hir(db, &resolver, &impl_data.target_type) + } TypeNs::AdtSelfType(adt) => db.ty(adt.into()), TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), @@ -250,14 +248,11 @@ impl Ty { GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), _ => None, }); - let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)).map(Trait::from); + let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)); for t in traits { - if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name) - { - let substs = Substs::build_for_def(db, t.id) - .push(self_ty.clone()) - .fill_with_unknown() - .build(); + if let Some(associated_ty) = db.trait_data(t).associated_type_by_name(&segment.name) { + let substs = + Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); // FIXME handle type parameters on the segment return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); } @@ -391,7 +386,7 @@ impl TraitRef { pub(super) fn from_resolved_path( db: &impl HirDatabase, resolver: &Resolver, - resolved: Trait, + resolved: TraitId, segment: &PathSegment, explicit_self_ty: Option, ) -> Self { @@ -399,7 +394,7 @@ impl TraitRef { if let Some(self_ty) = explicit_self_ty { make_mut_slice(&mut substs.0)[0] = self_ty; } - TraitRef { trait_: resolved.id, substs } + TraitRef { trait_: resolved, substs } } pub(crate) fn from_hir( @@ -419,11 +414,11 @@ impl TraitRef { db: &impl HirDatabase, resolver: &Resolver, segment: &PathSegment, - resolved: Trait, + resolved: TraitId, ) -> Substs { let has_self_param = segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); - substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param) + substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) } pub(crate) fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef { From a87579500a2c35597071efd0ad6983927f0c1815 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 17:46:02 +0300 Subject: [PATCH 57/65] Move Ty --- Cargo.lock | 1 + crates/ra_hir/src/code_model.rs | 47 +- crates/ra_hir/src/db.rs | 117 +- crates/ra_hir/src/diagnostics.rs | 91 +- crates/ra_hir/src/lib.rs | 9 +- crates/ra_hir/src/source_binder.rs | 22 +- crates/ra_hir/src/ty.rs | 1111 +--------------- crates/ra_hir/src/ty/primitive.rs | 3 - crates/ra_hir/src/util.rs | 12 - crates/ra_hir_def/src/lib.rs | 2 +- crates/ra_hir_ty/Cargo.toml | 1 + .../src/ty => ra_hir_ty/src}/autoderef.rs | 2 +- crates/ra_hir_ty/src/db.rs | 116 ++ crates/ra_hir_ty/src/diagnostics.rs | 91 ++ .../src/ty => ra_hir_ty/src}/display.rs | 0 crates/{ra_hir => ra_hir_ty}/src/expr.rs | 41 +- .../{ra_hir/src/ty => ra_hir_ty/src}/infer.rs | 10 +- .../src/ty => ra_hir_ty/src}/infer/coerce.rs | 5 +- .../src/ty => ra_hir_ty/src}/infer/expr.rs | 9 +- .../src/ty => ra_hir_ty/src}/infer/pat.rs | 5 +- .../src/ty => ra_hir_ty/src}/infer/path.rs | 9 +- .../src/ty => ra_hir_ty/src}/infer/unify.rs | 8 +- crates/ra_hir_ty/src/lib.rs | 1134 ++++++++++++++++- .../{ra_hir/src/ty => ra_hir_ty/src}/lower.rs | 22 +- crates/{ra_hir => ra_hir_ty}/src/marks.rs | 0 .../ty => ra_hir_ty/src}/method_resolution.rs | 11 +- crates/{ra_hir/src/ty => ra_hir_ty/src}/op.rs | 2 +- crates/{ra_hir => ra_hir_ty}/src/test_db.rs | 71 +- .../{ra_hir/src/ty => ra_hir_ty/src}/tests.rs | 110 +- .../ty => ra_hir_ty/src}/tests/coercion.rs | 0 .../ty => ra_hir_ty/src}/tests/never_type.rs | 0 .../src/ty => ra_hir_ty/src}/traits.rs | 0 .../src/ty => ra_hir_ty/src}/traits/chalk.rs | 30 +- .../{ra_hir/src/ty => ra_hir_ty/src}/utils.rs | 9 + crates/ra_ide_api/src/impls.rs | 17 +- xtask/tests/tidy-tests/docs.rs | 1 + 36 files changed, 1603 insertions(+), 1516 deletions(-) delete mode 100644 crates/ra_hir/src/ty/primitive.rs delete mode 100644 crates/ra_hir/src/util.rs rename crates/{ra_hir/src/ty => ra_hir_ty/src}/autoderef.rs (99%) create mode 100644 crates/ra_hir_ty/src/db.rs create mode 100644 crates/ra_hir_ty/src/diagnostics.rs rename crates/{ra_hir/src/ty => ra_hir_ty/src}/display.rs (100%) rename crates/{ra_hir => ra_hir_ty}/src/expr.rs (81%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/infer.rs (98%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/infer/coerce.rs (99%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/infer/expr.rs (99%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/infer/pat.rs (98%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/infer/path.rs (97%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/infer/unify.rs (96%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/lower.rs (97%) rename crates/{ra_hir => ra_hir_ty}/src/marks.rs (100%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/method_resolution.rs (98%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/op.rs (98%) rename crates/{ra_hir => ra_hir_ty}/src/test_db.rs (59%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/tests.rs (96%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/tests/coercion.rs (100%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/tests/never_type.rs (100%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/traits.rs (100%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/traits/chalk.rs (96%) rename crates/{ra_hir/src/ty => ra_hir_ty/src}/utils.rs (89%) diff --git a/Cargo.lock b/Cargo.lock index f751be2e38..c9227c911d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1023,6 +1023,7 @@ dependencies = [ name = "ra_hir_ty" version = "0.1.0" dependencies = [ + "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", "chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 52ad4e5d16..87c78d98e1 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -6,8 +6,10 @@ use std::sync::Arc; use hir_def::{ adt::VariantData, + body::{Body, BodySourceMap}, builtin_type::BuiltinType, docs::Documentation, + expr::{BindingAnnotation, Pat, PatId}, per_ns::PerNs, resolver::HasResolver, type_ref::{Mutability, TypeRef}, @@ -20,12 +22,12 @@ use hir_expand::{ name::{self, AsName}, AstId, MacroDefId, }; +use hir_ty::expr::ExprValidator; use ra_db::{CrateId, Edition, FileId, FilePosition}; use ra_syntax::{ast, AstNode, SyntaxNode}; use crate::{ db::{DefDatabase, HirDatabase}, - expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, ty::display::HirFormatter, ty::{ self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TyDefId, TypeCtor, @@ -353,8 +355,8 @@ impl Struct { .map(|(id, _)| StructField { parent: self.into(), id }) } - pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.ty(self.id.into()) + pub fn ty(self, db: &impl HirDatabase) -> Type { + Type::from_def(db, self.id.module(db).krate, self.id) } pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { @@ -380,8 +382,8 @@ impl Union { Module { id: self.id.module(db) } } - pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.ty(self.id.into()) + pub fn ty(self, db: &impl HirDatabase) -> Type { + Type::from_def(db, self.id.module(db).krate, self.id) } pub fn fields(self, db: &impl HirDatabase) -> Vec { @@ -441,8 +443,8 @@ impl Enum { .map(|(id, _)| EnumVariant { parent: self, id }) } - pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.ty(self.id.into()) + pub fn ty(self, db: &impl HirDatabase) -> Type { + Type::from_def(db, self.id.module(db).krate, self.id) } } @@ -640,7 +642,7 @@ impl Function { pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { let infer = self.infer(db); infer.add_diagnostics(db, self.id, sink); - let mut validator = ExprValidator::new(self, infer, sink); + let mut validator = ExprValidator::new(self.id, infer, sink); validator.validate_body(db); } } @@ -946,13 +948,12 @@ impl ImplBlock { db.impl_data(self.id).target_type.clone() } - pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { - Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) - } - - pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option { - let target_ty = self.target_ty(db); - TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) + pub fn target_ty(&self, db: &impl HirDatabase) -> Type { + let impl_data = db.impl_data(self.id); + let resolver = self.id.resolver(db); + let environment = TraitEnvironment::lower(db, &resolver); + let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); + Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } } } pub fn items(&self, db: &impl DefDatabase) -> Vec { @@ -1130,6 +1131,22 @@ impl Type { Some(adt.into()) } + // FIXME: provide required accessors such that it becomes implementable from outside. + pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { + match (&self.ty.value, &other.ty.value) { + (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => { + match ctor { + TypeCtor::Ref(..) => match parameters.as_single() { + Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, + _ => false, + }, + _ => a_original_ty.ctor == *ctor, + } + } + _ => false, + } + } + fn derived(&self, ty: Ty) -> Type { Type { krate: self.krate, diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index e192c8f470..bfae3660b4 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -1,18 +1,5 @@ //! FIXME: write short doc here -use std::sync::Arc; - -use hir_def::{DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; -use ra_arena::map::ArenaMap; -use ra_db::{salsa, CrateId}; - -use crate::ty::{ - method_resolution::CrateImplBlocks, - traits::{AssocTyValue, Impl}, - CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, - ValueTyDefId, -}; - pub use hir_def::db::{ BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, @@ -24,104 +11,12 @@ pub use hir_expand::db::{ AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery, }; - -#[salsa::query_group(HirDatabaseStorage)] -#[salsa::requires(salsa::Database)] -pub trait HirDatabase: DefDatabase { - #[salsa::invoke(crate::ty::infer_query)] - fn infer(&self, def: DefWithBodyId) -> Arc; - - #[salsa::invoke(crate::ty::ty_query)] - fn ty(&self, def: TyDefId) -> Ty; - - #[salsa::invoke(crate::ty::value_ty_query)] - fn value_ty(&self, def: ValueTyDefId) -> Ty; - - #[salsa::invoke(crate::ty::field_types_query)] - fn field_types(&self, var: VariantId) -> Arc>; - - #[salsa::invoke(crate::ty::callable_item_sig)] - fn callable_item_signature(&self, def: CallableDef) -> FnSig; - - #[salsa::invoke(crate::ty::generic_predicates_for_param_query)] - fn generic_predicates_for_param( - &self, - def: GenericDefId, - param_idx: u32, - ) -> Arc<[GenericPredicate]>; - - #[salsa::invoke(crate::ty::generic_predicates_query)] - fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>; - - #[salsa::invoke(crate::ty::generic_defaults_query)] - fn generic_defaults(&self, def: GenericDefId) -> Substs; - - #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] - fn impls_in_crate(&self, krate: CrateId) -> Arc; - - #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] - fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplId]>; - - /// This provides the Chalk trait solver instance. Because Chalk always - /// works from a specific crate, this query is keyed on the crate; and - /// because Chalk does its own internal caching, the solver is wrapped in a - /// Mutex and the query does an untracked read internally, to make sure the - /// cached state is thrown away when input facts change. - #[salsa::invoke(crate::ty::traits::trait_solver_query)] - fn trait_solver(&self, krate: CrateId) -> crate::ty::traits::TraitSolver; - - // Interned IDs for Chalk integration - #[salsa::interned] - fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::ty::TypeCtorId; - #[salsa::interned] - fn intern_chalk_impl(&self, impl_: Impl) -> crate::ty::traits::GlobalImplId; - #[salsa::interned] - fn intern_assoc_ty_value( - &self, - assoc_ty_value: AssocTyValue, - ) -> crate::ty::traits::AssocTyValueId; - - #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] - fn associated_ty_data( - &self, - id: chalk_ir::TypeId, - ) -> Arc>; - - #[salsa::invoke(crate::ty::traits::chalk::trait_datum_query)] - fn trait_datum( - &self, - krate: CrateId, - trait_id: chalk_ir::TraitId, - ) -> Arc>; - - #[salsa::invoke(crate::ty::traits::chalk::struct_datum_query)] - fn struct_datum( - &self, - krate: CrateId, - struct_id: chalk_ir::StructId, - ) -> Arc>; - - #[salsa::invoke(crate::ty::traits::chalk::impl_datum_query)] - fn impl_datum( - &self, - krate: CrateId, - impl_id: chalk_ir::ImplId, - ) -> Arc>; - - #[salsa::invoke(crate::ty::traits::chalk::associated_ty_value_query)] - fn associated_ty_value( - &self, - krate: CrateId, - id: chalk_rust_ir::AssociatedTyValueId, - ) -> Arc>; - - #[salsa::invoke(crate::ty::traits::trait_solve_query)] - fn trait_solve( - &self, - krate: CrateId, - goal: crate::ty::Canonical>, - ) -> Option; -} +pub use hir_ty::db::{ + AssociatedTyDataQuery, CallableItemSignatureQuery, FieldTypesQuery, GenericDefaultsQuery, + GenericPredicatesQuery, HirDatabase, HirDatabaseStorage, ImplDatumQuery, ImplsForTraitQuery, + ImplsInCrateQuery, InferQuery, StructDatumQuery, TraitDatumQuery, TraitSolveQuery, TyQuery, + ValueTyQuery, +}; #[test] fn hir_database_is_object_safe() { diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index 6db499e060..a9040ea3d5 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs @@ -1,93 +1,4 @@ //! FIXME: write short doc here - -use std::any::Any; - -use hir_expand::HirFileId; -use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; - -use crate::{db::AstDatabase, Name, Source}; - pub use hir_def::diagnostics::UnresolvedModule; pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; - -#[derive(Debug)] -pub struct NoSuchField { - pub file: HirFileId, - pub field: AstPtr, -} - -impl Diagnostic for NoSuchField { - fn message(&self) -> String { - "no such field".to_string() - } - - fn source(&self) -> Source { - Source { file_id: self.file, value: self.field.into() } - } - - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct MissingFields { - pub file: HirFileId, - pub field_list: AstPtr, - pub missed_fields: Vec, -} - -impl Diagnostic for MissingFields { - fn message(&self) -> String { - use std::fmt::Write; - let mut message = String::from("Missing structure fields:\n"); - for field in &self.missed_fields { - write!(message, "- {}\n", field).unwrap(); - } - message - } - fn source(&self) -> Source { - Source { file_id: self.file, value: self.field_list.into() } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -impl AstDiagnostic for MissingFields { - type AST = ast::RecordFieldList; - - fn ast(&self, db: &impl AstDatabase) -> Self::AST { - let root = db.parse_or_expand(self.source().file_id).unwrap(); - let node = self.source().value.to_node(&root); - ast::RecordFieldList::cast(node).unwrap() - } -} - -#[derive(Debug)] -pub struct MissingOkInTailExpr { - pub file: HirFileId, - pub expr: AstPtr, -} - -impl Diagnostic for MissingOkInTailExpr { - fn message(&self) -> String { - "wrap return expression in Ok".to_string() - } - fn source(&self) -> Source { - Source { file_id: self.file, value: self.expr.into() } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -impl AstDiagnostic for MissingOkInTailExpr { - type AST = ast::Expr; - - fn ast(&self, db: &impl AstDatabase) -> Self::AST { - let root = db.parse_or_expand(self.file).unwrap(); - let node = self.source().value.to_node(&root); - ast::Expr::cast(node).unwrap() - } -} +pub use hir_ty::diagnostics::{MissingFields, MissingOkInTailExpr, NoSuchField}; diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index b88e4c745a..3c12c61f03 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -32,20 +32,13 @@ pub mod db; pub mod source_binder; mod ty; -mod expr; pub mod diagnostics; -mod util; mod from_id; mod code_model; pub mod from_source; -#[cfg(test)] -mod test_db; -#[cfg(test)] -mod marks; - pub use crate::{ code_model::{ src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, @@ -53,7 +46,6 @@ pub use crate::{ HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, Union, VariantDef, }, - expr::ExprScopes, from_source::FromSource, source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, ty::{ @@ -64,6 +56,7 @@ pub use crate::{ }; pub use hir_def::{ + body::scope::ExprScopes, builtin_type::BuiltinType, docs::Documentation, path::{Path, PathKind}, diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 05f5bca575..76c493f1a8 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -8,6 +8,10 @@ use std::sync::Arc; use hir_def::{ + body::{ + scope::{ExprScopes, ScopeId}, + BodySourceMap, + }, expr::{ExprId, PatId}, path::known, resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, @@ -25,7 +29,6 @@ use ra_syntax::{ use crate::{ db::HirDatabase, - expr::{BodySourceMap, ExprScopes, ScopeId}, ty::{ method_resolution::{self, implements_trait}, InEnvironment, TraitEnvironment, Ty, @@ -91,7 +94,7 @@ pub struct SourceAnalyzer { body_owner: Option, body_source_map: Option>, infer: Option>, - scopes: Option>, + scopes: Option>, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -455,21 +458,6 @@ impl SourceAnalyzer { macro_file_kind: to_macro_file_kind(macro_call.value), }) } - - #[cfg(test)] - pub(crate) fn body_source_map(&self) -> Arc { - self.body_source_map.clone().unwrap() - } - - #[cfg(test)] - 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 e4ba8afa61..4ed69c00dc 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -1,1113 +1,4 @@ //! The type system. We currently use this to infer types for completion, hover //! information and various assists. -mod autoderef; -pub(crate) mod primitive; -pub(crate) mod traits; -pub(crate) mod method_resolution; -mod op; -mod lower; -mod infer; -pub(crate) mod display; -pub(crate) mod utils; - -#[cfg(test)] -mod tests; - -use std::ops::Deref; -use std::sync::Arc; -use std::{fmt, iter, mem}; - -use hir_def::{ - expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, - GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, -}; -use hir_expand::name::Name; -use ra_db::{impl_intern_key, salsa, CrateId}; - -use crate::{ - db::HirDatabase, - ty::primitive::{FloatTy, IntTy, Uncertain}, - util::make_mut_slice, -}; -use display::{HirDisplay, HirFormatter}; - -pub(crate) use autoderef::autoderef; -pub(crate) use infer::{infer_query, InferTy, InferenceResult}; -pub use lower::CallableDef; -pub(crate) use lower::{ - callable_item_sig, field_types_query, generic_defaults_query, - generic_predicates_for_param_query, generic_predicates_query, ty_query, value_ty_query, - TyDefId, ValueTyDefId, -}; -pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; - -/// A type constructor or type name: this might be something like the primitive -/// type `bool`, a struct like `Vec`, or things like function pointers or -/// tuples. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] -pub enum TypeCtor { - /// The primitive boolean type. Written as `bool`. - Bool, - - /// The primitive character type; holds a Unicode scalar value - /// (a non-surrogate code point). Written as `char`. - Char, - - /// A primitive integer type. For example, `i32`. - Int(Uncertain), - - /// A primitive floating-point type. For example, `f64`. - Float(Uncertain), - - /// Structures, enumerations and unions. - Adt(AdtId), - - /// The pointee of a string slice. Written as `str`. - Str, - - /// The pointee of an array slice. Written as `[T]`. - Slice, - - /// An array with the given length. Written as `[T; n]`. - Array, - - /// A raw pointer. Written as `*mut T` or `*const T` - RawPtr(Mutability), - - /// A reference; a pointer with an associated lifetime. Written as - /// `&'a mut T` or `&'a T`. - Ref(Mutability), - - /// The anonymous type of a function declaration/definition. Each - /// function has a unique type, which is output (for a function - /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. - /// - /// This includes tuple struct / enum variant constructors as well. - /// - /// For example the type of `bar` here: - /// - /// ``` - /// fn foo() -> i32 { 1 } - /// let bar = foo; // bar: fn() -> i32 {foo} - /// ``` - FnDef(CallableDef), - - /// A pointer to a function. Written as `fn() -> i32`. - /// - /// For example the type of `bar` here: - /// - /// ``` - /// fn foo() -> i32 { 1 } - /// let bar: fn() -> i32 = foo; - /// ``` - FnPtr { num_args: u16 }, - - /// The never type `!`. - Never, - - /// A tuple type. For example, `(i32, bool)`. - Tuple { cardinality: u16 }, - - /// Represents an associated item like `Iterator::Item`. This is used - /// when we have tried to normalize a projection like `T::Item` but - /// couldn't find a better representation. In that case, we generate - /// an **application type** like `(Iterator::Item)`. - AssociatedType(TypeAliasId), - - /// The type of a specific closure. - /// - /// The closure signature is stored in a `FnPtr` type in the first type - /// parameter. - Closure { def: DefWithBodyId, expr: ExprId }, -} - -/// This exists just for Chalk, because Chalk just has a single `StructId` where -/// we have different kinds of ADTs, primitive types and special type -/// constructors like tuples and function pointers. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TypeCtorId(salsa::InternId); -impl_intern_key!(TypeCtorId); - -impl TypeCtor { - pub fn num_ty_params(self, db: &impl HirDatabase) -> usize { - match self { - TypeCtor::Bool - | TypeCtor::Char - | TypeCtor::Int(_) - | TypeCtor::Float(_) - | TypeCtor::Str - | TypeCtor::Never => 0, - TypeCtor::Slice - | TypeCtor::Array - | TypeCtor::RawPtr(_) - | TypeCtor::Ref(_) - | TypeCtor::Closure { .. } // 1 param representing the signature of the closure - => 1, - TypeCtor::Adt(adt) => { - let generic_params = db.generic_params(AdtId::from(adt).into()); - generic_params.count_params_including_parent() - } - TypeCtor::FnDef(callable) => { - let generic_params = db.generic_params(callable.into()); - generic_params.count_params_including_parent() - } - TypeCtor::AssociatedType(type_alias) => { - let generic_params = db.generic_params(type_alias.into()); - generic_params.count_params_including_parent() - } - TypeCtor::FnPtr { num_args } => num_args as usize + 1, - TypeCtor::Tuple { cardinality } => cardinality as usize, - } - } - - pub fn krate(self, db: &impl HirDatabase) -> Option { - match self { - TypeCtor::Bool - | TypeCtor::Char - | TypeCtor::Int(_) - | TypeCtor::Float(_) - | TypeCtor::Str - | TypeCtor::Never - | TypeCtor::Slice - | TypeCtor::Array - | TypeCtor::RawPtr(_) - | TypeCtor::Ref(_) - | TypeCtor::FnPtr { .. } - | TypeCtor::Tuple { .. } => None, - // Closure's krate is irrelevant for coherence I would think? - TypeCtor::Closure { .. } => None, - TypeCtor::Adt(adt) => Some(adt.module(db).krate), - TypeCtor::FnDef(callable) => Some(callable.krate(db)), - TypeCtor::AssociatedType(type_alias) => Some(type_alias.lookup(db).module(db).krate), - } - } - - pub fn as_generic_def(self) -> Option { - match self { - TypeCtor::Bool - | TypeCtor::Char - | TypeCtor::Int(_) - | TypeCtor::Float(_) - | TypeCtor::Str - | TypeCtor::Never - | TypeCtor::Slice - | TypeCtor::Array - | TypeCtor::RawPtr(_) - | TypeCtor::Ref(_) - | TypeCtor::FnPtr { .. } - | TypeCtor::Tuple { .. } - | TypeCtor::Closure { .. } => None, - TypeCtor::Adt(adt) => Some(adt.into()), - TypeCtor::FnDef(callable) => Some(callable.into()), - TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), - } - } -} - -/// A nominal type with (maybe 0) type parameters. This might be a primitive -/// type like `bool`, a struct, tuple, function pointer, reference or -/// several other things. -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct ApplicationTy { - pub ctor: TypeCtor, - pub parameters: Substs, -} - -/// A "projection" type corresponds to an (unnormalized) -/// projection like `>::Foo`. Note that the -/// trait and all its parameters are fully known. -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct ProjectionTy { - pub associated_ty: TypeAliasId, - pub parameters: Substs, -} - -impl ProjectionTy { - pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef { - TraitRef { trait_: self.trait_(db).into(), substs: self.parameters.clone() } - } - - fn trait_(&self, db: &impl HirDatabase) -> TraitId { - match self.associated_ty.lookup(db).container { - ContainerId::TraitId(it) => it, - _ => panic!("projection ty without parent trait"), - } - } -} - -impl TypeWalk for ProjectionTy { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.parameters.walk(f); - } - - fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { - self.parameters.walk_mut_binders(f, binders); - } -} - -/// A type. -/// -/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents -/// the same thing (but in a different way). -/// -/// This should be cheap to clone. -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub enum Ty { - /// A nominal type with (maybe 0) type parameters. This might be a primitive - /// type like `bool`, a struct, tuple, function pointer, reference or - /// several other things. - Apply(ApplicationTy), - - /// A "projection" type corresponds to an (unnormalized) - /// projection like `>::Foo`. Note that the - /// trait and all its parameters are fully known. - Projection(ProjectionTy), - - /// A type parameter; for example, `T` in `fn f(x: T) {} - Param { - /// The index of the parameter (starting with parameters from the - /// surrounding impl, then the current function). - idx: u32, - /// The name of the parameter, for displaying. - // FIXME get rid of this - name: Name, - }, - - /// A bound type variable. Used during trait resolution to represent Chalk - /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. - Bound(u32), - - /// A type variable used during type checking. Not to be confused with a - /// type parameter. - Infer(InferTy), - - /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). - /// - /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)` - /// represents the `Self` type inside the bounds. This is currently - /// implicit; Chalk has the `Binders` struct to make it explicit, but it - /// didn't seem worth the overhead yet. - Dyn(Arc<[GenericPredicate]>), - - /// An opaque type (`impl Trait`). - /// - /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for - /// more. - Opaque(Arc<[GenericPredicate]>), - - /// A placeholder for a type which could not be computed; this is propagated - /// to avoid useless error messages. Doubles as a placeholder where type - /// variables are inserted before type checking, since we want to try to - /// infer a better type here anyway -- for the IDE use case, we want to try - /// to infer as much as possible even in the presence of type errors. - Unknown, -} - -/// A list of substitutions for generic parameters. -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct Substs(Arc<[Ty]>); - -impl TypeWalk for Substs { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - for t in self.0.iter() { - t.walk(f); - } - } - - fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { - for t in make_mut_slice(&mut self.0) { - t.walk_mut_binders(f, binders); - } - } -} - -impl Substs { - pub fn empty() -> Substs { - Substs(Arc::new([])) - } - - pub fn single(ty: Ty) -> Substs { - Substs(Arc::new([ty])) - } - - pub fn prefix(&self, n: usize) -> Substs { - Substs(self.0[..std::cmp::min(self.0.len(), n)].into()) - } - - pub fn as_single(&self) -> &Ty { - if self.0.len() != 1 { - panic!("expected substs of len 1, got {:?}", self); - } - &self.0[0] - } - - /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). - pub fn identity(generic_params: &GenericParams) -> Substs { - Substs( - generic_params - .params_including_parent() - .into_iter() - .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() }) - .collect(), - ) - } - - /// Return Substs that replace each parameter by a bound variable. - pub fn bound_vars(generic_params: &GenericParams) -> Substs { - Substs( - generic_params - .params_including_parent() - .into_iter() - .map(|p| Ty::Bound(p.idx)) - .collect(), - ) - } - - pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { - let def = def.into(); - let params = db.generic_params(def); - let param_count = params.count_params_including_parent(); - Substs::builder(param_count) - } - - pub fn build_for_generics(generic_params: &GenericParams) -> SubstsBuilder { - Substs::builder(generic_params.count_params_including_parent()) - } - - pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { - Substs::builder(type_ctor.num_ty_params(db)) - } - - fn builder(param_count: usize) -> SubstsBuilder { - SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } - } -} - -#[derive(Debug, Clone)] -pub struct SubstsBuilder { - vec: Vec, - param_count: usize, -} - -impl SubstsBuilder { - pub fn build(self) -> Substs { - assert_eq!(self.vec.len(), self.param_count); - Substs(self.vec.into()) - } - - pub fn push(mut self, ty: Ty) -> Self { - self.vec.push(ty); - self - } - - fn remaining(&self) -> usize { - self.param_count - self.vec.len() - } - - pub fn fill_with_bound_vars(self, starting_from: u32) -> Self { - self.fill((starting_from..).map(Ty::Bound)) - } - - pub fn fill_with_params(self) -> Self { - let start = self.vec.len() as u32; - self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() })) - } - - pub fn fill_with_unknown(self) -> Self { - self.fill(iter::repeat(Ty::Unknown)) - } - - pub fn fill(mut self, filler: impl Iterator) -> Self { - self.vec.extend(filler.take(self.remaining())); - assert_eq!(self.remaining(), 0); - self - } - - pub fn use_parent_substs(mut self, parent_substs: &Substs) -> Self { - assert!(self.vec.is_empty()); - assert!(parent_substs.len() <= self.param_count); - self.vec.extend(parent_substs.iter().cloned()); - self - } -} - -impl Deref for Substs { - type Target = [Ty]; - - fn deref(&self) -> &[Ty] { - &self.0 - } -} - -/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. -/// Name to be bikeshedded: TraitBound? TraitImplements? -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct TraitRef { - /// FIXME name? - pub trait_: TraitId, - pub substs: Substs, -} - -impl TraitRef { - pub fn self_ty(&self) -> &Ty { - &self.substs[0] - } -} - -impl TypeWalk for TraitRef { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.substs.walk(f); - } - - fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { - self.substs.walk_mut_binders(f, binders); - } -} - -/// Like `generics::WherePredicate`, but with resolved types: A condition on the -/// parameters of a generic item. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum GenericPredicate { - /// The given trait needs to be implemented for its type parameters. - Implemented(TraitRef), - /// An associated type bindings like in `Iterator`. - Projection(ProjectionPredicate), - /// We couldn't resolve the trait reference. (If some type parameters can't - /// be resolved, they will just be Unknown). - Error, -} - -impl GenericPredicate { - pub fn is_error(&self) -> bool { - match self { - GenericPredicate::Error => true, - _ => false, - } - } - - pub fn is_implemented(&self) -> bool { - match self { - GenericPredicate::Implemented(_) => true, - _ => false, - } - } - - pub fn trait_ref(&self, db: &impl HirDatabase) -> Option { - match self { - GenericPredicate::Implemented(tr) => Some(tr.clone()), - GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)), - GenericPredicate::Error => None, - } - } -} - -impl TypeWalk for GenericPredicate { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - match self { - GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), - GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), - GenericPredicate::Error => {} - } - } - - fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { - match self { - GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), - GenericPredicate::Projection(projection_pred) => { - projection_pred.walk_mut_binders(f, binders) - } - GenericPredicate::Error => {} - } - } -} - -/// Basically a claim (currently not validated / checked) that the contained -/// type / trait ref contains no inference variables; any inference variables it -/// contained have been replaced by bound variables, and `num_vars` tells us how -/// many there are. This is used to erase irrelevant differences between types -/// before using them in queries. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Canonical { - pub value: T, - pub num_vars: usize, -} - -/// A function signature as seen by type inference: Several parameter types and -/// one return type. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct FnSig { - params_and_return: Arc<[Ty]>, -} - -impl FnSig { - pub fn from_params_and_return(mut params: Vec, ret: Ty) -> FnSig { - params.push(ret); - FnSig { params_and_return: params.into() } - } - - pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig { - FnSig { params_and_return: Arc::clone(&substs.0) } - } - - pub fn params(&self) -> &[Ty] { - &self.params_and_return[0..self.params_and_return.len() - 1] - } - - pub fn ret(&self) -> &Ty { - &self.params_and_return[self.params_and_return.len() - 1] - } -} - -impl TypeWalk for FnSig { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - for t in self.params_and_return.iter() { - t.walk(f); - } - } - - fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { - for t in make_mut_slice(&mut self.params_and_return) { - t.walk_mut_binders(f, binders); - } - } -} - -impl Ty { - pub fn simple(ctor: TypeCtor) -> Ty { - Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() }) - } - pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty { - Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) }) - } - pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty { - Ty::Apply(ApplicationTy { ctor, parameters }) - } - pub fn unit() -> Self { - Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) - } - - pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { - match self { - Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { - Some((parameters.as_single(), *mutability)) - } - _ => None, - } - } - - pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { - match self { - Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { - Some((*adt_def, parameters)) - } - _ => None, - } - } - - pub fn as_tuple(&self) -> Option<&Substs> { - match self { - Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { - Some(parameters) - } - _ => None, - } - } - - pub fn as_callable(&self) -> Option<(CallableDef, &Substs)> { - match self { - Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => { - Some((*callable_def, parameters)) - } - _ => None, - } - } - - fn builtin_deref(&self) -> Option { - match self { - Ty::Apply(a_ty) => match a_ty.ctor { - TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), - TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), - _ => None, - }, - _ => None, - } - } - - fn callable_sig(&self, db: &impl HirDatabase) -> Option { - match self { - Ty::Apply(a_ty) => match a_ty.ctor { - TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), - TypeCtor::FnDef(def) => { - let sig = db.callable_item_signature(def); - Some(sig.subst(&a_ty.parameters)) - } - TypeCtor::Closure { .. } => { - let sig_param = &a_ty.parameters[0]; - sig_param.callable_sig(db) - } - _ => None, - }, - _ => None, - } - } - - /// If this is a type with type parameters (an ADT or function), replaces - /// the `Substs` for these type parameters with the given ones. (So e.g. if - /// `self` is `Option<_>` and the substs contain `u32`, we'll have - /// `Option` afterwards.) - pub fn apply_substs(self, substs: Substs) -> Ty { - match self { - Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { - assert_eq!(previous_substs.len(), substs.len()); - Ty::Apply(ApplicationTy { ctor, parameters: substs }) - } - _ => self, - } - } - - /// Returns the type parameters of this type if it has some (i.e. is an ADT - /// or function); so if `self` is `Option`, this returns the `u32`. - pub fn substs(&self) -> Option { - match self { - Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), - _ => None, - } - } - - /// If this is an `impl Trait` or `dyn Trait`, returns that trait. - pub fn inherent_trait(&self) -> Option { - match self { - Ty::Dyn(predicates) | Ty::Opaque(predicates) => { - predicates.iter().find_map(|pred| match pred { - GenericPredicate::Implemented(tr) => Some(tr.trait_), - _ => None, - }) - } - _ => None, - } - } -} - -/// This allows walking structures that contain types to do something with those -/// types, similar to Chalk's `Fold` trait. -pub trait TypeWalk { - fn walk(&self, f: &mut impl FnMut(&Ty)); - fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { - self.walk_mut_binders(&mut |ty, _binders| f(ty), 0); - } - /// Walk the type, counting entered binders. - /// - /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers - /// to the innermost binder, 1 to the next, etc.. So when we want to - /// substitute a certain bound variable, we can't just walk the whole type - /// and blindly replace each instance of a certain index; when we 'enter' - /// things that introduce new bound variables, we have to keep track of - /// that. Currently, the only thing that introduces bound variables on our - /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound - /// variable for the self type. - fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize); - - fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self - where - Self: Sized, - { - self.walk_mut(&mut |ty_mut| { - let ty = mem::replace(ty_mut, Ty::Unknown); - *ty_mut = f(ty); - }); - self - } - - /// Replaces type parameters in this type using the given `Substs`. (So e.g. - /// if `self` is `&[T]`, where type parameter T has index 0, and the - /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) - fn subst(self, substs: &Substs) -> Self - where - Self: Sized, - { - self.fold(&mut |ty| match ty { - Ty::Param { idx, name } => { - substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) - } - ty => ty, - }) - } - - /// Substitutes `Ty::Bound` vars (as opposed to type parameters). - fn subst_bound_vars(mut self, substs: &Substs) -> Self - where - Self: Sized, - { - self.walk_mut_binders( - &mut |ty, binders| match ty { - &mut Ty::Bound(idx) => { - if idx as usize >= binders && (idx as usize - binders) < substs.len() { - *ty = substs.0[idx as usize - binders].clone(); - } - } - _ => {} - }, - 0, - ); - self - } - - /// Shifts up `Ty::Bound` vars by `n`. - fn shift_bound_vars(self, n: i32) -> Self - where - Self: Sized, - { - self.fold(&mut |ty| match ty { - Ty::Bound(idx) => { - assert!(idx as i32 >= -n); - Ty::Bound((idx as i32 + n) as u32) - } - ty => ty, - }) - } -} - -impl TypeWalk for Ty { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - match self { - Ty::Apply(a_ty) => { - for t in a_ty.parameters.iter() { - t.walk(f); - } - } - Ty::Projection(p_ty) => { - for t in p_ty.parameters.iter() { - t.walk(f); - } - } - Ty::Dyn(predicates) | Ty::Opaque(predicates) => { - for p in predicates.iter() { - p.walk(f); - } - } - Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} - } - f(self); - } - - fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { - match self { - Ty::Apply(a_ty) => { - a_ty.parameters.walk_mut_binders(f, binders); - } - Ty::Projection(p_ty) => { - p_ty.parameters.walk_mut_binders(f, binders); - } - Ty::Dyn(predicates) | Ty::Opaque(predicates) => { - for p in make_mut_slice(predicates) { - p.walk_mut_binders(f, binders + 1); - } - } - Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} - } - f(self, binders); - } -} - -impl HirDisplay for &Ty { - fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { - HirDisplay::hir_fmt(*self, f) - } -} - -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")?, - TypeCtor::Int(t) => write!(f, "{}", t)?, - TypeCtor::Float(t) => write!(f, "{}", t)?, - TypeCtor::Str => write!(f, "str")?, - TypeCtor::Slice => { - let t = self.parameters.as_single(); - write!(f, "[{}]", t.display(f.db))?; - } - TypeCtor::Array => { - let t = self.parameters.as_single(); - write!(f, "[{};_]", t.display(f.db))?; - } - TypeCtor::RawPtr(m) => { - let t = self.parameters.as_single(); - write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?; - } - TypeCtor::Ref(m) => { - let t = self.parameters.as_single(); - write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?; - } - TypeCtor::Never => write!(f, "!")?, - TypeCtor::Tuple { .. } => { - let ts = &self.parameters; - if ts.len() == 1 { - write!(f, "({},)", ts[0].display(f.db))?; - } else { - write!(f, "(")?; - f.write_joined(&*ts.0, ", ")?; - write!(f, ")")?; - } - } - TypeCtor::FnPtr { .. } => { - let sig = FnSig::from_fn_ptr_substs(&self.parameters); - write!(f, "fn(")?; - f.write_joined(sig.params(), ", ")?; - write!(f, ") -> {}", sig.ret().display(f.db))?; - } - TypeCtor::FnDef(def) => { - let sig = f.db.callable_item_signature(def); - let name = match def { - CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), - CallableDef::StructId(s) => { - f.db.struct_data(s).name.clone().unwrap_or_else(Name::missing) - } - CallableDef::EnumVariantId(e) => { - let enum_data = f.db.enum_data(e.parent); - enum_data.variants[e.local_id].name.clone().unwrap_or_else(Name::missing) - } - }; - match def { - CallableDef::FunctionId(_) => write!(f, "fn {}", name)?, - CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { - write!(f, "{}", name)? - } - } - if self.parameters.len() > 0 { - write!(f, "<")?; - f.write_joined(&*self.parameters.0, ", ")?; - write!(f, ">")?; - } - write!(f, "(")?; - f.write_joined(sig.params(), ", ")?; - write!(f, ") -> {}", sig.ret().display(f.db))?; - } - TypeCtor::Adt(def_id) => { - let name = match def_id { - AdtId::StructId(it) => f.db.struct_data(it).name.clone(), - AdtId::UnionId(it) => f.db.union_data(it).name.clone(), - AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), - } - .unwrap_or_else(Name::missing); - write!(f, "{}", name)?; - if self.parameters.len() > 0 { - write!(f, "<")?; - f.write_joined(&*self.parameters.0, ", ")?; - write!(f, ">")?; - } - } - TypeCtor::AssociatedType(type_alias) => { - let trait_ = match type_alias.lookup(f.db).container { - ContainerId::TraitId(it) => it, - _ => panic!("not an associated type"), - }; - let trait_name = f.db.trait_data(trait_).name.clone().unwrap_or_else(Name::missing); - let name = f.db.type_alias_data(type_alias).name.clone(); - write!(f, "{}::{}", trait_name, name)?; - if self.parameters.len() > 0 { - write!(f, "<")?; - f.write_joined(&*self.parameters.0, ", ")?; - write!(f, ">")?; - } - } - TypeCtor::Closure { .. } => { - let sig = self.parameters[0] - .callable_sig(f.db) - .expect("first closure parameter should contain signature"); - write!(f, "|")?; - f.write_joined(sig.params(), ", ")?; - write!(f, "| -> {}", sig.ret().display(f.db))?; - } - } - Ok(()) - } -} - -impl HirDisplay for ProjectionTy { - fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { - if f.should_truncate() { - return write!(f, "…"); - } - - let trait_name = - f.db.trait_data(self.trait_(f.db)).name.clone().unwrap_or_else(Name::missing); - write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; - if self.parameters.len() > 1 { - write!(f, "<")?; - f.write_joined(&self.parameters[1..], ", ")?; - write!(f, ">")?; - } - write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; - Ok(()) - } -} - -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)?, - Ty::Param { name, .. } => write!(f, "{}", name)?, - Ty::Bound(idx) => write!(f, "?{}", idx)?, - Ty::Dyn(predicates) | Ty::Opaque(predicates) => { - match self { - Ty::Dyn(_) => write!(f, "dyn ")?, - Ty::Opaque(_) => write!(f, "impl ")?, - _ => unreachable!(), - }; - // Note: This code is written to produce nice results (i.e. - // corresponding to surface Rust) for types that can occur in - // actual Rust. It will have weird results if the predicates - // aren't as expected (i.e. self types = $0, projection - // predicates for a certain trait come after the Implemented - // predicate for that trait). - let mut first = true; - let mut angle_open = false; - for p in predicates.iter() { - match p { - GenericPredicate::Implemented(trait_ref) => { - if angle_open { - write!(f, ">")?; - } - if !first { - write!(f, " + ")?; - } - // We assume that the self type is $0 (i.e. the - // existential) here, which is the only thing that's - // possible in actual Rust, and hence don't print it - write!( - f, - "{}", - f.db.trait_data(trait_ref.trait_) - .name - .clone() - .unwrap_or_else(Name::missing) - )?; - if trait_ref.substs.len() > 1 { - write!(f, "<")?; - f.write_joined(&trait_ref.substs[1..], ", ")?; - // there might be assoc type bindings, so we leave the angle brackets open - angle_open = true; - } - } - GenericPredicate::Projection(projection_pred) => { - // in types in actual Rust, these will always come - // after the corresponding Implemented predicate - if angle_open { - write!(f, ", ")?; - } else { - write!(f, "<")?; - angle_open = true; - } - let name = - f.db.type_alias_data(projection_pred.projection_ty.associated_ty) - .name - .clone(); - write!(f, "{} = ", name)?; - projection_pred.ty.hir_fmt(f)?; - } - GenericPredicate::Error => { - if angle_open { - // impl Trait - write!(f, ", ")?; - } else if !first { - // impl Trait + {error} - write!(f, " + ")?; - } - p.hir_fmt(f)?; - } - } - first = false; - } - if angle_open { - write!(f, ">")?; - } - } - Ty::Unknown => write!(f, "{{unknown}}")?, - Ty::Infer(..) => write!(f, "_")?, - } - Ok(()) - } -} - -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 ")?; - } else { - write!(f, ": ")?; - } - write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?; - if self.substs.len() > 1 { - write!(f, "<")?; - f.write_joined(&self.substs[1..], ", ")?; - write!(f, ">")?; - } - Ok(()) - } -} - -impl HirDisplay for TraitRef { - fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { - self.hir_fmt_ext(f, false) - } -} - -impl HirDisplay for &GenericPredicate { - fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { - HirDisplay::hir_fmt(*self, f) - } -} - -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) => { - write!(f, "<")?; - projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; - write!( - f, - ">::{} = {}", - f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, - projection_pred.ty.display(f.db) - )?; - } - GenericPredicate::Error => write!(f, "{{error}}")?, - } - Ok(()) - } -} - -impl HirDisplay for Obligation { - fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { - match self { - Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)), - Obligation::Projection(proj) => write!( - f, - "Normalize({} => {})", - proj.projection_ty.display(f.db), - proj.ty.display(f.db) - ), - } - } -} +pub use hir_ty::*; diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs deleted file mode 100644 index 12dc965725..0000000000 --- a/crates/ra_hir/src/ty/primitive.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! FIXME: write short doc here - -pub use hir_ty::primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}; diff --git a/crates/ra_hir/src/util.rs b/crates/ra_hir/src/util.rs deleted file mode 100644 index 0095ee45d3..0000000000 --- a/crates/ra_hir/src/util.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Internal utility functions. - -use std::sync::Arc; - -/// Helper for mutating `Arc<[T]>` (i.e. `Arc::make_mut` for Arc slices). -/// The underlying values are cloned if there are other strong references. -pub(crate) fn make_mut_slice(a: &mut Arc<[T]>) -> &mut [T] { - if Arc::get_mut(a).is_none() { - *a = a.iter().cloned().collect(); - } - Arc::get_mut(a).unwrap() -} diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index ea3f00bb33..ddf464c605 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -27,7 +27,7 @@ pub mod body; pub mod resolver; mod trace; -mod nameres; +pub mod nameres; #[cfg(test)] mod test_db; diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index 027b508657..199afff493 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml @@ -8,6 +8,7 @@ authors = ["rust-analyzer developers"] doctest = false [dependencies] +arrayvec = "0.5.1" log = "0.4.5" rustc-hash = "1.0" parking_lot = "0.10.0" diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs similarity index 99% rename from crates/ra_hir/src/ty/autoderef.rs rename to crates/ra_hir_ty/src/autoderef.rs index ae68234aca..9d1d4e48c6 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir_ty/src/autoderef.rs @@ -19,7 +19,7 @@ use super::{ const AUTODEREF_RECURSION_LIMIT: usize = 10; -pub(crate) fn autoderef<'a>( +pub fn autoderef<'a>( db: &'a impl HirDatabase, krate: Option, ty: InEnvironment>, diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs new file mode 100644 index 0000000000..aa2659c4bf --- /dev/null +++ b/crates/ra_hir_ty/src/db.rs @@ -0,0 +1,116 @@ +//! FIXME: write short doc here + +use std::sync::Arc; + +use hir_def::{ + db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, +}; +use ra_arena::map::ArenaMap; +use ra_db::{salsa, CrateId}; + +use crate::{ + method_resolution::CrateImplBlocks, + traits::{AssocTyValue, Impl}, + CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, + ValueTyDefId, +}; + +#[salsa::query_group(HirDatabaseStorage)] +#[salsa::requires(salsa::Database)] +pub trait HirDatabase: DefDatabase { + #[salsa::invoke(crate::infer_query)] + fn infer(&self, def: DefWithBodyId) -> Arc; + + #[salsa::invoke(crate::lower::ty_query)] + fn ty(&self, def: TyDefId) -> Ty; + + #[salsa::invoke(crate::lower::value_ty_query)] + fn value_ty(&self, def: ValueTyDefId) -> Ty; + + #[salsa::invoke(crate::lower::field_types_query)] + fn field_types(&self, var: VariantId) -> Arc>; + + #[salsa::invoke(crate::callable_item_sig)] + fn callable_item_signature(&self, def: CallableDef) -> FnSig; + + #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] + fn generic_predicates_for_param( + &self, + def: GenericDefId, + param_idx: u32, + ) -> Arc<[GenericPredicate]>; + + #[salsa::invoke(crate::lower::generic_predicates_query)] + fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>; + + #[salsa::invoke(crate::lower::generic_defaults_query)] + fn generic_defaults(&self, def: GenericDefId) -> Substs; + + #[salsa::invoke(crate::method_resolution::CrateImplBlocks::impls_in_crate_query)] + fn impls_in_crate(&self, krate: CrateId) -> Arc; + + #[salsa::invoke(crate::traits::impls_for_trait_query)] + fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplId]>; + + /// This provides the Chalk trait solver instance. Because Chalk always + /// works from a specific crate, this query is keyed on the crate; and + /// because Chalk does its own internal caching, the solver is wrapped in a + /// Mutex and the query does an untracked read internally, to make sure the + /// cached state is thrown away when input facts change. + #[salsa::invoke(crate::traits::trait_solver_query)] + fn trait_solver(&self, krate: CrateId) -> crate::traits::TraitSolver; + + // Interned IDs for Chalk integration + #[salsa::interned] + fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId; + #[salsa::interned] + fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; + #[salsa::interned] + fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; + + #[salsa::invoke(crate::traits::chalk::associated_ty_data_query)] + fn associated_ty_data( + &self, + id: chalk_ir::TypeId, + ) -> Arc>; + + #[salsa::invoke(crate::traits::chalk::trait_datum_query)] + fn trait_datum( + &self, + krate: CrateId, + trait_id: chalk_ir::TraitId, + ) -> Arc>; + + #[salsa::invoke(crate::traits::chalk::struct_datum_query)] + fn struct_datum( + &self, + krate: CrateId, + struct_id: chalk_ir::StructId, + ) -> Arc>; + + #[salsa::invoke(crate::traits::chalk::impl_datum_query)] + fn impl_datum( + &self, + krate: CrateId, + impl_id: chalk_ir::ImplId, + ) -> Arc>; + + #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] + fn associated_ty_value( + &self, + krate: CrateId, + id: chalk_rust_ir::AssociatedTyValueId, + ) -> Arc>; + + #[salsa::invoke(crate::traits::trait_solve_query)] + fn trait_solve( + &self, + krate: CrateId, + goal: crate::Canonical>, + ) -> Option; +} + +#[test] +fn hir_database_is_object_safe() { + fn _assert_object_safe(_: &dyn HirDatabase) {} +} diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs new file mode 100644 index 0000000000..4a13fac239 --- /dev/null +++ b/crates/ra_hir_ty/src/diagnostics.rs @@ -0,0 +1,91 @@ +//! FIXME: write short doc here + +use std::any::Any; + +use hir_expand::{db::AstDatabase, name::Name, HirFileId, Source}; +use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; + +pub use hir_def::diagnostics::UnresolvedModule; +pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; + +#[derive(Debug)] +pub struct NoSuchField { + pub file: HirFileId, + pub field: AstPtr, +} + +impl Diagnostic for NoSuchField { + fn message(&self) -> String { + "no such field".to_string() + } + + fn source(&self) -> Source { + Source { file_id: self.file, value: self.field.into() } + } + + fn as_any(&self) -> &(dyn Any + Send + 'static) { + self + } +} + +#[derive(Debug)] +pub struct MissingFields { + pub file: HirFileId, + pub field_list: AstPtr, + pub missed_fields: Vec, +} + +impl Diagnostic for MissingFields { + fn message(&self) -> String { + use std::fmt::Write; + let mut message = String::from("Missing structure fields:\n"); + for field in &self.missed_fields { + write!(message, "- {}\n", field).unwrap(); + } + message + } + fn source(&self) -> Source { + Source { file_id: self.file, value: self.field_list.into() } + } + fn as_any(&self) -> &(dyn Any + Send + 'static) { + self + } +} + +impl AstDiagnostic for MissingFields { + type AST = ast::RecordFieldList; + + fn ast(&self, db: &impl AstDatabase) -> Self::AST { + let root = db.parse_or_expand(self.source().file_id).unwrap(); + let node = self.source().value.to_node(&root); + ast::RecordFieldList::cast(node).unwrap() + } +} + +#[derive(Debug)] +pub struct MissingOkInTailExpr { + pub file: HirFileId, + pub expr: AstPtr, +} + +impl Diagnostic for MissingOkInTailExpr { + fn message(&self) -> String { + "wrap return expression in Ok".to_string() + } + fn source(&self) -> Source { + Source { file_id: self.file, value: self.expr.into() } + } + fn as_any(&self) -> &(dyn Any + Send + 'static) { + self + } +} + +impl AstDiagnostic for MissingOkInTailExpr { + type AST = ast::Expr; + + fn ast(&self, db: &impl AstDatabase) -> Self::AST { + let root = db.parse_or_expand(self.file).unwrap(); + let node = self.source().value.to_node(&root); + ast::Expr::cast(node).unwrap() + } +} diff --git a/crates/ra_hir/src/ty/display.rs b/crates/ra_hir_ty/src/display.rs similarity index 100% rename from crates/ra_hir/src/ty/display.rs rename to crates/ra_hir_ty/src/display.rs diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir_ty/src/expr.rs similarity index 81% rename from crates/ra_hir/src/expr.rs rename to crates/ra_hir_ty/src/expr.rs index 5c82c23d6c..5c65f93707 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir_ty/src/expr.rs @@ -2,8 +2,12 @@ use std::sync::Arc; -use hir_def::{path::known, resolver::HasResolver, AdtId}; -use hir_expand::diagnostics::DiagnosticSink; +use hir_def::{ + path::{known, Path}, + resolver::HasResolver, + AdtId, FunctionId, +}; +use hir_expand::{diagnostics::DiagnosticSink, name::Name}; use ra_syntax::ast; use ra_syntax::AstPtr; use rustc_hash::FxHashSet; @@ -11,8 +15,7 @@ use rustc_hash::FxHashSet; use crate::{ db::HirDatabase, diagnostics::{MissingFields, MissingOkInTailExpr}, - ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, - Function, Name, Path, Struct, + ApplicationTy, InferenceResult, Ty, TypeCtor, }; pub use hir_def::{ @@ -26,23 +29,23 @@ pub use hir_def::{ }, }; -pub(crate) struct ExprValidator<'a, 'b: 'a> { - func: Function, +pub struct ExprValidator<'a, 'b: 'a> { + func: FunctionId, infer: Arc, sink: &'a mut DiagnosticSink<'b>, } impl<'a, 'b> ExprValidator<'a, 'b> { - pub(crate) fn new( - func: Function, + pub fn new( + func: FunctionId, infer: Arc, sink: &'a mut DiagnosticSink<'b>, ) -> ExprValidator<'a, 'b> { ExprValidator { func, infer, sink } } - pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { - let body = self.func.body(db); + pub fn validate_body(&mut self, db: &impl HirDatabase) { + let body = db.body(self.func.into()); for e in body.exprs.iter() { if let (id, Expr::RecordLit { path, fields, spread }) = e { @@ -69,16 +72,18 @@ impl<'a, 'b> ExprValidator<'a, 'b> { } let struct_def = match self.infer[id].as_adt() { - Some((AdtId::StructId(s), _)) => Struct::from(s), + Some((AdtId::StructId(s), _)) => s, _ => return, }; + let struct_data = db.struct_data(struct_def); let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); - let missed_fields: Vec = struct_def - .fields(db) + let missed_fields: Vec = struct_data + .variant_data + .fields() .iter() - .filter_map(|f| { - let name = f.name(db); + .filter_map(|(_f, d)| { + let name = d.name.clone(); if lit_fields.contains(&name) { None } else { @@ -89,7 +94,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { if missed_fields.is_empty() { return; } - let source_map = self.func.body_source_map(db); + let (_, source_map) = db.body_with_source_map(self.func.into()); if let Some(source_ptr) = source_map.expr_syntax(id) { if let Some(expr) = source_ptr.value.a() { @@ -121,7 +126,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { let std_result_path = known::std_result_result(); - let resolver = self.func.id.resolver(db); + let resolver = self.func.resolver(db); let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) { Some(it) => it, _ => return, @@ -134,7 +139,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { }; if params.len() == 2 && ¶ms[0] == &mismatch.actual { - let source_map = self.func.body_source_map(db); + let (_, source_map) = db.body_with_source_map(self.func.into()); if let Some(source_ptr) = source_map.expr_syntax(id) { if let Some(expr) = source_ptr.value.a() { diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir_ty/src/infer.rs similarity index 98% rename from crates/ra_hir/src/ty/infer.rs rename to crates/ra_hir_ty/src/infer.rs index 59e4e5f36b..1e9f4b208d 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -41,11 +41,11 @@ use super::{ ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }; -use crate::{db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic}; +use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; macro_rules! ty_app { ($ctor:pat, $param:pat) => { - crate::ty::Ty::Apply(crate::ty::ApplicationTy { ctor: $ctor, parameters: $param }) + crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param }) }; ($ctor:pat) => { ty_app!($ctor, _) @@ -128,8 +128,8 @@ pub struct InferenceResult { /// For each associated item record what it resolves to assoc_resolutions: FxHashMap, diagnostics: Vec, - pub(super) type_of_expr: ArenaMap, - pub(super) type_of_pat: ArenaMap, + pub type_of_expr: ArenaMap, + pub type_of_pat: ArenaMap, pub(super) type_mismatches: ArenaMap, } @@ -158,7 +158,7 @@ impl InferenceResult { pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { self.type_mismatches.get(expr) } - pub(crate) fn add_diagnostics( + pub fn add_diagnostics( &self, db: &impl HirDatabase, owner: FunctionId, diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs similarity index 99% rename from crates/ra_hir/src/ty/infer/coerce.rs rename to crates/ra_hir_ty/src/infer/coerce.rs index 3fb5d8a83b..d66a21932f 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs @@ -13,10 +13,7 @@ use hir_def::{ use rustc_hash::FxHashMap; use test_utils::tested_by; -use crate::{ - db::HirDatabase, - ty::{autoderef, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, -}; +use crate::{autoderef, db::HirDatabase, Substs, TraitRef, Ty, TypeCtor, TypeWalk}; use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs similarity index 99% rename from crates/ra_hir/src/ty/infer/expr.rs rename to crates/ra_hir_ty/src/infer/expr.rs index f9ededa235..2f9ca4bbbf 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -14,12 +14,9 @@ use hir_def::{ use hir_expand::name::{self, Name}; use crate::{ - db::HirDatabase, - ty::{ - autoderef, method_resolution, op, traits::InEnvironment, utils::variant_data, CallableDef, - InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, - TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, - }, + autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data, + CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, + TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }; use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs similarity index 98% rename from crates/ra_hir/src/ty/infer/pat.rs rename to crates/ra_hir_ty/src/infer/pat.rs index a147746077..1ebb362399 100644 --- a/crates/ra_hir/src/ty/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs @@ -12,10 +12,7 @@ use hir_expand::name::Name; use test_utils::tested_by; use super::{BindingMode, InferenceContext}; -use crate::{ - db::HirDatabase, - ty::{utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}, -}; +use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}; impl<'a, D: HirDatabase> InferenceContext<'a, D> { fn infer_tuple_struct_pat( diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs similarity index 97% rename from crates/ra_hir/src/ty/infer/path.rs rename to crates/ra_hir_ty/src/infer/path.rs index 09ff797288..e6676e1aa8 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir_ty/src/infer/path.rs @@ -1,16 +1,13 @@ //! Path expression resolution. use hir_def::{ - path::{Path, PathSegment}, + path::{Path, PathKind, PathSegment}, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, AssocItemId, ContainerId, Lookup, }; use hir_expand::name::Name; -use crate::{ - db::HirDatabase, - ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}, -}; +use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}; use super::{ExprOrPatId, InferenceContext, TraitRef}; @@ -33,7 +30,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { path: &Path, id: ExprOrPatId, ) -> Option { - let (value, self_subst) = if let crate::PathKind::Type(type_ref) = &path.kind { + let (value, self_subst) = if let PathKind::Type(type_ref) = &path.kind { if path.segments.is_empty() { // This can't actually happen syntax-wise return None; diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs similarity index 96% rename from crates/ra_hir/src/ty/infer/unify.rs rename to crates/ra_hir_ty/src/infer/unify.rs index e27bb2f825..f3a8756785 100644 --- a/crates/ra_hir/src/ty/infer/unify.rs +++ b/crates/ra_hir_ty/src/infer/unify.rs @@ -2,12 +2,8 @@ use super::{InferenceContext, Obligation}; use crate::{ - db::HirDatabase, - ty::{ - Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, - TypeWalk, - }, - util::make_mut_slice, + db::HirDatabase, utils::make_mut_slice, Canonical, InEnvironment, InferTy, ProjectionPredicate, + ProjectionTy, Substs, TraitRef, Ty, TypeWalk, }; impl<'a, D: HirDatabase> InferenceContext<'a, D> { diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 28859ba636..f258463268 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -1,4 +1,1134 @@ -//! Work in Progress: everything related to types, type inference and trait -//! solving. +//! The type system. We currently use this to infer types for completion, hover +//! information and various assists. +macro_rules! impl_froms { + ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { + $( + impl From<$v> for $e { + fn from(it: $v) -> $e { + $e::$v(it) + } + } + $($( + impl From<$sv> for $e { + fn from(it: $sv) -> $e { + $e::$v($v::$sv(it)) + } + } + )*)? + )* + } +} + +mod autoderef; pub mod primitive; +pub mod traits; +pub mod method_resolution; +mod op; +mod lower; +mod infer; +pub mod display; +pub(crate) mod utils; +pub mod db; +pub mod diagnostics; +pub mod expr; + +#[cfg(test)] +mod tests; +#[cfg(test)] +mod test_db; +mod marks; + +use std::ops::Deref; +use std::sync::Arc; +use std::{fmt, iter, mem}; + +use hir_def::{ + expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, + GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, +}; +use hir_expand::name::Name; +use ra_db::{impl_intern_key, salsa, CrateId}; + +use crate::{ + db::HirDatabase, + primitive::{FloatTy, IntTy, Uncertain}, + utils::make_mut_slice, +}; +use display::{HirDisplay, HirFormatter}; + +pub use autoderef::autoderef; +pub use infer::{infer_query, InferTy, InferenceResult}; +pub use lower::CallableDef; +pub use lower::{callable_item_sig, TyDefId, ValueTyDefId}; +pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; + +/// A type constructor or type name: this might be something like the primitive +/// type `bool`, a struct like `Vec`, or things like function pointers or +/// tuples. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] +pub enum TypeCtor { + /// The primitive boolean type. Written as `bool`. + Bool, + + /// The primitive character type; holds a Unicode scalar value + /// (a non-surrogate code point). Written as `char`. + Char, + + /// A primitive integer type. For example, `i32`. + Int(Uncertain), + + /// A primitive floating-point type. For example, `f64`. + Float(Uncertain), + + /// Structures, enumerations and unions. + Adt(AdtId), + + /// The pointee of a string slice. Written as `str`. + Str, + + /// The pointee of an array slice. Written as `[T]`. + Slice, + + /// An array with the given length. Written as `[T; n]`. + Array, + + /// A raw pointer. Written as `*mut T` or `*const T` + RawPtr(Mutability), + + /// A reference; a pointer with an associated lifetime. Written as + /// `&'a mut T` or `&'a T`. + Ref(Mutability), + + /// The anonymous type of a function declaration/definition. Each + /// function has a unique type, which is output (for a function + /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. + /// + /// This includes tuple struct / enum variant constructors as well. + /// + /// For example the type of `bar` here: + /// + /// ``` + /// fn foo() -> i32 { 1 } + /// let bar = foo; // bar: fn() -> i32 {foo} + /// ``` + FnDef(CallableDef), + + /// A pointer to a function. Written as `fn() -> i32`. + /// + /// For example the type of `bar` here: + /// + /// ``` + /// fn foo() -> i32 { 1 } + /// let bar: fn() -> i32 = foo; + /// ``` + FnPtr { num_args: u16 }, + + /// The never type `!`. + Never, + + /// A tuple type. For example, `(i32, bool)`. + Tuple { cardinality: u16 }, + + /// Represents an associated item like `Iterator::Item`. This is used + /// when we have tried to normalize a projection like `T::Item` but + /// couldn't find a better representation. In that case, we generate + /// an **application type** like `(Iterator::Item)`. + AssociatedType(TypeAliasId), + + /// The type of a specific closure. + /// + /// The closure signature is stored in a `FnPtr` type in the first type + /// parameter. + Closure { def: DefWithBodyId, expr: ExprId }, +} + +/// This exists just for Chalk, because Chalk just has a single `StructId` where +/// we have different kinds of ADTs, primitive types and special type +/// constructors like tuples and function pointers. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct TypeCtorId(salsa::InternId); +impl_intern_key!(TypeCtorId); + +impl TypeCtor { + pub fn num_ty_params(self, db: &impl HirDatabase) -> usize { + match self { + TypeCtor::Bool + | TypeCtor::Char + | TypeCtor::Int(_) + | TypeCtor::Float(_) + | TypeCtor::Str + | TypeCtor::Never => 0, + TypeCtor::Slice + | TypeCtor::Array + | TypeCtor::RawPtr(_) + | TypeCtor::Ref(_) + | TypeCtor::Closure { .. } // 1 param representing the signature of the closure + => 1, + TypeCtor::Adt(adt) => { + let generic_params = db.generic_params(AdtId::from(adt).into()); + generic_params.count_params_including_parent() + } + TypeCtor::FnDef(callable) => { + let generic_params = db.generic_params(callable.into()); + generic_params.count_params_including_parent() + } + TypeCtor::AssociatedType(type_alias) => { + let generic_params = db.generic_params(type_alias.into()); + generic_params.count_params_including_parent() + } + TypeCtor::FnPtr { num_args } => num_args as usize + 1, + TypeCtor::Tuple { cardinality } => cardinality as usize, + } + } + + pub fn krate(self, db: &impl HirDatabase) -> Option { + match self { + TypeCtor::Bool + | TypeCtor::Char + | TypeCtor::Int(_) + | TypeCtor::Float(_) + | TypeCtor::Str + | TypeCtor::Never + | TypeCtor::Slice + | TypeCtor::Array + | TypeCtor::RawPtr(_) + | TypeCtor::Ref(_) + | TypeCtor::FnPtr { .. } + | TypeCtor::Tuple { .. } => None, + // Closure's krate is irrelevant for coherence I would think? + TypeCtor::Closure { .. } => None, + TypeCtor::Adt(adt) => Some(adt.module(db).krate), + TypeCtor::FnDef(callable) => Some(callable.krate(db)), + TypeCtor::AssociatedType(type_alias) => Some(type_alias.lookup(db).module(db).krate), + } + } + + pub fn as_generic_def(self) -> Option { + match self { + TypeCtor::Bool + | TypeCtor::Char + | TypeCtor::Int(_) + | TypeCtor::Float(_) + | TypeCtor::Str + | TypeCtor::Never + | TypeCtor::Slice + | TypeCtor::Array + | TypeCtor::RawPtr(_) + | TypeCtor::Ref(_) + | TypeCtor::FnPtr { .. } + | TypeCtor::Tuple { .. } + | TypeCtor::Closure { .. } => None, + TypeCtor::Adt(adt) => Some(adt.into()), + TypeCtor::FnDef(callable) => Some(callable.into()), + TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), + } + } +} + +/// A nominal type with (maybe 0) type parameters. This might be a primitive +/// type like `bool`, a struct, tuple, function pointer, reference or +/// several other things. +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub struct ApplicationTy { + pub ctor: TypeCtor, + pub parameters: Substs, +} + +/// A "projection" type corresponds to an (unnormalized) +/// projection like `>::Foo`. Note that the +/// trait and all its parameters are fully known. +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub struct ProjectionTy { + pub associated_ty: TypeAliasId, + pub parameters: Substs, +} + +impl ProjectionTy { + pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef { + TraitRef { trait_: self.trait_(db).into(), substs: self.parameters.clone() } + } + + fn trait_(&self, db: &impl HirDatabase) -> TraitId { + match self.associated_ty.lookup(db).container { + ContainerId::TraitId(it) => it, + _ => panic!("projection ty without parent trait"), + } + } +} + +impl TypeWalk for ProjectionTy { + fn walk(&self, f: &mut impl FnMut(&Ty)) { + self.parameters.walk(f); + } + + fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { + self.parameters.walk_mut_binders(f, binders); + } +} + +/// A type. +/// +/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents +/// the same thing (but in a different way). +/// +/// This should be cheap to clone. +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub enum Ty { + /// A nominal type with (maybe 0) type parameters. This might be a primitive + /// type like `bool`, a struct, tuple, function pointer, reference or + /// several other things. + Apply(ApplicationTy), + + /// A "projection" type corresponds to an (unnormalized) + /// projection like `>::Foo`. Note that the + /// trait and all its parameters are fully known. + Projection(ProjectionTy), + + /// A type parameter; for example, `T` in `fn f(x: T) {} + Param { + /// The index of the parameter (starting with parameters from the + /// surrounding impl, then the current function). + idx: u32, + /// The name of the parameter, for displaying. + // FIXME get rid of this + name: Name, + }, + + /// A bound type variable. Used during trait resolution to represent Chalk + /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. + Bound(u32), + + /// A type variable used during type checking. Not to be confused with a + /// type parameter. + Infer(InferTy), + + /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). + /// + /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)` + /// represents the `Self` type inside the bounds. This is currently + /// implicit; Chalk has the `Binders` struct to make it explicit, but it + /// didn't seem worth the overhead yet. + Dyn(Arc<[GenericPredicate]>), + + /// An opaque type (`impl Trait`). + /// + /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for + /// more. + Opaque(Arc<[GenericPredicate]>), + + /// A placeholder for a type which could not be computed; this is propagated + /// to avoid useless error messages. Doubles as a placeholder where type + /// variables are inserted before type checking, since we want to try to + /// infer a better type here anyway -- for the IDE use case, we want to try + /// to infer as much as possible even in the presence of type errors. + Unknown, +} + +/// A list of substitutions for generic parameters. +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub struct Substs(Arc<[Ty]>); + +impl TypeWalk for Substs { + fn walk(&self, f: &mut impl FnMut(&Ty)) { + for t in self.0.iter() { + t.walk(f); + } + } + + fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { + for t in make_mut_slice(&mut self.0) { + t.walk_mut_binders(f, binders); + } + } +} + +impl Substs { + pub fn empty() -> Substs { + Substs(Arc::new([])) + } + + pub fn single(ty: Ty) -> Substs { + Substs(Arc::new([ty])) + } + + pub fn prefix(&self, n: usize) -> Substs { + Substs(self.0[..std::cmp::min(self.0.len(), n)].into()) + } + + pub fn as_single(&self) -> &Ty { + if self.0.len() != 1 { + panic!("expected substs of len 1, got {:?}", self); + } + &self.0[0] + } + + /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). + pub fn identity(generic_params: &GenericParams) -> Substs { + Substs( + generic_params + .params_including_parent() + .into_iter() + .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() }) + .collect(), + ) + } + + /// Return Substs that replace each parameter by a bound variable. + pub fn bound_vars(generic_params: &GenericParams) -> Substs { + Substs( + generic_params + .params_including_parent() + .into_iter() + .map(|p| Ty::Bound(p.idx)) + .collect(), + ) + } + + pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { + let def = def.into(); + let params = db.generic_params(def); + let param_count = params.count_params_including_parent(); + Substs::builder(param_count) + } + + pub fn build_for_generics(generic_params: &GenericParams) -> SubstsBuilder { + Substs::builder(generic_params.count_params_including_parent()) + } + + pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { + Substs::builder(type_ctor.num_ty_params(db)) + } + + fn builder(param_count: usize) -> SubstsBuilder { + SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } + } +} + +#[derive(Debug, Clone)] +pub struct SubstsBuilder { + vec: Vec, + param_count: usize, +} + +impl SubstsBuilder { + pub fn build(self) -> Substs { + assert_eq!(self.vec.len(), self.param_count); + Substs(self.vec.into()) + } + + pub fn push(mut self, ty: Ty) -> Self { + self.vec.push(ty); + self + } + + fn remaining(&self) -> usize { + self.param_count - self.vec.len() + } + + pub fn fill_with_bound_vars(self, starting_from: u32) -> Self { + self.fill((starting_from..).map(Ty::Bound)) + } + + pub fn fill_with_params(self) -> Self { + let start = self.vec.len() as u32; + self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() })) + } + + pub fn fill_with_unknown(self) -> Self { + self.fill(iter::repeat(Ty::Unknown)) + } + + pub fn fill(mut self, filler: impl Iterator) -> Self { + self.vec.extend(filler.take(self.remaining())); + assert_eq!(self.remaining(), 0); + self + } + + pub fn use_parent_substs(mut self, parent_substs: &Substs) -> Self { + assert!(self.vec.is_empty()); + assert!(parent_substs.len() <= self.param_count); + self.vec.extend(parent_substs.iter().cloned()); + self + } +} + +impl Deref for Substs { + type Target = [Ty]; + + fn deref(&self) -> &[Ty] { + &self.0 + } +} + +/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. +/// Name to be bikeshedded: TraitBound? TraitImplements? +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub struct TraitRef { + /// FIXME name? + pub trait_: TraitId, + pub substs: Substs, +} + +impl TraitRef { + pub fn self_ty(&self) -> &Ty { + &self.substs[0] + } +} + +impl TypeWalk for TraitRef { + fn walk(&self, f: &mut impl FnMut(&Ty)) { + self.substs.walk(f); + } + + fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { + self.substs.walk_mut_binders(f, binders); + } +} + +/// Like `generics::WherePredicate`, but with resolved types: A condition on the +/// parameters of a generic item. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum GenericPredicate { + /// The given trait needs to be implemented for its type parameters. + Implemented(TraitRef), + /// An associated type bindings like in `Iterator`. + Projection(ProjectionPredicate), + /// We couldn't resolve the trait reference. (If some type parameters can't + /// be resolved, they will just be Unknown). + Error, +} + +impl GenericPredicate { + pub fn is_error(&self) -> bool { + match self { + GenericPredicate::Error => true, + _ => false, + } + } + + pub fn is_implemented(&self) -> bool { + match self { + GenericPredicate::Implemented(_) => true, + _ => false, + } + } + + pub fn trait_ref(&self, db: &impl HirDatabase) -> Option { + match self { + GenericPredicate::Implemented(tr) => Some(tr.clone()), + GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)), + GenericPredicate::Error => None, + } + } +} + +impl TypeWalk for GenericPredicate { + fn walk(&self, f: &mut impl FnMut(&Ty)) { + match self { + GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), + GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), + GenericPredicate::Error => {} + } + } + + fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { + match self { + GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), + GenericPredicate::Projection(projection_pred) => { + projection_pred.walk_mut_binders(f, binders) + } + GenericPredicate::Error => {} + } + } +} + +/// Basically a claim (currently not validated / checked) that the contained +/// type / trait ref contains no inference variables; any inference variables it +/// contained have been replaced by bound variables, and `num_vars` tells us how +/// many there are. This is used to erase irrelevant differences between types +/// before using them in queries. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Canonical { + pub value: T, + pub num_vars: usize, +} + +/// A function signature as seen by type inference: Several parameter types and +/// one return type. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct FnSig { + params_and_return: Arc<[Ty]>, +} + +impl FnSig { + pub fn from_params_and_return(mut params: Vec, ret: Ty) -> FnSig { + params.push(ret); + FnSig { params_and_return: params.into() } + } + + pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig { + FnSig { params_and_return: Arc::clone(&substs.0) } + } + + pub fn params(&self) -> &[Ty] { + &self.params_and_return[0..self.params_and_return.len() - 1] + } + + pub fn ret(&self) -> &Ty { + &self.params_and_return[self.params_and_return.len() - 1] + } +} + +impl TypeWalk for FnSig { + fn walk(&self, f: &mut impl FnMut(&Ty)) { + for t in self.params_and_return.iter() { + t.walk(f); + } + } + + fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { + for t in make_mut_slice(&mut self.params_and_return) { + t.walk_mut_binders(f, binders); + } + } +} + +impl Ty { + pub fn simple(ctor: TypeCtor) -> Ty { + Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() }) + } + pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty { + Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) }) + } + pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty { + Ty::Apply(ApplicationTy { ctor, parameters }) + } + pub fn unit() -> Self { + Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) + } + + pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { + match self { + Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { + Some((parameters.as_single(), *mutability)) + } + _ => None, + } + } + + pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { + match self { + Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { + Some((*adt_def, parameters)) + } + _ => None, + } + } + + pub fn as_tuple(&self) -> Option<&Substs> { + match self { + Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { + Some(parameters) + } + _ => None, + } + } + + pub fn as_callable(&self) -> Option<(CallableDef, &Substs)> { + match self { + Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => { + Some((*callable_def, parameters)) + } + _ => None, + } + } + + fn builtin_deref(&self) -> Option { + match self { + Ty::Apply(a_ty) => match a_ty.ctor { + TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), + TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), + _ => None, + }, + _ => None, + } + } + + fn callable_sig(&self, db: &impl HirDatabase) -> Option { + match self { + Ty::Apply(a_ty) => match a_ty.ctor { + TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), + TypeCtor::FnDef(def) => { + let sig = db.callable_item_signature(def); + Some(sig.subst(&a_ty.parameters)) + } + TypeCtor::Closure { .. } => { + let sig_param = &a_ty.parameters[0]; + sig_param.callable_sig(db) + } + _ => None, + }, + _ => None, + } + } + + /// If this is a type with type parameters (an ADT or function), replaces + /// the `Substs` for these type parameters with the given ones. (So e.g. if + /// `self` is `Option<_>` and the substs contain `u32`, we'll have + /// `Option` afterwards.) + pub fn apply_substs(self, substs: Substs) -> Ty { + match self { + Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { + assert_eq!(previous_substs.len(), substs.len()); + Ty::Apply(ApplicationTy { ctor, parameters: substs }) + } + _ => self, + } + } + + /// Returns the type parameters of this type if it has some (i.e. is an ADT + /// or function); so if `self` is `Option`, this returns the `u32`. + pub fn substs(&self) -> Option { + match self { + Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), + _ => None, + } + } + + /// If this is an `impl Trait` or `dyn Trait`, returns that trait. + pub fn inherent_trait(&self) -> Option { + match self { + Ty::Dyn(predicates) | Ty::Opaque(predicates) => { + predicates.iter().find_map(|pred| match pred { + GenericPredicate::Implemented(tr) => Some(tr.trait_), + _ => None, + }) + } + _ => None, + } + } +} + +/// This allows walking structures that contain types to do something with those +/// types, similar to Chalk's `Fold` trait. +pub trait TypeWalk { + fn walk(&self, f: &mut impl FnMut(&Ty)); + fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { + self.walk_mut_binders(&mut |ty, _binders| f(ty), 0); + } + /// Walk the type, counting entered binders. + /// + /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers + /// to the innermost binder, 1 to the next, etc.. So when we want to + /// substitute a certain bound variable, we can't just walk the whole type + /// and blindly replace each instance of a certain index; when we 'enter' + /// things that introduce new bound variables, we have to keep track of + /// that. Currently, the only thing that introduces bound variables on our + /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound + /// variable for the self type. + fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize); + + fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self + where + Self: Sized, + { + self.walk_mut(&mut |ty_mut| { + let ty = mem::replace(ty_mut, Ty::Unknown); + *ty_mut = f(ty); + }); + self + } + + /// Replaces type parameters in this type using the given `Substs`. (So e.g. + /// if `self` is `&[T]`, where type parameter T has index 0, and the + /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) + fn subst(self, substs: &Substs) -> Self + where + Self: Sized, + { + self.fold(&mut |ty| match ty { + Ty::Param { idx, name } => { + substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) + } + ty => ty, + }) + } + + /// Substitutes `Ty::Bound` vars (as opposed to type parameters). + fn subst_bound_vars(mut self, substs: &Substs) -> Self + where + Self: Sized, + { + self.walk_mut_binders( + &mut |ty, binders| match ty { + &mut Ty::Bound(idx) => { + if idx as usize >= binders && (idx as usize - binders) < substs.len() { + *ty = substs.0[idx as usize - binders].clone(); + } + } + _ => {} + }, + 0, + ); + self + } + + /// Shifts up `Ty::Bound` vars by `n`. + fn shift_bound_vars(self, n: i32) -> Self + where + Self: Sized, + { + self.fold(&mut |ty| match ty { + Ty::Bound(idx) => { + assert!(idx as i32 >= -n); + Ty::Bound((idx as i32 + n) as u32) + } + ty => ty, + }) + } +} + +impl TypeWalk for Ty { + fn walk(&self, f: &mut impl FnMut(&Ty)) { + match self { + Ty::Apply(a_ty) => { + for t in a_ty.parameters.iter() { + t.walk(f); + } + } + Ty::Projection(p_ty) => { + for t in p_ty.parameters.iter() { + t.walk(f); + } + } + Ty::Dyn(predicates) | Ty::Opaque(predicates) => { + for p in predicates.iter() { + p.walk(f); + } + } + Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} + } + f(self); + } + + fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { + match self { + Ty::Apply(a_ty) => { + a_ty.parameters.walk_mut_binders(f, binders); + } + Ty::Projection(p_ty) => { + p_ty.parameters.walk_mut_binders(f, binders); + } + Ty::Dyn(predicates) | Ty::Opaque(predicates) => { + for p in make_mut_slice(predicates) { + p.walk_mut_binders(f, binders + 1); + } + } + Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} + } + f(self, binders); + } +} + +impl HirDisplay for &Ty { + fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + HirDisplay::hir_fmt(*self, f) + } +} + +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")?, + TypeCtor::Int(t) => write!(f, "{}", t)?, + TypeCtor::Float(t) => write!(f, "{}", t)?, + TypeCtor::Str => write!(f, "str")?, + TypeCtor::Slice => { + let t = self.parameters.as_single(); + write!(f, "[{}]", t.display(f.db))?; + } + TypeCtor::Array => { + let t = self.parameters.as_single(); + write!(f, "[{};_]", t.display(f.db))?; + } + TypeCtor::RawPtr(m) => { + let t = self.parameters.as_single(); + write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?; + } + TypeCtor::Ref(m) => { + let t = self.parameters.as_single(); + write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?; + } + TypeCtor::Never => write!(f, "!")?, + TypeCtor::Tuple { .. } => { + let ts = &self.parameters; + if ts.len() == 1 { + write!(f, "({},)", ts[0].display(f.db))?; + } else { + write!(f, "(")?; + f.write_joined(&*ts.0, ", ")?; + write!(f, ")")?; + } + } + TypeCtor::FnPtr { .. } => { + let sig = FnSig::from_fn_ptr_substs(&self.parameters); + write!(f, "fn(")?; + f.write_joined(sig.params(), ", ")?; + write!(f, ") -> {}", sig.ret().display(f.db))?; + } + TypeCtor::FnDef(def) => { + let sig = f.db.callable_item_signature(def); + let name = match def { + CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), + CallableDef::StructId(s) => { + f.db.struct_data(s).name.clone().unwrap_or_else(Name::missing) + } + CallableDef::EnumVariantId(e) => { + let enum_data = f.db.enum_data(e.parent); + enum_data.variants[e.local_id].name.clone().unwrap_or_else(Name::missing) + } + }; + match def { + CallableDef::FunctionId(_) => write!(f, "fn {}", name)?, + CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { + write!(f, "{}", name)? + } + } + if self.parameters.len() > 0 { + write!(f, "<")?; + f.write_joined(&*self.parameters.0, ", ")?; + write!(f, ">")?; + } + write!(f, "(")?; + f.write_joined(sig.params(), ", ")?; + write!(f, ") -> {}", sig.ret().display(f.db))?; + } + TypeCtor::Adt(def_id) => { + let name = match def_id { + AdtId::StructId(it) => f.db.struct_data(it).name.clone(), + AdtId::UnionId(it) => f.db.union_data(it).name.clone(), + AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), + } + .unwrap_or_else(Name::missing); + write!(f, "{}", name)?; + if self.parameters.len() > 0 { + write!(f, "<")?; + f.write_joined(&*self.parameters.0, ", ")?; + write!(f, ">")?; + } + } + TypeCtor::AssociatedType(type_alias) => { + let trait_ = match type_alias.lookup(f.db).container { + ContainerId::TraitId(it) => it, + _ => panic!("not an associated type"), + }; + let trait_name = f.db.trait_data(trait_).name.clone().unwrap_or_else(Name::missing); + let name = f.db.type_alias_data(type_alias).name.clone(); + write!(f, "{}::{}", trait_name, name)?; + if self.parameters.len() > 0 { + write!(f, "<")?; + f.write_joined(&*self.parameters.0, ", ")?; + write!(f, ">")?; + } + } + TypeCtor::Closure { .. } => { + let sig = self.parameters[0] + .callable_sig(f.db) + .expect("first closure parameter should contain signature"); + write!(f, "|")?; + f.write_joined(sig.params(), ", ")?; + write!(f, "| -> {}", sig.ret().display(f.db))?; + } + } + Ok(()) + } +} + +impl HirDisplay for ProjectionTy { + fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + if f.should_truncate() { + return write!(f, "…"); + } + + let trait_name = + f.db.trait_data(self.trait_(f.db)).name.clone().unwrap_or_else(Name::missing); + write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; + if self.parameters.len() > 1 { + write!(f, "<")?; + f.write_joined(&self.parameters[1..], ", ")?; + write!(f, ">")?; + } + write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; + Ok(()) + } +} + +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)?, + Ty::Param { name, .. } => write!(f, "{}", name)?, + Ty::Bound(idx) => write!(f, "?{}", idx)?, + Ty::Dyn(predicates) | Ty::Opaque(predicates) => { + match self { + Ty::Dyn(_) => write!(f, "dyn ")?, + Ty::Opaque(_) => write!(f, "impl ")?, + _ => unreachable!(), + }; + // Note: This code is written to produce nice results (i.e. + // corresponding to surface Rust) for types that can occur in + // actual Rust. It will have weird results if the predicates + // aren't as expected (i.e. self types = $0, projection + // predicates for a certain trait come after the Implemented + // predicate for that trait). + let mut first = true; + let mut angle_open = false; + for p in predicates.iter() { + match p { + GenericPredicate::Implemented(trait_ref) => { + if angle_open { + write!(f, ">")?; + } + if !first { + write!(f, " + ")?; + } + // We assume that the self type is $0 (i.e. the + // existential) here, which is the only thing that's + // possible in actual Rust, and hence don't print it + write!( + f, + "{}", + f.db.trait_data(trait_ref.trait_) + .name + .clone() + .unwrap_or_else(Name::missing) + )?; + if trait_ref.substs.len() > 1 { + write!(f, "<")?; + f.write_joined(&trait_ref.substs[1..], ", ")?; + // there might be assoc type bindings, so we leave the angle brackets open + angle_open = true; + } + } + GenericPredicate::Projection(projection_pred) => { + // in types in actual Rust, these will always come + // after the corresponding Implemented predicate + if angle_open { + write!(f, ", ")?; + } else { + write!(f, "<")?; + angle_open = true; + } + let name = + f.db.type_alias_data(projection_pred.projection_ty.associated_ty) + .name + .clone(); + write!(f, "{} = ", name)?; + projection_pred.ty.hir_fmt(f)?; + } + GenericPredicate::Error => { + if angle_open { + // impl Trait + write!(f, ", ")?; + } else if !first { + // impl Trait + {error} + write!(f, " + ")?; + } + p.hir_fmt(f)?; + } + } + first = false; + } + if angle_open { + write!(f, ">")?; + } + } + Ty::Unknown => write!(f, "{{unknown}}")?, + Ty::Infer(..) => write!(f, "_")?, + } + Ok(()) + } +} + +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 ")?; + } else { + write!(f, ": ")?; + } + write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?; + if self.substs.len() > 1 { + write!(f, "<")?; + f.write_joined(&self.substs[1..], ", ")?; + write!(f, ">")?; + } + Ok(()) + } +} + +impl HirDisplay for TraitRef { + fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + self.hir_fmt_ext(f, false) + } +} + +impl HirDisplay for &GenericPredicate { + fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + HirDisplay::hir_fmt(*self, f) + } +} + +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) => { + write!(f, "<")?; + projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; + write!( + f, + ">::{} = {}", + f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, + projection_pred.ty.display(f.db) + )?; + } + GenericPredicate::Error => write!(f, "{{error}}")?, + } + Ok(()) + } +} + +impl HirDisplay for Obligation { + fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result { + match self { + Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)), + Obligation::Projection(proj) => write!( + f, + "Normalize({} => {})", + proj.projection_ty.display(f.db), + proj.ty.display(f.db) + ), + } + } +} diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir_ty/src/lower.rs similarity index 97% rename from crates/ra_hir/src/ty/lower.rs rename to crates/ra_hir_ty/src/lower.rs index 2d447f1ea7..53d955a124 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use hir_def::{ builtin_type::BuiltinType, generics::WherePredicate, - path::{GenericArg, Path, PathSegment}, + path::{GenericArg, Path, PathKind, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, @@ -26,15 +26,13 @@ use super::{ }; use crate::{ db::HirDatabase, - ty::{ - primitive::{FloatTy, IntTy}, - utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, - }, - util::make_mut_slice, + primitive::{FloatTy, IntTy}, + utils::make_mut_slice, + utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, }; impl Ty { - pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { + pub fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { match type_ref { TypeRef::Never => Ty::simple(TypeCtor::Never), TypeRef::Tuple(inner) => { @@ -103,7 +101,7 @@ impl Ty { TypeRef::Path(path) => path, _ => return None, }; - if let crate::PathKind::Type(_) = &path.kind { + if let PathKind::Type(_) = &path.kind { return None; } if path.segments.len() > 1 { @@ -204,7 +202,7 @@ impl Ty { pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { // Resolve the path (in type namespace) - if let crate::PathKind::Type(type_ref) = &path.kind { + if let PathKind::Type(type_ref) = &path.kind { let ty = Ty::from_hir(db, resolver, &type_ref); let remaining_segments = &path.segments[..]; return Ty::from_type_relative_path(db, resolver, ty, remaining_segments); @@ -421,7 +419,7 @@ impl TraitRef { substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) } - pub(crate) fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef { + pub fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef { let substs = Substs::identity(&db.generic_params(trait_.into())); TraitRef { trait_, substs } } @@ -495,7 +493,7 @@ fn assoc_type_bindings_from_type_bound<'a>( } /// Build the signature of a callable item (function, struct or enum variant). -pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { +pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { match def { CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), @@ -544,7 +542,7 @@ pub(crate) fn generic_predicates_for_param_query( } impl TraitEnvironment { - pub(crate) fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc { + pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc { let predicates = resolver .where_predicates_in_scope() .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir_ty/src/marks.rs similarity index 100% rename from crates/ra_hir/src/marks.rs rename to crates/ra_hir_ty/src/marks.rs diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs similarity index 98% rename from crates/ra_hir/src/ty/method_resolution.rs rename to crates/ra_hir_ty/src/method_resolution.rs index 5cc2498552..53c541eb8e 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -16,8 +16,9 @@ use rustc_hash::FxHashMap; use crate::{ db::HirDatabase, - ty::primitive::{FloatBitness, Uncertain}, - ty::{utils::all_super_traits, Ty, TypeCtor}, + primitive::{FloatBitness, Uncertain}, + utils::all_super_traits, + Ty, TypeCtor, }; use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; @@ -97,7 +98,7 @@ impl CrateImplBlocks { } impl Ty { - pub(crate) fn def_crates( + pub fn def_crates( &self, db: &impl HirDatabase, cur_crate: CrateId, @@ -176,7 +177,7 @@ pub enum LookupMode { // This would be nicer if it just returned an iterator, but that runs into // lifetime problems, because we need to borrow temp `CrateImplBlocks`. // FIXME add a context type here? -pub(crate) fn iterate_method_candidates( +pub fn iterate_method_candidates( ty: &Canonical, db: &impl HirDatabase, resolver: &Resolver, @@ -323,7 +324,7 @@ fn is_valid_candidate( } } -pub(crate) fn implements_trait( +pub fn implements_trait( ty: &Canonical, db: &impl HirDatabase, resolver: &Resolver, diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir_ty/src/op.rs similarity index 98% rename from crates/ra_hir/src/ty/op.rs rename to crates/ra_hir_ty/src/op.rs index cc6e244f44..09c47a76d0 100644 --- a/crates/ra_hir/src/ty/op.rs +++ b/crates/ra_hir_ty/src/op.rs @@ -2,7 +2,7 @@ use hir_def::expr::{BinaryOp, CmpOp}; use super::{InferTy, Ty, TypeCtor}; -use crate::ty::ApplicationTy; +use crate::ApplicationTy; pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { match op { diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs similarity index 59% rename from crates/ra_hir/src/test_db.rs rename to crates/ra_hir_ty/src/test_db.rs index a2071f71cf..0e51f4130f 100644 --- a/crates/ra_hir/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs @@ -2,20 +2,20 @@ use std::{panic, sync::Arc}; -use hir_def::{db::DefDatabase, ModuleId}; +use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; use hir_expand::diagnostics::DiagnosticSink; use parking_lot::Mutex; use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; -use crate::{db, debug::HirDebugHelper}; +use crate::{db::HirDatabase, expr::ExprValidator}; #[salsa::database( ra_db::SourceDatabaseExtStorage, ra_db::SourceDatabaseStorage, - db::InternDatabaseStorage, - db::AstDatabaseStorage, - db::DefDatabaseStorage, - db::HirDatabaseStorage + hir_expand::db::AstDatabaseStorage, + hir_def::db::InternDatabaseStorage, + hir_def::db::DefDatabaseStorage, + crate::db::HirDatabaseStorage )] #[derive(Debug, Default)] pub struct TestDB { @@ -67,32 +67,53 @@ impl FileLoader for TestDB { } } -// FIXME: improve `WithFixture` to bring useful hir debugging back -impl HirDebugHelper for TestDB { - fn crate_name(&self, _krate: CrateId) -> Option { - None - } - - fn file_path(&self, _file_id: FileId) -> Option { - None - } -} - impl TestDB { + pub fn module_for_file(&self, file_id: FileId) -> ModuleId { + for &krate in self.relevant_crates(file_id).iter() { + let crate_def_map = self.crate_def_map(krate); + for (module_id, data) in crate_def_map.modules.iter() { + if data.definition == Some(file_id) { + return ModuleId { krate, module_id }; + } + } + } + panic!("Can't find module for file") + } + + // FIXME: don't duplicate this pub fn diagnostics(&self) -> String { let mut buf = String::new(); let crate_graph = self.crate_graph(); for krate in crate_graph.iter().next() { let crate_def_map = self.crate_def_map(krate); + + let mut fns = Vec::new(); for (module_id, _) in crate_def_map.modules.iter() { - let module_id = ModuleId { krate, module_id }; - let module = crate::Module::from(module_id); - module.diagnostics( - self, - &mut DiagnosticSink::new(|d| { - buf += &format!("{:?}: {}\n", d.syntax_node(self).text(), d.message()); - }), - ) + for decl in crate_def_map[module_id].scope.declarations() { + match decl { + ModuleDefId::FunctionId(f) => fns.push(f), + _ => (), + } + } + + for &impl_id in crate_def_map[module_id].impls.iter() { + let impl_data = self.impl_data(impl_id); + for item in impl_data.items.iter() { + if let AssocItemId::FunctionId(f) = item { + fns.push(*f) + } + } + } + } + + for f in fns { + let infer = self.infer(f.into()); + let mut sink = DiagnosticSink::new(|d| { + buf += &format!("{:?}: {}\n", d.syntax_node(self).text(), d.message()); + }); + infer.add_diagnostics(self, f, &mut sink); + let mut validator = ExprValidator::new(f, infer, &mut sink); + validator.validate_body(self); } } buf diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir_ty/src/tests.rs similarity index 96% rename from crates/ra_hir/src/ty/tests.rs rename to crates/ra_hir_ty/src/tests.rs index 98eb863cb9..c1744663a6 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs @@ -4,20 +4,20 @@ mod coercion; use std::fmt::Write; use std::sync::Arc; +use hir_def::{ + body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId, + LocalModuleId, Lookup, ModuleDefId, +}; +use hir_expand::Source; use insta::assert_snapshot; use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; use ra_syntax::{ algo, ast::{self, AstNode}, - SyntaxKind::*, }; -use rustc_hash::FxHashSet; use test_utils::covers; -use crate::{ - expr::BodySourceMap, test_db::TestDB, ty::display::HirDisplay, ty::InferenceResult, Source, - SourceAnalyzer, -}; +use crate::{db::HirDatabase, display::HirDisplay, test_db::TestDB, InferenceResult}; // These tests compare the inference results for all expressions in a file // against snapshots of the expected results using insta. Use cargo-insta to @@ -4674,10 +4674,20 @@ fn test() where T: Trait, U: Trait { fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { let file = db.parse(pos.file_id).ok().unwrap(); let expr = algo::find_node_at_offset::(file.syntax(), pos.offset).unwrap(); - let analyzer = - SourceAnalyzer::new(db, Source::new(pos.file_id.into(), expr.syntax()), Some(pos.offset)); - let ty = analyzer.type_of(db, &expr).unwrap(); - ty.display(db).to_string() + + let module = db.module_for_file(pos.file_id); + let crate_def_map = db.crate_def_map(module.krate); + for decl in crate_def_map[module.module_id].scope.declarations() { + if let ModuleDefId::FunctionId(func) = decl { + let (_body, source_map) = db.body_with_source_map(func.into()); + if let Some(expr_id) = source_map.node_expr(Source::new(pos.file_id.into(), &expr)) { + let infer = db.infer(func.into()); + let ty = &infer[expr_id]; + return ty.display(db).to_string(); + } + } + } + panic!("Can't find expression") } fn type_at(content: &str) -> String { @@ -4687,7 +4697,6 @@ fn type_at(content: &str) -> String { fn infer(content: &str) -> String { let (db, file_id) = TestDB::with_single_file(content); - let source_file = db.parse(file_id).ok().unwrap(); let mut acc = String::new(); @@ -4740,20 +4749,69 @@ 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); - if analyzed.insert(analyzer.analyzed_declaration()) { - infer_def(analyzer.inference_result(), analyzer.body_source_map()); - } + let module = db.module_for_file(file_id); + let crate_def_map = db.crate_def_map(module.krate); + + let mut defs: Vec = Vec::new(); + visit_module(&db, &crate_def_map, module.module_id, &mut |it| defs.push(it)); + defs.sort_by_key(|def| match def { + DefWithBodyId::FunctionId(it) => { + it.lookup(&db).ast_id.to_node(&db).syntax().text_range().start() } + DefWithBodyId::ConstId(it) => { + it.lookup(&db).ast_id.to_node(&db).syntax().text_range().start() + } + DefWithBodyId::StaticId(it) => { + it.lookup(&db).ast_id.to_node(&db).syntax().text_range().start() + } + }); + for def in defs { + let (_body, source_map) = db.body_with_source_map(def); + let infer = db.infer(def); + infer_def(infer, source_map); } acc.truncate(acc.trim_end().len()); acc } +fn visit_module( + db: &TestDB, + crate_def_map: &CrateDefMap, + module_id: LocalModuleId, + cb: &mut dyn FnMut(DefWithBodyId), +) { + for decl in crate_def_map[module_id].scope.declarations() { + match decl { + ModuleDefId::FunctionId(it) => cb(it.into()), + ModuleDefId::ConstId(it) => cb(it.into()), + ModuleDefId::StaticId(it) => cb(it.into()), + ModuleDefId::TraitId(it) => { + let trait_data = db.trait_data(it); + for &(_, item) in trait_data.items.iter() { + match item { + AssocItemId::FunctionId(it) => cb(it.into()), + AssocItemId::ConstId(it) => cb(it.into()), + AssocItemId::TypeAliasId(_) => (), + } + } + } + ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.module_id, cb), + _ => (), + } + } + for &impl_id in crate_def_map[module_id].impls.iter() { + let impl_data = db.impl_data(impl_id); + for &item in impl_data.items.iter() { + match item { + AssocItemId::FunctionId(it) => cb(it.into()), + AssocItemId::ConstId(it) => cb(it.into()), + AssocItemId::TypeAliasId(_) => (), + } + } + } +} + fn ellipsize(mut text: String, max_len: usize) -> String { if text.len() <= max_len { return text; @@ -4783,10 +4841,12 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { ", ); { - let file = db.parse(pos.file_id).ok().unwrap(); - let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent(); let events = db.log_executed(|| { - SourceAnalyzer::new(&db, Source::new(pos.file_id.into(), &node), None); + let module = db.module_for_file(pos.file_id); + let crate_def_map = db.crate_def_map(module.krate); + visit_module(&db, &crate_def_map, module.module_id, &mut |def| { + db.infer(def); + }); }); assert!(format!("{:?}", events).contains("infer")) } @@ -4803,10 +4863,12 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text)); { - let file = db.parse(pos.file_id).ok().unwrap(); - let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent(); let events = db.log_executed(|| { - SourceAnalyzer::new(&db, Source::new(pos.file_id.into(), &node), None); + let module = db.module_for_file(pos.file_id); + let crate_def_map = db.crate_def_map(module.krate); + visit_module(&db, &crate_def_map, module.module_id, &mut |def| { + db.infer(def); + }); }); assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) } diff --git a/crates/ra_hir/src/ty/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs similarity index 100% rename from crates/ra_hir/src/ty/tests/coercion.rs rename to crates/ra_hir_ty/src/tests/coercion.rs diff --git a/crates/ra_hir/src/ty/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs similarity index 100% rename from crates/ra_hir/src/ty/tests/never_type.rs rename to crates/ra_hir_ty/src/tests/never_type.rs diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir_ty/src/traits.rs similarity index 100% rename from crates/ra_hir/src/ty/traits.rs rename to crates/ra_hir_ty/src/traits.rs diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs similarity index 96% rename from crates/ra_hir/src/ty/traits/chalk.rs rename to crates/ra_hir_ty/src/traits/chalk.rs index 67ac5422cf..810e8c21a6 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -11,8 +11,8 @@ use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum use ra_db::CrateId; use hir_def::{ - lang_item::LangItemTarget, resolver::HasResolver, AssocItemId, AstItemDef, ContainerId, - GenericDefId, ImplId, Lookup, TraitId, TypeAliasId, + expr::Expr, lang_item::LangItemTarget, resolver::HasResolver, AssocItemId, AstItemDef, + ContainerId, GenericDefId, ImplId, Lookup, TraitId, TypeAliasId, }; use hir_expand::name; @@ -21,8 +21,8 @@ use ra_db::salsa::{InternId, InternKey}; use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; use crate::{ db::HirDatabase, - ty::display::HirDisplay, - ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, + display::HirDisplay, + {ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, }; /// This represents a trait whose name we could not resolve. @@ -723,7 +723,7 @@ fn closure_fn_trait_impl_datum( let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name::OUTPUT_TYPE)?; let num_args: u16 = match &db.body(data.def.into())[data.expr] { - crate::expr::Expr::Lambda { args, .. } => args.len() as u16, + Expr::Lambda { args, .. } => args.len() as u16, _ => { log::warn!("closure for closure type {:?} not found", data); 0 @@ -823,7 +823,7 @@ fn closure_fn_trait_output_assoc_ty_value( let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db); let num_args: u16 = match &db.body(data.def.into())[data.expr] { - crate::expr::Expr::Lambda { args, .. } => args.len() as u16, + Expr::Lambda { args, .. } => args.len() as u16, _ => { log::warn!("closure for closure type {:?} not found", data); 0 @@ -869,38 +869,38 @@ fn id_to_chalk(salsa_id: T) -> chalk_ir::RawId { chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } } -impl From for crate::ty::TypeCtorId { +impl From for crate::TypeCtorId { fn from(struct_id: chalk_ir::StructId) -> Self { id_from_chalk(struct_id.0) } } -impl From for chalk_ir::StructId { - fn from(type_ctor_id: crate::ty::TypeCtorId) -> Self { +impl From for chalk_ir::StructId { + fn from(type_ctor_id: crate::TypeCtorId) -> Self { chalk_ir::StructId(id_to_chalk(type_ctor_id)) } } -impl From for crate::ty::traits::GlobalImplId { +impl From for crate::traits::GlobalImplId { fn from(impl_id: chalk_ir::ImplId) -> Self { id_from_chalk(impl_id.0) } } -impl From for chalk_ir::ImplId { - fn from(impl_id: crate::ty::traits::GlobalImplId) -> Self { +impl From for chalk_ir::ImplId { + fn from(impl_id: crate::traits::GlobalImplId) -> Self { chalk_ir::ImplId(id_to_chalk(impl_id)) } } -impl From for crate::ty::traits::AssocTyValueId { +impl From for crate::traits::AssocTyValueId { fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self { id_from_chalk(id.0) } } -impl From for chalk_rust_ir::AssociatedTyValueId { - fn from(assoc_ty_value_id: crate::ty::traits::AssocTyValueId) -> Self { +impl From for chalk_rust_ir::AssociatedTyValueId { + fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id)) } } diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir_ty/src/utils.rs similarity index 89% rename from crates/ra_hir/src/ty/utils.rs rename to crates/ra_hir_ty/src/utils.rs index f82e6ac9b1..e4ba890efa 100644 --- a/crates/ra_hir/src/ty/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -73,3 +73,12 @@ pub(super) fn variant_data(db: &impl DefDatabase, var: VariantId) -> Arc` (i.e. `Arc::make_mut` for Arc slices). +/// The underlying values are cloned if there are other strong references. +pub(crate) fn make_mut_slice(a: &mut Arc<[T]>) -> &mut [T] { + if Arc::get_mut(a).is_none() { + *a = a.iter().cloned().collect(); + } + Arc::get_mut(a).unwrap() +} diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index b3ebd91454..aa480e399b 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use hir::{ApplicationTy, FromSource, ImplBlock, Ty, TypeCtor}; +use hir::{FromSource, ImplBlock}; use ra_db::SourceDatabase; use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; @@ -61,7 +61,7 @@ fn impls_for_def( Some( impls .into_iter() - .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) + .filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(db))) .map(|imp| imp.to_nav(db)) .collect(), ) @@ -82,19 +82,6 @@ fn impls_for_trait( Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect()) } -fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { - match (original_ty, impl_ty) { - (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor { - TypeCtor::Ref(..) => match parameters.as_single() { - Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, - _ => false, - }, - _ => a_original_ty.ctor == *ctor, - }, - _ => false, - } -} - #[cfg(test)] mod tests { use crate::mock_analysis::analysis_and_position; diff --git a/xtask/tests/tidy-tests/docs.rs b/xtask/tests/tidy-tests/docs.rs index fae871285a..e0653b460f 100644 --- a/xtask/tests/tidy-tests/docs.rs +++ b/xtask/tests/tidy-tests/docs.rs @@ -83,6 +83,7 @@ fn no_docs_comments() { "ra_syntax", "ra_text_edit", "ra_tt", + "ra_hir_ty", ]; let mut has_fixmes = whitelist.iter().map(|it| (*it, false)).collect::>(); From 47ec2ceb12df756b3482ddd2b1947e4b38f23706 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 21:23:31 +0300 Subject: [PATCH 58/65] prune deps --- Cargo.lock | 16 ---------------- crates/ra_hir/Cargo.toml | 20 -------------------- crates/ra_hir_ty/Cargo.toml | 11 +++++------ crates/ra_hir_ty/src/test_db.rs | 12 +++++++----- 4 files changed, 12 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9227c911d..0f7a45d6cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -962,28 +962,13 @@ dependencies = [ name = "ra_hir" version = "0.1.0" dependencies = [ - "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", - "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", - "chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", - "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ra_arena 0.1.0", - "ra_cfg 0.1.0", "ra_db 0.1.0", "ra_hir_def 0.1.0", "ra_hir_expand 0.1.0", "ra_hir_ty 0.1.0", - "ra_mbe 0.1.0", - "ra_prof 0.1.0", "ra_syntax 0.1.0", - "ra_tt 0.1.0", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "test_utils 0.1.0", ] [[package]] @@ -1031,7 +1016,6 @@ dependencies = [ "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ra_arena 0.1.0", "ra_db 0.1.0", "ra_hir_def 0.1.0", diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index caba85a4f0..e79361e7cc 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml @@ -8,31 +8,11 @@ authors = ["rust-analyzer developers"] doctest = false [dependencies] -arrayvec = "0.5.1" log = "0.4.5" rustc-hash = "1.0" -parking_lot = "0.10.0" -ena = "0.13" -once_cell = "1.0.1" ra_syntax = { path = "../ra_syntax" } -ra_arena = { path = "../ra_arena" } -ra_cfg = { path = "../ra_cfg" } ra_db = { path = "../ra_db" } -mbe = { path = "../ra_mbe", package = "ra_mbe" } -tt = { path = "../ra_tt", package = "ra_tt" } hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } -test_utils = { path = "../test_utils" } -ra_prof = { path = "../ra_prof" } - -# https://github.com/rust-lang/chalk/pull/294 -chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } -chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } -chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } - -lalrpop-intern = "0.15.1" - -[dev-dependencies] -insta = "0.12.0" diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index 199afff493..429242870f 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml @@ -9,18 +9,17 @@ doctest = false [dependencies] arrayvec = "0.5.1" +ena = "0.13" log = "0.4.5" rustc-hash = "1.0" -parking_lot = "0.10.0" -ena = "0.13" -ra_syntax = { path = "../ra_syntax" } +hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } +hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } ra_arena = { path = "../ra_arena" } ra_db = { path = "../ra_db" } -hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } -hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } -test_utils = { path = "../test_utils" } ra_prof = { path = "../ra_prof" } +ra_syntax = { path = "../ra_syntax" } +test_utils = { path = "../test_utils" } # https://github.com/rust-lang/chalk/pull/294 chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index 0e51f4130f..8743570085 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs @@ -1,10 +1,12 @@ //! Database used for testing `hir`. -use std::{panic, sync::Arc}; +use std::{ + panic, + sync::{Arc, Mutex}, +}; use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; use hir_expand::diagnostics::DiagnosticSink; -use parking_lot::Mutex; use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; use crate::{db::HirDatabase, expr::ExprValidator}; @@ -33,7 +35,7 @@ impl salsa::Database for TestDB { } fn salsa_event(&self, event: impl Fn() -> salsa::Event) { - let mut events = self.events.lock(); + let mut events = self.events.lock().unwrap(); if let Some(events) = &mut *events { events.push(event()); } @@ -122,9 +124,9 @@ impl TestDB { impl TestDB { pub fn log(&self, f: impl FnOnce()) -> Vec> { - *self.events.lock() = Some(Vec::new()); + *self.events.lock().unwrap() = Some(Vec::new()); f(); - self.events.lock().take().unwrap() + self.events.lock().unwrap().take().unwrap() } pub fn log_executed(&self, f: impl FnOnce()) -> Vec { From d9a36a736bfb91578a36505e7237212959bb55fe Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 21:31:51 +0300 Subject: [PATCH 59/65] Rename module_id -> local_id --- crates/ra_hir/src/code_model.rs | 20 +++++++++---------- crates/ra_hir/src/code_model/src.rs | 4 ++-- crates/ra_hir/src/from_source.rs | 8 ++++---- crates/ra_hir_def/src/attr.rs | 2 +- crates/ra_hir_def/src/body.rs | 2 +- crates/ra_hir_def/src/docs.rs | 2 +- crates/ra_hir_def/src/lang_item.rs | 4 ++-- crates/ra_hir_def/src/lib.rs | 2 +- crates/ra_hir_def/src/nameres/collector.rs | 14 ++++++------- .../ra_hir_def/src/nameres/path_resolution.rs | 16 +++++++-------- crates/ra_hir_def/src/resolver.rs | 6 +++--- crates/ra_hir_ty/src/test_db.rs | 4 ++-- crates/ra_hir_ty/src/tests.rs | 10 +++++----- 13 files changed, 47 insertions(+), 47 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 87c78d98e1..5a3e24e9e4 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -174,15 +174,15 @@ pub use hir_def::attr::Attrs; impl Module { pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { - Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } + Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } } } /// Name of this module. pub fn name(self, db: &impl DefDatabase) -> Option { let def_map = db.crate_def_map(self.id.krate); - let parent = def_map[self.id.module_id].parent?; + let parent = def_map[self.id.local_id].parent?; def_map[parent].children.iter().find_map(|(name, module_id)| { - if *module_id == self.id.module_id { + if *module_id == self.id.local_id { Some(name.clone()) } else { None @@ -206,14 +206,14 @@ impl Module { /// Finds a child module with the specified name. pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option { let def_map = db.crate_def_map(self.id.krate); - let child_id = def_map[self.id.module_id].children.get(name)?; + let child_id = def_map[self.id.local_id].children.get(name)?; Some(self.with_module_id(*child_id)) } /// Iterates over all child modules. pub fn children(self, db: &impl DefDatabase) -> impl Iterator { let def_map = db.crate_def_map(self.id.krate); - let children = def_map[self.id.module_id] + let children = def_map[self.id.local_id] .children .iter() .map(|(_, module_id)| self.with_module_id(*module_id)) @@ -224,7 +224,7 @@ impl Module { /// Finds a parent module. pub fn parent(self, db: &impl DefDatabase) -> Option { let def_map = db.crate_def_map(self.id.krate); - let parent_id = def_map[self.id.module_id].parent?; + let parent_id = def_map[self.id.local_id].parent?; Some(self.with_module_id(parent_id)) } @@ -240,7 +240,7 @@ impl Module { /// Returns a `ModuleScope`: a set of items, visible in this module. pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option)> { - db.crate_def_map(self.id.krate)[self.id.module_id] + db.crate_def_map(self.id.krate)[self.id.local_id] .scope .entries() .map(|(name, res)| { @@ -250,7 +250,7 @@ impl Module { } pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { - db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.module_id, sink); + db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink); for decl in self.declarations(db) { match decl { crate::ModuleDef::Function(f) => f.diagnostics(db, sink), @@ -275,12 +275,12 @@ 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.declarations().map(ModuleDef::from).collect() + def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() } pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec { let def_map = db.crate_def_map(self.id.krate); - def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() + def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() } fn with_module_id(self, module_id: LocalModuleId) -> Module { diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 076d86f2b9..bf3ee08341 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -22,7 +22,7 @@ impl Module { /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. pub fn definition_source(self, db: &impl DefDatabase) -> Source { let def_map = db.crate_def_map(self.id.krate); - let src = def_map[self.id.module_id].definition_source(db); + let src = def_map[self.id.local_id].definition_source(db); src.map(|it| match it { Either::A(it) => ModuleSource::SourceFile(it), Either::B(it) => ModuleSource::Module(it), @@ -33,7 +33,7 @@ impl Module { /// `None` for the crate root. pub fn declaration_source(self, db: &impl DefDatabase) -> Option> { let def_map = db.crate_def_map(self.id.krate); - def_map[self.id.module_id].declaration_source(db) + def_map[self.id.local_id].declaration_source(db) } } diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 95db7161bf..7756ca80e7 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -262,13 +262,13 @@ impl Module { let original_file = src.file_id.original_file(db); - let (krate, module_id) = + let (krate, local_id) = db.relevant_crates(original_file).iter().find_map(|&crate_id| { let crate_def_map = db.crate_def_map(crate_id); - let local_module_id = crate_def_map.modules_for_file(original_file).next()?; - Some((crate_id, local_module_id)) + let local_id = crate_def_map.modules_for_file(original_file).next()?; + Some((crate_id, local_id)) })?; - Some(Module { id: ModuleId { krate, module_id } }) + Some(Module { id: ModuleId { krate, local_id } }) } } diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 298608e27c..fffb22201d 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -35,7 +35,7 @@ impl Attrs { match def { AttrDefId::ModuleId(module) => { let def_map = db.crate_def_map(module.krate); - let src = match def_map[module.module_id].declaration_source(db) { + let src = match def_map[module.local_id].declaration_source(db) { Some(it) => it, None => return Attrs::default(), }; diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 78a532bdd6..a57a0176d4 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -82,7 +82,7 @@ impl Expander { } fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option { - self.crate_def_map.resolve_path(db, self.module.module_id, path).0.take_macros() + self.crate_def_map.resolve_path(db, self.module.local_id, path).0.take_macros() } } diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 4749b642f0..34ed9b7a5e 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -36,7 +36,7 @@ impl Documentation { match def { AttrDefId::ModuleId(module) => { let def_map = db.crate_def_map(module.krate); - let src = def_map[module.module_id].declaration_source(db)?; + let src = def_map[module.local_id].declaration_source(db)?; docs_from_ast(&src.value) } AttrDefId::StructFieldId(it) => { diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index f15c23db9d..f4fdbdcfc7 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs @@ -41,7 +41,7 @@ impl LangItems { crate_def_map .modules .iter() - .filter_map(|(module_id, _)| db.module_lang_items(ModuleId { krate, module_id })) + .filter_map(|(local_id, _)| db.module_lang_items(ModuleId { krate, local_id })) .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v)))); Arc::new(lang_items) @@ -80,7 +80,7 @@ impl LangItems { fn collect_lang_items(&mut self, db: &impl DefDatabase, module: ModuleId) { // Look for impl targets let def_map = db.crate_def_map(module.krate); - let module_data = &def_map[module.module_id]; + let module_data = &def_map[module.local_id]; for &impl_block in module_data.impls.iter() { self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId) } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index ddf464c605..bc55308969 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -50,7 +50,7 @@ impl_arena_id!(LocalImportId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ModuleId { pub krate: CrateId, - pub module_id: LocalModuleId, + pub local_id: LocalModuleId, } /// An ID of a module, **local** to a specific crate diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index ea3abfdae2..6cd14026bc 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -37,7 +37,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); def_map.extern_prelude.insert( dep.as_name(), - ModuleId { krate: dep.crate_id, module_id: dep_def_map.root }.into(), + ModuleId { krate: dep.crate_id, local_id: dep_def_map.root }.into(), ); // look for the prelude @@ -323,7 +323,7 @@ where tested_by!(glob_across_crates); // glob import from other crate => we can just import everything once let item_map = self.db.crate_def_map(m.krate); - let scope = &item_map[m.module_id].scope; + let scope = &item_map[m.local_id].scope; // Module scoped macros is included let items = scope @@ -337,7 +337,7 @@ where // glob import from same crate => we do an initial // import, and then need to propagate any further // additions - let scope = &self.def_map[m.module_id].scope; + let scope = &self.def_map[m.local_id].scope; // Module scoped macros is included let items = scope @@ -349,7 +349,7 @@ where self.update(module_id, Some(import_id), &items); // record the glob import in case we add further items self.glob_imports - .entry(m.module_id) + .entry(m.local_id) .or_default() .push((module_id, import_id)); } @@ -590,7 +590,7 @@ where raw::RawItemKind::Impl(imp) => { let module = ModuleId { krate: self.def_collector.def_map.krate, - module_id: self.module_id, + local_id: self.module_id, }; let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); let imp_id = ImplId::from_ast_id(ctx, self.raw_items[imp].ast_id); @@ -673,7 +673,7 @@ where modules[self.module_id].children.insert(name.clone(), res); let resolution = Resolution { def: PerNs::types( - ModuleId { krate: self.def_collector.def_map.krate, module_id: res }.into(), + ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), ), import: None, }; @@ -683,7 +683,7 @@ where fn define_def(&mut self, def: &raw::DefData) { let module = - ModuleId { krate: self.def_collector.def_map.krate, module_id: self.module_id }; + ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); let name = def.name.clone(); diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 9455f22bbd..b72c55bd10 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -74,19 +74,19 @@ impl CrateDefMap { PathKind::DollarCrate(krate) => { if krate == self.krate { tested_by!(macro_dollar_crate_self); - PerNs::types(ModuleId { krate: self.krate, module_id: self.root }.into()) + PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into()) } else { let def_map = db.crate_def_map(krate); - let module = ModuleId { krate, module_id: def_map.root }; + let module = ModuleId { krate, local_id: def_map.root }; tested_by!(macro_dollar_crate_other); PerNs::types(module.into()) } } PathKind::Crate => { - PerNs::types(ModuleId { krate: self.krate, module_id: self.root }.into()) + PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into()) } PathKind::Self_ => { - PerNs::types(ModuleId { krate: self.krate, module_id: original_module }.into()) + PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into()) } // plain import or absolute path in 2015: crate-relative with // fallback to extern prelude (with the simplification in @@ -113,7 +113,7 @@ impl CrateDefMap { } PathKind::Super => { if let Some(p) = self.modules[original_module].parent { - PerNs::types(ModuleId { krate: self.krate, module_id: p }.into()) + PerNs::types(ModuleId { krate: self.krate, local_id: p }.into()) } else { log::debug!("super path in root module"); return ResolvePathResult::empty(ReachedFixedPoint::Yes); @@ -160,7 +160,7 @@ impl CrateDefMap { Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; log::debug!("resolving {:?} in other crate", path); let defp_map = db.crate_def_map(module.krate); - let (def, s) = defp_map.resolve_path(db, module.module_id, &path); + let (def, s) = defp_map.resolve_path(db, module.local_id, &path); return ResolvePathResult::with( def, ReachedFixedPoint::Yes, @@ -169,7 +169,7 @@ impl CrateDefMap { } // Since it is a qualified path here, it should not contains legacy macros - match self[module.module_id].scope.get(&segment.name) { + match self[module.local_id].scope.get(&segment.name) { Some(res) => res.def, _ => { log::debug!("path segment {:?} not found", segment.name); @@ -254,7 +254,7 @@ impl CrateDefMap { keep = db.crate_def_map(prelude.krate); &keep }; - def_map[prelude.module_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) + def_map[prelude.local_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) } else { PerNs::none() } diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 5155365ccb..0847f6dcf4 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -325,7 +325,7 @@ impl Resolver { if let Scope::ModuleScope(m) = scope { if let Some(prelude) = m.crate_def_map.prelude { let prelude_def_map = db.crate_def_map(prelude.krate); - traits.extend(prelude_def_map[prelude.module_id].scope.traits()); + traits.extend(prelude_def_map[prelude.local_id].scope.traits()); } traits.extend(m.crate_def_map[m.module_id].scope.traits()); } @@ -402,7 +402,7 @@ impl Scope { }); if let Some(prelude) = m.crate_def_map.prelude { let prelude_def_map = db.crate_def_map(prelude.krate); - prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { + prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, res)| { f(name.clone(), ScopeDef::PerNs(res.def)); }); } @@ -492,7 +492,7 @@ pub trait HasResolver: Copy { impl HasResolver for ModuleId { fn resolver(self, db: &impl DefDatabase) -> Resolver { let def_map = db.crate_def_map(self.krate); - Resolver::default().push_module_scope(def_map, self.module_id) + Resolver::default().push_module_scope(def_map, self.local_id) } } diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index 8743570085..1dc9793f95 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs @@ -73,9 +73,9 @@ impl TestDB { pub fn module_for_file(&self, file_id: FileId) -> ModuleId { for &krate in self.relevant_crates(file_id).iter() { let crate_def_map = self.crate_def_map(krate); - for (module_id, data) in crate_def_map.modules.iter() { + for (local_id, data) in crate_def_map.modules.iter() { if data.definition == Some(file_id) { - return ModuleId { krate, module_id }; + return ModuleId { krate, local_id }; } } } diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index c1744663a6..c8461b447a 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs @@ -4677,7 +4677,7 @@ fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { let module = db.module_for_file(pos.file_id); let crate_def_map = db.crate_def_map(module.krate); - for decl in crate_def_map[module.module_id].scope.declarations() { + for decl in crate_def_map[module.local_id].scope.declarations() { if let ModuleDefId::FunctionId(func) = decl { let (_body, source_map) = db.body_with_source_map(func.into()); if let Some(expr_id) = source_map.node_expr(Source::new(pos.file_id.into(), &expr)) { @@ -4753,7 +4753,7 @@ fn infer(content: &str) -> String { let crate_def_map = db.crate_def_map(module.krate); let mut defs: Vec = Vec::new(); - visit_module(&db, &crate_def_map, module.module_id, &mut |it| defs.push(it)); + visit_module(&db, &crate_def_map, module.local_id, &mut |it| defs.push(it)); defs.sort_by_key(|def| match def { DefWithBodyId::FunctionId(it) => { it.lookup(&db).ast_id.to_node(&db).syntax().text_range().start() @@ -4796,7 +4796,7 @@ fn visit_module( } } } - ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.module_id, cb), + ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.local_id, cb), _ => (), } } @@ -4844,7 +4844,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id); let crate_def_map = db.crate_def_map(module.krate); - visit_module(&db, &crate_def_map, module.module_id, &mut |def| { + visit_module(&db, &crate_def_map, module.local_id, &mut |def| { db.infer(def); }); }); @@ -4866,7 +4866,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id); let crate_def_map = db.crate_def_map(module.krate); - visit_module(&db, &crate_def_map, module.module_id, &mut |def| { + visit_module(&db, &crate_def_map, module.local_id, &mut |def| { db.infer(def); }); }); From 757e593b253b4df7e6fc8bf15a4d4f34c9d484c5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 21:32:33 +0300 Subject: [PATCH 60/65] rename ra_ide_api -> ra_ide --- Cargo.lock | 8 +++---- README.md | 2 +- crates/ra_batch/Cargo.toml | 2 +- crates/ra_batch/src/lib.rs | 2 +- crates/ra_cli/Cargo.toml | 2 +- crates/ra_cli/src/analysis_bench.rs | 2 +- crates/ra_cli/src/main.rs | 2 +- crates/ra_db/src/lib.rs | 2 +- crates/{ra_ide_api => ra_ide}/Cargo.toml | 4 ++-- crates/{ra_ide_api => ra_ide}/src/assists.rs | 0 .../{ra_ide_api => ra_ide}/src/call_info.rs | 0 crates/{ra_ide_api => ra_ide}/src/change.rs | 0 .../{ra_ide_api => ra_ide}/src/completion.rs | 0 .../src/completion/complete_dot.rs | 0 .../src/completion/complete_fn_param.rs | 0 .../src/completion/complete_keyword.rs | 0 .../complete_macro_in_item_position.rs | 0 .../src/completion/complete_path.rs | 0 .../src/completion/complete_pattern.rs | 0 .../src/completion/complete_postfix.rs | 0 .../src/completion/complete_record_literal.rs | 0 .../src/completion/complete_record_pattern.rs | 0 .../src/completion/complete_scope.rs | 0 .../src/completion/complete_snippet.rs | 0 .../src/completion/completion_context.rs | 0 .../src/completion/completion_item.rs | 0 .../src/completion/presentation.rs | 0 crates/{ra_ide_api => ra_ide}/src/db.rs | 0 .../{ra_ide_api => ra_ide}/src/diagnostics.rs | 0 crates/{ra_ide_api => ra_ide}/src/display.rs | 0 .../src/display/function_signature.rs | 0 .../src/display/navigation_target.rs | 0 .../src/display/short_label.rs | 0 .../src/display/structure.rs | 0 crates/{ra_ide_api => ra_ide}/src/expand.rs | 0 .../src/expand_macro.rs | 0 .../src/extend_selection.rs | 0 .../src/feature_flags.rs | 0 .../src/folding_ranges.rs | 0 .../src/goto_definition.rs | 0 .../src/goto_type_definition.rs | 0 crates/{ra_ide_api => ra_ide}/src/hover.rs | 0 crates/{ra_ide_api => ra_ide}/src/impls.rs | 0 .../{ra_ide_api => ra_ide}/src/inlay_hints.rs | 0 .../{ra_ide_api => ra_ide}/src/join_lines.rs | 0 crates/{ra_ide_api => ra_ide}/src/lib.rs | 2 +- .../{ra_ide_api => ra_ide}/src/line_index.rs | 0 .../src/line_index_utils.rs | 0 crates/{ra_ide_api => ra_ide}/src/marks.rs | 0 .../src/matching_brace.rs | 0 .../src/mock_analysis.rs | 0 .../src/parent_module.rs | 0 .../{ra_ide_api => ra_ide}/src/references.rs | 0 .../src/references/classify.rs | 0 .../src/references/name_definition.rs | 0 .../src/references/rename.rs | 0 .../src/references/search_scope.rs | 0 .../{ra_ide_api => ra_ide}/src/runnables.rs | 0 .../src/snapshots/highlighting.html | 0 .../src/snapshots/rainbow_highlighting.html | 0 .../src/source_change.rs | 0 crates/{ra_ide_api => ra_ide}/src/status.rs | 0 .../src/symbol_index.rs | 0 .../src/syntax_highlighting.rs | 4 ++-- .../{ra_ide_api => ra_ide}/src/syntax_tree.rs | 0 .../{ra_ide_api => ra_ide}/src/test_utils.rs | 0 crates/{ra_ide_api => ra_ide}/src/typing.rs | 0 .../{ra_ide_api => ra_ide}/src/wasm_shims.rs | 0 crates/ra_lsp_server/Cargo.toml | 2 +- crates/ra_lsp_server/src/cargo_target_spec.rs | 2 +- crates/ra_lsp_server/src/conv.rs | 6 ++--- crates/ra_lsp_server/src/lib.rs | 2 +- crates/ra_lsp_server/src/main_loop.rs | 2 +- .../ra_lsp_server/src/main_loop/handlers.rs | 6 ++--- .../src/main_loop/subscriptions.rs | 2 +- crates/ra_lsp_server/src/world.rs | 2 +- docs/dev/README.md | 2 +- docs/dev/architecture.md | 12 +++++----- docs/dev/guide.md | 24 +++++++++---------- editors/code/src/utils/terminateProcess.sh | 0 xtask/tests/tidy-tests/docs.rs | 2 +- 81 files changed, 48 insertions(+), 48 deletions(-) rename crates/{ra_ide_api => ra_ide}/Cargo.toml (91%) rename crates/{ra_ide_api => ra_ide}/src/assists.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/call_info.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/change.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_dot.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_fn_param.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_keyword.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_macro_in_item_position.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_path.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_pattern.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_postfix.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_record_literal.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_record_pattern.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_scope.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/complete_snippet.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/completion_context.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/completion_item.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/completion/presentation.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/db.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/diagnostics.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/display.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/display/function_signature.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/display/navigation_target.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/display/short_label.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/display/structure.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/expand.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/expand_macro.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/extend_selection.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/feature_flags.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/folding_ranges.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/goto_definition.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/goto_type_definition.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/hover.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/impls.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/inlay_hints.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/join_lines.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/lib.rs (99%) rename crates/{ra_ide_api => ra_ide}/src/line_index.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/line_index_utils.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/marks.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/matching_brace.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/mock_analysis.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/parent_module.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/references.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/references/classify.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/references/name_definition.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/references/rename.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/references/search_scope.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/runnables.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/snapshots/highlighting.html (100%) rename crates/{ra_ide_api => ra_ide}/src/snapshots/rainbow_highlighting.html (100%) rename crates/{ra_ide_api => ra_ide}/src/source_change.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/status.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/symbol_index.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/syntax_highlighting.rs (98%) rename crates/{ra_ide_api => ra_ide}/src/syntax_tree.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/test_utils.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/typing.rs (100%) rename crates/{ra_ide_api => ra_ide}/src/wasm_shims.rs (100%) mode change 100755 => 100644 editors/code/src/utils/terminateProcess.sh diff --git a/Cargo.lock b/Cargo.lock index 0f7a45d6cb..b0a0e841c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -906,7 +906,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "ra_db 0.1.0", "ra_hir 0.1.0", - "ra_ide_api 0.1.0", + "ra_ide 0.1.0", "ra_project_model 0.1.0", "ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "ra_vfs_glob 0.1.0", @@ -932,7 +932,7 @@ dependencies = [ "ra_batch 0.1.0", "ra_db 0.1.0", "ra_hir 0.1.0", - "ra_ide_api 0.1.0", + "ra_ide 0.1.0", "ra_prof 0.1.0", "ra_syntax 0.1.0", ] @@ -1027,7 +1027,7 @@ dependencies = [ ] [[package]] -name = "ra_ide_api" +name = "ra_ide" version = "0.1.0" dependencies = [ "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1065,7 +1065,7 @@ dependencies = [ "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ra_ide_api 0.1.0", + "ra_ide 0.1.0", "ra_prof 0.1.0", "ra_project_model 0.1.0", "ra_syntax 0.1.0", diff --git a/README.md b/README.md index ea1c25d7f1..74c971c0d3 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frls-2.2E0 ## Quick Links -* API docs: https://rust-analyzer.github.io/rust-analyzer/ra_ide_api/ +* API docs: https://rust-analyzer.github.io/rust-analyzer/ra_ide/ ## License diff --git a/crates/ra_batch/Cargo.toml b/crates/ra_batch/Cargo.toml index 35626d77d2..3bf351fe37 100644 --- a/crates/ra_batch/Cargo.toml +++ b/crates/ra_batch/Cargo.toml @@ -15,6 +15,6 @@ crossbeam-channel = "0.4.0" ra_vfs = "0.5.0" ra_vfs_glob = { path = "../ra_vfs_glob" } ra_db = { path = "../ra_db" } -ra_ide_api = { path = "../ra_ide_api" } +ra_ide = { path = "../ra_ide" } ra_hir = { path = "../ra_hir" } ra_project_model = { path = "../ra_project_model" } diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index cb389eb261..2c9645c00a 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -6,7 +6,7 @@ use rustc_hash::FxHashMap; use crossbeam_channel::{unbounded, Receiver}; use ra_db::{CrateGraph, FileId, SourceRootId}; -use ra_ide_api::{AnalysisChange, AnalysisHost, FeatureFlags}; +use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags}; use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; use ra_vfs_glob::RustPackageFilterBuilder; diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index 3bb4759979..c7e0d0f0f3 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml @@ -10,7 +10,7 @@ pico-args = "0.3.0" flexi_logger = "0.14.0" ra_syntax = { path = "../ra_syntax" } -ra_ide_api = { path = "../ra_ide_api" } +ra_ide = { path = "../ra_ide" } ra_batch = { path = "../ra_batch" } ra_hir = { path = "../ra_hir" } ra_db = { path = "../ra_db" } diff --git a/crates/ra_cli/src/analysis_bench.rs b/crates/ra_cli/src/analysis_bench.rs index 34105af57f..5485a38ff2 100644 --- a/crates/ra_cli/src/analysis_bench.rs +++ b/crates/ra_cli/src/analysis_bench.rs @@ -10,7 +10,7 @@ use ra_db::{ salsa::{Database, Durability}, FileId, SourceDatabaseExt, }; -use ra_ide_api::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol}; +use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol}; use crate::Result; diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 08f3531477..fe847e6112 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -9,7 +9,7 @@ use std::{error::Error, fmt::Write, io::Read}; use flexi_logger::Logger; use pico_args::Arguments; -use ra_ide_api::{file_structure, Analysis}; +use ra_ide::{file_structure, Analysis}; use ra_prof::profile; use ra_syntax::{AstNode, SourceFile}; diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index e8852531bf..21341b7697 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -1,4 +1,4 @@ -//! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. +//! ra_db defines basic database traits. The concrete DB is defined by ra_ide. mod cancellation; mod input; pub mod fixture; diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide/Cargo.toml similarity index 91% rename from crates/ra_ide_api/Cargo.toml rename to crates/ra_ide/Cargo.toml index 15346f3881..e6383dd352 100644 --- a/crates/ra_ide_api/Cargo.toml +++ b/crates/ra_ide/Cargo.toml @@ -1,6 +1,6 @@ [package] edition = "2018" -name = "ra_ide_api" +name = "ra_ide" version = "0.1.0" authors = ["rust-analyzer developers"] @@ -32,7 +32,7 @@ ra_prof = { path = "../ra_prof" } test_utils = { path = "../test_utils" } ra_assists = { path = "../ra_assists" } -# ra_ide_api should depend only on the top-level `hir` package. if you need +# ra_ide should depend only on the top-level `hir` package. if you need # something from some `hir_xxx` subpackage, reexport the API via `hir`. hir = { path = "../ra_hir", package = "ra_hir" } diff --git a/crates/ra_ide_api/src/assists.rs b/crates/ra_ide/src/assists.rs similarity index 100% rename from crates/ra_ide_api/src/assists.rs rename to crates/ra_ide/src/assists.rs diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide/src/call_info.rs similarity index 100% rename from crates/ra_ide_api/src/call_info.rs rename to crates/ra_ide/src/call_info.rs diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide/src/change.rs similarity index 100% rename from crates/ra_ide_api/src/change.rs rename to crates/ra_ide/src/change.rs diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide/src/completion.rs similarity index 100% rename from crates/ra_ide_api/src/completion.rs rename to crates/ra_ide/src/completion.rs diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_dot.rs rename to crates/ra_ide/src/completion/complete_dot.rs diff --git a/crates/ra_ide_api/src/completion/complete_fn_param.rs b/crates/ra_ide/src/completion/complete_fn_param.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_fn_param.rs rename to crates/ra_ide/src/completion/complete_fn_param.rs diff --git a/crates/ra_ide_api/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_keyword.rs rename to crates/ra_ide/src/completion/complete_keyword.rs diff --git a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs rename to crates/ra_ide/src/completion/complete_macro_in_item_position.rs diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_path.rs rename to crates/ra_ide/src/completion/complete_path.rs diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_pattern.rs rename to crates/ra_ide/src/completion/complete_pattern.rs diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_postfix.rs rename to crates/ra_ide/src/completion/complete_postfix.rs diff --git a/crates/ra_ide_api/src/completion/complete_record_literal.rs b/crates/ra_ide/src/completion/complete_record_literal.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_record_literal.rs rename to crates/ra_ide/src/completion/complete_record_literal.rs diff --git a/crates/ra_ide_api/src/completion/complete_record_pattern.rs b/crates/ra_ide/src/completion/complete_record_pattern.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_record_pattern.rs rename to crates/ra_ide/src/completion/complete_record_pattern.rs diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_scope.rs rename to crates/ra_ide/src/completion/complete_scope.rs diff --git a/crates/ra_ide_api/src/completion/complete_snippet.rs b/crates/ra_ide/src/completion/complete_snippet.rs similarity index 100% rename from crates/ra_ide_api/src/completion/complete_snippet.rs rename to crates/ra_ide/src/completion/complete_snippet.rs diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs similarity index 100% rename from crates/ra_ide_api/src/completion/completion_context.rs rename to crates/ra_ide/src/completion/completion_context.rs diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs similarity index 100% rename from crates/ra_ide_api/src/completion/completion_item.rs rename to crates/ra_ide/src/completion/completion_item.rs diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs similarity index 100% rename from crates/ra_ide_api/src/completion/presentation.rs rename to crates/ra_ide/src/completion/presentation.rs diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide/src/db.rs similarity index 100% rename from crates/ra_ide_api/src/db.rs rename to crates/ra_ide/src/db.rs diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs similarity index 100% rename from crates/ra_ide_api/src/diagnostics.rs rename to crates/ra_ide/src/diagnostics.rs diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide/src/display.rs similarity index 100% rename from crates/ra_ide_api/src/display.rs rename to crates/ra_ide/src/display.rs diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs similarity index 100% rename from crates/ra_ide_api/src/display/function_signature.rs rename to crates/ra_ide/src/display/function_signature.rs diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs similarity index 100% rename from crates/ra_ide_api/src/display/navigation_target.rs rename to crates/ra_ide/src/display/navigation_target.rs diff --git a/crates/ra_ide_api/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs similarity index 100% rename from crates/ra_ide_api/src/display/short_label.rs rename to crates/ra_ide/src/display/short_label.rs diff --git a/crates/ra_ide_api/src/display/structure.rs b/crates/ra_ide/src/display/structure.rs similarity index 100% rename from crates/ra_ide_api/src/display/structure.rs rename to crates/ra_ide/src/display/structure.rs diff --git a/crates/ra_ide_api/src/expand.rs b/crates/ra_ide/src/expand.rs similarity index 100% rename from crates/ra_ide_api/src/expand.rs rename to crates/ra_ide/src/expand.rs diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide/src/expand_macro.rs similarity index 100% rename from crates/ra_ide_api/src/expand_macro.rs rename to crates/ra_ide/src/expand_macro.rs diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs similarity index 100% rename from crates/ra_ide_api/src/extend_selection.rs rename to crates/ra_ide/src/extend_selection.rs diff --git a/crates/ra_ide_api/src/feature_flags.rs b/crates/ra_ide/src/feature_flags.rs similarity index 100% rename from crates/ra_ide_api/src/feature_flags.rs rename to crates/ra_ide/src/feature_flags.rs diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs similarity index 100% rename from crates/ra_ide_api/src/folding_ranges.rs rename to crates/ra_ide/src/folding_ranges.rs diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs similarity index 100% rename from crates/ra_ide_api/src/goto_definition.rs rename to crates/ra_ide/src/goto_definition.rs diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs similarity index 100% rename from crates/ra_ide_api/src/goto_type_definition.rs rename to crates/ra_ide/src/goto_type_definition.rs diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide/src/hover.rs similarity index 100% rename from crates/ra_ide_api/src/hover.rs rename to crates/ra_ide/src/hover.rs diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide/src/impls.rs similarity index 100% rename from crates/ra_ide_api/src/impls.rs rename to crates/ra_ide/src/impls.rs diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs similarity index 100% rename from crates/ra_ide_api/src/inlay_hints.rs rename to crates/ra_ide/src/inlay_hints.rs diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs similarity index 100% rename from crates/ra_ide_api/src/join_lines.rs rename to crates/ra_ide/src/join_lines.rs diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide/src/lib.rs similarity index 99% rename from crates/ra_ide_api/src/lib.rs rename to crates/ra_ide/src/lib.rs index cb6c24eaa5..d1bff4a761 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -1,4 +1,4 @@ -//! ra_ide_api crate provides "ide-centric" APIs for the rust-analyzer. That is, +//! ra_ide crate provides "ide-centric" APIs for the rust-analyzer. That is, //! it generally operates with files and text ranges, and returns results as //! Strings, suitable for displaying to the human. //! diff --git a/crates/ra_ide_api/src/line_index.rs b/crates/ra_ide/src/line_index.rs similarity index 100% rename from crates/ra_ide_api/src/line_index.rs rename to crates/ra_ide/src/line_index.rs diff --git a/crates/ra_ide_api/src/line_index_utils.rs b/crates/ra_ide/src/line_index_utils.rs similarity index 100% rename from crates/ra_ide_api/src/line_index_utils.rs rename to crates/ra_ide/src/line_index_utils.rs diff --git a/crates/ra_ide_api/src/marks.rs b/crates/ra_ide/src/marks.rs similarity index 100% rename from crates/ra_ide_api/src/marks.rs rename to crates/ra_ide/src/marks.rs diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide/src/matching_brace.rs similarity index 100% rename from crates/ra_ide_api/src/matching_brace.rs rename to crates/ra_ide/src/matching_brace.rs diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs similarity index 100% rename from crates/ra_ide_api/src/mock_analysis.rs rename to crates/ra_ide/src/mock_analysis.rs diff --git a/crates/ra_ide_api/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs similarity index 100% rename from crates/ra_ide_api/src/parent_module.rs rename to crates/ra_ide/src/parent_module.rs diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide/src/references.rs similarity index 100% rename from crates/ra_ide_api/src/references.rs rename to crates/ra_ide/src/references.rs diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs similarity index 100% rename from crates/ra_ide_api/src/references/classify.rs rename to crates/ra_ide/src/references/classify.rs diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide/src/references/name_definition.rs similarity index 100% rename from crates/ra_ide_api/src/references/name_definition.rs rename to crates/ra_ide/src/references/name_definition.rs diff --git a/crates/ra_ide_api/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs similarity index 100% rename from crates/ra_ide_api/src/references/rename.rs rename to crates/ra_ide/src/references/rename.rs diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs similarity index 100% rename from crates/ra_ide_api/src/references/search_scope.rs rename to crates/ra_ide/src/references/search_scope.rs diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide/src/runnables.rs similarity index 100% rename from crates/ra_ide_api/src/runnables.rs rename to crates/ra_ide/src/runnables.rs diff --git a/crates/ra_ide_api/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html similarity index 100% rename from crates/ra_ide_api/src/snapshots/highlighting.html rename to crates/ra_ide/src/snapshots/highlighting.html diff --git a/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html similarity index 100% rename from crates/ra_ide_api/src/snapshots/rainbow_highlighting.html rename to crates/ra_ide/src/snapshots/rainbow_highlighting.html diff --git a/crates/ra_ide_api/src/source_change.rs b/crates/ra_ide/src/source_change.rs similarity index 100% rename from crates/ra_ide_api/src/source_change.rs rename to crates/ra_ide/src/source_change.rs diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide/src/status.rs similarity index 100% rename from crates/ra_ide_api/src/status.rs rename to crates/ra_ide/src/status.rs diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide/src/symbol_index.rs similarity index 100% rename from crates/ra_ide_api/src/symbol_index.rs rename to crates/ra_ide/src/symbol_index.rs diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs similarity index 98% rename from crates/ra_ide_api/src/syntax_highlighting.rs rename to crates/ra_ide/src/syntax_highlighting.rs index 10165a9bbc..2c568a747e 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -306,7 +306,7 @@ fn main() { "# .trim(), ); - let dst_file = project_dir().join("crates/ra_ide_api/src/snapshots/highlighting.html"); + let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlighting.html"); let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); let expected_html = &read_text(&dst_file); std::fs::write(dst_file, &actual_html).unwrap(); @@ -333,7 +333,7 @@ fn bar() { .trim(), ); let dst_file = - project_dir().join("crates/ra_ide_api/src/snapshots/rainbow_highlighting.html"); + project_dir().join("crates/ra_ide/src/snapshots/rainbow_highlighting.html"); let actual_html = &analysis.highlight_as_html(file_id, true).unwrap(); let expected_html = &read_text(&dst_file); std::fs::write(dst_file, &actual_html).unwrap(); diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs similarity index 100% rename from crates/ra_ide_api/src/syntax_tree.rs rename to crates/ra_ide/src/syntax_tree.rs diff --git a/crates/ra_ide_api/src/test_utils.rs b/crates/ra_ide/src/test_utils.rs similarity index 100% rename from crates/ra_ide_api/src/test_utils.rs rename to crates/ra_ide/src/test_utils.rs diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide/src/typing.rs similarity index 100% rename from crates/ra_ide_api/src/typing.rs rename to crates/ra_ide/src/typing.rs diff --git a/crates/ra_ide_api/src/wasm_shims.rs b/crates/ra_ide/src/wasm_shims.rs similarity index 100% rename from crates/ra_ide_api/src/wasm_shims.rs rename to crates/ra_ide/src/wasm_shims.rs diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 58b9cfaa00..21aef842ce 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -22,7 +22,7 @@ jod-thread = "0.1.0" ra_vfs = "0.5.0" ra_syntax = { path = "../ra_syntax" } ra_text_edit = { path = "../ra_text_edit" } -ra_ide_api = { path = "../ra_ide_api" } +ra_ide = { path = "../ra_ide" } lsp-server = "0.3.0" ra_project_model = { path = "../ra_project_model" } ra_prof = { path = "../ra_prof" } diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs index d996b53de4..c4a9e71018 100644 --- a/crates/ra_lsp_server/src/cargo_target_spec.rs +++ b/crates/ra_lsp_server/src/cargo_target_spec.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use ra_ide_api::{FileId, RunnableKind}; +use ra_ide::{FileId, RunnableKind}; use ra_project_model::{self, ProjectWorkspace, TargetKind}; use crate::{world::WorldSnapshot, Result}; diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 94ed619fae..b13093cfe6 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -6,7 +6,7 @@ use lsp_types::{ SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit, }; -use ra_ide_api::{ +use ra_ide::{ translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, FileRange, FileSystemEdit, Fold, FoldKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo, Severity, SourceChange, SourceFileEdit, @@ -173,7 +173,7 @@ impl ConvWith<&LineIndex> for Range { } } -impl Conv for ra_ide_api::Documentation { +impl Conv for ra_ide::Documentation { type Output = lsp_types::Documentation; fn conv(self) -> Documentation { Documentation::MarkupContent(MarkupContent { @@ -183,7 +183,7 @@ impl Conv for ra_ide_api::Documentation { } } -impl Conv for ra_ide_api::FunctionSignature { +impl Conv for ra_ide::FunctionSignature { type Output = lsp_types::SignatureInformation; fn conv(self) -> Self::Output { use lsp_types::{ParameterInformation, ParameterLabel, SignatureInformation}; diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 9c36402b0b..2ca149fd56 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs @@ -1,6 +1,6 @@ //! Implementation of the LSP for rust-analyzer. //! -//! This crate takes Rust-specific analysis results from ra_ide_api and +//! This crate takes Rust-specific analysis results from ra_ide and //! translates into LSP types. //! //! It also is the root of all state. `world` module defines the bulk of the diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 0dc0aeee86..83845f1e00 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -9,7 +9,7 @@ use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant}; use crossbeam_channel::{select, unbounded, RecvError, Sender}; use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; use lsp_types::{ClientCapabilities, NumberOrString}; -use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; +use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; use ra_prof::profile; use ra_vfs::{VfsTask, Watch}; use relative_path::RelativePathBuf; diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index e552f2106d..c81fa7f679 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -9,7 +9,7 @@ use lsp_types::{ Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse, Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, }; -use ra_ide_api::{ +use ra_ide::{ AssistId, FileId, FilePosition, FileRange, Query, Runnable, RunnableKind, SearchScope, }; use ra_prof::profile; @@ -162,7 +162,7 @@ pub fn handle_on_type_formatting( let line_index = world.analysis().file_line_index(position.file_id)?; let line_endings = world.file_line_endings(position.file_id); - // in `ra_ide_api`, the `on_type` invariant is that + // in `ra_ide`, the `on_type` invariant is that // `text.char_at(position) == typed_char`. position.offset = position.offset - TextUnit::of_char('.'); let char_typed = params.ch.chars().next().unwrap_or('\0'); @@ -894,7 +894,7 @@ pub fn handle_inlay_hints( label: api_type.label.to_string(), range: api_type.range.conv_with(&line_index), kind: match api_type.kind { - ra_ide_api::InlayKind::TypeHint => InlayKind::TypeHint, + ra_ide::InlayKind::TypeHint => InlayKind::TypeHint, }, }) .collect()) diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs index 3856263b0a..609b2adcc9 100644 --- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs +++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use ra_ide_api::FileId; +use ra_ide::FileId; use rustc_hash::FxHashSet; #[derive(Default, Debug)] diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 9bdea70c74..927449b45d 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -9,7 +9,7 @@ use crossbeam_channel::{unbounded, Receiver}; use lsp_server::ErrorCode; use lsp_types::Url; use parking_lot::RwLock; -use ra_ide_api::{ +use ra_ide::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FeatureFlags, FileId, LibraryData, SourceRootId, }; diff --git a/docs/dev/README.md b/docs/dev/README.md index 0823ca09ab..0f64d7e5f8 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md @@ -14,7 +14,7 @@ To learn more about how rust-analyzer works, see We also publish rustdoc docs to pages: -https://rust-analyzer.github.io/rust-analyzer/ra_ide_api/ +https://rust-analyzer.github.io/rust-analyzer/ra_ide/ Various organizational and process issues are discussed in this document. diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md index 6fd396dee6..629645757a 100644 --- a/docs/dev/architecture.md +++ b/docs/dev/architecture.md @@ -106,7 +106,7 @@ guessing a HIR for a particular source position. Underneath, HIR works on top of salsa, using a `HirDatabase` trait. -### `crates/ra_ide_api` +### `crates/ra_ide` A stateful library for analyzing many Rust files as they change. `AnalysisHost` is a mutable entity (clojure's atom) which holds the current state, incorporates @@ -124,11 +124,11 @@ offsets and strings as output. This works on top of rich code model powered by ### `crates/ra_lsp_server` -An LSP implementation which wraps `ra_ide_api` into a language server protocol. +An LSP implementation which wraps `ra_ide` into a language server protocol. ### `ra_vfs` -Although `hir` and `ra_ide_api` don't do any IO, we need to be able to read +Although `hir` and `ra_ide` don't do any IO, we need to be able to read files from disk at the end of the day. This is what `ra_vfs` does. It also manages overlays: "dirty" files in the editor, whose "true" contents is different from data on disk. This is more or less the single really @@ -162,13 +162,13 @@ disk. For this reason, we try to avoid writing too many tests on this boundary: in a statically typed language, it's hard to make an error in the protocol itself if messages are themselves typed. -The middle, and most important, boundary is `ra_ide_api`. Unlike -`ra_lsp_server`, which exposes API, `ide_api` uses Rust API and is intended to +The middle, and most important, boundary is `ra_ide`. Unlike +`ra_lsp_server`, which exposes API, `ide` uses Rust API and is intended to use by various tools. Typical test creates an `AnalysisHost`, calls some `Analysis` functions and compares the results against expectation. The innermost and most elaborate boundary is `hir`. It has a much richer -vocabulary of types than `ide_api`, but the basic testing setup is the same: we +vocabulary of types than `ide`, but the basic testing setup is the same: we create a database, run some queries, assert result. For comparisons, we use [insta](https://github.com/mitsuhiko/insta/) library for diff --git a/docs/dev/guide.md b/docs/dev/guide.md index abbe4c1542..c163a74b31 100644 --- a/docs/dev/guide.md +++ b/docs/dev/guide.md @@ -40,8 +40,8 @@ terms of files and offsets, and **not** in terms of Rust concepts like structs, traits, etc. The "typed" API with Rust specific types is slightly lower in the stack, we'll talk about it later. -[`AnalysisHost`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L265-L284 -[`Analysis`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L291-L478 +[`AnalysisHost`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L265-L284 +[`Analysis`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L291-L478 The reason for this separation of `Analysis` and `AnalysisHost` is that we want to apply changes "uniquely", but we might also want to fork an `Analysis` and send it to @@ -69,7 +69,7 @@ the `AnalysisHost::apply_change` method, which accepts a single argument, a "transaction", so it suffices to study its methods to understand all of the input data. -[`AnalysisChange`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L119-L167 +[`AnalysisChange`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L119-L167 The `(add|change|remove)_file` methods control the set of the input files, where each file has an integer id (`FileId`, picked by the client), text (`String`) @@ -253,7 +253,7 @@ All analyzer information is stored in a salsa database. `Analysis` and `AnalysisHost` types are newtype wrappers for [`RootDatabase`] -- a salsa database. -[`RootDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/db.rs#L88-L134 +[`RootDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/db.rs#L88-L134 Salsa input queries are defined in [`FilesDatabase`] (which is a part of `RootDatabase`). They closely mirror the familiar `AnalysisChange` structure: @@ -565,11 +565,11 @@ the type to completion. [schedule it on the threadpool]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L428 [catch]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L436-L442 [the handler]: https://salsa.zulipchat.com/#narrow/stream/181542-rfcs.2Fsalsa-query-group/topic/design.20next.20steps -[ask analysis for completion]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L439-L444 -[completion implementation]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L46-L62 -[`CompletionContext`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L14-L37 -["IntelliJ Trick"]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L72-L75 -[find an ancestor `fn` node]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L116-L120 -[semantic model]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L123 -[series of independent completion routines]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L52-L59 -[`complete_dot`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/complete_dot.rs#L6-L22 +[ask analysis for completion]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L439-L444 +[completion implementation]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion.rs#L46-L62 +[`CompletionContext`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L14-L37 +["IntelliJ Trick"]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L72-L75 +[find an ancestor `fn` node]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L116-L120 +[semantic model]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L123 +[series of independent completion routines]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion.rs#L52-L59 +[`complete_dot`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/complete_dot.rs#L6-L22 diff --git a/editors/code/src/utils/terminateProcess.sh b/editors/code/src/utils/terminateProcess.sh old mode 100755 new mode 100644 diff --git a/xtask/tests/tidy-tests/docs.rs b/xtask/tests/tidy-tests/docs.rs index e0653b460f..8a005d6c4d 100644 --- a/xtask/tests/tidy-tests/docs.rs +++ b/xtask/tests/tidy-tests/docs.rs @@ -74,7 +74,7 @@ fn no_docs_comments() { "ra_db", "ra_hir", "ra_hir_expand", - "ra_ide_api", + "ra_ide", "ra_lsp_server", "ra_mbe", "ra_parser", From 27b362b05910c81fd5b28f6cd5d2c075311032f9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 21:44:38 +0300 Subject: [PATCH 61/65] Reformat --- crates/ra_hir/src/from_source.rs | 11 +++++------ crates/ra_hir_def/src/nameres/collector.rs | 3 +-- crates/ra_ide/src/syntax_highlighting.rs | 3 +-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 7756ca80e7..9f7c22b211 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -262,12 +262,11 @@ impl Module { let original_file = src.file_id.original_file(db); - let (krate, local_id) = - db.relevant_crates(original_file).iter().find_map(|&crate_id| { - let crate_def_map = db.crate_def_map(crate_id); - let local_id = crate_def_map.modules_for_file(original_file).next()?; - Some((crate_id, local_id)) - })?; + let (krate, local_id) = db.relevant_crates(original_file).iter().find_map(|&crate_id| { + let crate_def_map = db.crate_def_map(crate_id); + let local_id = crate_def_map.modules_for_file(original_file).next()?; + Some((crate_id, local_id)) + })?; Some(Module { id: ModuleId { krate, local_id } }) } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 6cd14026bc..603b497380 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -682,8 +682,7 @@ where } fn define_def(&mut self, def: &raw::DefData) { - let module = - ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; + let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); let name = def.name.clone(); diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 2c568a747e..9a3e4c82f6 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -332,8 +332,7 @@ fn bar() { "# .trim(), ); - let dst_file = - project_dir().join("crates/ra_ide/src/snapshots/rainbow_highlighting.html"); + let dst_file = project_dir().join("crates/ra_ide/src/snapshots/rainbow_highlighting.html"); let actual_html = &analysis.highlight_as_html(file_id, true).unwrap(); let expected_html = &read_text(&dst_file); std::fs::write(dst_file, &actual_html).unwrap(); From 8d3469682681d5b206d5ae31fc63fb97d9cedb3a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 22:12:09 +0300 Subject: [PATCH 62/65] Memoize impl resolutions --- crates/ra_hir_ty/src/db.rs | 5 +++- crates/ra_hir_ty/src/infer/coerce.rs | 22 ++++---------- crates/ra_hir_ty/src/infer/path.rs | 10 +++---- crates/ra_hir_ty/src/lib.rs | 15 ++++++++++ crates/ra_hir_ty/src/lower.rs | 35 +++++++++++++++-------- crates/ra_hir_ty/src/method_resolution.rs | 30 +++++++------------ crates/ra_hir_ty/src/traits/chalk.rs | 34 +++++++++------------- 7 files changed, 76 insertions(+), 75 deletions(-) diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index aa2659c4bf..9ce1545939 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs @@ -11,7 +11,7 @@ use ra_db::{salsa, CrateId}; use crate::{ method_resolution::CrateImplBlocks, traits::{AssocTyValue, Impl}, - CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, + CallableDef, FnSig, GenericPredicate, ImplTy, InferenceResult, Substs, Ty, TyDefId, TypeCtor, ValueTyDefId, }; @@ -27,6 +27,9 @@ pub trait HirDatabase: DefDatabase { #[salsa::invoke(crate::lower::value_ty_query)] fn value_ty(&self, def: ValueTyDefId) -> Ty; + #[salsa::invoke(crate::lower::impl_ty_query)] + fn impl_ty(&self, def: ImplId) -> ImplTy; + #[salsa::invoke(crate::lower::field_types_query)] fn field_types(&self, var: VariantId) -> Arc>; diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index d66a21932f..719a0f3957 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs @@ -4,16 +4,11 @@ //! //! See: https://doc.rust-lang.org/nomicon/coercions.html -use hir_def::{ - lang_item::LangItemTarget, - resolver::{HasResolver, Resolver}, - type_ref::Mutability, - AdtId, -}; +use hir_def::{lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AdtId}; use rustc_hash::FxHashMap; use test_utils::tested_by; -use crate::{autoderef, db::HirDatabase, Substs, TraitRef, Ty, TypeCtor, TypeWalk}; +use crate::{autoderef, db::HirDatabase, ImplTy, Substs, Ty, TypeCtor, TypeWalk}; use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; @@ -59,17 +54,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { impls .iter() .filter_map(|&impl_id| { - let impl_data = db.impl_data(impl_id); - let resolver = impl_id.resolver(db); - let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); + let trait_ref = match db.impl_ty(impl_id) { + ImplTy::TraitRef(it) => it, + ImplTy::Inherent(_) => return None, + }; // `CoerseUnsized` has one generic parameter for the target type. - let trait_ref = TraitRef::from_hir( - db, - &resolver, - impl_data.target_trait.as_ref()?, - Some(target_ty), - )?; let cur_from_ty = trait_ref.substs.0.get(0)?; let cur_to_ty = trait_ref.substs.0.get(1)?; diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs index e6676e1aa8..14be668365 100644 --- a/crates/ra_hir_ty/src/infer/path.rs +++ b/crates/ra_hir_ty/src/infer/path.rs @@ -2,7 +2,7 @@ use hir_def::{ path::{Path, PathKind, PathSegment}, - resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, + resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, AssocItemId, ContainerId, Lookup, }; use hir_expand::name::Name; @@ -244,17 +244,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ContainerId::ImplId(it) => it, _ => return None, }; - let resolver = impl_id.resolver(self.db); - let impl_data = self.db.impl_data(impl_id); - let impl_block = Ty::from_hir(self.db, &resolver, &impl_data.target_type); - let impl_block_substs = impl_block.substs()?; + let self_ty = self.db.impl_ty(impl_id).self_type().clone(); + let self_ty_substs = self_ty.substs()?; let actual_substs = actual_def_ty.substs()?; let mut new_substs = vec![Ty::Unknown; gen.count_parent_params()]; // The following code *link up* the function actual parma type // and impl_block type param index - impl_block_substs.iter().zip(actual_substs.iter()).for_each(|(param, pty)| { + self_ty_substs.iter().zip(actual_substs.iter()).for_each(|(param, pty)| { if let Ty::Param { idx, .. } = param { if let Some(s) = new_substs.get_mut(*idx as usize) { *s = pty.clone(); diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index f258463268..c9ee34008a 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -486,6 +486,21 @@ impl TypeWalk for TraitRef { } } +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum ImplTy { + Inherent(Ty), + TraitRef(TraitRef), +} + +impl ImplTy { + pub(crate) fn self_type(&self) -> &Ty { + match self { + ImplTy::Inherent(it) => it, + ImplTy::TraitRef(tr) => &tr.substs[0], + } + } +} + /// Like `generics::WherePredicate`, but with resolved types: A condition on the /// parameters of a generic item. #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 53d955a124..f8331d2570 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -14,21 +14,21 @@ use hir_def::{ path::{GenericArg, Path, PathKind, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, + AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, }; use ra_arena::map::ArenaMap; use ra_db::CrateId; -use super::{ - FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, - Ty, TypeCtor, TypeWalk, -}; use crate::{ db::HirDatabase, primitive::{FloatTy, IntTy}, - utils::make_mut_slice, - utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, + utils::{ + all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, + variant_data, + }, + FnSig, GenericPredicate, ImplTy, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, + TraitRef, Ty, TypeCtor, TypeWalk, }; impl Ty { @@ -179,11 +179,7 @@ impl Ty { let name = resolved_segment.name.clone(); Ty::Param { idx, name } } - TypeNs::SelfType(impl_id) => { - let impl_data = db.impl_data(impl_id); - let resolver = impl_id.resolver(db); - Ty::from_hir(db, &resolver, &impl_data.target_type) - } + TypeNs::SelfType(impl_id) => db.impl_ty(impl_id).self_type().clone(), TypeNs::AdtSelfType(adt) => db.ty(adt.into()), TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), @@ -751,3 +747,18 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { ValueTyDefId::StaticId(it) => type_for_static(db, it), } } + +pub(crate) fn impl_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> ImplTy { + let impl_data = db.impl_data(impl_id); + let resolver = impl_id.resolver(db); + let self_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); + match impl_data.target_trait.as_ref() { + Some(trait_ref) => { + match TraitRef::from_hir(db, &resolver, trait_ref, Some(self_ty.clone())) { + Some(it) => ImplTy::TraitRef(it), + None => ImplTy::Inherent(self_ty), + } + } + None => ImplTy::Inherent(self_ty), + } +} diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 53c541eb8e..ee1936b0e5 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -6,8 +6,8 @@ use std::sync::Arc; use arrayvec::ArrayVec; use hir_def::{ - lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability, - AssocItemId, AstItemDef, FunctionId, HasModule, ImplId, TraitId, + lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocItemId, AstItemDef, + FunctionId, HasModule, ImplId, TraitId, }; use hir_expand::name::Name; use ra_db::CrateId; @@ -15,14 +15,13 @@ use ra_prof::profile; use rustc_hash::FxHashMap; use crate::{ + autoderef, db::HirDatabase, primitive::{FloatBitness, Uncertain}, utils::all_super_traits, - Ty, TypeCtor, + Canonical, ImplTy, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, }; -use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; - /// This is used as a key for indexing impls. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum TyFingerprint { @@ -59,22 +58,13 @@ impl CrateImplBlocks { let crate_def_map = db.crate_def_map(krate); for (_module_id, module_data) in crate_def_map.modules.iter() { for &impl_id in module_data.impls.iter() { - let impl_data = db.impl_data(impl_id); - let resolver = impl_id.resolver(db); - - let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); - - match &impl_data.target_trait { - Some(trait_ref) => { - if let Some(tr) = - TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) - { - res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); - } + match db.impl_ty(impl_id) { + ImplTy::TraitRef(tr) => { + res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); } - None => { - if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { - res.impls.entry(target_ty_fp).or_default().push(impl_id); + ImplTy::Inherent(self_ty) => { + if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) { + res.impls.entry(self_ty_fp).or_default().push(impl_id); } } } diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 810e8c21a6..35de37e6b6 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -11,8 +11,8 @@ use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum use ra_db::CrateId; use hir_def::{ - expr::Expr, lang_item::LangItemTarget, resolver::HasResolver, AssocItemId, AstItemDef, - ContainerId, GenericDefId, ImplId, Lookup, TraitId, TypeAliasId, + expr::Expr, lang_item::LangItemTarget, AssocItemId, AstItemDef, ContainerId, GenericDefId, + ImplId, Lookup, TraitId, TypeAliasId, }; use hir_expand::name; @@ -20,9 +20,8 @@ use ra_db::salsa::{InternId, InternKey}; use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; use crate::{ - db::HirDatabase, - display::HirDisplay, - {ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, + db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ImplTy, ProjectionTy, + Substs, TraitRef, Ty, TypeCtor, TypeWalk, }; /// This represents a trait whose name we could not resolve. @@ -631,13 +630,11 @@ fn impl_block_datum( chalk_id: chalk_ir::ImplId, impl_id: ImplId, ) -> Option>> { + let trait_ref = match db.impl_ty(impl_id) { + ImplTy::TraitRef(it) => it, + ImplTy::Inherent(_) => return None, + }; let impl_data = db.impl_data(impl_id); - let resolver = impl_id.resolver(db); - let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); - - // `CoerseUnsized` has one generic parameter for the target type. - let trait_ref = - TraitRef::from_hir(db, &resolver, impl_data.target_trait.as_ref()?, Some(target_ty))?; let generic_params = db.generic_params(impl_id.into()); let bound_vars = Substs::bound_vars(&generic_params); @@ -790,17 +787,14 @@ fn type_alias_associated_ty_value( _ => panic!("assoc ty value should be in impl"), }; - let impl_data = db.impl_data(impl_id); - let resolver = impl_id.resolver(db); - let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); - let target_trait = impl_data - .target_trait - .as_ref() - .and_then(|trait_ref| TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))) - .expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved + let trait_ref = match db.impl_ty(impl_id) { + ImplTy::TraitRef(it) => it, + // we don't return any assoc ty values if the impl'd trait can't be resolved + ImplTy::Inherent(_) => panic!("assoc ty value should not exist"), + }; let assoc_ty = db - .trait_data(target_trait.trait_) + .trait_data(trait_ref.trait_) .associated_type_by_name(&type_alias_data.name) .expect("assoc ty value should not exist"); // validated when building the impl data as well let generic_params = db.generic_params(impl_id.into()); From 04735abfaec30461252aecde10bb1d0d344728f1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 22:21:01 +0300 Subject: [PATCH 63/65] Minimize API --- crates/ra_hir/src/code_model.rs | 9 +-------- crates/ra_hir_ty/src/lower.rs | 11 +++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 5a3e24e9e4..9488521a94 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -29,10 +29,7 @@ use ra_syntax::{ast, AstNode, SyntaxNode}; use crate::{ db::{DefDatabase, HirDatabase}, ty::display::HirFormatter, - ty::{ - self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TyDefId, TypeCtor, - TypeWalk, - }, + ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk}, CallableDef, Either, HirDisplay, Name, Source, }; @@ -731,10 +728,6 @@ impl Trait { db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() } - pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { - TraitRef::for_trait(db, self.id) - } - pub fn is_auto(self, db: &impl DefDatabase) -> bool { db.trait_data(self.id).auto } diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index f8331d2570..091c60f4fe 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -363,7 +363,7 @@ pub(super) fn substs_from_path_segment( } impl TraitRef { - pub(crate) fn from_path( + fn from_path( db: &impl HirDatabase, resolver: &Resolver, path: &Path, @@ -377,7 +377,7 @@ impl TraitRef { Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) } - pub(super) fn from_resolved_path( + pub(crate) fn from_resolved_path( db: &impl HirDatabase, resolver: &Resolver, resolved: TraitId, @@ -391,7 +391,7 @@ impl TraitRef { TraitRef { trait_: resolved, substs } } - pub(crate) fn from_hir( + fn from_hir( db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef, @@ -415,11 +415,6 @@ impl TraitRef { substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) } - pub fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef { - let substs = Substs::identity(&db.generic_params(trait_.into())); - TraitRef { trait_, substs } - } - pub(crate) fn from_type_bound( db: &impl HirDatabase, resolver: &Resolver, From 1d14fd17372b42c3343daf6adc9a520fdf5e9810 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 23:22:20 +0300 Subject: [PATCH 64/65] Use Name::missing consistently --- crates/ra_hir/src/code_model.rs | 17 ++++++------- crates/ra_hir_def/src/adt.rs | 18 ++++++------- crates/ra_hir_def/src/data.rs | 11 ++++---- crates/ra_hir_def/src/nameres/collector.rs | 2 +- crates/ra_hir_ty/src/lib.rs | 25 ++++++------------- crates/ra_ide/src/completion/presentation.rs | 5 +--- .../ra_ide/src/display/function_signature.rs | 7 ++---- 7 files changed, 33 insertions(+), 52 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9488521a94..38d66c2a7c 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -330,7 +330,7 @@ impl Struct { Some(self.module(db).krate()) } - pub fn name(self, db: &impl DefDatabase) -> Option { + pub fn name(self, db: &impl DefDatabase) -> Name { db.struct_data(self.id.into()).name.clone() } @@ -371,7 +371,7 @@ pub struct Union { } impl Union { - pub fn name(self, db: &impl DefDatabase) -> Option { + pub fn name(self, db: &impl DefDatabase) -> Name { db.union_data(self.id).name.clone() } @@ -420,7 +420,7 @@ impl Enum { Some(self.module(db).krate()) } - pub fn name(self, db: &impl DefDatabase) -> Option { + pub fn name(self, db: &impl DefDatabase) -> Name { db.enum_data(self.id).name.clone() } @@ -433,11 +433,8 @@ impl Enum { } pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option { - db.enum_data(self.id) - .variants - .iter() - .find(|(_id, data)| data.name.as_ref() == Some(name)) - .map(|(id, _)| EnumVariant { parent: self, id }) + let id = db.enum_data(self.id).variant(name)?; + Some(EnumVariant { parent: self, id }) } pub fn ty(self, db: &impl HirDatabase) -> Type { @@ -459,7 +456,7 @@ impl EnumVariant { self.parent } - pub fn name(self, db: &impl DefDatabase) -> Option { + pub fn name(self, db: &impl DefDatabase) -> Name { db.enum_data(self.parent.id).variants[self.id].name.clone() } @@ -720,7 +717,7 @@ impl Trait { Module { id: self.id.module(db) } } - pub fn name(self, db: &impl DefDatabase) -> Option { + pub fn name(self, db: &impl DefDatabase) -> Name { db.trait_data(self.id).name.clone() } diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 0cf418d301..3666529b0c 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -18,19 +18,19 @@ use crate::{ /// Note that we use `StructData` for unions as well! #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructData { - pub name: Option, + pub name: Name, pub variant_data: Arc, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumData { - pub name: Option, + pub name: Name, pub variants: Arena, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumVariantData { - pub name: Option, + pub name: Name, pub variant_data: Arc, } @@ -51,14 +51,14 @@ pub struct StructFieldData { impl StructData { pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc { let src = id.source(db); - let name = src.value.name().map(|n| n.as_name()); + let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let variant_data = VariantData::new(src.value.kind()); let variant_data = Arc::new(variant_data); Arc::new(StructData { name, variant_data }) } pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc { let src = id.source(db); - let name = src.value.name().map(|n| n.as_name()); + let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let variant_data = VariantData::new( src.value .record_field_def_list() @@ -73,14 +73,14 @@ impl StructData { impl EnumData { pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc { let src = e.source(db); - let name = src.value.name().map(|n| n.as_name()); + let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let mut trace = Trace::new_for_arena(); lower_enum(&mut trace, &src.value); Arc::new(EnumData { name, variants: trace.into_arena() }) } - pub(crate) fn variant(&self, name: &Name) -> Option { - let (id, _) = self.variants.iter().find(|(_id, data)| data.name.as_ref() == Some(name))?; + pub fn variant(&self, name: &Name) -> Option { + let (id, _) = self.variants.iter().find(|(_id, data)| &data.name == name)?; Some(id) } } @@ -104,7 +104,7 @@ fn lower_enum( trace.alloc( || var.clone(), || EnumVariantData { - name: var.name().map(|it| it.as_name()), + name: var.name().map_or_else(Name::missing, |it| it.as_name()), variant_data: Arc::new(VariantData::new(var.kind())), }, ); diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 813099a058..fee10b2375 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -86,7 +86,7 @@ impl TypeAliasData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraitData { - pub name: Option, + pub name: Name, pub items: Vec<(Name, AssocItemId)>, pub auto: bool, } @@ -94,7 +94,7 @@ pub struct TraitData { impl TraitData { pub(crate) fn trait_data_query(db: &impl DefDatabase, tr: TraitId) -> Arc { let src = tr.source(db); - let name = src.value.name().map(|n| n.as_name()); + let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let auto = src.value.is_auto(); let ast_id_map = db.ast_id_map(src.file_id); @@ -104,7 +104,7 @@ impl TraitData { .impl_items() .map(|item_node| match item_node { ast::ImplItem::FnDef(it) => { - let name = it.name().map(|it| it.as_name()).unwrap_or_else(Name::missing); + let name = it.name().map_or_else(Name::missing, |it| it.as_name()); let def = FunctionLoc { container, ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), @@ -114,7 +114,7 @@ impl TraitData { (name, def) } ast::ImplItem::ConstDef(it) => { - let name = it.name().map(|it| it.as_name()).unwrap_or_else(Name::missing); + let name = it.name().map_or_else(Name::missing, |it| it.as_name()); let def = ConstLoc { container, ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), @@ -124,7 +124,7 @@ impl TraitData { (name, def) } ast::ImplItem::TypeAliasDef(it) => { - let name = it.name().map(|it| it.as_name()).unwrap_or_else(Name::missing); + let name = it.name().map_or_else(Name::missing, |it| it.as_name()); let def = TypeAliasLoc { container, ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), @@ -214,6 +214,7 @@ impl ImplData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstData { + /// const _: () = (); pub name: Option, pub type_ref: TypeRef, } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 603b497380..fd82451131 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -362,7 +362,7 @@ where .variants .iter() .filter_map(|(local_id, variant_data)| { - let name = variant_data.name.clone()?; + let name = variant_data.name.clone(); let variant = EnumVariantId { parent: e, local_id }; let res = Resolution { def: PerNs::both(variant.into(), variant.into()), diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index c9ee34008a..b45c8f82f4 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -901,12 +901,10 @@ impl HirDisplay for ApplicationTy { let sig = f.db.callable_item_signature(def); let name = match def { CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), - CallableDef::StructId(s) => { - f.db.struct_data(s).name.clone().unwrap_or_else(Name::missing) - } + CallableDef::StructId(s) => f.db.struct_data(s).name.clone(), CallableDef::EnumVariantId(e) => { let enum_data = f.db.enum_data(e.parent); - enum_data.variants[e.local_id].name.clone().unwrap_or_else(Name::missing) + enum_data.variants[e.local_id].name.clone() } }; match def { @@ -929,8 +927,7 @@ impl HirDisplay for ApplicationTy { AdtId::StructId(it) => f.db.struct_data(it).name.clone(), AdtId::UnionId(it) => f.db.union_data(it).name.clone(), AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), - } - .unwrap_or_else(Name::missing); + }; write!(f, "{}", name)?; if self.parameters.len() > 0 { write!(f, "<")?; @@ -943,7 +940,7 @@ impl HirDisplay for ApplicationTy { ContainerId::TraitId(it) => it, _ => panic!("not an associated type"), }; - let trait_name = f.db.trait_data(trait_).name.clone().unwrap_or_else(Name::missing); + let trait_name = f.db.trait_data(trait_).name.clone(); let name = f.db.type_alias_data(type_alias).name.clone(); write!(f, "{}::{}", trait_name, name)?; if self.parameters.len() > 0 { @@ -971,8 +968,7 @@ impl HirDisplay for ProjectionTy { return write!(f, "…"); } - let trait_name = - f.db.trait_data(self.trait_(f.db)).name.clone().unwrap_or_else(Name::missing); + let trait_name = f.db.trait_data(self.trait_(f.db)).name.clone(); write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; if self.parameters.len() > 1 { write!(f, "<")?; @@ -1021,14 +1017,7 @@ impl HirDisplay for Ty { // We assume that the self type is $0 (i.e. the // existential) here, which is the only thing that's // possible in actual Rust, and hence don't print it - write!( - f, - "{}", - f.db.trait_data(trait_ref.trait_) - .name - .clone() - .unwrap_or_else(Name::missing) - )?; + write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?; if trait_ref.substs.len() > 1 { write!(f, "<")?; f.write_joined(&trait_ref.substs[1..], ", ")?; @@ -1088,7 +1077,7 @@ impl TraitRef { } else { write!(f, ": ")?; } - write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?; + write!(f, "{}", f.db.trait_data(self.trait_).name.clone())?; if self.substs.len() > 1 { write!(f, "<")?; f.write_joined(&self.substs[1..], ", ")?; diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 5f056730ac..97475fc0bb 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -267,10 +267,7 @@ impl Completions { pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { let is_deprecated = is_deprecated(variant, ctx.db); - let name = match variant.name(ctx.db) { - Some(it) => it, - None => return, - }; + let name = variant.name(ctx.db); let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db)); let detail = join(detail_types.map(|t| t.display(ctx.db).to_string())) .separator(", ") diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs index d96de4e4ce..324ad95526 100644 --- a/crates/ra_ide/src/display/function_signature.rs +++ b/crates/ra_ide/src/display/function_signature.rs @@ -93,12 +93,9 @@ impl FunctionSignature { _ => (), }; - let parent_name = match variant.parent_enum(db).name(db) { - Some(name) => name.to_string(), - None => "missing".into(), - }; + let parent_name = variant.parent_enum(db).name(db).to_string(); - let name = format!("{}::{}", parent_name, variant.name(db).unwrap()); + let name = format!("{}::{}", parent_name, variant.name(db)); let params = variant .fields(db) From cf1d7bf5c9b36c13937ed033f693b6302fa7372c Mon Sep 17 00:00:00 2001 From: kjeremy Date: Wed, 27 Nov 2019 18:05:49 -0500 Subject: [PATCH 65/65] Update mio and anyhow --- Cargo.lock | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0a0e841c8..2557b5e59d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -656,9 +656,10 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.19" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -678,7 +679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -715,7 +716,7 @@ dependencies = [ "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1780,7 +1781,7 @@ dependencies = [ name = "xtask" version = "0.1.0" dependencies = [ - "anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1804,7 +1805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" -"checksum anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1072d8f55592084072d2d3cb23a4b680a8543c00f10d446118e85ad3718142" +"checksum anyhow 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b412394828b7ca486b362f300b762d8e43dafd6f0d727b63f1cd2ade207c6cef" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" @@ -1885,7 +1886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" -"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" +"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"