Skip to content

Commit

Permalink
auto merge of #20307 : nikomatsakis/rust/assoc-types-normalization-ex…
Browse files Browse the repository at this point in the history
…tend-bound, r=nrc

Rewrite associated types to use projection rather than dummy type parameters. This closes almost every (major) open issue, but I'm holding off on that until the code has landed and baked a bit. Probably it should have more tests, as well, but I wanted to get this landed as fast as possible so that we can collaborate on improving it.

The commit history is a little messy, particularly the merge commit at the end. If I get some time, I might just "reset" to the beginning and try to carve up the final state into logical pieces. Let me know if it seems hard to follow. By far the most crucial commit is "Implement associated type projection and normalization."

r? @nick29581
  • Loading branch information
bors committed Dec 30, 2014
2 parents 023dfb0 + e186acc commit 84f5ad8
Show file tree
Hide file tree
Showing 129 changed files with 5,519 additions and 3,108 deletions.
3 changes: 3 additions & 0 deletions src/librustc/metadata/common.rs
Expand Up @@ -256,3 +256,6 @@ pub const tag_predicate_space: uint = 0xa9;
pub const tag_predicate_data: uint = 0xb0;

pub const tag_unsafety: uint = 0xb1;

pub const tag_associated_type_names: uint = 0xb2;
pub const tag_associated_type_name: uint = 0xb3;
6 changes: 3 additions & 3 deletions src/librustc/metadata/csearch.rs
Expand Up @@ -226,7 +226,7 @@ pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: ast::DefId) -> HashM

pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> ty::Polytype<'tcx> {
-> ty::TypeScheme<'tcx> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_type(&*cdata, def.node, tcx)
Expand All @@ -239,7 +239,7 @@ pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> ty::TraitDe
}

pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
def: ast::DefId) -> ty::Polytype<'tcx> {
def: ast::DefId) -> ty::TypeScheme<'tcx> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(class_id.krate);
let all_items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
Expand All @@ -257,7 +257,7 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
def)).to_string()
});
let ty = decoder::item_type(def, the_field, tcx, &*cdata);
ty::Polytype {
ty::TypeScheme {
generics: ty::Generics::empty(),
ty: ty,
}
Expand Down
40 changes: 27 additions & 13 deletions src/librustc/metadata/decoder.rs
Expand Up @@ -172,14 +172,15 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
}

fn item_sort(item: rbml::Doc) -> char {
// NB(pcwalton): The default of 'r' here is relied upon in
// `is_associated_type` below.
let mut ret = 'r';
let mut ret = None;
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
ret = doc.as_str_slice().as_bytes()[0] as char;
ret = Some(doc.as_str_slice().as_bytes()[0] as char);
false
});
ret
match ret {
Some(r) => r,
None => panic!("No item_sort found")
}
}

fn item_symbol(item: rbml::Doc) -> String {
Expand Down Expand Up @@ -245,13 +246,13 @@ pub fn item_type<'tcx>(_item_id: ast::DefId, item: rbml::Doc,
}

fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-> ty::TraitRef<'tcx> {
-> Rc<ty::TraitRef<'tcx>> {
parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx,
|_, did| translate_def_id(cdata, did))
}

fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-> ty::TraitRef<'tcx> {
-> Rc<ty::TraitRef<'tcx>> {
let tp = reader::get_doc(doc, tag_item_trait_ref);
doc_trait_ref(tp, tcx, cdata)
}
Expand Down Expand Up @@ -369,6 +370,17 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
}
}

fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
let mut names = Vec::new();
reader::tagged_docs(names_doc, tag_associated_type_name, |name_doc| {
let name = token::intern(name_doc.as_str_slice());
names.push(name);
true
});
names
}

pub fn get_trait_def<'tcx>(cdata: Cmd,
item_id: ast::NodeId,
tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
Expand All @@ -377,17 +389,19 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
let bounds = trait_def_bounds(item_doc, tcx, cdata);
let unsafety = parse_unsafety(item_doc);
let associated_type_names = parse_associated_type_names(item_doc);

ty::TraitDef {
unsafety: unsafety,
generics: generics,
bounds: bounds,
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
trait_ref: item_trait_ref(item_doc, tcx, cdata),
associated_type_names: associated_type_names,
}
}

pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
-> ty::Polytype<'tcx> {
-> ty::TypeScheme<'tcx> {

let item = lookup_item(id, cdata.data());

Expand All @@ -396,7 +410,7 @@ pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)

let generics = doc_generics(item, tcx, cdata, tag_item_generics);

ty::Polytype {
ty::TypeScheme {
generics: generics,
ty: t
}
Expand Down Expand Up @@ -428,7 +442,7 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
{
let item_doc = lookup_item(id, cdata.data());
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
Rc::new(doc_trait_ref(tp, tcx, cdata))
doc_trait_ref(tp, tcx, cdata)
})
}

Expand Down Expand Up @@ -924,7 +938,7 @@ pub fn get_supertraits<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
// FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
results.push(Rc::new(trait_ref));
results.push(trait_ref);
}
true
});
Expand Down Expand Up @@ -1353,7 +1367,7 @@ pub fn get_dylib_dependency_formats(cdata: Cmd)
if spec.len() == 0 { continue }
let cnum = spec.split(':').nth(0).unwrap();
let link = spec.split(':').nth(1).unwrap();
let cnum = cnum.parse().unwrap();
let cnum: ast::CrateNum = cnum.parse().unwrap();
let cnum = match cdata.cnum_map.get(&cnum) {
Some(&n) => n,
None => panic!("didn't find a crate in the cnum_map")
Expand Down
19 changes: 17 additions & 2 deletions src/librustc/metadata/encoder.rs
Expand Up @@ -142,7 +142,7 @@ fn encode_item_variances(rbml_w: &mut Encoder,

fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>,
pty: &ty::Polytype<'tcx>) {
pty: &ty::TypeScheme<'tcx>) {
encode_generics(rbml_w, ecx, &pty.generics, tag_item_generics);
encode_type(ecx, rbml_w, pty.ty);
}
Expand Down Expand Up @@ -898,7 +898,10 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
encode_visibility(rbml_w, associated_type.vis);
encode_family(rbml_w, 'y');
encode_parent_item(rbml_w, local_def(parent_id));
encode_item_sort(rbml_w, 'r');
encode_item_sort(rbml_w, 't');

let type_scheme = ty::lookup_item_type(ecx.tcx, associated_type.def_id);
encode_bounds_and_type(rbml_w, ecx, &type_scheme);

let stab = stability::lookup(ecx.tcx, associated_type.def_id);
encode_stability(rbml_w, stab);
Expand Down Expand Up @@ -1316,6 +1319,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_item_variances(rbml_w, ecx, item.id);
let trait_def = ty::lookup_trait_def(tcx, def_id);
encode_unsafety(rbml_w, trait_def.unsafety);
encode_associated_type_names(rbml_w, trait_def.associated_type_names.as_slice());
encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
encode_name(rbml_w, item.ident.name);
Expand Down Expand Up @@ -1397,10 +1401,13 @@ fn encode_info_for_item(ecx: &EncodeContext,
ty::StaticExplicitSelfCategory;
}
ty::TypeTraitItem(associated_type) => {
encode_name(rbml_w, associated_type.name);

let elem = ast_map::PathName(associated_type.name);
encode_path(rbml_w,
path.clone().chain(Some(elem).into_iter()));

encode_item_sort(rbml_w, 't');
encode_family(rbml_w, 'y');

is_nonstatic_method = false;
Expand Down Expand Up @@ -1689,6 +1696,14 @@ fn encode_unsafety(rbml_w: &mut Encoder, unsafety: ast::Unsafety) {
rbml_w.wr_tagged_u8(tag_unsafety, byte);
}

fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
rbml_w.start_tag(tag_associated_type_names);
for &name in names.iter() {
rbml_w.wr_tagged_str(tag_associated_type_name, token::get_name(name).get());
}
rbml_w.end_tag();
}

fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
// Pull the cnums and name,vers,hash out of cstore
Expand Down

0 comments on commit 84f5ad8

Please sign in to comment.