From 0a20770f46138909d91a1db371ed7371caf704e1 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 9 Jul 2019 21:34:23 +0200 Subject: Some renamings for clarity --- crates/ra_hir/src/ty/autoderef.rs | 2 +- crates/ra_hir/src/ty/infer.rs | 8 ++++---- crates/ra_hir/src/ty/lower.rs | 7 +++++-- crates/ra_hir/src/ty/method_resolution.rs | 6 +++--- crates/ra_hir/src/ty/traits.rs | 14 +++++++------- crates/ra_hir/src/ty/traits/chalk.rs | 4 ++-- 6 files changed, 22 insertions(+), 19 deletions(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index c26513871..2535d4ae7 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -68,7 +68,7 @@ fn deref_by_trait( let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; - let solution = db.solve(krate, canonical)?; + let solution = db.trait_solve(krate, canonical)?; match &solution { Solution::Unique(vars) => { diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 5ad4f73ec..36189e20d 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -29,8 +29,8 @@ use test_utils::tested_by; use super::{ autoderef, lower, method_resolution, op, primitive, traits::{Guidance, Obligation, ProjectionPredicate, Solution}, - ApplicationTy, CallableDef, Environment, InEnvironment, ProjectionTy, Substs, TraitRef, Ty, - TypableDef, TypeCtor, + ApplicationTy, CallableDef, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, + Ty, TypableDef, TypeCtor, }; use crate::{ adt::VariantDef, @@ -170,7 +170,7 @@ struct InferenceContext<'a, D: HirDatabase> { body: Arc, resolver: Resolver, var_unification_table: InPlaceUnificationTable, - trait_env: Arc, + trait_env: Arc, obligations: Vec, method_resolutions: FxHashMap, field_resolutions: FxHashMap, @@ -345,7 +345,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); let solution = - self.db.solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); + self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); match solution { Some(Solution::Unique(substs)) => { diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index ca47d6e96..894ba0695 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -317,7 +317,10 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { Ty::from_hir(db, &resolver, type_ref) } -pub(crate) fn trait_env(db: &impl HirDatabase, resolver: &Resolver) -> Arc { +pub(crate) fn trait_env( + db: &impl HirDatabase, + resolver: &Resolver, +) -> Arc { let predicates = resolver .where_predicates_in_scope() .map(|pred| { @@ -326,7 +329,7 @@ pub(crate) fn trait_env(db: &impl HirDatabase, resolver: &Resolver) -> Arc>(); - Arc::new(super::Environment { predicates }) + Arc::new(super::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 353820436..d421bf9ef 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 rustc_hash::FxHashMap; -use super::{autoderef, lower, Canonical, Environment, InEnvironment, TraitRef}; +use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; use crate::{ generics::HasGenericParams, impl_block::{ImplBlock, ImplId, ImplItem}, @@ -214,7 +214,7 @@ fn iterate_trait_method_candidates( if name.map_or(true, |name| data.name() == name) && data.has_self_param() { if !known_implemented { let goal = generic_implements_goal(db, env.clone(), t, ty.clone()); - if db.solve(krate, goal).is_none() { + if db.trait_solve(krate, goal).is_none() { continue 'traits; } } @@ -283,7 +283,7 @@ impl Ty { /// for all other parameters, to query Chalk with it. fn generic_implements_goal( db: &impl HirDatabase, - env: Arc, + env: Arc, trait_: Trait, self_ty: Canonical, ) -> Canonical> { diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 2817c9e71..7dccd93be 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -27,7 +27,7 @@ struct ChalkContext<'a, DB> { krate: Crate, } -pub(crate) fn solver_query(_db: &impl HirDatabase, _krate: Crate) -> Arc> { +pub(crate) fn trait_solver_query(_db: &impl HirDatabase, _krate: Crate) -> Arc> { // krate parameter is just so we cache a unique solver per crate let solver_choice = chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE }; debug!("Creating new solver for crate {:?}", _krate); @@ -60,7 +60,7 @@ fn solve( goal: &chalk_ir::UCanonical>, ) -> Option { let context = ChalkContext { db, krate }; - let solver = db.solver(krate); + let solver = db.trait_solver(krate); debug!("solve goal: {:?}", goal); let solution = solver.lock().solve_with_fuel(&context, goal, Some(1000)); debug!("solve({:?}) => {:?}", goal, solution); @@ -73,19 +73,19 @@ fn solve( /// ``` /// we assume that `T: Default`. #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Environment { +pub struct TraitEnvironment { pub predicates: Vec, } /// Something (usually a goal), along with an environment. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct InEnvironment { - pub environment: Arc, + pub environment: Arc, pub value: T, } impl InEnvironment { - pub fn new(environment: Arc, value: T) -> InEnvironment { + pub fn new(environment: Arc, value: T) -> InEnvironment { InEnvironment { environment, value } } } @@ -117,12 +117,12 @@ pub struct ProjectionPredicate { } /// Solve a trait goal using Chalk. -pub(crate) fn solve_query( +pub(crate) fn trait_solve_query( db: &impl HirDatabase, krate: Crate, trait_ref: Canonical>, ) -> Option { - let _p = profile("solve_query"); + let _p = profile("trait_solve_query"); let canonical = trait_ref.to_chalk(db).cast(); // We currently don't deal with universes (I think / hope they're not yet // relevant for our use cases?) diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 2df4dd13f..1b9ae8dc1 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -266,7 +266,7 @@ where } } -impl ToChalk for Arc { +impl ToChalk for Arc { type Chalk = Arc; fn to_chalk(self, db: &impl HirDatabase) -> Arc { @@ -289,7 +289,7 @@ impl ToChalk for Arc { fn from_chalk( _db: &impl HirDatabase, _env: Arc, - ) -> Arc { + ) -> Arc { unimplemented!() } } -- cgit v1.2.3 From 1e60ba892793932dff57fd3357616f56e664bdcc Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 14 Jul 2019 14:23:44 +0200 Subject: Have InferenceContext contain an InferenceResult instead of duplicating all fields --- crates/ra_hir/src/ty/infer.rs | 55 +++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 36189e20d..0e030576d 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -107,7 +107,7 @@ impl Default for BindingMode { } /// The result of type inference: A mapping from expressions and patterns to types. -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Default)] pub struct InferenceResult { /// For each method call expr, records the function it resolves to. method_resolutions: FxHashMap, @@ -172,13 +172,7 @@ struct InferenceContext<'a, D: HirDatabase> { var_unification_table: InPlaceUnificationTable, trait_env: Arc, obligations: Vec, - method_resolutions: FxHashMap, - field_resolutions: FxHashMap, - variant_resolutions: FxHashMap, - assoc_resolutions: FxHashMap, - type_of_expr: ArenaMap, - type_of_pat: ArenaMap, - diagnostics: Vec, + result: InferenceResult, /// The return type of the function being inferred. return_ty: Ty, } @@ -186,13 +180,7 @@ struct InferenceContext<'a, D: HirDatabase> { impl<'a, D: HirDatabase> InferenceContext<'a, D> { fn new(db: &'a D, body: Arc, resolver: Resolver) -> Self { InferenceContext { - method_resolutions: FxHashMap::default(), - field_resolutions: FxHashMap::default(), - variant_resolutions: FxHashMap::default(), - assoc_resolutions: FxHashMap::default(), - type_of_expr: ArenaMap::default(), - type_of_pat: ArenaMap::default(), - diagnostics: Vec::default(), + result: InferenceResult::default(), var_unification_table: InPlaceUnificationTable::new(), obligations: Vec::default(), return_ty: Ty::Unknown, // set in collect_fn_signature @@ -205,50 +193,45 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { fn resolve_all(mut self) -> InferenceResult { // FIXME resolve obligations as well (use Guidance if necessary) + let mut result = mem::replace(&mut self.result, InferenceResult::default()); let mut tv_stack = Vec::new(); - let mut expr_types = mem::replace(&mut self.type_of_expr, ArenaMap::default()); - for ty in expr_types.values_mut() { + for ty in result.type_of_expr.values_mut() { let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); *ty = resolved; } - let mut pat_types = mem::replace(&mut self.type_of_pat, ArenaMap::default()); - for ty in pat_types.values_mut() { + for ty in result.type_of_pat.values_mut() { let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); *ty = resolved; } - InferenceResult { - method_resolutions: self.method_resolutions, - field_resolutions: self.field_resolutions, - variant_resolutions: self.variant_resolutions, - assoc_resolutions: self.assoc_resolutions, - type_of_expr: expr_types, - type_of_pat: pat_types, - diagnostics: self.diagnostics, - } + result } fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) { - self.type_of_expr.insert(expr, ty); + self.result.type_of_expr.insert(expr, ty); } fn write_method_resolution(&mut self, expr: ExprId, func: Function) { - self.method_resolutions.insert(expr, func); + self.result.method_resolutions.insert(expr, func); } fn write_field_resolution(&mut self, expr: ExprId, field: StructField) { - self.field_resolutions.insert(expr, field); + self.result.field_resolutions.insert(expr, field); } fn write_variant_resolution(&mut self, expr: ExprId, variant: VariantDef) { - self.variant_resolutions.insert(expr, variant); + self.result.variant_resolutions.insert(expr, variant); } fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) { - self.assoc_resolutions.insert(id, item); + self.result.assoc_resolutions.insert(id, item); } fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { - self.type_of_pat.insert(pat, ty); + self.result.type_of_pat.insert(pat, ty); + } + + fn push_diagnostic(&mut self, diagnostic: InferenceDiagnostic) { + self.result.diagnostics.push(diagnostic); } fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { @@ -565,7 +548,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Some(ty) } Resolution::LocalBinding(pat) => { - let ty = self.type_of_pat.get(pat)?.clone(); + let ty = self.result.type_of_pat.get(pat)?.clone(); let ty = self.resolve_ty_as_possible(&mut vec![], ty); Some(ty) } @@ -1090,7 +1073,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { .and_then(|it| match it.field(self.db, &field.name) { Some(field) => Some(field), None => { - self.diagnostics.push(InferenceDiagnostic::NoSuchField { + self.push_diagnostic(InferenceDiagnostic::NoSuchField { expr: tgt_expr, field: field_idx, }); -- cgit v1.2.3 From e2bce9e7ebd1879825f74aa34329911a6d3efa79 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 14 Jul 2019 18:21:50 +0200 Subject: Cargo update, including updating Chalk --- crates/ra_hir/src/ty/traits/chalk.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 1b9ae8dc1..203ec3b1b 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -460,6 +460,7 @@ pub(crate) fn trait_datum_query( associated_ty_ids: Vec::new(), where_clauses: Vec::new(), flags: chalk_rust_ir::TraitFlags { + non_enumerable: false, auto: false, marker: false, upstream: true, @@ -477,6 +478,7 @@ pub(crate) fn trait_datum_query( auto: trait_.is_auto(db), upstream: trait_.module(db).krate(db) != Some(krate), // FIXME set these flags correctly + non_enumerable: false, marker: false, fundamental: false, }; -- cgit v1.2.3 From dcb0c02e3afa8e163379b56a943f04e6e4879dd6 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 14 Jul 2019 19:40:19 +0200 Subject: Remove blacklist, instead mark `Sized` as non-enumerable This seems to be enough to prevent hanging in rust-analyzer, Chalk and the rustc repo. --- crates/ra_hir/src/ty/traits/chalk.rs | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 203ec3b1b..9e7ae0724 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -276,11 +276,6 @@ impl ToChalk for Arc { // for env, we just ignore errors continue; } - if let GenericPredicate::Implemented(trait_ref) = pred { - if blacklisted_trait(db, trait_ref.trait_) { - continue; - } - } clauses.push(pred.clone().to_chalk(db).cast()); } chalk_ir::Environment::new().add_clauses(clauses) @@ -322,10 +317,10 @@ fn make_binders(value: T, num_vars: usize) -> chalk_ir::Binders { } } -fn blacklisted_trait(db: &impl HirDatabase, trait_: Trait) -> bool { +fn is_non_enumerable_trait(db: &impl HirDatabase, trait_: Trait) -> bool { let name = trait_.name(db).unwrap_or_else(crate::Name::missing).to_string(); match &*name { - "Send" | "Sync" | "Sized" | "Fn" | "FnMut" | "FnOnce" => true, + "Sized" => true, _ => false, } } @@ -343,11 +338,6 @@ fn convert_where_clauses( // anyway), otherwise Chalk can easily get into slow situations return vec![pred.clone().subst(substs).to_chalk(db)]; } - if let GenericPredicate::Implemented(trait_ref) = pred { - if blacklisted_trait(db, trait_ref.trait_) { - continue; - } - } result.push(pred.clone().subst(substs).to_chalk(db)); } result @@ -375,10 +365,6 @@ where return Vec::new(); } let trait_: Trait = from_chalk(self.db, trait_id); - let blacklisted = blacklisted_trait(self.db, trait_); - if blacklisted { - return Vec::new(); - } let result: Vec<_> = self .db .impls_for_trait(self.krate, trait_) @@ -477,8 +463,8 @@ pub(crate) fn trait_datum_query( let flags = chalk_rust_ir::TraitFlags { auto: trait_.is_auto(db), upstream: trait_.module(db).krate(db) != Some(krate), + non_enumerable: is_non_enumerable_trait(db, trait_), // FIXME set these flags correctly - non_enumerable: false, marker: false, fundamental: false, }; -- cgit v1.2.3 From c8284d8424691dc348af8708abfc2172b7dd5dc5 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 14 Jul 2019 22:11:04 +0200 Subject: Switch to Chalk master, without fuel --- crates/ra_hir/src/ty/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 7dccd93be..0769e6e17 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -62,7 +62,7 @@ fn solve( let context = ChalkContext { db, krate }; let solver = db.trait_solver(krate); debug!("solve goal: {:?}", goal); - let solution = solver.lock().solve_with_fuel(&context, goal, Some(1000)); + let solution = solver.lock().solve(&context, goal); debug!("solve({:?}) => {:?}", goal, solution); solution } -- cgit v1.2.3