Skip to content

Commit

Permalink
auto merge of #4892 : pcwalton/rust/xc-newtype-structs, r=pcwalton
Browse files Browse the repository at this point in the history
  • Loading branch information
bors committed Feb 13, 2013
2 parents e92e3e4 + e07623d commit d06e6e7
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 36 deletions.
3 changes: 3 additions & 0 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,8 @@ pub const tag_lang_items_item: uint = 0x73;
pub const tag_lang_items_item_id: uint = 0x74;
pub const tag_lang_items_item_node_id: uint = 0x75;

pub const tag_item_unnamed_field: uint = 0x76;
pub const tag_items_data_item_struct_ctor: uint = 0x77;

pub type link_meta = {name: @str, vers: @str, extras_hash: @str};

5 changes: 3 additions & 2 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,9 @@ pub fn get_item_attrs(cstore: @mut cstore::CStore,
decoder::get_item_attrs(cdata, def_id.node, f)
}

pub fn get_struct_fields(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::field_ty] {
let cstore = tcx.cstore;
pub fn get_struct_fields(cstore: @mut cstore::CStore,
def: ast::def_id)
-> ~[ty::field_ty] {
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_struct_fields(cstore.intr, cdata, def.node)
}
Expand Down
24 changes: 18 additions & 6 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use std::serialize::Decodable;
use syntax::ast_map;
use syntax::attr;
use syntax::diagnostic::span_handler;
use syntax::parse::token::ident_interner;
use syntax::parse::token::{ident_interner, special_idents};
use syntax::print::pprust;
use syntax::{ast, ast_util};
use syntax::codemap;
Expand Down Expand Up @@ -231,7 +231,9 @@ pub fn item_type(item_id: ast::def_id, item: ebml::Doc,
let t = doc_type(item, tcx, cdata);
if family_names_type(item_family(item)) {
ty::mk_with_id(tcx, t, item_id)
} else { t }
} else {
t
}
}

fn item_impl_traits(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] {
Expand Down Expand Up @@ -661,11 +663,12 @@ fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc,
rslt
}

pub fn get_impls_for_mod(intr: @ident_interner, cdata: cmd,
m_id: ast::node_id, name: Option<ast::ident>,
get_cdata: fn(ast::crate_num) -> cmd)
pub fn get_impls_for_mod(intr: @ident_interner,
cdata: cmd,
m_id: ast::node_id,
name: Option<ast::ident>,
get_cdata: &fn(ast::crate_num) -> cmd)
-> @~[@_impl] {

let data = cdata.data;
let mod_item = lookup_item(m_id, data);
let mut result = ~[];
Expand Down Expand Up @@ -887,6 +890,15 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id)
});
}
}
for reader::tagged_docs(item, tag_item_unnamed_field) |an_item| {
let did = item_def_id(an_item, cdata);
result.push(ty::field_ty {
ident: special_idents::unnamed_field,
id: did,
vis: ast::inherited,
mutability: ast::struct_immutable,
});
}
result
}

Expand Down
90 changes: 69 additions & 21 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use syntax::ast_map;
use syntax::ast_util::*;
use syntax::attr;
use syntax::diagnostic::span_handler;
use syntax::parse::token::special_idents;
use syntax::print::pprust;
use syntax::{ast_util, visit};
use syntax;
Expand Down Expand Up @@ -328,7 +329,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder,
// Encode info about all the module children.
for md.items.each |item| {
match item.node {
item_impl(*) | item_struct(*) => {
item_impl(*) => {
let (ident, did) = (item.ident, item.id);
debug!("(encoding info for module) ... encoding impl %s \
(%?/%?)",
Expand Down Expand Up @@ -432,25 +433,28 @@ fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder,
/* We encode both private and public fields -- need to include
private fields to get the offsets right */
for fields.each |field| {
match field.node.kind {
named_field(nm, mt, vis) => {
let id = field.node.id;
index.push({val: id, pos: ebml_w.writer.tell()});
global_index.push({val: id,
pos: ebml_w.writer.tell()});
ebml_w.start_tag(tag_items_data_item);
debug!("encode_info_for_struct: doing %s %d",
tcx.sess.str_of(nm), id);
encode_visibility(ebml_w, vis);
encode_name(ecx, ebml_w, nm);
encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
encode_mutability(ebml_w, mt);
encode_def_id(ebml_w, local_def(id));
ebml_w.end_tag();
}
unnamed_field => {}
}
let (nm, mt, vis) = match field.node.kind {
named_field(nm, mt, vis) => (nm, mt, vis),
unnamed_field => (
special_idents::unnamed_field,
struct_immutable,
inherited
)
};

let id = field.node.id;
index.push({val: id, pos: ebml_w.writer.tell()});
global_index.push({val: id, pos: ebml_w.writer.tell()});
ebml_w.start_tag(tag_items_data_item);
debug!("encode_info_for_struct: doing %s %d",
tcx.sess.str_of(nm), id);
encode_visibility(ebml_w, vis);
encode_name(ecx, ebml_w, nm);
encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
encode_mutability(ebml_w, mt);
encode_def_id(ebml_w, local_def(id));
ebml_w.end_tag();
}
/*bad*/copy *index
}
Expand Down Expand Up @@ -481,6 +485,28 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ebml_w.end_tag();
}

fn encode_info_for_struct_ctor(ecx: @encode_ctxt,
ebml_w: writer::Encoder,
path: &[ast_map::path_elt],
name: ast::ident,
ctor_id: node_id,
index: @mut ~[entry<int>]) {
index.push({ val: ctor_id, pos: ebml_w.writer.tell() });

ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(ctor_id));
encode_family(ebml_w, 'f');
encode_name(ecx, ebml_w, name);
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
encode_path(ecx, ebml_w, path, ast_map::path_name(name));

if ecx.item_symbols.contains_key(&ctor_id) {
encode_symbol(ecx, ebml_w, ctor_id);
}

ebml_w.end_tag();
}

fn encode_info_for_method(ecx: @encode_ctxt,
ebml_w: writer::Encoder,
impl_path: &[ast_map::path_elt],
Expand Down Expand Up @@ -674,6 +700,24 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
encode_family(ebml_w, 'S');
encode_type_param_bounds(ebml_w, ecx, tps);
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
// constructor.
if struct_def.fields.len() > 0 &&
struct_def.fields[0].node.kind == ast::unnamed_field {
let ctor_id = match struct_def.ctor_id {
Some(ctor_id) => ctor_id,
None => ecx.tcx.sess.bug(~"struct def didn't have ctor id"),
};

encode_info_for_struct_ctor(ecx,
ebml_w,
path,
item.ident,
ctor_id,
index);
}

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);
Expand All @@ -697,7 +741,11 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
encode_def_id(ebml_w, local_def(f.node.id));
ebml_w.end_tag();
}
unnamed_field => {}
unnamed_field => {
ebml_w.start_tag(tag_item_unnamed_field);
encode_def_id(ebml_w, local_def(f.node.id));
ebml_w.end_tag();
}
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use core::prelude::*;
use driver::session;
use driver::session::Session;
use metadata::csearch::{each_path, get_method_names_if_trait};
use metadata::csearch::{get_static_methods_if_impl, get_type_name_if_impl};
use metadata::csearch::{get_static_methods_if_impl, get_struct_fields};
use metadata::csearch::{get_type_name_if_impl};
use metadata::cstore::find_use_stmt_cnum;
use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
use middle::lang_items::LanguageItems;
Expand Down Expand Up @@ -1745,10 +1746,12 @@ pub impl Resolver {
OverwriteDuplicates,
dummy_sp());

self.handle_external_def(def, modules,
self.handle_external_def(def,
modules,
child_name_bindings,
self.session.str_of(final_ident),
final_ident, new_parent);
final_ident,
new_parent);
}
dl_impl(def) => {
// We only process static methods of impls here.
Expand Down
9 changes: 7 additions & 2 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1905,8 +1905,13 @@ pub fn trans_tuple_struct(ccx: @crate_ctxt,
}
};

let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, ctor_id, None,
param_substs, None);
let fcx = new_fn_ctxt_w_id(ccx,
~[],
llfndecl,
ctor_id,
None,
param_substs,
None);

// XXX: Bad copy.
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, copy fn_args);
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/trans/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ fn traverse_public_item(cx: ctx, item: @item) {
}
}
item_struct(struct_def, tps) => {
for struct_def.ctor_id.each |&ctor_id| {
cx.rmap.insert(ctor_id, ());
}
do option::iter(&struct_def.dtor) |dtor| {
cx.rmap.insert(dtor.node.id, ());
if tps.len() > 0u || attr::find_inline_attr(dtor.node.attrs)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4012,7 +4012,7 @@ pub fn lookup_struct_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] {
}
}
else {
return csearch::get_struct_fields(cx, did);
return csearch::get_struct_fields(cx.sess.cstore, did);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ pub impl CoherenceChecker {
let implementations = get_impls_for_mod(crate_store,
module_def_id,
None);
for (*implementations).each |implementation| {
for implementations.each |implementation| {
debug!("coherence: adding impl from external crate: %s",
ty::item_path_str(self.crate_context.tcx,
implementation.did));
Expand Down
4 changes: 4 additions & 0 deletions src/test/auxiliary/newtype_struct_xc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[crate_type="lib"];

pub struct Au(int);

14 changes: 14 additions & 0 deletions src/test/run-pass/newtype-struct-xc-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// xfail-fast
// aux-build:newtype_struct_xc.rs

extern mod newtype_struct_xc;
use newtype_struct_xc::Au;

fn f() -> Au {
Au(2)
}

fn main() {
let _ = f();
}

9 changes: 9 additions & 0 deletions src/test/run-pass/newtype-struct-xc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// xfail-fast
// aux-build:newtype_struct_xc.rs

extern mod newtype_struct_xc;

fn main() {
let _ = newtype_struct_xc::Au(2);
}

0 comments on commit d06e6e7

Please sign in to comment.