Auto merge of #53150 - kennytm:rollup, r=kennytm

Rollup of 10 pull requests

Successful merges:

 - #52885 (Remove some unused method arguments from typeck)
 - #52886 (cleanup: Remove `Def::GlobalAsm`)
 - #53028 (Building librustc_codegen_llvm in a separate directory)
 - #53052 (fixed broken links to char)
 - #53060 (Change rustdoc style so fully qualified name does not overlap src link)
 - #53068 (Rename Executor trait to Spawn)
 - #53093 (Enable macros to pass $:literal to another macro)
 - #53107 (Remove references to `StaticMutex` which got removed a while ago)
 - #53135 (Rust 2018: Disable catch_expr, not targeted for 2018 edition)
 - #53139 (set emit_debug_gdb_scripts: false for riscv32imac-unknown-none target)
This commit is contained in:
bors 2018-08-07 11:00:07 +00:00
commit 18925dee25
28 changed files with 141 additions and 212 deletions

View file

@ -2184,30 +2184,10 @@ dependencies = [
name = "rustc_codegen_llvm"
version = "0.0.0"
dependencies = [
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_allocator 0.0.0",
"rustc_apfloat 0.0.0",
"rustc_codegen_utils 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_incremental 0.0.0",
"rustc_llvm 0.0.0",
"rustc_mir 0.0.0",
"rustc_platform_intrinsics 0.0.0",
"rustc_target 0.0.0",
"serialize 0.0.0",
"syntax 0.0.0",
"syntax_pos 0.0.0",
"tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View file

@ -137,8 +137,10 @@ impl Step for CodegenBackend {
let target = self.target;
let backend = self.backend;
let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
builder.clear_if_dirty(&out_dir, &librustc_stamp(builder, compiler, target));
let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "check");
let features = builder.rustc_features().to_string();
cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
rustc_cargo_env(builder, &mut cargo);
@ -146,7 +148,7 @@ impl Step for CodegenBackend {
let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
run_cargo(builder,
cargo.arg("--features").arg(features),
&mut cargo,
&codegen_backend_stamp(builder, compiler, target, backend),
true);
}

View file

@ -670,16 +670,17 @@ impl Step for CodegenBackend {
return;
}
let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
builder.clear_if_dirty(&out_dir, &librustc_stamp(builder, compiler, target));
let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "build");
let mut features = builder.rustc_features().to_string();
cargo.arg("--manifest-path")
.arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
rustc_cargo_env(builder, &mut cargo);
features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
let features = build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
let tmp_stamp = builder.cargo_out(compiler, Mode::Codegen, target)
.join(".tmp.stamp");
let tmp_stamp = out_dir.join(".tmp.stamp");
let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
let files = run_cargo(builder,

View file

@ -555,8 +555,8 @@ impl Build {
let suffix = match mode {
Mode::Std => "-std",
Mode::Test => "-test",
Mode::Codegen => "-rustc",
Mode::Rustc => "-rustc",
Mode::Codegen => "-codegen",
Mode::ToolBootstrap => "-bootstrap-tools",
Mode::ToolStd => "-tools",
Mode::ToolRustc => "-tools",

View file

@ -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, Executor, SpawnErrorKind, SpawnObjError};
use core::task::{Context, Poll, Spawn, SpawnErrorKind, SpawnObjError};
use raw_vec::RawVec;
use str::from_boxed_utf8_unchecked;
@ -973,11 +973,14 @@ 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
impl<Sp> Spawn for Box<Sp>
where Sp: Spawn + ?Sized
{
fn spawn_obj(&mut self, task: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
(**self).spawn_obj(task)
fn spawn_obj(
&mut self,
future: FutureObj<'static, ()>,
) -> Result<(), SpawnObjError> {
(**self).spawn_obj(future)
}
fn status(&self) -> Result<(), SpawnErrorKind> {

View file

@ -2117,8 +2117,6 @@ impl str {
/// This length is in bytes, not [`char`]s or graphemes. In other words,
/// it may not be what a human considers the length of the string.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
@ -2590,8 +2588,6 @@ impl str {
/// Value, and may not match your idea of what a 'character' is. Iteration
/// over grapheme clusters may be what you actually want.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
@ -2643,8 +2639,6 @@ impl str {
/// The iterator yields tuples. The position is first, the [`char`] is
/// second.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
@ -2946,7 +2940,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
@ -2994,7 +2987,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
@ -3050,7 +3042,6 @@ impl str {
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rsplit`] method can be used.
///
/// [`char`]: primitive.char.html
/// [`rsplit`]: #method.rsplit
///
/// # Examples
@ -3157,8 +3148,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
@ -3224,7 +3213,6 @@ impl str {
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
/// [`char`]: primitive.char.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rsplit_terminator`] method can be used.
@ -3259,8 +3247,6 @@ impl str {
/// Additional libraries might provide more complex patterns like
/// regular expressions.
///
/// [`char`]: primitive.char.html
///
/// Equivalent to [`split`], except that the trailing substring is
/// skipped if empty.
///
@ -3306,8 +3292,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will not be double ended, because it is
@ -3361,8 +3345,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines the split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will not be double ended, because it is not
@ -3407,8 +3389,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
@ -3416,7 +3396,6 @@ impl str {
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
/// [`char`]: primitive.char.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rmatches`] method can be used.
@ -3446,8 +3425,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
@ -3488,8 +3465,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines
/// if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
@ -3532,8 +3507,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines if a
/// character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
@ -3665,8 +3638,6 @@ impl str {
/// The pattern can be a [`char`] or a closure that determines if a
/// character matches.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Simple patterns:
@ -3711,8 +3682,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Left' in this context means the first
@ -3750,8 +3719,6 @@ impl str {
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Right' in this context means the last

View file

@ -13,7 +13,7 @@
issue = "50547")]
use fmt;
use super::{Executor, Waker, LocalWaker};
use super::{Spawn, Waker, LocalWaker};
/// Information about the currently-running task.
///
@ -21,7 +21,7 @@ use super::{Executor, Waker, LocalWaker};
/// when performing a single `poll` step on a task.
pub struct Context<'a> {
local_waker: &'a LocalWaker,
executor: &'a mut dyn Executor,
spawner: &'a mut dyn Spawn,
}
impl<'a> fmt::Debug for Context<'a> {
@ -32,13 +32,14 @@ impl<'a> fmt::Debug for Context<'a> {
}
impl<'a> Context<'a> {
/// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
/// Create a new task `Context` with the provided `local_waker`, `waker`,
/// and `spawner`.
#[inline]
pub fn new(local_waker: &'a LocalWaker, executor: &'a mut dyn Executor) -> Context<'a> {
Context {
local_waker,
executor,
}
pub fn new(
local_waker: &'a LocalWaker,
spawner: &'a mut dyn Spawn,
) -> Context<'a> {
Context { local_waker, spawner }
}
/// Get the `LocalWaker` associated with the current task.
@ -53,40 +54,45 @@ impl<'a> Context<'a> {
unsafe { &*(self.local_waker as *const LocalWaker as *const Waker) }
}
/// Get the default executor associated with this task.
/// Get the spawner associated with this task.
///
/// This method is useful primarily if you want to explicitly handle
/// spawn failures.
#[inline]
pub fn executor(&mut self) -> &mut dyn Executor {
self.executor
pub fn spawner(&mut self) -> &mut dyn Spawn {
self.spawner
}
/// Produce a context like the current one, but using the given waker instead.
/// Produce a context like the current one, but using the given waker
/// instead.
///
/// This advanced method is primarily used when building "internal
/// schedulers" within a task, where you want to provide some customized
/// wakeup logic.
#[inline]
pub fn with_waker<'b>(&'b mut self, local_waker: &'b LocalWaker) -> Context<'b> {
pub fn with_waker<'b>(
&'b mut self,
local_waker: &'b LocalWaker,
) -> Context<'b> {
Context {
local_waker,
executor: self.executor,
spawner: self.spawner,
}
}
/// Produce a context like the current one, but using the given executor
/// Produce a context like the current one, but using the given spawner
/// instead.
///
/// This advanced method is primarily used when building "internal
/// schedulers" within a task.
#[inline]
pub fn with_executor<'b, E>(&'b mut self, executor: &'b mut E) -> Context<'b>
where E: Executor
{
pub fn with_spawner<'b, Sp: Spawn>(
&'b mut self,
spawner: &'b mut Sp,
) -> Context<'b> {
Context {
local_waker: self.local_waker,
executor,
spawner,
}
}
}

View file

@ -17,10 +17,8 @@
mod context;
pub use self::context::Context;
mod executor;
pub use self::executor::{
Executor, SpawnErrorKind, SpawnObjError, SpawnLocalObjError
};
mod spawn;
pub use self::spawn::{Spawn, SpawnErrorKind, SpawnObjError, SpawnLocalObjError};
mod poll;
pub use self::poll::Poll;

View file

@ -15,16 +15,13 @@
use fmt;
use future::{FutureObj, LocalFutureObj};
/// A task executor.
/// Spawns tasks that poll futures to completion onto its associated task
/// executor.
///
/// 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 {
/// The term "task" refers to a kind of lightweight "thread". Task executors
/// are responsible for scheduling the execution of tasks on operating system
/// threads.
pub trait Spawn {
/// Spawns a new task with the given future. The future will be polled until
/// completion.
///

View file

@ -70,8 +70,6 @@ pub enum Def {
Macro(DefId, MacroKind),
NonMacroAttr, // e.g. `#[inline]` or `#[rustfmt::skip]`
GlobalAsm(DefId),
// Both namespaces
Err,
}
@ -251,8 +249,7 @@ impl Def {
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
Def::AssociatedConst(id) | Def::Macro(id, ..) |
Def::Existential(id) | Def::AssociatedExistential(id) |
Def::GlobalAsm(id) | Def::TyForeign(id) => {
Def::Existential(id) | Def::AssociatedExistential(id) | Def::TyForeign(id) => {
id
}
@ -302,7 +299,6 @@ impl Def {
Def::Label(..) => "label",
Def::SelfTy(..) => "self type",
Def::Macro(.., macro_kind) => macro_kind.descr(),
Def::GlobalAsm(..) => "global asm",
Def::ToolMod => "tool module",
Def::NonMacroAttr => "non-macro attribute",
Def::Err => "unresolved item",

View file

@ -432,7 +432,6 @@ impl<'hir> Map<'hir> {
ItemKind::Const(..) => Some(Def::Const(def_id())),
ItemKind::Fn(..) => Some(Def::Fn(def_id())),
ItemKind::Mod(..) => Some(Def::Mod(def_id())),
ItemKind::GlobalAsm(..) => Some(Def::GlobalAsm(def_id())),
ItemKind::Existential(..) => Some(Def::Existential(def_id())),
ItemKind::Ty(..) => Some(Def::TyAlias(def_id())),
ItemKind::Enum(..) => Some(Def::Enum(def_id())),
@ -445,6 +444,7 @@ impl<'hir> Map<'hir> {
ItemKind::ExternCrate(_) |
ItemKind::Use(..) |
ItemKind::ForeignMod(..) |
ItemKind::GlobalAsm(..) |
ItemKind::Impl(..) => None,
}
}

View file

@ -1015,7 +1015,6 @@ impl_stable_hash_for!(enum hir::def::Def {
Upvar(def_id, index, expr_id),
Label(node_id),
Macro(def_id, macro_kind),
GlobalAsm(def_id),
ToolMod,
NonMacroAttr,
Err

View file

@ -10,39 +10,12 @@ crate-type = ["dylib"]
test = false
[dependencies]
bitflags = "1.0.1"
cc = "1.0.1"
flate2 = "1.0"
jobserver = "0.1.5"
libc = "0.2"
log = "0.4"
num_cpus = "1.0"
rustc = { path = "../librustc" }
rustc-demangle = "0.1.4"
rustc_allocator = { path = "../librustc_allocator" }
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_target = { path = "../librustc_target" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
rustc_incremental = { path = "../librustc_incremental" }
rustc_llvm = { path = "../librustc_llvm" }
rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
rustc_mir = { path = "../librustc_mir" }
serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
tempfile = "3.0"
# not actually used but needed to make sure we enable the same feature set as
# winapi used in librustc
env_logger = { version = "0.5", default-features = false }
[features]
# Used to communicate the feature to `rustc_target` in the same manner that the
# `rustc` driver script communicate this.
jemalloc = ["rustc_target/jemalloc"]
# This is used to convince Cargo to separately cache builds of `rustc_codegen_llvm`
# when this option is enabled or not. That way we can build two, cache two
# artifacts, and have nice speedy rebuilds.

View file

@ -427,10 +427,10 @@ impl<'tcx> EntryKind<'tcx> {
EntryKind::Trait(_) => Def::Trait(did),
EntryKind::Enum(..) => Def::Enum(did),
EntryKind::MacroDef(_) => Def::Macro(did, MacroKind::Bang),
EntryKind::GlobalAsm => Def::GlobalAsm(did),
EntryKind::ForeignType => Def::TyForeign(did),
EntryKind::ForeignMod |
EntryKind::GlobalAsm |
EntryKind::Impl(_) |
EntryKind::Field |
EntryKind::Generator(_) |

View file

@ -1281,9 +1281,7 @@ const F: &'static C = &D; // error
```
This is because cell types do operations that are not thread-safe. Due to this,
they don't implement Sync and thus can't be placed in statics. In this
case, `StaticMutex` would work just fine, but it isn't stable yet:
https://doc.rust-lang.org/nightly/std/sync/struct.StaticMutex.html
they don't implement Sync and thus can't be placed in statics.
However, if you still wish to use these types, you can achieve this by an unsafe
wrapper:

View file

@ -810,7 +810,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
HirDef::SelfTy(..) |
HirDef::Label(..) |
HirDef::Macro(..) |
HirDef::GlobalAsm(..) |
HirDef::ToolMod |
HirDef::NonMacroAttr |
HirDef::Err => None,

View file

@ -33,6 +33,7 @@ pub fn target() -> TargetResult {
executables: true,
panic_strategy: PanicStrategy::Abort,
relocation_model: "static".to_string(),
emit_debug_gdb_scripts: false,
abi_blacklist: vec![
Abi::Cdecl,
Abi::Stdcall,

View file

@ -68,9 +68,7 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Err(ErrorReported) = compare_synthetic_generics(tcx,
impl_m,
impl_m_span,
trait_m,
trait_item_span) {
trait_m) {
return;
}
@ -729,14 +727,11 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_m: &ty::AssociatedItem,
_impl_m_span: Span, // FIXME necessary?
trait_m: &ty::AssociatedItem,
_trait_item_span: Option<Span>) // FIXME necessary?
trait_m: &ty::AssociatedItem)
-> Result<(), ErrorReported> {
// FIXME(chrisvittal) Clean up this function, list of FIXME items:
// 1. Better messages for the span labels
// 2. Explanation as to what is going on
// 3. Correct the function signature for what we actually use
// If we get here, we already have the same number of generics, so the zip will
// be okay.
let mut error_found = false;

View file

@ -41,21 +41,19 @@ struct Checker<'a, 'tcx: 'a> {
impl<'a, 'tcx> Checker<'a, 'tcx> {
fn check<F>(&self, trait_def_id: Option<DefId>, mut f: F) -> &Self
where F: FnMut(TyCtxt<'a, 'tcx, 'tcx>, DefId, DefId)
where F: FnMut(TyCtxt<'a, 'tcx, 'tcx>, DefId)
{
if Some(self.trait_def_id) == trait_def_id {
for &impl_id in self.tcx.hir.trait_impls(self.trait_def_id) {
let impl_def_id = self.tcx.hir.local_def_id(impl_id);
f(self.tcx, self.trait_def_id, impl_def_id);
f(self.tcx, impl_def_id);
}
}
self
}
}
fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_drop_did: DefId,
impl_did: DefId) {
fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
match tcx.type_of(impl_did).sty {
ty::TyAdt(..) => {}
_ => {
@ -87,9 +85,7 @@ fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_copy_did: DefId,
impl_did: DefId) {
fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
let impl_node_id = if let Some(n) = tcx.hir.as_local_node_id(impl_did) {
@ -157,9 +153,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_: DefId,
impl_did: DefId) {
fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
debug!("visit_implementation_of_coerce_unsized: impl_did={:?}",
impl_did);

View file

@ -1613,7 +1613,6 @@ impl fmt::Display for AllTypes {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"<h1 class='fqn'>\
<span class='in-band'>List of all items</span>\
<span class='out-of-band'>\
<span id='render-detail'>\
<a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\
@ -1621,6 +1620,7 @@ impl fmt::Display for AllTypes {
</a>\
</span>
</span>
<span class='in-band'>List of all items</span>\
</h1>")?;
print_entries(f, &self.structs, "Structs", "structs")?;
print_entries(f, &self.enums, "Enums", "enums")?;
@ -2068,7 +2068,34 @@ impl<'a> fmt::Display for Item<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
debug_assert!(!self.item.is_stripped());
// Write the breadcrumb trail header for the top
write!(fmt, "<h1 class='fqn'><span class='in-band'>")?;
write!(fmt, "<h1 class='fqn'><span class='out-of-band'>")?;
if let Some(version) = self.item.stable_since() {
write!(fmt, "<span class='since' title='Stable since Rust version {0}'>{0}</span>",
version)?;
}
write!(fmt,
"<span id='render-detail'>\
<a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
title=\"collapse all docs\">\
[<span class='inner'>&#x2212;</span>]\
</a>\
</span>")?;
// Write `src` tag
//
// When this item is part of a `pub use` in a downstream crate, the
// [src] link in the downstream documentation will actually come back to
// this page, and this link will be auto-clicked. The `id` attribute is
// used to find the link to auto-click.
if self.cx.shared.include_sources && !self.item.is_primitive() {
if let Some(l) = self.src_href() {
write!(fmt, "<a class='srclink' href='{}' title='{}'>[src]</a>",
l, "goto source code")?;
}
}
write!(fmt, "</span>")?; // out-of-band
write!(fmt, "<span class='in-band'>")?;
match self.item.inner {
clean::ModuleItem(ref m) => if m.is_crate {
write!(fmt, "Crate ")?;
@ -2105,34 +2132,7 @@ impl<'a> fmt::Display for Item<'a> {
write!(fmt, "<a class=\"{}\" href=''>{}</a>",
self.item.type_(), self.item.name.as_ref().unwrap())?;
write!(fmt, "</span>")?; // in-band
write!(fmt, "<span class='out-of-band'>")?;
if let Some(version) = self.item.stable_since() {
write!(fmt, "<span class='since' title='Stable since Rust version {0}'>{0}</span>",
version)?;
}
write!(fmt,
"<span id='render-detail'>\
<a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
title=\"collapse all docs\">\
[<span class='inner'>&#x2212;</span>]\
</a>\
</span>")?;
// Write `src` tag
//
// When this item is part of a `pub use` in a downstream crate, the
// [src] link in the downstream documentation will actually come back to
// this page, and this link will be auto-clicked. The `id` attribute is
// used to find the link to auto-click.
if self.cx.shared.include_sources && !self.item.is_primitive() {
if let Some(l) = self.src_href() {
write!(fmt, "<a class='srclink' href='{}' title='{}'>[src]</a>",
l, "goto source code")?;
}
}
write!(fmt, "</span></h1>")?; // out-of-band
write!(fmt, "</span></h1>")?; // in-band
match self.item.inner {
clean::ModuleItem(ref m) =>

View file

@ -97,7 +97,7 @@ h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.important), h4
h1.fqn {
border-bottom: 1px dashed;
margin-top: 0;
position: relative;
overflow: auto;
}
h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) {
border-bottom: 1px solid;
@ -352,14 +352,11 @@ nav.sub {
}
.content .out-of-band {
float: right;
font-size: 23px;
margin: 0px;
padding: 0px;
text-align: right;
display: inline-block;
font-weight: normal;
position: absolute;
right: 0;
}
h3.impl > .out-of-band {

View file

@ -31,12 +31,10 @@
// initialization closure panics, the Once enters a "poisoned" state which means
// that all future calls will immediately panic as well.
//
// So to implement this, one might first reach for a `StaticMutex`, but those
// unfortunately need to be deallocated (e.g. call `destroy()`) to free memory
// on all OSes (some of the BSDs allocate memory for mutexes). It also gets a
// lot harder with poisoning to figure out when the mutex needs to be
// deallocated because it's not after the closure finishes, but after the first
// successful closure finishes.
// So to implement this, one might first reach for a `Mutex`, but those cannot
// be put into a `static`. It also gets a lot harder with poisoning to figure
// out when the mutex needs to be deallocated because it's not after the closure
// finishes, but after the first successful closure finishes.
//
// All in all, this is instead implemented with atomics and lock-free
// operations! Whee! Each `Once` has one word of atomic state, and this state is

View file

@ -49,9 +49,6 @@ impl Mutex {
// references, we instead create the mutex with type
// PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
// re-lock it from the same thread, thus avoiding undefined behavior.
//
// We can't do anything for StaticMutex, but that type is deprecated
// anyways.
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
let r = libc::pthread_mutexattr_init(&mut attr);
debug_assert_eq!(r, 0);

View file

@ -323,7 +323,7 @@ declare_features! (
(active, abi_x86_interrupt, "1.17.0", Some(40180), None),
// Allows the `catch {...}` expression
(active, catch_expr, "1.17.0", Some(31436), Some(Edition::Edition2018)),
(active, catch_expr, "1.17.0", Some(31436), None),
// Used to preserve symbols (see llvm.used)
(active, used, "1.18.0", Some(40289), None),

View file

@ -302,6 +302,10 @@ impl Token {
BinOp(Minus) => true,
Ident(ident, false) if ident.name == keywords::True.name() => true,
Ident(ident, false) if ident.name == keywords::False.name() => true,
Interpolated(ref nt) => match nt.0 {
NtLiteral(..) => true,
_ => false,
},
_ => false,
}
}

View file

@ -22,7 +22,7 @@ use std::sync::{
use std::future::FutureObj;
use std::task::{
Context, Poll, Wake,
Executor, SpawnObjError,
Spawn, SpawnObjError,
local_waker_from_nonlocal,
};
@ -36,8 +36,8 @@ impl Wake for Counter {
}
}
struct NoopExecutor;
impl Executor for NoopExecutor {
struct NoopSpawner;
impl Spawn for NoopSpawner {
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
Ok(())
}
@ -127,8 +127,8 @@ where
let mut fut = PinBox::new(f(9));
let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
let waker = local_waker_from_nonlocal(counter.clone());
let executor = &mut NoopExecutor;
let cx = &mut Context::new(&waker, executor);
let spawner = &mut NoopSpawner;
let cx = &mut Context::new(&waker, spawner);
assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
assert_eq!(Poll::Pending, fut.as_pin_mut().poll(cx));

View file

@ -23,7 +23,7 @@ use std::future::FutureObj;
use std::task::{
Context, Poll,
Wake, Waker, LocalWaker,
Executor, SpawnObjError,
Spawn, SpawnObjError,
local_waker, local_waker_from_nonlocal,
};
@ -42,9 +42,9 @@ impl Wake for Counter {
}
}
struct NoopExecutor;
struct NoopSpawner;
impl Executor for NoopExecutor {
impl Spawn for NoopSpawner {
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
Ok(())
}
@ -59,7 +59,7 @@ impl Future for MyFuture {
cx.waker().wake();
cx.waker().wake();
cx.local_waker().wake();
cx.executor().spawn_obj(PinBox::new(MyFuture).into()).unwrap();
cx.spawner().spawn_obj(PinBox::new(MyFuture).into()).unwrap();
Poll::Ready(())
}
}
@ -70,8 +70,8 @@ fn test_local_waker() {
nonlocal_wakes: AtomicUsize::new(0),
});
let waker = unsafe { local_waker(counter.clone()) };
let executor = &mut NoopExecutor;
let cx = &mut Context::new(&waker, executor);
let spawner = &mut NoopSpawner;
let cx = &mut Context::new(&waker, spawner);
assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst));
assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
@ -83,8 +83,8 @@ fn test_local_as_nonlocal_waker() {
nonlocal_wakes: AtomicUsize::new(0),
});
let waker: LocalWaker = local_waker_from_nonlocal(counter.clone());
let executor = &mut NoopExecutor;
let cx = &mut Context::new(&waker, executor);
let spawner = &mut NoopSpawner;
let cx = &mut Context::new(&waker, spawner);
assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst));
assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));

View file

@ -0,0 +1,24 @@
// 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.
#![feature(macro_literal_matcher)]
macro_rules! a {
($i:literal) => { "right" };
($i:tt) => { "wrong" };
}
macro_rules! b {
($i:literal) => { a!($i) };
}
fn main() {
assert_eq!(b!(0), "right");
}