diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 9d459027bf5cd..d1e7084150eb3 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -892,6 +892,8 @@ register_diagnostics! { E0316, // nested quantification of lifetimes E0370, // discriminant overflow E0378, // method calls limited to constant inherent methods - E0394 // cannot refer to other statics by value, use the address-of + E0394, // cannot refer to other statics by value, use the address-of // operator or a constant instead + E0395, // pointer comparison in const-expr + E0396 // pointer dereference in const-expr } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index c54517e00173b..3e084f3eeb305 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -536,11 +536,32 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, "allocations are not allowed in {}s", v.msg()); } } - ast::ExprUnary(ast::UnDeref, ref ptr) => { - match ty::node_id_to_type(v.tcx, ptr.id).sty { + ast::ExprUnary(op, ref inner) => { + match ty::node_id_to_type(v.tcx, inner.id).sty { ty::ty_ptr(_) => { - // This shouldn't be allowed in constants at all. + assert!(op == ast::UnDeref); + + v.add_qualif(ConstQualif::NOT_CONST); + if v.mode != Mode::Var { + span_err!(v.tcx.sess, e.span, E0396, + "raw pointers cannot be dereferenced in {}s", v.msg()); + } + } + _ => {} + } + } + ast::ExprBinary(op, ref lhs, _) => { + match ty::node_id_to_type(v.tcx, lhs.id).sty { + ty::ty_ptr(_) => { + assert!(op.node == ast::BiEq || op.node == ast::BiNe || + op.node == ast::BiLe || op.node == ast::BiLt || + op.node == ast::BiGe || op.node == ast::BiGt); + v.add_qualif(ConstQualif::NOT_CONST); + if v.mode != Mode::Var { + span_err!(v.tcx.sess, e.span, E0395, + "raw pointers cannot be compared in {}s", v.msg()); + } } _ => {} } @@ -553,7 +574,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, v.add_qualif(ConstQualif::NOT_CONST); if v.mode != Mode::Var { span_err!(v.tcx.sess, e.span, E0018, - "can't cast a pointer to an integer in {}s", v.msg()); + "raw pointers cannot be cast to integers in {}s", v.msg()); } } _ => {} @@ -695,8 +716,6 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } ast::ExprBlock(_) | - ast::ExprUnary(..) | - ast::ExprBinary(..) | ast::ExprIndex(..) | ast::ExprField(..) | ast::ExprTupField(..) | diff --git a/src/test/compile-fail/const-deref-ptr.rs b/src/test/compile-fail/const-deref-ptr.rs new file mode 100644 index 0000000000000..fa15f3e87c694 --- /dev/null +++ b/src/test/compile-fail/const-deref-ptr.rs @@ -0,0 +1,16 @@ +// Copyright 2015 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. + +// Check that you can't dereference raw pointers in constants. + +fn main() { + static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396 + println!("{}", C); +} diff --git a/src/test/compile-fail/issue-17458.rs b/src/test/compile-fail/issue-17458.rs index a3a9e17cb3c06..f5b7a0c13b728 100644 --- a/src/test/compile-fail/issue-17458.rs +++ b/src/test/compile-fail/issue-17458.rs @@ -9,7 +9,7 @@ // except according to those terms. static X: usize = 0 as *const usize as usize; -//~^ ERROR: can't cast a pointer to an integer in statics +//~^ ERROR: raw pointers cannot be cast to integers in statics fn main() { assert_eq!(X, 0); diff --git a/src/test/compile-fail/issue-25826.rs b/src/test/compile-fail/issue-25826.rs new file mode 100644 index 0000000000000..00e1279d58a0e --- /dev/null +++ b/src/test/compile-fail/issue-25826.rs @@ -0,0 +1,16 @@ +// Copyright 2015 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. + +fn id(t: T) -> T { t } +fn main() { + const A: bool = id:: as *const () < id:: as *const (); + //~^ ERROR raw pointers cannot be compared in constants [E0395] + println!("{}", A); +}