diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index b151856e3094..245b9ef66ad3 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -233,6 +233,14 @@ pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> ty::TraitDe decoder::get_trait_def(&*cdata, def.node, tcx) } +pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) + -> ty::GenericPredicates<'tcx> +{ + let cstore = &tcx.sess.cstore; + let cdata = cstore.get_crate_data(def.krate); + decoder::get_predicates(&*cdata, def.node, tcx) +} + pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId, def: ast::DefId) -> ty::TypeScheme<'tcx> { let cstore = &tcx.sess.cstore; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 3a70490771eb..4924ebc57674 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -417,16 +417,22 @@ pub fn get_trait_def<'tcx>(cdata: Cmd, } } +pub fn get_predicates<'tcx>(cdata: Cmd, + item_id: ast::NodeId, + tcx: &ty::ctxt<'tcx>) + -> ty::GenericPredicates<'tcx> +{ + let item_doc = lookup_item(item_id, cdata.data()); + doc_predicates(item_doc, tcx, cdata, tag_item_generics) +} + pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) - -> ty::TypeScheme<'tcx> { - - let item = lookup_item(id, cdata.data()); - - let t = item_type(ast::DefId { krate: cdata.cnum, node: id }, item, tcx, + -> ty::TypeScheme<'tcx> +{ + let item_doc = lookup_item(id, cdata.data()); + let t = item_type(ast::DefId { krate: cdata.cnum, node: id }, item_doc, tcx, cdata); - - let generics = doc_generics(item, tcx, cdata, tag_item_generics); - + let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics); ty::TypeScheme { generics: generics, ty: t @@ -882,14 +888,15 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc, match item_sort(method_doc) { 'r' | 'p' => { - let generics = doc_generics(method_doc, tcx, cdata, - tag_method_ty_generics); + let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics); + let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics); let fty = doc_method_fty(method_doc, tcx, cdata); let explicit_self = get_explicit_self(method_doc); let provided_source = get_provided_source(method_doc, cdata); ty::MethodTraitItem(Rc::new(ty::Method::new(name, generics, + predicates, fty, explicit_self, vis, @@ -1520,6 +1527,17 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, true }); + ty::Generics { types: types, regions: regions } +} + +fn doc_predicates<'tcx>(base_doc: rbml::Doc, + tcx: &ty::ctxt<'tcx>, + cdata: Cmd, + tag: uint) + -> ty::GenericPredicates<'tcx> +{ + let doc = reader::get_doc(base_doc, tag); + let mut predicates = subst::VecPerParamSpace::empty(); reader::tagged_docs(doc, tag_predicate, |predicate_doc| { let space_doc = reader::get_doc(predicate_doc, tag_predicate_space); @@ -1533,7 +1551,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, true }); - ty::Generics { types: types, regions: regions, predicates: predicates } + ty::GenericPredicates { predicates: predicates } } pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool { diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index ef0c3fbb252f..3123fa31abdd 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -139,11 +139,21 @@ fn encode_item_variances(rbml_w: &mut Encoder, rbml_w.end_tag(); } +fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder, + ecx: &EncodeContext<'a, 'tcx>, + id: ast::NodeId) { + encode_bounds_and_type(rbml_w, + ecx, + &ty::lookup_item_type(ecx.tcx, local_def(id)), + &ty::lookup_predicates(ecx.tcx, local_def(id))); +} + fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, - pty: &ty::TypeScheme<'tcx>) { - encode_generics(rbml_w, ecx, &pty.generics, tag_item_generics); - encode_type(ecx, rbml_w, pty.ty); + scheme: &ty::TypeScheme<'tcx>, + predicates: &ty::GenericPredicates<'tcx>) { + encode_generics(rbml_w, ecx, &scheme.generics, &predicates, tag_item_generics); + encode_type(ecx, rbml_w, scheme.ty); } fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) { @@ -353,8 +363,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, encode_disr_val(ecx, rbml_w, (*vi)[i].disr_val); disr_val = (*vi)[i].disr_val; } - encode_bounds_and_type(rbml_w, ecx, - &lookup_item_type(ecx.tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, def_id.local_id()); ecx.tcx.map.with_path(variant.node.id, |path| encode_path(rbml_w, path)); rbml_w.end_tag(); @@ -698,8 +707,7 @@ fn encode_info_for_struct(ecx: &EncodeContext, token::get_name(nm), id); encode_struct_field_family(rbml_w, field.vis); encode_name(rbml_w, nm); - encode_bounds_and_type(rbml_w, ecx, - &lookup_item_type(ecx.tcx, local_def(id))); + encode_bounds_and_type_for_item(rbml_w, ecx, id); encode_def_id(rbml_w, local_def(id)); let stab = stability::lookup(ecx.tcx, field.id); @@ -724,8 +732,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, local_def(ctor_id)); encode_family(rbml_w, 'o'); - encode_bounds_and_type(rbml_w, ecx, - &lookup_item_type(ecx.tcx, local_def(ctor_id))); + encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id); encode_name(rbml_w, name.name); ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path)); encode_parent_item(rbml_w, local_def(struct_id)); @@ -749,6 +756,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, generics: &ty::Generics<'tcx>, + predicates: &ty::GenericPredicates<'tcx>, tag: uint) { rbml_w.start_tag(tag); @@ -790,7 +798,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, rbml_w.end_tag(); } - for (space, _, predicate) in generics.predicates.iter_enumerated() { + for (space, _, predicate) in predicates.predicates.iter_enumerated() { rbml_w.start_tag(tag_predicate); rbml_w.wr_tagged_u8(tag_predicate_space, space as u8); @@ -810,7 +818,7 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, method_ty: &ty::Method<'tcx>) { encode_def_id(rbml_w, method_ty.def_id); encode_name(rbml_w, method_ty.name); - encode_generics(rbml_w, ecx, &method_ty.generics, + encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates, tag_method_ty_generics); encode_method_fty(ecx, rbml_w, &method_ty.fty); encode_visibility(rbml_w, method_ty.vis); @@ -844,15 +852,15 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_stability(rbml_w, stab); // The type for methods gets encoded twice, which is unfortunate. - let pty = lookup_item_type(ecx.tcx, m.def_id); - encode_bounds_and_type(rbml_w, ecx, &pty); + encode_bounds_and_type_for_item(rbml_w, ecx, m.def_id.local_id()); let elem = ast_map::PathName(m.name); encode_path(rbml_w, impl_path.chain(Some(elem).into_iter())); match ast_item_opt { Some(&ast::MethodImplItem(ref ast_method)) => { encode_attributes(rbml_w, &ast_method.attrs[]); - let any_types = !pty.generics.types.is_empty(); + let scheme = ty::lookup_item_type(ecx.tcx, m.def_id); + let any_types = !scheme.generics.types.is_empty(); if any_types || is_default_impl || should_inline(&ast_method.attrs[]) { encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id), ast_item_opt.unwrap())); @@ -887,8 +895,7 @@ fn encode_info_for_associated_type(ecx: &EncodeContext, encode_parent_item(rbml_w, local_def(parent_id)); encode_item_sort(rbml_w, 't'); - let type_scheme = ty::lookup_item_type(ecx.tcx, associated_type.def_id); - encode_bounds_and_type(rbml_w, ecx, &type_scheme); + encode_bounds_and_type_for_item(rbml_w, ecx, associated_type.def_id.local_id()); let stab = stability::lookup(ecx.tcx, associated_type.def_id); encode_stability(rbml_w, stab); @@ -1027,7 +1034,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } else { encode_family(rbml_w, 'c'); } - encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_symbol(ecx, rbml_w, item.id); encode_name(rbml_w, item.ident.name); encode_path(rbml_w, path); @@ -1041,7 +1048,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'C'); - encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.ident.name); encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); @@ -1056,7 +1063,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_def_id(rbml_w, def_id); encode_family(rbml_w, FN_FAMILY); let tps_len = generics.ty_params.len(); - encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.ident.name); encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs[]); @@ -1105,7 +1112,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'y'); - encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.ident.name); encode_path(rbml_w, path); encode_visibility(rbml_w, vis); @@ -1119,7 +1126,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_def_id(rbml_w, def_id); encode_family(rbml_w, 't'); encode_item_variances(rbml_w, ecx, item.id); - encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.ident.name); encode_attributes(rbml_w, &item.attrs[]); encode_repr_attrs(rbml_w, ecx, &item.attrs[]); @@ -1161,7 +1168,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'S'); - encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_item_variances(rbml_w, ecx, item.id); encode_name(rbml_w, item.ident.name); @@ -1204,7 +1211,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'i'); - encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.ident.name); encode_attributes(rbml_w, &item.attrs[]); encode_unsafety(rbml_w, unsafety); @@ -1305,10 +1312,11 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_family(rbml_w, 'I'); encode_item_variances(rbml_w, ecx, item.id); let trait_def = ty::lookup_trait_def(tcx, def_id); + let trait_predicates = ty::lookup_predicates(tcx, def_id); encode_unsafety(rbml_w, trait_def.unsafety); encode_paren_sugar(rbml_w, trait_def.paren_sugar); encode_associated_type_names(rbml_w, &trait_def.associated_type_names); - encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics); + encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, tag_item_generics); encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref); encode_name(rbml_w, item.ident.name); encode_attributes(rbml_w, &item.attrs[]); @@ -1384,9 +1392,7 @@ fn encode_info_for_item(ecx: &EncodeContext, METHOD_FAMILY); } } - let pty = ty::lookup_item_type(tcx, - method_def_id); - encode_bounds_and_type(rbml_w, ecx, &pty); + encode_bounds_and_type_for_item(rbml_w, ecx, method_def_id.local_id()); is_nonstatic_method = method_ty.explicit_self != ty::StaticExplicitSelfCategory; @@ -1415,8 +1421,7 @@ fn encode_info_for_item(ecx: &EncodeContext, if is_nonstatic_method { // FIXME: I feel like there is something funny // going on. - let pty = ty::lookup_item_type(tcx, item_def_id.def_id()); - encode_bounds_and_type(rbml_w, ecx, &pty); + encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id()); } }; match trait_item { @@ -1468,8 +1473,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, match nitem.node { ast::ForeignItemFn(ref fndecl, _) => { encode_family(rbml_w, FN_FAMILY); - encode_bounds_and_type(rbml_w, ecx, - &lookup_item_type(ecx.tcx,local_def(nitem.id))); + encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id); encode_name(rbml_w, nitem.ident.name); if abi == abi::RustIntrinsic { encode_inlined_item(ecx, rbml_w, IIForeignRef(nitem)); @@ -1486,8 +1490,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, } else { encode_family(rbml_w, 'c'); } - encode_bounds_and_type(rbml_w, ecx, - &lookup_item_type(ecx.tcx,local_def(nitem.id))); + encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id); encode_attributes(rbml_w, &*nitem.attrs); let stab = stability::lookup(ecx.tcx, ast_util::local_def(nitem.id)); encode_stability(rbml_w, stab); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 8e3bf0fa28d2..423032d1287d 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -951,11 +951,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { Ok(encode_vec_per_param_space( this, &type_scheme.generics.regions, |this, def| def.encode(this).unwrap())) - }); - this.emit_struct_field("predicates", 2, |this| { - Ok(encode_vec_per_param_space( - this, &type_scheme.generics.predicates, - |this, def| this.emit_predicate(ecx, def))) }) }) }); @@ -1574,7 +1569,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { fn read_type_scheme<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::TypeScheme<'tcx> { - self.read_struct("TypeScheme", 2, |this| { + self.read_struct("TypeScheme", 3, |this| { Ok(ty::TypeScheme { generics: this.read_struct_field("generics", 0, |this| { this.read_struct("Generics", 2, |this| { @@ -1590,12 +1585,6 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { Ok(this.read_vec_per_param_space( |this| Decodable::decode(this).unwrap())) }).unwrap(), - - predicates: - this.read_struct_field("predicates", 2, |this| { - Ok(this.read_vec_per_param_space( - |this| this.read_predicate(dcx))) - }).unwrap(), }) }) }).unwrap(), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5979d339e17a..d6778be553e8 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -366,6 +366,14 @@ pub struct DefId { pub node: NodeId, } +impl DefId { + /// Read the node id, asserting that this def-id is krate-local. + pub fn local_id(&self) -> NodeId { + assert_eq!(self.krate, LOCAL_CRATE); + self.node + } +} + /// Item definitions in the currently-compiled crate would have the CrateNum /// LOCAL_CRATE in their DefId. pub const LOCAL_CRATE: CrateNum = 0;