Integrate projection bounds to ExistentialBounds
but do not use them for anything.
This commit is contained in:
parent
82787c2252
commit
becbd81aaa
@ -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, ¶m_bounds);
|
||||
}
|
||||
|
||||
pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
||||
|
@ -842,7 +842,8 @@ trait rbml_writer_helpers<'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 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
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 @@ trait rbml_decoder_decoder_helpers<'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 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
}
|
||||
|
||||
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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
(&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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
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 @@ pub trait Combine<'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 @@ pub trait Combine<'tcx> {
|
||||
|
||||
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 @@ impl<'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
|
||||
}
|
||||
}
|
||||
|
||||
ty_trait(box TyTrait { bounds, .. }) => {
|
||||
ty_trait(box TyTrait { ref bounds, .. }) => {
|
||||
object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
|
||||
}
|
||||
|
||||
@ -3391,7 +3420,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
|
||||
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 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> 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 @@ pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> 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 @@ pub trait TypeFolder<'tcx> {
|
||||
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 @@ impl<'tcx> TypeFoldable<'tcx> for 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 @@ impl<'tcx> TypeFoldable<'tcx> for 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 @@ impl<'tcx> Repr<'tcx> for ty::BuiltinBounds {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ impl<'tcx> UserString<'tcx> for ty::ParamBounds<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
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::{mod, HasProjectionTypes, Ty};
|
||||
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 constrain_cast(rcx: &mut Rcx,
|
||||
}
|
||||
|
||||
/*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 @@ impl Clean<TyParamBound> for ast::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 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||
}
|
||||
}
|
||||
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 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user