Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/autoderef.rs')
| -rw-r--r-- | crates/hir-ty/src/autoderef.rs | 63 |
1 files changed, 27 insertions, 36 deletions
diff --git a/crates/hir-ty/src/autoderef.rs b/crates/hir-ty/src/autoderef.rs index d21108fb5a..abab3bfb25 100644 --- a/crates/hir-ty/src/autoderef.rs +++ b/crates/hir-ty/src/autoderef.rs @@ -5,13 +5,12 @@ use std::fmt; -use hir_def::{TraitId, TypeAliasId, lang_item::LangItem}; +use hir_def::{TraitId, TypeAliasId}; use rustc_type_ir::inherent::{IntoKind, Ty as _}; use tracing::debug; -use triomphe::Arc; use crate::{ - TraitEnvironment, + ParamEnvAndCrate, db::HirDatabase, infer::InferenceContext, next_solver::{ @@ -35,13 +34,13 @@ const AUTODEREF_RECURSION_LIMIT: usize = 20; /// detects a cycle in the deref chain. pub fn autoderef<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, ty: Canonical<'db, Ty<'db>>, ) -> impl Iterator<Item = Ty<'db>> + use<'db> { - let interner = DbInterner::new_with(db, Some(env.krate), env.block); + let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let (ty, _) = infcx.instantiate_canonical(&ty); - let autoderef = Autoderef::new(&infcx, &env, ty); + let autoderef = Autoderef::new(&infcx, env.param_env, ty); let mut v = Vec::new(); for (ty, _steps) in autoderef { // `ty` may contain unresolved inference variables. Since there's no chance they would be @@ -111,12 +110,12 @@ struct AutoderefTraits { // borrows it. pub(crate) trait AutoderefCtx<'db> { fn infcx(&self) -> &InferCtxt<'db>; - fn env(&self) -> &TraitEnvironment<'db>; + fn param_env(&self) -> ParamEnv<'db>; } pub(crate) struct DefaultAutoderefCtx<'a, 'db> { infcx: &'a InferCtxt<'db>, - env: &'a TraitEnvironment<'db>, + param_env: ParamEnv<'db>, } impl<'db> AutoderefCtx<'db> for DefaultAutoderefCtx<'_, 'db> { #[inline] @@ -124,8 +123,8 @@ impl<'db> AutoderefCtx<'db> for DefaultAutoderefCtx<'_, 'db> { self.infcx } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - self.env + fn param_env(&self) -> ParamEnv<'db> { + self.param_env } } @@ -136,8 +135,8 @@ impl<'db> AutoderefCtx<'db> for InferenceContextAutoderefCtx<'_, '_, 'db> { &self.0.table.infer_ctxt } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - &self.0.table.trait_env + fn param_env(&self) -> ParamEnv<'db> { + self.0.table.param_env } } @@ -201,7 +200,7 @@ where // autoderef expect this type to have been structurally normalized. if let TyKind::Alias(..) = ty.kind() { let (normalized_ty, obligations) = - structurally_normalize_ty(self.infcx(), self.env().env, ty)?; + structurally_normalize_ty(self.infcx(), self.param_env(), ty)?; self.state.obligations.extend(obligations); (AutoderefKind::Builtin, normalized_ty) } else { @@ -231,10 +230,10 @@ impl<'a, 'db> Autoderef<'a, 'db> { #[inline] pub(crate) fn new_with_tracking( infcx: &'a InferCtxt<'db>, - env: &'a TraitEnvironment<'db>, + param_env: ParamEnv<'db>, base_ty: Ty<'db>, ) -> Self { - Self::new_impl(DefaultAutoderefCtx { infcx, env }, base_ty) + Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty) } } @@ -257,10 +256,10 @@ impl<'a, 'db> Autoderef<'a, 'db, usize> { #[inline] pub(crate) fn new( infcx: &'a InferCtxt<'db>, - env: &'a TraitEnvironment<'db>, + param_env: ParamEnv<'db>, base_ty: Ty<'db>, ) -> Self { - Self::new_impl(DefaultAutoderefCtx { infcx, env }, base_ty) + Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty) } } @@ -292,8 +291,8 @@ where } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - self.ctx.env() + fn param_env(&self) -> ParamEnv<'db> { + self.ctx.param_env() } #[inline] @@ -301,36 +300,28 @@ where self.infcx().interner } - #[inline] - fn db(&self) -> &'db dyn HirDatabase { - self.interner().db - } - fn autoderef_traits(&mut self) -> Option<AutoderefTraits> { + let lang_items = self.interner().lang_items(); match &mut self.traits { Some(it) => Some(*it), None => { let traits = if self.use_receiver_trait { (|| { Some(AutoderefTraits { - trait_: LangItem::Receiver - .resolve_trait(self.db(), self.env().krate)?, - trait_target: LangItem::ReceiverTarget - .resolve_type_alias(self.db(), self.env().krate)?, + trait_: lang_items.Receiver?, + trait_target: lang_items.ReceiverTarget?, }) })() .or_else(|| { Some(AutoderefTraits { - trait_: LangItem::Deref.resolve_trait(self.db(), self.env().krate)?, - trait_target: LangItem::DerefTarget - .resolve_type_alias(self.db(), self.env().krate)?, + trait_: lang_items.Deref?, + trait_target: lang_items.DerefTarget?, }) })? } else { AutoderefTraits { - trait_: LangItem::Deref.resolve_trait(self.db(), self.env().krate)?, - trait_target: LangItem::DerefTarget - .resolve_type_alias(self.db(), self.env().krate)?, + trait_: lang_items.Deref?, + trait_target: lang_items.DerefTarget?, } }; Some(*self.traits.insert(traits)) @@ -347,7 +338,7 @@ where let trait_ref = TraitRef::new(interner, trait_.into(), [ty]); let obligation = - Obligation::new(interner, ObligationCause::new(), self.env().env, trait_ref); + Obligation::new(interner, ObligationCause::new(), self.param_env(), trait_ref); // We detect whether the self type implements `Deref` before trying to // structurally normalize. We use `predicate_may_hold_opaque_types_jank` // to support not-yet-defined opaque types. It will succeed for `impl Deref` @@ -359,7 +350,7 @@ where let (normalized_ty, obligations) = structurally_normalize_ty( self.infcx(), - self.env().env, + self.param_env(), Ty::new_projection(interner, trait_target.into(), [ty]), )?; debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); |