Skip to content

Commit

Permalink
Auto merge of #52735 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
Rollup of 16 pull requests

Successful merges:

 - #52558 (Add tests for ICEs which no longer repro)
 - #52610 (Clarify what a task is)
 - #52617 (Don't match on region kinds when reporting NLL errors)
 - #52635 (Fix #[linkage] propagation though generic functions)
 - #52647 (Suggest to take and ignore args while closure args count mismatching)
 - #52649 (Point spans to inner elements of format strings)
 - #52654 (Format linker args in a way that works for gcc and ld)
 - #52667 (update the stdsimd submodule)
 - #52674 (Impl Executor for Box<E: Executor>)
 - #52690 (ARM: expose `rclass` and `dsp` target features)
 - #52692 (Improve readability in a few sorts)
 - #52695 (Hide some lints which are not quite right the way they are reported to the user)
 - #52718 (State default capacity for BufReader/BufWriter)
 - #52721 (std::ops::Try impl for std::task::Poll)
 - #52723 (rustc: Register crates under their real names)
 - #52734 (sparc ABI issue - structure returning from function is returned in 64bit registers (with tests))

Failed merges:

 - #52678 ([NLL] Use better spans in some errors)

r? @ghost
  • Loading branch information
bors committed Jul 26, 2018
2 parents bfbf837 + 995d719 commit 45b48b9
Show file tree
Hide file tree
Showing 109 changed files with 1,355 additions and 436 deletions.
15 changes: 14 additions & 1 deletion src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ use core::marker::{Unpin, Unsize};
use core::mem::{self, PinMut};
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
use core::ptr::{self, NonNull, Unique};
use core::task::{Context, Poll};
use core::task::{Context, Poll, Executor, SpawnErrorKind, SpawnObjError};

use raw_vec::RawVec;
use str::from_boxed_utf8_unchecked;
Expand Down Expand Up @@ -972,6 +972,19 @@ unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox<F>
}
}

#[unstable(feature = "futures_api", issue = "50547")]
impl<E> Executor for Box<E>
where E: Executor + ?Sized
{
fn spawn_obj(&mut self, task: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
(**self).spawn_obj(task)
}

fn status(&self) -> Result<(), SpawnErrorKind> {
(**self).status()
}
}

#[unstable(feature = "futures_api", issue = "50547")]
impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
fn from(boxed: PinBox<F>) -> Self {
Expand Down
30 changes: 18 additions & 12 deletions src/libcore/task/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,27 @@ use future::{FutureObj, LocalFutureObj};

/// 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
///
Expand Down Expand Up @@ -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
Expand All @@ -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, ()>,
}
54 changes: 54 additions & 0 deletions src/libcore/task/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
reason = "futures in libcore are unstable",
issue = "50547")]

use ops::Try;
use result::Result;

/// Indicates whether a value is available or if the current task has been
/// scheduled to receive a wakeup instead.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down Expand Up @@ -39,6 +42,7 @@ impl<T> Poll<T> {
}

/// Returns whether this is `Poll::Ready`
#[inline]
pub fn is_ready(&self) -> bool {
match *self {
Poll::Ready(_) => true,
Expand All @@ -47,6 +51,7 @@ impl<T> Poll<T> {
}

/// Returns whether this is `Poll::Pending`
#[inline]
pub fn is_pending(&self) -> bool {
!self.is_ready()
}
Expand Down Expand Up @@ -81,3 +86,52 @@ impl<T> From<T> for Poll<T> {
Poll::Ready(t)
}
}

impl<T, E> Try for Poll<Result<T, E>> {
type Ok = Poll<T>;
type Error = E;

#[inline]
fn into_result(self) -> Result<Self::Ok, Self::Error> {
match self {
Poll::Ready(Ok(x)) => Ok(Poll::Ready(x)),
Poll::Ready(Err(e)) => Err(e),
Poll::Pending => Ok(Poll::Pending),
}
}

#[inline]
fn from_error(e: Self::Error) -> Self {
Poll::Ready(Err(e))
}

#[inline]
fn from_ok(x: Self::Ok) -> Self {
x.map(Ok)
}
}

impl<T, E> Try for Poll<Option<Result<T, E>>> {
type Ok = Poll<Option<T>>;
type Error = E;

#[inline]
fn into_result(self) -> Result<Self::Ok, Self::Error> {
match self {
Poll::Ready(Some(Ok(x))) => Ok(Poll::Ready(Some(x))),
Poll::Ready(Some(Err(e))) => Err(e),
Poll::Ready(None) => Ok(Poll::Ready(None)),
Poll::Pending => Ok(Poll::Pending),
}
}

#[inline]
fn from_error(e: Self::Error) -> Self {
Poll::Ready(Some(Err(e)))
}

#[inline]
fn from_ok(x: Self::Ok) -> Self {
x.map(|x| x.map(Ok))
}
}
18 changes: 14 additions & 4 deletions src/libfmt_macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -168,9 +170,13 @@ impl<'a> Iterator for Parser<'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))
}
}
'}' => {
Expand Down Expand Up @@ -211,6 +217,7 @@ impl<'a> Parser<'a> {
curarg: 0,
style,
seen_newlines: 0,
arg_places: vec![],
}
}

Expand Down Expand Up @@ -271,20 +278,22 @@ impl<'a> Parser<'a> {

/// 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);

let padding = raw + self.seen_newlines;
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);
Expand All @@ -302,6 +311,7 @@ impl<'a> Parser<'a> {
} else {
self.err(msg, format!("expected `{:?}`", c), pos, pos);
}
None
}
}

Expand Down
24 changes: 24 additions & 0 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,30 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
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()
Expand Down
36 changes: 19 additions & 17 deletions src/librustc_codegen_llvm/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,24 +218,26 @@ impl<'a> GccLinker<'a> {
}

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); }
fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); }
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) {
Expand All @@ -253,23 +255,22 @@ impl<'a> Linker for GccLinker<'a> {
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");
Expand All @@ -294,8 +295,7 @@ impl<'a> Linker for GccLinker<'a> {
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
Expand Down Expand Up @@ -369,7 +369,8 @@ impl<'a> Linker for GccLinker<'a> {
// 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);
}
Expand Down Expand Up @@ -448,7 +449,8 @@ impl<'a> Linker for GccLinker<'a> {
}

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 {
Expand Down
Loading

0 comments on commit 45b48b9

Please sign in to comment.