Skip to content

Commit

Permalink
auto merge of #7291 : alexcrichton/rust/static-mut, r=huonw
Browse files Browse the repository at this point in the history
This adds both `static mut` items and `static mut` foreign items. This involved changing far less code than I thought it was going to, but the tests seem to pass and the variables seem functional.

I'm more than willing to write more tests, so suggestions are welcome!

Closes #553
  • Loading branch information
bors committed Jun 25, 2013
2 parents 5a089c2 + b94f89f commit b11346b
Show file tree
Hide file tree
Showing 40 changed files with 358 additions and 109 deletions.
16 changes: 10 additions & 6 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {

#[deriving(Eq)]
enum Family {
Const, // c
ImmStatic, // c
MutStatic, // b
Fn, // f
UnsafeFn, // u
PureFn, // p
Expand All @@ -121,7 +122,8 @@ enum Family {
fn item_family(item: ebml::Doc) -> Family {
let fam = reader::get_doc(item, tag_items_data_item_family);
match reader::doc_as_u8(fam) as char {
'c' => Const,
'c' => ImmStatic,
'b' => MutStatic,
'f' => Fn,
'u' => UnsafeFn,
'p' => PureFn,
Expand Down Expand Up @@ -320,7 +322,8 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
-> def_like {
let fam = item_family(item);
match fam {
Const => dl_def(ast::def_const(did)),
ImmStatic => dl_def(ast::def_static(did, false)),
MutStatic => dl_def(ast::def_static(did, true)),
Struct => dl_def(ast::def_struct(did)),
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
Expand Down Expand Up @@ -899,8 +902,8 @@ pub fn get_item_visibility(cdata: cmd, id: ast::node_id)

fn family_has_type_params(fam: Family) -> bool {
match fam {
Const | ForeignType | Mod | ForeignMod | PublicField | PrivateField
| ForeignFn => false,
ImmStatic | ForeignType | Mod | ForeignMod | PublicField | PrivateField
| ForeignFn | MutStatic => false,
_ => true
}
}
Expand Down Expand Up @@ -930,7 +933,8 @@ fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {

fn item_family_to_str(fam: Family) -> ~str {
match fam {
Const => ~"const",
ImmStatic => ~"static",
MutStatic => ~"static mut",
Fn => ~"fn",
UnsafeFn => ~"unsafe fn",
PureFn => ~"pure fn",
Expand Down
18 changes: 13 additions & 5 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
let must_write =
match item.node {
item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
item_mod(*) | item_foreign_mod(*) | item_const(*) => true,
item_mod(*) | item_foreign_mod(*) | item_static(*) => true,
_ => false
};
if !must_write && !reachable(ecx, item.id) { return; }
Expand All @@ -800,11 +800,15 @@ fn encode_info_for_item(ecx: &EncodeContext,
ecx.tcx.sess.codemap.span_to_str(item.span));

match item.node {
item_const(_, _) => {
item_static(_, m, _) => {
add_to_index();
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'c');
if m == ast::m_mutbl {
encode_family(ebml_w, 'b');
} else {
encode_family(ebml_w, 'c');
}
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_symbol(ecx, ebml_w, item.id);
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
Expand Down Expand Up @@ -1107,9 +1111,13 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
}
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
}
foreign_item_const(*) => {
foreign_item_static(_, mutbl) => {
encode_def_id(ebml_w, local_def(nitem.id));
encode_family(ebml_w, 'c');
if mutbl {
encode_family(ebml_w, 'b');
} else {
encode_family(ebml_w, 'c');
}
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
encode_symbol(ecx, ebml_w, nitem.id);
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ impl tr for ast::def {
ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) }
ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) }
ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) }
ast::def_const(did) => { ast::def_const(did.tr(xcx)) }
ast::def_static(did, m) => { ast::def_static(did.tr(xcx), m) }
ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) }
ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) }
ast::def_variant(e_did, v_did) => {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/check_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn check_item(sess: Session,
(_is_const, v): (bool,
visit::vt<bool>)) {
match it.node {
item_const(_, ex) => {
item_static(_, _, ex) => {
(v.visit_expr)(ex, (true, v));
check_item_recursion(sess, ast_map, def_map, it);
}
Expand Down Expand Up @@ -124,7 +124,7 @@ pub fn check_expr(sess: Session,
items without type parameters");
}
match def_map.find(&e.id) {
Some(&def_const(_)) |
Some(&def_static(*)) |
Some(&def_fn(_, _)) |
Some(&def_variant(_, _)) |
Some(&def_struct(_)) => { }
Expand Down Expand Up @@ -237,7 +237,7 @@ pub fn check_item_recursion(sess: Session,
match e.node {
expr_path(*) => {
match env.def_map.find(&e.id) {
Some(&def_const(def_id)) => {
Some(&def_static(def_id, _)) => {
if ast_util::is_local(def_id) {
match env.ast_map.get_copy(&def_id.node) {
ast_map::node_item(it, _) => {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option<ctor> {
pat_ident(_, _, _) | pat_enum(_, _) => {
match cx.tcx.def_map.find(&pat.id) {
Some(&def_variant(_, id)) => Some(variant(id)),
Some(&def_const(did)) => {
Some(&def_static(did, false)) => {
let const_expr = lookup_const_by_id(cx.tcx, did).get();
Some(val(eval_const_expr(cx.tcx, const_expr)))
}
Expand Down Expand Up @@ -339,7 +339,7 @@ pub fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool {
pat_wild => { true }
pat_ident(_, _, _) => {
match cx.tcx.def_map.find(&pat.id) {
Some(&def_variant(_, _)) | Some(&def_const(*)) => { false }
Some(&def_variant(_, _)) | Some(&def_static(*)) => { false }
_ => { true }
}
}
Expand Down Expand Up @@ -499,7 +499,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
None
}
}
Some(&def_const(did)) => {
Some(&def_static(did, _)) => {
let const_expr =
lookup_const_by_id(cx.tcx, did).get();
let e_v = eval_const_expr(cx.tcx, const_expr);
Expand Down Expand Up @@ -549,7 +549,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
}
pat_enum(_, args) => {
match cx.tcx.def_map.get_copy(&pat_id) {
def_const(did) => {
def_static(did, _) => {
let const_expr =
lookup_const_by_id(cx.tcx, did).get();
let e_v = eval_const_expr(cx.tcx, const_expr);
Expand Down Expand Up @@ -790,7 +790,7 @@ pub fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool {
return true;
}
}
Some(&def_const(*)) => return true,
Some(&def_static(*)) => return true,
_ => ()
}

Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ pub fn classify(e: @expr,

pub fn lookup_const(tcx: ty::ctxt, e: @expr) -> Option<@expr> {
match tcx.def_map.find(&e.id) {
Some(&ast::def_const(def_id)) => lookup_const_by_id(tcx, def_id),
Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id),
_ => None
}
}
Expand All @@ -178,7 +178,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
match tcx.items.find(&def_id.node) {
None => None,
Some(&ast_map::node_item(it, _)) => match it.node {
item_const(_, const_expr) => Some(const_expr),
item_static(_, ast::m_imm, const_expr) => Some(const_expr),
_ => None
},
Some(_) => None
Expand All @@ -195,7 +195,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
match csearch::maybe_get_item_ast(tcx, def_id,
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) {
csearch::found(ast::ii_item(item)) => match item.node {
item_const(_, const_expr) => Some(const_expr),
item_static(_, ast::m_imm, const_expr) => Some(const_expr),
_ => None
},
_ => None
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use middle::typeck::method_map;
use util::ppaux;

use syntax::ast::{deref, expr_call, expr_inline_asm, expr_method_call};
use syntax::ast::{expr_unary, node_id, unsafe_blk, unsafe_fn};
use syntax::ast::{expr_unary, node_id, unsafe_blk, unsafe_fn, expr_path};
use syntax::ast;
use syntax::codemap::span;
use syntax::visit::{fk_item_fn, fk_method};
Expand Down Expand Up @@ -143,6 +143,14 @@ pub fn check_crate(tcx: ty::ctxt,
expr_inline_asm(*) => {
require_unsafe(expr.span, "use of inline assembly")
}
expr_path(*) => {
match ty::resolve_expr(tcx, expr) {
ast::def_static(_, true) => {
require_unsafe(expr.span, "use of mutable static")
}
_ => {}
}
}
_ => {}
}

Expand Down
48 changes: 25 additions & 23 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,40 +709,42 @@ fn check_item_default_methods(cx: &Context, item: @ast::item) {
}

fn check_item_ctypes(cx: &Context, it: @ast::item) {
fn check_ty(cx: &Context, ty: @ast::Ty) {
match ty.node {
ast::ty_path(_, _, id) => {
match cx.tcx.def_map.get_copy(&id) {
ast::def_prim_ty(ast::ty_int(ast::ty_i)) => {
cx.span_lint(ctypes, ty.span,
"found rust type `int` in foreign module, while \
libc::c_int or libc::c_long should be used");
}
ast::def_prim_ty(ast::ty_uint(ast::ty_u)) => {
cx.span_lint(ctypes, ty.span,
"found rust type `uint` in foreign module, while \
libc::c_uint or libc::c_ulong should be used");
}
_ => ()
}
}
_ => ()
}
}

fn check_foreign_fn(cx: &Context, 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 {
ast::ty_path(_, _, id) => {
match cx.tcx.def_map.get_copy(&id) {
ast::def_prim_ty(ast::ty_int(ast::ty_i)) => {
cx.span_lint(ctypes, ty.span,
"found rust type `int` in foreign module, while \
libc::c_int or libc::c_long should be used");
}
ast::def_prim_ty(ast::ty_uint(ast::ty_u)) => {
cx.span_lint(ctypes, ty.span,
"found rust type `uint` in foreign module, while \
libc::c_uint or libc::c_ulong should be used");
}
_ => ()
}
}
_ => ()
}
check_ty(cx, *ty);
}
}

match it.node {
ast::item_foreign_mod(ref nmod) if !nmod.abis.is_intrinsic() => {
for nmod.items.iter().advance |ni| {
match ni.node {
ast::foreign_item_fn(ref decl, _, _) => {
check_foreign_fn(cx, decl);
}
// FIXME #4622: Not implemented.
ast::foreign_item_const(*) => {}
ast::foreign_item_fn(ref decl, _, _) => {
check_foreign_fn(cx, decl);
}
ast::foreign_item_static(t, _) => { check_ty(cx, t); }
}
}
}
Expand Down
28 changes: 19 additions & 9 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,19 +447,29 @@ impl mem_categorization_ctxt {
-> cmt {
match def {
ast::def_fn(*) | ast::def_static_method(*) | ast::def_mod(_) |
ast::def_foreign_mod(_) | ast::def_const(_) |
ast::def_foreign_mod(_) | ast::def_static(_, false) |
ast::def_use(_) | ast::def_variant(*) |
ast::def_trait(_) | ast::def_ty(_) | ast::def_prim_ty(_) |
ast::def_ty_param(*) | ast::def_struct(*) |
ast::def_typaram_binder(*) | ast::def_region(_) |
ast::def_label(_) | ast::def_self_ty(*) => {
@cmt_ {
id:id,
span:span,
cat:cat_static_item,
mutbl: McImmutable,
ty:expr_ty
}
@cmt_ {
id:id,
span:span,
cat:cat_static_item,
mutbl: McImmutable,
ty:expr_ty
}
}

ast::def_static(_, true) => {
@cmt_ {
id:id,
span:span,
cat:cat_static_item,
mutbl: McDeclared,
ty:expr_ty
}
}

ast::def_arg(vid, mutbl) => {
Expand Down Expand Up @@ -894,7 +904,7 @@ impl mem_categorization_ctxt {
self.cat_pattern(cmt_field, subpat, op);
}
}
Some(&ast::def_const(*)) => {
Some(&ast::def_static(*)) => {
for subpats.iter().advance |&subpat| {
self.cat_pattern(cmt, subpat, op);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/pat_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub fn pat_is_const(dm: resolve::DefMap, pat: &pat) -> bool {
match pat.node {
pat_ident(_, _, None) | pat_enum(*) => {
match dm.find(&pat.id) {
Some(&def_const(*)) => true,
Some(&def_static(_, false)) => true,
_ => false
}
}
Expand Down
Loading

0 comments on commit b11346b

Please sign in to comment.