From 8b8d41d28a2a2918dd6f08c16034bc5ae07bee81 Mon Sep 17 00:00:00 2001 From: xales Date: Sat, 25 Jan 2014 12:48:57 -0500 Subject: [PATCH 1/2] Allow mutable slices in statics. Fixes #11411 --- src/librustc/middle/borrowck/check_loans.rs | 3 +++ src/librustc/middle/check_const.rs | 19 ++++++++++++++----- src/librustc/middle/trans/consts.rs | 9 ++++++--- src/test/compile-fail/issue-11411.rs | 13 +++++++++++++ src/test/run-pass/issue-11411.rs | 18 ++++++++++++++++++ 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 src/test/compile-fail/issue-11411.rs create mode 100644 src/test/run-pass/issue-11411.rs diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 3a500a82664dd..c30ac8c56ed13 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -520,6 +520,9 @@ impl<'a> CheckLoanCtxt<'a> { None => { return true; } + Some(mc::AliasableStaticMut) => { + return true; + } Some(cause) => { this.bccx.report_aliasability_violation( expr.span, diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 3b8e708676235..b1b073c3ecb8b 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -29,14 +29,15 @@ pub struct CheckCrateVisitor { impl Visitor for CheckCrateVisitor { fn visit_item(&mut self, i: &Item, env: bool) { - check_item(self, self.sess, self.def_map, i, env); + check_item(self, self.sess, self.def_map, self.method_map, + self.tcx, i, env) } fn visit_pat(&mut self, p: &Pat, env: bool) { check_pat(self, p, env); } fn visit_expr(&mut self, ex: &Expr, env: bool) { check_expr(self, self.sess, self.def_map, self.method_map, - self.tcx, ex, env); + self.tcx, ex, env, false); } } @@ -58,11 +59,13 @@ pub fn check_crate(sess: Session, pub fn check_item(v: &mut CheckCrateVisitor, sess: Session, def_map: resolve::DefMap, + method_map: typeck::method_map, + tcx: ty::ctxt, it: &Item, _is_const: bool) { match it.node { - ItemStatic(_, _, ex) => { - v.visit_expr(ex, true); + ItemStatic(_, mut_, ex) => { + check_expr(v, sess, def_map, method_map, tcx, ex, true, mut_ == MutMutable); check_item_recursion(sess, &v.tcx.map, def_map, it); } ItemEnum(ref enum_definition, _) => { @@ -105,7 +108,8 @@ pub fn check_expr(v: &mut CheckCrateVisitor, method_map: typeck::MethodMap, tcx: ty::ctxt, e: &Expr, - is_const: bool) { + is_const: bool, + is_static_mut: bool) { if is_const { match e.node { ExprUnary(UnDeref, _) => { } @@ -187,6 +191,11 @@ pub fn check_expr(v: &mut CheckCrateVisitor, e.span, "references in constants may only refer to \ immutable values"); + } + ExprVstore(_, ExprVstoreMutSlice) => { + if !is_static_mut { + sess.span_err(e.span, "mutable slice is not allowed in immutable constants") + } }, ExprVstore(_, ExprVstoreUniq) => { sess.span_err(e.span, "cannot allocate vectors in constant expressions") diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 55d44e00bae46..d85da2ae3ef81 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -10,7 +10,8 @@ use back::abi; -use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True}; +use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True, + False}; use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE, RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE}; @@ -572,7 +573,8 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr, is_local); (v, inlineable) } - ast::ExprVstore(sub, ast::ExprVstoreSlice) => { + ast::ExprVstore(sub, store @ ast::ExprVstoreSlice) | + ast::ExprVstore(sub, store @ ast::ExprVstoreMutSlice) => { match sub.node { ast::ExprLit(ref lit) => { match lit.node { @@ -590,7 +592,8 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr, llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name) }); llvm::LLVMSetInitializer(gv, cv); - llvm::LLVMSetGlobalConstant(gv, True); + llvm::LLVMSetGlobalConstant(gv, + if store == ast::ExprVstoreMutSlice { False } else { True }); SetLinkage(gv, PrivateLinkage); let p = const_ptrcast(cx, gv, llunitty); (C_struct([p, C_uint(cx, es.len())], false), false) diff --git a/src/test/compile-fail/issue-11411.rs b/src/test/compile-fail/issue-11411.rs new file mode 100644 index 0000000000000..4ccee2b40c1ad --- /dev/null +++ b/src/test/compile-fail/issue-11411.rs @@ -0,0 +1,13 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +static TEST: &'static mut [int] = &mut []; //~ ERROR mutable slice is not allowed + +fn main() { } diff --git a/src/test/run-pass/issue-11411.rs b/src/test/run-pass/issue-11411.rs new file mode 100644 index 0000000000000..e0da80702d758 --- /dev/null +++ b/src/test/run-pass/issue-11411.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +static mut TEST: &'static mut [int] = &mut [1]; + +pub fn main() { + unsafe { + TEST[0] += 1; + } +} From abfc6db4c2b9c9c686a5c09d59e4c534e5f4f2ec Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Thu, 6 Mar 2014 22:48:52 +0100 Subject: [PATCH 2/2] rustc: Move mut slice check to `check_static` This is a follow-up patch that moves the mut slice check to the recently added `check_static` Closes #11411 --- src/librustc/middle/check_const.rs | 20 ++++++------------- src/librustc/middle/check_static.rs | 4 ++++ src/librustc/middle/trans/consts.rs | 2 +- ...s => check-static-immutable-mut-slices.rs} | 7 +++++-- ...ue-11411.rs => check-static-mut-slices.rs} | 2 ++ 5 files changed, 18 insertions(+), 17 deletions(-) rename src/test/compile-fail/{issue-11411.rs => check-static-immutable-mut-slices.rs} (71%) rename src/test/run-pass/{issue-11411.rs => check-static-mut-slices.rs} (86%) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index b1b073c3ecb8b..3792887709f74 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -29,15 +29,14 @@ pub struct CheckCrateVisitor { impl Visitor for CheckCrateVisitor { fn visit_item(&mut self, i: &Item, env: bool) { - check_item(self, self.sess, self.def_map, self.method_map, - self.tcx, i, env) + check_item(self, self.sess, self.def_map, i, env); } fn visit_pat(&mut self, p: &Pat, env: bool) { check_pat(self, p, env); } fn visit_expr(&mut self, ex: &Expr, env: bool) { check_expr(self, self.sess, self.def_map, self.method_map, - self.tcx, ex, env, false); + self.tcx, ex, env); } } @@ -59,13 +58,11 @@ pub fn check_crate(sess: Session, pub fn check_item(v: &mut CheckCrateVisitor, sess: Session, def_map: resolve::DefMap, - method_map: typeck::method_map, - tcx: ty::ctxt, it: &Item, _is_const: bool) { match it.node { - ItemStatic(_, mut_, ex) => { - check_expr(v, sess, def_map, method_map, tcx, ex, true, mut_ == MutMutable); + ItemStatic(_, _, ex) => { + v.visit_expr(ex, true); check_item_recursion(sess, &v.tcx.map, def_map, it); } ItemEnum(ref enum_definition, _) => { @@ -108,8 +105,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor, method_map: typeck::MethodMap, tcx: ty::ctxt, e: &Expr, - is_const: bool, - is_static_mut: bool) { + is_const: bool) { if is_const { match e.node { ExprUnary(UnDeref, _) => { } @@ -177,6 +173,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor, } } } + ExprVstore(_, ExprVstoreMutSlice) | ExprVstore(_, ExprVstoreSlice) | ExprVec(_, MutImmutable) | ExprAddrOf(MutImmutable, _) | @@ -191,11 +188,6 @@ pub fn check_expr(v: &mut CheckCrateVisitor, e.span, "references in constants may only refer to \ immutable values"); - } - ExprVstore(_, ExprVstoreMutSlice) => { - if !is_static_mut { - sess.span_err(e.span, "mutable slice is not allowed in immutable constants") - } }, ExprVstore(_, ExprVstoreUniq) => { sess.span_err(e.span, "cannot allocate vectors in constant expressions") diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs index ebf1904d3cb2a..62f9f512b5dd6 100644 --- a/src/librustc/middle/check_static.rs +++ b/src/librustc/middle/check_static.rs @@ -108,6 +108,10 @@ impl Visitor for CheckStaticVisitor { ast::ExprVstore(_, ast::ExprVstoreSlice) => { visit::walk_expr(self, e, is_const); } + ast::ExprVstore(_, ast::ExprVstoreMutSlice) => { + self.tcx.sess.span_err(e.span, + "static items are not allowed to have mutable slices"); + }, ast::ExprUnary(ast::UnBox, _) => { self.tcx.sess.span_err(e.span, "static items are not allowed to have managed pointers"); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index d85da2ae3ef81..5b011939c610c 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -574,7 +574,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr, (v, inlineable) } ast::ExprVstore(sub, store @ ast::ExprVstoreSlice) | - ast::ExprVstore(sub, store @ ast::ExprVstoreMutSlice) => { + ast::ExprVstore(sub, store @ ast::ExprVstoreMutSlice) => { match sub.node { ast::ExprLit(ref lit) => { match lit.node { diff --git a/src/test/compile-fail/issue-11411.rs b/src/test/compile-fail/check-static-immutable-mut-slices.rs similarity index 71% rename from src/test/compile-fail/issue-11411.rs rename to src/test/compile-fail/check-static-immutable-mut-slices.rs index 4ccee2b40c1ad..73ce488cbc669 100644 --- a/src/test/compile-fail/issue-11411.rs +++ b/src/test/compile-fail/check-static-immutable-mut-slices.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static TEST: &'static mut [int] = &mut []; //~ ERROR mutable slice is not allowed +// Checks that immutable static items can't have mutable slices -fn main() { } +static TEST: &'static mut [int] = &mut []; +//~^ ERROR static items are not allowed to have mutable slices + +pub fn main() { } diff --git a/src/test/run-pass/issue-11411.rs b/src/test/run-pass/check-static-mut-slices.rs similarity index 86% rename from src/test/run-pass/issue-11411.rs rename to src/test/run-pass/check-static-mut-slices.rs index e0da80702d758..af25c43005dd4 100644 --- a/src/test/run-pass/issue-11411.rs +++ b/src/test/run-pass/check-static-mut-slices.rs @@ -8,11 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Checks that mutable static items can have mutable slices static mut TEST: &'static mut [int] = &mut [1]; pub fn main() { unsafe { TEST[0] += 1; + assert_eq!(TEST[0], 2); } }