From 8b8d41d28a2a2918dd6f08c16034bc5ae07bee81 Mon Sep 17 00:00:00 2001 From: xales Date: Sat, 25 Jan 2014 12:48:57 -0500 Subject: [PATCH] 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 3a500a82664..c30ac8c56ed 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -520,6 +520,9 @@ fn check_for_aliasability_violation(this: &CheckLoanCtxt, 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 3b8e7086762..b1b073c3ecb 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 55d44e00bae..d85da2ae3ef 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 00000000000..4ccee2b40c1 --- /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 00000000000..e0da80702d7 --- /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; + } +} -- GitLab