..
}) => {
ty::trait_item(cx.tcx,
- trait_ref.def_id,
+ trait_ref.def_id(),
index).def_id()
}
}
// 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)
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)))
})
}
}
'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);
-> 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)),
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;
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, "]");
}
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, ".");
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");
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)
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))
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))
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);
})
})
}
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>)
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: {
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: {
}).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| {
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(),
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);
}
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;
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");
}
}
}
..
}) => {
let trait_item = ty::trait_item(self.tcx,
- trait_ref.def_id,
+ trait_ref.def_id(),
index);
match trait_item {
ty::MethodTraitItem(method) => {
}
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)
}
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())
}
}
}
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))
}
(_, &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)))
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,
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
}
(&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))
}
}
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)
}
}
}
}
-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)
}
}
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)
}
}
}
}
-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))))
}
}
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)
}
}
#[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
|| 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,
})
}
- 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),
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()
})
}
}
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)
}
}
};
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 {
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 {}",
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 {}",
// 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"));
}
}
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 {
}
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
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
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);
}
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>)
{
/*!
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;
}
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)]
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> {
#[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
}
}
-impl<'tcx> Obligation<'tcx,Rc<ty::TraitRef<'tcx>>> {
+impl<'tcx> TraitObligation<'tcx> {
pub fn self_ty(&self) -> Ty<'tcx> {
self.trait_ref.self_ty()
}
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;
/// 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>>>>,
}
// 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()));
}
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
// 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;
// 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;
}
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);
}
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);
// 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()));
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();
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(()); }
};
// 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(());
}
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) {
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()
})
}
}
}
- 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()))
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,
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()),
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
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={}",
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(()),
}
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>>
{
/// 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))
}
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)])
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()
}
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);
}
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 => {
})
}
-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());
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,
/// 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);
}
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,
#[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,
// 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.
/// 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>>>>,
#[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:
///
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
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
/// 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>),
}
}
- 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())
// 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
&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);
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
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));
}
}
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;
// 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),
{
}
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);
}
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))
}
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);
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
}
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, _, _) =>
/// 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));
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();
// 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,
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) => { }
}
// 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) {
}
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>
{
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 {
// 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
}
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);
}
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) => {
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)
+ }
+}
+
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,
}
}
-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))
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)
}
// 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))
}
}
}
-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
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)
}
});
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)
}
}
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()))
}
// 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
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)
/// 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();
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,
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>>,
/// 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, ()>>>,
}
&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
}
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
}
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 } ) => {
// 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 \
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 {
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,
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)
}
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);
/// 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={})",
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!")
};
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;
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.
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,
rscope: &RS,
ty: &ast::Ty,
bounds: &[ast::TyParamBound])
- -> Result<ty::TraitRef<'tcx>, ErrorReported>
+ -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
where AC : AstConv<'tcx>, RS : RegionScope
{
/*!
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");
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
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) => {
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())
}
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
{
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(
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
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>
{
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
{
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};
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);
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();
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));
};
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));
// 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,
.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) => {
&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)
}
}
}
}
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;
}
}
// 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,
// 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;
//
// 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),
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()));
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,
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> {
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>;
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, _) |
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()));
// 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
})
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,
// 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|)
{
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,
};
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);
}
// 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()));
// 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
// 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,
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)
// 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)
}
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()),
}
}
}
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))
}
}
}
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 {
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
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());
}
}
}
// 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());
}
}
}
// 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());
}
}
}
"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());
}
}
}
// 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 {
}
});
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)));
}
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));
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
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));
}
}
}
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);
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,
// 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};
// 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,
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);
}
}
// 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() {
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);
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(
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,
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
// 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!(
// 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 {
}
}
- 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
}
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);
///
/// 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);
}
}
}
ty_trait(ref t) => {
- Some(t.principal.def_id)
+ Some(t.principal.def_id())
}
ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
// 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
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,
}
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(
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
}
}
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,
¶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
}
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
});
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> =
}
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.
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);
}
// 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
}
}
}
+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() {
}
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()