mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Create distinct types for a PolyTraitRef (with bindings) and a normal TraitRef.
This commit is contained in:
parent
b3dcb85404
commit
3cf0fbeee9
@ -1785,7 +1785,7 @@ impl LintPass for Stability {
|
||||
..
|
||||
}) => {
|
||||
ty::trait_item(cx.tcx,
|
||||
trait_ref.def_id,
|
||||
trait_ref.def_id(),
|
||||
index).def_id()
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
|
||||
// if there is one.
|
||||
pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
def: ast::DefId)
|
||||
-> Option<Rc<ty::TraitRef<'tcx>>> {
|
||||
-> Option<Rc<ty::PolyTraitRef<'tcx>>> {
|
||||
let cstore = &tcx.sess.cstore;
|
||||
let cdata = cstore.get_crate_data(def.krate);
|
||||
decoder::get_impl_trait(&*cdata, def.node, tcx)
|
||||
|
@ -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,
|
||||
id: ast::NodeId,
|
||||
tcx: &ty::ctxt<'tcx>)
|
||||
-> Option<Rc<ty::TraitRef<'tcx>>>
|
||||
-> Option<Rc<ty::PolyTraitRef<'tcx>>>
|
||||
{
|
||||
let item_doc = lookup_item(id, cdata.data());
|
||||
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)))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
|
||||
}
|
||||
'x' => {
|
||||
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));
|
||||
assert_eq!(next(st), ']');
|
||||
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>
|
||||
{
|
||||
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)),
|
||||
parse_ty(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 {
|
||||
match next(st) {
|
||||
'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' => {
|
||||
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;
|
||||
|
@ -251,7 +251,7 @@ fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
||||
ty::ty_trait(box ty::TyTrait { ref principal,
|
||||
ref bounds }) => {
|
||||
mywrite!(w, "x[");
|
||||
enc_trait_ref(w, cx, principal);
|
||||
enc_trait_ref(w, cx, &principal.value);
|
||||
enc_existential_bounds(w, cx, bounds);
|
||||
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() {
|
||||
mywrite!(w, "I");
|
||||
enc_trait_ref(w, cx, &**tp);
|
||||
enc_trait_ref(w, cx, &tp.value);
|
||||
}
|
||||
|
||||
mywrite!(w, ".");
|
||||
@ -425,7 +425,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
|
||||
match *p {
|
||||
ty::Predicate::Trait(ref trait_ref) => {
|
||||
mywrite!(w, "t");
|
||||
enc_trait_ref(w, cx, &**trait_ref);
|
||||
enc_trait_ref(w, cx, &trait_ref.value);
|
||||
}
|
||||
ty::Predicate::Equate(a, b) => {
|
||||
mywrite!(w, "e");
|
||||
|
@ -887,7 +887,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
||||
this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
|
||||
this.emit_struct("MethodParam", 2, |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| {
|
||||
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_struct("MethodObject", 2, |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| {
|
||||
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_arg(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| {
|
||||
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.id(id);
|
||||
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_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, '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>)
|
||||
-> ty::TypeParameterDef<'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 {
|
||||
trait_ref: {
|
||||
this.read_struct_field("trait_ref", 0, |this| {
|
||||
Ok(this.read_trait_ref(dcx))
|
||||
Ok(this.read_poly_trait_ref(dcx))
|
||||
}).unwrap()
|
||||
},
|
||||
method_num: {
|
||||
@ -1473,7 +1475,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
ty::MethodObject {
|
||||
trait_ref: {
|
||||
this.read_struct_field("trait_ref", 0, |this| {
|
||||
Ok(this.read_trait_ref(dcx))
|
||||
Ok(this.read_poly_trait_ref(dcx))
|
||||
}).unwrap()
|
||||
},
|
||||
object_trait_id: {
|
||||
@ -1548,6 +1550,19 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
}).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>)
|
||||
-> ty::TypeParameterDef<'tcx> {
|
||||
self.read_opaque(|this, doc| {
|
||||
@ -1753,7 +1768,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
2 => {
|
||||
let ty_trait = try!(this.read_enum_variant_arg(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 {
|
||||
principal: (*principal).clone(),
|
||||
@ -1926,7 +1941,7 @@ fn decode_side_tables(dcx: &DecodeContext,
|
||||
dcx.tcx.method_map.borrow_mut().insert(method_call, method);
|
||||
}
|
||||
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()
|
||||
.insert(id, trait_ref);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ use middle::infer;
|
||||
use middle::traits;
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::expr_use_visitor as euv;
|
||||
use util::common::ErrorReported;
|
||||
use util::nodemap::NodeSet;
|
||||
|
||||
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 infcx = infer::new_infer_ctxt(self.tcx);
|
||||
let mut fulfill_cx = traits::FulfillmentContext::new();
|
||||
match traits::trait_ref_for_builtin_bound(self.tcx, ty::BoundSync, ty) {
|
||||
Ok(trait_ref) => {
|
||||
fulfill_cx.register_trait_ref(self.tcx, trait_ref,
|
||||
traits::ObligationCause::dummy());
|
||||
let env = ty::empty_parameter_environment();
|
||||
if !fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok() {
|
||||
self.tcx.sess.span_err(e.span, "shared static items must have a \
|
||||
type which implements Sync");
|
||||
}
|
||||
}
|
||||
Err(ErrorReported) => { }
|
||||
fulfill_cx.register_builtin_bound(self.tcx, ty, ty::BoundSync,
|
||||
traits::ObligationCause::dummy());
|
||||
let env = ty::empty_parameter_environment();
|
||||
if !fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok() {
|
||||
self.tcx.sess.span_err(e.span, "shared static items must have a \
|
||||
type which implements Sync");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
..
|
||||
}) => {
|
||||
let trait_item = ty::trait_item(self.tcx,
|
||||
trait_ref.def_id,
|
||||
trait_ref.def_id(),
|
||||
index);
|
||||
match trait_item {
|
||||
ty::MethodTraitItem(method) => {
|
||||
|
@ -265,7 +265,7 @@ impl OverloadedCallType {
|
||||
}
|
||||
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)
|
||||
@ -292,7 +292,7 @@ impl OverloadedCallType {
|
||||
}
|
||||
MethodTypeParam(MethodParam { 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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
|
||||
ty::ty_vec(..) => Some(VecSimplifiedType),
|
||||
ty::ty_ptr(_) => Some(PtrSimplifiedType),
|
||||
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, _) => {
|
||||
Some(StructSimplifiedType(def_id))
|
||||
|
@ -354,7 +354,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
(_, &ty::ty_trait(box ty::TyTrait { ref principal, bounds })) => {
|
||||
// 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(),
|
||||
bounds: bounds },
|
||||
ty_a)))
|
||||
@ -464,7 +464,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
|
||||
debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl);
|
||||
// FIXME what is purpose of this type `tr`?
|
||||
let tr = ty::mk_trait(tcx, (*principal).clone(), bounds);
|
||||
let tr = ty::mk_trait(tcx, principal.clone(), bounds);
|
||||
try!(self.subtype(mk_ty(tr), b));
|
||||
Ok(Some(AdjustDerefRef(AutoDerefRef {
|
||||
autoderefs: 1,
|
||||
|
@ -301,7 +301,21 @@ pub trait Combine<'tcx> {
|
||||
fn trait_refs(&self,
|
||||
a: &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
|
||||
// behavior
|
||||
}
|
||||
@ -410,7 +424,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
|
||||
(&ty::ty_trait(ref a_),
|
||||
&ty::ty_trait(ref 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));
|
||||
Ok(ty::mk_trait(tcx, principal, bounds))
|
||||
}
|
||||
|
@ -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>)
|
||||
-> cres<'tcx, ty::FnSig<'tcx>> {
|
||||
-> cres<'tcx, ty::FnSig<'tcx>>
|
||||
{
|
||||
try!(self.sub().fn_sigs(a, b));
|
||||
self.sub().fn_sigs(b, a)
|
||||
}
|
||||
|
||||
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::TraitRef<'tcx>> {
|
||||
try!(self.sub().trait_refs(a, b));
|
||||
self.sub().trait_refs(b, a)
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
try!(self.sub().poly_trait_refs(a, b));
|
||||
self.sub().poly_trait_refs(b, a)
|
||||
}
|
||||
}
|
||||
|
@ -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>)
|
||||
-> Rc<ty::TraitRef<'tcx>> {
|
||||
-> Rc<ty::PolyTraitRef<'tcx>> {
|
||||
Rc::new(infcx.resolve_type_vars_if_possible(&**self))
|
||||
}
|
||||
fn contains_error(&self) -> bool {
|
||||
ty::trait_ref_contains_error(&**self)
|
||||
ty::trait_ref_contains_error(&self.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,8 +126,8 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
|
||||
self.higher_ranked_glb(a, b)
|
||||
}
|
||||
|
||||
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::TraitRef<'tcx>> {
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>> {
|
||||
self.higher_ranked_glb(a, b)
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
a: &ty::TraitRef<'tcx>,
|
||||
b: &ty::TraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::TraitRef<'tcx>>
|
||||
a: &ty::PolyTraitRef<'tcx>,
|
||||
b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
// Different traits cannot be related
|
||||
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 })
|
||||
}
|
||||
Ok(ty::bind(try!(combiner.trait_refs(&a.value, &b.value))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,8 +122,8 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
|
||||
super_lattice_tys(self, a, b)
|
||||
}
|
||||
|
||||
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::TraitRef<'tcx>> {
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>> {
|
||||
self.higher_ranked_lub(a, b)
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ impl Copy for TypeOrigin {}
|
||||
#[deriving(Clone, Show)]
|
||||
pub enum ValuePairs<'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
|
||||
@ -402,17 +402,17 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
||||
|| 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,
|
||||
origin: TypeOrigin,
|
||||
a: Rc<ty::TraitRef<'tcx>>,
|
||||
b: Rc<ty::TraitRef<'tcx>>)
|
||||
a: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
b: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> ures<'tcx>
|
||||
{
|
||||
debug!("mk_sub_trait_refs({} <: {})",
|
||||
a.repr(cx.tcx), b.repr(cx.tcx));
|
||||
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,
|
||||
@ -679,12 +679,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn sub_trait_refs(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: Rc<ty::TraitRef<'tcx>>,
|
||||
b: Rc<ty::TraitRef<'tcx>>)
|
||||
-> ures<'tcx>
|
||||
pub fn sub_poly_trait_refs(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
b: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> ures<'tcx>
|
||||
{
|
||||
debug!("sub_trait_refs({} <: {})",
|
||||
a.repr(self.tcx),
|
||||
@ -695,7 +695,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
values: TraitRefs(expected_found(a_is_expected,
|
||||
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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -160,8 +160,8 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
|
||||
self.higher_ranked_sub(a, b)
|
||||
}
|
||||
|
||||
fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::TraitRef<'tcx>> {
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>> {
|
||||
self.higher_ranked_sub(a, b)
|
||||
}
|
||||
}
|
||||
|
@ -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 public_trait = tr.clone().map_or(false, |tr| {
|
||||
!is_local(tr.def_id) ||
|
||||
self.exported_items.contains(&tr.def_id.node)
|
||||
!is_local(tr.value.def_id) ||
|
||||
self.exported_items.contains(&tr.value.def_id.node)
|
||||
});
|
||||
|
||||
if public_ty || public_trait {
|
||||
@ -407,7 +407,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||
match ty::impl_trait_ref(self.tcx, id) {
|
||||
Some(t) => {
|
||||
debug!("privacy - impl of trait {}", id);
|
||||
self.def_privacy(t.def_id)
|
||||
self.def_privacy(t.value.def_id)
|
||||
}
|
||||
None => {
|
||||
debug!("privacy - found a method {}",
|
||||
@ -432,7 +432,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||
match ty::impl_trait_ref(self.tcx, id) {
|
||||
Some(t) => {
|
||||
debug!("privacy - impl of trait {}", id);
|
||||
self.def_privacy(t.def_id)
|
||||
self.def_privacy(t.value.def_id)
|
||||
}
|
||||
None => {
|
||||
debug!("privacy - found a typedef {}",
|
||||
@ -811,7 +811,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||
// is whether the trait itself is accessible or not.
|
||||
MethodTypeParam(MethodParam { 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"));
|
||||
}
|
||||
}
|
||||
|
@ -65,15 +65,15 @@ pub fn impl_is_local(tcx: &ty::ctxt,
|
||||
debug!("trait_ref={}", trait_ref.repr(tcx));
|
||||
|
||||
// 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",
|
||||
trait_ref.def_id.repr(tcx));
|
||||
trait_ref.value.def_id.repr(tcx));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, at least one of the input types must be local to the
|
||||
// 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 {
|
||||
@ -143,7 +143,7 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -28,7 +28,7 @@ use super::ObligationCause;
|
||||
use super::PredicateObligation;
|
||||
use super::Selection;
|
||||
use super::select::SelectionContext;
|
||||
use super::trait_ref_for_builtin_bound;
|
||||
use super::poly_trait_ref_for_builtin_bound;
|
||||
use super::Unimplemented;
|
||||
|
||||
/// The fulfillment context is used to drive trait resolution. It
|
||||
@ -107,7 +107,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
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) => {
|
||||
self.register_trait_ref(tcx, trait_ref, cause);
|
||||
}
|
||||
@ -117,7 +117,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
|
||||
|
||||
pub fn register_trait_ref<'a>(&mut self,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
cause: ObligationCause<'tcx>)
|
||||
{
|
||||
/*!
|
||||
|
@ -33,7 +33,7 @@ pub use self::util::supertraits;
|
||||
pub use self::util::Supertraits;
|
||||
pub use self::util::search_trait_and_supertraits_from_bound;
|
||||
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 fulfill;
|
||||
@ -54,7 +54,7 @@ pub struct Obligation<'tcx, T> {
|
||||
}
|
||||
|
||||
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.
|
||||
#[deriving(Copy, Clone)]
|
||||
@ -115,7 +115,9 @@ pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
|
||||
pub enum SelectionError<'tcx> {
|
||||
Unimplemented,
|
||||
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> {
|
||||
@ -226,7 +228,7 @@ pub struct VtableBuiltinData<N> {
|
||||
#[deriving(PartialEq,Eq,Clone)]
|
||||
pub struct VtableParamData<'tcx> {
|
||||
// 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
|
||||
@ -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> {
|
||||
self.trait_ref.self_ty()
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use super::{util};
|
||||
use middle::fast_reject;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::subst::{Subst, Substs, VecPerParamSpace};
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::ty::{mod, Ty, RegionEscape};
|
||||
use middle::infer;
|
||||
use middle::infer::{InferCtxt, TypeSkolemizer};
|
||||
use middle::ty_fold::TypeFoldable;
|
||||
@ -74,14 +74,14 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {
|
||||
|
||||
/// Trait ref from `obligation` but skolemized with the
|
||||
/// 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>>
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct SelectionCache<'tcx> {
|
||||
hashmap: RefCell<HashMap<Rc<ty::TraitRef<'tcx>>,
|
||||
hashmap: RefCell<HashMap<Rc<ty::PolyTraitRef<'tcx>>,
|
||||
SelectionResult<'tcx, Candidate<'tcx>>>>,
|
||||
}
|
||||
|
||||
@ -347,13 +347,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// This suffices to allow chains like `FnMut` implemented in
|
||||
// terms of `Fn` etc, but we could probably make this more
|
||||
// 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));
|
||||
if
|
||||
unbound_input_types &&
|
||||
(self.intercrate ||
|
||||
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",
|
||||
stack.skol_trait_ref.repr(self.tcx()));
|
||||
@ -569,7 +569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
fn pick_candidate_cache(&self,
|
||||
cache_skol_trait_ref: &Rc<ty::TraitRef<'tcx>>)
|
||||
cache_skol_trait_ref: &Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> &SelectionCache<'tcx>
|
||||
{
|
||||
// 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
|
||||
// the cache of the param-environment.
|
||||
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))
|
||||
{
|
||||
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.
|
||||
if
|
||||
!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))
|
||||
{
|
||||
return &self.param_env.selection_cache;
|
||||
@ -615,7 +615,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
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>>>
|
||||
{
|
||||
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,
|
||||
cache_skol_trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
cache_skol_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
candidate: SelectionResult<'tcx, Candidate<'tcx>>)
|
||||
{
|
||||
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
|
||||
// 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) => {
|
||||
debug!("obligation self ty is {}",
|
||||
obligation.self_ty().repr(self.tcx()));
|
||||
@ -696,7 +696,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
debug!("assemble_candidates_from_caller_bounds({})",
|
||||
obligation.repr(self.tcx()));
|
||||
|
||||
let caller_trait_refs: Vec<Rc<ty::TraitRef>> =
|
||||
let caller_trait_refs: Vec<_> =
|
||||
self.param_env.caller_bounds.predicates.iter()
|
||||
.filter_map(|o| o.to_trait())
|
||||
.collect();
|
||||
@ -731,7 +731,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
candidates: &mut CandidateSet<'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,
|
||||
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
|
||||
// the other traits (e.g. `FnMut`) since those are provided by blanket
|
||||
// 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(());
|
||||
}
|
||||
|
||||
@ -814,7 +814,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
candidates: &mut CandidateSet<'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() {
|
||||
self.infcx.probe(|| {
|
||||
match self.match_impl(impl_def_id, obligation) {
|
||||
@ -926,8 +926,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let origin =
|
||||
infer::RelateOutputImplTypes(stack.obligation.cause.span);
|
||||
self.infcx
|
||||
.sub_trait_refs(false, origin,
|
||||
impl_trait_ref, vt.bound.clone())
|
||||
.sub_poly_trait_refs(false, origin, impl_trait_ref, vt.bound.clone())
|
||||
.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 {
|
||||
ty::BoundSized => {
|
||||
Err(Unimplemented)
|
||||
}
|
||||
ty::BoundCopy | ty::BoundSync | ty::BoundSend => {
|
||||
if bounds.builtin_bounds.contains(&bound) {
|
||||
if data.bounds.builtin_bounds.contains(&bound) {
|
||||
Ok(If(Vec::new()))
|
||||
} else {
|
||||
// Recursively check all supertraits to find out if any further
|
||||
// bounds are required and thus we must fulfill.
|
||||
// We have to create a temp trait ref here since TyTraits don't
|
||||
// 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())
|
||||
});
|
||||
let tmp_tr = data.principal_trait_ref_with_self_ty(ty::mk_err());
|
||||
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) {
|
||||
return Ok(If(Vec::new()))
|
||||
@ -1534,10 +1527,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
vec![],
|
||||
vec![],
|
||||
self_ty);
|
||||
let trait_ref = Rc::new(ty::TraitRef {
|
||||
def_id: obligation.trait_ref.def_id,
|
||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef {
|
||||
def_id: obligation.trait_ref.def_id(),
|
||||
substs: substs,
|
||||
});
|
||||
}));
|
||||
|
||||
let () =
|
||||
try!(self.confirm(obligation.cause,
|
||||
@ -1577,10 +1570,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
vec![],
|
||||
vec![],
|
||||
obligation.self_ty());
|
||||
let trait_ref = Rc::new(ty::TraitRef {
|
||||
def_id: obligation.trait_ref.def_id,
|
||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef {
|
||||
def_id: obligation.trait_ref.def_id(),
|
||||
substs: substs,
|
||||
});
|
||||
}));
|
||||
|
||||
debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
|
||||
closure_def_id.repr(self.tcx()),
|
||||
@ -1650,7 +1643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
fn fast_reject_trait_refs(&mut self,
|
||||
obligation: &TraitObligation,
|
||||
impl_trait_ref: &ty::TraitRef)
|
||||
impl_trait_ref: &ty::PolyTraitRef)
|
||||
-> bool
|
||||
{
|
||||
// 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,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>)
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> Result<(),()>
|
||||
{
|
||||
debug!("match_trait_refs: obligation={} trait_ref={}",
|
||||
@ -1681,10 +1674,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
trait_ref.repr(self.tcx()));
|
||||
|
||||
let origin = infer::RelateOutputImplTypes(obligation.cause.span);
|
||||
match self.infcx.sub_trait_refs(false,
|
||||
origin,
|
||||
trait_ref,
|
||||
obligation.trait_ref.clone()) {
|
||||
match self.infcx.sub_poly_trait_refs(false,
|
||||
origin,
|
||||
trait_ref,
|
||||
obligation.trait_ref.clone()) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => Err(()),
|
||||
}
|
||||
@ -1783,7 +1776,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
fn confirm_impl_vtable(&mut self,
|
||||
impl_def_id: ast::DefId,
|
||||
obligation_cause: ObligationCause<'tcx>,
|
||||
obligation_trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
obligation_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Result<(), SelectionError<'tcx>>
|
||||
{
|
||||
@ -1814,17 +1807,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
/// we report an error to the user.
|
||||
fn confirm(&mut self,
|
||||
obligation_cause: ObligationCause,
|
||||
obligation_trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
expected_trait_ref: Rc<ty::TraitRef<'tcx>>)
|
||||
obligation_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
expected_trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> Result<(), SelectionError<'tcx>>
|
||||
{
|
||||
let origin = infer::RelateOutputImplTypes(obligation_cause.span);
|
||||
|
||||
let obligation_trait_ref = obligation_trait_ref.clone();
|
||||
match self.infcx.sub_trait_refs(false,
|
||||
origin,
|
||||
expected_trait_ref.clone(),
|
||||
obligation_trait_ref.clone()) {
|
||||
match self.infcx.sub_poly_trait_refs(false,
|
||||
origin,
|
||||
expected_trait_ref.clone(),
|
||||
obligation_trait_ref.clone()) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(e) => Err(OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ struct StackEntry<'tcx> {
|
||||
|
||||
pub fn elaborate_trait_ref<'cx, 'tcx>(
|
||||
tcx: &'cx ty::ctxt<'tcx>,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>)
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> Elaborator<'cx, 'tcx>
|
||||
{
|
||||
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>(
|
||||
tcx: &'cx ty::ctxt<'tcx>,
|
||||
trait_refs: &[Rc<ty::TraitRef<'tcx>>])
|
||||
trait_refs: &[Rc<ty::PolyTraitRef<'tcx>>])
|
||||
-> Elaborator<'cx, 'tcx>
|
||||
{
|
||||
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>,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>)
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> Supertraits<'cx, 'tcx>
|
||||
{
|
||||
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>,
|
||||
bounds: &[Rc<ty::TraitRef<'tcx>>])
|
||||
bounds: &[Rc<ty::PolyTraitRef<'tcx>>])
|
||||
-> Supertraits<'cx, 'tcx>
|
||||
{
|
||||
let elaborator = elaborate_trait_refs(tcx, bounds);
|
||||
Supertraits { elaborator: elaborator }
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> Iterator<Rc<ty::TraitRef<'tcx>>> for Supertraits<'cx, 'tcx> {
|
||||
fn next(&mut self) -> Option<Rc<ty::TraitRef<'tcx>>> {
|
||||
impl<'cx, 'tcx> Iterator<Rc<ty::PolyTraitRef<'tcx>>> for Supertraits<'cx, 'tcx> {
|
||||
fn next(&mut self) -> Option<Rc<ty::PolyTraitRef<'tcx>>> {
|
||||
loop {
|
||||
match self.elaborator.next() {
|
||||
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>,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
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) {
|
||||
Ok(def_id) => {
|
||||
Ok(Rc::new(ty::TraitRef {
|
||||
Ok(Rc::new(ty::bind(ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: Substs::empty().with_self_ty(param_ty)
|
||||
}))
|
||||
})))
|
||||
}
|
||||
Err(e) => {
|
||||
tcx.sess.err(e.as_slice());
|
||||
@ -294,7 +294,7 @@ pub fn predicate_for_builtin_bound<'tcx>(
|
||||
param_ty: Ty<'tcx>)
|
||||
-> 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 {
|
||||
cause: cause,
|
||||
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
|
||||
/// 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`.
|
||||
pub fn search_trait_and_supertraits_from_bound<'tcx, F>(tcx: &ty::ctxt<'tcx>,
|
||||
caller_bound: Rc<ty::TraitRef<'tcx>>,
|
||||
mut test: F)
|
||||
-> Option<VtableParamData<'tcx>> where
|
||||
F: FnMut(ast::DefId) -> bool,
|
||||
pub fn search_trait_and_supertraits_from_bound<'tcx,F>(tcx: &ty::ctxt<'tcx>,
|
||||
caller_bound: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
mut test: F)
|
||||
-> Option<VtableParamData<'tcx>>
|
||||
where F: FnMut(ast::DefId) -> bool,
|
||||
{
|
||||
for bound in transitive_bounds(tcx, &[caller_bound]) {
|
||||
if test(bound.def_id) {
|
||||
if test(bound.def_id()) {
|
||||
let vtable_param = VtableParamData { bound: bound };
|
||||
return Some(vtable_param);
|
||||
}
|
||||
|
@ -479,7 +479,7 @@ pub enum MethodOrigin<'tcx> {
|
||||
pub struct MethodParam<'tcx> {
|
||||
// the precise trait reference that occurs as a bound -- this may
|
||||
// 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
|
||||
pub method_num: uint,
|
||||
@ -489,7 +489,7 @@ pub struct MethodParam<'tcx> {
|
||||
#[deriving(Clone, Show)]
|
||||
pub struct MethodObject<'tcx> {
|
||||
// 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
|
||||
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
|
||||
// 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
|
||||
/// `transmute` gives rise to these restrictions.
|
||||
@ -665,7 +665,7 @@ pub struct ctxt<'tcx> {
|
||||
/// A cache for the trait_items() routine
|
||||
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_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
|
||||
@ -1308,10 +1308,23 @@ pub enum sty<'tcx> {
|
||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||
pub struct TyTrait<'tcx> {
|
||||
// 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
|
||||
}
|
||||
|
||||
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,
|
||||
/// but perhaps the most recognizable form is in a where clause:
|
||||
///
|
||||
@ -1333,6 +1346,26 @@ pub struct TraitRef<'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
|
||||
/// 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
|
||||
@ -1416,7 +1449,7 @@ impl<'tcx> Copy for type_err<'tcx> {}
|
||||
pub struct ParamBounds<'tcx> {
|
||||
pub region_bounds: Vec<ty::Region>,
|
||||
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
|
||||
@ -1657,7 +1690,7 @@ pub enum Predicate<'tcx> {
|
||||
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
|
||||
/// the `Self` type of the trait reference and `A`, `B`, and `C`
|
||||
/// would be the parameters in the `TypeSpace`.
|
||||
Trait(Rc<TraitRef<'tcx>>),
|
||||
Trait(Rc<PolyTraitRef<'tcx>>),
|
||||
|
||||
/// where `T1 == T2`.
|
||||
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 {
|
||||
Predicate::Trait(ref t) => {
|
||||
Some(t.clone())
|
||||
@ -1748,14 +1781,6 @@ impl<'tcx> TraitRef<'tcx> {
|
||||
// associated types.
|
||||
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
|
||||
@ -2160,7 +2185,7 @@ impl FlagComputation {
|
||||
|
||||
&ty_trait(box TyTrait { ref principal, ref bounds }) => {
|
||||
let mut computation = FlagComputation::new();
|
||||
computation.add_substs(&principal.substs);
|
||||
computation.add_substs(principal.substs());
|
||||
self.add_bound_computation(&computation);
|
||||
|
||||
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>,
|
||||
principal: ty::TraitRef<'tcx>,
|
||||
principal: ty::PolyTraitRef<'tcx>,
|
||||
bounds: ExistentialBounds)
|
||||
-> Ty<'tcx> {
|
||||
// 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);
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -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>,
|
||||
bounds: BuiltinBounds,
|
||||
traits: &[Rc<TraitRef<'tcx>>])
|
||||
traits: &[Rc<PolyTraitRef<'tcx>>])
|
||||
-> TypeContents {
|
||||
let _i = indenter();
|
||||
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.
|
||||
fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
bounds: BuiltinBounds,
|
||||
traits: &[Rc<TraitRef<'tcx>>],
|
||||
traits: &[Rc<PolyTraitRef<'tcx>>],
|
||||
mut f: F) where
|
||||
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| {
|
||||
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() {
|
||||
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_closure(_) => "fn".to_string(),
|
||||
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, _) => {
|
||||
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)
|
||||
-> Option<Rc<TraitRef<'tcx>>> {
|
||||
-> Option<Rc<PolyTraitRef<'tcx>>> {
|
||||
memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
|
||||
if id.krate == ast::LOCAL_CRATE {
|
||||
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, _, _) => {
|
||||
match opt_trait {
|
||||
&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
|
||||
}
|
||||
@ -4813,7 +4840,7 @@ pub fn try_add_builtin_trait(
|
||||
pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
|
||||
match ty.sty {
|
||||
ty_trait(ref tt) =>
|
||||
Some(tt.principal.def_id),
|
||||
Some(tt.principal.def_id()),
|
||||
ty_struct(id, _) |
|
||||
ty_enum(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
|
||||
/// on the trait, with appropriate substitutions applied.
|
||||
pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
|
||||
trait_ref: &TraitRef<'tcx>)
|
||||
trait_ref: &PolyTraitRef<'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={})",
|
||||
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
|
||||
.iter()
|
||||
.map(|bound_trait_ref| {
|
||||
ty::TraitRef::new(bound_trait_ref.def_id,
|
||||
bound_trait_ref.substs.subst(tcx, &trait_ref.substs))
|
||||
ty::bind(
|
||||
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))
|
||||
.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
|
||||
// binders so we can just substitute in a straightforward way here.
|
||||
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 =
|
||||
trait_def.bounds.builtin_bounds.subst(tcx, &trait_ref.substs);
|
||||
trait_def.bounds.builtin_bounds.subst(tcx, trait_ref.substs());
|
||||
|
||||
let bounds = ty::ParamBounds {
|
||||
trait_bounds: trait_bounds,
|
||||
@ -5183,7 +5211,7 @@ pub fn predicates<'tcx>(
|
||||
let mut vec = Vec::new();
|
||||
|
||||
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)); }
|
||||
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
|
||||
// list.
|
||||
pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
|
||||
bounds: &[Rc<TraitRef<'tcx>>],
|
||||
bounds: &[Rc<PolyTraitRef<'tcx>>],
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(Rc<TraitRef<'tcx>>) -> bool,
|
||||
F: FnMut(Rc<PolyTraitRef<'tcx>>) -> bool,
|
||||
{
|
||||
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
|
||||
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>,
|
||||
opt_principal: Option<&TraitRef<'tcx>>, // None for boxed closures
|
||||
opt_principal: Option<&PolyTraitRef<'tcx>>, // None for closures
|
||||
others: BuiltinBounds)
|
||||
-> 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 opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| {
|
||||
let substs = principal.substs.with_self_ty(open_ty);
|
||||
vec!(Rc::new(ty::TraitRef::new(principal.def_id, substs)))
|
||||
let substs = principal.substs().with_self_ty(open_ty);
|
||||
vec!(Rc::new(ty::bind(ty::TraitRef::new(principal.def_id(), substs))))
|
||||
});
|
||||
|
||||
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.
|
||||
let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
|
||||
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
|
||||
@ -5938,11 +5966,11 @@ pub fn hash_crate_independent(tcx: &ctxt, ty: Ty, svh: &Svh) -> u64 {
|
||||
}
|
||||
ty_trait(box TyTrait { ref principal, bounds }) => {
|
||||
byte!(17);
|
||||
did(state, principal.def_id);
|
||||
did(state, principal.def_id());
|
||||
hash!(bounds);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -6200,7 +6228,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
|
||||
accumulator.push(region)
|
||||
}
|
||||
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_struct(_, ref substs) => {
|
||||
@ -6538,3 +6566,43 @@ pub fn can_type_implement_copy<'tcx>(tcx: &ctxt<'tcx>,
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
t: &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 {
|
||||
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> {
|
||||
fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
|
||||
ty::bind(self.value.fold_with(folder))
|
||||
|
@ -433,16 +433,11 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
||||
ty_trait(box ty::TyTrait {
|
||||
ref principal, ref bounds
|
||||
}) => {
|
||||
let base = ty::item_path_str(cx, principal.def_id);
|
||||
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 principal = principal.user_string(cx);
|
||||
let bound_str = bounds.user_string(cx);
|
||||
let bound_sep = if bound_str.is_empty() { "" } else { " + " };
|
||||
format!("{}{}{}",
|
||||
ty,
|
||||
principal,
|
||||
bound_sep,
|
||||
bound_str)
|
||||
}
|
||||
@ -749,7 +744,7 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
|
||||
// tells you everything you need to know.
|
||||
let base = ty::item_path_str(tcx, self.def_id);
|
||||
let trait_def = ty::lookup_trait_def(tcx, self.def_id);
|
||||
format!("<{} : {}>",
|
||||
format!("TraitRef({}, {})",
|
||||
self.substs.self_ty().repr(tcx),
|
||||
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 {
|
||||
// Replace any anonymous late-bound regions with named
|
||||
// variants, using gensym'd identifiers, so that we can
|
||||
@ -1178,7 +1173,7 @@ impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
|
||||
ty::BrAnon(_) |
|
||||
ty::BrFresh(_) |
|
||||
ty::BrEnv => {
|
||||
let name = token::gensym("r");
|
||||
let name = token::gensym("'r");
|
||||
names.push(token::get_name(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 the base string be either `SomeTrait` for `for<'a,'b> SomeTrait`,
|
||||
// depending on whether there are bound regions.
|
||||
let path_str = ty::item_path_str(tcx, self.def_id);
|
||||
let base =
|
||||
if names.is_empty() {
|
||||
path_str
|
||||
} else {
|
||||
format!("for<{}> {}", names.connect(","), path_str)
|
||||
};
|
||||
let trait_ref_str = trait_ref.value.user_string(tcx);
|
||||
if names.len() == 0 {
|
||||
trait_ref_str
|
||||
} else {
|
||||
format!("for<{}> {}", names.connect(","), trait_ref_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 did = trait_def.trait_ref.def_id;
|
||||
parameterized(tcx, base.as_slice(), &trait_ref.substs, &trait_def.generics, did)
|
||||
parameterized(tcx, path_str.as_slice(), &self.substs,
|
||||
&trait_def.generics, self.def_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -941,14 +941,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
ty::MethodTypeParam(ref mp) => {
|
||||
// method invoked on a type parameter
|
||||
let trait_item = ty::trait_item(&self.analysis.ty_cx,
|
||||
mp.trait_ref.def_id,
|
||||
mp.trait_ref.def_id(),
|
||||
mp.method_num);
|
||||
(None, Some(trait_item.def_id()))
|
||||
}
|
||||
ty::MethodTraitObject(ref mo) => {
|
||||
// method invoked on a trait instance
|
||||
let trait_item = ty::trait_item(&self.analysis.ty_cx,
|
||||
mo.trait_ref.def_id,
|
||||
mo.trait_ref.def_id(),
|
||||
mo.method_num);
|
||||
(None, Some(trait_item.def_id()))
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
|
||||
|
||||
// Compute the first substitution
|
||||
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();
|
||||
|
||||
// And compose them
|
||||
@ -435,7 +435,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
|
||||
debug!("trans_fn_with_vtables - default method: \
|
||||
substs = {}, trait_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));
|
||||
|
||||
(true, source_id, new_substs)
|
||||
|
@ -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.
|
||||
pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
span: Span,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>)
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> traits::Vtable<'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()));
|
||||
|
||||
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);
|
||||
|
||||
// Parameter environment is used to give details about type parameters,
|
||||
|
@ -99,7 +99,7 @@ pub struct LocalCrateContext<'tcx> {
|
||||
monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
|
||||
monomorphizing: RefCell<DefIdMap<uint>>,
|
||||
/// 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,
|
||||
const_cstr_cache: RefCell<FnvHashMap<InternedString, ValueRef>>,
|
||||
|
||||
@ -150,7 +150,7 @@ pub struct LocalCrateContext<'tcx> {
|
||||
/// contexts around the same size.
|
||||
n_llvm_insns: Cell<uint>,
|
||||
|
||||
trait_cache: RefCell<FnvHashMap<Rc<ty::TraitRef<'tcx>>,
|
||||
trait_cache: RefCell<FnvHashMap<Rc<ty::PolyTraitRef<'tcx>>,
|
||||
traits::Vtable<'tcx, ()>>>,
|
||||
}
|
||||
|
||||
@ -601,7 +601,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
&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>> {
|
||||
&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);
|
||||
}
|
||||
|
||||
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, ()>>> {
|
||||
&self.local.trait_cache
|
||||
}
|
||||
|
@ -429,8 +429,8 @@ impl<'tcx> TypeMap<'tcx> {
|
||||
|
||||
from_def_id_and_substs(self,
|
||||
cx,
|
||||
trait_data.principal.def_id,
|
||||
&trait_data.principal.substs,
|
||||
trait_data.principal.def_id(),
|
||||
trait_data.principal.substs(),
|
||||
&mut unique_type_id);
|
||||
},
|
||||
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.
|
||||
|
||||
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);
|
||||
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(']');
|
||||
},
|
||||
ty::ty_trait(ref trait_data) => {
|
||||
push_item_name(cx, trait_data.principal.def_id, false, output);
|
||||
push_type_params(cx, &trait_data.principal.substs, output);
|
||||
push_item_name(cx, trait_data.principal.def_id(), false, output);
|
||||
push_type_params(cx, trait_data.principal.substs(), output);
|
||||
},
|
||||
ty::ty_bare_fn(ty::BareFnTy{ unsafety, abi, ref sig } ) => {
|
||||
if unsafety == ast::Unsafety::Unsafe {
|
||||
|
@ -316,10 +316,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
bcx.ty_to_string(unadjusted_ty)).as_slice())
|
||||
},
|
||||
&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 =
|
||||
Rc::new(ty::TraitRef { def_id: principal.def_id,
|
||||
substs: substs });
|
||||
Rc::new(ty::bind(ty::TraitRef { def_id: principal.def_id(),
|
||||
substs: substs }));
|
||||
let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs);
|
||||
let box_ty = mk_ty(unadjusted_ty);
|
||||
PointerCast(bcx,
|
||||
|
@ -142,7 +142,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
span,
|
||||
(*trait_ref).clone());
|
||||
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)
|
||||
}
|
||||
|
||||
@ -239,8 +239,8 @@ pub fn trans_static_method_callee(bcx: Block,
|
||||
rcvr_assoc,
|
||||
Vec::new()));
|
||||
debug!("trait_substs={}", trait_substs.repr(bcx.tcx()));
|
||||
let trait_ref = Rc::new(ty::TraitRef { def_id: trait_id,
|
||||
substs: trait_substs });
|
||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef { def_id: trait_id,
|
||||
substs: trait_substs }));
|
||||
let vtbl = fulfill_obligation(bcx.ccx(),
|
||||
DUMMY_SP,
|
||||
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.
|
||||
pub fn get_vtable<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
box_ty: Ty<'tcx>,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>)
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>)
|
||||
-> ValueRef
|
||||
{
|
||||
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 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 \
|
||||
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>,
|
||||
datum: Datum<'tcx, Expr>,
|
||||
id: ast::NodeId,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
dest: expr::Dest)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let mut bcx = bcx;
|
||||
|
@ -524,6 +524,19 @@ fn convert_parenthesized_parameters<'tcx,AC>(this: &AC,
|
||||
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
|
||||
/// 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>,
|
||||
RS: RegionScope
|
||||
{
|
||||
match ::lookup_def_tcx(this.tcx(),
|
||||
ast_trait_ref.path.span,
|
||||
ast_trait_ref.ref_id) {
|
||||
match ::lookup_def_tcx(this.tcx(), ast_trait_ref.path.span, ast_trait_ref.ref_id) {
|
||||
def::DefTrait(trait_def_id) => {
|
||||
let trait_ref = Rc::new(ast_path_to_trait_ref(this,
|
||||
rscope,
|
||||
@ -749,7 +760,7 @@ fn ast_ty_to_trait_ref<'tcx,AC,RS>(this: &AC,
|
||||
rscope: &RS,
|
||||
ty: &ast::Ty,
|
||||
bounds: &[ast::TyParamBound])
|
||||
-> Result<ty::TraitRef<'tcx>, ErrorReported>
|
||||
-> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
|
||||
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) => {
|
||||
match this.tcx().def_map.borrow().get(&id) {
|
||||
Some(&def::DefTrait(trait_def_id)) => {
|
||||
return Ok(ast_path_to_trait_ref(this,
|
||||
rscope,
|
||||
trait_def_id,
|
||||
None,
|
||||
path,
|
||||
AllowEqConstraints::Allow));
|
||||
return Ok(ty::bind(ast_path_to_trait_ref(this,
|
||||
rscope,
|
||||
trait_def_id,
|
||||
None,
|
||||
path,
|
||||
AllowEqConstraints::Allow)));
|
||||
}
|
||||
_ => {
|
||||
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,
|
||||
rscope: &RS,
|
||||
span: Span,
|
||||
trait_ref: ty::TraitRef<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
bounds: &[ast::TyParamBound])
|
||||
-> Ty<'tcx>
|
||||
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) => {
|
||||
// N.B. this case overlaps somewhat with
|
||||
// TyObjectSum, see that fn for details
|
||||
let result = ast_path_to_trait_ref(this,
|
||||
rscope,
|
||||
trait_def_id,
|
||||
None,
|
||||
path,
|
||||
AllowEqConstraints::Allow);
|
||||
let result = ty::bind(ast_path_to_trait_ref(this,
|
||||
rscope,
|
||||
trait_def_id,
|
||||
None,
|
||||
path,
|
||||
AllowEqConstraints::Allow));
|
||||
trait_ref_to_object_type(this, rscope, path.span, result, &[])
|
||||
}
|
||||
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 tp_def = &(*ty_param_defs)[did.node];
|
||||
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();
|
||||
(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,
|
||||
rscope: &RS,
|
||||
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])
|
||||
-> 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) {
|
||||
Some(trait_bound) => {
|
||||
Some(instantiate_trait_ref(this,
|
||||
rscope,
|
||||
&trait_bound.trait_ref,
|
||||
None,
|
||||
AllowEqConstraints::Allow))
|
||||
Some(instantiate_poly_trait_ref(this,
|
||||
rscope,
|
||||
trait_bound,
|
||||
None,
|
||||
AllowEqConstraints::Allow))
|
||||
}
|
||||
None => {
|
||||
this.tcx().sess.span_err(
|
||||
@ -1481,7 +1492,7 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx, AC, RS>(
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
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)
|
||||
-> ty::ExistentialBounds
|
||||
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>,
|
||||
span: Span,
|
||||
explicit_region_bounds: &[&ast::Lifetime],
|
||||
principal_trait_ref: Option<&ty::TraitRef<'tcx>>,
|
||||
principal_trait_ref: Option<&ty::PolyTraitRef<'tcx>>,
|
||||
builtin_bounds: ty::BuiltinBounds)
|
||||
-> Option<ty::Region>
|
||||
{
|
||||
@ -1579,7 +1590,7 @@ fn compute_region_bound<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
|
||||
rscope: &RS,
|
||||
span: Span,
|
||||
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)
|
||||
-> ty::Region
|
||||
{
|
||||
|
@ -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 require_same_types;
|
||||
use util::nodemap::FnvHashMap;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std::cmp;
|
||||
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 tcx = pcx.fcx.ccx.tcx;
|
||||
|
||||
debug!("check_pat(pat={},expected={})",
|
||||
pat.repr(tcx),
|
||||
expected.repr(tcx));
|
||||
|
||||
match pat.node {
|
||||
ast::PatWild(_) => {
|
||||
fcx.write_ty(pat.id, expected);
|
||||
|
@ -180,7 +180,7 @@ fn deduce_unboxed_closure_expectations_from_expected_type<'a,'tcx>(
|
||||
|
||||
fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
|
||||
fcx: &FnCtxt<'a,'tcx>,
|
||||
trait_ref: &ty::TraitRef<'tcx>)
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>)
|
||||
-> Option<(ty::FnSig<'tcx>, ty::UnboxedClosureKind)>
|
||||
{
|
||||
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({})",
|
||||
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,
|
||||
None => { return None; }
|
||||
};
|
||||
|
||||
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);
|
||||
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));
|
||||
|
||||
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);
|
||||
debug!("ret_param_ty {}", ret_param_ty.repr(tcx));
|
||||
|
||||
|
@ -222,15 +222,15 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
// argument type), but those cases have already
|
||||
// been ruled out when we deemed the trait to be
|
||||
// "object safe".
|
||||
let substs = data.principal.substs.clone().with_self_ty(object_ty);
|
||||
let original_trait_ref =
|
||||
Rc::new(ty::TraitRef::new(data.principal.def_id, substs));
|
||||
let upcast_trait_ref = this.upcast(original_trait_ref.clone(), trait_def_id);
|
||||
data.principal_trait_ref_with_self_ty(object_ty);
|
||||
let upcast_trait_ref =
|
||||
this.upcast(original_trait_ref.clone(), trait_def_id);
|
||||
debug!("original_trait_ref={} upcast_trait_ref={} target_trait={}",
|
||||
original_trait_ref.repr(this.tcx()),
|
||||
upcast_trait_ref.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 {
|
||||
trait_ref: upcast_trait_ref,
|
||||
object_trait_id: trait_def_id,
|
||||
@ -257,7 +257,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
.subst(self.tcx(), &impl_polytype.substs);
|
||||
let origin = MethodTypeParam(MethodParam { trait_ref: impl_trait_ref.clone(),
|
||||
method_num: method_num });
|
||||
(impl_trait_ref.substs.clone(), origin)
|
||||
(impl_trait_ref.substs().clone(), origin)
|
||||
}
|
||||
|
||||
probe::TraitPick(trait_def_id, method_num) => {
|
||||
@ -272,16 +272,16 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
&trait_def.generics,
|
||||
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,
|
||||
method_num: method_num });
|
||||
(substs, origin)
|
||||
}
|
||||
|
||||
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 });
|
||||
(trait_ref.substs.clone(), origin)
|
||||
(trait_ref.substs().clone(), origin)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -637,12 +637,12 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
}
|
||||
|
||||
fn upcast(&mut self,
|
||||
source_trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
source_trait_ref: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
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()) {
|
||||
if super_trait_ref.def_id == target_trait_def_id {
|
||||
if super_trait_ref.def_id() == target_trait_def_id {
|
||||
return super_trait_ref;
|
||||
}
|
||||
}
|
||||
|
@ -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>`
|
||||
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
|
||||
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
|
||||
// late-bound regions from the fn itself, not the impl.
|
||||
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,
|
||||
infer::FnCall,
|
||||
&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
|
||||
// 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());
|
||||
fcx.add_obligations_for_parameters(
|
||||
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(),
|
||||
method_num: method_num}),
|
||||
ty: fty,
|
||||
substs: trait_ref.substs.clone()
|
||||
substs: trait_ref.substs().clone()
|
||||
};
|
||||
|
||||
debug!("callee = {}", callee.repr(fcx.tcx()));
|
||||
@ -379,7 +379,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
None => format!(""),
|
||||
Some(trait_ref) => format!(" of the trait `{}`",
|
||||
ty::item_path_str(fcx.tcx(),
|
||||
trait_ref.def_id)),
|
||||
trait_ref.def_id())),
|
||||
};
|
||||
|
||||
span_note!(fcx.sess(), method_span,
|
||||
|
@ -59,10 +59,10 @@ struct Candidate<'tcx> {
|
||||
enum CandidateKind<'tcx> {
|
||||
InherentImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>),
|
||||
ObjectCandidate(MethodObject<'tcx>),
|
||||
ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>,
|
||||
ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::PolyTraitRef<'tcx>>,
|
||||
subst::Substs<'tcx>, MethodIndex),
|
||||
UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
|
||||
WhereClauseCandidate(Rc<ty::TraitRef<'tcx>>, MethodIndex),
|
||||
WhereClauseCandidate(Rc<ty::PolyTraitRef<'tcx>>, MethodIndex),
|
||||
}
|
||||
|
||||
pub struct Pick<'tcx> {
|
||||
@ -77,7 +77,7 @@ pub enum PickKind<'tcx> {
|
||||
ObjectPick(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint),
|
||||
ExtensionImplPick(/* Impl */ 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>;
|
||||
@ -231,9 +231,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
self_ty.repr(self.tcx()));
|
||||
|
||||
match self_ty.sty {
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds, .. }) => {
|
||||
self.assemble_inherent_candidates_from_object(self_ty, &*principal, bounds);
|
||||
self.assemble_inherent_impl_candidates_for_type(principal.def_id);
|
||||
ty::ty_trait(box ref data) => {
|
||||
self.assemble_inherent_candidates_from_object(self_ty, data);
|
||||
self.assemble_inherent_impl_candidates_for_type(data.principal.def_id());
|
||||
}
|
||||
ty::ty_enum(did, _) |
|
||||
ty::ty_struct(did, _) |
|
||||
@ -290,8 +290,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
|
||||
fn assemble_inherent_candidates_from_object(&mut self,
|
||||
self_ty: Ty<'tcx>,
|
||||
principal: &ty::TraitRef<'tcx>,
|
||||
_bounds: ty::ExistentialBounds) {
|
||||
data: &ty::TyTrait<'tcx>) {
|
||||
debug!("assemble_inherent_candidates_from_object(self_ty={})",
|
||||
self_ty.repr(self.tcx()));
|
||||
|
||||
@ -304,26 +303,20 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
// a substitution that replaces `Self` with the object type
|
||||
// itself. Hence, a `&self` method will wind up with an
|
||||
// argument type like `&Trait`.
|
||||
let rcvr_substs = principal.substs.clone().with_self_ty(self_ty);
|
||||
let trait_ref = Rc::new(ty::TraitRef {
|
||||
def_id: principal.def_id,
|
||||
substs: rcvr_substs.clone()
|
||||
});
|
||||
|
||||
let trait_ref = data.principal_trait_ref_with_self_ty(self_ty);
|
||||
self.elaborate_bounds(&[trait_ref.clone()], false, |this, new_trait_ref, m, method_num| {
|
||||
let vtable_index =
|
||||
get_method_index(tcx, &*new_trait_ref,
|
||||
trait_ref.clone(), method_num);
|
||||
get_method_index(tcx, &*new_trait_ref, trait_ref.clone(), method_num);
|
||||
|
||||
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 {
|
||||
xform_self_ty: xform_self_ty,
|
||||
method_ty: m,
|
||||
kind: ObjectCandidate(MethodObject {
|
||||
trait_ref: new_trait_ref,
|
||||
object_trait_id: principal.def_id,
|
||||
object_trait_id: trait_ref.def_id(),
|
||||
method_num: method_num,
|
||||
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| {
|
||||
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={}",
|
||||
trait_ref.repr(this.tcx()),
|
||||
trait_ref.substs.repr(this.tcx()),
|
||||
trait_ref.substs().repr(this.tcx()),
|
||||
m.repr(this.tcx()));
|
||||
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(),
|
||||
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(),
|
||||
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(),
|
||||
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
|
||||
// should not contain any inference variables or other
|
||||
// artifacts. This means it is safe to put into the
|
||||
// `WhereClauseCandidate` and (eventually) into the
|
||||
// `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 {
|
||||
xform_self_ty: xform_self_ty,
|
||||
@ -392,10 +385,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
// create the candidates.
|
||||
fn elaborate_bounds(
|
||||
&mut self,
|
||||
bounds: &[Rc<ty::TraitRef<'tcx>>],
|
||||
bounds: &[Rc<ty::PolyTraitRef<'tcx>>],
|
||||
num_includes_types: bool,
|
||||
mk_cand: for<'b> |this: &mut ProbeContext<'b, 'tcx>,
|
||||
tr: Rc<ty::TraitRef<'tcx>>,
|
||||
tr: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
m: Rc<ty::Method<'tcx>>,
|
||||
method_num: uint|)
|
||||
{
|
||||
@ -405,12 +398,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
let mut cache = HashSet::new();
|
||||
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
|
||||
// Already visited this trait, skip it.
|
||||
if !cache.insert(bound_trait_ref.def_id) {
|
||||
if !cache.insert(bound_trait_ref.def_id()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let (pos, method) = match trait_method(tcx,
|
||||
bound_trait_ref.def_id,
|
||||
bound_trait_ref.def_id(),
|
||||
self.method_name,
|
||||
num_includes_types) {
|
||||
Some(v) => v,
|
||||
@ -418,7 +411,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
};
|
||||
|
||||
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 {
|
||||
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.
|
||||
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()));
|
||||
|
||||
@ -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
|
||||
// to a trait and its supertraits.
|
||||
fn get_method_index<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
trait_ref: &ty::TraitRef<'tcx>,
|
||||
subtrait: Rc<ty::TraitRef<'tcx>>,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
subtrait: Rc<ty::PolyTraitRef<'tcx>>,
|
||||
n_method: uint) -> uint {
|
||||
// We need to figure the "real index" of the method in a
|
||||
// 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.
|
||||
let mut method_count = n_method;
|
||||
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
|
||||
} 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() {
|
||||
match *trait_item {
|
||||
ty::MethodTraitItem(_) => method_count += 1,
|
||||
@ -1043,7 +1036,7 @@ impl<'tcx> Candidate<'tcx> {
|
||||
InherentImplPick(def_id)
|
||||
}
|
||||
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) => {
|
||||
ExtensionImplPick(def_id, index)
|
||||
@ -1057,7 +1050,7 @@ impl<'tcx> Candidate<'tcx> {
|
||||
// inference variables or other artifacts. This
|
||||
// means they are safe to put into the
|
||||
// `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)
|
||||
}
|
||||
@ -1068,10 +1061,10 @@ impl<'tcx> Candidate<'tcx> {
|
||||
fn to_source(&self) -> CandidateSource {
|
||||
match self.kind {
|
||||
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),
|
||||
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) |
|
||||
WhereClauseCandidate(ref trait_ref, method_num) => {
|
||||
Some((trait_ref.def_id, method_num))
|
||||
Some((trait_ref.def_id(), method_num))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -625,23 +625,20 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||
let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
|
||||
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);
|
||||
|
||||
let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
|
||||
|
||||
match *opt_trait_ref {
|
||||
Some(ref ast_trait_ref) => {
|
||||
let impl_trait_ref =
|
||||
ty::node_id_to_trait_ref(ccx.tcx, ast_trait_ref.ref_id);
|
||||
match ty::impl_trait_ref(ccx.tcx, local_def(it.id)) {
|
||||
Some(impl_trait_ref) => {
|
||||
check_impl_items_against_trait(ccx,
|
||||
it.span,
|
||||
ast_trait_ref,
|
||||
&*impl_trait_ref,
|
||||
impl_items.as_slice());
|
||||
}
|
||||
None => { }
|
||||
}
|
||||
}
|
||||
None => { }
|
||||
}
|
||||
|
||||
for impl_item in impl_items.iter() {
|
||||
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>,
|
||||
impl_span: Span,
|
||||
ast_trait_ref: &ast::TraitRef,
|
||||
impl_trait_ref: &ty::TraitRef<'tcx>,
|
||||
impl_trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
impl_items: &[ast::ImplItem]) {
|
||||
// Locate trait methods
|
||||
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
|
||||
// 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.pe_body().id,
|
||||
&**trait_method_ty,
|
||||
impl_trait_ref);
|
||||
&*impl_trait_ref);
|
||||
}
|
||||
_ => {
|
||||
// This is span_bug as it should have already been
|
||||
// caught in resolve.
|
||||
tcx.sess
|
||||
.span_bug(impl_method.span,
|
||||
format!("item `{}` is of a \
|
||||
different kind from \
|
||||
its trait `{}`",
|
||||
token::get_name(
|
||||
impl_item_ty.name()),
|
||||
pprust::path_to_string(
|
||||
&ast_trait_ref.path))
|
||||
.as_slice());
|
||||
tcx.sess.span_bug(
|
||||
impl_method.span,
|
||||
format!("item `{}` is of a different kind from its trait `{}`",
|
||||
token::get_name(impl_item_ty.name()),
|
||||
impl_trait_ref.repr(tcx)).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -795,11 +786,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// caught in resolve.
|
||||
tcx.sess.span_bug(
|
||||
impl_method.span,
|
||||
format!(
|
||||
"method `{}` is not a member of trait `{}`",
|
||||
token::get_name(impl_item_ty.name()),
|
||||
pprust::path_to_string(
|
||||
&ast_trait_ref.path)).as_slice());
|
||||
format!("method `{}` is not a member of trait `{}`",
|
||||
token::get_name(impl_item_ty.name()),
|
||||
impl_trait_ref.repr(tcx)).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -812,27 +801,19 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// corresponding type definition in the trait.
|
||||
let opt_associated_type =
|
||||
trait_items.iter()
|
||||
.find(|ti| {
|
||||
ti.name() == typedef_ty.name()
|
||||
});
|
||||
.find(|ti| ti.name() == typedef_ty.name());
|
||||
match opt_associated_type {
|
||||
Some(associated_type) => {
|
||||
match (associated_type, &typedef_ty) {
|
||||
(&ty::TypeTraitItem(_),
|
||||
&ty::TypeTraitItem(_)) => {}
|
||||
(&ty::TypeTraitItem(_), &ty::TypeTraitItem(_)) => {}
|
||||
_ => {
|
||||
// This is `span_bug` as it should have
|
||||
// already been caught in resolve.
|
||||
tcx.sess
|
||||
.span_bug(typedef.span,
|
||||
format!("item `{}` is of a \
|
||||
different kind from \
|
||||
its trait `{}`",
|
||||
token::get_name(
|
||||
typedef_ty.name()),
|
||||
pprust::path_to_string(
|
||||
&ast_trait_ref.path))
|
||||
.as_slice());
|
||||
tcx.sess.span_bug(
|
||||
typedef.span,
|
||||
format!("item `{}` is of a different kind from its trait `{}`",
|
||||
token::get_name(typedef_ty.name()),
|
||||
impl_trait_ref.repr(tcx)).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 \
|
||||
trait `{}`",
|
||||
token::get_name(typedef_ty.name()),
|
||||
pprust::path_to_string(
|
||||
&ast_trait_ref.path)).as_slice());
|
||||
impl_trait_ref.repr(tcx)).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -855,7 +835,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
// Check for missing items from trait
|
||||
let provided_methods = ty::provided_trait_methods(tcx,
|
||||
impl_trait_ref.def_id);
|
||||
impl_trait_ref.def_id());
|
||||
let mut missing_methods = Vec::new();
|
||||
for trait_item in trait_items.iter() {
|
||||
match *trait_item {
|
||||
@ -870,8 +850,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
}
|
||||
});
|
||||
let is_provided =
|
||||
provided_methods.iter().any(
|
||||
|m| m.name == trait_method.name);
|
||||
provided_methods.iter().any(|m| m.name == trait_method.name);
|
||||
if !is_implemented && !is_provided {
|
||||
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_body_id: ast::NodeId,
|
||||
trait_m: &ty::Method<'tcx>,
|
||||
impl_trait_ref: &ty::TraitRef<'tcx>) {
|
||||
impl_trait_ref: &ty::PolyTraitRef<'tcx>) {
|
||||
debug!("compare_impl_method(impl_trait_ref={})",
|
||||
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 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
|
||||
// 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 =
|
||||
trait_bound.subst(tcx, &trait_to_skol_substs);
|
||||
let infcx = infer::new_infer_ctxt(tcx);
|
||||
infer::mk_sub_trait_refs(&infcx,
|
||||
true,
|
||||
infer::Misc(impl_m_span),
|
||||
trait_bound,
|
||||
impl_trait_bound.clone()).is_ok()
|
||||
infer::mk_sub_poly_trait_refs(&infcx,
|
||||
true,
|
||||
infer::Misc(impl_m_span),
|
||||
trait_bound,
|
||||
impl_trait_bound.clone()).is_ok()
|
||||
});
|
||||
|
||||
if !found_match_in_trait {
|
||||
span_err!(tcx.sess, impl_m_span, E0052,
|
||||
"in method `{}`, type parameter {} requires bound `{}`, which is not \
|
||||
required by the corresponding type parameter in the trait declaration",
|
||||
token::get_name(trait_m.name),
|
||||
i,
|
||||
ppaux::trait_ref_to_string(tcx, &*impl_trait_bound));
|
||||
"in method `{}`, type parameter {} requires bound `{}`, which is not \
|
||||
required by the corresponding type parameter in the trait declaration",
|
||||
token::get_name(trait_m.name),
|
||||
i,
|
||||
impl_trait_bound.user_string(tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1647,7 +1626,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
pub fn write_object_cast(&self,
|
||||
key: ast::NodeId,
|
||||
trait_ref: Rc<ty::TraitRef<'tcx>>) {
|
||||
trait_ref: Rc<ty::PolyTraitRef<'tcx>>) {
|
||||
debug!("write_object_cast key={} trait_ref={}",
|
||||
key, trait_ref.repr(self.tcx()));
|
||||
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)
|
||||
}
|
||||
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
|
||||
// being cast to `Foo+'a` implements `Foo`:
|
||||
vtable::register_object_cast_obligations(self,
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use check::{FnCtxt, structurally_resolved_type};
|
||||
use middle::subst::{SelfSpace, FnSpace};
|
||||
use middle::subst::{FnSpace};
|
||||
use middle::traits;
|
||||
use middle::traits::{SelectionError, OutputTypeParameterMismatch, Overflow, Unimplemented};
|
||||
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
|
||||
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,
|
||||
@ -68,7 +68,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
target_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
|
||||
// in self position.
|
||||
pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
object_trait: &ty::TraitRef<'tcx>,
|
||||
span: Span) {
|
||||
|
||||
let mut object = object_trait.clone();
|
||||
if object.substs.types.len(SelfSpace) == 0 {
|
||||
object.substs.types.push(SelfSpace, ty::mk_err());
|
||||
}
|
||||
|
||||
let object = Rc::new(object);
|
||||
for tr in traits::supertraits(tcx, object) {
|
||||
object_trait: &ty::TyTrait<'tcx>,
|
||||
span: Span)
|
||||
{
|
||||
let object_trait_ref = object_trait.principal_trait_ref_with_self_ty(ty::mk_err());
|
||||
for tr in traits::supertraits(tcx, object_trait_ref) {
|
||||
check_object_safety_inner(tcx, &*tr, span);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
object_trait: &ty::TraitRef<'tcx>,
|
||||
object_trait: &ty::PolyTraitRef<'tcx>,
|
||||
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();
|
||||
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();
|
||||
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,
|
||||
"cannot convert to a trait object because trait `{}` is not object-safe",
|
||||
trait_name);
|
||||
@ -237,7 +232,7 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
span: Span,
|
||||
object_trait: &ty::TyTrait<'tcx>,
|
||||
referent_ty: Ty<'tcx>)
|
||||
-> Rc<ty::TraitRef<'tcx>>
|
||||
-> Rc<ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
// We can only make objects from sized types.
|
||||
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()),
|
||||
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.
|
||||
let object_trait_ref =
|
||||
Rc::new(ty::TraitRef { def_id: object_trait.principal.def_id,
|
||||
substs: object_substs });
|
||||
object_trait.principal_trait_ref_with_self_ty(referent_ty);
|
||||
let object_obligation =
|
||||
Obligation::new(
|
||||
ObligationCause::new(span,
|
||||
@ -457,7 +444,7 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
trait_ref.repr(fcx.tcx()),
|
||||
self_ty.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)) {
|
||||
} else if all_types.iter().any(|&t| ty::type_needs_infer(t)) {
|
||||
// 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.
|
||||
if !fcx.tcx().sess.has_errors() {
|
||||
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(
|
||||
obligation.cause.span,
|
||||
format!(
|
||||
|
@ -186,7 +186,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||
|
||||
// There are special rules that apply to drop.
|
||||
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")
|
||||
{
|
||||
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.
|
||||
return
|
||||
}
|
||||
@ -219,7 +219,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||
traits::ObligationCause::new(
|
||||
item.span,
|
||||
fcx.body_id,
|
||||
traits::ItemObligation(trait_ref.def_id));
|
||||
traits::ItemObligation(trait_ref.def_id()));
|
||||
|
||||
// Find the supertrait bounds. This will add `int:Bar`.
|
||||
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
|
||||
/// to the point where impl `A : Trait<B>` is implemented).
|
||||
pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
|
||||
let trait_def = ty::lookup_trait_def(self.fcx.tcx(), trait_ref.def_id);
|
||||
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 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(
|
||||
traits::ObligationCause::new(
|
||||
self.span,
|
||||
self.fcx.body_id,
|
||||
traits::ItemObligation(trait_ref.def_id)),
|
||||
traits::ItemObligation(trait_ref.def_id())),
|
||||
&bounds);
|
||||
|
||||
for &ty in trait_ref.substs.types.iter() {
|
||||
for &ty in trait_ref.substs().types.iter() {
|
||||
self.check_traits_in_ty(ty);
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
ty_trait(ref t) => {
|
||||
Some(t.principal.def_id)
|
||||
Some(t.principal.def_id())
|
||||
}
|
||||
|
||||
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.
|
||||
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
|
||||
|
@ -55,7 +55,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
|
||||
self.check_def_id(item.span, def_id);
|
||||
}
|
||||
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,
|
||||
|
@ -45,7 +45,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
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) {
|
||||
(ast::Unsafety::Normal, ast::Unsafety::Unsafe) => {
|
||||
self.tcx.sess.span_err(
|
||||
|
@ -652,7 +652,7 @@ fn is_associated_type_valid_for_param(ty: Ty,
|
||||
if let ty::ty_param(param_ty) = ty.sty {
|
||||
let type_parameter = generics.types.get(param_ty.space, param_ty.idx);
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -1638,8 +1638,8 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
let param_id = trait_id;
|
||||
|
||||
let self_trait_ref =
|
||||
Rc::new(ty::TraitRef { def_id: local_def(trait_id),
|
||||
substs: (*substs).clone() });
|
||||
Rc::new(ty::bind(ty::TraitRef { def_id: local_def(trait_id),
|
||||
substs: (*substs).clone() }));
|
||||
|
||||
let def = ty::TypeParameterDef {
|
||||
space: subst::SelfSpace,
|
||||
@ -2015,7 +2015,7 @@ fn compute_bounds<'tcx,AC>(this: &AC,
|
||||
¶m_bounds,
|
||||
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
|
||||
}
|
||||
@ -2031,13 +2031,13 @@ fn check_bounds_compatible<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
tcx,
|
||||
param_bounds.trait_bounds.as_slice(),
|
||||
|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) {
|
||||
span_err!(tcx.sess, span, E0129,
|
||||
"incompatible bounds on type parameter `{}`, \
|
||||
bound `{}` does not allow unsized type",
|
||||
name_of_bounded_thing.user_string(tcx),
|
||||
ppaux::trait_ref_to_string(tcx, &*trait_ref));
|
||||
trait_ref.user_string(tcx));
|
||||
}
|
||||
true
|
||||
});
|
||||
@ -2057,14 +2057,14 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
|
||||
trait_bounds,
|
||||
region_bounds } =
|
||||
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()
|
||||
.map(|bound| {
|
||||
astconv::instantiate_trait_ref(this,
|
||||
&ExplicitRscope,
|
||||
&bound.trait_ref,
|
||||
Some(param_ty.to_ty(this.tcx())),
|
||||
AllowEqConstraints::Allow)
|
||||
astconv::instantiate_poly_trait_ref(this,
|
||||
&ExplicitRscope,
|
||||
bound,
|
||||
Some(param_ty.to_ty(this.tcx())),
|
||||
AllowEqConstraints::Allow)
|
||||
})
|
||||
.collect();
|
||||
let region_bounds: Vec<ty::Region> =
|
||||
|
@ -777,13 +777,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Traits DO have a Self type parameter, but it is
|
||||
// erased from object types.
|
||||
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
|
||||
// space.
|
||||
@ -799,10 +799,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraints_from_region(bounds.region_bound, contra);
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
principal.def_id,
|
||||
principal.def_id(),
|
||||
generics.types.get_slice(subst::TypeSpace),
|
||||
generics.regions.get_slice(subst::TypeSpace),
|
||||
&principal.substs,
|
||||
principal.substs(),
|
||||
variance);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
match associated_trait {
|
||||
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)) {
|
||||
return None
|
||||
}
|
||||
|
@ -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> {
|
||||
fn clean(&self, cx: &DocContext) -> TyParamBound {
|
||||
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_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: Vec<String> = fqn.into_iter().map(|i| {
|
||||
i.to_string()
|
||||
|
Loading…
Reference in New Issue
Block a user