Skip to content

Commit a41d32f

Browse files
committed
Minor refactoring in coercion.rs
1 parent 3ebb495 commit a41d32f

File tree

1 file changed

+122
-129
lines changed

1 file changed

+122
-129
lines changed

src/librustc_typeck/check/coercion.rs

Lines changed: 122 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -252,70 +252,64 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
252252

253253
match (&a.sty, &b.sty) {
254254
(&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_rptr(_, mt_b)) => {
255-
self.unpack_actual_value(t_a, |a| {
256-
match self.unsize_ty(t_a, a, mt_b.ty) {
257-
Some((ty, kind)) => {
258-
if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
259-
return Err(ty::terr_mutability);
260-
}
261-
262-
let coercion = Coercion(self.trace.clone());
263-
let r_borrow = self.fcx.infcx().next_region_var(coercion);
264-
let ty = ty::mk_rptr(self.tcx(),
265-
self.tcx().mk_region(r_borrow),
266-
ty::mt{ty: ty, mutbl: mt_b.mutbl});
267-
try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
268-
debug!("Success, coerced with AutoDerefRef(1, \
269-
AutoPtr(AutoUnsize({:?})))", kind);
270-
Ok(Some(AdjustDerefRef(AutoDerefRef {
271-
autoderefs: 1,
272-
autoref: Some(ty::AutoPtr(r_borrow, mt_b.mutbl,
273-
Some(box AutoUnsize(kind))))
274-
})))
255+
match self.unsize_ty(t_a, mt_b.ty) {
256+
Some((ty, kind)) => {
257+
if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
258+
return Err(ty::terr_mutability);
275259
}
276-
_ => Err(ty::terr_mismatch)
260+
261+
let coercion = Coercion(self.trace.clone());
262+
let r_borrow = self.fcx.infcx().next_region_var(coercion);
263+
let ty = ty::mk_rptr(self.tcx(),
264+
self.tcx().mk_region(r_borrow),
265+
ty::mt{ty: ty, mutbl: mt_b.mutbl});
266+
try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
267+
debug!("Success, coerced with AutoDerefRef(1, \
268+
AutoPtr(AutoUnsize({:?})))", kind);
269+
Ok(Some(AdjustDerefRef(AutoDerefRef {
270+
autoderefs: 1,
271+
autoref: Some(ty::AutoPtr(r_borrow, mt_b.mutbl,
272+
Some(box AutoUnsize(kind))))
273+
})))
277274
}
278-
})
275+
_ => Err(ty::terr_mismatch)
276+
}
279277
}
280278
(&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_ptr(mt_b)) => {
281-
self.unpack_actual_value(t_a, |a| {
282-
match self.unsize_ty(t_a, a, mt_b.ty) {
283-
Some((ty, kind)) => {
284-
if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
285-
return Err(ty::terr_mutability);
286-
}
287-
288-
let ty = ty::mk_ptr(self.tcx(),
289-
ty::mt{ty: ty, mutbl: mt_b.mutbl});
290-
try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
291-
debug!("Success, coerced with AutoDerefRef(1, \
292-
AutoPtr(AutoUnsize({:?})))", kind);
293-
Ok(Some(AdjustDerefRef(AutoDerefRef {
294-
autoderefs: 1,
295-
autoref: Some(ty::AutoUnsafe(mt_b.mutbl,
296-
Some(box AutoUnsize(kind))))
297-
})))
279+
match self.unsize_ty(t_a, mt_b.ty) {
280+
Some((ty, kind)) => {
281+
if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
282+
return Err(ty::terr_mutability);
298283
}
299-
_ => Err(ty::terr_mismatch)
284+
285+
let ty = ty::mk_ptr(self.tcx(),
286+
ty::mt{ty: ty, mutbl: mt_b.mutbl});
287+
try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
288+
debug!("Success, coerced with AutoDerefRef(1, \
289+
AutoPtr(AutoUnsize({:?})))", kind);
290+
Ok(Some(AdjustDerefRef(AutoDerefRef {
291+
autoderefs: 1,
292+
autoref: Some(ty::AutoUnsafe(mt_b.mutbl,
293+
Some(box AutoUnsize(kind))))
294+
})))
300295
}
301-
})
296+
_ => Err(ty::terr_mismatch)
297+
}
302298
}
303299
(&ty::ty_uniq(t_a), &ty::ty_uniq(t_b)) => {
304-
self.unpack_actual_value(t_a, |a| {
305-
match self.unsize_ty(t_a, a, t_b) {
306-
Some((ty, kind)) => {
307-
let ty = ty::mk_uniq(self.tcx(), ty);
308-
try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
309-
debug!("Success, coerced with AutoDerefRef(1, \
310-
AutoUnsizeUniq({:?}))", kind);
311-
Ok(Some(AdjustDerefRef(AutoDerefRef {
312-
autoderefs: 1,
313-
autoref: Some(ty::AutoUnsizeUniq(kind))
314-
})))
315-
}
316-
_ => Err(ty::terr_mismatch)
300+
match self.unsize_ty(t_a, t_b) {
301+
Some((ty, kind)) => {
302+
let ty = ty::mk_uniq(self.tcx(), ty);
303+
try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
304+
debug!("Success, coerced with AutoDerefRef(1, \
305+
AutoUnsizeUniq({:?}))", kind);
306+
Ok(Some(AdjustDerefRef(AutoDerefRef {
307+
autoderefs: 1,
308+
autoref: Some(ty::AutoUnsizeUniq(kind))
309+
})))
317310
}
318-
})
311+
_ => Err(ty::terr_mismatch)
312+
}
319313
}
320314
_ => Err(ty::terr_mismatch)
321315
}
@@ -326,93 +320,92 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
326320
// E.g., `[T, ..n]` -> `([T], UnsizeLength(n))`
327321
fn unsize_ty(&self,
328322
ty_a: Ty<'tcx>,
329-
a: Ty<'tcx>, // TODO unwrap ty_a here, not in the caller
330323
ty_b: Ty<'tcx>)
331324
-> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)>
332325
{
333326
let tcx = self.tcx();
334327

335-
self.unpack_actual_value(ty_b, |b| {
336-
debug!("unsize_ty(a={}, b={})", a.repr(self.tcx()), b.repr(self.tcx()));
337-
match (&a.sty, &b.sty) {
338-
(&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => {
339-
let ty = ty::mk_vec(tcx, t_a, None);
340-
Some((ty, ty::UnsizeLength(len)))
341-
}
342-
(&ty::ty_trait(ref data_a), &ty::ty_trait(ref data_b)) => {
343-
// For now, we only support upcasts from
344-
// `Foo+Send` to `Foo` (really, any time there are
345-
// fewer builtin bounds then before). These are
346-
// convenient because they don't require any sort
347-
// of change to the vtable at runtime.
348-
if data_a.bounds.builtin_bounds != data_b.bounds.builtin_bounds &&
349-
data_a.bounds.builtin_bounds.is_superset(&data_b.bounds.builtin_bounds)
350-
{
351-
let bounds_a1 = ty::ExistentialBounds {
352-
region_bound: data_a.bounds.region_bound,
353-
builtin_bounds: data_b.bounds.builtin_bounds,
354-
projection_bounds: data_a.bounds.projection_bounds.clone(),
355-
};
356-
let ty_a1 = ty::mk_trait(tcx, data_a.principal.clone(), bounds_a1);
357-
match self.fcx.infcx().try(|_| self.subtype(ty_a1, ty_b)) {
358-
Ok(_) => Some((ty_b, ty::UnsizeUpcast(ty_b))),
359-
Err(_) => None,
360-
}
361-
} else {
362-
None
328+
self.unpack_actual_value(ty_a, |a| {
329+
self.unpack_actual_value(ty_b, |b| {
330+
debug!("unsize_ty(a={}, b={})", a.repr(self.tcx()), b.repr(self.tcx()));
331+
match (&a.sty, &b.sty) {
332+
(&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => {
333+
let ty = ty::mk_vec(tcx, t_a, None);
334+
Some((ty, ty::UnsizeLength(len)))
363335
}
364-
}
365-
(_, &ty::ty_trait(ref data)) => {
366-
Some((ty_b, ty::UnsizeVtable(ty::TyTrait { principal: data.principal.clone(),
367-
bounds: data.bounds.clone() },
368-
ty_a)))
369-
}
370-
(&ty::ty_struct(did_a, substs_a), &ty::ty_struct(did_b, substs_b))
371-
if did_a == did_b => {
372-
debug!("unsizing a struct");
373-
// Try unsizing each type param in turn to see if we end up with ty_b.
374-
let ty_substs_a = substs_a.types.get_slice(subst::TypeSpace);
375-
let ty_substs_b = substs_b.types.get_slice(subst::TypeSpace);
376-
assert!(ty_substs_a.len() == ty_substs_b.len());
377-
378-
let mut result = None;
379-
let tps = ty_substs_a.iter().zip(ty_substs_b.iter()).enumerate();
380-
for (i, (tp_a, tp_b)) in tps {
381-
if self.fcx.infcx().try(|_| self.subtype(*tp_a, *tp_b)).is_ok() {
382-
continue;
383-
}
384-
match
385-
self.unpack_actual_value(
386-
*tp_a,
387-
|tp| self.unsize_ty(*tp_a, tp, *tp_b))
336+
(&ty::ty_trait(ref data_a), &ty::ty_trait(ref data_b)) => {
337+
// For now, we only support upcasts from
338+
// `Foo+Send` to `Foo` (really, any time there are
339+
// fewer builtin bounds then before). These are
340+
// convenient because they don't require any sort
341+
// of change to the vtable at runtime.
342+
if data_a.bounds.builtin_bounds != data_b.bounds.builtin_bounds &&
343+
data_a.bounds.builtin_bounds.is_superset(&data_b.bounds.builtin_bounds)
388344
{
389-
Some((new_tp, k)) => {
390-
// Check that the whole types match.
391-
let mut new_substs = substs_a.clone();
392-
new_substs.types.get_mut_slice(subst::TypeSpace)[i] = new_tp;
393-
let ty = ty::mk_struct(tcx, did_a, tcx.mk_substs(new_substs));
394-
if self.fcx.infcx().try(|_| self.subtype(ty, ty_b)).is_err() {
395-
debug!("Unsized type parameter '{}', but still \
396-
could not match types {} and {}",
397-
ppaux::ty_to_string(tcx, *tp_a),
398-
ppaux::ty_to_string(tcx, ty),
399-
ppaux::ty_to_string(tcx, ty_b));
400-
// We can only unsize a single type parameter, so
401-
// if we unsize one and it doesn't give us the
402-
// type we want, then we won't succeed later.
345+
let bounds_a1 = ty::ExistentialBounds {
346+
region_bound: data_a.bounds.region_bound,
347+
builtin_bounds: data_b.bounds.builtin_bounds,
348+
projection_bounds: data_a.bounds.projection_bounds.clone(),
349+
};
350+
let ty_a1 = ty::mk_trait(tcx, data_a.principal.clone(), bounds_a1);
351+
match self.fcx.infcx().try(|_| self.subtype(ty_a1, ty_b)) {
352+
Ok(_) => Some((ty_b, ty::UnsizeUpcast(ty_b))),
353+
Err(_) => None,
354+
}
355+
} else {
356+
None
357+
}
358+
}
359+
(_, &ty::ty_trait(ref data)) => {
360+
Some((ty_b, ty::UnsizeVtable(ty::TyTrait {
361+
principal: data.principal.clone(),
362+
bounds: data.bounds.clone()
363+
},
364+
ty_a)))
365+
}
366+
(&ty::ty_struct(did_a, substs_a), &ty::ty_struct(did_b, substs_b))
367+
if did_a == did_b => {
368+
debug!("unsizing a struct");
369+
// Try unsizing each type param in turn to see if we end up with ty_b.
370+
let ty_substs_a = substs_a.types.get_slice(subst::TypeSpace);
371+
let ty_substs_b = substs_b.types.get_slice(subst::TypeSpace);
372+
assert!(ty_substs_a.len() == ty_substs_b.len());
373+
374+
let mut result = None;
375+
let tps = ty_substs_a.iter().zip(ty_substs_b.iter()).enumerate();
376+
for (i, (tp_a, tp_b)) in tps {
377+
if self.fcx.infcx().try(|_| self.subtype(*tp_a, *tp_b)).is_ok() {
378+
continue;
379+
}
380+
match self.unsize_ty(*tp_a, *tp_b) {
381+
Some((new_tp, k)) => {
382+
// Check that the whole types match.
383+
let mut new_substs = substs_a.clone();
384+
new_substs.types.get_mut_slice(subst::TypeSpace)[i] = new_tp;
385+
let ty = ty::mk_struct(tcx, did_a, tcx.mk_substs(new_substs));
386+
if self.fcx.infcx().try(|_| self.subtype(ty, ty_b)).is_err() {
387+
debug!("Unsized type parameter '{}', but still \
388+
could not match types {} and {}",
389+
ppaux::ty_to_string(tcx, *tp_a),
390+
ppaux::ty_to_string(tcx, ty),
391+
ppaux::ty_to_string(tcx, ty_b));
392+
// We can only unsize a single type parameter, so
393+
// if we unsize one and it doesn't give us the
394+
// type we want, then we won't succeed later.
395+
break;
396+
}
397+
398+
result = Some((ty, ty::UnsizeStruct(box k, i)));
403399
break;
404400
}
405-
406-
result = Some((ty, ty::UnsizeStruct(box k, i)));
407-
break;
401+
None => {}
408402
}
409-
None => {}
410403
}
404+
result
411405
}
412-
result
406+
_ => None
413407
}
414-
_ => None
415-
}
408+
})
416409
})
417410
}
418411

0 commit comments

Comments
 (0)