Skip to content

Commit 8fdc8f3

Browse files
committed
Support foreign 'static mut' variables as well
1 parent 1841b31 commit 8fdc8f3

File tree

16 files changed

+129
-40
lines changed

16 files changed

+129
-40
lines changed

src/librustc/metadata/encoder.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1111,9 +1111,13 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
11111111
}
11121112
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
11131113
}
1114-
foreign_item_const(*) => {
1114+
foreign_item_static(_, mutbl) => {
11151115
encode_def_id(ebml_w, local_def(nitem.id));
1116-
encode_family(ebml_w, 'c');
1116+
if mutbl {
1117+
encode_family(ebml_w, 'b');
1118+
} else {
1119+
encode_family(ebml_w, 'c');
1120+
}
11171121
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
11181122
encode_symbol(ecx, ebml_w, nitem.id);
11191123
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));

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/resolve.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1566,8 +1566,8 @@ impl Resolver {
15661566
visit_foreign_item(foreign_item, (new_parent, visitor));
15671567
}
15681568
}
1569-
foreign_item_const(*) => {
1570-
let def = def_static(local_def(foreign_item.id), false);
1569+
foreign_item_static(_, m) => {
1570+
let def = def_static(local_def(foreign_item.id), m);
15711571
name_bindings.define_value(Public, def, foreign_item.span);
15721572

15731573
visit_foreign_item(foreign_item, (new_parent, visitor));
@@ -3665,7 +3665,7 @@ impl Resolver {
36653665
|| visit_foreign_item(*foreign_item,
36663666
((), visitor)));
36673667
}
3668-
foreign_item_const(_) => {
3668+
foreign_item_static(*) => {
36693669
visit_foreign_item(*foreign_item,
36703670
((), visitor));
36713671
}

src/librustc/middle/trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2463,7 +2463,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
24632463
ni.id,
24642464
ni.attrs)
24652465
}
2466-
ast::foreign_item_const(*) => {
2466+
ast::foreign_item_static(*) => {
24672467
let typ = ty::node_id_to_type(ccx.tcx, ni.id);
24682468
let ident = token::ident_to_str(&ni.ident);
24692469
let g = do str::as_c_str(ident) |buf| {

src/librustc/middle/trans/foreign.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
332332
}
333333
}
334334
}
335-
ast::foreign_item_const(*) => {
335+
ast::foreign_item_static(*) => {
336336
let ident = token::ident_to_str(&foreign_item.ident);
337337
ccx.item_symbols.insert(foreign_item.id, /* bad */ident.to_owned());
338338
}

src/librustc/middle/typeck/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
11531153
generics,
11541154
abis)
11551155
}
1156-
ast::foreign_item_const(t) => {
1156+
ast::foreign_item_static(t, _) => {
11571157
ty::ty_param_bounds_and_ty {
11581158
generics: ty::Generics {
11591159
type_param_defs: @~[],

src/librustdoc/extract.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ fn nmoddoc_from_mod(
150150
ast::foreign_item_fn(*) => {
151151
fns.push(fndoc_from_fn(ItemDoc));
152152
}
153-
ast::foreign_item_const(*) => {} // XXX: Not implemented.
153+
ast::foreign_item_static(*) => {} // XXX: Not implemented.
154154
}
155155
}
156156
doc::NmodDoc {

src/libsyntax/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ pub struct foreign_item {
11241124
#[deriving(Eq, Encodable, Decodable)]
11251125
pub enum foreign_item_ {
11261126
foreign_item_fn(fn_decl, purity, Generics),
1127-
foreign_item_const(@Ty)
1127+
foreign_item_static(@Ty, /* is_mutbl */ bool),
11281128
}
11291129

11301130
// The data we save and restore about an inlined item or method. This is not

src/libsyntax/fold.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold)
236236
purity,
237237
fold_generics(generics, fld))
238238
}
239-
foreign_item_const(t) => {
240-
foreign_item_const(fld.fold_ty(t))
239+
foreign_item_static(t, m) => {
240+
foreign_item_static(fld.fold_ty(t), m)
241241
}
242242
},
243243
id: fld.new_id(ni.id),

src/libsyntax/parse/parser.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use ast::{expr_vec, expr_vstore, expr_vstore_mut_box};
3333
use ast::{expr_vstore_slice, expr_vstore_box};
3434
use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
3535
use ast::{expr_vstore_uniq, Onceness, Once, Many};
36-
use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod};
36+
use ast::{foreign_item, foreign_item_static, foreign_item_fn, foreign_mod};
3737
use ast::{ident, impure_fn, inherited, item, item_, item_static};
3838
use ast::{item_enum, item_fn, item_foreign_mod, item_impl};
3939
use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
@@ -3684,6 +3684,7 @@ impl Parser {
36843684
} else {
36853685
self.expect_keyword(keywords::Static);
36863686
}
3687+
let mutbl = self.eat_keyword(keywords::Mut);
36873688

36883689
let ident = self.parse_ident();
36893690
self.expect(&token::COLON);
@@ -3692,7 +3693,7 @@ impl Parser {
36923693
self.expect(&token::SEMI);
36933694
@ast::foreign_item { ident: ident,
36943695
attrs: attrs,
3695-
node: foreign_item_const(ty),
3696+
node: foreign_item_static(ty, mutbl),
36963697
id: self.get_id(),
36973698
span: mk_sp(lo, hi),
36983699
vis: vis }

src/libsyntax/print/pprust.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,11 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) {
458458
word(s.s, ";");
459459
end(s); // end the outer fn box
460460
}
461-
ast::foreign_item_const(t) => {
461+
ast::foreign_item_static(t, m) => {
462462
head(s, "static");
463+
if m {
464+
word_space(s, "mut");
465+
}
463466
print_ident(s, item.ident);
464467
word_space(s, ":");
465468
print_type(s, t);

src/libsyntax/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ pub fn visit_foreign_item<E: Copy>(ni: @foreign_item, (e, v): (E, vt<E>)) {
326326
visit_fn_decl(fd, (copy e, v));
327327
(v.visit_generics)(generics, (e, v));
328328
}
329-
foreign_item_const(t) => {
329+
foreign_item_static(t, _) => {
330330
(v.visit_ty)(t, (e, v));
331331
}
332332
}

src/rt/rust_builtin.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ debug_abi_2(floats f) {
154154
return ff;
155155
}
156156

157+
extern "C" int
158+
debug_static_mut;
159+
160+
int debug_static_mut = 3;
161+
162+
extern "C" void
163+
debug_static_mut_check_four() {
164+
assert(debug_static_mut == 4);
165+
}
166+
157167
/* Debug builtins for std::dbg. */
158168

159169
static void

src/rt/rustrt.def.in

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ debug_tydesc
77
debug_get_stk_seg
88
debug_abi_1
99
debug_abi_2
10+
debug_static_mut
11+
debug_static_mut_check_four
1012
get_task_id
1113
get_time
1214
rust_tzset
@@ -239,4 +241,4 @@ rust_valgrind_stack_deregister
239241
rust_take_env_lock
240242
rust_drop_env_lock
241243
rust_update_log_settings
242-
rust_running_on_valgrind
244+
rust_running_on_valgrind
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::libc;
12+
13+
extern {
14+
static mut a: libc::c_int;
15+
}
16+
17+
fn main() {
18+
a += 3; //~ ERROR: requires unsafe
19+
a = 4; //~ ERROR: requires unsafe
20+
let _b = a; //~ ERROR: requires unsafe
21+
}
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Constants (static variables) can be used to match in patterns, but mutable
12+
// statics cannot. This ensures that there's some form of error if this is
13+
// attempted.
14+
15+
use std::libc;
16+
17+
#[nolink]
18+
extern {
19+
static mut debug_static_mut: libc::c_int;
20+
pub fn debug_static_mut_check_four();
21+
}
22+
23+
unsafe fn static_bound(_: &'static libc::c_int) {}
24+
25+
fn static_bound_set(a: &'static mut libc::c_int) {
26+
*a = 3;
27+
}
28+
29+
unsafe fn run() {
30+
assert!(debug_static_mut == 3);
31+
debug_static_mut = 4;
32+
assert!(debug_static_mut == 4);
33+
debug_static_mut_check_four();
34+
debug_static_mut += 1;
35+
assert!(debug_static_mut == 5);
36+
debug_static_mut *= 3;
37+
assert!(debug_static_mut == 15);
38+
debug_static_mut = -3;
39+
assert!(debug_static_mut == -3);
40+
static_bound(&debug_static_mut);
41+
static_bound_set(&mut debug_static_mut);
42+
}
43+
44+
fn main() {
45+
unsafe { run() }
46+
}

0 commit comments

Comments
 (0)