Skip to content

Commit b11346b

Browse files
committed
auto merge of #7291 : alexcrichton/rust/static-mut, r=huonw
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
2 parents 5a089c2 + b94f89f commit b11346b

40 files changed

+358
-109
lines changed

src/librustc/metadata/decoder.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
9696

9797
#[deriving(Eq)]
9898
enum Family {
99-
Const, // c
99+
ImmStatic, // c
100+
MutStatic, // b
100101
Fn, // f
101102
UnsafeFn, // u
102103
PureFn, // p
@@ -121,7 +122,8 @@ enum Family {
121122
fn item_family(item: ebml::Doc) -> Family {
122123
let fam = reader::get_doc(item, tag_items_data_item_family);
123124
match reader::doc_as_u8(fam) as char {
124-
'c' => Const,
125+
'c' => ImmStatic,
126+
'b' => MutStatic,
125127
'f' => Fn,
126128
'u' => UnsafeFn,
127129
'p' => PureFn,
@@ -320,7 +322,8 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
320322
-> def_like {
321323
let fam = item_family(item);
322324
match fam {
323-
Const => dl_def(ast::def_const(did)),
325+
ImmStatic => dl_def(ast::def_static(did, false)),
326+
MutStatic => dl_def(ast::def_static(did, true)),
324327
Struct => dl_def(ast::def_struct(did)),
325328
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
326329
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
@@ -899,8 +902,8 @@ pub fn get_item_visibility(cdata: cmd, id: ast::node_id)
899902

900903
fn family_has_type_params(fam: Family) -> bool {
901904
match fam {
902-
Const | ForeignType | Mod | ForeignMod | PublicField | PrivateField
903-
| ForeignFn => false,
905+
ImmStatic | ForeignType | Mod | ForeignMod | PublicField | PrivateField
906+
| ForeignFn | MutStatic => false,
904907
_ => true
905908
}
906909
}
@@ -930,7 +933,8 @@ fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {
930933

931934
fn item_family_to_str(fam: Family) -> ~str {
932935
match fam {
933-
Const => ~"const",
936+
ImmStatic => ~"static",
937+
MutStatic => ~"static mut",
934938
Fn => ~"fn",
935939
UnsafeFn => ~"unsafe fn",
936940
PureFn => ~"pure fn",

src/librustc/metadata/encoder.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
785785
let must_write =
786786
match item.node {
787787
item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
788-
item_mod(*) | item_foreign_mod(*) | item_const(*) => true,
788+
item_mod(*) | item_foreign_mod(*) | item_static(*) => true,
789789
_ => false
790790
};
791791
if !must_write && !reachable(ecx, item.id) { return; }
@@ -800,11 +800,15 @@ fn encode_info_for_item(ecx: &EncodeContext,
800800
ecx.tcx.sess.codemap.span_to_str(item.span));
801801

802802
match item.node {
803-
item_const(_, _) => {
803+
item_static(_, m, _) => {
804804
add_to_index();
805805
ebml_w.start_tag(tag_items_data_item);
806806
encode_def_id(ebml_w, local_def(item.id));
807-
encode_family(ebml_w, 'c');
807+
if m == ast::m_mutbl {
808+
encode_family(ebml_w, 'b');
809+
} else {
810+
encode_family(ebml_w, 'c');
811+
}
808812
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
809813
encode_symbol(ecx, ebml_w, item.id);
810814
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
@@ -1107,9 +1111,13 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
11071111
}
11081112
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
11091113
}
1110-
foreign_item_const(*) => {
1114+
foreign_item_static(_, mutbl) => {
11111115
encode_def_id(ebml_w, local_def(nitem.id));
1112-
encode_family(ebml_w, 'c');
1116+
if mutbl {
1117+
encode_family(ebml_w, 'b');
1118+
} else {
1119+
encode_family(ebml_w, 'c');
1120+
}
11131121
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
11141122
encode_symbol(ecx, ebml_w, nitem.id);
11151123
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));

src/librustc/middle/astencode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ impl tr for ast::def {
384384
ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) }
385385
ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) }
386386
ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) }
387-
ast::def_const(did) => { ast::def_const(did.tr(xcx)) }
387+
ast::def_static(did, m) => { ast::def_static(did.tr(xcx), m) }
388388
ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) }
389389
ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) }
390390
ast::def_variant(e_did, v_did) => {

src/librustc/middle/check_const.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn check_item(sess: Session,
4343
(_is_const, v): (bool,
4444
visit::vt<bool>)) {
4545
match it.node {
46-
item_const(_, ex) => {
46+
item_static(_, _, ex) => {
4747
(v.visit_expr)(ex, (true, v));
4848
check_item_recursion(sess, ast_map, def_map, it);
4949
}
@@ -124,7 +124,7 @@ pub fn check_expr(sess: Session,
124124
items without type parameters");
125125
}
126126
match def_map.find(&e.id) {
127-
Some(&def_const(_)) |
127+
Some(&def_static(*)) |
128128
Some(&def_fn(_, _)) |
129129
Some(&def_variant(_, _)) |
130130
Some(&def_struct(_)) => { }
@@ -237,7 +237,7 @@ pub fn check_item_recursion(sess: Session,
237237
match e.node {
238238
expr_path(*) => {
239239
match env.def_map.find(&e.id) {
240-
Some(&def_const(def_id)) => {
240+
Some(&def_static(def_id, _)) => {
241241
if ast_util::is_local(def_id) {
242242
match env.ast_map.get_copy(&def_id.node) {
243243
ast_map::node_item(it, _) => {

src/librustc/middle/check_match.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option<ctor> {
304304
pat_ident(_, _, _) | pat_enum(_, _) => {
305305
match cx.tcx.def_map.find(&pat.id) {
306306
Some(&def_variant(_, id)) => Some(variant(id)),
307-
Some(&def_const(did)) => {
307+
Some(&def_static(did, false)) => {
308308
let const_expr = lookup_const_by_id(cx.tcx, did).get();
309309
Some(val(eval_const_expr(cx.tcx, const_expr)))
310310
}
@@ -339,7 +339,7 @@ pub fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool {
339339
pat_wild => { true }
340340
pat_ident(_, _, _) => {
341341
match cx.tcx.def_map.find(&pat.id) {
342-
Some(&def_variant(_, _)) | Some(&def_const(*)) => { false }
342+
Some(&def_variant(_, _)) | Some(&def_static(*)) => { false }
343343
_ => { true }
344344
}
345345
}
@@ -499,7 +499,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
499499
None
500500
}
501501
}
502-
Some(&def_const(did)) => {
502+
Some(&def_static(did, _)) => {
503503
let const_expr =
504504
lookup_const_by_id(cx.tcx, did).get();
505505
let e_v = eval_const_expr(cx.tcx, const_expr);
@@ -549,7 +549,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
549549
}
550550
pat_enum(_, args) => {
551551
match cx.tcx.def_map.get_copy(&pat_id) {
552-
def_const(did) => {
552+
def_static(did, _) => {
553553
let const_expr =
554554
lookup_const_by_id(cx.tcx, did).get();
555555
let e_v = eval_const_expr(cx.tcx, const_expr);
@@ -790,7 +790,7 @@ pub fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool {
790790
return true;
791791
}
792792
}
793-
Some(&def_const(*)) => return true,
793+
Some(&def_static(*)) => return true,
794794
_ => ()
795795
}
796796

src/librustc/middle/const_eval.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ pub fn classify(e: @expr,
166166

167167
pub fn lookup_const(tcx: ty::ctxt, e: @expr) -> Option<@expr> {
168168
match tcx.def_map.find(&e.id) {
169-
Some(&ast::def_const(def_id)) => lookup_const_by_id(tcx, def_id),
169+
Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id),
170170
_ => None
171171
}
172172
}
@@ -178,7 +178,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
178178
match tcx.items.find(&def_id.node) {
179179
None => None,
180180
Some(&ast_map::node_item(it, _)) => match it.node {
181-
item_const(_, const_expr) => Some(const_expr),
181+
item_static(_, ast::m_imm, const_expr) => Some(const_expr),
182182
_ => None
183183
},
184184
Some(_) => None
@@ -195,7 +195,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
195195
match csearch::maybe_get_item_ast(tcx, def_id,
196196
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) {
197197
csearch::found(ast::ii_item(item)) => match item.node {
198-
item_const(_, const_expr) => Some(const_expr),
198+
item_static(_, ast::m_imm, const_expr) => Some(const_expr),
199199
_ => None
200200
},
201201
_ => None

src/librustc/middle/effect.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use middle::typeck::method_map;
1717
use util::ppaux;
1818

1919
use syntax::ast::{deref, expr_call, expr_inline_asm, expr_method_call};
20-
use syntax::ast::{expr_unary, node_id, unsafe_blk, unsafe_fn};
20+
use syntax::ast::{expr_unary, node_id, unsafe_blk, unsafe_fn, expr_path};
2121
use syntax::ast;
2222
use syntax::codemap::span;
2323
use syntax::visit::{fk_item_fn, fk_method};
@@ -143,6 +143,14 @@ pub fn check_crate(tcx: ty::ctxt,
143143
expr_inline_asm(*) => {
144144
require_unsafe(expr.span, "use of inline assembly")
145145
}
146+
expr_path(*) => {
147+
match ty::resolve_expr(tcx, expr) {
148+
ast::def_static(_, true) => {
149+
require_unsafe(expr.span, "use of mutable static")
150+
}
151+
_ => {}
152+
}
153+
}
146154
_ => {}
147155
}
148156

src/librustc/middle/lint.rs

+25-23
Original file line numberDiff line numberDiff line change
@@ -709,40 +709,42 @@ fn check_item_default_methods(cx: &Context, item: @ast::item) {
709709
}
710710

711711
fn check_item_ctypes(cx: &Context, it: @ast::item) {
712+
fn check_ty(cx: &Context, ty: @ast::Ty) {
713+
match ty.node {
714+
ast::ty_path(_, _, id) => {
715+
match cx.tcx.def_map.get_copy(&id) {
716+
ast::def_prim_ty(ast::ty_int(ast::ty_i)) => {
717+
cx.span_lint(ctypes, ty.span,
718+
"found rust type `int` in foreign module, while \
719+
libc::c_int or libc::c_long should be used");
720+
}
721+
ast::def_prim_ty(ast::ty_uint(ast::ty_u)) => {
722+
cx.span_lint(ctypes, ty.span,
723+
"found rust type `uint` in foreign module, while \
724+
libc::c_uint or libc::c_ulong should be used");
725+
}
726+
_ => ()
727+
}
728+
}
729+
_ => ()
730+
}
731+
}
712732

713733
fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) {
714734
let tys = vec::map(decl.inputs, |a| a.ty );
715735
for vec::each(vec::append_one(tys, decl.output)) |ty| {
716-
match ty.node {
717-
ast::ty_path(_, _, id) => {
718-
match cx.tcx.def_map.get_copy(&id) {
719-
ast::def_prim_ty(ast::ty_int(ast::ty_i)) => {
720-
cx.span_lint(ctypes, ty.span,
721-
"found rust type `int` in foreign module, while \
722-
libc::c_int or libc::c_long should be used");
723-
}
724-
ast::def_prim_ty(ast::ty_uint(ast::ty_u)) => {
725-
cx.span_lint(ctypes, ty.span,
726-
"found rust type `uint` in foreign module, while \
727-
libc::c_uint or libc::c_ulong should be used");
728-
}
729-
_ => ()
730-
}
731-
}
732-
_ => ()
733-
}
736+
check_ty(cx, *ty);
734737
}
735738
}
736739

737740
match it.node {
738741
ast::item_foreign_mod(ref nmod) if !nmod.abis.is_intrinsic() => {
739742
for nmod.items.iter().advance |ni| {
740743
match ni.node {
741-
ast::foreign_item_fn(ref decl, _, _) => {
742-
check_foreign_fn(cx, decl);
743-
}
744-
// FIXME #4622: Not implemented.
745-
ast::foreign_item_const(*) => {}
744+
ast::foreign_item_fn(ref decl, _, _) => {
745+
check_foreign_fn(cx, decl);
746+
}
747+
ast::foreign_item_static(t, _) => { check_ty(cx, t); }
746748
}
747749
}
748750
}

src/librustc/middle/mem_categorization.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -447,19 +447,29 @@ impl mem_categorization_ctxt {
447447
-> cmt {
448448
match def {
449449
ast::def_fn(*) | ast::def_static_method(*) | ast::def_mod(_) |
450-
ast::def_foreign_mod(_) | ast::def_const(_) |
450+
ast::def_foreign_mod(_) | ast::def_static(_, false) |
451451
ast::def_use(_) | ast::def_variant(*) |
452452
ast::def_trait(_) | ast::def_ty(_) | ast::def_prim_ty(_) |
453453
ast::def_ty_param(*) | ast::def_struct(*) |
454454
ast::def_typaram_binder(*) | ast::def_region(_) |
455455
ast::def_label(_) | ast::def_self_ty(*) => {
456-
@cmt_ {
457-
id:id,
458-
span:span,
459-
cat:cat_static_item,
460-
mutbl: McImmutable,
461-
ty:expr_ty
462-
}
456+
@cmt_ {
457+
id:id,
458+
span:span,
459+
cat:cat_static_item,
460+
mutbl: McImmutable,
461+
ty:expr_ty
462+
}
463+
}
464+
465+
ast::def_static(_, true) => {
466+
@cmt_ {
467+
id:id,
468+
span:span,
469+
cat:cat_static_item,
470+
mutbl: McDeclared,
471+
ty:expr_ty
472+
}
463473
}
464474

465475
ast::def_arg(vid, mutbl) => {
@@ -894,7 +904,7 @@ impl mem_categorization_ctxt {
894904
self.cat_pattern(cmt_field, subpat, op);
895905
}
896906
}
897-
Some(&ast::def_const(*)) => {
907+
Some(&ast::def_static(*)) => {
898908
for subpats.iter().advance |&subpat| {
899909
self.cat_pattern(cmt, subpat, op);
900910
}

src/librustc/middle/pat_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub fn pat_is_const(dm: resolve::DefMap, pat: &pat) -> bool {
4545
match pat.node {
4646
pat_ident(_, _, None) | pat_enum(*) => {
4747
match dm.find(&pat.id) {
48-
Some(&def_const(*)) => true,
48+
Some(&def_static(_, false)) => true,
4949
_ => false
5050
}
5151
}

0 commit comments

Comments
 (0)