diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2015-01-17 22:44:42 +0200 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2015-01-30 00:27:12 +0200 |
| commit | 6a478bdfd24ccc4df99a23d275a82e71a990115d (patch) | |
| tree | a76fcf4d161d28942af71df88246cf1597a2a329 | |
| parent | f9f3ba5920ddb2b8bae5047eea556081e0da159d (diff) | |
| download | rust-6a478bdfd24ccc4df99a23d275a82e71a990115d.tar.gz rust-6a478bdfd24ccc4df99a23d275a82e71a990115d.zip | |
rustc_typeck: use FnCtxt in coercion, instead of mimicking a combiner.
| -rw-r--r-- | src/librustc_typeck/check/coercion.rs | 130 | ||||
| -rw-r--r-- | src/librustc_typeck/check/demand.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 18 |
3 files changed, 65 insertions, 87 deletions
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index e375647bc28..79d57d957ab 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -60,10 +60,11 @@ //! sort of a minor point so I've opted to leave it for later---after all //! we may want to adjust precisely when coercions occur. -use middle::infer::{cres, Coercion, InferCtxt, TypeOrigin, TypeTrace}; -use middle::infer::combine::{CombineFields, Combine}; -use middle::infer::sub::Sub; +use check::FnCtxt; +use middle::infer::{self, cres, Coercion, TypeTrace}; +use middle::infer::combine::Combine; +use middle::infer::sub::Sub; use middle::subst; use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe}; use middle::ty::{mt}; @@ -74,21 +75,31 @@ use util::ppaux::Repr; use syntax::ast; -// Note: Coerce is not actually a combiner, in that it does not -// conform to the same interface, though it performs a similar -// function. -pub struct Coerce<'f, 'tcx: 'f>(pub CombineFields<'f, 'tcx>); +struct Coerce<'a, 'tcx: 'a> { + fcx: &'a FnCtxt<'a, 'tcx>, + trace: TypeTrace<'tcx> +} + +type CoerceResult<'tcx> = cres<'tcx, Option<ty::AutoAdjustment<'tcx>>>; impl<'f, 'tcx> Coerce<'f, 'tcx> { - pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f, 'tcx> { - let Coerce(ref v) = *self; v + fn tcx(&self) -> &ty::ctxt<'tcx> { + self.fcx.tcx() } - fn tcx(&self) -> &ty::ctxt<'tcx> { - self.get_ref().infcx.tcx + fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { + let sub = Sub(self.fcx.infcx().combine_fields(false, self.trace.clone())); + try!(sub.tys(a, b)); + Ok(None) // No coercion required. } - pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { + fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where + F: FnOnce(Ty<'tcx>) -> T, + { + f(self.fcx.infcx().shallow_resolve(a)) + } + + fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { debug!("Coerce.tys({} => {})", a.repr(self.tcx()), b.repr(self.tcx())); @@ -179,25 +190,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }) } - pub fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { - match Sub(self.get_ref().clone()).tys(a, b) { - Ok(_) => Ok(None), // No coercion required. - Err(ref e) => Err(*e) - } - } - - pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where - F: FnOnce(Ty<'tcx>) -> T, - { - f(self.get_ref().infcx.shallow_resolve(a)) - } - // ~T -> &T or &mut T -> &T (including where T = [U] or str) - pub fn coerce_borrowed_pointer(&self, - a: Ty<'tcx>, - b: Ty<'tcx>, - mutbl_b: ast::Mutability) - -> CoerceResult<'tcx> { + fn coerce_borrowed_pointer(&self, + a: Ty<'tcx>, + b: Ty<'tcx>, + mutbl_b: ast::Mutability) + -> CoerceResult<'tcx> { debug!("coerce_borrowed_pointer(a={}, b={})", a.repr(self.tcx()), b.repr(self.tcx())); @@ -208,9 +206,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // to type check, we will construct the type that `&M*expr` would // yield. - let sub = Sub(self.get_ref().clone()); - let coercion = Coercion(self.get_ref().trace.clone()); - let r_borrow = self.get_ref().infcx.next_region_var(coercion); + let coercion = Coercion(self.trace.clone()); + let r_borrow = self.fcx.infcx().next_region_var(coercion); let inner_ty = match a.sty { ty::ty_uniq(_) => return Err(ty::terr_mismatch), @@ -220,15 +217,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } mt_a.ty } - _ => { - return self.subtype(a, b); - } + _ => return self.subtype(a, b) }; let a_borrowed = ty::mk_rptr(self.tcx(), self.tcx().mk_region(r_borrow), mt {ty: inner_ty, mutbl: mutbl_b}); - try!(sub.tys(a_borrowed, b)); + try!(self.subtype(a_borrowed, b)); + if let Err(original_err) = self.subtype(a_borrowed, b) { Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 1, @@ -253,8 +249,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // we can't unify [T] with U. But to properly support DST, we need to allow // that, at which point we will need extra checks on b here. - let sub = Sub(self.get_ref().clone()); - match (&a.sty, &b.sty) { (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_rptr(_, mt_b)) => { self.unpack_actual_value(t_a, |a| { @@ -264,12 +258,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { return Err(ty::terr_mutability); } - let coercion = Coercion(self.get_ref().trace.clone()); - let r_borrow = self.get_ref().infcx.next_region_var(coercion); + let coercion = Coercion(self.trace.clone()); + let r_borrow = self.fcx.infcx().next_region_var(coercion); let ty = ty::mk_rptr(self.tcx(), self.tcx().mk_region(r_borrow), ty::mt{ty: ty, mutbl: mt_b.mutbl}); - try!(self.get_ref().infcx.try(|_| sub.tys(ty, b))); + try!(self.fcx.infcx().try(|_| self.subtype(ty, b))); debug!("Success, coerced with AutoDerefRef(1, \ AutoPtr(AutoUnsize({:?})))", kind); Ok(Some(AdjustDerefRef(AutoDerefRef { @@ -292,7 +286,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let ty = ty::mk_ptr(self.tcx(), ty::mt{ty: ty, mutbl: mt_b.mutbl}); - try!(self.get_ref().infcx.try(|_| sub.tys(ty, b))); + try!(self.fcx.infcx().try(|_| self.subtype(ty, b))); debug!("Success, coerced with AutoDerefRef(1, \ AutoPtr(AutoUnsize({:?})))", kind); Ok(Some(AdjustDerefRef(AutoDerefRef { @@ -310,7 +304,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { match self.unsize_ty(t_a, a, t_b) { Some((ty, kind)) => { let ty = ty::mk_uniq(self.tcx(), ty); - try!(self.get_ref().infcx.try(|_| sub.tys(ty, b))); + try!(self.fcx.infcx().try(|_| self.subtype(ty, b))); debug!("Success, coerced with AutoDerefRef(1, \ AutoUnsizeUniq({:?}))", kind); Ok(Some(AdjustDerefRef(AutoDerefRef { @@ -362,12 +356,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let ty_substs_b = substs_b.types.get_slice(subst::TypeSpace); assert!(ty_substs_a.len() == ty_substs_b.len()); - let sub = Sub(self.get_ref().clone()); - let mut result = None; let mut tps = ty_substs_a.iter().zip(ty_substs_b.iter()).enumerate(); for (i, (tp_a, tp_b)) in tps { - if self.get_ref().infcx.try(|_| sub.tys(*tp_a, *tp_b)).is_ok() { + if self.fcx.infcx().try(|_| self.subtype(*tp_a, *tp_b)).is_ok() { continue; } match @@ -380,7 +372,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let mut new_substs = substs_a.clone(); new_substs.types.get_mut_slice(subst::TypeSpace)[i] = new_tp; let ty = ty::mk_struct(tcx, did_a, tcx.mk_substs(new_substs)); - if self.get_ref().infcx.try(|_| sub.tys(ty, ty_b)).is_err() { + if self.fcx.infcx().try(|_| self.subtype(ty, ty_b)).is_err() { debug!("Unsized type parameter '{}', but still \ could not match types {} and {}", ppaux::ty_to_string(tcx, *tp_a), @@ -416,8 +408,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { a.repr(tcx), b.repr(tcx), b_mutbl); - let coercion = Coercion(self.get_ref().trace.clone()); - let r_a = self.get_ref().infcx.next_region_var(coercion); + let coercion = Coercion(self.trace.clone()); + let r_a = self.fcx.infcx().next_region_var(coercion); self.coerce_object(a, b, b_mutbl, |tr| ty::mk_rptr(tcx, tcx.mk_region(r_a), @@ -501,11 +493,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }) } - pub fn coerce_unsafe_ptr(&self, - a: Ty<'tcx>, - b: Ty<'tcx>, - mutbl_b: ast::Mutability) - -> CoerceResult<'tcx> { + fn coerce_unsafe_ptr(&self, + a: Ty<'tcx>, + b: Ty<'tcx>, + mutbl_b: ast::Mutability) + -> CoerceResult<'tcx> { debug!("coerce_unsafe_ptr(a={}, b={})", a.repr(self.tcx()), b.repr(self.tcx())); @@ -534,21 +526,25 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } } -pub type CoerceResult<'tcx> = cres<'tcx, Option<ty::AutoAdjustment<'tcx>>>; - -pub fn mk_coercety<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, - a_is_expected: bool, - origin: TypeOrigin, +pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, + expr: &ast::Expr, a: Ty<'tcx>, b: Ty<'tcx>) - -> CoerceResult<'tcx> { - debug!("mk_coercety({} -> {})", a.repr(cx.tcx), b.repr(cx.tcx)); - indent(|| { - cx.commit_if_ok(|| { - let trace = TypeTrace::types(origin, a_is_expected, a, b); - Coerce(cx.combine_fields(a_is_expected, trace)).tys(a, b) + -> cres<'tcx, ()> { + debug!("mk_assignty({} -> {})", a.repr(fcx.tcx()), b.repr(fcx.tcx())); + let adjustment = try!(indent(|| { + fcx.infcx().commit_if_ok(|| { + let origin = infer::ExprAssignable(expr.span); + Coerce { + fcx: fcx, + trace: infer::TypeTrace::types(origin, false, a, b) + }.coerce(a, b) }) - }) + })); + if let Some(adjustment) = adjustment { + fcx.write_adjustment(expr.id, expr.span, adjustment); + } + Ok(()) } fn can_coerce_mutbls(from_mutbl: ast::Mutability, diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 8188835718c..6f2d0cb3667 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -9,7 +9,7 @@ // except according to those terms. -use check::FnCtxt; +use check::{coercion, FnCtxt}; use middle::ty::{self, Ty}; use middle::infer; @@ -62,7 +62,7 @@ pub fn coerce<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, expr_ty.repr(fcx.ccx.tcx)); let expr_ty = fcx.resolve_type_vars_if_possible(expr_ty); let expected = fcx.resolve_type_vars_if_possible(expected); - match fcx.mk_assignty(expr, expr_ty, expected) { + match coercion::mk_assignty(fcx, expr, expr_ty, expected) { Ok(()) => { /* ok */ } Err(ref err) => { fcx.report_mismatched_types(sp, expected, expr_ty, err); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 799c7a355b7..8d1a43cb081 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1726,24 +1726,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup) } - pub fn mk_assignty(&self, - expr: &ast::Expr, - sub: Ty<'tcx>, - sup: Ty<'tcx>) - -> Result<(), ty::type_err<'tcx>> { - match try!(coercion::mk_coercety(self.infcx(), - false, - infer::ExprAssignable(expr.span), - sub, - sup)) { - None => {} - Some(adjustment) => { - self.write_adjustment(expr.id, expr.span, adjustment); - } - } - Ok(()) - } - pub fn mk_eqty(&self, a_is_expected: bool, origin: infer::TypeOrigin, |
