From c8292fcd6ad2a06d2529f5dcea4b9133930211b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20CORTIER?= Date: Wed, 15 Feb 2017 13:44:52 +0100 Subject: [PATCH 01/11] Correct a typo in procedural macros chapter of the Book. --- src/doc/book/src/procedural-macros.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/src/procedural-macros.md b/src/doc/book/src/procedural-macros.md index d286c3b7bdc63..334f5e8d6567b 100644 --- a/src/doc/book/src/procedural-macros.md +++ b/src/doc/book/src/procedural-macros.md @@ -169,7 +169,7 @@ So this is where quotes comes in. The `ast` argument is a struct that gives us a representation of our type (which can be either a `struct` or an `enum`). Check out the [docs](https://docs.rs/syn/0.10.5/syn/struct.MacroInput.html), there is some useful information there. We are able to get the name of the -type using `ast.ident`. The `quote!` macro let's us write up the Rust code +type using `ast.ident`. The `quote!` macro let us write up the Rust code that we wish to return and convert it into `Tokens`. `quote!` let's us use some really cool templating mechanics; we simply write `#name` and `quote!` will replace it with the variable named `name`. You can even do some repetition From 4a3c66ad2f4211137fcb98a31d1e1033d5765e22 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 15 Feb 2017 21:21:36 +0200 Subject: [PATCH 02/11] [MIR] Make InlineAsm a Statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously InlineAsm was an Rvalue, but its semantics doesn’t really match the semantics of an Rvalue – rather it behaves more like a Statement. --- src/librustc/mir/mod.rs | 21 +++++++++---------- src/librustc/mir/tcx.rs | 1 - src/librustc/mir/visit.rs | 21 +++++++++---------- .../borrowck/mir/dataflow/impls.rs | 1 + .../borrowck/mir/dataflow/sanity_check.rs | 1 + .../borrowck/mir/gather_moves.rs | 4 ++-- src/librustc_borrowck/borrowck/mir/mod.rs | 1 + src/librustc_mir/build/expr/as_rvalue.rs | 16 +------------- src/librustc_mir/build/expr/into.rs | 2 +- src/librustc_mir/build/expr/stmt.rs | 17 +++++++++++++++ src/librustc_mir/transform/qualify_consts.rs | 5 +---- src/librustc_mir/transform/type_check.rs | 5 +++-- src/librustc_passes/mir_stats.rs | 2 +- src/librustc_trans/mir/constant.rs | 3 ++- src/librustc_trans/mir/rvalue.rs | 21 ++----------------- src/librustc_trans/mir/statement.rs | 14 +++++++++++++ 16 files changed, 67 insertions(+), 68 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d8212807eb277..3403cf0477450 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -777,6 +777,12 @@ pub enum StatementKind<'tcx> { /// End the current live range for the storage of the local. StorageDead(Lvalue<'tcx>), + InlineAsm { + asm: InlineAsm, + outputs: Vec>, + inputs: Vec> + }, + /// No-op. Useful for deleting instructions without affecting statement indices. Nop, } @@ -790,7 +796,10 @@ impl<'tcx> Debug for Statement<'tcx> { StorageDead(ref lv) => write!(fmt, "StorageDead({:?})", lv), SetDiscriminant{lvalue: ref lv, variant_index: index} => { write!(fmt, "discriminant({:?}) = {:?}", lv, index) - } + }, + InlineAsm { ref asm, ref outputs, ref inputs } => { + write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs) + }, Nop => write!(fmt, "nop"), } } @@ -1004,12 +1013,6 @@ pub enum Rvalue<'tcx> { /// that `Foo` has a destructor. These rvalues can be optimized /// away after type-checking and before lowering. Aggregate(AggregateKind<'tcx>, Vec>), - - InlineAsm { - asm: InlineAsm, - outputs: Vec>, - inputs: Vec> - } } #[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] @@ -1111,10 +1114,6 @@ impl<'tcx> Debug for Rvalue<'tcx> { UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a), Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval), Box(ref t) => write!(fmt, "Box({:?})", t), - InlineAsm { ref asm, ref outputs, ref inputs } => { - write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs) - } - Ref(_, borrow_kind, ref lv) => { let kind_str = match borrow_kind { BorrowKind::Shared => "", diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 7b0863b4c42bc..5c8d031caf60d 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -207,7 +207,6 @@ impl<'tcx> Rvalue<'tcx> { } } } - Rvalue::InlineAsm { .. } => None } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index be3c43db7badd..7cdbd5cae061f 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -333,6 +333,16 @@ macro_rules! make_mir_visitor { StatementKind::StorageDead(ref $($mutability)* lvalue) => { self.visit_lvalue(lvalue, LvalueContext::StorageDead, location); } + StatementKind::InlineAsm { ref $($mutability)* outputs, + ref $($mutability)* inputs, + asm: _ } => { + for output in & $($mutability)* outputs[..] { + self.visit_lvalue(output, LvalueContext::Store, location); + } + for input in & $($mutability)* inputs[..] { + self.visit_operand(input, location); + } + } StatementKind::Nop => {} } } @@ -526,17 +536,6 @@ macro_rules! make_mir_visitor { self.visit_operand(operand, location); } } - - Rvalue::InlineAsm { ref $($mutability)* outputs, - ref $($mutability)* inputs, - asm: _ } => { - for output in & $($mutability)* outputs[..] { - self.visit_lvalue(output, LvalueContext::Store, location); - } - for input in & $($mutability)* inputs[..] { - self.visit_operand(input, location); - } - } } } diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs index 1fa4da94dd6bf..7888a56d39dfb 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs @@ -473,6 +473,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> { } mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::Nop => {} } } diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs index ea6ef423c92ce..940dd5433a0d9 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs @@ -104,6 +104,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::Nop => continue, mir::StatementKind::SetDiscriminant{ .. } => span_bug!(stmt.source_info.span, diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 0c7e922c48ab4..35ace6628cfed 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -412,6 +412,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { span_bug!(stmt.source_info.span, "SetDiscriminant should not exist during borrowck"); } + StatementKind::InlineAsm { .. } | StatementKind::Nop => {} } } @@ -436,8 +437,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { } Rvalue::Ref(..) | Rvalue::Discriminant(..) | - Rvalue::Len(..) | - Rvalue::InlineAsm { .. } => {} + Rvalue::Len(..) => {} Rvalue::Box(..) => { // This returns an rvalue with uninitialized contents. We can't // move out of it here because it is an rvalue - assignments always diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index a0c36139ddcd2..d9283e7037f50 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -378,6 +378,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>( } mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::Nop => {} }, None => { diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index dad1d713168cd..7adcc0e730b15 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -49,21 +49,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Scope { extent, value } => { this.in_scope(extent, block, |this| this.as_rvalue(block, value)) } - ExprKind::InlineAsm { asm, outputs, inputs } => { - let outputs = outputs.into_iter().map(|output| { - unpack!(block = this.as_lvalue(block, output)) - }).collect(); - - let inputs = inputs.into_iter().map(|input| { - unpack!(block = this.as_operand(block, input)) - }).collect(); - - block.and(Rvalue::InlineAsm { - asm: asm.clone(), - outputs: outputs, - inputs: inputs - }) - } ExprKind::Repeat { value, count } => { let value_operand = unpack!(block = this.as_operand(block, value)); block.and(Rvalue::Repeat(value_operand, count)) @@ -238,6 +223,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } | + ExprKind::InlineAsm { .. } | ExprKind::StaticRef { .. } => { // these do not have corresponding `Rvalue` variants, // so make an operand and then return that diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 35841c2cbdf01..e66f2b4e2bfc0 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -232,6 +232,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::AssignOp { .. } | ExprKind::Continue { .. } | ExprKind::Break { .. } | + ExprKind::InlineAsm { .. } | ExprKind::Return {.. } => { this.stmt_expr(block, expr) } @@ -257,7 +258,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Literal { .. } | - ExprKind::InlineAsm { .. } | ExprKind::Field { .. } => { debug_assert!(match Category::of(&expr.kind).unwrap() { Category::Rvalue(RvalueFunc::Into) => false, diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index f04d630379a35..c577aab40dbeb 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -117,6 +117,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { this.exit_scope(expr_span, extent, block, return_block); this.cfg.start_new_block().unit() } + ExprKind::InlineAsm { asm, outputs, inputs } => { + let outputs = outputs.into_iter().map(|output| { + unpack!(block = this.as_lvalue(block, output)) + }).collect(); + let inputs = inputs.into_iter().map(|input| { + unpack!(block = this.as_operand(block, input)) + }).collect(); + this.cfg.push(block, Statement { + source_info: source_info, + kind: StatementKind::InlineAsm { + asm: asm.clone(), + outputs: outputs, + inputs: inputs + }, + }); + block.unit() + } _ => { let expr_ty = expr.ty; let temp = this.temp(expr.ty.clone()); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 922521726c626..4459142cfb274 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -774,10 +774,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } } } - - Rvalue::InlineAsm {..} => { - self.not_const(); - } } } @@ -933,6 +929,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | + StatementKind::InlineAsm {..} | StatementKind::Nop => {} } }); diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 8ede7aaab5f68..8d108815e0f3c 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -361,9 +361,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}", lv_ty, rv_ty, terr); } - // FIXME: rvalue with undeterminable type - e.g. inline - // asm. } + // FIXME: rvalue with undeterminable type - e.g. AggregateKind::Array branch that + // returns `None`. } StatementKind::SetDiscriminant{ ref lvalue, variant_index } => { let lvalue_type = lvalue.ty(mir, tcx).to_ty(tcx); @@ -392,6 +392,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } } + StatementKind::InlineAsm { .. } | StatementKind::Nop => {} } } diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index 517a472056334..33b7089c38214 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -128,6 +128,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { StatementKind::SetDiscriminant { .. } => "StatementKind::SetDiscriminant", StatementKind::StorageLive(..) => "StatementKind::StorageLive", StatementKind::StorageDead(..) => "StatementKind::StorageDead", + StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm", StatementKind::Nop => "StatementKind::Nop", }, &statement.kind); self.super_statement(block, statement, location); @@ -198,7 +199,6 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { "Rvalue::Aggregate" } - Rvalue::InlineAsm { .. } => "Rvalue::InlineAsm", }; self.record(rvalue_kind, rvalue); self.super_rvalue(rvalue, location); diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 19139301bb0c4..7e17ae5f1d389 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -287,8 +287,9 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | mir::StatementKind::Nop => {} + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::SetDiscriminant{ .. } => { - span_bug!(span, "SetDiscriminant should not appear in constants?"); + span_bug!(span, "{:?} should not appear in constants?", statement.kind); } } } diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 38ee67796c6de..7d4f542addbb1 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -16,7 +16,6 @@ use rustc::mir::tcx::LvalueTy; use rustc::mir; use middle::lang_items::ExchangeMallocFnLangItem; -use asm; use base; use builder::Builder; use callee::Callee; @@ -156,20 +155,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { bcx } - mir::Rvalue::InlineAsm { ref asm, ref outputs, ref inputs } => { - let outputs = outputs.iter().map(|output| { - let lvalue = self.trans_lvalue(&bcx, output); - (lvalue.llval, lvalue.ty.to_ty(bcx.tcx())) - }).collect(); - - let input_vals = inputs.iter().map(|input| { - self.trans_operand(&bcx, input).immediate() - }).collect(); - - asm::trans_inline_asm(&bcx, asm, outputs, input_vals); - bcx - } - _ => { assert!(rvalue_creates_operand(rvalue)); let (bcx, temp) = self.trans_rvalue_operand(bcx, rvalue); @@ -468,8 +453,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { (bcx, operand) } mir::Rvalue::Repeat(..) | - mir::Rvalue::Aggregate(..) | - mir::Rvalue::InlineAsm { .. } => { + mir::Rvalue::Aggregate(..) => { bug!("cannot generate operand from rvalue {:?}", rvalue); } @@ -669,8 +653,7 @@ pub fn rvalue_creates_operand(rvalue: &mir::Rvalue) -> bool { mir::Rvalue::Use(..) => true, mir::Rvalue::Repeat(..) | - mir::Rvalue::Aggregate(..) | - mir::Rvalue::InlineAsm { .. } => + mir::Rvalue::Aggregate(..) => false, } diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs index 48fc9720e4b83..29a0648c8f8f8 100644 --- a/src/librustc_trans/mir/statement.rs +++ b/src/librustc_trans/mir/statement.rs @@ -11,6 +11,7 @@ use rustc::mir; use base; +use asm; use common; use builder::Builder; @@ -73,6 +74,19 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::StatementKind::StorageDead(ref lvalue) => { self.trans_storage_liveness(bcx, lvalue, base::Lifetime::End) } + mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => { + let outputs = outputs.iter().map(|output| { + let lvalue = self.trans_lvalue(&bcx, output); + (lvalue.llval, lvalue.ty.to_ty(bcx.tcx())) + }).collect(); + + let input_vals = inputs.iter().map(|input| { + self.trans_operand(&bcx, input).immediate() + }).collect(); + + asm::trans_inline_asm(&bcx, asm, outputs, input_vals); + bcx + } mir::StatementKind::Nop => bcx, } } From d22891eb3ef50c30e5ac8b5f891ffaa0963963b7 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 15 Feb 2017 17:00:41 -0500 Subject: [PATCH 03/11] cleanup: remove the *san Cargo features from std these belong to a previous iteration of the sanitizer implementation --- src/bootstrap/lib.rs | 2 +- src/libstd/Cargo.toml | 12 ++++-------- src/rustc/std_shim/Cargo.toml | 4 ---- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 7bd611eb53e3c..218a9fa732087 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -602,7 +602,7 @@ impl Build { /// Get the space-separated set of activated features for the standard /// library. fn std_features(&self) -> String { - let mut features = "panic-unwind asan lsan msan tsan".to_string(); + let mut features = "panic-unwind".to_string(); if self.config.debug_jemalloc { features.push_str(" debug-jemalloc"); diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 2ba7517d3d202..46511452a7237 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,22 +24,18 @@ std_unicode = { path = "../libstd_unicode" } unwind = { path = "../libunwind" } [target.x86_64-unknown-linux-gnu.dependencies] -rustc_asan = { path = "../librustc_asan", optional = true } -rustc_lsan = { path = "../librustc_lsan", optional = true } -rustc_msan = { path = "../librustc_msan", optional = true } -rustc_tsan = { path = "../librustc_tsan", optional = true } +rustc_asan = { path = "../librustc_asan" } +rustc_lsan = { path = "../librustc_lsan" } +rustc_msan = { path = "../librustc_msan" } +rustc_tsan = { path = "../librustc_tsan" } [build-dependencies] build_helper = { path = "../build_helper" } gcc = "0.3.27" [features] -asan = ["rustc_asan"] backtrace = [] debug-jemalloc = ["alloc_jemalloc/debug"] jemalloc = ["alloc_jemalloc"] force_alloc_system = [] -lsan = ["rustc_lsan"] -msan = ["rustc_msan"] panic-unwind = ["panic_unwind"] -tsan = ["rustc_tsan"] diff --git a/src/rustc/std_shim/Cargo.toml b/src/rustc/std_shim/Cargo.toml index db96079d3e916..14c9c5544b188 100644 --- a/src/rustc/std_shim/Cargo.toml +++ b/src/rustc/std_shim/Cargo.toml @@ -35,12 +35,8 @@ core = { path = "../../libcore" } # Reexport features from std [features] -asan = ["std/asan"] backtrace = ["std/backtrace"] debug-jemalloc = ["std/debug-jemalloc"] jemalloc = ["std/jemalloc"] force_alloc_system = ["std/force_alloc_system"] -lsan = ["std/lsan"] -msan = ["std/msan"] panic-unwind = ["std/panic-unwind"] -tsan = ["std/tsan"] From 1fbbe79bcb97cc85dfe5f6c431b7aca9784a9bd4 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Wed, 15 Feb 2017 23:26:29 +0100 Subject: [PATCH 04/11] Fix wording in LocalKey documentation --- src/libstd/sync/once.rs | 2 +- src/libstd/thread/local.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index ba99375139139..1e7394c0b09e7 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -316,7 +316,7 @@ impl Once { } // Once we've enqueued ourselves, wait in a loop. - // Aftewards reload the state and continue with what we + // Afterwards reload the state and continue with what we // were doing from before. while !node.signaled.load(Ordering::SeqCst) { thread::park(); diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 5166ddf8a21b6..66f09a7069c13 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -28,8 +28,8 @@ use mem; /// # Initialization and Destruction /// /// Initialization is dynamically performed on the first call to `with()` -/// within a thread, and values support destructors which will be run when a -/// thread exits. +/// within a thread, and values that implement `Drop` get destructed when a +/// thread exits. Some caveats apply, which are explained below. /// /// # Examples /// From ab57e7b86817b8ca9b7e6afb2f689ae67274ec7c Mon Sep 17 00:00:00 2001 From: Amos Onn Date: Thu, 16 Feb 2017 02:16:41 +0100 Subject: [PATCH 05/11] std::io::cursor Added test for seeking beyond i64. --- src/libstd/io/cursor.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 0cff8661d8871..9427e4afa2142 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -526,6 +526,43 @@ mod tests { assert_eq!(r.write(&[3]).unwrap(), 0); } + #[test] + fn seek_past_i64() { + let buf = [0xff]; + let mut r = Cursor::new(&buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut buf = [0]; + let mut r = Cursor::new(&mut buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10].into_boxed_slice()); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + } + #[test] fn seek_before_0() { let buf = [0xff]; From ebf70a9a206e3ecff7d442a7edf297731e9fe042 Mon Sep 17 00:00:00 2001 From: Shawn Walker-Salas Date: Wed, 15 Feb 2017 17:48:20 -0800 Subject: [PATCH 06/11] libstd needs update for pending libc change Fixes #39868 --- src/libstd/sys/unix/os.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 6992a17832e41..1dbfa640d5251 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -483,7 +483,6 @@ pub fn home_dir() -> Option { target_os = "nacl", target_os = "emscripten")))] unsafe fn fallback() -> Option { - #[cfg(not(target_os = "solaris"))] unsafe fn getpwduid_r(me: libc::uid_t, passwd: &mut libc::passwd, buf: &mut Vec) -> Option<()> { let mut result = ptr::null_mut(); @@ -495,16 +494,6 @@ pub fn home_dir() -> Option { } } - #[cfg(target_os = "solaris")] - unsafe fn getpwduid_r(me: libc::uid_t, passwd: &mut libc::passwd, - buf: &mut Vec) -> Option<()> { - // getpwuid_r semantics is different on Illumos/Solaris: - // http://illumos.org/man/3c/getpwuid_r - let result = libc::getpwuid_r(me, passwd, buf.as_mut_ptr(), - buf.capacity()); - if result.is_null() { None } else { Some(()) } - } - let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { n if n < 0 => 512 as usize, n => n as usize, From a2d176e8f4774b84db22540a45eed7b29482f154 Mon Sep 17 00:00:00 2001 From: Amos Onn Date: Thu, 16 Feb 2017 02:21:08 +0100 Subject: [PATCH 07/11] std::io::cursor: Fixed Seek so test passes. --- src/libstd/io/cursor.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 9427e4afa2142..60767ea478661 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -200,18 +200,20 @@ impl Cursor { #[stable(feature = "rust1", since = "1.0.0")] impl io::Seek for Cursor where T: AsRef<[u8]> { fn seek(&mut self, style: SeekFrom) -> io::Result { - let pos = match style { - SeekFrom::Start(n) => { self.pos = n; return Ok(n) } - SeekFrom::End(n) => self.inner.as_ref().len() as i64 + n, - SeekFrom::Current(n) => self.pos as i64 + n, + let (base_pos, offset) = match style { + SeekFrom::Start(n) => { self.pos = n; return Ok(n); } + SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), + SeekFrom::Current(n) => (self.pos, n), }; - - if pos < 0 { - Err(Error::new(ErrorKind::InvalidInput, - "invalid seek to a negative position")) + let new_pos = if offset >= 0 { + base_pos.checked_add(offset as u64) } else { - self.pos = pos as u64; - Ok(self.pos) + base_pos.checked_sub((offset.wrapping_neg()) as u64) + }; + match new_pos { + Some(n) => {self.pos = n; Ok(self.pos)} + None => Err(Error::new(ErrorKind::InvalidInput, + "invalid seek to a negative or overflowing position")) } } } From 57895393115c61ec01fcbc9815f9821b2bfe5886 Mon Sep 17 00:00:00 2001 From: Shawn Walker-Salas Date: Wed, 15 Feb 2017 22:52:47 -0800 Subject: [PATCH 08/11] simplify home_dir by removing unnecessary getpwuid_r wrapper --- src/libstd/sys/unix/os.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 1dbfa640d5251..e78928c266792 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -483,30 +483,21 @@ pub fn home_dir() -> Option { target_os = "nacl", target_os = "emscripten")))] unsafe fn fallback() -> Option { - unsafe fn getpwduid_r(me: libc::uid_t, passwd: &mut libc::passwd, - buf: &mut Vec) -> Option<()> { - let mut result = ptr::null_mut(); - match libc::getpwuid_r(me, passwd, buf.as_mut_ptr(), - buf.capacity(), - &mut result) { - 0 if !result.is_null() => Some(()), - _ => None - } - } - let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { n if n < 0 => 512 as usize, n => n as usize, }; let mut buf = Vec::with_capacity(amt); let mut passwd: libc::passwd = mem::zeroed(); - - if getpwduid_r(libc::getuid(), &mut passwd, &mut buf).is_some() { - let ptr = passwd.pw_dir as *const _; - let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); - Some(OsStringExt::from_vec(bytes)) - } else { - None + let mut result = ptr::null_mut(); + match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(), + buf.capacity(), &mut result) { + 0 if !result.is_null() => { + let ptr = passwd.pw_dir as *const _; + let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); + Some(OsStringExt::from_vec(bytes)) + }, + _ => None, } } } From 36b00cf217f354b9169cc5c529642bfd958295a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20CORTIER?= Date: Thu, 16 Feb 2017 09:18:19 +0100 Subject: [PATCH 09/11] Correct a typo in procedural macros chapter of the Book. (fixup [c8292fcd6ad2a06d2529f5]) --- src/doc/book/src/procedural-macros.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/src/procedural-macros.md b/src/doc/book/src/procedural-macros.md index 334f5e8d6567b..df49c70aada73 100644 --- a/src/doc/book/src/procedural-macros.md +++ b/src/doc/book/src/procedural-macros.md @@ -169,7 +169,7 @@ So this is where quotes comes in. The `ast` argument is a struct that gives us a representation of our type (which can be either a `struct` or an `enum`). Check out the [docs](https://docs.rs/syn/0.10.5/syn/struct.MacroInput.html), there is some useful information there. We are able to get the name of the -type using `ast.ident`. The `quote!` macro let us write up the Rust code +type using `ast.ident`. The `quote!` macro lets us write up the Rust code that we wish to return and convert it into `Tokens`. `quote!` let's us use some really cool templating mechanics; we simply write `#name` and `quote!` will replace it with the variable named `name`. You can even do some repetition From 0e45a5ed3f79338656b19a41172d3a7761586ebc Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 16 Feb 2017 20:52:56 +0200 Subject: [PATCH 10/11] [rustbuild] add a way to run command after failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a simple way to workaround the debugging issues caused by the rustc wrapper used in the bootstrap process. Namely, it uses some obscure environment variables and you can’t just copy the failed command and run it in the shell or debugger to examine the failure more closely. With `--on-fail` its possible to run an arbitrary command within exactly the same environment under which rustc failed. Theres’s multiple ways to use this new flag: $ python x.py build --stage=1 --on-fail=env would print a list of environment variables and the failed command, so a few copy-pastes and you now can run the same rust in your shell outside the bootstrap system. $ python x.py build --stage=1 --on-fail=bash Is a more useful variation of the command above in that it launches a whole shell with environment already in place! All that’s left to do is copy-paste the command just above the shell prompt! Fixes #38686 Fixes #38221 --- src/bootstrap/bin/rustc.rs | 18 +++++++++++++++--- src/bootstrap/flags.rs | 3 +++ src/bootstrap/lib.rs | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 90fd31ecbdd73..bf1da57607d5f 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -68,6 +68,7 @@ fn main() { }; let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); + let mut on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of)); let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); @@ -212,9 +213,20 @@ fn main() { } // Actually run the compiler! - std::process::exit(match exec_cmd(&mut cmd) { - Ok(s) => s.code().unwrap_or(0xfe), - Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), + std::process::exit(if let Some(ref mut on_fail) = on_fail { + match cmd.status() { + Ok(s) if s.success() => 0, + _ => { + println!("\nDid not run successfully:\n{:?}\n-------------", cmd); + exec_cmd(on_fail).expect("could not run the backup command"); + 1 + } + } + } else { + std::process::exit(match exec_cmd(&mut cmd) { + Ok(s) => s.code().unwrap_or(0xfe), + Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), + }) }) } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index c5bbfd89b2787..b55f3d710ca7b 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -28,6 +28,7 @@ use step; /// Deserialized version of all flags for this compile. pub struct Flags { pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose + pub on_fail: Option, pub stage: Option, pub keep_stage: Option, pub build: String, @@ -81,6 +82,7 @@ impl Flags { opts.optopt("", "build", "build target of the stage0 compiler", "BUILD"); opts.optmulti("", "host", "host targets to build", "HOST"); opts.optmulti("", "target", "target targets to build", "TARGET"); + opts.optopt("", "on-fail", "command to run on failure", "CMD"); opts.optopt("", "stage", "stage to build", "N"); opts.optopt("", "keep-stage", "stage to keep without recompiling", "N"); opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); @@ -283,6 +285,7 @@ To learn more about a subcommand, run `./x.py -h` Flags { verbose: m.opt_count("v"), stage: stage, + on_fail: m.opt_str("on-fail"), keep_stage: m.opt_str("keep-stage").map(|j| j.parse().unwrap()), build: m.opt_str("build").unwrap_or_else(|| { env::var("BUILD").unwrap() diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 7bd611eb53e3c..a28cb24a8166f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -499,6 +499,10 @@ impl Build { cargo.env("RUSTC_INCREMENTAL", incr_dir); } + if let Some(ref on_fail) = self.flags.on_fail { + cargo.env("RUSTC_ON_FAIL", on_fail); + } + let verbose = cmp::max(self.config.verbose, self.flags.verbose); cargo.env("RUSTC_VERBOSE", format!("{}", verbose)); From 68a9d8bf217572ee32bce12e311d5849d149b6b4 Mon Sep 17 00:00:00 2001 From: Shawn Walker-Salas Date: Thu, 16 Feb 2017 13:04:14 -0800 Subject: [PATCH 11/11] Update src/liblibc --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liblibc b/src/liblibc index 8d8264b967a31..7a3754f2bb5e6 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 8d8264b967a31a1a8cebe2a05110564106b6e909 +Subproject commit 7a3754f2bb5e65eb39adacb189c3626173032177