"crates-io 0.21.0",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
name = "crates-io"
version = "0.21.0"
dependencies = [
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "curl"
-version = "0.4.18"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "curl-sys"
-version = "0.4.13"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "tar"
-version = "0.4.16"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
"checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
-"checksum curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e5285b49b44401518c947d3b808d14d99a538a6c9ffb3ec0205c11f9fc4389"
-"checksum curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08459503c415173da1ce6b41036a37b8bfdd86af46d45abb9964d4c61fe670ef"
+"checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"
+"checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870"
"checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
"checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a"
"checksum derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46c7f14685a20f5dd08e7f754f2ea8cc064d8f4214ae21116c106a2768ba7b9b"
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
-"checksum tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f41ca4a5689f06998f0247fcb60da6c760f1950cc9df2a10d71575ad0b062a"
+"checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c"
"checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76"
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
// Pass down configuration from the LLVM build into the build of
// librustc_llvm and librustc_codegen_llvm.
- if builder.is_rust_llvm(target) {
+ if builder.is_rust_llvm(target) && backend != "emscripten" {
cargo.env("LLVM_RUSTLLVM", "1");
}
cargo.env("LLVM_CONFIG", &llvm_config);
RUN sh /scripts/sccache.sh
ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
-ENV PATH=$PATH:/emsdk-portable/node/4.1.1_64bit/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
ENV EM_CONFIG=/emsdk-portable/.emscripten
ENV TARGETS=asmjs-unknown-emscripten
RUN sh /scripts/sccache.sh
ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
-ENV PATH=$PATH:/node-v8.0.0-linux-x64/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
ENV EM_CONFIG=/emsdk-portable/.emscripten
ENV TARGETS=wasm32-unknown-emscripten
cd /emsdk-portable
./emsdk update
-hide_output ./emsdk install sdk-1.37.13-64bit
-./emsdk activate sdk-1.37.13-64bit
+hide_output ./emsdk install sdk-1.38.15-64bit
+./emsdk activate sdk-1.38.15-64bit
# Compile and cache libc
source ./emsdk_env.sh
# Make emsdk usable by any user
cp /root/.emscripten /emsdk-portable
chmod a+rxw -R /emsdk-portable
-
-# node 8 is required to run wasm
-cd /
-curl -sL https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
- tar -xJ
/// y < 0 or y >= N, where N is the width of T in bits.
pub fn unchecked_shr<T>(x: T, y: T) -> T;
+ /// Performs rotate left.
+ /// The stabilized versions of this intrinsic are available on the integer
+ /// primitives via the `rotate_left` method. For example,
+ /// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
+ #[cfg(not(stage0))]
+ pub fn rotate_left<T>(x: T, y: T) -> T;
+
+ /// Performs rotate right.
+ /// The stabilized versions of this intrinsic are available on the integer
+ /// primitives via the `rotate_right` method. For example,
+ /// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
+ #[cfg(not(stage0))]
+ pub fn rotate_right<T>(x: T, y: T) -> T;
+
/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_add` method. For example,
#[rustc_const_unstable(feature = "const_int_rotate")]
#[inline]
pub const fn rotate_left(self, n: u32) -> Self {
- (self << (n % $BITS)) | (self >> (($BITS - (n % $BITS)) % $BITS))
+ #[cfg(not(stage0))] {
+ unsafe { intrinsics::rotate_left(self, n as $SelfT) }
+ }
+ #[cfg(stage0)] {
+ (self << (n % $BITS)) | (self >> (($BITS - (n % $BITS)) % $BITS))
+ }
}
}
#[rustc_const_unstable(feature = "const_int_rotate")]
#[inline]
pub const fn rotate_right(self, n: u32) -> Self {
- (self >> (n % $BITS)) | (self << (($BITS - (n % $BITS)) % $BITS))
+ #[cfg(not(stage0))] {
+ unsafe { intrinsics::rotate_right(self, n as $SelfT) }
+ }
+ #[cfg(stage0)] {
+ (self >> (n % $BITS)) | (self << (($BITS - (n % $BITS)) % $BITS))
+ }
}
}
pub mod personalities {
#[no_mangle]
#[cfg(not(any(
- target_arch = "wasm32",
+ all(
+ target_arch = "wasm32",
+ not(target_os = "emscripten"),
+ ),
all(
target_os = "windows",
target_env = "gnu",
let ohs = P(self.lower_expr(ohs));
hir::ExprKind::Unary(op, ohs)
}
- ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((**l).clone())),
+ ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((*l).clone())),
ExprKind::Cast(ref expr, ref ty) => {
let expr = P(self.lower_expr(expr));
hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
self.msg_span_from_early_bound_and_free_regions(region)
}
ty::ReStatic => ("the static lifetime".to_owned(), None),
+ ty::ReEmpty => ("an empty lifetime".to_owned(), None),
_ => bug!("{:?}", region),
}
}
})
}
+ /// Returns an iterator over all user-declared mutable locals.
+ #[inline]
+ pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
+ (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
+ let local = Local::new(index);
+ let decl = &self.local_decls[local];
+ if decl.is_user_variable.is_some() && decl.mutability == Mutability::Mut {
+ Some(local)
+ } else {
+ None
+ }
+ })
+ }
+
/// Returns an iterator over all user-declared mutable arguments and locals.
#[inline]
pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
elem: &PlaceElem<'tcx>)
-> PlaceTy<'tcx>
{
- self.projection_ty_core(tcx, elem, |_, _, ty| ty)
+ self.projection_ty_core(tcx, elem, |_, _, ty| -> Result<Ty<'tcx>, ()> { Ok(ty) })
+ .unwrap()
}
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
/// `Ty` or downcast variant corresponding to that projection.
/// The `handle_field` callback must map a `Field` to its `Ty`,
/// (which should be trivial when `T` = `Ty`).
- pub fn projection_ty_core<V, T>(self,
- tcx: TyCtxt<'a, 'gcx, 'tcx>,
- elem: &ProjectionElem<'tcx, V, T>,
- mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>)
- -> PlaceTy<'tcx>
+ pub fn projection_ty_core<V, T, E>(
+ self,
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ elem: &ProjectionElem<'tcx, V, T>,
+ mut handle_field: impl FnMut(&Self, &Field, &T) -> Result<Ty<'tcx>, E>)
+ -> Result<PlaceTy<'tcx>, E>
where
V: ::std::fmt::Debug, T: ::std::fmt::Debug
{
bug!("cannot downcast non-ADT type: `{:?}`", self)
}
},
- ProjectionElem::Field(ref f, ref fty) => PlaceTy::Ty { ty: handle_field(&self, f, fty) }
+ ProjectionElem::Field(ref f, ref fty) =>
+ PlaceTy::Ty { ty: handle_field(&self, f, fty)? },
};
debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
- answer
+ Ok(answer)
}
}
error_format,
&format!(
"optimization level needs to be \
- between 0-3 (instead was `{}`)",
+ between 0-3, s or z (instead was `{}`)",
arg
),
);
let recursion_limit = *selcx.tcx().sess.recursion_limit.get();
if obligation.recursion_depth >= recursion_limit {
debug!("project: overflow!");
- selcx.infcx().report_overflow_error(&obligation, true);
+ return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
}
let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.tcx());
if !substs.is_noop() {
types_without_default_bounds.extend(substs.types());
w.push('<');
- w.push_str(&substs.iter().map(|k| k.to_string()).collect::<Vec<_>>().join(", "));
+ w.push_str(&substs.iter()
+ .map(|k| k.to_string())
+ .filter(|k| &k[..] != "'_")
+ .collect::<Vec<_>>().join(", "));
w.push('>');
}
.map(|&(cnum, ..)| cnum)
.max()
.unwrap_or(0) + 1;
- let mut map = IndexVec::new();
- map.resize(map_size as usize, None);
+ let mut map = IndexVec::from_elem_n(None, map_size as usize);
for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
let key = (crate_name.clone(), crate_disambiguator);
// ...and then memcpy it to the intended destination.
base::call_memcpy(bx,
bx.pointercast(dst.llval, Type::i8p(cx)),
+ self.layout.align,
bx.pointercast(llscratch, Type::i8p(cx)),
+ scratch_align,
C_usize(cx, self.layout.size.bytes()),
- self.layout.align.min(scratch_align),
MemFlags::empty());
bx.lifetime_end(llscratch, scratch_size);
if self.src_archive().is_none() {
return Vec::new()
}
+
let archive = self.src_archive.as_ref().unwrap().as_ref().unwrap();
- let ret = archive.iter()
- .filter_map(|child| child.ok())
- .filter(is_relevant_child)
- .filter_map(|child| child.name())
- .filter(|name| !self.removals.iter().any(|x| x == name))
- .map(|name| name.to_string())
- .collect();
- return ret;
+
+ archive.iter()
+ .filter_map(|child| child.ok())
+ .filter(is_relevant_child)
+ .filter_map(|child| child.name())
+ .filter(|name| !self.removals.iter().any(|x| x == name))
+ .map(|name| name.to_owned())
+ .collect()
}
fn src_archive(&mut self) -> Option<&ArchiveRO> {
let name = file.file_name().unwrap().to_str().unwrap();
self.additions.push(Addition::File {
path: file.to_path_buf(),
- name_in_archive: name.to_string(),
+ name_in_archive: name.to_owned(),
});
}
/// Combine the provided files, rlibs, and native libraries into a single
/// `Archive`.
pub fn build(&mut self) {
- let kind = match self.llvm_archive_kind() {
- Ok(kind) => kind,
- Err(kind) => {
- self.config.sess.fatal(&format!("Don't know how to build archive of type: {}",
- kind));
- }
- };
+ let kind = self.llvm_archive_kind().unwrap_or_else(|kind|
+ self.config.sess.fatal(&format!("Don't know how to build archive of type: {}", kind)));
if let Err(e) = self.build_with_llvm(kind) {
self.config.sess.fatal(&format!("failed to build archive: {}", e));
let ret = if r.into_result().is_err() {
let err = llvm::LLVMRustGetLastError();
let msg = if err.is_null() {
- "failed to write archive".to_string()
+ "failed to write archive".into()
} else {
String::from_utf8_lossy(CStr::from_ptr(err).to_bytes())
- .into_owned()
};
Err(io::Error::new(io::ErrorKind::Other, msg))
} else {
for member in members {
llvm::LLVMRustArchiveMemberFree(member);
}
- return ret
+ ret
}
}
}
// This is the "magic number" expected at the beginning of a LLVM bytecode
// object in an rlib.
-pub const RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
+pub const RLIB_BYTECODE_OBJECT_MAGIC: &[u8] = b"RUST_OBJECT";
// The version number this compiler will write to bytecode objects in rlibs
pub const RLIB_BYTECODE_OBJECT_VERSION: u8 = 2;
}
impl<'a> DecodedBytecode<'a> {
- pub fn new(data: &'a [u8]) -> Result<DecodedBytecode<'a>, String> {
+ pub fn new(data: &'a [u8]) -> Result<DecodedBytecode<'a>, &'static str> {
if !data.starts_with(RLIB_BYTECODE_OBJECT_MAGIC) {
- return Err("magic bytecode prefix not found".to_string())
+ return Err("magic bytecode prefix not found")
}
let data = &data[RLIB_BYTECODE_OBJECT_MAGIC.len()..];
if !data.starts_with(&[RLIB_BYTECODE_OBJECT_VERSION, 0, 0, 0]) {
- return Err("wrong version prefix found in bytecode".to_string())
+ return Err("wrong version prefix found in bytecode")
}
let data = &data[4..];
if data.len() < 4 {
- return Err("bytecode corrupted".to_string())
+ return Err("bytecode corrupted")
}
let identifier_len = unsafe {
u32::from_le(ptr::read_unaligned(data.as_ptr() as *const u32)) as usize
};
let data = &data[4..];
if data.len() < identifier_len {
- return Err("bytecode corrupted".to_string())
+ return Err("bytecode corrupted")
}
let identifier = match str::from_utf8(&data[..identifier_len]) {
Ok(s) => s,
- Err(_) => return Err("bytecode corrupted".to_string())
+ Err(_) => return Err("bytecode corrupted")
};
let data = &data[identifier_len..];
if data.len() < 8 {
- return Err("bytecode corrupted".to_string())
+ return Err("bytecode corrupted")
}
let bytecode_len = unsafe {
u64::from_le(ptr::read_unaligned(data.as_ptr() as *const u64)) as usize
};
let data = &data[8..];
if data.len() < bytecode_len {
- return Err("bytecode corrupted".to_string())
+ return Err("bytecode corrupted")
}
let encoded_bytecode = &data[..bytecode_len];
use syntax::attr;
pub use rustc_codegen_utils::link::{find_crate_name, filename_for_input, default_output_for_target,
- invalid_output_for_target, out_filename, check_file_is_writeable,
- filename_for_metadata};
+ invalid_output_for_target, filename_for_metadata,
+ out_filename, check_file_is_writeable};
// The third parameter is for env vars, used on windows to set up the
// path for MSVC to find its DLLs, and gcc to find its bundled
}
pub fn remove(sess: &Session, path: &Path) {
- match fs::remove_file(path) {
- Ok(..) => {}
- Err(e) => {
- sess.err(&format!("failed to remove {}: {}",
- path.display(),
- e));
- }
+ if let Err(e) = fs::remove_file(path) {
+ sess.err(&format!("failed to remove {}: {}",
+ path.display(),
+ e));
}
}
// Remove the temporary object file and metadata if we aren't saving temps
if !sess.opts.cg.save_temps {
- if sess.opts.output_types.should_codegen() &&
- !preserve_objects_for_their_debuginfo(sess)
- {
+ if sess.opts.output_types.should_codegen() && !preserve_objects_for_their_debuginfo(sess) {
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
remove(sess, obj);
}
// the objects as they're losslessly contained inside the archives.
let output_linked = sess.crate_types.borrow()
.iter()
- .any(|x| *x != config::CrateType::Rlib && *x != config::CrateType::Staticlib);
+ .any(|&x| x != config::CrateType::Rlib && x != config::CrateType::Staticlib);
if !output_linked {
return false
}
// crates providing these functions don't participate in LTO (e.g.
// no_builtins or compiler builtins crates).
!sess.target.target.options.no_builtins &&
- (info.is_no_builtins.contains(&cnum) || info.compiler_builtins == Some(cnum))
+ (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
}
fn link_binary_output(sess: &Session,
// final destination, with a `fs::rename` call. In order for the rename to
// always succeed, the temporary file needs to be on the same filesystem,
// which is why we create it inside the output directory specifically.
- let metadata_tmpdir = match TempFileBuilder::new()
+ let metadata_tmpdir = TempFileBuilder::new()
.prefix("rmeta")
.tempdir_in(out_filename.parent().unwrap())
- {
- Ok(tmpdir) => tmpdir,
- Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
- };
+ .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err)));
let metadata = emit_metadata(sess, codegen_results, &metadata_tmpdir);
if let Err(e) = fs::rename(metadata, &out_filename) {
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
out_filenames.push(out_filename);
}
- let tmpdir = match TempFileBuilder::new().prefix("rustc").tempdir() {
- Ok(tmpdir) => tmpdir,
- Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
- };
+ let tmpdir = TempFileBuilder::new().prefix("rustc").tempdir().unwrap_or_else(|err|
+ sess.fatal(&format!("couldn't create a temp dir: {}", err)));
if outputs.outputs.should_codegen() {
let out_filename = out_filename(sess, crate_type, outputs, crate_name);
sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
search.push(path.to_path_buf());
});
- return search;
+
+ search
}
fn archive_config<'a>(sess: &'a Session,
.unwrap_or_else(|_| {
let mut x = "Non-UTF-8 output: ".to_string();
x.extend(s.iter()
- .flat_map(|&b| ascii::escape_default(b))
- .map(|b| char::from_u32(b as u32).unwrap()));
+ .flat_map(|&b| ascii::escape_default(b))
+ .map(char::from));
x
})
}
sess.opts.debuginfo != DebugInfo::None &&
!preserve_objects_for_their_debuginfo(sess)
{
- match Command::new("dsymutil").arg(out_filename).output() {
- Ok(..) => {}
- Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)),
+ if let Err(e) = Command::new("dsymutil").arg(out_filename).output() {
+ sess.fatal(&format!("failed to run dsymutil: {}", e))
}
}
// ensure the line is interpreted as one whole argument.
for c in self.arg.chars() {
match c {
- '\\' |
- ' ' => write!(f, "\\{}", c)?,
+ '\\' | ' ' => write!(f, "\\{}", c)?,
c => write!(f, "{}", c)?,
}
}
for f in archive.src_files() {
if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME {
archive.remove_file(&f);
- continue
}
}
Lto::Fat => {
assert!(cached_modules.is_empty());
let opt_jobs = fat_lto(cgcx,
- &diag_handler,
- modules,
- upstream_modules,
- &symbol_white_list,
- timeline);
+ &diag_handler,
+ modules,
+ upstream_modules,
+ &symbol_white_list,
+ timeline);
opt_jobs.map(|opt_jobs| (opt_jobs, vec![]))
}
Lto::Thin |
let data = bc_decoded.data();
linker.add(&data).map_err(|()| {
let msg = format!("failed to load bc of {:?}", name);
- write::llvm_err(&diag_handler, msg)
+ write::llvm_err(&diag_handler, &msg)
})
})?;
timeline.record(&format!("link {:?}", name));
unsafe {
let ptr = symbol_white_list.as_ptr();
llvm::LLVMRustRunRestrictionPass(llmod,
- ptr as *const *const libc::c_char,
- symbol_white_list.len() as libc::size_t);
+ ptr as *const *const libc::c_char,
+ symbol_white_list.len() as libc::size_t);
cgcx.save_temp_bitcode(&module, "lto.after-restriction");
}
symbol_white_list.as_ptr(),
symbol_white_list.len() as u32,
).ok_or_else(|| {
- write::llvm_err(&diag_handler, "failed to prepare thin LTO context".to_string())
+ write::llvm_err(&diag_handler, "failed to prepare thin LTO context")
})?;
info!("thin LTO data created");
llvm::LLVMRustAddPass(pm, pass.unwrap());
}
- time_ext(cgcx.time_passes, None, "LTO passes", ||
- llvm::LLVMRunPassManager(pm, llmod));
+ time_ext(cgcx.time_passes, None, "LTO passes", || llvm::LLVMRunPassManager(pm, llmod));
llvm::LLVMDisposePassManager(pm);
}
{
let diag_handler = cgcx.create_diag_handler();
let tm = (cgcx.tm_factory)().map_err(|e| {
- write::llvm_err(&diag_handler, e)
+ write::llvm_err(&diag_handler, &e)
})?;
// Right now the implementation we've got only works over serialized
self.data().len(),
self.shared.module_names[self.idx].as_ptr(),
).ok_or_else(|| {
- let msg = "failed to parse bitcode for thin LTO module".to_string();
+ let msg = "failed to parse bitcode for thin LTO module";
write::llvm_err(&diag_handler, msg)
})? as *const _;
let module = ModuleCodegen {
let mut cu2 = ptr::null_mut();
llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
if !cu2.is_null() {
- let msg = "multiple source DICompileUnits found".to_string();
+ let msg = "multiple source DICompileUnits found";
return Err(write::llvm_err(&diag_handler, msg))
}
// You can find some more comments about these functions in the LLVM
// bindings we've got (currently `PassWrapper.cpp`)
if !llvm::LLVMRustPrepareThinLTORename(self.shared.data.0, llmod) {
- let msg = "failed to prepare thin LTO module".to_string();
+ let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg))
}
cgcx.save_temp_bitcode(&module, "thin-lto-after-rename");
timeline.record("rename");
if !llvm::LLVMRustPrepareThinLTOResolveWeak(self.shared.data.0, llmod) {
- let msg = "failed to prepare thin LTO module".to_string();
+ let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg))
}
cgcx.save_temp_bitcode(&module, "thin-lto-after-resolve");
timeline.record("resolve");
if !llvm::LLVMRustPrepareThinLTOInternalize(self.shared.data.0, llmod) {
- let msg = "failed to prepare thin LTO module".to_string();
+ let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg))
}
cgcx.save_temp_bitcode(&module, "thin-lto-after-internalize");
timeline.record("internalize");
if !llvm::LLVMRustPrepareThinLTOImport(self.shared.data.0, llmod) {
- let msg = "failed to prepare thin LTO module".to_string();
+ let msg = "failed to prepare thin LTO module";
return Err(write::llvm_err(&diag_handler, msg))
}
cgcx.save_temp_bitcode(&module, "thin-lto-after-import");
}
fn module_name_to_str(c_str: &CStr) -> &str {
- match c_str.to_str() {
- Ok(s) => s,
- Err(e) => {
- bug!("Encountered non-utf8 LLVM module name `{}`: {}",
- c_str.to_string_lossy(),
- e)
- }
- }
+ c_str.to_str().unwrap_or_else(|e|
+ bug!("Encountered non-utf8 LLVM module name `{}`: {}", c_str.to_string_lossy(), e))
}
// Use DT_RUNPATH instead of DT_RPATH if available
if config.linker_is_gnu {
- flags.push("-Wl,--enable-new-dtags".to_string());
+ flags.push("-Wl,--enable-new-dtags".to_owned());
}
flags
ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
}
}
- return ret;
+
+ ret
}
fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
// Remove duplicates
let rpaths = minimize_rpaths(&rpaths);
- return rpaths;
+
+ rpaths
}
fn get_rpaths_relative_to_output(config: &mut RPathConfig,
let relative = path_relative_from(&lib, &output).unwrap_or_else(||
panic!("couldn't create relative path from {:?} to {:?}", output, lib));
// FIXME (#9639): This needs to handle non-utf8 paths
- format!("{}/{}", prefix,
- relative.to_str().expect("non-utf8 component in path"))
+ format!("{}/{}", prefix, relative.to_str().expect("non-utf8 component in path"))
}
// This routine is adapted from the *old* Path's `path_relative_from`
let path = (config.get_install_prefix_lib_path)();
let path = env::current_dir().unwrap().join(&path);
// FIXME (#9639): This needs to handle non-utf8 paths
- path.to_str().expect("non-utf8 component in rpath").to_string()
+ path.to_str().expect("non-utf8 component in rpath").to_owned()
}
fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
/// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still
/// needs to be added, tracked at https://bugs.llvm.org/show_bug.cgi?id=37168
pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) {
- if import_map.len() == 0 {
+ if import_map.is_empty() {
return
}
type Item = (u8, &'a [u8]);
fn next(&mut self) -> Option<(u8, &'a [u8])> {
- if self.0.data.len() == 0 {
+ if self.0.data.is_empty() {
return None
}
use std::thread;
use libc::{c_uint, c_void, c_char, size_t};
-pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [
+pub const RELOC_MODEL_ARGS : [(&str, llvm::RelocMode); 7] = [
("pic", llvm::RelocMode::PIC),
("static", llvm::RelocMode::Static),
("default", llvm::RelocMode::Default),
("large", llvm::CodeModel::Large),
];
-pub const TLS_MODEL_ARGS : [(&'static str, llvm::ThreadLocalMode); 4] = [
+pub const TLS_MODEL_ARGS : [(&str, llvm::ThreadLocalMode); 4] = [
("global-dynamic", llvm::ThreadLocalMode::GeneralDynamic),
("local-dynamic", llvm::ThreadLocalMode::LocalDynamic),
("initial-exec", llvm::ThreadLocalMode::InitialExec),
const PRE_THIN_LTO_BC_EXT: &str = "pre-thin-lto.bc";
-pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
+pub fn llvm_err(handler: &errors::Handler, msg: &str) -> FatalError {
match llvm::last_error() {
Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
None => handler.fatal(&msg),
file_type: llvm::FileType) -> Result<(), FatalError> {
unsafe {
let output_c = path2cstr(output);
- let result = llvm::LLVMRustWriteOutputFile(
- target, pm, m, output_c.as_ptr(), file_type);
+ let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
if result.into_result().is_err() {
let msg = format!("could not write output to {}", output.display());
- Err(llvm_err(handler, msg))
+ Err(llvm_err(handler, &msg))
} else {
Ok(())
}
find_features: bool,
) -> &'static mut llvm::TargetMachine {
target_machine_factory(sess, find_features)().unwrap_or_else(|err| {
- llvm_err(sess.diagnostic(), err).raise()
+ llvm_err(sess.diagnostic(), &err).raise()
})
}
unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext,
msg: &'b str,
cookie: c_uint) {
- cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_string());
+ cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
}
unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic,
for pass in &config.passes {
if !addpass(pass) {
- diag_handler.warn(&format!("unknown pass `{}`, ignoring",
- pass));
+ diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass));
}
if pass == "name-anon-globals" {
have_name_anon_globals_pass = true;
for pass in &cgcx.plugin_passes {
if !addpass(pass) {
diag_handler.err(&format!("a plugin asked for LLVM pass \
- `{}` but LLVM does not \
- recognize it", pass));
+ `{}` but LLVM does not \
+ recognize it", pass));
}
if pass == "name-anon-globals" {
have_name_anon_globals_pass = true;
// As described above, this will probably cause an error in LLVM
if config.no_prepopulate_passes {
diag_handler.err("The current compilation is going to use thin LTO buffers \
- without running LLVM's NameAnonGlobals pass. \
- This will likely cause errors in LLVM. Consider adding \
- -C passes=name-anon-globals to the compiler command line.");
+ without running LLVM's NameAnonGlobals pass. \
+ This will likely cause errors in LLVM. Consider adding \
+ -C passes=name-anon-globals to the compiler command line.");
} else {
bug!("We are using thin LTO buffers without running the NameAnonGlobals pass. \
- This will likely cause errors in LLVM and should never happen.");
+ This will likely cause errors in LLVM and should never happen.");
}
}
}
// escape the closure itself, and the manager should only be
// used once.
unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine,
- llmod: &'ll llvm::Module,
- no_builtins: bool,
- f: F) -> R
+ llmod: &'ll llvm::Module,
+ no_builtins: bool,
+ f: F) -> R
where F: FnOnce(&'ll mut PassManager<'ll>) -> R,
{
let cpm = llvm::LLVMCreatePassManager();
};
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(diag_handler, tm, cpm, llmod, &path,
- llvm::FileType::AssemblyFile)
+ llvm::FileType::AssemblyFile)
})?;
timeline.record("asm");
}
if write_obj {
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
- llvm::FileType::ObjectFile)
+ llvm::FileType::ObjectFile)
})?;
timeline.record("obj");
} else if asm_to_obj {
}
pub fn start_async_codegen(tcx: TyCtxt,
- time_graph: Option<TimeGraph>,
- metadata: EncodedMetadata,
- coordinator_receive: Receiver<Box<dyn Any + Send>>,
- total_cgus: usize)
- -> OngoingCodegen {
+ time_graph: Option<TimeGraph>,
+ metadata: EncodedMetadata,
+ coordinator_receive: Receiver<Box<dyn Any + Send>>,
+ total_cgus: usize)
+ -> OngoingCodegen {
let sess = tcx.sess;
let crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_hash = tcx.crate_hash(LOCAL_CRATE);
}
if let Some((id, product)) =
- copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) {
+ copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files)
+ {
work_products.insert(id, product);
}
}
module.name,
source_file,
obj_out.display());
- match link_or_copy(&source_file, &obj_out) {
- Ok(_) => { }
- Err(err) => {
- let diag_handler = cgcx.create_diag_handler();
- diag_handler.err(&format!("unable to copy {} to {}: {}",
- source_file.display(),
- obj_out.display(),
- err));
- }
+ if let Err(err) = link_or_copy(&source_file, &obj_out) {
+ let diag_handler = cgcx.create_diag_handler();
+ diag_handler.err(&format!("unable to copy {} to {}: {}",
+ source_file.display(),
+ obj_out.display(),
+ err));
}
}
let (name, mut cmd) = get_linker(sess, &linker, flavor);
cmd.args(&sess.target.target.options.asm_args);
- Some(Arc::new(AssemblerCommand {
- name,
- cmd,
- }))
+
+ Some(Arc::new(AssemblerCommand { name, cmd }))
} else {
None
};
handler.struct_err(&format!("linking with `{}` failed: {}",
pname.display(),
prog.status))
- .note(&format!("{:?}", &cmd))
- .note(str::from_utf8(¬e[..]).unwrap())
- .emit();
+ .note(&format!("{:?}", &cmd))
+ .note(str::from_utf8(¬e[..]).unwrap())
+ .emit();
handler.abort_if_errors();
}
},
}
pub(crate) fn submit_pre_codegened_module_to_llvm(&self,
- tcx: TyCtxt,
- module: ModuleCodegen) {
+ tcx: TyCtxt,
+ module: ModuleCodegen) {
self.wait_for_signal_to_codegen_item();
self.check_for_errors(tcx.sess);
use attributes;
use builder::{Builder, MemFlags};
use callee;
-use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
+use common::{C_bool, C_bytes_in_context, C_usize};
use rustc_mir::monomorphize::item::DefPathBasedNames;
use common::{C_struct_in_context, C_array, val_ty};
use consts;
use std::any::Any;
use std::cmp;
use std::ffi::CString;
-use std::i32;
use std::ops::{Deref, DerefMut};
use std::sync::mpsc;
use std::time::{Instant, Duration};
}
if src_f.layout.ty == dst_f.layout.ty {
- memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout,
- src_f.align.min(dst_f.align), MemFlags::empty());
+ memcpy_ty(bx, dst_f.llval, dst_f.align, src_f.llval, src_f.align,
+ src_f.layout, MemFlags::empty());
} else {
coerce_unsized_into(bx, src_f, dst_f);
}
pub fn call_memcpy(
bx: &Builder<'_, 'll, '_>,
dst: &'ll Value,
+ dst_align: Align,
src: &'ll Value,
+ src_align: Align,
n_bytes: &'ll Value,
- align: Align,
flags: MemFlags,
) {
if flags.contains(MemFlags::NONTEMPORAL) {
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
- let val = bx.load(src, align);
+ let val = bx.load(src, src_align);
let ptr = bx.pointercast(dst, val_ty(val).ptr_to());
- bx.store_with_flags(val, ptr, align, flags);
+ bx.store_with_flags(val, ptr, dst_align, flags);
return;
}
let cx = bx.cx;
- let ptr_width = &cx.sess().target.target.target_pointer_width;
- let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
- let memcpy = cx.get_intrinsic(&key);
let src_ptr = bx.pointercast(src, Type::i8p(cx));
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
let size = bx.intcast(n_bytes, cx.isize_ty, false);
- let align = C_i32(cx, align.abi() as i32);
- let volatile = C_bool(cx, flags.contains(MemFlags::VOLATILE));
- bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
+ let volatile = flags.contains(MemFlags::VOLATILE);
+ bx.memcpy(dst_ptr, dst_align.abi(), src_ptr, src_align.abi(), size, volatile);
}
pub fn memcpy_ty(
bx: &Builder<'_, 'll, 'tcx>,
dst: &'ll Value,
+ dst_align: Align,
src: &'ll Value,
+ src_align: Align,
layout: TyLayout<'tcx>,
- align: Align,
flags: MemFlags,
) {
let size = layout.size.bytes();
return;
}
- call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags);
+ call_memcpy(bx, dst, dst_align, src, src_align, C_usize(bx.cx, size), flags);
}
pub fn call_memset(
}
}
+ pub fn memcpy(&self, dst: &'ll Value, dst_align: u64,
+ src: &'ll Value, src_align: u64,
+ size: &'ll Value, is_volatile: bool) -> &'ll Value {
+ unsafe {
+ llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align as c_uint,
+ src, src_align as c_uint, size, is_volatile)
+ }
+ }
+
+ pub fn memmove(&self, dst: &'ll Value, dst_align: u64,
+ src: &'ll Value, src_align: u64,
+ size: &'ll Value, is_volatile: bool) -> &'ll Value {
+ unsafe {
+ llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align as c_uint,
+ src, src_align as c_uint, size, is_volatile)
+ }
+ }
+
pub fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("minnum");
unsafe {
let t_v4f64 = Type::vector(t_f64, 4);
let t_v8f64 = Type::vector(t_f64, 8);
- ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
- ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
- ifn!("llvm.memcpy.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
- ifn!("llvm.memmove.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
- ifn!("llvm.memmove.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
- ifn!("llvm.memmove.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
+ ifn!("llvm.fshl.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+ ifn!("llvm.fshl.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+ ifn!("llvm.fshl.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+ ifn!("llvm.fshl.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+ ifn!("llvm.fshl.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
+ ifn!("llvm.fshr.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+ ifn!("llvm.fshr.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+ ifn!("llvm.fshr.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+ ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+ ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
use llvm;
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
DICompositeType, DILexicalBlock, DIFlags};
+use llvm_util;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc::hir::CodegenFnAttrFlags;
fn use_enum_fallback(cx: &CodegenCx) -> bool {
// On MSVC we have to use the fallback mode, because LLVM doesn't
// lower variant parts to PDB.
- return cx.sess().target.target.options.is_like_msvc || unsafe {
- llvm::LLVMRustVersionMajor() < 7
- };
+ return cx.sess().target.target.options.is_like_msvc
+ || llvm_util::get_major_version() < 7;
}
// Describes the members of an enum value: An enum is described as a union of
use attributes;
use intrinsics::{self, Intrinsic};
use llvm::{self, TypeKind};
+use llvm_util;
use abi::{Abi, FnType, LlvmType, PassMode};
use mir::place::PlaceRef;
use mir::operand::{OperandRef, OperandValue};
use type_::Type;
use type_of::LayoutLlvmExt;
use rustc::ty::{self, Ty};
-use rustc::ty::layout::{HasDataLayout, LayoutOf};
+use rustc::ty::layout::LayoutOf;
use rustc::hir;
use syntax::ast;
use syntax::symbol::Symbol;
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
"bitreverse" | "add_with_overflow" | "sub_with_overflow" |
"mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
- "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" => {
+ "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" |
+ "rotate_left" | "rotate_right" => {
let ty = arg_tys[0];
match int_type_width_signed(ty, cx) {
Some((width, signed)) =>
} else {
bx.lshr(args[0].immediate(), args[1].immediate())
},
+ "rotate_left" | "rotate_right" => {
+ let is_left = name == "rotate_left";
+ let val = args[0].immediate();
+ let raw_shift = args[1].immediate();
+ if llvm_util::get_major_version() >= 7 {
+ // rotate = funnel shift with first two args the same
+ let llvm_name = &format!("llvm.fsh{}.i{}",
+ if is_left { 'l' } else { 'r' }, width);
+ let llfn = cx.get_intrinsic(llvm_name);
+ bx.call(llfn, &[val, val, raw_shift], None)
+ } else {
+ // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
+ // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
+ let width = C_uint(Type::ix(cx, width), width);
+ let shift = bx.urem(raw_shift, width);
+ let inv_shift = bx.urem(bx.sub(width, raw_shift), width);
+ let shift1 = bx.shl(val, if is_left { shift } else { inv_shift });
+ let shift2 = bx.lshr(val, if !is_left { shift } else { inv_shift });
+ bx.or(shift1, shift2)
+ }
+ },
_ => bug!(),
},
None => {
let cx = bx.cx;
let (size, align) = cx.size_and_align_of(ty);
let size = C_usize(cx, size.bytes());
- let align = C_i32(cx, align.abi() as i32);
-
- let operation = if allow_overlap {
- "memmove"
- } else {
- "memcpy"
- };
-
- let name = format!("llvm.{}.p0i8.p0i8.i{}", operation,
- cx.data_layout().pointer_size.bits());
-
+ let align = align.abi();
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
let src_ptr = bx.pointercast(src, Type::i8p(cx));
- let llfn = cx.get_intrinsic(&name);
-
- bx.call(llfn,
- &[dst_ptr,
- src_ptr,
- bx.mul(size, count),
- align,
- C_bool(cx, volatile)],
- None)
+ if allow_overlap {
+ bx.memmove(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
+ } else {
+ bx.memcpy(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
+ }
}
fn memset_intrinsic(
Bundle: Option<&OperandBundleDef<'a>>,
Name: *const c_char)
-> &'a Value;
+ pub fn LLVMRustBuildMemCpy(B: &Builder<'a>,
+ Dst: &'a Value,
+ DstAlign: c_uint,
+ Src: &'a Value,
+ SrcAlign: c_uint,
+ Size: &'a Value,
+ IsVolatile: bool)
+ -> &'a Value;
+ pub fn LLVMRustBuildMemMove(B: &Builder<'a>,
+ Dst: &'a Value,
+ DstAlign: c_uint,
+ Src: &'a Value,
+ SrcAlign: c_uint,
+ Size: &'a Value,
+ IsVolatile: bool)
+ -> &'a Value;
pub fn LLVMBuildSelect(B: &Builder<'a>,
If: &'a Value,
Then: &'a Value,
"hexagon" => HEXAGON_WHITELIST,
"mips" | "mips64" => MIPS_WHITELIST,
"powerpc" | "powerpc64" => POWERPC_WHITELIST,
- "wasm32" => WASM_WHITELIST,
+ // wasm32 on emscripten does not support these target features
+ "wasm32" if !sess.target.target.options.is_like_emscripten => WASM_WHITELIST,
_ => &[],
}
}
}
}
+pub fn get_major_version() -> u32 {
+ unsafe { llvm::LLVMRustVersionMajor() }
+}
+
pub fn print_passes() {
// Can be called without initializing LLVM
unsafe { llvm::LLVMRustPrintPasses(); }
// have scary latent bugs around.
let scratch = PlaceRef::alloca(bx, arg.layout, "arg");
- base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, MemFlags::empty());
+ base::memcpy_ty(bx, scratch.llval, scratch.align, llval, align,
+ op.layout, MemFlags::empty());
(scratch.llval, scratch.align, true)
} else {
(llval, align, true)
use libc::c_uint;
use llvm::{self, BasicBlock};
use llvm::debuginfo::DIScope;
+use llvm_util;
use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
use rustc::ty::layout::{LayoutOf, TyLayout};
use rustc::mir::{self, Mir};
// doesn't actually strip the offset when splitting the closure
// environment into its components so it ends up out of bounds.
// (cuviper) It seems to be fine without the alloca on LLVM 6 and later.
- let env_alloca = !env_ref && unsafe { llvm::LLVMRustVersionMajor() < 6 };
+ let env_alloca = !env_ref && llvm_util::get_major_version() < 6;
let env_ptr = if env_alloca {
let scratch = PlaceRef::alloca(bx,
bx.cx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
}
match self {
OperandValue::Ref(r, None, source_align) => {
- base::memcpy_ty(bx, dest.llval, r, dest.layout,
- source_align.min(dest.align), flags)
+ base::memcpy_ty(bx, dest.llval, dest.align, r, source_align,
+ dest.layout, flags)
}
OperandValue::Ref(_, Some(_), _) => {
bug!("cannot directly store unsized values");
// Allocate an appropriate region on the stack, and copy the value into it
let (llsize, _) = glue::size_and_align_of_dst(&bx, unsized_ty, Some(llextra));
let lldst = bx.array_alloca(Type::i8(bx.cx), llsize, "unsized_tmp", max_align);
- base::call_memcpy(&bx, lldst, llptr, llsize, min_align, flags);
+ base::call_memcpy(&bx, lldst, max_align, llptr, min_align, llsize, flags);
// Store the allocated region and the extra to the indirect place.
let indirect_operand = OperandValue::Pair(lldst, llextra);
}
impl<'a> Linker for GccLinker<'a> {
- fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}",lib)); }
+ fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}", lib)); }
fn link_staticlib(&mut self, lib: &str) {
- self.hint_static(); self.cmd.arg(format!("-l{}",lib));
+ self.hint_static(); self.cmd.arg(format!("-l{}", lib));
}
fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
self.hint_dynamic();
- self.cmd.arg(format!("-l{}",lib));
+ self.cmd.arg(format!("-l{}", lib));
}
fn link_framework(&mut self, framework: &str) {
self.hint_static();
let target = &self.sess.target.target;
if !target.options.is_like_osx {
- self.linker_arg("--whole-archive").cmd.arg(format!("-l{}",lib));
+ self.linker_arg("--whole-archive").cmd.arg(format!("-l{}", lib));
self.linker_arg("--no-whole-archive");
} else {
// -force_load is the macOS equivalent of --whole-archive, but it
}
fn debuginfo(&mut self) {
- match self.sess.opts.debuginfo {
- DebugInfo::None => {
- // If we are building without debuginfo enabled and we were called with
- // `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
- // found when linking to get rid of symbols from libstd.
- match self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
- Some(true) => { self.linker_arg("-S"); },
- _ => {},
- }
- },
- _ => {},
+ if let DebugInfo::None = self.sess.opts.debuginfo {
+ // If we are building without debuginfo enabled and we were called with
+ // `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
+ // found when linking to get rid of symbols from libstd.
+ if let Some(true) = self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
+ self.linker_arg("-S");
+ }
};
}
// purely to support rustbuild right now, we should get a more
// principled solution at some point to force the compiler to pass
// the right `-Wl,-install_name` with an `@rpath` in it.
- if self.sess.opts.cg.rpath ||
- self.sess.opts.debugging_opts.osx_rpath_install_name {
+ if self.sess.opts.cg.rpath || self.sess.opts.debugging_opts.osx_rpath_install_name {
self.linker_arg("-install_name");
let mut v = OsString::from("@rpath/");
v.push(out_filename.file_name().unwrap());
fn finalize(&mut self) -> Command {
self.hint_dynamic(); // Reset to default before returning the composed command line.
- let mut cmd = Command::new("");
- ::std::mem::swap(&mut cmd, &mut self.cmd);
- cmd
+
+ ::std::mem::replace(&mut self.cmd, Command::new(""))
}
fn group_start(&mut self) {
}
fn finalize(&mut self) -> Command {
- let mut cmd = Command::new("");
- ::std::mem::swap(&mut cmd, &mut self.cmd);
- cmd
+ ::std::mem::replace(&mut self.cmd, Command::new(""))
}
// MSVC doesn't need group indicators
let res = encoder.emit_seq(symbols.len(), |encoder| {
for (i, sym) in symbols.iter().enumerate() {
encoder.emit_seq_elt(i, |encoder| {
- encoder.emit_str(&("_".to_string() + sym))
+ encoder.emit_str(&("_".to_owned() + sym))
})?;
}
Ok(())
}
fn finalize(&mut self) -> Command {
- let mut cmd = Command::new("");
- ::std::mem::swap(&mut cmd, &mut self.cmd);
- cmd
+ ::std::mem::replace(&mut self.cmd, Command::new(""))
}
// Appears not necessary on Emscripten
// indicative of bugs, let's prevent them.
self.cmd.arg("--fatal-warnings");
- let mut cmd = Command::new("");
- ::std::mem::swap(&mut cmd, &mut self.cmd);
- cmd
+ ::std::mem::replace(&mut self.cmd, Command::new(""))
}
// Not needed for now with LLD
}
}
-pub fn crates_export_threshold(crate_types: &[config::CrateType])
- -> SymbolExportLevel {
- if crate_types.iter().any(|&crate_type| {
- crate_export_threshold(crate_type) == SymbolExportLevel::Rust
- }) {
+pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExportLevel {
+ if crate_types.iter().any(|&crate_type|
+ crate_export_threshold(crate_type) == SymbolExportLevel::Rust)
+ {
SymbolExportLevel::Rust
} else {
SymbolExportLevel::C
!tcx.reachable_set(LOCAL_CRATE).0.contains(&node_id)
} else {
bug!("is_unreachable_local_definition called with non-local DefId: {:?}",
- def_id)
+ def_id)
}
}
codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
if is_extern && !std_internal {
+ // Emscripten cannot export statics, so reduce their export level here
+ if tcx.sess.target.target.options.is_like_emscripten {
+ if let Some(Node::Item(&hir::Item {
+ node: hir::ItemKind::Static(..),
+ ..
+ })) = tcx.hir.get_if_local(sym_def_id) {
+ return SymbolExportLevel::Rust;
+ }
+ }
+
SymbolExportLevel::C
} else {
SymbolExportLevel::Rust
impl ColorConfig {
fn to_color_choice(&self) -> ColorChoice {
match *self {
- ColorConfig::Always => ColorChoice::Always,
+ ColorConfig::Always => {
+ if atty::is(atty::Stream::Stderr) {
+ ColorChoice::Always
+ } else {
+ ColorChoice::AlwaysAnsi
+ }
+ }
ColorConfig::Never => ColorChoice::Never,
ColorConfig::Auto if atty::is(atty::Stream::Stderr) => {
ColorChoice::Auto
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::bit_set::BitSet;
use std::fmt;
-use std::hash::Hash;
use std::ops::Index;
crate struct BorrowSet<'tcx> {
self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx);
- insert(&mut self.region_map, ®ion, idx);
+ self.region_map.entry(region).or_default().insert(idx);
if let Some(local) = borrowed_place.root_local() {
- insert(&mut self.local_map, &local, idx);
+ self.local_map.entry(local).or_default().insert(idx);
}
}
- return self.super_assign(block, assigned_place, rvalue, location);
-
- fn insert<'a, K, V>(map: &'a mut FxHashMap<K, FxHashSet<V>>, k: &K, v: V)
- where
- K: Clone + Eq + Hash,
- V: Eq + Hash,
- {
- map.entry(k.clone()).or_default().insert(v);
- }
+ self.super_assign(block, assigned_place, rvalue, location)
}
fn visit_place(
// Note that this set is expected to be small - only upvars from closures
// would have a chance of erroneously adding non-user-defined mutable vars
// to the set.
- let temporary_used_locals: FxHashSet<Local> = mbcx
- .used_mut
- .iter()
+ let temporary_used_locals: FxHashSet<Local> = mbcx.used_mut.iter()
.filter(|&local| mbcx.mir.local_decls[*local].is_user_variable.is_none())
.cloned()
.collect();
- mbcx.gather_used_muts(temporary_used_locals);
+ // For the remaining unused locals that are marked as mutable, we avoid linting any that
+ // were never initialized. These locals may have been removed as unreachable code; or will be
+ // linted as unused variables.
+ let unused_mut_locals = mbcx.mir.mut_vars_iter()
+ .filter(|local| !mbcx.used_mut.contains(local))
+ .collect();
+ mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals);
debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
-
let used_mut = mbcx.used_mut;
-
- for local in mbcx
- .mir
- .mut_vars_and_args_iter()
- .filter(|local| !used_mut.contains(local))
- {
+ for local in mbcx.mir.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
if let ClearCrossCrate::Set(ref vsi) = mbcx.mir.source_scope_local_data {
let local_decl = &mbcx.mir.local_decls[local];
let v1 = ty::Contravariant.xform(v);
let tcx = self.infcx.tcx;
- let mut projected_ty = PlaceTy::from_ty(ty);
+ let ty = self.normalize(ty, locations);
+
+ // We need to follow any provided projetions into the type.
+ //
+ // if we hit a ty var as we descend, then just skip the
+ // attempt to relate the mir local with any type.
+ #[derive(Debug)] struct HitTyVar;
+ let mut curr_projected_ty: Result<PlaceTy, HitTyVar>;
+
+ curr_projected_ty = Ok(PlaceTy::from_ty(ty));
for proj in &user_ty.projs {
- projected_ty = projected_ty.projection_ty_core(
+ let projected_ty = if let Ok(projected_ty) = curr_projected_ty {
+ projected_ty
+ } else {
+ break;
+ };
+ curr_projected_ty = projected_ty.projection_ty_core(
tcx, proj, |this, field, &()| {
- let ty = this.field_ty(tcx, field);
- self.normalize(ty, locations)
+ if this.to_ty(tcx).is_ty_var() {
+ Err(HitTyVar)
+ } else {
+ let ty = this.field_ty(tcx, field);
+ Ok(self.normalize(ty, locations))
+ }
});
}
debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
- user_ty.base, ty, user_ty.projs, projected_ty);
+ user_ty.base, ty, user_ty.projs, curr_projected_ty);
- let ty = projected_ty.to_ty(tcx);
-
- self.relate_types(ty, v1, a, locations, category)?;
+ if let Ok(projected_ty) = curr_projected_ty {
+ let ty = projected_ty.to_ty(tcx);
+ self.relate_types(ty, v1, a, locations, category)?;
+ }
}
UserTypeAnnotation::TypeOf(def_id, canonical_substs) => {
let (
// except according to those terms.
use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Local, Location, Place};
+use rustc::mir::{BasicBlock, Local, Location, Place, Statement, StatementKind, TerminatorKind};
use rustc_data_structures::fx::FxHashSet;
use borrow_check::MirBorrowckCtxt;
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
- /// Walks the MIR looking for assignments to a set of locals, as part of the unused mutable
- /// local variables lint, to update the context's `used_mut` in a single walk.
- crate fn gather_used_muts(&mut self, locals: FxHashSet<Local>) {
- let mut visitor = GatherUsedMutsVisitor {
- needles: locals,
- mbcx: self,
- };
- visitor.visit_mir(visitor.mbcx.mir);
+ /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes
+ /// of the `unused_mut` lint.
+ ///
+ /// `temporary_used_locals` should contain locals that were found to be temporary, mutable and
+ /// used from borrow checking. This function looks for assignments into these locals from
+ /// user-declared locals and adds those user-defined locals to the `used_mut` set. This can
+ /// occur due to a rare case involving upvars in closures.
+ ///
+ /// `never_initialized_mut_locals` should contain the set of user-declared mutable locals
+ /// (not arguments) that have not already been marked as being used.
+ /// This function then looks for assignments from statements or the terminator into the locals
+ /// from this set and removes them from the set. This leaves only those locals that have not
+ /// been assigned to - this set is used as a proxy for locals that were not initialized due to
+ /// unreachable code. These locals are then considered "used" to silence the lint for them.
+ /// See #55344 for context.
+ crate fn gather_used_muts(
+ &mut self,
+ temporary_used_locals: FxHashSet<Local>,
+ mut never_initialized_mut_locals: FxHashSet<Local>,
+ ) {
+ {
+ let mut visitor = GatherUsedMutsVisitor {
+ temporary_used_locals,
+ never_initialized_mut_locals: &mut never_initialized_mut_locals,
+ mbcx: self,
+ };
+ visitor.visit_mir(visitor.mbcx.mir);
+ }
+
+ // Take the union of the existed `used_mut` set with those variables we've found were
+ // never initialized.
+ debug!("gather_used_muts: never_initialized_mut_locals={:?}", never_initialized_mut_locals);
+ self.used_mut = self.used_mut.union(&never_initialized_mut_locals).cloned().collect();
}
}
-/// MIR visitor gathering the assignments to a set of locals, in a single walk.
-/// 'visit = the duration of the MIR walk
+/// MIR visitor for collecting used mutable variables.
+/// The 'visit lifetime represents the duration of the MIR walk.
struct GatherUsedMutsVisitor<'visit, 'cx: 'visit, 'gcx: 'tcx, 'tcx: 'cx> {
- needles: FxHashSet<Local>,
+ temporary_used_locals: FxHashSet<Local>,
+ never_initialized_mut_locals: &'visit mut FxHashSet<Local>,
mbcx: &'visit mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
}
impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> {
+ fn visit_terminator_kind(
+ &mut self,
+ _block: BasicBlock,
+ kind: &TerminatorKind<'tcx>,
+ _location: Location,
+ ) {
+ debug!("visit_terminator_kind: kind={:?}", kind);
+ match &kind {
+ TerminatorKind::Call { destination: Some((into, _)), .. } => {
+ if let Some(local) = into.base_local() {
+ debug!(
+ "visit_terminator_kind: kind={:?} local={:?} \
+ never_initialized_mut_locals={:?}",
+ kind, local, self.never_initialized_mut_locals
+ );
+ let _ = self.never_initialized_mut_locals.remove(&local);
+ }
+ },
+ _ => {},
+ }
+ }
+
+ fn visit_statement(
+ &mut self,
+ _block: BasicBlock,
+ statement: &Statement<'tcx>,
+ _location: Location,
+ ) {
+ match &statement.kind {
+ StatementKind::Assign(into, _) => {
+ // Remove any locals that we found were initialized from the
+ // `never_initialized_mut_locals` set. At the end, the only remaining locals will
+ // be those that were never initialized - we will consider those as being used as
+ // they will either have been removed by unreachable code optimizations; or linted
+ // as unused variables.
+ if let Some(local) = into.base_local() {
+ debug!(
+ "visit_statement: statement={:?} local={:?} \
+ never_initialized_mut_locals={:?}",
+ statement, local, self.never_initialized_mut_locals
+ );
+ let _ = self.never_initialized_mut_locals.remove(&local);
+ }
+ },
+ _ => {},
+ }
+ }
+
fn visit_local(
&mut self,
local: &Local,
place_context: PlaceContext<'tcx>,
location: Location,
) {
- if !self.needles.contains(local) {
- return;
- }
-
- if place_context.is_place_assignment() {
+ if place_context.is_place_assignment() && self.temporary_used_locals.contains(local) {
// Propagate the Local assigned at this Location as a used mutable local variable
for moi in &self.mbcx.move_data.loc_map[location] {
let mpi = &self.mbcx.move_data.moves[*moi].path;
}
self.write_scalar(val, dest)?;
}
+ "rotate_left" | "rotate_right" => {
+ // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
+ // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
+ let layout = self.layout_of(substs.type_at(0))?;
+ let val_bits = self.read_scalar(args[0])?.to_bits(layout.size)?;
+ let raw_shift_bits = self.read_scalar(args[1])?.to_bits(layout.size)?;
+ let width_bits = layout.size.bits() as u128;
+ let shift_bits = raw_shift_bits % width_bits;
+ let inv_shift_bits = (width_bits - raw_shift_bits) % width_bits;
+ let result_bits = if intrinsic_name == "rotate_left" {
+ (val_bits << shift_bits) | (val_bits >> inv_shift_bits)
+ } else {
+ (val_bits >> shift_bits) | (val_bits << inv_shift_bits)
+ };
+ let truncated_bits = self.truncate(result_bits, layout);
+ let result = Scalar::from_uint(truncated_bits, layout.size);
+ self.write_scalar(result, dest)?;
+ }
"transmute" => {
self.copy_op_transmute(args[0], dest)?;
}
let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
let return_block = BasicBlock::new(1);
- let mut blocks = IndexVec::new();
+ let mut blocks = IndexVec::with_capacity(2);
let block = |blocks: &mut IndexVec<_, _>, kind| {
blocks.push(BasicBlockData {
statements: vec![],
}));
}
- let mut blocks = IndexVec::new();
+ let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
+ let mut blocks = IndexVec::with_capacity(n_blocks);
let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
blocks.push(BasicBlockData {
statements,
let callee_mir = match self.tcx.try_optimized_mir(callsite.location.span,
callsite.callee) {
- Ok(callee_mir) if self.should_inline(callsite, callee_mir) => {
+ Ok(callee_mir) if self.consider_optimizing(callsite, callee_mir) => {
self.tcx.subst_and_normalize_erasing_regions(
&callsite.substs,
param_env,
}
}
+ fn consider_optimizing(&self,
+ callsite: CallSite<'tcx>,
+ callee_mir: &Mir<'tcx>)
+ -> bool
+ {
+ debug!("consider_optimizing({:?})", callsite);
+ self.should_inline(callsite, callee_mir)
+ && self.tcx.consider_optimizing(|| format!("Inline {:?} into {:?}",
+ callee_mir.span,
+ callsite))
+ }
+
fn should_inline(&self,
callsite: CallSite<'tcx>,
callee_mir: &Mir<'tcx>)
match statement.kind {
StatementKind::Assign(_, box Rvalue::Ref(_, _, ref mut place)) => {
// Find the underlying local for this (necessarily interior) borrow.
- // HACK(eddyb) using a recursive function because of mutable borrows.
- fn interior_base<'a, 'tcx>(place: &'a mut Place<'tcx>)
- -> &'a mut Place<'tcx> {
- if let Place::Projection(ref mut proj) = *place {
- assert_ne!(proj.elem, ProjectionElem::Deref);
- return interior_base(&mut proj.base);
- }
- place
- }
- let place = interior_base(place);
+ let mut place = place;
+ while let Place::Projection(ref mut proj) = *place {
+ assert_ne!(proj.elem, ProjectionElem::Deref);
+ place = &mut proj.base;
+ };
let ty = place.ty(local_decls, self.tcx).to_ty(self.tcx);
let span = statement.source_info.span;
| "overflowing_mul"
| "unchecked_shl"
| "unchecked_shr"
+ | "rotate_left"
+ | "rotate_right"
| "add_with_overflow"
| "sub_with_overflow"
| "mul_with_overflow"
// argument is *not* necessary for normal builds, but it can't hurt!
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--eh-frame-hdr".to_string());
- // There's a whole bunch of circular dependencies when dealing with MUSL
- // unfortunately. To put this in perspective libc is statically linked to
- // liblibc and libunwind is statically linked to libstd:
- //
- // * libcore depends on `fmod` which is in libc (transitively in liblibc).
- // liblibc, however, depends on libcore.
- // * compiler-rt has personality symbols that depend on libunwind, but
- // libunwind is in libstd which depends on compiler-rt.
- //
- // Recall that linkers discard libraries and object files as much as
- // possible, and with all the static linking and archives flying around with
- // MUSL the linker is super aggressively stripping out objects. For example
- // the first case has fmod stripped from liblibc (it's in its own object
- // file) so it's not there when libcore needs it. In the second example all
- // the unused symbols from libunwind are stripped (each is in its own object
- // file in libstd) before we end up linking compiler-rt which depends on
- // those symbols.
- //
- // To deal with these circular dependencies we just force the compiler to
- // link everything as a group, not stripping anything out until everything
- // is processed. The linker will still perform a pass to strip out object
- // files but it won't do so until all objects/archives have been processed.
- base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-(".to_string());
- base.post_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-)".to_string()]);
-
// When generating a statically linked executable there's generally some
// small setup needed which is listed in these files. These are provided by
// a musl toolchain and are linked by default by the `musl-gcc` script. Note
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
let ty = self.normalize(ty);
- let mut projected_ty = PlaceTy::from_ty(ty);
+ // We need to follow any provided projetions into the type.
+ //
+ // if we hit a ty var as we descend, then just skip the
+ // attempt to relate the mir local with any type.
+
+ struct HitTyVar;
+ let mut curr_projected_ty: Result<PlaceTy, HitTyVar>;
+ curr_projected_ty = Ok(PlaceTy::from_ty(ty));
for proj in projs {
- projected_ty = projected_ty.projection_ty_core(
+ let projected_ty = if let Ok(projected_ty) = curr_projected_ty {
+ projected_ty
+ } else {
+ break;
+ };
+ curr_projected_ty = projected_ty.projection_ty_core(
tcx, proj, |this, field, &()| {
- let ty = this.field_ty(tcx, field);
- self.normalize(ty)
+ if this.to_ty(tcx).is_ty_var() {
+ Err(HitTyVar)
+ } else {
+ let ty = this.field_ty(tcx, field);
+ Ok(self.normalize(ty))
+ }
});
}
- let ty = projected_ty.to_ty(tcx);
- self.relate(mir_ty, variance, ty)?;
+ if let Ok(projected_ty) = curr_projected_ty {
+ let ty = projected_ty.to_ty(tcx);
+ self.relate(mir_ty, variance, ty)?;
+ }
if let Some(UserSelfTy {
impl_def_id,
report_unexpected_def(def);
return self.tcx.types.err;
}
- // Replace constructor type with constructed type for tuple struct patterns.
- let pat_ty = pat_ty.fn_sig(tcx).output();
- let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
-
- self.demand_eqtype(pat.span, expected, pat_ty);
let variant = match def {
Def::Err => {
}
_ => bug!("unexpected pattern definition: {:?}", def)
};
+
+ // Replace constructor type with constructed type for tuple struct patterns.
+ let pat_ty = pat_ty.fn_sig(tcx).output();
+ let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
+
+ self.demand_eqtype(pat.span, expected, pat_ty);
+
// Type check subpatterns.
if subpats.len() == variant.fields.len() ||
subpats.len() < variant.fields.len() && ddpos.is_some() {
"unchecked_div" | "unchecked_rem" | "exact_div" =>
(1, vec![param(0), param(0)], param(0)),
- "unchecked_shl" | "unchecked_shr" =>
+ "unchecked_shl" | "unchecked_shr" |
+ "rotate_left" | "rotate_right" =>
(1, vec![param(0), param(0)], param(0)),
"overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
/* General structure and fonts */
body {
- font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
+ font: 16px/1.4 "Source Serif Pro", serif;
margin: 0;
position: relative;
padding: 10px 15px 20px 15px;
h1, h2, h3, h4,
.sidebar, a.source, .search-input, .content table :not(code)>a,
.collapse-toggle, div.item-list .out-of-band {
- font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-family: "Fira Sans", sans-serif;
}
ol, ul {
}
code, pre {
- font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace;
+ font-family: "Source Code Pro", monospace;
white-space: pre-wrap;
}
.docblock code, .docblock-short code {
}
#main > .since {
top: inherit;
- font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-family: "Fira Sans", sans-serif;
}
.content table:not(.table-display) {
kbd {
display: inline-block;
padding: 3px 5px;
- font: 15px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ font: 15px monospace;
line-height: 10px;
vertical-align: middle;
border: solid 1px;
/// For more information about select, see the `std::sync::mpsc::Select` structure.
#[macro_export]
#[unstable(feature = "mpsc_select", issue = "27800")]
+#[rustc_deprecated(since = "1.32.0",
+ reason = "channel selection will be removed in a future release")]
macro_rules! select {
(
$($name:pat = $rx:ident.$meth:ident() => $code:expr),+
//! ```
#![stable(feature = "rust1", since = "1.0.0")]
+#![allow(deprecated)] // for mpsc_select
// A description of how Rust's channel implementation works
//
#![unstable(feature = "mpsc_select",
reason = "This implementation, while likely sufficient, is unsafe and \
likely to be error prone. At some point in the future this \
- module will likely be replaced, and it is currently \
- unknown how much API breakage that will cause. The ability \
- to select over a number of channels will remain forever, \
- but no guarantees beyond this are being made",
+ module will be removed.",
issue = "27800")]
+#![rustc_deprecated(since = "1.32.0",
+ reason = "channel selection will be removed in a future release")]
use fmt;
/// A unary operation (For example: `!x`, `*x`)
Unary(UnOp, P<Expr>),
/// A literal (For example: `1`, `"foo"`)
- Lit(P<Lit>),
+ Lit(Lit),
/// A cast (`foo as f64`)
Cast(P<Expr>, P<Ty>),
Type(P<Expr>, P<Ty>),
pub fn raw_expr(sp: Span) -> P<ast::Expr> {
P(ast::Expr {
id: ast::DUMMY_NODE_ID,
- node: ast::ExprKind::Lit(P(source_map::respan(sp, ast::LitKind::Bool(false)))),
+ node: ast::ExprKind::Lit(source_map::respan(sp, ast::LitKind::Bool(false))),
span: sp,
attrs: ThinVec::new(),
})
}
fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P<ast::Expr> {
- self.expr(sp, ast::ExprKind::Lit(P(respan(sp, lit))))
+ self.expr(sp, ast::ExprKind::Lit(respan(sp, lit)))
}
fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> {
self.expr_lit(span, ast::LitKind::Int(i as u128,
// FIXME: This is wrong
P(ast::Expr {
id: ast::DUMMY_NODE_ID,
- node: ast::ExprKind::Lit(P(self.clone())),
+ node: ast::ExprKind::Lit(self.clone()),
span: DUMMY_SP,
attrs: ThinVec::new(),
}).to_tokens(cx)
let lit = ast::LitKind::Int(val as u128, ast::LitIntType::Signed($tag));
let lit = P(ast::Expr {
id: ast::DUMMY_NODE_ID,
- node: ast::ExprKind::Lit(P(dummy_spanned(lit))),
+ node: ast::ExprKind::Lit(dummy_spanned(lit)),
span: DUMMY_SP,
attrs: ThinVec::new(),
});
let minus_lo = self.span;
let minus_present = self.eat(&token::BinOp(token::Minus));
let lo = self.span;
- let literal = P(self.parse_lit()?);
+ let literal = self.parse_lit()?;
let hi = self.prev_span;
let expr = self.mk_expr(lo.to(hi), ExprKind::Lit(literal), ThinVec::new());
-Subproject commit 2717444753318e461e0c3b30dacd03ffbac96903
+Subproject commit 7f23313edff8beccb3fe44b815714269c5124c15
LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
const char* PGOGenPath, const char* PGOUsePath) {
-#if LLVM_RUSTLLVM
+#if LLVM_VERSION_GE(7, 0)
unwrap(PMBR)->MergeFunctions = MergeFunctions;
#endif
unwrap(PMBR)->SLPVectorize = SLPVectorize;
unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name));
}
+extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
+ LLVMValueRef Dst, unsigned DstAlign,
+ LLVMValueRef Src, unsigned SrcAlign,
+ LLVMValueRef Size, bool IsVolatile) {
+#if LLVM_VERSION_GE(7, 0)
+ return wrap(unwrap(B)->CreateMemCpy(
+ unwrap(Dst), DstAlign,
+ unwrap(Src), SrcAlign,
+ unwrap(Size), IsVolatile));
+#else
+ unsigned Align = std::min(DstAlign, SrcAlign);
+ return wrap(unwrap(B)->CreateMemCpy(
+ unwrap(Dst), unwrap(Src),
+ unwrap(Size), Align, IsVolatile));
+#endif
+}
+
+extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
+ LLVMValueRef Dst, unsigned DstAlign,
+ LLVMValueRef Src, unsigned SrcAlign,
+ LLVMValueRef Size, bool IsVolatile) {
+#if LLVM_VERSION_GE(7, 0)
+ return wrap(unwrap(B)->CreateMemMove(
+ unwrap(Dst), DstAlign,
+ unwrap(Src), SrcAlign,
+ unwrap(Size), IsVolatile));
+#else
+ unsigned Align = std::min(DstAlign, SrcAlign);
+ return wrap(unwrap(B)->CreateMemMove(
+ unwrap(Dst), unwrap(Src),
+ unwrap(Size), Align, IsVolatile));
+#endif
+}
+
extern "C" LLVMValueRef
LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
unsigned NumArgs, LLVMBasicBlockRef Then,
pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 1 %{{.*}}, i{{[0-9]+}} 32, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
// check that calls whose destination is a field of a packed struct
// go through an alloca rather than calling the function with an
// unaligned destination.
pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 2 %{{.*}}, i{{[0-9]+}} 32, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
// check that calls whose destination is a field of a packed struct
// go through an alloca rather than calling the function with an
// unaligned destination.
// CHECK: store i32 %0, i32* [[TMP]]
// CHECK: [[Y8:%[0-9]+]] = bitcast [4 x i8]* %y to i8*
// CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 4 [[TMP8]], i{{[0-9]+}} 4, i1 false)
*x = y;
}
// CHECK: store i32 %0, i32* [[TMP]]
// CHECK: [[Y8:%[0-9]+]] = bitcast %Bytes* %y to i8*
// CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 4 [[TMP8]], i{{[0-9]+}} 4, i1 false)
*x = y;
}
if self.0 == 1 {
panic!("panic 1");
} else {
- eprint!("drop {}", self.0);
+ eprintln!("drop {}", self.0);
}
}
}
fn main() {
panic::set_hook(Box::new(|i| {
- eprint!("greetings from the panic handler");
+ eprintln!("greetings from the panic handler");
}));
panic!("foobar");
}
assert_eq!(BE_U32, b(55u32).to_be());
assert_eq!(LE_U32, b(55u32).to_le());
- #[cfg(not(target_arch = "asmjs"))]
+ #[cfg(not(target_os = "emscripten"))]
{
const BE_U128: u128 = 999999u128.to_be();
const LE_I128: i128 = (-999999i128).to_le();
// expose is still present.
#![feature(mpsc_select)]
+#![allow(deprecated)]
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;
--- /dev/null
+// compile-pass
+
+// rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274
+// (for ensuring that NLL respects user-provided lifetime annotations)
+// did not handle the case where the ascribed type has some expliit
+// wildcards (`_`) mixed in, and it caused an internal compiler error
+// (ICE).
+//
+// This test is just checking that we do not ICE when such things
+// occur.
+
+struct X;
+struct Y;
+struct Z;
+
+struct Pair { x: X, y: Y }
+
+pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
+where A: FnOnce() -> RA + Send,
+ B: FnOnce() -> RB + Send,
+ RA: Send,
+ RB: Send
+{
+ (oper_a(), oper_b())
+}
+
+fn main() {
+ let ((_x, _y), _z): (_, Z) = join(|| (X, Y), || Z);
+
+ let (Pair { x: _x, y: _y }, Z): (_, Z) = join(|| Pair { x: X, y: Y }, || Z);
+}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- - impl<'_, T> std::marker::Copy for &T
+ - impl<T> std::marker::Copy for &T
where T: ?Sized;
error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- - impl<'_, T> std::marker::Copy for &T
+ - impl<T> std::marker::Copy for &T
where T: ?Sized;
error[E0206]: the trait `Copy` may not be implemented for this type
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- - impl<'_, T> std::ops::Deref for &T
+ - impl<T> std::ops::Deref for &T
where T: ?Sized;
error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<Foo>`)
--- /dev/null
+// Check extern items cannot be const + `rustfix` suggests using
+// extern static.
+//
+// #54388: an unused reference to an undefined static may or may not
+// compile. To sidestep this by using one that *is* defined.
+
+// run-rustfix
+// ignore-wasm32 no external library to link to.
+// compile-flags: -g -Z continue-parse-after-error
+#![feature(libc)]
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+ static rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
+}
+
+fn main() {
+ // We suggest turning the (illegal) extern `const` into an extern `static`,
+ // but this also requires `unsafe` (a deny-by-default lint at comment time,
+ // future error; Issue #36247)
+ unsafe {
+ let _x = rust_dbg_static_mut;
+ }
+}
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// Check extern items cannot be const + `rustfix` suggests using
+// extern static.
//
-// 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.
+// #54388: an unused reference to an undefined static may or may not
+// compile. To sidestep this by using one that *is* defined.
-// FIXME(#54388): re-enable rustfix later, when this test has consistent output across targets
-// compile-flags: -Z continue-parse-after-error
+// run-rustfix
+// ignore-wasm32 no external library to link to.
+// compile-flags: -g -Z continue-parse-after-error
+#![feature(libc)]
+extern crate libc;
+#[link(name = "rust_test_helpers", kind = "static")]
extern "C" {
- const C: u8; //~ ERROR extern items cannot be `const`
+ const rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
}
fn main() {
// but this also requires `unsafe` (a deny-by-default lint at comment time,
// future error; Issue #36247)
unsafe {
- let _x = C;
+ let _x = rust_dbg_static_mut;
}
}
error: extern items cannot be `const`
--> $DIR/extern-const.rs:15:5
|
-LL | const C: u8; //~ ERROR extern items cannot be `const`
+LL | const rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
| ^^^^^ help: try using a static value: `static`
error: aborting due to previous error
--- /dev/null
+// This used to ICE because it creates an `impl Trait` that captures a
+// hidden empty region.
+
+#![feature(conservative_impl_trait)]
+
+fn server() -> impl FilterBase2 { //~ ERROR [E0700]
+ segment2(|| { loop { } }).map2(|| "")
+}
+
+trait FilterBase2 {
+ fn map2<F>(self, _fn: F) -> Map2<F> where Self: Sized { loop { } }
+}
+
+struct Map2<F> { _func: F }
+
+impl<F> FilterBase2 for Map2<F> { }
+
+fn segment2<F>(_fn: F) -> Map2<F> where F: Fn() -> Result<(), ()> {
+ loop { }
+}
+
+fn main() { server(); }
--- /dev/null
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+ --> $DIR/issue-55608-captures-empty-region.rs:6:16
+ |
+LL | fn server() -> impl FilterBase2 { //~ ERROR [E0700]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: hidden type `Map2<[closure@$DIR/issue-55608-captures-empty-region.rs:7:36: 7:41]>` captures an empty lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
// Test that the compiler will catch invalid inline assembly constraints.
+// ignore-emscripten
+
#![feature(asm)]
extern "C" {
error[E0668]: malformed inline assembly
- --> $DIR/inline-asm-bad-constraint.rs:29:9
+ --> $DIR/inline-asm-bad-constraint.rs:31:9
|
LL | asm!("" :"={rax"(rax)) //~ ERROR E0668
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0668]: malformed inline assembly
- --> $DIR/inline-asm-bad-constraint.rs:37:9
+ --> $DIR/inline-asm-bad-constraint.rs:39:9
|
LL | asm!("callq $0" : : "0"(foo)) //~ ERROR E0668
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0668]: malformed inline assembly
- --> $DIR/inline-asm-bad-constraint.rs:44:9
+ --> $DIR/inline-asm-bad-constraint.rs:46:9
|
LL | asm!("addb $1, $0" : "={rax}"((0i32, rax))); //~ ERROR E0668
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Test that the compiler will catch passing invalid values to inline assembly
// operands.
+// ignore-emscripten
+
#![feature(asm)]
#[repr(C)]
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:29:24
+ --> $DIR/inline-asm-bad-operand.rs:31:24
|
LL | asm!("" :: "r"("")); //~ ERROR E0669
| ^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:34:32
+ --> $DIR/inline-asm-bad-operand.rs:36:32
|
LL | asm!("ret" : : "{rdi}"(target)); //~ ERROR E0669
| ^^^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:41:29
+ --> $DIR/inline-asm-bad-operand.rs:43:29
|
LL | unsafe { asm!("" :: "i"(hello)) }; //~ ERROR E0669
| ^^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:49:38
+ --> $DIR/inline-asm-bad-operand.rs:51:38
|
LL | asm!("movups $1, %xmm0"::"m"(arr)); //~ ERROR E0669
| ^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:56:32
+ --> $DIR/inline-asm-bad-operand.rs:58:32
|
LL | asm!("mov sp, $0"::"r"(addr)); //~ ERROR E0669
| ^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:63:32
+ --> $DIR/inline-asm-bad-operand.rs:65:32
|
LL | asm!("mov sp, $0"::"r"(addr), //~ ERROR E0669
| ^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:64:32
+ --> $DIR/inline-asm-bad-operand.rs:66:32
|
LL | "r"("hello e0669")); //~ ERROR E0669
| ^^^^^^^^^^^^^
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next`
+error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: std::marker::Sized`
--> $DIR/issue-23122-2.rs:17:15
|
LL | impl<T: Next> Next for GetNext<T> {
| ^^^^
|
= help: consider adding a `#![recursion_limit="128"]` attribute to your crate
+ = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
error: aborting due to previous error
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-
// compile-pass
+// ignore-emscripten no i128 support
#![feature(nll)]
--- /dev/null
+use std::path::Path;
+
+fn main() {
+ let path = Path::new("foo");
+ match path {
+ Path::new("foo") => println!("foo"),
+ //~^ ERROR expected tuple struct/variant
+ Path::new("bar") => println!("bar"),
+ //~^ ERROR expected tuple struct/variant
+ _ => (),
+ }
+}
--- /dev/null
+error[E0164]: expected tuple struct/variant, found method `<Path>::new`
+ --> $DIR/match-fn-call.rs:6:9
+ |
+LL | Path::new("foo") => println!("foo"),
+ | ^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error[E0164]: expected tuple struct/variant, found method `<Path>::new`
+ --> $DIR/match-fn-call.rs:8:9
+ |
+LL | Path::new("bar") => println!("bar"),
+ | ^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0164`.
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+
+#![feature(nll)]
+#![allow(unreachable_code)]
+#![deny(unused_mut)]
+
+pub fn foo() {
+ return;
+
+ let mut v = 0;
+ assert_eq!(v, 0);
+ v = 1;
+ assert_eq!(v, 1);
+}
+
+fn main() {}
use core::ops::RangeBounds;
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))]
#[lang = "eh_personality"]
extern fn eh_personality() {}
-Subproject commit 1fa30882067703202d13ad0bd53d630bc2c1de66
+Subproject commit 241fac0e3933063fa48a1a01f5d577e40af12e4d
} else {
self.fatal("no NodeJS binary found (--nodejs)");
}
- }
-
- // If this is otherwise wasm , then run tests under nodejs with our
+ // If this is otherwise wasm, then run tests under nodejs with our
// shim
- if self.config.target.contains("wasm32") {
+ } else if self.config.target.contains("wasm32") {
if let Some(ref p) = self.config.nodejs {
args.push(p.clone());
} else {
[features]
-all-static = ['openssl/vendored', 'curl-sys/static-curl']
+all-static = ['openssl/vendored', 'curl-sys/static-curl', 'curl-sys/force-system-lib-on-osx']