Skip to content

Commit a5ca477

Browse files
Cache more things that are related to lang items (paren traits, children/sibling assoc types/functions) but are not lang items themselves
And make use of them.
1 parent b4ca747 commit a5ca477

13 files changed

Lines changed: 267 additions & 218 deletions

File tree

crates/hir-def/src/lang_item.rs

Lines changed: 157 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,115 @@ fn resolve_core_macro(
194194

195195
impl LangItems {
196196
fn resolve_manually(&mut self, db: &dyn DefDatabase) {
197-
(|| {
198-
let into_future_into_future = self.IntoFutureIntoFuture?;
199-
let ItemContainerId::TraitId(into_future) = into_future_into_future.loc(db).container
200-
else {
201-
return None;
197+
let parent_trait =
198+
|lang_item: &mut Option<TraitId>, def: Option<FunctionId>| match def?.loc(db).container
199+
{
200+
ItemContainerId::TraitId(trait_) => {
201+
*lang_item = Some(trait_);
202+
Some(trait_)
203+
}
204+
_ => None,
205+
};
206+
let assoc_types =
207+
|trait_: TraitId, assoc_types: &mut [(&mut Option<TypeAliasId>, Symbol)]| {
208+
let trait_items = trait_.trait_items(db);
209+
for (assoc_type, name) in assoc_types {
210+
**assoc_type =
211+
trait_items.associated_type_by_name(&Name::new_symbol_root(name.clone()));
212+
}
202213
};
203-
self.IntoFuture = Some(into_future);
204-
self.IntoFutureOutput = into_future
205-
.trait_items(db)
206-
.associated_type_by_name(&Name::new_symbol_root(sym::Output));
214+
let methods = |trait_: TraitId, assoc_types: &mut [(&mut Option<FunctionId>, Symbol)]| {
215+
let trait_items = trait_.trait_items(db);
216+
for (assoc_type, name) in assoc_types {
217+
**assoc_type = trait_items.method_by_name(&Name::new_symbol_root(name.clone()));
218+
}
219+
};
220+
(|| {
221+
let into_future = parent_trait(&mut self.IntoFuture, self.IntoFutureIntoFuture)?;
222+
assoc_types(into_future, &mut [(&mut self.IntoFutureOutput, sym::Output)]);
223+
Some(())
224+
})();
225+
226+
(|| {
227+
let into_iterator = parent_trait(&mut self.IntoIterator, self.IntoIterIntoIter)?;
228+
assoc_types(
229+
into_iterator,
230+
&mut [
231+
(&mut self.IntoIteratorItem, sym::Item),
232+
(&mut self.IntoIterIntoIterType, sym::IntoIter),
233+
],
234+
);
235+
Some(())
236+
})();
237+
238+
(|| {
239+
assoc_types(self.Iterator?, &mut [(&mut self.IteratorItem, sym::Item)]);
240+
Some(())
241+
})();
242+
243+
(|| {
244+
assoc_types(self.AsyncIterator?, &mut [(&mut self.AsyncIteratorItem, sym::Item)]);
245+
Some(())
246+
})();
247+
248+
for (op_trait, op_method, op_method_name) in [
249+
(self.Fn, &mut self.Fn_call, sym::call),
250+
(self.FnMut, &mut self.FnMut_call_mut, sym::call_mut),
251+
(self.FnOnce, &mut self.FnOnce_call_once, sym::call_once),
252+
(self.AsyncFn, &mut self.AsyncFn_async_call, sym::async_call),
253+
(self.AsyncFnMut, &mut self.AsyncFnMut_async_call_mut, sym::async_call_mut),
254+
(self.AsyncFnOnce, &mut self.AsyncFnOnce_async_call_once, sym::async_call_once),
255+
(self.Not, &mut self.Not_not, sym::not),
256+
(self.Neg, &mut self.Neg_neg, sym::neg),
257+
(self.Add, &mut self.Add_add, sym::add),
258+
(self.Mul, &mut self.Mul_mul, sym::mul),
259+
(self.Sub, &mut self.Sub_sub, sym::sub),
260+
(self.Div, &mut self.Div_div, sym::div),
261+
(self.Rem, &mut self.Rem_rem, sym::rem),
262+
(self.Shl, &mut self.Shl_shl, sym::shl),
263+
(self.Shr, &mut self.Shr_shr, sym::shr),
264+
(self.BitXor, &mut self.BitXor_bitxor, sym::bitxor),
265+
(self.BitOr, &mut self.BitOr_bitor, sym::bitor),
266+
(self.BitAnd, &mut self.BitAnd_bitand, sym::bitand),
267+
(self.AddAssign, &mut self.AddAssign_add_assign, sym::add_assign),
268+
(self.MulAssign, &mut self.MulAssign_mul_assign, sym::mul_assign),
269+
(self.SubAssign, &mut self.SubAssign_sub_assign, sym::sub_assign),
270+
(self.DivAssign, &mut self.DivAssign_div_assign, sym::div_assign),
271+
(self.RemAssign, &mut self.RemAssign_rem_assign, sym::rem_assign),
272+
(self.ShlAssign, &mut self.ShlAssign_shl_assign, sym::shl_assign),
273+
(self.ShrAssign, &mut self.ShrAssign_shr_assign, sym::shr_assign),
274+
(self.BitXorAssign, &mut self.BitXorAssign_bitxor_assign, sym::bitxor_assign),
275+
(self.BitOrAssign, &mut self.BitOrAssign_bitor_assign, sym::bitor_assign),
276+
(self.BitAndAssign, &mut self.BitAndAssign_bitand_assign, sym::bitand_assign),
277+
(self.Drop, &mut self.Drop_drop, sym::drop),
278+
(self.Debug, &mut self.Debug_fmt, sym::fmt),
279+
(self.Deref, &mut self.Deref_deref, sym::deref),
280+
(self.DerefMut, &mut self.DerefMut_deref_mut, sym::deref_mut),
281+
(self.Index, &mut self.Index_index, sym::index),
282+
(self.IndexMut, &mut self.IndexMut_index_mut, sym::index_mut),
283+
] {
284+
(|| {
285+
methods(op_trait?, &mut [(op_method, op_method_name)]);
286+
Some(())
287+
})();
288+
}
289+
(|| {
290+
methods(
291+
self.PartialEq?,
292+
&mut [(&mut self.PartialEq_eq, sym::eq), (&mut self.PartialEq_ne, sym::ne)],
293+
);
294+
Some(())
295+
})();
296+
(|| {
297+
methods(
298+
self.PartialOrd?,
299+
&mut [
300+
(&mut self.PartialOrd_le, sym::le),
301+
(&mut self.PartialOrd_lt, sym::lt),
302+
(&mut self.PartialOrd_ge, sym::ge),
303+
(&mut self.PartialOrd_gt, sym::gt),
304+
],
305+
);
207306
Some(())
208307
})();
209308
}
@@ -567,6 +666,53 @@ language_item_table! { LangItems =>
567666
core::clone, Clone, CloneDerive;
568667

569668
@resolve_manually:
570-
IntoFuture, TraitId;
571-
IntoFutureOutput, TypeAliasId;
669+
670+
IntoFuture, TraitId;
671+
IntoFutureOutput, TypeAliasId;
672+
IntoIterator, TraitId;
673+
IntoIteratorItem, TypeAliasId;
674+
IntoIterIntoIterType, TypeAliasId;
675+
IteratorItem, TypeAliasId;
676+
AsyncIteratorItem, TypeAliasId;
677+
678+
Fn_call, FunctionId;
679+
FnMut_call_mut, FunctionId;
680+
FnOnce_call_once, FunctionId;
681+
AsyncFn_async_call, FunctionId;
682+
AsyncFnMut_async_call_mut, FunctionId;
683+
AsyncFnOnce_async_call_once, FunctionId;
684+
Not_not, FunctionId;
685+
Neg_neg, FunctionId;
686+
Add_add, FunctionId;
687+
Mul_mul, FunctionId;
688+
Sub_sub, FunctionId;
689+
Div_div, FunctionId;
690+
Rem_rem, FunctionId;
691+
Shl_shl, FunctionId;
692+
Shr_shr, FunctionId;
693+
BitXor_bitxor, FunctionId;
694+
BitOr_bitor, FunctionId;
695+
BitAnd_bitand, FunctionId;
696+
AddAssign_add_assign, FunctionId;
697+
MulAssign_mul_assign, FunctionId;
698+
SubAssign_sub_assign, FunctionId;
699+
DivAssign_div_assign, FunctionId;
700+
RemAssign_rem_assign, FunctionId;
701+
ShlAssign_shl_assign, FunctionId;
702+
ShrAssign_shr_assign, FunctionId;
703+
BitXorAssign_bitxor_assign, FunctionId;
704+
BitOrAssign_bitor_assign, FunctionId;
705+
BitAndAssign_bitand_assign, FunctionId;
706+
PartialEq_eq, FunctionId;
707+
PartialEq_ne, FunctionId;
708+
PartialOrd_le, FunctionId;
709+
PartialOrd_lt, FunctionId;
710+
PartialOrd_ge, FunctionId;
711+
PartialOrd_gt, FunctionId;
712+
Drop_drop, FunctionId;
713+
Debug_fmt, FunctionId;
714+
Deref_deref, FunctionId;
715+
DerefMut_deref_mut, FunctionId;
716+
Index_index, FunctionId;
717+
IndexMut_index_mut, FunctionId;
572718
}

crates/hir-ty/src/display.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,11 +1726,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
17261726
subst.split_coroutine_args();
17271727
match kind {
17281728
HirClosureKind::Coroutine { kind: CoroutineKind::Async, .. } => {
1729-
let future_trait = f.lang_items().Future;
1730-
let output = future_trait.and_then(|t| {
1731-
t.trait_items(db)
1732-
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
1733-
});
1729+
let lang_items = f.lang_items();
1730+
let future_trait = lang_items.Future;
1731+
let output = lang_items.FutureOutput;
17341732
write!(f, "impl ")?;
17351733
if let Some(t) = future_trait {
17361734
f.start_location_link(t.into());
@@ -1752,11 +1750,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
17521750
write!(f, ">")?;
17531751
}
17541752
HirClosureKind::Coroutine { kind: CoroutineKind::Gen, .. } => {
1755-
let iterator_trait = f.lang_items().Iterator;
1756-
let item = iterator_trait.and_then(|t| {
1757-
t.trait_items(db)
1758-
.associated_type_by_name(&Name::new_symbol_root(sym::Item))
1759-
});
1753+
let lang_items = f.lang_items();
1754+
let iterator_trait = lang_items.Iterator;
1755+
let item = lang_items.IteratorItem;
17601756
write!(f, "impl ")?;
17611757
if let Some(t) = iterator_trait {
17621758
f.start_location_link(t.into());
@@ -1778,11 +1774,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
17781774
write!(f, ">")?;
17791775
}
17801776
HirClosureKind::Coroutine { kind: CoroutineKind::AsyncGen, .. } => {
1781-
let async_iterator_trait = f.lang_items().AsyncIterator;
1782-
let item = async_iterator_trait.and_then(|t| {
1783-
t.trait_items(db)
1784-
.associated_type_by_name(&Name::new_symbol_root(sym::Item))
1785-
});
1777+
let lang_items = f.lang_items();
1778+
let async_iterator_trait = lang_items.AsyncIterator;
1779+
let item = lang_items.AsyncIteratorItem;
17861780
write!(f, "impl ")?;
17871781
if let Some(t) = async_iterator_trait {
17881782
f.start_location_link(t.into());

crates/hir-ty/src/infer/callee.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use std::iter;
44

5-
use intern::sym;
65
use tracing::debug;
76

87
use hir_def::{CallableDefId, ConstParamId, hir::ExprId, signatures::FunctionSignature};
@@ -277,27 +276,28 @@ impl<'db> InferenceContext<'_, 'db> {
277276

278277
let call_trait_choices = if self.shallow_resolve(adjusted_ty).is_coroutine_closure() {
279278
[
280-
(self.lang_items.AsyncFn, sym::async_call, true),
281-
(self.lang_items.AsyncFnMut, sym::async_call_mut, true),
282-
(self.lang_items.AsyncFnOnce, sym::async_call_once, false),
283-
(self.lang_items.Fn, sym::call, true),
284-
(self.lang_items.FnMut, sym::call_mut, true),
285-
(self.lang_items.FnOnce, sym::call_once, false),
279+
(self.lang_items.AsyncFn, self.lang_items.AsyncFn_async_call, true),
280+
(self.lang_items.AsyncFnMut, self.lang_items.AsyncFnMut_async_call_mut, true),
281+
(self.lang_items.AsyncFnOnce, self.lang_items.AsyncFnOnce_async_call_once, false),
282+
(self.lang_items.Fn, self.lang_items.Fn_call, true),
283+
(self.lang_items.FnMut, self.lang_items.FnMut_call_mut, true),
284+
(self.lang_items.FnOnce, self.lang_items.FnOnce_call_once, false),
286285
]
287286
} else {
288287
[
289-
(self.lang_items.Fn, sym::call, true),
290-
(self.lang_items.FnMut, sym::call_mut, true),
291-
(self.lang_items.FnOnce, sym::call_once, false),
292-
(self.lang_items.AsyncFn, sym::async_call, true),
293-
(self.lang_items.AsyncFnMut, sym::async_call_mut, true),
294-
(self.lang_items.AsyncFnOnce, sym::async_call_once, false),
288+
(self.lang_items.Fn, self.lang_items.Fn_call, true),
289+
(self.lang_items.FnMut, self.lang_items.FnMut_call_mut, true),
290+
(self.lang_items.FnOnce, self.lang_items.FnOnce_call_once, false),
291+
(self.lang_items.AsyncFn, self.lang_items.AsyncFn_async_call, true),
292+
(self.lang_items.AsyncFnMut, self.lang_items.AsyncFnMut_async_call_mut, true),
293+
(self.lang_items.AsyncFnOnce, self.lang_items.AsyncFnOnce_async_call_once, false),
295294
]
296295
};
297296

298297
// Try the options that are least restrictive on the caller first.
299-
for (opt_trait_def_id, method_name, borrow) in call_trait_choices {
300-
let Some(trait_def_id) = opt_trait_def_id else {
298+
for (opt_trait_def_id, opt_method_def_id, borrow) in call_trait_choices {
299+
let (Some(trait_def_id), Some(method_def_id)) = (opt_trait_def_id, opt_method_def_id)
300+
else {
301301
continue;
302302
};
303303

@@ -316,8 +316,8 @@ impl<'db> InferenceContext<'_, 'db> {
316316
// `Box<impl FnOnce()>: Fn` is considered ambiguous and chosen.
317317
if let Some(ok) = self.table.lookup_method_for_operator(
318318
ObligationCause::new(call_expr),
319-
method_name,
320319
trait_def_id,
320+
method_def_id,
321321
adjusted_ty,
322322
opt_input_type,
323323
TreatNotYetDefinedOpaques::AsRigid,

crates/hir-ty/src/infer/op.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
33
use std::collections::hash_map;
44

5-
use hir_def::{GenericParamId, TraitId, hir::ExprId};
6-
use intern::{Symbol, sym};
5+
use hir_def::{FunctionId, GenericParamId, TraitId, hir::ExprId};
76
use rustc_ast_ir::Mutability;
87
use rustc_type_ir::inherent::{IntoKind, Ty as _};
98
use syntax::ast::{ArithOp, BinaryOp, UnaryOp};
@@ -283,16 +282,16 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
283282
expr: ExprId,
284283
lhs_ty: Ty<'db>,
285284
opt_rhs: Option<(ExprId, Ty<'db>)>,
286-
(opname, trait_did): (Symbol, Option<TraitId>),
285+
(op_method, trait_did): (Option<FunctionId>, Option<TraitId>),
287286
) -> Result<MethodCallee<'db>, Vec<NextSolverError<'db>>> {
288-
let Some(trait_did) = trait_did else {
287+
let (Some(trait_did), Some(op_method)) = (trait_did, op_method) else {
289288
// Bail if the operator trait is not defined.
290289
return Err(vec![]);
291290
};
292291

293292
debug!(
294293
"lookup_op_method(lhs_ty={:?}, opname={:?}, trait_did={:?})",
295-
lhs_ty, opname, trait_did
294+
lhs_ty, op_method, trait_did
296295
);
297296

298297
let opt_rhs_ty = opt_rhs.map(|it| it.1);
@@ -304,8 +303,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
304303
let treat_opaques = TreatNotYetDefinedOpaques::AsInfer;
305304
let method = self.table.lookup_method_for_operator(
306305
cause,
307-
opname,
308306
trait_did,
307+
op_method,
309308
lhs_ty,
310309
opt_rhs_ty,
311310
treat_opaques,
@@ -360,20 +359,20 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
360359
}
361360
}
362361

363-
fn lang_item_for_bin_op(&self, op: BinaryOp) -> (Symbol, Option<TraitId>) {
364-
let (method_name, trait_lang_item) =
362+
fn lang_item_for_bin_op(&self, op: BinaryOp) -> (Option<FunctionId>, Option<TraitId>) {
363+
let (method, trait_lang_item) =
365364
crate::lang_items::lang_items_for_bin_op(self.lang_items, op)
366365
.expect("invalid operator provided");
367-
(method_name, trait_lang_item)
366+
(method, trait_lang_item)
368367
}
369368

370-
fn lang_item_for_unop(&self, op: UnaryOp) -> (Symbol, Option<TraitId>) {
371-
let (method_name, trait_lang_item) = match op {
372-
UnaryOp::Not => (sym::not, self.lang_items.Not),
373-
UnaryOp::Neg => (sym::neg, self.lang_items.Neg),
369+
fn lang_item_for_unop(&self, op: UnaryOp) -> (Option<FunctionId>, Option<TraitId>) {
370+
let (method, trait_lang_item) = match op {
371+
UnaryOp::Not => (self.lang_items.Not_not, self.lang_items.Not),
372+
UnaryOp::Neg => (self.lang_items.Neg_neg, self.lang_items.Neg),
374373
UnaryOp::Deref => panic!("Deref is not overloadable"),
375374
};
376-
(method_name, trait_lang_item)
375+
(method, trait_lang_item)
377376
}
378377
}
379378

0 commit comments

Comments
 (0)