# 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
-Subproject commit 1c9bf65aa0e371b84755a8ddd6e79497fac57171
+Subproject commit 17841e155edf858c8ea7802dd5f5ecbef54b989f
//
// 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())
}
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);
}
//! 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::*;
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,
python: Option<String>,
full_bootstrap: Option<bool>,
extended: Option<bool>,
+ tools: Option<HashSet<String>>,
verbose: Option<usize>,
sanitizers: Option<bool>,
profiler: Option<bool>,
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);
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")
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;
.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);
}
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));
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;
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;
--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
-Subproject commit a2b424b600235af58f453577c2da1b0e1de2ffa5
+Subproject commit 9b2dcac06c3e23235f8997b3c5f2325a6d3382df
-Subproject commit a645960fe48946153936dd5628df4a90bd837981
+Subproject commit ec5660820dea91df470dab0b9eb26ef798f20889
-Subproject commit fec3182d0b0a3cf8122e192b3270064a5b19be5b
+Subproject commit ad5ddd62c098d5b424151beda574ae7df2154df1
-Subproject commit e6a5d5d10aa2fde0baed7b29bf672bd9f3af8962
+Subproject commit 254df654a9b75abf6ca08806535dbe1fad41be3f
-Subproject commit 4ebb8169dfe569b3dcbeab560607800bb717978a
+Subproject commit 919980be7df4ea7d45a9dca8efc34da89bcf7d6b
/// 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,
}
/// ```
#[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.
/// ```
#[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.
$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.
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
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
}
}
+#[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 {
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);
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);
#![feature(try_from)]
#![feature(try_trait)]
#![feature(exact_chunks)]
+#![feature(atomic_nand)]
extern crate core;
extern crate test;
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);
} 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,
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,
);
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);
+ }
}
}
+++ /dev/null
-// 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]);
- }
-}
pub mod base_n;
pub mod bitslice;
pub mod bitvec;
-pub mod blake2b;
pub mod graph;
pub mod indexed_set;
pub mod indexed_vec;
pub mod unify;
pub mod fx;
pub mod tuple_slice;
-pub mod veccell;
pub mod control_flow_graph;
pub mod flock;
pub mod sync;
+++ /dev/null
-// 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
- }
-}
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
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 {
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)
}
_ => {
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))
}
}
}
+ self.check_rustc_args_require_const(def.def_id(), node_id, span);
+
debug!("instantiate_value_path: type of {:?} is {:?}",
node_id,
ty_substituted);
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,
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) =
}
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
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";
}
}
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;
}
}
}
#main {
- margin-top: 50px;
+ margin-top: 45px;
padding: 0;
}
"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),
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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) {}
--- /dev/null
+// 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;
--- /dev/null
+// 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;
+ });
+ };
+}
--- /dev/null
+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
+
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
|
= 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`
//~^ 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() {}
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
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