Skip to content

Commit

Permalink
Auto merge of #47682 - MaloJaffre:beta-backport, r=alexcrichton
Browse files Browse the repository at this point in the history
[beta] Backports

Cherry-picked into beta:
- #47401
- #47494
- #47503
- #47507
  • Loading branch information
bors committed Jan 23, 2018
2 parents c7037ff + 590924b commit ed9751a
Show file tree
Hide file tree
Showing 19 changed files with 374 additions and 84 deletions.
5 changes: 5 additions & 0 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,11 @@ static HOST_COMPILETESTS: &[Test] = &[
mode: "compile-fail",
suite: "compile-fail-fulldeps",
},
Test {
path: "src/test/incremental-fulldeps",
mode: "incremental",
suite: "incremental-fulldeps",
},
Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" },
Test { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" },

Expand Down
16 changes: 7 additions & 9 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
pub use self::code_stats::{CodeStats, DataTypeKind, FieldInfo};
pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo};

use hir::def_id::{CrateNum, DefIndex};
use hir::def_id::CrateNum;
use ich::Fingerprint;

use lint;
Expand Down Expand Up @@ -558,18 +558,16 @@ impl Session {

/// Returns the symbol name for the registrar function,
/// given the crate Svh and the function DefIndex.
pub fn generate_plugin_registrar_symbol(&self, disambiguator: CrateDisambiguator,
index: DefIndex)
pub fn generate_plugin_registrar_symbol(&self,
disambiguator: CrateDisambiguator)
-> String {
format!("__rustc_plugin_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
index.as_usize())
format!("__rustc_plugin_registrar_{}__", disambiguator.to_fingerprint().to_hex())
}

pub fn generate_derive_registrar_symbol(&self, disambiguator: CrateDisambiguator,
index: DefIndex)
pub fn generate_derive_registrar_symbol(&self,
disambiguator: CrateDisambiguator)
-> String {
format!("__rustc_derive_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
index.as_usize())
format!("__rustc_derive_registrar_{}__", disambiguator.to_fingerprint().to_hex())
}

pub fn sysroot<'a>(&'a self) -> &'a Path {
Expand Down
16 changes: 7 additions & 9 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use locator::{self, CratePaths};
use native_libs::relevant_lib;
use schema::CrateRoot;

use rustc::hir::def_id::{CrateNum, DefIndex, CRATE_DEF_INDEX};
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX};
use rustc::hir::svh::Svh;
use rustc::middle::allocator::AllocatorKind;
use rustc::middle::cstore::DepKind;
Expand Down Expand Up @@ -532,8 +532,7 @@ impl<'a> CrateLoader<'a> {
Err(err) => self.sess.span_fatal(span, &err),
};

let sym = self.sess.generate_derive_registrar_symbol(root.disambiguator,
root.macro_derive_registrar.unwrap());
let sym = self.sess.generate_derive_registrar_symbol(root.disambiguator);
let registrar = unsafe {
let sym = match lib.symbol(&sym) {
Ok(f) => f,
Expand Down Expand Up @@ -588,7 +587,7 @@ impl<'a> CrateLoader<'a> {
pub fn find_plugin_registrar(&mut self,
span: Span,
name: &str)
-> Option<(PathBuf, CrateDisambiguator, DefIndex)> {
-> Option<(PathBuf, CrateDisambiguator)> {
let name = Symbol::intern(name);
let ekrate = self.read_extension_crate(span, name, name);

Expand All @@ -603,11 +602,11 @@ impl<'a> CrateLoader<'a> {
}

let root = ekrate.metadata.get_root();
match (ekrate.dylib.as_ref(), root.plugin_registrar_fn) {
(Some(dylib), Some(reg)) => {
Some((dylib.to_path_buf(), root.disambiguator, reg))
match ekrate.dylib.as_ref() {
Some(dylib) => {
Some((dylib.to_path_buf(), root.disambiguator))
}
(None, Some(_)) => {
None => {
span_err!(self.sess, span, E0457,
"plugin `{}` only found in rlib format, but must be available \
in dylib format",
Expand All @@ -616,7 +615,6 @@ impl<'a> CrateLoader<'a> {
// empty dylib.
None
}
_ => None,
}
}

Expand Down
74 changes: 51 additions & 23 deletions src/librustc_mir/build/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,50 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
}

/// Convert a byte array or byte slice to a byte slice.
fn to_slice_operand(&mut self,
block: BasicBlock,
source_info: SourceInfo,
operand: Operand<'tcx>)
-> Operand<'tcx>
{
let tcx = self.hir.tcx();
let ty = operand.ty(&self.local_decls, tcx);
debug!("to_slice_operand({:?}, {:?}: {:?})", block, operand, ty);
match ty.sty {
ty::TyRef(region, mt) => match mt.ty.sty {
ty::TyArray(ety, _) => {
let ty = tcx.mk_imm_ref(region, tcx.mk_slice(ety));
let temp = self.temp(ty, source_info.span);
self.cfg.push_assign(block, source_info, &temp,
Rvalue::Cast(CastKind::Unsize, operand, ty));
Operand::Move(temp)
}
ty::TySlice(_) => operand,
_ => {
span_bug!(source_info.span,
"bad operand {:?}: {:?} to `to_slice_operand`", operand, ty)
}
}
_ => {
span_bug!(source_info.span,
"bad operand {:?}: {:?} to `to_slice_operand`", operand, ty)
}
}

}

/// Generates the code to perform a test.
pub fn perform_test(&mut self,
block: BasicBlock,
place: &Place<'tcx>,
test: &Test<'tcx>)
-> Vec<BasicBlock> {
debug!("perform_test({:?}, {:?}: {:?}, {:?})",
block,
place,
place.ty(&self.local_decls, self.hir.tcx()),
test);
let source_info = self.source_info(test.span);
match test.kind {
TestKind::Switch { adt_def, ref variants } => {
Expand Down Expand Up @@ -258,45 +296,35 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ret
}

TestKind::Eq { value, mut ty } => {
TestKind::Eq { value, ty } => {
let tcx = self.hir.tcx();
let mut val = Operand::Copy(place.clone());

// If we're using b"..." as a pattern, we need to insert an
// unsizing coercion, as the byte string has the type &[u8; N].
let expect = if let ConstVal::ByteStr(bytes) = value.val {
let tcx = self.hir.tcx();

// Unsize the place to &[u8], too, if necessary.
if let ty::TyRef(region, mt) = ty.sty {
if let ty::TyArray(_, _) = mt.ty.sty {
ty = tcx.mk_imm_ref(region, tcx.mk_slice(tcx.types.u8));
let val_slice = self.temp(ty, test.span);
self.cfg.push_assign(block, source_info, &val_slice,
Rvalue::Cast(CastKind::Unsize, val, ty));
val = Operand::Move(val_slice);
}
}

assert!(ty.is_slice());

//
// We want to do this even when the scrutinee is a reference to an
// array, so we can call `<[u8]>::eq` rather than having to find an
// `<[u8; N]>::eq`.
let (expect, val) = if let ConstVal::ByteStr(bytes) = value.val {
let array_ty = tcx.mk_array(tcx.types.u8, bytes.data.len() as u64);
let array_ref = tcx.mk_imm_ref(tcx.types.re_static, array_ty);
let array = self.literal_operand(test.span, array_ref, Literal::Value {
value
});

let slice = self.temp(ty, test.span);
self.cfg.push_assign(block, source_info, &slice,
Rvalue::Cast(CastKind::Unsize, array, ty));
Operand::Move(slice)
let val = self.to_slice_operand(block, source_info, val);
let slice = self.to_slice_operand(block, source_info, array);
(slice, val)
} else {
self.literal_operand(test.span, ty, Literal::Value {
(self.literal_operand(test.span, ty, Literal::Value {
value
})
}), val)
};

// Use PartialEq::eq for &str and &[u8] slices, instead of BinOp::Eq.
let fail = self.cfg.start_new_block();
let ty = expect.ty(&self.local_decls, tcx);
if let ty::TyRef(_, mt) = ty.sty {
assert!(ty.is_slice());
let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_plugin/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ impl<'a> PluginLoader<'a> {
fn load_plugin(&mut self, span: Span, name: &str, args: Vec<ast::NestedMetaItem>) {
let registrar = self.reader.find_plugin_registrar(span, name);

if let Some((lib, disambiguator, index)) = registrar {
let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator, index);
if let Some((lib, disambiguator)) = registrar {
let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
let fun = self.dylink_registrar(span, lib, symbol);
self.plugins.push(PluginRegistrar {
fun,
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_trans/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,6 @@ impl<'a, 'tcx> ArgType<'tcx> {
}

pub fn store_fn_arg(&self, bcx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) {
if self.pad.is_some() {
*idx += 1;
}
let mut next = || {
let val = llvm::get_param(bcx.llfn(), *idx as c_uint);
*idx += 1;
Expand Down
72 changes: 60 additions & 12 deletions src/librustc_trans/back/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,34 @@
use std::ffi::{OsStr, OsString};
use std::fmt;
use std::io;
use std::mem;
use std::process::{self, Output, Child};

#[derive(Clone)]
pub struct Command {
program: OsString,
program: Program,
args: Vec<OsString>,
env: Vec<(OsString, OsString)>,
}

#[derive(Clone)]
enum Program {
Normal(OsString),
CmdBatScript(OsString),
}

impl Command {
pub fn new<P: AsRef<OsStr>>(program: P) -> Command {
Command::_new(program.as_ref())
Command::_new(Program::Normal(program.as_ref().to_owned()))
}

pub fn bat_script<P: AsRef<OsStr>>(program: P) -> Command {
Command::_new(Program::CmdBatScript(program.as_ref().to_owned()))
}

fn _new(program: &OsStr) -> Command {
fn _new(program: Program) -> Command {
Command {
program: program.to_owned(),
program,
args: Vec::new(),
env: Vec::new(),
}
Expand Down Expand Up @@ -86,24 +98,60 @@ impl Command {
}

pub fn command(&self) -> process::Command {
let mut ret = process::Command::new(&self.program);
let mut ret = match self.program {
Program::Normal(ref p) => process::Command::new(p),
Program::CmdBatScript(ref p) => {
let mut c = process::Command::new("cmd");
c.arg("/c").arg(p);
c
}
};
ret.args(&self.args);
ret.envs(self.env.clone());
return ret
}

// extensions

pub fn get_program(&self) -> &OsStr {
&self.program
pub fn take_args(&mut self) -> Vec<OsString> {
mem::replace(&mut self.args, Vec::new())
}

pub fn get_args(&self) -> &[OsString] {
&self.args
}
/// Returns a `true` if we're pretty sure that this'll blow OS spawn limits,
/// or `false` if we should attempt to spawn and see what the OS says.
pub fn very_likely_to_exceed_some_spawn_limit(&self) -> bool {
// We mostly only care about Windows in this method, on Unix the limits
// can be gargantuan anyway so we're pretty unlikely to hit them
if cfg!(unix) {
return false
}

pub fn get_env(&self) -> &[(OsString, OsString)] {
&self.env
// Ok so on Windows to spawn a process is 32,768 characters in its
// command line [1]. Unfortunately we don't actually have access to that
// as it's calculated just before spawning. Instead we perform a
// poor-man's guess as to how long our command line will be. We're
// assuming here that we don't have to escape every character...
//
// Turns out though that `cmd.exe` has even smaller limits, 8192
// characters [2]. Linkers can often be batch scripts (for example
// Emscripten, Gecko's current build system) which means that we're
// running through batch scripts. These linkers often just forward
// arguments elsewhere (and maybe tack on more), so if we blow 8192
// bytes we'll typically cause them to blow as well.
//
// Basically as a result just perform an inflated estimate of what our
// command line will look like and test if it's > 8192 (we actually
// test against 6k to artificially inflate our estimate). If all else
// fails we'll fall back to the normal unix logic of testing the OS
// error code if we fail to spawn and automatically re-spawning the
// linker with smaller arguments.
//
// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
// [2]: https://blogs.msdn.microsoft.com/oldnewthing/20031210-00/?p=41553

let estimated_command_line_len =
self.args.iter().map(|a| a.len()).sum::<usize>();
estimated_command_line_len > 1024 * 6
}
}

Expand Down
Loading

0 comments on commit ed9751a

Please sign in to comment.