about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-15 20:23:15 +0000
committerbors <bors@rust-lang.org>2022-04-15 20:23:15 +0000
commit1c22537b3b7012f76952546ef90b18509a056690 (patch)
tree9139f19803494054c5c216e72055bc2e3c7ec394
parente10284a10c07065d72bdaac1ed3059ad80df8318 (diff)
parente5bf60fee2de60a85076aaffd71df249a8ac41cb (diff)
downloadrust-1c22537b3b7012f76952546ef90b18509a056690.tar.gz
rust-1c22537b3b7012f76952546ef90b18509a056690.zip
Auto merge of #12005 - Veykril:hir-ty-simplify, r=Veykril
internal: Remove frequent `Arc<Body>` clones in type checking

bors r+
-rw-r--r--crates/hir_ty/src/infer.rs130
-rw-r--r--crates/hir_ty/src/infer/expr.rs28
-rw-r--r--crates/hir_ty/src/infer/pat.rs9
3 files changed, 86 insertions, 81 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index eca6b3a0762..1892e30a425 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -59,7 +59,8 @@ mod closure;
 pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
     let _p = profile::span("infer_query");
     let resolver = def.resolver(db.upcast());
-    let mut ctx = InferenceContext::new(db, def, resolver);
+    let body = db.body(def);
+    let mut ctx = InferenceContext::new(db, def, &body, resolver);
 
     match def {
         DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
@@ -360,7 +361,7 @@ impl Index<PatId> for InferenceResult {
 pub(crate) struct InferenceContext<'a> {
     pub(crate) db: &'a dyn HirDatabase,
     pub(crate) owner: DefWithBodyId,
-    pub(crate) body: Arc<Body>,
+    pub(crate) body: &'a Body,
     pub(crate) resolver: Resolver,
     table: unify::InferenceTable<'a>,
     trait_env: Arc<TraitEnvironment>,
@@ -394,7 +395,12 @@ fn find_breakable<'c>(
 }
 
 impl<'a> InferenceContext<'a> {
-    fn new(db: &'a dyn HirDatabase, owner: DefWithBodyId, resolver: Resolver) -> Self {
+    fn new(
+        db: &'a dyn HirDatabase,
+        owner: DefWithBodyId,
+        body: &'a Body,
+        resolver: Resolver,
+    ) -> Self {
         let krate = owner.module(db.upcast()).krate();
         let trait_env = owner
             .as_generic_def_id()
@@ -406,46 +412,76 @@ impl<'a> InferenceContext<'a> {
             return_ty: TyKind::Error.intern(Interner), // set in collect_fn_signature
             db,
             owner,
-            body: db.body(owner),
+            body,
             resolver,
             diverges: Diverges::Maybe,
             breakables: Vec::new(),
         }
     }
 
-    fn err_ty(&self) -> Ty {
-        self.result.standard_types.unknown.clone()
-    }
+    fn resolve_all(self) -> InferenceResult {
+        let InferenceContext { mut table, mut result, .. } = self;
 
-    fn resolve_all(mut self) -> InferenceResult {
         // FIXME resolve obligations as well (use Guidance if necessary)
-        self.table.resolve_obligations_as_possible();
+        table.resolve_obligations_as_possible();
 
         // make sure diverging type variables are marked as such
-        self.table.propagate_diverging_flag();
-        let mut result = std::mem::take(&mut self.result);
+        table.propagate_diverging_flag();
         for ty in result.type_of_expr.values_mut() {
-            *ty = self.table.resolve_completely(ty.clone());
+            *ty = table.resolve_completely(ty.clone());
         }
         for ty in result.type_of_pat.values_mut() {
-            *ty = self.table.resolve_completely(ty.clone());
+            *ty = table.resolve_completely(ty.clone());
         }
         for mismatch in result.type_mismatches.values_mut() {
-            mismatch.expected = self.table.resolve_completely(mismatch.expected.clone());
-            mismatch.actual = self.table.resolve_completely(mismatch.actual.clone());
+            mismatch.expected = table.resolve_completely(mismatch.expected.clone());
+            mismatch.actual = table.resolve_completely(mismatch.actual.clone());
         }
         for (_, subst) in result.method_resolutions.values_mut() {
-            *subst = self.table.resolve_completely(subst.clone());
+            *subst = table.resolve_completely(subst.clone());
         }
         for adjustment in result.expr_adjustments.values_mut().flatten() {
-            adjustment.target = self.table.resolve_completely(adjustment.target.clone());
+            adjustment.target = table.resolve_completely(adjustment.target.clone());
         }
         for adjustment in result.pat_adjustments.values_mut().flatten() {
-            adjustment.target = self.table.resolve_completely(adjustment.target.clone());
+            adjustment.target = table.resolve_completely(adjustment.target.clone());
         }
         result
     }
 
+    fn collect_const(&mut self, data: &ConstData) {
+        self.return_ty = self.make_ty(&data.type_ref);
+    }
+
+    fn collect_static(&mut self, data: &StaticData) {
+        self.return_ty = self.make_ty(&data.type_ref);
+    }
+
+    fn collect_fn(&mut self, data: &FunctionData) {
+        let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
+            .with_impl_trait_mode(ImplTraitLoweringMode::Param);
+        let param_tys =
+            data.params.iter().map(|(_, type_ref)| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
+        for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
+            let ty = self.insert_type_vars(ty);
+            let ty = self.normalize_associated_types_in(ty);
+
+            self.infer_pat(*pat, &ty, BindingMode::default());
+        }
+        let error_ty = &TypeRef::Error;
+        let return_ty = if data.has_async_kw() {
+            data.async_ret_type.as_deref().unwrap_or(error_ty)
+        } else {
+            &*data.ret_type
+        };
+        let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
+        self.return_ty = return_ty;
+    }
+
+    fn infer_body(&mut self) {
+        self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
+    }
+
     fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
         self.result.type_of_expr.insert(expr, ty);
     }
@@ -491,6 +527,10 @@ impl<'a> InferenceContext<'a> {
         self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Disallowed)
     }
 
+    fn err_ty(&self) -> Ty {
+        self.result.standard_types.unknown.clone()
+    }
+
     /// Replaces ConstScalar::Unknown by a new type var, so we can maybe still infer it.
     fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
         let data = c.data(Interner);
@@ -544,6 +584,16 @@ impl<'a> InferenceContext<'a> {
         self.table.unify(ty1, ty2)
     }
 
+    /// Recurses through the given type, normalizing associated types mentioned
+    /// in it by replacing them by type variables and registering obligations to
+    /// resolve later. This should be done once for every type we get from some
+    /// type annotation (e.g. from a let type annotation, field type or function
+    /// call). `make_ty` handles this already, but e.g. for field types we need
+    /// to do it as well.
+    fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
+        self.table.normalize_associated_types_in(ty)
+    }
+
     fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
         self.resolve_obligations_as_possible();
         self.table.resolve_ty_shallow(ty)
@@ -586,16 +636,6 @@ impl<'a> InferenceContext<'a> {
         }
     }
 
-    /// Recurses through the given type, normalizing associated types mentioned
-    /// in it by replacing them by type variables and registering obligations to
-    /// resolve later. This should be done once for every type we get from some
-    /// type annotation (e.g. from a let type annotation, field type or function
-    /// call). `make_ty` handles this already, but e.g. for field types we need
-    /// to do it as well.
-    fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
-        self.table.normalize_associated_types_in(ty)
-    }
-
     fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Option<VariantId>) {
         let path = match path {
             Some(path) => path,
@@ -727,40 +767,6 @@ impl<'a> InferenceContext<'a> {
         }
     }
 
-    fn collect_const(&mut self, data: &ConstData) {
-        self.return_ty = self.make_ty(&data.type_ref);
-    }
-
-    fn collect_static(&mut self, data: &StaticData) {
-        self.return_ty = self.make_ty(&data.type_ref);
-    }
-
-    fn collect_fn(&mut self, data: &FunctionData) {
-        let body = Arc::clone(&self.body); // avoid borrow checker problem
-        let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
-            .with_impl_trait_mode(ImplTraitLoweringMode::Param);
-        let param_tys =
-            data.params.iter().map(|(_, type_ref)| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
-        for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
-            let ty = self.insert_type_vars(ty);
-            let ty = self.normalize_associated_types_in(ty);
-
-            self.infer_pat(*pat, &ty, BindingMode::default());
-        }
-        let error_ty = &TypeRef::Error;
-        let return_ty = if data.has_async_kw() {
-            data.async_ret_type.as_deref().unwrap_or(error_ty)
-        } else {
-            &*data.ret_type
-        };
-        let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
-        self.return_ty = return_ty;
-    }
-
-    fn infer_body(&mut self) {
-        self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
-    }
-
     fn resolve_lang_item(&self, name: Name) -> Option<LangItemTarget> {
         let krate = self.resolver.krate();
         self.db.lang_item(krate, name.to_smol_str())
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 7426a22e6af..fef02e63b70 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -4,7 +4,6 @@ use std::{
     collections::hash_map::Entry,
     iter::{repeat, repeat_with},
     mem,
-    sync::Arc,
 };
 
 use chalk_ir::{
@@ -80,8 +79,7 @@ impl<'a> InferenceContext<'a> {
     fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
         self.db.unwind_if_cancelled();
 
-        let body = Arc::clone(&self.body); // avoid borrow checker problem
-        let ty = match &body[tgt_expr] {
+        let ty = match &self.body[tgt_expr] {
             Expr::Missing => self.err_ty(),
             &Expr::If { condition, then_branch, else_branch } => {
                 self.infer_expr(
@@ -560,17 +558,7 @@ impl<'a> InferenceContext<'a> {
                 }
                 .intern(Interner)
             }
-            Expr::Box { expr } => {
-                let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
-                if let Some(box_) = self.resolve_boxed_box() {
-                    TyBuilder::adt(self.db, box_)
-                        .push(inner_ty)
-                        .fill_with_defaults(self.db, || self.table.new_type_var())
-                        .build()
-                } else {
-                    self.err_ty()
-                }
-            }
+            &Expr::Box { expr } => self.infer_expr_box(expr),
             Expr::UnaryOp { expr, op } => {
                 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
                 let inner_ty = self.resolve_ty_shallow(&inner_ty);
@@ -798,6 +786,18 @@ impl<'a> InferenceContext<'a> {
         ty
     }
 
+    fn infer_expr_box(&mut self, inner_expr: ExprId) -> chalk_ir::Ty<Interner> {
+        let inner_ty = self.infer_expr_inner(inner_expr, &Expectation::none());
+        if let Some(box_) = self.resolve_boxed_box() {
+            TyBuilder::adt(self.db, box_)
+                .push(inner_ty)
+                .fill_with_defaults(self.db, || self.table.new_type_var())
+                .build()
+        } else {
+            self.err_ty()
+        }
+    }
+
     fn infer_overloadable_binop(
         &mut self,
         lhs: ExprId,
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 9821815ca33..600b82ca414 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -1,6 +1,6 @@
 //! Type inference for patterns.
 
-use std::{iter::repeat, sync::Arc};
+use std::iter::repeat;
 
 use chalk_ir::Mutability;
 use hir_def::{
@@ -100,10 +100,9 @@ impl<'a> InferenceContext<'a> {
         expected: &Ty,
         mut default_bm: BindingMode,
     ) -> Ty {
-        let body = Arc::clone(&self.body); // avoid borrow checker problem
         let mut expected = self.resolve_ty_shallow(expected);
 
-        if is_non_ref_pat(&body, pat) {
+        if is_non_ref_pat(&self.body, pat) {
             let mut pat_adjustments = Vec::new();
             while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
                 pat_adjustments.push(Adjustment {
@@ -122,7 +121,7 @@ impl<'a> InferenceContext<'a> {
                 pat_adjustments.shrink_to_fit();
                 self.result.pat_adjustments.insert(pat, pat_adjustments);
             }
-        } else if let Pat::Ref { .. } = &body[pat] {
+        } else if let Pat::Ref { .. } = &self.body[pat] {
             cov_mark::hit!(match_ergonomics_ref);
             // When you encounter a `&pat` pattern, reset to Move.
             // This is so that `w` is by value: `let (_, &w) = &(1, &2);`
@@ -133,7 +132,7 @@ impl<'a> InferenceContext<'a> {
         let default_bm = default_bm;
         let expected = expected;
 
-        let ty = match &body[pat] {
+        let ty = match &self.body[pat] {
             Pat::Tuple { args, ellipsis } => {
                 let expectations = match expected.as_tuple() {
                     Some(parameters) => &*parameters.as_slice(Interner),