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

Rollup of 20 pull requests

- Successful merges: #47790, #47835, #47854, #48015, #48047, #48051, #48058, #48059, #48064, #48078, #48080, #48086, #48098, #48101, #48107, #48100, #48085, #48120, #48124, #47547
- Failed merges:
This commit is contained in:
bors 2018-02-10 19:48:20 +00:00
commit 45fba43b3d
55 changed files with 398 additions and 533 deletions

View file

@ -151,6 +151,10 @@
# default.
#extended = false
# Installs choosen set of extended tools if enables. By default builds all.
# If choosen tool failed to build the installation fails.
#tools = ["cargo", "rls", "rustfmt", "analysis", "src"]
# Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
#verbose = 0

@ -1 +1 @@
Subproject commit 1c9bf65aa0e371b84755a8ddd6e79497fac57171
Subproject commit 17841e155edf858c8ea7802dd5f5ecbef54b989f

View file

@ -570,7 +570,7 @@ impl<'a> Builder<'a> {
// build scripts in that situation.
//
// If LLVM support is disabled we need to use the snapshot compiler to compile
// build scripts, as the new compiler doesnt support executables.
// build scripts, as the new compiler doesn't support executables.
if mode == Mode::Libstd || !self.build.config.llvm_enabled {
cargo.env("RUSTC_SNAPSHOT", &self.initial_rustc)
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
@ -600,9 +600,25 @@ impl<'a> Builder<'a> {
//
// FIXME: the guard against msvc shouldn't need to be here
if !target.contains("msvc") {
let cc = self.cc(target);
cargo.env(format!("CC_{}", target), cc)
.env("CC", cc);
let ccache = self.config.ccache.as_ref();
let ccacheify = |s: &Path| {
let ccache = match ccache {
Some(ref s) => s,
None => return s.display().to_string(),
};
// FIXME: the cc-rs crate only recognizes the literal strings
// `ccache` and `sccache` when doing caching compilations, so we
// mirror that here. It should probably be fixed upstream to
// accept a new env var or otherwise work with custom ccache
// vars.
match &ccache[..] {
"ccache" | "sccache" => format!("{} {}", ccache, s.display()),
_ => s.display().to_string(),
}
};
let cc = ccacheify(&self.cc(target));
cargo.env(format!("CC_{}", target), &cc)
.env("CC", &cc);
let cflags = self.cflags(target).join(" ");
cargo.env(format!("CFLAGS_{}", target), cflags.clone())
@ -617,8 +633,9 @@ impl<'a> Builder<'a> {
}
if let Ok(cxx) = self.cxx(target) {
cargo.env(format!("CXX_{}", target), cxx)
.env("CXX", cxx)
let cxx = ccacheify(&cxx);
cargo.env(format!("CXX_{}", target), &cxx)
.env("CXX", &cxx)
.env(format!("CXXFLAGS_{}", target), cflags.clone())
.env("CXXFLAGS", cflags);
}

View file

@ -13,7 +13,7 @@
//! This module implements parsing `config.toml` configuration files to tweak
//! how the build runs.
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::env;
use std::fs::File;
use std::io::prelude::*;
@ -52,6 +52,7 @@ pub struct Config {
pub target_config: HashMap<Interned<String>, Target>,
pub full_bootstrap: bool,
pub extended: bool,
pub tools: Option<HashSet<String>>,
pub sanitizers: bool,
pub profiler: bool,
pub ignore_git: bool,
@ -191,6 +192,7 @@ struct Build {
python: Option<String>,
full_bootstrap: Option<bool>,
extended: Option<bool>,
tools: Option<HashSet<String>>,
verbose: Option<usize>,
sanitizers: Option<bool>,
profiler: Option<bool>,
@ -395,6 +397,7 @@ impl Config {
set(&mut config.vendor, build.vendor);
set(&mut config.full_bootstrap, build.full_bootstrap);
set(&mut config.extended, build.extended);
config.tools = build.tools;
set(&mut config.verbose, build.verbose);
set(&mut config.sanitizers, build.sanitizers);
set(&mut config.profiler, build.profiler);

View file

@ -144,6 +144,7 @@ o("jemalloc", "rust.use-jemalloc", "build liballoc with jemalloc")
o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two")
o("extended", "build.extended", "build an extended rust tool set")
v("tools", "build.tools", "List of extended tools will be installed")
v("build", "build.build", "GNUs ./configure syntax LLVM build triple")
v("host", None, "GNUs ./configure syntax LLVM host triples")
v("target", None, "GNUs ./configure syntax LLVM target triples")

View file

@ -31,6 +31,7 @@ use channel;
use util::{cp_r, libdir, is_dylib, cp_filtered, copy, replace_in_file};
use builder::{Builder, RunConfig, ShouldRun, Step};
use compile;
use native;
use tool::{self, Tool};
use cache::{INTERNER, Interned};
use time;
@ -898,6 +899,12 @@ impl Step for PlainSourceTarball {
.arg("--vers").arg(CARGO_VENDOR_VERSION)
.arg("cargo-vendor")
.env("RUSTC", &build.initial_rustc);
if let Some(dir) = build.openssl_install_dir(build.config.build) {
builder.ensure(native::Openssl {
target: build.config.build,
});
cmd.env("OPENSSL_DIR", dir);
}
build.run(&mut cmd);
}

View file

@ -22,6 +22,7 @@ use dist::{self, pkgname, sanitize_sh, tmpdir};
use builder::{Builder, RunConfig, ShouldRun, Step};
use cache::Interned;
use config::Config;
pub fn install_docs(builder: &Builder, stage: u32, host: Interned<String>) {
install_sh(builder, "docs", "rust-docs", stage, Some(host));
@ -144,6 +145,19 @@ macro_rules! install {
pub host: Interned<String>,
}
impl $name {
#[allow(dead_code)]
fn should_build(config: &Config) -> bool {
config.extended && config.tools.as_ref()
.map_or(true, |t| t.contains($path))
}
#[allow(dead_code)]
fn should_install(builder: &Builder) -> bool {
builder.config.tools.as_ref().map_or(false, |t| t.contains($path))
}
}
impl Step for $name {
type Output = ();
const DEFAULT: bool = true;
@ -185,32 +199,34 @@ install!((self, builder, _config),
install_std(builder, self.stage, *target);
}
};
Cargo, "cargo", _config.extended, only_hosts: true, {
Cargo, "cargo", Self::should_build(_config), only_hosts: true, {
builder.ensure(dist::Cargo { stage: self.stage, target: self.target });
install_cargo(builder, self.stage, self.target);
};
Rls, "rls", _config.extended, only_hosts: true, {
if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() {
Rls, "rls", Self::should_build(_config), only_hosts: true, {
if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() ||
Self::should_install(builder) {
install_rls(builder, self.stage, self.target);
} else {
println!("skipping Install RLS stage{} ({})", self.stage, self.target);
}
};
Rustfmt, "rustfmt", _config.extended, only_hosts: true, {
if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() {
Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, {
if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() ||
Self::should_install(builder) {
install_rustfmt(builder, self.stage, self.target);
} else {
println!("skipping Install Rustfmt stage{} ({})", self.stage, self.target);
}
};
Analysis, "analysis", _config.extended, only_hosts: false, {
Analysis, "analysis", Self::should_build(_config), only_hosts: false, {
builder.ensure(dist::Analysis {
compiler: builder.compiler(self.stage, self.host),
target: self.target
});
install_analysis(builder, self.stage, self.target);
};
Src, "src", _config.extended, only_hosts: true, {
Src, "src", Self::should_build(_config) , only_hosts: true, {
builder.ensure(dist::Src);
install_src(builder, self.stage);
}, ONLY_BUILD;

View file

@ -666,7 +666,7 @@ impl Build {
}
}
/// Returns the path to the linker for the given target if it needs to be overriden.
/// Returns the path to the linker for the given target if it needs to be overridden.
fn linker(&self, target: Interned<String>) -> Option<&Path> {
if let Some(linker) = self.config.target_config.get(&target)
.and_then(|c| c.linker.as_ref()) {

View file

@ -902,7 +902,7 @@ impl Step for Compiletest {
}
}
if suite == "run-make" && !build.config.llvm_enabled {
println!("Ignoring run-make test suite as they generally dont work without LLVM");
println!("Ignoring run-make test suite as they generally don't work without LLVM");
return;
}

View file

@ -86,7 +86,8 @@ ENV RUST_CONFIGURE_ARGS \
--enable-extended \
--enable-sanitizers \
--enable-profiler \
--enable-emscripten
--enable-emscripten \
--build=i686-unknown-linux-gnu
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
# This is the only builder which will create source tarballs

View file

@ -54,7 +54,7 @@ cd usr/src
# The options, in order, do the following
# * this is an unprivileged build
# * output to a predictable location
# * disable various uneeded stuff
# * disable various unneeded stuff
MKUNPRIVED=yes TOOLDIR=/x-tools/x86_64-unknown-netbsd \
MKSHARE=no MKDOC=no MKHTML=no MKINFO=no MKKMOD=no MKLINT=no MKMAN=no MKNLS=no MKPROFILE=no \
hide_output ./build.sh -j10 -m amd64 tools

@ -1 +1 @@
Subproject commit a2b424b600235af58f453577c2da1b0e1de2ffa5
Subproject commit 9b2dcac06c3e23235f8997b3c5f2325a6d3382df

@ -1 +1 @@
Subproject commit a645960fe48946153936dd5628df4a90bd837981
Subproject commit ec5660820dea91df470dab0b9eb26ef798f20889

@ -1 +1 @@
Subproject commit fec3182d0b0a3cf8122e192b3270064a5b19be5b
Subproject commit ad5ddd62c098d5b424151beda574ae7df2154df1

@ -1 +1 @@
Subproject commit e6a5d5d10aa2fde0baed7b29bf672bd9f3af8962
Subproject commit 254df654a9b75abf6ca08806535dbe1fad41be3f

@ -1 +1 @@
Subproject commit 4ebb8169dfe569b3dcbeab560607800bb717978a
Subproject commit 919980be7df4ea7d45a9dca8efc34da89bcf7d6b

View file

@ -18,7 +18,7 @@
<!-- Upgrade code should be different for each platform -->
<?if $(sys.BUILDARCH)="x64" ?>
<?if $(env.CFG_ABI)="GNU" ?>
<!-- UpgradeCode shoud stay the same for all MSI versions in channel -->
<!-- UpgradeCode should stay the same for all MSI versions in channel -->
<?if $(env.CFG_CHANNEL)="stable" ?>
<?define UpgradeCode="B440B077-F8D1-4730-8E1D-D6D37702B4CE" ?>
<?elseif $(env.CFG_CHANNEL)="beta" ?>
@ -129,7 +129,7 @@
<!-- Path of cmd.exe for the shortcut -->
<Property Id="SHORTCUTTARGET" Value="%windir%\System32\cmd.exe" />
<!-- Microsoft Installer will resolve any Enviroment Variables in the working directory at install time -->
<!-- Microsoft Installer will resolve any Environment Variables in the working directory at install time -->
<Property Id="SHORTCUTWKDIR" Value="%SystemDrive%\" />
<InstallUISequence>

View file

@ -591,7 +591,7 @@ def parse_args():
The X86 architecture is specified as multiple files (for the different
instruction sets that x86 supports). To generate the compiler
definitions one needs to pass the script a "platform information file"
(with the -i flag) next to the files of the different intruction sets.
(with the -i flag) next to the files of the different instruction sets.
For example, to generate the X86 compiler-definitions for SSE4.2, just:
python generator.py --format compiler-defs -i x86/info.json sse42.json

View file

@ -41,7 +41,7 @@ Instead, we take the input and compute the true value with bignum arithmetic
(as a fraction, using the ``fractions`` module).
Given an input string and the corresponding float computed via Rust, simply
decode the float into f * 2^k (for intergers f, k) and the ULP.
decode the float into f * 2^k (for integers f, k) and the ULP.
We can now easily compute the error and check if it is within 0.5 ULP as it
should be. Zero and infinites are handled similarly:

View file

@ -487,7 +487,7 @@ func_mkdir_p ()
# While some portion of DIR does not yet exist...
while test ! -d "$my_directory_path"; do
# ...make a list in topmost first order. Use a colon delimited
# list incase some portion of path contains whitespace.
# list in case some portion of path contains whitespace.
my_dir_list="$my_directory_path:$my_dir_list"
# If the last portion added has no slash in it, the list is done

View file

@ -327,7 +327,7 @@ macho_get_commands (struct backtrace_state *state, int descriptor,
goto end;
file_header_view_valid = 1;
// The endianess of the slice may be different than the fat image
// The endianness of the slice may be different than the fat image
switch (*(uint32_t *) file_header_view.data)
{
case MH_MAGIC:

View file

@ -211,7 +211,7 @@ impl From<u8> for char {
/// An error which can be returned when parsing a char.
#[stable(feature = "char_from_str", since = "1.20.0")]
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseCharError {
kind: CharErrorKind,
}

View file

@ -1431,6 +1431,10 @@ pub trait Iterator {
/// Folding is useful whenever you have a collection of something, and want
/// to produce a single value from it.
///
/// Note: `fold()`, and similar methods that traverse the entire iterator,
/// may not terminate for infinite iterators, even on traits for which a
/// result is determinable in finite time.
///
/// # Examples
///
/// Basic usage:

View file

@ -298,7 +298,21 @@
//!
//! This will print the numbers `0` through `4`, each on their own line.
//!
//! Bear in mind that methods on infinite iterators, even those for which a
//! result can be determined mathematically in finite time, may not terminate.
//! Specifically, methods such as [`min`], which in the general case require
//! traversing every element in the iterator, are likely not to return
//! successfully for any infinite iterators.
//!
//! ```no_run
//! let ones = std::iter::repeat(1);
//! let least = ones.min().unwrap(); // Oh no! An infinite loop!
//! // `ones.min()` causes an infinite loop, so we won't reach this point!
//! println!("The smallest number one is {}.", least);
//! ```
//!
//! [`take`]: trait.Iterator.html#method.take
//! [`min`]: trait.Iterator.html#method.min
#![stable(feature = "rust1", since = "1.0.0")]

View file

@ -327,7 +327,7 @@ macro_rules! debug_assert_ne {
/// }
/// }
///
/// // The prefered method of quick returning Errors
/// // The preferred method of quick returning Errors
/// fn write_to_file_question() -> Result<(), MyError> {
/// let mut file = File::create("my_best_friends.txt")?;
/// file.write_all(b"This is a list of my best friends.")?;

View file

@ -181,7 +181,7 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "sub"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(message="cannot substract `{RHS}` from `{Self}`",
#[rustc_on_unimplemented(message="cannot subtract `{RHS}` from `{Self}`",
label="no implementation for `{Self} - {RHS}`")]
pub trait Sub<RHS=Self> {
/// The resulting type after applying the `-` operator.
@ -716,7 +716,7 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "sub_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
#[rustc_on_unimplemented(message="cannot substract-assign `{Rhs}` from `{Self}`",
#[rustc_on_unimplemented(message="cannot subtract-assign `{Rhs}` from `{Self}`",
label="no implementation for `{Self} -= {Rhs}`")]
pub trait SubAssign<Rhs=Self> {
/// Performs the `-=` operation.

View file

@ -945,6 +945,7 @@ macro_rules! atomic_int {
$stable_debug:meta,
$stable_access:meta,
$stable_from:meta,
$stable_nand:meta,
$s_int_type:expr, $int_ref:expr,
$int_type:ident $atomic_type:ident $atomic_init:ident) => {
/// An integer type which can be safely shared between threads.
@ -1325,6 +1326,29 @@ macro_rules! atomic_int {
unsafe { atomic_and(self.v.get(), val, order) }
}
/// Bitwise "nand" with the current value.
///
/// Performs a bitwise "nand" operation on the current value and the argument `val`, and
/// sets the new value to the result.
///
/// Returns the previous value.
///
/// # Examples
///
/// ```
/// #![feature(atomic_nand)]
///
/// use std::sync::atomic::{AtomicIsize, Ordering};
///
/// let foo = AtomicIsize::new(0xf731);
/// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731);
/// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f));
#[inline]
#[$stable_nand]
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
unsafe { atomic_nand(self.v.get(), val, order) }
}
/// Bitwise "or" with the current value.
///
/// Performs a bitwise "or" operation on the current value and the argument `val`, and
@ -1377,6 +1401,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i8", "../../../std/primitive.i8.html",
i8 AtomicI8 ATOMIC_I8_INIT
}
@ -1387,6 +1412,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u8", "../../../std/primitive.u8.html",
u8 AtomicU8 ATOMIC_U8_INIT
}
@ -1397,6 +1423,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i16", "../../../std/primitive.i16.html",
i16 AtomicI16 ATOMIC_I16_INIT
}
@ -1407,6 +1434,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u16", "../../../std/primitive.u16.html",
u16 AtomicU16 ATOMIC_U16_INIT
}
@ -1417,6 +1445,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i32", "../../../std/primitive.i32.html",
i32 AtomicI32 ATOMIC_I32_INIT
}
@ -1427,6 +1456,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u32", "../../../std/primitive.u32.html",
u32 AtomicU32 ATOMIC_U32_INIT
}
@ -1437,6 +1467,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i64", "../../../std/primitive.i64.html",
i64 AtomicI64 ATOMIC_I64_INIT
}
@ -1447,6 +1478,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u64", "../../../std/primitive.u64.html",
u64 AtomicU64 ATOMIC_U64_INIT
}
@ -1457,6 +1489,7 @@ atomic_int!{
stable(feature = "atomic_debug", since = "1.3.0"),
stable(feature = "atomic_access", since = "1.15.0"),
stable(feature = "atomic_from", since = "1.23.0"),
unstable(feature = "atomic_nand", issue = "13226"),
"isize", "../../../std/primitive.isize.html",
isize AtomicIsize ATOMIC_ISIZE_INIT
}
@ -1467,6 +1500,7 @@ atomic_int!{
stable(feature = "atomic_debug", since = "1.3.0"),
stable(feature = "atomic_access", since = "1.15.0"),
stable(feature = "atomic_from", since = "1.23.0"),
unstable(feature = "atomic_nand", issue = "13226"),
"usize", "../../../std/primitive.usize.html",
usize AtomicUsize ATOMIC_USIZE_INIT
}
@ -1609,6 +1643,18 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
}
}
#[inline]
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_nand_acq(dst, val),
Release => intrinsics::atomic_nand_rel(dst, val),
AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
SeqCst => intrinsics::atomic_nand(dst, val),
__Nonexhaustive => panic!("invalid memory ordering"),
}
}
#[inline]
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {

View file

@ -48,6 +48,13 @@ fn uint_and() {
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}
#[test]
fn uint_nand() {
let x = AtomicUsize::new(0xf731);
assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}
#[test]
fn uint_or() {
let x = AtomicUsize::new(0xf731);
@ -69,6 +76,13 @@ fn int_and() {
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}
#[test]
fn int_nand() {
let x = AtomicIsize::new(0xf731);
assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}
#[test]
fn int_or() {
let x = AtomicIsize::new(0xf731);

View file

@ -42,6 +42,7 @@
#![feature(try_from)]
#![feature(try_trait)]
#![feature(exact_chunks)]
#![feature(atomic_nand)]
extern crate core;
extern crate test;

View file

@ -73,7 +73,7 @@ pub struct FormatSpec<'a> {
/// Enum describing where an argument for a format can be located.
#[derive(Copy, Clone, PartialEq)]
pub enum Position<'a> {
/// The arugment is implied to be located at an index
/// The argument is implied to be located at an index
ArgumentImplicitlyIs(usize),
/// The argument is located at a specific index given in the format
ArgumentIs(usize),

View file

@ -965,8 +965,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
walk_list!(visitor, visit_expr, subexpressions);
}
ExprCall(ref callee_expression, ref arguments) => {
visitor.visit_expr(callee_expression);
walk_list!(visitor, visit_expr, arguments);
visitor.visit_expr(callee_expression)
}
ExprMethodCall(ref segment, _, ref arguments) => {
visitor.visit_path_segment(expression.span, segment);

View file

@ -764,8 +764,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
} else {
let (closure_span, found) = found_did
.and_then(|did| self.tcx.hir.get_if_local(did))
.map(|node| self.get_fn_like_arguments(node))
.unwrap_or((found_span.unwrap(), found));
.map(|node| {
let (found_span, found) = self.get_fn_like_arguments(node);
(Some(found_span), found)
}).unwrap_or((found_span, found));
self.report_arg_count_mismatch(span,
closure_span,
@ -875,7 +877,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn report_arg_count_mismatch(
&self,
span: Span,
found_span: Span,
found_span: Option<Span>,
expected_args: Vec<ArgKind>,
found_args: Vec<ArgKind>,
is_closure: bool,
@ -913,48 +915,51 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
);
err.span_label(span, format!( "expected {} that takes {}", kind, expected_str));
err.span_label(found_span, format!("takes {}", found_str));
if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
if fields.len() == expected_args.len() {
let sugg = fields.iter()
.map(|(name, _)| name.to_owned())
.collect::<Vec<String>>().join(", ");
err.span_suggestion(found_span,
"change the closure to take multiple arguments instead of \
a single tuple",
format!("|{}|", sugg));
if let Some(found_span) = found_span {
err.span_label(found_span, format!("takes {}", found_str));
if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
if fields.len() == expected_args.len() {
let sugg = fields.iter()
.map(|(name, _)| name.to_owned())
.collect::<Vec<String>>().join(", ");
err.span_suggestion(found_span,
"change the closure to take multiple arguments instead of \
a single tuple",
format!("|{}|", sugg));
}
}
}
if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
if fields.len() == found_args.len() && is_closure {
let sugg = format!(
"|({}){}|",
found_args.iter()
.map(|arg| match arg {
ArgKind::Arg(name, _) => name.to_owned(),
_ => "_".to_owned(),
})
.collect::<Vec<String>>()
.join(", "),
// add type annotations if available
if found_args.iter().any(|arg| match arg {
ArgKind::Arg(_, ty) => ty != "_",
_ => false,
}) {
format!(": ({})",
fields.iter()
.map(|(_, ty)| ty.to_owned())
.collect::<Vec<String>>()
.join(", "))
} else {
"".to_owned()
},
);
err.span_suggestion(found_span,
"change the closure to accept a tuple instead of individual \
arguments",
sugg);
if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
if fields.len() == found_args.len() && is_closure {
let sugg = format!(
"|({}){}|",
found_args.iter()
.map(|arg| match arg {
ArgKind::Arg(name, _) => name.to_owned(),
_ => "_".to_owned(),
})
.collect::<Vec<String>>()
.join(", "),
// add type annotations if available
if found_args.iter().any(|arg| match arg {
ArgKind::Arg(_, ty) => ty != "_",
_ => false,
}) {
format!(": ({})",
fields.iter()
.map(|(_, ty)| ty.to_owned())
.collect::<Vec<String>>()
.join(", "))
} else {
"".to_owned()
},
);
err.span_suggestion(found_span,
"change the closure to accept a tuple instead of \
individual arguments",
sugg);
}
}
}

View file

@ -1,363 +0,0 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// An implementation of the Blake2b cryptographic hash function.
// The implementation closely follows: https://tools.ietf.org/html/rfc7693
//
// "BLAKE2 is a cryptographic hash function faster than MD5, SHA-1, SHA-2, and
// SHA-3, yet is at least as secure as the latest standard SHA-3."
// according to their own website :)
//
// Indeed this implementation is two to three times as fast as our SHA-256
// implementation. If you have the luxury of being able to use crates from
// crates.io, you can go there and find still faster implementations.
use std::mem;
use std::slice;
#[repr(C)]
struct Blake2bCtx {
b: [u8; 128],
h: [u64; 8],
t: [u64; 2],
c: usize,
outlen: u16,
finalized: bool,
#[cfg(debug_assertions)]
fnv_hash: u64,
}
#[cfg(debug_assertions)]
impl ::std::fmt::Debug for Blake2bCtx {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(fmt, "{:x}", self.fnv_hash)
}
}
#[cfg(not(debug_assertions))]
impl ::std::fmt::Debug for Blake2bCtx {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(fmt, "Enable debug_assertions() for more info.")
}
}
#[inline(always)]
fn b2b_g(v: &mut [u64; 16],
a: usize,
b: usize,
c: usize,
d: usize,
x: u64,
y: u64)
{
v[a] = v[a].wrapping_add(v[b]).wrapping_add(x);
v[d] = (v[d] ^ v[a]).rotate_right(32);
v[c] = v[c].wrapping_add(v[d]);
v[b] = (v[b] ^ v[c]).rotate_right(24);
v[a] = v[a].wrapping_add(v[b]).wrapping_add(y);
v[d] = (v[d] ^ v[a]).rotate_right(16);
v[c] = v[c].wrapping_add(v[d]);
v[b] = (v[b] ^ v[c]).rotate_right(63);
}
// Initialization vector
const BLAKE2B_IV: [u64; 8] = [
0x6A09E667F3BCC908, 0xBB67AE8584CAA73B,
0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1,
0x510E527FADE682D1, 0x9B05688C2B3E6C1F,
0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179
];
fn blake2b_compress(ctx: &mut Blake2bCtx, last: bool) {
const SIGMA: [[usize; 16]; 12] = [
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ],
[14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ],
[11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ],
[7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ],
[9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ],
[2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ],
[12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ],
[13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ],
[6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ],
[10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 ],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ],
[14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ]
];
let mut v: [u64; 16] = [
ctx.h[0],
ctx.h[1],
ctx.h[2],
ctx.h[3],
ctx.h[4],
ctx.h[5],
ctx.h[6],
ctx.h[7],
BLAKE2B_IV[0],
BLAKE2B_IV[1],
BLAKE2B_IV[2],
BLAKE2B_IV[3],
BLAKE2B_IV[4],
BLAKE2B_IV[5],
BLAKE2B_IV[6],
BLAKE2B_IV[7],
];
v[12] ^= ctx.t[0]; // low 64 bits of offset
v[13] ^= ctx.t[1]; // high 64 bits
if last {
v[14] = !v[14];
}
{
// Re-interpret the input buffer in the state as an array
// of little-endian u64s, converting them to machine
// endianness. It's OK to modify the buffer in place
// since this is the last time this data will be accessed
// before it's overwritten.
let m: &mut [u64; 16] = unsafe {
let b: &mut [u8; 128] = &mut ctx.b;
::std::mem::transmute(b)
};
if cfg!(target_endian = "big") {
for word in &mut m[..] {
*word = u64::from_le(*word);
}
}
for i in 0 .. 12 {
b2b_g(&mut v, 0, 4, 8, 12, m[SIGMA[i][ 0]], m[SIGMA[i][ 1]]);
b2b_g(&mut v, 1, 5, 9, 13, m[SIGMA[i][ 2]], m[SIGMA[i][ 3]]);
b2b_g(&mut v, 2, 6, 10, 14, m[SIGMA[i][ 4]], m[SIGMA[i][ 5]]);
b2b_g(&mut v, 3, 7, 11, 15, m[SIGMA[i][ 6]], m[SIGMA[i][ 7]]);
b2b_g(&mut v, 0, 5, 10, 15, m[SIGMA[i][ 8]], m[SIGMA[i][ 9]]);
b2b_g(&mut v, 1, 6, 11, 12, m[SIGMA[i][10]], m[SIGMA[i][11]]);
b2b_g(&mut v, 2, 7, 8, 13, m[SIGMA[i][12]], m[SIGMA[i][13]]);
b2b_g(&mut v, 3, 4, 9, 14, m[SIGMA[i][14]], m[SIGMA[i][15]]);
}
}
for i in 0 .. 8 {
ctx.h[i] ^= v[i] ^ v[i + 8];
}
}
fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx {
assert!(outlen > 0 && outlen <= 64 && key.len() <= 64);
let mut ctx = Blake2bCtx {
b: [0; 128],
h: BLAKE2B_IV,
t: [0; 2],
c: 0,
outlen: outlen as u16,
finalized: false,
#[cfg(debug_assertions)]
fnv_hash: 0xcbf29ce484222325,
};
ctx.h[0] ^= 0x01010000 ^ ((key.len() << 8) as u64) ^ (outlen as u64);
if key.len() > 0 {
blake2b_update(&mut ctx, key);
ctx.c = ctx.b.len();
}
ctx
}
fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8]) {
assert!(!ctx.finalized, "Blake2bCtx already finalized");
let mut bytes_to_copy = data.len();
let mut space_in_buffer = ctx.b.len() - ctx.c;
while bytes_to_copy > space_in_buffer {
checked_mem_copy(data, &mut ctx.b[ctx.c .. ], space_in_buffer);
ctx.t[0] = ctx.t[0].wrapping_add(ctx.b.len() as u64);
if ctx.t[0] < (ctx.b.len() as u64) {
ctx.t[1] += 1;
}
blake2b_compress(ctx, false);
ctx.c = 0;
data = &data[space_in_buffer .. ];
bytes_to_copy -= space_in_buffer;
space_in_buffer = ctx.b.len();
}
if bytes_to_copy > 0 {
checked_mem_copy(data, &mut ctx.b[ctx.c .. ], bytes_to_copy);
ctx.c += bytes_to_copy;
}
#[cfg(debug_assertions)]
{
// compute additional FNV hash for simpler to read debug output
const MAGIC_PRIME: u64 = 0x00000100000001b3;
for &byte in data {
ctx.fnv_hash = (ctx.fnv_hash ^ byte as u64).wrapping_mul(MAGIC_PRIME);
}
}
}
fn blake2b_final(ctx: &mut Blake2bCtx)
{
assert!(!ctx.finalized, "Blake2bCtx already finalized");
ctx.t[0] = ctx.t[0].wrapping_add(ctx.c as u64);
if ctx.t[0] < ctx.c as u64 {
ctx.t[1] += 1;
}
while ctx.c < 128 {
ctx.b[ctx.c] = 0;
ctx.c += 1;
}
blake2b_compress(ctx, true);
// Modify our buffer to little-endian format as it will be read
// as a byte array. It's OK to modify the buffer in place since
// this is the last time this data will be accessed.
if cfg!(target_endian = "big") {
for word in &mut ctx.h {
*word = word.to_le();
}
}
ctx.finalized = true;
}
#[inline(always)]
fn checked_mem_copy<T1, T2>(from: &[T1], to: &mut [T2], byte_count: usize) {
let from_size = from.len() * mem::size_of::<T1>();
let to_size = to.len() * mem::size_of::<T2>();
assert!(from_size >= byte_count);
assert!(to_size >= byte_count);
let from_byte_ptr = from.as_ptr() as * const u8;
let to_byte_ptr = to.as_mut_ptr() as * mut u8;
unsafe {
::std::ptr::copy_nonoverlapping(from_byte_ptr, to_byte_ptr, byte_count);
}
}
pub fn blake2b(out: &mut [u8], key: &[u8], data: &[u8])
{
let mut ctx = blake2b_new(out.len(), key);
blake2b_update(&mut ctx, data);
blake2b_final(&mut ctx);
checked_mem_copy(&ctx.h, out, ctx.outlen as usize);
}
pub struct Blake2bHasher(Blake2bCtx);
impl ::std::hash::Hasher for Blake2bHasher {
fn write(&mut self, bytes: &[u8]) {
blake2b_update(&mut self.0, bytes);
}
fn finish(&self) -> u64 {
assert!(self.0.outlen == 8,
"Hasher initialized with incompatible output length");
u64::from_le(self.0.h[0])
}
}
impl Blake2bHasher {
pub fn new(outlen: usize, key: &[u8]) -> Blake2bHasher {
Blake2bHasher(blake2b_new(outlen, key))
}
pub fn finalize(&mut self) -> &[u8] {
if !self.0.finalized {
blake2b_final(&mut self.0);
}
debug_assert!(mem::size_of_val(&self.0.h) >= self.0.outlen as usize);
let raw_ptr = (&self.0.h[..]).as_ptr() as * const u8;
unsafe {
slice::from_raw_parts(raw_ptr, self.0.outlen as usize)
}
}
}
impl ::std::fmt::Debug for Blake2bHasher {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
write!(fmt, "{:?}", self.0)
}
}
#[cfg(test)]
fn selftest_seq(out: &mut [u8], seed: u32)
{
let mut a: u32 = 0xDEAD4BADu32.wrapping_mul(seed);
let mut b: u32 = 1;
for i in 0 .. out.len() {
let t: u32 = a.wrapping_add(b);
a = b;
b = t;
out[i] = ((t >> 24) & 0xFF) as u8;
}
}
#[test]
fn blake2b_selftest()
{
use std::hash::Hasher;
// grand hash of hash results
const BLAKE2B_RES: [u8; 32] = [
0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD,
0x10, 0xF5, 0x06, 0xC6, 0x1E, 0x29, 0xDA, 0x56,
0x03, 0xD7, 0x63, 0xB8, 0xBB, 0xAD, 0x2E, 0x73,
0x7F, 0x5E, 0x76, 0x5A, 0x7B, 0xCC, 0xD4, 0x75
];
// parameter sets
const B2B_MD_LEN: [usize; 4] = [20, 32, 48, 64];
const B2B_IN_LEN: [usize; 6] = [0, 3, 128, 129, 255, 1024];
let mut data = [0u8; 1024];
let mut md = [0u8; 64];
let mut key = [0u8; 64];
let mut hasher = Blake2bHasher::new(32, &[]);
for i in 0 .. 4 {
let outlen = B2B_MD_LEN[i];
for j in 0 .. 6 {
let inlen = B2B_IN_LEN[j];
selftest_seq(&mut data[.. inlen], inlen as u32); // unkeyed hash
blake2b(&mut md[.. outlen], &[], &data[.. inlen]);
hasher.write(&md[.. outlen]); // hash the hash
selftest_seq(&mut key[0 .. outlen], outlen as u32); // keyed hash
blake2b(&mut md[.. outlen], &key[.. outlen], &data[.. inlen]);
hasher.write(&md[.. outlen]); // hash the hash
}
}
// compute and compare the hash of hashes
let md = hasher.finalize();
for i in 0 .. 32 {
assert_eq!(md[i], BLAKE2B_RES[i]);
}
}

View file

@ -57,7 +57,6 @@ pub mod small_vec;
pub mod base_n;
pub mod bitslice;
pub mod bitvec;
pub mod blake2b;
pub mod graph;
pub mod indexed_set;
pub mod indexed_vec;
@ -70,7 +69,6 @@ pub mod transitive_relation;
pub mod unify;
pub mod fx;
pub mod tuple_slice;
pub mod veccell;
pub mod control_flow_graph;
pub mod flock;
pub mod sync;

View file

@ -1,47 +0,0 @@
// Copyright 2012-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.
use std::cell::UnsafeCell;
use std::mem;
pub struct VecCell<T> {
data: UnsafeCell<Vec<T>>,
}
impl<T> VecCell<T> {
pub fn with_capacity(capacity: usize) -> VecCell<T> {
VecCell { data: UnsafeCell::new(Vec::with_capacity(capacity)) }
}
#[inline]
pub fn push(&self, data: T) -> usize {
// The logic here, and in `swap` below, is that the `push`
// method on the vector will not recursively access this
// `VecCell`. Therefore, we can temporarily obtain mutable
// access, secure in the knowledge that even if aliases exist
// -- indeed, even if aliases are reachable from within the
// vector -- they will not be used for the duration of this
// particular fn call. (Note that we also are relying on the
// fact that `VecCell` is not `Sync`.)
unsafe {
let v = self.data.get();
(*v).push(data);
(*v).len()
}
}
pub fn swap(&self, mut data: Vec<T>) -> Vec<T> {
unsafe {
let v = self.data.get();
mem::swap(&mut *v, &mut data);
}
data
}
}

View file

@ -170,6 +170,13 @@ pub fn compile_input(trans: Box<TransCrate>,
return Ok(())
}
if let &Some(ref dir) = outdir {
if fs::create_dir_all(dir).is_err() {
sess.err("failed to find or create the directory specified by --out-dir");
return Err(CompileIncomplete::Stopped);
}
}
let arenas = AllArenas::new();
// Construct the HIR map

View file

@ -716,6 +716,10 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
ReifyFnPointer => {
match self.eval_operand(operand)?.ty.sty {
ty::TyFnDef(def_id, substs) => {
if self.tcx.has_attr(def_id, "rustc_args_required_const") {
bug!("reifying a fn ptr that requires \
const arguments");
}
let instance = self.resolve(def_id, substs)?;
let fn_ptr = self.memory.create_fn_alloc(instance);
let valty = ValTy {

View file

@ -1026,9 +1026,14 @@ fn import_path_to_string(names: &[SpannedIdent],
if names.is_empty() {
import_directive_subclass_to_string(subclass)
} else {
let x = format!("{}::{}",
names_to_string(names),
import_directive_subclass_to_string(subclass));
// Note that this code looks a little wonky, it's currently here to
// hopefully help debug #48116, but otherwise isn't intended to
// cause any problems.
let x = format!(
"{}::{}",
names_to_string(names),
import_directive_subclass_to_string(subclass),
);
assert!(!names.is_empty());
assert!(!x.starts_with("::"));
return x

View file

@ -714,6 +714,10 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
mir::CastKind::ReifyFnPointer => {
match operand.ty.sty {
ty::TyFnDef(def_id, substs) => {
if tcx.has_attr(def_id, "rustc_args_required_const") {
bug!("reifying a fn ptr that requires \
const arguments");
}
callee::resolve_and_get_fn(self.cx, def_id, substs)
}
_ => {

View file

@ -195,6 +195,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
mir::CastKind::ReifyFnPointer => {
match operand.layout.ty.sty {
ty::TyFnDef(def_id, substs) => {
if bx.cx.tcx.has_attr(def_id, "rustc_args_required_const") {
bug!("reifying a fn ptr that requires \
const arguments");
}
OperandValue::Immediate(
callee::resolve_and_get_fn(bx.cx, def_id, substs))
}

View file

@ -4897,6 +4897,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}
self.check_rustc_args_require_const(def.def_id(), node_id, span);
debug!("instantiate_value_path: type of {:?} is {:?}",
node_id,
ty_substituted);
@ -4904,6 +4906,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty_substituted
}
fn check_rustc_args_require_const(&self,
def_id: DefId,
node_id: ast::NodeId,
span: Span) {
// We're only interested in functions tagged with
// #[rustc_args_required_const], so ignore anything that's not.
if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
return
}
// If our calling expression is indeed the function itself, we're good!
// If not, generate an error that this can only be called directly.
match self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
Node::NodeExpr(expr) => {
match expr.node {
hir::ExprCall(ref callee, ..) => {
if callee.id == node_id {
return
}
}
_ => {}
}
}
_ => {}
}
self.tcx.sess.span_err(span, "this function can only be invoked \
directly, not through a function pointer");
}
/// Report errors if the provided parameters are too few or too many.
fn check_path_parameter_count(&self,
span: Span,

View file

@ -1051,6 +1051,10 @@ impl Clean<Attributes> for [ast::Attribute] {
if UnstableFeatures::from_environment().is_nightly_build() {
let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
for link in markdown_links(&dox, cx.render_type) {
// bail early for real links
if link.contains('/') {
continue;
}
let (def, fragment) = {
let mut kind = PathKind::Unknown;
let path_str = if let Some(prefix) =

View file

@ -106,7 +106,9 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
}
PP::Parenthesized { ref mut output, .. } => {
assert!(output.is_none());
*output = Some(rhs.clone());
if *rhs != clean::Type::Tuple(Vec::new()) {
*output = Some(rhs.clone());
}
}
};
true

View file

@ -123,25 +123,9 @@
sidebar.appendChild(div);
}
}
var themeChoices = document.getElementById("theme-choices");
if (themeChoices) {
if (!themesWidth) {
var savedState = themeChoices.style.display;
themeChoices.style.display = 'block';
themesWidth = themeChoices.offsetWidth + 'px';
themeChoices.style.display = savedState;
}
themeChoices.style.position = "fixed";
themeChoices.style.width = themesWidth;
themeChoices.style.top = '78px';
themeChoices.style.left = '250px';
}
document.getElementsByTagName("body")[0].style.marginTop = '45px';
var themePicker = document.getElementById("theme-picker");
if (themePicker) {
themePicker.style.position = "fixed";
themePicker.style.top = "50px";
themePicker.style.left = "250px";
var themePicker = document.getElementsByClassName("theme-picker");
if (themePicker && themePicker.length > 0) {
themePicker[0].style.display = "none";
}
}
@ -157,18 +141,9 @@
filler.remove();
}
document.getElementsByTagName("body")[0].style.marginTop = '';
var themePicker = document.getElementById("theme-picker");
if (themePicker) {
themePicker.style.position = "absolute";
themePicker.style.top = null;
themePicker.style.left = null;
}
var themeChoices = document.getElementById("theme-choices");
if (themeChoices) {
themeChoices.style.position = 'absolute';
themeChoices.style.width = null;
themeChoices.style.top = null;
themeChoices.style.left = null;
var themePicker = document.getElementsByClassName("theme-picker");
if (themePicker && themePicker.length > 0) {
themePicker[0].style.display = null;
}
}

View file

@ -899,7 +899,7 @@ span.since {
}
#main {
margin-top: 50px;
margin-top: 45px;
padding: 0;
}

View file

@ -984,6 +984,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
"wasm_import_memory attribute is currently unstable",
cfg_fn!(wasm_import_memory))),
("rustc_args_required_const", Whitelisted, Gated(Stability::Unstable,
"rustc_attrs",
"never will be stable",
cfg_fn!(rustc_attrs))),
// Crate level attributes
("crate_name", CrateLevel, Ungated),
("crate_type", CrateLevel, Ungated),

View file

@ -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.
#![feature(attr_literals, rustc_attrs, const_fn)]
#[rustc_args_required_const(0)]
fn foo(_a: i32) {
}
fn main() {
let a = foo; //~ ERROR: this function can only be invoked directly
a(2);
}

View file

@ -0,0 +1,13 @@
// 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 fn f2<F: FnMut(u32) + Clone>(f: F) {}
pub fn f3<F: FnMut(u64) -> () + Clone>(f: F) {}

View file

@ -0,0 +1,27 @@
// 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.
// aux-build:unit-return.rs
#![crate_name = "foo"]
extern crate unit_return;
// @has 'foo/fn.f0.html' '//*[@class="rust fn"]' 'F: FnMut(u8) + Clone'
pub fn f0<F: FnMut(u8) + Clone>(f: F) {}
// @has 'foo/fn.f1.html' '//*[@class="rust fn"]' 'F: FnMut(u16) + Clone'
pub fn f1<F: FnMut(u16) -> () + Clone>(f: F) {}
// @has 'foo/fn.f2.html' '//*[@class="rust fn"]' 'F: FnMut(u32) + Clone'
pub use unit_return::f2;
// @has 'foo/fn.f3.html' '//*[@class="rust fn"]' 'F: FnMut(u64) + Clone'
pub use unit_return::f3;

View file

@ -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.
#![feature(generators)]
fn main() {
let x = (|_| {},);
|| {
let x = x;
x.0({ //~ ERROR borrow may still be in use when generator yields
yield;
});
};
}

View file

@ -0,0 +1,10 @@
error[E0626]: borrow may still be in use when generator yields
--> $DIR/issue-48048.rs:19:9
|
19 | x.0({ //~ ERROR borrow may still be in use when generator yields
| ^^^
20 | yield;
| ----- possible yield occurs here
error: aborting due to previous error

View file

@ -10,7 +10,7 @@
fn main() {
1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
2 as usize - Some(1); //~ ERROR cannot subtract `std::option::Option<{integer}>` from `usize`
3 * (); //~ ERROR cannot multiply `()` to `{integer}`
4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
5 < String::new(); //~ ERROR is not satisfied

View file

@ -6,10 +6,10 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}`
|
= help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize`
error[E0277]: cannot subtract `std::option::Option<{integer}>` from `usize`
--> $DIR/binops.rs:13:16
|
13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
13 | 2 as usize - Some(1); //~ ERROR cannot subtract `std::option::Option<{integer}>` from `usize`
| ^ no implementation for `usize - std::option::Option<{integer}>`
|
= help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`

View file

@ -36,6 +36,9 @@ fn main() {
//~^ ERROR closure is expected to take
let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
//~^ ERROR function is expected to take
let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
//~^ ERROR function is expected to take
}
fn foo() {}

View file

@ -90,7 +90,7 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it
32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
| ^^^ expected function that takes a single 2-tuple as argument
...
41 | fn foo() {}
44 | fn foo() {}
| -------- takes 0 arguments
error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
@ -107,8 +107,14 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it
37 | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
| ^^^ expected function that takes a single 2-tuple as argument
...
42 | fn qux(x: usize, y: usize) {}
45 | fn qux(x: usize, y: usize) {}
| -------------------------- takes 2 distinct arguments
error: aborting due to 11 previous errors
error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
--> $DIR/closure-arg-count.rs:40:41
|
40 | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
| ^^^ expected function that takes 1 argument
error: aborting due to 12 previous errors