rustc: Don't require that structs have constructors

This commit is contained in:
Patrick Walton 2012-07-24 15:29:14 -07:00
parent 695ab09899
commit 587b0edbbf
11 changed files with 165 additions and 109 deletions

View file

@ -193,7 +193,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
encode_name_and_def_id(ebml_w, it.ident, it.id);
}
}
item_class(_, _, items, ctor, m_dtor) {
item_class(_, _, items, m_ctor, m_dtor) {
do ebml_w.wr_tag(tag_paths_data_item) {
encode_name_and_def_id(ebml_w, it.ident, it.id);
}
@ -201,8 +201,17 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
// We add the same ident twice: for the
// class and for its ctor
add_to_index(ebml_w, path, index, it.ident);
encode_named_def_id(ebml_w, it.ident,
local_def(ctor.node.id));
alt m_ctor {
none => {
// Nothing to do.
}
some(ctor) {
encode_named_def_id(ebml_w, it.ident,
local_def(ctor.node.id));
}
}
encode_class_item_paths(ebml_w, items,
vec::append_one(path, it.ident),
index);
@ -817,18 +826,20 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_info_for_item(ecx, ebml_w, i, index, *pt);
/* encode ctor, then encode items */
alt i.node {
item_class(tps, _, _, ctor, m_dtor) {
#debug("encoding info for ctor %s %d", *i.ident,
ctor.node.id);
vec::push(*index,
{val: ctor.node.id, pos: ebml_w.writer.tell()});
encode_info_for_fn(ecx, ebml_w, ctor.node.id, i.ident,
*pt, if tps.len() > 0u {
some(ii_ctor(ctor, i.ident, tps,
local_def(i.id))) }
else { none }, tps, ctor.node.dec);
}
_ {}
item_class(tps, _, _, some(ctor), m_dtor) {
#debug("encoding info for ctor %s %d", *i.ident,
ctor.node.id);
vec::push(*index, {
val: ctor.node.id,
pos: ebml_w.writer.tell()
});
encode_info_for_fn(ecx, ebml_w, ctor.node.id, i.ident,
*pt, if tps.len() > 0u {
some(ii_ctor(ctor, i.ident, tps,
local_def(i.id))) }
else { none }, tps, ctor.node.dec);
}
_ {}
}
}
}

View file

@ -878,12 +878,20 @@ class Resolver {
visitor);
}
}
item_class(_, _, class_members, ctor, _) {
item_class(_, _, class_members, optional_ctor, _) {
(*name_bindings).define_type(def_ty(local_def(item.id)));
let purity = ctor.node.dec.purity;
let ctor_def = def_fn(local_def(ctor.node.id), purity);
(*name_bindings).define_value(ctor_def);
alt optional_ctor {
none => {
// Nothing to do.
}
some(ctor) => {
let purity = ctor.node.dec.purity;
let ctor_def = def_fn(local_def(ctor.node.id),
purity);
(*name_bindings).define_value(ctor_def);
}
}
// Create the set of implementation information that the
// implementation scopes (ImplScopes) need and write it into
@ -3043,14 +3051,14 @@ class Resolver {
(*self.type_ribs).pop();
}
item_class(ty_params, interfaces, class_members, constructor,
optional_destructor) {
item_class(ty_params, interfaces, class_members,
optional_constructor, optional_destructor) {
self.resolve_class(item.id,
@copy ty_params,
interfaces,
class_members,
constructor,
optional_constructor,
optional_destructor,
visitor);
}
@ -3273,7 +3281,7 @@ class Resolver {
type_parameters: @~[ty_param],
interfaces: ~[@trait_ref],
class_members: ~[@class_member],
constructor: class_ctor,
optional_constructor: option<class_ctor>,
optional_destructor: option<class_dtor>,
visitor: ResolveVisitor) {
@ -3285,8 +3293,7 @@ class Resolver {
let borrowed_type_parameters: &~[ty_param] = &*type_parameters;
do self.with_type_parameter_rib(HasTypeParameters
(borrowed_type_parameters, id, 0u,
NormalRibKind))
|| {
NormalRibKind)) {
// Resolve the type parameters.
self.resolve_type_parameters(*type_parameters, visitor);
@ -3331,15 +3338,22 @@ class Resolver {
}
}
// Resolve the constructor.
self.resolve_function(NormalRibKind,
some(@constructor.node.dec),
NoTypeParameters,
constructor.node.body,
HasSelfBinding(constructor.node.self_id),
NoCaptureClause,
visitor);
// Resolve the constructor, if applicable.
alt optional_constructor {
none => {
// Nothing to do.
}
some(constructor) => {
self.resolve_function(NormalRibKind,
some(@constructor.node.dec),
NoTypeParameters,
constructor.node.body,
HasSelfBinding(constructor.node.
self_id),
NoCaptureClause,
visitor);
}
}
// Resolve the destructor, if applicable.
alt optional_destructor {

View file

@ -5015,15 +5015,17 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
};
foreign::trans_foreign_mod(ccx, foreign_mod, abi);
}
ast::item_class(tps, _traits, items, ctor, m_dtor) {
ast::item_class(tps, _traits, items, m_ctor, m_dtor) {
if tps.len() == 0u {
let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps),
vtables: none,
bounds: @~[]};
trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body,
get_item_val(ccx, ctor.node.id), psubsts,
ctor.node.id, local_def(item.id), ctor.span);
do option::iter(m_dtor) |dtor| {
do option::iter(m_ctor) |ctor| {
trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body,
get_item_val(ccx, ctor.node.id), psubsts,
ctor.node.id, local_def(item.id), ctor.span);
}
do option::iter(m_dtor) |dtor| {
trans_class_dtor(ccx, *path, dtor.node.body,
dtor.node.id, none, none, local_def(item.id));
};

View file

@ -109,11 +109,13 @@ fn traverse_public_item(cx: ctx, item: @item) {
}
}
}
item_class(tps, _traits, items, ctor, m_dtor) {
cx.rmap.insert(ctor.node.id, ());
if tps.len() > 0u || attr::find_inline_attr(ctor.node.attrs)
!= attr::ia_none {
traverse_inline_body(cx, ctor.node.body);
item_class(tps, _traits, items, m_ctor, m_dtor) {
do option::iter(m_ctor) |ctor| {
cx.rmap.insert(ctor.node.id, ());
if tps.len() > 0u || attr::find_inline_attr(ctor.node.attrs)
!= attr::ia_none {
traverse_inline_body(cx, ctor.node.body);
}
}
do option::iter(m_dtor) |dtor| {
cx.rmap.insert(dtor.node.id, ());

View file

@ -392,25 +392,29 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
let self_ty = ccx.to_ty(rscope::type_rscope(rp), ty);
for ms.each |m| { check_method(ccx, m, self_ty);}
}
ast::item_class(tps, traits, members, ctor, m_dtor) {
let tcx = ccx.tcx;
let class_t = ty::node_id_to_type(tcx, it.id);
// typecheck the ctor
check_bare_fn(ccx, ctor.node.dec,
ctor.node.body, ctor.node.id,
some(class_t));
// Write the ctor's self's type
write_ty_to_tcx(tcx, ctor.node.self_id, class_t);
ast::item_class(tps, traits, members, m_ctor, m_dtor) {
let tcx = ccx.tcx;
let class_t = ty::node_id_to_type(tcx, it.id);
do option::iter(m_ctor) |ctor| {
// typecheck the ctor
check_bare_fn(ccx, ctor.node.dec,
ctor.node.body, ctor.node.id,
some(class_t));
// Write the ctor's self's type
write_ty_to_tcx(tcx, ctor.node.self_id, class_t);
}
do option::iter(m_dtor) |dtor| {
// typecheck the dtor
check_bare_fn(ccx, ast_util::dtor_dec(),
dtor.node.body, dtor.node.id,
some(class_t));
// Write the dtor's self's type
write_ty_to_tcx(tcx, dtor.node.self_id, class_t);
};
// typecheck the members
check_bare_fn(ccx, ast_util::dtor_dec(),
dtor.node.body, dtor.node.id,
some(class_t));
// Write the dtor's self's type
write_ty_to_tcx(tcx, dtor.node.self_id, class_t);
};
// typecheck the members
for members.each |m| { check_class_member(ccx, class_t, m); }
// Check that there's at least one field
let (fields,_) = split_class_items(members);

View file

@ -346,31 +346,34 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
write_ty_to_tcx(tcx, it.id, tpt.ty);
ensure_trait_methods(ccx, it.id);
}
ast::item_class(tps, traits, members, ctor, m_dtor) {
ast::item_class(tps, traits, members, m_ctor, m_dtor) {
// Write the class type
let tpt = ty_of_item(ccx, it);
write_ty_to_tcx(tcx, it.id, tpt.ty);
tcx.tcache.insert(local_def(it.id), tpt);
// Write the ctor type
let t_args = ctor.node.dec.inputs.map(
|a| ty_of_arg(ccx, type_rscope(rp), a, none) );
let t_res = ty::mk_class(
tcx, local_def(it.id),
{self_r: if rp {some(ty::re_bound(ty::br_self))} else {none},
self_ty: none,
tps: ty::ty_params_to_tys(tcx, tps)});
let t_ctor = ty::mk_fn(
tcx, {purity: ast::impure_fn,
proto: ast::proto_any,
inputs: t_args,
output: t_res,
ret_style: ast::return_val});
// constraints, or remove constraints from the language
write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
tcx.tcache.insert(local_def(ctor.node.id),
{bounds: tpt.bounds,
rp: rp,
ty: t_ctor});
do option::iter(m_ctor) |ctor| {
// Write the ctor type
let t_args = ctor.node.dec.inputs.map(
|a| ty_of_arg(ccx, type_rscope(rp), a, none) );
let t_res = ty::mk_class(
tcx, local_def(it.id),
{self_r: if rp {some(ty::re_bound(ty::br_self))} else {none},
self_ty: none,
tps: ty::ty_params_to_tys(tcx, tps)});
let t_ctor = ty::mk_fn(
tcx, {purity: ast::impure_fn,
proto: ast::proto_any,
inputs: t_args,
output: t_res,
ret_style: ast::return_val});
write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
tcx.tcache.insert(local_def(ctor.node.id),
{bounds: tpt.bounds,
rp: rp,
ty: t_ctor});
}
do option::iter(m_dtor) |dtor| {
// Write the dtor type
let t_dtor = ty::mk_fn(