hir_ty/infer/
autoderef.rs1use std::iter;
4
5use rustc_ast_ir::Mutability;
6
7use crate::{
8 Adjust, Adjustment, OverloadedDeref, Span,
9 autoderef::{Autoderef, AutoderefCtx, AutoderefKind, GeneralAutoderef},
10 infer::unify::InferenceTable,
11 next_solver::{
12 Ty,
13 infer::{InferOk, traits::PredicateObligations},
14 },
15};
16
17impl<'db> InferenceTable<'db> {
18 pub(crate) fn autoderef(&self, base_ty: Ty<'db>, span: Span) -> Autoderef<'_, 'db, usize> {
19 Autoderef::new(&self.infer_ctxt, self.param_env, base_ty, span)
20 }
21
22 pub(crate) fn autoderef_with_tracking(
23 &self,
24 base_ty: Ty<'db>,
25 span: Span,
26 ) -> Autoderef<'_, 'db> {
27 Autoderef::new_with_tracking(&self.infer_ctxt, self.param_env, base_ty, span)
28 }
29}
30
31impl<'db, Ctx: AutoderefCtx<'db>> GeneralAutoderef<'db, Ctx> {
32 pub(crate) fn adjust_steps_as_infer_ok(&mut self) -> InferOk<'db, Vec<Adjustment>> {
33 let steps = self.steps();
34 if steps.is_empty() {
35 return InferOk { obligations: PredicateObligations::new(), value: vec![] };
36 }
37
38 let targets = steps.iter().skip(1).map(|&(ty, _)| ty).chain(iter::once(self.final_ty()));
39 let steps: Vec<_> = steps
40 .iter()
41 .map(|&(_source, kind)| {
42 if let AutoderefKind::Overloaded = kind {
43 Some(OverloadedDeref(Mutability::Not))
44 } else {
45 None
46 }
47 })
48 .zip(targets)
49 .map(|(autoderef, target)| Adjustment {
50 kind: Adjust::Deref(autoderef),
51 target: target.store(),
52 })
53 .collect();
54
55 InferOk { obligations: self.take_obligations(), value: steps }
56 }
57}