Skip to content

Commit 84f5ad8

Browse files
committed
auto merge of #20307 : nikomatsakis/rust/assoc-types-normalization-extend-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
2 parents 023dfb0 + e186acc commit 84f5ad8

File tree

129 files changed

+5519
-3108
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+5519
-3108
lines changed

src/librustc/metadata/common.rs

+3
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,6 @@ pub const tag_predicate_space: uint = 0xa9;
256256
pub const tag_predicate_data: uint = 0xb0;
257257

258258
pub const tag_unsafety: uint = 0xb1;
259+
260+
pub const tag_associated_type_names: uint = 0xb2;
261+
pub const tag_associated_type_name: uint = 0xb3;

src/librustc/metadata/csearch.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: ast::DefId) -> HashM
226226

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

241241
pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
242-
def: ast::DefId) -> ty::Polytype<'tcx> {
242+
def: ast::DefId) -> ty::TypeScheme<'tcx> {
243243
let cstore = &tcx.sess.cstore;
244244
let cdata = cstore.get_crate_data(class_id.krate);
245245
let all_items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
@@ -257,7 +257,7 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
257257
def)).to_string()
258258
});
259259
let ty = decoder::item_type(def, the_field, tcx, &*cdata);
260-
ty::Polytype {
260+
ty::TypeScheme {
261261
generics: ty::Generics::empty(),
262262
ty: ty,
263263
}

src/librustc/metadata/decoder.rs

+27-13
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,15 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
172172
}
173173

174174
fn item_sort(item: rbml::Doc) -> char {
175-
// NB(pcwalton): The default of 'r' here is relied upon in
176-
// `is_associated_type` below.
177-
let mut ret = 'r';
175+
let mut ret = None;
178176
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
179-
ret = doc.as_str_slice().as_bytes()[0] as char;
177+
ret = Some(doc.as_str_slice().as_bytes()[0] as char);
180178
false
181179
});
182-
ret
180+
match ret {
181+
Some(r) => r,
182+
None => panic!("No item_sort found")
183+
}
183184
}
184185

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

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

253254
fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
254-
-> ty::TraitRef<'tcx> {
255+
-> Rc<ty::TraitRef<'tcx>> {
255256
let tp = reader::get_doc(doc, tag_item_trait_ref);
256257
doc_trait_ref(tp, tcx, cdata)
257258
}
@@ -369,6 +370,17 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
369370
}
370371
}
371372

373+
fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
374+
let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
375+
let mut names = Vec::new();
376+
reader::tagged_docs(names_doc, tag_associated_type_name, |name_doc| {
377+
let name = token::intern(name_doc.as_str_slice());
378+
names.push(name);
379+
true
380+
});
381+
names
382+
}
383+
372384
pub fn get_trait_def<'tcx>(cdata: Cmd,
373385
item_id: ast::NodeId,
374386
tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
@@ -377,17 +389,19 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
377389
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
378390
let bounds = trait_def_bounds(item_doc, tcx, cdata);
379391
let unsafety = parse_unsafety(item_doc);
392+
let associated_type_names = parse_associated_type_names(item_doc);
380393

381394
ty::TraitDef {
382395
unsafety: unsafety,
383396
generics: generics,
384397
bounds: bounds,
385-
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
398+
trait_ref: item_trait_ref(item_doc, tcx, cdata),
399+
associated_type_names: associated_type_names,
386400
}
387401
}
388402

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

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

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

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

399-
ty::Polytype {
413+
ty::TypeScheme {
400414
generics: generics,
401415
ty: t
402416
}
@@ -428,7 +442,7 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
428442
{
429443
let item_doc = lookup_item(id, cdata.data());
430444
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
431-
Rc::new(doc_trait_ref(tp, tcx, cdata))
445+
doc_trait_ref(tp, tcx, cdata)
432446
})
433447
}
434448

@@ -924,7 +938,7 @@ pub fn get_supertraits<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
924938
// FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
925939
let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
926940
if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
927-
results.push(Rc::new(trait_ref));
941+
results.push(trait_ref);
928942
}
929943
true
930944
});
@@ -1353,7 +1367,7 @@ pub fn get_dylib_dependency_formats(cdata: Cmd)
13531367
if spec.len() == 0 { continue }
13541368
let cnum = spec.split(':').nth(0).unwrap();
13551369
let link = spec.split(':').nth(1).unwrap();
1356-
let cnum = cnum.parse().unwrap();
1370+
let cnum: ast::CrateNum = cnum.parse().unwrap();
13571371
let cnum = match cdata.cnum_map.get(&cnum) {
13581372
Some(&n) => n,
13591373
None => panic!("didn't find a crate in the cnum_map")

src/librustc/metadata/encoder.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fn encode_item_variances(rbml_w: &mut Encoder,
142142

143143
fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
144144
ecx: &EncodeContext<'a, 'tcx>,
145-
pty: &ty::Polytype<'tcx>) {
145+
pty: &ty::TypeScheme<'tcx>) {
146146
encode_generics(rbml_w, ecx, &pty.generics, tag_item_generics);
147147
encode_type(ecx, rbml_w, pty.ty);
148148
}
@@ -898,7 +898,10 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
898898
encode_visibility(rbml_w, associated_type.vis);
899899
encode_family(rbml_w, 'y');
900900
encode_parent_item(rbml_w, local_def(parent_id));
901-
encode_item_sort(rbml_w, 'r');
901+
encode_item_sort(rbml_w, 't');
902+
903+
let type_scheme = ty::lookup_item_type(ecx.tcx, associated_type.def_id);
904+
encode_bounds_and_type(rbml_w, ecx, &type_scheme);
902905

903906
let stab = stability::lookup(ecx.tcx, associated_type.def_id);
904907
encode_stability(rbml_w, stab);
@@ -1316,6 +1319,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
13161319
encode_item_variances(rbml_w, ecx, item.id);
13171320
let trait_def = ty::lookup_trait_def(tcx, def_id);
13181321
encode_unsafety(rbml_w, trait_def.unsafety);
1322+
encode_associated_type_names(rbml_w, trait_def.associated_type_names.as_slice());
13191323
encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
13201324
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
13211325
encode_name(rbml_w, item.ident.name);
@@ -1397,10 +1401,13 @@ fn encode_info_for_item(ecx: &EncodeContext,
13971401
ty::StaticExplicitSelfCategory;
13981402
}
13991403
ty::TypeTraitItem(associated_type) => {
1404+
encode_name(rbml_w, associated_type.name);
1405+
14001406
let elem = ast_map::PathName(associated_type.name);
14011407
encode_path(rbml_w,
14021408
path.clone().chain(Some(elem).into_iter()));
14031409

1410+
encode_item_sort(rbml_w, 't');
14041411
encode_family(rbml_w, 'y');
14051412

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

1699+
fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
1700+
rbml_w.start_tag(tag_associated_type_names);
1701+
for &name in names.iter() {
1702+
rbml_w.wr_tagged_str(tag_associated_type_name, token::get_name(name).get());
1703+
}
1704+
rbml_w.end_tag();
1705+
}
1706+
16921707
fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
16931708
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
16941709
// Pull the cnums and name,vers,hash out of cstore

0 commit comments

Comments
 (0)