From 3cf0fbeee9b6e90de6e7d44ab9461963729f0365 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 11 Dec 2014 13:37:37 -0500 Subject: [PATCH] Create distinct types for a PolyTraitRef (with bindings) and a normal TraitRef. --- src/librustc/lint/builtin.rs | 2 +- src/librustc/metadata/csearch.rs | 2 +- src/librustc/metadata/decoder.rs | 4 +- src/librustc/metadata/tydecode.rs | 10 +- src/librustc/metadata/tyencode.rs | 6 +- src/librustc/middle/astencode.rs | 31 +++- src/librustc/middle/check_static.rs | 18 +-- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 4 +- src/librustc/middle/fast_reject.rs | 2 +- src/librustc/middle/infer/coercion.rs | 4 +- src/librustc/middle/infer/combine.rs | 18 ++- src/librustc/middle/infer/equate.rs | 12 +- src/librustc/middle/infer/error_reporting.rs | 6 +- src/librustc/middle/infer/glb.rs | 4 +- .../middle/infer/higher_ranked/mod.rs | 18 +-- src/librustc/middle/infer/lub.rs | 4 +- src/librustc/middle/infer/mod.rs | 24 +-- src/librustc/middle/infer/sub.rs | 4 +- src/librustc/middle/privacy.rs | 10 +- src/librustc/middle/traits/coherence.rs | 8 +- src/librustc/middle/traits/fulfill.rs | 6 +- src/librustc/middle/traits/mod.rs | 12 +- src/librustc/middle/traits/select.rs | 85 +++++----- src/librustc/middle/traits/util.rs | 34 ++-- src/librustc/middle/ty.rs | 152 +++++++++++++----- src/librustc/middle/ty_fold.rs | 16 -- src/librustc/util/ppaux.rs | 39 +++-- src/librustc_trans/save/mod.rs | 4 +- src/librustc_trans/trans/callee.rs | 4 +- src/librustc_trans/trans/common.rs | 4 +- src/librustc_trans/trans/context.rs | 8 +- src/librustc_trans/trans/debuginfo.rs | 10 +- src/librustc_trans/trans/expr.rs | 6 +- src/librustc_trans/trans/meth.rs | 12 +- src/librustc_typeck/astconv.rs | 65 ++++---- src/librustc_typeck/check/_match.rs | 5 + src/librustc_typeck/check/closure.rs | 8 +- src/librustc_typeck/check/method/confirm.rs | 22 +-- src/librustc_typeck/check/method/mod.rs | 10 +- src/librustc_typeck/check/method/probe.rs | 73 ++++----- src/librustc_typeck/check/mod.rs | 104 +++++------- src/librustc_typeck/check/vtable.rs | 43 ++--- src/librustc_typeck/check/wf.rs | 16 +- src/librustc_typeck/coherence/mod.rs | 4 +- src/librustc_typeck/coherence/orphan.rs | 2 +- src/librustc_typeck/coherence/unsafety.rs | 2 +- src/librustc_typeck/collect.rs | 24 +-- src/librustc_typeck/variance.rs | 8 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 12 +- 51 files changed, 516 insertions(+), 469 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 8c25bc702b3..ca8eee847d3 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1785,7 +1785,7 @@ impl LintPass for Stability { .. }) => { ty::trait_item(cx.tcx, - trait_ref.def_id, + trait_ref.def_id(), index).def_id() } } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 4cbb1babf9a..1a1c810b278 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -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>> { + -> Option>> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); decoder::get_impl_trait(&*cdata, def.node, tcx) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index b78112f1f78..1b3a6c0e6ba 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -425,11 +425,11 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec { pub fn get_impl_trait<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) - -> Option>> + -> Option>> { 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))) }) } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index d649c649131..3d0b63139e4 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -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; diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 2a057da7db3..fd13ea57e6b 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -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"); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index a37f9cb939d..3f0e28589fc 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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>; fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Rc>; + fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) + -> Rc>; 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> { + 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); } diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs index 65412ff8eff..af2be6e088d 100644 --- a/src/librustc/middle/check_static.rs +++ b/src/librustc/middle/check_static.rs @@ -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"); } } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 939775e7507..46c4de5c35e 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -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) => { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 901944cd016..41020df6399 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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()) } } } diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs index 6780177933f..2be5e46fcbb 100644 --- a/src/librustc/middle/fast_reject.rs +++ b/src/librustc/middle/fast_reject.rs @@ -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)) diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs index edb544aca6d..805d4532aa1 100644 --- a/src/librustc/middle/infer/coercion.rs +++ b/src/librustc/middle/infer/coercion.rs @@ -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, diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 1b72a572e9e..1681731005d 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -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)) } diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs index 1738b8db99b..79fbc33f2a1 100644 --- a/src/librustc/middle/infer/equate.rs +++ b/src/librustc/middle/infer/equate.rs @@ -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) } } diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index e1473847c23..89d6a7df050 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -1647,13 +1647,13 @@ impl<'tcx> Resolvable<'tcx> for Ty<'tcx> { } } -impl<'tcx> Resolvable<'tcx> for Rc> { +impl<'tcx> Resolvable<'tcx> for Rc> { fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>) - -> Rc> { + -> Rc> { 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) } } diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs index 9fc4e095c43..f751931a941 100644 --- a/src/librustc/middle/infer/glb.rs +++ b/src/librustc/middle/infer/glb.rs @@ -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) } } diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index ef8c2f414ac..93a4d7c2f46 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -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>(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)))) } } diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs index f27b07c9c9d..e142e3dbe44 100644 --- a/src/librustc/middle/infer/lub.rs +++ b/src/librustc/middle/infer/lub.rs @@ -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) } } diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 0c70d208119..80508a8f16f 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -133,7 +133,7 @@ impl Copy for TypeOrigin {} #[deriving(Clone, Show)] pub enum ValuePairs<'tcx> { Types(ty::expected_found>), - TraitRefs(ty::expected_found>>), + TraitRefs(ty::expected_found>>), } /// 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>, - b: Rc>) + a: Rc>, + b: Rc>) -> 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(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>, - b: Rc>) - -> ures<'tcx> + pub fn sub_poly_trait_refs(&self, + a_is_expected: bool, + origin: TypeOrigin, + a: Rc>, + b: Rc>) + -> 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() }) } } diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs index 00c79bc726c..e7b7791cc2a 100644 --- a/src/librustc/middle/infer/sub.rs +++ b/src/librustc/middle/infer/sub.rs @@ -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) } } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 8cce1321d72..b0d62644ca5 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -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")); } } diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 822979c8601..011f86e2810 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -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 diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 412c188f5f4..8433313cb37 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -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>, + trait_ref: Rc>, cause: ObligationCause<'tcx>) { /*! diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 936304c5eb4..3289acd0c2e 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -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>>; +pub type TraitObligation<'tcx> = Obligation<'tcx, Rc>>; /// 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>, Rc>, ty::type_err<'tcx>), + OutputTypeParameterMismatch(Rc>, + Rc>, + ty::type_err<'tcx>), } pub struct FulfillmentError<'tcx> { @@ -226,7 +228,7 @@ pub struct VtableBuiltinData { #[deriving(PartialEq,Eq,Clone)] pub struct VtableParamData<'tcx> { // In the above example, this would `Eq` - pub bound: Rc>, + pub bound: Rc>, } /// 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>> { +impl<'tcx> TraitObligation<'tcx> { pub fn self_ty(&self) -> Ty<'tcx> { self.trait_ref.self_ty() } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index f551ff06165..86435267be0 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -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>, + skol_trait_ref: Rc>, previous: Option<&'prev TraitObligationStack<'prev, 'tcx>> } #[deriving(Clone)] pub struct SelectionCache<'tcx> { - hashmap: RefCell>, + hashmap: RefCell>, 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>) + cache_skol_trait_ref: &Rc>) -> &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>) + cache_skol_trait_ref: Rc>) -> Option>> { 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>, + cache_skol_trait_ref: Rc>, 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> = + 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>) + trait_ref: Rc>) -> 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>, + obligation_trait_ref: Rc>, 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>, - expected_trait_ref: Rc>) + obligation_trait_ref: Rc>, + expected_trait_ref: Rc>) -> 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)) } diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index d8956246d32..2daf5453745 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -47,7 +47,7 @@ struct StackEntry<'tcx> { pub fn elaborate_trait_ref<'cx, 'tcx>( tcx: &'cx ty::ctxt<'tcx>, - trait_ref: Rc>) + trait_ref: Rc>) -> 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>]) + trait_refs: &[Rc>]) -> 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>) + trait_ref: Rc>) -> 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>]) + bounds: &[Rc>]) -> Supertraits<'cx, 'tcx> { let elaborator = elaborate_trait_refs(tcx, bounds); Supertraits { elaborator: elaborator } } -impl<'cx, 'tcx> Iterator>> for Supertraits<'cx, 'tcx> { - fn next(&mut self) -> Option>> { +impl<'cx, 'tcx> Iterator>> for Supertraits<'cx, 'tcx> { + fn next(&mut self) -> Option>> { 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>, ErrorReported> + -> Result>, 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, 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>, - mut test: F) - -> Option> where - F: FnMut(ast::DefId) -> bool, +pub fn search_trait_and_supertraits_from_bound<'tcx,F>(tcx: &ty::ctxt<'tcx>, + caller_bound: Rc>, + mut test: F) + -> Option> + 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); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 0ad07bed7d9..ee4097b4d0a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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>, + pub trait_ref: Rc>, // 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>, + pub trait_ref: Rc>, // 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>>>; +pub type ObjectCastMap<'tcx> = RefCell>>>; /// 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>>>>, - pub impl_trait_cache: RefCell>>>>, + pub impl_trait_cache: RefCell>>>>, pub trait_refs: RefCell>>>, pub trait_defs: RefCell>>>, @@ -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, but it runs afoul of some static rules + pub principal: PolyTraitRef<'tcx>, // would use Rc, 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> { + 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>; + +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, pub builtin_bounds: BuiltinBounds, - pub trait_bounds: Vec>> + pub trait_bounds: Vec>> } /// Bounds suitable for an existentially quantified type parameter @@ -1657,7 +1690,7 @@ pub enum Predicate<'tcx> { /// Corresponds to `where Foo : Bar`. `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>), + Trait(Rc>), /// where `T1 == T2`. Equate(/* T1 */ Ty<'tcx>, /* T2 */ Ty<'tcx>), @@ -1680,7 +1713,7 @@ impl<'tcx> Predicate<'tcx> { } } - pub fn to_trait(&self) -> Option>> { + pub fn to_trait(&self) -> Option>> { 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>]) + traits: &[Rc>]) -> 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>], + traits: &[Rc>], 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>> { + -> Option>> { 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 { 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> { - 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>], + bounds: &[Rc>], mut f: F) -> bool where - F: FnMut(Rc>) -> bool, + F: FnMut(Rc>) -> 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 { @@ -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, 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 { + fn has_regions_escaping_depth(&self, depth: uint) -> bool { + self.value.has_regions_escaping_depth(depth + 1) + } +} + +impl Binder { + pub fn has_bound_regions(&self) -> bool { + self.value.has_regions_escaping_depth(0) + } +} + diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 3da9fba0ee8..da6ddf7461b 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -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>(&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 { fn fold_contents>(&self, folder: &mut F) -> ty::Binder { ty::bind(self.value.fold_with(folder)) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 13b5c262bf7..afa7ce18675 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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) } } diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 1a4f06663ef..2162055f287 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -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())) } diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index ff2f686fff8..7c2f7196116 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -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) diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 83938fa3357..ab18a05a251 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -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>) + trait_ref: Rc>) -> 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, diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index 89fa6a72e88..af003b01157 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -99,7 +99,7 @@ pub struct LocalCrateContext<'tcx> { monomorphized: RefCell, ValueRef>>, monomorphizing: RefCell>, /// Cache generated vtables - vtables: RefCell, Rc>), ValueRef>>, + vtables: RefCell, Rc>), ValueRef>>, /// Cache of constant strings, const_cstr_cache: RefCell>, @@ -150,7 +150,7 @@ pub struct LocalCrateContext<'tcx> { /// contexts around the same size. n_llvm_insns: Cell, - trait_cache: RefCell>, + trait_cache: RefCell>, traits::Vtable<'tcx, ()>>>, } @@ -601,7 +601,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local.monomorphizing } - pub fn vtables<'a>(&'a self) -> &'a RefCell, Rc>), + pub fn vtables<'a>(&'a self) -> &'a RefCell, Rc>), 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>, + pub fn trait_cache(&self) -> &RefCell>, traits::Vtable<'tcx, ()>>> { &self.local.trait_cache } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index e9730f7af0e..8fcab0a3144 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -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 { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 304142453a9..0bcca6c80ff 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -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, diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 9a2bc38acdf..b386df85d62 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -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>) + trait_ref: Rc>) -> 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>, + trait_ref: Rc>, dest: expr::Dest) -> Block<'blk, 'tcx> { let mut bcx = bcx; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 87eda76db29..1acd5684d16 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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>, + allow_eq: AllowEqConstraints) + -> Rc> + 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, ErrorReported> + -> Result, 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 { @@ -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 { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index b31683219f1..44cc5fce53d 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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); diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index a4fee8573c5..6e5fdbfac9f 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -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)); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 7463652a931..0d07957ba3d 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -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>, + source_trait_ref: Rc>, target_trait_def_id: ast::DefId) - -> Rc> + -> Rc> { 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; } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index ac7bc81b2f8..14bd0edda10 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -166,7 +166,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, // Construct a trait-reference `self_ty : Trait` 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, diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 80e511b8fdf..452d001fe8a 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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>, + ExtensionImplCandidate(/* Impl */ ast::DefId, Rc>, subst::Substs<'tcx>, MethodIndex), UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex), - WhereClauseCandidate(Rc>, MethodIndex), + WhereClauseCandidate(Rc>, 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>, MethodIndex), + WhereClausePick(/* Trait */ Rc>, MethodIndex), } pub type PickResult<'tcx> = Result, 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>], + bounds: &[Rc>], num_includes_types: bool, mk_cand: for<'b> |this: &mut ProbeContext<'b, 'tcx>, - tr: Rc>, + tr: Rc>, m: Rc>, 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>, + trait_ref: &ty::PolyTraitRef<'tcx>, + subtrait: Rc>, 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)) } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index eabf52c2cc8..1e9f7992fb7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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>) { + trait_ref: Rc>) { 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, diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 664705c89ab..4a10c698f7d 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -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> + -> Rc> { // 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!( diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 8c82429e1c2..e11f388b116 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -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` 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); } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 16a77315bd5..e9a3db1b0e6 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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 diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 1803bf766dd..bb8efd29910 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -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, diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 07a84846c47..6a24bdbb9f0 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -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( diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 91947f67dd7..8930ae01160 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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> = + let trait_bounds: Vec> = 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 = diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 8fe14bae0f5..a70058b977e 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -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); } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d0988af1cb4..49e45c9e56c 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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 } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d640f055388..9509986af47 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -575,6 +575,12 @@ impl Clean for ty::BuiltinBound { } } +impl<'tcx> Clean for ty::PolyTraitRef<'tcx> { + fn clean(&self, cx: &DocContext) -> TyParamBound { + self.value.clean(cx) + } +} + impl<'tcx> Clean for ty::TraitRef<'tcx> { fn clean(&self, cx: &DocContext) -> TyParamBound { let tcx = match cx.tcx_opt() { @@ -1391,8 +1397,10 @@ impl<'tcx> Clean 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 = fqn.into_iter().map(|i| { i.to_string()