Skip to content

Commit e7f11f2

Browse files
committed
auto merge of #14604 : nikomatsakis/rust/issue-5527-namespace-substs, r=pcwalton
The current setup is to have a single vector of type parameters in scope at any one time. We then have to concatenate the parameters from the impl/trait with those of the method. This makes a lot of things awkward, most notably associated fns ("static fns"). This branch restructures the substitutions into three distinct namespaces (type, self, fn). This makes most of the "type parameter management" trivial. This also sets us up to support UFCS (though I haven't made any particular changes in that direction in this patch). Along the way, this patch fixes a few miscellaneous bits of code cleanup: 1. Patch resolve to detect references to out-of-scope type parameters, rather than checking for "out of bound" indices during substitution (fixes #14603). 2. Move def out of libsyntax into librustc where it belongs. I should have moved DefId too, but didn't. 3. Permit homogeneous tuples like `(T, T, T)` to be used as fixed-length vectors like `[T, ..3]`. This is awfully handy, though public facing. I suppose it requires an RFC. 4. Add some missing tests. cc #5527 r? @pcwalton or @pnkfelix
2 parents 0422934 + 9153d8a commit e7f11f2

Some content is hidden

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

49 files changed

+2571
-2226
lines changed

src/librustc/metadata/common.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,7 @@ pub static tag_impls_impl: uint = 0x81;
189189
pub static tag_items_data_item_inherent_impl: uint = 0x82;
190190
pub static tag_items_data_item_extension_impl: uint = 0x83;
191191

192-
pub static tag_region_param_def: uint = 0x84;
193-
pub static tag_region_param_def_ident: uint = 0x85;
194-
pub static tag_region_param_def_def_id: uint = 0x86;
192+
// GAP 0x84, 0x85, 0x86
195193

196194
pub static tag_native_libraries: uint = 0x87;
197195
pub static tag_native_libraries_lib: uint = 0x88;
@@ -217,3 +215,9 @@ pub struct LinkMeta {
217215
pub crateid: CrateId,
218216
pub crate_hash: Svh,
219217
}
218+
219+
pub static tag_region_param_def: uint = 0x90;
220+
pub static tag_region_param_def_ident: uint = 0x91;
221+
pub static tag_region_param_def_def_id: uint = 0x92;
222+
pub static tag_region_param_def_space: uint = 0x93;
223+
pub static tag_region_param_def_index: uint = 0x94;

src/librustc/metadata/csearch.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use metadata::decoder;
1818
use middle::lang_items;
1919
use middle::ty;
2020
use middle::typeck;
21+
use middle::subst::VecPerParamSpace;
2122

2223
use serialize::ebml;
2324
use serialize::ebml::reader;
@@ -223,8 +224,8 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,
223224
});
224225
let ty = decoder::item_type(def, the_field, tcx, &*cdata);
225226
ty::ty_param_bounds_and_ty {
226-
generics: ty::Generics {type_param_defs: Rc::new(Vec::new()),
227-
region_param_defs: Rc::new(Vec::new())},
227+
generics: ty::Generics {types: VecPerParamSpace::empty(),
228+
regions: VecPerParamSpace::empty()},
228229
ty: ty
229230
}
230231
}
@@ -240,7 +241,8 @@ pub fn get_impl_trait(tcx: &ty::ctxt,
240241

241242
// Given a def_id for an impl, return information about its vtables
242243
pub fn get_impl_vtables(tcx: &ty::ctxt,
243-
def: ast::DefId) -> typeck::impl_res {
244+
def: ast::DefId)
245+
-> typeck::vtable_res {
244246
let cstore = &tcx.sess.cstore;
245247
let cdata = cstore.get_crate_data(def.krate);
246248
decoder::get_impl_vtables(&*cdata, def.node, tcx)

src/librustc/metadata/decoder.rs

+38-30
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use metadata::tydecode::{parse_ty_data, parse_def_id,
2323
parse_bare_fn_ty_data, parse_trait_ref_data};
2424
use middle::lang_items;
2525
use middle::def;
26+
use middle::subst;
2627
use middle::ty::{ImplContainer, TraitContainer};
2728
use middle::ty;
2829
use middle::typeck;
@@ -257,34 +258,44 @@ fn item_ty_param_defs(item: ebml::Doc,
257258
tcx: &ty::ctxt,
258259
cdata: Cmd,
259260
tag: uint)
260-
-> Rc<Vec<ty::TypeParameterDef> > {
261-
let mut bounds = Vec::new();
261+
-> subst::VecPerParamSpace<ty::TypeParameterDef> {
262+
let mut bounds = subst::VecPerParamSpace::empty();
262263
reader::tagged_docs(item, tag, |p| {
263264
let bd = parse_type_param_def_data(
264265
p.data, p.start, cdata.cnum, tcx,
265266
|_, did| translate_def_id(cdata, did));
266-
bounds.push(bd);
267+
bounds.push(bd.space, bd);
267268
true
268269
});
269-
Rc::new(bounds)
270+
bounds
270271
}
271272

272273
fn item_region_param_defs(item_doc: ebml::Doc, cdata: Cmd)
273-
-> Rc<Vec<ty::RegionParameterDef> > {
274-
let mut v = Vec::new();
274+
-> subst::VecPerParamSpace<ty::RegionParameterDef>
275+
{
276+
let mut v = subst::VecPerParamSpace::empty();
275277
reader::tagged_docs(item_doc, tag_region_param_def, |rp_doc| {
276-
let ident_str_doc = reader::get_doc(rp_doc,
277-
tag_region_param_def_ident);
278-
let ident = item_name(&*token::get_ident_interner(), ident_str_doc);
279-
let def_id_doc = reader::get_doc(rp_doc,
280-
tag_region_param_def_def_id);
281-
let def_id = reader::with_doc_data(def_id_doc, parse_def_id);
282-
let def_id = translate_def_id(cdata, def_id);
283-
v.push(ty::RegionParameterDef { name: ident.name,
284-
def_id: def_id });
285-
true
286-
});
287-
Rc::new(v)
278+
let ident_str_doc = reader::get_doc(rp_doc,
279+
tag_region_param_def_ident);
280+
let ident = item_name(&*token::get_ident_interner(), ident_str_doc);
281+
let def_id_doc = reader::get_doc(rp_doc,
282+
tag_region_param_def_def_id);
283+
let def_id = reader::with_doc_data(def_id_doc, parse_def_id);
284+
let def_id = translate_def_id(cdata, def_id);
285+
286+
let doc = reader::get_doc(rp_doc, tag_region_param_def_space);
287+
let space = subst::ParamSpace::from_uint(reader::doc_as_u64(doc) as uint);
288+
289+
let doc = reader::get_doc(rp_doc, tag_region_param_def_index);
290+
let index = reader::doc_as_u64(doc) as uint;
291+
292+
v.push(space, ty::RegionParameterDef { name: ident.name,
293+
def_id: def_id,
294+
space: space,
295+
index: index });
296+
true
297+
});
298+
v
288299
}
289300

290301
fn enum_variant_ids(item: ebml::Doc, cdata: Cmd) -> Vec<ast::DefId> {
@@ -403,8 +414,8 @@ pub fn get_trait_def(cdata: Cmd,
403414
}
404415

405416
ty::TraitDef {
406-
generics: ty::Generics {type_param_defs: tp_defs,
407-
region_param_defs: rp_defs},
417+
generics: ty::Generics {types: tp_defs,
418+
regions: rp_defs},
408419
bounds: bounds,
409420
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
410421
}
@@ -422,8 +433,8 @@ pub fn get_type(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
422433
let rp_defs = item_region_param_defs(item, cdata);
423434

424435
ty::ty_param_bounds_and_ty {
425-
generics: ty::Generics {type_param_defs: tp_defs,
426-
region_param_defs: rp_defs},
436+
generics: ty::Generics {types: tp_defs,
437+
regions: rp_defs},
427438
ty: t
428439
}
429440
}
@@ -440,16 +451,13 @@ pub fn get_impl_trait(cdata: Cmd,
440451

441452
pub fn get_impl_vtables(cdata: Cmd,
442453
id: ast::NodeId,
443-
tcx: &ty::ctxt) -> typeck::impl_res
454+
tcx: &ty::ctxt)
455+
-> typeck::vtable_res
444456
{
445457
let item_doc = lookup_item(id, cdata.data());
446458
let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables);
447459
let mut decoder = reader::Decoder::new(vtables_doc);
448-
449-
typeck::impl_res {
450-
trait_vtables: decoder.read_vtable_res(tcx, cdata),
451-
self_vtables: decoder.read_vtable_param_res(tcx, cdata)
452-
}
460+
decoder.read_vtable_res(tcx, cdata)
453461
}
454462

455463

@@ -802,8 +810,8 @@ pub fn get_method(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
802810
ty::Method::new(
803811
name,
804812
ty::Generics {
805-
type_param_defs: type_param_defs,
806-
region_param_defs: rp_defs,
813+
types: type_param_defs,
814+
regions: rp_defs,
807815
},
808816
fty,
809817
explicit_self,

src/librustc/metadata/encoder.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use metadata::common::*;
1919
use metadata::cstore;
2020
use metadata::decoder;
2121
use metadata::tyencode;
22+
use middle::subst::VecPerParamSpace;
2223
use middle::ty::{node_id_to_type, lookup_item_type};
2324
use middle::astencode;
2425
use middle::ty;
@@ -128,10 +129,9 @@ fn encode_trait_ref(ebml_w: &mut Encoder,
128129

129130
fn encode_impl_vtables(ebml_w: &mut Encoder,
130131
ecx: &EncodeContext,
131-
vtables: &typeck::impl_res) {
132+
vtables: &typeck::vtable_res) {
132133
ebml_w.start_tag(tag_item_impl_vtables);
133-
astencode::encode_vtable_res(ecx, ebml_w, &vtables.trait_vtables);
134-
astencode::encode_vtable_param_res(ecx, ebml_w, &vtables.self_vtables);
134+
astencode::encode_vtable_res(ecx, ebml_w, vtables);
135135
ebml_w.end_tag();
136136
}
137137

@@ -148,7 +148,7 @@ pub fn def_to_str(did: DefId) -> String {
148148

149149
fn encode_ty_type_param_defs(ebml_w: &mut Encoder,
150150
ecx: &EncodeContext,
151-
params: &[ty::TypeParameterDef],
151+
params: &VecPerParamSpace<ty::TypeParameterDef>,
152152
tag: uint) {
153153
let ty_str_ctxt = &tyencode::ctxt {
154154
diag: ecx.diag,
@@ -164,7 +164,7 @@ fn encode_ty_type_param_defs(ebml_w: &mut Encoder,
164164
}
165165

166166
fn encode_region_param_defs(ebml_w: &mut Encoder,
167-
params: &[ty::RegionParameterDef]) {
167+
params: &VecPerParamSpace<ty::RegionParameterDef>) {
168168
for param in params.iter() {
169169
ebml_w.start_tag(tag_region_param_def);
170170

@@ -175,6 +175,12 @@ fn encode_region_param_defs(ebml_w: &mut Encoder,
175175
ebml_w.wr_tagged_str(tag_region_param_def_def_id,
176176
def_to_str(param.def_id).as_slice());
177177

178+
ebml_w.wr_tagged_u64(tag_region_param_def_space,
179+
param.space.to_uint() as u64);
180+
181+
ebml_w.wr_tagged_u64(tag_region_param_def_index,
182+
param.index as u64);
183+
178184
ebml_w.end_tag();
179185
}
180186
}
@@ -191,9 +197,9 @@ fn encode_item_variances(ebml_w: &mut Encoder,
191197
fn encode_bounds_and_type(ebml_w: &mut Encoder,
192198
ecx: &EncodeContext,
193199
tpt: &ty::ty_param_bounds_and_ty) {
194-
encode_ty_type_param_defs(ebml_w, ecx, tpt.generics.type_param_defs(),
200+
encode_ty_type_param_defs(ebml_w, ecx, &tpt.generics.types,
195201
tag_items_data_item_ty_param_bounds);
196-
encode_region_param_defs(ebml_w, tpt.generics.region_param_defs());
202+
encode_region_param_defs(ebml_w, &tpt.generics.regions);
197203
encode_type(ecx, ebml_w, tpt.ty);
198204
}
199205

@@ -725,8 +731,7 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
725731
method_ty: &ty::Method) {
726732
encode_def_id(ebml_w, method_ty.def_id);
727733
encode_name(ebml_w, method_ty.ident.name);
728-
encode_ty_type_param_defs(ebml_w, ecx,
729-
method_ty.generics.type_param_defs(),
734+
encode_ty_type_param_defs(ebml_w, ecx, &method_ty.generics.types,
730735
tag_item_method_tps);
731736
encode_method_fty(ecx, ebml_w, &method_ty.fty);
732737
encode_visibility(ebml_w, method_ty.vis);
@@ -770,10 +775,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
770775
}
771776

772777
for &ast_method in ast_method_opt.iter() {
773-
let num_params = tpt.generics.type_param_defs().len();
774-
if num_params > 0u ||
775-
is_default_impl ||
776-
should_inline(ast_method.attrs.as_slice()) {
778+
let any_types = !tpt.generics.types.is_empty();
779+
if any_types || is_default_impl || should_inline(ast_method.attrs.as_slice()) {
777780
encode_inlined_item(ecx, ebml_w,
778781
IIMethodRef(local_def(parent_id), false,
779782
&*ast_method));
@@ -1125,9 +1128,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
11251128
encode_item_variances(ebml_w, ecx, item.id);
11261129
let trait_def = ty::lookup_trait_def(tcx, def_id);
11271130
encode_ty_type_param_defs(ebml_w, ecx,
1128-
trait_def.generics.type_param_defs(),
1131+
&trait_def.generics.types,
11291132
tag_items_data_item_ty_param_bounds);
1130-
encode_region_param_defs(ebml_w, trait_def.generics.region_param_defs());
1133+
encode_region_param_defs(ebml_w, &trait_def.generics.regions);
11311134
encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
11321135
encode_name(ebml_w, item.ident.name);
11331136
encode_attributes(ebml_w, item.attrs.as_slice());

0 commit comments

Comments
 (0)