]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #52674 - tinaun:patch-2, r=cramertj
authorMark Rousskov <mark.simulacrum@gmail.com>
Thu, 26 Jul 2018 15:18:34 +0000 (09:18 -0600)
committerGitHub <noreply@github.com>
Thu, 26 Jul 2018 15:18:34 +0000 (09:18 -0600)
Impl Executor for Box<E: Executor>

removes the need for the compatibility lib between futures 0.1 and 0.3 to use a wrapper type to implement Executor for Box<Executor>

125 files changed:
RELEASES.md
src/ci/docker/dist-various-1/Dockerfile
src/libcore/hash/mod.rs
src/libcore/intrinsics.rs
src/libcore/ptr.rs
src/libcore/str/mod.rs
src/libcore/task/executor.rs
src/libfmt_macros/lib.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/on_unimplemented.rs
src/librustc/ty/mod.rs
src/librustc_codegen_llvm/back/linker.rs
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/consts.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/mir/operand.rs
src/librustc_driver/lib.rs
src/librustc_metadata/locator.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_typeck/check/intrinsic.rs
src/librustdoc/lib.rs
src/librustdoc/passes/collapse_docs.rs
src/librustdoc/passes/mod.rs
src/librustdoc/passes/propagate_doc_cfg.rs
src/librustdoc/passes/strip_hidden.rs
src/librustdoc/passes/strip_priv_imports.rs
src/librustdoc/passes/strip_private.rs
src/librustdoc/passes/unindent_comments.rs
src/librustdoc/plugins.rs [deleted file]
src/librustdoc/test.rs
src/libstd/net/parser.rs
src/libstd/path.rs
src/libstd/sys/redox/ext/net.rs
src/libstd/sys_common/backtrace.rs
src/libsyntax/parse/parser.rs
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/format.rs
src/libsyntax_ext/format_foreign.rs
src/stdsimd
src/test/compile-fail/ifmt-bad-arg.rs [deleted file]
src/test/run-make-fulldeps/volatile-intrinsics/main.rs
src/test/run-pass/issue-18804/auxiliary/lib.rs [new file with mode: 0644]
src/test/run-pass/issue-18804/main.rs [new file with mode: 0644]
src/test/run-pass/issue-33264.rs [new file with mode: 0644]
src/test/run-pass/issue-34784.rs [new file with mode: 0644]
src/test/run-pass/issue-44005.rs [new file with mode: 0644]
src/test/rustdoc-ui/failed-doctest-output.rs [new file with mode: 0644]
src/test/rustdoc-ui/failed-doctest-output.stdout [new file with mode: 0644]
src/test/ui/borrowck/borrowck-escaping-closure-error-1.nll.stderr
src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr
src/test/ui/dropck/dropck-eyepatch-extern-crate.nll.stderr
src/test/ui/dropck/dropck-eyepatch-reorder.nll.stderr
src/test/ui/dropck/dropck-eyepatch.nll.stderr
src/test/ui/error-codes/E0597.nll.stderr
src/test/ui/generator/borrowing.nll.stderr
src/test/ui/generator/dropck.nll.stderr
src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr
src/test/ui/ifmt-bad-arg.rs [new file with mode: 0644]
src/test/ui/ifmt-bad-arg.stderr [new file with mode: 0644]
src/test/ui/impl-trait/existential_type_in_fn_body.rs [new file with mode: 0644]
src/test/ui/issue-12470.nll.stderr
src/test/ui/issue-13497-2.nll.stderr [new file with mode: 0644]
src/test/ui/issue-17954.ast.nll.stderr
src/test/ui/issue-17954.mir.stderr
src/test/ui/issue-17954.rs
src/test/ui/issue-18118.nll.stderr
src/test/ui/issue-30438-c.nll.stderr
src/test/ui/issue-42060.rs [new file with mode: 0644]
src/test/ui/issue-42060.stderr [new file with mode: 0644]
src/test/ui/issue-43196.rs [new file with mode: 0644]
src/test/ui/issue-43196.stderr [new file with mode: 0644]
src/test/ui/issue-4335.nll.stderr
src/test/ui/issue-46036.stderr
src/test/ui/issue-46471-1.stderr
src/test/ui/issue-46471.stderr
src/test/ui/issue-52126-assign-op-invariance.nll.stderr
src/test/ui/macros/format-foreign.rs
src/test/ui/macros/format-foreign.stderr
src/test/ui/macros/format-unused-lables.stderr
src/test/ui/mismatched_types/closure-arg-count.stderr
src/test/ui/nll/borrowed-local-error.stderr
src/test/ui/nll/borrowed-universal-error-2.stderr
src/test/ui/nll/capture-ref-in-struct.stderr
src/test/ui/nll/closure-requirements/escape-argument.stderr
src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
src/test/ui/nll/issue-31567.stderr
src/test/ui/nll/issue-47470.stderr
src/test/ui/region-borrow-params-issue-29793-small.nll.stderr
src/test/ui/regions-nested-fns-2.nll.stderr
src/test/ui/span/destructor-restrictions.nll.stderr
src/test/ui/span/dropck-object-cycle.nll.stderr
src/test/ui/span/dropck_arr_cycle_checked.nll.stderr
src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr
src/test/ui/span/dropck_misc_variants.nll.stderr
src/test/ui/span/dropck_vec_cycle_checked.nll.stderr
src/test/ui/span/issue-11925.nll.stderr
src/test/ui/span/issue-23338-locals-die-before-temps-of-body.nll.stderr
src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.nll.stderr
src/test/ui/span/issue-24805-dropck-trait-has-items.nll.stderr
src/test/ui/span/issue-24895-copy-clone-dropck.nll.stderr
src/test/ui/span/issue-25199.nll.stderr
src/test/ui/span/issue-26656.nll.stderr
src/test/ui/span/issue-29106.nll.stderr
src/test/ui/span/issue-36537.nll.stderr
src/test/ui/span/issue-40157.nll.stderr
src/test/ui/span/issue28498-reject-ex1.nll.stderr
src/test/ui/span/issue28498-reject-lifetime-param.nll.stderr
src/test/ui/span/issue28498-reject-passed-to-fn.nll.stderr
src/test/ui/span/issue28498-reject-trait-bound.nll.stderr
src/test/ui/span/mut-ptr-cant-outlive-ref.nll.stderr
src/test/ui/span/range-2.nll.stderr
src/test/ui/span/regionck-unboxed-closure-lifetimes.nll.stderr
src/test/ui/span/regions-close-over-type-parameter-2.nll.stderr
src/test/ui/span/regions-escape-loop-via-variable.nll.stderr
src/test/ui/span/regions-escape-loop-via-vec.nll.stderr
src/test/ui/span/regions-infer-borrow-scope-within-loop.nll.stderr
src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr
src/test/ui/span/send-is-not-static-std-sync-2.nll.stderr
src/test/ui/span/send-is-not-static-std-sync.nll.stderr
src/test/ui/span/vec-must-not-hide-type-from-dropck.nll.stderr
src/test/ui/span/vec_refs_data_with_early_death.nll.stderr
src/test/ui/span/wf-method-late-bound-regions.nll.stderr
src/tools/compiletest/src/header.rs

index 1e1ae4a8b6af955f84b8f627e93b55f96afcc9af..b983851f881987a11089e8409ca0c5666e378c5f 100644 (file)
@@ -52,6 +52,16 @@ Stabilized APIs
 ---------------
 - [`Iterator::step_by`]
 - [`Path::ancestors`]
+- [`SystemTime::UNIX_EPOCH`]
+- [`alloc::GlobalAlloc`]
+- [`alloc::Layout`]
+- [`alloc::LayoutErr`]
+- [`alloc::System`]
+- [`alloc::alloc`]
+- [`alloc::alloc_zeroed`]
+- [`alloc::dealloc`]
+- [`alloc::realloc`]
+- [`alloc::handle_alloc_error`]
 - [`btree_map::Entry::or_default`]
 - [`fmt::Alignment`]
 - [`hash_map::Entry::or_default`]
@@ -122,6 +132,16 @@ Compatibility Notes
 [cargo/5584]: https://github.com/rust-lang/cargo/pull/5584/
 [`Iterator::step_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.step_by
 [`Path::ancestors`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.ancestors
+[`SystemTime::UNIX_EPOCH`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#associatedconstant.UNIX_EPOCH
+[`alloc::GlobalAlloc`]: https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html
+[`alloc::Layout`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html
+[`alloc::LayoutErr`]: https://doc.rust-lang.org/std/alloc/struct.LayoutErr.html
+[`alloc::System`]: https://doc.rust-lang.org/std/alloc/struct.System.html
+[`alloc::alloc`]: https://doc.rust-lang.org/std/alloc/fn.alloc.html
+[`alloc::alloc_zeroed`]: https://doc.rust-lang.org/std/alloc/fn.alloc_zeroed.html
+[`alloc::dealloc`]: https://doc.rust-lang.org/std/alloc/fn.dealloc.html
+[`alloc::realloc`]: https://doc.rust-lang.org/std/alloc/fn.realloc.html
+[`alloc::handle_alloc_error`]: https://doc.rust-lang.org/std/alloc/fn.handle_alloc_error.html
 [`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
 [`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html
 [`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
@@ -3162,7 +3182,7 @@ Stabilized APIs
 * [`UnixDatagram::shutdown`](http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.shutdown)
 * RawFd impls for `UnixDatagram`
 * `{BTree,Hash}Map::values_mut`
-* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/beta/std/primitive.slice.html#method.binary_search_by_key)
+* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by_key)
 
 Libraries
 ---------
@@ -4080,7 +4100,7 @@ Compatibility Notes
 [1.6bh]: https://github.com/rust-lang/rust/pull/29811
 [1.6c]: https://github.com/rust-lang/cargo/pull/2192
 [1.6cc]: https://github.com/rust-lang/cargo/pull/2131
-[1.6co]: http://doc.rust-lang.org/beta/core/index.html
+[1.6co]: http://doc.rust-lang.org/core/index.html
 [1.6dv]: https://github.com/rust-lang/rust/pull/30000
 [1.6f]: https://github.com/rust-lang/rust/pull/29129
 [1.6m]: https://github.com/rust-lang/rust/pull/29828
index 702f9b2886e708d14aac472e6d3674d72e2c16be..6302f550091ad6285df2584ed6a26022f462cf18 100644 (file)
@@ -103,16 +103,10 @@ ENV TARGETS=$TARGETS,thumbv7m-none-eabi
 ENV TARGETS=$TARGETS,thumbv7em-none-eabi
 ENV TARGETS=$TARGETS,thumbv7em-none-eabihf
 
-# FIXME: remove armv5te vars after https://github.com/alexcrichton/cc-rs/issues/271
-#        get fixed and cc update
 ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
     CC_sparc64_unknown_linux_gnu=sparc64-linux-gnu-gcc \
-    CC_x86_64_unknown_redox=x86_64-unknown-redox-gcc \
-    CC_armv5te_unknown_linux_gnueabi=arm-linux-gnueabi-gcc \
-    CFLAGS_armv5te_unknown_linux_gnueabi="-march=armv5te -marm -mfloat-abi=soft" \
-    CC_armv5te_unknown_linux_musleabi=arm-linux-gnueabi-gcc \
-    CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"
+    CC_x86_64_unknown_redox=x86_64-unknown-redox-gcc
 
 ENV RUST_CONFIGURE_ARGS \
       --musl-root-armv5te=/musl-armv5te \
index e6f8dfffd633049569d4d431dcf83ef45cb38561..e7907e0344493bf13b8a298a84f4ec08ce21c69b 100644 (file)
@@ -542,6 +542,16 @@ fn default() -> BuildHasherDefault<H> {
     }
 }
 
+#[stable(since = "1.29.0", feature = "build_hasher_eq")]
+impl<H> PartialEq for BuildHasherDefault<H> {
+    fn eq(&self, _other: &BuildHasherDefault<H>) -> bool {
+        true
+    }
+}
+
+#[stable(since = "1.29.0", feature = "build_hasher_eq")]
+impl<H> Eq for BuildHasherDefault<H> {}
+
 //////////////////////////////////////////////////////////////////////////////
 
 mod impls {
index 89fe2d941a350c0f84f5b212d41d92aa868e3288..854cb5f4e3b3f77a1791896e3f8df6d0eaba57dd 100644 (file)
@@ -1085,6 +1085,15 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// [`std::ptr::write_volatile`](../../std/ptr/fn.write_volatile.html).
     pub fn volatile_store<T>(dst: *mut T, val: T);
 
+    /// Perform a volatile load from the `src` pointer
+    /// The pointer is not required to be aligned.
+    #[cfg(not(stage0))]
+    pub fn unaligned_volatile_load<T>(src: *const T) -> T;
+    /// Perform a volatile store to the `dst` pointer.
+    /// The pointer is not required to be aligned.
+    #[cfg(not(stage0))]
+    pub fn unaligned_volatile_store<T>(dst: *mut T, val: T);
+
     /// Returns the square root of an `f32`
     pub fn sqrtf32(x: f32) -> f32;
     /// Returns the square root of an `f64`
index d020e14be4cbdd8a6dba3e445e6af0e08dc4404e..be82ab44cd1fcbf3b00d40ce528652d0aebc223d 100644 (file)
@@ -591,7 +591,7 @@ pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of an allocated object.
+    ///   byte past the end of *the same* allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -643,9 +643,15 @@ pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
     ///
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
+    /// In particular, the resulting pointer may *not* be used to access a
+    /// different allocated object than the one `self` points to. In other
+    /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
+    /// *not* the same as `y`, and dereferencing it is undefined behavior
+    /// unless `x` and `y` point into the same allocated object.
     ///
     /// Always use `.offset(count)` instead when possible, because `offset`
-    /// allows the compiler to optimize better.
+    /// allows the compiler to optimize better.  If you need to cross object
+    /// boundaries, cast the pointer to an integer and do the arithmetic there.
     ///
     /// # Examples
     ///
@@ -1340,7 +1346,7 @@ pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of an allocated object.
+    ///   byte past the end of *the same* allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1391,9 +1397,15 @@ pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
     ///
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
+    /// In particular, the resulting pointer may *not* be used to access a
+    /// different allocated object than the one `self` points to. In other
+    /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
+    /// *not* the same as `y`, and dereferencing it is undefined behavior
+    /// unless `x` and `y` point into the same allocated object.
     ///
     /// Always use `.offset(count)` instead when possible, because `offset`
-    /// allows the compiler to optimize better.
+    /// allows the compiler to optimize better.  If you need to cross object
+    /// boundaries, cast the pointer to an integer and do the arithmetic there.
     ///
     /// # Examples
     ///
index 3e215de58dd219be108ee841a3324449b7928a34..86b8349fa3c89cd1894f39d8172b4d02e9465873 100644 (file)
@@ -696,13 +696,10 @@ fn last(mut self) -> Option<(usize, char)> {
 impl<'a> DoubleEndedIterator for CharIndices<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<(usize, char)> {
-        match self.iter.next_back() {
-            None => None,
-            Some(ch) => {
-                let index = self.front_offset + self.iter.iter.len();
-                Some((index, ch))
-            }
-        }
+        self.iter.next_back().map(|ch| {
+            let index = self.front_offset + self.iter.iter.len();
+            (index, ch)
+        })
     }
 }
 
index f1db5093e9880ab84fe4940c455bbd893700d073..affcbf464da221214da7c8712e5c7972bde24d23 100644 (file)
 
 /// A task executor.
 ///
-/// A *task* is a `()`-producing async value that runs at the top level, and will
-/// be `poll`ed until completion. It's also the unit at which wake-up
-/// notifications occur. Executors, such as thread pools, allow tasks to be
-/// spawned and are responsible for putting tasks onto ready queues when
-/// they are woken up, and polling them when they are ready.
+/// Futures are polled until completion by tasks, a kind of lightweight
+/// "thread". A *task executor* is responsible for the creation of these tasks
+/// and the coordination of their execution on real operating system threads. In
+/// particular, whenever a task signals that it can make further progress via a
+/// wake-up notification, it is the responsibility of the task executor to put
+/// the task into a queue to continue executing it, i.e. polling the future in
+/// it, later.
 pub trait Executor {
-    /// Spawn the given task, polling it until completion.
+    /// Spawns a new task with the given future. The future will be polled until
+    /// completion.
     ///
     /// # Errors
     ///
     /// The executor may be unable to spawn tasks, either because it has
     /// been shut down or is resource-constrained.
-    fn spawn_obj(&mut self, task: FutureObj<'static, ()>) -> Result<(), SpawnObjError>;
+    fn spawn_obj(
+        &mut self,
+        future: FutureObj<'static, ()>,
+    ) -> Result<(), SpawnObjError>;
 
-    /// Determine whether the executor is able to spawn new tasks.
+    /// Determines whether the executor is able to spawn new tasks.
     ///
     /// # Returns
     ///
@@ -75,8 +81,8 @@ pub struct SpawnObjError {
     /// The kind of error
     pub kind: SpawnErrorKind,
 
-    /// The task for which spawning was attempted
-    pub task: FutureObj<'static, ()>,
+    /// The future for which spawning inside a task was attempted
+    pub future: FutureObj<'static, ()>,
 }
 
 /// The result of a failed spawn
@@ -85,6 +91,6 @@ pub struct SpawnLocalObjError {
     /// The kind of error
     pub kind: SpawnErrorKind,
 
-    /// The task for which spawning was attempted
-    pub task: LocalFutureObj<'static, ()>,
+    /// The future for which spawning inside a task was attempted
+    pub future: LocalFutureObj<'static, ()>,
 }
index 9952e5f64d6ab2f59e9ca303e99b69577aaa5689..30a3bbdc58e988b4c85326c774f318aa1428b39e 100644 (file)
@@ -154,6 +154,8 @@ pub struct Parser<'a> {
     style: Option<usize>,
     /// How many newlines have been seen in the string so far, to adjust the error spans
     seen_newlines: usize,
+    /// Start and end byte offset of every successfuly parsed argument
+    pub arg_places: Vec<(usize, usize)>,
 }
 
 impl<'a> Iterator for Parser<'a> {
@@ -168,9 +170,13 @@ fn next(&mut self) -> Option<Piece<'a>> {
                     if self.consume('{') {
                         Some(String(self.string(pos + 1)))
                     } else {
-                        let ret = Some(NextArgument(self.argument()));
-                        self.must_consume('}');
-                        ret
+                        let mut arg = self.argument();
+                        if let Some(arg_pos) = self.must_consume('}').map(|end| {
+                            (pos + raw + 1, end + raw + 2)
+                        }) {
+                            self.arg_places.push(arg_pos);
+                        }
+                        Some(NextArgument(arg))
                     }
                 }
                 '}' => {
@@ -211,6 +217,7 @@ pub fn new(s: &'a str, style: Option<usize>) -> Parser<'a> {
             curarg: 0,
             style,
             seen_newlines: 0,
+            arg_places: vec![],
         }
     }
 
@@ -271,7 +278,7 @@ fn consume(&mut self, c: char) -> bool {
 
     /// Forces consumption of the specified character. If the character is not
     /// found, an error is emitted.
-    fn must_consume(&mut self, c: char) {
+    fn must_consume(&mut self, c: char) -> Option<usize> {
         self.ws();
         let raw = self.style.unwrap_or(0);
 
@@ -279,12 +286,14 @@ fn must_consume(&mut self, c: char) {
         if let Some(&(pos, maybe)) = self.cur.peek() {
             if c == maybe {
                 self.cur.next();
+                Some(pos)
             } else {
                 let pos = pos + padding + 1;
                 self.err(format!("expected `{:?}`, found `{:?}`", c, maybe),
                          format!("expected `{}`", c),
                          pos,
                          pos);
+                None
             }
         } else {
             let msg = format!("expected `{:?}` but string was terminated", c);
@@ -302,6 +311,7 @@ fn must_consume(&mut self, c: char) {
             } else {
                 self.err(msg, format!("expected `{:?}`", c), pos, pos);
             }
+            None
         }
     }
 
index df26ac670601c529f7d635dd51c62e80bc149acd..8300f98fb1cd5bee246364c6d36850b73a8deadc 100644 (file)
@@ -1050,6 +1050,30 @@ pub fn report_arg_count_mismatch(
         if let Some(found_span) = found_span {
             err.span_label(found_span, format!("takes {}", found_str));
 
+            // Suggest to take and ignore the arguments with expected_args_length `_`s if
+            // found arguments is empty (assume the user just wants to ignore args in this case).
+            // For example, if `expected_args_length` is 2, suggest `|_, _|`.
+            if found_args.is_empty() && is_closure {
+                let mut underscores = "_".repeat(expected_args.len())
+                                      .split("")
+                                      .filter(|s| !s.is_empty())
+                                      .collect::<Vec<_>>()
+                                      .join(", ");
+                err.span_suggestion_with_applicability(
+                    found_span,
+                    &format!(
+                        "consider changing the closure to take and ignore the expected argument{}",
+                        if expected_args.len() < 2 {
+                            ""
+                        } else {
+                            "s"
+                        }
+                    ),
+                    format!("|{}|", underscores),
+                    Applicability::MachineApplicable,
+                );
+            }
+
             if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
                 if fields.len() == expected_args.len() {
                     let sugg = fields.iter()
index 925d3504f75fc120c2a44f1c7d2ea0ca82fc7107..e1395c3fa442723c2bba781ea5918aee35bd902d 100644 (file)
@@ -190,11 +190,10 @@ pub fn evaluate(&self,
         for command in self.subcommands.iter().chain(Some(self)).rev() {
             if let Some(ref condition) = command.condition {
                 if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
-                    options.contains(&(c.name().as_str().to_string(),
-                                      match c.value_str().map(|s| s.as_str().to_string()) {
-                                          Some(s) => Some(s),
-                                          None => None
-                                      }))
+                    options.contains(&(
+                        c.name().as_str().to_string(),
+                        c.value_str().map(|s| s.as_str().to_string())
+                    ))
                 }) {
                     debug!("evaluate: skipping {:?} due to condition", command);
                     continue
index bd24b93f0293f63353adda235e86d9b54a72974c..c2795bae01029f4e27871d91441beecc8400a0d4 100644 (file)
@@ -2697,15 +2697,12 @@ pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
             self.opt_associated_item(def_id)
         };
 
-        match item {
-            Some(trait_item) => {
-                match trait_item.container {
-                    TraitContainer(_) => None,
-                    ImplContainer(def_id) => Some(def_id),
-                }
+        item.and_then(|trait_item|
+            match trait_item.container {
+                TraitContainer(_) => None,
+                ImplContainer(def_id) => Some(def_id),
             }
-            None => None
-        }
+        )
     }
 
     /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
index f5f486893854f8999d9ff6b959e9e58598c2c49b..f5bd31a67e5ce8b16569a65710846915a8a3e0f4 100644 (file)
@@ -218,8 +218,10 @@ fn push_cross_lang_lto_args(&mut self, plugin_path: Option<&OsStr>) {
 }
 
 impl<'a> Linker for GccLinker<'a> {
-    fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg("-l").arg(lib); }
-    fn link_staticlib(&mut self, lib: &str) { self.hint_static(); self.cmd.arg("-l").arg(lib); }
+    fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}",lib)); }
+    fn link_staticlib(&mut self, lib: &str) {
+        self.hint_static(); self.cmd.arg(format!("-l{}",lib));
+    }
     fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
     fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
     fn framework_path(&mut self, path: &Path) { self.cmd.arg("-F").arg(path); }
@@ -227,15 +229,15 @@ impl<'a> Linker for GccLinker<'a> {
     fn add_object(&mut self, path: &Path) { self.cmd.arg(path); }
     fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
     fn no_position_independent_executable(&mut self) { self.cmd.arg("-no-pie"); }
-    fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
-    fn partial_relro(&mut self) { self.linker_arg("-z,relro"); }
-    fn no_relro(&mut self) { self.linker_arg("-z,norelro"); }
+    fn full_relro(&mut self) { self.linker_arg("-zrelro"); self.linker_arg("-znow"); }
+    fn partial_relro(&mut self) { self.linker_arg("-zrelro"); }
+    fn no_relro(&mut self) { self.linker_arg("-znorelro"); }
     fn build_static_executable(&mut self) { self.cmd.arg("-static"); }
     fn args(&mut self, args: &[String]) { self.cmd.args(args); }
 
     fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
         self.hint_dynamic();
-        self.cmd.arg("-l").arg(lib);
+        self.cmd.arg(format!("-l{}",lib));
     }
 
     fn link_framework(&mut self, framework: &str) {
@@ -253,23 +255,22 @@ fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]) {
         self.hint_static();
         let target = &self.sess.target.target;
         if !target.options.is_like_osx {
-            self.linker_arg("--whole-archive").cmd.arg("-l").arg(lib);
+            self.linker_arg("--whole-archive").cmd.arg(format!("-l{}",lib));
             self.linker_arg("--no-whole-archive");
         } else {
             // -force_load is the macOS equivalent of --whole-archive, but it
             // involves passing the full path to the library to link.
-            let mut v = OsString::from("-force_load,");
-            v.push(&archive::find_library(lib, search_path, &self.sess));
-            self.linker_arg(&v);
+            self.linker_arg("-force_load");
+            let lib = archive::find_library(lib, search_path, &self.sess);
+            self.linker_arg(&lib);
         }
     }
 
     fn link_whole_rlib(&mut self, lib: &Path) {
         self.hint_static();
         if self.sess.target.target.options.is_like_osx {
-            let mut v = OsString::from("-force_load,");
-            v.push(lib);
-            self.linker_arg(&v);
+            self.linker_arg("-force_load");
+            self.linker_arg(&lib);
         } else {
             self.linker_arg("--whole-archive").cmd.arg(lib);
             self.linker_arg("--no-whole-archive");
@@ -294,8 +295,7 @@ fn gc_sections(&mut self, keep_metadata: bool) {
         if self.sess.target.target.options.is_like_osx {
             self.linker_arg("-dead_strip");
         } else if self.sess.target.target.options.is_like_solaris {
-            self.linker_arg("-z");
-            self.linker_arg("ignore");
+            self.linker_arg("-zignore");
 
         // If we're building a dylib, we don't use --gc-sections because LLVM
         // has already done the best it can do, and we also don't want to
@@ -369,7 +369,8 @@ fn build_dylib(&mut self, out_filename: &Path) {
             // the right `-Wl,-install_name` with an `@rpath` in it.
             if self.sess.opts.cg.rpath ||
                self.sess.opts.debugging_opts.osx_rpath_install_name {
-                let mut v = OsString::from("-install_name,@rpath/");
+                self.linker_arg("-install_name");
+                let mut v = OsString::from("@rpath/");
                 v.push(out_filename.file_name().unwrap());
                 self.linker_arg(&v);
             }
@@ -448,7 +449,8 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
     }
 
     fn subsystem(&mut self, subsystem: &str) {
-        self.linker_arg(&format!("--subsystem,{}", subsystem));
+        self.linker_arg("--subsystem");
+        self.linker_arg(&subsystem);
     }
 
     fn finalize(&mut self) -> Command {
index e4acb2ad4b161d2d684a403acc62605b48099e8f..b34d0f1cd9070854c013d58fcfa43c1c7a220570 100644 (file)
@@ -54,6 +54,7 @@ fn noname() -> *const c_char {
     pub struct MemFlags: u8 {
         const VOLATILE = 1 << 0;
         const NONTEMPORAL = 1 << 1;
+        const UNALIGNED = 1 << 2;
     }
 }
 
@@ -602,7 +603,12 @@ pub fn store_with_flags(
         let ptr = self.check_store(val, ptr);
         unsafe {
             let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
-            llvm::LLVMSetAlignment(store, align.abi() as c_uint);
+            let align = if flags.contains(MemFlags::UNALIGNED) {
+                1
+            } else {
+                align.abi() as c_uint
+            };
+            llvm::LLVMSetAlignment(store, align);
             if flags.contains(MemFlags::VOLATILE) {
                 llvm::LLVMSetVolatile(store, llvm::True);
             }
index 5a2d95803842215fb7ec7de49212fbf8d488ad45..f0b5f4b887971f1cffa7bc150ef450d24d7c2ab0 100644 (file)
 use common::{CodegenCx, val_ty};
 use declare;
 use monomorphize::Instance;
+use syntax_pos::Span;
+use syntax_pos::symbol::LocalInternedString;
 use type_::Type;
 use type_of::LayoutLlvmExt;
-use rustc::ty;
+use rustc::ty::{self, Ty};
 use rustc::ty::layout::{Align, LayoutOf};
 
-use rustc::hir::{self, CodegenFnAttrFlags};
+use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags};
 
 use std::ffi::{CStr, CString};
 
@@ -119,6 +121,8 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
     let ty = instance.ty(cx.tcx);
     let sym = cx.tcx.symbol_name(instance).as_str();
 
+    debug!("get_static: sym={} instance={:?}", sym, instance);
+
     let g = if let Some(id) = cx.tcx.hir.as_local_node_id(def_id) {
 
         let llty = cx.layout_of(ty).llvm_type(cx);
@@ -144,50 +148,15 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
             hir_map::NodeForeignItem(&hir::ForeignItem {
                 ref attrs, span, node: hir::ForeignItemKind::Static(..), ..
             }) => {
-                let g = if let Some(linkage) = cx.tcx.codegen_fn_attrs(def_id).linkage {
-                    // If this is a static with a linkage specified, then we need to handle
-                    // it a little specially. The typesystem prevents things like &T and
-                    // extern "C" fn() from being non-null, so we can't just declare a
-                    // static and call it a day. Some linkages (like weak) will make it such
-                    // that the static actually has a null value.
-                    let llty2 = match ty.sty {
-                        ty::TyRawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
-                        _ => {
-                            cx.sess().span_fatal(span, "must have type `*const T` or `*mut T`");
-                        }
-                    };
-                    unsafe {
-                        // Declare a symbol `foo` with the desired linkage.
-                        let g1 = declare::declare_global(cx, &sym, llty2);
-                        llvm::LLVMRustSetLinkage(g1, base::linkage_to_llvm(linkage));
-
-                        // Declare an internal global `extern_with_linkage_foo` which
-                        // is initialized with the address of `foo`.  If `foo` is
-                        // discarded during linking (for example, if `foo` has weak
-                        // linkage and there are no definitions), then
-                        // `extern_with_linkage_foo` will instead be initialized to
-                        // zero.
-                        let mut real_name = "_rust_extern_with_linkage_".to_string();
-                        real_name.push_str(&sym);
-                        let g2 = declare::define_global(cx, &real_name, llty).unwrap_or_else(||{
-                            cx.sess().span_fatal(span,
-                                &format!("symbol `{}` is already defined", &sym))
-                        });
-                        llvm::LLVMRustSetLinkage(g2, llvm::Linkage::InternalLinkage);
-                        llvm::LLVMSetInitializer(g2, g1);
-                        g2
-                    }
-                } else {
-                    // Generate an external declaration.
-                    declare::declare_global(cx, &sym, llty)
-                };
-
-                (g, attrs)
+                let fn_attrs = cx.tcx.codegen_fn_attrs(def_id);
+                (check_and_apply_linkage(cx, &fn_attrs, ty, sym, Some(span)), attrs)
             }
 
             item => bug!("get_static: expected static, found {:?}", item)
         };
 
+        debug!("get_static: sym={} attrs={:?}", sym, attrs);
+
         for attr in attrs {
             if attr.check_name("thread_local") {
                 llvm::set_thread_local_mode(g, cx.tls_model);
@@ -197,19 +166,21 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
         g
     } else {
         // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
-        // FIXME(nagisa): investigate whether it can be changed into define_global
-        let g = declare::declare_global(cx, &sym, cx.layout_of(ty).llvm_type(cx));
+        debug!("get_static: sym={} item_attr={:?}", sym, cx.tcx.item_attrs(def_id));
+
+        let attrs = cx.tcx.codegen_fn_attrs(def_id);
+        let g = check_and_apply_linkage(cx, &attrs, ty, sym, None);
+
         // Thread-local statics in some other crate need to *always* be linked
         // against in a thread-local fashion, so we need to be sure to apply the
         // thread-local attribute locally if it was present remotely. If we
         // don't do this then linker errors can be generated where the linker
         // complains that one object files has a thread local version of the
         // symbol and another one doesn't.
-        for attr in cx.tcx.get_attrs(def_id).iter() {
-            if attr.check_name("thread_local") {
-                llvm::set_thread_local_mode(g, cx.tls_model);
-            }
+        if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
+            llvm::set_thread_local_mode(g, cx.tls_model);
         }
+
         if cx.use_dll_storage_attrs && !cx.tcx.is_foreign_item(def_id) {
             // This item is external but not foreign, i.e. it originates from an external Rust
             // crate. Since we don't know whether this crate will be linked dynamically or
@@ -242,6 +213,66 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
     g
 }
 
+fn check_and_apply_linkage<'tcx>(
+    cx: &CodegenCx<'_, 'tcx>,
+    attrs: &CodegenFnAttrs,
+    ty: Ty<'tcx>,
+    sym: LocalInternedString,
+    span: Option<Span>
+) -> ValueRef {
+    let llty = cx.layout_of(ty).llvm_type(cx);
+    if let Some(linkage) = attrs.linkage {
+        debug!("get_static: sym={} linkage={:?}", sym, linkage);
+
+        // If this is a static with a linkage specified, then we need to handle
+        // it a little specially. The typesystem prevents things like &T and
+        // extern "C" fn() from being non-null, so we can't just declare a
+        // static and call it a day. Some linkages (like weak) will make it such
+        // that the static actually has a null value.
+        let llty2 = match ty.sty {
+            ty::TyRawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
+            _ => {
+                if span.is_some() {
+                    cx.sess().span_fatal(span.unwrap(), "must have type `*const T` or `*mut T`")
+                } else {
+                    bug!("must have type `*const T` or `*mut T`")
+                }
+            }
+        };
+        unsafe {
+            // Declare a symbol `foo` with the desired linkage.
+            let g1 = declare::declare_global(cx, &sym, llty2);
+            llvm::LLVMRustSetLinkage(g1, base::linkage_to_llvm(linkage));
+
+            // Declare an internal global `extern_with_linkage_foo` which
+            // is initialized with the address of `foo`.  If `foo` is
+            // discarded during linking (for example, if `foo` has weak
+            // linkage and there are no definitions), then
+            // `extern_with_linkage_foo` will instead be initialized to
+            // zero.
+            let mut real_name = "_rust_extern_with_linkage_".to_string();
+            real_name.push_str(&sym);
+            let g2 = declare::define_global(cx, &real_name, llty).unwrap_or_else(||{
+                if span.is_some() {
+                    cx.sess().span_fatal(
+                        span.unwrap(),
+                        &format!("symbol `{}` is already defined", &sym)
+                    )
+                } else {
+                    bug!("symbol `{}` is already defined", &sym)
+                }
+            });
+            llvm::LLVMRustSetLinkage(g2, llvm::Linkage::InternalLinkage);
+            llvm::LLVMSetInitializer(g2, g1);
+            g2
+        }
+    } else {
+        // Generate an external declaration.
+        // FIXME(nagisa): investigate whether it can be changed into define_global
+        declare::declare_global(cx, &sym, llty)
+    }
+}
+
 pub fn codegen_static<'a, 'tcx>(
     cx: &CodegenCx<'a, 'tcx>,
     def_id: DefId,
index 58a32ad9774f61c113d9a0df3a670540bfab3d4b..9c5c0f730c161e8e8eb6a4fed1989a6e0c178c43 100644 (file)
@@ -234,15 +234,20 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
             memset_intrinsic(bx, true, substs.type_at(0),
                              args[0].immediate(), args[1].immediate(), args[2].immediate())
         }
-        "volatile_load" => {
+        "volatile_load" | "unaligned_volatile_load" => {
             let tp_ty = substs.type_at(0);
             let mut ptr = args[0].immediate();
             if let PassMode::Cast(ty) = fn_ty.ret.mode {
                 ptr = bx.pointercast(ptr, ty.llvm_type(cx).ptr_to());
             }
             let load = bx.volatile_load(ptr);
+            let align = if name == "unaligned_volatile_load" {
+                1
+            } else {
+                cx.align_of(tp_ty).abi() as u32
+            };
             unsafe {
-                llvm::LLVMSetAlignment(load, cx.align_of(tp_ty).abi() as u32);
+                llvm::LLVMSetAlignment(load, align);
             }
             to_immediate(bx, load, cx.layout_of(tp_ty))
         },
@@ -251,6 +256,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
             args[1].val.volatile_store(bx, dst);
             return;
         },
+        "unaligned_volatile_store" => {
+            let dst = args[0].deref(bx.cx);
+            args[1].val.unaligned_volatile_store(bx, dst);
+            return;
+        },
         "prefetch_read_data" | "prefetch_write_data" |
         "prefetch_read_instruction" | "prefetch_write_instruction" => {
             let expect = cx.get_intrinsic(&("llvm.prefetch"));
index 777054014dc470b2dd1e700b34c93d5ff3a71cbe..c433df51110e352b9cabc0b41418abd8858df37e 100644 (file)
@@ -276,6 +276,10 @@ pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
         self.store_with_flags(bx, dest, MemFlags::VOLATILE);
     }
 
+    pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
+        self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
+    }
+
     pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
         self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
     }
index f60954ea02166398216ae597daee4879783a1257..2100ceea22849713c853d10cf810dd61ae7628b3 100644 (file)
@@ -1497,10 +1497,12 @@ fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<as
     }
 }
 
-/// Runs `f` in a suitable thread for running `rustc`; returns a
-/// `Result` with either the return value of `f` or -- if a panic
-/// occurs -- the panic value.
-pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<dyn Any + Send>>
+/// Runs `f` in a suitable thread for running `rustc`; returns a `Result` with either the return
+/// value of `f` or -- if a panic occurs -- the panic value.
+///
+/// This version applies the given name to the thread. This is used by rustdoc to ensure consistent
+/// doctest output across platforms and executions.
+pub fn in_named_rustc_thread<F, R>(name: String, f: F) -> Result<R, Box<dyn Any + Send>>
     where F: FnOnce() -> R + Send + 'static,
           R: Send + 'static,
 {
@@ -1564,7 +1566,7 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<dyn Any + Send>>
 
     // The or condition is added from backward compatibility.
     if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() {
-        let mut cfg = thread::Builder::new().name("rustc".to_string());
+        let mut cfg = thread::Builder::new().name(name);
 
         // FIXME: Hacks on hacks. If the env is trying to override the stack size
         // then *don't* set it explicitly.
@@ -1580,6 +1582,16 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<dyn Any + Send>>
     }
 }
 
+/// Runs `f` in a suitable thread for running `rustc`; returns a
+/// `Result` with either the return value of `f` or -- if a panic
+/// occurs -- the panic value.
+pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<dyn Any + Send>>
+    where F: FnOnce() -> R + Send + 'static,
+          R: Send + 'static,
+{
+    in_named_rustc_thread("rustc".to_string(), f)
+}
+
 /// Get a list of extra command-line flags provided by the user, as strings.
 ///
 /// This function is used during ICEs to show more information useful for
index b747624338c83c8208e8eef55739019fa583de66..42af5db82942aadb25b10a31ccf10733dfde08fa 100644 (file)
@@ -824,17 +824,14 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
         if rlib.is_none() && rmeta.is_none() && dylib.is_none() {
             return None;
         }
-        match slot {
-            Some((_, metadata)) => {
-                Some(Library {
-                    dylib,
-                    rlib,
-                    rmeta,
-                    metadata,
-                })
+        slot.map(|(_, metadata)|
+            Library {
+                dylib,
+                rlib,
+                rmeta,
+                metadata,
             }
-            None => None,
-        }
+        )
     }
 }
 
index 9dcee3207565ff6abb9a01491543843325bbe69b..e20e608a2cd5400b02112271b775a6ccba5f85ef 100644 (file)
@@ -14,7 +14,7 @@
 use rustc::mir::{LocalDecl, LocalKind, Location, Operand, Place};
 use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind};
 use rustc::mir::VarBindingForm;
-use rustc::ty::{self, RegionKind};
+use rustc::ty;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::Span;
@@ -427,34 +427,9 @@ pub(super) fn report_borrowed_value_does_not_live_long_enough(
         self.access_place_error_reported
             .insert((root_place.clone(), borrow_span));
 
-        match (borrow.region, &self.describe_place(&borrow.borrowed_place)) {
-            (RegionKind::ReScope(_), Some(name)) => {
-                self.report_scoped_local_value_does_not_live_long_enough(
-                    context,
-                    name,
-                    &scope_tree,
-                    &borrow,
-                    drop_span,
-                    borrow_span,
-                    proper_span,
-                );
-            }
-            (RegionKind::ReScope(_), None) => {
-                self.report_scoped_temporary_value_does_not_live_long_enough(
-                    context,
-                    &scope_tree,
-                    &borrow,
-                    drop_span,
-                    borrow_span,
-                    proper_span,
-                );
-            }
-            (RegionKind::ReEarlyBound(_), Some(name))
-            | (RegionKind::ReFree(_), Some(name))
-            | (RegionKind::ReStatic, Some(name))
-            | (RegionKind::ReEmpty, Some(name))
-            | (RegionKind::ReVar(_), Some(name)) => {
-                self.report_unscoped_local_value_does_not_live_long_enough(
+        match &self.describe_place(&borrow.borrowed_place) {
+            Some(name) => {
+                self.report_local_value_does_not_live_long_enough(
                     context,
                     name,
                     &scope_tree,
@@ -465,12 +440,8 @@ pub(super) fn report_borrowed_value_does_not_live_long_enough(
                     kind.map(|k| (k, place_span.0)),
                 );
             }
-            (RegionKind::ReEarlyBound(_), None)
-            | (RegionKind::ReFree(_), None)
-            | (RegionKind::ReStatic, None)
-            | (RegionKind::ReEmpty, None)
-            | (RegionKind::ReVar(_), None) => {
-                self.report_unscoped_temporary_value_does_not_live_long_enough(
+            None => {
+                self.report_temporary_value_does_not_live_long_enough(
                     context,
                     &scope_tree,
                     &borrow,
@@ -479,65 +450,10 @@ pub(super) fn report_borrowed_value_does_not_live_long_enough(
                     proper_span,
                 );
             }
-            (RegionKind::ReLateBound(_, _), _)
-            | (RegionKind::ReSkolemized(_, _), _)
-            | (RegionKind::ReClosureBound(_), _)
-            | (RegionKind::ReCanonical(_), _)
-            | (RegionKind::ReErased, _) => {
-                span_bug!(
-                    drop_span,
-                    "region {:?} does not make sense in this context",
-                    borrow.region
-                );
-            }
         }
     }
 
-    fn report_scoped_local_value_does_not_live_long_enough(
-        &mut self,
-        context: Context,
-        name: &String,
-        _scope_tree: &Lrc<ScopeTree>,
-        borrow: &BorrowData<'tcx>,
-        drop_span: Span,
-        borrow_span: Span,
-        _proper_span: Span,
-    ) {
-        let tcx = self.tcx;
-        let mut err =
-            tcx.path_does_not_live_long_enough(borrow_span, &format!("`{}`", name), Origin::Mir);
-        err.span_label(borrow_span, "borrowed value does not live long enough");
-        err.span_label(
-            drop_span,
-            format!("`{}` dropped here while still borrowed", name),
-        );
-        self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
-        err.buffer(&mut self.errors_buffer);
-    }
-
-    fn report_scoped_temporary_value_does_not_live_long_enough(
-        &mut self,
-        context: Context,
-        _scope_tree: &Lrc<ScopeTree>,
-        borrow: &BorrowData<'tcx>,
-        drop_span: Span,
-        _borrow_span: Span,
-        proper_span: Span,
-    ) {
-        let tcx = self.tcx;
-        let mut err =
-            tcx.path_does_not_live_long_enough(proper_span, "borrowed value", Origin::Mir);
-        err.span_label(proper_span, "temporary value does not live long enough");
-        err.span_label(
-            drop_span,
-            "temporary value dropped here while still borrowed",
-        );
-        err.note("consider using a `let` binding to increase its lifetime");
-        self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
-        err.buffer(&mut self.errors_buffer);
-    }
-
-    fn report_unscoped_local_value_does_not_live_long_enough(
+    fn report_local_value_does_not_live_long_enough(
         &mut self,
         context: Context,
         name: &String,
@@ -549,7 +465,7 @@ fn report_unscoped_local_value_does_not_live_long_enough(
         kind_place: Option<(WriteKind, &Place<'tcx>)>,
     ) {
         debug!(
-            "report_unscoped_local_value_does_not_live_long_enough(\
+            "report_local_value_does_not_live_long_enough(\
              {:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
              )",
             context, name, scope_tree, borrow, drop_span, borrow_span
@@ -559,13 +475,16 @@ fn report_unscoped_local_value_does_not_live_long_enough(
         let mut err =
             tcx.path_does_not_live_long_enough(borrow_span, &format!("`{}`", name), Origin::Mir);
         err.span_label(borrow_span, "borrowed value does not live long enough");
-        err.span_label(drop_span, "borrowed value only lives until here");
+        err.span_label(
+            drop_span,
+            format!("`{}` dropped here while still borrowed", name),
+        );
 
         self.explain_why_borrow_contains_point(context, borrow, kind_place, &mut err);
         err.buffer(&mut self.errors_buffer);
     }
 
-    fn report_unscoped_temporary_value_does_not_live_long_enough(
+    fn report_temporary_value_does_not_live_long_enough(
         &mut self,
         context: Context,
         scope_tree: &Lrc<ScopeTree>,
@@ -575,7 +494,7 @@ fn report_unscoped_temporary_value_does_not_live_long_enough(
         proper_span: Span,
     ) {
         debug!(
-            "report_unscoped_temporary_value_does_not_live_long_enough(\
+            "report_temporary_value_does_not_live_long_enough(\
              {:?}, {:?}, {:?}, {:?}, {:?}\
              )",
             context, scope_tree, borrow, drop_span, proper_span
index e26bf1b4f77cd0e05750275700c15f3647634a42..af4356dc8de7816e1da472accfdf96903b0059c9 100644 (file)
@@ -270,9 +270,9 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             "roundf32"     => (0, vec![ tcx.types.f32 ], tcx.types.f32),
             "roundf64"     => (0, vec![ tcx.types.f64 ], tcx.types.f64),
 
-            "volatile_load" =>
+            "volatile_load" | "unaligned_volatile_load" =>
                 (1, vec![ tcx.mk_imm_ptr(param(0)) ], param(0)),
-            "volatile_store" =>
+            "volatile_store" | "unaligned_volatile_store" =>
                 (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()),
 
             "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" |
index ae64c6f1bfd7fb3f47ee6e2fe8d0cdebc86eb3ed..9ebefdabbb410db556cec73d5dcebd2b265a6494 100644 (file)
@@ -90,7 +90,6 @@ pub mod html {
 }
 pub mod markdown;
 pub mod passes;
-pub mod plugins;
 pub mod visit_ast;
 pub mod visit_lib;
 pub mod test;
@@ -750,25 +749,22 @@ fn report_deprecated_attr(name: &str, diag: &errors::Handler) {
             eprintln!("WARNING: --plugin-path no longer functions; see CVE-2018-1000622");
         }
 
-        // Load all plugins/passes into a PluginManager
-        let mut pm = plugins::PluginManager::new();
+        info!("Executing passes");
+
         for pass in &passes {
-            let plugin = match passes::PASSES.iter()
-                                             .position(|&(p, ..)| {
-                                                 p == *pass
-                                             }) {
-                Some(i) => passes::PASSES[i].1,
+            // determine if we know about this pass
+            let pass = match passes::PASSES.iter().find(|(p, ..)| p == pass) {
+                Some(pass) => pass.1,
                 None => {
                     error!("unknown pass {}, skipping", *pass);
+
                     continue
                 },
             };
-            pm.add_plugin(plugin);
-        }
 
-        // Run everything!
-        info!("Executing passes/plugins");
-        let krate = pm.run_plugins(krate);
+            // run it
+            krate = pass(krate);
+        }
 
         tx.send(f(Output { krate: krate, renderinfo: renderinfo, passes: passes })).unwrap();
     }));
index a2d651d29de93362e00aee7d4857537d4ac5ff1e..6f70fcf1099e634dbecc643b5b14c8e756db6487 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use clean::{self, DocFragment, Item};
-use plugins;
 use fold;
 use fold::DocFolder;
 use std::mem::replace;
@@ -31,7 +30,7 @@ fn kind(&self) -> DocFragmentKind {
     }
 }
 
-pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
+pub fn collapse_docs(krate: clean::Crate) -> clean::Crate {
     Collapser.fold_crate(krate)
 }
 
index 699ee25436a10ea784abe8791ab1d17980b3adb5..63b74ceafacb466cde15c71ece1e74c6eef4754e 100644 (file)
@@ -16,7 +16,6 @@
 use clean::{self, GetDefId, Item};
 use fold;
 use fold::FoldItem::Strip;
-use plugins;
 
 mod collapse_docs;
 pub use self::collapse_docs::collapse_docs;
@@ -37,7 +36,7 @@
 pub use self::propagate_doc_cfg::propagate_doc_cfg;
 
 type Pass = (&'static str,                                      // name
-             fn(clean::Crate) -> plugins::PluginResult,         // fn
+             fn(clean::Crate) -> clean::Crate,                  // fn
              &'static str);                                     // description
 
 pub const PASSES: &'static [Pass] = &[
index fc8abafd4d89b549cb71e4b139f1a8532abec4d0..572a8d3f470f2ac24ad038d5b9e2a94c4154786d 100644 (file)
@@ -13,9 +13,8 @@
 use clean::{Crate, Item};
 use clean::cfg::Cfg;
 use fold::DocFolder;
-use plugins::PluginResult;
 
-pub fn propagate_doc_cfg(cr: Crate) -> PluginResult {
+pub fn propagate_doc_cfg(cr: Crate) -> Crate {
     CfgPropagator { parent_cfg: None }.fold_crate(cr)
 }
 
index 68c1231fc6f7c58e7266ee3e3c52708fa36e7b68..b1545233f8a2b52f4fc0d039ddef8d3816b496b9 100644 (file)
 
 use clean::{self, AttributesExt, NestedAttributesExt};
 use clean::Item;
-use plugins;
 use fold;
 use fold::DocFolder;
 use fold::FoldItem::Strip;
 use passes::ImplStripper;
 
 /// Strip items marked `#[doc(hidden)]`
-pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
+pub fn strip_hidden(krate: clean::Crate) -> clean::Crate {
     let mut retained = DefIdSet();
 
     // strip all #[doc(hidden)] items
index 91f8be43c281a629de133d6de245e973fc35191c..c4640839923bdc2d781decc786d16a48f8c2bd1d 100644 (file)
@@ -10,9 +10,8 @@
 
 use clean;
 use fold::DocFolder;
-use plugins;
 use passes::ImportStripper;
 
-pub fn strip_priv_imports(krate: clean::Crate)  -> plugins::PluginResult {
+pub fn strip_priv_imports(krate: clean::Crate)  -> clean::Crate {
     ImportStripper.fold_crate(krate)
 }
index acd735739e4887520b3c36a605f487239d6a7de8..45f706590e32e558d6a9af4d001b60402ff75339 100644 (file)
 use rustc::util::nodemap::DefIdSet;
 
 use clean;
-use plugins;
 use fold::DocFolder;
 use passes::{ImplStripper, ImportStripper, Stripper};
 
 /// Strip private items from the point of view of a crate or externally from a
 /// crate, specified by the `xcrate` flag.
-pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
+pub fn strip_private(mut krate: clean::Crate) -> clean::Crate {
     // This stripper collects all *retained* nodes.
     let mut retained = DefIdSet();
     let access_levels = krate.access_levels.clone();
index 912c7646a06e58414fc5f0784856b99f7393b325..2510ec011b64ca499227e915100e538489fb1fd3 100644 (file)
 use std::usize;
 
 use clean::{self, DocFragment, Item};
-use plugins;
 use fold::{self, DocFolder};
 
-pub fn unindent_comments(krate: clean::Crate) -> plugins::PluginResult {
+pub fn unindent_comments(krate: clean::Crate) -> clean::Crate {
     CommentCleaner.fold_crate(krate)
 }
 
diff --git a/src/librustdoc/plugins.rs b/src/librustdoc/plugins.rs
deleted file mode 100644 (file)
index 261ff72..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012-2013 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.
-
-#![allow(deprecated)]
-
-use clean;
-
-pub type PluginResult = clean::Crate;
-pub type PluginCallback = fn (clean::Crate) -> PluginResult;
-
-/// Manages loading and running of plugins
-pub struct PluginManager {
-    callbacks: Vec<PluginCallback> ,
-}
-
-impl PluginManager {
-    /// Create a new plugin manager
-    pub fn new() -> PluginManager {
-        PluginManager {
-            callbacks: Vec::new(),
-        }
-    }
-
-    /// Load a normal Rust function as a plugin.
-    ///
-    /// This is to run passes over the cleaned crate. Plugins run this way
-    /// correspond to the A-aux tag on Github.
-    pub fn add_plugin(&mut self, plugin: PluginCallback) {
-        self.callbacks.push(plugin);
-    }
-    /// Run all the loaded plugins over the crate, returning their results
-    pub fn run_plugins(&self, mut krate: clean::Crate) -> clean::Crate {
-        for &callback in &self.callbacks {
-            krate = callback(krate);
-        }
-        krate
-    }
-}
index b7040ed37d732ae314f3893893104107a3c65d08..eb980a7369bf27ac2e62370c268d6f6072fcf017 100644 (file)
@@ -232,31 +232,35 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
         ..config::basic_options().clone()
     };
 
-    let (libdir, outdir) = driver::spawn_thread_pool(sessopts, |sessopts| {
-        // Shuffle around a few input and output handles here. We're going to pass
-        // an explicit handle into rustc to collect output messages, but we also
-        // want to catch the error message that rustc prints when it fails.
-        //
-        // We take our thread-local stderr (likely set by the test runner) and replace
-        // it with a sink that is also passed to rustc itself. When this function
-        // returns the output of the sink is copied onto the output of our own thread.
-        //
-        // The basic idea is to not use a default Handler for rustc, and then also
-        // not print things by default to the actual stderr.
-        struct Sink(Arc<Mutex<Vec<u8>>>);
-        impl Write for Sink {
-            fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-                Write::write(&mut *self.0.lock().unwrap(), data)
-            }
-            fn flush(&mut self) -> io::Result<()> { Ok(()) }
+    // Shuffle around a few input and output handles here. We're going to pass
+    // an explicit handle into rustc to collect output messages, but we also
+    // want to catch the error message that rustc prints when it fails.
+    //
+    // We take our thread-local stderr (likely set by the test runner) and replace
+    // it with a sink that is also passed to rustc itself. When this function
+    // returns the output of the sink is copied onto the output of our own thread.
+    //
+    // The basic idea is to not use a default Handler for rustc, and then also
+    // not print things by default to the actual stderr.
+    struct Sink(Arc<Mutex<Vec<u8>>>);
+    impl Write for Sink {
+        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+            Write::write(&mut *self.0.lock().unwrap(), data)
         }
-        struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
-        impl Drop for Bomb {
-            fn drop(&mut self) {
-                let _ = self.1.write_all(&self.0.lock().unwrap());
-            }
+        fn flush(&mut self) -> io::Result<()> { Ok(()) }
+    }
+    struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
+    impl Drop for Bomb {
+        fn drop(&mut self) {
+            let _ = self.1.write_all(&self.0.lock().unwrap());
         }
-        let data = Arc::new(Mutex::new(Vec::new()));
+    }
+    let data = Arc::new(Mutex::new(Vec::new()));
+
+    let old = io::set_panic(Some(box Sink(data.clone())));
+    let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
+
+    let (libdir, outdir, compile_result) = driver::spawn_thread_pool(sessopts, |sessopts| {
         let codemap = Lrc::new(CodeMap::new_doctest(
             sessopts.file_path_mapping(), filename.clone(), line as isize - line_offset as isize
         ));
@@ -264,8 +268,6 @@ fn drop(&mut self) {
                                                         Some(codemap.clone()),
                                                         false,
                                                         false);
-        let old = io::set_panic(Some(box Sink(data.clone())));
-        let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
 
         // Compile the code
         let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter);
@@ -312,28 +314,28 @@ fn drop(&mut self) {
             Err(_) | Ok(Err(CompileIncomplete::Errored(_))) => Err(())
         };
 
-        match (compile_result, compile_fail) {
-            (Ok(()), true) => {
-                panic!("test compiled while it wasn't supposed to")
-            }
-            (Ok(()), false) => {}
-            (Err(()), true) => {
-                if error_codes.len() > 0 {
-                    let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
-                    error_codes.retain(|err| !out.contains(err));
-                }
-            }
-            (Err(()), false) => {
-                panic!("couldn't compile the test")
+        (libdir, outdir, compile_result)
+    });
+
+    match (compile_result, compile_fail) {
+        (Ok(()), true) => {
+            panic!("test compiled while it wasn't supposed to")
+        }
+        (Ok(()), false) => {}
+        (Err(()), true) => {
+            if error_codes.len() > 0 {
+                let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
+                error_codes.retain(|err| !out.contains(err));
             }
         }
-
-        if error_codes.len() > 0 {
-            panic!("Some expected error codes were not found: {:?}", error_codes);
+        (Err(()), false) => {
+            panic!("couldn't compile the test")
         }
+    }
 
-        (libdir, outdir)
-    });
+    if error_codes.len() > 0 {
+        panic!("Some expected error codes were not found: {:?}", error_codes);
+    }
 
     if no_run { return }
 
@@ -548,7 +550,7 @@ pub fn add_test(&mut self, test: String,
         debug!("Creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
             desc: testing::TestDesc {
-                name: testing::DynTestName(name),
+                name: testing::DynTestName(name.clone()),
                 ignore: should_ignore,
                 // compiler failures are test failures
                 should_panic: testing::ShouldPanic::No,
@@ -558,7 +560,7 @@ pub fn add_test(&mut self, test: String,
                 let panic = io::set_panic(None);
                 let print = io::set_print(None);
                 match {
-                    rustc_driver::in_rustc_thread(move || with_globals(move || {
+                    rustc_driver::in_named_rustc_thread(name, move || with_globals(move || {
                         io::set_panic(panic);
                         io::set_print(print);
                         hygiene::set_default_edition(edition);
index ae5037cc44e80103ea38e705c4808120e205d398..008c5da171ffc663e68a1afe06701b71b40b3f23 100644 (file)
@@ -53,10 +53,7 @@ fn read_till_eof<T, F>(&mut self, cb: F) -> Option<T> where
         F: FnOnce(&mut Parser) -> Option<T>,
     {
         self.read_atomically(move |p| {
-            match cb(p) {
-                Some(x) => if p.is_eof() {Some(x)} else {None},
-                None => None,
-            }
+            cb(p).filter(|_| p.is_eof())
         })
     }
 
index 0c60129494d5c3ecf0a012c73fa697be38a9c4a1..688a7e99f10edf0b7cb57fc136122d2e2a016c50 100644 (file)
@@ -1065,10 +1065,7 @@ impl<'a> Iterator for Ancestors<'a> {
 
     fn next(&mut self) -> Option<Self::Item> {
         let next = self.next;
-        self.next = match next {
-            Some(path) => path.parent(),
-            None => None,
-        };
+        self.next = next.and_then(Path::parent);
         next
     }
 }
index 4c5f857462193ddf51dc2eb630eb4c882358e0af..2ab7770324254b8109aaf705630c6cc0c42f5d5d 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable(feature = "unix_socket_redox", reason = "new feature", issue="51553")]
+#![stable(feature = "unix_socket_redox", since = "1.29")]
 
 //! Unix-specific networking functionality
 
@@ -37,6 +37,7 @@
 /// let addr = socket.local_addr().expect("Couldn't get local address");
 /// ```
 #[derive(Clone)]
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 pub struct SocketAddr(());
 
 impl SocketAddr {
@@ -64,6 +65,7 @@ impl SocketAddr {
     /// let addr = socket.local_addr().expect("Couldn't get local address");
     /// assert_eq!(addr.as_pathname(), None);
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn as_pathname(&self) -> Option<&Path> {
         None
     }
@@ -91,10 +93,12 @@ pub fn as_pathname(&self) -> Option<&Path> {
     /// let addr = socket.local_addr().expect("Couldn't get local address");
     /// assert_eq!(addr.is_unnamed(), true);
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn is_unnamed(&self) -> bool {
         false
     }
 }
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl fmt::Debug for SocketAddr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "SocketAddr")
@@ -115,8 +119,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 /// stream.read_to_string(&mut response).unwrap();
 /// println!("{}", response);
 /// ```
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 pub struct UnixStream(FileDesc);
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl fmt::Debug for UnixStream {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixStream");
@@ -147,6 +153,7 @@ impl UnixStream {
     ///     }
     /// };
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
         if let Some(s) = path.as_ref().to_str() {
             cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC))
@@ -177,6 +184,7 @@ pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
     ///     }
     /// };
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
         let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC))
             .map(FileDesc::new)?;
@@ -200,6 +208,7 @@ pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
     /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn try_clone(&self) -> io::Result<UnixStream> {
         self.0.duplicate().map(UnixStream)
     }
@@ -214,6 +223,7 @@ pub fn try_clone(&self) -> io::Result<UnixStream> {
     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
     /// let addr = socket.local_addr().expect("Couldn't get local address");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox"))
     }
@@ -228,6 +238,7 @@ pub fn local_addr(&self) -> io::Result<SocketAddr> {
     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
     /// let addr = socket.peer_addr().expect("Couldn't get peer address");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox"))
     }
@@ -266,6 +277,7 @@ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
     /// let err = result.unwrap_err();
     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
         Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox"))
     }
@@ -304,6 +316,7 @@ pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
     /// let err = result.unwrap_err();
     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
         Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox"))
     }
@@ -320,6 +333,7 @@ pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
     /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
     /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox"))
     }
@@ -336,6 +350,7 @@ pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
     /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
     /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox"))
     }
@@ -350,6 +365,7 @@ pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
     /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
@@ -369,6 +385,7 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
     ///
     /// # Platform specific
     /// On Redox this always returns None.
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         Ok(None)
     }
@@ -390,11 +407,13 @@ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
     /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
         Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox"))
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl io::Read for UnixStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         io::Read::read(&mut &*self, buf)
@@ -406,6 +425,7 @@ unsafe fn initializer(&self) -> Initializer {
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl<'a> io::Read for &'a UnixStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.read(buf)
@@ -417,6 +437,7 @@ unsafe fn initializer(&self) -> Initializer {
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl io::Write for UnixStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         io::Write::write(&mut &*self, buf)
@@ -427,6 +448,7 @@ fn flush(&mut self) -> io::Result<()> {
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl<'a> io::Write for &'a UnixStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
@@ -437,18 +459,21 @@ fn flush(&mut self) -> io::Result<()> {
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl AsRawFd for UnixStream {
     fn as_raw_fd(&self) -> RawFd {
         self.0.raw()
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl FromRawFd for UnixStream {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
         UnixStream(FileDesc::new(fd))
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl IntoRawFd for UnixStream {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_raw()
@@ -483,8 +508,10 @@ fn into_raw_fd(self) -> RawFd {
 ///     }
 /// }
 /// ```
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 pub struct UnixListener(FileDesc);
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl fmt::Debug for UnixListener {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixListener");
@@ -512,6 +539,7 @@ impl UnixListener {
     ///     }
     /// };
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
         if let Some(s) = path.as_ref().to_str() {
             cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC))
@@ -545,6 +573,7 @@ pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
     ///     Err(e) => println!("accept function failed: {:?}", e),
     /// }
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
         self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(())))
     }
@@ -564,6 +593,7 @@ pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
     ///
     /// let listener_copy = listener.try_clone().expect("try_clone failed");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn try_clone(&self) -> io::Result<UnixListener> {
         self.0.duplicate().map(UnixListener)
     }
@@ -579,6 +609,7 @@ pub fn try_clone(&self) -> io::Result<UnixListener> {
     ///
     /// let addr = listener.local_addr().expect("Couldn't get local address");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox"))
     }
@@ -594,6 +625,7 @@ pub fn local_addr(&self) -> io::Result<SocketAddr> {
     ///
     /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
@@ -614,6 +646,7 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
     ///
     /// # Platform specific
     /// On Redox this always returns None.
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         Ok(None)
     }
@@ -649,29 +682,34 @@ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
     ///     }
     /// }
     /// ```
+    #[stable(feature = "unix_socket_redox", since = "1.29")]
     pub fn incoming<'a>(&'a self) -> Incoming<'a> {
         Incoming { listener: self }
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl AsRawFd for UnixListener {
     fn as_raw_fd(&self) -> RawFd {
         self.0.raw()
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl FromRawFd for UnixListener {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
         UnixListener(FileDesc::new(fd))
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl IntoRawFd for UnixListener {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_raw()
     }
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl<'a> IntoIterator for &'a UnixListener {
     type Item = io::Result<UnixStream>;
     type IntoIter = Incoming<'a>;
@@ -712,10 +750,12 @@ fn into_iter(self) -> Incoming<'a> {
 /// }
 /// ```
 #[derive(Debug)]
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 pub struct Incoming<'a> {
     listener: &'a UnixListener,
 }
 
+#[stable(feature = "unix_socket_redox", since = "1.29")]
 impl<'a> Iterator for Incoming<'a> {
     type Item = io::Result<UnixStream>;
 
index 61d7ed463dd3856010c89f9ab624602fb0708b26..2db47bd59475e5feb57b96d1a3ddbfa74b59071b 100644 (file)
@@ -156,16 +156,15 @@ pub fn log_enabled() -> Option<PrintFormat> {
         _ => return Some(PrintFormat::Full),
     }
 
-    let val = match env::var_os("RUST_BACKTRACE") {
-        Some(x) => if &x == "0" {
+    let val = env::var_os("RUST_BACKTRACE").and_then(|x|
+        if &x == "0" {
             None
         } else if &x == "full" {
             Some(PrintFormat::Full)
         } else {
             Some(PrintFormat::Short)
-        },
-        None => None,
-    };
+        }
+    );
     ENABLED.store(match val {
         Some(v) => v as isize,
         None => 1,
index 54376797dea990a1cdc6be11a38c5fecb43981be..64309dd9b8b93f2e9274325f4201c769195e545f 100644 (file)
@@ -4391,6 +4391,11 @@ fn is_extern_non_path(&self) -> bool {
         self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
     }
 
+    fn is_existential_type_decl(&self) -> bool {
+        self.token.is_keyword(keywords::Existential) &&
+        self.look_ahead(1, |t| t.is_keyword(keywords::Type))
+    }
+
     fn is_auto_trait_item(&mut self) -> bool {
         // auto trait
         (self.token.is_keyword(keywords::Auto)
@@ -4495,6 +4500,7 @@ fn parse_stmt_without_recovery(&mut self,
                   !self.is_union_item() &&
                   !self.is_crate_vis() &&
                   !self.is_extern_non_path() &&
+                  !self.is_existential_type_decl() &&
                   !self.is_auto_trait_item() {
             let pth = self.parse_path(PathStyle::Expr)?;
 
index dcccb187bef4b0415b04507aceb6b93cb1915a20..a0845e0982d2ad362deb7dc55a23a052405f1eba 100644 (file)
@@ -138,17 +138,13 @@ pub fn nil_ty<'r>() -> Ty<'r> {
 }
 
 fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
-    match *lt {
-        Some(s) => Some(cx.lifetime(span, Ident::from_str(s))),
-        None => None,
-    }
+    lt.map(|s|
+        cx.lifetime(span, Ident::from_str(s))
+    )
 }
 
 fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
-    match *lt {
-        Some(s) => vec![cx.lifetime(span, Ident::from_str(s))],
-        None => vec![],
-    }
+    mk_lifetime(cx, span, lt).into_iter().collect()
 }
 
 impl<'a> Ty<'a> {
index 755d2b476b7167ae33b94f195aabc075d8b52ebb..98de3d80b1e1f354ab2827b19b6a1f168637e2a5 100644 (file)
 use fmt_macros as parse;
 
 use syntax::ast;
-use syntax::ext::base::*;
 use syntax::ext::base;
+use syntax::ext::base::*;
 use syntax::ext::build::AstBuilder;
 use syntax::feature_gate;
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
-use syntax_pos::{Span, DUMMY_SP};
 use syntax::tokenstream;
+use syntax_pos::{MultiSpan, Span, DUMMY_SP};
 
-use std::collections::{HashMap, HashSet};
 use std::collections::hash_map::Entry;
+use std::collections::{HashMap, HashSet};
 
 #[derive(PartialEq)]
 enum ArgumentType {
@@ -111,8 +111,14 @@ struct Context<'a, 'b: 'a> {
     /// still existed in this phase of processing.
     /// Used only for `all_pieces_simple` tracking in `build_piece`.
     curarg: usize,
-    /// Keep track of invalid references to positional arguments
-    invalid_refs: Vec<usize>,
+    /// Current piece being evaluated, used for error reporting.
+    curpiece: usize,
+    /// Keep track of invalid references to positional arguments.
+    invalid_refs: Vec<(usize, usize)>,
+    /// Spans of all the formatting arguments, in order.
+    arg_spans: Vec<Span>,
+    /// Wether this formatting string is a literal or it comes from a macro.
+    is_literal: bool,
 }
 
 /// Parses the arguments from the given list of tokens, returning None
@@ -155,15 +161,20 @@ fn parse_args(ecx: &mut ExtCtxt,
                     i
                 }
                 _ if named => {
-                    ecx.span_err(p.span,
-                                 "expected ident, positional arguments \
-                                 cannot follow named arguments");
+                    ecx.span_err(
+                        p.span,
+                        "expected ident, positional arguments cannot follow named arguments",
+                    );
                     return None;
                 }
                 _ => {
-                    ecx.span_err(p.span,
-                                 &format!("expected ident for named argument, found `{}`",
-                                          p.this_token_to_string()));
+                    ecx.span_err(
+                        p.span,
+                        &format!(
+                            "expected ident for named argument, found `{}`",
+                            p.this_token_to_string()
+                        ),
+                    );
                     return None;
                 }
             };
@@ -235,6 +246,7 @@ fn verify_piece(&mut self, p: &parse::Piece) {
 
                 let ty = Placeholder(arg.format.ty.to_string());
                 self.verify_arg_type(pos, ty);
+                self.curpiece += 1;
             }
         }
     }
@@ -266,29 +278,59 @@ fn describe_num_args(&self) -> String {
     /// format string.
     fn report_invalid_references(&self, numbered_position_args: bool) {
         let mut e;
-        let mut refs: Vec<String> = self.invalid_refs
-                                        .iter()
-                                        .map(|r| r.to_string())
-                                        .collect();
+        let sp = if self.is_literal {
+            MultiSpan::from_spans(self.arg_spans.clone())
+        } else {
+            MultiSpan::from_span(self.fmtsp)
+        };
+        let mut refs: Vec<_> = self
+            .invalid_refs
+            .iter()
+            .map(|(r, pos)| (r.to_string(), self.arg_spans.get(*pos)))
+            .collect();
 
         if self.names.is_empty() && !numbered_position_args {
-            e = self.ecx.mut_span_err(self.fmtsp,
-                &format!("{} positional argument{} in format string, but {}",
+            e = self.ecx.mut_span_err(
+                sp,
+                &format!(
+                    "{} positional argument{} in format string, but {}",
                          self.pieces.len(),
                          if self.pieces.len() > 1 { "s" } else { "" },
-                         self.describe_num_args()));
+                    self.describe_num_args()
+                ),
+            );
         } else {
-            let arg_list = match refs.len() {
-                1 => format!("argument {}", refs.pop().unwrap()),
-                _ => format!("arguments {head} and {tail}",
-                             tail=refs.pop().unwrap(),
-                             head=refs.join(", "))
+            let (arg_list, mut sp) = match refs.len() {
+                1 => {
+                    let (reg, pos) = refs.pop().unwrap();
+                    (
+                        format!("argument {}", reg),
+                        MultiSpan::from_span(*pos.unwrap_or(&self.fmtsp)),
+                    )
+                }
+                _ => {
+                    let pos =
+                        MultiSpan::from_spans(refs.iter().map(|(_, p)| *p.unwrap()).collect());
+                    let mut refs: Vec<String> = refs.iter().map(|(s, _)| s.to_owned()).collect();
+                    let reg = refs.pop().unwrap();
+                    (
+                        format!(
+                            "arguments {head} and {tail}",
+                            tail = reg,
+                            head = refs.join(", ")
+                        ),
+                        pos,
+                    )
+                }
             };
+            if !self.is_literal {
+                sp = MultiSpan::from_span(self.fmtsp);
+            }
 
-            e = self.ecx.mut_span_err(self.fmtsp,
+            e = self.ecx.mut_span_err(sp,
                 &format!("invalid reference to positional {} ({})",
-                        arg_list,
-                        self.describe_num_args()));
+                         arg_list,
+                         self.describe_num_args()));
             e.note("positional arguments are zero-based");
         };
 
@@ -301,7 +343,7 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
         match arg {
             Exact(arg) => {
                 if self.args.len() <= arg {
-                    self.invalid_refs.push(arg);
+                    self.invalid_refs.push((arg, self.curpiece));
                     return;
                 }
                 match ty {
@@ -337,7 +379,13 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
                     Some(e) => *e,
                     None => {
                         let msg = format!("there is no argument named `{}`", name);
-                        self.ecx.span_err(self.fmtsp, &msg[..]);
+                        let sp = if self.is_literal {
+                            *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
+                        } else {
+                            self.fmtsp
+                        };
+                        let mut err = self.ecx.struct_span_err(sp, &msg[..]);
+                        err.emit();
                         return;
                     }
                 };
@@ -505,33 +553,27 @@ fn build_piece(&mut self,
                 let prec = self.build_count(arg.format.precision);
                 let width = self.build_count(arg.format.width);
                 let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec"));
-                let fmt =
-                    self.ecx.expr_struct(sp,
+                let fmt = self.ecx.expr_struct(
+                    sp,
                                          path,
-                                         vec![self.ecx
-                                                  .field_imm(sp, self.ecx.ident_of("fill"), fill),
-                                              self.ecx.field_imm(sp,
-                                                                 self.ecx.ident_of("align"),
-                                                                 align),
-                                              self.ecx.field_imm(sp,
-                                                                 self.ecx.ident_of("flags"),
-                                                                 flags),
-                                              self.ecx.field_imm(sp,
-                                                                 self.ecx.ident_of("precision"),
-                                                                 prec),
-                                              self.ecx.field_imm(sp,
-                                                                 self.ecx.ident_of("width"),
-                                                                 width)]);
+                    vec![
+                        self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("align"), align),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("flags"), flags),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("precision"), prec),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("width"), width),
+                    ],
+                );
 
                 let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "Argument"));
-                Some(self.ecx.expr_struct(sp,
+                Some(self.ecx.expr_struct(
+                    sp,
                                           path,
-                                          vec![self.ecx.field_imm(sp,
-                                                                  self.ecx.ident_of("position"),
-                                                                  pos),
-                                               self.ecx.field_imm(sp,
-                                                                  self.ecx.ident_of("format"),
-                                                                  fmt)]))
+                    vec![
+                        self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt),
+                    ],
+                ))
             }
         }
     }
@@ -544,9 +586,9 @@ fn into_expr(self) -> P<ast::Expr> {
         let mut pats = Vec::new();
         let mut heads = Vec::new();
 
-        let names_pos: Vec<_> = (0..self.args.len()).map(|i| {
-            self.ecx.ident_of(&format!("arg{}", i)).gensym()
-        }).collect();
+        let names_pos: Vec<_> = (0..self.args.len())
+            .map(|i| self.ecx.ident_of(&format!("arg{}", i)).gensym())
+            .collect();
 
         // First, build up the static array which will become our precompiled
         // format "string"
@@ -690,10 +732,11 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
     }
 }
 
-pub fn expand_format_args_nl<'cx>(ecx: &'cx mut ExtCtxt,
-                                  mut sp: Span,
-                                  tts: &[tokenstream::TokenTree])
-                                  -> Box<dyn base::MacResult + 'cx> {
+pub fn expand_format_args_nl<'cx>(
+    ecx: &'cx mut ExtCtxt,
+    mut sp: Span,
+    tts: &[tokenstream::TokenTree],
+) -> Box<dyn base::MacResult + 'cx> {
     //if !ecx.ecfg.enable_allow_internal_unstable() {
 
     // For some reason, the only one that actually works for `println` is the first check
@@ -744,7 +787,6 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
             let sugg_fmt = match args.len() {
                 0 => "{}".to_string(),
                 _ => format!("{}{{}}", "{} ".repeat(args.len())),
-
             };
             err.span_suggestion(
                 fmt_sp.shrink_to_lo(),
@@ -753,7 +795,11 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
             );
             err.emit();
             return DummyResult::raw_expr(sp);
-        },
+        }
+    };
+    let is_literal = match ecx.codemap().span_to_snippet(fmt_sp) {
+        Ok(ref s) if s.starts_with("\"") || s.starts_with("r#") => true,
+        _ => false,
     };
 
     let mut cx = Context {
@@ -763,6 +809,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
         arg_unique_types,
         names,
         curarg: 0,
+        curpiece: 0,
         arg_index_map: Vec::new(),
         count_args: Vec::new(),
         count_positions: HashMap::new(),
@@ -775,6 +822,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
         macsp,
         fmtsp: fmt.span,
         invalid_refs: Vec::new(),
+        arg_spans: Vec::new(),
+        is_literal,
     };
 
     let fmt_str = &*fmt.node.0.as_str();
@@ -783,12 +832,22 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
         ast::StrStyle::Raw(raw) => Some(raw as usize),
     };
     let mut parser = parse::Parser::new(fmt_str, str_style);
+    let mut unverified_pieces = vec![];
     let mut pieces = vec![];
 
-    while let Some(mut piece) = parser.next() {
+    while let Some(piece) = parser.next() {
         if !parser.errors.is_empty() {
             break;
         }
+        unverified_pieces.push(piece);
+    }
+
+    cx.arg_spans = parser.arg_places.iter()
+        .map(|&(start, end)| fmt.span.from_inner_byte_pos(start, end))
+        .collect();
+
+    // This needs to happen *after* the Parser has consumed all pieces to create all the spans
+    for mut piece in unverified_pieces {
         cx.verify_piece(&piece);
         cx.resolve_name_inplace(&mut piece);
         pieces.push(piece);
@@ -856,24 +915,27 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
             errs.push((cx.args[i].span, msg));
         }
     }
-    if errs.len() > 0 {
-        let args_used = cx.arg_types.len() - errs.len();
-        let args_unused = errs.len();
+    let errs_len = errs.len();
+    if errs_len > 0 {
+        let args_used = cx.arg_types.len() - errs_len;
+        let args_unused = errs_len;
 
         let mut diag = {
-            if errs.len() == 1 {
+            if errs_len == 1 {
                 let (sp, msg) = errs.into_iter().next().unwrap();
                 cx.ecx.struct_span_err(sp, msg)
             } else {
                 let mut diag = cx.ecx.struct_span_err(
                     errs.iter().map(|&(sp, _)| sp).collect::<Vec<Span>>(),
-                    "multiple unused formatting arguments"
+                    "multiple unused formatting arguments",
                 );
-                diag.span_label(cx.fmtsp, "multiple missing formatting arguments");
+                diag.span_label(cx.fmtsp, "multiple missing formatting specifiers");
                 diag
             }
         };
 
+        // Used to ensure we only report translations for *one* kind of foreign format.
+        let mut found_foreign = false;
         // Decide if we want to look for foreign formatting directives.
         if args_used < args_unused {
             use super::format_foreign as foreign;
@@ -882,13 +944,11 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
             // with `%d should be written as {}` over and over again.
             let mut explained = HashSet::new();
 
-            // Used to ensure we only report translations for *one* kind of foreign format.
-            let mut found_foreign = false;
-
             macro_rules! check_foreign {
                 ($kind:ident) => {{
                     let mut show_doc_note = false;
 
+                    let mut suggestions = vec![];
                     for sub in foreign::$kind::iter_subs(fmt_str) {
                         let trn = match sub.translate() {
                             Some(trn) => trn,
@@ -897,6 +957,7 @@ macro_rules! check_foreign {
                             None => continue,
                         };
 
+                        let pos = sub.position();
                         let sub = String::from(sub.as_str());
                         if explained.contains(&sub) {
                             continue;
@@ -908,7 +969,14 @@ macro_rules! check_foreign {
                             show_doc_note = true;
                         }
 
-                        diag.help(&format!("`{}` should be written as `{}`", sub, trn));
+                        if let Some((start, end)) = pos {
+                            // account for `"` and account for raw strings `r#`
+                            let padding = str_style.map(|i| i + 2).unwrap_or(1);
+                            let sp = fmt_sp.from_inner_byte_pos(start + padding, end + padding);
+                            suggestions.push((sp, trn));
+                        } else {
+                            diag.help(&format!("`{}` should be written as `{}`", sub, trn));
+                        }
                     }
 
                     if show_doc_note {
@@ -917,6 +985,12 @@ macro_rules! check_foreign {
                             " formatting not supported; see the documentation for `std::fmt`",
                         ));
                     }
+                    if suggestions.len() > 0 {
+                        diag.multipart_suggestion(
+                            "format specifiers use curly braces",
+                            suggestions,
+                        );
+                    }
                 }};
             }
 
@@ -925,6 +999,9 @@ macro_rules! check_foreign {
                 check_foreign!(shell);
             }
         }
+        if !found_foreign && errs_len == 1 {
+            diag.span_label(cx.fmtsp, "formatting specifier missing");
+        }
 
         diag.emit();
     }
index 8ccb3be1ad912431f5de64226f8c1427c4b51770..23a37ca34853c6ad39586a3c2e26422038ca645e 100644 (file)
@@ -14,7 +14,7 @@ pub mod printf {
     /// Represents a single `printf`-style substitution.
     #[derive(Clone, PartialEq, Debug)]
     pub enum Substitution<'a> {
-        /// A formatted output substitution.
+        /// A formatted output substitution with its internal byte offset.
         Format(Format<'a>),
         /// A literal `%%` escape.
         Escape,
@@ -28,6 +28,23 @@ pub fn as_str(&self) -> &str {
             }
         }
 
+        pub fn position(&self) -> Option<(usize, usize)> {
+            match *self {
+                Substitution::Format(ref fmt) => Some(fmt.position),
+                _ => None,
+            }
+        }
+
+        pub fn set_position(&mut self, start: usize, end: usize) {
+            match self {
+                Substitution::Format(ref mut fmt) => {
+                    fmt.position = (start, end);
+                }
+                _ => {}
+            }
+        }
+
+
         /// Translate this substitution into an equivalent Rust formatting directive.
         ///
         /// This ignores cases where the substitution does not have an exact equivalent, or where
@@ -57,6 +74,8 @@ pub struct Format<'a> {
         pub length: Option<&'a str>,
         /// Type of parameter being converted.
         pub type_: &'a str,
+        /// Byte offset for the start and end of this formatting directive.
+        pub position: (usize, usize),
     }
 
     impl<'a> Format<'a> {
@@ -257,19 +276,28 @@ fn translate(&self, s: &mut String) -> ::std::fmt::Result {
     pub fn iter_subs(s: &str) -> Substitutions {
         Substitutions {
             s,
+            pos: 0,
         }
     }
 
     /// Iterator over substitutions in a string.
     pub struct Substitutions<'a> {
         s: &'a str,
+        pos: usize,
     }
 
     impl<'a> Iterator for Substitutions<'a> {
         type Item = Substitution<'a>;
         fn next(&mut self) -> Option<Self::Item> {
-            let (sub, tail) = parse_next_substitution(self.s)?;
+            let (mut sub, tail) = parse_next_substitution(self.s)?;
             self.s = tail;
+            match sub {
+                Substitution::Format(_) => if let Some((start, end)) = sub.position() {
+                    sub.set_position(start + self.pos, end + self.pos);
+                    self.pos += end;
+                }
+                Substitution::Escape => self.pos += 2,
+            }
             Some(sub)
         }
 
@@ -301,7 +329,7 @@ pub fn parse_next_substitution(s: &str) -> Option<(Substitution, &str)> {
                 _ => {/* fall-through */},
             }
 
-            Cur::new_at_start(&s[start..])
+            Cur::new_at(&s[..], start)
         };
 
         // This is meant to be a translation of the following regex:
@@ -355,6 +383,7 @@ macro_rules! move_to {
                     precision: None,
                     length: None,
                     type_: at.slice_between(next).unwrap(),
+                    position: (start.at, next.at),
                 }),
                 next.slice_after()
             ));
@@ -541,6 +570,7 @@ macro_rules! move_to {
         drop(next);
 
         end = at;
+        let position = (start.at, end.at);
 
         let f = Format {
             span: start.slice_between(end).unwrap(),
@@ -550,6 +580,7 @@ macro_rules! move_to {
             precision,
             length,
             type_,
+            position,
         };
         Some((Substitution::Format(f), end.slice_after()))
     }
@@ -616,6 +647,7 @@ macro_rules! assert_pns_eq_sub {
                 ($in_:expr, {
                     $param:expr, $flags:expr,
                     $width:expr, $prec:expr, $len:expr, $type_:expr,
+                    $pos:expr,
                 }) => {
                     assert_eq!(
                         pns(concat!($in_, "!")),
@@ -628,6 +660,7 @@ macro_rules! assert_pns_eq_sub {
                                 precision: $prec,
                                 length: $len,
                                 type_: $type_,
+                                position: $pos,
                             }),
                             "!"
                         ))
@@ -636,53 +669,53 @@ macro_rules! assert_pns_eq_sub {
             }
 
             assert_pns_eq_sub!("%!",
-                { None, "", None, None, None, "!", });
+                { None, "", None, None, None, "!", (0, 2), });
             assert_pns_eq_sub!("%c",
-                { None, "", None, None, None, "c", });
+                { None, "", None, None, None, "c", (0, 2), });
             assert_pns_eq_sub!("%s",
-                { None, "", None, None, None, "s", });
+                { None, "", None, None, None, "s", (0, 2), });
             assert_pns_eq_sub!("%06d",
-                { None, "0", Some(N::Num(6)), None, None, "d", });
+                { None, "0", Some(N::Num(6)), None, None, "d", (0, 4), });
             assert_pns_eq_sub!("%4.2f",
-                { None, "", Some(N::Num(4)), Some(N::Num(2)), None, "f", });
+                { None, "", Some(N::Num(4)), Some(N::Num(2)), None, "f", (0, 5), });
             assert_pns_eq_sub!("%#x",
-                { None, "#", None, None, None, "x", });
+                { None, "#", None, None, None, "x", (0, 3), });
             assert_pns_eq_sub!("%-10s",
-                { None, "-", Some(N::Num(10)), None, None, "s", });
+                { None, "-", Some(N::Num(10)), None, None, "s", (0, 5), });
             assert_pns_eq_sub!("%*s",
-                { None, "", Some(N::Next), None, None, "s", });
+                { None, "", Some(N::Next), None, None, "s", (0, 3), });
             assert_pns_eq_sub!("%-10.*s",
-                { None, "-", Some(N::Num(10)), Some(N::Next), None, "s", });
+                { None, "-", Some(N::Num(10)), Some(N::Next), None, "s", (0, 7), });
             assert_pns_eq_sub!("%-*.*s",
-                { None, "-", Some(N::Next), Some(N::Next), None, "s", });
+                { None, "-", Some(N::Next), Some(N::Next), None, "s", (0, 6), });
             assert_pns_eq_sub!("%.6i",
-                { None, "", None, Some(N::Num(6)), None, "i", });
+                { None, "", None, Some(N::Num(6)), None, "i", (0, 4), });
             assert_pns_eq_sub!("%+i",
-                { None, "+", None, None, None, "i", });
+                { None, "+", None, None, None, "i", (0, 3), });
             assert_pns_eq_sub!("%08X",
-                { None, "0", Some(N::Num(8)), None, None, "X", });
+                { None, "0", Some(N::Num(8)), None, None, "X", (0, 4), });
             assert_pns_eq_sub!("%lu",
-                { None, "", None, None, Some("l"), "u", });
+                { None, "", None, None, Some("l"), "u", (0, 3), });
             assert_pns_eq_sub!("%Iu",
-                { None, "", None, None, Some("I"), "u", });
+                { None, "", None, None, Some("I"), "u", (0, 3), });
             assert_pns_eq_sub!("%I32u",
-                { None, "", None, None, Some("I32"), "u", });
+                { None, "", None, None, Some("I32"), "u", (0, 5), });
             assert_pns_eq_sub!("%I64u",
-                { None, "", None, None, Some("I64"), "u", });
+                { None, "", None, None, Some("I64"), "u", (0, 5), });
             assert_pns_eq_sub!("%'d",
-                { None, "'", None, None, None, "d", });
+                { None, "'", None, None, None, "d", (0, 3), });
             assert_pns_eq_sub!("%10s",
-                { None, "", Some(N::Num(10)), None, None, "s", });
+                { None, "", Some(N::Num(10)), None, None, "s", (0, 4), });
             assert_pns_eq_sub!("%-10.10s",
-                { None, "-", Some(N::Num(10)), Some(N::Num(10)), None, "s", });
+                { None, "-", Some(N::Num(10)), Some(N::Num(10)), None, "s", (0, 8), });
             assert_pns_eq_sub!("%1$d",
-                { Some(1), "", None, None, None, "d", });
+                { Some(1), "", None, None, None, "d", (0, 4), });
             assert_pns_eq_sub!("%2$.*3$d",
-                { Some(2), "", None, Some(N::Arg(3)), None, "d", });
+                { Some(2), "", None, Some(N::Arg(3)), None, "d", (0, 8), });
             assert_pns_eq_sub!("%1$*2$.*3$d",
-                { Some(1), "", Some(N::Arg(2)), Some(N::Arg(3)), None, "d", });
+                { Some(1), "", Some(N::Arg(2)), Some(N::Arg(3)), None, "d", (0, 11), });
             assert_pns_eq_sub!("%-8ld",
-                { None, "-", Some(N::Num(8)), None, Some("l"), "d", });
+                { None, "-", Some(N::Num(8)), None, Some("l"), "d", (0, 5), });
         }
 
         #[test]
@@ -755,6 +788,12 @@ pub fn as_str(&self) -> String {
             }
         }
 
+        pub fn position(&self) -> Option<(usize, usize)> {
+            match *self {
+                _ => None,
+            }
+        }
+
         pub fn translate(&self) -> Option<String> {
             match *self {
                 Substitution::Ordinal(n) => Some(format!("{{{}}}", n)),
@@ -918,7 +957,7 @@ mod strcursor {
 
     pub struct StrCursor<'a> {
         s: &'a str,
-        at: usize,
+        pub at: usize,
     }
 
     impl<'a> StrCursor<'a> {
@@ -929,6 +968,13 @@ pub fn new_at_start(s: &'a str) -> StrCursor<'a> {
             }
         }
 
+        pub fn new_at(s: &'a str, at: usize) -> StrCursor<'a> {
+            StrCursor {
+                s,
+                at,
+            }
+        }
+
         pub fn at_next_cp(mut self) -> Option<StrCursor<'a>> {
             match self.try_seek_right_cp() {
                 true => Some(self),
index b9de11ab43090c71ff7ab159a479394df1f968ab..05c2f61c384e2097a3a4c648344114fc4ac983be 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b9de11ab43090c71ff7ab159a479394df1f968ab
+Subproject commit 05c2f61c384e2097a3a4c648344114fc4ac983be
diff --git a/src/test/compile-fail/ifmt-bad-arg.rs b/src/test/compile-fail/ifmt-bad-arg.rs
deleted file mode 100644 (file)
index afe9bc1..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 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.
-
-fn main() {
-    // bad arguments to the format! call
-
-    // bad number of arguments, see #44954 (originally #15780)
-
-    format!("{}");
-    //~^ ERROR: 1 positional argument in format string, but no arguments were given
-
-    format!("{1}", 1);
-    //~^ ERROR: invalid reference to positional argument 1 (there is 1 argument)
-    //~^^ ERROR: argument never used
-
-    format!("{} {}");
-    //~^ ERROR: 2 positional arguments in format string, but no arguments were given
-
-    format!("{0} {1}", 1);
-    //~^ ERROR: invalid reference to positional argument 1 (there is 1 argument)
-
-    format!("{0} {1} {2}", 1, 2);
-    //~^ ERROR: invalid reference to positional argument 2 (there are 2 arguments)
-
-    format!("{} {value} {} {}", 1, value=2);
-    //~^ ERROR: invalid reference to positional argument 2 (there are 2 arguments)
-    format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
-    //~^ ERROR: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments)
-
-    format!("{} {foo} {} {bar} {}", 1, 2, 3);
-    //~^ ERROR: there is no argument named `foo`
-    //~^^ ERROR: there is no argument named `bar`
-
-    format!("{foo}");                //~ ERROR: no argument named `foo`
-    format!("", 1, 2);               //~ ERROR: multiple unused formatting arguments
-    format!("{}", 1, 2);             //~ ERROR: argument never used
-    format!("{1}", 1, 2);            //~ ERROR: argument never used
-    format!("{}", 1, foo=2);         //~ ERROR: named argument never used
-    format!("{foo}", 1, foo=2);      //~ ERROR: argument never used
-    format!("", foo=2);              //~ ERROR: named argument never used
-    format!("{} {}", 1, 2, foo=1, bar=2);  //~ ERROR: multiple unused formatting arguments
-
-    format!("{foo}", foo=1, foo=2);  //~ ERROR: duplicate argument
-    format!("", foo=1, 2);           //~ ERROR: positional arguments cannot follow
-
-    // bad named arguments, #35082
-
-    format!("{valuea} {valueb}", valuea=5, valuec=7);
-    //~^ ERROR there is no argument named `valueb`
-    //~^^ ERROR named argument never used
-
-    // bad syntax of the format string
-
-    format!("{"); //~ ERROR: expected `'}'` but string was terminated
-
-    format!("foo } bar"); //~ ERROR: unmatched `}` found
-    format!("foo }"); //~ ERROR: unmatched `}` found
-
-    format!("foo %s baz", "bar"); //~ ERROR: argument never used
-}
index 4d0d7672101c36c4377fe04f5e806abb7ba0cb25..d214a20139c9ca8bfd597ed9c82247d08ebc7a8e 100644 (file)
 
 #![feature(core_intrinsics, volatile)]
 
-use std::intrinsics::{volatile_load, volatile_store};
+use std::intrinsics::{
+    unaligned_volatile_load, unaligned_volatile_store, volatile_load, volatile_store,
+};
 use std::ptr::{read_volatile, write_volatile};
 
 pub fn main() {
     unsafe {
-        let mut i : isize = 1;
+        let mut i: isize = 1;
         volatile_store(&mut i, 2);
         assert_eq!(volatile_load(&i), 2);
     }
     unsafe {
-        let mut i : isize = 1;
+        let mut i: isize = 1;
+        unaligned_volatile_store(&mut i, 2);
+        assert_eq!(unaligned_volatile_load(&i), 2);
+    }
+    unsafe {
+        let mut i: isize = 1;
         write_volatile(&mut i, 2);
         assert_eq!(read_volatile(&i), 2);
     }
diff --git a/src/test/run-pass/issue-18804/auxiliary/lib.rs b/src/test/run-pass/issue-18804/auxiliary/lib.rs
new file mode 100644 (file)
index 0000000..06d454b
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+#![crate_type = "rlib"]
+#![feature(linkage)]
+
+pub fn foo<T>() -> *const() {
+    extern {
+        #[linkage = "extern_weak"]
+        static FOO: *const();
+    }
+    unsafe { FOO }
+}
diff --git a/src/test/run-pass/issue-18804/main.rs b/src/test/run-pass/issue-18804/main.rs
new file mode 100644 (file)
index 0000000..b5aa052
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+// Test for issue #18804, #[linkage] does not propagate thorugh generic
+// functions. Failure results in a linker error.
+
+// ignore-asmjs no weak symbol support
+// ignore-emscripten no weak symbol support
+
+// aux-build:lib.rs
+
+extern crate lib;
+
+fn main() {
+    lib::foo::<i32>();
+}
diff --git a/src/test/run-pass/issue-33264.rs b/src/test/run-pass/issue-33264.rs
new file mode 100644 (file)
index 0000000..cb4b227
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2018 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.
+
+// only-x86_64
+
+#![allow(dead_code, non_upper_case_globals)]
+#![feature(asm)]
+
+#[repr(C)]
+pub struct D32x4(f32,f32,f32,f32);
+
+impl D32x4 {
+    fn add(&self, vec: Self) -> Self {
+        unsafe {
+            let ret: Self;
+            asm!("
+                 movaps $1, %xmm1
+                 movaps $2, %xmm2
+                 addps %xmm1, %xmm2
+                 movaps $xmm1, $0
+                 "
+                 : "=r"(ret)
+                 : "1"(self), "2"(vec)
+                 : "xmm1", "xmm2"
+                 );
+            ret
+        }
+    }
+}
+
+fn main() { }
+
diff --git a/src/test/run-pass/issue-34784.rs b/src/test/run-pass/issue-34784.rs
new file mode 100644 (file)
index 0000000..c9a214e
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2018 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.
+
+const C: *const u8 = &0;
+
+fn foo(x: *const u8) {
+    match x {
+        C => {}
+        _ => {}
+    }
+}
+
+const D: *const [u8; 4] = b"abcd";
+
+fn main() {
+    match D {
+        D => {}
+        _ => {}
+    }
+}
+
diff --git a/src/test/run-pass/issue-44005.rs b/src/test/run-pass/issue-44005.rs
new file mode 100644 (file)
index 0000000..a53026f
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2018 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.
+
+pub trait Foo<'a> {
+    type Bar;
+    fn foo(&'a self) -> Self::Bar;
+}
+
+impl<'a, 'b, T: 'a> Foo<'a> for &'b T {
+    type Bar = &'a T;
+    fn foo(&'a self) -> &'a T {
+        self
+    }
+}
+
+pub fn uncallable<T, F>(x: T, f: F)
+    where T: for<'a> Foo<'a>,
+          F: for<'a> Fn(<T as Foo<'a>>::Bar)
+{
+    f(x.foo());
+}
+
+pub fn catalyst(x: &i32) {
+    broken(x, |_| {})
+}
+
+pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
+    uncallable(x, |y| f(y));
+}
+
+fn main() { }
+
diff --git a/src/test/rustdoc-ui/failed-doctest-output.rs b/src/test/rustdoc-ui/failed-doctest-output.rs
new file mode 100644 (file)
index 0000000..62e4952
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+// Issue #51162: A failed doctest was not printing its stdout/stderr
+// FIXME: if/when the output of the test harness can be tested on its own, this test should be
+// adapted to use that, and that normalize line can go away
+
+// compile-flags:--test
+// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
+// failure-status: 101
+
+// doctest fails at runtime
+/// ```
+/// panic!("oh no");
+/// ```
+pub struct SomeStruct;
+
+// doctest fails at compile time
+/// ```
+/// no
+/// ```
+pub struct OtherStruct;
diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout
new file mode 100644 (file)
index 0000000..cf417f8
--- /dev/null
@@ -0,0 +1,32 @@
+
+running 2 tests
+test $DIR/failed-doctest-output.rs - OtherStruct (line 26) ... FAILED
+test $DIR/failed-doctest-output.rs - SomeStruct (line 20) ... FAILED
+
+failures:
+
+---- $DIR/failed-doctest-output.rs - OtherStruct (line 26) stdout ----
+error[E0425]: cannot find value `no` in this scope
+ --> $DIR/failed-doctest-output.rs:27:1
+  |
+3 | no
+  | ^^ not found in this scope
+
+thread '$DIR/failed-doctest-output.rs - OtherStruct (line 26)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13
+note: Run with `RUST_BACKTRACE=1` for a backtrace.
+
+---- $DIR/failed-doctest-output.rs - SomeStruct (line 20) stdout ----
+thread '$DIR/failed-doctest-output.rs - SomeStruct (line 20)' panicked at 'test executable failed:
+
+thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
+note: Run with `RUST_BACKTRACE=1` for a backtrace.
+
+', librustdoc/test.rs:367:17
+
+
+failures:
+    $DIR/failed-doctest-output.rs - OtherStruct (line 26)
+    $DIR/failed-doctest-output.rs - SomeStruct (line 20)
+
+test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
+
index b931bc45b77ee37661e64aaafb9c5af2f16a95e5..b15f156b7c2013510162f1d3a1a1ed7281a14c99 100644 (file)
@@ -5,7 +5,7 @@ LL |     spawn(|| books.push(4));
    |           ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 LL |     //~^ ERROR E0373
 LL | }
-   | - borrowed value only lives until here
+   | - `books` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index 5448049a8017d899fa87389b24cc20f3e875b765..8c643973af67b85f8b850a69bf3817a4a4c6e0b9 100644 (file)
@@ -5,7 +5,7 @@ LL |     Box::new(|| books.push(4))
    |              ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 LL |     //~^ ERROR E0373
 LL | }
-   | - borrowed value only lives until here
+   | - `books` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 19:8...
   --> $DIR/borrowck-escaping-closure-error-2.rs:19:8
index 730ace7858bd19c572b902e4ad4ee259c1de57e7..b59f628c746bb775a76f56f29ad6be7eb9b2ff90 100644 (file)
@@ -7,7 +7,7 @@ LL |     dt = Dt("dt", &c_shortest);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c_shortest` dropped here while still borrowed
    | borrow later used here, when `dt` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index f0df7109ba4b6bce70d48a4c5cd1958c6974a371..ad460fcf55e57d4cda386772cd6a795d88c1cfad 100644 (file)
@@ -7,7 +7,7 @@ LL |     dt = Dt("dt", &c_shortest);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c_shortest` dropped here while still borrowed
    | borrow later used here, when `dt` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 2072bc6a756c9f32f0045e5464172fa3e0a5a218..864fb2f2ea6f43934fd2b97cc0523c3a65bd45b5 100644 (file)
@@ -7,7 +7,7 @@ LL |     dt = Dt("dt", &c_shortest);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c_shortest` dropped here while still borrowed
    | borrow later used here, when `dt` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 172db9ced82f9ef706d3d147f374c0574f4f0cf8..31ba24b0004fb4e68dcf9ce41e408ca8b87c0fce 100644 (file)
@@ -7,7 +7,7 @@ LL |     //~^ `y` does not live long enough [E0597]
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `y` dropped here while still borrowed
    | borrow later used here, when `x` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 015538b16f971e4d94d9dc87df35a81aa7894b46..e03d72a02f0aa6eb2c7ed842ee5cbc79cbca7175 100644 (file)
@@ -5,7 +5,7 @@ LL |         unsafe { (|| yield &a).resume() }
    |                  ^^^^^^^^^^^^^ borrowed value does not live long enough
 LL |         //~^ ERROR: `a` does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `a` dropped here while still borrowed
 
 error[E0597]: `a` does not live long enough
   --> $DIR/borrowing.rs:24:9
@@ -16,7 +16,7 @@ LL | |             //~^ ERROR: `a` does not live long enough
 LL | |         }
    | |_________^ borrowed value does not live long enough
 LL |       };
-   |       - borrowed value only lives until here
+   |       - `a` dropped here while still borrowed
 LL |   }
    |   - borrow later used here, when `_b` is dropped
 
index 01a53cdd6dd4a21f9f6c696a38bc27addb0e4adc..ef7e64ffd97ae251494a68b10e5b8548955c115b 100644 (file)
@@ -7,7 +7,7 @@ LL |     let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `*cell` dropped here while still borrowed
    | borrow later used here, when `gen` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
@@ -26,7 +26,7 @@ LL | |     };
 LL |   }
    |   -
    |   |
-   |   borrowed value only lives until here
+   |   `ref_` dropped here while still borrowed
    |   borrow later used here, when `gen` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 08839c23c37622261aa1cb76e3a157e323af6534..56d853c2966c5de5b0e2f6cc89d9eecd64a37122 100644 (file)
@@ -5,7 +5,7 @@ LL |         a = &b;
    |             ^^ borrowed value does not live long enough
 LL |         //~^ ERROR `b` does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `b` dropped here while still borrowed
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/ifmt-bad-arg.rs b/src/test/ui/ifmt-bad-arg.rs
new file mode 100644 (file)
index 0000000..bbd75f3
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright 2013 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.
+
+fn main() {
+    // bad arguments to the format! call
+
+    // bad number of arguments, see #44954 (originally #15780)
+
+    format!("{}");
+    //~^ ERROR: 1 positional argument in format string, but no arguments were given
+
+    format!("{1}", 1);
+    //~^ ERROR: invalid reference to positional argument 1 (there is 1 argument)
+    //~^^ ERROR: argument never used
+
+    format!("{} {}");
+    //~^ ERROR: 2 positional arguments in format string, but no arguments were given
+
+    format!("{0} {1}", 1);
+    //~^ ERROR: invalid reference to positional argument 1 (there is 1 argument)
+
+    format!("{0} {1} {2}", 1, 2);
+    //~^ ERROR: invalid reference to positional argument 2 (there are 2 arguments)
+
+    format!("{} {value} {} {}", 1, value=2);
+    //~^ ERROR: invalid reference to positional argument 2 (there are 2 arguments)
+    format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
+    //~^ ERROR: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments)
+
+    format!("{} {foo} {} {bar} {}", 1, 2, 3);
+    //~^ ERROR: there is no argument named `foo`
+    //~^^ ERROR: there is no argument named `bar`
+
+    format!("{foo}");                //~ ERROR: no argument named `foo`
+    format!("", 1, 2);               //~ ERROR: multiple unused formatting arguments
+    format!("{}", 1, 2);             //~ ERROR: argument never used
+    format!("{1}", 1, 2);            //~ ERROR: argument never used
+    format!("{}", 1, foo=2);         //~ ERROR: named argument never used
+    format!("{foo}", 1, foo=2);      //~ ERROR: argument never used
+    format!("", foo=2);              //~ ERROR: named argument never used
+    format!("{} {}", 1, 2, foo=1, bar=2);  //~ ERROR: multiple unused formatting arguments
+
+    format!("{foo}", foo=1, foo=2);  //~ ERROR: duplicate argument
+    format!("", foo=1, 2);           //~ ERROR: positional arguments cannot follow
+
+    // bad named arguments, #35082
+
+    format!("{valuea} {valueb}", valuea=5, valuec=7);
+    //~^ ERROR there is no argument named `valueb`
+    //~^^ ERROR named argument never used
+
+    // bad syntax of the format string
+
+    format!("{"); //~ ERROR: expected `'}'` but string was terminated
+
+    format!("foo } bar"); //~ ERROR: unmatched `}` found
+    format!("foo }"); //~ ERROR: unmatched `}` found
+
+    format!("foo %s baz", "bar"); //~ ERROR: argument never used
+
+    format!(r##"
+
+        {foo}
+
+    "##);
+    //~^^^ ERROR: there is no argument named `foo`
+}
diff --git a/src/test/ui/ifmt-bad-arg.stderr b/src/test/ui/ifmt-bad-arg.stderr
new file mode 100644 (file)
index 0000000..c8fd8ba
--- /dev/null
@@ -0,0 +1,208 @@
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/ifmt-bad-arg.rs:16:14
+   |
+LL |     format!("{}");
+   |              ^^
+
+error: invalid reference to positional argument 1 (there is 1 argument)
+  --> $DIR/ifmt-bad-arg.rs:19:14
+   |
+LL |     format!("{1}", 1);
+   |              ^^^
+   |
+   = note: positional arguments are zero-based
+
+error: argument never used
+  --> $DIR/ifmt-bad-arg.rs:19:20
+   |
+LL |     format!("{1}", 1);
+   |             -----  ^
+   |             |
+   |             formatting specifier missing
+
+error: 2 positional arguments in format string, but no arguments were given
+  --> $DIR/ifmt-bad-arg.rs:23:14
+   |
+LL |     format!("{} {}");
+   |              ^^ ^^
+
+error: invalid reference to positional argument 1 (there is 1 argument)
+  --> $DIR/ifmt-bad-arg.rs:26:18
+   |
+LL |     format!("{0} {1}", 1);
+   |                  ^^^
+   |
+   = note: positional arguments are zero-based
+
+error: invalid reference to positional argument 2 (there are 2 arguments)
+  --> $DIR/ifmt-bad-arg.rs:29:22
+   |
+LL |     format!("{0} {1} {2}", 1, 2);
+   |                      ^^^
+   |
+   = note: positional arguments are zero-based
+
+error: invalid reference to positional argument 2 (there are 2 arguments)
+  --> $DIR/ifmt-bad-arg.rs:32:28
+   |
+LL |     format!("{} {value} {} {}", 1, value=2);
+   |                            ^^
+   |
+   = note: positional arguments are zero-based
+
+error: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments)
+  --> $DIR/ifmt-bad-arg.rs:34:38
+   |
+LL |     format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
+   |                                      ^^ ^^ ^^
+   |
+   = note: positional arguments are zero-based
+
+error: there is no argument named `foo`
+  --> $DIR/ifmt-bad-arg.rs:37:17
+   |
+LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
+   |                 ^^^^^
+
+error: there is no argument named `bar`
+  --> $DIR/ifmt-bad-arg.rs:37:26
+   |
+LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
+   |                          ^^^^^
+
+error: there is no argument named `foo`
+  --> $DIR/ifmt-bad-arg.rs:41:14
+   |
+LL |     format!("{foo}");                //~ ERROR: no argument named `foo`
+   |              ^^^^^
+
+error: multiple unused formatting arguments
+  --> $DIR/ifmt-bad-arg.rs:42:17
+   |
+LL |     format!("", 1, 2);               //~ ERROR: multiple unused formatting arguments
+   |             --  ^  ^
+   |             |
+   |             multiple missing formatting specifiers
+
+error: argument never used
+  --> $DIR/ifmt-bad-arg.rs:43:22
+   |
+LL |     format!("{}", 1, 2);             //~ ERROR: argument never used
+   |             ----     ^
+   |             |
+   |             formatting specifier missing
+
+error: argument never used
+  --> $DIR/ifmt-bad-arg.rs:44:20
+   |
+LL |     format!("{1}", 1, 2);            //~ ERROR: argument never used
+   |             -----  ^
+   |             |
+   |             formatting specifier missing
+
+error: named argument never used
+  --> $DIR/ifmt-bad-arg.rs:45:26
+   |
+LL |     format!("{}", 1, foo=2);         //~ ERROR: named argument never used
+   |             ----         ^
+   |             |
+   |             formatting specifier missing
+
+error: argument never used
+  --> $DIR/ifmt-bad-arg.rs:46:22
+   |
+LL |     format!("{foo}", 1, foo=2);      //~ ERROR: argument never used
+   |             -------  ^
+   |             |
+   |             formatting specifier missing
+
+error: named argument never used
+  --> $DIR/ifmt-bad-arg.rs:47:21
+   |
+LL |     format!("", foo=2);              //~ ERROR: named argument never used
+   |             --      ^
+   |             |
+   |             formatting specifier missing
+
+error: multiple unused formatting arguments
+  --> $DIR/ifmt-bad-arg.rs:48:32
+   |
+LL |     format!("{} {}", 1, 2, foo=1, bar=2);  //~ ERROR: multiple unused formatting arguments
+   |             -------            ^      ^
+   |             |
+   |             multiple missing formatting specifiers
+
+error: duplicate argument named `foo`
+  --> $DIR/ifmt-bad-arg.rs:50:33
+   |
+LL |     format!("{foo}", foo=1, foo=2);  //~ ERROR: duplicate argument
+   |                                 ^
+   |
+note: previously here
+  --> $DIR/ifmt-bad-arg.rs:50:26
+   |
+LL |     format!("{foo}", foo=1, foo=2);  //~ ERROR: duplicate argument
+   |                          ^
+
+error: expected ident, positional arguments cannot follow named arguments
+  --> $DIR/ifmt-bad-arg.rs:51:24
+   |
+LL |     format!("", foo=1, 2);           //~ ERROR: positional arguments cannot follow
+   |                        ^
+
+error: there is no argument named `valueb`
+  --> $DIR/ifmt-bad-arg.rs:55:23
+   |
+LL |     format!("{valuea} {valueb}", valuea=5, valuec=7);
+   |                       ^^^^^^^^
+
+error: named argument never used
+  --> $DIR/ifmt-bad-arg.rs:55:51
+   |
+LL |     format!("{valuea} {valueb}", valuea=5, valuec=7);
+   |             -------------------                   ^
+   |             |
+   |             formatting specifier missing
+
+error: invalid format string: expected `'}'` but string was terminated
+  --> $DIR/ifmt-bad-arg.rs:61:15
+   |
+LL |     format!("{"); //~ ERROR: expected `'}'` but string was terminated
+   |               ^ expected `'}'` in format string
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: unmatched `}` found
+  --> $DIR/ifmt-bad-arg.rs:63:18
+   |
+LL |     format!("foo } bar"); //~ ERROR: unmatched `}` found
+   |                  ^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+
+error: invalid format string: unmatched `}` found
+  --> $DIR/ifmt-bad-arg.rs:64:18
+   |
+LL |     format!("foo }"); //~ ERROR: unmatched `}` found
+   |                  ^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+
+error: argument never used
+  --> $DIR/ifmt-bad-arg.rs:66:27
+   |
+LL |     format!("foo %s baz", "bar"); //~ ERROR: argument never used
+   |                  --       ^^^^^
+   |                  |
+   |                  help: format specifiers use curly braces: `{}`
+   |
+   = note: printf formatting not supported; see the documentation for `std::fmt`
+
+error: there is no argument named `foo`
+  --> $DIR/ifmt-bad-arg.rs:70:9
+   |
+LL |         {foo}
+   |         ^^^^^
+
+error: aborting due to 27 previous errors
+
diff --git a/src/test/ui/impl-trait/existential_type_in_fn_body.rs b/src/test/ui/impl-trait/existential_type_in_fn_body.rs
new file mode 100644 (file)
index 0000000..20f9e0d
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// compile-pass
+
+#![feature(existential_type)]
+
+use std::fmt::Debug;
+
+fn main() {
+    existential type Existential: Debug;
+
+    fn f() -> Existential {}
+    println!("{:?}", f());
+}
index 09cbfe4f66daa3aaaae4d49fd735851fbd85a6ae..6eb2765514054d15f2e0eddbd297ecb495f193c4 100644 (file)
@@ -5,7 +5,7 @@ LL |     let bb: &B = &*b;    //~ ERROR does not live long enough
    |                  ^^^ borrowed value does not live long enough
 LL |     make_a(bb)
 LL | }
-   | - borrowed value only lives until here
+   | - `*b` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 36:16...
   --> $DIR/issue-12470.rs:36:16
diff --git a/src/test/ui/issue-13497-2.nll.stderr b/src/test/ui/issue-13497-2.nll.stderr
new file mode 100644 (file)
index 0000000..5c592f6
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0597]: `rawLines` does not live long enough
+  --> $DIR/issue-13497-2.rs:13:5
+   |
+LL |     rawLines //~ ERROR `rawLines` does not live long enough
+   |     ^^^^^^^^ borrowed value does not live long enough
+LL |         .iter().map(|l| l.trim()).collect()
+LL | }
+   | - `rawLines` dropped here while still borrowed
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 11:24...
+  --> $DIR/issue-13497-2.rs:11:24
+   |
+LL | fn read_lines_borrowed<'a>() -> Vec<&'a str> {
+   |                        ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
index f731e8eeae67f191ec8475ffc6cbb7d47cf97b48..5cab7ca9e7a3fa6d7e6d405194923c3d9103327e 100644 (file)
@@ -5,7 +5,7 @@ LL |     let a = &FOO;
    |             ^^^^ borrowed value does not live long enough
 ...
 LL | }
-   | - borrowed value only lives until here
+   | - `FOO` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index f731e8eeae67f191ec8475ffc6cbb7d47cf97b48..5cab7ca9e7a3fa6d7e6d405194923c3d9103327e 100644 (file)
@@ -5,7 +5,7 @@ LL |     let a = &FOO;
    |             ^^^^ borrowed value does not live long enough
 ...
 LL | }
-   | - borrowed value only lives until here
+   | - `FOO` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index 4211057610bc7ebf60e5ae3f805b330209eda5c2..b5e550e5be1c9d963a3a7483d86dbc19523a19d3 100644 (file)
@@ -29,5 +29,5 @@ fn main() {
         println!("{}", a);
     });
 }
-//[mir]~^ borrowed value only lives until here
+//[mir]~^ `FOO` dropped here while still borrowed
 //[ast]~^^ temporary value only lives until here
index 7acab8426f62b23bf1251971c9524b3c3cbe5371..860359b5937cc15634ab505f6483fc7a35649dcc 100644 (file)
@@ -57,7 +57,7 @@ LL |         &p //~ ERROR `p` does not live long enough
    |         ^^ borrowed value does not live long enough
 LL |         //~^ ERROR let bindings in constants are unstable
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `p` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index 0bfac131e224d3c90d8edd03e9933c4750e9462c..28e63b2d36b114bc6d6b7cd545d0e1da65a316b4 100644 (file)
@@ -5,7 +5,7 @@ LL |     &x
    |     ^^ borrowed value does not live long enough
 LL |     //~^ ERROR: `x` does not live long enough
 LL | }
-   | - borrowed value only lives until here
+   | - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'y as defined on the function body at 17:10...
   --> $DIR/issue-30438-c.rs:17:10
diff --git a/src/test/ui/issue-42060.rs b/src/test/ui/issue-42060.rs
new file mode 100644 (file)
index 0000000..23df42d
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+fn main() {
+    let thing = ();
+    let other: typeof(thing) = thing; //~ ERROR attempt to use a non-constant value in a constant
+    //~^ ERROR `typeof` is a reserved keyword but unimplemented [E0516]
+}
+
+fn f(){
+    let q = 1;
+    <typeof(q)>::N //~ ERROR attempt to use a non-constant value in a constant
+    //~^ ERROR `typeof` is a reserved keyword but unimplemented [E0516]
+}
+
diff --git a/src/test/ui/issue-42060.stderr b/src/test/ui/issue-42060.stderr
new file mode 100644 (file)
index 0000000..69abac8
--- /dev/null
@@ -0,0 +1,28 @@
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/issue-42060.rs:13:23
+   |
+LL |     let other: typeof(thing) = thing; //~ ERROR attempt to use a non-constant value in a constant
+   |                       ^^^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/issue-42060.rs:19:13
+   |
+LL |     <typeof(q)>::N //~ ERROR attempt to use a non-constant value in a constant
+   |             ^ non-constant value
+
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/issue-42060.rs:13:16
+   |
+LL |     let other: typeof(thing) = thing; //~ ERROR attempt to use a non-constant value in a constant
+   |                ^^^^^^^^^^^^^ reserved keyword
+
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/issue-42060.rs:19:6
+   |
+LL |     <typeof(q)>::N //~ ERROR attempt to use a non-constant value in a constant
+   |      ^^^^^^^^^ reserved keyword
+
+error: aborting due to 4 previous errors
+
+Some errors occurred: E0435, E0516.
+For more information about an error, try `rustc --explain E0435`.
diff --git a/src/test/ui/issue-43196.rs b/src/test/ui/issue-43196.rs
new file mode 100644 (file)
index 0000000..ff53c9a
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 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.
+
+fn main() {
+    |
+}
+//~^ ERROR expected `|`, found `}`
+|
+//~^ ERROR expected item, found `|`
+
diff --git a/src/test/ui/issue-43196.stderr b/src/test/ui/issue-43196.stderr
new file mode 100644 (file)
index 0000000..2418f51
--- /dev/null
@@ -0,0 +1,16 @@
+error: expected `|`, found `}`
+  --> $DIR/issue-43196.rs:13:1
+   |
+LL |     |
+   |      - expected `|` here
+LL | }
+   | ^ unexpected token
+
+error: expected item, found `|`
+  --> $DIR/issue-43196.rs:15:1
+   |
+LL | |
+   | ^ expected item
+
+error: aborting due to 2 previous errors
+
index eacd8b5e58047878ddf102835b172c4edb859809..40d7838a8032519573159508158cdca96ab6305f 100644 (file)
@@ -11,7 +11,7 @@ LL |     id(Box::new(|| *v))
    |                 ^^^^^ borrowed value does not live long enough
 ...
 LL | }
-   | - borrowed value only lives until here
+   | - `v` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'r as defined on the function body at 15:6...
   --> $DIR/issue-4335.rs:15:6
index e0df49f582338ec5b1856b7d5e94a1cde8aad0d4..463abaede88f9315d3f886e1e5f8638bd7850ff5 100644 (file)
@@ -5,7 +5,7 @@ LL |     let foo = Foo { x: &a }; //~ ERROR E0597
    |                        ^^ borrowed value does not live long enough
 LL |     loop { }
 LL | }
-   | - borrowed value only lives until here
+   | - `a` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index 0108056bc7278265ae61aba0d7c536908bfcd6d8..7d12827dda5d2e958d9a4d2339749af16d4a21df 100644 (file)
@@ -20,7 +20,7 @@ LL | |         &mut z
 LL | |     };
    | |     -
    | |     |
-   | |_____borrowed value only lives until here
+   | |_____`z` dropped here while still borrowed
    |       borrow later used here
 
 error: aborting due to 2 previous errors
index ac974afa13a1e5b432e5c60cceb98a7282de71a4..560c341b4df051606a804be229d743b8d14957fe 100644 (file)
@@ -16,7 +16,7 @@ LL |     &x
    |     ^^ borrowed value does not live long enough
 ...
 LL | }
-   | - borrowed value only lives until here
+   | - `x` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index dcca491a87bb4aae390a8473d9384e1d8f793425..ccbb852b1457484b78f384873994876c539a1f7b 100644 (file)
@@ -8,7 +8,7 @@ LL |         println!("accumulator before add_assign {:?}", acc.map);
    |                                                        ------- borrow later used here
 ...
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `line` dropped here while still borrowed
 
 error: aborting due to previous error
 
index ec0eaed43aea650c3cde1f89c108152a3ce452ca..33401424c9ada42cce9be51c6bc30d09e617e7fb 100644 (file)
 fn main() {
     println!("%.*3$s %s!\n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
     println!("%1$*2$.*3$f", 123.456); //~ ERROR never used
+    println!(r###"%.*3$s
+        %s!\n
+"###, "Hello,", "World", 4);
+    //~^ ERROR multiple unused formatting arguments
+    // correctly account for raw strings in inline suggestions
 
     // This should *not* produce hints, on the basis that there's equally as
     // many "correct" format specifiers.  It's *probably* just an actual typo.
index 401b2f6d67e399c8d52f2328f45dfb966af0ccb1..5e76c0a322e51b941296762b1e793191c4112ba8 100644 (file)
@@ -4,29 +4,52 @@ error: multiple unused formatting arguments
 LL |     println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
    |              --------------  ^^^^^^^^  ^^^^^^^  ^
    |              |
-   |              multiple missing formatting arguments
+   |              multiple missing formatting specifiers
    |
-   = help: `%.*3$s` should be written as `{:.2$}`
-   = help: `%s` should be written as `{}`
    = note: printf formatting not supported; see the documentation for `std::fmt`
+help: format specifiers use curly braces
+   |
+LL |     println!("{:.2$} {}!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
+   |               ^^^^^^ ^^
 
 error: argument never used
   --> $DIR/format-foreign.rs:13:29
    |
 LL |     println!("%1$*2$.*3$f", 123.456); //~ ERROR never used
-   |                             ^^^^^^^
+   |               -----------   ^^^^^^^
+   |               |
+   |               help: format specifiers use curly braces: `{0:1$.2$}`
    |
-   = help: `%1$*2$.*3$f` should be written as `{0:1$.2$}`
    = note: printf formatting not supported; see the documentation for `std::fmt`
 
+error: multiple unused formatting arguments
+  --> $DIR/format-foreign.rs:16:7
+   |
+LL |       println!(r###"%.*3$s
+   |  ______________-
+LL | |         %s!/n
+LL | | "###, "Hello,", "World", 4);
+   | |    -  ^^^^^^^^  ^^^^^^^  ^
+   | |____|
+   |      multiple missing formatting specifiers
+   |
+   = note: printf formatting not supported; see the documentation for `std::fmt`
+help: format specifiers use curly braces
+   |
+LL |     println!(r###"{:.2$}
+LL |         {}!/n
+   |
+
 error: argument never used
-  --> $DIR/format-foreign.rs:17:30
+  --> $DIR/format-foreign.rs:22:30
    |
 LL |     println!("{} %f", "one", 2.0); //~ ERROR never used
-   |                              ^^^
+   |              -------         ^^^
+   |              |
+   |              formatting specifier missing
 
 error: named argument never used
-  --> $DIR/format-foreign.rs:19:39
+  --> $DIR/format-foreign.rs:24:39
    |
 LL |     println!("Hi there, $NAME.", NAME="Tim"); //~ ERROR never used
    |                                       ^^^^^
@@ -34,5 +57,5 @@ LL |     println!("Hi there, $NAME.", NAME="Tim"); //~ ERROR never used
    = help: `$NAME` should be written as `{NAME}`
    = note: shell formatting not supported; see the documentation for `std::fmt`
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
index f764190438f3355c54e38f3b11cfb2a5fb349fe4..81171a1ed01de5dfe035f8ab353e727ba8b2300a 100644 (file)
@@ -4,13 +4,13 @@ error: multiple unused formatting arguments
 LL |     println!("Test", 123, 456, 789);
    |              ------  ^^^  ^^^  ^^^
    |              |
-   |              multiple missing formatting arguments
+   |              multiple missing formatting specifiers
 
 error: multiple unused formatting arguments
   --> $DIR/format-unused-lables.rs:16:9
    |
 LL |     println!("Test2",
-   |              ------- multiple missing formatting arguments
+   |              ------- multiple missing formatting specifiers
 LL |         123,  //~ ERROR multiple unused formatting arguments
    |         ^^^
 LL |         456,
@@ -22,13 +22,15 @@ error: named argument never used
   --> $DIR/format-unused-lables.rs:21:35
    |
 LL |     println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used
-   |                                   ^^^^^^
+   |              ------------         ^^^^^^
+   |              |
+   |              formatting specifier missing
 
 error: multiple unused formatting arguments
   --> $DIR/format-unused-lables.rs:24:9
    |
 LL |     println!("Some more $STUFF",
-   |              ------------------ multiple missing formatting arguments
+   |              ------------------ multiple missing formatting specifiers
 LL |         "woo!",  //~ ERROR multiple unused formatting arguments
    |         ^^^^^^
 LL |             STUFF=
index 6270e794498766f17fcba58f4b3e8e130e07b981..057cf6efa1dea415fa4e72d11c48419496b4a1eb 100644 (file)
@@ -5,6 +5,10 @@ LL |     [1, 2, 3].sort_by(|| panic!());
    |               ^^^^^^^ -- takes 0 arguments
    |               |
    |               expected closure that takes 2 arguments
+help: consider changing the closure to take and ignore the expected arguments
+   |
+LL |     [1, 2, 3].sort_by(|_, _| panic!());
+   |                       ^^^^^^
 
 error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument
   --> $DIR/closure-arg-count.rs:17:15
@@ -51,6 +55,10 @@ note: required by `f`
    |
 LL | fn f<F: Fn<usize>>(_: F) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the closure to take and ignore the expected argument
+   |
+LL |     f(|_| panic!());
+   |       ^^^
 
 error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
   --> $DIR/closure-arg-count.rs:26:53
index 901b1ca271a5f6ef24b5c82e40c5ded39e3d6717..28353a8bc2be7cd96173b85ba924110d998d6d35 100644 (file)
@@ -10,7 +10,7 @@ LL | |         //~^ ERROR `v` does not live long enough [E0597]
 LL | |     });
    | |_____-- borrow later used here
    |       |
-   |       borrowed value only lives until here
+   |       `v` dropped here while still borrowed
 
 error: aborting due to previous error
 
index ea7d81993844382cd06f14a66af91637b00f7451..867e473af2c0ee2c3ab5fec18c6842455c328993 100644 (file)
@@ -5,7 +5,7 @@ LL |     &v
    |     ^^ borrowed value does not live long enough
 LL |     //~^ ERROR `v` does not live long enough [E0597]
 LL | }
-   | - borrowed value only lives until here
+   | - `v` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:8...
   --> $DIR/borrowed-universal-error-2.rs:14:8
index 81946de612afe34a8c65e6b53349386618c4538a..12a9adf6e0ba67b2dc6593acb4e2acf142027f23 100644 (file)
@@ -5,7 +5,7 @@ LL |             y: &y,
    |                ^^ borrowed value does not live long enough
 ...
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `y` dropped here while still borrowed
 LL | 
 LL |     deref(p);
    |           - borrow later used here
index dba27f16e8cac234111f4735c8e9c9db2086c057..a830768b36e1cd1bd1efefce51034e051c10aa93 100644 (file)
@@ -30,7 +30,7 @@ LL |         closure(&mut p, &y);
    |                         ^^ borrowed value does not live long enough
 LL |         //~^ ERROR `y` does not live long enough [E0597]
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `y` dropped here while still borrowed
 LL | 
 LL |     deref(p);
    |           - borrow later used here
index a7fb9d90a2183d0da5623a26ed1d26969f6cb420..bf12800e58d71ffbcc4679f56e7e9cf8fa6a23d8 100644 (file)
@@ -57,7 +57,7 @@ LL | |         };
    | |_________^ borrowed value does not live long enough
 ...
 LL |       }
-   |       - borrowed value only lives until here
+   |       - `y` dropped here while still borrowed
 LL | 
 LL |       deref(p);
    |             - borrow later used here
index fd6b7a2e68d339488537e8c6c54f749f56db6fac..4b0dad3bda0229c93083e54301c77666ffe15a3d 100644 (file)
@@ -34,7 +34,7 @@ LL |         let mut closure = || p = &y;
    |                           ^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `y` dropped here while still borrowed
 LL | 
 LL |     deref(p);
    |           - borrow later used here
index d51ba8201aaa62a168151c3ab24b0bf4b3393aeb..0295747d529f1a2c3c83a38ed3e80504c414410e 100644 (file)
@@ -82,7 +82,7 @@ LL |     let cell = Cell::new(&a);
    |                          ^^ borrowed value does not live long enough
 ...
 LL | }
-   | - borrowed value only lives until here
+   | - `a` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index 065de6ea600b4eb46116b7989d67679c9f1d1f9c..532bc493e7dbcc0400d8699dc2793c1f2106a49a 100644 (file)
@@ -5,7 +5,7 @@ LL |     let s_inner: &'a S = &*v.0; //~ ERROR `*v.0` does not live long enough
    |                          ^^^^^ borrowed value does not live long enough
 LL |     &s_inner.0
 LL | }
-   | - borrowed value only lives until here
+   | - `*v.0` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 21:17...
   --> $DIR/issue-31567.rs:21:17
index a89e186540a47c74f1f9abf056528e9be4c8352d..e73df61a30371963f3a1dcdea36aab51a4198ca9 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `local` does not live long enough
 LL |         &local //~ ERROR `local` does not live long enough
    |         ^^^^^^ borrowed value does not live long enough
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `local` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the impl at 23:6...
   --> $DIR/issue-47470.rs:23:6
index 443af08e1cc7ccdfe3687fa5e14b271c6e38a7d5..ae7193ef4fa793d44b6a515ff55774f76277ab51 100644 (file)
@@ -5,7 +5,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |      - borrowed value only lives until here
+   |      - `x` dropped here while still borrowed
 
 error[E0597]: `y` does not live long enough
   --> $DIR/region-borrow-params-issue-29793-small.rs:19:17
@@ -14,7 +14,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |      - borrowed value only lives until here
+   |      - `y` dropped here while still borrowed
 
 error[E0597]: `x` does not live long enough
   --> $DIR/region-borrow-params-issue-29793-small.rs:34:17
@@ -23,7 +23,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |      - borrowed value only lives until here
+   |      - `x` dropped here while still borrowed
 
 error[E0597]: `y` does not live long enough
   --> $DIR/region-borrow-params-issue-29793-small.rs:34:17
@@ -32,7 +32,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |      - borrowed value only lives until here
+   |      - `y` dropped here while still borrowed
 
 error[E0597]: `x` does not live long enough
   --> $DIR/region-borrow-params-issue-29793-small.rs:65:17
@@ -41,7 +41,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 64:10...
   --> $DIR/region-borrow-params-issue-29793-small.rs:64:10
@@ -56,7 +56,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 64:10...
   --> $DIR/region-borrow-params-issue-29793-small.rs:64:10
@@ -71,7 +71,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 75:10...
   --> $DIR/region-borrow-params-issue-29793-small.rs:75:10
@@ -86,7 +86,7 @@ LL |         let f = |t: bool| if t { x } else { y }; // (separate errors for `x
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 75:10...
   --> $DIR/region-borrow-params-issue-29793-small.rs:75:10
@@ -101,7 +101,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 99:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:99:14
@@ -116,7 +116,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 99:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:99:14
@@ -131,7 +131,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 113:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:113:14
@@ -146,7 +146,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 113:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:113:14
@@ -161,7 +161,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 141:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:141:14
@@ -176,7 +176,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 141:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:141:14
@@ -191,7 +191,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 156:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:156:14
@@ -206,7 +206,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 156:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:156:14
@@ -221,7 +221,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 184:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:184:14
@@ -236,7 +236,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 184:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:184:14
@@ -251,7 +251,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `x` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 198:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:198:14
@@ -266,7 +266,7 @@ LL |             let f = |t: bool| if t { x } else { y }; // (separate errors fo
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
 LL |         }
-   |         - borrowed value only lives until here
+   |         - `y` dropped here while still borrowed
    |
 note: borrowed value must be valid for the lifetime 'a as defined on the method body at 198:14...
   --> $DIR/region-borrow-params-issue-29793-small.rs:198:14
index 2c973f9bdea5e4683cb55fdf25b3399d393443b9..13e34d85210a785d33d277ec3a68d38aa0df5887 100644 (file)
@@ -7,7 +7,7 @@ LL | |             if false { &y } else { z }
 LL | |         });
    | |_________^ borrowed value does not live long enough
 LL |   }
-   |   - borrowed value only lives until here
+   |   - `y` dropped here while still borrowed
    |
    = note: borrowed value must be valid for the static lifetime...
 
index 8be4cf445da3f77c2261843cd1c3b8a39c445176..22f2f13f1f7cf60db1c8d206de3c0626b22dcb2c 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `*a` does not live long enough
 LL |         *a.borrow() + 1
    |          ^ borrowed value does not live long enough
 LL |     }; //~^ ERROR `*a` does not live long enough
-   |     - borrowed value only lives until here
+   |     - `*a` dropped here while still borrowed
 
 error: aborting due to previous error
 
index b268f6e3ab014ea0c6b368b5384e4465d822b56b..225ed0f9cc832c50b66076604ea79f2190e3a316 100644 (file)
@@ -7,7 +7,7 @@ LL |     assert_eq!(object_invoke1(&*m), (4,5));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `*m` dropped here while still borrowed
    | borrow later used here, when `m` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index cbb9d0429c616350bcf11d035b5a382bf0cfa39d..6c0373ce1570a176a2001345ce741e4f128d2a59 100644 (file)
@@ -7,7 +7,7 @@ LL |     b1.a[1].v.set(Some(&b3));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `b3` dropped here while still borrowed
    | borrow later used here, when `b1` is dropped
 
 error[E0597]: `b2` does not live long enough
@@ -19,7 +19,7 @@ LL |     b1.a[0].v.set(Some(&b2));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `b2` dropped here while still borrowed
    | borrow later used here, when `b1` is dropped
 
 error[E0597]: `b1` does not live long enough
@@ -31,7 +31,7 @@ LL |     b3.a[0].v.set(Some(&b1));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `b1` dropped here while still borrowed
    | borrow later used here, when `b1` is dropped
 
 error: aborting due to 3 previous errors
index 37fffe886e30950cc2882aec517ece53f6b9812a..2884b1818baa9cf23801cd1e28dbc4f393af7543 100644 (file)
@@ -7,7 +7,7 @@ LL |     d1.p.set(Some(&d2));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `d2` dropped here while still borrowed
    | borrow later used here, when `d1` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
@@ -21,7 +21,7 @@ LL |     //~^ ERROR `d1` does not live long enough
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `d1` dropped here while still borrowed
    | borrow later used here, when `d1` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 0eb84e4a7d0b23394a4106bfcf2760787abc0b86..27a52360bb7010f6788f9d6551cffdbe9eb5bc07 100644 (file)
@@ -6,7 +6,7 @@ LL |     _w = Wrap::<&[&str]>(NoisyDrop(&bomb));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `bomb` dropped here while still borrowed
    | borrow later used here, when `_w` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
@@ -20,7 +20,7 @@ LL |         let u = NoisyDrop(&v);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `v` dropped here while still borrowed
    | borrow later used here, when `_w` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 13bd1f54198212077863744198898998f925bef6..c0950e79296784067ecc8d666f505e5c85aa7da6 100644 (file)
@@ -7,7 +7,7 @@ LL |     c1.v[1].v.set(Some(&c3));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c3` dropped here while still borrowed
    | borrow later used here, when `c1` is dropped
 
 error[E0597]: `c2` does not live long enough
@@ -19,7 +19,7 @@ LL |     c1.v[0].v.set(Some(&c2));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c2` dropped here while still borrowed
    | borrow later used here, when `c1` is dropped
 
 error[E0597]: `c1` does not live long enough
@@ -31,7 +31,7 @@ LL |     c3.v[0].v.set(Some(&c1));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c1` dropped here while still borrowed
    | borrow later used here, when `c1` is dropped
 
 error: aborting due to 3 previous errors
index 68a4d5d25f424df093fb1541d02b9a24d71684b7..e841e6c635bc31aedf064d36f11b50ac3500802c 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `x` does not live long enough
 LL |         let f = to_fn_once(move|| &x); //~ ERROR does not live long enough
    |                                   ^-
    |                                   ||
-   |                                   |borrowed value only lives until here
+   |                                   |`x` dropped here while still borrowed
    |                                   borrowed value does not live long enough
 
 error: aborting due to previous error
index ec2f5a25631c4aedb4748dbde77c01a39c9e5190..fe0187f38637898f045a56766ae14cb0bfee185f 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `y` does not live long enough
 LL |     y.borrow().clone()
    |     ^ borrowed value does not live long enough
 LL | }
-   | - borrowed value only lives until here
+   | - `y` dropped here while still borrowed
 
 error[E0597]: `y` does not live long enough
   --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:27:9
@@ -12,7 +12,7 @@ error[E0597]: `y` does not live long enough
 LL |         y.borrow().clone()
    |         ^ borrowed value does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `y` dropped here while still borrowed
 
 error: aborting due to 2 previous errors
 
index ec1df8aeca15a312d1b6c4f9f6c90d7e014dd29a..b9834a3d4379e550b95321da5bcac9c68be8f405 100644 (file)
@@ -7,7 +7,7 @@ LL |     _d = D_Child(&d1);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `d1` dropped here while still borrowed
    | borrow later used here, when `_d` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 288c196b27b2df2413bf402aaa644ceacc0722f8..cd3d658aa8726eea3ba8f555cb0eee02e223efe4 100644 (file)
@@ -6,7 +6,7 @@ LL |     _d = D_HasSelfMethod(&d1);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `d1` dropped here while still borrowed
    | borrow later used here, when `_d` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
@@ -19,7 +19,7 @@ LL |     _d = D_HasMethodWithSelfArg(&d1);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `d1` dropped here while still borrowed
    | borrow later used here, when `_d` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
@@ -32,7 +32,7 @@ LL |     _d = D_HasType(&d1);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `d1` dropped here while still borrowed
    | borrow later used here, when `_d` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index c89e68bcd0ae06f0ef10d18f705dbcb17b898133..54c6ac43f347c33d93de70cf2624529f449cb7b1 100644 (file)
@@ -6,7 +6,7 @@ LL |     d2 = D(S(&d1, "inner"), "d2");
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `d1` dropped here while still borrowed
    | borrow later used here, when `d2` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 770fed8cd9cc9341c4aaabd1f556ed89c24fb231..a81b591d288eb234a93e9ab67851d73638385da6 100644 (file)
@@ -7,7 +7,7 @@ LL |     let test = Test{test: &container};
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `container` dropped here while still borrowed
    | borrow later used here, when `container` is dropped
 
 error: aborting due to previous error
index bea6dc6b3f6a06d4a46af3c71b755bb1eab14301..b6c28828120880ea36de2937eeda12862e16edc4 100644 (file)
@@ -6,7 +6,7 @@ LL |     zook.button = B::BigRedButton(&ticking);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `ticking` dropped here while still borrowed
    | borrow later used here, when `zook` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 80a7421f4bd20b7172bc98d3e775e389ff534908..2cf408d097b837b382c43a8927a98d77bb9fca77 100644 (file)
@@ -6,7 +6,7 @@ LL |         y = Arc::new(Foo(&x));
 LL |     }
    |     -
    |     |
-   |     borrowed value only lives until here
+   |     `x` dropped here while still borrowed
    |     borrow later used here, when `y` is dropped
 
 error[E0597]: `x` does not live long enough
@@ -17,7 +17,7 @@ LL |         y = Rc::new(Foo(&x));
 LL |     }
    |     -
    |     |
-   |     borrowed value only lives until here
+   |     `x` dropped here while still borrowed
    |     borrow later used here, when `y` is dropped
 
 error: aborting due to 2 previous errors
index a3b8a3e766bbfb7c01ffe4674bd815a64aadd949..0d13c9844b331377c98db5622e0c46a8b67ae716 100644 (file)
@@ -5,7 +5,7 @@ LL |         p = &a;
    |         ^^^^^^ borrowed value does not live long enough
 ...
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `a` dropped here while still borrowed
 LL |     p.use_ref();
    |     - borrow later used here
 
index d9608f3a8963005e343e82a8cbd73cdba77de653..def4a308bc75efac4ab5f0088faf6dc3104f750f 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `foo` does not live long enough
 LL |     {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });}
    |                       ------------------------------^^^--------------------
    |                       |                             |          |
-   |                       |                             |          borrowed value only lives until here
+   |                       |                             |          `foo` dropped here while still borrowed
    |                       |                             borrowed value does not live long enough
    |                       borrow later used here
 
index 3ed13f2653ccd769a884f130c206acfe0de6fb32..27eb4a3afed6d90decde00d95696e01fcf0bac0d 100644 (file)
@@ -7,7 +7,7 @@ LL |     foo.data[0].1.set(Some(&foo.data[1]));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `foo.data` dropped here while still borrowed
    | borrow later used here, when `foo` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index ce9e75b44831874efa2cb710545b4d6490ffc134..72acc54bffb321468473a4ffb1a2a0c488cf7898 100644 (file)
@@ -7,7 +7,7 @@ LL |     foo1 = Foo(1, &first_dropped);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `first_dropped` dropped here while still borrowed
    | borrow later used here, when `foo1` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index fcdc1c3f9452de27eb491f269f1328bde8f90180..a39050a5199117d7ae8273ffabe77a99b2ce536b 100644 (file)
@@ -7,7 +7,7 @@ LL |     foo1 = Foo(1, &first_dropped, Box::new(callback));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `first_dropped` dropped here while still borrowed
    | borrow later used here, when `foo1` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 6300bb3eacd643821b1c92e8c773964651ac3bdc..fcffea25702b92b23544da0303d61e8a1ca3fc55 100644 (file)
@@ -7,7 +7,7 @@ LL |     foo1 = Foo(1, &first_dropped);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `first_dropped` dropped here while still borrowed
    | borrow later used here, when `foo1` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index a99ff9e272619110a708e131294c70ac7e083a45..e5139dca351a6295c42a69af281702a5e05b715b 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `b` does not live long enough
 LL |         p = &*b;
    |               ^ borrowed value does not live long enough
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `b` dropped here while still borrowed
 LL |     //~^^ ERROR `b` does not live long enough
 LL |     p.use_ref();
    |     - borrow later used here
index aff1fededbb3c4a5d0ac8cebf5dc1a27abd84725..049618fe4744bbc618dc5329dd26dbd4b5581c12 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `b` does not live long enough
 LL |         &a..&b
    |             ^^ borrowed value does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `b` dropped here while still borrowed
 ...
 LL |     r.use_ref();
    |     - borrow later used here
@@ -15,7 +15,7 @@ error[E0597]: `a` does not live long enough
 LL |         &a..&b
    |         ^^ borrowed value does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `a` dropped here while still borrowed
 ...
 LL |     r.use_ref();
    |     - borrow later used here
index 71e02af1f845fe82abd1f7b6498f79ea1fde2069..4881259ff23abb30bc4cbaf2da5031d9d9206460 100644 (file)
@@ -5,7 +5,7 @@ LL |         let c_ref = &c;
    |                     ^^ borrowed value does not live long enough
 ...
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `c` dropped here while still borrowed
 LL |     f.use_mut();
    |     - borrow later used here
 
index c8a1f801201489dc58324d3b0ed2d82b3bfa5134..f522521b400e405faec70ce4842488266a36b494 100644 (file)
@@ -10,7 +10,7 @@ LL | |         repeater3(tmp1)
 LL | |     };
    | |     -
    | |     |
-   | |_____borrowed value only lives until here
+   | |_____`tmp0` dropped here while still borrowed
    |       borrow later used here
 
 error: aborting due to previous error
index 7fd2bfbdd8f9745e4cbcab5048f25a8955690aa6..08ca100c247dc16d2b083ea0f7e54ddfb1063f7c 100644 (file)
@@ -6,7 +6,7 @@ LL |         let x = 1 + *p;
 LL |         p = &x;
    |             ^^ borrowed value does not live long enough
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `x` dropped here while still borrowed
 
 error: aborting due to previous error
 
index c7aa40f18e36a8315b89aa73a9e8173e0454947a..33fca7fa703b0589fc5282e55f98c116d00eefe3 100644 (file)
@@ -41,7 +41,7 @@ LL |         _y.push(&mut z);
    |         borrow later used here
 ...
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `z` dropped here while still borrowed
 
 error: aborting due to 4 previous errors
 
index 034f80c7d54af7d87b52464c222604962f0c9475..5fa25ae8506e6d092a38c20af46d22cbef6742c7 100644 (file)
@@ -5,7 +5,7 @@ LL |         y = borrow(&*x);
    |                    ^^^ borrowed value does not live long enough
 ...
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `*x` dropped here while still borrowed
 LL |     assert!(*y != 0);
    |             -- borrow later used here
 
index 710b19e193264e508b4b4c0fafb55edf5bb542cf..7f7217b8004a6338709027816597c38c07d48d31 100644 (file)
@@ -8,7 +8,7 @@ LL | |             //~^ ERROR `y` does not live long enough
 LL | |         })
    | |_________^ borrowed value does not live long enough
 LL |       };
-   |       - borrowed value only lives until here
+   |       - `y` dropped here while still borrowed
 LL | 
 LL |       bad.join();
    |       --- borrow later used here
@@ -20,7 +20,7 @@ LL |         let y = &x;
    |                 ^^ borrowed value does not live long enough
 ...
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `x` dropped here while still borrowed
 LL | 
 LL |     bad.join();
    |     --- borrow later used here
index e794f8c27e854e11a9ea295b6681443e4561d12a..58dad753ac4a16041cec864287eb65cd278acf0c 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `x` does not live long enough
 LL |         Mutex::new(&x)
    |                    ^^ borrowed value does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `x` dropped here while still borrowed
 ...
 LL |     let _dangling = *lock.lock().unwrap();
    |                      ---- borrow later used here
@@ -15,7 +15,7 @@ error[E0597]: `x` does not live long enough
 LL |         RwLock::new(&x)
    |                     ^^ borrowed value does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `x` dropped here while still borrowed
 LL |     //~^^ ERROR `x` does not live long enough
 LL |     let _dangling = *lock.read().unwrap();
    |                      ---- borrow later used here
@@ -30,7 +30,7 @@ LL |         let _ = tx.send(&x);
    |                         ^^ borrowed value does not live long enough
 LL |         (tx, rx)
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `x` dropped here while still borrowed
 
 error: aborting due to 3 previous errors
 
index 6ebbf3e1ec4d22017d985637808dbe699648179d..878ae36386371e884198de18717031aa84d74094 100644 (file)
@@ -15,7 +15,7 @@ error[E0597]: `z` does not live long enough
 LL |         *lock.lock().unwrap() = &z;
    |                                 ^^ borrowed value does not live long enough
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `z` dropped here while still borrowed
 LL |     //~^^ ERROR `z` does not live long enough
 LL |     lock.use_ref(); // (Mutex is #[may_dangle] so its dtor does not use `z` => needs explicit use)
    |     ---- borrow later used here
@@ -37,7 +37,7 @@ error[E0597]: `z` does not live long enough
 LL |         *lock.write().unwrap() = &z;
    |                                  ^^ borrowed value does not live long enough
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `z` dropped here while still borrowed
 LL |     //~^^ ERROR `z` does not live long enough
 LL |     lock.use_ref(); // (RwLock is #[may_dangle] so its dtor does not use `z` => needs explicit use)
    |     ---- borrow later used here
@@ -59,7 +59,7 @@ error[E0597]: `z` does not live long enough
 LL |         tx.send(&z).unwrap();
    |                 ^^ borrowed value does not live long enough
 LL |     }
-   |     - borrowed value only lives until here
+   |     - `z` dropped here while still borrowed
 ...
 LL | }
    | - borrow later used here, when `tx` is dropped
index 100b4c1292f44ad73c36be2c8ea02c36fb600d69..ee51304800d3264dcff930fe25a774f7fa98dcd4 100644 (file)
@@ -7,7 +7,7 @@ LL |     c1.v[0].v.set(Some(&c2));
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c2` dropped here while still borrowed
    | borrow later used here, when `c1` is dropped
 
 error[E0597]: `c1` does not live long enough
@@ -19,7 +19,7 @@ LL |     //~^ ERROR `c1` does not live long enough
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `c1` dropped here while still borrowed
    | borrow later used here, when `c1` is dropped
 
 error: aborting due to 2 previous errors
index 9d89fac08ffe2eb0a8c7c5596065e27897c34470..73256b4fb17c9e6ec66d32c02cf59f1e5ba2d742 100644 (file)
@@ -7,7 +7,7 @@ LL |     v.push(&y);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `y` dropped here while still borrowed
    | borrow later used here, when `v` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
@@ -21,7 +21,7 @@ LL |     v.push(&x);
 LL | }
    | -
    | |
-   | borrowed value only lives until here
+   | `x` dropped here while still borrowed
    | borrow later used here, when `v` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
index 063ac376b05ecc43f9e08ed87345336f6e4deeee..cc32eaaa9799121650b389d6f458396411e32d95 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `pointer` does not live long enough
 LL |         f2.xmute(&pointer)
    |                  ^^^^^^^^ borrowed value does not live long enough
 LL |     };
-   |     - borrowed value only lives until here
+   |     - `pointer` dropped here while still borrowed
 LL |     //~^^ ERROR `pointer` does not live long enough
 LL |     println!("{}", dangling);
    |                    -------- borrow later used here
index edab2a5ec034c15511349c0c86635c4a535c8805..eeb280e1de36cbd62f54dc9c981ba78bd96c0089 100644 (file)
@@ -392,11 +392,6 @@ fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
 
             if let Some(code) = config.parse_failure_status(ln) {
                 self.failure_status = code;
-            } else {
-                self.failure_status = match config.mode {
-                    Mode::RunFail => 101,
-                    _ => 1,
-                };
             }
 
             if !self.run_rustfix {
@@ -404,6 +399,13 @@ fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
             }
         });
 
+        if self.failure_status == -1 {
+            self.failure_status = match config.mode {
+                Mode::RunFail => 101,
+                _ => 1,
+            };
+        }
+
         for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
             if let Ok(val) = env::var(key) {
                 if self.exec_env.iter().find(|&&(ref x, _)| x == key).is_none() {