rustc: use Ty instead of passing ty::sty around.
This commit is contained in:
parent
1c2df5cc3c
commit
e0d44386d3
@ -55,7 +55,103 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
|
||||
None => {}
|
||||
}
|
||||
let pos = w.tell().unwrap();
|
||||
enc_sty(w, cx, &t.sty);
|
||||
|
||||
match t.sty {
|
||||
ty::ty_bool => mywrite!(w, "b"),
|
||||
ty::ty_char => mywrite!(w, "c"),
|
||||
ty::ty_int(t) => {
|
||||
match t {
|
||||
ast::TyI => mywrite!(w, "i"),
|
||||
ast::TyI8 => mywrite!(w, "MB"),
|
||||
ast::TyI16 => mywrite!(w, "MW"),
|
||||
ast::TyI32 => mywrite!(w, "ML"),
|
||||
ast::TyI64 => mywrite!(w, "MD")
|
||||
}
|
||||
}
|
||||
ty::ty_uint(t) => {
|
||||
match t {
|
||||
ast::TyU => mywrite!(w, "u"),
|
||||
ast::TyU8 => mywrite!(w, "Mb"),
|
||||
ast::TyU16 => mywrite!(w, "Mw"),
|
||||
ast::TyU32 => mywrite!(w, "Ml"),
|
||||
ast::TyU64 => mywrite!(w, "Md")
|
||||
}
|
||||
}
|
||||
ty::ty_float(t) => {
|
||||
match t {
|
||||
ast::TyF32 => mywrite!(w, "Mf"),
|
||||
ast::TyF64 => mywrite!(w, "MF"),
|
||||
}
|
||||
}
|
||||
ty::ty_enum(def, ref substs) => {
|
||||
mywrite!(w, "t[{}|", (cx.ds)(def));
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait { ref principal,
|
||||
ref bounds }) => {
|
||||
mywrite!(w, "x[");
|
||||
enc_trait_ref(w, cx, &principal.0);
|
||||
enc_existential_bounds(w, cx, bounds);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_tup(ref ts) => {
|
||||
mywrite!(w, "T[");
|
||||
for t in ts.iter() { enc_ty(w, cx, *t); }
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
|
||||
ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
|
||||
ty::ty_rptr(r, mt) => {
|
||||
mywrite!(w, "&");
|
||||
enc_region(w, cx, r);
|
||||
enc_mt(w, cx, mt);
|
||||
}
|
||||
ty::ty_vec(t, sz) => {
|
||||
mywrite!(w, "V");
|
||||
enc_ty(w, cx, t);
|
||||
mywrite!(w, "/");
|
||||
match sz {
|
||||
Some(n) => mywrite!(w, "{}|", n),
|
||||
None => mywrite!(w, "|"),
|
||||
}
|
||||
}
|
||||
ty::ty_str => {
|
||||
mywrite!(w, "v");
|
||||
}
|
||||
ty::ty_closure(ref f) => {
|
||||
mywrite!(w, "f");
|
||||
enc_closure_ty(w, cx, &**f);
|
||||
}
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
mywrite!(w, "F");
|
||||
enc_bare_fn_ty(w, cx, f);
|
||||
}
|
||||
ty::ty_infer(_) => {
|
||||
cx.diag.handler().bug("cannot encode inference variable types");
|
||||
}
|
||||
ty::ty_param(ParamTy {space, idx: id, def_id: did}) => {
|
||||
mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint())
|
||||
}
|
||||
ty::ty_struct(def, ref substs) => {
|
||||
mywrite!(w, "a[{}|", (cx.ds)(def));
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_unboxed_closure(def, region, ref substs) => {
|
||||
mywrite!(w, "k[{}|", (cx.ds)(def));
|
||||
enc_region(w, cx, region);
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_err => {
|
||||
mywrite!(w, "e");
|
||||
}
|
||||
ty::ty_open(_) => {
|
||||
cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
|
||||
}
|
||||
}
|
||||
|
||||
let end = w.tell().unwrap();
|
||||
let len = end - pos;
|
||||
fn estimate_sz(u: u64) -> u64 {
|
||||
@ -214,105 +310,6 @@ pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore)
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
||||
st: &ty::sty<'tcx>) {
|
||||
match *st {
|
||||
ty::ty_bool => mywrite!(w, "b"),
|
||||
ty::ty_char => mywrite!(w, "c"),
|
||||
ty::ty_int(t) => {
|
||||
match t {
|
||||
ast::TyI => mywrite!(w, "i"),
|
||||
ast::TyI8 => mywrite!(w, "MB"),
|
||||
ast::TyI16 => mywrite!(w, "MW"),
|
||||
ast::TyI32 => mywrite!(w, "ML"),
|
||||
ast::TyI64 => mywrite!(w, "MD")
|
||||
}
|
||||
}
|
||||
ty::ty_uint(t) => {
|
||||
match t {
|
||||
ast::TyU => mywrite!(w, "u"),
|
||||
ast::TyU8 => mywrite!(w, "Mb"),
|
||||
ast::TyU16 => mywrite!(w, "Mw"),
|
||||
ast::TyU32 => mywrite!(w, "Ml"),
|
||||
ast::TyU64 => mywrite!(w, "Md")
|
||||
}
|
||||
}
|
||||
ty::ty_float(t) => {
|
||||
match t {
|
||||
ast::TyF32 => mywrite!(w, "Mf"),
|
||||
ast::TyF64 => mywrite!(w, "MF"),
|
||||
}
|
||||
}
|
||||
ty::ty_enum(def, ref substs) => {
|
||||
mywrite!(w, "t[{}|", (cx.ds)(def));
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait { ref principal,
|
||||
ref bounds }) => {
|
||||
mywrite!(w, "x[");
|
||||
enc_trait_ref(w, cx, &principal.0);
|
||||
enc_existential_bounds(w, cx, bounds);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_tup(ref ts) => {
|
||||
mywrite!(w, "T[");
|
||||
for t in ts.iter() { enc_ty(w, cx, *t); }
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
|
||||
ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
|
||||
ty::ty_rptr(r, mt) => {
|
||||
mywrite!(w, "&");
|
||||
enc_region(w, cx, r);
|
||||
enc_mt(w, cx, mt);
|
||||
}
|
||||
ty::ty_vec(t, sz) => {
|
||||
mywrite!(w, "V");
|
||||
enc_ty(w, cx, t);
|
||||
mywrite!(w, "/");
|
||||
match sz {
|
||||
Some(n) => mywrite!(w, "{}|", n),
|
||||
None => mywrite!(w, "|"),
|
||||
}
|
||||
}
|
||||
ty::ty_str => {
|
||||
mywrite!(w, "v");
|
||||
}
|
||||
ty::ty_closure(ref f) => {
|
||||
mywrite!(w, "f");
|
||||
enc_closure_ty(w, cx, &**f);
|
||||
}
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
mywrite!(w, "F");
|
||||
enc_bare_fn_ty(w, cx, f);
|
||||
}
|
||||
ty::ty_infer(_) => {
|
||||
cx.diag.handler().bug("cannot encode inference variable types");
|
||||
}
|
||||
ty::ty_param(ParamTy {space, idx: id, def_id: did}) => {
|
||||
mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint())
|
||||
}
|
||||
ty::ty_struct(def, ref substs) => {
|
||||
mywrite!(w, "a[{}|", (cx.ds)(def));
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_unboxed_closure(def, region, ref substs) => {
|
||||
mywrite!(w, "k[{}|", (cx.ds)(def));
|
||||
enc_region(w, cx, region);
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_err => {
|
||||
mywrite!(w, "e");
|
||||
}
|
||||
ty::ty_open(_) => {
|
||||
cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
|
||||
match p {
|
||||
ast::Unsafety::Normal => mywrite!(w, "n"),
|
||||
|
@ -90,8 +90,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
// Consider coercing the subtype to a DST
|
||||
let unsize = self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_unsized(a, sty_a, b)
|
||||
let unsize = self.unpack_actual_value(a, |a| {
|
||||
self.coerce_unsized(a, b)
|
||||
});
|
||||
if unsize.is_ok() {
|
||||
return unsize;
|
||||
@ -105,14 +105,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
ty::ty_ptr(mt_b) => {
|
||||
match mt_b.ty.sty {
|
||||
ty::ty_str => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_unsafe_ptr(a, sty_a, b, ast::MutImmutable)
|
||||
return self.unpack_actual_value(a, |a| {
|
||||
self.coerce_unsafe_ptr(a, b, ast::MutImmutable)
|
||||
});
|
||||
}
|
||||
|
||||
ty::ty_trait(..) => {
|
||||
let result = self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_unsafe_object(a, sty_a, b, mt_b.mutbl)
|
||||
let result = self.unpack_actual_value(a, |a| {
|
||||
self.coerce_unsafe_object(a, b, mt_b.mutbl)
|
||||
});
|
||||
|
||||
match result {
|
||||
@ -122,8 +122,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
|
||||
_ => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_unsafe_ptr(a, sty_a, b, mt_b.mutbl)
|
||||
return self.unpack_actual_value(a, |a| {
|
||||
self.coerce_unsafe_ptr(a, b, mt_b.mutbl)
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -132,14 +132,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
ty::ty_rptr(_, mt_b) => {
|
||||
match mt_b.ty.sty {
|
||||
ty::ty_str => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_pointer(a, sty_a, b, ast::MutImmutable)
|
||||
return self.unpack_actual_value(a, |a| {
|
||||
self.coerce_borrowed_pointer(a, b, ast::MutImmutable)
|
||||
});
|
||||
}
|
||||
|
||||
ty::ty_trait(..) => {
|
||||
let result = self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl)
|
||||
let result = self.unpack_actual_value(a, |a| {
|
||||
self.coerce_borrowed_object(a, b, mt_b.mutbl)
|
||||
});
|
||||
|
||||
match result {
|
||||
@ -149,8 +149,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
|
||||
_ => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_pointer(a, sty_a, b, mt_b.mutbl)
|
||||
return self.unpack_actual_value(a, |a| {
|
||||
self.coerce_borrowed_pointer(a, b, mt_b.mutbl)
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -160,16 +160,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
store: ty::RegionTraitStore(..),
|
||||
..
|
||||
}) => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_fn(a, sty_a, b)
|
||||
return self.unpack_actual_value(a, |a| {
|
||||
self.coerce_borrowed_fn(a, b)
|
||||
});
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.unpack_actual_value(a, |sty_a| {
|
||||
match *sty_a {
|
||||
self.unpack_actual_value(a, |a| {
|
||||
match a.sty {
|
||||
ty::ty_bare_fn(ref a_f) => {
|
||||
// Bare functions are coercible to any closure type.
|
||||
//
|
||||
@ -194,20 +194,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
|
||||
F: FnOnce(&ty::sty<'tcx>) -> T,
|
||||
F: FnOnce(Ty<'tcx>) -> T,
|
||||
{
|
||||
f(&self.get_ref().infcx.shallow_resolve(a).sty)
|
||||
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>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
mutbl_b: ast::Mutability)
|
||||
-> CoerceResult<'tcx> {
|
||||
debug!("coerce_borrowed_pointer(a={}, sty_a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx), sty_a,
|
||||
debug!("coerce_borrowed_pointer(a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx),
|
||||
b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
// If we have a parameter of type `&M T_a` and the value
|
||||
@ -220,7 +219,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
let coercion = Coercion(self.get_ref().trace.clone());
|
||||
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
|
||||
|
||||
let inner_ty = match *sty_a {
|
||||
let inner_ty = match a.sty {
|
||||
ty::ty_uniq(_) => return Err(ty::terr_mismatch),
|
||||
ty::ty_rptr(_, mt_a) => mt_a.ty,
|
||||
_ => {
|
||||
@ -245,11 +244,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// or &Concrete -> &Trait, etc.
|
||||
fn coerce_unsized(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> CoerceResult<'tcx> {
|
||||
debug!("coerce_unsized(a={}, sty_a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx), sty_a,
|
||||
debug!("coerce_unsized(a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx),
|
||||
b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
// Note, we want to avoid unnecessary unsizing. We don't want to coerce to
|
||||
@ -259,11 +257,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
let sub = Sub(self.get_ref().clone());
|
||||
|
||||
let sty_b = &b.sty;
|
||||
match (sty_a, sty_b) {
|
||||
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, |sty_a| {
|
||||
match self.unsize_ty(t_a, sty_a, mt_b.ty) {
|
||||
self.unpack_actual_value(t_a, |a| {
|
||||
match self.unsize_ty(t_a, a, mt_b.ty) {
|
||||
Some((ty, kind)) => {
|
||||
if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
|
||||
return Err(ty::terr_mutability);
|
||||
@ -288,8 +285,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
})
|
||||
}
|
||||
(&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_ptr(mt_b)) => {
|
||||
self.unpack_actual_value(t_a, |sty_a| {
|
||||
match self.unsize_ty(t_a, sty_a, mt_b.ty) {
|
||||
self.unpack_actual_value(t_a, |a| {
|
||||
match self.unsize_ty(t_a, a, mt_b.ty) {
|
||||
Some((ty, kind)) => {
|
||||
if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
|
||||
return Err(ty::terr_mutability);
|
||||
@ -311,8 +308,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
})
|
||||
}
|
||||
(&ty::ty_uniq(t_a), &ty::ty_uniq(t_b)) => {
|
||||
self.unpack_actual_value(t_a, |sty_a| {
|
||||
match self.unsize_ty(t_a, sty_a, t_b) {
|
||||
self.unpack_actual_value(t_a, |a| {
|
||||
match self.unsize_ty(t_a, a, t_b) {
|
||||
Some((ty, kind)) => {
|
||||
let ty = ty::mk_uniq(self.get_ref().infcx.tcx, ty);
|
||||
try!(self.get_ref().infcx.try(|_| sub.tys(ty, b)));
|
||||
@ -336,15 +333,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// E.g., `[T, ..n]` -> `([T], UnsizeLength(n))`
|
||||
fn unsize_ty(&self,
|
||||
ty_a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
ty_b: Ty<'tcx>)
|
||||
-> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> {
|
||||
debug!("unsize_ty(sty_a={}, ty_b={})", sty_a, ty_b.repr(self.get_ref().infcx.tcx));
|
||||
debug!("unsize_ty(a={}, ty_b={})", a, ty_b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
let tcx = self.get_ref().infcx.tcx;
|
||||
|
||||
self.unpack_actual_value(ty_b, |sty_b|
|
||||
match (sty_a, sty_b) {
|
||||
self.unpack_actual_value(ty_b, |b|
|
||||
match (&a.sty, &b.sty) {
|
||||
(&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => {
|
||||
let ty = ty::mk_vec(tcx, t_a, None);
|
||||
Some((ty, ty::UnsizeLength(len)))
|
||||
@ -412,44 +409,41 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
fn coerce_borrowed_object(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
b_mutbl: ast::Mutability) -> CoerceResult<'tcx>
|
||||
{
|
||||
let tcx = self.get_ref().infcx.tcx;
|
||||
|
||||
debug!("coerce_borrowed_object(a={}, sty_a={}, b={}, b_mutbl={})",
|
||||
a.repr(tcx), sty_a,
|
||||
debug!("coerce_borrowed_object(a={}, b={}, b_mutbl={})",
|
||||
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);
|
||||
|
||||
self.coerce_object(a, sty_a, b, b_mutbl,
|
||||
self.coerce_object(a, b, b_mutbl,
|
||||
|tr| ty::mk_rptr(tcx, r_a, ty::mt{ mutbl: b_mutbl, ty: tr }),
|
||||
|| AutoPtr(r_a, b_mutbl, None))
|
||||
}
|
||||
|
||||
fn coerce_unsafe_object(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
b_mutbl: ast::Mutability) -> CoerceResult<'tcx>
|
||||
{
|
||||
let tcx = self.get_ref().infcx.tcx;
|
||||
|
||||
debug!("coerce_unsafe_object(a={}, sty_a={}, b={}, b_mutbl={})",
|
||||
a.repr(tcx), sty_a,
|
||||
debug!("coerce_unsafe_object(a={}, b={}, b_mutbl={})",
|
||||
a.repr(tcx),
|
||||
b.repr(tcx), b_mutbl);
|
||||
|
||||
self.coerce_object(a, sty_a, b, b_mutbl,
|
||||
self.coerce_object(a, b, b_mutbl,
|
||||
|tr| ty::mk_ptr(tcx, ty::mt{ mutbl: b_mutbl, ty: tr }),
|
||||
|| AutoUnsafe(b_mutbl, None))
|
||||
}
|
||||
|
||||
fn coerce_object<F, G>(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
b_mutbl: ast::Mutability,
|
||||
mk_ty: F,
|
||||
@ -459,7 +453,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
{
|
||||
let tcx = self.get_ref().infcx.tcx;
|
||||
|
||||
match *sty_a {
|
||||
match a.sty {
|
||||
ty::ty_rptr(_, ty::mt{ty, mutbl}) => match ty.sty {
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
|
||||
debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl);
|
||||
@ -483,14 +477,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
pub fn coerce_borrowed_fn(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> CoerceResult<'tcx> {
|
||||
debug!("coerce_borrowed_fn(a={}, sty_a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx), sty_a,
|
||||
debug!("coerce_borrowed_fn(a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx),
|
||||
b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
match *sty_a {
|
||||
match a.sty {
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
self.coerce_from_bare_fn(a, f, b)
|
||||
}
|
||||
@ -504,7 +497,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
/// `proc`.
|
||||
fn coerce_from_bare_fn(&self, a: Ty<'tcx>, fn_ty_a: &ty::BareFnTy<'tcx>, b: Ty<'tcx>)
|
||||
-> CoerceResult<'tcx> {
|
||||
self.unpack_actual_value(b, |sty_b| {
|
||||
self.unpack_actual_value(b, |b| {
|
||||
|
||||
debug!("coerce_from_bare_fn(a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx));
|
||||
@ -513,7 +506,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
return self.subtype(a, b);
|
||||
}
|
||||
|
||||
let fn_ty_b = match *sty_b {
|
||||
let fn_ty_b = match b.sty {
|
||||
ty::ty_closure(ref f) => (*f).clone(),
|
||||
_ => return self.subtype(a, b)
|
||||
};
|
||||
@ -531,15 +524,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
pub fn coerce_unsafe_ptr(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
mutbl_b: ast::Mutability)
|
||||
-> CoerceResult<'tcx> {
|
||||
debug!("coerce_unsafe_ptr(a={}, sty_a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx), sty_a,
|
||||
debug!("coerce_unsafe_ptr(a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx),
|
||||
b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
let mt_a = match *sty_a {
|
||||
let mt_a = match a.sty {
|
||||
ty::ty_rptr(_, mt) | ty::ty_ptr(mt) => mt,
|
||||
_ => {
|
||||
return self.subtype(a, b);
|
||||
|
@ -82,10 +82,6 @@ pub trait TypeFolder<'tcx> {
|
||||
super_fold_trait_ref(self, t)
|
||||
}
|
||||
|
||||
fn fold_sty(&mut self, sty: &ty::sty<'tcx>) -> ty::sty<'tcx> {
|
||||
super_fold_sty(self, sty)
|
||||
}
|
||||
|
||||
fn fold_substs(&mut self,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> subst::Substs<'tcx> {
|
||||
@ -260,12 +256,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::sty<'tcx> {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::sty<'tcx> {
|
||||
folder.fold_sty(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::TraitRef<'tcx> {
|
||||
folder.fold_trait_ref(self)
|
||||
@ -521,9 +511,55 @@ impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
|
||||
// They should invoke `foo.fold_with()` to do recursive folding.
|
||||
|
||||
pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
t: Ty<'tcx>)
|
||||
ty: Ty<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
let sty = t.sty.fold_with(this);
|
||||
let sty = match ty.sty {
|
||||
ty::ty_uniq(typ) => {
|
||||
ty::ty_uniq(typ.fold_with(this))
|
||||
}
|
||||
ty::ty_ptr(ref tm) => {
|
||||
ty::ty_ptr(tm.fold_with(this))
|
||||
}
|
||||
ty::ty_vec(typ, sz) => {
|
||||
ty::ty_vec(typ.fold_with(this), sz)
|
||||
}
|
||||
ty::ty_open(typ) => {
|
||||
ty::ty_open(typ.fold_with(this))
|
||||
}
|
||||
ty::ty_enum(tid, ref substs) => {
|
||||
ty::ty_enum(tid, substs.fold_with(this))
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
principal: (*principal).fold_with(this),
|
||||
bounds: bounds.fold_with(this),
|
||||
})
|
||||
}
|
||||
ty::ty_tup(ref ts) => {
|
||||
ty::ty_tup(ts.fold_with(this))
|
||||
}
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
ty::ty_bare_fn(f.fold_with(this))
|
||||
}
|
||||
ty::ty_closure(ref f) => {
|
||||
ty::ty_closure(box f.fold_with(this))
|
||||
}
|
||||
ty::ty_rptr(r, ref tm) => {
|
||||
ty::ty_rptr(r.fold_with(this), tm.fold_with(this))
|
||||
}
|
||||
ty::ty_struct(did, ref substs) => {
|
||||
ty::ty_struct(did, substs.fold_with(this))
|
||||
}
|
||||
ty::ty_unboxed_closure(did, ref region, ref substs) => {
|
||||
ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this))
|
||||
}
|
||||
ty::ty_bool | ty::ty_char | ty::ty_str |
|
||||
ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
|
||||
ty::ty_err | ty::ty_infer(_) |
|
||||
ty::ty_param(..) => {
|
||||
ty.sty.clone()
|
||||
}
|
||||
};
|
||||
ty::mk_t(this.tcx(), sty)
|
||||
}
|
||||
|
||||
@ -601,58 +637,6 @@ pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
mutbl: mt.mutbl}
|
||||
}
|
||||
|
||||
pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
sty: &ty::sty<'tcx>)
|
||||
-> ty::sty<'tcx> {
|
||||
match *sty {
|
||||
ty::ty_uniq(typ) => {
|
||||
ty::ty_uniq(typ.fold_with(this))
|
||||
}
|
||||
ty::ty_ptr(ref tm) => {
|
||||
ty::ty_ptr(tm.fold_with(this))
|
||||
}
|
||||
ty::ty_vec(typ, sz) => {
|
||||
ty::ty_vec(typ.fold_with(this), sz)
|
||||
}
|
||||
ty::ty_open(typ) => {
|
||||
ty::ty_open(typ.fold_with(this))
|
||||
}
|
||||
ty::ty_enum(tid, ref substs) => {
|
||||
ty::ty_enum(tid, substs.fold_with(this))
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
principal: (*principal).fold_with(this),
|
||||
bounds: bounds.fold_with(this),
|
||||
})
|
||||
}
|
||||
ty::ty_tup(ref ts) => {
|
||||
ty::ty_tup(ts.fold_with(this))
|
||||
}
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
ty::ty_bare_fn(f.fold_with(this))
|
||||
}
|
||||
ty::ty_closure(ref f) => {
|
||||
ty::ty_closure(box f.fold_with(this))
|
||||
}
|
||||
ty::ty_rptr(r, ref tm) => {
|
||||
ty::ty_rptr(r.fold_with(this), tm.fold_with(this))
|
||||
}
|
||||
ty::ty_struct(did, ref substs) => {
|
||||
ty::ty_struct(did, substs.fold_with(this))
|
||||
}
|
||||
ty::ty_unboxed_closure(did, ref region, ref substs) => {
|
||||
ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this))
|
||||
}
|
||||
ty::ty_bool | ty::ty_char | ty::ty_str |
|
||||
ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
|
||||
ty::ty_err | ty::ty_infer(_) |
|
||||
ty::ty_param(..) => {
|
||||
(*sty).clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_fold_trait_store<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
trait_store: ty::TraitStore)
|
||||
-> ty::TraitStore {
|
||||
|
@ -261,44 +261,43 @@ fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
// Find the expected input/output types (if any). Substitute
|
||||
// fresh bound regions for any bound regions we find in the
|
||||
// expected types so as to avoid capture.
|
||||
let expected_sty = expected.map_to_option(fcx, |x| Some((*x).clone()));
|
||||
let (expected_sig,
|
||||
expected_onceness,
|
||||
expected_bounds) = {
|
||||
match expected_sty {
|
||||
Some(ty::ty_closure(ref cenv)) => {
|
||||
let (sig, _) =
|
||||
ty::replace_late_bound_regions(
|
||||
tcx,
|
||||
&cenv.sig,
|
||||
|_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn));
|
||||
let onceness = match (&store, &cenv.store) {
|
||||
// As the closure type and onceness go, only three
|
||||
// combinations are legit:
|
||||
// once closure
|
||||
// many closure
|
||||
// once proc
|
||||
// If the actual and expected closure type disagree with
|
||||
// each other, set expected onceness to be always Once or
|
||||
// Many according to the actual type. Otherwise, it will
|
||||
// yield either an illegal "many proc" or a less known
|
||||
// "once closure" in the error message.
|
||||
(&ty::UniqTraitStore, &ty::UniqTraitStore) |
|
||||
(&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
|
||||
cenv.onceness,
|
||||
(&ty::UniqTraitStore, _) => ast::Once,
|
||||
(&ty::RegionTraitStore(..), _) => ast::Many,
|
||||
};
|
||||
(Some(sig), onceness, cenv.bounds)
|
||||
}
|
||||
_ => {
|
||||
// Not an error! Means we're inferring the closure type
|
||||
let region = fcx.infcx().next_region_var(
|
||||
infer::AddrOfRegion(expr.span));
|
||||
let bounds = ty::region_existential_bound(region);
|
||||
let onceness = ast::Many;
|
||||
(None, onceness, bounds)
|
||||
}
|
||||
let expected_cenv = expected.map_to_option(fcx, |ty| match ty.sty {
|
||||
ty::ty_closure(ref cenv) => Some(cenv),
|
||||
_ => None
|
||||
});
|
||||
let (expected_sig, expected_onceness, expected_bounds) = match expected_cenv {
|
||||
Some(cenv) => {
|
||||
let (sig, _) =
|
||||
ty::replace_late_bound_regions(
|
||||
tcx,
|
||||
&cenv.sig,
|
||||
|_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn));
|
||||
let onceness = match (&store, &cenv.store) {
|
||||
// As the closure type and onceness go, only three
|
||||
// combinations are legit:
|
||||
// once closure
|
||||
// many closure
|
||||
// once proc
|
||||
// If the actual and expected closure type disagree with
|
||||
// each other, set expected onceness to be always Once or
|
||||
// Many according to the actual type. Otherwise, it will
|
||||
// yield either an illegal "many proc" or a less known
|
||||
// "once closure" in the error message.
|
||||
(&ty::UniqTraitStore, &ty::UniqTraitStore) |
|
||||
(&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
|
||||
cenv.onceness,
|
||||
(&ty::UniqTraitStore, _) => ast::Once,
|
||||
(&ty::RegionTraitStore(..), _) => ast::Many,
|
||||
};
|
||||
(Some(sig), onceness, cenv.bounds)
|
||||
}
|
||||
_ => {
|
||||
// Not an error! Means we're inferring the closure type
|
||||
let region = fcx.infcx().next_region_var(
|
||||
infer::AddrOfRegion(expr.span));
|
||||
let bounds = ty::region_existential_bound(region);
|
||||
let onceness = ast::Many;
|
||||
(None, onceness, bounds)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2042,7 +2042,7 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
-> bool {
|
||||
// Bail out if the callee is a bare function or a closure. We check those
|
||||
// manually.
|
||||
match *structure_of(fcx, callee.span, callee_type) {
|
||||
match structurally_resolved_type(fcx, callee.span, callee_type).sty {
|
||||
ty::ty_bare_fn(_) | ty::ty_closure(_) => return false,
|
||||
_ => {}
|
||||
}
|
||||
@ -2717,10 +2717,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
ast::LitInt(_, ast::SignedIntLit(t, _)) => ty::mk_mach_int(t),
|
||||
ast::LitInt(_, ast::UnsignedIntLit(t)) => ty::mk_mach_uint(t),
|
||||
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
|
||||
let opt_ty = expected.map_to_option(fcx, |sty| {
|
||||
match *sty {
|
||||
ty::ty_int(i) => Some(ty::mk_mach_int(i)),
|
||||
ty::ty_uint(i) => Some(ty::mk_mach_uint(i)),
|
||||
let opt_ty = expected.map_to_option(fcx, |ty| {
|
||||
match ty.sty {
|
||||
ty::ty_int(_) | ty::ty_uint(_) => Some(ty),
|
||||
ty::ty_char => Some(ty::mk_mach_uint(ast::TyU8)),
|
||||
ty::ty_ptr(..) => Some(ty::mk_mach_uint(ast::TyU)),
|
||||
ty::ty_bare_fn(..) => Some(ty::mk_mach_uint(ast::TyU)),
|
||||
@ -2732,9 +2731,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
}
|
||||
ast::LitFloat(_, t) => ty::mk_mach_float(t),
|
||||
ast::LitFloatUnsuffixed(_) => {
|
||||
let opt_ty = expected.map_to_option(fcx, |sty| {
|
||||
match *sty {
|
||||
ty::ty_float(i) => Some(ty::mk_mach_float(i)),
|
||||
let opt_ty = expected.map_to_option(fcx, |ty| {
|
||||
match ty.sty {
|
||||
ty::ty_float(_) => Some(ty),
|
||||
_ => None
|
||||
}
|
||||
});
|
||||
@ -2910,7 +2909,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
let fn_ty = fcx.expr_ty(f);
|
||||
|
||||
// Extract the function signature from `in_fty`.
|
||||
let fn_sty = structure_of(fcx, f.span, fn_ty);
|
||||
let fn_ty = structurally_resolved_type(fcx, f.span, fn_ty);
|
||||
|
||||
// This is the "default" function signature, used in case of error.
|
||||
// In that case, we check each argument against "error" in order to
|
||||
@ -2921,7 +2920,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
variadic: false
|
||||
});
|
||||
|
||||
let fn_sig = match *fn_sty {
|
||||
let fn_sig = match fn_ty.sty {
|
||||
ty::ty_bare_fn(ty::BareFnTy {ref sig, ..}) |
|
||||
ty::ty_closure(box ty::ClosureTy {ref sig, ..}) => sig,
|
||||
_ => {
|
||||
@ -3655,9 +3654,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(unop, ref oprnd) => {
|
||||
let expected_inner = expected.map(fcx, |sty| {
|
||||
let expected_inner = expected.map(fcx, |ty| {
|
||||
match unop {
|
||||
ast::UnUniq => match *sty {
|
||||
ast::UnUniq => match ty.sty {
|
||||
ty::ty_uniq(ty) => {
|
||||
ExpectHasType(ty)
|
||||
}
|
||||
@ -3746,9 +3745,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
}
|
||||
ast::ExprAddrOf(mutbl, ref oprnd) => {
|
||||
let expected = expected.only_has_type();
|
||||
let hint = expected.map(fcx, |sty| {
|
||||
match *sty { ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty),
|
||||
_ => NoExpectation }
|
||||
let hint = expected.map(fcx, |ty| {
|
||||
match ty.sty {
|
||||
ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty),
|
||||
_ => NoExpectation
|
||||
}
|
||||
});
|
||||
let lvalue_pref = match mutbl {
|
||||
ast::MutMutable => PreferMutLvalue,
|
||||
@ -4037,9 +4038,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
}
|
||||
ast::ExprTup(ref elts) => {
|
||||
let expected = expected.only_has_type();
|
||||
let flds = expected.map_to_option(fcx, |sty| {
|
||||
match *sty {
|
||||
ty::ty_tup(ref flds) => Some((*flds).clone()),
|
||||
let flds = expected.map_to_option(fcx, |ty| {
|
||||
match ty.sty {
|
||||
ty::ty_tup(ref flds) => Some(flds[]),
|
||||
_ => None
|
||||
}
|
||||
});
|
||||
@ -4304,20 +4305,20 @@ impl<'tcx> Expectation<'tcx> {
|
||||
}
|
||||
|
||||
fn map<'a, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Expectation<'tcx> where
|
||||
F: FnOnce(&ty::sty<'tcx>) -> Expectation<'tcx>
|
||||
F: FnOnce(Ty<'tcx>) -> Expectation<'tcx>
|
||||
{
|
||||
match self.resolve(fcx) {
|
||||
NoExpectation => NoExpectation,
|
||||
ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
|
||||
ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option<O> where
|
||||
F: FnOnce(&ty::sty<'tcx>) -> Option<O>,
|
||||
F: FnOnce(Ty<'tcx>) -> Option<O>,
|
||||
{
|
||||
match self.resolve(fcx) {
|
||||
NoExpectation => None,
|
||||
ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
|
||||
ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5320,12 +5321,6 @@ pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
|
||||
ty
|
||||
}
|
||||
|
||||
// Returns the one-level-deep structure of the given type.
|
||||
pub fn structure_of<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, typ: Ty<'tcx>)
|
||||
-> &'tcx ty::sty<'tcx> {
|
||||
&structurally_resolved_type(fcx, sp, typ).sty
|
||||
}
|
||||
|
||||
// Returns true if b contains a break that can exit from b
|
||||
pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
|
||||
// First: is there an unlabeled break immediately
|
||||
|
@ -17,7 +17,7 @@ use middle::subst::{Subst};
|
||||
use middle::traits;
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::ty::liberate_late_bound_regions;
|
||||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||
use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std::collections::HashSet;
|
||||
@ -368,8 +368,8 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
|
||||
|
||||
self.binding_count -= 1;
|
||||
}
|
||||
ref sty => {
|
||||
self.fold_sty(sty);
|
||||
_ => {
|
||||
super_fold_ty(self, t);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user