Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1c22537

Browse files
committed
Auto merge of rust-lang#12005 - Veykril:hir-ty-simplify, r=Veykril
internal: Remove frequent `Arc<Body>` clones in type checking bors r+
2 parents e10284a + e5bf60f commit 1c22537

File tree

3 files changed

+86
-81
lines changed

3 files changed

+86
-81
lines changed

crates/hir_ty/src/infer.rs

Lines changed: 68 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ mod closure;
5959
pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
6060
let _p = profile::span("infer_query");
6161
let resolver = def.resolver(db.upcast());
62-
let mut ctx = InferenceContext::new(db, def, resolver);
62+
let body = db.body(def);
63+
let mut ctx = InferenceContext::new(db, def, &body, resolver);
6364

6465
match def {
6566
DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
@@ -360,7 +361,7 @@ impl Index<PatId> for InferenceResult {
360361
pub(crate) struct InferenceContext<'a> {
361362
pub(crate) db: &'a dyn HirDatabase,
362363
pub(crate) owner: DefWithBodyId,
363-
pub(crate) body: Arc<Body>,
364+
pub(crate) body: &'a Body,
364365
pub(crate) resolver: Resolver,
365366
table: unify::InferenceTable<'a>,
366367
trait_env: Arc<TraitEnvironment>,
@@ -394,7 +395,12 @@ fn find_breakable<'c>(
394395
}
395396

396397
impl<'a> InferenceContext<'a> {
397-
fn new(db: &'a dyn HirDatabase, owner: DefWithBodyId, resolver: Resolver) -> Self {
398+
fn new(
399+
db: &'a dyn HirDatabase,
400+
owner: DefWithBodyId,
401+
body: &'a Body,
402+
resolver: Resolver,
403+
) -> Self {
398404
let krate = owner.module(db.upcast()).krate();
399405
let trait_env = owner
400406
.as_generic_def_id()
@@ -406,46 +412,76 @@ impl<'a> InferenceContext<'a> {
406412
return_ty: TyKind::Error.intern(Interner), // set in collect_fn_signature
407413
db,
408414
owner,
409-
body: db.body(owner),
415+
body,
410416
resolver,
411417
diverges: Diverges::Maybe,
412418
breakables: Vec::new(),
413419
}
414420
}
415421

416-
fn err_ty(&self) -> Ty {
417-
self.result.standard_types.unknown.clone()
418-
}
422+
fn resolve_all(self) -> InferenceResult {
423+
let InferenceContext { mut table, mut result, .. } = self;
419424

420-
fn resolve_all(mut self) -> InferenceResult {
421425
// FIXME resolve obligations as well (use Guidance if necessary)
422-
self.table.resolve_obligations_as_possible();
426+
table.resolve_obligations_as_possible();
423427

424428
// make sure diverging type variables are marked as such
425-
self.table.propagate_diverging_flag();
426-
let mut result = std::mem::take(&mut self.result);
429+
table.propagate_diverging_flag();
427430
for ty in result.type_of_expr.values_mut() {
428-
*ty = self.table.resolve_completely(ty.clone());
431+
*ty = table.resolve_completely(ty.clone());
429432
}
430433
for ty in result.type_of_pat.values_mut() {
431-
*ty = self.table.resolve_completely(ty.clone());
434+
*ty = table.resolve_completely(ty.clone());
432435
}
433436
for mismatch in result.type_mismatches.values_mut() {
434-
mismatch.expected = self.table.resolve_completely(mismatch.expected.clone());
435-
mismatch.actual = self.table.resolve_completely(mismatch.actual.clone());
437+
mismatch.expected = table.resolve_completely(mismatch.expected.clone());
438+
mismatch.actual = table.resolve_completely(mismatch.actual.clone());
436439
}
437440
for (_, subst) in result.method_resolutions.values_mut() {
438-
*subst = self.table.resolve_completely(subst.clone());
441+
*subst = table.resolve_completely(subst.clone());
439442
}
440443
for adjustment in result.expr_adjustments.values_mut().flatten() {
441-
adjustment.target = self.table.resolve_completely(adjustment.target.clone());
444+
adjustment.target = table.resolve_completely(adjustment.target.clone());
442445
}
443446
for adjustment in result.pat_adjustments.values_mut().flatten() {
444-
adjustment.target = self.table.resolve_completely(adjustment.target.clone());
447+
adjustment.target = table.resolve_completely(adjustment.target.clone());
445448
}
446449
result
447450
}
448451

452+
fn collect_const(&mut self, data: &ConstData) {
453+
self.return_ty = self.make_ty(&data.type_ref);
454+
}
455+
456+
fn collect_static(&mut self, data: &StaticData) {
457+
self.return_ty = self.make_ty(&data.type_ref);
458+
}
459+
460+
fn collect_fn(&mut self, data: &FunctionData) {
461+
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
462+
.with_impl_trait_mode(ImplTraitLoweringMode::Param);
463+
let param_tys =
464+
data.params.iter().map(|(_, type_ref)| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
465+
for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
466+
let ty = self.insert_type_vars(ty);
467+
let ty = self.normalize_associated_types_in(ty);
468+
469+
self.infer_pat(*pat, &ty, BindingMode::default());
470+
}
471+
let error_ty = &TypeRef::Error;
472+
let return_ty = if data.has_async_kw() {
473+
data.async_ret_type.as_deref().unwrap_or(error_ty)
474+
} else {
475+
&*data.ret_type
476+
};
477+
let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
478+
self.return_ty = return_ty;
479+
}
480+
481+
fn infer_body(&mut self) {
482+
self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
483+
}
484+
449485
fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
450486
self.result.type_of_expr.insert(expr, ty);
451487
}
@@ -491,6 +527,10 @@ impl<'a> InferenceContext<'a> {
491527
self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Disallowed)
492528
}
493529

530+
fn err_ty(&self) -> Ty {
531+
self.result.standard_types.unknown.clone()
532+
}
533+
494534
/// Replaces ConstScalar::Unknown by a new type var, so we can maybe still infer it.
495535
fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
496536
let data = c.data(Interner);
@@ -544,6 +584,16 @@ impl<'a> InferenceContext<'a> {
544584
self.table.unify(ty1, ty2)
545585
}
546586

587+
/// Recurses through the given type, normalizing associated types mentioned
588+
/// in it by replacing them by type variables and registering obligations to
589+
/// resolve later. This should be done once for every type we get from some
590+
/// type annotation (e.g. from a let type annotation, field type or function
591+
/// call). `make_ty` handles this already, but e.g. for field types we need
592+
/// to do it as well.
593+
fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
594+
self.table.normalize_associated_types_in(ty)
595+
}
596+
547597
fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
548598
self.resolve_obligations_as_possible();
549599
self.table.resolve_ty_shallow(ty)
@@ -586,16 +636,6 @@ impl<'a> InferenceContext<'a> {
586636
}
587637
}
588638

589-
/// Recurses through the given type, normalizing associated types mentioned
590-
/// in it by replacing them by type variables and registering obligations to
591-
/// resolve later. This should be done once for every type we get from some
592-
/// type annotation (e.g. from a let type annotation, field type or function
593-
/// call). `make_ty` handles this already, but e.g. for field types we need
594-
/// to do it as well.
595-
fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
596-
self.table.normalize_associated_types_in(ty)
597-
}
598-
599639
fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Option<VariantId>) {
600640
let path = match path {
601641
Some(path) => path,
@@ -727,40 +767,6 @@ impl<'a> InferenceContext<'a> {
727767
}
728768
}
729769

730-
fn collect_const(&mut self, data: &ConstData) {
731-
self.return_ty = self.make_ty(&data.type_ref);
732-
}
733-
734-
fn collect_static(&mut self, data: &StaticData) {
735-
self.return_ty = self.make_ty(&data.type_ref);
736-
}
737-
738-
fn collect_fn(&mut self, data: &FunctionData) {
739-
let body = Arc::clone(&self.body); // avoid borrow checker problem
740-
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
741-
.with_impl_trait_mode(ImplTraitLoweringMode::Param);
742-
let param_tys =
743-
data.params.iter().map(|(_, type_ref)| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
744-
for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
745-
let ty = self.insert_type_vars(ty);
746-
let ty = self.normalize_associated_types_in(ty);
747-
748-
self.infer_pat(*pat, &ty, BindingMode::default());
749-
}
750-
let error_ty = &TypeRef::Error;
751-
let return_ty = if data.has_async_kw() {
752-
data.async_ret_type.as_deref().unwrap_or(error_ty)
753-
} else {
754-
&*data.ret_type
755-
};
756-
let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
757-
self.return_ty = return_ty;
758-
}
759-
760-
fn infer_body(&mut self) {
761-
self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
762-
}
763-
764770
fn resolve_lang_item(&self, name: Name) -> Option<LangItemTarget> {
765771
let krate = self.resolver.krate();
766772
self.db.lang_item(krate, name.to_smol_str())

crates/hir_ty/src/infer/expr.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::{
44
collections::hash_map::Entry,
55
iter::{repeat, repeat_with},
66
mem,
7-
sync::Arc,
87
};
98

109
use chalk_ir::{
@@ -80,8 +79,7 @@ impl<'a> InferenceContext<'a> {
8079
fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
8180
self.db.unwind_if_cancelled();
8281

83-
let body = Arc::clone(&self.body); // avoid borrow checker problem
84-
let ty = match &body[tgt_expr] {
82+
let ty = match &self.body[tgt_expr] {
8583
Expr::Missing => self.err_ty(),
8684
&Expr::If { condition, then_branch, else_branch } => {
8785
self.infer_expr(
@@ -560,17 +558,7 @@ impl<'a> InferenceContext<'a> {
560558
}
561559
.intern(Interner)
562560
}
563-
Expr::Box { expr } => {
564-
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
565-
if let Some(box_) = self.resolve_boxed_box() {
566-
TyBuilder::adt(self.db, box_)
567-
.push(inner_ty)
568-
.fill_with_defaults(self.db, || self.table.new_type_var())
569-
.build()
570-
} else {
571-
self.err_ty()
572-
}
573-
}
561+
&Expr::Box { expr } => self.infer_expr_box(expr),
574562
Expr::UnaryOp { expr, op } => {
575563
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
576564
let inner_ty = self.resolve_ty_shallow(&inner_ty);
@@ -798,6 +786,18 @@ impl<'a> InferenceContext<'a> {
798786
ty
799787
}
800788

789+
fn infer_expr_box(&mut self, inner_expr: ExprId) -> chalk_ir::Ty<Interner> {
790+
let inner_ty = self.infer_expr_inner(inner_expr, &Expectation::none());
791+
if let Some(box_) = self.resolve_boxed_box() {
792+
TyBuilder::adt(self.db, box_)
793+
.push(inner_ty)
794+
.fill_with_defaults(self.db, || self.table.new_type_var())
795+
.build()
796+
} else {
797+
self.err_ty()
798+
}
799+
}
800+
801801
fn infer_overloadable_binop(
802802
&mut self,
803803
lhs: ExprId,

crates/hir_ty/src/infer/pat.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Type inference for patterns.
22
3-
use std::{iter::repeat, sync::Arc};
3+
use std::iter::repeat;
44

55
use chalk_ir::Mutability;
66
use hir_def::{
@@ -100,10 +100,9 @@ impl<'a> InferenceContext<'a> {
100100
expected: &Ty,
101101
mut default_bm: BindingMode,
102102
) -> Ty {
103-
let body = Arc::clone(&self.body); // avoid borrow checker problem
104103
let mut expected = self.resolve_ty_shallow(expected);
105104

106-
if is_non_ref_pat(&body, pat) {
105+
if is_non_ref_pat(&self.body, pat) {
107106
let mut pat_adjustments = Vec::new();
108107
while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
109108
pat_adjustments.push(Adjustment {
@@ -122,7 +121,7 @@ impl<'a> InferenceContext<'a> {
122121
pat_adjustments.shrink_to_fit();
123122
self.result.pat_adjustments.insert(pat, pat_adjustments);
124123
}
125-
} else if let Pat::Ref { .. } = &body[pat] {
124+
} else if let Pat::Ref { .. } = &self.body[pat] {
126125
cov_mark::hit!(match_ergonomics_ref);
127126
// When you encounter a `&pat` pattern, reset to Move.
128127
// This is so that `w` is by value: `let (_, &w) = &(1, &2);`
@@ -133,7 +132,7 @@ impl<'a> InferenceContext<'a> {
133132
let default_bm = default_bm;
134133
let expected = expected;
135134

136-
let ty = match &body[pat] {
135+
let ty = match &self.body[pat] {
137136
Pat::Tuple { args, ellipsis } => {
138137
let expectations = match expected.as_tuple() {
139138
Some(parameters) => &*parameters.as_slice(Interner),

0 commit comments

Comments
 (0)