Create distinct types for a PolyTraitRef (with bindings) and a normal TraitRef.

This commit is contained in:
Niko Matsakis 2014-12-11 13:37:37 -05:00
parent b3dcb85404
commit 3cf0fbeee9
51 changed files with 516 additions and 469 deletions

View File

@ -1785,7 +1785,7 @@ impl LintPass for Stability {
.. ..
}) => { }) => {
ty::trait_item(cx.tcx, ty::trait_item(cx.tcx,
trait_ref.def_id, trait_ref.def_id(),
index).def_id() index).def_id()
} }
} }

View File

@ -262,7 +262,7 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
// if there is one. // if there is one.
pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>, pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId) def: ast::DefId)
-> Option<Rc<ty::TraitRef<'tcx>>> { -> Option<Rc<ty::PolyTraitRef<'tcx>>> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); let cdata = cstore.get_crate_data(def.krate);
decoder::get_impl_trait(&*cdata, def.node, tcx) decoder::get_impl_trait(&*cdata, def.node, tcx)

View File

@ -425,11 +425,11 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
pub fn get_impl_trait<'tcx>(cdata: Cmd, pub fn get_impl_trait<'tcx>(cdata: Cmd,
id: ast::NodeId, id: ast::NodeId,
tcx: &ty::ctxt<'tcx>) tcx: &ty::ctxt<'tcx>)
-> Option<Rc<ty::TraitRef<'tcx>>> -> Option<Rc<ty::PolyTraitRef<'tcx>>>
{ {
let item_doc = lookup_item(id, cdata.data()); let item_doc = lookup_item(id, cdata.data());
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| { reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
Rc::new(doc_trait_ref(tp, tcx, cdata)) Rc::new(ty::bind(doc_trait_ref(tp, tcx, cdata)))
}) })
} }

View File

@ -414,7 +414,7 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
} }
'x' => { 'x' => {
assert_eq!(next(st), '['); assert_eq!(next(st), '[');
let trait_ref = parse_trait_ref(st, |x,y| conv(x,y)); let trait_ref = ty::bind(parse_trait_ref(st, |x,y| conv(x,y)));
let bounds = parse_existential_bounds(st, |x,y| conv(x,y)); let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
assert_eq!(next(st), ']'); assert_eq!(next(st), ']');
return ty::mk_trait(st.tcx, trait_ref, bounds); return ty::mk_trait(st.tcx, trait_ref, bounds);
@ -669,7 +669,7 @@ pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>,
-> ty::Predicate<'tcx> -> ty::Predicate<'tcx>
{ {
match next(st) { match next(st) {
't' => ty::Predicate::Trait(Rc::new(parse_trait_ref(st, conv))), 't' => ty::Predicate::Trait(Rc::new(ty::bind(parse_trait_ref(st, conv)))),
'e' => ty::Predicate::Equate(parse_ty(st, |x,y| conv(x,y)), 'e' => ty::Predicate::Equate(parse_ty(st, |x,y| conv(x,y)),
parse_ty(st, |x,y| conv(x,y))), parse_ty(st, |x,y| conv(x,y))),
'r' => ty::Predicate::RegionOutlives(parse_region(st, |x,y| conv(x,y)), 'r' => ty::Predicate::RegionOutlives(parse_region(st, |x,y| conv(x,y)),
@ -759,10 +759,12 @@ fn parse_bounds<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
loop { loop {
match next(st) { match next(st) {
'R' => { 'R' => {
param_bounds.region_bounds.push(parse_region(st, |x, y| conv (x, y))); param_bounds.region_bounds.push(
parse_region(st, |x, y| conv (x, y)));
} }
'I' => { 'I' => {
param_bounds.trait_bounds.push(Rc::new(parse_trait_ref(st, |x,y| conv(x,y)))); param_bounds.trait_bounds.push(
Rc::new(ty::bind(parse_trait_ref(st, |x,y| conv(x,y)))));
} }
'.' => { '.' => {
return param_bounds; return param_bounds;

View File

@ -251,7 +251,7 @@ fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
ty::ty_trait(box ty::TyTrait { ref principal, ty::ty_trait(box ty::TyTrait { ref principal,
ref bounds }) => { ref bounds }) => {
mywrite!(w, "x["); mywrite!(w, "x[");
enc_trait_ref(w, cx, principal); enc_trait_ref(w, cx, &principal.value);
enc_existential_bounds(w, cx, bounds); enc_existential_bounds(w, cx, bounds);
mywrite!(w, "]"); mywrite!(w, "]");
} }
@ -401,7 +401,7 @@ pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
for tp in bs.trait_bounds.iter() { for tp in bs.trait_bounds.iter() {
mywrite!(w, "I"); mywrite!(w, "I");
enc_trait_ref(w, cx, &**tp); enc_trait_ref(w, cx, &tp.value);
} }
mywrite!(w, "."); mywrite!(w, ".");
@ -425,7 +425,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
match *p { match *p {
ty::Predicate::Trait(ref trait_ref) => { ty::Predicate::Trait(ref trait_ref) => {
mywrite!(w, "t"); mywrite!(w, "t");
enc_trait_ref(w, cx, &**trait_ref); enc_trait_ref(w, cx, &trait_ref.value);
} }
ty::Predicate::Equate(a, b) => { ty::Predicate::Equate(a, b) => {
mywrite!(w, "e"); mywrite!(w, "e");

View File

@ -887,7 +887,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
this.emit_enum_variant("MethodTypeParam", 2, 1, |this| { this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
this.emit_struct("MethodParam", 2, |this| { this.emit_struct("MethodParam", 2, |this| {
try!(this.emit_struct_field("trait_ref", 0, |this| { try!(this.emit_struct_field("trait_ref", 0, |this| {
Ok(this.emit_trait_ref(ecx, &*p.trait_ref)) Ok(this.emit_trait_ref(ecx, &p.trait_ref.value))
})); }));
try!(this.emit_struct_field("method_num", 0, |this| { try!(this.emit_struct_field("method_num", 0, |this| {
this.emit_uint(p.method_num) this.emit_uint(p.method_num)
@ -901,7 +901,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
this.emit_enum_variant("MethodTraitObject", 3, 1, |this| { this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
this.emit_struct("MethodObject", 2, |this| { this.emit_struct("MethodObject", 2, |this| {
try!(this.emit_struct_field("trait_ref", 0, |this| { try!(this.emit_struct_field("trait_ref", 0, |this| {
Ok(this.emit_trait_ref(ecx, &*o.trait_ref)) Ok(this.emit_trait_ref(ecx, &o.trait_ref.value))
})); }));
try!(this.emit_struct_field("object_trait_id", 0, |this| { try!(this.emit_struct_field("object_trait_id", 0, |this| {
Ok(this.emit_def_id(o.object_trait_id)) Ok(this.emit_def_id(o.object_trait_id))
@ -1113,7 +1113,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
this.emit_enum_variant("UnsizeVtable", 2, 4, |this| { this.emit_enum_variant("UnsizeVtable", 2, 4, |this| {
this.emit_enum_variant_arg(0, |this| { this.emit_enum_variant_arg(0, |this| {
try!(this.emit_struct_field("principal", 0, |this| { try!(this.emit_struct_field("principal", 0, |this| {
Ok(this.emit_trait_ref(ecx, &*principal)) Ok(this.emit_trait_ref(ecx, &principal.value))
})); }));
this.emit_struct_field("bounds", 1, |this| { this.emit_struct_field("bounds", 1, |this| {
Ok(this.emit_existential_bounds(ecx, b)) Ok(this.emit_existential_bounds(ecx, b))
@ -1277,7 +1277,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| { rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
rbml_w.id(id); rbml_w.id(id);
rbml_w.tag(c::tag_table_val, |rbml_w| { rbml_w.tag(c::tag_table_val, |rbml_w| {
rbml_w.emit_trait_ref(ecx, &**trait_ref); rbml_w.emit_trait_ref(ecx, &trait_ref.value);
}) })
}) })
} }
@ -1356,6 +1356,8 @@ trait rbml_decoder_decoder_helpers<'tcx> {
fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>; fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> Rc<ty::TraitRef<'tcx>>; -> Rc<ty::TraitRef<'tcx>>;
fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> Rc<ty::PolyTraitRef<'tcx>>;
fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::TypeParameterDef<'tcx>; -> ty::TypeParameterDef<'tcx>;
fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@ -1455,7 +1457,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
ty::MethodParam { ty::MethodParam {
trait_ref: { trait_ref: {
this.read_struct_field("trait_ref", 0, |this| { this.read_struct_field("trait_ref", 0, |this| {
Ok(this.read_trait_ref(dcx)) Ok(this.read_poly_trait_ref(dcx))
}).unwrap() }).unwrap()
}, },
method_num: { method_num: {
@ -1473,7 +1475,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
ty::MethodObject { ty::MethodObject {
trait_ref: { trait_ref: {
this.read_struct_field("trait_ref", 0, |this| { this.read_struct_field("trait_ref", 0, |this| {
Ok(this.read_trait_ref(dcx)) Ok(this.read_poly_trait_ref(dcx))
}).unwrap() }).unwrap()
}, },
object_trait_id: { object_trait_id: {
@ -1548,6 +1550,19 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
}).unwrap()) }).unwrap())
} }
fn read_poly_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> Rc<ty::PolyTraitRef<'tcx>> {
Rc::new(ty::bind(self.read_opaque(|this, doc| {
let ty = tydecode::parse_trait_ref_data(
doc.data,
dcx.cdata.cnum,
doc.start,
dcx.tcx,
|s, a| this.convert_def_id(dcx, s, a));
Ok(ty)
}).unwrap()))
}
fn read_type_param_def<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) fn read_type_param_def<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::TypeParameterDef<'tcx> { -> ty::TypeParameterDef<'tcx> {
self.read_opaque(|this, doc| { self.read_opaque(|this, doc| {
@ -1753,7 +1768,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
2 => { 2 => {
let ty_trait = try!(this.read_enum_variant_arg(0, |this| { let ty_trait = try!(this.read_enum_variant_arg(0, |this| {
let principal = try!(this.read_struct_field("principal", 0, |this| { let principal = try!(this.read_struct_field("principal", 0, |this| {
Ok(this.read_trait_ref(dcx)) Ok(this.read_poly_trait_ref(dcx))
})); }));
Ok(ty::TyTrait { Ok(ty::TyTrait {
principal: (*principal).clone(), principal: (*principal).clone(),
@ -1926,7 +1941,7 @@ fn decode_side_tables(dcx: &DecodeContext,
dcx.tcx.method_map.borrow_mut().insert(method_call, method); dcx.tcx.method_map.borrow_mut().insert(method_call, method);
} }
c::tag_table_object_cast_map => { c::tag_table_object_cast_map => {
let trait_ref = val_dsr.read_trait_ref(dcx); let trait_ref = val_dsr.read_poly_trait_ref(dcx);
dcx.tcx.object_cast_map.borrow_mut() dcx.tcx.object_cast_map.borrow_mut()
.insert(id, trait_ref); .insert(id, trait_ref);
} }

View File

@ -31,7 +31,6 @@ use middle::infer;
use middle::traits; use middle::traits;
use middle::mem_categorization as mc; use middle::mem_categorization as mc;
use middle::expr_use_visitor as euv; use middle::expr_use_visitor as euv;
use util::common::ErrorReported;
use util::nodemap::NodeSet; use util::nodemap::NodeSet;
use syntax::ast; use syntax::ast;
@ -122,17 +121,12 @@ impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
let ty = ty::node_id_to_type(self.tcx, e.id); let ty = ty::node_id_to_type(self.tcx, e.id);
let infcx = infer::new_infer_ctxt(self.tcx); let infcx = infer::new_infer_ctxt(self.tcx);
let mut fulfill_cx = traits::FulfillmentContext::new(); let mut fulfill_cx = traits::FulfillmentContext::new();
match traits::trait_ref_for_builtin_bound(self.tcx, ty::BoundSync, ty) { fulfill_cx.register_builtin_bound(self.tcx, ty, ty::BoundSync,
Ok(trait_ref) => { traits::ObligationCause::dummy());
fulfill_cx.register_trait_ref(self.tcx, trait_ref, let env = ty::empty_parameter_environment();
traits::ObligationCause::dummy()); if !fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok() {
let env = ty::empty_parameter_environment(); self.tcx.sess.span_err(e.span, "shared static items must have a \
if !fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok() { type which implements Sync");
self.tcx.sess.span_err(e.span, "shared static items must have a \
type which implements Sync");
}
}
Err(ErrorReported) => { }
} }
} }
} }

View File

@ -112,7 +112,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
.. ..
}) => { }) => {
let trait_item = ty::trait_item(self.tcx, let trait_item = ty::trait_item(self.tcx,
trait_ref.def_id, trait_ref.def_id(),
index); index);
match trait_item { match trait_item {
ty::MethodTraitItem(method) => { ty::MethodTraitItem(method) => {

View File

@ -265,7 +265,7 @@ impl OverloadedCallType {
} }
Some(ref trait_ref) => (*trait_ref).clone(), Some(ref trait_ref) => (*trait_ref).clone(),
}; };
OverloadedCallType::from_trait_id(tcx, trait_ref.def_id) OverloadedCallType::from_trait_id(tcx, trait_ref.value.def_id)
} }
fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId) fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
@ -292,7 +292,7 @@ impl OverloadedCallType {
} }
MethodTypeParam(MethodParam { ref trait_ref, .. }) | MethodTypeParam(MethodParam { ref trait_ref, .. }) |
MethodTraitObject(MethodObject { ref trait_ref, .. }) => { MethodTraitObject(MethodObject { ref trait_ref, .. }) => {
OverloadedCallType::from_trait_id(tcx, trait_ref.def_id) OverloadedCallType::from_trait_id(tcx, trait_ref.def_id())
} }
} }
} }

View File

@ -60,7 +60,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
ty::ty_vec(..) => Some(VecSimplifiedType), ty::ty_vec(..) => Some(VecSimplifiedType),
ty::ty_ptr(_) => Some(PtrSimplifiedType), ty::ty_ptr(_) => Some(PtrSimplifiedType),
ty::ty_trait(ref trait_info) => { ty::ty_trait(ref trait_info) => {
Some(TraitSimplifiedType(trait_info.principal.def_id)) Some(TraitSimplifiedType(trait_info.principal.value.def_id))
} }
ty::ty_struct(def_id, _) => { ty::ty_struct(def_id, _) => {
Some(StructSimplifiedType(def_id)) Some(StructSimplifiedType(def_id))

View File

@ -354,7 +354,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
} }
(_, &ty::ty_trait(box ty::TyTrait { ref principal, bounds })) => { (_, &ty::ty_trait(box ty::TyTrait { ref principal, bounds })) => {
// FIXME what is the purpose of `ty`? // FIXME what is the purpose of `ty`?
let ty = ty::mk_trait(tcx, (*principal).clone(), bounds); let ty = ty::mk_trait(tcx, principal.clone(), bounds);
Some((ty, ty::UnsizeVtable(ty::TyTrait { principal: (*principal).clone(), Some((ty, ty::UnsizeVtable(ty::TyTrait { principal: (*principal).clone(),
bounds: bounds }, bounds: bounds },
ty_a))) ty_a)))
@ -464,7 +464,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => { ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl); debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl);
// FIXME what is purpose of this type `tr`? // 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);
try!(self.subtype(mk_ty(tr), b)); try!(self.subtype(mk_ty(tr), b));
Ok(Some(AdjustDerefRef(AutoDerefRef { Ok(Some(AdjustDerefRef(AutoDerefRef {
autoderefs: 1, autoderefs: 1,

View File

@ -301,7 +301,21 @@ pub trait Combine<'tcx> {
fn trait_refs(&self, fn trait_refs(&self,
a: &ty::TraitRef<'tcx>, a: &ty::TraitRef<'tcx>,
b: &ty::TraitRef<'tcx>) b: &ty::TraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>>; -> cres<'tcx, ty::TraitRef<'tcx>>
{
// Different traits cannot be related
if a.def_id != b.def_id {
Err(ty::terr_traits(expected_found(self, a.def_id, b.def_id)))
} else {
let substs = try!(self.substs(a.def_id, &a.substs, &b.substs));
Ok(ty::TraitRef { def_id: a.def_id, substs: substs })
}
}
fn poly_trait_refs(&self,
a: &ty::PolyTraitRef<'tcx>,
b: &ty::PolyTraitRef<'tcx>)
-> cres<'tcx, ty::PolyTraitRef<'tcx>>;
// this must be overridden to do correctly, so as to account for higher-ranked // this must be overridden to do correctly, so as to account for higher-ranked
// behavior // behavior
} }
@ -410,7 +424,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
(&ty::ty_trait(ref a_), (&ty::ty_trait(ref a_),
&ty::ty_trait(ref b_)) => { &ty::ty_trait(ref b_)) => {
debug!("Trying to match traits {} and {}", a, b); debug!("Trying to match traits {} and {}", a, b);
let principal = try!(this.trait_refs(&a_.principal, &b_.principal)); let principal = try!(this.poly_trait_refs(&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)) Ok(ty::mk_trait(tcx, principal, bounds))
} }

View File

@ -134,14 +134,16 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
} }
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>) fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
-> cres<'tcx, ty::FnSig<'tcx>> { -> cres<'tcx, ty::FnSig<'tcx>>
{
try!(self.sub().fn_sigs(a, b)); try!(self.sub().fn_sigs(a, b));
self.sub().fn_sigs(b, a) self.sub().fn_sigs(b, a)
} }
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>> { -> cres<'tcx, ty::PolyTraitRef<'tcx>>
try!(self.sub().trait_refs(a, b)); {
self.sub().trait_refs(b, a) try!(self.sub().poly_trait_refs(a, b));
self.sub().poly_trait_refs(b, a)
} }
} }

View File

@ -1647,13 +1647,13 @@ impl<'tcx> Resolvable<'tcx> for Ty<'tcx> {
} }
} }
impl<'tcx> Resolvable<'tcx> for Rc<ty::TraitRef<'tcx>> { impl<'tcx> Resolvable<'tcx> for Rc<ty::PolyTraitRef<'tcx>> {
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>) fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>)
-> Rc<ty::TraitRef<'tcx>> { -> Rc<ty::PolyTraitRef<'tcx>> {
Rc::new(infcx.resolve_type_vars_if_possible(&**self)) Rc::new(infcx.resolve_type_vars_if_possible(&**self))
} }
fn contains_error(&self) -> bool { fn contains_error(&self) -> bool {
ty::trait_ref_contains_error(&**self) ty::trait_ref_contains_error(&self.value)
} }
} }

View File

@ -126,8 +126,8 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
self.higher_ranked_glb(a, b) self.higher_ranked_glb(a, b)
} }
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>> { -> cres<'tcx, ty::PolyTraitRef<'tcx>> {
self.higher_ranked_glb(a, b) self.higher_ranked_glb(a, b)
} }
} }

View File

@ -377,21 +377,13 @@ impl<'tcx> HigherRankedCombineable<'tcx> for ty::FnSig<'tcx> {
} }
} }
impl<'tcx> HigherRankedCombineable<'tcx> for ty::TraitRef<'tcx> { impl<'tcx> HigherRankedCombineable<'tcx> for ty::PolyTraitRef<'tcx> {
fn super_combine<C:Combine<'tcx>>(combiner: &C, fn super_combine<C:Combine<'tcx>>(combiner: &C,
a: &ty::TraitRef<'tcx>, a: &ty::PolyTraitRef<'tcx>,
b: &ty::TraitRef<'tcx>) b: &ty::PolyTraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>> -> cres<'tcx, ty::PolyTraitRef<'tcx>>
{ {
// Different traits cannot be related Ok(ty::bind(try!(combiner.trait_refs(&a.value, &b.value))))
if a.def_id != b.def_id {
Err(ty::terr_traits(
combine::expected_found(combiner, a.def_id, b.def_id)))
} else {
let substs = try!(combiner.substs(a.def_id, &a.substs, &b.substs));
Ok(ty::TraitRef { def_id: a.def_id,
substs: substs })
}
} }
} }

View File

@ -122,8 +122,8 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
super_lattice_tys(self, a, b) super_lattice_tys(self, a, b)
} }
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>> { -> cres<'tcx, ty::PolyTraitRef<'tcx>> {
self.higher_ranked_lub(a, b) self.higher_ranked_lub(a, b)
} }
} }

View File

@ -133,7 +133,7 @@ impl Copy for TypeOrigin {}
#[deriving(Clone, Show)] #[deriving(Clone, Show)]
pub enum ValuePairs<'tcx> { pub enum ValuePairs<'tcx> {
Types(ty::expected_found<Ty<'tcx>>), Types(ty::expected_found<Ty<'tcx>>),
TraitRefs(ty::expected_found<Rc<ty::TraitRef<'tcx>>>), TraitRefs(ty::expected_found<Rc<ty::PolyTraitRef<'tcx>>>),
} }
/// The trace designates the path through inference that we took to /// The trace designates the path through inference that we took to
@ -402,17 +402,17 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|| cx.eq_types(a_is_expected, origin, a, b)) || cx.eq_types(a_is_expected, origin, a, b))
} }
pub fn mk_sub_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
a_is_expected: bool, a_is_expected: bool,
origin: TypeOrigin, origin: TypeOrigin,
a: Rc<ty::TraitRef<'tcx>>, a: Rc<ty::PolyTraitRef<'tcx>>,
b: Rc<ty::TraitRef<'tcx>>) b: Rc<ty::PolyTraitRef<'tcx>>)
-> ures<'tcx> -> ures<'tcx>
{ {
debug!("mk_sub_trait_refs({} <: {})", debug!("mk_sub_trait_refs({} <: {})",
a.repr(cx.tcx), b.repr(cx.tcx)); a.repr(cx.tcx), b.repr(cx.tcx));
cx.commit_if_ok( cx.commit_if_ok(
|| cx.sub_trait_refs(a_is_expected, origin, a.clone(), b.clone())) || cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
} }
fn expected_found<T>(a_is_expected: bool, fn expected_found<T>(a_is_expected: bool,
@ -679,12 +679,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}) })
} }
pub fn sub_trait_refs(&self, pub fn sub_poly_trait_refs(&self,
a_is_expected: bool, a_is_expected: bool,
origin: TypeOrigin, origin: TypeOrigin,
a: Rc<ty::TraitRef<'tcx>>, a: Rc<ty::PolyTraitRef<'tcx>>,
b: Rc<ty::TraitRef<'tcx>>) b: Rc<ty::PolyTraitRef<'tcx>>)
-> ures<'tcx> -> ures<'tcx>
{ {
debug!("sub_trait_refs({} <: {})", debug!("sub_trait_refs({} <: {})",
a.repr(self.tcx), a.repr(self.tcx),
@ -695,7 +695,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
values: TraitRefs(expected_found(a_is_expected, values: TraitRefs(expected_found(a_is_expected,
a.clone(), b.clone())) a.clone(), b.clone()))
}; };
self.sub(a_is_expected, trace).trait_refs(&*a, &*b).to_ures() self.sub(a_is_expected, trace).poly_trait_refs(&*a, &*b).to_ures()
}) })
} }
} }

View File

@ -160,8 +160,8 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
self.higher_ranked_sub(a, b) self.higher_ranked_sub(a, b)
} }
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>> { -> cres<'tcx, ty::PolyTraitRef<'tcx>> {
self.higher_ranked_sub(a, b) self.higher_ranked_sub(a, b)
} }
} }

View File

@ -257,8 +257,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
}; };
let tr = ty::impl_trait_ref(self.tcx, local_def(item.id)); let tr = ty::impl_trait_ref(self.tcx, local_def(item.id));
let public_trait = tr.clone().map_or(false, |tr| { let public_trait = tr.clone().map_or(false, |tr| {
!is_local(tr.def_id) || !is_local(tr.value.def_id) ||
self.exported_items.contains(&tr.def_id.node) self.exported_items.contains(&tr.value.def_id.node)
}); });
if public_ty || public_trait { if public_ty || public_trait {
@ -407,7 +407,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
match ty::impl_trait_ref(self.tcx, id) { match ty::impl_trait_ref(self.tcx, id) {
Some(t) => { Some(t) => {
debug!("privacy - impl of trait {}", id); debug!("privacy - impl of trait {}", id);
self.def_privacy(t.def_id) self.def_privacy(t.value.def_id)
} }
None => { None => {
debug!("privacy - found a method {}", debug!("privacy - found a method {}",
@ -432,7 +432,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
match ty::impl_trait_ref(self.tcx, id) { match ty::impl_trait_ref(self.tcx, id) {
Some(t) => { Some(t) => {
debug!("privacy - impl of trait {}", id); debug!("privacy - impl of trait {}", id);
self.def_privacy(t.def_id) self.def_privacy(t.value.def_id)
} }
None => { None => {
debug!("privacy - found a typedef {}", debug!("privacy - found a typedef {}",
@ -811,7 +811,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// is whether the trait itself is accessible or not. // is whether the trait itself is accessible or not.
MethodTypeParam(MethodParam { ref trait_ref, .. }) | MethodTypeParam(MethodParam { ref trait_ref, .. }) |
MethodTraitObject(MethodObject { ref trait_ref, .. }) => { MethodTraitObject(MethodObject { ref trait_ref, .. }) => {
self.report_error(self.ensure_public(span, trait_ref.def_id, self.report_error(self.ensure_public(span, trait_ref.def_id(),
None, "source trait")); None, "source trait"));
} }
} }

View File

@ -65,15 +65,15 @@ pub fn impl_is_local(tcx: &ty::ctxt,
debug!("trait_ref={}", trait_ref.repr(tcx)); debug!("trait_ref={}", trait_ref.repr(tcx));
// If the trait is local to the crate, ok. // If the trait is local to the crate, ok.
if trait_ref.def_id.krate == ast::LOCAL_CRATE { if trait_ref.value.def_id.krate == ast::LOCAL_CRATE {
debug!("trait {} is local to current crate", debug!("trait {} is local to current crate",
trait_ref.def_id.repr(tcx)); trait_ref.value.def_id.repr(tcx));
return true; return true;
} }
// Otherwise, at least one of the input types must be local to the // Otherwise, at least one of the input types must be local to the
// crate. // crate.
trait_ref.input_types().iter().any(|&t| ty_is_local(tcx, t)) trait_ref.value.input_types().iter().any(|&t| ty_is_local(tcx, t))
} }
pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
@ -143,7 +143,7 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
} }
ty::ty_trait(ref tt) => { ty::ty_trait(ref tt) => {
tt.principal.def_id.krate == ast::LOCAL_CRATE tt.principal.value.def_id.krate == ast::LOCAL_CRATE
} }
// Type parameters may be bound to types that are not local to // Type parameters may be bound to types that are not local to

View File

@ -28,7 +28,7 @@ use super::ObligationCause;
use super::PredicateObligation; use super::PredicateObligation;
use super::Selection; use super::Selection;
use super::select::SelectionContext; use super::select::SelectionContext;
use super::trait_ref_for_builtin_bound; use super::poly_trait_ref_for_builtin_bound;
use super::Unimplemented; use super::Unimplemented;
/// The fulfillment context is used to drive trait resolution. It /// The fulfillment context is used to drive trait resolution. It
@ -107,7 +107,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
builtin_bound: ty::BuiltinBound, builtin_bound: ty::BuiltinBound,
cause: ObligationCause<'tcx>) cause: ObligationCause<'tcx>)
{ {
match trait_ref_for_builtin_bound(tcx, builtin_bound, ty) { match poly_trait_ref_for_builtin_bound(tcx, builtin_bound, ty) {
Ok(trait_ref) => { Ok(trait_ref) => {
self.register_trait_ref(tcx, trait_ref, cause); self.register_trait_ref(tcx, trait_ref, cause);
} }
@ -117,7 +117,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn register_trait_ref<'a>(&mut self, pub fn register_trait_ref<'a>(&mut self,
tcx: &ty::ctxt<'tcx>, tcx: &ty::ctxt<'tcx>,
trait_ref: Rc<ty::TraitRef<'tcx>>, trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
cause: ObligationCause<'tcx>) cause: ObligationCause<'tcx>)
{ {
/*! /*!

View File

@ -33,7 +33,7 @@ pub use self::util::supertraits;
pub use self::util::Supertraits; pub use self::util::Supertraits;
pub use self::util::search_trait_and_supertraits_from_bound; pub use self::util::search_trait_and_supertraits_from_bound;
pub use self::util::transitive_bounds; pub use self::util::transitive_bounds;
pub use self::util::trait_ref_for_builtin_bound; pub use self::util::poly_trait_ref_for_builtin_bound;
mod coherence; mod coherence;
mod fulfill; mod fulfill;
@ -54,7 +54,7 @@ pub struct Obligation<'tcx, T> {
} }
pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
pub type TraitObligation<'tcx> = Obligation<'tcx, Rc<ty::TraitRef<'tcx>>>; pub type TraitObligation<'tcx> = Obligation<'tcx, Rc<ty::PolyTraitRef<'tcx>>>;
/// Why did we incur this obligation? Used for error reporting. /// Why did we incur this obligation? Used for error reporting.
#[deriving(Copy, Clone)] #[deriving(Copy, Clone)]
@ -115,7 +115,9 @@ pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
pub enum SelectionError<'tcx> { pub enum SelectionError<'tcx> {
Unimplemented, Unimplemented,
Overflow, Overflow,
OutputTypeParameterMismatch(Rc<ty::TraitRef<'tcx>>, Rc<ty::TraitRef<'tcx>>, ty::type_err<'tcx>), OutputTypeParameterMismatch(Rc<ty::PolyTraitRef<'tcx>>,
Rc<ty::PolyTraitRef<'tcx>>,
ty::type_err<'tcx>),
} }
pub struct FulfillmentError<'tcx> { pub struct FulfillmentError<'tcx> {
@ -226,7 +228,7 @@ pub struct VtableBuiltinData<N> {
#[deriving(PartialEq,Eq,Clone)] #[deriving(PartialEq,Eq,Clone)]
pub struct VtableParamData<'tcx> { pub struct VtableParamData<'tcx> {
// In the above example, this would `Eq` // In the above example, this would `Eq`
pub bound: Rc<ty::TraitRef<'tcx>>, pub bound: Rc<ty::PolyTraitRef<'tcx>>,
} }
/// True if neither the trait nor self type is local. Note that `impl_def_id` must refer to an impl /// True if neither the trait nor self type is local. Note that `impl_def_id` must refer to an impl
@ -278,7 +280,7 @@ impl<'tcx,O> Obligation<'tcx,O> {
} }
} }
impl<'tcx> Obligation<'tcx,Rc<ty::TraitRef<'tcx>>> { impl<'tcx> TraitObligation<'tcx> {
pub fn self_ty(&self) -> Ty<'tcx> { pub fn self_ty(&self) -> Ty<'tcx> {
self.trait_ref.self_ty() self.trait_ref.self_ty()
} }

View File

@ -28,7 +28,7 @@ use super::{util};
use middle::fast_reject; use middle::fast_reject;
use middle::mem_categorization::Typer; use middle::mem_categorization::Typer;
use middle::subst::{Subst, Substs, VecPerParamSpace}; use middle::subst::{Subst, Substs, VecPerParamSpace};
use middle::ty::{mod, Ty}; use middle::ty::{mod, Ty, RegionEscape};
use middle::infer; use middle::infer;
use middle::infer::{InferCtxt, TypeSkolemizer}; use middle::infer::{InferCtxt, TypeSkolemizer};
use middle::ty_fold::TypeFoldable; use middle::ty_fold::TypeFoldable;
@ -74,14 +74,14 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {
/// Trait ref from `obligation` but skolemized with the /// Trait ref from `obligation` but skolemized with the
/// selection-context's skolemizer. Used to check for recursion. /// selection-context's skolemizer. Used to check for recursion.
skol_trait_ref: Rc<ty::TraitRef<'tcx>>, skol_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
previous: Option<&'prev TraitObligationStack<'prev, 'tcx>> previous: Option<&'prev TraitObligationStack<'prev, 'tcx>>
} }
#[deriving(Clone)] #[deriving(Clone)]
pub struct SelectionCache<'tcx> { pub struct SelectionCache<'tcx> {
hashmap: RefCell<HashMap<Rc<ty::TraitRef<'tcx>>, hashmap: RefCell<HashMap<Rc<ty::PolyTraitRef<'tcx>>,
SelectionResult<'tcx, Candidate<'tcx>>>>, SelectionResult<'tcx, Candidate<'tcx>>>>,
} }
@ -347,13 +347,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// This suffices to allow chains like `FnMut` implemented in // This suffices to allow chains like `FnMut` implemented in
// terms of `Fn` etc, but we could probably make this more // terms of `Fn` etc, but we could probably make this more
// precise still. // precise still.
let input_types = stack.skol_trait_ref.input_types(); let input_types = stack.skol_trait_ref.value.input_types();
let unbound_input_types = input_types.iter().any(|&t| ty::type_is_skolemized(t)); let unbound_input_types = input_types.iter().any(|&t| ty::type_is_skolemized(t));
if if
unbound_input_types && unbound_input_types &&
(self.intercrate || (self.intercrate ||
stack.iter().skip(1).any( stack.iter().skip(1).any(
|prev| stack.skol_trait_ref.def_id == prev.skol_trait_ref.def_id)) |prev| stack.skol_trait_ref.value.def_id == prev.skol_trait_ref.value.def_id))
{ {
debug!("evaluate_stack({}) --> unbound argument, recursion --> ambiguous", debug!("evaluate_stack({}) --> unbound argument, recursion --> ambiguous",
stack.skol_trait_ref.repr(self.tcx())); stack.skol_trait_ref.repr(self.tcx()));
@ -569,7 +569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
fn pick_candidate_cache(&self, fn pick_candidate_cache(&self,
cache_skol_trait_ref: &Rc<ty::TraitRef<'tcx>>) cache_skol_trait_ref: &Rc<ty::PolyTraitRef<'tcx>>)
-> &SelectionCache<'tcx> -> &SelectionCache<'tcx>
{ {
// High-level idea: we have to decide whether to consult the // High-level idea: we have to decide whether to consult the
@ -591,7 +591,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If the trait refers to any parameters in scope, then use // If the trait refers to any parameters in scope, then use
// the cache of the param-environment. // the cache of the param-environment.
if if
cache_skol_trait_ref.input_types().iter().any( cache_skol_trait_ref.value.input_types().iter().any(
|&t| ty::type_has_self(t) || ty::type_has_params(t)) |&t| ty::type_has_self(t) || ty::type_has_params(t))
{ {
return &self.param_env.selection_cache; return &self.param_env.selection_cache;
@ -604,7 +604,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// See the discussion in doc.rs for more details. // See the discussion in doc.rs for more details.
if if
!self.param_env.caller_bounds.is_empty() && !self.param_env.caller_bounds.is_empty() &&
cache_skol_trait_ref.input_types().iter().any( cache_skol_trait_ref.value.input_types().iter().any(
|&t| ty::type_has_ty_infer(t)) |&t| ty::type_has_ty_infer(t))
{ {
return &self.param_env.selection_cache; return &self.param_env.selection_cache;
@ -615,7 +615,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
fn check_candidate_cache(&mut self, fn check_candidate_cache(&mut self,
cache_skol_trait_ref: Rc<ty::TraitRef<'tcx>>) cache_skol_trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
-> Option<SelectionResult<'tcx, Candidate<'tcx>>> -> Option<SelectionResult<'tcx, Candidate<'tcx>>>
{ {
let cache = self.pick_candidate_cache(&cache_skol_trait_ref); let cache = self.pick_candidate_cache(&cache_skol_trait_ref);
@ -624,7 +624,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
fn insert_candidate_cache(&mut self, fn insert_candidate_cache(&mut self,
cache_skol_trait_ref: Rc<ty::TraitRef<'tcx>>, cache_skol_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
candidate: SelectionResult<'tcx, Candidate<'tcx>>) candidate: SelectionResult<'tcx, Candidate<'tcx>>)
{ {
let cache = self.pick_candidate_cache(&cache_skol_trait_ref); let cache = self.pick_candidate_cache(&cache_skol_trait_ref);
@ -648,7 +648,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Other bounds. Consider both in-scope bounds from fn decl // Other bounds. Consider both in-scope bounds from fn decl
// and applicable impls. There is a certain set of precedence rules here. // and applicable impls. There is a certain set of precedence rules here.
match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.def_id) { match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.value.def_id) {
Some(ty::BoundCopy) => { Some(ty::BoundCopy) => {
debug!("obligation self ty is {}", debug!("obligation self ty is {}",
obligation.self_ty().repr(self.tcx())); obligation.self_ty().repr(self.tcx()));
@ -696,7 +696,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!("assemble_candidates_from_caller_bounds({})", debug!("assemble_candidates_from_caller_bounds({})",
obligation.repr(self.tcx())); obligation.repr(self.tcx()));
let caller_trait_refs: Vec<Rc<ty::TraitRef>> = let caller_trait_refs: Vec<_> =
self.param_env.caller_bounds.predicates.iter() self.param_env.caller_bounds.predicates.iter()
.filter_map(|o| o.to_trait()) .filter_map(|o| o.to_trait())
.collect(); .collect();
@ -731,7 +731,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates: &mut CandidateSet<'tcx>) candidates: &mut CandidateSet<'tcx>)
-> Result<(),SelectionError<'tcx>> -> Result<(),SelectionError<'tcx>>
{ {
let kind = match self.fn_family_trait_kind(obligation.trait_ref.def_id) { let kind = match self.fn_family_trait_kind(obligation.trait_ref.value.def_id) {
Some(k) => k, Some(k) => k,
None => { return Ok(()); } None => { return Ok(()); }
}; };
@ -779,7 +779,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// We provide a `Fn` impl for fn pointers. There is no need to provide // We provide a `Fn` impl for fn pointers. There is no need to provide
// the other traits (e.g. `FnMut`) since those are provided by blanket // the other traits (e.g. `FnMut`) since those are provided by blanket
// impls. // impls.
if Some(obligation.trait_ref.def_id) != self.tcx().lang_items.fn_trait() { if Some(obligation.trait_ref.value.def_id) != self.tcx().lang_items.fn_trait() {
return Ok(()); return Ok(());
} }
@ -814,7 +814,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates: &mut CandidateSet<'tcx>) candidates: &mut CandidateSet<'tcx>)
-> Result<(), SelectionError<'tcx>> -> Result<(), SelectionError<'tcx>>
{ {
let all_impls = self.all_impls(obligation.trait_ref.def_id); let all_impls = self.all_impls(obligation.trait_ref.value.def_id);
for &impl_def_id in all_impls.iter() { for &impl_def_id in all_impls.iter() {
self.infcx.probe(|| { self.infcx.probe(|| {
match self.match_impl(impl_def_id, obligation) { match self.match_impl(impl_def_id, obligation) {
@ -926,8 +926,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let origin = let origin =
infer::RelateOutputImplTypes(stack.obligation.cause.span); infer::RelateOutputImplTypes(stack.obligation.cause.span);
self.infcx self.infcx
.sub_trait_refs(false, origin, .sub_poly_trait_refs(false, origin, impl_trait_ref, vt.bound.clone())
impl_trait_ref, vt.bound.clone())
.is_ok() .is_ok()
}) })
} }
@ -1071,26 +1070,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
} }
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => { ty::ty_trait(ref data) => {
match bound { match bound {
ty::BoundSized => { ty::BoundSized => {
Err(Unimplemented) Err(Unimplemented)
} }
ty::BoundCopy | ty::BoundSync | ty::BoundSend => { ty::BoundCopy | ty::BoundSync | ty::BoundSend => {
if bounds.builtin_bounds.contains(&bound) { if data.bounds.builtin_bounds.contains(&bound) {
Ok(If(Vec::new())) Ok(If(Vec::new()))
} else { } else {
// Recursively check all supertraits to find out if any further // Recursively check all supertraits to find out if any further
// bounds are required and thus we must fulfill. // bounds are required and thus we must fulfill.
// We have to create a temp trait ref here since TyTraits don't let tmp_tr = data.principal_trait_ref_with_self_ty(ty::mk_err());
// have actual self type info (which is required for the
// supertraits iterator).
let tmp_tr = Rc::new(ty::TraitRef {
def_id: principal.def_id,
substs: principal.substs.with_self_ty(ty::mk_err())
});
for tr in util::supertraits(self.tcx(), tmp_tr) { for tr in util::supertraits(self.tcx(), tmp_tr) {
let td = ty::lookup_trait_def(self.tcx(), tr.def_id); let td = ty::lookup_trait_def(self.tcx(), tr.value.def_id);
if td.bounds.builtin_bounds.contains(&bound) { if td.bounds.builtin_bounds.contains(&bound) {
return Ok(If(Vec::new())) return Ok(If(Vec::new()))
@ -1534,10 +1527,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
vec![], vec![],
vec![], vec![],
self_ty); self_ty);
let trait_ref = Rc::new(ty::TraitRef { let trait_ref = Rc::new(ty::bind(ty::TraitRef {
def_id: obligation.trait_ref.def_id, def_id: obligation.trait_ref.def_id(),
substs: substs, substs: substs,
}); }));
let () = let () =
try!(self.confirm(obligation.cause, try!(self.confirm(obligation.cause,
@ -1577,10 +1570,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
vec![], vec![],
vec![], vec![],
obligation.self_ty()); obligation.self_ty());
let trait_ref = Rc::new(ty::TraitRef { let trait_ref = Rc::new(ty::bind(ty::TraitRef {
def_id: obligation.trait_ref.def_id, def_id: obligation.trait_ref.def_id(),
substs: substs, substs: substs,
}); }));
debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})", debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
closure_def_id.repr(self.tcx()), closure_def_id.repr(self.tcx()),
@ -1650,7 +1643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn fast_reject_trait_refs(&mut self, fn fast_reject_trait_refs(&mut self,
obligation: &TraitObligation, obligation: &TraitObligation,
impl_trait_ref: &ty::TraitRef) impl_trait_ref: &ty::PolyTraitRef)
-> bool -> bool
{ {
// We can avoid creating type variables and doing the full // We can avoid creating type variables and doing the full
@ -1673,7 +1666,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn match_trait_refs(&mut self, fn match_trait_refs(&mut self,
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
trait_ref: Rc<ty::TraitRef<'tcx>>) trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
-> Result<(),()> -> Result<(),()>
{ {
debug!("match_trait_refs: obligation={} trait_ref={}", debug!("match_trait_refs: obligation={} trait_ref={}",
@ -1681,10 +1674,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
trait_ref.repr(self.tcx())); trait_ref.repr(self.tcx()));
let origin = infer::RelateOutputImplTypes(obligation.cause.span); let origin = infer::RelateOutputImplTypes(obligation.cause.span);
match self.infcx.sub_trait_refs(false, match self.infcx.sub_poly_trait_refs(false,
origin, origin,
trait_ref, trait_ref,
obligation.trait_ref.clone()) { obligation.trait_ref.clone()) {
Ok(()) => Ok(()), Ok(()) => Ok(()),
Err(_) => Err(()), Err(_) => Err(()),
} }
@ -1783,7 +1776,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_impl_vtable(&mut self, fn confirm_impl_vtable(&mut self,
impl_def_id: ast::DefId, impl_def_id: ast::DefId,
obligation_cause: ObligationCause<'tcx>, obligation_cause: ObligationCause<'tcx>,
obligation_trait_ref: Rc<ty::TraitRef<'tcx>>, obligation_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
substs: &Substs<'tcx>) substs: &Substs<'tcx>)
-> Result<(), SelectionError<'tcx>> -> Result<(), SelectionError<'tcx>>
{ {
@ -1814,17 +1807,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// we report an error to the user. /// we report an error to the user.
fn confirm(&mut self, fn confirm(&mut self,
obligation_cause: ObligationCause, obligation_cause: ObligationCause,
obligation_trait_ref: Rc<ty::TraitRef<'tcx>>, obligation_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
expected_trait_ref: Rc<ty::TraitRef<'tcx>>) expected_trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
-> Result<(), SelectionError<'tcx>> -> Result<(), SelectionError<'tcx>>
{ {
let origin = infer::RelateOutputImplTypes(obligation_cause.span); let origin = infer::RelateOutputImplTypes(obligation_cause.span);
let obligation_trait_ref = obligation_trait_ref.clone(); let obligation_trait_ref = obligation_trait_ref.clone();
match self.infcx.sub_trait_refs(false, match self.infcx.sub_poly_trait_refs(false,
origin, origin,
expected_trait_ref.clone(), expected_trait_ref.clone(),
obligation_trait_ref.clone()) { obligation_trait_ref.clone()) {
Ok(()) => Ok(()), Ok(()) => Ok(()),
Err(e) => Err(OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e)) Err(e) => Err(OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
} }

View File

@ -47,7 +47,7 @@ struct StackEntry<'tcx> {
pub fn elaborate_trait_ref<'cx, 'tcx>( pub fn elaborate_trait_ref<'cx, 'tcx>(
tcx: &'cx ty::ctxt<'tcx>, tcx: &'cx ty::ctxt<'tcx>,
trait_ref: Rc<ty::TraitRef<'tcx>>) trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
-> Elaborator<'cx, 'tcx> -> Elaborator<'cx, 'tcx>
{ {
elaborate_predicates(tcx, vec![ty::Predicate::Trait(trait_ref)]) elaborate_predicates(tcx, vec![ty::Predicate::Trait(trait_ref)])
@ -55,7 +55,7 @@ pub fn elaborate_trait_ref<'cx, 'tcx>(
pub fn elaborate_trait_refs<'cx, 'tcx>( pub fn elaborate_trait_refs<'cx, 'tcx>(
tcx: &'cx ty::ctxt<'tcx>, tcx: &'cx ty::ctxt<'tcx>,
trait_refs: &[Rc<ty::TraitRef<'tcx>>]) trait_refs: &[Rc<ty::PolyTraitRef<'tcx>>])
-> Elaborator<'cx, 'tcx> -> Elaborator<'cx, 'tcx>
{ {
let predicates = trait_refs.iter() let predicates = trait_refs.iter()
@ -174,7 +174,7 @@ pub struct Supertraits<'cx, 'tcx:'cx> {
} }
pub fn supertraits<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>, pub fn supertraits<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>,
trait_ref: Rc<ty::TraitRef<'tcx>>) trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
-> Supertraits<'cx, 'tcx> -> Supertraits<'cx, 'tcx>
{ {
let elaborator = elaborate_trait_ref(tcx, trait_ref); let elaborator = elaborate_trait_ref(tcx, trait_ref);
@ -182,15 +182,15 @@ pub fn supertraits<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>,
} }
pub fn transitive_bounds<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>, pub fn transitive_bounds<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>,
bounds: &[Rc<ty::TraitRef<'tcx>>]) bounds: &[Rc<ty::PolyTraitRef<'tcx>>])
-> Supertraits<'cx, 'tcx> -> Supertraits<'cx, 'tcx>
{ {
let elaborator = elaborate_trait_refs(tcx, bounds); let elaborator = elaborate_trait_refs(tcx, bounds);
Supertraits { elaborator: elaborator } Supertraits { elaborator: elaborator }
} }
impl<'cx, 'tcx> Iterator<Rc<ty::TraitRef<'tcx>>> for Supertraits<'cx, 'tcx> { impl<'cx, 'tcx> Iterator<Rc<ty::PolyTraitRef<'tcx>>> for Supertraits<'cx, 'tcx> {
fn next(&mut self) -> Option<Rc<ty::TraitRef<'tcx>>> { fn next(&mut self) -> Option<Rc<ty::PolyTraitRef<'tcx>>> {
loop { loop {
match self.elaborator.next() { match self.elaborator.next() {
None => { None => {
@ -266,18 +266,18 @@ pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
}) })
} }
pub fn trait_ref_for_builtin_bound<'tcx>( pub fn poly_trait_ref_for_builtin_bound<'tcx>(
tcx: &ty::ctxt<'tcx>, tcx: &ty::ctxt<'tcx>,
builtin_bound: ty::BuiltinBound, builtin_bound: ty::BuiltinBound,
param_ty: Ty<'tcx>) param_ty: Ty<'tcx>)
-> Result<Rc<ty::TraitRef<'tcx>>, ErrorReported> -> Result<Rc<ty::PolyTraitRef<'tcx>>, ErrorReported>
{ {
match tcx.lang_items.from_builtin_kind(builtin_bound) { match tcx.lang_items.from_builtin_kind(builtin_bound) {
Ok(def_id) => { Ok(def_id) => {
Ok(Rc::new(ty::TraitRef { Ok(Rc::new(ty::bind(ty::TraitRef {
def_id: def_id, def_id: def_id,
substs: Substs::empty().with_self_ty(param_ty) substs: Substs::empty().with_self_ty(param_ty)
})) })))
} }
Err(e) => { Err(e) => {
tcx.sess.err(e.as_slice()); tcx.sess.err(e.as_slice());
@ -294,7 +294,7 @@ pub fn predicate_for_builtin_bound<'tcx>(
param_ty: Ty<'tcx>) param_ty: Ty<'tcx>)
-> Result<PredicateObligation<'tcx>, ErrorReported> -> Result<PredicateObligation<'tcx>, ErrorReported>
{ {
let trait_ref = try!(trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty)); let trait_ref = try!(poly_trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty));
Ok(Obligation { Ok(Obligation {
cause: cause, cause: cause,
recursion_depth: recursion_depth, recursion_depth: recursion_depth,
@ -306,14 +306,14 @@ pub fn predicate_for_builtin_bound<'tcx>(
/// of caller obligations), search through the trait and supertraits to find one where `test(d)` is /// of caller obligations), search through the trait and supertraits to find one where `test(d)` is
/// true, where `d` is the def-id of the trait/supertrait. If any is found, return `Some(p)` where /// true, where `d` is the def-id of the trait/supertrait. If any is found, return `Some(p)` where
/// `p` is the path to that trait/supertrait. Else `None`. /// `p` is the path to that trait/supertrait. Else `None`.
pub fn search_trait_and_supertraits_from_bound<'tcx, F>(tcx: &ty::ctxt<'tcx>, pub fn search_trait_and_supertraits_from_bound<'tcx,F>(tcx: &ty::ctxt<'tcx>,
caller_bound: Rc<ty::TraitRef<'tcx>>, caller_bound: Rc<ty::PolyTraitRef<'tcx>>,
mut test: F) mut test: F)
-> Option<VtableParamData<'tcx>> where -> Option<VtableParamData<'tcx>>
F: FnMut(ast::DefId) -> bool, where F: FnMut(ast::DefId) -> bool,
{ {
for bound in transitive_bounds(tcx, &[caller_bound]) { for bound in transitive_bounds(tcx, &[caller_bound]) {
if test(bound.def_id) { if test(bound.def_id()) {
let vtable_param = VtableParamData { bound: bound }; let vtable_param = VtableParamData { bound: bound };
return Some(vtable_param); return Some(vtable_param);
} }

View File

@ -479,7 +479,7 @@ pub enum MethodOrigin<'tcx> {
pub struct MethodParam<'tcx> { pub struct MethodParam<'tcx> {
// the precise trait reference that occurs as a bound -- this may // the precise trait reference that occurs as a bound -- this may
// be a supertrait of what the user actually typed. // be a supertrait of what the user actually typed.
pub trait_ref: Rc<ty::TraitRef<'tcx>>, pub trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
// index of uint in the list of methods for the trait // index of uint in the list of methods for the trait
pub method_num: uint, pub method_num: uint,
@ -489,7 +489,7 @@ pub struct MethodParam<'tcx> {
#[deriving(Clone, Show)] #[deriving(Clone, Show)]
pub struct MethodObject<'tcx> { pub struct MethodObject<'tcx> {
// the (super)trait containing the method to be invoked // the (super)trait containing the method to be invoked
pub trait_ref: Rc<ty::TraitRef<'tcx>>, pub trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
// the actual base trait id of the object // the actual base trait id of the object
pub object_trait_id: ast::DefId, pub object_trait_id: ast::DefId,
@ -609,7 +609,7 @@ pub enum vtable_origin<'tcx> {
// For every explicit cast into an object type, maps from the cast // For every explicit cast into an object type, maps from the cast
// expr to the associated trait ref. // expr to the associated trait ref.
pub type ObjectCastMap<'tcx> = RefCell<NodeMap<Rc<ty::TraitRef<'tcx>>>>; pub type ObjectCastMap<'tcx> = RefCell<NodeMap<Rc<ty::PolyTraitRef<'tcx>>>>;
/// A restriction that certain types must be the same size. The use of /// A restriction that certain types must be the same size. The use of
/// `transmute` gives rise to these restrictions. /// `transmute` gives rise to these restrictions.
@ -665,7 +665,7 @@ pub struct ctxt<'tcx> {
/// A cache for the trait_items() routine /// A cache for the trait_items() routine
pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem<'tcx>>>>>, pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem<'tcx>>>>>,
pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef<'tcx>>>>>, pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::PolyTraitRef<'tcx>>>>>,
pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>, pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>, pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
@ -1308,10 +1308,23 @@ pub enum sty<'tcx> {
#[deriving(Clone, PartialEq, Eq, Hash, Show)] #[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct TyTrait<'tcx> { pub struct TyTrait<'tcx> {
// Principal trait reference. // Principal trait reference.
pub principal: TraitRef<'tcx>, // would use Rc<TraitRef>, but it runs afoul of some static rules pub principal: PolyTraitRef<'tcx>, // would use Rc<TraitRef>, but it runs afoul of some static rules
pub bounds: ExistentialBounds pub bounds: ExistentialBounds
} }
impl<'tcx> TyTrait<'tcx> {
/// Object types don't have a self-type specified. Therefore, when
/// we convert the principal trait-ref into a normal trait-ref,
/// you must give *some* self-type. A common choice is `mk_err()`
/// or some skolemized type.
pub fn principal_trait_ref_with_self_ty(&self, self_ty: Ty<'tcx>) -> Rc<ty::PolyTraitRef<'tcx>> {
Rc::new(ty::bind(ty::TraitRef {
def_id: self.principal.value.def_id,
substs: self.principal.value.substs.with_self_ty(self_ty),
}))
}
}
/// A complete reference to a trait. These take numerous guises in syntax, /// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where clause: /// but perhaps the most recognizable form is in a where clause:
/// ///
@ -1333,6 +1346,26 @@ pub struct TraitRef<'tcx> {
pub substs: Substs<'tcx>, pub substs: Substs<'tcx>,
} }
pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
impl<'tcx> PolyTraitRef<'tcx> {
pub fn self_ty(&self) -> Ty<'tcx> {
self.value.self_ty()
}
pub fn def_id(&self) -> ast::DefId {
self.value.def_id
}
pub fn substs(&self) -> &Substs<'tcx> {
&self.value.substs
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
self.value.input_types()
}
}
/// Binder serves as a synthetic binder for lifetimes. It is used when /// Binder serves as a synthetic binder for lifetimes. It is used when
/// we wish to replace the escaping higher-ranked lifetimes in a type /// we wish to replace the escaping higher-ranked lifetimes in a type
/// or something else that is not itself a binder (this is because the /// or something else that is not itself a binder (this is because the
@ -1416,7 +1449,7 @@ impl<'tcx> Copy for type_err<'tcx> {}
pub struct ParamBounds<'tcx> { pub struct ParamBounds<'tcx> {
pub region_bounds: Vec<ty::Region>, pub region_bounds: Vec<ty::Region>,
pub builtin_bounds: BuiltinBounds, pub builtin_bounds: BuiltinBounds,
pub trait_bounds: Vec<Rc<TraitRef<'tcx>>> pub trait_bounds: Vec<Rc<PolyTraitRef<'tcx>>>
} }
/// Bounds suitable for an existentially quantified type parameter /// Bounds suitable for an existentially quantified type parameter
@ -1657,7 +1690,7 @@ pub enum Predicate<'tcx> {
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C` /// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the parameters in the `TypeSpace`. /// would be the parameters in the `TypeSpace`.
Trait(Rc<TraitRef<'tcx>>), Trait(Rc<PolyTraitRef<'tcx>>),
/// where `T1 == T2`. /// where `T1 == T2`.
Equate(/* T1 */ Ty<'tcx>, /* T2 */ Ty<'tcx>), Equate(/* T1 */ Ty<'tcx>, /* T2 */ Ty<'tcx>),
@ -1680,7 +1713,7 @@ impl<'tcx> Predicate<'tcx> {
} }
} }
pub fn to_trait(&self) -> Option<Rc<TraitRef<'tcx>>> { pub fn to_trait(&self) -> Option<Rc<PolyTraitRef<'tcx>>> {
match *self { match *self {
Predicate::Trait(ref t) => { Predicate::Trait(ref t) => {
Some(t.clone()) Some(t.clone())
@ -1748,14 +1781,6 @@ impl<'tcx> TraitRef<'tcx> {
// associated types. // associated types.
self.substs.types.as_slice() self.substs.types.as_slice()
} }
pub fn has_escaping_regions(&self) -> bool {
self.substs.has_regions_escaping_depth(1)
}
pub fn has_bound_regions(&self) -> bool {
self.substs.has_regions_escaping_depth(0)
}
} }
/// When type checking, we use the `ParameterEnvironment` to track /// When type checking, we use the `ParameterEnvironment` to track
@ -2160,7 +2185,7 @@ impl FlagComputation {
&ty_trait(box TyTrait { ref principal, ref bounds }) => { &ty_trait(box TyTrait { ref principal, ref bounds }) => {
let mut computation = FlagComputation::new(); let mut computation = FlagComputation::new();
computation.add_substs(&principal.substs); computation.add_substs(principal.substs());
self.add_bound_computation(&computation); self.add_bound_computation(&computation);
self.add_bounds(bounds); self.add_bounds(bounds);
@ -2366,7 +2391,7 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>, pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
principal: ty::TraitRef<'tcx>, principal: ty::PolyTraitRef<'tcx>,
bounds: ExistentialBounds) bounds: ExistentialBounds)
-> Ty<'tcx> { -> Ty<'tcx> {
// take a copy of substs so that we own the vectors inside // take a copy of substs so that we own the vectors inside
@ -2439,7 +2464,7 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
maybe_walk_ty(tm.ty, f); maybe_walk_ty(tm.ty, f);
} }
ty_trait(box TyTrait { ref principal, .. }) => { ty_trait(box TyTrait { ref principal, .. }) => {
for subty in principal.substs.types.iter() { for subty in principal.substs().types.iter() {
maybe_walk_ty(*subty, |x| f(x)); maybe_walk_ty(*subty, |x| f(x));
} }
} }
@ -3182,7 +3207,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
fn kind_bounds_to_contents<'tcx>(cx: &ctxt<'tcx>, fn kind_bounds_to_contents<'tcx>(cx: &ctxt<'tcx>,
bounds: BuiltinBounds, bounds: BuiltinBounds,
traits: &[Rc<TraitRef<'tcx>>]) traits: &[Rc<PolyTraitRef<'tcx>>])
-> TypeContents { -> TypeContents {
let _i = indenter(); let _i = indenter();
let mut tc = TC::All; let mut tc = TC::All;
@ -3198,7 +3223,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
// those inherited from traits with builtin-kind-supertraits. // those inherited from traits with builtin-kind-supertraits.
fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>, fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>,
bounds: BuiltinBounds, bounds: BuiltinBounds,
traits: &[Rc<TraitRef<'tcx>>], traits: &[Rc<PolyTraitRef<'tcx>>],
mut f: F) where mut f: F) where
F: FnMut(BuiltinBound), F: FnMut(BuiltinBound),
{ {
@ -3207,7 +3232,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
} }
each_bound_trait_and_supertraits(cx, traits, |trait_ref| { each_bound_trait_and_supertraits(cx, traits, |trait_ref| {
let trait_def = lookup_trait_def(cx, trait_ref.def_id); let trait_def = lookup_trait_def(cx, trait_ref.def_id());
for bound in trait_def.bounds.builtin_bounds.iter() { for bound in trait_def.bounds.builtin_bounds.iter() {
f(bound); f(bound);
} }
@ -4393,7 +4418,7 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
ty_bare_fn(_) => "extern fn".to_string(), ty_bare_fn(_) => "extern fn".to_string(),
ty_closure(_) => "fn".to_string(), ty_closure(_) => "fn".to_string(),
ty_trait(ref inner) => { ty_trait(ref inner) => {
format!("trait {}", item_path_str(cx, inner.principal.def_id)) format!("trait {}", item_path_str(cx, inner.principal.def_id()))
} }
ty_struct(id, _) => { ty_struct(id, _) => {
format!("struct {}", item_path_str(cx, id)) format!("struct {}", item_path_str(cx, id))
@ -4760,7 +4785,7 @@ pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
} }
pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-> Option<Rc<TraitRef<'tcx>>> { -> Option<Rc<PolyTraitRef<'tcx>>> {
memoized(&cx.impl_trait_cache, id, |id: ast::DefId| { memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
if id.krate == ast::LOCAL_CRATE { if id.krate == ast::LOCAL_CRATE {
debug!("(impl_trait_ref) searching for trait impl {}", id); debug!("(impl_trait_ref) searching for trait impl {}", id);
@ -4770,7 +4795,9 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
ast::ItemImpl(_, _, ref opt_trait, _, _) => { ast::ItemImpl(_, _, ref opt_trait, _, _) => {
match opt_trait { match opt_trait {
&Some(ref t) => { &Some(ref t) => {
Some(ty::node_id_to_trait_ref(cx, t.ref_id)) let trait_ref =
(*ty::node_id_to_trait_ref(cx, t.ref_id)).clone();
Some(Rc::new(ty::bind(trait_ref)))
} }
&None => None &None => None
} }
@ -4813,7 +4840,7 @@ pub fn try_add_builtin_trait(
pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> { pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
match ty.sty { match ty.sty {
ty_trait(ref tt) => ty_trait(ref tt) =>
Some(tt.principal.def_id), Some(tt.principal.def_id()),
ty_struct(id, _) | ty_struct(id, _) |
ty_enum(id, _) | ty_enum(id, _) |
ty_unboxed_closure(id, _, _) => ty_unboxed_closure(id, _, _) =>
@ -5073,10 +5100,10 @@ pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
/// Given a reference to a trait, returns the "superbounds" declared /// Given a reference to a trait, returns the "superbounds" declared
/// on the trait, with appropriate substitutions applied. /// on the trait, with appropriate substitutions applied.
pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>, pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
trait_ref: &TraitRef<'tcx>) trait_ref: &PolyTraitRef<'tcx>)
-> Vec<ty::Predicate<'tcx>> -> Vec<ty::Predicate<'tcx>>
{ {
let trait_def = lookup_trait_def(tcx, trait_ref.def_id); let trait_def = lookup_trait_def(tcx, trait_ref.def_id());
debug!("bounds_for_trait_ref(trait_def={}, trait_ref={})", debug!("bounds_for_trait_ref(trait_def={}, trait_ref={})",
trait_def.repr(tcx), trait_ref.repr(tcx)); trait_def.repr(tcx), trait_ref.repr(tcx));
@ -5149,8 +5176,9 @@ pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
trait_def.bounds.trait_bounds trait_def.bounds.trait_bounds
.iter() .iter()
.map(|bound_trait_ref| { .map(|bound_trait_ref| {
ty::TraitRef::new(bound_trait_ref.def_id, ty::bind(
bound_trait_ref.substs.subst(tcx, &trait_ref.substs)) ty::TraitRef::new(bound_trait_ref.def_id(),
bound_trait_ref.substs().subst(tcx, trait_ref.substs())))
}) })
.map(|bound_trait_ref| Rc::new(bound_trait_ref)) .map(|bound_trait_ref| Rc::new(bound_trait_ref))
.collect(); .collect();
@ -5161,9 +5189,9 @@ pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
// The region bounds and builtin bounds do not currently introduce // The region bounds and builtin bounds do not currently introduce
// binders so we can just substitute in a straightforward way here. // binders so we can just substitute in a straightforward way here.
let region_bounds = let region_bounds =
trait_def.bounds.region_bounds.subst(tcx, &trait_ref.substs); trait_def.bounds.region_bounds.subst(tcx, trait_ref.substs());
let builtin_bounds = let builtin_bounds =
trait_def.bounds.builtin_bounds.subst(tcx, &trait_ref.substs); trait_def.bounds.builtin_bounds.subst(tcx, trait_ref.substs());
let bounds = ty::ParamBounds { let bounds = ty::ParamBounds {
trait_bounds: trait_bounds, trait_bounds: trait_bounds,
@ -5183,7 +5211,7 @@ pub fn predicates<'tcx>(
let mut vec = Vec::new(); let mut vec = Vec::new();
for builtin_bound in bounds.builtin_bounds.iter() { for builtin_bound in bounds.builtin_bounds.iter() {
match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) { match traits::poly_trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) {
Ok(trait_ref) => { vec.push(Predicate::Trait(trait_ref)); } Ok(trait_ref) => { vec.push(Predicate::Trait(trait_ref)); }
Err(ErrorReported) => { } Err(ErrorReported) => { }
} }
@ -5545,10 +5573,10 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
// relation on the supertraits from each bounded trait's constraint // relation on the supertraits from each bounded trait's constraint
// list. // list.
pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>, pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
bounds: &[Rc<TraitRef<'tcx>>], bounds: &[Rc<PolyTraitRef<'tcx>>],
mut f: F) mut f: F)
-> bool where -> bool where
F: FnMut(Rc<TraitRef<'tcx>>) -> bool, F: FnMut(Rc<PolyTraitRef<'tcx>>) -> bool,
{ {
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
if !f(bound_trait_ref) { if !f(bound_trait_ref) {
@ -5559,7 +5587,7 @@ pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
} }
pub fn object_region_bounds<'tcx>(tcx: &ctxt<'tcx>, pub fn object_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
opt_principal: Option<&TraitRef<'tcx>>, // None for boxed closures opt_principal: Option<&PolyTraitRef<'tcx>>, // None for closures
others: BuiltinBounds) others: BuiltinBounds)
-> Vec<ty::Region> -> Vec<ty::Region>
{ {
@ -5569,8 +5597,8 @@ pub fn object_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
let open_ty = ty::mk_infer(tcx, SkolemizedTy(0)); let open_ty = ty::mk_infer(tcx, SkolemizedTy(0));
let opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| { let opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| {
let substs = principal.substs.with_self_ty(open_ty); let substs = principal.substs().with_self_ty(open_ty);
vec!(Rc::new(ty::TraitRef::new(principal.def_id, substs))) vec!(Rc::new(ty::bind(ty::TraitRef::new(principal.def_id(), substs))))
}); });
let param_bounds = ty::ParamBounds { let param_bounds = ty::ParamBounds {
@ -5663,7 +5691,7 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
// Record the trait->implementation mappings, if applicable. // Record the trait->implementation mappings, if applicable.
let associated_traits = csearch::get_impl_trait(tcx, impl_def_id); let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
for trait_ref in associated_traits.iter() { for trait_ref in associated_traits.iter() {
record_trait_implementation(tcx, trait_ref.def_id, impl_def_id); record_trait_implementation(tcx, trait_ref.def_id(), impl_def_id);
} }
// For any methods that use a default implementation, add them to // For any methods that use a default implementation, add them to
@ -5938,11 +5966,11 @@ pub fn hash_crate_independent(tcx: &ctxt, ty: Ty, svh: &Svh) -> u64 {
} }
ty_trait(box TyTrait { ref principal, bounds }) => { ty_trait(box TyTrait { ref principal, bounds }) => {
byte!(17); byte!(17);
did(state, principal.def_id); did(state, principal.def_id());
hash!(bounds); hash!(bounds);
let principal = anonymize_late_bound_regions(tcx, principal); let principal = anonymize_late_bound_regions(tcx, principal);
for subty in principal.substs.types.iter() { for subty in principal.substs().types.iter() {
helper(tcx, *subty, svh, state); helper(tcx, *subty, svh, state);
} }
@ -6200,7 +6228,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
accumulator.push(region) accumulator.push(region)
} }
ty_trait(ref t) => { ty_trait(ref t) => {
accumulator.push_all(t.principal.substs.regions().as_slice()); accumulator.push_all(t.principal.substs().regions().as_slice());
} }
ty_enum(_, ref substs) | ty_enum(_, ref substs) |
ty_struct(_, ref substs) => { ty_struct(_, ref substs) => {
@ -6538,3 +6566,43 @@ pub fn can_type_implement_copy<'tcx>(tcx: &ctxt<'tcx>,
Ok(()) Ok(())
} }
pub trait RegionEscape {
fn has_escaping_regions(&self) -> bool {
self.has_regions_escaping_depth(0)
}
fn has_regions_escaping_depth(&self, depth: uint) -> bool;
}
impl<'tcx> RegionEscape for Ty<'tcx> {
fn has_regions_escaping_depth(&self, depth: uint) -> bool {
ty::type_escapes_depth(*self, depth)
}
}
impl RegionEscape for Region {
fn has_regions_escaping_depth(&self, depth: uint) -> bool {
self.escapes_depth(depth)
}
}
impl<'tcx> RegionEscape for TraitRef<'tcx> {
fn has_regions_escaping_depth(&self, depth: uint) -> bool {
self.substs.types.iter().any(|t| t.has_regions_escaping_depth(depth)) &&
self.substs.regions().iter().any(|t| t.has_regions_escaping_depth(depth))
}
}
impl<'tcx,T:RegionEscape> RegionEscape for Binder<T> {
fn has_regions_escaping_depth(&self, depth: uint) -> bool {
self.value.has_regions_escaping_depth(depth + 1)
}
}
impl<T:RegionEscape> Binder<T> {
pub fn has_bound_regions(&self) -> bool {
self.value.has_regions_escaping_depth(0)
}
}

View File

@ -583,16 +583,6 @@ pub fn super_fold_closure_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
pub fn super_fold_trait_ref<'tcx, T: TypeFolder<'tcx>>(this: &mut T, pub fn super_fold_trait_ref<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
t: &ty::TraitRef<'tcx>) t: &ty::TraitRef<'tcx>)
-> ty::TraitRef<'tcx> -> ty::TraitRef<'tcx>
{
this.enter_region_binder();
let result = super_fold_trait_ref_contents(this, t);
this.exit_region_binder();
result
}
pub fn super_fold_trait_ref_contents<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
t: &ty::TraitRef<'tcx>)
-> ty::TraitRef<'tcx>
{ {
ty::TraitRef { ty::TraitRef {
def_id: t.def_id, def_id: t.def_id,
@ -722,12 +712,6 @@ impl<'tcx> HigherRankedFoldable<'tcx> for ty::FnSig<'tcx> {
} }
} }
impl<'tcx> HigherRankedFoldable<'tcx> for ty::TraitRef<'tcx> {
fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::TraitRef<'tcx> {
super_fold_trait_ref_contents(folder, self)
}
}
impl<'tcx, T:TypeFoldable<'tcx>+Repr<'tcx>> HigherRankedFoldable<'tcx> for ty::Binder<T> { impl<'tcx, T:TypeFoldable<'tcx>+Repr<'tcx>> HigherRankedFoldable<'tcx> for ty::Binder<T> {
fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> { fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
ty::bind(self.value.fold_with(folder)) ty::bind(self.value.fold_with(folder))

View File

@ -433,16 +433,11 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
ty_trait(box ty::TyTrait { ty_trait(box ty::TyTrait {
ref principal, ref bounds ref principal, ref bounds
}) => { }) => {
let base = ty::item_path_str(cx, principal.def_id); let principal = principal.user_string(cx);
let trait_def = ty::lookup_trait_def(cx, principal.def_id);
let did = trait_def.trait_ref.def_id;
let ty = parameterized(cx, base.as_slice(),
&principal.substs, &trait_def.generics,
did);
let bound_str = bounds.user_string(cx); let bound_str = bounds.user_string(cx);
let bound_sep = if bound_str.is_empty() { "" } else { " + " }; let bound_sep = if bound_str.is_empty() { "" } else { " + " };
format!("{}{}{}", format!("{}{}{}",
ty, principal,
bound_sep, bound_sep,
bound_str) bound_str)
} }
@ -749,7 +744,7 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
// tells you everything you need to know. // tells you everything you need to know.
let base = ty::item_path_str(tcx, self.def_id); let base = ty::item_path_str(tcx, self.def_id);
let trait_def = ty::lookup_trait_def(tcx, self.def_id); let trait_def = ty::lookup_trait_def(tcx, self.def_id);
format!("<{} : {}>", format!("TraitRef({}, {})",
self.substs.self_ty().repr(tcx), self.substs.self_ty().repr(tcx),
parameterized(tcx, base.as_slice(), &self.substs, &trait_def.generics, self.def_id)) parameterized(tcx, base.as_slice(), &self.substs, &trait_def.generics, self.def_id))
} }
@ -1161,7 +1156,7 @@ impl<'tcx> UserString<'tcx> for ty::BuiltinBounds {
} }
} }
impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> { impl<'tcx> UserString<'tcx> for ty::PolyTraitRef<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
// Replace any anonymous late-bound regions with named // Replace any anonymous late-bound regions with named
// variants, using gensym'd identifiers, so that we can // variants, using gensym'd identifiers, so that we can
@ -1178,7 +1173,7 @@ impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
ty::BrAnon(_) | ty::BrAnon(_) |
ty::BrFresh(_) | ty::BrFresh(_) |
ty::BrEnv => { ty::BrEnv => {
let name = token::gensym("r"); let name = token::gensym("'r");
names.push(token::get_name(name)); names.push(token::get_name(name));
ty::BrNamed(ast_util::local_def(ast::DUMMY_NODE_ID), name) ty::BrNamed(ast_util::local_def(ast::DUMMY_NODE_ID), name)
} }
@ -1186,19 +1181,21 @@ impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
}); });
let names: Vec<_> = names.iter().map(|s| s.get()).collect(); let names: Vec<_> = names.iter().map(|s| s.get()).collect();
// Let the base string be either `SomeTrait` for `for<'a,'b> SomeTrait`, let trait_ref_str = trait_ref.value.user_string(tcx);
// depending on whether there are bound regions. if names.len() == 0 {
let path_str = ty::item_path_str(tcx, self.def_id); trait_ref_str
let base = } else {
if names.is_empty() { format!("for<{}> {}", names.connect(","), trait_ref_str)
path_str }
} else { }
format!("for<{}> {}", names.connect(","), path_str) }
};
impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
let path_str = ty::item_path_str(tcx, self.def_id);
let trait_def = ty::lookup_trait_def(tcx, self.def_id); let trait_def = ty::lookup_trait_def(tcx, self.def_id);
let did = trait_def.trait_ref.def_id; parameterized(tcx, path_str.as_slice(), &self.substs,
parameterized(tcx, base.as_slice(), &trait_ref.substs, &trait_def.generics, did) &trait_def.generics, self.def_id)
} }
} }

View File

@ -941,14 +941,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
ty::MethodTypeParam(ref mp) => { ty::MethodTypeParam(ref mp) => {
// method invoked on a type parameter // method invoked on a type parameter
let trait_item = ty::trait_item(&self.analysis.ty_cx, let trait_item = ty::trait_item(&self.analysis.ty_cx,
mp.trait_ref.def_id, mp.trait_ref.def_id(),
mp.method_num); mp.method_num);
(None, Some(trait_item.def_id())) (None, Some(trait_item.def_id()))
} }
ty::MethodTraitObject(ref mo) => { ty::MethodTraitObject(ref mo) => {
// method invoked on a trait instance // method invoked on a trait instance
let trait_item = ty::trait_item(&self.analysis.ty_cx, let trait_item = ty::trait_item(&self.analysis.ty_cx,
mo.trait_ref.def_id, mo.trait_ref.def_id(),
mo.method_num); mo.method_num);
(None, Some(trait_item.def_id())) (None, Some(trait_item.def_id()))
} }

View File

@ -426,7 +426,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
// Compute the first substitution // Compute the first substitution
let first_subst = let first_subst =
ty::make_substs_for_receiver_types(tcx, &*trait_ref, &*method) ty::make_substs_for_receiver_types(tcx, &trait_ref.value, &*method)
.erase_regions(); .erase_regions();
// And compose them // And compose them
@ -435,7 +435,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
debug!("trans_fn_with_vtables - default method: \ debug!("trans_fn_with_vtables - default method: \
substs = {}, trait_subst = {}, \ substs = {}, trait_subst = {}, \
first_subst = {}, new_subst = {}", first_subst = {}, new_subst = {}",
substs.repr(tcx), trait_ref.substs.repr(tcx), substs.repr(tcx), trait_ref.substs().repr(tcx),
first_subst.repr(tcx), new_substs.repr(tcx)); first_subst.repr(tcx), new_substs.repr(tcx));
(true, source_id, new_substs) (true, source_id, new_substs)

View File

@ -764,7 +764,7 @@ pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ex: &ast::Expr) -> T
/// guarantee to us that all nested obligations *could be* resolved if we wanted to. /// guarantee to us that all nested obligations *could be* resolved if we wanted to.
pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
span: Span, span: Span,
trait_ref: Rc<ty::TraitRef<'tcx>>) trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
-> traits::Vtable<'tcx, ()> -> traits::Vtable<'tcx, ()>
{ {
let tcx = ccx.tcx(); let tcx = ccx.tcx();
@ -783,7 +783,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
debug!("trans fulfill_obligation: trait_ref={}", trait_ref.repr(ccx.tcx())); debug!("trans fulfill_obligation: trait_ref={}", trait_ref.repr(ccx.tcx()));
ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id); ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx); let infcx = infer::new_infer_ctxt(tcx);
// Parameter environment is used to give details about type parameters, // Parameter environment is used to give details about type parameters,

View File

@ -99,7 +99,7 @@ pub struct LocalCrateContext<'tcx> {
monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>, monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
monomorphizing: RefCell<DefIdMap<uint>>, monomorphizing: RefCell<DefIdMap<uint>>,
/// Cache generated vtables /// Cache generated vtables
vtables: RefCell<FnvHashMap<(Ty<'tcx>, Rc<ty::TraitRef<'tcx>>), ValueRef>>, vtables: RefCell<FnvHashMap<(Ty<'tcx>, Rc<ty::PolyTraitRef<'tcx>>), ValueRef>>,
/// Cache of constant strings, /// Cache of constant strings,
const_cstr_cache: RefCell<FnvHashMap<InternedString, ValueRef>>, const_cstr_cache: RefCell<FnvHashMap<InternedString, ValueRef>>,
@ -150,7 +150,7 @@ pub struct LocalCrateContext<'tcx> {
/// contexts around the same size. /// contexts around the same size.
n_llvm_insns: Cell<uint>, n_llvm_insns: Cell<uint>,
trait_cache: RefCell<FnvHashMap<Rc<ty::TraitRef<'tcx>>, trait_cache: RefCell<FnvHashMap<Rc<ty::PolyTraitRef<'tcx>>,
traits::Vtable<'tcx, ()>>>, traits::Vtable<'tcx, ()>>>,
} }
@ -601,7 +601,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
&self.local.monomorphizing &self.local.monomorphizing
} }
pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<(Ty<'tcx>, Rc<ty::TraitRef<'tcx>>), pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<(Ty<'tcx>, Rc<ty::PolyTraitRef<'tcx>>),
ValueRef>> { ValueRef>> {
&self.local.vtables &self.local.vtables
} }
@ -699,7 +699,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
self.local.n_llvm_insns.set(self.local.n_llvm_insns.get() + 1); self.local.n_llvm_insns.set(self.local.n_llvm_insns.get() + 1);
} }
pub fn trait_cache(&self) -> &RefCell<FnvHashMap<Rc<ty::TraitRef<'tcx>>, pub fn trait_cache(&self) -> &RefCell<FnvHashMap<Rc<ty::PolyTraitRef<'tcx>>,
traits::Vtable<'tcx, ()>>> { traits::Vtable<'tcx, ()>>> {
&self.local.trait_cache &self.local.trait_cache
} }

View File

@ -429,8 +429,8 @@ impl<'tcx> TypeMap<'tcx> {
from_def_id_and_substs(self, from_def_id_and_substs(self,
cx, cx,
trait_data.principal.def_id, trait_data.principal.def_id(),
&trait_data.principal.substs, trait_data.principal.substs(),
&mut unique_type_id); &mut unique_type_id);
}, },
ty::ty_bare_fn(ty::BareFnTy{ unsafety, abi, ref sig } ) => { ty::ty_bare_fn(ty::BareFnTy{ unsafety, abi, ref sig } ) => {
@ -2834,7 +2834,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// But it does not describe the trait's methods. // But it does not describe the trait's methods.
let def_id = match trait_type.sty { let def_id = match trait_type.sty {
ty::ty_trait(box ty::TyTrait { ref principal, .. }) => principal.def_id, ty::ty_trait(box ty::TyTrait { ref principal, .. }) => principal.def_id(),
_ => { _ => {
let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type); let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \ cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
@ -3765,8 +3765,8 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push(']'); output.push(']');
}, },
ty::ty_trait(ref trait_data) => { ty::ty_trait(ref trait_data) => {
push_item_name(cx, trait_data.principal.def_id, false, output); push_item_name(cx, trait_data.principal.def_id(), false, output);
push_type_params(cx, &trait_data.principal.substs, output); push_type_params(cx, trait_data.principal.substs(), output);
}, },
ty::ty_bare_fn(ty::BareFnTy{ unsafety, abi, ref sig } ) => { ty::ty_bare_fn(ty::BareFnTy{ unsafety, abi, ref sig } ) => {
if unsafety == ast::Unsafety::Unsafe { if unsafety == ast::Unsafety::Unsafe {

View File

@ -316,10 +316,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bcx.ty_to_string(unadjusted_ty)).as_slice()) bcx.ty_to_string(unadjusted_ty)).as_slice())
}, },
&ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => { &ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => {
let substs = principal.substs.with_self_ty(unadjusted_ty).erase_regions(); let substs = principal.substs().with_self_ty(unadjusted_ty).erase_regions();
let trait_ref = let trait_ref =
Rc::new(ty::TraitRef { def_id: principal.def_id, Rc::new(ty::bind(ty::TraitRef { def_id: principal.def_id(),
substs: substs }); substs: substs }));
let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs); let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs);
let box_ty = mk_ty(unadjusted_ty); let box_ty = mk_ty(unadjusted_ty);
PointerCast(bcx, PointerCast(bcx,

View File

@ -142,7 +142,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
span, span,
(*trait_ref).clone()); (*trait_ref).clone());
debug!("origin = {}", origin.repr(bcx.tcx())); debug!("origin = {}", origin.repr(bcx.tcx()));
trans_monomorphized_callee(bcx, method_call, trait_ref.def_id, trans_monomorphized_callee(bcx, method_call, trait_ref.def_id(),
method_num, origin) method_num, origin)
} }
@ -239,8 +239,8 @@ pub fn trans_static_method_callee(bcx: Block,
rcvr_assoc, rcvr_assoc,
Vec::new())); Vec::new()));
debug!("trait_substs={}", trait_substs.repr(bcx.tcx())); debug!("trait_substs={}", trait_substs.repr(bcx.tcx()));
let trait_ref = Rc::new(ty::TraitRef { def_id: trait_id, let trait_ref = Rc::new(ty::bind(ty::TraitRef { def_id: trait_id,
substs: trait_substs }); substs: trait_substs }));
let vtbl = fulfill_obligation(bcx.ccx(), let vtbl = fulfill_obligation(bcx.ccx(),
DUMMY_SP, DUMMY_SP,
trait_ref); trait_ref);
@ -515,7 +515,7 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
/// This will hopefully change now that DST is underway. /// This will hopefully change now that DST is underway.
pub fn get_vtable<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pub fn get_vtable<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
box_ty: Ty<'tcx>, box_ty: Ty<'tcx>,
trait_ref: Rc<ty::TraitRef<'tcx>>) trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
-> ValueRef -> ValueRef
{ {
debug!("get_vtable(box_ty={}, trait_ref={})", debug!("get_vtable(box_ty={}, trait_ref={})",
@ -618,7 +618,7 @@ fn emit_vtable_methods<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let tcx = ccx.tcx(); let tcx = ccx.tcx();
let trt_id = match ty::impl_trait_ref(tcx, impl_id) { let trt_id = match ty::impl_trait_ref(tcx, impl_id) {
Some(t_id) => t_id.def_id, Some(t_id) => t_id.def_id(),
None => ccx.sess().bug("make_impl_vtable: don't know how to \ None => ccx.sess().bug("make_impl_vtable: don't know how to \
make a vtable for a type impl!") make a vtable for a type impl!")
}; };
@ -670,7 +670,7 @@ fn emit_vtable_methods<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
datum: Datum<'tcx, Expr>, datum: Datum<'tcx, Expr>,
id: ast::NodeId, id: ast::NodeId,
trait_ref: Rc<ty::TraitRef<'tcx>>, trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
dest: expr::Dest) dest: expr::Dest)
-> Block<'blk, 'tcx> { -> Block<'blk, 'tcx> {
let mut bcx = bcx; let mut bcx = bcx;

View File

@ -524,6 +524,19 @@ fn convert_parenthesized_parameters<'tcx,AC>(this: &AC,
vec![input_ty, output] vec![input_ty, output]
} }
pub fn instantiate_poly_trait_ref<'tcx,AC,RS>(
this: &AC,
rscope: &RS,
ast_trait_ref: &ast::PolyTraitRef,
self_ty: Option<Ty<'tcx>>,
allow_eq: AllowEqConstraints)
-> Rc<ty::PolyTraitRef<'tcx>>
where AC: AstConv<'tcx>, RS: RegionScope
{
let trait_ref = instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref, self_ty, allow_eq);
let trait_ref = (*trait_ref).clone();
Rc::new(ty::bind(trait_ref)) // Ugh.
}
/// Instantiates the path for the given trait reference, assuming that it's /// Instantiates the path for the given trait reference, assuming that it's
/// bound to a valid trait type. Returns the def_id for the defining trait. /// bound to a valid trait type. Returns the def_id for the defining trait.
@ -537,9 +550,7 @@ pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
where AC: AstConv<'tcx>, where AC: AstConv<'tcx>,
RS: RegionScope RS: RegionScope
{ {
match ::lookup_def_tcx(this.tcx(), match ::lookup_def_tcx(this.tcx(), ast_trait_ref.path.span, ast_trait_ref.ref_id) {
ast_trait_ref.path.span,
ast_trait_ref.ref_id) {
def::DefTrait(trait_def_id) => { def::DefTrait(trait_def_id) => {
let trait_ref = Rc::new(ast_path_to_trait_ref(this, let trait_ref = Rc::new(ast_path_to_trait_ref(this,
rscope, rscope,
@ -749,7 +760,7 @@ fn ast_ty_to_trait_ref<'tcx,AC,RS>(this: &AC,
rscope: &RS, rscope: &RS,
ty: &ast::Ty, ty: &ast::Ty,
bounds: &[ast::TyParamBound]) bounds: &[ast::TyParamBound])
-> Result<ty::TraitRef<'tcx>, ErrorReported> -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
where AC : AstConv<'tcx>, RS : RegionScope where AC : AstConv<'tcx>, RS : RegionScope
{ {
/*! /*!
@ -767,12 +778,12 @@ fn ast_ty_to_trait_ref<'tcx,AC,RS>(this: &AC,
ast::TyPath(ref path, id) => { ast::TyPath(ref path, id) => {
match this.tcx().def_map.borrow().get(&id) { match this.tcx().def_map.borrow().get(&id) {
Some(&def::DefTrait(trait_def_id)) => { Some(&def::DefTrait(trait_def_id)) => {
return Ok(ast_path_to_trait_ref(this, return Ok(ty::bind(ast_path_to_trait_ref(this,
rscope, rscope,
trait_def_id, trait_def_id,
None, None,
path, path,
AllowEqConstraints::Allow)); AllowEqConstraints::Allow)));
} }
_ => { _ => {
span_err!(this.tcx().sess, ty.span, E0172, "expected a reference to a trait"); span_err!(this.tcx().sess, ty.span, E0172, "expected a reference to a trait");
@ -814,7 +825,7 @@ fn ast_ty_to_trait_ref<'tcx,AC,RS>(this: &AC,
fn trait_ref_to_object_type<'tcx,AC,RS>(this: &AC, fn trait_ref_to_object_type<'tcx,AC,RS>(this: &AC,
rscope: &RS, rscope: &RS,
span: Span, span: Span,
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
bounds: &[ast::TyParamBound]) bounds: &[ast::TyParamBound])
-> Ty<'tcx> -> Ty<'tcx>
where AC : AstConv<'tcx>, RS : RegionScope where AC : AstConv<'tcx>, RS : RegionScope
@ -982,12 +993,12 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
def::DefTrait(trait_def_id) => { def::DefTrait(trait_def_id) => {
// N.B. this case overlaps somewhat with // N.B. this case overlaps somewhat with
// TyObjectSum, see that fn for details // TyObjectSum, see that fn for details
let result = ast_path_to_trait_ref(this, let result = ty::bind(ast_path_to_trait_ref(this,
rscope, rscope,
trait_def_id, trait_def_id,
None, None,
path, path,
AllowEqConstraints::Allow); AllowEqConstraints::Allow));
trait_ref_to_object_type(this, rscope, path.span, result, &[]) trait_ref_to_object_type(this, rscope, path.span, result, &[])
} }
def::DefTy(did, _) | def::DefStruct(did) => { def::DefTy(did, _) | def::DefStruct(did) => {
@ -1039,7 +1050,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
let ty_param_defs = tcx.ty_param_defs.borrow(); let ty_param_defs = tcx.ty_param_defs.borrow();
let tp_def = &(*ty_param_defs)[did.node]; let tp_def = &(*ty_param_defs)[did.node];
let assoc_tys = tp_def.bounds.trait_bounds.iter() let assoc_tys = tp_def.bounds.trait_bounds.iter()
.filter_map(|b| find_assoc_ty(this, &**b, assoc_ident)) .filter_map(|b| find_assoc_ty(this, &b.value, assoc_ident))
.collect(); .collect();
(assoc_tys, token::get_name(tp_def.name).to_string()) (assoc_tys, token::get_name(tp_def.name).to_string())
} }
@ -1423,7 +1434,7 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
this: &AC, this: &AC,
rscope: &RS, rscope: &RS,
span: Span, span: Span,
principal_trait_ref: Option<&ty::TraitRef<'tcx>>, // None for boxed closures principal_trait_ref: Option<&ty::PolyTraitRef<'tcx>>, // None for boxed closures
ast_bounds: &[ast::TyParamBound]) ast_bounds: &[ast::TyParamBound])
-> ty::ExistentialBounds -> ty::ExistentialBounds
{ {
@ -1450,11 +1461,11 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) { let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) {
Some(trait_bound) => { Some(trait_bound) => {
Some(instantiate_trait_ref(this, Some(instantiate_poly_trait_ref(this,
rscope, rscope,
&trait_bound.trait_ref, trait_bound,
None, None,
AllowEqConstraints::Allow)) AllowEqConstraints::Allow))
} }
None => { None => {
this.tcx().sess.span_err( this.tcx().sess.span_err(
@ -1481,7 +1492,7 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx, AC, RS>(
this: &AC, this: &AC,
rscope: &RS, rscope: &RS,
span: Span, span: Span,
principal_trait_ref: Option<&ty::TraitRef<'tcx>>, // None for boxed closures principal_trait_ref: Option<&ty::PolyTraitRef<'tcx>>, // None for boxed closures
partitioned_bounds: PartitionedBounds) partitioned_bounds: PartitionedBounds)
-> ty::ExistentialBounds -> ty::ExistentialBounds
where AC: AstConv<'tcx>, RS:RegionScope where AC: AstConv<'tcx>, RS:RegionScope
@ -1519,7 +1530,7 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx, AC, RS>(
fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>, fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
span: Span, span: Span,
explicit_region_bounds: &[&ast::Lifetime], explicit_region_bounds: &[&ast::Lifetime],
principal_trait_ref: Option<&ty::TraitRef<'tcx>>, principal_trait_ref: Option<&ty::PolyTraitRef<'tcx>>,
builtin_bounds: ty::BuiltinBounds) builtin_bounds: ty::BuiltinBounds)
-> Option<ty::Region> -> Option<ty::Region>
{ {
@ -1579,7 +1590,7 @@ fn compute_region_bound<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
rscope: &RS, rscope: &RS,
span: Span, span: Span,
region_bounds: &[&ast::Lifetime], region_bounds: &[&ast::Lifetime],
principal_trait_ref: Option<&ty::TraitRef<'tcx>>, // None for closures principal_trait_ref: Option<&ty::PolyTraitRef<'tcx>>, // None for closures
builtin_bounds: ty::BuiltinBounds) builtin_bounds: ty::BuiltinBounds)
-> ty::Region -> ty::Region
{ {

View File

@ -18,6 +18,7 @@ use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
use check::{instantiate_path, structurally_resolved_type, valid_range_bounds}; use check::{instantiate_path, structurally_resolved_type, valid_range_bounds};
use require_same_types; use require_same_types;
use util::nodemap::FnvHashMap; use util::nodemap::FnvHashMap;
use util::ppaux::Repr;
use std::cmp; use std::cmp;
use std::collections::hash_map::{Occupied, Vacant}; use std::collections::hash_map::{Occupied, Vacant};
@ -33,6 +34,10 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
let fcx = pcx.fcx; let fcx = pcx.fcx;
let tcx = pcx.fcx.ccx.tcx; let tcx = pcx.fcx.ccx.tcx;
debug!("check_pat(pat={},expected={})",
pat.repr(tcx),
expected.repr(tcx));
match pat.node { match pat.node {
ast::PatWild(_) => { ast::PatWild(_) => {
fcx.write_ty(pat.id, expected); fcx.write_ty(pat.id, expected);

View File

@ -180,7 +180,7 @@ fn deduce_unboxed_closure_expectations_from_expected_type<'a,'tcx>(
fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>( fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
fcx: &FnCtxt<'a,'tcx>, fcx: &FnCtxt<'a,'tcx>,
trait_ref: &ty::TraitRef<'tcx>) trait_ref: &ty::PolyTraitRef<'tcx>)
-> Option<(ty::FnSig<'tcx>, ty::UnboxedClosureKind)> -> Option<(ty::FnSig<'tcx>, ty::UnboxedClosureKind)>
{ {
let tcx = fcx.tcx(); let tcx = fcx.tcx();
@ -188,14 +188,14 @@ fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
debug!("deduce_unboxed_closure_expectations_from_object_type({})", debug!("deduce_unboxed_closure_expectations_from_object_type({})",
trait_ref.repr(tcx)); trait_ref.repr(tcx));
let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id) { let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id()) {
Some(k) => k, Some(k) => k,
None => { return None; } None => { return None; }
}; };
debug!("found object type {}", kind); debug!("found object type {}", kind);
let arg_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 0); let arg_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 0);
let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(&arg_param_ty); let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(&arg_param_ty);
debug!("arg_param_ty {}", arg_param_ty.repr(tcx)); debug!("arg_param_ty {}", arg_param_ty.repr(tcx));
@ -205,7 +205,7 @@ fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
}; };
debug!("input_tys {}", input_tys.repr(tcx)); debug!("input_tys {}", input_tys.repr(tcx));
let ret_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 1); let ret_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 1);
let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(&ret_param_ty); let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(&ret_param_ty);
debug!("ret_param_ty {}", ret_param_ty.repr(tcx)); debug!("ret_param_ty {}", ret_param_ty.repr(tcx));

View File

@ -222,15 +222,15 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
// argument type), but those cases have already // argument type), but those cases have already
// been ruled out when we deemed the trait to be // been ruled out when we deemed the trait to be
// "object safe". // "object safe".
let substs = data.principal.substs.clone().with_self_ty(object_ty);
let original_trait_ref = let original_trait_ref =
Rc::new(ty::TraitRef::new(data.principal.def_id, substs)); data.principal_trait_ref_with_self_ty(object_ty);
let upcast_trait_ref = this.upcast(original_trait_ref.clone(), trait_def_id); let upcast_trait_ref =
this.upcast(original_trait_ref.clone(), trait_def_id);
debug!("original_trait_ref={} upcast_trait_ref={} target_trait={}", debug!("original_trait_ref={} upcast_trait_ref={} target_trait={}",
original_trait_ref.repr(this.tcx()), original_trait_ref.repr(this.tcx()),
upcast_trait_ref.repr(this.tcx()), upcast_trait_ref.repr(this.tcx()),
trait_def_id.repr(this.tcx())); trait_def_id.repr(this.tcx()));
let substs = upcast_trait_ref.substs.clone(); let substs = upcast_trait_ref.substs().clone();
let origin = MethodTraitObject(MethodObject { let origin = MethodTraitObject(MethodObject {
trait_ref: upcast_trait_ref, trait_ref: upcast_trait_ref,
object_trait_id: trait_def_id, object_trait_id: trait_def_id,
@ -257,7 +257,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
.subst(self.tcx(), &impl_polytype.substs); .subst(self.tcx(), &impl_polytype.substs);
let origin = MethodTypeParam(MethodParam { trait_ref: impl_trait_ref.clone(), let origin = MethodTypeParam(MethodParam { trait_ref: impl_trait_ref.clone(),
method_num: method_num }); method_num: method_num });
(impl_trait_ref.substs.clone(), origin) (impl_trait_ref.substs().clone(), origin)
} }
probe::TraitPick(trait_def_id, method_num) => { probe::TraitPick(trait_def_id, method_num) => {
@ -272,16 +272,16 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
&trait_def.generics, &trait_def.generics,
self.infcx().next_ty_var()); self.infcx().next_ty_var());
let trait_ref = Rc::new(ty::TraitRef::new(trait_def_id, substs.clone())); let trait_ref = Rc::new(ty::bind(ty::TraitRef::new(trait_def_id, substs.clone())));
let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref, let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref,
method_num: method_num }); method_num: method_num });
(substs, origin) (substs, origin)
} }
probe::WhereClausePick(ref trait_ref, method_num) => { probe::WhereClausePick(ref trait_ref, method_num) => {
let origin = MethodTypeParam(MethodParam { trait_ref: (*trait_ref).clone(), let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref.clone(),
method_num: method_num }); method_num: method_num });
(trait_ref.substs.clone(), origin) (trait_ref.substs().clone(), origin)
} }
} }
} }
@ -637,12 +637,12 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
} }
fn upcast(&mut self, fn upcast(&mut self,
source_trait_ref: Rc<ty::TraitRef<'tcx>>, source_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
target_trait_def_id: ast::DefId) target_trait_def_id: ast::DefId)
-> Rc<ty::TraitRef<'tcx>> -> Rc<ty::PolyTraitRef<'tcx>>
{ {
for super_trait_ref in traits::supertraits(self.tcx(), source_trait_ref.clone()) { for super_trait_ref in traits::supertraits(self.tcx(), source_trait_ref.clone()) {
if super_trait_ref.def_id == target_trait_def_id { if super_trait_ref.def_id() == target_trait_def_id {
return super_trait_ref; return super_trait_ref;
} }
} }

View File

@ -166,7 +166,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
// Construct a trait-reference `self_ty : Trait<input_tys>` // Construct a trait-reference `self_ty : Trait<input_tys>`
let substs = subst::Substs::new_trait(input_types, Vec::new(), assoc_types, self_ty); let substs = subst::Substs::new_trait(input_types, Vec::new(), assoc_types, self_ty);
let trait_ref = Rc::new(ty::TraitRef::new(trait_def_id, substs)); let trait_ref = Rc::new(ty::bind(ty::TraitRef::new(trait_def_id, substs)));
// Construct an obligation // Construct an obligation
let obligation = traits::Obligation::misc(span, let obligation = traits::Obligation::misc(span,
@ -198,7 +198,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
// Note that as the method comes from a trait, it can only have // Note that as the method comes from a trait, it can only have
// late-bound regions from the fn itself, not the impl. // late-bound regions from the fn itself, not the impl.
let ref bare_fn_ty = method_ty.fty; let ref bare_fn_ty = method_ty.fty;
let fn_sig = bare_fn_ty.sig.subst(tcx, &trait_ref.substs); let fn_sig = bare_fn_ty.sig.subst(tcx, trait_ref.substs());
let fn_sig = fcx.infcx().replace_late_bound_regions_with_fresh_var(span, let fn_sig = fcx.infcx().replace_late_bound_regions_with_fresh_var(span,
infer::FnCall, infer::FnCall,
&fn_sig).0; &fn_sig).0;
@ -221,7 +221,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
// //
// Note that as the method comes from a trait, it should not have // Note that as the method comes from a trait, it should not have
// any late-bound regions appearing in its bounds. // any late-bound regions appearing in its bounds.
let method_bounds = method_ty.generics.to_bounds(fcx.tcx(), &trait_ref.substs); let method_bounds = method_ty.generics.to_bounds(fcx.tcx(), trait_ref.substs());
assert!(!method_bounds.has_escaping_regions()); assert!(!method_bounds.has_escaping_regions());
fcx.add_obligations_for_parameters( fcx.add_obligations_for_parameters(
traits::ObligationCause::misc(span, fcx.body_id), traits::ObligationCause::misc(span, fcx.body_id),
@ -293,7 +293,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
origin: MethodTypeParam(MethodParam{trait_ref: trait_ref.clone(), origin: MethodTypeParam(MethodParam{trait_ref: trait_ref.clone(),
method_num: method_num}), method_num: method_num}),
ty: fty, ty: fty,
substs: trait_ref.substs.clone() substs: trait_ref.substs().clone()
}; };
debug!("callee = {}", callee.repr(fcx.tcx())); debug!("callee = {}", callee.repr(fcx.tcx()));
@ -379,7 +379,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
None => format!(""), None => format!(""),
Some(trait_ref) => format!(" of the trait `{}`", Some(trait_ref) => format!(" of the trait `{}`",
ty::item_path_str(fcx.tcx(), ty::item_path_str(fcx.tcx(),
trait_ref.def_id)), trait_ref.def_id())),
}; };
span_note!(fcx.sess(), method_span, span_note!(fcx.sess(), method_span,

View File

@ -59,10 +59,10 @@ struct Candidate<'tcx> {
enum CandidateKind<'tcx> { enum CandidateKind<'tcx> {
InherentImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>), InherentImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>),
ObjectCandidate(MethodObject<'tcx>), ObjectCandidate(MethodObject<'tcx>),
ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>, ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::PolyTraitRef<'tcx>>,
subst::Substs<'tcx>, MethodIndex), subst::Substs<'tcx>, MethodIndex),
UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex), UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
WhereClauseCandidate(Rc<ty::TraitRef<'tcx>>, MethodIndex), WhereClauseCandidate(Rc<ty::PolyTraitRef<'tcx>>, MethodIndex),
} }
pub struct Pick<'tcx> { pub struct Pick<'tcx> {
@ -77,7 +77,7 @@ pub enum PickKind<'tcx> {
ObjectPick(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint), ObjectPick(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint),
ExtensionImplPick(/* Impl */ ast::DefId, MethodIndex), ExtensionImplPick(/* Impl */ ast::DefId, MethodIndex),
TraitPick(/* Trait */ ast::DefId, MethodIndex), TraitPick(/* Trait */ ast::DefId, MethodIndex),
WhereClausePick(/* Trait */ Rc<ty::TraitRef<'tcx>>, MethodIndex), WhereClausePick(/* Trait */ Rc<ty::PolyTraitRef<'tcx>>, MethodIndex),
} }
pub type PickResult<'tcx> = Result<Pick<'tcx>, MethodError>; pub type PickResult<'tcx> = Result<Pick<'tcx>, MethodError>;
@ -231,9 +231,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
self_ty.repr(self.tcx())); self_ty.repr(self.tcx()));
match self_ty.sty { match self_ty.sty {
ty::ty_trait(box ty::TyTrait { ref principal, bounds, .. }) => { ty::ty_trait(box ref data) => {
self.assemble_inherent_candidates_from_object(self_ty, &*principal, bounds); self.assemble_inherent_candidates_from_object(self_ty, data);
self.assemble_inherent_impl_candidates_for_type(principal.def_id); self.assemble_inherent_impl_candidates_for_type(data.principal.def_id());
} }
ty::ty_enum(did, _) | ty::ty_enum(did, _) |
ty::ty_struct(did, _) | ty::ty_struct(did, _) |
@ -290,8 +290,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
fn assemble_inherent_candidates_from_object(&mut self, fn assemble_inherent_candidates_from_object(&mut self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
principal: &ty::TraitRef<'tcx>, data: &ty::TyTrait<'tcx>) {
_bounds: ty::ExistentialBounds) {
debug!("assemble_inherent_candidates_from_object(self_ty={})", debug!("assemble_inherent_candidates_from_object(self_ty={})",
self_ty.repr(self.tcx())); self_ty.repr(self.tcx()));
@ -304,26 +303,20 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
// a substitution that replaces `Self` with the object type // a substitution that replaces `Self` with the object type
// itself. Hence, a `&self` method will wind up with an // itself. Hence, a `&self` method will wind up with an
// argument type like `&Trait`. // argument type like `&Trait`.
let rcvr_substs = principal.substs.clone().with_self_ty(self_ty); let trait_ref = data.principal_trait_ref_with_self_ty(self_ty);
let trait_ref = Rc::new(ty::TraitRef {
def_id: principal.def_id,
substs: rcvr_substs.clone()
});
self.elaborate_bounds(&[trait_ref.clone()], false, |this, new_trait_ref, m, method_num| { self.elaborate_bounds(&[trait_ref.clone()], false, |this, new_trait_ref, m, method_num| {
let vtable_index = let vtable_index =
get_method_index(tcx, &*new_trait_ref, get_method_index(tcx, &*new_trait_ref, trait_ref.clone(), method_num);
trait_ref.clone(), method_num);
let xform_self_ty = let xform_self_ty =
this.xform_self_ty(&m, &new_trait_ref.substs); this.xform_self_ty(&m, new_trait_ref.substs());
this.inherent_candidates.push(Candidate { this.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty, xform_self_ty: xform_self_ty,
method_ty: m, method_ty: m,
kind: ObjectCandidate(MethodObject { kind: ObjectCandidate(MethodObject {
trait_ref: new_trait_ref, trait_ref: new_trait_ref,
object_trait_id: principal.def_id, object_trait_id: trait_ref.def_id(),
method_num: method_num, method_num: method_num,
real_index: vtable_index real_index: vtable_index
}) })
@ -358,27 +351,27 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
self.elaborate_bounds(bounds.as_slice(), true, |this, trait_ref, m, method_num| { self.elaborate_bounds(bounds.as_slice(), true, |this, trait_ref, m, method_num| {
let xform_self_ty = let xform_self_ty =
this.xform_self_ty(&m, &trait_ref.substs); this.xform_self_ty(&m, trait_ref.substs());
debug!("found match: trait_ref={} substs={} m={}", debug!("found match: trait_ref={} substs={} m={}",
trait_ref.repr(this.tcx()), trait_ref.repr(this.tcx()),
trait_ref.substs.repr(this.tcx()), trait_ref.substs().repr(this.tcx()),
m.repr(this.tcx())); m.repr(this.tcx()));
assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(), assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
trait_ref.substs.types.get_slice(subst::TypeSpace).len()); trait_ref.substs().types.get_slice(subst::TypeSpace).len());
assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(), assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
trait_ref.substs.regions().get_slice(subst::TypeSpace).len()); trait_ref.substs().regions().get_slice(subst::TypeSpace).len());
assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(), assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
trait_ref.substs.types.get_slice(subst::SelfSpace).len()); trait_ref.substs().types.get_slice(subst::SelfSpace).len());
assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(), assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
trait_ref.substs.regions().get_slice(subst::SelfSpace).len()); trait_ref.substs().regions().get_slice(subst::SelfSpace).len());
// Because this trait derives from a where-clause, it // Because this trait derives from a where-clause, it
// should not contain any inference variables or other // should not contain any inference variables or other
// artifacts. This means it is safe to put into the // artifacts. This means it is safe to put into the
// `WhereClauseCandidate` and (eventually) into the // `WhereClauseCandidate` and (eventually) into the
// `WhereClausePick`. // `WhereClausePick`.
assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t))); assert!(trait_ref.substs().types.iter().all(|&t| !ty::type_needs_infer(t)));
this.inherent_candidates.push(Candidate { this.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty, xform_self_ty: xform_self_ty,
@ -392,10 +385,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
// create the candidates. // create the candidates.
fn elaborate_bounds( fn elaborate_bounds(
&mut self, &mut self,
bounds: &[Rc<ty::TraitRef<'tcx>>], bounds: &[Rc<ty::PolyTraitRef<'tcx>>],
num_includes_types: bool, num_includes_types: bool,
mk_cand: for<'b> |this: &mut ProbeContext<'b, 'tcx>, mk_cand: for<'b> |this: &mut ProbeContext<'b, 'tcx>,
tr: Rc<ty::TraitRef<'tcx>>, tr: Rc<ty::PolyTraitRef<'tcx>>,
m: Rc<ty::Method<'tcx>>, m: Rc<ty::Method<'tcx>>,
method_num: uint|) method_num: uint|)
{ {
@ -405,12 +398,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
let mut cache = HashSet::new(); let mut cache = HashSet::new();
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
// Already visited this trait, skip it. // Already visited this trait, skip it.
if !cache.insert(bound_trait_ref.def_id) { if !cache.insert(bound_trait_ref.def_id()) {
continue; continue;
} }
let (pos, method) = match trait_method(tcx, let (pos, method) = match trait_method(tcx,
bound_trait_ref.def_id, bound_trait_ref.def_id(),
self.method_name, self.method_name,
num_includes_types) { num_includes_types) {
Some(v) => v, Some(v) => v,
@ -418,7 +411,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
}; };
if !self.has_applicable_self(&*method) { if !self.has_applicable_self(&*method) {
self.record_static_candidate(TraitSource(bound_trait_ref.def_id)); self.record_static_candidate(TraitSource(bound_trait_ref.def_id()));
} else { } else {
mk_cand(self, bound_trait_ref, method, pos); mk_cand(self, bound_trait_ref, method, pos);
} }
@ -510,7 +503,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
// Determine the receiver type that the method itself expects. // Determine the receiver type that the method itself expects.
let xform_self_ty = let xform_self_ty =
self.xform_self_ty(&method, &impl_trait_ref.substs); self.xform_self_ty(&method, impl_trait_ref.substs());
debug!("xform_self_ty={}", xform_self_ty.repr(self.tcx())); debug!("xform_self_ty={}", xform_self_ty.repr(self.tcx()));
@ -1007,8 +1000,8 @@ fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
// Determine the index of a method in the list of all methods belonging // Determine the index of a method in the list of all methods belonging
// to a trait and its supertraits. // to a trait and its supertraits.
fn get_method_index<'tcx>(tcx: &ty::ctxt<'tcx>, fn get_method_index<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_ref: &ty::TraitRef<'tcx>, trait_ref: &ty::PolyTraitRef<'tcx>,
subtrait: Rc<ty::TraitRef<'tcx>>, subtrait: Rc<ty::PolyTraitRef<'tcx>>,
n_method: uint) -> uint { n_method: uint) -> uint {
// We need to figure the "real index" of the method in a // We need to figure the "real index" of the method in a
// listing of all the methods of an object. We do this by // listing of all the methods of an object. We do this by
@ -1017,10 +1010,10 @@ fn get_method_index<'tcx>(tcx: &ty::ctxt<'tcx>,
// methods from them. // methods from them.
let mut method_count = n_method; let mut method_count = n_method;
ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| { ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
if bound_ref.def_id == trait_ref.def_id { if bound_ref.def_id() == trait_ref.def_id() {
false false
} else { } else {
let trait_items = ty::trait_items(tcx, bound_ref.def_id); let trait_items = ty::trait_items(tcx, bound_ref.def_id());
for trait_item in trait_items.iter() { for trait_item in trait_items.iter() {
match *trait_item { match *trait_item {
ty::MethodTraitItem(_) => method_count += 1, ty::MethodTraitItem(_) => method_count += 1,
@ -1043,7 +1036,7 @@ impl<'tcx> Candidate<'tcx> {
InherentImplPick(def_id) InherentImplPick(def_id)
} }
ObjectCandidate(ref data) => { ObjectCandidate(ref data) => {
ObjectPick(data.trait_ref.def_id, data.method_num, data.real_index) ObjectPick(data.trait_ref.def_id(), data.method_num, data.real_index)
} }
ExtensionImplCandidate(def_id, _, _, index) => { ExtensionImplCandidate(def_id, _, _, index) => {
ExtensionImplPick(def_id, index) ExtensionImplPick(def_id, index)
@ -1057,7 +1050,7 @@ impl<'tcx> Candidate<'tcx> {
// inference variables or other artifacts. This // inference variables or other artifacts. This
// means they are safe to put into the // means they are safe to put into the
// `WhereClausePick`. // `WhereClausePick`.
assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t))); assert!(trait_ref.substs().types.iter().all(|&t| !ty::type_needs_infer(t)));
WhereClausePick((*trait_ref).clone(), index) WhereClausePick((*trait_ref).clone(), index)
} }
@ -1068,10 +1061,10 @@ impl<'tcx> Candidate<'tcx> {
fn to_source(&self) -> CandidateSource { fn to_source(&self) -> CandidateSource {
match self.kind { match self.kind {
InherentImplCandidate(def_id, _) => ImplSource(def_id), InherentImplCandidate(def_id, _) => ImplSource(def_id),
ObjectCandidate(ref obj) => TraitSource(obj.trait_ref.def_id), ObjectCandidate(ref obj) => TraitSource(obj.trait_ref.def_id()),
ExtensionImplCandidate(def_id, _, _, _) => ImplSource(def_id), ExtensionImplCandidate(def_id, _, _, _) => ImplSource(def_id),
UnboxedClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id), UnboxedClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id),
WhereClauseCandidate(ref trait_ref, _) => TraitSource(trait_ref.def_id), WhereClauseCandidate(ref trait_ref, _) => TraitSource(trait_ref.def_id()),
} }
} }
@ -1086,7 +1079,7 @@ impl<'tcx> Candidate<'tcx> {
} }
ExtensionImplCandidate(_, ref trait_ref, _, method_num) | ExtensionImplCandidate(_, ref trait_ref, _, method_num) |
WhereClauseCandidate(ref trait_ref, method_num) => { WhereClauseCandidate(ref trait_ref, method_num) => {
Some((trait_ref.def_id, method_num)) Some((trait_ref.def_id(), method_num))
} }
} }
} }

View File

@ -625,23 +625,20 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id); let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env); check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
} }
ast::ItemImpl(_, _, ref opt_trait_ref, _, ref impl_items) => { ast::ItemImpl(_, _, _, _, ref impl_items) => {
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id); debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id)); let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
match *opt_trait_ref { match ty::impl_trait_ref(ccx.tcx, local_def(it.id)) {
Some(ref ast_trait_ref) => { Some(impl_trait_ref) => {
let impl_trait_ref =
ty::node_id_to_trait_ref(ccx.tcx, ast_trait_ref.ref_id);
check_impl_items_against_trait(ccx, check_impl_items_against_trait(ccx,
it.span, it.span,
ast_trait_ref,
&*impl_trait_ref, &*impl_trait_ref,
impl_items.as_slice()); impl_items.as_slice());
} }
None => { } None => { }
} }
for impl_item in impl_items.iter() { for impl_item in impl_items.iter() {
match *impl_item { match *impl_item {
@ -739,12 +736,11 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
impl_span: Span, impl_span: Span,
ast_trait_ref: &ast::TraitRef, impl_trait_ref: &ty::PolyTraitRef<'tcx>,
impl_trait_ref: &ty::TraitRef<'tcx>,
impl_items: &[ast::ImplItem]) { impl_items: &[ast::ImplItem]) {
// Locate trait methods // Locate trait methods
let tcx = ccx.tcx; let tcx = ccx.tcx;
let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id); let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id());
// Check existing impl methods to see if they are both present in trait // Check existing impl methods to see if they are both present in trait
// and compatible with trait signature // and compatible with trait signature
@ -772,21 +768,16 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
impl_method.span, impl_method.span,
impl_method.pe_body().id, impl_method.pe_body().id,
&**trait_method_ty, &**trait_method_ty,
impl_trait_ref); &*impl_trait_ref);
} }
_ => { _ => {
// This is span_bug as it should have already been // This is span_bug as it should have already been
// caught in resolve. // caught in resolve.
tcx.sess tcx.sess.span_bug(
.span_bug(impl_method.span, impl_method.span,
format!("item `{}` is of a \ format!("item `{}` is of a different kind from its trait `{}`",
different kind from \ token::get_name(impl_item_ty.name()),
its trait `{}`", impl_trait_ref.repr(tcx)).as_slice());
token::get_name(
impl_item_ty.name()),
pprust::path_to_string(
&ast_trait_ref.path))
.as_slice());
} }
} }
} }
@ -795,11 +786,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// caught in resolve. // caught in resolve.
tcx.sess.span_bug( tcx.sess.span_bug(
impl_method.span, impl_method.span,
format!( format!("method `{}` is not a member of trait `{}`",
"method `{}` is not a member of trait `{}`", token::get_name(impl_item_ty.name()),
token::get_name(impl_item_ty.name()), impl_trait_ref.repr(tcx)).as_slice());
pprust::path_to_string(
&ast_trait_ref.path)).as_slice());
} }
} }
} }
@ -812,27 +801,19 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// corresponding type definition in the trait. // corresponding type definition in the trait.
let opt_associated_type = let opt_associated_type =
trait_items.iter() trait_items.iter()
.find(|ti| { .find(|ti| ti.name() == typedef_ty.name());
ti.name() == typedef_ty.name()
});
match opt_associated_type { match opt_associated_type {
Some(associated_type) => { Some(associated_type) => {
match (associated_type, &typedef_ty) { match (associated_type, &typedef_ty) {
(&ty::TypeTraitItem(_), (&ty::TypeTraitItem(_), &ty::TypeTraitItem(_)) => {}
&ty::TypeTraitItem(_)) => {}
_ => { _ => {
// This is `span_bug` as it should have // This is `span_bug` as it should have
// already been caught in resolve. // already been caught in resolve.
tcx.sess tcx.sess.span_bug(
.span_bug(typedef.span, typedef.span,
format!("item `{}` is of a \ format!("item `{}` is of a different kind from its trait `{}`",
different kind from \ token::get_name(typedef_ty.name()),
its trait `{}`", impl_trait_ref.repr(tcx)).as_slice());
token::get_name(
typedef_ty.name()),
pprust::path_to_string(
&ast_trait_ref.path))
.as_slice());
} }
} }
} }
@ -845,8 +826,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
"associated type `{}` is not a member of \ "associated type `{}` is not a member of \
trait `{}`", trait `{}`",
token::get_name(typedef_ty.name()), token::get_name(typedef_ty.name()),
pprust::path_to_string( impl_trait_ref.repr(tcx)).as_slice());
&ast_trait_ref.path)).as_slice());
} }
} }
} }
@ -855,7 +835,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// Check for missing items from trait // Check for missing items from trait
let provided_methods = ty::provided_trait_methods(tcx, let provided_methods = ty::provided_trait_methods(tcx,
impl_trait_ref.def_id); impl_trait_ref.def_id());
let mut missing_methods = Vec::new(); let mut missing_methods = Vec::new();
for trait_item in trait_items.iter() { for trait_item in trait_items.iter() {
match *trait_item { match *trait_item {
@ -870,8 +850,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
} }
}); });
let is_provided = let is_provided =
provided_methods.iter().any( provided_methods.iter().any(|m| m.name == trait_method.name);
|m| m.name == trait_method.name);
if !is_implemented && !is_provided { if !is_implemented && !is_provided {
missing_methods.push(format!("`{}`", token::get_name(trait_method.name))); missing_methods.push(format!("`{}`", token::get_name(trait_method.name)));
} }
@ -915,7 +894,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
impl_m_span: Span, impl_m_span: Span,
impl_m_body_id: ast::NodeId, impl_m_body_id: ast::NodeId,
trait_m: &ty::Method<'tcx>, trait_m: &ty::Method<'tcx>,
impl_trait_ref: &ty::TraitRef<'tcx>) { impl_trait_ref: &ty::PolyTraitRef<'tcx>) {
debug!("compare_impl_method(impl_trait_ref={})", debug!("compare_impl_method(impl_trait_ref={})",
impl_trait_ref.repr(tcx)); impl_trait_ref.repr(tcx));
@ -945,7 +924,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
let infcx = infer::new_infer_ctxt(tcx); let infcx = infer::new_infer_ctxt(tcx);
let trait_to_impl_substs = &impl_trait_ref.substs; let trait_to_impl_substs = impl_trait_ref.substs();
// Try to give more informative error messages about self typing // Try to give more informative error messages about self typing
// mismatches. Note that any mismatch will also be detected // mismatches. Note that any mismatch will also be detected
@ -1167,20 +1146,20 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
let trait_bound = let trait_bound =
trait_bound.subst(tcx, &trait_to_skol_substs); trait_bound.subst(tcx, &trait_to_skol_substs);
let infcx = infer::new_infer_ctxt(tcx); let infcx = infer::new_infer_ctxt(tcx);
infer::mk_sub_trait_refs(&infcx, infer::mk_sub_poly_trait_refs(&infcx,
true, true,
infer::Misc(impl_m_span), infer::Misc(impl_m_span),
trait_bound, trait_bound,
impl_trait_bound.clone()).is_ok() impl_trait_bound.clone()).is_ok()
}); });
if !found_match_in_trait { if !found_match_in_trait {
span_err!(tcx.sess, impl_m_span, E0052, span_err!(tcx.sess, impl_m_span, E0052,
"in method `{}`, type parameter {} requires bound `{}`, which is not \ "in method `{}`, type parameter {} requires bound `{}`, which is not \
required by the corresponding type parameter in the trait declaration", required by the corresponding type parameter in the trait declaration",
token::get_name(trait_m.name), token::get_name(trait_m.name),
i, i,
ppaux::trait_ref_to_string(tcx, &*impl_trait_bound)); impl_trait_bound.user_string(tcx));
} }
} }
} }
@ -1647,7 +1626,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn write_object_cast(&self, pub fn write_object_cast(&self,
key: ast::NodeId, key: ast::NodeId,
trait_ref: Rc<ty::TraitRef<'tcx>>) { trait_ref: Rc<ty::PolyTraitRef<'tcx>>) {
debug!("write_object_cast key={} trait_ref={}", debug!("write_object_cast key={} trait_ref={}",
key, trait_ref.repr(self.tcx())); key, trait_ref.repr(self.tcx()));
self.inh.object_cast_map.borrow_mut().insert(key, trait_ref); self.inh.object_cast_map.borrow_mut().insert(key, trait_ref);
@ -1745,7 +1724,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.register_unsize_obligations(span, &**u) self.register_unsize_obligations(span, &**u)
} }
ty::UnsizeVtable(ref ty_trait, self_ty) => { ty::UnsizeVtable(ref ty_trait, self_ty) => {
vtable::check_object_safety(self.tcx(), &ty_trait.principal, span); vtable::check_object_safety(self.tcx(), ty_trait, span);
// If the type is `Foo+'a`, ensures that the type // If the type is `Foo+'a`, ensures that the type
// being cast to `Foo+'a` implements `Foo`: // being cast to `Foo+'a` implements `Foo`:
vtable::register_object_cast_obligations(self, vtable::register_object_cast_obligations(self,

View File

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use check::{FnCtxt, structurally_resolved_type}; use check::{FnCtxt, structurally_resolved_type};
use middle::subst::{SelfSpace, FnSpace}; use middle::subst::{FnSpace};
use middle::traits; use middle::traits;
use middle::traits::{SelectionError, OutputTypeParameterMismatch, Overflow, Unimplemented}; use middle::traits::{SelectionError, OutputTypeParameterMismatch, Overflow, Unimplemented};
use middle::traits::{Obligation, ObligationCause}; use middle::traits::{Obligation, ObligationCause};
@ -44,7 +44,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// Ensure that if ~T is cast to ~Trait, then T : Trait // Ensure that if ~T is cast to ~Trait, then T : Trait
push_cast_obligation(fcx, cast_expr, object_trait, referent_ty); push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
check_object_safety(fcx.tcx(), &object_trait.principal, source_expr.span); check_object_safety(fcx.tcx(), object_trait, source_expr.span);
} }
(&ty::ty_rptr(referent_region, ty::mt { ty: referent_ty, (&ty::ty_rptr(referent_region, ty::mt { ty: referent_ty,
@ -68,7 +68,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
target_region, target_region,
referent_region); referent_region);
check_object_safety(fcx.tcx(), &object_trait.principal, source_expr.span); check_object_safety(fcx.tcx(), object_trait, source_expr.span);
} }
} }
@ -132,24 +132,19 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// self by value, has no type parameters and does not use the `Self` type, except // self by value, has no type parameters and does not use the `Self` type, except
// in self position. // in self position.
pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>, pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
object_trait: &ty::TraitRef<'tcx>, object_trait: &ty::TyTrait<'tcx>,
span: Span) { span: Span)
{
let mut object = object_trait.clone(); let object_trait_ref = object_trait.principal_trait_ref_with_self_ty(ty::mk_err());
if object.substs.types.len(SelfSpace) == 0 { for tr in traits::supertraits(tcx, object_trait_ref) {
object.substs.types.push(SelfSpace, ty::mk_err());
}
let object = Rc::new(object);
for tr in traits::supertraits(tcx, object) {
check_object_safety_inner(tcx, &*tr, span); check_object_safety_inner(tcx, &*tr, span);
} }
} }
fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>, fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
object_trait: &ty::TraitRef<'tcx>, object_trait: &ty::PolyTraitRef<'tcx>,
span: Span) { span: Span) {
let trait_items = ty::trait_items(tcx, object_trait.def_id); let trait_items = ty::trait_items(tcx, object_trait.def_id());
let mut errors = Vec::new(); let mut errors = Vec::new();
for item in trait_items.iter() { for item in trait_items.iter() {
@ -163,7 +158,7 @@ fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
let mut errors = errors.iter().flat_map(|x| x.iter()).peekable(); let mut errors = errors.iter().flat_map(|x| x.iter()).peekable();
if errors.peek().is_some() { if errors.peek().is_some() {
let trait_name = ty::item_path_str(tcx, object_trait.def_id); let trait_name = ty::item_path_str(tcx, object_trait.def_id());
span_err!(tcx.sess, span, E0038, span_err!(tcx.sess, span, E0038,
"cannot convert to a trait object because trait `{}` is not object-safe", "cannot convert to a trait object because trait `{}` is not object-safe",
trait_name); trait_name);
@ -237,7 +232,7 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
span: Span, span: Span,
object_trait: &ty::TyTrait<'tcx>, object_trait: &ty::TyTrait<'tcx>,
referent_ty: Ty<'tcx>) referent_ty: Ty<'tcx>)
-> Rc<ty::TraitRef<'tcx>> -> Rc<ty::PolyTraitRef<'tcx>>
{ {
// We can only make objects from sized types. // We can only make objects from sized types.
fcx.register_builtin_bound( fcx.register_builtin_bound(
@ -256,17 +251,9 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
referent_ty.repr(fcx.tcx()), referent_ty.repr(fcx.tcx()),
object_trait_ty.repr(fcx.tcx())); object_trait_ty.repr(fcx.tcx()));
// Take the type parameters from the object type, but set
// the Self type (which is unknown, for the object type)
// to be the type we are casting from.
let mut object_substs = object_trait.principal.substs.clone();
assert!(object_substs.self_ty().is_none());
object_substs.types.push(SelfSpace, referent_ty);
// Create the obligation for casting from T to Trait. // Create the obligation for casting from T to Trait.
let object_trait_ref = let object_trait_ref =
Rc::new(ty::TraitRef { def_id: object_trait.principal.def_id, object_trait.principal_trait_ref_with_self_ty(referent_ty);
substs: object_substs });
let object_obligation = let object_obligation =
Obligation::new( Obligation::new(
ObligationCause::new(span, ObligationCause::new(span,
@ -457,7 +444,7 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
trait_ref.repr(fcx.tcx()), trait_ref.repr(fcx.tcx()),
self_ty.repr(fcx.tcx()), self_ty.repr(fcx.tcx()),
obligation.repr(fcx.tcx())); obligation.repr(fcx.tcx()));
let all_types = &trait_ref.substs.types; let all_types = &trait_ref.substs().types;
if all_types.iter().any(|&t| ty::type_is_error(t)) { if all_types.iter().any(|&t| ty::type_is_error(t)) {
} else if all_types.iter().any(|&t| ty::type_needs_infer(t)) { } else if all_types.iter().any(|&t| ty::type_needs_infer(t)) {
// This is kind of a hack: it frequently happens that some earlier // This is kind of a hack: it frequently happens that some earlier
@ -476,7 +463,7 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// anyway. In that case, why inundate the user. // anyway. In that case, why inundate the user.
if !fcx.tcx().sess.has_errors() { if !fcx.tcx().sess.has_errors() {
if fcx.ccx.tcx.lang_items.sized_trait() if fcx.ccx.tcx.lang_items.sized_trait()
.map_or(false, |sized_id| sized_id == trait_ref.def_id) { .map_or(false, |sized_id| sized_id == trait_ref.def_id()) {
fcx.tcx().sess.span_err( fcx.tcx().sess.span_err(
obligation.cause.span, obligation.cause.span,
format!( format!(

View File

@ -186,7 +186,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
// There are special rules that apply to drop. // There are special rules that apply to drop.
if if
fcx.tcx().lang_items.drop_trait() == Some(trait_ref.def_id) && fcx.tcx().lang_items.drop_trait() == Some(trait_ref.def_id()) &&
!attr::contains_name(item.attrs.as_slice(), "unsafe_destructor") !attr::contains_name(item.attrs.as_slice(), "unsafe_destructor")
{ {
match self_ty.sty { match self_ty.sty {
@ -200,7 +200,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
} }
} }
if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id) { if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id()) {
// This is checked in coherence. // This is checked in coherence.
return return
} }
@ -219,7 +219,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
traits::ObligationCause::new( traits::ObligationCause::new(
item.span, item.span,
fcx.body_id, fcx.body_id,
traits::ItemObligation(trait_ref.def_id)); traits::ItemObligation(trait_ref.def_id()));
// Find the supertrait bounds. This will add `int:Bar`. // Find the supertrait bounds. This will add `int:Bar`.
let predicates = ty::predicates_for_trait_ref(fcx.tcx(), &trait_ref); let predicates = ty::predicates_for_trait_ref(fcx.tcx(), &trait_ref);
@ -264,18 +264,18 @@ impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
/// ///
/// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated /// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
/// to the point where impl `A : Trait<B>` is implemented). /// to the point where impl `A : Trait<B>` is implemented).
pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) { pub fn check_trait_ref(&mut self, trait_ref: &ty::PolyTraitRef<'tcx>) {
let trait_def = ty::lookup_trait_def(self.fcx.tcx(), trait_ref.def_id); let trait_def = ty::lookup_trait_def(self.fcx.tcx(), trait_ref.def_id());
let bounds = trait_def.generics.to_bounds(self.tcx(), &trait_ref.substs); let bounds = trait_def.generics.to_bounds(self.tcx(), trait_ref.substs());
self.fcx.add_obligations_for_parameters( self.fcx.add_obligations_for_parameters(
traits::ObligationCause::new( traits::ObligationCause::new(
self.span, self.span,
self.fcx.body_id, self.fcx.body_id,
traits::ItemObligation(trait_ref.def_id)), traits::ItemObligation(trait_ref.def_id())),
&bounds); &bounds);
for &ty in trait_ref.substs.types.iter() { for &ty in trait_ref.substs().types.iter() {
self.check_traits_in_ty(ty); self.check_traits_in_ty(ty);
} }
} }

View File

@ -64,7 +64,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
} }
ty_trait(ref t) => { ty_trait(ref t) => {
Some(t.principal.def_id) Some(t.principal.def_id())
} }
ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
@ -339,7 +339,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
// Record all the trait items. // Record all the trait items.
for trait_ref in associated_traits.iter() { for trait_ref in associated_traits.iter() {
self.add_trait_impl(trait_ref.def_id, impl_def_id); self.add_trait_impl(trait_ref.def_id(), impl_def_id);
} }
// For any methods that use a default implementation, add them to // For any methods that use a default implementation, add them to

View File

@ -55,7 +55,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
self.check_def_id(item.span, def_id); self.check_def_id(item.span, def_id);
} }
ty::ty_trait(box ty::TyTrait{ ref principal, ..}) => { ty::ty_trait(box ty::TyTrait{ ref principal, ..}) => {
self.check_def_id(item.span, principal.def_id); self.check_def_id(item.span, principal.def_id());
} }
_ => { _ => {
span_err!(self.tcx.sess, item.span, E0118, span_err!(self.tcx.sess, item.span, E0118,

View File

@ -45,7 +45,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
} }
Some(trait_ref) => { Some(trait_ref) => {
let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id); let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id());
match (trait_def.unsafety, unsafety) { match (trait_def.unsafety, unsafety) {
(ast::Unsafety::Normal, ast::Unsafety::Unsafe) => { (ast::Unsafety::Normal, ast::Unsafety::Unsafe) => {
self.tcx.sess.span_err( self.tcx.sess.span_err(

View File

@ -652,7 +652,7 @@ fn is_associated_type_valid_for_param(ty: Ty,
if let ty::ty_param(param_ty) = ty.sty { if let ty::ty_param(param_ty) = ty.sty {
let type_parameter = generics.types.get(param_ty.space, param_ty.idx); let type_parameter = generics.types.get(param_ty.space, param_ty.idx);
for trait_bound in type_parameter.bounds.trait_bounds.iter() { for trait_bound in type_parameter.bounds.trait_bounds.iter() {
if trait_bound.def_id == trait_id { if trait_bound.def_id() == trait_id {
return true return true
} }
} }
@ -1638,8 +1638,8 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let param_id = trait_id; let param_id = trait_id;
let self_trait_ref = let self_trait_ref =
Rc::new(ty::TraitRef { def_id: local_def(trait_id), Rc::new(ty::bind(ty::TraitRef { def_id: local_def(trait_id),
substs: (*substs).clone() }); substs: (*substs).clone() }));
let def = ty::TypeParameterDef { let def = ty::TypeParameterDef {
space: subst::SelfSpace, space: subst::SelfSpace,
@ -2015,7 +2015,7 @@ fn compute_bounds<'tcx,AC>(this: &AC,
&param_bounds, &param_bounds,
span); span);
param_bounds.trait_bounds.sort_by(|a,b| a.def_id.cmp(&b.def_id)); param_bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
param_bounds param_bounds
} }
@ -2031,13 +2031,13 @@ fn check_bounds_compatible<'tcx>(tcx: &ty::ctxt<'tcx>,
tcx, tcx,
param_bounds.trait_bounds.as_slice(), param_bounds.trait_bounds.as_slice(),
|trait_ref| { |trait_ref| {
let trait_def = ty::lookup_trait_def(tcx, trait_ref.def_id); let trait_def = ty::lookup_trait_def(tcx, trait_ref.def_id());
if trait_def.bounds.builtin_bounds.contains(&ty::BoundSized) { if trait_def.bounds.builtin_bounds.contains(&ty::BoundSized) {
span_err!(tcx.sess, span, E0129, span_err!(tcx.sess, span, E0129,
"incompatible bounds on type parameter `{}`, \ "incompatible bounds on type parameter `{}`, \
bound `{}` does not allow unsized type", bound `{}` does not allow unsized type",
name_of_bounded_thing.user_string(tcx), name_of_bounded_thing.user_string(tcx),
ppaux::trait_ref_to_string(tcx, &*trait_ref)); trait_ref.user_string(tcx));
} }
true true
}); });
@ -2057,14 +2057,14 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
trait_bounds, trait_bounds,
region_bounds } = region_bounds } =
astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice()); astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice());
let trait_bounds: Vec<Rc<ty::TraitRef>> = let trait_bounds: Vec<Rc<ty::PolyTraitRef>> =
trait_bounds.into_iter() trait_bounds.into_iter()
.map(|bound| { .map(|bound| {
astconv::instantiate_trait_ref(this, astconv::instantiate_poly_trait_ref(this,
&ExplicitRscope, &ExplicitRscope,
&bound.trait_ref, bound,
Some(param_ty.to_ty(this.tcx())), Some(param_ty.to_ty(this.tcx())),
AllowEqConstraints::Allow) AllowEqConstraints::Allow)
}) })
.collect(); .collect();
let region_bounds: Vec<ty::Region> = let region_bounds: Vec<ty::Region> =

View File

@ -777,13 +777,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
} }
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => { ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
let trait_def = ty::lookup_trait_def(self.tcx(), principal.def_id); let trait_def = ty::lookup_trait_def(self.tcx(), principal.def_id());
let generics = &trait_def.generics; let generics = &trait_def.generics;
// Traits DO have a Self type parameter, but it is // Traits DO have a Self type parameter, but it is
// erased from object types. // erased from object types.
assert!(!generics.types.is_empty_in(subst::SelfSpace) && assert!(!generics.types.is_empty_in(subst::SelfSpace) &&
principal.substs.types.is_empty_in(subst::SelfSpace)); principal.substs().types.is_empty_in(subst::SelfSpace));
// Traits never declare region parameters in the self // Traits never declare region parameters in the self
// space. // space.
@ -799,10 +799,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_region(bounds.region_bound, contra); self.add_constraints_from_region(bounds.region_bound, contra);
self.add_constraints_from_substs( self.add_constraints_from_substs(
principal.def_id, principal.def_id(),
generics.types.get_slice(subst::TypeSpace), generics.types.get_slice(subst::TypeSpace),
generics.regions.get_slice(subst::TypeSpace), generics.regions.get_slice(subst::TypeSpace),
&principal.substs, principal.substs(),
variance); variance);
} }

View File

@ -281,7 +281,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
// If this is an impl for a #[doc(hidden)] trait, be sure to not inline it. // If this is an impl for a #[doc(hidden)] trait, be sure to not inline it.
match associated_trait { match associated_trait {
Some(ref t) => { Some(ref t) => {
let trait_attrs = load_attrs(cx, tcx, t.def_id); let trait_attrs = load_attrs(cx, tcx, t.def_id());
if trait_attrs.iter().any(|a| is_doc_hidden(a)) { if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
return None return None
} }

View File

@ -575,6 +575,12 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
} }
} }
impl<'tcx> Clean<TyParamBound> for ty::PolyTraitRef<'tcx> {
fn clean(&self, cx: &DocContext) -> TyParamBound {
self.value.clean(cx)
}
}
impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> { impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
fn clean(&self, cx: &DocContext) -> TyParamBound { fn clean(&self, cx: &DocContext) -> TyParamBound {
let tcx = match cx.tcx_opt() { let tcx = match cx.tcx_opt() {
@ -1391,8 +1397,10 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
} }
ty::ty_struct(did, ref substs) | ty::ty_struct(did, ref substs) |
ty::ty_enum(did, ref substs) | ty::ty_enum(did, ref substs) |
ty::ty_trait(box ty::TyTrait { principal: ty::TraitRef { def_id: did, ref substs }, ty::ty_trait(box ty::TyTrait {
.. }) => { principal: ty::Binder { value: ty::TraitRef { def_id: did, ref substs } },
.. }) =>
{
let fqn = csearch::get_item_path(cx.tcx(), did); let fqn = csearch::get_item_path(cx.tcx(), did);
let fqn: Vec<String> = fqn.into_iter().map(|i| { let fqn: Vec<String> = fqn.into_iter().map(|i| {
i.to_string() i.to_string()