Support foreign 'static mut' variables as well
This commit is contained in:
parent
1841b31c61
commit
8fdc8f392c
@ -1111,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));
|
||||
|
@ -709,28 +709,31 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -738,11 +741,10 @@ fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) {
|
||||
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); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1566,8 +1566,8 @@ pub fn build_reduced_graph_for_foreign_item(@mut self,
|
||||
visit_foreign_item(foreign_item, (new_parent, visitor));
|
||||
}
|
||||
}
|
||||
foreign_item_const(*) => {
|
||||
let def = def_static(local_def(foreign_item.id), false);
|
||||
foreign_item_static(_, m) => {
|
||||
let def = def_static(local_def(foreign_item.id), m);
|
||||
name_bindings.define_value(Public, def, foreign_item.span);
|
||||
|
||||
visit_foreign_item(foreign_item, (new_parent, visitor));
|
||||
@ -3665,7 +3665,7 @@ pub fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) {
|
||||
|| visit_foreign_item(*foreign_item,
|
||||
((), visitor)));
|
||||
}
|
||||
foreign_item_const(_) => {
|
||||
foreign_item_static(*) => {
|
||||
visit_foreign_item(*foreign_item,
|
||||
((), visitor));
|
||||
}
|
||||
|
@ -2463,7 +2463,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||
ni.id,
|
||||
ni.attrs)
|
||||
}
|
||||
ast::foreign_item_const(*) => {
|
||||
ast::foreign_item_static(*) => {
|
||||
let typ = ty::node_id_to_type(ccx.tcx, ni.id);
|
||||
let ident = token::ident_to_str(&ni.ident);
|
||||
let g = do str::as_c_str(ident) |buf| {
|
||||
|
@ -332,7 +332,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::foreign_item_const(*) => {
|
||||
ast::foreign_item_static(*) => {
|
||||
let ident = token::ident_to_str(&foreign_item.ident);
|
||||
ccx.item_symbols.insert(foreign_item.id, /* bad */ident.to_owned());
|
||||
}
|
||||
|
@ -1153,7 +1153,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
|
||||
generics,
|
||||
abis)
|
||||
}
|
||||
ast::foreign_item_const(t) => {
|
||||
ast::foreign_item_static(t, _) => {
|
||||
ty::ty_param_bounds_and_ty {
|
||||
generics: ty::Generics {
|
||||
type_param_defs: @~[],
|
||||
|
@ -150,7 +150,7 @@ fn nmoddoc_from_mod(
|
||||
ast::foreign_item_fn(*) => {
|
||||
fns.push(fndoc_from_fn(ItemDoc));
|
||||
}
|
||||
ast::foreign_item_const(*) => {} // XXX: Not implemented.
|
||||
ast::foreign_item_static(*) => {} // XXX: Not implemented.
|
||||
}
|
||||
}
|
||||
doc::NmodDoc {
|
||||
|
@ -1124,7 +1124,7 @@ pub struct foreign_item {
|
||||
#[deriving(Eq, Encodable, Decodable)]
|
||||
pub enum foreign_item_ {
|
||||
foreign_item_fn(fn_decl, purity, Generics),
|
||||
foreign_item_const(@Ty)
|
||||
foreign_item_static(@Ty, /* is_mutbl */ bool),
|
||||
}
|
||||
|
||||
// The data we save and restore about an inlined item or method. This is not
|
||||
|
@ -236,8 +236,8 @@ fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold)
|
||||
purity,
|
||||
fold_generics(generics, fld))
|
||||
}
|
||||
foreign_item_const(t) => {
|
||||
foreign_item_const(fld.fold_ty(t))
|
||||
foreign_item_static(t, m) => {
|
||||
foreign_item_static(fld.fold_ty(t), m)
|
||||
}
|
||||
},
|
||||
id: fld.new_id(ni.id),
|
||||
|
@ -33,7 +33,7 @@
|
||||
use ast::{expr_vstore_slice, expr_vstore_box};
|
||||
use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
|
||||
use ast::{expr_vstore_uniq, Onceness, Once, Many};
|
||||
use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod};
|
||||
use ast::{foreign_item, foreign_item_static, foreign_item_fn, foreign_mod};
|
||||
use ast::{ident, impure_fn, inherited, item, item_, item_static};
|
||||
use ast::{item_enum, item_fn, item_foreign_mod, item_impl};
|
||||
use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
|
||||
@ -3684,6 +3684,7 @@ fn parse_item_foreign_const(&self, vis: ast::visibility,
|
||||
} else {
|
||||
self.expect_keyword(keywords::Static);
|
||||
}
|
||||
let mutbl = self.eat_keyword(keywords::Mut);
|
||||
|
||||
let ident = self.parse_ident();
|
||||
self.expect(&token::COLON);
|
||||
@ -3692,7 +3693,7 @@ fn parse_item_foreign_const(&self, vis: ast::visibility,
|
||||
self.expect(&token::SEMI);
|
||||
@ast::foreign_item { ident: ident,
|
||||
attrs: attrs,
|
||||
node: foreign_item_const(ty),
|
||||
node: foreign_item_static(ty, mutbl),
|
||||
id: self.get_id(),
|
||||
span: mk_sp(lo, hi),
|
||||
vis: vis }
|
||||
|
@ -458,8 +458,11 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) {
|
||||
word(s.s, ";");
|
||||
end(s); // end the outer fn box
|
||||
}
|
||||
ast::foreign_item_const(t) => {
|
||||
ast::foreign_item_static(t, m) => {
|
||||
head(s, "static");
|
||||
if m {
|
||||
word_space(s, "mut");
|
||||
}
|
||||
print_ident(s, item.ident);
|
||||
word_space(s, ":");
|
||||
print_type(s, t);
|
||||
|
@ -326,7 +326,7 @@ pub fn visit_foreign_item<E: Copy>(ni: @foreign_item, (e, v): (E, vt<E>)) {
|
||||
visit_fn_decl(fd, (copy e, v));
|
||||
(v.visit_generics)(generics, (e, v));
|
||||
}
|
||||
foreign_item_const(t) => {
|
||||
foreign_item_static(t, _) => {
|
||||
(v.visit_ty)(t, (e, v));
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +154,16 @@ debug_abi_2(floats f) {
|
||||
return ff;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
debug_static_mut;
|
||||
|
||||
int debug_static_mut = 3;
|
||||
|
||||
extern "C" void
|
||||
debug_static_mut_check_four() {
|
||||
assert(debug_static_mut == 4);
|
||||
}
|
||||
|
||||
/* Debug builtins for std::dbg. */
|
||||
|
||||
static void
|
||||
|
@ -7,6 +7,8 @@ debug_tydesc
|
||||
debug_get_stk_seg
|
||||
debug_abi_1
|
||||
debug_abi_2
|
||||
debug_static_mut
|
||||
debug_static_mut_check_four
|
||||
get_task_id
|
||||
get_time
|
||||
rust_tzset
|
||||
@ -239,4 +241,4 @@ rust_valgrind_stack_deregister
|
||||
rust_take_env_lock
|
||||
rust_drop_env_lock
|
||||
rust_update_log_settings
|
||||
rust_running_on_valgrind
|
||||
rust_running_on_valgrind
|
||||
|
21
src/test/compile-fail/static-mut-foreign-requires-unsafe.rs
Normal file
21
src/test/compile-fail/static-mut-foreign-requires-unsafe.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::libc;
|
||||
|
||||
extern {
|
||||
static mut a: libc::c_int;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
a += 3; //~ ERROR: requires unsafe
|
||||
a = 4; //~ ERROR: requires unsafe
|
||||
let _b = a; //~ ERROR: requires unsafe
|
||||
}
|
46
src/test/run-pass/static-mut-foreign.rs
Normal file
46
src/test/run-pass/static-mut-foreign.rs
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Constants (static variables) can be used to match in patterns, but mutable
|
||||
// statics cannot. This ensures that there's some form of error if this is
|
||||
// attempted.
|
||||
|
||||
use std::libc;
|
||||
|
||||
#[nolink]
|
||||
extern {
|
||||
static mut debug_static_mut: libc::c_int;
|
||||
pub fn debug_static_mut_check_four();
|
||||
}
|
||||
|
||||
unsafe fn static_bound(_: &'static libc::c_int) {}
|
||||
|
||||
fn static_bound_set(a: &'static mut libc::c_int) {
|
||||
*a = 3;
|
||||
}
|
||||
|
||||
unsafe fn run() {
|
||||
assert!(debug_static_mut == 3);
|
||||
debug_static_mut = 4;
|
||||
assert!(debug_static_mut == 4);
|
||||
debug_static_mut_check_four();
|
||||
debug_static_mut += 1;
|
||||
assert!(debug_static_mut == 5);
|
||||
debug_static_mut *= 3;
|
||||
assert!(debug_static_mut == 15);
|
||||
debug_static_mut = -3;
|
||||
assert!(debug_static_mut == -3);
|
||||
static_bound(&debug_static_mut);
|
||||
static_bound_set(&mut debug_static_mut);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { run() }
|
||||
}
|
Loading…
Reference in New Issue
Block a user