2014-02-10 15:36:31 +01:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 16:48:01 -08:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2011-06-27 16:03:01 -07:00
|
|
|
// Metadata encoding
|
|
|
|
|
2014-03-21 18:05:05 -07:00
|
|
|
#![allow(unused_must_use)] // everything is just a MemWriter, can't fail
|
|
|
|
#![allow(non_camel_case_types)]
|
2013-05-17 15:28:44 -07:00
|
|
|
|
2014-02-24 19:45:20 -08:00
|
|
|
use back::svh::Svh;
|
2012-12-23 17:41:37 -05:00
|
|
|
use metadata::common::*;
|
|
|
|
use metadata::cstore;
|
|
|
|
use metadata::decoder;
|
|
|
|
use metadata::tyencode;
|
2013-07-16 16:28:33 -07:00
|
|
|
use middle::ty::{node_id_to_type, lookup_item_type};
|
2013-08-07 00:11:34 -07:00
|
|
|
use middle::astencode;
|
2012-12-23 17:41:37 -05:00
|
|
|
use middle::ty;
|
2013-07-22 16:40:31 -07:00
|
|
|
use middle::typeck;
|
2012-12-23 17:41:37 -05:00
|
|
|
use middle;
|
2014-02-28 14:34:26 -08:00
|
|
|
use util::nodemap::{NodeMap, NodeSet};
|
2012-04-26 12:15:46 -07:00
|
|
|
|
2014-02-05 08:52:54 -08:00
|
|
|
use serialize::Encodable;
|
Store metadata separately in rlib files
Right now whenever an rlib file is linked against, all of the metadata from the
rlib is pulled in to the final staticlib or binary. The reason for this is that
the metadata is currently stored in a section of the object file. Note that this
is intentional for dynamic libraries in order to distribute metadata bundled
with static libraries.
This commit alters the situation for rlib libraries to instead store the
metadata in a separate file in the archive. In doing so, when the archive is
passed to the linker, none of the metadata will get pulled into the result
executable. Furthermore, the metadata file is skipped when assembling rlibs into
an archive.
The snag in this implementation comes with multiple output formats. When
generating a dylib, the metadata needs to be in the object file, but when
generating an rlib this needs to be separate. In order to accomplish this, the
metadata variable is inserted into an entirely separate LLVM Module which is
then codegen'd into a different location (foo.metadata.o). This is then linked
into dynamic libraries and silently ignored for rlib files.
While changing how metadata is inserted into archives, I have also stopped
compressing metadata when inserted into rlib files. We have wanted to stop
compressing metadata, but the sections it creates in object file sections are
apparently too large. Thankfully if it's just an arbitrary file it doesn't
matter how large it is.
I have seen massive reductions in executable sizes, as well as staticlib output
sizes (to confirm that this is all working).
2013-12-03 17:41:01 -08:00
|
|
|
use std::cast;
|
2014-04-22 03:25:56 +03:00
|
|
|
use std::cell::RefCell;
|
2014-02-23 21:29:35 +11:00
|
|
|
use std::hash;
|
|
|
|
use std::hash::Hash;
|
2014-01-15 13:25:09 -08:00
|
|
|
use std::io::MemWriter;
|
2013-06-28 18:32:26 -04:00
|
|
|
use std::str;
|
2014-02-28 14:34:26 -08:00
|
|
|
use collections::HashMap;
|
2014-04-02 01:19:41 -07:00
|
|
|
use syntax::abi;
|
2012-09-04 11:54:36 -07:00
|
|
|
use syntax::ast::*;
|
2012-12-23 17:41:37 -05:00
|
|
|
use syntax::ast;
|
2014-02-14 07:07:09 +02:00
|
|
|
use syntax::ast_map::{PathElem, PathElems};
|
2012-09-04 11:54:36 -07:00
|
|
|
use syntax::ast_map;
|
2012-12-23 17:41:37 -05:00
|
|
|
use syntax::ast_util::*;
|
2014-01-08 10:35:15 -08:00
|
|
|
use syntax::ast_util;
|
2013-07-19 21:51:37 +10:00
|
|
|
use syntax::attr::AttrMetaMethods;
|
2014-01-08 10:35:15 -08:00
|
|
|
use syntax::attr;
|
2014-02-24 18:13:51 -08:00
|
|
|
use syntax::crateid::CrateId;
|
2013-12-31 23:17:59 +09:00
|
|
|
use syntax::diagnostic::SpanHandler;
|
2014-01-08 10:35:15 -08:00
|
|
|
use syntax::parse::token::InternedString;
|
2013-05-24 19:35:29 -07:00
|
|
|
use syntax::parse::token::special_idents;
|
2014-01-08 10:35:15 -08:00
|
|
|
use syntax::parse::token;
|
2013-08-20 14:55:54 -07:00
|
|
|
use syntax::visit::Visitor;
|
2013-08-12 14:05:43 +02:00
|
|
|
use syntax::visit;
|
2012-12-23 17:41:37 -05:00
|
|
|
use syntax;
|
2014-02-05 08:52:54 -08:00
|
|
|
use writer = serialize::ebml::writer;
|
2012-09-19 13:13:24 -07:00
|
|
|
|
2014-01-09 15:05:33 +02:00
|
|
|
/// A borrowed version of ast::InlinedItem.
|
2014-01-06 14:00:46 +02:00
|
|
|
pub enum InlinedItemRef<'a> {
|
2014-01-09 15:05:33 +02:00
|
|
|
IIItemRef(&'a ast::Item),
|
|
|
|
IIMethodRef(ast::DefId, bool, &'a ast::Method),
|
|
|
|
IIForeignRef(&'a ast::ForeignItem)
|
2014-01-06 14:00:46 +02:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
pub type Encoder<'a> = writer::Encoder<'a, MemWriter>;
|
|
|
|
|
2014-04-07 13:30:48 -07:00
|
|
|
pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
|
|
|
|
ebml_w: &mut Encoder,
|
|
|
|
ii: InlinedItemRef|: 'a;
|
2012-05-14 17:38:17 -07:00
|
|
|
|
2013-12-09 23:16:18 -08:00
|
|
|
pub struct EncodeParams<'a> {
|
2014-03-28 10:05:27 -07:00
|
|
|
pub diag: &'a SpanHandler,
|
|
|
|
pub tcx: &'a ty::ctxt,
|
2014-04-22 19:06:43 +03:00
|
|
|
pub reexports2: &'a middle::resolve::ExportMap2,
|
2014-03-28 10:05:27 -07:00
|
|
|
pub item_symbols: &'a RefCell<NodeMap<~str>>,
|
|
|
|
pub non_inlineable_statics: &'a RefCell<NodeSet>,
|
|
|
|
pub link_meta: &'a LinkMeta,
|
|
|
|
pub cstore: &'a cstore::CStore,
|
|
|
|
pub encode_inlined_item: EncodeInlinedItem<'a>,
|
2013-02-19 02:40:42 -05:00
|
|
|
}
|
2012-05-13 17:01:52 -07:00
|
|
|
|
2013-12-09 23:16:18 -08:00
|
|
|
pub struct EncodeContext<'a> {
|
2014-03-28 10:05:27 -07:00
|
|
|
pub diag: &'a SpanHandler,
|
|
|
|
pub tcx: &'a ty::ctxt,
|
2014-04-22 19:06:43 +03:00
|
|
|
pub reexports2: &'a middle::resolve::ExportMap2,
|
2014-03-28 10:05:27 -07:00
|
|
|
pub item_symbols: &'a RefCell<NodeMap<~str>>,
|
|
|
|
pub non_inlineable_statics: &'a RefCell<NodeSet>,
|
|
|
|
pub link_meta: &'a LinkMeta,
|
|
|
|
pub cstore: &'a cstore::CStore,
|
|
|
|
pub encode_inlined_item: EncodeInlinedItem<'a>,
|
2014-04-22 19:06:43 +03:00
|
|
|
pub type_abbrevs: tyencode::abbrev_map,
|
2012-04-23 23:40:53 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_name(ebml_w: &mut Encoder, name: Name) {
|
2014-02-22 04:04:03 +08:00
|
|
|
ebml_w.wr_tagged_str(tag_paths_data_name, token::get_name(name).get());
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_impl_type_basename(ebml_w: &mut Encoder, name: Ident) {
|
2014-02-14 07:07:09 +02:00
|
|
|
ebml_w.wr_tagged_str(tag_item_impl_type_basename, token::get_ident(name).get());
|
2012-10-18 13:29:34 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
pub fn encode_def_id(ebml_w: &mut Encoder, id: DefId) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
|
2012-02-06 07:13:14 -08:00
|
|
|
}
|
|
|
|
|
2013-07-02 12:47:32 -07:00
|
|
|
#[deriving(Clone)]
|
2013-02-19 02:40:42 -05:00
|
|
|
struct entry<T> {
|
|
|
|
val: T,
|
2013-10-21 17:11:42 -07:00
|
|
|
pos: u64
|
2013-02-19 02:40:42 -05:00
|
|
|
}
|
2011-07-26 14:06:02 +02:00
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_trait_ref(ebml_w: &mut Encoder,
|
2013-06-13 19:19:50 +12:00
|
|
|
ecx: &EncodeContext,
|
2013-03-27 06:16:28 -04:00
|
|
|
trait_ref: &ty::TraitRef,
|
2013-05-01 17:54:54 -07:00
|
|
|
tag: uint) {
|
2014-03-06 05:28:28 +02:00
|
|
|
let ty_str_ctxt = &tyencode::ctxt {
|
2013-03-27 06:16:28 -04:00
|
|
|
diag: ecx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: ecx.tcx,
|
2014-04-22 19:06:43 +03:00
|
|
|
abbrevs: &ecx.type_abbrevs
|
2013-06-14 18:21:47 -07:00
|
|
|
};
|
2013-03-27 06:16:28 -04:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag);
|
|
|
|
tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref);
|
2012-04-26 12:15:46 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_impl_vtables(ebml_w: &mut Encoder,
|
2013-07-22 16:40:31 -07:00
|
|
|
ecx: &EncodeContext,
|
|
|
|
vtables: &typeck::impl_res) {
|
|
|
|
ebml_w.start_tag(tag_item_impl_vtables);
|
2014-04-10 14:04:45 +03:00
|
|
|
astencode::encode_vtable_res(ecx, ebml_w, &vtables.trait_vtables);
|
|
|
|
astencode::encode_vtable_param_res(ecx, ebml_w, &vtables.self_vtables);
|
2013-07-22 16:40:31 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2011-06-27 15:20:17 -07:00
|
|
|
// Item info table encoding
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_family(ebml_w: &mut Encoder, c: char) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item_family);
|
2012-06-29 16:26:56 -07:00
|
|
|
ebml_w.writer.write(&[c as u8]);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2013-09-02 03:45:37 +02:00
|
|
|
pub fn def_to_str(did: DefId) -> ~str {
|
2014-02-05 22:15:24 +01:00
|
|
|
format!("{}:{}", did.krate, did.node)
|
2013-05-01 17:54:54 -07:00
|
|
|
}
|
2011-06-27 15:20:17 -07:00
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_ty_type_param_defs(ebml_w: &mut Encoder,
|
2013-06-13 19:19:50 +12:00
|
|
|
ecx: &EncodeContext,
|
2014-02-01 15:57:59 +11:00
|
|
|
params: &[ty::TypeParameterDef],
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-08 22:54:49 -07:00
|
|
|
tag: uint) {
|
2014-03-06 05:28:28 +02:00
|
|
|
let ty_str_ctxt = &tyencode::ctxt {
|
2013-01-08 14:00:45 -08:00
|
|
|
diag: ecx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: ecx.tcx,
|
2014-04-22 19:06:43 +03:00
|
|
|
abbrevs: &ecx.type_abbrevs
|
2013-06-14 18:21:47 -07:00
|
|
|
};
|
2013-08-03 12:45:23 -04:00
|
|
|
for param in params.iter() {
|
2013-03-27 10:26:57 -04:00
|
|
|
ebml_w.start_tag(tag);
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-08 22:54:49 -07:00
|
|
|
tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-07-29 16:40:23 -07:00
|
|
|
}
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_region_param_defs(ebml_w: &mut Encoder,
|
2014-02-01 15:57:59 +11:00
|
|
|
params: &[ty::RegionParameterDef]) {
|
2013-10-29 06:03:32 -04:00
|
|
|
for param in params.iter() {
|
|
|
|
ebml_w.start_tag(tag_region_param_def);
|
|
|
|
|
|
|
|
ebml_w.start_tag(tag_region_param_def_ident);
|
2014-03-05 06:59:35 +01:00
|
|
|
encode_name(ebml_w, param.name);
|
2013-10-29 06:03:32 -04:00
|
|
|
ebml_w.end_tag();
|
|
|
|
|
|
|
|
ebml_w.wr_tagged_str(tag_region_param_def_def_id,
|
|
|
|
def_to_str(param.def_id));
|
|
|
|
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_item_variances(ebml_w: &mut Encoder,
|
2013-10-29 06:08:34 -04:00
|
|
|
ecx: &EncodeContext,
|
|
|
|
id: ast::NodeId) {
|
|
|
|
let v = ty::item_variances(ecx.tcx, ast_util::local_def(id));
|
|
|
|
ebml_w.start_tag(tag_item_variances);
|
|
|
|
v.encode(ebml_w);
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_bounds_and_type(ebml_w: &mut Encoder,
|
2013-07-16 16:28:33 -07:00
|
|
|
ecx: &EncodeContext,
|
|
|
|
tpt: &ty::ty_param_bounds_and_ty) {
|
2014-02-01 15:57:59 +11:00
|
|
|
encode_ty_type_param_defs(ebml_w, ecx, tpt.generics.type_param_defs(),
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-08 22:54:49 -07:00
|
|
|
tag_items_data_item_ty_param_bounds);
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_region_param_defs(ebml_w, tpt.generics.region_param_defs());
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_type(ecx, ebml_w, tpt.ty);
|
2012-08-02 16:01:38 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item_variant);
|
2013-06-11 13:10:37 +10:00
|
|
|
let s = def_to_str(vid);
|
|
|
|
ebml_w.writer.write(s.as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
pub fn write_type(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-05-01 17:54:54 -07:00
|
|
|
typ: ty::t) {
|
2014-03-06 05:28:28 +02:00
|
|
|
let ty_str_ctxt = &tyencode::ctxt {
|
2013-01-08 14:00:45 -08:00
|
|
|
diag: ecx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: ecx.tcx,
|
2014-04-22 19:06:43 +03:00
|
|
|
abbrevs: &ecx.type_abbrevs
|
2013-06-14 18:21:47 -07:00
|
|
|
};
|
2012-01-11 15:15:54 +01:00
|
|
|
tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
|
2012-01-05 10:57:19 +01:00
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_type(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-05-01 17:54:54 -07:00
|
|
|
typ: ty::t) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item_type);
|
2012-01-05 10:57:19 +01:00
|
|
|
write_type(ecx, ebml_w, typ);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_method_fty(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-05-01 17:54:54 -07:00
|
|
|
typ: &ty::BareFnTy) {
|
2013-03-27 10:26:57 -04:00
|
|
|
ebml_w.start_tag(tag_item_method_fty);
|
|
|
|
|
2014-03-06 05:28:28 +02:00
|
|
|
let ty_str_ctxt = &tyencode::ctxt {
|
2013-03-27 10:26:57 -04:00
|
|
|
diag: ecx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: ecx.tcx,
|
2014-04-22 19:06:43 +03:00
|
|
|
abbrevs: &ecx.type_abbrevs
|
2013-06-14 18:21:47 -07:00
|
|
|
};
|
2013-03-27 10:26:57 -04:00
|
|
|
tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ);
|
|
|
|
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_symbol(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-07-27 10:25:59 +02:00
|
|
|
id: NodeId) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item_symbol);
|
2014-03-20 19:49:20 -07:00
|
|
|
match ecx.item_symbols.borrow().find(&id) {
|
2013-03-22 22:26:41 -04:00
|
|
|
Some(x) => {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("encode_symbol(id={:?}, str={})", id, *x);
|
2013-06-11 13:10:37 +10:00
|
|
|
ebml_w.writer.write(x.as_bytes());
|
2013-03-06 12:27:23 -05:00
|
|
|
}
|
|
|
|
None => {
|
|
|
|
ecx.diag.handler().bug(
|
2013-09-27 22:38:08 -07:00
|
|
|
format!("encode_symbol: id not found {}", id));
|
2013-03-06 12:27:23 -05:00
|
|
|
}
|
|
|
|
}
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_disr_val(_: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-03-11 22:37:01 -07:00
|
|
|
disr_val: ty::Disr) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_disr_val);
|
2013-08-17 22:47:54 -04:00
|
|
|
let s = disr_val.to_str();
|
2013-06-11 13:10:37 +10:00
|
|
|
ebml_w.writer.write(s.as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2012-01-10 14:50:40 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_parent_item(ebml_w: &mut Encoder, id: DefId) {
|
2012-03-08 23:13:57 +01:00
|
|
|
ebml_w.start_tag(tag_items_data_parent_item);
|
2013-06-11 13:10:37 +10:00
|
|
|
let s = def_to_str(id);
|
|
|
|
ebml_w.writer.write(s.as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_struct_fields(ebml_w: &mut Encoder,
|
2014-04-22 19:06:43 +03:00
|
|
|
fields: &[ty::field_ty],
|
2014-02-24 20:17:02 +13:00
|
|
|
origin: DefId) {
|
|
|
|
for f in fields.iter() {
|
|
|
|
if f.name == special_idents::unnamed_field.name {
|
|
|
|
ebml_w.start_tag(tag_item_unnamed_field);
|
|
|
|
} else {
|
|
|
|
ebml_w.start_tag(tag_item_field);
|
|
|
|
encode_name(ebml_w, f.name);
|
2013-09-08 20:36:01 -04:00
|
|
|
}
|
2014-02-24 20:17:02 +13:00
|
|
|
encode_struct_field_family(ebml_w, f.vis);
|
|
|
|
encode_def_id(ebml_w, f.id);
|
|
|
|
ebml_w.start_tag(tag_item_field_origin);
|
|
|
|
let s = def_to_str(origin);
|
|
|
|
ebml_w.writer.write(s.as_bytes());
|
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2013-09-08 20:36:01 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_enum_variant_info(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-07-27 10:25:59 +02:00
|
|
|
id: NodeId,
|
2014-01-09 15:05:33 +02:00
|
|
|
variants: &[P<Variant>],
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &mut Vec<entry<i64>>,
|
2013-02-14 21:50:03 -08:00
|
|
|
generics: &ast::Generics) {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("encode_enum_variant_info(id={:?})", id);
|
2013-03-06 12:27:23 -05:00
|
|
|
|
2012-03-15 09:47:03 -04:00
|
|
|
let mut disr_val = 0;
|
|
|
|
let mut i = 0;
|
2013-01-13 11:05:40 -08:00
|
|
|
let vi = ty::enum_variants(ecx.tcx,
|
2014-02-05 22:15:24 +01:00
|
|
|
ast::DefId { krate: LOCAL_CRATE, node: id });
|
2013-08-03 12:45:23 -04:00
|
|
|
for variant in variants.iter() {
|
2013-07-16 16:28:33 -07:00
|
|
|
let def_id = local_def(variant.node.id);
|
2014-04-22 19:06:43 +03:00
|
|
|
index.push(entry {
|
2014-03-20 19:49:20 -07:00
|
|
|
val: variant.node.id as i64,
|
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
|
|
|
});
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2013-09-08 20:36:01 -04:00
|
|
|
match variant.node.kind {
|
2014-01-09 15:05:33 +02:00
|
|
|
ast::TupleVariantKind(_) => encode_family(ebml_w, 'v'),
|
|
|
|
ast::StructVariantKind(_) => encode_family(ebml_w, 'V')
|
2013-09-08 20:36:01 -04:00
|
|
|
}
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, variant.node.name.name);
|
2012-03-08 23:13:57 +01:00
|
|
|
encode_parent_item(ebml_w, local_def(id));
|
2013-05-16 15:37:52 -07:00
|
|
|
encode_visibility(ebml_w, variant.node.vis);
|
2014-02-28 15:25:15 -08:00
|
|
|
encode_attributes(ebml_w, variant.node.attrs.as_slice());
|
2012-08-07 14:24:04 -07:00
|
|
|
match variant.node.kind {
|
2014-01-09 15:05:33 +02:00
|
|
|
ast::TupleVariantKind(ref args)
|
2013-02-14 21:50:03 -08:00
|
|
|
if args.len() > 0 && generics.ty_params.len() == 0 => {
|
2012-08-07 14:24:04 -07:00
|
|
|
encode_symbol(ecx, ebml_w, variant.node.id);
|
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ast::TupleVariantKind(_) => {},
|
2014-02-24 20:17:02 +13:00
|
|
|
ast::StructVariantKind(_) => {
|
|
|
|
let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
|
2014-02-28 15:25:15 -08:00
|
|
|
let idx = encode_info_for_struct(ecx,
|
|
|
|
ebml_w,
|
2014-04-22 19:06:43 +03:00
|
|
|
fields.as_slice(),
|
2014-02-28 15:25:15 -08:00
|
|
|
index);
|
2014-04-22 19:06:43 +03:00
|
|
|
encode_struct_fields(ebml_w, fields.as_slice(), def_id);
|
|
|
|
encode_index(ebml_w, idx, write_i64);
|
2013-09-08 20:36:01 -04:00
|
|
|
}
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2014-03-08 21:36:22 +01:00
|
|
|
if vi.get(i).disr_val != disr_val {
|
|
|
|
encode_disr_val(ecx, ebml_w, vi.get(i).disr_val);
|
|
|
|
disr_val = vi.get(i).disr_val;
|
2012-01-10 14:50:40 -07:00
|
|
|
}
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx,
|
|
|
|
&lookup_item_type(ecx.tcx, def_id));
|
2014-02-14 07:07:09 +02:00
|
|
|
|
|
|
|
ecx.tcx.map.with_path(variant.node.id, |path| encode_path(ebml_w, path));
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2012-01-10 14:50:40 -07:00
|
|
|
disr_val += 1;
|
2012-01-16 02:36:47 -07:00
|
|
|
i += 1;
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_path<PI: Iterator<PathElem> + Clone>(ebml_w: &mut Encoder,
|
2014-02-14 07:07:09 +02:00
|
|
|
mut path: PI) {
|
2013-05-01 17:54:54 -07:00
|
|
|
ebml_w.start_tag(tag_path);
|
2014-02-14 07:07:09 +02:00
|
|
|
ebml_w.wr_tagged_u32(tag_path_len, path.clone().len() as u32);
|
|
|
|
for pe in path {
|
|
|
|
let tag = match pe {
|
|
|
|
ast_map::PathMod(_) => tag_path_elem_mod,
|
|
|
|
ast_map::PathName(_) => tag_path_elem_name
|
|
|
|
};
|
|
|
|
ebml_w.wr_tagged_str(tag, token::get_name(pe.name()).get());
|
2012-02-10 06:01:32 -08:00
|
|
|
}
|
2013-05-01 17:54:54 -07:00
|
|
|
ebml_w.end_tag();
|
2012-02-10 06:01:32 -08:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_reexported_static_method(ebml_w: &mut Encoder,
|
2013-05-08 23:13:53 -07:00
|
|
|
exp: &middle::resolve::Export2,
|
2013-09-02 03:45:37 +02:00
|
|
|
method_def_id: DefId,
|
2013-09-02 02:50:59 +02:00
|
|
|
method_ident: Ident) {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encode reexported static method) {}::{}",
|
2014-02-14 07:07:09 +02:00
|
|
|
exp.name, token::get_ident(method_ident));
|
2013-05-08 23:13:53 -07:00
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport);
|
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
|
2013-06-01 02:54:39 -07:00
|
|
|
ebml_w.wr_str(def_to_str(method_def_id));
|
2013-05-08 23:13:53 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport_name);
|
2014-02-14 07:07:09 +02:00
|
|
|
ebml_w.wr_str(format!("{}::{}", exp.name, token::get_ident(method_ident)));
|
2013-05-08 23:13:53 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_reexported_static_base_methods(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-06-01 02:54:39 -07:00
|
|
|
exp: &middle::resolve::Export2)
|
|
|
|
-> bool {
|
2014-04-21 12:04:35 +03:00
|
|
|
let impl_methods = ecx.tcx.impl_methods.borrow();
|
2014-03-20 19:49:20 -07:00
|
|
|
match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) {
|
2013-06-01 02:54:39 -07:00
|
|
|
Some(implementations) => {
|
2014-04-21 12:04:35 +03:00
|
|
|
for base_impl_did in implementations.borrow().iter() {
|
|
|
|
for &method_did in impl_methods.get(base_impl_did).iter() {
|
|
|
|
let m = ty::method(ecx.tcx, method_did);
|
2014-01-09 15:05:33 +02:00
|
|
|
if m.explicit_self == ast::SelfStatic {
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
|
2013-06-01 02:54:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
|
|
|
}
|
|
|
|
None => { false }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-06-01 02:54:39 -07:00
|
|
|
exp: &middle::resolve::Export2)
|
|
|
|
-> bool {
|
2014-03-20 19:49:20 -07:00
|
|
|
match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
|
2013-06-01 02:54:39 -07:00
|
|
|
Some(methods) => {
|
2014-04-22 02:21:52 +03:00
|
|
|
for m in methods.iter() {
|
2014-01-09 15:05:33 +02:00
|
|
|
if m.explicit_self == ast::SelfStatic {
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
|
2013-06-01 02:54:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
|
|
|
}
|
|
|
|
None => { false }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_reexported_static_methods(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2014-02-14 07:07:09 +02:00
|
|
|
mod_path: PathElems,
|
2013-05-08 23:13:53 -07:00
|
|
|
exp: &middle::resolve::Export2) {
|
2014-02-14 07:07:09 +02:00
|
|
|
match ecx.tcx.map.find(exp.def_id.node) {
|
|
|
|
Some(ast_map::NodeItem(item)) => {
|
|
|
|
let original_name = token::get_ident(item.ident);
|
|
|
|
|
|
|
|
let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| {
|
|
|
|
let (mut a, mut b) = (path, mod_path.clone());
|
|
|
|
loop {
|
|
|
|
match (a.next(), b.next()) {
|
|
|
|
(None, None) => return true,
|
|
|
|
(None, _) | (_, None) => return false,
|
|
|
|
(Some(x), Some(y)) => if x != y { return false },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2013-06-01 02:54:39 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// We don't need to reexport static methods on items
|
|
|
|
// declared in the same module as our `pub use ...` since
|
2013-06-01 04:24:31 -07:00
|
|
|
// that's done when we encode the item itself.
|
2013-06-01 02:54:39 -07:00
|
|
|
//
|
|
|
|
// The only exception is when the reexport *changes* the
|
|
|
|
// name e.g. `pub use Foo = self::Bar` -- we have
|
|
|
|
// encoded metadata for static methods relative to Bar,
|
|
|
|
// but not yet for Foo.
|
|
|
|
//
|
2014-02-14 07:07:09 +02:00
|
|
|
if path_differs || original_name.get() != exp.name {
|
2013-06-01 02:54:39 -07:00
|
|
|
if !encode_reexported_static_base_methods(ecx, ebml_w, exp) {
|
|
|
|
if encode_reexported_static_trait_methods(ecx, ebml_w, exp) {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encode reexported static methods) {} \
|
2013-09-27 22:38:08 -07:00
|
|
|
[trait]",
|
|
|
|
original_name);
|
2013-05-08 23:13:53 -07:00
|
|
|
}
|
|
|
|
}
|
2013-06-01 02:54:39 -07:00
|
|
|
else {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encode reexported static methods) {} [base]",
|
2013-09-27 22:38:08 -07:00
|
|
|
original_name);
|
2013-06-01 02:54:39 -07:00
|
|
|
}
|
2013-05-08 23:13:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-18 09:39:16 -07:00
|
|
|
/// Iterates through "auxiliary node IDs", which are node IDs that describe
|
|
|
|
/// top-level items that are sub-items of the given item. Specifically:
|
|
|
|
///
|
|
|
|
/// * For enums, iterates through the node IDs of the variants.
|
|
|
|
///
|
|
|
|
/// * For newtype structs, iterates through the node ID of the constructor.
|
2014-01-09 15:05:33 +02:00
|
|
|
fn each_auxiliary_node_id(item: @Item, callback: |NodeId| -> bool) -> bool {
|
2013-09-25 17:56:54 -07:00
|
|
|
let mut continue_ = true;
|
2013-06-18 09:39:16 -07:00
|
|
|
match item.node {
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemEnum(ref enum_def, _) => {
|
2013-08-03 12:45:23 -04:00
|
|
|
for variant in enum_def.variants.iter() {
|
2013-09-25 17:56:54 -07:00
|
|
|
continue_ = callback(variant.node.id);
|
|
|
|
if !continue_ {
|
2013-06-18 09:39:16 -07:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemStruct(struct_def, _) => {
|
2013-06-18 09:39:16 -07:00
|
|
|
// If this is a newtype struct, return the constructor.
|
|
|
|
match struct_def.ctor_id {
|
|
|
|
Some(ctor_id) if struct_def.fields.len() > 0 &&
|
2014-03-25 16:53:52 -07:00
|
|
|
struct_def.fields.get(0).node.kind.is_unnamed() => {
|
2013-09-25 17:56:54 -07:00
|
|
|
continue_ = callback(ctor_id);
|
2013-06-18 09:39:16 -07:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
2013-09-25 17:56:54 -07:00
|
|
|
continue_
|
2013-06-18 09:39:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn encode_reexports(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-07-27 10:25:59 +02:00
|
|
|
id: NodeId,
|
2014-02-14 07:07:09 +02:00
|
|
|
path: PathElems) {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encoding info for module) encoding reexports for {}", id);
|
2014-03-20 19:49:20 -07:00
|
|
|
match ecx.reexports2.borrow().find(&id) {
|
2013-06-18 09:39:16 -07:00
|
|
|
Some(ref exports) => {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encoding info for module) found reexports for {}", id);
|
2013-08-03 12:45:23 -04:00
|
|
|
for exp in exports.iter() {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encoding info for module) reexport '{}' ({}/{}) for \
|
2013-09-27 22:38:08 -07:00
|
|
|
{}",
|
2013-08-23 18:31:43 -07:00
|
|
|
exp.name,
|
2014-02-05 22:15:24 +01:00
|
|
|
exp.def_id.krate,
|
2013-08-23 18:31:43 -07:00
|
|
|
exp.def_id.node,
|
|
|
|
id);
|
2013-06-18 09:39:16 -07:00
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport);
|
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
|
|
|
|
ebml_w.wr_str(def_to_str(exp.def_id));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport_name);
|
|
|
|
ebml_w.wr_str(exp.name);
|
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_reexported_static_methods(ecx, ebml_w, path.clone(), exp);
|
2013-06-18 09:39:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encoding info for module) found no reexports for {}",
|
2013-06-18 09:39:16 -07:00
|
|
|
id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_info_for_mod(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2014-01-09 15:05:33 +02:00
|
|
|
md: &Mod,
|
2013-07-27 10:25:59 +02:00
|
|
|
id: NodeId,
|
2014-02-14 07:07:09 +02:00
|
|
|
path: PathElems,
|
2013-09-02 02:50:59 +02:00
|
|
|
name: Ident,
|
2014-01-09 15:05:33 +02:00
|
|
|
vis: Visibility) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-12-16 14:41:12 +01:00
|
|
|
encode_def_id(ebml_w, local_def(id));
|
2012-02-13 20:55:23 +01:00
|
|
|
encode_family(ebml_w, 'm');
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, name.name);
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encoding info for module) encoding info for module ID {}", id);
|
2012-08-17 16:38:07 -07:00
|
|
|
|
|
|
|
// Encode info about all the module children.
|
2013-08-03 12:45:23 -04:00
|
|
|
for item in md.items.iter() {
|
2013-06-18 09:39:16 -07:00
|
|
|
ebml_w.start_tag(tag_mod_child);
|
|
|
|
ebml_w.wr_str(def_to_str(local_def(item.id)));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
|
2013-11-21 15:42:55 -08:00
|
|
|
each_auxiliary_node_id(*item, |auxiliary_node_id| {
|
2013-06-18 09:39:16 -07:00
|
|
|
ebml_w.start_tag(tag_mod_child);
|
|
|
|
ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id)));
|
|
|
|
ebml_w.end_tag();
|
2013-08-02 02:17:20 -04:00
|
|
|
true
|
2013-11-21 15:42:55 -08:00
|
|
|
});
|
2013-06-18 09:39:16 -07:00
|
|
|
|
2012-08-17 16:38:07 -07:00
|
|
|
match item.node {
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemImpl(..) => {
|
2012-08-17 16:38:07 -07:00
|
|
|
let (ident, did) = (item.ident, item.id);
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encoding info for module) ... encoding impl {} \
|
2013-09-27 22:38:08 -07:00
|
|
|
({:?}/{:?})",
|
2014-02-14 07:07:09 +02:00
|
|
|
token::get_ident(ident),
|
|
|
|
did, ecx.tcx.map.node_to_str(did));
|
2012-08-17 16:38:07 -07:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_mod_impl);
|
|
|
|
ebml_w.wr_str(def_to_str(local_def(did)));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
2013-06-18 09:39:16 -07:00
|
|
|
_ => {}
|
2012-08-17 16:38:07 -07:00
|
|
|
}
|
|
|
|
}
|
2012-05-16 22:28:01 -07:00
|
|
|
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path.clone());
|
2013-10-07 13:01:47 -07:00
|
|
|
encode_visibility(ebml_w, vis);
|
2012-08-17 12:41:34 -07:00
|
|
|
|
2013-06-18 09:39:16 -07:00
|
|
|
// Encode the reexports of this module, if this module is public.
|
2014-01-09 15:05:33 +02:00
|
|
|
if vis == Public {
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("(encoding info for module) encoding reexports for {}", id);
|
2013-06-18 09:39:16 -07:00
|
|
|
encode_reexports(ecx, ebml_w, id, path);
|
2012-08-17 12:41:34 -07:00
|
|
|
}
|
|
|
|
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-12-16 14:41:12 +01:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_struct_field_family(ebml_w: &mut Encoder,
|
2014-01-09 15:05:33 +02:00
|
|
|
visibility: Visibility) {
|
2012-08-06 12:34:08 -07:00
|
|
|
encode_family(ebml_w, match visibility {
|
2014-01-09 15:05:33 +02:00
|
|
|
Public => 'g',
|
|
|
|
Inherited => 'N'
|
2012-05-08 16:06:24 +02:00
|
|
|
});
|
2012-03-26 09:59:59 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_visibility(ebml_w: &mut Encoder, visibility: Visibility) {
|
2013-02-27 13:45:37 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item_visibility);
|
|
|
|
let ch = match visibility {
|
2014-01-09 15:05:33 +02:00
|
|
|
Public => 'y',
|
|
|
|
Inherited => 'i',
|
2013-02-27 13:45:37 -08:00
|
|
|
};
|
|
|
|
ebml_w.wr_str(str::from_char(ch));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_explicit_self(ebml_w: &mut Encoder, explicit_self: ast::ExplicitSelf_) {
|
2013-04-30 08:49:48 -07:00
|
|
|
ebml_w.start_tag(tag_item_trait_method_explicit_self);
|
2012-07-31 16:32:37 -07:00
|
|
|
|
|
|
|
// Encode the base self type.
|
2013-04-30 08:49:48 -07:00
|
|
|
match explicit_self {
|
2014-01-29 18:42:19 -08:00
|
|
|
SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
|
|
|
|
SelfValue => { ebml_w.writer.write(&[ 'v' as u8 ]); }
|
|
|
|
SelfUniq => { ebml_w.writer.write(&[ '~' as u8 ]); }
|
2014-01-09 15:05:33 +02:00
|
|
|
SelfRegion(_, m) => {
|
2013-03-09 19:43:53 -05:00
|
|
|
// FIXME(#4846) encode custom lifetime
|
2014-01-27 14:18:36 +02:00
|
|
|
ebml_w.writer.write(&['&' as u8]);
|
2013-10-20 02:34:01 -04:00
|
|
|
encode_mutability(ebml_w, m);
|
2012-07-31 16:32:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ebml_w.end_tag();
|
2013-03-09 19:43:53 -05:00
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_mutability(ebml_w: &mut Encoder,
|
2013-09-02 03:45:37 +02:00
|
|
|
m: ast::Mutability) {
|
2013-03-09 19:43:53 -05:00
|
|
|
match m {
|
2014-01-29 18:42:19 -08:00
|
|
|
MutImmutable => { ebml_w.writer.write(&[ 'i' as u8 ]); }
|
|
|
|
MutMutable => { ebml_w.writer.write(&[ 'm' as u8 ]); }
|
2013-03-09 19:43:53 -05:00
|
|
|
}
|
|
|
|
}
|
2012-07-31 16:32:37 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_method_sort(ebml_w: &mut Encoder, sort: char) {
|
2012-10-08 12:39:30 -07:00
|
|
|
ebml_w.start_tag(tag_item_trait_method_sort);
|
|
|
|
ebml_w.writer.write(&[ sort as u8 ]);
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_provided_source(ebml_w: &mut Encoder,
|
2013-09-02 03:45:37 +02:00
|
|
|
source_opt: Option<DefId>) {
|
2013-08-03 12:45:23 -04:00
|
|
|
for source in source_opt.iter() {
|
2013-07-11 17:07:57 -07:00
|
|
|
ebml_w.start_tag(tag_item_method_provided_source);
|
|
|
|
let s = def_to_str(*source);
|
|
|
|
ebml_w.writer.write(s.as_bytes());
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-19 10:19:00 -07:00
|
|
|
/* Returns an index of items in this class */
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_info_for_struct(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2014-04-22 19:06:43 +03:00
|
|
|
fields: &[ty::field_ty],
|
|
|
|
global_index: &mut Vec<entry<i64>>)
|
2014-03-04 10:02:49 -08:00
|
|
|
-> Vec<entry<i64>> {
|
2012-06-25 16:49:14 -07:00
|
|
|
/* Each class has its own index, since different classes
|
|
|
|
may have fields with the same name */
|
2014-03-04 10:02:49 -08:00
|
|
|
let mut index = Vec::new();
|
2012-05-13 17:01:52 -07:00
|
|
|
let tcx = ecx.tcx;
|
2012-03-19 10:19:00 -07:00
|
|
|
/* We encode both private and public fields -- need to include
|
|
|
|
private fields to get the offsets right */
|
2013-08-03 12:45:23 -04:00
|
|
|
for field in fields.iter() {
|
2014-02-24 20:17:02 +13:00
|
|
|
let nm = field.name;
|
|
|
|
let id = field.id.node;
|
2013-02-11 16:28:39 -08:00
|
|
|
|
2014-01-29 18:42:19 -08:00
|
|
|
index.push(entry {val: id as i64, pos: ebml_w.writer.tell().unwrap()});
|
2014-04-22 19:06:43 +03:00
|
|
|
global_index.push(entry {
|
2014-03-20 19:49:20 -07:00
|
|
|
val: id as i64,
|
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
|
|
|
});
|
2013-02-11 16:28:39 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("encode_info_for_struct: doing {} {}",
|
2014-02-24 20:17:02 +13:00
|
|
|
token::get_name(nm), id);
|
|
|
|
encode_struct_field_family(ebml_w, field.vis);
|
|
|
|
encode_name(ebml_w, nm);
|
2013-02-11 16:28:39 -08:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
|
|
|
|
encode_def_id(ebml_w, local_def(id));
|
|
|
|
ebml_w.end_tag();
|
2012-08-15 15:53:58 -07:00
|
|
|
}
|
2013-07-02 12:47:32 -07:00
|
|
|
index
|
2012-03-06 08:02:13 -08:00
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_info_for_struct_ctor(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-09-02 02:50:59 +02:00
|
|
|
name: ast::Ident,
|
2013-07-27 10:25:59 +02:00
|
|
|
ctor_id: NodeId,
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &mut Vec<entry<i64>>,
|
2013-09-26 21:53:40 -07:00
|
|
|
struct_id: NodeId) {
|
2014-04-22 19:06:43 +03:00
|
|
|
index.push(entry {
|
2014-03-20 19:49:20 -07:00
|
|
|
val: ctor_id as i64,
|
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
|
|
|
});
|
2013-02-11 16:28:39 -08:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
|
|
|
encode_def_id(ebml_w, local_def(ctor_id));
|
|
|
|
encode_family(ebml_w, 'f');
|
2014-01-23 19:21:45 +01:00
|
|
|
encode_bounds_and_type(ebml_w, ecx,
|
|
|
|
&lookup_item_type(ecx.tcx, local_def(ctor_id)));
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, name.name);
|
2013-02-11 16:28:39 -08:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
|
2014-02-14 07:07:09 +02:00
|
|
|
ecx.tcx.map.with_path(ctor_id, |path| encode_path(ebml_w, path));
|
2013-09-26 21:53:40 -07:00
|
|
|
encode_parent_item(ebml_w, local_def(struct_id));
|
2013-02-11 16:28:39 -08:00
|
|
|
|
2014-03-20 19:49:20 -07:00
|
|
|
if ecx.item_symbols.borrow().contains_key(&ctor_id) {
|
2013-02-11 16:28:39 -08:00
|
|
|
encode_symbol(ecx, ebml_w, ctor_id);
|
|
|
|
}
|
|
|
|
|
2014-01-30 23:36:05 +11:00
|
|
|
// indicate that this is a tuple struct ctor, because downstream users will normally want
|
|
|
|
// the tuple struct definition, but without this there is no way for them to tell that
|
|
|
|
// they actually have a ctor rather than a normal function
|
|
|
|
ebml_w.start_tag(tag_items_data_item_is_tuple_struct_ctor);
|
|
|
|
ebml_w.end_tag();
|
|
|
|
|
2013-02-11 16:28:39 -08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_method_ty_fields(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-05-02 08:11:15 -07:00
|
|
|
method_ty: &ty::Method) {
|
2013-03-28 14:27:54 -04:00
|
|
|
encode_def_id(ebml_w, method_ty.def_id);
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, method_ty.ident.name);
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-08 22:54:49 -07:00
|
|
|
encode_ty_type_param_defs(ebml_w, ecx,
|
2014-02-01 15:57:59 +11:00
|
|
|
method_ty.generics.type_param_defs(),
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-08 22:54:49 -07:00
|
|
|
tag_item_method_tps);
|
2013-03-28 14:27:54 -04:00
|
|
|
encode_method_fty(ecx, ebml_w, &method_ty.fty);
|
|
|
|
encode_visibility(ebml_w, method_ty.vis);
|
2013-04-30 08:49:48 -07:00
|
|
|
encode_explicit_self(ebml_w, method_ty.explicit_self);
|
2014-04-06 18:04:40 -07:00
|
|
|
let fn_style = method_ty.fty.fn_style;
|
2013-07-16 16:28:33 -07:00
|
|
|
match method_ty.explicit_self {
|
2014-01-09 15:05:33 +02:00
|
|
|
ast::SelfStatic => {
|
2014-04-06 18:04:40 -07:00
|
|
|
encode_family(ebml_w, fn_style_static_method_family(fn_style));
|
2013-07-16 16:28:33 -07:00
|
|
|
}
|
2014-04-06 18:04:40 -07:00
|
|
|
_ => encode_family(ebml_w, style_fn_family(fn_style))
|
2013-07-16 16:28:33 -07:00
|
|
|
}
|
2013-07-11 17:07:57 -07:00
|
|
|
encode_provided_source(ebml_w, method_ty.provided_source);
|
2013-03-28 14:27:54 -04:00
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_info_for_method(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-07-16 16:28:33 -07:00
|
|
|
m: &ty::Method,
|
2014-02-14 07:07:09 +02:00
|
|
|
impl_path: PathElems,
|
2013-07-16 16:28:33 -07:00
|
|
|
is_default_impl: bool,
|
2013-07-27 10:25:59 +02:00
|
|
|
parent_id: NodeId,
|
2014-01-09 15:05:33 +02:00
|
|
|
ast_method_opt: Option<@Method>) {
|
2013-07-16 16:28:33 -07:00
|
|
|
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("encode_info_for_method: {:?} {}", m.def_id,
|
2014-02-14 07:07:09 +02:00
|
|
|
token::get_ident(m.ident));
|
2012-03-19 10:19:00 -07:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-03-28 14:27:54 -04:00
|
|
|
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_method_ty_fields(ecx, ebml_w, m);
|
2013-07-15 17:26:56 -07:00
|
|
|
encode_parent_item(ebml_w, local_def(parent_id));
|
2013-02-27 13:45:37 -08:00
|
|
|
|
2013-07-16 16:28:33 -07:00
|
|
|
// The type for methods gets encoded twice, which is unfortunate.
|
|
|
|
let tpt = lookup_item_type(ecx.tcx, m.def_id);
|
|
|
|
encode_bounds_and_type(ebml_w, ecx, &tpt);
|
2013-02-14 21:50:03 -08:00
|
|
|
|
2014-02-14 07:07:09 +02:00
|
|
|
let elem = ast_map::PathName(m.ident.name);
|
|
|
|
encode_path(ebml_w, impl_path.chain(Some(elem).move_iter()));
|
2013-12-15 21:52:48 -05:00
|
|
|
match ast_method_opt {
|
2014-02-28 15:25:15 -08:00
|
|
|
Some(ast_method) => {
|
|
|
|
encode_attributes(ebml_w, ast_method.attrs.as_slice())
|
|
|
|
}
|
2013-12-15 21:52:48 -05:00
|
|
|
None => ()
|
|
|
|
}
|
2013-02-27 13:45:37 -08:00
|
|
|
|
2014-01-06 14:00:46 +02:00
|
|
|
for &ast_method in ast_method_opt.iter() {
|
2014-02-01 15:57:59 +11:00
|
|
|
let num_params = tpt.generics.type_param_defs().len();
|
2014-02-28 15:25:15 -08:00
|
|
|
if num_params > 0u ||
|
|
|
|
is_default_impl ||
|
|
|
|
should_inline(ast_method.attrs.as_slice()) {
|
2013-07-16 16:28:33 -07:00
|
|
|
(ecx.encode_inlined_item)(
|
2014-02-14 07:07:09 +02:00
|
|
|
ecx, ebml_w, IIMethodRef(local_def(parent_id), false, ast_method));
|
2013-07-16 16:28:33 -07:00
|
|
|
} else {
|
|
|
|
encode_symbol(ecx, ebml_w, m.def_id.node);
|
|
|
|
}
|
2012-03-19 10:19:00 -07:00
|
|
|
}
|
2013-03-28 14:27:54 -04:00
|
|
|
|
2012-03-19 10:19:00 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-04-06 18:04:40 -07:00
|
|
|
fn style_fn_family(s: FnStyle) -> char {
|
|
|
|
match s {
|
2014-01-09 15:05:33 +02:00
|
|
|
UnsafeFn => 'u',
|
2014-04-06 18:04:40 -07:00
|
|
|
NormalFn => 'f',
|
2014-01-09 15:05:33 +02:00
|
|
|
ExternFn => 'e'
|
2012-08-02 16:01:38 -07:00
|
|
|
}
|
|
|
|
}
|
2013-02-27 13:45:37 -08:00
|
|
|
|
2014-04-06 18:04:40 -07:00
|
|
|
fn fn_style_static_method_family(s: FnStyle) -> char {
|
|
|
|
match s {
|
2014-01-09 15:05:33 +02:00
|
|
|
UnsafeFn => 'U',
|
2014-04-06 18:04:40 -07:00
|
|
|
NormalFn => 'F',
|
2014-01-09 15:05:33 +02:00
|
|
|
_ => fail!("extern fn can't be static")
|
2012-02-10 13:39:15 -08:00
|
|
|
}
|
2012-02-13 18:56:09 +01:00
|
|
|
}
|
|
|
|
|
2012-03-02 13:14:10 -08:00
|
|
|
|
2013-07-19 21:51:37 +10:00
|
|
|
fn should_inline(attrs: &[Attribute]) -> bool {
|
|
|
|
use syntax::attr::*;
|
|
|
|
match find_inline_attr(attrs) {
|
|
|
|
InlineNone | InlineNever => false,
|
|
|
|
InlineHint | InlineAlways => true
|
2012-03-02 13:14:10 -08:00
|
|
|
}
|
2012-03-19 10:19:00 -07:00
|
|
|
}
|
|
|
|
|
2013-08-23 14:34:00 -07:00
|
|
|
// Encodes the inherent implementations of a structure, enumeration, or trait.
|
|
|
|
fn encode_inherent_implementations(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-09-02 03:45:37 +02:00
|
|
|
def_id: DefId) {
|
2014-03-20 19:49:20 -07:00
|
|
|
match ecx.tcx.inherent_impls.borrow().find(&def_id) {
|
2013-08-23 14:34:00 -07:00
|
|
|
None => {}
|
2014-04-22 19:06:43 +03:00
|
|
|
Some(implementations) => {
|
2014-04-21 12:04:35 +03:00
|
|
|
for &impl_def_id in implementations.borrow().iter() {
|
2013-08-23 14:34:00 -07:00
|
|
|
ebml_w.start_tag(tag_items_data_item_inherent_impl);
|
2014-04-21 12:04:35 +03:00
|
|
|
encode_def_id(ebml_w, impl_def_id);
|
2013-08-23 14:34:00 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Encodes the implementations of a trait defined in this crate.
|
|
|
|
fn encode_extension_implementations(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-09-02 03:45:37 +02:00
|
|
|
trait_def_id: DefId) {
|
2014-03-20 19:49:20 -07:00
|
|
|
match ecx.tcx.trait_impls.borrow().find(&trait_def_id) {
|
2013-08-23 14:34:00 -07:00
|
|
|
None => {}
|
2014-04-22 19:06:43 +03:00
|
|
|
Some(implementations) => {
|
2014-04-21 12:04:35 +03:00
|
|
|
for &impl_def_id in implementations.borrow().iter() {
|
2013-08-23 14:34:00 -07:00
|
|
|
ebml_w.start_tag(tag_items_data_item_extension_impl);
|
2014-04-21 12:04:35 +03:00
|
|
|
encode_def_id(ebml_w, impl_def_id);
|
2013-08-23 14:34:00 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_info_for_item(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2014-01-09 15:05:33 +02:00
|
|
|
item: &Item,
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &mut Vec<entry<i64>>,
|
2014-02-14 07:07:09 +02:00
|
|
|
path: PathElems,
|
2014-01-09 15:05:33 +02:00
|
|
|
vis: ast::Visibility) {
|
2012-05-13 17:01:52 -07:00
|
|
|
let tcx = ecx.tcx;
|
2012-03-22 18:03:12 -07:00
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn add_to_index(item: &Item, ebml_w: &Encoder,
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &mut Vec<entry<i64>>) {
|
|
|
|
index.push(entry {
|
2013-12-21 14:44:18 -08:00
|
|
|
val: item.id as i64,
|
2014-01-29 18:42:19 -08:00
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
2013-12-21 14:44:18 -08:00
|
|
|
});
|
2012-03-22 18:03:12 -07:00
|
|
|
}
|
2012-03-06 12:52:13 +01:00
|
|
|
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("encoding info for item at {}",
|
2014-03-16 20:56:24 +02:00
|
|
|
ecx.tcx.sess.codemap().span_to_str(item.span));
|
2012-10-30 11:19:15 -07:00
|
|
|
|
2013-07-16 16:28:33 -07:00
|
|
|
let def_id = local_def(item.id);
|
2013-03-20 01:17:42 -04:00
|
|
|
match item.node {
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemStatic(_, m, _) => {
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2013-09-02 03:45:37 +02:00
|
|
|
if m == ast::MutMutable {
|
2013-06-21 18:46:34 -07:00
|
|
|
encode_family(ebml_w, 'b');
|
|
|
|
} else {
|
|
|
|
encode_family(ebml_w, 'c');
|
|
|
|
}
|
2012-01-30 17:28:30 +01:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2011-07-27 14:19:39 +02:00
|
|
|
encode_symbol(ecx, ebml_w, item.id);
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path);
|
2013-12-18 18:11:41 -08:00
|
|
|
|
2014-03-20 19:49:20 -07:00
|
|
|
let inlineable = !ecx.non_inlineable_statics.borrow().contains(&item.id);
|
2013-12-18 18:11:41 -08:00
|
|
|
|
2014-02-14 07:07:09 +02:00
|
|
|
if inlineable {
|
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
|
2013-09-11 10:06:16 -07:00
|
|
|
}
|
2013-08-07 00:11:34 -07:00
|
|
|
encode_visibility(ebml_w, vis);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-04-06 18:04:40 -07:00
|
|
|
ItemFn(_, fn_style, _, ref generics, _) => {
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2014-04-06 18:04:40 -07:00
|
|
|
encode_family(ebml_w, style_fn_family(fn_style));
|
2013-02-14 21:50:03 -08:00
|
|
|
let tps_len = generics.ty_params.len();
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path);
|
2014-02-28 15:25:15 -08:00
|
|
|
encode_attributes(ebml_w, item.attrs.as_slice());
|
|
|
|
if tps_len > 0u || should_inline(item.attrs.as_slice()) {
|
2014-02-14 07:07:09 +02:00
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
|
2012-03-08 13:30:22 +01:00
|
|
|
} else {
|
|
|
|
encode_symbol(ecx, ebml_w, item.id);
|
2012-02-14 15:21:53 -08:00
|
|
|
}
|
2013-08-07 00:11:34 -07:00
|
|
|
encode_visibility(ebml_w, vis);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemMod(ref m) => {
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2013-06-18 09:39:16 -07:00
|
|
|
encode_info_for_mod(ecx,
|
|
|
|
ebml_w,
|
|
|
|
m,
|
|
|
|
item.id,
|
|
|
|
path,
|
|
|
|
item.ident,
|
|
|
|
item.vis);
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemForeignMod(ref fm) => {
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2012-02-13 20:55:23 +01:00
|
|
|
encode_family(ebml_w, 'n');
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path);
|
2013-06-18 09:39:16 -07:00
|
|
|
|
|
|
|
// Encode all the items in this module.
|
2013-08-03 12:45:23 -04:00
|
|
|
for foreign_item in fm.items.iter() {
|
2013-06-18 09:39:16 -07:00
|
|
|
ebml_w.start_tag(tag_mod_child);
|
|
|
|
ebml_w.wr_str(def_to_str(local_def(foreign_item.id)));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
2013-08-07 00:11:34 -07:00
|
|
|
encode_visibility(ebml_w, vis);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemTy(..) => {
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2012-02-13 20:55:23 +01:00
|
|
|
encode_family(ebml_w, 'y');
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path);
|
2013-08-07 00:11:34 -07:00
|
|
|
encode_visibility(ebml_w, vis);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemEnum(ref enum_definition, ref generics) => {
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2013-05-01 17:54:54 -07:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2013-05-01 17:54:54 -07:00
|
|
|
encode_family(ebml_w, 't');
|
2013-10-29 06:08:34 -04:00
|
|
|
encode_item_variances(ebml_w, ecx, item.id);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-28 15:25:15 -08:00
|
|
|
encode_attributes(ebml_w, item.attrs.as_slice());
|
2013-08-03 12:45:23 -04:00
|
|
|
for v in (*enum_definition).variants.iter() {
|
2013-05-01 17:54:54 -07:00
|
|
|
encode_variant_id(ebml_w, local_def(v.node.id));
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2014-02-14 07:07:09 +02:00
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
|
|
|
|
encode_path(ebml_w, path);
|
2013-08-23 14:34:00 -07:00
|
|
|
|
|
|
|
// Encode inherent implementations for this enumeration.
|
|
|
|
encode_inherent_implementations(ecx, ebml_w, def_id);
|
|
|
|
|
2013-08-07 00:11:34 -07:00
|
|
|
encode_visibility(ebml_w, vis);
|
2013-05-01 17:54:54 -07:00
|
|
|
ebml_w.end_tag();
|
|
|
|
|
2012-12-04 21:13:02 -08:00
|
|
|
encode_enum_variant_info(ecx,
|
|
|
|
ebml_w,
|
|
|
|
item.id,
|
2014-02-28 15:25:15 -08:00
|
|
|
(*enum_definition).variants.as_slice(),
|
2012-12-04 21:13:02 -08:00
|
|
|
index,
|
2013-02-14 21:50:03 -08:00
|
|
|
generics);
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemStruct(struct_def, _) => {
|
2014-02-24 20:17:02 +13:00
|
|
|
let fields = ty::lookup_struct_fields(tcx, def_id);
|
|
|
|
|
2012-12-10 13:47:54 -08:00
|
|
|
/* First, encode the fields
|
2012-03-22 18:03:12 -07:00
|
|
|
These come first because we need to write them to make
|
|
|
|
the index, and the index needs to be in the item for the
|
|
|
|
class itself */
|
2014-02-24 20:17:02 +13:00
|
|
|
let idx = encode_info_for_struct(ecx,
|
|
|
|
ebml_w,
|
2014-04-22 19:06:43 +03:00
|
|
|
fields.as_slice(),
|
2014-02-24 20:17:02 +13:00
|
|
|
index);
|
2012-06-12 16:25:09 -07:00
|
|
|
|
2012-03-22 18:03:12 -07:00
|
|
|
/* Index the class*/
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2013-02-14 21:50:03 -08:00
|
|
|
|
2012-03-22 18:03:12 -07:00
|
|
|
/* Now, make an item for the class itself */
|
2012-03-16 19:19:37 -07:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2012-10-08 11:49:01 -07:00
|
|
|
encode_family(ebml_w, 'S');
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
|
2013-02-11 16:28:39 -08:00
|
|
|
|
2013-10-29 06:08:34 -04:00
|
|
|
encode_item_variances(ebml_w, ecx, item.id);
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-28 15:25:15 -08:00
|
|
|
encode_attributes(ebml_w, item.attrs.as_slice());
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path.clone());
|
2013-08-07 00:11:34 -07:00
|
|
|
encode_visibility(ebml_w, vis);
|
2012-06-12 16:25:09 -07:00
|
|
|
|
2012-03-22 18:03:12 -07:00
|
|
|
/* Encode def_ids for each field and method
|
2012-07-03 16:30:42 -07:00
|
|
|
for methods, write all the stuff get_trait_method
|
2012-03-22 18:03:12 -07:00
|
|
|
needs to know*/
|
2014-04-22 19:06:43 +03:00
|
|
|
encode_struct_fields(ebml_w, fields.as_slice(), def_id);
|
2012-08-15 15:53:58 -07:00
|
|
|
|
2014-02-14 07:07:09 +02:00
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
|
2013-09-26 21:53:40 -07:00
|
|
|
|
2013-08-23 14:34:00 -07:00
|
|
|
// Encode inherent implementations for this structure.
|
|
|
|
encode_inherent_implementations(ecx, ebml_w, def_id);
|
|
|
|
|
2012-03-22 18:03:12 -07:00
|
|
|
/* Each class has its own index -- encode it */
|
2014-04-22 19:06:43 +03:00
|
|
|
encode_index(ebml_w, idx, write_i64);
|
2012-03-16 19:19:37 -07:00
|
|
|
ebml_w.end_tag();
|
2013-06-14 18:21:47 -07:00
|
|
|
|
2014-02-14 07:07:09 +02:00
|
|
|
// If this is a tuple-like struct, encode the type of the constructor.
|
|
|
|
match struct_def.ctor_id {
|
|
|
|
Some(ctor_id) => {
|
|
|
|
encode_info_for_struct_ctor(ecx, ebml_w, item.ident,
|
|
|
|
ctor_id, index, def_id.node);
|
|
|
|
}
|
|
|
|
None => {}
|
2013-06-14 18:21:47 -07:00
|
|
|
}
|
2012-01-31 19:30:40 -08:00
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemImpl(_, ref opt_trait, ty, ref ast_methods) => {
|
2013-07-16 16:28:33 -07:00
|
|
|
// We need to encode information about the default methods we
|
|
|
|
// have inherited, so we drive this based on the impl structure.
|
2014-04-21 12:04:35 +03:00
|
|
|
let impl_methods = tcx.impl_methods.borrow();
|
|
|
|
let methods = impl_methods.get(&def_id);
|
2013-07-16 16:28:33 -07:00
|
|
|
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2012-02-13 20:55:23 +01:00
|
|
|
encode_family(ebml_w, 'i');
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-28 15:25:15 -08:00
|
|
|
encode_attributes(ebml_w, item.attrs.as_slice());
|
2012-10-18 13:29:34 -07:00
|
|
|
match ty.node {
|
2014-01-09 15:05:33 +02:00
|
|
|
ast::TyPath(ref path, ref bounds, _) if path.segments
|
|
|
|
.len() == 1 => {
|
2013-06-20 18:23:25 -04:00
|
|
|
assert!(bounds.is_none());
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_impl_type_basename(ebml_w, ast_util::path_to_ident(path));
|
2012-10-18 13:29:34 -07:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
2014-04-21 12:04:35 +03:00
|
|
|
for &method_def_id in methods.iter() {
|
2012-11-13 19:08:01 -08:00
|
|
|
ebml_w.start_tag(tag_item_impl_method);
|
2014-04-21 12:04:35 +03:00
|
|
|
let s = def_to_str(method_def_id);
|
2013-06-11 13:10:37 +10:00
|
|
|
ebml_w.writer.write(s.as_bytes());
|
2012-11-13 19:08:01 -08:00
|
|
|
ebml_w.end_tag();
|
2011-12-16 14:17:52 +01:00
|
|
|
}
|
2013-08-03 12:45:23 -04:00
|
|
|
for ast_trait_ref in opt_trait.iter() {
|
2013-07-16 16:28:33 -07:00
|
|
|
let trait_ref = ty::node_id_to_trait_ref(
|
|
|
|
tcx, ast_trait_ref.ref_id);
|
2014-04-22 02:21:52 +03:00
|
|
|
encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_trait_ref);
|
2013-07-22 16:40:31 -07:00
|
|
|
let impl_vtables = ty::lookup_impl_vtables(tcx, def_id);
|
|
|
|
encode_impl_vtables(ebml_w, ecx, &impl_vtables);
|
2012-07-18 09:31:53 -07:00
|
|
|
}
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path.clone());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-12-16 14:17:52 +01:00
|
|
|
|
2013-07-11 17:07:57 -07:00
|
|
|
// Iterate down the methods, emitting them. We rely on the
|
|
|
|
// assumption that all of the actually implemented methods
|
|
|
|
// appear first in the impl structure, in the same order they do
|
|
|
|
// in the ast. This is a little sketchy.
|
|
|
|
let num_implemented_methods = ast_methods.len();
|
2014-04-21 12:04:35 +03:00
|
|
|
for (i, &method_def_id) in methods.iter().enumerate() {
|
2013-07-11 17:07:57 -07:00
|
|
|
let ast_method = if i < num_implemented_methods {
|
2014-02-28 15:25:15 -08:00
|
|
|
Some(*ast_methods.get(i))
|
2013-07-11 17:07:57 -07:00
|
|
|
} else { None };
|
|
|
|
|
2014-04-22 19:06:43 +03:00
|
|
|
index.push(entry {
|
2014-04-21 12:04:35 +03:00
|
|
|
val: method_def_id.node as i64,
|
2014-03-20 19:49:20 -07:00
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
|
|
|
});
|
2013-02-27 13:45:37 -08:00
|
|
|
encode_info_for_method(ecx,
|
|
|
|
ebml_w,
|
2014-04-22 02:21:52 +03:00
|
|
|
&*ty::method(tcx, method_def_id),
|
2014-02-14 07:07:09 +02:00
|
|
|
path.clone(),
|
2013-07-16 16:28:33 -07:00
|
|
|
false,
|
2013-02-27 13:45:37 -08:00
|
|
|
item.id,
|
2013-07-11 17:07:57 -07:00
|
|
|
ast_method)
|
2011-12-16 14:17:52 +01:00
|
|
|
}
|
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemTrait(_, ref super_traits, ref ms) => {
|
2014-02-07 14:44:56 -05:00
|
|
|
add_to_index(item, ebml_w, index);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_def_id(ebml_w, def_id);
|
2012-02-13 20:55:23 +01:00
|
|
|
encode_family(ebml_w, 'I');
|
2013-10-29 06:08:34 -04:00
|
|
|
encode_item_variances(ebml_w, ecx, item.id);
|
2013-07-16 16:28:33 -07:00
|
|
|
let trait_def = ty::lookup_trait_def(tcx, def_id);
|
|
|
|
encode_ty_type_param_defs(ebml_w, ecx,
|
2014-02-01 15:57:59 +11:00
|
|
|
trait_def.generics.type_param_defs(),
|
2013-07-16 16:28:33 -07:00
|
|
|
tag_items_data_item_ty_param_bounds);
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_region_param_defs(ebml_w, trait_def.generics.region_param_defs());
|
2014-04-22 02:21:52 +03:00
|
|
|
encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, item.ident.name);
|
2014-02-28 15:25:15 -08:00
|
|
|
encode_attributes(ebml_w, item.attrs.as_slice());
|
2014-01-17 15:23:19 -08:00
|
|
|
encode_visibility(ebml_w, vis);
|
2013-08-03 12:45:23 -04:00
|
|
|
for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
|
2013-03-27 10:26:57 -04:00
|
|
|
ebml_w.start_tag(tag_item_trait_method);
|
|
|
|
encode_def_id(ebml_w, method_def_id);
|
|
|
|
ebml_w.end_tag();
|
2013-06-18 09:39:16 -07:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_mod_child);
|
|
|
|
ebml_w.wr_str(def_to_str(method_def_id));
|
|
|
|
ebml_w.end_tag();
|
2012-01-05 13:57:27 +01:00
|
|
|
}
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path.clone());
|
2013-08-16 16:57:42 -04:00
|
|
|
// FIXME(#8559): This should use the tcx's supertrait cache instead of
|
|
|
|
// reading the AST's list, because the former has already filtered out
|
|
|
|
// the builtin-kinds-as-supertraits. See corresponding fixme in decoder.
|
2013-08-03 12:45:23 -04:00
|
|
|
for ast_trait_ref in super_traits.iter() {
|
2013-03-27 06:16:28 -04:00
|
|
|
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
|
2014-04-22 02:21:52 +03:00
|
|
|
encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_super_trait_ref);
|
2012-08-03 15:02:01 -07:00
|
|
|
}
|
2013-08-23 14:34:00 -07:00
|
|
|
|
|
|
|
// Encode the implementations of this trait.
|
|
|
|
encode_extension_implementations(ecx, ebml_w, def_id);
|
|
|
|
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2012-08-02 16:01:38 -07:00
|
|
|
|
2013-03-27 10:26:57 -04:00
|
|
|
// Now output the method info for each method.
|
2013-07-16 16:28:33 -07:00
|
|
|
let r = ty::trait_method_def_ids(tcx, def_id);
|
2013-08-03 12:45:23 -04:00
|
|
|
for (i, &method_def_id) in r.iter().enumerate() {
|
2014-02-05 22:15:24 +01:00
|
|
|
assert_eq!(method_def_id.krate, ast::LOCAL_CRATE);
|
2012-08-02 16:01:38 -07:00
|
|
|
|
2013-05-02 08:11:15 -07:00
|
|
|
let method_ty = ty::method(tcx, method_def_id);
|
2013-03-27 10:26:57 -04:00
|
|
|
|
2014-04-22 19:06:43 +03:00
|
|
|
index.push(entry {
|
2014-03-20 19:49:20 -07:00
|
|
|
val: method_def_id.node as i64,
|
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
|
|
|
});
|
2012-08-02 16:01:38 -07:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-03-27 10:26:57 -04:00
|
|
|
|
2014-04-22 02:21:52 +03:00
|
|
|
encode_method_ty_fields(ecx, ebml_w, &*method_ty);
|
2013-03-28 14:27:54 -04:00
|
|
|
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_parent_item(ebml_w, def_id);
|
2013-03-28 14:27:54 -04:00
|
|
|
|
2014-02-14 07:07:09 +02:00
|
|
|
let elem = ast_map::PathName(method_ty.ident.name);
|
|
|
|
encode_path(ebml_w, path.clone().chain(Some(elem).move_iter()));
|
2013-03-27 10:26:57 -04:00
|
|
|
|
2013-04-30 08:49:48 -07:00
|
|
|
match method_ty.explicit_self {
|
2014-01-09 15:05:33 +02:00
|
|
|
SelfStatic => {
|
2013-03-27 10:26:57 -04:00
|
|
|
encode_family(ebml_w,
|
2014-04-06 18:04:40 -07:00
|
|
|
fn_style_static_method_family(
|
|
|
|
method_ty.fty.fn_style));
|
2013-03-27 10:26:57 -04:00
|
|
|
|
|
|
|
let tpt = ty::lookup_item_type(tcx, method_def_id);
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx, &tpt);
|
2013-03-27 10:26:57 -04:00
|
|
|
}
|
2013-03-18 17:20:45 -07:00
|
|
|
|
2013-03-27 10:26:57 -04:00
|
|
|
_ => {
|
|
|
|
encode_family(ebml_w,
|
2014-04-06 18:04:40 -07:00
|
|
|
style_fn_family(
|
|
|
|
method_ty.fty.fn_style));
|
2013-03-27 10:26:57 -04:00
|
|
|
}
|
|
|
|
}
|
2012-08-02 16:01:38 -07:00
|
|
|
|
2014-02-28 15:25:15 -08:00
|
|
|
match ms.get(i) {
|
|
|
|
&Required(ref tm) => {
|
|
|
|
encode_attributes(ebml_w, tm.attrs.as_slice());
|
2013-03-27 10:26:57 -04:00
|
|
|
encode_method_sort(ebml_w, 'r');
|
|
|
|
}
|
2013-02-14 21:50:03 -08:00
|
|
|
|
2014-02-28 15:25:15 -08:00
|
|
|
&Provided(m) => {
|
|
|
|
encode_attributes(ebml_w, m.attrs.as_slice());
|
2013-07-11 15:08:43 -07:00
|
|
|
// If this is a static method, we've already encoded
|
|
|
|
// this.
|
2014-01-09 15:05:33 +02:00
|
|
|
if method_ty.explicit_self != SelfStatic {
|
2014-01-26 03:43:42 -05:00
|
|
|
// FIXME: I feel like there is something funny going on.
|
2013-07-16 16:28:33 -07:00
|
|
|
let tpt = ty::lookup_item_type(tcx, method_def_id);
|
|
|
|
encode_bounds_and_type(ebml_w, ecx, &tpt);
|
2013-03-27 10:26:57 -04:00
|
|
|
}
|
|
|
|
encode_method_sort(ebml_w, 'p');
|
|
|
|
(ecx.encode_inlined_item)(
|
2014-02-14 07:07:09 +02:00
|
|
|
ecx, ebml_w, IIMethodRef(def_id, true, m));
|
2013-03-27 10:26:57 -04:00
|
|
|
}
|
|
|
|
}
|
2013-02-14 21:50:03 -08:00
|
|
|
|
2013-03-27 10:26:57 -04:00
|
|
|
ebml_w.end_tag();
|
2012-10-08 12:39:30 -07:00
|
|
|
}
|
2013-08-23 14:34:00 -07:00
|
|
|
|
|
|
|
// Encode inherent implementations for this trait.
|
|
|
|
encode_inherent_implementations(ecx, ebml_w, def_id);
|
2012-01-05 13:57:27 +01:00
|
|
|
}
|
2013-12-25 11:10:33 -07:00
|
|
|
ItemMac(..) => {
|
|
|
|
// macros are encoded separately
|
|
|
|
}
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2014-01-09 15:05:33 +02:00
|
|
|
nitem: &ForeignItem,
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &mut Vec<entry<i64>>,
|
2014-02-14 07:07:09 +02:00
|
|
|
path: PathElems,
|
2014-04-02 01:19:41 -07:00
|
|
|
abi: abi::Abi) {
|
2014-04-22 19:06:43 +03:00
|
|
|
index.push(entry {
|
2014-03-20 19:49:20 -07:00
|
|
|
val: nitem.id as i64,
|
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
|
|
|
});
|
2012-03-08 23:37:45 +01:00
|
|
|
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_def_id(ebml_w, local_def(nitem.id));
|
2013-02-14 21:50:03 -08:00
|
|
|
match nitem.node {
|
2014-01-09 15:05:33 +02:00
|
|
|
ForeignItemFn(..) => {
|
2014-04-06 18:04:40 -07:00
|
|
|
encode_family(ebml_w, style_fn_family(NormalFn));
|
2013-07-16 16:28:33 -07:00
|
|
|
encode_bounds_and_type(ebml_w, ecx,
|
|
|
|
&lookup_item_type(ecx.tcx,local_def(nitem.id)));
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, nitem.ident.name);
|
2014-04-02 01:19:41 -07:00
|
|
|
if abi == abi::RustIntrinsic {
|
2014-02-14 07:07:09 +02:00
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, IIForeignRef(nitem));
|
2012-03-21 15:42:20 +01:00
|
|
|
} else {
|
|
|
|
encode_symbol(ecx, ebml_w, nitem.id);
|
|
|
|
}
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
ForeignItemStatic(_, mutbl) => {
|
2013-06-21 22:46:27 -07:00
|
|
|
if mutbl {
|
|
|
|
encode_family(ebml_w, 'b');
|
|
|
|
} else {
|
|
|
|
encode_family(ebml_w, 'c');
|
|
|
|
}
|
2012-08-25 15:09:33 -07:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
|
|
|
encode_symbol(ecx, ebml_w, nitem.id);
|
2014-02-22 04:04:03 +08:00
|
|
|
encode_name(ebml_w, nitem.ident.name);
|
2012-08-25 15:09:33 -07:00
|
|
|
}
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_path(ebml_w, path);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2014-01-06 14:00:46 +02:00
|
|
|
fn my_visit_expr(_e: &Expr) { }
|
2013-08-12 14:05:43 +02:00
|
|
|
|
2014-01-09 15:05:33 +02:00
|
|
|
fn my_visit_item(i: &Item,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-12-20 17:36:07 -08:00
|
|
|
ecx_ptr: *int,
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &mut Vec<entry<i64>>) {
|
2014-02-14 07:07:09 +02:00
|
|
|
let mut ebml_w = unsafe { ebml_w.unsafe_clone() };
|
|
|
|
// See above
|
|
|
|
let ecx: &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
|
|
|
ecx.tcx.map.with_path(i.id, |path| {
|
|
|
|
encode_info_for_item(ecx, &mut ebml_w, i, index, path, i.vis);
|
|
|
|
});
|
2013-08-12 14:05:43 +02:00
|
|
|
}
|
|
|
|
|
2014-01-09 15:05:33 +02:00
|
|
|
fn my_visit_foreign_item(ni: &ForeignItem,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2013-12-20 17:36:07 -08:00
|
|
|
ecx_ptr:*int,
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &mut Vec<entry<i64>>) {
|
2014-02-14 07:07:09 +02:00
|
|
|
// See above
|
|
|
|
let ecx: &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
|
|
|
debug!("writing foreign item {}::{}",
|
|
|
|
ecx.tcx.map.path_to_str(ni.id),
|
|
|
|
token::get_ident(ni.ident));
|
|
|
|
|
|
|
|
let mut ebml_w = unsafe {
|
|
|
|
ebml_w.unsafe_clone()
|
|
|
|
};
|
2014-04-02 01:19:41 -07:00
|
|
|
let abi = ecx.tcx.map.get_foreign_abi(ni.id);
|
2014-02-14 07:07:09 +02:00
|
|
|
ecx.tcx.map.with_path(ni.id, |path| {
|
|
|
|
encode_info_for_foreign_item(ecx, &mut ebml_w,
|
|
|
|
ni, index,
|
2014-04-02 01:19:41 -07:00
|
|
|
path, abi);
|
2014-02-14 07:07:09 +02:00
|
|
|
});
|
2013-08-12 14:05:43 +02:00
|
|
|
}
|
|
|
|
|
2013-12-20 17:36:07 -08:00
|
|
|
struct EncodeVisitor<'a,'b> {
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w_for_visit_item: &'a mut Encoder<'b>,
|
2013-08-12 14:05:43 +02:00
|
|
|
ecx_ptr:*int,
|
2014-04-22 19:06:43 +03:00
|
|
|
index: &'a mut Vec<entry<i64>>,
|
2013-08-12 14:05:43 +02:00
|
|
|
}
|
|
|
|
|
2013-12-20 17:36:07 -08:00
|
|
|
impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> {
|
2014-01-06 14:00:46 +02:00
|
|
|
fn visit_expr(&mut self, ex: &Expr, _: ()) {
|
2013-08-20 14:55:54 -07:00
|
|
|
visit::walk_expr(self, ex, ());
|
|
|
|
my_visit_expr(ex);
|
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
fn visit_item(&mut self, i: &Item, _: ()) {
|
2013-08-12 14:05:43 +02:00
|
|
|
visit::walk_item(self, i, ());
|
|
|
|
my_visit_item(i,
|
2013-12-20 17:36:07 -08:00
|
|
|
self.ebml_w_for_visit_item,
|
2013-08-12 14:05:43 +02:00
|
|
|
self.ecx_ptr,
|
|
|
|
self.index);
|
|
|
|
}
|
2014-01-09 15:05:33 +02:00
|
|
|
fn visit_foreign_item(&mut self, ni: &ForeignItem, _: ()) {
|
2013-08-12 14:05:43 +02:00
|
|
|
visit::walk_foreign_item(self, ni, ());
|
|
|
|
my_visit_foreign_item(ni,
|
2013-12-20 17:36:07 -08:00
|
|
|
self.ebml_w_for_visit_item,
|
2013-08-12 14:05:43 +02:00
|
|
|
self.ecx_ptr,
|
|
|
|
self.index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 19:19:50 +12:00
|
|
|
fn encode_info_for_items(ecx: &EncodeContext,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder,
|
2014-02-05 22:15:24 +01:00
|
|
|
krate: &Crate)
|
2014-03-04 10:02:49 -08:00
|
|
|
-> Vec<entry<i64>> {
|
2014-04-22 19:06:43 +03:00
|
|
|
let mut index = Vec::new();
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items_data);
|
2014-04-22 19:06:43 +03:00
|
|
|
index.push(entry {
|
2014-03-20 19:49:20 -07:00
|
|
|
val: CRATE_NODE_ID as i64,
|
|
|
|
pos: ebml_w.writer.tell().unwrap(),
|
|
|
|
});
|
2013-06-18 09:39:16 -07:00
|
|
|
encode_info_for_mod(ecx,
|
|
|
|
ebml_w,
|
2014-02-05 22:15:24 +01:00
|
|
|
&krate.module,
|
2013-07-27 10:25:59 +02:00
|
|
|
CRATE_NODE_ID,
|
2014-02-14 07:07:09 +02:00
|
|
|
ast_map::Values([].iter()).chain(None),
|
2013-06-18 09:39:16 -07:00
|
|
|
syntax::parse::token::special_idents::invalid,
|
2014-01-09 15:05:33 +02:00
|
|
|
Public);
|
2013-06-13 19:19:50 +12:00
|
|
|
|
|
|
|
// See comment in `encode_side_tables_for_ii` in astencode
|
2014-02-14 07:07:09 +02:00
|
|
|
let ecx_ptr: *int = unsafe { cast::transmute(ecx) };
|
2014-04-22 19:06:43 +03:00
|
|
|
visit::walk_crate(&mut EncodeVisitor {
|
|
|
|
index: &mut index,
|
|
|
|
ecx_ptr: ecx_ptr,
|
|
|
|
ebml_w_for_visit_item: &mut *ebml_w,
|
|
|
|
}, krate, ());
|
2013-08-12 14:05:43 +02:00
|
|
|
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2014-04-22 19:06:43 +03:00
|
|
|
index
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Path and definition ID indexing
|
|
|
|
|
2014-04-22 19:06:43 +03:00
|
|
|
fn encode_index<T: Hash>(ebml_w: &mut Encoder, index: Vec<entry<T>>,
|
|
|
|
write_fn: |&mut MemWriter, &T|) {
|
|
|
|
let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
|
|
|
|
for elt in index.move_iter() {
|
2014-02-23 21:29:35 +11:00
|
|
|
let h = hash::hash(&elt.val) as uint;
|
2014-04-22 19:06:43 +03:00
|
|
|
buckets.get_mut(h % 256).push(elt);
|
2011-07-14 14:25:43 -07:00
|
|
|
}
|
2011-06-27 15:20:17 -07:00
|
|
|
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_index);
|
2014-03-04 10:02:49 -08:00
|
|
|
let mut bucket_locs = Vec::new();
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_index_buckets);
|
2013-08-03 12:45:23 -04:00
|
|
|
for bucket in buckets.iter() {
|
2014-01-29 18:42:19 -08:00
|
|
|
bucket_locs.push(ebml_w.writer.tell().unwrap());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_index_buckets_bucket);
|
2014-04-22 19:06:43 +03:00
|
|
|
for elt in bucket.iter() {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_index_buckets_bucket_elt);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(elt.pos < 0xffff_ffff);
|
2013-10-21 17:11:42 -07:00
|
|
|
{
|
|
|
|
let wr: &mut MemWriter = ebml_w.writer;
|
2013-10-25 18:08:45 -07:00
|
|
|
wr.write_be_u32(elt.pos as u32);
|
2013-10-21 17:11:42 -07:00
|
|
|
}
|
|
|
|
write_fn(ebml_w.writer, &elt.val);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_index_table);
|
2013-08-03 12:45:23 -04:00
|
|
|
for pos in bucket_locs.iter() {
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(*pos < 0xffff_ffff);
|
2013-10-21 17:11:42 -07:00
|
|
|
let wr: &mut MemWriter = ebml_w.writer;
|
2013-10-25 18:08:45 -07:00
|
|
|
wr.write_be_u32(*pos as u32);
|
2012-08-02 17:17:07 -07:00
|
|
|
}
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2013-12-20 17:36:07 -08:00
|
|
|
fn write_i64(writer: &mut MemWriter, &n: &i64) {
|
2013-10-21 17:11:42 -07:00
|
|
|
let wr: &mut MemWriter = writer;
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(n < 0x7fff_ffff);
|
2013-10-25 18:08:45 -07:00
|
|
|
wr.write_be_u32(n as u32);
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_meta_item(ebml_w: &mut Encoder, mi: @MetaItem) {
|
2012-08-06 12:34:08 -07:00
|
|
|
match mi.node {
|
2014-01-08 10:35:15 -08:00
|
|
|
MetaWord(ref name) => {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_meta_item_word);
|
|
|
|
ebml_w.start_tag(tag_meta_item_name);
|
2014-01-08 10:35:15 -08:00
|
|
|
ebml_w.writer.write(name.get().as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-01-10 14:02:36 -08:00
|
|
|
MetaNameValue(ref name, ref value) => {
|
2012-08-06 12:34:08 -07:00
|
|
|
match value.node {
|
2014-01-10 14:02:36 -08:00
|
|
|
LitStr(ref value, _) => {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_meta_item_name_value);
|
|
|
|
ebml_w.start_tag(tag_meta_item_name);
|
2014-01-08 10:35:15 -08:00
|
|
|
ebml_w.writer.write(name.get().as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_meta_item_value);
|
2014-01-10 14:02:36 -08:00
|
|
|
ebml_w.writer.write(value.get().as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2012-08-03 19:59:04 -07:00
|
|
|
_ => {/* FIXME (#623): encode other variants */ }
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
|
|
|
}
|
2014-01-08 10:35:15 -08:00
|
|
|
MetaList(ref name, ref items) => {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_meta_item_list);
|
|
|
|
ebml_w.start_tag(tag_meta_item_name);
|
2014-01-08 10:35:15 -08:00
|
|
|
ebml_w.writer.write(name.get().as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2013-08-03 12:45:23 -04:00
|
|
|
for inner_item in items.iter() {
|
2013-02-25 06:19:44 -08:00
|
|
|
encode_meta_item(ebml_w, *inner_item);
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2011-06-27 19:41:48 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_attributes);
|
2013-08-03 12:45:23 -04:00
|
|
|
for attr in attrs.iter() {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_attribute);
|
2011-06-27 19:41:48 -07:00
|
|
|
encode_meta_item(ebml_w, attr.node.value);
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 19:41:48 -07:00
|
|
|
}
|
|
|
|
|
2013-12-28 12:16:48 -05:00
|
|
|
// So there's a special crate attribute called 'crate_id' which defines the
|
2013-12-09 14:56:53 -07:00
|
|
|
// metadata that Rust cares about for linking crates. If the user didn't
|
|
|
|
// provide it we will throw it in anyway with a default value.
|
2013-06-13 19:19:50 +12:00
|
|
|
fn synthesize_crate_attrs(ecx: &EncodeContext,
|
2014-03-04 10:02:49 -08:00
|
|
|
krate: &Crate) -> Vec<Attribute> {
|
2011-06-29 14:17:23 -07:00
|
|
|
|
2013-12-28 12:16:48 -05:00
|
|
|
fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
|
|
|
|
assert!(!ecx.link_meta.crateid.name.is_empty());
|
2011-06-29 14:17:23 -07:00
|
|
|
|
2013-12-09 14:56:53 -07:00
|
|
|
attr::mk_attr(
|
|
|
|
attr::mk_name_value_item_str(
|
2014-01-08 10:35:15 -08:00
|
|
|
InternedString::new("crate_id"),
|
2014-01-10 14:02:36 -08:00
|
|
|
token::intern_and_get_ident(ecx.link_meta.crateid.to_str())))
|
2011-06-29 14:17:23 -07:00
|
|
|
}
|
|
|
|
|
2014-03-04 10:02:49 -08:00
|
|
|
let mut attrs = Vec::new();
|
2014-02-05 22:15:24 +01:00
|
|
|
for attr in krate.attrs.iter() {
|
2014-01-08 10:35:15 -08:00
|
|
|
if !attr.name().equiv(&("crate_id")) {
|
2013-12-09 14:56:53 -07:00
|
|
|
attrs.push(*attr);
|
|
|
|
}
|
2011-06-29 14:17:23 -07:00
|
|
|
}
|
2013-12-28 12:16:48 -05:00
|
|
|
attrs.push(synthesize_crateid_attr(ecx));
|
2011-06-29 14:17:23 -07:00
|
|
|
|
2013-12-09 14:56:53 -07:00
|
|
|
attrs
|
2011-06-29 14:17:23 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
|
2014-03-04 10:02:49 -08:00
|
|
|
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
|
2012-04-08 01:59:37 +08:00
|
|
|
// Pull the cnums and name,vers,hash out of cstore
|
2014-03-04 10:02:49 -08:00
|
|
|
let mut deps = Vec::new();
|
2013-12-25 13:08:04 -07:00
|
|
|
cstore.iter_crate_data(|key, val| {
|
2014-02-14 07:07:09 +02:00
|
|
|
let dep = decoder::CrateDep {
|
|
|
|
cnum: key,
|
2014-02-24 18:13:51 -08:00
|
|
|
crate_id: decoder::get_crate_id(val.data()),
|
2014-02-14 07:07:09 +02:00
|
|
|
hash: decoder::get_crate_hash(val.data())
|
|
|
|
};
|
2012-09-26 17:33:34 -07:00
|
|
|
deps.push(dep);
|
2013-11-21 15:42:55 -08:00
|
|
|
});
|
2011-07-08 11:29:56 -07:00
|
|
|
|
|
|
|
// Sort by cnum
|
2013-12-20 14:42:00 +11:00
|
|
|
deps.sort_by(|kv1, kv2| kv1.cnum.cmp(&kv2.cnum));
|
2011-07-08 11:29:56 -07:00
|
|
|
|
|
|
|
// Sanity-check the crate numbers
|
2012-03-15 09:47:03 -04:00
|
|
|
let mut expected_cnum = 1;
|
2013-08-03 12:45:23 -04:00
|
|
|
for n in deps.iter() {
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(n.cnum, expected_cnum);
|
2011-07-08 11:29:56 -07:00
|
|
|
expected_cnum += 1;
|
|
|
|
}
|
|
|
|
|
2013-06-29 15:05:50 +10:00
|
|
|
deps
|
2011-07-08 11:29:56 -07:00
|
|
|
}
|
|
|
|
|
2012-04-08 01:59:37 +08:00
|
|
|
// We're just going to write a list of crate 'name-hash-version's, with
|
|
|
|
// the assumption that they are numbered 1 to n.
|
2012-06-21 16:44:10 -07:00
|
|
|
// FIXME (#2166): This is not nearly enough to support correct versioning
|
2011-07-08 11:29:56 -07:00
|
|
|
// but is enough to get transitive crate dependencies working.
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_crate_deps);
|
2014-02-14 07:07:09 +02:00
|
|
|
let r = get_ordered_deps(cstore);
|
2013-08-03 12:45:23 -04:00
|
|
|
for dep in r.iter() {
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_crate_dep(ebml_w, (*dep).clone());
|
2011-07-08 11:29:56 -07:00
|
|
|
}
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-07-08 11:29:56 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_lang_items(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
2013-01-07 10:51:53 -08:00
|
|
|
ebml_w.start_tag(tag_lang_items);
|
|
|
|
|
2013-09-30 02:34:36 +02:00
|
|
|
for (i, def_id) in ecx.tcx.lang_items.items() {
|
2013-08-03 12:45:23 -04:00
|
|
|
for id in def_id.iter() {
|
2014-02-05 22:15:24 +01:00
|
|
|
if id.krate == LOCAL_CRATE {
|
2013-08-02 02:17:20 -04:00
|
|
|
ebml_w.start_tag(tag_lang_items_item);
|
2013-01-07 10:51:53 -08:00
|
|
|
|
2013-08-02 02:17:20 -04:00
|
|
|
ebml_w.start_tag(tag_lang_items_item_id);
|
2013-10-21 17:11:42 -07:00
|
|
|
{
|
|
|
|
let wr: &mut MemWriter = ebml_w.writer;
|
2013-10-25 18:08:45 -07:00
|
|
|
wr.write_be_u32(i as u32);
|
2013-10-21 17:11:42 -07:00
|
|
|
}
|
2013-08-02 02:17:20 -04:00
|
|
|
ebml_w.end_tag(); // tag_lang_items_item_id
|
2013-01-07 10:51:53 -08:00
|
|
|
|
2013-08-02 02:17:20 -04:00
|
|
|
ebml_w.start_tag(tag_lang_items_item_node_id);
|
2013-10-21 17:11:42 -07:00
|
|
|
{
|
|
|
|
let wr: &mut MemWriter = ebml_w.writer;
|
2013-10-25 18:08:45 -07:00
|
|
|
wr.write_be_u32(id.node as u32);
|
2013-10-21 17:11:42 -07:00
|
|
|
}
|
2013-08-02 02:17:20 -04:00
|
|
|
ebml_w.end_tag(); // tag_lang_items_item_node_id
|
2013-01-07 10:51:53 -08:00
|
|
|
|
2013-08-02 02:17:20 -04:00
|
|
|
ebml_w.end_tag(); // tag_lang_items_item
|
|
|
|
}
|
|
|
|
}
|
2013-09-30 02:34:36 +02:00
|
|
|
}
|
2013-01-07 10:51:53 -08:00
|
|
|
|
|
|
|
ebml_w.end_tag(); // tag_lang_items
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
ebml_w.start_tag(tag_native_libraries);
|
|
|
|
|
2014-03-20 19:49:20 -07:00
|
|
|
for &(ref lib, kind) in ecx.tcx.sess.cstore.get_used_libraries()
|
|
|
|
.borrow().iter() {
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
match kind {
|
|
|
|
cstore::NativeStatic => {} // these libraries are not propagated
|
2013-11-30 11:39:55 -08:00
|
|
|
cstore::NativeFramework | cstore::NativeUnknown => {
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
ebml_w.start_tag(tag_native_libraries_lib);
|
2013-11-30 11:39:55 -08:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_native_libraries_kind);
|
|
|
|
ebml_w.writer.write_be_u32(kind as u32);
|
|
|
|
ebml_w.end_tag();
|
|
|
|
|
|
|
|
ebml_w.start_tag(tag_native_libraries_name);
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
ebml_w.writer.write(lib.as_bytes());
|
|
|
|
ebml_w.end_tag();
|
2013-11-30 11:39:55 -08:00
|
|
|
|
|
|
|
ebml_w.end_tag();
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_macro_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
2014-04-13 11:26:43 -07:00
|
|
|
match ecx.tcx.sess.macro_registrar_fn.get() {
|
|
|
|
Some(id) => { ebml_w.wr_tagged_u32(tag_macro_registrar_fn, id); }
|
2013-12-25 11:10:33 -07:00
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct MacroDefVisitor<'a, 'b> {
|
|
|
|
ecx: &'a EncodeContext<'a>,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &'a mut Encoder<'b>
|
2013-12-25 11:10:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'b> Visitor<()> for MacroDefVisitor<'a, 'b> {
|
|
|
|
fn visit_item(&mut self, item: &Item, _: ()) {
|
|
|
|
match item.node {
|
|
|
|
ItemMac(..) => {
|
2014-03-16 20:56:24 +02:00
|
|
|
let def = self.ecx.tcx.sess.codemap().span_to_snippet(item.span)
|
2014-01-21 23:09:53 -08:00
|
|
|
.expect("Unable to find source for macro");
|
2013-12-25 11:10:33 -07:00
|
|
|
self.ebml_w.start_tag(tag_macro_def);
|
2014-01-21 23:09:53 -08:00
|
|
|
self.ebml_w.wr_str(def);
|
2013-12-25 11:10:33 -07:00
|
|
|
self.ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
2014-01-20 09:22:46 -08:00
|
|
|
visit::walk_item(self, item, ());
|
2013-12-25 11:10:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn encode_macro_defs(ecx: &EncodeContext,
|
2014-02-05 22:15:24 +01:00
|
|
|
krate: &Crate,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder) {
|
2013-12-25 11:10:33 -07:00
|
|
|
ebml_w.start_tag(tag_exported_macros);
|
|
|
|
{
|
|
|
|
let mut visitor = MacroDefVisitor {
|
|
|
|
ecx: ecx,
|
|
|
|
ebml_w: ebml_w,
|
|
|
|
};
|
2014-02-05 22:15:24 +01:00
|
|
|
visit::walk_crate(&mut visitor, krate, ());
|
2013-12-25 11:10:33 -07:00
|
|
|
}
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-12-20 17:36:07 -08:00
|
|
|
struct ImplVisitor<'a,'b> {
|
2013-12-09 23:16:18 -08:00
|
|
|
ecx: &'a EncodeContext<'a>,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &'a mut Encoder<'b>,
|
2013-08-20 14:55:54 -07:00
|
|
|
}
|
|
|
|
|
2013-12-20 17:36:07 -08:00
|
|
|
impl<'a,'b> Visitor<()> for ImplVisitor<'a,'b> {
|
2014-01-09 15:05:33 +02:00
|
|
|
fn visit_item(&mut self, item: &Item, _: ()) {
|
2013-08-20 14:55:54 -07:00
|
|
|
match item.node {
|
2014-01-09 15:05:33 +02:00
|
|
|
ItemImpl(_, Some(ref trait_ref), _, _) => {
|
2014-04-22 19:06:43 +03:00
|
|
|
let def_map = &self.ecx.tcx.def_map;
|
2014-03-20 19:49:20 -07:00
|
|
|
let trait_def = def_map.borrow().get_copy(&trait_ref.ref_id);
|
2013-08-23 14:34:00 -07:00
|
|
|
let def_id = ast_util::def_id_of_def(trait_def);
|
|
|
|
|
|
|
|
// Load eagerly if this is an implementation of the Drop trait
|
|
|
|
// or if the trait is not defined in this crate.
|
Extract privacy checking from name resolution
This commit is the culmination of my recent effort to refine Rust's notion of
privacy and visibility among crates. The major goals of this commit were to
remove privacy checking from resolve for the sake of sane error messages, and to
attempt a much more rigid and well-tested implementation of visibility
throughout rust. The implemented rules for name visibility are:
1. Everything pub from the root namespace is visible to anyone
2. You may access any private item of your ancestors.
"Accessing a private item" depends on what the item is, so for a function this
means that you can call it, but for a module it means that you can look inside
of it. Once you look inside a private module, any accessed item must be "pub
from the root" where the new root is the private module that you looked into.
These rules required some more analysis results to get propagated from trans to
privacy in the form of a few hash tables.
I added a new test in which my goal was to showcase all of the privacy nuances
of the language, and I hope to place any new bugs into this file to prevent
regressions.
Overall, I was unable to completely remove the notion of privacy from resolve.
One use of privacy is for dealing with glob imports. Essentially a glob import
can only import *public* items from the destination, and because this must be
done at namespace resolution time, resolve must maintain the notion of "what
items are public in a module". There are some sad approximations of privacy, but
I unfortunately can't see clear methods to extract them outside.
The other use case of privacy in resolve now is one that must stick around
regardless of glob imports. When dealing with privacy, checking a private path
needs to know "what the last private thing was" when looking at a path. Resolve
is the only compiler pass which knows the answer to this question, so it
maintains the answer on a per-path resolution basis (works similarly to the
def_map generated).
Closes #8215
2013-10-05 14:37:39 -07:00
|
|
|
if Some(def_id) == self.ecx.tcx.lang_items.drop_trait() ||
|
2014-02-05 22:15:24 +01:00
|
|
|
def_id.krate != LOCAL_CRATE {
|
2013-08-23 14:34:00 -07:00
|
|
|
self.ebml_w.start_tag(tag_impls_impl);
|
|
|
|
encode_def_id(self.ebml_w, local_def(item.id));
|
|
|
|
self.ebml_w.end_tag();
|
|
|
|
}
|
2013-08-20 14:55:54 -07:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
visit::walk_item(self, item, ());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-23 14:34:00 -07:00
|
|
|
/// Encodes implementations that are eagerly loaded.
|
|
|
|
///
|
|
|
|
/// None of this is necessary in theory; we can load all implementations
|
|
|
|
/// lazily. However, in two cases the optimizations to lazily load
|
|
|
|
/// implementations are not yet implemented. These two cases, which require us
|
|
|
|
/// to load implementations eagerly, are:
|
|
|
|
///
|
|
|
|
/// * Destructors (implementations of the Drop trait).
|
|
|
|
///
|
|
|
|
/// * Implementations of traits not defined in this crate.
|
2013-08-20 14:55:54 -07:00
|
|
|
fn encode_impls(ecx: &EncodeContext,
|
2014-02-05 22:15:24 +01:00
|
|
|
krate: &Crate,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder) {
|
2013-08-20 14:55:54 -07:00
|
|
|
ebml_w.start_tag(tag_impls);
|
|
|
|
|
|
|
|
{
|
|
|
|
let mut visitor = ImplVisitor {
|
|
|
|
ecx: ecx,
|
|
|
|
ebml_w: ebml_w,
|
|
|
|
};
|
2014-02-05 22:15:24 +01:00
|
|
|
visit::walk_crate(&mut visitor, krate, ());
|
2013-08-20 14:55:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-06-18 09:39:16 -07:00
|
|
|
fn encode_misc_info(ecx: &EncodeContext,
|
2014-02-05 22:15:24 +01:00
|
|
|
krate: &Crate,
|
2014-03-18 10:58:26 -07:00
|
|
|
ebml_w: &mut Encoder) {
|
2013-06-18 09:39:16 -07:00
|
|
|
ebml_w.start_tag(tag_misc_info);
|
|
|
|
ebml_w.start_tag(tag_misc_info_crate_items);
|
2014-02-05 22:15:24 +01:00
|
|
|
for &item in krate.module.items.iter() {
|
2013-06-18 09:39:16 -07:00
|
|
|
ebml_w.start_tag(tag_mod_child);
|
|
|
|
ebml_w.wr_str(def_to_str(local_def(item.id)));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
|
2013-11-21 15:42:55 -08:00
|
|
|
each_auxiliary_node_id(item, |auxiliary_node_id| {
|
2013-06-18 09:39:16 -07:00
|
|
|
ebml_w.start_tag(tag_mod_child);
|
|
|
|
ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id)));
|
|
|
|
ebml_w.end_tag();
|
2013-08-02 02:17:20 -04:00
|
|
|
true
|
2013-11-21 15:42:55 -08:00
|
|
|
});
|
2013-06-18 09:39:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Encode reexports for the root module.
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_reexports(ecx, ebml_w, 0, ast_map::Values([].iter()).chain(None));
|
2013-06-18 09:39:16 -07:00
|
|
|
|
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_crate_dep(ebml_w: &mut Encoder,
|
2013-08-31 18:13:04 +02:00
|
|
|
dep: decoder::CrateDep) {
|
2012-04-08 01:59:37 +08:00
|
|
|
ebml_w.start_tag(tag_crate_dep);
|
2014-02-24 18:13:51 -08:00
|
|
|
ebml_w.start_tag(tag_crate_dep_crateid);
|
|
|
|
ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
|
2012-04-08 01:59:37 +08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_crate_dep_hash);
|
2014-02-24 19:45:20 -08:00
|
|
|
ebml_w.writer.write(dep.hash.as_str().as_bytes());
|
2012-04-08 01:59:37 +08:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_hash(ebml_w: &mut Encoder, hash: &Svh) {
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_crate_hash);
|
2014-02-24 19:45:20 -08:00
|
|
|
ebml_w.writer.write(hash.as_str().as_bytes());
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2011-12-11 23:23:38 +08:00
|
|
|
}
|
|
|
|
|
2014-03-18 10:58:26 -07:00
|
|
|
fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
|
2014-02-24 18:13:51 -08:00
|
|
|
ebml_w.start_tag(tag_crate_crateid);
|
|
|
|
ebml_w.writer.write(crate_id.to_str().as_bytes());
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2012-09-05 15:27:22 -07:00
|
|
|
// NB: Increment this as you change the metadata encoding version.
|
2013-03-22 14:00:15 -07:00
|
|
|
pub static metadata_encoding_version : &'static [u8] =
|
2013-02-26 14:34:00 -05:00
|
|
|
&[0x72, //'r' as u8,
|
|
|
|
0x75, //'u' as u8,
|
|
|
|
0x73, //'s' as u8,
|
|
|
|
0x74, //'t' as u8,
|
|
|
|
0, 0, 0, 1 ];
|
2012-09-05 15:27:22 -07:00
|
|
|
|
2014-03-04 10:02:49 -08:00
|
|
|
pub fn encode_metadata(parms: EncodeParams, krate: &Crate) -> Vec<u8> {
|
2013-12-21 17:52:27 -08:00
|
|
|
let mut wr = MemWriter::new();
|
2014-02-05 22:15:24 +01:00
|
|
|
encode_metadata_inner(&mut wr, parms, krate);
|
2014-03-08 21:36:22 +01:00
|
|
|
wr.unwrap().move_iter().collect()
|
2014-01-03 16:28:26 -08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:15:24 +01:00
|
|
|
fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) {
|
2014-04-22 03:25:56 +03:00
|
|
|
struct Stats {
|
|
|
|
attr_bytes: u64,
|
|
|
|
dep_bytes: u64,
|
|
|
|
lang_item_bytes: u64,
|
|
|
|
native_lib_bytes: u64,
|
|
|
|
macro_registrar_fn_bytes: u64,
|
|
|
|
macro_defs_bytes: u64,
|
|
|
|
impl_bytes: u64,
|
|
|
|
misc_bytes: u64,
|
|
|
|
item_bytes: u64,
|
|
|
|
index_bytes: u64,
|
|
|
|
zero_bytes: u64,
|
|
|
|
total_bytes: u64,
|
|
|
|
}
|
|
|
|
let mut stats = Stats {
|
|
|
|
attr_bytes: 0,
|
|
|
|
dep_bytes: 0,
|
|
|
|
lang_item_bytes: 0,
|
|
|
|
native_lib_bytes: 0,
|
|
|
|
macro_registrar_fn_bytes: 0,
|
|
|
|
macro_defs_bytes: 0,
|
|
|
|
impl_bytes: 0,
|
|
|
|
misc_bytes: 0,
|
|
|
|
item_bytes: 0,
|
|
|
|
index_bytes: 0,
|
|
|
|
zero_bytes: 0,
|
|
|
|
total_bytes: 0,
|
2013-02-04 14:02:01 -08:00
|
|
|
};
|
2013-06-18 09:39:16 -07:00
|
|
|
let EncodeParams {
|
|
|
|
item_symbols,
|
|
|
|
diag,
|
|
|
|
tcx,
|
|
|
|
reexports2,
|
|
|
|
cstore,
|
|
|
|
encode_inlined_item,
|
|
|
|
link_meta,
|
2013-09-11 10:06:16 -07:00
|
|
|
non_inlineable_statics,
|
2013-11-28 12:22:53 -08:00
|
|
|
..
|
2013-06-18 09:39:16 -07:00
|
|
|
} = parms;
|
2013-06-13 19:19:50 +12:00
|
|
|
let ecx = EncodeContext {
|
2013-03-22 22:26:41 -04:00
|
|
|
diag: diag,
|
|
|
|
tcx: tcx,
|
|
|
|
reexports2: reexports2,
|
|
|
|
item_symbols: item_symbols,
|
2013-09-11 10:06:16 -07:00
|
|
|
non_inlineable_statics: non_inlineable_statics,
|
2013-03-22 22:26:41 -04:00
|
|
|
link_meta: link_meta,
|
|
|
|
cstore: cstore,
|
|
|
|
encode_inlined_item: encode_inlined_item,
|
2014-04-22 19:06:43 +03:00
|
|
|
type_abbrevs: RefCell::new(HashMap::new()),
|
2013-02-19 02:40:42 -05:00
|
|
|
};
|
2011-07-07 23:55:41 -07:00
|
|
|
|
2014-01-03 16:28:26 -08:00
|
|
|
let mut ebml_w = writer::Encoder(wr);
|
2011-06-27 15:20:17 -07:00
|
|
|
|
2014-02-24 18:13:51 -08:00
|
|
|
encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
|
2014-02-24 19:45:20 -08:00
|
|
|
encode_hash(&mut ebml_w, &ecx.link_meta.crate_hash);
|
2011-12-11 23:23:38 +08:00
|
|
|
|
2014-01-29 18:42:19 -08:00
|
|
|
let mut i = ebml_w.writer.tell().unwrap();
|
2014-02-05 22:15:24 +01:00
|
|
|
let crate_attrs = synthesize_crate_attrs(&ecx, krate);
|
2014-03-08 21:36:22 +01:00
|
|
|
encode_attributes(&mut ebml_w, crate_attrs.as_slice());
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
|
2011-07-08 11:29:56 -07:00
|
|
|
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2014-02-14 07:07:09 +02:00
|
|
|
encode_crate_deps(&mut ebml_w, ecx.cstore);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.dep_bytes = ebml_w.writer.tell().unwrap() - i;
|
2011-07-08 11:29:56 -07:00
|
|
|
|
2013-01-07 10:51:53 -08:00
|
|
|
// Encode the language items.
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2013-06-13 19:19:50 +12:00
|
|
|
encode_lang_items(&ecx, &mut ebml_w);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.lang_item_bytes = ebml_w.writer.tell().unwrap() - i;
|
2013-01-07 10:51:53 -08:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
// Encode the native libraries used
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
encode_native_libraries(&ecx, &mut ebml_w);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.native_lib_bytes = ebml_w.writer.tell().unwrap() - i;
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
|
2013-12-25 11:10:33 -07:00
|
|
|
// Encode the macro registrar function
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2013-12-25 11:10:33 -07:00
|
|
|
encode_macro_registrar_fn(&ecx, &mut ebml_w);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.macro_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i;
|
2013-12-25 11:10:33 -07:00
|
|
|
|
|
|
|
// Encode macro definitions
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2014-02-05 22:15:24 +01:00
|
|
|
encode_macro_defs(&ecx, krate, &mut ebml_w);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.macro_defs_bytes = ebml_w.writer.tell().unwrap() - i;
|
2013-12-25 11:10:33 -07:00
|
|
|
|
2013-08-20 14:55:54 -07:00
|
|
|
// Encode the def IDs of impls, for coherence checking.
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2014-02-05 22:15:24 +01:00
|
|
|
encode_impls(&ecx, krate, &mut ebml_w);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.impl_bytes = ebml_w.writer.tell().unwrap() - i;
|
2013-08-20 14:55:54 -07:00
|
|
|
|
2013-06-18 09:39:16 -07:00
|
|
|
// Encode miscellaneous info.
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2014-02-05 22:15:24 +01:00
|
|
|
encode_misc_info(&ecx, krate, &mut ebml_w);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.misc_bytes = ebml_w.writer.tell().unwrap() - i;
|
2013-06-18 09:39:16 -07:00
|
|
|
|
2012-01-11 15:15:54 +01:00
|
|
|
// Encode and index the items.
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.start_tag(tag_items);
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2014-02-05 22:15:24 +01:00
|
|
|
let items_index = encode_info_for_items(&ecx, &mut ebml_w, krate);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.item_bytes = ebml_w.writer.tell().unwrap() - i;
|
2012-08-27 16:53:54 -07:00
|
|
|
|
2014-01-29 18:42:19 -08:00
|
|
|
i = ebml_w.writer.tell().unwrap();
|
2014-04-22 19:06:43 +03:00
|
|
|
encode_index(&mut ebml_w, items_index, write_i64);
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.index_bytes = ebml_w.writer.tell().unwrap() - i;
|
2012-02-14 15:21:53 -08:00
|
|
|
ebml_w.end_tag();
|
2012-01-11 15:15:54 +01:00
|
|
|
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.total_bytes = ebml_w.writer.tell().unwrap();
|
2012-08-27 16:53:54 -07:00
|
|
|
|
2014-01-19 19:21:14 +11:00
|
|
|
if tcx.sess.meta_stats() {
|
2014-01-07 20:05:33 -08:00
|
|
|
for e in ebml_w.writer.get_ref().iter() {
|
2013-03-07 18:37:14 -05:00
|
|
|
if *e == 0 {
|
2014-04-22 03:25:56 +03:00
|
|
|
stats.zero_bytes += 1;
|
2012-08-27 16:53:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-09 21:06:55 +11:00
|
|
|
println!("metadata stats:");
|
2014-04-22 03:25:56 +03:00
|
|
|
println!(" attribute bytes: {}", stats.attr_bytes);
|
|
|
|
println!(" dep bytes: {}", stats.dep_bytes);
|
|
|
|
println!(" lang item bytes: {}", stats.lang_item_bytes);
|
|
|
|
println!(" native bytes: {}", stats.native_lib_bytes);
|
|
|
|
println!("macro registrar bytes: {}", stats.macro_registrar_fn_bytes);
|
|
|
|
println!(" macro def bytes: {}", stats.macro_defs_bytes);
|
|
|
|
println!(" impl bytes: {}", stats.impl_bytes);
|
|
|
|
println!(" misc bytes: {}", stats.misc_bytes);
|
|
|
|
println!(" item bytes: {}", stats.item_bytes);
|
|
|
|
println!(" index bytes: {}", stats.index_bytes);
|
|
|
|
println!(" zero bytes: {}", stats.zero_bytes);
|
|
|
|
println!(" total bytes: {}", stats.total_bytes);
|
2012-08-27 16:53:54 -07:00
|
|
|
}
|
2011-06-27 15:20:17 -07:00
|
|
|
}
|
2011-06-27 19:16:16 -07:00
|
|
|
|
2011-07-07 12:47:39 -07:00
|
|
|
// Get the encoded string for a type
|
2014-03-06 05:07:47 +02:00
|
|
|
pub fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> ~str {
|
2014-04-22 19:06:43 +03:00
|
|
|
let mut wr = MemWriter::new();
|
|
|
|
tyencode::enc_ty(&mut wr, &tyencode::ctxt {
|
2014-03-16 20:56:24 +02:00
|
|
|
diag: tcx.sess.diagnostic(),
|
2013-01-08 14:00:45 -08:00
|
|
|
ds: def_to_str,
|
|
|
|
tcx: tcx,
|
2014-04-22 19:06:43 +03:00
|
|
|
abbrevs: &RefCell::new(HashMap::new())
|
|
|
|
}, t);
|
2013-12-23 17:45:01 +01:00
|
|
|
str::from_utf8_owned(wr.get_ref().to_owned()).unwrap()
|
2011-07-07 12:47:39 -07:00
|
|
|
}
|