Skip to content

Commit 8b8d41d

Browse files
xalesflaper87
authored andcommitted
Allow mutable slices in statics.
Fixes #11411
1 parent 1eb3f63 commit 8b8d41d

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

Diff for: src/librustc/middle/borrowck/check_loans.rs

+3
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ impl<'a> CheckLoanCtxt<'a> {
520520
None => {
521521
return true;
522522
}
523+
Some(mc::AliasableStaticMut) => {
524+
return true;
525+
}
523526
Some(cause) => {
524527
this.bccx.report_aliasability_violation(
525528
expr.span,

Diff for: src/librustc/middle/check_const.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ pub struct CheckCrateVisitor {
2929

3030
impl Visitor<bool> for CheckCrateVisitor {
3131
fn visit_item(&mut self, i: &Item, env: bool) {
32-
check_item(self, self.sess, self.def_map, i, env);
32+
check_item(self, self.sess, self.def_map, self.method_map,
33+
self.tcx, i, env)
3334
}
3435
fn visit_pat(&mut self, p: &Pat, env: bool) {
3536
check_pat(self, p, env);
3637
}
3738
fn visit_expr(&mut self, ex: &Expr, env: bool) {
3839
check_expr(self, self.sess, self.def_map, self.method_map,
39-
self.tcx, ex, env);
40+
self.tcx, ex, env, false);
4041
}
4142
}
4243

@@ -58,11 +59,13 @@ pub fn check_crate(sess: Session,
5859
pub fn check_item(v: &mut CheckCrateVisitor,
5960
sess: Session,
6061
def_map: resolve::DefMap,
62+
method_map: typeck::method_map,
63+
tcx: ty::ctxt,
6164
it: &Item,
6265
_is_const: bool) {
6366
match it.node {
64-
ItemStatic(_, _, ex) => {
65-
v.visit_expr(ex, true);
67+
ItemStatic(_, mut_, ex) => {
68+
check_expr(v, sess, def_map, method_map, tcx, ex, true, mut_ == MutMutable);
6669
check_item_recursion(sess, &v.tcx.map, def_map, it);
6770
}
6871
ItemEnum(ref enum_definition, _) => {
@@ -105,7 +108,8 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
105108
method_map: typeck::MethodMap,
106109
tcx: ty::ctxt,
107110
e: &Expr,
108-
is_const: bool) {
111+
is_const: bool,
112+
is_static_mut: bool) {
109113
if is_const {
110114
match e.node {
111115
ExprUnary(UnDeref, _) => { }
@@ -187,6 +191,11 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
187191
e.span,
188192
"references in constants may only refer to \
189193
immutable values");
194+
}
195+
ExprVstore(_, ExprVstoreMutSlice) => {
196+
if !is_static_mut {
197+
sess.span_err(e.span, "mutable slice is not allowed in immutable constants")
198+
}
190199
},
191200
ExprVstore(_, ExprVstoreUniq) => {
192201
sess.span_err(e.span, "cannot allocate vectors in constant expressions")

Diff for: src/librustc/middle/trans/consts.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111

1212
use back::abi;
13-
use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True};
13+
use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True,
14+
False};
1415
use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
1516
RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};
1617

@@ -572,7 +573,8 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
572573
is_local);
573574
(v, inlineable)
574575
}
575-
ast::ExprVstore(sub, ast::ExprVstoreSlice) => {
576+
ast::ExprVstore(sub, store @ ast::ExprVstoreSlice) |
577+
ast::ExprVstore(sub, store @ ast::ExprVstoreMutSlice) => {
576578
match sub.node {
577579
ast::ExprLit(ref lit) => {
578580
match lit.node {
@@ -590,7 +592,8 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
590592
llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
591593
});
592594
llvm::LLVMSetInitializer(gv, cv);
593-
llvm::LLVMSetGlobalConstant(gv, True);
595+
llvm::LLVMSetGlobalConstant(gv,
596+
if store == ast::ExprVstoreMutSlice { False } else { True });
594597
SetLinkage(gv, PrivateLinkage);
595598
let p = const_ptrcast(cx, gv, llunitty);
596599
(C_struct([p, C_uint(cx, es.len())], false), false)

Diff for: src/test/compile-fail/issue-11411.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 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+
static TEST: &'static mut [int] = &mut []; //~ ERROR mutable slice is not allowed
12+
13+
fn main() { }

Diff for: src/test/run-pass/issue-11411.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2014 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+
12+
static mut TEST: &'static mut [int] = &mut [1];
13+
14+
pub fn main() {
15+
unsafe {
16+
TEST[0] += 1;
17+
}
18+
}

0 commit comments

Comments
 (0)