提交 becbd81a 编写于 作者: N Niko Matsakis

Integrate projection bounds to `ExistentialBounds` but do not use them for anything.

上级 82787c22
......@@ -200,9 +200,9 @@ pub fn parse_bounds_data<'tcx>(data: &[u8], crate_num: ast::CrateNum,
parse_bounds(&mut st, conv)
}
pub fn parse_existential_bounds_data(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt, conv: conv_did)
-> ty::ExistentialBounds {
pub fn parse_existential_bounds_data<'tcx>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: conv_did)
-> ty::ExistentialBounds<'tcx> {
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_existential_bounds(&mut st, conv)
}
......@@ -744,10 +744,18 @@ fn parse_type_param_def<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
}
}
fn parse_existential_bounds(st: &mut PState, conv: conv_did) -> ty::ExistentialBounds {
let r = parse_region(st, |x,y| conv(x,y));
let bb = parse_builtin_bounds(st, conv);
return ty::ExistentialBounds { region_bound: r, builtin_bounds: bb };
fn parse_existential_bounds<'a,'tcx>(st: &mut PState<'a,'tcx>,
conv: conv_did)
-> ty::ExistentialBounds<'tcx>
{
let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
parse_bounds(st, conv);
assert_eq!(region_bounds.len(), 1);
assert_eq!(trait_bounds.len(), 0);
let region_bound = region_bounds.pop().unwrap();
return ty::ExistentialBounds { region_bound: region_bound,
builtin_bounds: builtin_bounds,
projection_bounds: projection_bounds };
}
fn parse_builtin_bounds(st: &mut PState, _conv: conv_did) -> ty::BuiltinBounds {
......
......@@ -392,9 +392,14 @@ pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::Builti
mywrite!(w, ".");
}
pub fn enc_existential_bounds(w: &mut SeekableMemWriter, cx: &ctxt, bs: &ty::ExistentialBounds) {
enc_region(w, cx, bs.region_bound);
enc_builtin_bounds(w, cx, &bs.builtin_bounds);
pub fn enc_existential_bounds<'a,'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a,'tcx>,
bs: &ty::ExistentialBounds<'tcx>) {
let param_bounds = ty::ParamBounds { trait_bounds: vec!(),
region_bounds: vec!(bs.region_bound),
builtin_bounds: bs.builtin_bounds,
projection_bounds: bs.projection_bounds.clone() };
enc_bounds(w, cx, &param_bounds);
}
pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
......
......@@ -842,7 +842,8 @@ fn emit_type_scheme<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
type_scheme: ty::TypeScheme<'tcx>);
fn emit_substs<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
substs: &subst::Substs<'tcx>);
fn emit_existential_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::ExistentialBounds);
fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
bounds: &ty::ExistentialBounds<'tcx>);
fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds);
fn emit_auto_adjustment<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
adj: &ty::AutoAdjustment<'tcx>);
......@@ -982,7 +983,8 @@ fn emit_type_scheme<'b>(&mut self,
});
}
fn emit_existential_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::ExistentialBounds) {
fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
bounds: &ty::ExistentialBounds<'tcx>) {
self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this.writer,
&ecx.ty_str_ctxt(),
bounds)));
......@@ -1372,7 +1374,7 @@ fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
fn read_type_scheme<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::TypeScheme<'tcx>;
fn read_existential_bounds<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::ExistentialBounds;
-> ty::ExistentialBounds<'tcx>;
fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> subst::Substs<'tcx>;
fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
......@@ -1626,7 +1628,7 @@ fn read_type_scheme<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
}
fn read_existential_bounds<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::ExistentialBounds
-> ty::ExistentialBounds<'tcx>
{
self.read_opaque(|this, doc| {
Ok(tydecode::parse_existential_bounds_data(doc.data,
......
......@@ -351,11 +351,11 @@ fn unsize_ty(&self,
(&ty::ty_trait(..), &ty::ty_trait(..)) => {
None
}
(_, &ty::ty_trait(box ty::TyTrait { ref principal, bounds })) => {
(_, &ty::ty_trait(box ty::TyTrait { ref principal, ref bounds })) => {
// FIXME what is the purpose of `ty`?
let ty = ty::mk_trait(tcx, principal.clone(), bounds);
Some((ty, ty::UnsizeVtable(ty::TyTrait { principal: (*principal).clone(),
bounds: bounds },
let ty = ty::mk_trait(tcx, principal.clone(), bounds.clone());
Some((ty, ty::UnsizeVtable(ty::TyTrait { principal: principal.clone(),
bounds: bounds.clone() },
ty_a)))
}
(&ty::ty_struct(did_a, substs_a), &ty::ty_struct(did_b, substs_b))
......@@ -458,10 +458,9 @@ fn coerce_object<F, G>(&self,
match a.sty {
ty::ty_rptr(_, ty::mt{ty, mutbl}) => match ty.sty {
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl);
// FIXME what is purpose of this type `tr`?
let tr = ty::mk_trait(tcx, principal.clone(), bounds);
let tr = ty::mk_trait(tcx, principal.clone(), bounds.clone());
try!(self.subtype(mk_ty(tr), b));
Ok(Some(AdjustDerefRef(AutoDerefRef {
autoderefs: 1,
......
......@@ -222,7 +222,7 @@ fn closure_tys(&self, a: &ty::ClosureTy<'tcx>,
};
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
let onceness = try!(self.oncenesses(a.onceness, b.onceness));
let bounds = try!(self.existential_bounds(a.bounds, b.bounds));
let bounds = try!(self.existential_bounds(&a.bounds, &b.bounds));
let sig = try!(self.binders(&a.sig, &b.sig));
let abi = try!(self.abi(a.abi, b.abi));
Ok(ty::ClosureTy {
......@@ -289,15 +289,61 @@ fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres<'tcx, abi::Abi> {
fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness>;
fn projection_tys(&self,
a: &ty::ProjectionTy<'tcx>,
b: &ty::ProjectionTy<'tcx>)
-> cres<'tcx, ty::ProjectionTy<'tcx>>
{
if a.item_name != b.item_name {
Err(ty::terr_projection_name_mismatched(
expected_found(self, a.item_name, b.item_name)))
} else {
let trait_ref = try!(self.trait_refs(&*a.trait_ref, &*b.trait_ref));
Ok(ty::ProjectionTy { trait_ref: Rc::new(trait_ref), item_name: a.item_name })
}
}
fn projection_predicates(&self,
a: &ty::ProjectionPredicate<'tcx>,
b: &ty::ProjectionPredicate<'tcx>)
-> cres<'tcx, ty::ProjectionPredicate<'tcx>>
{
let projection_ty = try!(self.projection_tys(&a.projection_ty, &b.projection_ty));
let ty = try!(self.tys(a.ty, b.ty));
Ok(ty::ProjectionPredicate { projection_ty: projection_ty, ty: ty })
}
fn projection_bounds(&self,
a: &Vec<ty::PolyProjectionPredicate<'tcx>>,
b: &Vec<ty::PolyProjectionPredicate<'tcx>>)
-> cres<'tcx, Vec<ty::PolyProjectionPredicate<'tcx>>>
{
// To be compatible, `a` and `b` must be for precisely the
// same set of traits and item names. We always require that
// projection bounds lists are sorted by trait-def-id and item-name,
// so we can just iterate through the lists pairwise, so long as they are the
// same length.
if a.len() != b.len() {
Err(ty::terr_projection_bounds_length(expected_found(self, a.len(), b.len())))
} else {
a.iter()
.zip(b.iter())
.map(|(a, b)| self.binders(a, b))
.collect()
}
}
fn existential_bounds(&self,
a: ty::ExistentialBounds,
b: ty::ExistentialBounds)
-> cres<'tcx, ty::ExistentialBounds>
a: &ty::ExistentialBounds<'tcx>,
b: &ty::ExistentialBounds<'tcx>)
-> cres<'tcx, ty::ExistentialBounds<'tcx>>
{
let r = try!(self.contraregions(a.region_bound, b.region_bound));
let nb = try!(self.builtin_bounds(a.builtin_bounds, b.builtin_bounds));
let pb = try!(self.projection_bounds(&a.projection_bounds, &b.projection_bounds));
Ok(ty::ExistentialBounds { region_bound: r,
builtin_bounds: nb })
builtin_bounds: nb,
projection_bounds: pb })
}
fn builtin_bounds(&self,
......@@ -381,6 +427,16 @@ fn combine<C:Combine<'tcx>>(combiner: &C,
}
}
impl<'tcx> Combineable<'tcx> for ty::ProjectionPredicate<'tcx> {
fn combine<C:Combine<'tcx>>(combiner: &C,
a: &ty::ProjectionPredicate<'tcx>,
b: &ty::ProjectionPredicate<'tcx>)
-> cres<'tcx, ty::ProjectionPredicate<'tcx>>
{
combiner.projection_predicates(a, b)
}
}
impl<'tcx> Combineable<'tcx> for ty::FnSig<'tcx> {
fn combine<C:Combine<'tcx>>(combiner: &C,
a: &ty::FnSig<'tcx>,
......@@ -496,7 +552,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
&ty::ty_trait(ref b_)) => {
debug!("Trying to match traits {} and {}", a, b);
let principal = try!(this.binders(&a_.principal, &b_.principal));
let bounds = try!(this.existential_bounds(a_.bounds, b_.bounds));
let bounds = try!(this.existential_bounds(&a_.bounds, &b_.bounds));
Ok(ty::mk_trait(tcx, principal, bounds))
}
......@@ -595,12 +651,8 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
}
(&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) => {
if a_data.item_name == b_data.item_name {
let trait_ref = try!(this.trait_refs(&*a_data.trait_ref, &*b_data.trait_ref));
Ok(ty::mk_projection(tcx, Rc::new(trait_ref), a_data.item_name))
} else {
Err(ty::terr_sorts(expected_found(this, a, b)))
}
let projection_ty = try!(this.projection_tys(a_data, b_data));
Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name))
}
_ => Err(ty::terr_sorts(expected_found(this, a, b)))
......
......@@ -396,14 +396,14 @@ pub fn type_of_adjust<'tcx>(cx: &ctxt<'tcx>, adj: &AutoAdjustment<'tcx>) -> Opti
fn type_of_autoref<'tcx>(cx: &ctxt<'tcx>, autoref: &AutoRef<'tcx>) -> Option<Ty<'tcx>> {
match autoref {
&AutoUnsize(ref k) => match k {
&UnsizeVtable(TyTrait { ref principal, bounds }, _) => {
Some(mk_trait(cx, (*principal).clone(), bounds))
&UnsizeVtable(TyTrait { ref principal, ref bounds }, _) => {
Some(mk_trait(cx, principal.clone(), bounds.clone()))
}
_ => None
},
&AutoUnsizeUniq(ref k) => match k {
&UnsizeVtable(TyTrait { ref principal, bounds }, _) => {
Some(mk_uniq(cx, mk_trait(cx, (*principal).clone(), bounds)))
&UnsizeVtable(TyTrait { ref principal, ref bounds }, _) => {
Some(mk_uniq(cx, mk_trait(cx, principal.clone(), bounds.clone())))
}
_ => None
},
......@@ -1040,7 +1040,7 @@ pub struct ClosureTy<'tcx> {
pub unsafety: ast::Unsafety,
pub onceness: ast::Onceness,
pub store: TraitStore,
pub bounds: ExistentialBounds,
pub bounds: ExistentialBounds<'tcx>,
pub sig: PolyFnSig<'tcx>,
pub abi: abi::Abi,
}
......@@ -1376,7 +1376,7 @@ pub enum sty<'tcx> {
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct TyTrait<'tcx> {
pub principal: ty::PolyTraitRef<'tcx>,
pub bounds: ExistentialBounds
pub bounds: ExistentialBounds<'tcx>,
}
impl<'tcx> TyTrait<'tcx> {
......@@ -1510,7 +1510,9 @@ pub enum type_err<'tcx> {
terr_builtin_bounds(expected_found<BuiltinBounds>),
terr_variadic_mismatch(expected_found<bool>),
terr_cyclic_ty,
terr_convergence_mismatch(expected_found<bool>)
terr_convergence_mismatch(expected_found<bool>),
terr_projection_name_mismatched(expected_found<ast::Name>),
terr_projection_bounds_length(expected_found<uint>),
}
/// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
......@@ -1528,10 +1530,11 @@ pub struct ParamBounds<'tcx> {
/// major difference between this case and `ParamBounds` is that
/// general purpose trait bounds are omitted and there must be
/// *exactly one* region.
#[deriving(Copy, PartialEq, Eq, Hash, Clone, Show)]
pub struct ExistentialBounds {
#[deriving(PartialEq, Eq, Hash, Clone, Show)]
pub struct ExistentialBounds<'tcx> {
pub region_bound: ty::Region,
pub builtin_bounds: BuiltinBounds
pub builtin_bounds: BuiltinBounds,
pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
}
pub type BuiltinBounds = EnumSet<BuiltinBound>;
......@@ -1559,9 +1562,10 @@ pub fn all_builtin_bounds() -> BuiltinBounds {
}
/// An existential bound that does not implement any traits.
pub fn region_existential_bound(r: ty::Region) -> ExistentialBounds {
pub fn region_existential_bound<'tcx>(r: ty::Region) -> ExistentialBounds<'tcx> {
ty::ExistentialBounds { region_bound: r,
builtin_bounds: empty_builtin_bounds() }
builtin_bounds: empty_builtin_bounds(),
projection_bounds: Vec::new() }
}
impl CLike for BuiltinBound {
......@@ -1820,12 +1824,24 @@ pub struct ProjectionPredicate<'tcx> {
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
impl<'tcx> PolyProjectionPredicate<'tcx> {
pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
self.0.projection_ty.sort_key()
}
}
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct ProjectionTy<'tcx> {
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
pub item_name: ast::Name,
}
impl<'tcx> ProjectionTy<'tcx> {
pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
(self.trait_ref.def_id, self.item_name)
}
}
pub trait ToPolyTraitRef<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}
......@@ -2675,8 +2691,11 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
principal: ty::PolyTraitRef<'tcx>,
bounds: ExistentialBounds)
-> Ty<'tcx> {
bounds: ExistentialBounds<'tcx>)
-> Ty<'tcx>
{
assert!(bound_list_is_sorted(bounds.projection_bounds.as_slice()));
let inner = box TyTrait {
principal: principal,
bounds: bounds
......@@ -2684,6 +2703,16 @@ pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
mk_t(cx, ty_trait(inner))
}
fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
bounds.len() == 0 ||
bounds[1..].iter().enumerate().all(
|(index, bound)| bounds[index].sort_key() <= bound.sort_key())
}
pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) {
bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key()))
}
pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>,
trait_ref: Rc<ty::TraitRef<'tcx>>,
item_name: ast::Name)
......@@ -3226,7 +3255,7 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
}
}
ty_trait(box TyTrait { bounds, .. }) => {
ty_trait(box TyTrait { ref bounds, .. }) => {
object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
}
......@@ -3391,7 +3420,7 @@ fn borrowed_contents(region: ty::Region,
fn closure_contents(cty: &ClosureTy) -> TypeContents {
// Closure contents are just like trait contents, but with potentially
// even more stuff.
let st = object_contents(cty.bounds);
let st = object_contents(&cty.bounds);
let st = match cty.store {
UniqTraitStore => {
......@@ -3405,7 +3434,7 @@ fn closure_contents(cty: &ClosureTy) -> TypeContents {
st
}
fn object_contents(bounds: ExistentialBounds) -> TypeContents {
fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
// These are the type contents of the (opaque) interior. We
// make no assumptions (other than that it cannot have an
// in-scope type parameter within, which makes no sense).
......@@ -4205,6 +4234,7 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
let bounds = ty::ExistentialBounds {
region_bound: ReStatic,
builtin_bounds: all_builtin_bounds(),
projection_bounds: vec!(),
};
ty::mk_closure(
......@@ -4339,8 +4369,8 @@ pub fn unsize_ty<'tcx>(cx: &ctxt<'tcx>,
format!("UnsizeStruct with bad sty: {}",
ty_to_string(cx, ty))[])
},
&UnsizeVtable(TyTrait { ref principal, bounds }, _) => {
mk_trait(cx, (*principal).clone(), bounds)
&UnsizeVtable(TyTrait { ref principal, ref bounds }, _) => {
mk_trait(cx, principal.clone(), bounds.clone())
}
}
}
......@@ -4760,6 +4790,16 @@ fn tstore_to_closure(s: &TraitStore) -> String {
if values.expected { "converging" } else { "diverging" },
if values.found { "converging" } else { "diverging" })
}
terr_projection_name_mismatched(ref values) => {
format!("expected {}, found {}",
token::get_name(values.expected),
token::get_name(values.found))
}
terr_projection_bounds_length(ref values) => {
format!("expected {} associated type bindings, found {}",
values.expected,
values.found)
}
}
}
......
......@@ -121,8 +121,8 @@ fn fold_trait_store(&mut self, s: ty::TraitStore) -> ty::TraitStore {
super_fold_trait_store(self, s)
}
fn fold_existential_bounds(&mut self, s: ty::ExistentialBounds)
-> ty::ExistentialBounds {
fn fold_existential_bounds(&mut self, s: &ty::ExistentialBounds<'tcx>)
-> ty::ExistentialBounds<'tcx> {
super_fold_existential_bounds(self, s)
}
......@@ -349,9 +349,9 @@ fn fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> ty::BuiltinBounds {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialBounds {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ExistentialBounds {
folder.fold_existential_bounds(*self)
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialBounds<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ExistentialBounds<'tcx> {
folder.fold_existential_bounds(self)
}
}
......@@ -449,7 +449,7 @@ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::UnsizeKind<'tcx>
match *self {
ty::UnsizeLength(len) => ty::UnsizeLength(len),
ty::UnsizeStruct(box ref k, n) => ty::UnsizeStruct(box k.fold_with(folder), n),
ty::UnsizeVtable(ty::TyTrait{ref principal, bounds}, self_ty) => {
ty::UnsizeVtable(ty::TyTrait{ref principal, ref bounds}, self_ty) => {
ty::UnsizeVtable(
ty::TyTrait {
principal: principal.fold_with(folder),
......@@ -565,9 +565,9 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
let substs = substs.fold_with(this);
ty::ty_enum(tid, this.tcx().mk_substs(substs))
}
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
ty::ty_trait(box ty::TyTrait {
principal: (*principal).fold_with(this),
principal: principal.fold_with(this),
bounds: bounds.fold_with(this),
})
}
......@@ -693,12 +693,15 @@ pub fn super_fold_trait_store<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
}
}
pub fn super_fold_existential_bounds<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
bounds: ty::ExistentialBounds)
-> ty::ExistentialBounds {
pub fn super_fold_existential_bounds<'tcx, T: TypeFolder<'tcx>>(
this: &mut T,
bounds: &ty::ExistentialBounds<'tcx>)
-> ty::ExistentialBounds<'tcx>
{
ty::ExistentialBounds {
region_bound: bounds.region_bound.fold_with(this),
builtin_bounds: bounds.builtin_bounds,
projection_bounds: bounds.projection_bounds.fold_with(this),
}
}
......
......@@ -739,8 +739,8 @@ fn repr(&self, _tcx: &ctxt) -> String {
}
}
impl<'tcx> Repr<'tcx> for ty::ExistentialBounds {
fn repr(&self, tcx: &ctxt) -> String {
impl<'tcx> Repr<'tcx> for ty::ExistentialBounds<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
self.user_string(tcx)
}
}
......@@ -1142,8 +1142,8 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
}
}
impl<'tcx> UserString<'tcx> for ty::ExistentialBounds {
fn user_string(&self, tcx: &ctxt) -> String {
impl<'tcx> UserString<'tcx> for ty::ExistentialBounds<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
if self.builtin_bounds.contains(&ty::BoundSend) &&
self.region_bound == ty::ReStatic
{ // Region bound is implied by builtin bounds:
......
......@@ -810,11 +810,13 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
}
}
type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec<ty::PolyProjectionPredicate<'tcx>>);
fn ast_ty_to_trait_ref<'tcx,AC,RS>(this: &AC,
rscope: &RS,
ty: &ast::Ty,
bounds: &[ast::TyParamBound])
-> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
-> Result<TraitAndProjections<'tcx>, ErrorReported>
where AC : AstConv<'tcx>, RS : RegionScope
{
/*!
......@@ -832,14 +834,17 @@ fn ast_ty_to_trait_ref<'tcx,AC,RS>(this: &AC,
ast::TyPath(ref path, id) => {
match this.tcx().def_map.borrow().get(&id) {
Some(&def::DefTrait(trait_def_id)) => {
// TODO do something with this
let mut projections = Vec::new();
Ok(ty::Binder(ast_path_to_trait_ref(this,
rscope,
trait_def_id,
None,
path,
Some(&mut projections))))
let mut projection_bounds = Vec::new();
let trait_ref = ty::Binder(ast_path_to_trait_ref(this,
rscope,
trait_def_id,
None,
path,
Some(&mut projection_bounds)));
let projection_bounds = projection_bounds.into_iter()
.map(ty::Binder)
.collect();
Ok((trait_ref, projection_bounds))
}
_ => {
span_err!(this.tcx().sess, ty.span, E0172, "expected a reference to a trait");
......@@ -882,6 +887,7 @@ fn trait_ref_to_object_type<'tcx,AC,RS>(this: &AC,
rscope: &RS,
span: Span,
trait_ref: ty::PolyTraitRef<'tcx>,
projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
bounds: &[ast::TyParamBound])
-> Ty<'tcx>
where AC : AstConv<'tcx>, RS : RegionScope
......@@ -890,6 +896,7 @@ fn trait_ref_to_object_type<'tcx,AC,RS>(this: &AC,
rscope,
span,
Some(trait_ref.clone()),
projection_bounds,
bounds);
let result = ty::mk_trait(this.tcx(), trait_ref, existential_bounds);
......@@ -1019,9 +1026,9 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
}
ast::TyObjectSum(ref ty, ref bounds) => {
match ast_ty_to_trait_ref(this, rscope, &**ty, bounds[]) {
Ok(trait_ref) => {
Ok((trait_ref, projection_bounds)) => {
trait_ref_to_object_type(this, rscope, ast_ty.span,
trait_ref, bounds[])
trait_ref, projection_bounds, bounds[])
}
Err(ErrorReported) => {
this.tcx().types.err
......@@ -1062,13 +1069,15 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
rscope,
ast_ty.span,
None,
Vec::new(),
f.bounds.as_slice());
let region_bound = bounds.region_bound;
let fn_decl = ty_of_closure(this,
f.unsafety,
f.onceness,
bounds,
ty::RegionTraitStore(
bounds.region_bound,
region_bound,
ast::MutMutable),
&*f.decl,
abi::Rust,
......@@ -1092,15 +1101,19 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
def::DefTrait(trait_def_id) => {
// N.B. this case overlaps somewhat with
// TyObjectSum, see that fn for details
let mut projections = Vec::new(); // TODO
let mut projection_bounds = Vec::new();
let trait_ref = ast_path_to_trait_ref(this,
rscope,
trait_def_id,
None,
path,
Some(&mut projections));
Some(&mut projection_bounds));
let trait_ref = ty::Binder(trait_ref);
trait_ref_to_object_type(this, rscope, path.span, trait_ref, &[])
let projection_bounds = projection_bounds.into_iter()
.map(ty::Binder)
.collect();
trait_ref_to_object_type(this, rscope, path.span,
trait_ref, projection_bounds, &[])
}
def::DefTy(did, _) | def::DefStruct(did) => {
ast_path_to_ty(this, rscope, did, path).ty
......@@ -1437,7 +1450,7 @@ pub fn ty_of_closure<'tcx, AC: AstConv<'tcx>>(
this: &AC,
unsafety: ast::Unsafety,
onceness: ast::Onceness,
bounds: ty::ExistentialBounds,
bounds: ty::ExistentialBounds<'tcx>,
store: ty::TraitStore,
decl: &ast::FnDecl,
abi: abi::Abi,
......@@ -1500,14 +1513,15 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
rscope: &RS,
span: Span,
principal_trait_ref: Option<ty::PolyTraitRef<'tcx>>, // None for boxed closures
projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
ast_bounds: &[ast::TyParamBound])
-> ty::ExistentialBounds
-> ty::ExistentialBounds<'tcx>
{
let partitioned_bounds =
partition_bounds(this.tcx(), span, ast_bounds);
conv_existential_bounds_from_partitioned_bounds(
this, rscope, span, principal_trait_ref, partitioned_bounds)
this, rscope, span, principal_trait_ref, projection_bounds, partitioned_bounds)
}
fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
......@@ -1520,14 +1534,14 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
{
let mut partitioned_bounds = partition_bounds(this.tcx(), span, ast_bounds[]);
let mut projections = Vec::new();
let mut projection_bounds = Vec::new();
let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) {
Some(trait_bound) => {
let ptr = instantiate_poly_trait_ref(this,
rscope,
trait_bound,
None,
&mut projections);
&mut projection_bounds);
Some(ptr)
}
None => {
......@@ -1538,13 +1552,12 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
}
};
// TODO use projections somewhere
let bounds =
conv_existential_bounds_from_partitioned_bounds(this,
rscope,
span,
main_trait_bound.clone(),
projection_bounds,
partitioned_bounds);
match main_trait_bound {
......@@ -1558,8 +1571,9 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx, AC, RS>(
rscope: &RS,
span: Span,
principal_trait_ref: Option<ty::PolyTraitRef<'tcx>>, // None for boxed closures
mut projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>, // Empty for boxed closures
partitioned_bounds: PartitionedBounds)
-> ty::ExistentialBounds
-> ty::ExistentialBounds<'tcx>
where AC: AstConv<'tcx>, RS:RegionScope
{
let PartitionedBounds { builtin_bounds,
......@@ -1582,9 +1596,12 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx, AC, RS>(
principal_trait_ref,
builtin_bounds);
ty::sort_bounds_list(projection_bounds.as_mut_slice());
ty::ExistentialBounds {
region_bound: region_bound,
builtin_bounds: builtin_bounds,
projection_bounds: projection_bounds,
}
}
......
......@@ -15,7 +15,6 @@
use middle::ty_fold::{mod, TypeFoldable, TypeFolder};
use syntax::ast;
use syntax::codemap::Span;
use std::rc::Rc;
pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
fulfillment_cx: &mut FulfillmentContext<'tcx>,
......
......@@ -289,7 +289,7 @@ fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
(&ty::UniqTraitStore, _) => ast::Once,
(&ty::RegionTraitStore(..), _) => ast::Many,
};
(Some(sig), onceness, cenv.bounds)
(Some(sig), onceness, cenv.bounds.clone())
}
_ => {
// Not an error! Means we're inferring the closure type
......
......@@ -768,7 +768,7 @@ fn walk_cast<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
}
/*From:*/ (_,
/*To: */ &ty::ty_trait(box ty::TyTrait { bounds, .. })) => {
/*To: */ &ty::ty_trait(box ty::TyTrait { ref bounds, .. })) => {
// When T is existentially quantified as a trait
// `Foo+'to`, it must outlive the region bound `'to`.
type_must_outlive(rcx, infer::RelateObjectBound(cast_expr.span),
......@@ -851,7 +851,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
}
match function_type.sty {
ty::ty_closure(box ty::ClosureTy {bounds, ..}) => {
ty::ty_closure(box ty::ClosureTy {ref bounds, ..}) => {
ty::with_freevars(tcx, expr.id, |freevars| {
ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars);
})
......@@ -859,7 +859,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
ty::ty_unboxed_closure(_, region, _) => {
ty::with_freevars(tcx, expr.id, |freevars| {
let bounds = ty::region_existential_bound(*region);
ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars);
ensure_free_variable_types_outlive_closure_bound(rcx, &bounds, expr, freevars);
})
}
_ => {}
......@@ -870,7 +870,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
/// over values outliving the object's lifetime bound.
fn ensure_free_variable_types_outlive_closure_bound(
rcx: &mut Rcx,
bounds: ty::ExistentialBounds,
bounds: &ty::ExistentialBounds,
expr: &ast::Expr,
freevars: &[ty::Freevar])
{
......
......@@ -244,7 +244,7 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let object_trait_ty =
ty::mk_trait(fcx.tcx(),
object_trait.principal.clone(),
object_trait.bounds);
object_trait.bounds.clone());
debug!("register_object_cast_obligations: referent_ty={} object_trait_ty={}",
referent_ty.repr(fcx.tcx()),
......
......@@ -500,13 +500,14 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
}
}
impl Clean<Vec<TyParamBound>> for ty::ExistentialBounds {
impl<'tcx> Clean<Vec<TyParamBound>> for ty::ExistentialBounds<'tcx> {
fn clean(&self, cx: &DocContext) -> Vec<TyParamBound> {
let mut vec = vec![];
self.region_bound.clean(cx).map(|b| vec.push(RegionBound(b)));
for bb in self.builtin_bounds.iter() {
vec.push(bb.clean(cx));
}
// TODO projection bounds
vec
}
}
......@@ -1441,18 +1442,11 @@ fn clean(&self, cx: &DocContext) -> Type {
}
}
ty::ty_struct(did, substs) |
ty::ty_enum(did, substs) |
ty::ty_trait(box ty::TyTrait {
principal: ty::Binder(ty::TraitRef { def_id: did, substs }),
.. }) =>
{
ty::ty_enum(did, substs) => {
let fqn = csearch::get_item_path(cx.tcx(), did);
let fqn: Vec<String> = fqn.into_iter().map(|i| {
i.to_string()
}).collect();
let fqn: Vec<_> = fqn.into_iter().map(|i| i.to_string()).collect();
let kind = match self.sty {
ty::ty_struct(..) => TypeStruct,
ty::ty_trait(..) => TypeTrait,
_ => TypeEnum,
};
let path = external_path(cx, fqn.last().unwrap().to_string().as_slice(),
......@@ -1464,11 +1458,24 @@ fn clean(&self, cx: &DocContext) -> Type {
did: did,
}
}
ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
let did = principal.def_id();
let fqn = csearch::get_item_path(cx.tcx(), did);
let fqn: Vec<_> = fqn.into_iter().map(|i| i.to_string()).collect();
let path = external_path(cx, fqn.last().unwrap().to_string().as_slice(),
Some(did), principal.substs());
cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, TypeTrait));
ResolvedPath {
path: path,
typarams: Some(bounds.clean(cx)),
did: did,
}
}
ty::ty_tup(ref t) => Tuple(t.clean(cx)),
ty::ty_projection(ref data) => {
let trait_ref = match data.trait_ref.clean(cx) {
TyParamBound::TraitBound(t) => t,
TyParamBound::TraitBound(t) => t.trait_,
TyParamBound::RegionBound(_) => panic!("cleaning a trait got a region??"),
};
Type::QPath {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册