mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-28 03:07:24 +03:00
Auto merge of #37540 - jonathandturner:rollup, r=jonathandturner
Rollup of 10 pull requests - Successful merges: #37351, #37405, #37473, #37482, #37488, #37498, #37502, #37513, #37517, #37523 - Failed merges: #37521
This commit is contained in:
+1
-1
@@ -15,7 +15,7 @@ before_install:
|
||||
script:
|
||||
- docker run -v `pwd`:/build rust
|
||||
sh -c "
|
||||
./configure --enable-rustbuild --llvm-root=/usr/lib/llvm-3.7 &&
|
||||
./configure --enable-rustbuild --llvm-root=/usr/lib/llvm-3.7 --enable-quiet-tests &&
|
||||
make tidy &&
|
||||
make check -j4
|
||||
"
|
||||
|
||||
@@ -507,11 +507,16 @@ case $CFG_CPUTYPE in
|
||||
CFG_CPUTYPE=arm
|
||||
;;
|
||||
|
||||
armv7l)
|
||||
armv6l)
|
||||
CFG_CPUTYPE=arm
|
||||
CFG_OSTYPE="${CFG_OSTYPE}eabihf"
|
||||
;;
|
||||
|
||||
armv7l)
|
||||
CFG_CPUTYPE=armv7
|
||||
CFG_OSTYPE="${CFG_OSTYPE}eabihf"
|
||||
;;
|
||||
|
||||
aarch64)
|
||||
CFG_CPUTYPE=aarch64
|
||||
;;
|
||||
@@ -610,6 +615,7 @@ opt docs 1 "build standard library documentation"
|
||||
opt compiler-docs 0 "build compiler documentation"
|
||||
opt optimize-tests 1 "build tests with optimizations"
|
||||
opt debuginfo-tests 0 "build tests with debugger metadata"
|
||||
opt quiet-tests 0 "enable quieter output when running tests"
|
||||
opt libcpp 1 "build llvm with libc++ instead of libstdc++ when using clang"
|
||||
opt llvm-assertions 0 "build LLVM with assertions"
|
||||
opt debug-assertions 0 "build with debugging assertions"
|
||||
|
||||
+16
-1
@@ -187,6 +187,10 @@ pub fn compiletest(build: &Build,
|
||||
cmd.arg("--verbose");
|
||||
}
|
||||
|
||||
if build.config.quiet_tests {
|
||||
cmd.arg("--quiet");
|
||||
}
|
||||
|
||||
// Only pass correct values for these flags for the `run-make` suite as it
|
||||
// requires that a C++ compiler was configured which isn't always the case.
|
||||
if suite == "run-make" {
|
||||
@@ -277,7 +281,13 @@ fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
|
||||
build.add_rustc_lib_path(compiler, &mut cmd);
|
||||
cmd.arg("--test");
|
||||
cmd.arg(markdown);
|
||||
cmd.arg("--test-args").arg(build.flags.args.join(" "));
|
||||
|
||||
let mut test_args = build.flags.args.join(" ");
|
||||
if build.config.quiet_tests {
|
||||
test_args.push_str(" --quiet");
|
||||
}
|
||||
cmd.arg("--test-args").arg(test_args);
|
||||
|
||||
build.run(&mut cmd);
|
||||
}
|
||||
|
||||
@@ -367,6 +377,11 @@ pub fn krate(build: &Build,
|
||||
dylib_path.insert(0, build.sysroot_libdir(compiler, target));
|
||||
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||
|
||||
if build.config.quiet_tests {
|
||||
cargo.arg("--");
|
||||
cargo.arg("--quiet");
|
||||
}
|
||||
|
||||
if target.contains("android") {
|
||||
build.run(cargo.arg("--no-run"));
|
||||
krate_android(build, compiler, target, mode);
|
||||
|
||||
@@ -77,6 +77,7 @@ pub struct Config {
|
||||
|
||||
// misc
|
||||
pub channel: String,
|
||||
pub quiet_tests: bool,
|
||||
// Fallback musl-root for all targets
|
||||
pub musl_root: Option<PathBuf>,
|
||||
pub prefix: Option<String>,
|
||||
@@ -338,6 +339,7 @@ macro_rules! check {
|
||||
("RPATH", self.rust_rpath),
|
||||
("OPTIMIZE_TESTS", self.rust_optimize_tests),
|
||||
("DEBUGINFO_TESTS", self.rust_debuginfo_tests),
|
||||
("QUIET_TESTS", self.quiet_tests),
|
||||
("LOCAL_REBUILD", self.local_rebuild),
|
||||
("NINJA", self.ninja),
|
||||
("CODEGEN_TESTS", self.codegen_tests),
|
||||
|
||||
+20
-18
@@ -317,26 +317,27 @@ macro_rules! try {
|
||||
|
||||
/// Write formatted data into a buffer
|
||||
///
|
||||
/// This macro accepts any value with `write_fmt` method as a writer, a format string, and a list
|
||||
/// of arguments to format.
|
||||
/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
|
||||
/// list of arguments to format.
|
||||
///
|
||||
/// `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write] or
|
||||
/// [`std::io::Write`][io_write] traits. These are sometimes called 'writers'.
|
||||
/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
|
||||
/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
|
||||
/// these two traits.
|
||||
///
|
||||
/// Passed arguments will be formatted according to the specified format string and the resulting
|
||||
/// string will be passed to the writer.
|
||||
///
|
||||
/// See [`std::fmt`][fmt] for more information on format syntax.
|
||||
///
|
||||
/// Return value is completely dependent on the 'write_fmt' method.
|
||||
/// `write!` returns whatever the 'write_fmt' method returns.
|
||||
///
|
||||
/// Common return values are: [`Result`][enum_result], [`io::Result`][type_result]
|
||||
/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
|
||||
///
|
||||
/// [fmt]: ../std/fmt/index.html
|
||||
/// [fmt_write]: ../std/fmt/trait.Write.html
|
||||
/// [io_write]: ../std/io/trait.Write.html
|
||||
/// [enum_result]: ../std/result/enum.Result.html
|
||||
/// [type_result]: ../std/io/type.Result.html
|
||||
/// [fmt_result]: ../std/fmt/type.Result.html
|
||||
/// [io_result]: ../std/io/type.Result.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@@ -355,31 +356,32 @@ macro_rules! write {
|
||||
($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
/// Write formatted data into a buffer, with appending a newline.
|
||||
/// Write formatted data into a buffer, with a newline appended.
|
||||
///
|
||||
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
|
||||
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
|
||||
///
|
||||
/// This macro accepts any value with `write_fmt` method as a writer, a format string, and a list
|
||||
/// of arguments to format.
|
||||
/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
|
||||
/// list of arguments to format.
|
||||
///
|
||||
/// `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write] or
|
||||
/// [`std::io::Write`][io_write] traits. These are sometimes called 'writers'.
|
||||
/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
|
||||
/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
|
||||
/// these two traits.
|
||||
///
|
||||
/// Passed arguments will be formatted according to the specified format string and the resulting
|
||||
/// string will be passed to the writer.
|
||||
/// string will be passed to the writer, along with the appended newline.
|
||||
///
|
||||
/// See [`std::fmt`][fmt] for more information on format syntax.
|
||||
///
|
||||
/// Return value is completely dependent on the 'write_fmt' method.
|
||||
/// `write!` returns whatever the 'write_fmt' method returns.
|
||||
///
|
||||
/// Common return values are: [`Result`][enum_result], [`io::Result`][type_result]
|
||||
/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
|
||||
///
|
||||
/// [fmt]: ../std/fmt/index.html
|
||||
/// [fmt_write]: ../std/fmt/trait.Write.html
|
||||
/// [io_write]: ../std/io/trait.Write.html
|
||||
/// [enum_result]: ../std/result/enum.Result.html
|
||||
/// [type_result]: ../std/io/type.Result.html
|
||||
/// [fmt_result]: ../std/fmt/type.Result.html
|
||||
/// [io_result]: ../std/io/type.Result.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
||||
+2
-2
@@ -2484,13 +2484,13 @@ fn deref(&self) -> &T { *self }
|
||||
/// impl<T> Deref for DerefMutExample<T> {
|
||||
/// type Target = T;
|
||||
///
|
||||
/// fn deref<'a>(&'a self) -> &'a T {
|
||||
/// fn deref(&self) -> &T {
|
||||
/// &self.value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl<T> DerefMut for DerefMutExample<T> {
|
||||
/// fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
||||
/// fn deref_mut(&mut self) -> &mut T {
|
||||
/// &mut self.value
|
||||
/// }
|
||||
/// }
|
||||
|
||||
@@ -821,7 +821,7 @@ impl<T: Default, E> Result<T, E> {
|
||||
/// [`FromStr`]: ../../std/str/trait.FromStr.html
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "result_unwrap_or_default", issue = "0")]
|
||||
#[unstable(feature = "result_unwrap_or_default", issue = "37516")]
|
||||
pub fn unwrap_or_default(self) -> T {
|
||||
match self {
|
||||
Ok(x) => x,
|
||||
|
||||
@@ -166,6 +166,10 @@ pub enum Ordering {
|
||||
/// sequentially consistent operations in the same order.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
SeqCst,
|
||||
// Prevent exhaustive matching to allow for future extension
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "future_atomic_orderings", issue = "0")]
|
||||
__Nonexhaustive,
|
||||
}
|
||||
|
||||
/// An `AtomicBool` initialized to `false`.
|
||||
@@ -1277,6 +1281,7 @@ fn strongest_failure_ordering(order: Ordering) -> Ordering {
|
||||
SeqCst => SeqCst,
|
||||
Acquire => Acquire,
|
||||
AcqRel => Acquire,
|
||||
__Nonexhaustive => __Nonexhaustive,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1288,6 +1293,7 @@ unsafe fn atomic_store<T>(dst: *mut T, val: T, order: Ordering) {
|
||||
SeqCst => intrinsics::atomic_store(dst, val),
|
||||
Acquire => panic!("there is no such thing as an acquire store"),
|
||||
AcqRel => panic!("there is no such thing as an acquire/release store"),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1299,6 +1305,7 @@ unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T {
|
||||
SeqCst => intrinsics::atomic_load(dst),
|
||||
Release => panic!("there is no such thing as a release load"),
|
||||
AcqRel => panic!("there is no such thing as an acquire/release load"),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1310,6 +1317,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
|
||||
Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
|
||||
SeqCst => intrinsics::atomic_xchg(dst, val),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1322,6 +1330,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
|
||||
Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
|
||||
SeqCst => intrinsics::atomic_xadd(dst, val),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1334,6 +1343,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
|
||||
Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
|
||||
SeqCst => intrinsics::atomic_xsub(dst, val),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1354,6 +1364,8 @@ unsafe fn atomic_compare_exchange<T>(dst: *mut T,
|
||||
(AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
|
||||
(SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
|
||||
(SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
|
||||
(__Nonexhaustive, _) => panic!("invalid memory ordering"),
|
||||
(_, __Nonexhaustive) => panic!("invalid memory ordering"),
|
||||
(_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
|
||||
(_, Release) => panic!("there is no such thing as a release failure ordering"),
|
||||
_ => panic!("a failure ordering can't be stronger than a success ordering"),
|
||||
@@ -1378,6 +1390,8 @@ unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T,
|
||||
(AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new),
|
||||
(SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new),
|
||||
(SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new),
|
||||
(__Nonexhaustive, _) => panic!("invalid memory ordering"),
|
||||
(_, __Nonexhaustive) => panic!("invalid memory ordering"),
|
||||
(_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
|
||||
(_, Release) => panic!("there is no such thing as a release failure ordering"),
|
||||
_ => panic!("a failure ordering can't be stronger than a success ordering"),
|
||||
@@ -1393,6 +1407,7 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
AcqRel => intrinsics::atomic_and_acqrel(dst, val),
|
||||
Relaxed => intrinsics::atomic_and_relaxed(dst, val),
|
||||
SeqCst => intrinsics::atomic_and(dst, val),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1404,6 +1419,7 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
AcqRel => intrinsics::atomic_or_acqrel(dst, val),
|
||||
Relaxed => intrinsics::atomic_or_relaxed(dst, val),
|
||||
SeqCst => intrinsics::atomic_or(dst, val),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1415,6 +1431,7 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
|
||||
Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
|
||||
SeqCst => intrinsics::atomic_xor(dst, val),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1448,6 +1465,7 @@ pub fn fence(order: Ordering) {
|
||||
AcqRel => intrinsics::atomic_fence_acqrel(),
|
||||
SeqCst => intrinsics::atomic_fence(),
|
||||
Relaxed => panic!("there is no such thing as a relaxed fence"),
|
||||
__Nonexhaustive => panic!("invalid memory ordering"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,13 +21,11 @@
|
||||
//! `a[x]` would still overlap them both. But that is not this
|
||||
//! representation does today.)
|
||||
|
||||
use rustc::mir::{Lvalue, LvalueElem};
|
||||
use rustc::mir::{Operand, Projection, ProjectionElem};
|
||||
use rustc::mir::LvalueElem;
|
||||
use rustc::mir::{Operand, ProjectionElem};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct AbstractOperand;
|
||||
pub type AbstractProjection<'tcx> =
|
||||
Projection<'tcx, Lvalue<'tcx>, AbstractOperand>;
|
||||
pub type AbstractElem<'tcx> =
|
||||
ProjectionElem<'tcx, AbstractOperand>;
|
||||
|
||||
|
||||
@@ -300,8 +300,6 @@ struct BorrowStats {
|
||||
guaranteed_paths: usize
|
||||
}
|
||||
|
||||
pub type BckResult<'tcx, T> = Result<T, BckError<'tcx>>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Loans and loan paths
|
||||
|
||||
@@ -1064,6 +1062,19 @@ pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<
|
||||
db.note("values in a scope are dropped in the opposite order \
|
||||
they are created");
|
||||
}
|
||||
(Some(s1), Some(s2)) if !is_temporary && !is_closure => {
|
||||
db.span = MultiSpan::from_span(s2);
|
||||
db.span_label(error_span, &format!("borrow occurs here"));
|
||||
let msg = match opt_loan_path(&err.cmt) {
|
||||
None => "borrowed value".to_string(),
|
||||
Some(lp) => {
|
||||
format!("`{}`", self.loan_path_to_string(&lp))
|
||||
}
|
||||
};
|
||||
db.span_label(s2,
|
||||
&format!("{} dropped here while still borrowed", msg));
|
||||
db.span_label(s1, &format!("{} needs to live until here", value_kind));
|
||||
}
|
||||
_ => {
|
||||
match sub_span {
|
||||
Some(s) => {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
use self::SawTraitOrImplItemComponent::*;
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{self, Name, NodeId};
|
||||
use syntax::attr;
|
||||
use syntax::parse::token;
|
||||
use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
|
||||
use rustc::hir;
|
||||
@@ -53,6 +54,7 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
|
||||
def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
|
||||
hash_spans: bool,
|
||||
codemap: &'a mut CachingCodemapView<'tcx>,
|
||||
overflow_checks_enabled: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
|
||||
@@ -62,12 +64,16 @@ pub fn new(st: &'a mut IchHasher,
|
||||
codemap: &'a mut CachingCodemapView<'tcx>,
|
||||
hash_spans: bool)
|
||||
-> Self {
|
||||
let check_overflow = tcx.sess.opts.debugging_opts.force_overflow_checks
|
||||
.unwrap_or(tcx.sess.opts.debug_assertions);
|
||||
|
||||
StrictVersionHashVisitor {
|
||||
st: st,
|
||||
tcx: tcx,
|
||||
def_path_hashes: def_path_hashes,
|
||||
hash_spans: hash_spans,
|
||||
codemap: codemap,
|
||||
overflow_checks_enabled: check_overflow,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +89,6 @@ fn compute_def_id_hash(&mut self, def_id: DefId) -> u64 {
|
||||
// Also note that we are hashing byte offsets for the column, not unicode
|
||||
// codepoint offsets. For the purpose of the hash that's sufficient.
|
||||
fn hash_span(&mut self, span: Span) {
|
||||
debug_assert!(self.hash_spans);
|
||||
debug!("hash_span: st={:?}", self.st);
|
||||
|
||||
// If this is not an empty or invalid span, we want to hash the last
|
||||
@@ -241,37 +246,80 @@ enum SawExprComponent<'a> {
|
||||
SawExprRepeat,
|
||||
}
|
||||
|
||||
fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
|
||||
// The boolean returned indicates whether the span of this expression is always
|
||||
// significant, regardless of debuginfo.
|
||||
fn saw_expr<'a>(node: &'a Expr_,
|
||||
overflow_checks_enabled: bool)
|
||||
-> (SawExprComponent<'a>, bool) {
|
||||
let binop_can_panic_at_runtime = |binop| {
|
||||
match binop {
|
||||
BiAdd |
|
||||
BiSub |
|
||||
BiMul => overflow_checks_enabled,
|
||||
|
||||
BiDiv |
|
||||
BiRem => true,
|
||||
|
||||
BiAnd |
|
||||
BiOr |
|
||||
BiBitXor |
|
||||
BiBitAnd |
|
||||
BiBitOr |
|
||||
BiShl |
|
||||
BiShr |
|
||||
BiEq |
|
||||
BiLt |
|
||||
BiLe |
|
||||
BiNe |
|
||||
BiGe |
|
||||
BiGt => false
|
||||
}
|
||||
};
|
||||
|
||||
let unop_can_panic_at_runtime = |unop| {
|
||||
match unop {
|
||||
UnDeref |
|
||||
UnNot => false,
|
||||
UnNeg => overflow_checks_enabled,
|
||||
}
|
||||
};
|
||||
|
||||
match *node {
|
||||
ExprBox(..) => SawExprBox,
|
||||
ExprArray(..) => SawExprArray,
|
||||
ExprCall(..) => SawExprCall,
|
||||
ExprMethodCall(..) => SawExprMethodCall,
|
||||
ExprTup(..) => SawExprTup,
|
||||
ExprBinary(op, ..) => SawExprBinary(op.node),
|
||||
ExprUnary(op, _) => SawExprUnary(op),
|
||||
ExprLit(ref lit) => SawExprLit(lit.node.clone()),
|
||||
ExprCast(..) => SawExprCast,
|
||||
ExprType(..) => SawExprType,
|
||||
ExprIf(..) => SawExprIf,
|
||||
ExprWhile(..) => SawExprWhile,
|
||||
ExprLoop(_, id) => SawExprLoop(id.map(|id| id.node.as_str())),
|
||||
ExprMatch(..) => SawExprMatch,
|
||||
ExprClosure(cc, _, _, _) => SawExprClosure(cc),
|
||||
ExprBlock(..) => SawExprBlock,
|
||||
ExprAssign(..) => SawExprAssign,
|
||||
ExprAssignOp(op, ..) => SawExprAssignOp(op.node),
|
||||
ExprField(_, name) => SawExprField(name.node.as_str()),
|
||||
ExprTupField(_, id) => SawExprTupField(id.node),
|
||||
ExprIndex(..) => SawExprIndex,
|
||||
ExprPath(ref qself, _) => SawExprPath(qself.as_ref().map(|q| q.position)),
|
||||
ExprAddrOf(m, _) => SawExprAddrOf(m),
|
||||
ExprBreak(id) => SawExprBreak(id.map(|id| id.node.as_str())),
|
||||
ExprAgain(id) => SawExprAgain(id.map(|id| id.node.as_str())),
|
||||
ExprRet(..) => SawExprRet,
|
||||
ExprInlineAsm(ref a,..) => SawExprInlineAsm(a),
|
||||
ExprStruct(..) => SawExprStruct,
|
||||
ExprRepeat(..) => SawExprRepeat,
|
||||
ExprBox(..) => (SawExprBox, false),
|
||||
ExprArray(..) => (SawExprArray, false),
|
||||
ExprCall(..) => (SawExprCall, false),
|
||||
ExprMethodCall(..) => (SawExprMethodCall, false),
|
||||
ExprTup(..) => (SawExprTup, false),
|
||||
ExprBinary(op, ..) => {
|
||||
(SawExprBinary(op.node), binop_can_panic_at_runtime(op.node))
|
||||
}
|
||||
ExprUnary(op, _) => {
|
||||
(SawExprUnary(op), unop_can_panic_at_runtime(op))
|
||||
}
|
||||
ExprLit(ref lit) => (SawExprLit(lit.node.clone()), false),
|
||||
ExprCast(..) => (SawExprCast, false),
|
||||
ExprType(..) => (SawExprType, false),
|
||||
ExprIf(..) => (SawExprIf, false),
|
||||
ExprWhile(..) => (SawExprWhile, false),
|
||||
ExprLoop(_, id) => (SawExprLoop(id.map(|id| id.node.as_str())), false),
|
||||
ExprMatch(..) => (SawExprMatch, false),
|
||||
ExprClosure(cc, _, _, _) => (SawExprClosure(cc), false),
|
||||
ExprBlock(..) => (SawExprBlock, false),
|
||||
ExprAssign(..) => (SawExprAssign, false),
|
||||
ExprAssignOp(op, ..) => {
|
||||
(SawExprAssignOp(op.node), binop_can_panic_at_runtime(op.node))
|
||||
}
|
||||
ExprField(_, name) => (SawExprField(name.node.as_str()), false),
|
||||
ExprTupField(_, id) => (SawExprTupField(id.node), false),
|
||||
ExprIndex(..) => (SawExprIndex, true),
|
||||
ExprPath(ref qself, _) => (SawExprPath(qself.as_ref().map(|q| q.position)), false),
|
||||
ExprAddrOf(m, _) => (SawExprAddrOf(m), false),
|
||||
ExprBreak(id) => (SawExprBreak(id.map(|id| id.node.as_str())), false),
|
||||
ExprAgain(id) => (SawExprAgain(id.map(|id| id.node.as_str())), false),
|
||||
ExprRet(..) => (SawExprRet, false),
|
||||
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(a), false),
|
||||
ExprStruct(..) => (SawExprStruct, false),
|
||||
ExprRepeat(..) => (SawExprRepeat, false),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,10 +469,13 @@ macro_rules! hash_attrs {
|
||||
|
||||
macro_rules! hash_span {
|
||||
($visitor:expr, $span:expr) => ({
|
||||
if $visitor.hash_spans {
|
||||
hash_span!($visitor, $span, false)
|
||||
});
|
||||
($visitor:expr, $span:expr, $force:expr) => ({
|
||||
if $force || $visitor.hash_spans {
|
||||
$visitor.hash_span($span);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
|
||||
@@ -474,10 +525,12 @@ fn visit_lifetime_def(&mut self, l: &'tcx LifetimeDef) {
|
||||
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr) {
|
||||
debug!("visit_expr: st={:?}", self.st);
|
||||
SawExpr(saw_expr(&ex.node)).hash(self.st);
|
||||
let (saw_expr, force_span) = saw_expr(&ex.node,
|
||||
self.overflow_checks_enabled);
|
||||
SawExpr(saw_expr).hash(self.st);
|
||||
// No need to explicitly hash the discriminant here, since we are
|
||||
// implicitly hashing the discriminant of SawExprComponent.
|
||||
hash_span!(self, ex.span);
|
||||
hash_span!(self, ex.span, force_span);
|
||||
hash_attrs!(self, &ex.attrs);
|
||||
visit::walk_expr(self, ex)
|
||||
}
|
||||
@@ -519,6 +572,9 @@ fn visit_foreign_item(&mut self, i: &'tcx ForeignItem) {
|
||||
|
||||
fn visit_item(&mut self, i: &'tcx Item) {
|
||||
debug!("visit_item: {:?} st={:?}", i, self.st);
|
||||
|
||||
self.maybe_enable_overflow_checks(&i.attrs);
|
||||
|
||||
SawItem(saw_item(&i.node)).hash(self.st);
|
||||
hash_span!(self, i.span);
|
||||
hash_attrs!(self, &i.attrs);
|
||||
@@ -545,6 +601,9 @@ fn visit_generics(&mut self, g: &'tcx Generics) {
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &'tcx TraitItem) {
|
||||
debug!("visit_trait_item: st={:?}", self.st);
|
||||
|
||||
self.maybe_enable_overflow_checks(&ti.attrs);
|
||||
|
||||
SawTraitItem(saw_trait_item(&ti.node)).hash(self.st);
|
||||
hash_span!(self, ti.span);
|
||||
hash_attrs!(self, &ti.attrs);
|
||||
@@ -553,6 +612,9 @@ fn visit_trait_item(&mut self, ti: &'tcx TraitItem) {
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'tcx ImplItem) {
|
||||
debug!("visit_impl_item: st={:?}", self.st);
|
||||
|
||||
self.maybe_enable_overflow_checks(&ii.attrs);
|
||||
|
||||
SawImplItem(saw_impl_item(&ii.node)).hash(self.st);
|
||||
hash_span!(self, ii.span);
|
||||
hash_attrs!(self, &ii.attrs);
|
||||
@@ -842,4 +904,10 @@ fn indices_sorted_by<T, K, F>(&mut self, items: &[T], get_key: F) -> Vec<usize>
|
||||
indices.sort_by_key(|index| get_key(&items[*index]));
|
||||
indices
|
||||
}
|
||||
|
||||
fn maybe_enable_overflow_checks(&mut self, item_attrs: &[ast::Attribute]) {
|
||||
if attr::contains_name(item_attrs, "rustc_inherit_overflow_checks") {
|
||||
self.overflow_checks_enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
|
||||
pub type DirtyNodes = FnvHashSet<DepNode<DefPathIndex>>;
|
||||
|
||||
type CleanEdges = Vec<(DepNode<DefId>, DepNode<DefId>)>;
|
||||
|
||||
/// If we are in incremental mode, and a previous dep-graph exists,
|
||||
/// then load up those nodes/edges that are still valid into the
|
||||
/// dep-graph for this session. (This is assumed to be running very
|
||||
|
||||
@@ -1189,7 +1189,7 @@ impl LateLintPass for MutableTransmutes {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &hir::Expr) {
|
||||
use syntax::abi::Abi::RustIntrinsic;
|
||||
|
||||
let msg = "mutating transmuted &mut T from &T may cause undefined behavior,\
|
||||
let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \
|
||||
consider instead using an UnsafeCell";
|
||||
match get_transmute_from_to(cx, expr) {
|
||||
Some((&ty::TyRef(_, from_mt), &ty::TyRef(_, to_mt))) => {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
use build_reduced_graph::BuildReducedGraphVisitor;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
|
||||
use rustc::hir::map::{self, DefCollector};
|
||||
use rustc::util::nodemap::FnvHashMap;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
@@ -80,8 +79,6 @@ pub struct LegacyBinding<'a> {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
pub type LegacyImports = FnvHashMap<ast::Name, (Rc<SyntaxExtension>, Span)>;
|
||||
|
||||
impl<'a> base::Resolver for Resolver<'a> {
|
||||
fn next_node_id(&mut self) -> ast::NodeId {
|
||||
self.session.next_node_id()
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
use llvm::{ValueRef, True, IntEQ, IntNE};
|
||||
use rustc::ty::layout;
|
||||
use rustc::ty::{self, Ty, AdtKind};
|
||||
use syntax::attr;
|
||||
use build::*;
|
||||
use common::*;
|
||||
use debuginfo::DebugLoc;
|
||||
@@ -66,8 +65,6 @@ pub enum BranchKind {
|
||||
Single
|
||||
}
|
||||
|
||||
type Hint = attr::ReprAttr;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct MaybeSizedValue {
|
||||
pub value: ValueRef,
|
||||
@@ -119,9 +116,6 @@ fn compute_fields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
/// This represents the (GEP) indices to follow to get to the discriminant field
|
||||
pub type DiscrField = Vec<usize>;
|
||||
|
||||
/// LLVM-level types are a little complicated.
|
||||
///
|
||||
/// C-like enums need to be actual ints, not wrapped in a struct,
|
||||
|
||||
@@ -171,8 +171,6 @@ struct ConvertedBinding<'tcx> {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec<ty::PolyProjectionPredicate<'tcx>>);
|
||||
|
||||
/// Dummy type used for the `Self` of a `TraitRef` created for converting
|
||||
/// a trait object, and which gets removed in `ExistentialTraitRef`.
|
||||
/// This type must not appear anywhere in other converted types.
|
||||
|
||||
@@ -124,10 +124,6 @@ pub struct FullBucket<K, V, M> {
|
||||
table: M,
|
||||
}
|
||||
|
||||
pub type EmptyBucketImm<'table, K, V> = EmptyBucket<K, V, &'table RawTable<K, V>>;
|
||||
pub type FullBucketImm<'table, K, V> = FullBucket<K, V, &'table RawTable<K, V>>;
|
||||
|
||||
pub type EmptyBucketMut<'table, K, V> = EmptyBucket<K, V, &'table mut RawTable<K, V>>;
|
||||
pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
|
||||
|
||||
pub enum BucketState<K, V, M> {
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
// 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.
|
||||
|
||||
// This test case tests the incremental compilation hash (ICH) implementation
|
||||
// for exprs that can panic at runtime (e.g. because of bounds checking). For
|
||||
// these expressions an error message containing their source location is
|
||||
// generated, so their hash must always depend on their location in the source
|
||||
// code, not just when debuginfo is enabled.
|
||||
|
||||
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||
// rev3 and make sure that the hash has not changed.
|
||||
|
||||
// must-compile-successfully
|
||||
// revisions: cfail1 cfail2 cfail3
|
||||
// compile-flags: -Z query-dep-graph -C debug-assertions
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![crate_type="rlib"]
|
||||
|
||||
|
||||
// Indexing expression ---------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn indexing(slice: &[u8]) -> u8 {
|
||||
slice[100]
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn indexing(slice: &[u8]) -> u8 {
|
||||
slice[100]
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow plus ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_plus(val: i32) -> i32 {
|
||||
val + 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_plus(val: i32) -> i32 {
|
||||
val + 1
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow minus ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_minus(val: i32) -> i32 {
|
||||
val - 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_minus(val: i32) -> i32 {
|
||||
val - 1
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow mult ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_mult(val: i32) -> i32 {
|
||||
val * 2
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_mult(val: i32) -> i32 {
|
||||
val * 2
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow negation ------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_negation(val: i32) -> i32 {
|
||||
-val
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_negation(val: i32) -> i32 {
|
||||
-val
|
||||
}
|
||||
|
||||
|
||||
// Division by zero ------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn division_by_zero(val: i32) -> i32 {
|
||||
2 / val
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn division_by_zero(val: i32) -> i32 {
|
||||
2 / val
|
||||
}
|
||||
|
||||
// Division by zero ------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn mod_by_zero(val: i32) -> i32 {
|
||||
2 % val
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn mod_by_zero(val: i32) -> i32 {
|
||||
2 % val
|
||||
}
|
||||
|
||||
|
||||
|
||||
// THE FOLLOWING ITEMS SHOULD NOT BE INFLUENCED BY THEIR SOURCE LOCATION
|
||||
|
||||
// bitwise ---------------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn bitwise(val: i32) -> i32 {
|
||||
!val & 0x101010101 | 0x45689 ^ 0x2372382 << 1 >> 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn bitwise(val: i32) -> i32 {
|
||||
!val & 0x101010101 | 0x45689 ^ 0x2372382 << 1 >> 1
|
||||
}
|
||||
|
||||
|
||||
// logical ---------------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {
|
||||
val1 && val2 || val3
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {
|
||||
val1 && val2 || val3
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
// 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.
|
||||
|
||||
// This test case tests the incremental compilation hash (ICH) implementation
|
||||
// for exprs that can panic at runtime (e.g. because of bounds checking). For
|
||||
// these expressions an error message containing their source location is
|
||||
// generated, so their hash must always depend on their location in the source
|
||||
// code, not just when debuginfo is enabled.
|
||||
|
||||
// As opposed to the panic_exprs.rs test case, this test case checks that things
|
||||
// behave as expected when overflow checks are off:
|
||||
//
|
||||
// - Addition, subtraction, and multiplication do not change the ICH, unless
|
||||
// the function containing them is marked with rustc_inherit_overflow_checks.
|
||||
// - Division by zero and bounds checks always influence the ICH
|
||||
|
||||
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||
// rev3 and make sure that the hash has not changed.
|
||||
|
||||
// must-compile-successfully
|
||||
// revisions: cfail1 cfail2 cfail3
|
||||
// compile-flags: -Z query-dep-graph -Z force-overflow-checks=off
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![crate_type="rlib"]
|
||||
|
||||
|
||||
// Indexing expression ---------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn indexing(slice: &[u8]) -> u8 {
|
||||
slice[100]
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn indexing(slice: &[u8]) -> u8 {
|
||||
slice[100]
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow plus ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_plus_inherit(val: i32) -> i32 {
|
||||
val + 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_plus_inherit(val: i32) -> i32 {
|
||||
val + 1
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow minus ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_minus_inherit(val: i32) -> i32 {
|
||||
val - 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_minus_inherit(val: i32) -> i32 {
|
||||
val - 1
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow mult ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_mult_inherit(val: i32) -> i32 {
|
||||
val * 2
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_mult_inherit(val: i32) -> i32 {
|
||||
val * 2
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow negation ------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_negation_inherit(val: i32) -> i32 {
|
||||
-val
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn arithmetic_overflow_negation_inherit(val: i32) -> i32 {
|
||||
-val
|
||||
}
|
||||
|
||||
|
||||
// Division by zero ------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn division_by_zero(val: i32) -> i32 {
|
||||
2 / val
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn division_by_zero(val: i32) -> i32 {
|
||||
2 / val
|
||||
}
|
||||
|
||||
// Division by zero ------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn mod_by_zero(val: i32) -> i32 {
|
||||
2 % val
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn mod_by_zero(val: i32) -> i32 {
|
||||
2 % val
|
||||
}
|
||||
|
||||
|
||||
|
||||
// THE FOLLOWING ITEMS SHOULD NOT BE INFLUENCED BY THEIR SOURCE LOCATION
|
||||
|
||||
// bitwise ---------------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn bitwise(val: i32) -> i32 {
|
||||
!val & 0x101010101 | 0x45689 ^ 0x2372382 << 1 >> 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn bitwise(val: i32) -> i32 {
|
||||
!val & 0x101010101 | 0x45689 ^ 0x2372382 << 1 >> 1
|
||||
}
|
||||
|
||||
|
||||
// logical ---------------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {
|
||||
val1 && val2 || val3
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {
|
||||
val1 && val2 || val3
|
||||
}
|
||||
|
||||
// Arithmetic overflow plus ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_plus(val: i32) -> i32 {
|
||||
val + 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_plus(val: i32) -> i32 {
|
||||
val + 1
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow minus ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_minus(val: i32) -> i32 {
|
||||
val - 1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_minus(val: i32) -> i32 {
|
||||
val - 1
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow mult ----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_mult(val: i32) -> i32 {
|
||||
val * 2
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_mult(val: i32) -> i32 {
|
||||
val * 2
|
||||
}
|
||||
|
||||
|
||||
// Arithmetic overflow negation ------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
pub fn arithmetic_overflow_negation(val: i32) -> i32 {
|
||||
-val
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_negation(val: i32) -> i32 {
|
||||
-val
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
error: borrowed value does not live long enough
|
||||
--> $DIR/borrowck-ref-into-rvalue.rs:18:5
|
||||
|
|
||||
14 | Some(ref m) => { //~ ERROR borrowed value does not live long enough
|
||||
| ----- borrow occurs here
|
||||
...
|
||||
18 | }
|
||||
| ^ borrowed value dropped here while still borrowed
|
||||
19 | println!("{}", *msg);
|
||||
20 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
|
||||
= note: consider using a `let` binding to increase its lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
error: `*a` does not live long enough
|
||||
--> $DIR/destructor-restrictions.rs:19:5
|
||||
|
|
||||
18 | *a.borrow() + 1 //~ ERROR `*a` does not live long enough
|
||||
| - borrow occurs here
|
||||
19 | };
|
||||
| ^- borrowed value needs to live until here
|
||||
| |
|
||||
| `*a` dropped here while still borrowed
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -4,8 +4,8 @@ error: `x` does not live long enough
|
||||
18 | let f = to_fn_once(move|| &x);
|
||||
| ^
|
||||
| |
|
||||
| does not live long enough
|
||||
| borrowed value only lives until here
|
||||
| borrow occurs here
|
||||
| `x` dropped here while still borrowed
|
||||
...
|
||||
23 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
@@ -9,14 +9,14 @@ error: `y` does not live long enough
|
||||
= note: values in a scope are dropped in the opposite order they are created
|
||||
|
||||
error: `y` does not live long enough
|
||||
--> $DIR/issue-23338-locals-die-before-temps-of-body.rs:27:9
|
||||
--> $DIR/issue-23338-locals-die-before-temps-of-body.rs:28:5
|
||||
|
|
||||
27 | y.borrow().clone() //~ ERROR `y` does not live long enough
|
||||
| ^ does not live long enough
|
||||
| - borrow occurs here
|
||||
28 | };
|
||||
| -- borrowed value needs to live until here
|
||||
| ^- borrowed value needs to live until here
|
||||
| |
|
||||
| borrowed value only lives until here
|
||||
| `y` dropped here while still borrowed
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
error: `b` does not live long enough
|
||||
--> $DIR/mut-ptr-cant-outlive-ref.rs:19:5
|
||||
|
|
||||
18 | p = &*b; //~ ERROR `b` does not live long enough
|
||||
| - borrow occurs here
|
||||
19 | }
|
||||
| ^ `b` dropped here while still borrowed
|
||||
20 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
error: `a` does not live long enough
|
||||
--> $DIR/range-2.rs:20:5
|
||||
|
|
||||
17 | &a..&b
|
||||
| - borrow occurs here
|
||||
...
|
||||
20 | };
|
||||
| ^ `a` dropped here while still borrowed
|
||||
21 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: `b` does not live long enough
|
||||
--> $DIR/range-2.rs:20:5
|
||||
|
|
||||
17 | &a..&b
|
||||
| - borrow occurs here
|
||||
...
|
||||
20 | };
|
||||
| ^ `b` dropped here while still borrowed
|
||||
21 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
error: `c` does not live long enough
|
||||
--> $DIR/regionck-unboxed-closure-lifetimes.rs:19:5
|
||||
|
|
||||
17 | let c_ref = &c; //~ ERROR `c` does not live long enough
|
||||
| - borrow occurs here
|
||||
18 | f = move |a: isize, b: isize| { a + b + *c_ref };
|
||||
19 | }
|
||||
| ^ `c` dropped here while still borrowed
|
||||
20 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
error: `tmp0` does not live long enough
|
||||
--> $DIR/regions-close-over-type-parameter-2.rs:35:5
|
||||
|
|
||||
33 | let tmp1 = &tmp0; //~ ERROR `tmp0` does not live long enough
|
||||
| ---- borrow occurs here
|
||||
34 | repeater3(tmp1)
|
||||
35 | };
|
||||
| ^- borrowed value needs to live until here
|
||||
| |
|
||||
| `tmp0` dropped here while still borrowed
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
error: `x` does not live long enough
|
||||
--> $DIR/regions-escape-loop-via-variable.rs:22:5
|
||||
|
|
||||
21 | p = &x; //~ ERROR `x` does not live long enough
|
||||
| - borrow occurs here
|
||||
22 | }
|
||||
| ^ `x` dropped here while still borrowed
|
||||
23 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
error: `z` does not live long enough
|
||||
--> $DIR/regions-escape-loop-via-vec.rs:26:5
|
||||
|
|
||||
22 | _y.push(&mut z); //~ ERROR `z` does not live long enough
|
||||
| - borrow occurs here
|
||||
...
|
||||
26 | }
|
||||
| ^ `z` dropped here while still borrowed
|
||||
27 | //~^ NOTE borrowed value only lives until here
|
||||
28 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error[E0503]: cannot use `x` because it was mutably borrowed
|
||||
--> $DIR/regions-escape-loop-via-vec.rs:18:11
|
||||
|
|
||||
14 | let mut _y = vec![&mut x];
|
||||
| - borrow of `x` occurs here
|
||||
...
|
||||
18 | while x < 10 { //~ ERROR cannot use `x` because it was mutably borrowed
|
||||
| ^ use of borrowed `x`
|
||||
|
||||
error[E0503]: cannot use `x` because it was mutably borrowed
|
||||
--> $DIR/regions-escape-loop-via-vec.rs:20:13
|
||||
|
|
||||
14 | let mut _y = vec![&mut x];
|
||||
| - borrow of `x` occurs here
|
||||
...
|
||||
20 | let mut z = x; //~ ERROR cannot use `x` because it was mutably borrowed
|
||||
| ^^^^^ use of borrowed `x`
|
||||
|
||||
error[E0506]: cannot assign to `x` because it is borrowed
|
||||
--> $DIR/regions-escape-loop-via-vec.rs:24:9
|
||||
|
|
||||
14 | let mut _y = vec![&mut x];
|
||||
| - borrow of `x` occurs here
|
||||
...
|
||||
24 | x += 1; //~ ERROR cannot assign
|
||||
| ^^^^^^ assignment to borrowed `x` occurs here
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
error: `*x` does not live long enough
|
||||
--> $DIR/regions-infer-borrow-scope-within-loop.rs:28:5
|
||||
|
|
||||
24 | y = borrow(&*x); //~ ERROR `*x` does not live long enough
|
||||
| -- borrow occurs here
|
||||
...
|
||||
28 | }
|
||||
| ^ `*x` dropped here while still borrowed
|
||||
29 | assert!(*y != 0);
|
||||
30 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
error: `x` does not live long enough
|
||||
--> $DIR/send-is-not-static-ensures-scoping.rs:32:5
|
||||
|
|
||||
26 | let y = &x; //~ ERROR `x` does not live long enough
|
||||
| - borrow occurs here
|
||||
...
|
||||
32 | };
|
||||
| ^ `x` dropped here while still borrowed
|
||||
...
|
||||
35 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: `y` does not live long enough
|
||||
--> $DIR/send-is-not-static-ensures-scoping.rs:29:22
|
||||
|
|
||||
28 | scoped(|| {
|
||||
| -- capture occurs here
|
||||
29 | let _z = y;
|
||||
| ^ does not live long enough
|
||||
...
|
||||
32 | };
|
||||
| - borrowed value only lives until here
|
||||
...
|
||||
35 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
error: `x` does not live long enough
|
||||
--> $DIR/send-is-not-static-std-sync-2.rs:22:5
|
||||
|
|
||||
21 | Mutex::new(&x) //~ ERROR does not live long enough
|
||||
| - borrow occurs here
|
||||
22 | };
|
||||
| ^ `x` dropped here while still borrowed
|
||||
...
|
||||
25 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: `x` does not live long enough
|
||||
--> $DIR/send-is-not-static-std-sync-2.rs:31:5
|
||||
|
|
||||
30 | RwLock::new(&x) //~ ERROR does not live long enough
|
||||
| - borrow occurs here
|
||||
31 | };
|
||||
| ^ `x` dropped here while still borrowed
|
||||
32 | let _dangling = *lock.read().unwrap();
|
||||
33 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: `x` does not live long enough
|
||||
--> $DIR/send-is-not-static-std-sync-2.rs:41:5
|
||||
|
|
||||
39 | let _ = tx.send(&x); //~ ERROR does not live long enough
|
||||
| - borrow occurs here
|
||||
40 | (tx, rx)
|
||||
41 | };
|
||||
| ^ `x` dropped here while still borrowed
|
||||
...
|
||||
44 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
error: `z` does not live long enough
|
||||
--> $DIR/send-is-not-static-std-sync.rs:27:5
|
||||
|
|
||||
26 | *lock.lock().unwrap() = &z; //~ ERROR does not live long enough
|
||||
| - borrow occurs here
|
||||
27 | }
|
||||
| ^ `z` dropped here while still borrowed
|
||||
28 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error[E0505]: cannot move out of `y` because it is borrowed
|
||||
--> $DIR/send-is-not-static-std-sync.rs:23:10
|
||||
|
|
||||
22 | *lock.lock().unwrap() = &*y;
|
||||
| -- borrow of `*y` occurs here
|
||||
23 | drop(y); //~ ERROR cannot move out
|
||||
| ^ move out of `y` occurs here
|
||||
|
||||
error: `z` does not live long enough
|
||||
--> $DIR/send-is-not-static-std-sync.rs:39:5
|
||||
|
|
||||
38 | *lock.write().unwrap() = &z; //~ ERROR does not live long enough
|
||||
| - borrow occurs here
|
||||
39 | }
|
||||
| ^ `z` dropped here while still borrowed
|
||||
40 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error[E0505]: cannot move out of `y` because it is borrowed
|
||||
--> $DIR/send-is-not-static-std-sync.rs:35:10
|
||||
|
|
||||
34 | *lock.write().unwrap() = &*y;
|
||||
| -- borrow of `*y` occurs here
|
||||
35 | drop(y); //~ ERROR cannot move out
|
||||
| ^ move out of `y` occurs here
|
||||
|
||||
error: `z` does not live long enough
|
||||
--> $DIR/send-is-not-static-std-sync.rs:53:5
|
||||
|
|
||||
52 | tx.send(&z).unwrap(); //~ ERROR does not live long enough
|
||||
| - borrow occurs here
|
||||
53 | }
|
||||
| ^ `z` dropped here while still borrowed
|
||||
54 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error[E0505]: cannot move out of `y` because it is borrowed
|
||||
--> $DIR/send-is-not-static-std-sync.rs:49:10
|
||||
|
|
||||
48 | tx.send(&*y);
|
||||
| -- borrow of `*y` occurs here
|
||||
49 | drop(y); //~ ERROR cannot move out
|
||||
| ^ move out of `y` occurs here
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
error: `pointer` does not live long enough
|
||||
--> $DIR/wf-method-late-bound-regions.rs:31:5
|
||||
|
|
||||
30 | f2.xmute(&pointer) //~ ERROR `pointer` does not live long enough
|
||||
| ------- borrow occurs here
|
||||
31 | };
|
||||
| ^ `pointer` dropped here while still borrowed
|
||||
32 | println!("{}", dangling);
|
||||
33 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
Reference in New Issue
Block a user