fn main() {
println!("You have readline version {} installed.",
- rl_readline_version as i32);
+ unsafe { rl_readline_version as i32 });
}
```
// Again, I'm not entirely sure what this is describing, it just seems to work.
#[cfg_attr(not(test), lang = "msvc_try_filter")]
static mut TYPE_DESCRIPTOR1: _TypeDescriptor = _TypeDescriptor {
- pVFTable: &TYPE_INFO_VTABLE as *const _ as *const _,
+ pVFTable: unsafe { &TYPE_INFO_VTABLE } as *const _ as *const _,
spare: 0 as *mut _,
name: imp::NAME1,
};
static mut TYPE_DESCRIPTOR2: _TypeDescriptor = _TypeDescriptor {
- pVFTable: &TYPE_INFO_VTABLE as *const _ as *const _,
+ pVFTable: unsafe { &TYPE_INFO_VTABLE } as *const _ as *const _,
spare: 0 as *mut _,
name: imp::NAME2,
};
"lifetimes or labels named `'_` were erroneously allowed"
}
+declare_lint! {
+ pub SAFE_EXTERN_STATICS,
+ Warn,
+ "safe access to extern statics was erroneously allowed"
+}
+
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
RENAMED_AND_REMOVED_LINTS,
SUPER_OR_SELF_IN_GLOBAL_PATH,
HR_LIFETIME_IN_ASSOC_TYPE,
- LIFETIME_UNDERSCORE
+ LIFETIME_UNDERSCORE,
+ SAFE_EXTERN_STATICS
)
}
}
use dep_graph::DepNode;
use ty::{self, Ty, TyCtxt};
use ty::MethodCall;
+use lint;
use syntax::ast;
use syntax_pos::Span;
}
impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
- fn require_unsafe(&mut self, span: Span, description: &str) {
+ fn require_unsafe_ext(&mut self, node_id: ast::NodeId, span: Span,
+ description: &str, is_lint: bool) {
if self.unsafe_context.push_unsafe_count > 0 { return; }
match self.unsafe_context.root {
SafeContext => {
- // Report an error.
- struct_span_err!(
- self.tcx.sess, span, E0133,
- "{} requires unsafe function or block", description)
- .span_label(span, &description)
- .emit();
+ if is_lint {
+ self.tcx.sess.add_lint(lint::builtin::SAFE_EXTERN_STATICS,
+ node_id,
+ span,
+ format!("{} requires unsafe function or \
+ block (error E0133)", description));
+ } else {
+ // Report an error.
+ struct_span_err!(
+ self.tcx.sess, span, E0133,
+ "{} requires unsafe function or block", description)
+ .span_label(span, &description)
+ .emit();
+ }
}
UnsafeBlock(block_id) => {
// OK, but record this.
UnsafeFn => {}
}
}
+
+ fn require_unsafe(&mut self, span: Span, description: &str) {
+ self.require_unsafe_ext(ast::DUMMY_NODE_ID, span, description, false)
+ }
}
impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.require_unsafe(expr.span, "use of inline assembly");
}
hir::ExprPath(..) => {
- if let Def::Static(_, true) = self.tcx.expect_def(expr.id) {
- self.require_unsafe(expr.span, "use of mutable static");
+ if let Def::Static(def_id, mutbl) = self.tcx.expect_def(expr.id) {
+ if mutbl {
+ self.require_unsafe(expr.span, "use of mutable static");
+ } else if match self.tcx.map.get_if_local(def_id) {
+ Some(hir::map::NodeForeignItem(..)) => true,
+ Some(..) => false,
+ None => self.tcx.sess.cstore.is_foreign_item(def_id),
+ } {
+ self.require_unsafe_ext(expr.id, expr.span, "use of extern static", true);
+ }
}
}
hir::ExprField(ref base_expr, field) => {
id: LintId::of(LIFETIME_UNDERSCORE),
reference: "RFC 1177 <https://github.com/rust-lang/rfcs/pull/1177>",
},
+ FutureIncompatibleInfo {
+ id: LintId::of(SAFE_EXTERN_STATICS),
+ reference: "issue 36247 <https://github.com/rust-lang/rust/issues/35112>",
+ },
]);
// Register renamed and removed lints
--- /dev/null
+// Copyright 2016 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.
+
+extern {
+ pub static XA: u8;
+ pub static mut XB: u8;
+}
}
fn main() {
- println!("{}", foo);
+ println!("{}", unsafe { foo });
}
}
fn main() {
- println!("{:?}", foo);
+ println!("{:?}", unsafe { foo });
}
--- /dev/null
+// Copyright 2016 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.
+
+// aux-build:extern-statics.rs
+
+#![allow(unused)]
+#![deny(safe_extern_statics)]
+
+extern crate extern_statics;
+use extern_statics::*;
+
+extern {
+ static mut B: u8;
+}
+
+fn main() {
+ let b = B; //~ ERROR use of mutable static requires unsafe function or block
+ let rb = &B; //~ ERROR use of mutable static requires unsafe function or block
+ let xb = XB; //~ ERROR use of mutable static requires unsafe function or block
+ let xrb = &XB; //~ ERROR use of mutable static requires unsafe function or block
+}
--- /dev/null
+// Copyright 2016 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.
+
+// aux-build:extern-statics.rs
+
+#![allow(unused)]
+#![deny(safe_extern_statics)]
+
+extern crate extern_statics;
+use extern_statics::*;
+
+extern {
+ static A: u8;
+}
+
+fn main() {
+ let a = A; //~ ERROR use of extern static requires unsafe function or block
+ //~^ WARN this was previously accepted by the compiler
+ let ra = &A; //~ ERROR use of extern static requires unsafe function or block
+ //~^ WARN this was previously accepted by the compiler
+ let xa = XA; //~ ERROR use of extern static requires unsafe function or block
+ //~^ WARN this was previously accepted by the compiler
+ let xra = &XA; //~ ERROR use of extern static requires unsafe function or block
+ //~^ WARN this was previously accepted by the compiler
+}
static test_static: c_int;
}
-static B: &'static c_int = &test_static;
+static B: &'static c_int = unsafe { &test_static };
pub fn main() {}