Skip to content
/ rust Public
forked from rust-lang/rust

Commit 3528a65

Browse files
committed
Deduplicate target type setting in unify_and callbacks
1 parent 34258d6 commit 3528a65

File tree

1 file changed

+50
-40
lines changed

1 file changed

+50
-40
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+50-40
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ fn coerce_mutbls<'tcx>(
103103
if from_mutbl >= to_mutbl { Ok(()) } else { Err(TypeError::Mutability) }
104104
}
105105

106-
fn simple<'tcx>(kind: Adjust) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>> {
107-
move |target| vec![Adjustment { kind, target }]
108-
}
109-
110106
/// This always returns `Ok(...)`.
111107
fn success<'tcx>(
112108
adj: Vec<Adjustment<'tcx>>,
@@ -163,12 +159,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
163159
}
164160

165161
/// Unify two types (using sub or lub) and produce a specific coercion.
166-
fn unify_and<F>(&self, a: Ty<'tcx>, b: Ty<'tcx>, f: F) -> CoerceResult<'tcx>
167-
where
168-
F: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
169-
{
170-
self.unify_raw(a, b)
171-
.and_then(|InferOk { value: ty, obligations }| success(f(ty), ty, obligations))
162+
fn unify_and(
163+
&self,
164+
a: Ty<'tcx>,
165+
b: Ty<'tcx>,
166+
mut adjustments: Vec<Adjustment<'tcx>>,
167+
final_adjustment: Adjust,
168+
) -> CoerceResult<'tcx> {
169+
self.unify_raw(a, b).and_then(|InferOk { value: ty, obligations }| {
170+
adjustments.push(Adjustment { target: ty, kind: final_adjustment });
171+
success(adjustments, ty, obligations)
172+
})
172173
}
173174

174175
#[instrument(skip(self))]
@@ -181,7 +182,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
181182
// Coercing from `!` to any type is allowed:
182183
if a.is_never() {
183184
if self.coerce_never {
184-
return success(simple(Adjust::NeverToAny)(b), b, PredicateObligations::new());
185+
return success(
186+
vec![Adjustment { kind: Adjust::NeverToAny, target: b }],
187+
b,
188+
PredicateObligations::new(),
189+
);
185190
} else {
186191
// Otherwise the only coercion we can do is unification.
187192
return self.unify(a, b);
@@ -574,13 +579,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
574579
// We only have the latter, so we use an inference variable
575580
// for the former and let type inference do the rest.
576581
let coerce_target = self.next_ty_var(self.cause.span);
577-
let mut coercion = self.unify_and(coerce_target, target, |target| {
578-
let unsize = Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), target };
582+
let mut coercion = self.unify_and(
583+
coerce_target,
584+
target,
579585
match reborrow {
580-
None => vec![unsize],
581-
Some((ref deref, ref autoref)) => vec![deref.clone(), autoref.clone(), unsize],
582-
}
583-
})?;
586+
None => vec![],
587+
Some((ref deref, ref autoref)) => vec![deref.clone(), autoref.clone()],
588+
},
589+
Adjust::Pointer(PointerCoercion::Unsize),
590+
)?;
584591

585592
let mut selcx = traits::SelectionContext::new(self);
586593

@@ -803,7 +810,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
803810

804811
// To complete the reborrow, we need to make sure we can unify the inner types, and if so we
805812
// add the adjustments.
806-
self.unify_and(a, b, simple(Adjust::ReborrowPin(mut_b)))
813+
self.unify_and(a, b, vec![], Adjust::ReborrowPin(mut_b))
807814
}
808815

809816
fn coerce_from_safe_fn(
@@ -820,22 +827,24 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
820827
&& hdr_b.safety.is_unsafe()
821828
{
822829
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
823-
self.unify_and(unsafe_a, b, |target| match adjustment {
824-
Some(kind) => vec![
825-
Adjustment { kind, target: Ty::new_fn_ptr(self.tcx, fn_ty_a) },
826-
Adjustment {
827-
kind: Adjust::Pointer(PointerCoercion::UnsafeFnPointer),
828-
target,
829-
},
830-
],
831-
None => simple(Adjust::Pointer(PointerCoercion::UnsafeFnPointer))(target),
832-
})
830+
let adjustments = match adjustment {
831+
Some(kind) => {
832+
vec![Adjustment { kind, target: Ty::new_fn_ptr(self.tcx, fn_ty_a) }]
833+
}
834+
None => vec![],
835+
};
836+
self.unify_and(
837+
unsafe_a,
838+
b,
839+
adjustments,
840+
Adjust::Pointer(PointerCoercion::UnsafeFnPointer),
841+
)
833842
} else {
834843
let a = Ty::new_fn_ptr(self.tcx, fn_ty_a);
835-
self.unify_and(a, b, |target| match adjustment {
836-
None => vec![],
837-
Some(kind) => vec![Adjustment { kind, target }],
838-
})
844+
match adjustment {
845+
Some(adjust) => self.unify_and(a, b, vec![], adjust),
846+
None => self.unify(a, b),
847+
}
839848
};
840849

841850
// FIXME(#73154): This is a hack. Currently LUB can generate
@@ -962,7 +971,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
962971
self.unify_and(
963972
pointer_ty,
964973
b,
965-
simple(Adjust::Pointer(PointerCoercion::ClosureFnPointer(safety))),
974+
vec![],
975+
Adjust::Pointer(PointerCoercion::ClosureFnPointer(safety)),
966976
)
967977
}
968978
_ => self.unify(a, b),
@@ -990,14 +1000,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
9901000
// representation, we still register an Adjust::DerefRef so that
9911001
// regionck knows that the region for `a` must be valid here.
9921002
if is_ref {
993-
self.unify_and(a_raw, b, |target| {
994-
vec![
995-
Adjustment { kind: Adjust::Deref(None), target: mt_a.ty },
996-
Adjustment { kind: Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)), target },
997-
]
998-
})
1003+
self.unify_and(
1004+
a_raw,
1005+
b,
1006+
vec![Adjustment { kind: Adjust::Deref(None), target: mt_a.ty }],
1007+
Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)),
1008+
)
9991009
} else if mt_a.mutbl != mutbl_b {
1000-
self.unify_and(a_raw, b, simple(Adjust::Pointer(PointerCoercion::MutToConstPointer)))
1010+
self.unify_and(a_raw, b, vec![], Adjust::Pointer(PointerCoercion::MutToConstPointer))
10011011
} else {
10021012
self.unify(a_raw, b)
10031013
}

0 commit comments

Comments
 (0)