Skip to content

Commit

Permalink
Introduce lifetime declarations into the lists of type parameters.
Browse files Browse the repository at this point in the history
Major changes are:
- replace ~[ty_param] with Generics structure, which includes
  both OptVec<TyParam> and OptVec<Lifetime>;
- the use of syntax::opt_vec to avoid allocation for empty lists;

cc rust-lang#4846
  • Loading branch information
nikomatsakis committed Feb 28, 2013
1 parent 061a223 commit c623d21
Show file tree
Hide file tree
Showing 34 changed files with 1,067 additions and 719 deletions.
6 changes: 3 additions & 3 deletions src/librustc/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,14 @@ fn is_bench_fn(i: @ast::item) -> bool {
vec::len(attr::find_attrs_by_name(i.attrs, ~"bench")) > 0u;

fn has_test_signature(i: @ast::item) -> bool {
match /*bad*/copy i.node {
ast::item_fn(decl, _, tps, _) => {
match i.node {
ast::item_fn(ref decl, _, ref generics, _) => {
let input_cnt = vec::len(decl.inputs);
let no_output = match decl.output.node {
ast::ty_nil => true,
_ => false
};
let tparm_cnt = vec::len(tps);
let tparm_cnt = generics.ty_params.len();
// NB: inadequate check, but we're running
// well before resolve, can't get too deep.
input_cnt == 1u
Expand Down
101 changes: 62 additions & 39 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ use syntax::diagnostic::span_handler;
use syntax::parse::token::special_idents;
use syntax::print::pprust;
use syntax::{ast_util, visit};
use syntax::opt_vec::OptVec;
use syntax::opt_vec;
use syntax;
use writer = std::ebml::writer;

Expand Down Expand Up @@ -187,10 +189,11 @@ fn encode_ty_type_param_bounds(ebml_w: writer::Encoder, ecx: @EncodeContext,
}
}

fn encode_type_param_bounds(ebml_w: writer::Encoder, ecx: @EncodeContext,
params: &[ty_param]) {
fn encode_type_param_bounds(ebml_w: writer::Encoder,
ecx: @EncodeContext,
params: &OptVec<TyParam>) {
let ty_param_bounds =
@params.map(|param| ecx.tcx.ty_param_bounds.get(&param.id));
@params.map_to_vec(|param| ecx.tcx.ty_param_bounds.get(&param.id));
encode_ty_type_param_bounds(ebml_w, ecx, ty_param_bounds);
}

Expand Down Expand Up @@ -265,7 +268,7 @@ fn encode_enum_variant_info(ecx: @EncodeContext, ebml_w: writer::Encoder,
id: node_id, variants: &[variant],
path: &[ast_map::path_elt],
index: @mut ~[entry<int>],
ty_params: &[ty_param]) {
generics: &ast::Generics) {
let mut disr_val = 0;
let mut i = 0;
let vi = ty::enum_variants(ecx.tcx,
Expand All @@ -281,7 +284,7 @@ fn encode_enum_variant_info(ecx: @EncodeContext, ebml_w: writer::Encoder,
node_id_to_type(ecx.tcx, variant.node.id));
match variant.node.kind {
ast::tuple_variant_kind(ref args)
if args.len() > 0 && ty_params.len() == 0 => {
if args.len() > 0 && generics.ty_params.len() == 0 => {
encode_symbol(ecx, ebml_w, variant.node.id);
}
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) |
Expand All @@ -292,7 +295,7 @@ fn encode_enum_variant_info(ecx: @EncodeContext, ebml_w: writer::Encoder,
encode_disr_val(ecx, ebml_w, vi[i].disr_val);
disr_val = vi[i].disr_val;
}
encode_type_param_bounds(ebml_w, ecx, ty_params);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_path(ecx, ebml_w, path,
ast_map::path_name(variant.node.name));
ebml_w.end_tag();
Expand Down Expand Up @@ -465,14 +468,18 @@ fn encode_info_for_struct(ecx: @EncodeContext, ebml_w: writer::Encoder,
}

// This is for encoding info for ctors and dtors
fn encode_info_for_ctor(ecx: @EncodeContext, ebml_w: writer::Encoder,
id: node_id, ident: ident, path: &[ast_map::path_elt],
item: Option<inlined_item>, tps: &[ty_param]) {
fn encode_info_for_ctor(ecx: @EncodeContext,
ebml_w: writer::Encoder,
id: node_id,
ident: ident,
path: &[ast_map::path_elt],
item: Option<inlined_item>,
generics: &ast::Generics) {
ebml_w.start_tag(tag_items_data_item);
encode_name(ecx, ebml_w, ident);
encode_def_id(ebml_w, local_def(id));
encode_family(ebml_w, purity_fn_family(ast::impure_fn));
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
let its_ty = node_id_to_type(ecx.tcx, id);
debug!("fn name = %s ty = %s its node id = %d",
*ecx.tcx.sess.str_of(ident),
Expand Down Expand Up @@ -518,9 +525,12 @@ fn encode_info_for_method(ecx: @EncodeContext,
should_inline: bool,
parent_id: node_id,
m: @method,
+all_tps: ~[ty_param]) {
debug!("encode_info_for_method: %d %s %u", m.id,
*ecx.tcx.sess.str_of(m.ident), all_tps.len());
owner_generics: &ast::Generics,
method_generics: &ast::Generics) {
debug!("encode_info_for_method: %d %s %u %u", m.id,
*ecx.tcx.sess.str_of(m.ident),
owner_generics.ty_params.len(),
method_generics.ty_params.len());
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(m.id));
match m.self_ty.node {
Expand All @@ -529,8 +539,13 @@ fn encode_info_for_method(ecx: @EncodeContext,
}
_ => encode_family(ebml_w, purity_fn_family(m.purity))
}
let len = all_tps.len();
encode_type_param_bounds(ebml_w, ecx, all_tps);

let mut combined_ty_params = opt_vec::Empty;
combined_ty_params.push_all(&owner_generics.ty_params);
combined_ty_params.push_all(&method_generics.ty_params);
let len = combined_ty_params.len();
encode_type_param_bounds(ebml_w, ecx, &combined_ty_params);

encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
encode_name(ecx, ebml_w, m.ident);
encode_path(ecx, ebml_w, impl_path, ast_map::path_name(m.ident));
Expand Down Expand Up @@ -604,13 +619,13 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
ebml_w.end_tag();
}
item_fn(_, purity, tps, _) => {
item_fn(_, purity, ref generics, _) => {
add_to_index();
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, purity_fn_family(purity));
let tps_len = tps.len();
encode_type_param_bounds(ebml_w, ecx, tps);
let tps_len = generics.ty_params.len();
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
encode_attributes(ebml_w, item.attrs);
Expand All @@ -634,24 +649,24 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
ebml_w.end_tag();
}
item_ty(_, tps) => {
item_ty(_, ref generics) => {
add_to_index();
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'y');
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ecx, ebml_w, item.ident);
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
encode_region_param(ecx, ebml_w, item);
ebml_w.end_tag();
}
item_enum(ref enum_definition, ref tps) => {
item_enum(ref enum_definition, ref generics) => {
add_to_index();
do ebml_w.wr_tag(tag_items_data_item) {
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 't');
encode_type_param_bounds(ebml_w, ecx, *tps);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ecx, ebml_w, item.ident);
for (*enum_definition).variants.each |v| {
Expand All @@ -667,9 +682,9 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
(*enum_definition).variants,
path,
index,
*tps);
generics);
}
item_struct(struct_def, tps) => {
item_struct(struct_def, ref generics) => {
/* First, encode the fields
These come first because we need to write them to make
the index, and the index needs to be in the item for the
Expand All @@ -686,24 +701,25 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
*ecx.tcx.sess.str_of(item.ident) +
~"_dtor"),
path,
if tps.len() > 0u {
if generics.ty_params.len() > 0u {
Some(ii_dtor(copy *dtor,
item.ident,
copy tps,
copy *generics,
local_def(item.id))) }
else {
None
},
tps);
generics);
}

/* Index the class*/
add_to_index();

/* Now, make an item for the class itself */
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'S');
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));

// If this is a tuple- or enum-like struct, encode the type of the
Expand Down Expand Up @@ -759,13 +775,13 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
encode_index(ebml_w, bkts, write_int);
ebml_w.end_tag();
}
item_impl(tps, opt_trait, ty, methods) => {
item_impl(ref generics, opt_trait, ty, ref methods) => {
add_to_index();
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'i');
encode_region_param(ecx, ebml_w, item);
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ecx, ebml_w, item.ident);
encode_attributes(ebml_w, item.attrs);
Expand Down Expand Up @@ -797,18 +813,18 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
encode_info_for_method(ecx, ebml_w, impl_path,
should_inline(m.attrs),
item.id, *m,
vec::append(/*bad*/copy tps, m.tps));
generics, &m.generics);
}
}
item_trait(ref tps, ref traits, ref ms) => {
item_trait(ref generics, ref traits, ref ms) => {
let provided_methods = dvec::DVec();

add_to_index();
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'I');
encode_region_param(ecx, ebml_w, item);
encode_type_param_bounds(ebml_w, ecx, *tps);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ecx, ebml_w, item.ident);
encode_attributes(ebml_w, item.attrs);
Expand All @@ -820,7 +836,7 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
encode_def_id(ebml_w, local_def((*ty_m).id));
encode_name(ecx, ebml_w, mty.ident);
encode_type_param_bounds(ebml_w, ecx,
(*ty_m).tps);
&ty_m.generics.ty_params);
encode_type(ecx, ebml_w,
ty::mk_bare_fn(tcx, copy mty.fty));
encode_family(ebml_w, purity_fn_family(mty.fty.purity));
Expand All @@ -834,7 +850,8 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
ebml_w.start_tag(tag_item_trait_method);
encode_def_id(ebml_w, local_def(m.id));
encode_name(ecx, ebml_w, mty.ident);
encode_type_param_bounds(ebml_w, ecx, m.tps);
encode_type_param_bounds(ebml_w, ecx,
&m.generics.ty_params);
encode_type(ecx, ebml_w,
ty::mk_bare_fn(tcx, copy mty.fty));
encode_family(ebml_w, purity_fn_family(mty.fty.purity));
Expand Down Expand Up @@ -880,8 +897,14 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
// Finally, output all the provided methods as items.
for provided_methods.each |m| {
index.push(entry { val: m.id, pos: ebml_w.writer.tell() });

// We do not concatenate the generics of the owning impl and that
// of provided methods. I am not sure why this is. -ndm
let owner_generics = ast_util::empty_generics();

encode_info_for_method(ecx, ebml_w, /*bad*/copy path,
true, item.id, *m, /*bad*/copy m.tps);
true, item.id, *m,
&owner_generics, &m.generics);
}
}
item_mac(*) => fail!(~"item macros unimplemented")
Expand All @@ -898,11 +921,11 @@ fn encode_info_for_foreign_item(ecx: @EncodeContext,
index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });

ebml_w.start_tag(tag_items_data_item);
match /*bad*/copy nitem.node {
foreign_item_fn(_, purity, tps) => {
match nitem.node {
foreign_item_fn(_, purity, ref generics) => {
encode_def_id(ebml_w, local_def(nitem.id));
encode_family(ebml_w, purity_fn_family(purity));
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
if abi == foreign_abi_rust_intrinsic {
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem));
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,10 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
ast::ii_foreign(i) => {
ast::ii_foreign(fld.fold_foreign_item(i))
}
ast::ii_dtor(ref dtor, nm, ref tps, parent_id) => {
ast::ii_dtor(ref dtor, nm, ref generics, parent_id) => {
let dtor_body = fld.fold_block((*dtor).node.body);
let dtor_attrs = fld.fold_attributes(/*bad*/copy (*dtor).node.attrs);
let new_params = fold::fold_ty_params(/*bad*/copy *tps, fld);
let dtor_attrs = fld.fold_attributes(copy dtor.node.attrs);
let new_generics = fold::fold_generics(generics, fld);
let dtor_id = fld.new_id((*dtor).node.id);
let new_parent = xcx.tr_def_id(parent_id);
let new_self = fld.new_id((*dtor).node.self_id);
Expand All @@ -386,7 +386,7 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
body: dtor_body },
.. (/*bad*/copy *dtor)
},
nm, new_params, new_parent)
nm, new_generics, new_parent)
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ fn check_item_structural_records(cx: ty::ctxt, it: @ast::item) {
fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {

fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
decl: ast::fn_decl) {
decl: ast::fn_decl) {
let tys = vec::map(decl.inputs, |a| a.ty );
for vec::each(vec::append_one(tys, decl.output)) |ty| {
match ty.node {
Expand Down Expand Up @@ -786,9 +786,9 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
if attr::foreign_abi(it.attrs) !=
either::Right(ast::foreign_abi_rust_intrinsic) => {
for nmod.items.each |ni| {
match /*bad*/copy ni.node {
ast::foreign_item_fn(decl, _, _) => {
check_foreign_fn(cx, it.id, decl);
match ni.node {
ast::foreign_item_fn(ref decl, _, _) => {
check_foreign_fn(cx, it.id, *decl);
}
// FIXME #4622: Not implemented.
ast::foreign_item_const(*) => {}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,8 @@ pub fn determine_rp_in_fn(fk: visit::fn_kind,
}
}
(visitor.visit_ty)(decl.output, cx, visitor);
(visitor.visit_ty_params)(visit::tps_of_fn(fk), cx, visitor);
let generics = visit::generics_of_fn(fk);
(visitor.visit_generics)(&generics, cx, visitor);
(visitor.visit_block)(body, cx, visitor);
}
}
Expand Down
Loading

1 comment on commit c623d21

@nikomatsakis
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+ (carrying over)

Please sign in to comment.