From 5a2fb8806ba841c74dee49a732937a71d16caff5 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 22 Oct 2016 14:09:45 +0100 Subject: [PATCH 01/12] Prevent exhaustive matching of Ordering to allow for future extension --- src/libcore/sync/atomic.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 657f7e7992fee..c10f7e39fc39d 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -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(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(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(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(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(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(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(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(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(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(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"), } } } From 07bff08e4f3b3fd57adb02af63150b5893a864db Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 29 Oct 2016 15:44:43 -0700 Subject: [PATCH 02/12] Copyediting on documentation for write! and writeln! Fix various sentence fragments, missing articles, and other grammatical issues in the documentation for write! and writeln!. Also fix the links (and link names) for common return types. --- src/libcore/macros.rs | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index e6c3f549ec8e6..b73166ebef3d4 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -316,26 +316,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 /// @@ -354,31 +355,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 /// From 10ce90fca20fce776b8bdad504a5e3b915ded99f Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Sun, 30 Oct 2016 11:26:25 +0300 Subject: [PATCH 03/12] Fix armv7 autodetection armv7l is armv7 architecture and CFG_CPUTYPE should be armv7 in order to end up with armv7-unknown-linux-gnueabihf.mk rather than arm-unknown-linux-gnueabihf.mk --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 2bc8c72e3ea1c..d62084cb4653f 100755 --- a/configure +++ b/configure @@ -508,7 +508,7 @@ case $CFG_CPUTYPE in ;; armv7l) - CFG_CPUTYPE=arm + CFG_CPUTYPE=armv7 CFG_OSTYPE="${CFG_OSTYPE}eabihf" ;; From 9b81f3c81b6340221f9713afa9ead070086d7314 Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Sun, 30 Oct 2016 11:27:58 +0300 Subject: [PATCH 04/12] Add armv6l autodetection Use arm-unknown-linux-gnueabihf for hardware floating point armv6 variant --- configure | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure b/configure index d62084cb4653f..4e62e49412e2d 100755 --- a/configure +++ b/configure @@ -507,6 +507,11 @@ case $CFG_CPUTYPE in CFG_CPUTYPE=arm ;; + armv6l) + CFG_CPUTYPE=arm + CFG_OSTYPE="${CFG_OSTYPE}eabihf" + ;; + armv7l) CFG_CPUTYPE=armv7 CFG_OSTYPE="${CFG_OSTYPE}eabihf" From c8c6d2c73269d759aec764a3356d4e19781de53c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 29 Oct 2016 21:58:52 -0400 Subject: [PATCH 05/12] Use quieter test output when running tests on Travis CI. Fixes https://github.com/rust-lang/rust/issues/36788. --- .travis.yml | 2 +- configure | 1 + src/bootstrap/check.rs | 17 ++++++++++++++++- src/bootstrap/config.rs | 2 ++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c5d8a94f39b05..0bc9a4ad4198c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 " diff --git a/configure b/configure index 2bc8c72e3ea1c..5e670c29a74ec 100755 --- a/configure +++ b/configure @@ -610,6 +610,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" diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index af76a49fed045..0a281b89c571f 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -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); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 8c0ad1ccf825f..abaa9389d809a 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -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, pub prefix: Option, @@ -338,6 +339,7 @@ impl Config { ("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), From 07c8a25f42d1dcd8bd2bd22c8804e4bc5b6583a9 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 31 Oct 2016 23:14:27 +0900 Subject: [PATCH 06/12] Remove unused type aliases --- src/librustc_borrowck/borrowck/mir/abs_domain.rs | 6 ++---- src/librustc_borrowck/borrowck/mod.rs | 2 -- src/librustc_incremental/persist/load.rs | 2 -- src/librustc_resolve/macros.rs | 3 --- src/librustc_trans/adt.rs | 6 ------ src/librustc_typeck/astconv.rs | 2 -- src/libstd/collections/hash/table.rs | 4 ---- 7 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/librustc_borrowck/borrowck/mir/abs_domain.rs b/src/librustc_borrowck/borrowck/mir/abs_domain.rs index dc450433ad9fa..5e61c2ec7a292 100644 --- a/src/librustc_borrowck/borrowck/mir/abs_domain.rs +++ b/src/librustc_borrowck/borrowck/mir/abs_domain.rs @@ -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>; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index ef6936b6e7db3..f85309cf51818 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -300,8 +300,6 @@ struct BorrowStats { guaranteed_paths: usize } -pub type BckResult<'tcx, T> = Result>; - /////////////////////////////////////////////////////////////////////////// // Loans and loan paths diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 1f43e79ace3ae..7cef246b6cb2c 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -32,8 +32,6 @@ use super::file_format; pub type DirtyNodes = FnvHashSet>; -type CleanEdges = Vec<(DepNode, DepNode)>; - /// 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 diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 72e5823598ea1..ed46c1d96ad17 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -12,7 +12,6 @@ use {Module, Resolver}; 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, Span)>; - impl<'a> base::Resolver for Resolver<'a> { fn next_node_id(&mut self) -> ast::NodeId { self.session.next_node_id() diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs index c6f3ef0a5beed..4d3361c1873f0 100644 --- a/src/librustc_trans/adt.rs +++ b/src/librustc_trans/adt.rs @@ -48,7 +48,6 @@ use std; 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; - /// LLVM-level types are a little complicated. /// /// C-like enums need to be actual ints, not wrapped in a struct, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8799050b1b999..1aa502fc443ec 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -171,8 +171,6 @@ struct ConvertedBinding<'tcx> { span: Span, } -type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec>); - /// 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. diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index b357bc3552a5e..73e9f1a500437 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -113,10 +113,6 @@ pub struct FullBucket { table: M, } -pub type EmptyBucketImm<'table, K, V> = EmptyBucket>; -pub type FullBucketImm<'table, K, V> = FullBucket>; - -pub type EmptyBucketMut<'table, K, V> = EmptyBucket>; pub type FullBucketMut<'table, K, V> = FullBucket>; pub enum BucketState { From b926e8d08989a6e45f00c952f1867000fd9f58ea Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Mon, 31 Oct 2016 19:41:22 +0100 Subject: [PATCH 07/12] Add missing space in mutable_transmutes lint --- src/librustc_lint/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index eee34324a6583..a28109c147191 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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))) => { From e3025a07338eca4092f96c16011caccee149c8d4 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 31 Oct 2016 16:37:13 -0400 Subject: [PATCH 08/12] ICH: Hash expression spans if their source location is captured for panics --- .../calculate_svh/svh_visitor.rs | 138 ++++++++++---- src/test/incremental/hashes/panic_exprs.rs | 173 ++++++++++++++++++ 2 files changed, 276 insertions(+), 35 deletions(-) create mode 100644 src/test/incremental/hashes/panic_exprs.rs diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 51c894e1b78f0..80c41f855ba5c 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -21,6 +21,7 @@ use self::SawTyComponent::*; 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 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { 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 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { // 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 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has 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 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has 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 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has 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 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has 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 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { 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; + } + } } diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs new file mode 100644 index 0000000000000..f5f4c0042b432 --- /dev/null +++ b/src/test/incremental/hashes/panic_exprs.rs @@ -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 or the MIT license +// , 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 +} From 6720e0191cc7a735b9991a955c7acf26cbab3c49 Mon Sep 17 00:00:00 2001 From: Mark-Simulacrum Date: Tue, 1 Nov 2016 09:47:09 -0600 Subject: [PATCH 09/12] Add tracking issue number to Result::unwrap_or_default unstable annotation. --- src/libcore/result.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 3d34f62006785..9ba5ff7c3a462 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -821,7 +821,7 @@ impl Result { /// [`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, From a0e7e357a796f93527d0a0e850fa71c48594b91d Mon Sep 17 00:00:00 2001 From: Mikhail Modin Date: Wed, 26 Oct 2016 19:10:39 +0300 Subject: [PATCH 10/12] Improve "Doesn't live long enough" error case with different lifetime with spans --- src/librustc_borrowck/borrowck/mod.rs | 13 +++++ .../span}/borrowck-ref-into-rvalue.rs | 0 .../ui/span/borrowck-ref-into-rvalue.stderr | 16 ++++++ .../span}/destructor-restrictions.rs | 0 .../ui/span/destructor-restrictions.stderr | 12 ++++ src/test/ui/span/issue-11925.stderr | 4 +- ...338-locals-die-before-temps-of-body.stderr | 8 +-- .../span}/mut-ptr-cant-outlive-ref.rs | 0 .../ui/span/mut-ptr-cant-outlive-ref.stderr | 12 ++++ src/test/{compile-fail => ui/span}/range-2.rs | 0 src/test/ui/span/range-2.stderr | 24 ++++++++ .../regionck-unboxed-closure-lifetimes.rs | 0 .../regionck-unboxed-closure-lifetimes.stderr | 13 +++++ .../regions-close-over-type-parameter-2.rs | 0 ...regions-close-over-type-parameter-2.stderr | 13 +++++ .../span}/regions-escape-loop-via-variable.rs | 0 .../regions-escape-loop-via-variable.stderr | 12 ++++ .../span}/regions-escape-loop-via-vec.rs | 0 .../span/regions-escape-loop-via-vec.stderr | 41 ++++++++++++++ .../regions-infer-borrow-scope-within-loop.rs | 0 ...ions-infer-borrow-scope-within-loop.stderr | 14 +++++ .../send-is-not-static-ensures-scoping.rs | 0 .../send-is-not-static-ensures-scoping.stderr | 28 ++++++++++ .../span}/send-is-not-static-std-sync-2.rs | 0 .../span/send-is-not-static-std-sync-2.stderr | 36 ++++++++++++ .../span}/send-is-not-static-std-sync.rs | 0 .../span/send-is-not-static-std-sync.stderr | 56 +++++++++++++++++++ .../span}/wf-method-late-bound-regions.rs | 0 .../span/wf-method-late-bound-regions.stderr | 13 +++++ 29 files changed, 309 insertions(+), 6 deletions(-) rename src/test/{compile-fail/borrowck => ui/span}/borrowck-ref-into-rvalue.rs (100%) create mode 100644 src/test/ui/span/borrowck-ref-into-rvalue.stderr rename src/test/{compile-fail => ui/span}/destructor-restrictions.rs (100%) create mode 100644 src/test/ui/span/destructor-restrictions.stderr rename src/test/{compile-fail => ui/span}/mut-ptr-cant-outlive-ref.rs (100%) create mode 100644 src/test/ui/span/mut-ptr-cant-outlive-ref.stderr rename src/test/{compile-fail => ui/span}/range-2.rs (100%) create mode 100644 src/test/ui/span/range-2.stderr rename src/test/{compile-fail => ui/span}/regionck-unboxed-closure-lifetimes.rs (100%) create mode 100644 src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr rename src/test/{compile-fail => ui/span}/regions-close-over-type-parameter-2.rs (100%) create mode 100644 src/test/ui/span/regions-close-over-type-parameter-2.stderr rename src/test/{compile-fail => ui/span}/regions-escape-loop-via-variable.rs (100%) create mode 100644 src/test/ui/span/regions-escape-loop-via-variable.stderr rename src/test/{compile-fail => ui/span}/regions-escape-loop-via-vec.rs (100%) create mode 100644 src/test/ui/span/regions-escape-loop-via-vec.stderr rename src/test/{compile-fail => ui/span}/regions-infer-borrow-scope-within-loop.rs (100%) create mode 100644 src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr rename src/test/{compile-fail => ui/span}/send-is-not-static-ensures-scoping.rs (100%) create mode 100644 src/test/ui/span/send-is-not-static-ensures-scoping.stderr rename src/test/{compile-fail => ui/span}/send-is-not-static-std-sync-2.rs (100%) create mode 100644 src/test/ui/span/send-is-not-static-std-sync-2.stderr rename src/test/{compile-fail => ui/span}/send-is-not-static-std-sync.rs (100%) create mode 100644 src/test/ui/span/send-is-not-static-std-sync.stderr rename src/test/{compile-fail => ui/span}/wf-method-late-bound-regions.rs (100%) create mode 100644 src/test/ui/span/wf-method-late-bound-regions.stderr diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index ef6936b6e7db3..0d084d9b930db 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -1064,6 +1064,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { 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) => { diff --git a/src/test/compile-fail/borrowck/borrowck-ref-into-rvalue.rs b/src/test/ui/span/borrowck-ref-into-rvalue.rs similarity index 100% rename from src/test/compile-fail/borrowck/borrowck-ref-into-rvalue.rs rename to src/test/ui/span/borrowck-ref-into-rvalue.rs diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.stderr b/src/test/ui/span/borrowck-ref-into-rvalue.stderr new file mode 100644 index 0000000000000..adbf39b3f7580 --- /dev/null +++ b/src/test/ui/span/borrowck-ref-into-rvalue.stderr @@ -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 + diff --git a/src/test/compile-fail/destructor-restrictions.rs b/src/test/ui/span/destructor-restrictions.rs similarity index 100% rename from src/test/compile-fail/destructor-restrictions.rs rename to src/test/ui/span/destructor-restrictions.rs diff --git a/src/test/ui/span/destructor-restrictions.stderr b/src/test/ui/span/destructor-restrictions.stderr new file mode 100644 index 0000000000000..3253212c5b87b --- /dev/null +++ b/src/test/ui/span/destructor-restrictions.stderr @@ -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 + diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr index 3fedb2884bc58..6ad9c27b8b910 100644 --- a/src/test/ui/span/issue-11925.stderr +++ b/src/test/ui/span/issue-11925.stderr @@ -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 diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr index f10ba0bf2210f..85a0002f24180 100644 --- a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr +++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr @@ -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 diff --git a/src/test/compile-fail/mut-ptr-cant-outlive-ref.rs b/src/test/ui/span/mut-ptr-cant-outlive-ref.rs similarity index 100% rename from src/test/compile-fail/mut-ptr-cant-outlive-ref.rs rename to src/test/ui/span/mut-ptr-cant-outlive-ref.rs diff --git a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr new file mode 100644 index 0000000000000..0417eb075af85 --- /dev/null +++ b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr @@ -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 + diff --git a/src/test/compile-fail/range-2.rs b/src/test/ui/span/range-2.rs similarity index 100% rename from src/test/compile-fail/range-2.rs rename to src/test/ui/span/range-2.rs diff --git a/src/test/ui/span/range-2.stderr b/src/test/ui/span/range-2.stderr new file mode 100644 index 0000000000000..9f11de77be7e7 --- /dev/null +++ b/src/test/ui/span/range-2.stderr @@ -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 + diff --git a/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs b/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs similarity index 100% rename from src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs rename to src/test/ui/span/regionck-unboxed-closure-lifetimes.rs diff --git a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr new file mode 100644 index 0000000000000..9c369e03e33ab --- /dev/null +++ b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr @@ -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 + diff --git a/src/test/compile-fail/regions-close-over-type-parameter-2.rs b/src/test/ui/span/regions-close-over-type-parameter-2.rs similarity index 100% rename from src/test/compile-fail/regions-close-over-type-parameter-2.rs rename to src/test/ui/span/regions-close-over-type-parameter-2.rs diff --git a/src/test/ui/span/regions-close-over-type-parameter-2.stderr b/src/test/ui/span/regions-close-over-type-parameter-2.stderr new file mode 100644 index 0000000000000..ea652da7da46f --- /dev/null +++ b/src/test/ui/span/regions-close-over-type-parameter-2.stderr @@ -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 + diff --git a/src/test/compile-fail/regions-escape-loop-via-variable.rs b/src/test/ui/span/regions-escape-loop-via-variable.rs similarity index 100% rename from src/test/compile-fail/regions-escape-loop-via-variable.rs rename to src/test/ui/span/regions-escape-loop-via-variable.rs diff --git a/src/test/ui/span/regions-escape-loop-via-variable.stderr b/src/test/ui/span/regions-escape-loop-via-variable.stderr new file mode 100644 index 0000000000000..09f2154905f38 --- /dev/null +++ b/src/test/ui/span/regions-escape-loop-via-variable.stderr @@ -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 + diff --git a/src/test/compile-fail/regions-escape-loop-via-vec.rs b/src/test/ui/span/regions-escape-loop-via-vec.rs similarity index 100% rename from src/test/compile-fail/regions-escape-loop-via-vec.rs rename to src/test/ui/span/regions-escape-loop-via-vec.rs diff --git a/src/test/ui/span/regions-escape-loop-via-vec.stderr b/src/test/ui/span/regions-escape-loop-via-vec.stderr new file mode 100644 index 0000000000000..58f7849e443f5 --- /dev/null +++ b/src/test/ui/span/regions-escape-loop-via-vec.stderr @@ -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 + diff --git a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs b/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs similarity index 100% rename from src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs rename to src/test/ui/span/regions-infer-borrow-scope-within-loop.rs diff --git a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr new file mode 100644 index 0000000000000..0e7b64ec2b36c --- /dev/null +++ b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr @@ -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 + diff --git a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs b/src/test/ui/span/send-is-not-static-ensures-scoping.rs similarity index 100% rename from src/test/compile-fail/send-is-not-static-ensures-scoping.rs rename to src/test/ui/span/send-is-not-static-ensures-scoping.rs diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr new file mode 100644 index 0000000000000..5897921476d3f --- /dev/null +++ b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr @@ -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 + diff --git a/src/test/compile-fail/send-is-not-static-std-sync-2.rs b/src/test/ui/span/send-is-not-static-std-sync-2.rs similarity index 100% rename from src/test/compile-fail/send-is-not-static-std-sync-2.rs rename to src/test/ui/span/send-is-not-static-std-sync-2.rs diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.stderr b/src/test/ui/span/send-is-not-static-std-sync-2.stderr new file mode 100644 index 0000000000000..08f85f17bf8ad --- /dev/null +++ b/src/test/ui/span/send-is-not-static-std-sync-2.stderr @@ -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 + diff --git a/src/test/compile-fail/send-is-not-static-std-sync.rs b/src/test/ui/span/send-is-not-static-std-sync.rs similarity index 100% rename from src/test/compile-fail/send-is-not-static-std-sync.rs rename to src/test/ui/span/send-is-not-static-std-sync.rs diff --git a/src/test/ui/span/send-is-not-static-std-sync.stderr b/src/test/ui/span/send-is-not-static-std-sync.stderr new file mode 100644 index 0000000000000..a86cf1e58846d --- /dev/null +++ b/src/test/ui/span/send-is-not-static-std-sync.stderr @@ -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 + diff --git a/src/test/compile-fail/wf-method-late-bound-regions.rs b/src/test/ui/span/wf-method-late-bound-regions.rs similarity index 100% rename from src/test/compile-fail/wf-method-late-bound-regions.rs rename to src/test/ui/span/wf-method-late-bound-regions.rs diff --git a/src/test/ui/span/wf-method-late-bound-regions.stderr b/src/test/ui/span/wf-method-late-bound-regions.stderr new file mode 100644 index 0000000000000..aeac3102fbf3a --- /dev/null +++ b/src/test/ui/span/wf-method-late-bound-regions.stderr @@ -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 + From 7d5b788edffc447946e8c27d683e8604b59443c5 Mon Sep 17 00:00:00 2001 From: Dmitry Gritsay Date: Tue, 1 Nov 2016 23:18:02 +0200 Subject: [PATCH 11/12] Elide lifetimes in DerefMut documentation - Elide lifetimes to increase the readability of `DerefMut` examples --- src/libcore/ops.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 62aa57bbbbf05..5c36d337799eb 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -2484,13 +2484,13 @@ impl<'a, T: ?Sized> Deref for &'a mut T { /// impl Deref for DerefMutExample { /// type Target = T; /// -/// fn deref<'a>(&'a self) -> &'a T { +/// fn deref(&self) -> &T { /// &self.value /// } /// } /// /// impl DerefMut for DerefMutExample { -/// fn deref_mut<'a>(&'a mut self) -> &'a mut T { +/// fn deref_mut(&mut self) -> &mut T { /// &mut self.value /// } /// } From 0e391bf22c4810cdb2f0e026037b4b9d1234c679 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 2 Nov 2016 10:00:11 -0400 Subject: [PATCH 12/12] ICH: Add test case for when overflow checks are disabled. --- .../hashes/panic_exprs_no_overflow_checks.rs | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs diff --git a/src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs b/src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs new file mode 100644 index 0000000000000..b84b7f5f378aa --- /dev/null +++ b/src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs @@ -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 or the MIT license +// , 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 +}