Add 'static mut' items to the language
This commit is contained in:
parent
f82756180b
commit
1841b31c61
34 changed files with 230 additions and 70 deletions
|
@ -97,7 +97,8 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
enum Family {
|
enum Family {
|
||||||
Const, // c
|
ImmStatic, // c
|
||||||
|
MutStatic, // b
|
||||||
Fn, // f
|
Fn, // f
|
||||||
UnsafeFn, // u
|
UnsafeFn, // u
|
||||||
PureFn, // p
|
PureFn, // p
|
||||||
|
@ -122,7 +123,8 @@ enum Family {
|
||||||
fn item_family(item: ebml::Doc) -> Family {
|
fn item_family(item: ebml::Doc) -> Family {
|
||||||
let fam = reader::get_doc(item, tag_items_data_item_family);
|
let fam = reader::get_doc(item, tag_items_data_item_family);
|
||||||
match reader::doc_as_u8(fam) as char {
|
match reader::doc_as_u8(fam) as char {
|
||||||
'c' => Const,
|
'c' => ImmStatic,
|
||||||
|
'b' => MutStatic,
|
||||||
'f' => Fn,
|
'f' => Fn,
|
||||||
'u' => UnsafeFn,
|
'u' => UnsafeFn,
|
||||||
'p' => PureFn,
|
'p' => PureFn,
|
||||||
|
@ -321,7 +323,8 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
|
||||||
-> def_like {
|
-> def_like {
|
||||||
let fam = item_family(item);
|
let fam = item_family(item);
|
||||||
match fam {
|
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)),
|
Struct => dl_def(ast::def_struct(did)),
|
||||||
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
|
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
|
||||||
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
|
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
|
||||||
|
@ -900,8 +903,8 @@ pub fn get_item_visibility(cdata: cmd, id: ast::node_id)
|
||||||
|
|
||||||
fn family_has_type_params(fam: Family) -> bool {
|
fn family_has_type_params(fam: Family) -> bool {
|
||||||
match fam {
|
match fam {
|
||||||
Const | ForeignType | Mod | ForeignMod | PublicField | PrivateField
|
ImmStatic | ForeignType | Mod | ForeignMod | PublicField | PrivateField
|
||||||
| ForeignFn => false,
|
| ForeignFn | MutStatic => false,
|
||||||
_ => true
|
_ => true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -931,7 +934,8 @@ fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {
|
||||||
|
|
||||||
fn item_family_to_str(fam: Family) -> ~str {
|
fn item_family_to_str(fam: Family) -> ~str {
|
||||||
match fam {
|
match fam {
|
||||||
Const => ~"const",
|
ImmStatic => ~"static",
|
||||||
|
MutStatic => ~"static mut",
|
||||||
Fn => ~"fn",
|
Fn => ~"fn",
|
||||||
UnsafeFn => ~"unsafe fn",
|
UnsafeFn => ~"unsafe fn",
|
||||||
PureFn => ~"pure fn",
|
PureFn => ~"pure fn",
|
||||||
|
|
|
@ -785,7 +785,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
let must_write =
|
let must_write =
|
||||||
match item.node {
|
match item.node {
|
||||||
item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
|
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
|
_ => false
|
||||||
};
|
};
|
||||||
if !must_write && !reachable(ecx, item.id) { return; }
|
if !must_write && !reachable(ecx, item.id) { return; }
|
||||||
|
@ -800,11 +800,15 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
ecx.tcx.sess.codemap.span_to_str(item.span));
|
ecx.tcx.sess.codemap.span_to_str(item.span));
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
item_const(_, _) => {
|
item_static(_, m, _) => {
|
||||||
add_to_index();
|
add_to_index();
|
||||||
ebml_w.start_tag(tag_items_data_item);
|
ebml_w.start_tag(tag_items_data_item);
|
||||||
encode_def_id(ebml_w, local_def(item.id));
|
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_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||||
encode_symbol(ecx, ebml_w, item.id);
|
encode_symbol(ecx, ebml_w, item.id);
|
||||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||||
|
|
|
@ -384,7 +384,7 @@ impl tr for ast::def {
|
||||||
ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) }
|
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_mod(did) => { ast::def_mod(did.tr(xcx)) }
|
||||||
ast::def_foreign_mod(did) => { ast::def_foreign_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_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_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) }
|
||||||
ast::def_variant(e_did, v_did) => {
|
ast::def_variant(e_did, v_did) => {
|
||||||
|
|
|
@ -43,7 +43,7 @@ pub fn check_item(sess: Session,
|
||||||
(_is_const, v): (bool,
|
(_is_const, v): (bool,
|
||||||
visit::vt<bool>)) {
|
visit::vt<bool>)) {
|
||||||
match it.node {
|
match it.node {
|
||||||
item_const(_, ex) => {
|
item_static(_, _, ex) => {
|
||||||
(v.visit_expr)(ex, (true, v));
|
(v.visit_expr)(ex, (true, v));
|
||||||
check_item_recursion(sess, ast_map, def_map, it);
|
check_item_recursion(sess, ast_map, def_map, it);
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ pub fn check_expr(sess: Session,
|
||||||
items without type parameters");
|
items without type parameters");
|
||||||
}
|
}
|
||||||
match def_map.find(&e.id) {
|
match def_map.find(&e.id) {
|
||||||
Some(&def_const(_)) |
|
Some(&def_static(*)) |
|
||||||
Some(&def_fn(_, _)) |
|
Some(&def_fn(_, _)) |
|
||||||
Some(&def_variant(_, _)) |
|
Some(&def_variant(_, _)) |
|
||||||
Some(&def_struct(_)) => { }
|
Some(&def_struct(_)) => { }
|
||||||
|
@ -237,7 +237,7 @@ pub fn check_item_recursion(sess: Session,
|
||||||
match e.node {
|
match e.node {
|
||||||
expr_path(*) => {
|
expr_path(*) => {
|
||||||
match env.def_map.find(&e.id) {
|
match env.def_map.find(&e.id) {
|
||||||
Some(&def_const(def_id)) => {
|
Some(&def_static(def_id, _)) => {
|
||||||
if ast_util::is_local(def_id) {
|
if ast_util::is_local(def_id) {
|
||||||
match env.ast_map.get_copy(&def_id.node) {
|
match env.ast_map.get_copy(&def_id.node) {
|
||||||
ast_map::node_item(it, _) => {
|
ast_map::node_item(it, _) => {
|
||||||
|
|
|
@ -304,7 +304,7 @@ pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option<ctor> {
|
||||||
pat_ident(_, _, _) | pat_enum(_, _) => {
|
pat_ident(_, _, _) | pat_enum(_, _) => {
|
||||||
match cx.tcx.def_map.find(&pat.id) {
|
match cx.tcx.def_map.find(&pat.id) {
|
||||||
Some(&def_variant(_, id)) => Some(variant(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();
|
let const_expr = lookup_const_by_id(cx.tcx, did).get();
|
||||||
Some(val(eval_const_expr(cx.tcx, const_expr)))
|
Some(val(eval_const_expr(cx.tcx, const_expr)))
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ pub fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool {
|
||||||
pat_wild => { true }
|
pat_wild => { true }
|
||||||
pat_ident(_, _, _) => {
|
pat_ident(_, _, _) => {
|
||||||
match cx.tcx.def_map.find(&pat.id) {
|
match cx.tcx.def_map.find(&pat.id) {
|
||||||
Some(&def_variant(_, _)) | Some(&def_const(*)) => { false }
|
Some(&def_variant(_, _)) | Some(&def_static(*)) => { false }
|
||||||
_ => { true }
|
_ => { true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,7 +499,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&def_const(did)) => {
|
Some(&def_static(did, _)) => {
|
||||||
let const_expr =
|
let const_expr =
|
||||||
lookup_const_by_id(cx.tcx, did).get();
|
lookup_const_by_id(cx.tcx, did).get();
|
||||||
let e_v = eval_const_expr(cx.tcx, const_expr);
|
let e_v = eval_const_expr(cx.tcx, const_expr);
|
||||||
|
@ -549,7 +549,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
|
||||||
}
|
}
|
||||||
pat_enum(_, args) => {
|
pat_enum(_, args) => {
|
||||||
match cx.tcx.def_map.get_copy(&pat_id) {
|
match cx.tcx.def_map.get_copy(&pat_id) {
|
||||||
def_const(did) => {
|
def_static(did, _) => {
|
||||||
let const_expr =
|
let const_expr =
|
||||||
lookup_const_by_id(cx.tcx, did).get();
|
lookup_const_by_id(cx.tcx, did).get();
|
||||||
let e_v = eval_const_expr(cx.tcx, const_expr);
|
let e_v = eval_const_expr(cx.tcx, const_expr);
|
||||||
|
@ -790,7 +790,7 @@ pub fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&def_const(*)) => return true,
|
Some(&def_static(*)) => return true,
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ pub fn classify(e: @expr,
|
||||||
|
|
||||||
pub fn lookup_const(tcx: ty::ctxt, e: @expr) -> Option<@expr> {
|
pub fn lookup_const(tcx: ty::ctxt, e: @expr) -> Option<@expr> {
|
||||||
match tcx.def_map.find(&e.id) {
|
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
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
|
||||||
match tcx.items.find(&def_id.node) {
|
match tcx.items.find(&def_id.node) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(&ast_map::node_item(it, _)) => match it.node {
|
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
|
_ => None
|
||||||
},
|
},
|
||||||
Some(_) => None
|
Some(_) => None
|
||||||
|
@ -195,7 +195,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
|
||||||
match csearch::maybe_get_item_ast(tcx, def_id,
|
match csearch::maybe_get_item_ast(tcx, def_id,
|
||||||
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) {
|
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) {
|
||||||
csearch::found(ast::ii_item(item)) => match item.node {
|
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
|
||||||
},
|
},
|
||||||
_ => None
|
_ => None
|
||||||
|
|
|
@ -17,7 +17,7 @@ use middle::typeck::method_map;
|
||||||
use util::ppaux;
|
use util::ppaux;
|
||||||
|
|
||||||
use syntax::ast::{deref, expr_call, expr_inline_asm, expr_method_call};
|
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::ast;
|
||||||
use syntax::codemap::span;
|
use syntax::codemap::span;
|
||||||
use syntax::visit::{fk_item_fn, fk_method};
|
use syntax::visit::{fk_item_fn, fk_method};
|
||||||
|
@ -143,6 +143,14 @@ pub fn check_crate(tcx: ty::ctxt,
|
||||||
expr_inline_asm(*) => {
|
expr_inline_asm(*) => {
|
||||||
require_unsafe(expr.span, "use of inline assembly")
|
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")
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -447,19 +447,29 @@ impl mem_categorization_ctxt {
|
||||||
-> cmt {
|
-> cmt {
|
||||||
match def {
|
match def {
|
||||||
ast::def_fn(*) | ast::def_static_method(*) | ast::def_mod(_) |
|
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_use(_) | ast::def_variant(*) |
|
||||||
ast::def_trait(_) | ast::def_ty(_) | ast::def_prim_ty(_) |
|
ast::def_trait(_) | ast::def_ty(_) | ast::def_prim_ty(_) |
|
||||||
ast::def_ty_param(*) | ast::def_struct(*) |
|
ast::def_ty_param(*) | ast::def_struct(*) |
|
||||||
ast::def_typaram_binder(*) | ast::def_region(_) |
|
ast::def_typaram_binder(*) | ast::def_region(_) |
|
||||||
ast::def_label(_) | ast::def_self_ty(*) => {
|
ast::def_label(_) | ast::def_self_ty(*) => {
|
||||||
@cmt_ {
|
@cmt_ {
|
||||||
id:id,
|
id:id,
|
||||||
span:span,
|
span:span,
|
||||||
cat:cat_static_item,
|
cat:cat_static_item,
|
||||||
mutbl: McImmutable,
|
mutbl: McImmutable,
|
||||||
ty:expr_ty
|
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) => {
|
ast::def_arg(vid, mutbl) => {
|
||||||
|
@ -894,7 +904,7 @@ impl mem_categorization_ctxt {
|
||||||
self.cat_pattern(cmt_field, subpat, op);
|
self.cat_pattern(cmt_field, subpat, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&ast::def_const(*)) => {
|
Some(&ast::def_static(*)) => {
|
||||||
for subpats.iter().advance |&subpat| {
|
for subpats.iter().advance |&subpat| {
|
||||||
self.cat_pattern(cmt, subpat, op);
|
self.cat_pattern(cmt, subpat, op);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub fn pat_is_const(dm: resolve::DefMap, pat: &pat) -> bool {
|
||||||
match pat.node {
|
match pat.node {
|
||||||
pat_ident(_, _, None) | pat_enum(*) => {
|
pat_ident(_, _, None) | pat_enum(*) => {
|
||||||
match dm.find(&pat.id) {
|
match dm.find(&pat.id) {
|
||||||
Some(&def_const(*)) => true,
|
Some(&def_static(_, false)) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1146,12 +1146,13 @@ impl Resolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
// These items live in the value namespace.
|
// These items live in the value namespace.
|
||||||
item_const(*) => {
|
item_static(_, m, _) => {
|
||||||
let (name_bindings, _) =
|
let (name_bindings, _) =
|
||||||
self.add_child(ident, parent, ForbidDuplicateValues, sp);
|
self.add_child(ident, parent, ForbidDuplicateValues, sp);
|
||||||
|
let mutbl = m == ast::m_mutbl;
|
||||||
|
|
||||||
name_bindings.define_value
|
name_bindings.define_value
|
||||||
(privacy, def_const(local_def(item.id)), sp);
|
(privacy, def_static(local_def(item.id), mutbl), sp);
|
||||||
}
|
}
|
||||||
item_fn(_, purity, _, _, _) => {
|
item_fn(_, purity, _, _, _) => {
|
||||||
let (name_bindings, new_parent) =
|
let (name_bindings, new_parent) =
|
||||||
|
@ -1566,7 +1567,7 @@ impl Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreign_item_const(*) => {
|
foreign_item_const(*) => {
|
||||||
let def = def_const(local_def(foreign_item.id));
|
let def = def_static(local_def(foreign_item.id), false);
|
||||||
name_bindings.define_value(Public, def, foreign_item.span);
|
name_bindings.define_value(Public, def, foreign_item.span);
|
||||||
|
|
||||||
visit_foreign_item(foreign_item, (new_parent, visitor));
|
visit_foreign_item(foreign_item, (new_parent, visitor));
|
||||||
|
@ -1673,7 +1674,7 @@ impl Resolver {
|
||||||
let privacy = variant_visibility_to_privacy(visibility, true);
|
let privacy = variant_visibility_to_privacy(visibility, true);
|
||||||
child_name_bindings.define_value(privacy, def, dummy_sp());
|
child_name_bindings.define_value(privacy, def, dummy_sp());
|
||||||
}
|
}
|
||||||
def_fn(*) | def_static_method(*) | def_const(*) => {
|
def_fn(*) | def_static_method(*) | def_static(*) => {
|
||||||
debug!("(building reduced graph for external \
|
debug!("(building reduced graph for external \
|
||||||
crate) building value %s", final_ident);
|
crate) building value %s", final_ident);
|
||||||
child_name_bindings.define_value(privacy, def, dummy_sp());
|
child_name_bindings.define_value(privacy, def, dummy_sp());
|
||||||
|
@ -3686,7 +3687,7 @@ impl Resolver {
|
||||||
visitor);
|
visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
item_const(*) => {
|
item_static(*) => {
|
||||||
self.with_constant_rib(|| {
|
self.with_constant_rib(|| {
|
||||||
visit_item(item, ((), visitor));
|
visit_item(item, ((), visitor));
|
||||||
});
|
});
|
||||||
|
@ -4344,7 +4345,7 @@ impl Resolver {
|
||||||
Some(def @ def_struct(*)) => {
|
Some(def @ def_struct(*)) => {
|
||||||
self.record_def(pattern.id, def);
|
self.record_def(pattern.id, def);
|
||||||
}
|
}
|
||||||
Some(def @ def_const(*)) => {
|
Some(def @ def_static(*)) => {
|
||||||
self.enforce_default_binding_mode(
|
self.enforce_default_binding_mode(
|
||||||
pattern,
|
pattern,
|
||||||
binding_mode,
|
binding_mode,
|
||||||
|
@ -4376,7 +4377,7 @@ impl Resolver {
|
||||||
Some(def @ def_fn(*)) |
|
Some(def @ def_fn(*)) |
|
||||||
Some(def @ def_variant(*)) |
|
Some(def @ def_variant(*)) |
|
||||||
Some(def @ def_struct(*)) |
|
Some(def @ def_struct(*)) |
|
||||||
Some(def @ def_const(*)) => {
|
Some(def @ def_static(*)) => {
|
||||||
self.record_def(pattern.id, def);
|
self.record_def(pattern.id, def);
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
@ -4459,7 +4460,7 @@ impl Resolver {
|
||||||
def @ def_variant(*) | def @ def_struct(*) => {
|
def @ def_variant(*) | def @ def_struct(*) => {
|
||||||
return FoundStructOrEnumVariant(def);
|
return FoundStructOrEnumVariant(def);
|
||||||
}
|
}
|
||||||
def @ def_const(*) => {
|
def @ def_static(_, false) => {
|
||||||
return FoundConst(def);
|
return FoundConst(def);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -820,7 +820,7 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] {
|
||||||
add_to_set(ccx.tcx, &mut found,
|
add_to_set(ccx.tcx, &mut found,
|
||||||
lit(UnitLikeStructLit(cur.id)));
|
lit(UnitLikeStructLit(cur.id)));
|
||||||
}
|
}
|
||||||
Some(&ast::def_const(const_did)) => {
|
Some(&ast::def_static(const_did, false)) => {
|
||||||
add_to_set(ccx.tcx, &mut found,
|
add_to_set(ccx.tcx, &mut found,
|
||||||
lit(ConstLit(const_did)));
|
lit(ConstLit(const_did)));
|
||||||
}
|
}
|
||||||
|
@ -836,7 +836,7 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] {
|
||||||
add_to_set(ccx.tcx, &mut found,
|
add_to_set(ccx.tcx, &mut found,
|
||||||
variant_opt(bcx, cur.id));
|
variant_opt(bcx, cur.id));
|
||||||
}
|
}
|
||||||
Some(&ast::def_const(const_did)) => {
|
Some(&ast::def_static(const_did, false)) => {
|
||||||
add_to_set(ccx.tcx, &mut found,
|
add_to_set(ccx.tcx, &mut found,
|
||||||
lit(ConstLit(const_did)));
|
lit(ConstLit(const_did)));
|
||||||
}
|
}
|
||||||
|
@ -1831,8 +1831,9 @@ pub fn bind_irrefutable_pat(bcx: block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&ast::def_const(*)) => {
|
Some(&ast::def_static(_, false)) => {
|
||||||
bcx = bind_irrefutable_pat(bcx, pat, val, make_copy, binding_mode);
|
bcx = bind_irrefutable_pat(bcx, pat, val, make_copy,
|
||||||
|
binding_mode);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Nothing to do here.
|
// Nothing to do here.
|
||||||
|
|
|
@ -2122,14 +2122,19 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
|
||||||
trans_enum_def(ccx, enum_definition, item.id, vi, &mut i);
|
trans_enum_def(ccx, enum_definition, item.id, vi, &mut i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::item_const(_, expr) => {
|
ast::item_static(_, m, expr) => {
|
||||||
consts::trans_const(ccx, expr, item.id);
|
consts::trans_const(ccx, m, item.id);
|
||||||
// Do static_assert checking. It can't really be done much earlier because we need to get
|
// Do static_assert checking. It can't really be done much earlier because we need to get
|
||||||
// the value of the bool out of LLVM
|
// the value of the bool out of LLVM
|
||||||
for item.attrs.iter().advance |attr| {
|
for item.attrs.iter().advance |attr| {
|
||||||
match attr.node.value.node {
|
match attr.node.value.node {
|
||||||
ast::meta_word(x) => {
|
ast::meta_word(x) => {
|
||||||
if x.slice(0, x.len()) == "static_assert" {
|
if x.slice(0, x.len()) == "static_assert" {
|
||||||
|
if m == ast::m_mutbl {
|
||||||
|
ccx.sess.span_fatal(expr.span,
|
||||||
|
"cannot have static_assert \
|
||||||
|
on a mutable static");
|
||||||
|
}
|
||||||
let v = ccx.const_values.get_copy(&item.id);
|
let v = ccx.const_values.get_copy(&item.id);
|
||||||
unsafe {
|
unsafe {
|
||||||
if !(llvm::LLVMConstIntGetZExtValue(v) as bool) {
|
if !(llvm::LLVMConstIntGetZExtValue(v) as bool) {
|
||||||
|
@ -2398,13 +2403,14 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||||
let my_path = vec::append(/*bad*/copy *pth,
|
let my_path = vec::append(/*bad*/copy *pth,
|
||||||
[path_name(i.ident)]);
|
[path_name(i.ident)]);
|
||||||
match i.node {
|
match i.node {
|
||||||
ast::item_const(_, expr) => {
|
ast::item_static(_, m, expr) => {
|
||||||
let typ = ty::node_id_to_type(ccx.tcx, i.id);
|
let typ = ty::node_id_to_type(ccx.tcx, i.id);
|
||||||
let s = mangle_exported_name(ccx, my_path, typ);
|
let s = mangle_exported_name(ccx, my_path, typ);
|
||||||
// We need the translated value here, because for enums the
|
// We need the translated value here, because for enums the
|
||||||
// LLVM type is not fully determined by the Rust type.
|
// LLVM type is not fully determined by the Rust type.
|
||||||
let v = consts::const_expr(ccx, expr);
|
let v = consts::const_expr(ccx, expr);
|
||||||
ccx.const_values.insert(id, v);
|
ccx.const_values.insert(id, v);
|
||||||
|
exprt = m == ast::m_mutbl;
|
||||||
unsafe {
|
unsafe {
|
||||||
let llty = llvm::LLVMTypeOf(v);
|
let llty = llvm::LLVMTypeOf(v);
|
||||||
let g = str::as_c_str(s, |buf| {
|
let g = str::as_c_str(s, |buf| {
|
||||||
|
|
|
@ -143,7 +143,7 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
|
||||||
datum_callee(bcx, ref_expr)
|
datum_callee(bcx, ref_expr)
|
||||||
}
|
}
|
||||||
ast::def_mod(*) | ast::def_foreign_mod(*) | ast::def_trait(*) |
|
ast::def_mod(*) | ast::def_foreign_mod(*) | ast::def_trait(*) |
|
||||||
ast::def_const(*) | ast::def_ty(*) | ast::def_prim_ty(*) |
|
ast::def_static(*) | ast::def_ty(*) | ast::def_prim_ty(*) |
|
||||||
ast::def_use(*) | ast::def_typaram_binder(*) |
|
ast::def_use(*) | ast::def_typaram_binder(*) |
|
||||||
ast::def_region(*) | ast::def_label(*) | ast::def_ty_param(*) |
|
ast::def_region(*) | ast::def_label(*) | ast::def_ty_param(*) |
|
||||||
ast::def_self_ty(*) => {
|
ast::def_self_ty(*) => {
|
||||||
|
|
|
@ -164,9 +164,9 @@ pub fn get_const_val(cx: @mut CrateContext, mut def_id: ast::def_id) -> ValueRef
|
||||||
}
|
}
|
||||||
match cx.tcx.items.get_copy(&def_id.node) {
|
match cx.tcx.items.get_copy(&def_id.node) {
|
||||||
ast_map::node_item(@ast::item {
|
ast_map::node_item(@ast::item {
|
||||||
node: ast::item_const(_, subexpr), _
|
node: ast::item_static(_, ast::m_imm, _), _
|
||||||
}, _) => {
|
}, _) => {
|
||||||
trans_const(cx, subexpr, def_id.node);
|
trans_const(cx, ast::m_imm, def_id.node);
|
||||||
}
|
}
|
||||||
_ => cx.tcx.sess.bug("expected a const to be an item")
|
_ => cx.tcx.sess.bug("expected a const to be an item")
|
||||||
}
|
}
|
||||||
|
@ -538,7 +538,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
|
||||||
base::get_item_val(cx, def_id.node)
|
base::get_item_val(cx, def_id.node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&ast::def_const(def_id)) => {
|
Some(&ast::def_static(def_id, false)) => {
|
||||||
get_const_val(cx, def_id)
|
get_const_val(cx, def_id)
|
||||||
}
|
}
|
||||||
Some(&ast::def_variant(enum_did, variant_did)) => {
|
Some(&ast::def_variant(enum_did, variant_did)) => {
|
||||||
|
@ -587,7 +587,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trans_const(ccx: @mut CrateContext, _e: @ast::expr, id: ast::node_id) {
|
pub fn trans_const(ccx: @mut CrateContext, m: ast::mutability, id: ast::node_id) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _icx = push_ctxt("trans_const");
|
let _icx = push_ctxt("trans_const");
|
||||||
let g = base::get_item_val(ccx, id);
|
let g = base::get_item_val(ccx, id);
|
||||||
|
@ -595,6 +595,8 @@ pub fn trans_const(ccx: @mut CrateContext, _e: @ast::expr, id: ast::node_id) {
|
||||||
// constant's initializer to determine its LLVM type.
|
// constant's initializer to determine its LLVM type.
|
||||||
let v = ccx.const_values.get_copy(&id);
|
let v = ccx.const_values.get_copy(&id);
|
||||||
llvm::LLVMSetInitializer(g, v);
|
llvm::LLVMSetInitializer(g, v);
|
||||||
llvm::LLVMSetGlobalConstant(g, True);
|
if m != ast::m_mutbl {
|
||||||
|
llvm::LLVMSetGlobalConstant(g, True);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -945,7 +945,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||||
let _icx = push_ctxt("trans_def_lvalue");
|
let _icx = push_ctxt("trans_def_lvalue");
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
match def {
|
match def {
|
||||||
ast::def_const(did) => {
|
ast::def_static(did, _) => {
|
||||||
let const_ty = expr_ty(bcx, ref_expr);
|
let const_ty = expr_ty(bcx, ref_expr);
|
||||||
|
|
||||||
fn get_did(ccx: @mut CrateContext, did: ast::def_id)
|
fn get_did(ccx: @mut CrateContext, did: ast::def_id)
|
||||||
|
|
|
@ -146,7 +146,7 @@ fn traverse_public_item(cx: @mut ctx, item: @item) {
|
||||||
visit::mk_vt(@visit::Visitor {visit_ty: traverse_ty,
|
visit::mk_vt(@visit::Visitor {visit_ty: traverse_ty,
|
||||||
..*visit::default_visitor()})))
|
..*visit::default_visitor()})))
|
||||||
}
|
}
|
||||||
item_const(*) |
|
item_static(*) |
|
||||||
item_enum(*) | item_trait(*) => (),
|
item_enum(*) | item_trait(*) => (),
|
||||||
item_mac(*) => fail!("item macros unimplemented")
|
item_mac(*) => fail!("item macros unimplemented")
|
||||||
}
|
}
|
||||||
|
|
|
@ -3269,7 +3269,7 @@ pub fn expr_kind(tcx: ctxt,
|
||||||
// Note: there is actually a good case to be made that
|
// Note: there is actually a good case to be made that
|
||||||
// def_args, particularly those of immediate type, ought to
|
// def_args, particularly those of immediate type, ought to
|
||||||
// considered rvalues.
|
// considered rvalues.
|
||||||
ast::def_const(*) |
|
ast::def_static(*) |
|
||||||
ast::def_binding(*) |
|
ast::def_binding(*) |
|
||||||
ast::def_upvar(*) |
|
ast::def_upvar(*) |
|
||||||
ast::def_arg(*) |
|
ast::def_arg(*) |
|
||||||
|
|
|
@ -585,7 +585,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
|
||||||
match it.node {
|
match it.node {
|
||||||
ast::item_const(_, e) => check_const(ccx, it.span, e, it.id),
|
ast::item_static(_, _, e) => check_const(ccx, it.span, e, it.id),
|
||||||
ast::item_enum(ref enum_definition, _) => {
|
ast::item_enum(ref enum_definition, _) => {
|
||||||
check_enum_variants(ccx,
|
check_enum_variants(ccx,
|
||||||
it.span,
|
it.span,
|
||||||
|
@ -3216,7 +3216,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::def_fn(id, _) | ast::def_static_method(id, _, _) |
|
ast::def_fn(id, _) | ast::def_static_method(id, _, _) |
|
||||||
ast::def_const(id) | ast::def_variant(_, id) |
|
ast::def_static(id, _) | ast::def_variant(_, id) |
|
||||||
ast::def_struct(id) => {
|
ast::def_struct(id) => {
|
||||||
return ty::lookup_item_type(fcx.ccx.tcx, id);
|
return ty::lookup_item_type(fcx.ccx.tcx, id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1060,7 +1060,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
|
||||||
}
|
}
|
||||||
let rp = tcx.region_paramd_items.find(&it.id).map_consume(|x| *x);
|
let rp = tcx.region_paramd_items.find(&it.id).map_consume(|x| *x);
|
||||||
match it.node {
|
match it.node {
|
||||||
ast::item_const(t, _) => {
|
ast::item_static(t, _, _) => {
|
||||||
let typ = ccx.to_ty(&empty_rscope, t);
|
let typ = ccx.to_ty(&empty_rscope, t);
|
||||||
let tpt = no_params(typ);
|
let tpt = no_params(typ);
|
||||||
tcx.tcache.insert(local_def(it.id), tpt);
|
tcx.tcache.insert(local_def(it.id), tpt);
|
||||||
|
|
|
@ -102,7 +102,7 @@ fn moddoc_from_mod(
|
||||||
fndoc_from_fn(ItemDoc)
|
fndoc_from_fn(ItemDoc)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
ast::item_const(_, _) => {
|
ast::item_static(*) => {
|
||||||
Some(doc::ConstTag(
|
Some(doc::ConstTag(
|
||||||
constdoc_from_const(ItemDoc)
|
constdoc_from_const(ItemDoc)
|
||||||
))
|
))
|
||||||
|
|
|
@ -96,7 +96,7 @@ fn fold_const(
|
||||||
do astsrv::exec(srv) |ctxt| {
|
do astsrv::exec(srv) |ctxt| {
|
||||||
match ctxt.ast_map.get_copy(&doc.id()) {
|
match ctxt.ast_map.get_copy(&doc.id()) {
|
||||||
ast_map::node_item(@ast::item {
|
ast_map::node_item(@ast::item {
|
||||||
node: ast::item_const(ty, _), _
|
node: ast::item_static(ty, _, _), _
|
||||||
}, _) => {
|
}, _) => {
|
||||||
pprust::ty_to_str(ty, extract::interner())
|
pprust::ty_to_str(ty, extract::interner())
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,7 +190,7 @@ pub enum def {
|
||||||
def_self_ty(/* trait id */ node_id),
|
def_self_ty(/* trait id */ node_id),
|
||||||
def_mod(def_id),
|
def_mod(def_id),
|
||||||
def_foreign_mod(def_id),
|
def_foreign_mod(def_id),
|
||||||
def_const(def_id),
|
def_static(def_id, bool /* is_mutbl */),
|
||||||
def_arg(node_id, bool /* is_mutbl */),
|
def_arg(node_id, bool /* is_mutbl */),
|
||||||
def_local(node_id, bool /* is_mutbl */),
|
def_local(node_id, bool /* is_mutbl */),
|
||||||
def_variant(def_id /* enum */, def_id /* variant */),
|
def_variant(def_id /* enum */, def_id /* variant */),
|
||||||
|
@ -1095,7 +1095,7 @@ pub struct item {
|
||||||
|
|
||||||
#[deriving(Eq, Encodable, Decodable)]
|
#[deriving(Eq, Encodable, Decodable)]
|
||||||
pub enum item_ {
|
pub enum item_ {
|
||||||
item_const(@Ty, @expr),
|
item_static(@Ty, mutability, @expr),
|
||||||
item_fn(fn_decl, purity, AbiSet, Generics, blk),
|
item_fn(fn_decl, purity, AbiSet, Generics, blk),
|
||||||
item_mod(_mod),
|
item_mod(_mod),
|
||||||
item_foreign_mod(foreign_mod),
|
item_foreign_mod(foreign_mod),
|
||||||
|
|
|
@ -339,7 +339,7 @@ pub fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str {
|
||||||
Some(&node_item(item, path)) => {
|
Some(&node_item(item, path)) => {
|
||||||
let path_str = path_ident_to_str(path, item.ident, itr);
|
let path_str = path_ident_to_str(path, item.ident, itr);
|
||||||
let item_str = match item.node {
|
let item_str = match item.node {
|
||||||
item_const(*) => ~"const",
|
item_static(*) => ~"static",
|
||||||
item_fn(*) => ~"fn",
|
item_fn(*) => ~"fn",
|
||||||
item_mod(*) => ~"mod",
|
item_mod(*) => ~"mod",
|
||||||
item_foreign_mod(*) => ~"foreign mod",
|
item_foreign_mod(*) => ~"foreign mod",
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub fn variant_def_ids(d: def) -> Option<(def_id, def_id)> {
|
||||||
pub fn def_id_of_def(d: def) -> def_id {
|
pub fn def_id_of_def(d: def) -> def_id {
|
||||||
match d {
|
match d {
|
||||||
def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) |
|
def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) |
|
||||||
def_foreign_mod(id) | def_const(id) |
|
def_foreign_mod(id) | def_static(id, _) |
|
||||||
def_variant(_, id) | def_ty(id) | def_ty_param(id, _) |
|
def_variant(_, id) | def_ty(id) | def_ty_param(id, _) |
|
||||||
def_use(id) | def_struct(id) | def_trait(id) => {
|
def_use(id) | def_struct(id) | def_trait(id) => {
|
||||||
id
|
id
|
||||||
|
|
|
@ -270,7 +270,7 @@ fn noop_fold_struct_field(sf: @struct_field, fld: @ast_fold)
|
||||||
|
|
||||||
pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ {
|
pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ {
|
||||||
match *i {
|
match *i {
|
||||||
item_const(t, e) => item_const(fld.fold_ty(t), fld.fold_expr(e)),
|
item_static(t, m, e) => item_static(fld.fold_ty(t), m, fld.fold_expr(e)),
|
||||||
item_fn(ref decl, purity, abi, ref generics, ref body) => {
|
item_fn(ref decl, purity, abi, ref generics, ref body) => {
|
||||||
item_fn(
|
item_fn(
|
||||||
fold_fn_decl(decl, fld),
|
fold_fn_decl(decl, fld),
|
||||||
|
|
|
@ -34,7 +34,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_mut_slice, expr_while, extern_fn, field, fn_decl};
|
||||||
use ast::{expr_vstore_uniq, Onceness, Once, Many};
|
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_const, foreign_item_fn, foreign_mod};
|
||||||
use ast::{ident, impure_fn, inherited, item, item_, item_const};
|
use ast::{ident, impure_fn, inherited, item, item_, item_static};
|
||||||
use ast::{item_enum, item_fn, item_foreign_mod, item_impl};
|
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_};
|
use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
|
||||||
use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
|
use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
|
||||||
|
@ -3556,13 +3556,14 @@ impl Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_item_const(&self) -> item_info {
|
fn parse_item_const(&self) -> item_info {
|
||||||
|
let m = if self.eat_keyword(keywords::Mut) {m_mutbl} else {m_imm};
|
||||||
let id = self.parse_ident();
|
let id = self.parse_ident();
|
||||||
self.expect(&token::COLON);
|
self.expect(&token::COLON);
|
||||||
let ty = self.parse_ty(false);
|
let ty = self.parse_ty(false);
|
||||||
self.expect(&token::EQ);
|
self.expect(&token::EQ);
|
||||||
let e = self.parse_expr();
|
let e = self.parse_expr();
|
||||||
self.expect(&token::SEMI);
|
self.expect(&token::SEMI);
|
||||||
(id, item_const(ty, e), None)
|
(id, item_static(ty, m, e), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse a mod { ...} item
|
// parse a mod { ...} item
|
||||||
|
|
|
@ -477,8 +477,11 @@ pub fn print_item(s: @ps, item: @ast::item) {
|
||||||
let ann_node = node_item(s, item);
|
let ann_node = node_item(s, item);
|
||||||
(s.ann.pre)(ann_node);
|
(s.ann.pre)(ann_node);
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::item_const(ty, expr) => {
|
ast::item_static(ty, m, expr) => {
|
||||||
head(s, visibility_qualified(item.vis, "static"));
|
head(s, visibility_qualified(item.vis, "static"));
|
||||||
|
if m == ast::m_mutbl {
|
||||||
|
word_space(s, "mut");
|
||||||
|
}
|
||||||
print_ident(s, item.ident);
|
print_ident(s, item.ident);
|
||||||
word_space(s, ":");
|
word_space(s, ":");
|
||||||
print_type(s, ty);
|
print_type(s, ty);
|
||||||
|
|
|
@ -148,7 +148,7 @@ fn visit_trait_ref<E: Copy>(tref: @ast::trait_ref, (e, v): (E, vt<E>)) {
|
||||||
|
|
||||||
pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
|
pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
|
||||||
match i.node {
|
match i.node {
|
||||||
item_const(t, ex) => {
|
item_static(t, _, ex) => {
|
||||||
(v.visit_ty)(t, (copy e, v));
|
(v.visit_ty)(t, (copy e, v));
|
||||||
(v.visit_expr)(ex, (copy e, v));
|
(v.visit_expr)(ex, (copy e, v));
|
||||||
}
|
}
|
||||||
|
|
1
src/test/auxiliary/static_mut_xc.rs
Normal file
1
src/test/auxiliary/static_mut_xc.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub static mut a: int = 3;
|
17
src/test/compile-fail/static-mut-bad-types.rs
Normal file
17
src/test/compile-fail/static-mut-bad-types.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
static mut a: int = 3;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
a = true; //~ ERROR: mismatched types
|
||||||
|
}
|
||||||
|
}
|
13
src/test/compile-fail/static-mut-not-constant.rs
Normal file
13
src/test/compile-fail/static-mut-not-constant.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
static mut a: ~int = ~3; //~ ERROR: disallowed operator in constant
|
||||||
|
|
||||||
|
fn main() {}
|
26
src/test/compile-fail/static-mut-not-pat.rs
Normal file
26
src/test/compile-fail/static-mut-not-pat.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
static mut a: int = 3;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// If they can't be matched against, then it's possible to capture the same
|
||||||
|
// name as a variable, hence this should be an unreachable pattern situation
|
||||||
|
// instead of spitting out a custom error about some identifier collisions
|
||||||
|
// (we should allow shadowing)
|
||||||
|
match 4 {
|
||||||
|
a => {}
|
||||||
|
_ => {} //~ ERROR: unreachable pattern
|
||||||
|
}
|
||||||
|
}
|
17
src/test/compile-fail/static-mut-requires-unsafe.rs
Normal file
17
src/test/compile-fail/static-mut-requires-unsafe.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
static mut a: int = 3;
|
||||||
|
|
||||||
|
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-xc.rs
Normal file
46
src/test/run-pass/static-mut-xc.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.
|
||||||
|
|
||||||
|
// xfail-fast
|
||||||
|
// aux-build:static_mut_xc.rs
|
||||||
|
|
||||||
|
extern mod static_mut_xc;
|
||||||
|
|
||||||
|
unsafe fn static_bound(_: &'static int) {}
|
||||||
|
|
||||||
|
fn static_bound_set(a: &'static mut int) {
|
||||||
|
*a = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn run() {
|
||||||
|
assert!(static_mut_xc::a == 3);
|
||||||
|
static_mut_xc::a = 4;
|
||||||
|
assert!(static_mut_xc::a == 4);
|
||||||
|
static_mut_xc::a += 1;
|
||||||
|
assert!(static_mut_xc::a == 5);
|
||||||
|
static_mut_xc::a *= 3;
|
||||||
|
assert!(static_mut_xc::a == 15);
|
||||||
|
static_mut_xc::a = -3;
|
||||||
|
assert!(static_mut_xc::a == -3);
|
||||||
|
static_bound(&static_mut_xc::a);
|
||||||
|
static_bound_set(&mut static_mut_xc::a);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
unsafe { run() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod inner {
|
||||||
|
pub static mut a: int = 4;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue