impl From<io::Stdout> for Stdio { fn from(_: io::Stdout) -> Stdio { <del> // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> Stdio::ParentStdout </ins> } } impl From<io::Stderr> for Stdio { fn from(_: io::Stderr) -> Stdio { <del> // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> Stdio::ParentStderr </ins> } } impl From<File> for Stdio { <del> fn from(_file: File) -> Stdio { // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> fn from(file: File) -> Stdio { Stdio::InheritFile(file) </ins> } } impl fmt::Debug for Command { <del> fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) </del> <ins> // show all attributes fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { let mut debug_command = f.debug_struct("Command"); debug_command.field("program", &self.program).field("args", &self.args); if !self.env.is_unchanged() { debug_command.field("env", &self.env); } if self.cwd.is_some() { debug_command.field("cwd", &self.cwd); } if self.stdin.is_some() { debug_command.field("stdin", &self.stdin); } if self.stdout.is_some() { debug_command.field("stdout", &self.stdout); } if self.stderr.is_some() { debug_command.field("stderr", &self.stderr); } debug_command.finish() } else { if let Some(ref cwd) = self.cwd { write!(f, "cd {cwd:?} && ")?; } if self.env.does_clear() { write!(f, "env -i ")?; // Altered env vars will be printed next, that should exactly work as expected. } else { // Removed env vars need the command to be wrapped in `env`. let mut any_removed = false; for (key, value_opt) in self.get_envs() { if value_opt.is_none() { if !any_removed { write!(f, "env ")?; any_removed = true; } write!(f, "-u {} ", key.to_string_lossy())?; } } } // Altered env vars can just be added in front of the program. for (key, value_opt) in self.get_envs() { if let Some(value) = value_opt { write!(f, "{}={value:?} ", key.to_string_lossy())?; } } if self.program != self.args[0] { write!(f, "[{:?}] ", self.program)?; } write!(f, "{:?}", self.args[0])?; for arg in &self.args[1..] { write!(f, " {:?}", arg)?; } Ok(()) } </ins> } }


} pub struct CommandArgs<'a> { <del> _p: PhantomData<&'a ()>, </del> <ins> iter: crate::slice::Iter<'a, OsString>, </ins> } impl<'a> Iterator for CommandArgs<'a> { type Item = &'a OsStr; fn next(&mut self) -> Option<&'a OsStr> { <del> None </del> <ins> self.iter.next().map(|os| &**os) </ins> } fn size_hint(&self) -> (usize, Option<usize>) { <del> (0, Some(0)) </del> <ins> self.iter.size_hint() </ins> } } <del> impl<'a> ExactSizeIterator for CommandArgs<'a> {} </del> <ins> impl<'a> ExactSizeIterator for CommandArgs<'a> { fn len(&self) -> usize { self.iter.len() } fn is_empty(&self) -> bool { self.iter.is_empty() } } </ins> impl<'a> fmt::Debug for CommandArgs<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { <del> f.debug_list().finish() </del> <ins> f.debug_list().entries(self.iter.clone()).finish() </ins> } }


rustup toolchain install --profile minimal nightly-${TOOLCHAIN} # Sanity check to see if the nightly exists echo nightly-${TOOLCHAIN} > rust-toolchain <del> echo "=> Uninstalling all old nighlies" </del> <ins> echo "=> Uninstalling all old nightlies" </ins> for nightly in $(rustup toolchain list | grep nightly | grep -v $TOOLCHAIN | grep -v nightly-x86_64); do rustup toolchain uninstall $nightly done


} fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { <ins> // if the expression was produced by a macro expansion, if e.span.expn_info.is_some() { return } </ins> let id = match e.node { ast::ExprPath(..) | ast::ExprStruct(..) => { match cx.tcx.def_map.borrow().find(&e.id) {


#![crate_id="lint_stability#0.1"] #![crate_type = "lib"] <ins> #![feature(macro_rules)] #![macro_escape] </ins> #[deprecated] pub fn deprecated() {} #[deprecated="text"]


pub struct FrozenTupleStruct(pub int); #[locked] pub struct LockedTupleStruct(pub int); <ins> #[macro_export] macro_rules! macro_test( () => (deprecated()); ) </ins>


// aux-build:lint_stability.rs // aux-build:inherited_stability.rs <del> #![feature(globs)] </del> <ins> #![feature(globs, phase)] </ins> #![deny(unstable)] #![deny(deprecated)] #![deny(experimental)] #![allow(dead_code)] mod cross_crate { <ins> #[phase(plugin, link)] </ins> extern crate lint_stability; use self::lint_stability::*;


foo.method_locked_text(); foo.trait_locked_text(); let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item let _ = ExperimentalStruct { i: 0 }; //~ ERROR use of experimental item let _ = UnstableStruct { i: 0 }; //~ ERROR use of unstable item


let _ = StableTupleStruct (1); let _ = FrozenTupleStruct (1); let _ = LockedTupleStruct (1); <ins> // At the moment, the following just checks that the stability // level of expanded code does not trigger the // lint. Eventually, we will want to lint the contents of the // macro in the module *defining* it. Also, stability levels // on macros themselves are not yet linted. macro_test!(); </ins> } fn test_method_param<F: Trait>(foo: F) {


**Source:** https://github.com/rust-lang/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs[config.rs] <del> The <<_installation,Installation>> section contains details on configuration for some of the editors. </del> <ins> The <<installation,Installation>> section contains details on configuration for some of the editors. </ins> In general `rust-analyzer` is configured via LSP messages, which means that it's up to the editor to decide on the exact format and location of configuration files. Some clients, such as <<vs-code,VS Code>> or <<coc-rust-analyzer,COC plugin in Vim>> provide `rust-analyzer` specific configuration UIs. Others may require you to know a bit more about the interaction with `rust-analyzer`.


crate_name: crate_name.to_string(), deriving_hash_type_parameter: sess.features.borrow().default_type_params, enable_quotes: sess.features.borrow().quote, <ins> recursion_limit: sess.recursion_limit.get(), </ins> }; let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, cfg,


pub exported_macros: Vec<P<ast::Item>>, pub syntax_env: SyntaxEnv, <ins> pub recursion_count: uint, </ins> } impl<'a> ExtCtxt<'a> {


trace_mac: false, exported_macros: Vec::new(), syntax_env: env, <ins> recursion_count: 0, </ins> } }


return v; } pub fn bt_push(&mut self, ei: ExpnInfo) { <ins> self.recursion_count += 1; if self.recursion_count > self.ecfg.recursion_limit { self.span_fatal(ei.call_site, format!("Recursion limit reached while expanding the macro `{}`", ei.callee.name).as_slice()); } </ins> let mut call_site = ei.call_site; call_site.expn_id = self.backtrace; self.backtrace = self.codemap().record_expansion(ExpnInfo {


match self.backtrace { NO_EXPANSION => self.bug("tried to pop without a push"), expn_id => { <ins> self.recursion_count -= 1; </ins> self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| { expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id) });


pub crate_name: String, pub deriving_hash_type_parameter: bool, pub enable_quotes: bool, <ins> pub recursion_limit: uint, </ins> } impl ExpansionConfig {


crate_name: crate_name, deriving_hash_type_parameter: false, enable_quotes: false, <ins> recursion_limit: 64, </ins> } } }


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(macro_rules)] macro_rules! recursive( () => ( recursive!() //~ ERROR Recursion limit reached while expanding the macro `recursive` ) ) fn main() { recursive!() } </ins>


# } fn compute_area(shape: &Shape) -> f64 { match *shape { <del> Circle(_, radius) => 2.0 * std::f64::consts::PI * radius * radius, </del> <ins> Circle(_, radius) => std::f64::consts::PI * radius * radius, </ins> Rectangle(_, ref size) => size.w * size.h } }


self.span_err(ty.span, "`virtual` structs have been removed from the language"); } <del> self.parse_where_clause(&mut generics); </del> <ins> // There is a special case worth noting here, as reported in issue #17904. // If we are parsing a tuple struct it is the case that the where clause // should follow the field list. Like so: // // struct Foo<T>(T) where T: Copy; // // If we are parsing a normal record-style struct it is the case // that the where clause comes before the body, and after the generics. // So if we look ahead and see a brace or a where-clause we begin // parsing a record style struct. // // Otherwise if we look ahead and see a paren we parse a tuple-style // struct. let (fields, ctor_id) = if self.token.is_keyword(keywords::Where) { self.parse_where_clause(&mut generics); if self.eat(&token::Semi) { // If we see a: `struct Foo<T> where T: Copy;` style decl. (Vec::new(), Some(ast::DUMMY_NODE_ID)) } else { // If we see: `struct Foo<T> where T: Copy { ... }` (self.parse_record_struct_body(&class_name), None) } // No `where` so: `struct Foo<T>;` } else if self.eat(&token::Semi) { (Vec::new(), Some(ast::DUMMY_NODE_ID)) // Record-style struct definition } else if self.token == token::OpenDelim(token::Brace) { let fields = self.parse_record_struct_body(&class_name); (fields, None) // Tuple-style struct definition with optional where-clause. } else { let fields = self.parse_tuple_struct_body(&class_name, &mut generics); (fields, Some(ast::DUMMY_NODE_ID)) }; </ins> <del> let mut fields: Vec<StructField>; let is_tuple_like; </del> <ins> (class_name, ItemStruct(P(ast::StructDef { fields: fields, ctor_id: ctor_id, }), generics), None) } pub fn parse_record_struct_body(&mut self, class_name: &ast::Ident) -> Vec<StructField> { let mut fields = Vec::new(); </ins> if self.eat(&token::OpenDelim(token::Brace)) { <del> // It's a record-like struct. is_tuple_like = false; fields = Vec::new(); </del> while self.token != token::CloseDelim(token::Brace) { fields.push(self.parse_struct_decl_field(true)); } if fields.len() == 0 { self.fatal(format!("unit-like struct definition should be  <del> written as `struct {};`", token::get_ident(class_name))[]); </del> <ins> written as `struct {};`", token::get_ident(class_name.clone()))[]); </ins> } self.bump(); <del> } else if self.check(&token::OpenDelim(token::Paren)) { // It's a tuple-like struct. is_tuple_like = true; fields = self.parse_unspanned_seq( </del> <ins> } else { let token_str = self.this_token_to_string(); self.fatal(format!("expected `where`, or `{}` after struct  name, found `{}`", "{", token_str)[]); } fields } pub fn parse_tuple_struct_body(&mut self, class_name: &ast::Ident, generics: &mut ast::Generics) -> Vec<StructField> { // This is the case where we find `struct Foo<T>(T) where T: Copy;` if self.check(&token::OpenDelim(token::Paren)) { let fields = self.parse_unspanned_seq( </ins> &token::OpenDelim(token::Paren), &token::CloseDelim(token::Paren), seq_sep_trailing_allowed(token::Comma), |p| { <del> let attrs = p.parse_outer_attributes(); let lo = p.span.lo; let struct_field_ = ast::StructField_ { kind: UnnamedField(p.parse_visibility()), id: ast::DUMMY_NODE_ID, ty: p.parse_ty_sum(), attrs: attrs, }; spanned(lo, p.span.hi, struct_field_) }); </del> <ins> let attrs = p.parse_outer_attributes(); let lo = p.span.lo; let struct_field_ = ast::StructField_ { kind: UnnamedField(p.parse_visibility()), id: ast::DUMMY_NODE_ID, ty: p.parse_ty_sum(), attrs: attrs, }; spanned(lo, p.span.hi, struct_field_) }); </ins> if fields.len() == 0 { self.fatal(format!("unit-like struct definition should be  <del> written as `struct {};`", token::get_ident(class_name))[]); </del> <ins> written as `struct {};`", token::get_ident(class_name.clone()))[]); </ins> } <ins> self.parse_where_clause(generics); </ins> self.expect(&token::Semi); <del> } else if self.eat(&token::Semi) { // It's a unit-like struct. is_tuple_like = true; fields = Vec::new(); </del> <ins> fields // This is the case where we just see struct Foo<T> where T: Copy; } else if self.token.is_keyword(keywords::Where) { self.parse_where_clause(generics); self.expect(&token::Semi); Vec::new() // This case is where we see: `struct Foo<T>;` </ins> } else { let token_str = self.this_token_to_string(); <del> self.fatal(format!("expected `{}`, `(`, or `;` after struct  name, found `{}`", "{", token_str)[]) </del> <ins> self.fatal(format!("expected `where`, `{}`, `(`, or `;` after struct  name, found `{}`", "{", token_str)[]); </ins> } <del> let _ = ast::DUMMY_NODE_ID;  // FIXME: Workaround for crazy bug. let new_id = ast::DUMMY_NODE_ID; (class_name, ItemStruct(P(ast::StructDef { fields: fields, ctor_id: if is_tuple_like { Some(new_id) } else { None }, }), generics), None) </del> } /// Parse a structure field declaration


span: codemap::Span) -> IoResult<()> { try!(self.print_ident(ident)); try!(self.print_generics(generics)); <del> try!(self.print_where_clause(generics)); </del> if ast_util::struct_def_is_tuple_like(struct_def) { if !struct_def.fields.is_empty() { try!(self.popen());


)); try!(self.pclose()); } <ins> try!(self.print_where_clause(generics)); </ins> try!(word(&mut self.s, ";")); try!(self.end()); self.end() // close the outer-box } else { <ins> try!(self.print_where_clause(generics)); </ins> try!(self.nbsp()); try!(self.bopen()); try!(self.hardbreak_if_not_bol());


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. struct Baz<U> where U: Eq(U); //This is parsed as the new Fn* style parenthesis syntax. struct Baz<U> where U: Eq(U) -> R; // Notice this parses as well. struct Baz<U>(U) where U: Eq; // This rightfully signals no error as well. struct Foo<T> where T: Copy, (T); //~ ERROR unexpected token in `where` clause struct Bar<T> { x: T } where T: Copy //~ ERROR expected item, found `where` fn main() {} </ins>


// Test syntax checks for `type` keyword. <del> struct S1 for type; //~ ERROR expected `{`, `(`, or `;` after struct name, found `for` </del> <ins> struct S1 for type; //~ ERROR expected `where`, `{`, `(`, or `;` after struct name, found `for` </ins> pub fn main() { }


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. struct Foo<T> where T: Copy; struct Bar<T>(T) where T: Copy; struct Bleh<T, U>(T, U) where T: Copy, U: Sized; struct Baz<T> where T: Copy { field: T } fn main() {} </ins>


<ins> // Copyright 2015 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. impl Undefined {} //~^ ERROR use of undeclared type name `Undefined` fn main() {} </ins>


AssignmentLhsSized,        // L = X implies that L is Sized StructInitializerSized,    // S { ... } must be Sized VariableType(ast::NodeId), // Type of each variable must be Sized <ins> ReturnType,                // Return type must be Sized </ins> RepeatVec,                 // [T,..n] --> T must be Copy // Captures of variable the given id by a closure (span is the


// Remember return type so that regionck can access it later. let fn_sig_tys: Vec<ty::t> = <del> arg_tys.iter() .chain([ret_ty].iter()) .map(|&ty| ty) .collect(); </del> <ins> arg_tys.iter().chain([ret_ty].iter()).map(|&ty| ty).collect(); </ins> debug!("fn-sig-map: fn_id={} fn_sig_tys={}", fn_id, fn_sig_tys.repr(tcx)); <del> inherited.fn_sig_map .borrow_mut() .insert(fn_id, fn_sig_tys); </del> <ins> inherited.fn_sig_map.borrow_mut().insert(fn_id, fn_sig_tys); </ins> { let mut visit = GatherLocalsVisitor { fcx: &fcx, };


visit.visit_block(body); } <ins> fcx.require_type_is_sized(ret_ty, decl.output.span, traits::ReturnType); </ins> check_block_with_expected(&fcx, body, ExpectHasType(ret_ty));


traits::RepeatVec => { tcx.sess.span_note( obligation.cause.span, <del> format!( "the `Copy` trait is required because the  repeated element will be copied").as_slice()); </del> <ins> "the `Copy` trait is required because the  repeated element will be copied"); </ins> } traits::VariableType(_) => { tcx.sess.span_note( obligation.cause.span, "all local variables must have a statically known size"); } <ins> traits::ReturnType => { tcx.sess.span_note( obligation.cause.span, "the return type of a function must have a  statically known size"); } </ins> traits::AssignmentLhsSized => { tcx.sess.span_note( obligation.cause.span,


#![no_std] #![feature(lang_items)] <ins> #[lang="sized"] pub trait Sized for Sized? {} </ins> #[lang="fail"] fn fail(_: &(&'static str, &'static str, uint)) -> ! { loop {} }


C([Box<A>]), } <del> fn c(c:char) -> A { B(c) //~ ERROR cannot move a value of type A: the size of A cannot be statically determined </del> <ins> fn c(c:char) { B(c); //~^ ERROR cannot move a value of type A: the size of A cannot be statically determined </ins> } pub fn main() {}


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. pub trait AbstractRenderer {} fn _create_render(_: &()) -> AbstractRenderer //~^ ERROR: the trait `core::kinds::Sized` is not implemented { match 0u { _ => unimplemented!() } } fn main() { } </ins>


r: A+'static } <del> fn new_struct(r: A+'static) -> Struct { </del> <ins> fn new_struct(r: A+'static) -> Struct { //~^  ERROR the trait `core::kinds::Sized` is not implemented </ins> //~^ ERROR the trait `core::kinds::Sized` is not implemented Struct { r: r } //~^ ERROR the trait `core::kinds::Sized` is not implemented


// option. This file may not be copied, modified, or distributed // except according to those terms. <del> #![feature(globs)] </del> <ins> #![feature(globs, lang_items)] </ins> #![no_std] // makes debugging this test *a lot* easier (during resolve) <ins> #[lang = "sized"] pub trait Sized for Sized? {} </ins> // Test to make sure that private items imported through globs remain private // when  they're used.


// option. This file may not be copied, modified, or distributed // except according to those terms. <ins> #![feature(lang_items)] </ins> #![no_std] <ins> #[lang="sized"] pub trait Sized for Sized? {} </ins> // error-pattern:requires `start` lang_item fn main() {}


#[inline] unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> { <del> let v: Vec<u8> = mem::transmute(self); v.into_ascii_nocheck() </del> <ins> self.into_bytes().into_ascii_nocheck() </ins> } }


#[inline] unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> { <del> mem::transmute(self) </del> <ins> let v = Vec::from_raw_parts(self.len(), self.capacity(), mem::transmute(self.as_ptr())); // We forget `self` to avoid freeing it at the end of the scope // Otherwise, the returned `Vec` would point to freed memory mem::forget(self); v </ins> } }


impl IntoBytes for Vec<Ascii> { fn into_bytes(self) -> Vec<u8> { <del> unsafe { mem::transmute(self) } </del> <ins> unsafe { let v = Vec::from_raw_parts(self.len(), self.capacity(), mem::transmute(self.as_ptr())); // We forget `self` to avoid freeing it at the end of the scope // Otherwise, the returned `Vec` would point to freed memory mem::forget(self); v } </ins> } }


let const_did = tcx.def_map.borrow().get_copy(&pat.id).def_id(); let const_pty = ty::lookup_item_type(tcx, const_did); fcx.write_ty(pat.id, const_pty.ty); <del> demand::eqtype(fcx, pat.span, expected, const_pty.ty); </del> <ins> demand::suptype(fcx, pat.span, expected, const_pty.ty); </ins> } ast::PatIdent(bm, ref path, ref sub) if pat_is_binding(&tcx.def_map, pat) => { let typ = fcx.local_ty(pat.span, pat.id);


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. const X: &'static str = "12345"; fn test(s: String) -> bool { match s.as_slice() { X => true, _ => false } } fn main() { assert!(test("12345".to_string())); } </ins>


use {uint, u8, u16, u32, u64}; use {f32, f64}; use clone::Clone; <del> use cmp::{PartialEq, PartialOrd}; </del> <ins> use cmp::{Ord, PartialEq, PartialOrd}; </ins> use kinds::Copy; use mem::size_of; use ops::{Add, Sub, Mul, Div, Rem, Neg};


/// A primitive signed or unsigned integer equipped with various bitwise /// operators, bit counting methods, and endian conversion functions. pub trait Int: Primitive <ins> + Ord </ins> + CheckedAdd + CheckedSub + CheckedMul


/// ``` #[macro_export] macro_rules! unreachable( <del> () => (panic!("internal error: entered unreachable code")) </del> <ins> () => ({ panic!("internal error: entered unreachable code") }); ($msg:expr) => ({ unreachable!("{}", $msg) }); ($fmt:expr, $($arg:tt)*) => ({ panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*) }); </ins> ) /// A standardised placeholder for marking unfinished code. It panics with the


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // error-pattern:internal error: entered unreachable code: 6 is not prime fn main() { unreachable!("{} is not {}", 6u32, "prime"); } </ins>


<del> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // error-pattern:internal error: entered unreachable code fn main() { unreachable!() } </del>


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // error-pattern:internal error: entered unreachable code: uhoh fn main() { unreachable!("uhoh") } </ins>


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // error-pattern:internal error: entered unreachable code fn main() { unreachable!() } </ins>


/// context it's calculated within. This is used by the `type_id` intrinsic. pub fn hash_crate_independent(tcx: &ctxt, ty: Ty, svh: &Svh) -> u64 { let mut state = sip::SipState::new(); <del> macro_rules! byte( ($b:expr) => { ($b as u8).hash(&mut state) } ); macro_rules! hash( ($e:expr) => { $e.hash(&mut state) } ); let region = |_state: &mut sip::SipState, r: Region| { match r { ReStatic => {} ReEmpty | ReEarlyBound(..) | ReLateBound(..) | ReFree(..) | ReScope(..) | ReInfer(..) => { tcx.sess.bug("non-static region found when hashing a type") </del> <ins> helper(tcx, ty, svh, &mut state); return state.result(); fn helper(tcx: &ctxt, ty: Ty, svh: &Svh, state: &mut sip::SipState) { macro_rules! byte( ($b:expr) => { ($b as u8).hash(state) } ); macro_rules! hash( ($e:expr) => { $e.hash(state) } ); let region = |state: &mut sip::SipState, r: Region| { match r { ReStatic => {} ReLateBound(db, BrAnon(i)) => { db.hash(state); i.hash(state); } ReEmpty | ReEarlyBound(..) | ReLateBound(..) | ReFree(..) | ReScope(..) | ReInfer(..) => { tcx.sess.bug("unexpected region found when hashing a type") } </ins> } <del> } }; let did = |state: &mut sip::SipState, did: DefId| { let h = if ast_util::is_local(did) { svh.clone() } else { tcx.sess.cstore.get_crate_hash(did.krate) </del> }; <del> h.as_str().hash(state); did.node.hash(state); }; let mt = |state: &mut sip::SipState, mt: mt| { mt.mutbl.hash(state); }; ty::walk_ty(ty, |ty| { match ty.sty { ty_bool => byte!(2), ty_char => byte!(3), ty_int(i) => { byte!(4); hash!(i); } ty_uint(u) => { byte!(5); hash!(u); } ty_float(f) => { byte!(6); hash!(f); } ty_str => { byte!(7); } ty_enum(d, _) => { byte!(8); did(&mut state, d); } ty_uniq(_) => { byte!(9); } ty_vec(_, Some(n)) => { byte!(10); n.hash(&mut state); } ty_vec(_, None) => { byte!(11); } ty_ptr(m) => { byte!(12); mt(&mut state, m); } ty_rptr(r, m) => { byte!(13); region(&mut state, r); mt(&mut state, m); } ty_bare_fn(ref b) => { byte!(14); hash!(b.unsafety); hash!(b.abi); </del> <ins> let did = |state: &mut sip::SipState, did: DefId| { let h = if ast_util::is_local(did) { svh.clone() } else { tcx.sess.cstore.get_crate_hash(did.krate) }; h.as_str().hash(state); did.node.hash(state); }; let mt = |state: &mut sip::SipState, mt: mt| { mt.mutbl.hash(state); }; let fn_sig = |state: &mut sip::SipState, sig: &FnSig| { let sig = anonymize_late_bound_regions(tcx, sig); for a in sig.inputs.iter() { helper(tcx, *a, svh, state); } if let ty::FnConverging(output) = sig.output { helper(tcx, output, svh, state); </ins> } <del> ty_closure(ref c) => { byte!(15); hash!(c.unsafety); hash!(c.onceness); hash!(c.bounds); match c.store { UniqTraitStore => byte!(0), RegionTraitStore(r, m) => { byte!(1) region(&mut state, r); assert_eq!(m, ast::MutMutable); </del> <ins> }; maybe_walk_ty(ty, |ty| { match ty.sty { ty_bool => byte!(2), ty_char => byte!(3), ty_int(i) => { byte!(4); hash!(i); } ty_uint(u) => { byte!(5); hash!(u); } ty_float(f) => { byte!(6); hash!(f); } ty_str => { byte!(7); } ty_enum(d, _) => { byte!(8); did(state, d); } ty_uniq(_) => { byte!(9); } ty_vec(_, Some(n)) => { byte!(10); n.hash(state); } ty_vec(_, None) => { byte!(11); } ty_ptr(m) => { byte!(12); mt(state, m); } ty_rptr(r, m) => { byte!(13); region(state, r); mt(state, m); } ty_bare_fn(ref b) => { byte!(14); hash!(b.unsafety); hash!(b.abi); fn_sig(state, &b.sig); return false; } ty_closure(ref c) => { byte!(15); hash!(c.unsafety); hash!(c.onceness); hash!(c.bounds); match c.store { UniqTraitStore => byte!(0), RegionTraitStore(r, m) => { byte!(1); region(state, r); assert_eq!(m, ast::MutMutable); } </ins> } <ins> fn_sig(state, &c.sig); return false; </ins> } <del> } ty_trait(box TyTrait { ref principal, bounds }) => { byte!(17); did(&mut state, principal.def_id); hash!(bounds); } ty_struct(d, _) => { byte!(18); did(&mut state, d); } ty_tup(ref inner) => { byte!(19); hash!(inner.len()); } ty_param(p) => { byte!(20); hash!(p.idx); did(&mut state, p.def_id); } ty_open(_) => byte!(22), ty_infer(_) => unreachable!(), ty_err => byte!(23), ty_unboxed_closure(d, r, _) => { byte!(24); did(&mut state, d); region(&mut state, r); } } }); </del> <ins> ty_trait(box TyTrait { ref principal, bounds }) => { byte!(17); did(state, principal.def_id); hash!(bounds); let principal = anonymize_late_bound_regions(tcx, principal); for subty in principal.substs.types.iter() { helper(tcx, *subty, svh, state); } </ins> <del> state.result() </del> <ins> return false; } ty_struct(d, _) => { byte!(18); did(state, d); } ty_tup(ref inner) => { byte!(19); hash!(inner.len()); } ty_param(p) => { byte!(20); hash!(p.idx); did(state, p.def_id); } ty_open(_) => byte!(22), ty_infer(_) => unreachable!(), ty_err => byte!(23), ty_unboxed_closure(d, r, _) => { byte!(24); did(state, d); region(state, r); } } true }); } </ins> } impl Variance {


replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic).0 } <ins> /// Rewrite any late-bound regions so that they are anonymous.  Region numbers are /// assigned starting at 1 and increasing monotonically in the order traversed /// by the fold operation. /// /// The chief purpose of this function is to canonicalize regions so that two /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become /// structurally identical.  For example, `for<'a, 'b> fn(&'a int, &'b int)` and /// `for<'a, 'b> fn(&'b int, &'a int)` will become identical after anonymization. pub fn anonymize_late_bound_regions<'tcx, HR>(tcx: &ctxt<'tcx>, sig: &HR) -> HR where HR: HigherRankedFoldable<'tcx> { let mut counter = 0; replace_late_bound_regions(tcx, sig, |_, db| { counter += 1; ReLateBound(db, BrAnon(counter)) }).0 } </ins> /// Replaces the late-bound-regions in `value` that are bound by `value`. pub fn replace_late_bound_regions<'tcx, HR, F>( tcx: &ty::ctxt<'tcx>,


fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> { if !t.bound_lifetimes.is_empty() { try!(word(&mut self.s, "for<")); <ins> let mut comma = false; </ins> for lifetime_def in t.bound_lifetimes.iter() { <ins> if comma { try!(self.word_space(",")) } </ins> try!(self.print_lifetime_def(lifetime_def)); <ins> comma = true; </ins> } try!(word(&mut self.s, ">")); }


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Test that type IDs correctly account for higher-rank lifetimes // Also acts as a regression test for an ICE (issue #19791) #![feature(unboxed_closures)] use std::intrinsics::TypeId; fn main() { // Bare fns { let a = TypeId::of::<fn(&'static int, &'static int)>(); let b = TypeId::of::<for<'a> fn(&'static int, &'a int)>(); let c = TypeId::of::<for<'a, 'b> fn(&'a int, &'b int)>(); let d = TypeId::of::<for<'a, 'b> fn(&'b int, &'a int)>(); assert!(a != b); assert!(a != c); assert!(a != d); assert!(b != c); assert!(b != d); assert_eq!(c, d); // Make sure De Bruijn indices are handled correctly let e = TypeId::of::<for<'a> fn(fn(&'a int) -> &'a int)>(); let f = TypeId::of::<fn(for<'a> fn(&'a int) -> &'a int)>(); assert!(e != f); } // Stack closures { let a = TypeId::of::<|&'static int, &'static int|>(); let b = TypeId::of::<for<'a> |&'static int, &'a int|>(); let c = TypeId::of::<for<'a, 'b> |&'a int, &'b int|>(); let d = TypeId::of::<for<'a, 'b> |&'b int, &'a int|>(); assert!(a != b); assert!(a != c); assert!(a != d); assert!(b != c); assert!(b != d); assert_eq!(c, d); // Make sure De Bruijn indices are handled correctly let e = TypeId::of::<for<'a> |(|&'a int| -> &'a int)|>(); let f = TypeId::of::<|for<'a> |&'a int| -> &'a int|>(); assert!(e != f); } // Boxed unboxed closures { let a = TypeId::of::<Box<Fn(&'static int, &'static int)>>(); let b = TypeId::of::<Box<for<'a> Fn(&'static int, &'a int)>>(); let c = TypeId::of::<Box<for<'a, 'b> Fn(&'a int, &'b int)>>(); let d = TypeId::of::<Box<for<'a, 'b> Fn(&'b int, &'a int)>>(); assert!(a != b); assert!(a != c); assert!(a != d); assert!(b != c); assert!(b != d); assert_eq!(c, d); // Make sure De Bruijn indices are handled correctly let e = TypeId::of::<Box<for<'a> Fn(Box<Fn(&'a int) -> &'a int>)>>(); let f = TypeId::of::<Box<Fn(Box<for<'a> Fn(&'a int) -> &'a int>)>>(); assert!(e != f); } // Raw unboxed closures // Note that every unboxed closure has its own anonymous type, // so no two IDs should equal each other, even when compatible { let a = id(|&: _: &int, _: &int| {}); let b = id(|&: _: &int, _: &int| {}); assert!(a != b); } fn id<T:'static>(_: T) -> TypeId { TypeId::of::<T>() } } </ins>


* [Iterators](iterators.md) * [Generics](generics.md) * [Traits](traits.md) <del> * [Threads](threads.md) </del> <ins> * [Concurrency](concurrency.md) </ins> * [Error Handling](error-handling.md) * [Documentation](documentation.md) * [III: Advanced Topics](advanced.md)


<ins> % Concurrency Concurrency and parallelism are incredibly important topics in computer science, and are also a hot topic in industry today. Computers are gaining more and more cores, yet many programmers aren't prepared to fully utilize them. Rust's memory safety features also apply to its concurrency story too. Even concurrent Rust programs must be memory safe, having no data races. Rust's type system is up to the task, and gives you powerful ways to reason about concurrent code at compile time. Before we talk about the concurrency features that come with Rust, it's important to understand something: Rust is low-level enough that all of this is provided by the standard library, not by the language. This means that if you don't like some aspect of the way Rust handles concurrency, you can implement an alternative way of doing things. [mio](https://github.com/carllerche/mio) is a real-world example of this principle in action. ## Background: `Send` and `Sync` Concurrency is difficult to reason about. In Rust, we have a strong, static type system to help us reason about our code. As such, Rust gives us two traits to help us make sense of code that can possibly be concurrent. ### `Send` The first trait we're going to talk about is [`Send`](../std/marker/trait.Send.html). When a type `T` implements `Send`, it indicates to the compiler that something of this type is able to have ownership transferred safely between threads. This is important to enforce certain restrictions. For example, if we have a channel connecting two threads, we would want to be able to send some data down the channel and to the other thread. Therefore, we'd ensure that `Send` was implemented for that type. In the opposite way, if we were wrapping a library with FFI that isn't threadsafe, we wouldn't want to implement `Send`, and so the compiler will help us enforce that it can't leave the current thread. ### `Sync` The second of these two trait is called [`Sync`](../std/marker/trait.Sync.html). When a type `T` implements `Sync`, it indicates to the compiler that something of this type has no possibility of introducing memory unsafety when used from multiple threads concurrently. For example, sharing immutable data with an atomic reference count is threadsafe. Rust provides a type like this, `Arc<T>`, and it implements `Sync`, so that it could be safely shared between threads. These two traits allow you to use the type system to make strong guarantees about the properties of your code under concurrency. Before we demonstrate why, we need to learn how to create a concurrent Rust program in the first place! ## Threads Rust's standard library provides a library for 'threads', which allow you to run Rust code in parallel. Here's a basic example of using `Thread`: ``` use std::thread::Thread; fn main() { Thread::scoped(|| { println!("Hello from a thread!"); }); } ``` The `Thread::scoped()` method accepts a closure, which is executed in a new thread. It's called `scoped` because this thread returns a join guard: ``` use std::thread::Thread; fn main() { let guard = Thread::scoped(|| { println!("Hello from a thread!"); }); // guard goes out of scope here } ``` When `guard` goes out of scope, it will block execution until the thread is finished. If we didn't want this behaviour, we could use `Thread::spawn()`: ``` use std::thread::Thread; use std::old_io::timer; use std::time::Duration; fn main() { Thread::spawn(|| { println!("Hello from a thread!"); }); timer::sleep(Duration::milliseconds(50)); } ``` Or call `.detach()`: ``` use std::thread::Thread; use std::old_io::timer; use std::time::Duration; fn main() { let guard = Thread::scoped(|| { println!("Hello from a thread!"); }); guard.detach(); timer::sleep(Duration::milliseconds(50)); } ``` We need to `sleep` here because when `main()` ends, it kills all of the running threads. [`scoped`](std/thread/struct.Builder.html#method.scoped) has an interesting type signature: ```text fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T> where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a ``` Specifically, `F`, the closure that we pass to execute in the new thread. It has two restrictions: It must be a `FnOnce` from `()` to `T`. Using `FnOnce` allows the closure to take ownership of any data it mentions from the parent thread. The other restriction is that `F` must be `Send`. We aren't allowed to transfer this ownership unless the type thinks that's okay. Many languages have the ability to execute threads, but it's wildly unsafe. There are entire books about how to prevent errors that occur from shared mutable state. Rust helps out with its type system here as well, by preventing data races at compile time. Let's talk about how you actually share things between threads. ## Safe Shared Mutable State Due to Rust's type system, we have a concept that sounds like a lie: "safe shared mutable state." Many programmers agree that shared mutable state is very, very bad. Someone once said this: > Shared mutable state is the root of all evil. Most languages attempt to deal > with this problem through the 'mutable' part, but Rust deals with it by > solving the 'shared' part. The same [ownership system](ownership.html) that helps prevent using pointers incorrectly also helps rule out data races, one of the worst kinds of concurrency bugs. As an example, here is a Rust program that would have a data race in many languages. It will not compile: ```ignore use std::thread::Thread; use std::old_io::timer; use std::time::Duration; fn main() { let mut data = vec![1u32, 2, 3]; for i in 0 .. 2 { Thread::spawn(move || { data[i] += 1; }); } timer::sleep(Duration::milliseconds(50)); } ``` This gives us an error: ```text 12:17 error: capture of moved value: `data` data[i] += 1; ^~~~ ``` In this case, we know that our code _should_ be safe, but Rust isn't sure. And it's actually not safe: if we had a reference to `data` in each thread, and the thread takes ownership of the reference, we have three owners! That's bad. We can fix this by using the `Arc<T>` type, which is an atomic reference counted pointer. The 'atomic' part means that it's safe to share across threads. `Arc<T>` assumes one more property about its contents to ensure that it is safe to share across threads: it assumes its contents are `Sync`. But in our case, we want to be able to mutate the value. We need a type that can ensure only one person at a time can mutate what's inside. For that, we can use the `Mutex<T>` type. Here's the second version of our code. It still doesn't work, but for a different reason: ```ignore use std::thread::Thread; use std::old_io::timer; use std::time::Duration; use std::sync::Mutex; fn main() { let mut data = Mutex::new(vec![1u32, 2, 3]); for i in 0 .. 2 { let data = data.lock().unwrap(); Thread::spawn(move || { data[i] += 1; }); } timer::sleep(Duration::milliseconds(50)); } ``` Here's the error: ```text <anon>:11:9: 11:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277] <anon>:11         Thread::spawn(move || { ^~~~~~~~~~~~~ <anon>:11:9: 11:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely <anon>:11         Thread::spawn(move || { ^~~~~~~~~~~~~ ``` You see, [`Mutex`](std/sync/struct.Mutex.html) has a [`lock`](http://doc.rust-lang.org/nightly/std/sync/struct.Mutex.html#method.lock) method which has this signature: ```ignore fn lock(&self) -> LockResult<MutexGuard<T>> ``` If we [look at the code for MutexGuard](https://github.com/rust-lang/rust/blob/ca4b9674c26c1de07a2042cb68e6a062d7184cef/src/libstd/sync/mutex.rs#L172), we'll see this: ```ignore __marker: marker::NoSend, ``` Because our guard is `NoSend`, it's not `Send`. Which means we can't actually transfer the guard across thread boundaries, which gives us our error. We can use `Arc<T>` to fix this. Here's the working version: ``` use std::sync::{Arc, Mutex}; use std::thread::Thread; use std::old_io::timer; use std::time::Duration; fn main() { let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); for i in (0us..2) { let data = data.clone(); Thread::spawn(move || { let mut data = data.lock().unwrap(); data[i] += 1; }); } timer::sleep(Duration::milliseconds(50)); } ``` We now call `clone()` on our `Arc`, which increases the internal count. This handle is then moved into the new thread. Let's examine the body of the thread more closely: ``` # use std::sync::{Arc, Mutex}; # use std::thread::Thread; # use std::old_io::timer; # use std::time::Duration; # fn main() { #     let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); #     for i in (0us..2) { #         let data = data.clone(); Thread::spawn(move || { let mut data = data.lock().unwrap(); data[i] += 1; }); #     } # } ``` First, we call `lock()`, which acquires the mutex's lock. Because this may fail, it returns an `Result<T, E>`, and because this is just an example, we `unwrap()` it to get a reference to the data. Real code would have more robust error handling here. We're then free to mutate it, since we have the lock. This timer bit is a bit awkward, however. We have picked a reasonable amount of time to wait, but it's entirely possible that we've picked too high, and that we could be taking less time. It's also possible that we've picked too low, and that we aren't actually finishing this computation. Rust's standard library provides a few more mechanisms for two threads to synchronize with each other. Let's talk about one: channels. ## Channels Here's a version of our code that uses channels for synchronization, rather than waiting for a specific time: ``` use std::sync::{Arc, Mutex}; use std::thread::Thread; use std::sync::mpsc; fn main() { let data = Arc::new(Mutex::new(0u32)); let (tx, rx) = mpsc::channel(); for _ in (0..10) { let (data, tx) = (data.clone(), tx.clone()); Thread::spawn(move || { let mut data = data.lock().unwrap(); *data += 1; tx.send(()); }); } for _ in 0 .. 10 { rx.recv(); } } ``` We use the `mpsc::channel()` method to construct a new channel. We just `send` a simple `()` down the channel, and then wait for ten of them to come back. While this channel is just sending a generic signal, we can send any data that is `Send` over the channel! ``` use std::sync::{Arc, Mutex}; use std::thread::Thread; use std::sync::mpsc; fn main() { let (tx, rx) = mpsc::channel(); for _ in range(0, 10) { let tx = tx.clone(); Thread::spawn(move || { let answer = 42u32; tx.send(answer); }); } rx.recv().ok().expect("Could not recieve answer"); } ``` A `u32` is `Send` because we can make a copy. So we create a thread, ask it to calculate the answer, and then it `send()`s us the answer over the channel. ## Panics A `panic!` will crash the currently executing thread. You can use Rust's threads as a simple isolation mechanism: ``` use std::thread::Thread; let result = Thread::scoped(move || { panic!("oops!"); }).join(); assert!(result.is_err()); ``` Our `Thread` gives us a `Result` back, which allows us to check if the thread has panicked or not. </ins>


<del> % The Rust Threads and Communication Guide **NOTE** This guide is badly out of date and needs to be rewritten. # Introduction Rust provides safe concurrent abstractions through a number of core library primitives. This guide will describe the concurrency model in Rust, how it relates to the Rust type system, and introduce the fundamental library abstractions for constructing concurrent programs. Threads provide failure isolation and recovery. When a fatal error occurs in Rust code as a result of an explicit call to `panic!()`, an assertion failure, or another invalid operation, the runtime system destroys the entire thread. Unlike in languages such as Java and C++, there is no way to `catch` an exception. Instead, threads may monitor each other to see if they panic. Threads use Rust's type system to provide strong memory safety guarantees.  In particular, the type system guarantees that threads cannot induce a data race from shared mutable state. # Basics At its simplest, creating a thread is a matter of calling the `spawn` function with a closure argument. `spawn` executes the closure in the new thread. ```{rust,ignore} # use std::thread::spawn; // Print something profound in a different thread using a named function fn print_message() { println!("I am running in a different thread!"); } spawn(print_message); // Alternatively, use a `move ||` expression instead of a named function. // `||` expressions evaluate to an unnamed closure. The `move` keyword // indicates that the closure should take ownership of any variables it // touches. spawn(move || println!("I am also running in a different thread!")); ``` In Rust, a thread is not a concept that appears in the language semantics. Instead, Rust's type system provides all the tools necessary to implement safe concurrency: particularly, ownership. The language leaves the implementation details to the standard library. The `spawn` function has the type signature: `fn spawn<F:FnOnce()+Send>(f: F)`.  This indicates that it takes as argument a closure (of type `F`) that it will run exactly once. This closure is limited to capturing `Send`-able data from its environment (that is, data which is deeply owned). Limiting the closure to `Send` ensures that `spawn` can safely move the entire closure and all its associated state into an entirely different thread for execution. ```rust use std::thread::Thread; fn generate_thread_number() -> i32 { 4 } // a very simple generation // Generate some state locally let child_thread_number = generate_thread_number(); Thread::spawn(move || { // Capture it in the remote thread. The `move` keyword indicates // that this closure should move `child_thread_number` into its // environment, rather than capturing a reference into the // enclosing stack frame. println!("I am child number {}", child_thread_number); }); ``` ## Communication Now that we have spawned a new thread, it would be nice if we could communicate with it. For this, we use *channels*. A channel is simply a pair of endpoints: one for sending messages and another for receiving messages. The simplest way to create a channel is to use the `channel` function to create a `(Sender, Receiver)` pair. In Rust parlance, a *sender* is a sending endpoint of a channel, and a *receiver* is the receiving endpoint. Consider the following example of calculating two results concurrently: ```rust use std::thread::Thread; use std::sync::mpsc; let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel(); Thread::spawn(move || { let result = some_expensive_computation(); tx.send(result); }); some_other_expensive_computation(); let result = rx.recv(); fn some_expensive_computation() -> u32 { 42 } // very expensive ;) fn some_other_expensive_computation() {}      // even more so ``` Let's examine this example in detail. First, the `let` statement creates a stream for sending and receiving integers (the left-hand side of the `let`, `(tx, rx)`, is an example of a destructuring let: the pattern separates a tuple into its component parts). ```rust # use std::sync::mpsc; let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel(); ``` The child thread will use the sender to send data to the parent thread, which will wait to receive the data on the receiver. The next statement spawns the child thread. ```rust # use std::thread::Thread; # use std::sync::mpsc; # fn some_expensive_computation() -> u32 { 42 } # let (tx, rx) = mpsc::channel(); Thread::spawn(move || { let result = some_expensive_computation(); tx.send(result); }); ``` Notice that the creation of the thread closure transfers `tx` to the child thread implicitly: the closure captures `tx` in its environment. Both `Sender` and `Receiver` are sendable types and may be captured into threads or otherwise transferred between them. In the example, the child thread runs an expensive computation, then sends the result over the captured channel. Finally, the parent continues with some other expensive computation, then waits for the child's result to arrive on the receiver: ```rust # use std::sync::mpsc; # fn some_other_expensive_computation() {} # let (tx, rx) = mpsc::channel::<u32>(); # tx.send(0); some_other_expensive_computation(); let result = rx.recv(); ``` The `Sender` and `Receiver` pair created by `channel` enables efficient communication between a single sender and a single receiver, but multiple senders cannot use a single `Sender` value, and multiple receivers cannot use a single `Receiver` value.  What if our example needed to compute multiple results across a number of threads? The following program is ill-typed: ```{rust,ignore} # use std::sync::mpsc; # fn some_expensive_computation() -> u32 { 42 } let (tx, rx) = mpsc::channel(); spawn(move || { tx.send(some_expensive_computation()); }); // ERROR! The previous spawn statement already owns the sender, // so the compiler will not allow it to be captured again spawn(move || { tx.send(some_expensive_computation()); }); ``` Instead we can clone the `tx`, which allows for multiple senders. ```rust use std::thread::Thread; use std::sync::mpsc; let (tx, rx) = mpsc::channel(); for init_val in 0 .. 3 { // Create a new channel handle to distribute to the child thread let child_tx = tx.clone(); Thread::spawn(move || { child_tx.send(some_expensive_computation(init_val)); }); } let result = rx.recv().unwrap() + rx.recv().unwrap() + rx.recv().unwrap(); # fn some_expensive_computation(_i: i32) -> i32 { 42 } ``` Cloning a `Sender` produces a new handle to the same channel, allowing multiple threads to send data to a single receiver. It upgrades the channel internally in order to allow this functionality, which means that channels that are not cloned can avoid the overhead required to handle multiple senders. But this fact has no bearing on the channel's usage: the upgrade is transparent. Note that the above cloning example is somewhat contrived since you could also simply use three `Sender` pairs, but it serves to illustrate the point. For reference, written with multiple streams, it might look like the example below. ```rust use std::thread::Thread; use std::sync::mpsc; // Create a vector of ports, one for each child thread let rxs = (0 .. 3).map(|&:init_val| { let (tx, rx) = mpsc::channel(); Thread::spawn(move || { tx.send(some_expensive_computation(init_val)); }); rx }).collect::<Vec<_>>(); // Wait on each port, accumulating the results let result = rxs.iter().fold(0, |&:accum, rx| accum + rx.recv().unwrap() ); # fn some_expensive_computation(_i: i32) -> i32 { 42 } ``` ## Backgrounding computations: Futures With `sync::Future`, rust has a mechanism for requesting a computation and getting the result later. The basic example below illustrates this. ```{rust,ignore} # #![allow(deprecated)] use std::sync::Future; # fn main() { # fn make_a_sandwich() {}; fn fib(n: u64) -> u64 { // lengthy computation returning an 64 12586269025 } let mut delayed_fib = Future::spawn(move || fib(50)); make_a_sandwich(); println!("fib(50) = {}", delayed_fib.get()) # } ``` The call to `future::spawn` immediately returns a `future` object regardless of how long it takes to run `fib(50)`. You can then make yourself a sandwich while the computation of `fib` is running. The result of the execution of the method is obtained by calling `get` on the future. This call will block until the value is available (*i.e.* the computation is complete). Note that the future needs to be mutable so that it can save the result for next time `get` is called. Here is another example showing how futures allow you to background computations. The workload will be distributed on the available cores. ```{rust,ignore} # #![allow(deprecated)] # use std::num::Float; # use std::sync::Future; fn partial_sum(start: u64) -> f64 { let mut local_sum = 0f64; for num in range(start*100000, (start+1)*100000) { local_sum += (num as f64 + 1.0).powf(-2.0); } local_sum } fn main() { let mut futures = Vec::from_fn(200, |ind| Future::spawn(move || partial_sum(ind))); let mut final_res = 0f64; for ft in futures.iter_mut()  { final_res += ft.get(); } println!("π^2/6 is not far from : {}", final_res); } ``` ## Sharing without copying: Arc To share data between threads, a first approach would be to only use channel as we have seen previously. A copy of the data to share would then be made for each thread. In some cases, this would add up to a significant amount of wasted memory and would require copying the same data more than necessary. To tackle this issue, one can use an Atomically Reference Counted wrapper (`Arc`) as implemented in the `sync` library of Rust. With an Arc, the data will no longer be copied for each thread. The Arc acts as a reference to the shared data and only this reference is shared and cloned. Here is a small example showing how to use Arcs. We wish to run concurrently several computations on a single large vector of floats. Each thread needs the full vector to perform its duty. ```{rust,ignore} use std::num::Float; use std::rand; use std::sync::Arc; fn pnorm(nums: &[f64], p: u64) -> f64 { nums.iter().fold(0.0, |a, b| a + b.powf(p as f64)).powf(1.0 / (p as f64)) } fn main() { let numbers = Vec::from_fn(1000000, |_| rand::random::<f64>()); let numbers_arc = Arc::new(numbers); for num in range(1, 10) { let thread_numbers = numbers_arc.clone(); spawn(move || { println!("{}-norm = {}", num, pnorm(thread_numbers.as_slice(), num)); }); } } ``` The function `pnorm` performs a simple computation on the vector (it computes the sum of its items at the power given as argument and takes the inverse power of this value). The Arc on the vector is created by the line: ```{rust,ignore} # use std::rand; # use std::sync::Arc; # fn main() { # let numbers = Vec::from_fn(1000000, |_| rand::random::<f64>()); let numbers_arc = Arc::new(numbers); # } ``` and a clone is captured for each thread via a procedure. This only copies the wrapper and not its contents. Within the thread's procedure, the captured Arc reference can be used as a shared reference to the underlying vector as if it were local. ```{rust,ignore} # use std::rand; # use std::sync::Arc; # fn pnorm(nums: &[f64], p: u64) -> f64 { 4.0 } # fn main() { # let numbers=Vec::from_fn(1000000, |_| rand::random::<f64>()); # let numbers_arc = Arc::new(numbers); # let num = 4; let thread_numbers = numbers_arc.clone(); spawn(move || { // Capture thread_numbers and use it as if it was the underlying vector println!("{}-norm = {}", num, pnorm(thread_numbers.as_slice(), num)); }); # } ``` # Handling thread panics Rust has a built-in mechanism for raising exceptions. The `panic!()` macro (which can also be written with an error string as an argument: `panic!( ~reason)`) and the `assert!` construct (which effectively calls `panic!()` if a boolean expression is false) are both ways to raise exceptions. When a thread raises an exception, the thread unwinds its stack—running destructors and freeing memory along the way—and then exits. Unlike exceptions in C++, exceptions in Rust are unrecoverable within a single thread: once a thread panics, there is no way to "catch" the exception. While it isn't possible for a thread to recover from panicking, threads may notify each other if they panic. The simplest way of handling a panic is with the `try` function, which is similar to `spawn`, but immediately blocks and waits for the child thread to finish. `try` returns a value of type `Result<T, Box<Any + Send>>`. `Result` is an `enum` type with two variants: `Ok` and `Err`. In this case, because the type arguments to `Result` are `i32` and `()`, callers can pattern-match on a result to check whether it's an `Ok` result with an `i32` field (representing a successful result) or an `Err` result (representing termination with an error). ```{rust,ignore} # use std::thread::Thread; # fn some_condition() -> bool { false } # fn calculate_result() -> i32 { 0 } let result: Result<i32, Box<std::any::Any + Send>> = Thread::spawn(move || { if some_condition() { calculate_result() } else { panic!("oops!"); } }).join(); assert!(result.is_err()); ``` Unlike `spawn`, the function spawned using `try` may return a value, which `try` will dutifully propagate back to the caller in a [`Result`] enum. If the child thread terminates successfully, `try` will return an `Ok` result; if the child thread panics, `try` will return an `Error` result. [`Result`]: ../std/result/index.html > *Note:* A panicked thread does not currently produce a useful error > value (`try` always returns `Err(())`). In the > future, it may be possible for threads to intercept the value passed to > `panic!()`. But not all panics are created equal. In some cases you might need to abort the entire program (perhaps you're writing an assert which, if it trips, indicates an unrecoverable logic error); in other cases you might want to contain the panic at a certain boundary (perhaps a small piece of input from the outside world, which you happen to be processing in parallel, is malformed such that the processing thread cannot proceed). </del>


pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) { THREAD_INFO.with(|c| assert!(c.borrow().is_none())); <del> match thread.name() { Some(name) => unsafe { ::sys::thread::set_name(name); }, None => {} } </del> THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{ stack_bounds: stack_bounds, stack_guard: stack_guard,


use option::Option::{self, Some, None}; use result::Result::{Err, Ok}; use sync::{Mutex, Condvar, Arc}; <ins> use str::Str; </ins> use string::String; use rt::{self, unwind}; use old_io::{Writer, stdio};


unsafe { stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top); } <ins> match their_thread.name() { Some(name) => unsafe { imp::set_name(name.as_slice()); }, None => {} } </ins> thread_info::set( (my_stack_bottom, my_stack_top), unsafe { imp::guard::current() },


<ins> // Copyright 2015 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. trait Trait { type A; type B; } fn foo<T: Trait<A = T::B>>() { } //~^ ERROR: unsupported cyclic reference between types/traits detected fn main() { } </ins>


<ins> // Copyright 2015 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. fn foo<U>(t: U) { let y = t(); //~^ ERROR: expected function, found `U` } struct Bar; pub fn some_func() { let f = Bar(); //~^ ERROR: expected function, found `Bar` } fn main() { foo(|| { 1 }); } </ins>


<ins> // Copyright 2015 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. trait A { type Output; fn a(&self) -> <Self as A>::X; //~^ ERROR: use of undeclared associated type `A::X` } impl A for u32 { type Output = u32; fn a(&self) -> u32 { 0 } } fn main() { let a: u32 = 0; let b: u32 = a.a(); } </ins>


<ins> -include ../tools.mk # Test output to be four # The original error only occurred when printing, not when comparing using assert! all: $(RUSTC) foo.rs -O [ `$(call RUN,foo)` = "4" ] </ins>


<ins> // Copyright 2015 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. fn identity(a: &u32) -> &u32 { a } fn print_foo(f: &fn(&u32) -> &u32, x: &u32) { print!("{}", (*f)(x)); } fn main() { let x = &4; let f: fn(&u32) -> &u32 = identity; // Didn't print 4 on optimized builds print_foo(&f, x); } </ins>


<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(core)] extern crate core; use core::marker::Sync; static SARRAY: [i32; 1] = [11]; struct MyStruct { pub arr: *const [i32], } unsafe impl Sync for MyStruct {} static mystruct: MyStruct = MyStruct { arr: &SARRAY }; fn main() {} </ins>


<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. use std::ops::Add; fn f<T: Add>(a: T, b: T) -> <T as Add>::Output { a + b } fn main() { println!("a + b is {}", f::<f32>(100f32, 200f32)); } </ins>


<ins> // Copyright 2015 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. macro_rules! items { () => { type A = (); fn a() {} } } trait Foo { type A; fn a(); } impl Foo for () { items!(); } fn main() { } </ins>


// except according to those terms. /// Creates a `Vec` containing the arguments. <ins> /// /// `vec!` allows `Vec`s to be defined with the same syntax as array expressions. /// There are two forms of this macro: /// /// - Create a `Vec` containing a given list of elements: /// /// ``` /// let v = vec![1, 2, 3]; /// assert_eq!(v[0], 1); /// assert_eq!(v[1], 2); /// assert_eq!(v[2], 3); /// ``` /// /// - Create a `Vec` from a given element and size: /// /// ``` /// let v = vec![1; 3]; /// assert_eq!(v, vec![1, 1, 1]); /// ``` /// /// Note that unlike array expressions this syntax supports all elements /// which implement `Clone` and the number of elements doesn't have to be /// a constant. </ins> #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! vec { <del> ($x:expr; $y:expr) => ( <[_] as $crate::slice::SliceExt>::into_vec( $crate::boxed::Box::new([$x; $y])) </del> <ins> ($elem:expr; $n:expr) => ( $crate::vec::from_elem($elem, $n) </ins> ); ($($x:expr),*) => ( <[_] as $crate::slice::SliceExt>::into_vec(


} } <ins> #[doc(hidden)] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> { unsafe { let mut v = Vec::with_capacity(n); let mut ptr = v.as_mut_ptr(); // Write all elements except the last one for i in 1..n { ptr::write(ptr, Clone::clone(&elem)); ptr = ptr.offset(1); v.set_len(i); // Increment the length in every step in case Clone::clone() panics } if n > 0 { // We can write the last element directly without cloning needlessly ptr::write(ptr, elem); v.set_len(n); } v } } </ins> //////////////////////////////////////////////////////////////////////////////// // Common trait implementations for Vec ////////////////////////////////////////////////////////////////////////////////


assert_eq!(vec![1; 2], vec![1, 1]); assert_eq!(vec![1; 1], vec![1]); assert_eq!(vec![1; 0], vec![]); <ins> // from_elem syntax (see RFC 832) let el = Box::new(1); let n = 3; assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); </ins> }


err.set_primary_message( "cannot initialize a tuple struct which contains private fields", ); <ins> if !def_id.is_local() && self .r .tcx .inherent_impls(def_id) .iter() .flat_map(|impl_def_id| { self.r.tcx.provided_trait_methods(*impl_def_id) }) .any(|assoc| !assoc.fn_has_self_parameter && assoc.name == sym::new) { // FIXME: look for associated functions with Self return type, // instead of relying only on the name and lack of self receiver. err.span_suggestion_verbose( span.shrink_to_hi(), "you might have meant to use the `new` associated function", "::new".to_string(), Applicability::MaybeIncorrect, ); } </ins> // Use spans of the tuple struct definition. self.r.field_def_ids(def_id).map(|field_ids| { field_ids


<ins> // run-rustfix #![allow(dead_code)] struct U <T> { wtf: Option<Box<U<T>>>, x: T, } fn main() { U { wtf: Some(Box::new(U { //~ ERROR cannot initialize a tuple struct which contains private fields wtf: None, x: (), })), x: () }; } </ins>


<ins> // run-rustfix #![allow(dead_code)] struct U <T> { wtf: Option<Box<U<T>>>, x: T, } fn main() { U { wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields wtf: None, x: (), })), x: () }; } </ins>


<ins> error[E0423]: cannot initialize a tuple struct which contains private fields --> $DIR/suggest-box-new.rs:9:19 | LL |         wtf: Some(Box(U { |                   ^^^ | note: constructor is not visible here due to private fields --> $SRC_DIR/alloc/src/boxed.rs:LL:COL | = note: private field | = note: private field help: you might have meant to use the `new` associated function | LL |         wtf: Some(Box::new(U { |                      +++++ error: aborting due to previous error For more information about this error, try `rustc --explain E0423`. </ins>


Exercise: use macros to reduce duplication in the above definition of the `bct!` macro. <ins> # Common macros Here are some common macros you’ll see in Rust code. ## panic! This macro causes the current thread to panic. You can give it a message to panic with: ```rust,no_run panic!("oh no!"); ``` ## vec! The `vec!` macro is used throughout the book, so you’ve probably seen it already. It creates `Vec<T>`s with ease: ```rust let v = vec![1, 2, 3, 4, 5]; ``` It also lets you make vectors with repeating values. For example, a hundred zeroes: ```rust let v = vec![0; 100]; ``` ## assert! and assert_eq! These two macros are used in tests. `assert!` takes a boolean, and `assert_eq!` takes two values and compares them. Truth passes, success `panic!`s. Like this: ```rust,no_run // A-ok! assert!(true); assert_eq!(5, 3 + 2); // nope :( assert!(5 < 3); assert_eq!(5, 3); ``` ## try! `try!` is used for error handling. It takes something that can return a `Result<T, E>`, and gives `T` if it’s a `Ok<T>`, and `return`s with the `Err(E)` if it’s that. Like this: ```rust,no_run use std::fs::File; fn foo() -> std::io::Result<()> { let f = try!(File::create("foo.txt")); Ok(()) } ``` This is cleaner than doing this: ```rust,no_run use std::fs::File; fn foo() -> std::io::Result<()> { let f = File::create("foo.txt"); let f = match f { Ok(t) => t, Err(e) => return Err(e), }; Ok(()) } ``` ## unreachable! This macro is used when you think some code should never execute: ```rust if false { unreachable!(); } ``` Sometimes, the compiler may make you have a different branch that you know will never, ever run. In these cases, use this macro, so that if you end up wrong, you’ll get a `panic!` about it. ```rust let x: Option<i32> = None; match x { Some(_) => unreachable!(), None => println!("I know x is None!"), } ``` ## unimplemented! The `unimplemented!` macro can be used when you’re trying to get your functions to typecheck, and don’t want to worry about writing out the body of the function. One example of this situation is implementing a trait with multiple required methods, where you want to tackle one at a time. Define the others as `unimplemented!` until you’re ready to write them. </ins> # Procedural macros If Rust's macro system can't do what you need, you may want to write a


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. trait Expr : PartialEq<Self::Item> { //~^ ERROR: unsupported cyclic reference between types/traits detected type Item = Expr; } fn main() {} </ins>


<ins> // Copyright 2015 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. // Test that `quote`-related macro are gated by `quote` feature gate. // (To sanity-check the code, uncomment this.) // #![feature(quote)] // FIXME the error message that is current emitted seems pretty bad. #![feature(rustc_private)] #![allow(dead_code, unused_imports, unused_variables)] #[macro_use] extern crate syntax; use syntax::ast; use syntax::codemap::Span; use syntax::parse; struct ParseSess; impl ParseSess { fn cfg(&self) -> ast::CrateConfig { loop { } } fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess { loop { } } fn call_site(&self) -> Span { loop { } } fn ident_of(&self, st: &str) -> ast::Ident { loop { } } fn name_of(&self, st: &str) -> ast::Name { loop { } } } pub fn main() { let ecx = &ParseSess; let x = quote_tokens!(ecx, 3);   //~ ERROR macro undefined: 'quote_tokens!' let x = quote_expr!(ecx, 3);     //~ ERROR macro undefined: 'quote_expr!' let x = quote_ty!(ecx, 3);       //~ ERROR macro undefined: 'quote_ty!' let x = quote_method!(ecx, 3);   //~ ERROR macro undefined: 'quote_method!' let x = quote_item!(ecx, 3);     //~ ERROR macro undefined: 'quote_item!' let x = quote_pat!(ecx, 3);      //~ ERROR macro undefined: 'quote_pat!' let x = quote_arm!(ecx, 3);      //~ ERROR macro undefined: 'quote_arm!' let x = quote_stmt!(ecx, 3);     //~ ERROR macro undefined: 'quote_stmt!' let x = quote_matcher!(ecx, 3);  //~ ERROR macro undefined: 'quote_matcher!' let x = quote_attr!(ecx, 3);     //~ ERROR macro undefined: 'quote_attr!' } </ins>


<ins> // Copyright 2015 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. // Test that `#[link_args]` attribute is gated by `link_args` // feature gate. #[link_args = "aFdEfSeVEEE"] extern {} //~^ ERROR the `link_args` attribute is not portable across platforms //~| HELP add #![feature(link_args)] to the crate attributes to enable fn main() { } </ins>


<ins> // Copyright 2015 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. extern { #[link_name = "llvm.sqrt.f32"] fn sqrt(x: f32) -> f32; //~^ ERROR linking to LLVM intrinsics is experimental //~| HELP add #![feature(link_llvm_intrinsics)] to the crate attributes } fn main(){ } </ins>


// option. This file may not be copied, modified, or distributed // except according to those terms. <ins> // Test that `#[plugin_registrar]` attribute is gated by `plugin_registrar` // feature gate. </ins> // the registration function isn't typechecked yet #[plugin_registrar] <del> pub fn registrar() {} //~ ERROR compiler plugins are experimental </del> <ins> pub fn registrar() {} //~^ ERROR compiler plugins are experimental //~| HELP add #![feature(plugin_registrar)] to the crate attributes to enable </ins> fn main() {}


<ins> // Copyright 2015 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. // Test that `#[thread_local]` attribute is gated by `thread_local` // feature gate. // // (Note that the `thread_local!` macro is explicitly *not* gated; it // is given permission to expand into this unstable attribute even // when the surrounding context does not have permission to use it.) #[thread_local] //~ ERROR `#[thread_local]` is an experimental feature static FOO: i32 = 3; pub fn main() { FOO.with(|x| { println!("x: {}", x); }); } </ins>


<ins> // Copyright 2015 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. // Test that `#[unsafe_destructor]` attribute is gated by `unsafe_destructor` // feature gate. struct D<'a>(&'a u32); #[unsafe_destructor] impl<'a> Drop for D<'a> { //~^ ERROR `#[unsafe_destructor]` allows too many unsafe patterns fn drop(&mut self) { } } //~^ HELP: add #![feature(unsafe_destructor)] to the crate attributes to enable pub fn main() { } </ins>


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Test that macro reexports item are gated by `macro_reexport` feature gate. // aux-build:macro_reexport_1.rs // ignore-stage1 #![crate_type = "dylib"] #[macro_reexport(reexported)] #[macro_use] #[no_link] extern crate macro_reexport_1; //~^ ERROR macros reexports are experimental and possibly buggy //~| HELP add #![feature(macro_reexport)] to the crate attributes to enable </ins>


<ins> // Copyright 2015 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. // Test that patterns including the box syntax are gated by `box_patterns` feature gate. fn main() { let x = Box::new(1); match x { box 1 => (), //~^ box pattern syntax is experimental //~| add #![feature(box_patterns)] to the crate attributes to enable _     => () }; } </ins>


<ins> // Copyright 2015 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. // Test that the use of the box syntax is gated by `box_syntax` feature gate. fn main() { let x = box 3; //~^ ERROR box expression syntax is experimental; you can call `Box::new` instead. //~| HELP add #![feature(box_syntax)] to the crate attributes to enable } </ins>


<ins> // Copyright 2015 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. // Test that the use of smid types in the ffi is gated by `smid_ffi` feature gate. #![feature(simd)] #[repr(C)] #[derive(Copy)] #[simd] pub struct f32x4(f32, f32, f32, f32); #[allow(dead_code)] extern { fn foo(x: f32x4); //~^ ERROR use of SIMD type `f32x4` in FFI is highly experimental and may result in invalid code //~| HELP add #![feature(simd_ffi)] to the crate attributes to enable } fn main() {} </ins>


```rust let captured_var = 10; <del> let closure_no_args = |&:| println!("captured_var={}", captured_var); </del> <ins> let closure_no_args = || println!("captured_var={}", captured_var); </ins> <del> let closure_args = |&: arg: i32| -> i32 { </del> <ins> let closure_args = |arg: i32| -> i32 { </ins> println!("captured_var={}, arg={}", captured_var, arg); arg // Note lack of semicolon after 'arg' };


} } (Ok(const_int(a)), Ok(const_int(b))) => { <del> let is_a_min_value = |&:| { </del> <ins> let is_a_min_value = || { </ins> let int_ty = match ty::expr_ty_opt(tcx, e).map(|ty| &ty.sty) { Some(&ty::ty_int(int_ty)) => int_ty, _ => return false


scope: region::CodeExtent, depth: uint) { <del> let origin = |&:| infer::SubregionOrigin::SafeDestructor(span); </del> <ins> let origin = || infer::SubregionOrigin::SafeDestructor(span); </ins> let mut walker = ty_root.walk(); let opt_phantom_data_def_id = rcx.tcx().lang_items.phantom_data();


// file descriptor. Otherwise, the first file descriptor opened // up in the child would be numbered as one of the stdio file // descriptors, which is likely to wreak havoc. <del> let setup = |&: src: Option<AnonPipe>, dst: c_int| { </del> <ins> let setup = |src: Option<AnonPipe>, dst: c_int| { </ins> let src = match src { None => { let flags = if dst == libc::STDIN_FILENO {


// Similarly to unix, we don't actually leave holes for the stdio file // descriptors, but rather open up /dev/null equivalents. These // equivalents are drawn from libuv's windows process spawning. <del> let set_fd = |&: fd: &Option<AnonPipe>, slot: &mut HANDLE, </del> <ins> let set_fd = |fd: &Option<AnonPipe>, slot: &mut HANDLE, </ins> is_stdin: bool| { match *fd { None => {


{ self.bump(); self.bump(); <del> return; </del> } else if self.eat(&token::Colon) {


<ins> // Copyright 2015 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. // Test that we generate obsolete syntax errors around usages of closure kinds: `|:|`, `|&:|` and // `|&mut:|`. fn main() { let a = |:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:` let a = |&:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:` let a = |&mut:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:` } </ins>


f: F, /// The current internal state to be passed to the closure next. <ins> #[unstable(feature = "core")] </ins> pub state: St, }


pub struct Unfold<St, F> { f: F, /// Internal state that will be passed to the closure on the next iteration <ins> #[unstable(feature = "core")] </ins> pub state: St, }


if i < 0 || buf[i as usize] == b'-' || buf[i as usize] == b'+' { <del> for j in (i as usize + 1..end).rev() { </del> <ins> for j in ((i + 1) as usize..end).rev() { </ins> buf[j + 1] = buf[j]; } buf[(i + 1) as usize] = value2ascii(1);


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #[test] fn test_format_float() { assert!("1" == format!("{:.0}", 1.0f64)); assert!("9" == format!("{:.0}", 9.4f64)); assert!("10" == format!("{:.0}", 9.9f64)); assert!("9.9" == format!("{:.1}", 9.85f64)); } </ins>


// empty. } <ins> unsafe impl Send for .. { } </ins> impl<T> !Send for *const T { } impl<T> !Send for *mut T { } impl !Send for Managed { }


// Empty } <ins> unsafe impl Sync for .. { } </ins> impl<T> !Sync for *const T { } impl<T> !Sync for *mut T { } impl !Sync for Managed { }


pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool { populate_implementations_for_trait_if_necessary(tcx, trait_def_id); <del> match tcx.lang_items.to_builtin_kind(trait_def_id) { Some(BoundSend) | Some(BoundSync) => true, _ => tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id), } </del> <ins> tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id) </ins> } /// Records a trait-to-implementation mapping.


tcx: &'cx ty::ctxt<'tcx> } <del> impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> { fn visit_item(&mut self, item: &'v ast::Item) { match item.node { ast::ItemImpl(unsafety, polarity, _, _, _, _) => { match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) { None => { // Inherent impl. match unsafety { ast::Unsafety::Normal => { /* OK */ } ast::Unsafety::Unsafe => { span_err!(self.tcx.sess, item.span, E0197, "inherent impls cannot be declared as unsafe"); } } </del> <ins> impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { fn check_unsafety_coherence(&mut self, item: &'v ast::Item, unsafety: ast::Unsafety, polarity: ast::ImplPolarity) { match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) { None => { // Inherent impl. match unsafety { ast::Unsafety::Normal => { /* OK */ } ast::Unsafety::Unsafe => { span_err!(self.tcx.sess, item.span, E0197, "inherent impls cannot be declared as unsafe"); </ins> } <ins> } } </ins> <del> Some(trait_ref) => { let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id); match (trait_def.unsafety, unsafety, polarity) { (ast::Unsafety::Unsafe, ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => { span_err!(self.tcx.sess, item.span, E0198, "negative implementations are not unsafe"); } </del> <ins> Some(trait_ref) => { let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id); match (trait_def.unsafety, unsafety, polarity) { (ast::Unsafety::Unsafe, ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => { span_err!(self.tcx.sess, item.span, E0198, "negative implementations are not unsafe"); } </ins> <del> (ast::Unsafety::Normal, ast::Unsafety::Unsafe, _) => { span_err!(self.tcx.sess, item.span, E0199, "implementing the trait `{}` is not unsafe", trait_ref.user_string(self.tcx)); } </del> <ins> (ast::Unsafety::Normal, ast::Unsafety::Unsafe, _) => { span_err!(self.tcx.sess, item.span, E0199, "implementing the trait `{}` is not unsafe", trait_ref.user_string(self.tcx)); } </ins> <del> (ast::Unsafety::Unsafe, ast::Unsafety::Normal, ast::ImplPolarity::Positive) => { span_err!(self.tcx.sess, item.span, E0200, "the trait `{}` requires an `unsafe impl` declaration", trait_ref.user_string(self.tcx)); } </del> <ins> (ast::Unsafety::Unsafe, ast::Unsafety::Normal, ast::ImplPolarity::Positive) => { span_err!(self.tcx.sess, item.span, E0200, "the trait `{}` requires an `unsafe impl` declaration", trait_ref.user_string(self.tcx)); } </ins> <del> (ast::Unsafety::Unsafe, ast::Unsafety::Normal, ast::ImplPolarity::Negative) | (ast::Unsafety::Unsafe, ast::Unsafety::Unsafe, ast::ImplPolarity::Positive) | (ast::Unsafety::Normal, ast::Unsafety::Normal, _) => { /* OK */ } } </del> <ins> (ast::Unsafety::Unsafe, ast::Unsafety::Normal, ast::ImplPolarity::Negative) | (ast::Unsafety::Unsafe, ast::Unsafety::Unsafe, ast::ImplPolarity::Positive) | (ast::Unsafety::Normal, ast::Unsafety::Normal, _) => { /* OK */ </ins> } } } <ins> } } } impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> { fn visit_item(&mut self, item: &'v ast::Item) { match item.node { ast::ItemDefaultImpl(unsafety, _) => { self.check_unsafety_coherence(item, unsafety, ast::ImplPolarity::Positive); } ast::ItemImpl(unsafety, polarity, _, _, _, _) => { self.check_unsafety_coherence(item, unsafety, polarity); } </ins> _ => { } }


} } <ins> ast::ItemDefaultImpl(..) => { self.gate_feature("optin_builtin_traits", i.span, "default trait implementations are experimental  and possibly buggy"); } </ins> ast::ItemImpl(_, polarity, _, _, _, _) => { match polarity { ast::ImplPolarity::Negative => {


impl MyTrait for .. {} //~^ ERROR conflicting implementations for trait `MyTrait` <ins> trait MySafeTrait: MarkerTrait {} unsafe impl MySafeTrait for .. {} //~^ ERROR implementing the trait `MySafeTrait` is not unsafe unsafe trait MyUnsafeTrait: MarkerTrait {} impl MyUnsafeTrait for .. {} //~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration </ins> fn main() {}


// option. This file may not be copied, modified, or distributed // except according to those terms. <ins> #![feature(optin_builtin_traits)] </ins> pub mod bar { use std::marker;


* Sending signals * Accessing/modifying the file system * Unsigned integer overflow (well-defined as wrapping) <del> * Signed integer overflow (well-defined as two's complement representation </del> <ins> * Signed integer overflow (well-defined as two’s complement representation </ins> wrapping) #### Diverging functions


: Exclusive or. Calls the `bitxor` method of the `std::ops::BitXor` trait. * `<<` <del> : Logical left shift. </del> <ins> : Left shift. </ins> Calls the `shl` method of the `std::ops::Shl` trait. * `>>` <del> : Logical right shift. </del> <ins> : Right shift. </ins> Calls the `shr` method of the `std::ops::Shr` trait. #### Lazy boolean operators


#[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { let path = path.as_path(); <del> if path.is_dir() { return Ok(()) } </del> <ins> if path == Path::new("") || path.is_dir() { return Ok(()) } </ins> if let Some(p) = path.parent() { try!(create_dir_all(p)) } create_dir(path) }


<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. use std::env; use std::fs::{self, TempDir}; fn main() { let td = TempDir::new("create-dir-all-bare").unwrap(); env::set_current_dir(td.path()).unwrap(); fs::create_dir_all("create-dir-all-bare").unwrap(); } </ins>


/// ``` #[macro_export] macro_rules! write { <del> ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*))) </del> <ins> ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*))) </ins> } /// Equivalent to the `write!` macro, except that a newline is appended after


<ins> // 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. #![crate_name = "foo"] #[doc(hidden)] pub trait Foo {} trait Dark {} pub trait Bam {} pub struct Bar; struct Hidden; // @!has foo/struct.Bar.html '//*[@id="impl-Foo"]' 'impl Foo for Bar' impl Foo for Bar {} // @!has foo/struct.Bar.html '//*[@id="impl-Dark"]' 'impl Dark for Bar' impl Dark for Bar {} // @has foo/struct.Bar.html '//*[@id="impl-Bam"]' 'impl Bam for Bar' // @has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Bar' impl Bam for Bar {} // @!has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Hidden' impl Bam for Hidden {} </ins>


- name: install WIX run: src/ci/scripts/install-wix.sh if: success() && !env.SKIP_JOB <del> - name: install InnoSetup run: src/ci/scripts/install-innosetup.sh if: success() && !env.SKIP_JOB </del> - name: ensure the build happens on a partition with enough space run: src/ci/scripts/symlink-build-dir.sh if: success() && !env.SKIP_JOB


prepare("rust-mingw"); } <del> builder.install(&xform(&etc.join("exe/rust.iss")), &exe, 0o644); builder.install(&etc.join("exe/modpath.iss"), &exe, 0o644); builder.install(&etc.join("exe/upgrade.iss"), &exe, 0o644); </del> builder.install(&etc.join("gfx/rust-logo.ico"), &exe, 0o644); <del> builder.create(&exe.join("LICENSE.txt"), &license); // Generate exe installer builder.info("building `exe` installer with `iscc`"); let mut cmd = Command::new("iscc"); cmd.arg("rust.iss").arg("/Q").current_dir(&exe); if target.contains("windows-gnu") { cmd.arg("/dMINGW"); } add_env(builder, &mut cmd, target); let time = timeit(builder); builder.run(&mut cmd); drop(time); builder.install( &exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)), &distdir(builder), 0o755, ); </del> // Generate msi installer let wix = PathBuf::from(env::var_os("WIX").unwrap());


displayName: Install wix condition: and(succeeded(), not(variables.SKIP_JOB)) <del> - bash: src/ci/scripts/install-innosetup.sh displayName: Install InnoSetup condition: and(succeeded(), not(variables.SKIP_JOB)) </del> - bash: src/ci/scripts/symlink-build-dir.sh displayName: Ensure the build happens on a partition with enough space condition: and(succeeded(), not(variables.SKIP_JOB))


run: src/ci/scripts/install-wix.sh <<: *step <del> - name: install InnoSetup run: src/ci/scripts/install-innosetup.sh <<: *step </del> - name: ensure the build happens on a partition with enough space run: src/ci/scripts/symlink-build-dir.sh <<: *step


<del> #!/bin/bash # We use InnoSetup and its `iscc` program to also create combined installers. # Honestly at this point WIX above and `iscc` are just holdovers from # oh-so-long-ago and are required for creating installers on Windows. I think # one is MSI installers and one is EXE, but they're not used so frequently at # this point anyway so perhaps it's a wash! set -euo pipefail IFS=$'nt' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" if isWindows; then curl.exe -o is-install.exe "${MIRRORS_BASE}/2017-08-22-is.exe" cmd.exe //c "is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" ciCommandAddPath "C:Program Files (x86)Inno Setup 5" fi </del>