From c4fd3f47f5b4f34476f8f085f2412a46aa0fd24f Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 21 Mar 2021 20:19:07 +0100 Subject: Align InEnvironment with Chalk This in particular means storing a chalk_ir::Environment, not our TraitEnvironment. This makes InEnvironment not usable for Type, where we need to keep the full TraitEnvironment. --- crates/hir_ty/src/autoderef.rs | 24 ++++++++++++------------ crates/hir_ty/src/infer.rs | 2 +- crates/hir_ty/src/infer/coerce.rs | 6 +++--- crates/hir_ty/src/infer/expr.rs | 16 ++++++++-------- crates/hir_ty/src/infer/unify.rs | 7 ++----- crates/hir_ty/src/method_resolution.rs | 6 +++--- crates/hir_ty/src/traits.rs | 17 ++++++++--------- crates/hir_ty/src/traits/chalk/mapping.rs | 5 +---- 8 files changed, 38 insertions(+), 45 deletions(-) (limited to 'crates/hir_ty/src') diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index d6f0553b1..dc5fc759a 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs @@ -27,9 +27,9 @@ pub fn autoderef<'a>( krate: Option, ty: InEnvironment>, ) -> impl Iterator> + 'a { - let InEnvironment { value: ty, environment } = ty; + let InEnvironment { goal: ty, environment } = ty; successors(Some(ty), move |ty| { - deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) + deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() }) }) .take(AUTODEREF_RECURSION_LIMIT) } @@ -39,8 +39,8 @@ pub(crate) fn deref( krate: CrateId, ty: InEnvironment<&Canonical>, ) -> Option> { - if let Some(derefed) = ty.value.value.builtin_deref() { - Some(Canonical { value: derefed, binders: ty.value.binders.clone() }) + if let Some(derefed) = ty.goal.value.builtin_deref() { + Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }) } else { deref_by_trait(db, krate, ty) } @@ -67,15 +67,15 @@ fn deref_by_trait( // FIXME make the Canonical / bound var handling nicer let parameters = - Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); + Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build(); // Check that the type implements Deref at all let trait_ref = TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() }; let implements_goal = Canonical { - binders: ty.value.binders.clone(), + binders: ty.goal.binders.clone(), value: InEnvironment { - value: trait_ref.cast(&Interner), + goal: trait_ref.cast(&Interner), environment: ty.environment.clone(), }, }; @@ -91,20 +91,20 @@ fn deref_by_trait( }), ty: TyKind::BoundVar(BoundVar::new( DebruijnIndex::INNERMOST, - ty.value.binders.len(&Interner), + ty.goal.binders.len(&Interner), )) .intern(&Interner), }; let obligation = projection.cast(&Interner); - let in_env = InEnvironment { value: obligation, environment: ty.environment }; + let in_env = InEnvironment { goal: obligation, environment: ty.environment }; let canonical = Canonical { value: in_env, binders: CanonicalVarKinds::from_iter( &Interner, - ty.value.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new( + ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new( chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), chalk_ir::UniverseIndex::ROOT, ))), @@ -134,7 +134,7 @@ fn deref_by_trait( if vars.0.value[i - 1].interned(&Interner) != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) { - warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); + warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); return None; } } @@ -144,7 +144,7 @@ fn deref_by_trait( }) } Solution::Ambig(_) => { - info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); + info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution); None } } diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index b9e434c78..8f9cf7480 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -331,7 +331,7 @@ impl<'a> InferenceContext<'a> { fn resolve_obligations_as_possible(&mut self) { let obligations = mem::replace(&mut self.obligations, Vec::new()); for obligation in obligations { - let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); + let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone()); let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); let solution = self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 07eb96573..9c62932b1 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs @@ -142,7 +142,7 @@ impl<'a> InferenceContext<'a> { .build(); let trait_ref = TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs }; - let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner)); + let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); let canonicalizer = self.canonicalizer(); let canonicalized = canonicalizer.canonicalize_obligation(goal); @@ -170,8 +170,8 @@ impl<'a> InferenceContext<'a> { self.db, self.resolver.krate(), InEnvironment { - value: canonicalized.value.clone(), - environment: self.trait_env.clone(), + goal: canonicalized.value.clone(), + environment: self.trait_env.env.clone(), }, ) { let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 17849d552..4e2a432ed 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -90,12 +90,12 @@ impl<'a> InferenceContext<'a> { let substs = Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); - let trait_env = Arc::clone(&self.trait_env); + let trait_env = self.trait_env.env.clone(); let implements_fn_trait: DomainGoal = TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } .cast(&Interner); let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { - value: implements_fn_trait.clone(), + goal: implements_fn_trait.clone(), environment: trait_env, }); if self.db.trait_solve(krate, goal.value).is_some() { @@ -299,8 +299,8 @@ impl<'a> InferenceContext<'a> { self.db, self.resolver.krate(), InEnvironment { - value: canonicalized.value.clone(), - environment: self.trait_env.clone(), + goal: canonicalized.value.clone(), + environment: self.trait_env.env.clone(), }, ); let (param_tys, ret_ty): (Vec, Ty) = derefs @@ -438,8 +438,8 @@ impl<'a> InferenceContext<'a> { self.db, self.resolver.krate(), InEnvironment { - value: canonicalized.value.clone(), - environment: self.trait_env.clone(), + goal: canonicalized.value.clone(), + environment: self.trait_env.env.clone(), }, ) .find_map(|derefed_ty| { @@ -538,8 +538,8 @@ impl<'a> InferenceContext<'a> { self.db, krate, InEnvironment { - value: &canonicalized.value, - environment: self.trait_env.clone(), + goal: &canonicalized.value, + environment: self.trait_env.env.clone(), }, ) { Some(derefed_ty) => { diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 7595b46cf..75250a369 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -98,15 +98,12 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { mut self, obligation: InEnvironment, ) -> Canonicalized> { - let result = match obligation.value { + let result = match obligation.goal { DomainGoal::Holds(wc) => { DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) } }; - self.into_canonicalized(InEnvironment { - value: result, - environment: obligation.environment, - }) + self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment }) } } diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 0abe8f0a3..8e986ddde 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -376,7 +376,7 @@ fn iterate_method_candidates_impl( // 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). - let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; + let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() }; // We have to be careful about the order we're looking at candidates // in here. Consider the case where we're resolving `x.clone()` @@ -622,7 +622,7 @@ pub fn resolve_indexing_op( krate: CrateId, index_trait: TraitId, ) -> Option> { - let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; + let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() }; let deref_chain = autoderef_method_receiver(db, krate, ty); for ty in deref_chain { let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone()); @@ -794,7 +794,7 @@ fn generic_implements_goal( let obligation = trait_ref.cast(&Interner); Canonical { binders: CanonicalVarKinds::from_iter(&Interner, kinds), - value: InEnvironment::new(env, obligation), + value: InEnvironment::new(env.env.clone(), obligation), } } diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index 7dadd1ffb..ccee0e5ad 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs @@ -1,6 +1,5 @@ //! Trait solving using Chalk. use std::env::var; -use std::sync::Arc; use base_db::CrateId; use chalk_ir::cast::Cast; @@ -44,7 +43,7 @@ pub struct TraitEnvironment { // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord, // but for now it's too annoying... pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, - pub(crate) env: chalk_ir::Environment, + pub env: chalk_ir::Environment, } impl TraitEnvironment { @@ -74,13 +73,13 @@ impl Default for TraitEnvironment { /// Something (usually a goal), along with an environment. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct InEnvironment { - pub environment: Arc, - pub value: T, + pub environment: chalk_ir::Environment, + pub goal: T, } impl InEnvironment { - pub fn new(environment: Arc, value: T) -> InEnvironment { - InEnvironment { environment, value } + pub fn new(environment: chalk_ir::Environment, value: T) -> InEnvironment { + InEnvironment { environment, goal: value } } } @@ -126,18 +125,18 @@ pub(crate) fn trait_solve_query( krate: CrateId, goal: Canonical>, ) -> Option { - let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { + let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal { DomainGoal::Holds(WhereClause::Implemented(it)) => { db.trait_data(it.hir_trait_id()).name.to_string() } DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), }); - log::info!("trait_solve_query({})", goal.value.value.display(db)); + log::info!("trait_solve_query({})", goal.value.goal.display(db)); if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. - })) = &goal.value.value + })) = &goal.value.goal { if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 58d8f2894..aef6b8a15 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -455,10 +455,7 @@ where type Chalk = chalk_ir::InEnvironment; fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment { - chalk_ir::InEnvironment { - environment: self.environment.env.clone(), - goal: self.value.to_chalk(db), - } + chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) } } fn from_chalk( -- cgit v1.2.3