Skip to content

Commit 92e265c

Browse files
committed
auto merge of #5802 : nikomatsakis/rust/issue-4183-trait-substs, r=nikomatsakis
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. r? @catamorphism
2 parents 5e570ce + e8cd29b commit 92e265c

32 files changed

+1253
-620
lines changed

src/librustc/metadata/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
127127
tag_table_node_type_subst = 0x58,
128128
tag_table_freevars = 0x59,
129129
tag_table_tcache = 0x5a,
130-
tag_table_param_bounds = 0x5b,
130+
tag_table_param_defs = 0x5b,
131131
tag_table_inferred_modes = 0x5c,
132132
tag_table_mutbl = 0x5d,
133133
tag_table_last_use = 0x5e,

src/librustc/metadata/csearch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
210210
debug!("got field data %?", the_field);
211211
let ty = decoder::item_type(def, the_field, tcx, cdata);
212212
ty::ty_param_bounds_and_ty {
213-
generics: ty::Generics {bounds: @~[],
213+
generics: ty::Generics {type_param_defs: @~[],
214214
region_param: None},
215215
ty: ty
216216
}

src/librustc/metadata/decoder.rs

+21-19
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use metadata::csearch::{ProvidedTraitMethodInfo, StaticMethodInfo};
1919
use metadata::csearch;
2020
use metadata::cstore;
2121
use metadata::decoder;
22-
use metadata::tydecode::{parse_ty_data, parse_def_id, parse_bounds_data,
22+
use metadata::tydecode::{parse_ty_data, parse_def_id,
23+
parse_type_param_def_data,
2324
parse_bare_fn_ty_data, parse_trait_ref_data};
2425
use middle::{ty, resolve};
2526

@@ -266,13 +267,14 @@ fn item_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
266267
doc_trait_ref(tp, tcx, cdata)
267268
}
268269
269-
fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd,
270-
tag: uint)
271-
-> @~[ty::param_bounds] {
270+
fn item_ty_param_defs(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd,
271+
tag: uint)
272+
-> @~[ty::TypeParameterDef] {
272273
let mut bounds = ~[];
273274
for reader::tagged_docs(item, tag) |p| {
274-
let bd = parse_bounds_data(p.data, p.start, cdata.cnum, tcx,
275-
|_, did| translate_def_id(cdata, did));
275+
let bd = parse_type_param_def_data(
276+
p.data, p.start, cdata.cnum, tcx,
277+
|_, did| translate_def_id(cdata, did));
276278
bounds.push(bd);
277279
}
278280
@bounds
@@ -378,11 +380,11 @@ pub fn get_trait_def(cdata: cmd,
378380
tcx: ty::ctxt) -> ty::TraitDef
379381
{
380382
let item_doc = lookup_item(item_id, cdata.data);
381-
let tp_bounds = item_ty_param_bounds(item_doc, tcx, cdata,
382-
tag_items_data_item_ty_param_bounds);
383+
let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
384+
tag_items_data_item_ty_param_bounds);
383385
let rp = item_ty_region_param(item_doc);
384386
ty::TraitDef {
385-
generics: ty::Generics {bounds: tp_bounds,
387+
generics: ty::Generics {type_param_defs: tp_defs,
386388
region_param: rp},
387389
trait_ref: @item_trait_ref(item_doc, tcx, cdata)
388390
}
@@ -394,12 +396,12 @@ pub fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
394396
let item = lookup_item(id, cdata.data);
395397
let t = item_type(ast::def_id { crate: cdata.cnum, node: id }, item, tcx,
396398
cdata);
397-
let tp_bounds = if family_has_type_params(item_family(item)) {
398-
item_ty_param_bounds(item, tcx, cdata, tag_items_data_item_ty_param_bounds)
399+
let tp_defs = if family_has_type_params(item_family(item)) {
400+
item_ty_param_defs(item, tcx, cdata, tag_items_data_item_ty_param_bounds)
399401
} else { @~[] };
400402
let rp = item_ty_region_param(item);
401403
ty::ty_param_bounds_and_ty {
402-
generics: ty::Generics {bounds: tp_bounds,
404+
generics: ty::Generics {type_param_defs: tp_defs,
403405
region_param: rp},
404406
ty: t
405407
}
@@ -753,17 +755,16 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
753755
let method_doc = lookup_item(id, cdata.data);
754756
let def_id = item_def_id(method_doc, cdata);
755757
let name = item_name(intr, method_doc);
756-
let bounds =
757-
item_ty_param_bounds(method_doc, tcx, cdata,
758-
tag_item_method_tps);
758+
let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
759+
tag_item_method_tps);
759760
let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
760761
let fty = doc_method_fty(method_doc, tcx, cdata);
761762
let vis = item_visibility(method_doc);
762763
let self_ty = get_self_ty(method_doc);
763764
ty::method {
764765
ident: name,
765766
generics: ty::Generics {
766-
bounds: bounds,
767+
type_param_defs: type_param_defs,
767768
region_param: None
768769
},
769770
transformed_self_ty: transformed_self_ty,
@@ -797,8 +798,9 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
797798

798799
let did = item_def_id(mth, cdata);
799800

800-
let bounds = item_ty_param_bounds(mth, tcx, cdata,
801-
tag_items_data_item_ty_param_bounds);
801+
let type_param_defs =
802+
item_ty_param_defs(mth, tcx, cdata,
803+
tag_items_data_item_ty_param_bounds);
802804
let name = item_name(intr, mth);
803805
let ty = doc_type(mth, tcx, cdata);
804806

@@ -815,7 +817,7 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
815817
let ty_method = ty::method {
816818
ident: name,
817819
generics: ty::Generics {
818-
bounds: bounds,
820+
type_param_defs: type_param_defs,
819821
region_param: None
820822
},
821823
transformed_self_ty: transformed_self_ty,

src/librustc/metadata/encoder.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@ fn encode_family(ebml_w: writer::Encoder, c: char) {
179179

180180
pub fn def_to_str(did: def_id) -> ~str { fmt!("%d:%d", did.crate, did.node) }
181181

182-
fn encode_ty_type_param_bounds(ebml_w: writer::Encoder,
183-
ecx: @EncodeContext,
184-
params: @~[ty::param_bounds],
185-
tag: uint) {
182+
fn encode_ty_type_param_defs(ebml_w: writer::Encoder,
183+
ecx: @EncodeContext,
184+
params: @~[ty::TypeParameterDef],
185+
tag: uint) {
186186
let ty_str_ctxt = @tyencode::ctxt {
187187
diag: ecx.diag,
188188
ds: def_to_str,
@@ -191,18 +191,18 @@ fn encode_ty_type_param_bounds(ebml_w: writer::Encoder,
191191
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
192192
for params.each |param| {
193193
ebml_w.start_tag(tag);
194-
tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, *param);
194+
tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param);
195195
ebml_w.end_tag();
196196
}
197197
}
198198

199199
fn encode_type_param_bounds(ebml_w: writer::Encoder,
200200
ecx: @EncodeContext,
201201
params: &OptVec<TyParam>) {
202-
let ty_param_bounds =
203-
@params.map_to_vec(|param| *ecx.tcx.ty_param_bounds.get(&param.id));
204-
encode_ty_type_param_bounds(ebml_w, ecx, ty_param_bounds,
205-
tag_items_data_item_ty_param_bounds);
202+
let ty_param_defs =
203+
@params.map_to_vec(|param| *ecx.tcx.ty_param_defs.get(&param.id));
204+
encode_ty_type_param_defs(ebml_w, ecx, ty_param_defs,
205+
tag_items_data_item_ty_param_bounds);
206206
}
207207

208208

@@ -588,8 +588,9 @@ fn encode_method_ty_fields(ecx: @EncodeContext,
588588
{
589589
encode_def_id(ebml_w, method_ty.def_id);
590590
encode_name(ecx, ebml_w, method_ty.ident);
591-
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.generics.bounds,
592-
tag_item_method_tps);
591+
encode_ty_type_param_defs(ebml_w, ecx,
592+
method_ty.generics.type_param_defs,
593+
tag_item_method_tps);
593594
encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
594595
encode_method_fty(ecx, ebml_w, &method_ty.fty);
595596
encode_visibility(ebml_w, method_ty.vis);
@@ -952,8 +953,9 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
952953
method_ty.fty.purity));
953954
954955
let tpt = ty::lookup_item_type(tcx, method_def_id);
955-
encode_ty_type_param_bounds(ebml_w, ecx, tpt.generics.bounds,
956-
tag_items_data_item_ty_param_bounds);
956+
encode_ty_type_param_defs(ebml_w, ecx,
957+
tpt.generics.type_param_defs,
958+
tag_items_data_item_ty_param_bounds);
957959
encode_type(ecx, ebml_w, tpt.ty);
958960
}
959961

src/librustc/metadata/tydecode.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -547,11 +547,17 @@ pub fn parse_def_id(buf: &[u8]) -> ast::def_id {
547547
ast::def_id { crate: crate_num, node: def_num }
548548
}
549549
550-
pub fn parse_bounds_data(data: @~[u8], start: uint,
551-
crate_num: int, tcx: ty::ctxt, conv: conv_did)
552-
-> @~[ty::param_bound] {
550+
pub fn parse_type_param_def_data(data: @~[u8], start: uint,
551+
crate_num: int, tcx: ty::ctxt,
552+
conv: conv_did) -> ty::TypeParameterDef
553+
{
553554
let st = parse_state_from_data(data, crate_num, start, tcx);
554-
parse_bounds(st, conv)
555+
parse_type_param_def(st, conv)
556+
}
557+
558+
fn parse_type_param_def(st: @mut PState, conv: conv_did) -> ty::TypeParameterDef {
559+
ty::TypeParameterDef {def_id: parse_def(st, NominalType, conv),
560+
bounds: parse_bounds(st, conv)}
555561
}
556562
557563
fn parse_bounds(st: @mut PState, conv: conv_did) -> @~[ty::param_bound] {

src/librustc/metadata/tyencode.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) {
412412
enc_ty(w, cx, fsig.output);
413413
}
414414

415-
pub fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) {
415+
fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) {
416416
for vec::each(*bs) |bound| {
417417
match *bound {
418418
ty::bound_owned => w.write_char('S'),
@@ -428,6 +428,12 @@ pub fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) {
428428
w.write_char('.');
429429
}
430430

431+
pub fn enc_type_param_def(w: @io::Writer, cx: @ctxt, v: &ty::TypeParameterDef) {
432+
w.write_str((cx.ds)(v.def_id));
433+
w.write_char('|');
434+
enc_bounds(w, cx, v.bounds);
435+
}
436+
431437
//
432438
// Local Variables:
433439
// mode: rust

src/librustc/middle/astencode.rs

+24-18
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,9 @@ trait ebml_writer_helpers {
741741
fn emit_ty(&self, ecx: @e::EncodeContext, ty: ty::t);
742742
fn emit_vstore(&self, ecx: @e::EncodeContext, vstore: ty::vstore);
743743
fn emit_tys(&self, ecx: @e::EncodeContext, tys: ~[ty::t]);
744-
fn emit_bounds(&self, ecx: @e::EncodeContext, bs: ty::param_bounds);
744+
fn emit_type_param_def(&self,
745+
ecx: @e::EncodeContext,
746+
type_param_def: &ty::TypeParameterDef);
745747
fn emit_tpbt(&self, ecx: @e::EncodeContext,
746748
tpbt: ty::ty_param_bounds_and_ty);
747749
}
@@ -771,9 +773,12 @@ impl ebml_writer_helpers for writer::Encoder {
771773
}
772774
}
773775
774-
fn emit_bounds(&self, ecx: @e::EncodeContext, bs: ty::param_bounds) {
776+
fn emit_type_param_def(&self,
777+
ecx: @e::EncodeContext,
778+
type_param_def: &ty::TypeParameterDef) {
775779
do self.emit_opaque {
776-
tyencode::enc_bounds(self.writer, ecx.ty_str_ctxt(), bs)
780+
tyencode::enc_type_param_def(self.writer, ecx.ty_str_ctxt(),
781+
type_param_def)
777782
}
778783
}
779784
@@ -782,9 +787,11 @@ impl ebml_writer_helpers for writer::Encoder {
782787
do self.emit_struct("ty_param_bounds_and_ty", 2) {
783788
do self.emit_field(~"generics", 0) {
784789
do self.emit_struct("Generics", 2) {
785-
do self.emit_field(~"bounds", 0) {
786-
do self.emit_from_vec(*tpbt.generics.bounds) |bs| {
787-
self.emit_bounds(ecx, *bs);
790+
do self.emit_field(~"type_param_defs", 0) {
791+
do self.emit_from_vec(*tpbt.generics.type_param_defs)
792+
|type_param_def|
793+
{
794+
self.emit_type_param_def(ecx, type_param_def);
788795
}
789796
}
790797
do self.emit_field(~"region_param", 1) {
@@ -889,11 +896,11 @@ fn encode_side_tables_for_id(ecx: @e::EncodeContext,
889896
}
890897
}
891898
892-
for tcx.ty_param_bounds.find(&id).each |&pbs| {
893-
do ebml_w.tag(c::tag_table_param_bounds) {
899+
for tcx.ty_param_defs.find(&id).each |&type_param_def| {
900+
do ebml_w.tag(c::tag_table_param_defs) {
894901
ebml_w.id(id);
895902
do ebml_w.tag(c::tag_table_val) {
896-
ebml_w.emit_bounds(ecx, *pbs)
903+
ebml_w.emit_type_param_def(ecx, type_param_def)
897904
}
898905
}
899906
}
@@ -990,7 +997,7 @@ trait ebml_decoder_decoder_helpers {
990997
fn read_arg(&self, xcx: @ExtendedDecodeContext) -> ty::arg;
991998
fn read_ty(&self, xcx: @ExtendedDecodeContext) -> ty::t;
992999
fn read_tys(&self, xcx: @ExtendedDecodeContext) -> ~[ty::t];
993-
fn read_bounds(&self, xcx: @ExtendedDecodeContext) -> @~[ty::param_bound];
1000+
fn read_type_param_def(&self, xcx: @ExtendedDecodeContext) -> ty::TypeParameterDef;
9941001
fn read_ty_param_bounds_and_ty(&self, xcx: @ExtendedDecodeContext)
9951002
-> ty::ty_param_bounds_and_ty;
9961003
fn convert_def_id(&self, xcx: @ExtendedDecodeContext,
@@ -1038,10 +1045,9 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
10381045
self.read_to_vec(|| self.read_ty(xcx) )
10391046
}
10401047
1041-
fn read_bounds(&self, xcx: @ExtendedDecodeContext)
1042-
-> @~[ty::param_bound] {
1048+
fn read_type_param_def(&self, xcx: @ExtendedDecodeContext) -> ty::TypeParameterDef {
10431049
do self.read_opaque |doc| {
1044-
tydecode::parse_bounds_data(
1050+
tydecode::parse_type_param_def_data(
10451051
doc.data, doc.start, xcx.dcx.cdata.cnum, xcx.dcx.tcx,
10461052
|s, a| self.convert_def_id(xcx, s, a))
10471053
}
@@ -1054,8 +1060,8 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
10541060
ty::ty_param_bounds_and_ty {
10551061
generics: do self.read_struct("Generics", 2) {
10561062
ty::Generics {
1057-
bounds: self.read_field(~"bounds", 0, || {
1058-
@self.read_to_vec(|| self.read_bounds(xcx) )
1063+
type_param_defs: self.read_field("type_param_defs", 0, || {
1064+
@self.read_to_vec(|| self.read_type_param_def(xcx))
10591065
}),
10601066
region_param: self.read_field(~"region_param", 1, || {
10611067
Decodable::decode(self)
@@ -1134,9 +1140,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
11341140
let tpbt = val_dsr.read_ty_param_bounds_and_ty(xcx);
11351141
let lid = ast::def_id { crate: ast::local_crate, node: id };
11361142
dcx.tcx.tcache.insert(lid, tpbt);
1137-
} else if tag == (c::tag_table_param_bounds as uint) {
1138-
let bounds = val_dsr.read_bounds(xcx);
1139-
dcx.tcx.ty_param_bounds.insert(id, bounds);
1143+
} else if tag == (c::tag_table_param_defs as uint) {
1144+
let bounds = val_dsr.read_type_param_def(xcx);
1145+
dcx.tcx.ty_param_defs.insert(id, bounds);
11401146
} else if tag == (c::tag_table_last_use as uint) {
11411147
let ids = val_dsr.read_to_vec(|| {
11421148
xcx.tr_id(val_dsr.read_int())

src/librustc/middle/borrowck/gather_loans.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use middle::pat_util;
2929
use middle::ty::{ty_region};
3030
use middle::ty;
3131
use util::common::indenter;
32-
use util::ppaux::{expr_repr, region_to_str};
32+
use util::ppaux::{Repr, region_to_str};
3333

3434
use core::hashmap::{HashSet, HashMap};
3535
use core::vec;
@@ -282,7 +282,7 @@ pub impl GatherLoanCtxt {
282282
expr: @ast::expr,
283283
adjustment: &ty::AutoAdjustment) {
284284
debug!("guarantee_adjustments(expr=%s, adjustment=%?)",
285-
expr_repr(self.tcx(), expr), adjustment);
285+
expr.repr(self.tcx()), adjustment);
286286
let _i = indenter();
287287

288288
match *adjustment {

0 commit comments

Comments
 (0)