diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index 9371fc14dd..e6986dd1fc 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -93,6 +93,8 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast Option>; diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs index 28ae4c349f..68375f9e1e 100644 --- a/crates/hir-ty/src/chalk_db.rs +++ b/crates/hir-ty/src/chalk_db.rs @@ -1,8 +1,7 @@ //! The implementation of `RustIrDatabase` for Chalk, which provides information //! about the code that Chalk needs. -use std::sync::Arc; +use std::{iter, sync::Arc}; -use cov_mark::hit; use tracing::debug; use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds}; @@ -12,17 +11,16 @@ use base_db::CrateId; use hir_def::{ expr::Movability, lang_item::{lang_attr, LangItem, LangItemTarget}, - AssocItemId, GenericDefId, HasModule, ItemContainerId, Lookup, ModuleId, TypeAliasId, + AssocItemId, BlockId, GenericDefId, HasModule, ItemContainerId, Lookup, TypeAliasId, }; use hir_expand::name::name; use crate::{ db::HirDatabase, display::HirDisplay, - from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, make_binders, - make_single_type_binders, + from_assoc_type_id, from_chalk_trait_id, make_binders, make_single_type_binders, mapping::{from_chalk, ToChalk, TypeAliasAsValue}, - method_resolution::{TraitImpls, TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, + method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, to_assoc_type_id, to_chalk_trait_id, traits::ChalkContext, utils::generics, @@ -108,53 +106,41 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), }; - fn local_impls(db: &dyn HirDatabase, module: ModuleId) -> Option> { - let block = module.containing_block()?; - hit!(block_local_impls); - db.trait_impls_in_block(block) - } - // Note: Since we're using impls_for_trait, only impls where the trait // can be resolved should ever reach Chalk. impl_datum relies on that // and will panic if the trait can't be resolved. let in_deps = self.db.trait_impls_in_deps(self.krate); let in_self = self.db.trait_impls_in_crate(self.krate); - let trait_module = trait_.module(self.db.upcast()); - let type_module = match self_ty_fp { - Some(TyFingerprint::Adt(adt_id)) => Some(adt_id.module(self.db.upcast())), - Some(TyFingerprint::ForeignType(type_id)) => { - Some(from_foreign_def_id(type_id).module(self.db.upcast())) - } - Some(TyFingerprint::Dyn(trait_id)) => Some(trait_id.module(self.db.upcast())), - _ => None, - }; - let impl_maps = [ - Some(in_deps), - Some(in_self), - local_impls(self.db, trait_module), - type_module.and_then(|m| local_impls(self.db, m)), - ]; + + let impl_maps = [in_deps, in_self]; + let block_impls = iter::successors(self.block, |&block_id| { + cov_mark::hit!(block_local_impls); + self.db + .block_def_map(block_id) + .and_then(|map| map.parent()) + .and_then(|module| module.containing_block()) + }) + .filter_map(|block_id| self.db.trait_impls_in_block(block_id)); let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db); - - let result: Vec<_> = if fps.is_empty() { - debug!("Unrestricted search for {:?} impls...", trait_); - impl_maps - .iter() - .filter_map(|o| o.as_ref()) - .flat_map(|impls| impls.for_trait(trait_).map(id_to_chalk)) - .collect() - } else { - impl_maps - .iter() - .filter_map(|o| o.as_ref()) - .flat_map(|impls| { - fps.iter().flat_map(move |fp| { - impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) - }) - }) - .collect() - }; + let mut result = vec![]; + match fps { + [] => { + debug!("Unrestricted search for {:?} impls...", trait_); + impl_maps.into_iter().chain(block_impls).for_each(|impls| { + result.extend(impls.for_trait(trait_).map(id_to_chalk)); + }); + } + fps => { + impl_maps.into_iter().chain(block_impls).for_each(|impls| { + result.extend( + fps.iter().flat_map(|fp| { + impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) + }), + ); + }); + } + } debug!("impls_for_trait returned {} impls", result.len()); result @@ -193,7 +179,7 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { &self, environment: &chalk_ir::Environment, ) -> chalk_ir::ProgramClauses { - self.db.program_clauses_for_chalk_env(self.krate, environment.clone()) + self.db.program_clauses_for_chalk_env(self.krate, self.block, environment.clone()) } fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId) -> Arc { @@ -451,9 +437,10 @@ impl<'a> chalk_ir::UnificationDatabase for &'a dyn HirDatabase { pub(crate) fn program_clauses_for_chalk_env_query( db: &dyn HirDatabase, krate: CrateId, + block: Option, environment: chalk_ir::Environment, ) -> chalk_ir::ProgramClauses { - chalk_solve::program_clauses_for_env(&ChalkContext { db, krate }, &environment) + chalk_solve::program_clauses_for_env(&ChalkContext { db, krate, block }, &environment) } pub(crate) fn associated_ty_data_query( diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 000944e0b5..56f5d90bb3 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -129,7 +129,7 @@ pub trait HirDatabase: DefDatabase + Upcast { fn trait_impls_in_crate(&self, krate: CrateId) -> Arc; #[salsa::invoke(TraitImpls::trait_impls_in_block_query)] - fn trait_impls_in_block(&self, krate: BlockId) -> Option>; + fn trait_impls_in_block(&self, block: BlockId) -> Option>; #[salsa::invoke(TraitImpls::trait_impls_in_deps_query)] fn trait_impls_in_deps(&self, krate: CrateId) -> Arc; @@ -197,6 +197,7 @@ pub trait HirDatabase: DefDatabase + Upcast { fn trait_solve( &self, krate: CrateId, + block: Option, goal: crate::Canonical>, ) -> Option; @@ -204,6 +205,7 @@ pub trait HirDatabase: DefDatabase + Upcast { fn trait_solve_query( &self, krate: CrateId, + block: Option, goal: crate::Canonical>, ) -> Option; @@ -211,6 +213,7 @@ pub trait HirDatabase: DefDatabase + Upcast { fn program_clauses_for_chalk_env( &self, krate: CrateId, + block: Option, env: chalk_ir::Environment, ) -> chalk_ir::ProgramClauses; } @@ -232,10 +235,11 @@ fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc fn trait_solve_wait( db: &dyn HirDatabase, krate: CrateId, + block: Option, goal: crate::Canonical>, ) -> Option { let _p = profile::span("trait_solve::wait"); - db.trait_solve_query(krate, goal) + db.trait_solve_query(krate, block, goal) } #[test] diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 38b7dee75f..493f45d40c 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -40,7 +40,7 @@ use crate::{ db::HirDatabase, fold_tys, fold_tys_and_consts, infer::coerce::CoerceMany, lower::ImplTraitLoweringMode, static_lifetime, to_assoc_type_id, AliasEq, AliasTy, Const, DomainGoal, GenericArg, Goal, ImplTraitId, InEnvironment, Interner, ProjectionTy, RpitId, - Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, + Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, }; // This lint has a false positive here. See the link below for details. @@ -442,7 +442,6 @@ pub(crate) struct InferenceContext<'a> { pub(crate) body: &'a Body, pub(crate) resolver: Resolver, table: unify::InferenceTable<'a>, - trait_env: Arc, /// The traits in scope, disregarding block modules. This is used for caching purposes. traits_in_scope: FxHashSet, pub(crate) result: InferenceResult, @@ -516,8 +515,7 @@ impl<'a> InferenceContext<'a> { let trait_env = db.trait_environment_for_body(owner); InferenceContext { result: InferenceResult::default(), - table: unify::InferenceTable::new(db, trait_env.clone()), - trait_env, + table: unify::InferenceTable::new(db, trait_env), return_ty: TyKind::Error.intern(Interner), // set in collect_* calls resume_yield_tys: None, return_coercion: None, diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs index 6e899249b6..6bf9f421fc 100644 --- a/crates/hir-ty/src/infer/coerce.rs +++ b/crates/hir-ty/src/infer/coerce.rs @@ -636,7 +636,7 @@ impl<'a> InferenceTable<'a> { // Need to find out in what cases this is necessary let solution = self .db - .trait_solve(krate, canonicalized.value.clone().cast(Interner)) + .trait_solve(krate, self.trait_env.block, canonicalized.value.clone().cast(Interner)) .ok_or(TypeError)?; match solution { diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index d52188bb28..ea44fa1857 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -3,6 +3,7 @@ use std::{ iter::{repeat, repeat_with}, mem, + sync::Arc, }; use chalk_ir::{ @@ -15,7 +16,7 @@ use hir_def::{ generics::TypeOrConstParamData, lang_item::LangItem, path::{GenericArg, GenericArgs}, - ConstParamId, FieldId, ItemContainerId, Lookup, + BlockId, ConstParamId, FieldId, ItemContainerId, Lookup, }; use hir_expand::name::{name, Name}; use stdx::always; @@ -147,19 +148,19 @@ impl<'a> InferenceContext<'a> { self.infer_top_pat(pat, &input_ty); self.result.standard_types.bool_.clone() } - Expr::Block { statements, tail, label, id: _ } => { - self.infer_block(tgt_expr, statements, *tail, *label, expected) + Expr::Block { statements, tail, label, id } => { + self.infer_block(tgt_expr, *id, statements, *tail, *label, expected) } - Expr::Unsafe { id: _, statements, tail } => { - self.infer_block(tgt_expr, statements, *tail, None, expected) + Expr::Unsafe { id, statements, tail } => { + self.infer_block(tgt_expr, *id, statements, *tail, None, expected) } - Expr::Const { id: _, statements, tail } => { + Expr::Const { id, statements, tail } => { self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { - this.infer_block(tgt_expr, statements, *tail, None, expected) + this.infer_block(tgt_expr, *id, statements, *tail, None, expected) }) .1 } - Expr::Async { id: _, statements, tail } => { + Expr::Async { id, statements, tail } => { let ret_ty = self.table.new_type_var(); let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone()); @@ -170,6 +171,7 @@ impl<'a> InferenceContext<'a> { self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { this.infer_block( tgt_expr, + *id, statements, *tail, None, @@ -394,7 +396,7 @@ impl<'a> InferenceContext<'a> { } } let trait_ = fn_x - .get_id(self.db, self.trait_env.krate) + .get_id(self.db, self.table.trait_env.krate) .expect("We just used it"); let trait_data = self.db.trait_data(trait_); if let Some(func) = trait_data.method_by_name(&fn_x.method_name()) { @@ -787,7 +789,7 @@ impl<'a> InferenceContext<'a> { let canonicalized = self.canonicalize(base_ty.clone()); let receiver_adjustments = method_resolution::resolve_indexing_op( self.db, - self.trait_env.clone(), + self.table.trait_env.clone(), canonicalized.value, index_trait, ); @@ -1205,6 +1207,7 @@ impl<'a> InferenceContext<'a> { fn infer_block( &mut self, expr: ExprId, + block_id: Option, statements: &[Statement], tail: Option, label: Option, @@ -1212,6 +1215,11 @@ impl<'a> InferenceContext<'a> { ) -> Ty { let coerce_ty = expected.coercion_target_type(&mut self.table); let g = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr); + let prev_env = block_id.map(|block_id| { + let prev_env = self.table.trait_env.clone(); + Arc::make_mut(&mut self.table.trait_env).block = Some(block_id); + prev_env + }); let (break_ty, ty) = self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty.clone()), label, |this| { @@ -1300,6 +1308,9 @@ impl<'a> InferenceContext<'a> { } }); self.resolver.reset_to_guard(g); + if let Some(prev_env) = prev_env { + self.table.trait_env = prev_env; + } break_ty.unwrap_or(ty) } @@ -1398,7 +1409,7 @@ impl<'a> InferenceContext<'a> { method_resolution::lookup_method( self.db, &canonicalized_receiver.value, - self.trait_env.clone(), + self.table.trait_env.clone(), self.get_traits_in_scope().as_ref().left_or_else(|&it| it), VisibleFromModule::Filter(self.resolver.module()), name, @@ -1431,7 +1442,7 @@ impl<'a> InferenceContext<'a> { let resolved = method_resolution::lookup_method( self.db, &canonicalized_receiver.value, - self.trait_env.clone(), + self.table.trait_env.clone(), self.get_traits_in_scope().as_ref().left_or_else(|&it| it), VisibleFromModule::Filter(self.resolver.module()), method_name, diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index 0e516b9399..f0e0714e1d 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -462,7 +462,8 @@ impl<'a> InferenceTable<'a> { pub(crate) fn try_obligation(&mut self, goal: Goal) -> Option { let in_env = InEnvironment::new(&self.trait_env.env, goal); let canonicalized = self.canonicalize(in_env); - let solution = self.db.trait_solve(self.trait_env.krate, canonicalized.value); + let solution = + self.db.trait_solve(self.trait_env.krate, self.trait_env.block, canonicalized.value); solution } @@ -597,7 +598,11 @@ impl<'a> InferenceTable<'a> { &mut self, canonicalized: &Canonicalized>, ) -> bool { - let solution = self.db.trait_solve(self.trait_env.krate, canonicalized.value.clone()); + let solution = self.db.trait_solve( + self.trait_env.krate, + self.trait_env.block, + canonicalized.value.clone(), + ); match solution { Some(Solution::Unique(canonical_subst)) => { @@ -684,7 +689,11 @@ impl<'a> InferenceTable<'a> { environment: trait_env.clone(), }; let canonical = self.canonicalize(obligation.clone()); - if self.db.trait_solve(krate, canonical.value.cast(Interner)).is_some() { + if self + .db + .trait_solve(krate, self.trait_env.block, canonical.value.cast(Interner)) + .is_some() + { self.register_obligation(obligation.goal); let return_ty = self.normalize_projection_ty(projection); for fn_x in [FnTrait::Fn, FnTrait::FnMut, FnTrait::FnOnce] { @@ -695,7 +704,11 @@ impl<'a> InferenceTable<'a> { environment: trait_env.clone(), }; let canonical = self.canonicalize(obligation.clone()); - if self.db.trait_solve(krate, canonical.value.cast(Interner)).is_some() { + if self + .db + .trait_solve(krate, self.trait_env.block, canonical.value.cast(Interner)) + .is_some() + { return Some((fn_x, arg_tys, return_ty)); } } diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index 782a8ab4aa..54bbda2ba0 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -1,6 +1,5 @@ //! The type system. We currently use this to infer types for completion, hover //! information and various assists. - #![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)] #[allow(unused)] diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index e7490087e7..797e9ad0e9 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -1507,7 +1507,7 @@ pub(crate) fn trait_environment_query( let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses); - Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env }) + Arc::new(TraitEnvironment { krate, block: None, traits_from_clauses: traits_in_scope, env }) } /// Resolve the where clause(s) of an item with generics. diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 2003d24038..94c0d3c0c1 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -271,6 +271,7 @@ pub struct InherentImpls { impl InherentImpls { pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc { + let _p = profile::span("inherent_impls_in_crate_query").detail(|| format!("{krate:?}")); let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() }; let crate_def_map = db.crate_def_map(krate); @@ -284,13 +285,14 @@ impl InherentImpls { db: &dyn HirDatabase, block: BlockId, ) -> Option> { + let _p = profile::span("inherent_impls_in_block_query"); let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() }; - if let Some(block_def_map) = db.block_def_map(block) { - impls.collect_def_map(db, &block_def_map); - impls.shrink_to_fit(); - return Some(Arc::new(impls)); - } - None + + let block_def_map = db.block_def_map(block)?; + impls.collect_def_map(db, &block_def_map); + impls.shrink_to_fit(); + + Some(Arc::new(impls)) } fn shrink_to_fit(&mut self) { @@ -1140,7 +1142,7 @@ fn iterate_trait_method_candidates( }; if !known_implemented { let goal = generic_implements_goal(db, env.clone(), t, &canonical_self_ty); - if db.trait_solve(env.krate, goal.cast(Interner)).is_none() { + if db.trait_solve(env.krate, env.block, goal.cast(Interner)).is_none() { continue 'traits; } } @@ -1317,7 +1319,7 @@ pub fn resolve_indexing_op( let deref_chain = autoderef_method_receiver(&mut table, ty); for (ty, adj) in deref_chain { let goal = generic_implements_goal(db, env.clone(), index_trait, &ty); - if db.trait_solve(env.krate, goal.cast(Interner)).is_some() { + if db.trait_solve(env.krate, env.block, goal.cast(Interner)).is_some() { return Some(adj); } } @@ -1342,14 +1344,12 @@ fn is_valid_candidate( ) -> IsValidCandidate { let db = table.db; match item { - AssocItemId::FunctionId(m) => { - is_valid_fn_candidate(table, m, name, receiver_ty, self_ty, visible_from_module) + AssocItemId::FunctionId(f) => { + is_valid_fn_candidate(table, f, name, receiver_ty, self_ty, visible_from_module) } AssocItemId::ConstId(c) => { - let data = db.const_data(c); check_that!(receiver_ty.is_none()); - - check_that!(name.map_or(true, |n| data.name.as_ref() == Some(n))); + check_that!(name.map_or(true, |n| db.const_data(c).name.as_ref() == Some(n))); if let Some(from_module) = visible_from_module { if !db.const_visibility(c).is_visible_from(db.upcast(), from_module) { @@ -1473,7 +1473,7 @@ pub fn implements_trait( trait_: TraitId, ) -> bool { let goal = generic_implements_goal(db, env.clone(), trait_, ty); - let solution = db.trait_solve(env.krate, goal.cast(Interner)); + let solution = db.trait_solve(env.krate, env.block, goal.cast(Interner)); solution.is_some() } @@ -1485,7 +1485,7 @@ pub fn implements_trait_unique( trait_: TraitId, ) -> bool { let goal = generic_implements_goal(db, env.clone(), trait_, ty); - let solution = db.trait_solve(env.krate, goal.cast(Interner)); + let solution = db.trait_solve(env.krate, env.block, goal.cast(Interner)); matches!(solution, Some(crate::Solution::Unique(_))) } diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index 97ec1bb871..e9c26bf473 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -3717,7 +3717,6 @@ async fn get_accounts() -> Result { #[test] fn local_impl_1() { - check!(block_local_impls); check_types( r#" trait Trait { @@ -3739,7 +3738,6 @@ fn test() { #[test] fn local_impl_2() { - check!(block_local_impls); check_types( r#" struct S; @@ -3761,7 +3759,6 @@ fn test() { #[test] fn local_impl_3() { - check!(block_local_impls); check_types( r#" trait Trait { @@ -3785,6 +3782,33 @@ fn test() { ); } +#[test] +fn foreign_trait_with_local_trait_impl() { + check!(block_local_impls); + check( + r#" +mod module { + pub trait T { + const C: usize; + fn f(&self); + } +} + +fn f() { + use module::T; + impl T for usize { + const C: usize = 0; + fn f(&self) {} + } + 0usize.f(); + //^^^^^^^^^^ type: () + usize::C; + //^^^^^^^^type: usize +} +"#, + ); +} + #[test] fn associated_type_sized_bounds() { check_infer( diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs index e7fffc4cc7..deb6ce5677 100644 --- a/crates/hir-ty/src/traits.rs +++ b/crates/hir-ty/src/traits.rs @@ -9,7 +9,7 @@ use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; use base_db::CrateId; use hir_def::{ lang_item::{LangItem, LangItemTarget}, - TraitId, + BlockId, TraitId, }; use hir_expand::name::{name, Name}; use stdx::panic_context; @@ -27,6 +27,7 @@ const CHALK_SOLVER_FUEL: i32 = 1000; pub(crate) struct ChalkContext<'a> { pub(crate) db: &'a dyn HirDatabase, pub(crate) krate: CrateId, + pub(crate) block: Option, } fn create_chalk_solver() -> chalk_recursive::RecursiveSolver { @@ -44,6 +45,7 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TraitEnvironment { pub krate: CrateId, + pub block: Option, // FIXME make this a BTreeMap pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, pub env: chalk_ir::Environment, @@ -53,6 +55,7 @@ impl TraitEnvironment { pub fn empty(krate: CrateId) -> Self { TraitEnvironment { krate, + block: None, traits_from_clauses: Vec::new(), env: chalk_ir::Environment::new(Interner), } @@ -79,6 +82,7 @@ pub(crate) fn normalize_projection_query( pub(crate) fn trait_solve_query( db: &dyn HirDatabase, krate: CrateId, + block: Option, goal: Canonical>, ) -> Option { let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal.data(Interner) { @@ -104,15 +108,16 @@ pub(crate) fn trait_solve_query( // We currently don't deal with universes (I think / hope they're not yet // relevant for our use cases?) let u_canonical = chalk_ir::UCanonical { canonical: goal, universes: 1 }; - solve(db, krate, &u_canonical) + solve(db, krate, block, &u_canonical) } fn solve( db: &dyn HirDatabase, krate: CrateId, + block: Option, goal: &chalk_ir::UCanonical>>, ) -> Option> { - let context = ChalkContext { db, krate }; + let context = ChalkContext { db, krate, block }; tracing::debug!("solve goal: {:?}", goal); let mut solver = create_chalk_solver(); diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index dbf618afa6..ea851a11a8 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -3331,7 +3331,7 @@ impl Type { binders: CanonicalVarKinds::empty(Interner), }; - db.trait_solve(self.env.krate, goal).is_some() + db.trait_solve(self.env.krate, self.env.block, goal).is_some() } pub fn normalize_trait_assoc_type(