#![stable(feature = "raw_ext", since = "1.1.0")] <del> use os::raw::c_long; use os::unix::raw::{uid_t, gid_t}; </del> <ins> #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64; #[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u16; #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u16; #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; #[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; </ins> <del> #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i64; #[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u16; #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u16; #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64; #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; </del> <ins> #[doc(inline)] pub use self::arch::{stat, time_t}; </ins> <del> #[repr(C)] #[stable(feature = "raw_ext", since = "1.1.0")] pub struct stat { #[stable(feature = "raw_ext", since = "1.1.0")] pub st_dev: dev_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ino: ino_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mode: mode_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_nlink: nlink_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_uid: uid_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_gid: gid_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_rdev: dev_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_size: off_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blocks: blkcnt_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blksize: blksize_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_flags: fflags_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_gen: u32, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_lspare: i32, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_birthtime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_birthtime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub __unused: [u8; 2], </del> <ins> #[cfg(target_arch = "x86")] mod arch { use super::{off_t, dev_t, ino_t, mode_t, nlink_t, blksize_t, blkcnt_t, fflags_t}; use os::raw::c_long; use os::unix::raw::{uid_t, gid_t}; #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32; #[repr(C)] #[stable(feature = "raw_ext", since = "1.1.0")] pub struct stat { #[stable(feature = "raw_ext", since = "1.1.0")] pub st_dev: dev_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ino: ino_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mode: mode_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_nlink: nlink_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_uid: uid_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_gid: gid_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_rdev: dev_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_size: off_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blocks: blkcnt_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blksize: blksize_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_flags: fflags_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_gen: u32, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_lspare: i32, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_birthtime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_birthtime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub __unused: [u8; 8], } </ins> } <ins> #[cfg(target_arch = "x86_64")] mod arch { use super::{off_t, dev_t, ino_t, mode_t, nlink_t, blksize_t, blkcnt_t, fflags_t}; use os::raw::c_long; use os::unix::raw::{uid_t, gid_t}; #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; #[repr(C)] #[stable(feature = "raw_ext", since = "1.1.0")] pub struct stat { #[stable(feature = "raw_ext", since = "1.1.0")] pub st_dev: dev_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ino: ino_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mode: mode_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_nlink: nlink_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_uid: uid_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_gid: gid_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_rdev: dev_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_size: off_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blocks: blkcnt_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blksize: blksize_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_flags: fflags_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_gen: u32, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_lspare: i32, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_birthtime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_birthtime_nsec: c_long, } } </ins>


let info = Load(bcx, get_len(bcx, base_datum.val)); Store(bcx, info, get_len(bcx, scratch.val)); <del> DatumBlock::new(bcx, scratch.to_expr_datum()) </del> <ins> // Always generate an lvalue datum, because this pointer doesn't own // the data and cleanup is scheduled elsewhere. DatumBlock::new(bcx, Datum::new(scratch.val, scratch.ty, LvalueExpr)) </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::rc::Rc; struct Foo<'r>(&'r mut i32); impl<'r> Drop for Foo<'r> { fn drop(&mut self) { *self.0 += 1; } } fn main() { let mut drops = 0; { let _: Rc<Send> = Rc::new(Foo(&mut drops)); } assert_eq!(1, drops); } </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. struct Foo<'r>(&'r mut i32); impl<'r> Drop for Foo<'r> { fn drop(&mut self) { *self.0 += 1; } } trait Trait {} impl<'r> Trait for Foo<'r> {} struct Holder<T: ?Sized>(T); fn main() { let mut drops = 0; { let y = &Holder([Foo(&mut drops)]) as &Holder<[Foo]>; // this used to cause an extra drop of the Foo instance let x = &y.0; } assert_eq!(1, drops); drops = 0; { let y = &Holder(Foo(&mut drops)) as &Holder<Trait>; // this used to cause an extra drop of the Foo instance let x = &y.0; } assert_eq!(1, drops); } </ins>


## Macros ```antlr <del> expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ; </del> <ins> expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ';' | "macro_rules" '!' ident '{' macro_rule * '}' ; </ins> macro_rule : '(' matcher * ')' "=>" '(' transcriber * ')' ';' ; matcher : '(' matcher * ')' | '[' matcher * ']' | '{' matcher * '}' | '$' ident ':' ident


use dep_graph::DepGraph; use middle::infer::InferCtxt; <del> use middle::ty::{self, Ty, TypeFoldable}; </del> <ins> use middle::ty::{self, Ty, TypeFoldable, ToPolyTraitRef}; </ins> use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error}; use std::iter; use syntax::ast;


} } <ins> /// Return the set of type variables contained in a trait ref fn trait_ref_type_vars<'a, 'tcx>(selcx: &mut SelectionContext<'a, 'tcx>, t: ty::PolyTraitRef<'tcx>) -> Vec<Ty<'tcx>> { t.skip_binder() // ok b/c this check doesn't care about regions .input_types() .iter() .map(|t| selcx.infcx().resolve_type_vars_if_possible(t)) .filter(|t| t.has_infer_types()) .flat_map(|t| t.walk()) .filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false }) .collect() } </ins> /// Processes a predicate obligation and returns either: /// - `Ok(Some(v))` if the predicate is true, presuming that `v` are also true /// - `Ok(None)` if we don't have enough info to be sure


// doing more work yet if !pending_obligation.stalled_on.is_empty() { if pending_obligation.stalled_on.iter().all(|&ty| { <del> let resolved_ty = selcx.infcx().resolve_type_vars_if_possible(&ty); </del> <ins> let resolved_ty = selcx.infcx().shallow_resolve(&ty); </ins> resolved_ty == ty // nothing changed here }) { debug!("process_predicate: pending obligation {:?} still stalled on {:?}",


// of its type, and those types are resolved at // the same time. pending_obligation.stalled_on = <del> data.skip_binder() // ok b/c this check doesn't care about regions .input_types() .iter() .map(|t| selcx.infcx().resolve_type_vars_if_possible(t)) .filter(|t| t.has_infer_types()) .flat_map(|t| t.walk()) .filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false }) .collect(); </del> <ins> trait_ref_type_vars(selcx, data.to_poly_trait_ref()); </ins> debug!("process_predicate: pending obligation {:?} now stalled on {:?}", selcx.infcx().resolve_type_vars_if_possible(obligation),


ty::Predicate::Projection(ref data) => { let project_obligation = obligation.with(data.clone()); match project::poly_project_and_unify_type(selcx, &project_obligation) { <ins> Ok(None) => { pending_obligation.stalled_on = trait_ref_type_vars(selcx, data.to_poly_trait_ref()); Ok(None) } </ins> Ok(v) => Ok(v), Err(e) => Err(CodeProjectionError(e)) }


} ty::Predicate::WellFormed(ty) => { <del> Ok(ty::wf::obligations(selcx.infcx(), obligation.cause.body_id, ty, obligation.cause.span)) </del> <ins> match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id, ty, obligation.cause.span) { None => { pending_obligation.stalled_on = vec![ty]; Ok(None) } s => Ok(s) } </ins> } } }


impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { <del> self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone()) </del> <ins> self.map_bound_ref(|trait_pred| trait_pred.trait_ref) </ins> } }


// This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. <del> ty::Binder(self.0.projection_ty.trait_ref.clone()) </del> <ins> ty::Binder(self.0.projection_ty.trait_ref) </ins> } }


<ins> // Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn main() { macro_rules! f { () => { 0 + 0 } } // 16 per line f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); } </ins>


tts: vec![TtToken(sp, token::Ident(token::str_to_ident("doc"), token::Plain)), TtToken(sp, token::Eq), <del> TtToken(sp, token::Literal(token::Str_(name), None))], </del> <ins> TtToken(sp, token::Literal(token::StrRaw(name, 0), None))], </ins> close_span: sp, })) }


<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. // When expanding a macro, documentation attributes (including documentation comments) must be // passed "as is" without being parsed. Otherwise, some text will be incorrectly interpreted as // escape sequences, leading to an ICE. // // Related issues: #25929, #25943 macro_rules! homura { (#[$x:meta]) => () } homura! { /// madoka x41 } fn main() { } </ins>


<ins> // ignore-tidy-linelength // regression test for #26376 trait Foo { fn foo(&self) -> [u8]; } fn foo(f: Option<&dyn Foo>) { if let Some(f) = f { let _ = f.foo(); //~^ ERROR cannot move a value of type [u8]: the size of [u8] cannot be statically determined } } fn main() { foo(None) } </ins>


<ins> error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined --> $DIR/return-unsized-from-trait-method.rs:11:17 | LL |         let _ = f.foo(); |                 ^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0161`. </ins>


//! //! where `&.T` and `*T` are references of either mutability, //! and where unsize_kind(`T`) is the kind of the unsize info <del> //! in `T` - a vtable or a length (or `()` if `T: Sized`). </del> <ins> //! in `T` - the vtable for a trait definition (e.g. `fmt::Display` or //! `Iterator`, not `Iterator<Item=u8>`) or a length (or `()` if `T: Sized`). //! //! Note that lengths are not adjusted when casting raw slices - //! `T: *const [u16] as *const [u8]` creates a slice that only includes //! half of the original memory. </ins> //! //! Casting is not transitive, that is, even if `e as U1 as U2` is a valid //! expression, `e as U2` is not necessarily so (in fact it will only be valid if


/// fat pointers if their unsize-infos have the same kind. #[derive(Copy, Clone, PartialEq, Eq)] enum UnsizeKind<'tcx> { <del> Vtable, </del> <ins> Vtable(ast::DefId), </ins> Length, /// The unsize info of this projection OfProjection(&'tcx ty::ProjectionTy<'tcx>),


-> Option<UnsizeKind<'tcx>> { match t.sty { ty::TySlice(_) | ty::TyStr => Some(UnsizeKind::Length), <del> ty::TyTrait(_) => Some(UnsizeKind::Vtable), </del> <ins> ty::TyTrait(ref tty) => Some(UnsizeKind::Vtable(tty.principal_def_id())), </ins> ty::TyStruct(did, substs) => { match ty::struct_fields(fcx.tcx(), did, substs).pop() { None => None,


trait Foo { fn foo(&self) {} } impl<T> Foo for T {} <ins> trait Bar { fn foo(&self) {} } impl<T> Bar for T {} </ins> enum E { A, B }


// check no error cascade let _ = main.f as *const u32; //~ ERROR attempted access of field <ins> let cf: *const Foo = &0; let _ = cf as *const [u8]; //~ ERROR vtable kinds let _ = cf as *const Bar; //~ ERROR vtable kinds </ins> }


impl Foo<u32> for u32 { fn foo(&self, _: u32) -> u32 { self+43 } } impl Bar for () {} <del> unsafe fn fool<'a>(t: *const (Foo<u32>+'a)) -> u32 { let bar : *const Bar = t as *const Bar; </del> <ins> unsafe fn round_trip_and_call<'a>(t: *const (Foo<u32>+'a)) -> u32 { </ins> let foo_e : *const Foo<u16> = t as *const _; let r_1 = foo_e as *mut Foo<u32>; <del> (&*r_1).foo(0)*(&*(bar as *const Foo<u32>)).foo(0) </del> <ins> (&*r_1).foo(0) </ins> } #[repr(C)]


fn main() { let x = 4u32; let y : &Foo<u32> = &x; <del> let fl = unsafe { fool(y as *const Foo<u32>) }; assert_eq!(fl, (43+4)*(43+4)); </del> <ins> let fl = unsafe { round_trip_and_call(y as *const Foo<u32>) }; assert_eq!(fl, (43+4)); </ins> let s = FooS([0,1,2]); let u: &FooS<[u32]> = &s;


assert_eq!(u as *const u8, p as *const u8); assert_eq!(u as *const u16, p as *const u16); <del> // ptr-ptr-cast (both vk=Length) </del> <ins> // ptr-ptr-cast (Length vtables) </ins> let mut l : [u8; 2] = [0,1]; let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _; let w: *mut [u16] = unsafe {&mut *w};


let l_via_str = unsafe{&*(s as *const [u8])}; assert_eq!(&l, l_via_str); <ins> // ptr-ptr-cast (Length vtables, check length is preserved) let l: [[u8; 3]; 2] = [[3, 2, 6], [4, 5, 1]]; let p: *const [[u8; 3]] = &l; let p: &[[u8; 2]] = unsafe {&*(p as *const [[u8; 2]])}; assert_eq!(p, [[3, 2], [6, 4]]); </ins> // enum-cast assert_eq!(Simple::A as u8, 0); assert_eq!(Simple::B as u8, 1);


let impl_m = &cm.mty; <del> if impl_m.fty.meta.purity != trait_m.fty.meta.purity { tcx.sess.span_err( cm.span, fmt!("method `%s`'s purity does  not match the trait method's  purity", tcx.sess.str_of(impl_m.ident))); } // is this check right? </del> <ins> // FIXME(#2687)---this check is too strict.  For example, a trait // method with self type `&self` or `&mut self` should be // implementable by an `&const self` method (the impl assumes less // than the trait provides). </ins> if impl_m.self_ty != trait_m.self_ty { tcx.sess.span_err( cm.span,


return; } <ins> // FIXME(#2687)---we should be checking that the bounds of the // trait imply the bounds of the subtype, but it appears // we are...not checking this. </ins> for trait_m.tps.eachi() |i, trait_param_bounds| { // For each of the corresponding impl ty param's bounds... let impl_param_bounds = impl_m.tps[i];


debug!("trait_fty (pre-subst): %s", ty_to_str(tcx, trait_fty)); ty::subst(tcx, &substs, trait_fty) }; <del> debug!("trait_fty: %s", ty_to_str(tcx, trait_fty)); require_same_types( tcx, None, false, cm.span, impl_fty, trait_fty, || fmt!("method `%s` has an incompatible type", tcx.sess.str_of(trait_m.ident))); </del> <ins> let infcx = infer::new_infer_ctxt(tcx); match infer::mk_subty(infcx, false, cm.span, impl_fty, trait_fty) { result::Ok(()) => {} result::Err(ref terr) => { tcx.sess.span_err( cm.span, fmt!("method `%s` has an incompatible type: %s", tcx.sess.str_of(trait_m.ident), ty::type_err_to_str(tcx, terr))); ty::note_and_explain_type_err(tcx, terr); } } </ins> return; // Replaces bound references to the self region with `with_r`.


<ins> trait Mumbo { pure fn jumbo(&self, x: @uint) -> uint; fn jambo(&self, x: @const uint) -> uint; fn jbmbo(&self) -> @uint; } impl uint: Mumbo { // Cannot have a larger effect than the trait: fn jumbo(&self, x: @uint) { *self + *x; } //~^ ERROR expected pure fn but found impure fn // Cannot accept a narrower range of parameters: fn jambo(&self, x: @uint) { *self + *x; } //~^ ERROR values differ in mutability // Cannot return a wider range of values: fn jbmbo(&self) -> @const uint { @const 0 } //~^ ERROR values differ in mutability } fn main() {} </ins>


<ins> trait Mumbo { fn jumbo(&self, x: @uint) -> uint; } impl uint: Mumbo { // Note: this method def is ok, it is more accepting and // less effecting than the trait method: pure fn jumbo(&self, x: @const uint) -> uint { *self + *x } } fn main() { let a = 3u; let b = a.jumbo(@mut 6); let x = @a as @Mumbo; let y = x.jumbo(@mut 6); //~ ERROR values differ in mutability let z = x.jumbo(@6); } </ins>


fn bar<'a>(...) ``` <del> This part declares our lifetimes. This says that `bar` has one lifetime, `'a`. If we had two reference parameters, it would look like this: </del> <ins> We previously talked a little about [function syntax][functions], but we didn’t discuss the `<>`s after a function’s name. A function can have ‘generic parameters’ between the `<>`s, of which lifetimes are one kind. We’ll discuss other kinds of generics [later in the book][generics], but for now, let’s just focus on the lifteimes aspect. [functions]: functions.html [generics]: generics.html We use `<>` to declare our lifetimes. This says that `bar` has one lifetime, `'a`. If we had two reference parameters, it would look like this: </ins> ```rust,ignore fn bar<'a, 'b>(...)


let mut sign = None; if !is_positive { sign = Some('-'); width += 1; <del> } else if self.flags & (1 << (FlagV1::SignPlus as u32)) != 0 { </del> <ins> } else if self.sign_plus() { </ins> sign = Some('+'); width += 1; } let mut prefixed = false; <del> if self.flags & (1 << (FlagV1::Alternate as u32)) != 0 { </del> <ins> if self.alternate() { </ins> prefixed = true; width += prefix.char_len(); }


} // The sign and prefix goes before the padding if the fill character // is zero <del> Some(min) if self.flags & (1 << (FlagV1::SignAwareZeroPad as u32)) != 0 => { </del> <ins> Some(min) if self.sign_aware_zero_pad() => { </ins> self.fill = '0'; try!(write_prefix(self)); self.with_padding(min - width, Alignment::Right, |f| {


let mut formatted = formatted.clone(); let mut align = self.align; let old_fill = self.fill; <del> if self.flags & (1 << (FlagV1::SignAwareZeroPad as u32)) != 0 { </del> <ins> if self.sign_aware_zero_pad() { </ins> // a sign always goes first let sign = unsafe { str::from_utf8_unchecked(formatted.sign) }; try!(self.buf.write_str(sign));


issue = "27726")] pub fn precision(&self) -> Option<usize> { self.precision } <ins> /// Determines if the `+` flag was specified. #[unstable(feature = "fmt_flags", reason = "method was just created", issue = "27726")] pub fn sign_plus(&self) -> bool { self.flags & (1 << FlagV1::SignPlus as u32) != 0 } /// Determines if the `-` flag was specified. #[unstable(feature = "fmt_flags", reason = "method was just created", issue = "27726")] pub fn sign_minus(&self) -> bool { self.flags & (1 << FlagV1::SignMinus as u32) != 0 } /// Determines if the `#` flag was specified. #[unstable(feature = "fmt_flags", reason = "method was just created", issue = "27726")] pub fn alternate(&self) -> bool { self.flags & (1 << FlagV1::Alternate as u32) != 0 } /// Determines if the `0` flag was specified. #[unstable(feature = "fmt_flags", reason = "method was just created", issue = "27726")] pub fn sign_aware_zero_pad(&self) -> bool { self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0 } </ins> /// Creates a `DebugStruct` builder designed to assist with creation of /// `fmt::Debug` implementations for structs. ///


// it denotes whether to prefix with 0x. We use it to work out whether // or not to zero extend, and then unconditionally set it to get the // prefix. <del> if f.flags & 1 << (FlagV1::Alternate as u32) > 0 { </del> <ins> if f.alternate() { </ins> f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32); if let None = f.width {


fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result where T: flt2dec::DecodableFloat { <del> let force_sign = fmt.flags & (1 << (FlagV1::SignPlus as u32)) != 0; </del> <ins> let force_sign = fmt.sign_plus(); </ins> let sign = match (force_sign, negative_zero) { (false, false) => flt2dec::Sign::Minus, (false, true)  => flt2dec::Sign::MinusRaw,


fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) -> Result where T: flt2dec::DecodableFloat { <del> let force_sign = fmt.flags & (1 << (FlagV1::SignPlus as u32)) != 0; </del> <ins> let force_sign = fmt.sign_plus(); </ins> let sign = match force_sign { false => flt2dec::Sign::Minus, true  => flt2dec::Sign::MinusPlus,


// // Local Variables: <del> // mode: C++ </del> <ins> // mode: rust </ins> // fill-column: 78; // indent-tabs-mode: nil // c-basic-offset: 4


} function startSearch() { <ins> $(".search-input").on("keyup",function() { if ($(this).val().length === 0) { window.history.replaceState("", "std - Rust", "?search="); $('#main.content').removeClass('hidden'); $('#search.content').addClass('hidden'); } }); </ins> var keyUpTimeout; $('.do-search').on('click', search); $('.search-input').on('keyup', function() {


E0495, // cannot infer an appropriate lifetime due to conflicting requirements E0496, // .. name `..` shadows a .. name that is already in scope E0498, // malformed plugin attribute <ins> E0514, // metadata version mismatch </ins> }


pub const tag_impl_coerce_unsized_kind: usize = 0xa5; pub const tag_items_data_item_constness: usize = 0xa6; <ins> pub const tag_rustc_version: usize = 0x10f; pub fn rustc_version() -> String { format!( "rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version") ) } </ins>


use back::svh::Svh; use session::{config, Session}; use session::search_paths::PathKind; <ins> use metadata::common::rustc_version; </ins> use metadata::cstore; use metadata::cstore::{CStore, CrateSource, MetadataBlob}; use metadata::decoder;


return ret; } <ins> fn verify_rustc_version(&self, name: &str, span: Span, metadata: &MetadataBlob) { let crate_rustc_version = decoder::crate_rustc_version(metadata.as_slice()); if crate_rustc_version != Some(rustc_version()) { span_err!(self.sess, span, E0514, "the crate `{}` has been compiled with {}, which is  incompatible with this version of rustc", name, crate_rustc_version .as_ref().map(|s|&**s) .unwrap_or("an old version of rustc") ); self.sess.abort_if_errors(); } } </ins> fn register_crate(&mut self, root: &Option<CratePaths>, ident: &str,


explicitly_linked: bool) -> (ast::CrateNum, Rc<cstore::crate_metadata>, cstore::CrateSource) { <ins> self.verify_rustc_version(name, span, &lib.metadata); </ins> // Claim this crate number and cache it let cnum = self.next_crate_num; self.next_crate_num += 1;


index::Index::from_buf(index.data, index.start, index.end) } <ins> pub fn crate_rustc_version(data: &[u8]) -> Option<String> { let doc = rbml::Doc::new(data); reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.as_str()) } </ins> #[derive(Debug, PartialEq)] enum Family { ImmStatic,             // c


rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str()); } <ins> fn encode_rustc_version(rbml_w: &mut Encoder) { rbml_w.wr_tagged_str(tag_rustc_version, &rustc_version()); } </ins> fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) { rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name); }


let mut rbml_w = Encoder::new(wr); <ins> encode_rustc_version(&mut rbml_w); </ins> encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name); encode_crate_triple(&mut rbml_w, &tcx.sess.opts.target_triple); encode_hash(&mut rbml_w, &ecx.link_meta.crate_hash);


// can just use the tcx as the typer. // // FIXME(stage0): the :'t here is probably only important for stage0 <del> pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d+'t> { </del> <ins> pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d> { </ins> typer: &'t infer::InferCtxt<'a, 'tcx>, mc: mc::MemCategorizationContext<'t, 'a, 'tcx>, delegate: &'d mut Delegate<'tcx>,


impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { pub fn new(delegate: &'d mut Delegate<'tcx>, typer: &'t infer::InferCtxt<'a, 'tcx>) <del> -> ExprUseVisitor<'d,'t,'a,'tcx> </del> <ins> -> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a </ins> { ExprUseVisitor { typer: typer,


% Closures <del> Rust not only has named functions, but anonymous functions as well. Anonymous functions that have an associated environment are called ‘closures’, because they close over an environment. Rust has a really great implementation of them, as we’ll see. </del> <ins> Sometimes it is useful to wrap up a function and _free variables_ for better clarity and reuse. The free variables that can be used come from the enclosing scope and are ‘closed over’ when used in the function. From this, we get the name ‘closures’ and Rust provides a really great implementation of them, as we’ll see. </ins> # Syntax


``` You’ll notice a few things about closures that are a bit different from regular <del> functions defined with `fn`. The first is that we did not need to </del> <ins> named functions defined with `fn`. The first is that we did not need to </ins> annotate the types of arguments the closure takes or the values it returns. We can:


assert_eq!(2, plus_one(1)); ``` <del> But we don’t have to. Why is this? Basically, it was chosen for ergonomic reasons. While specifying the full type for named functions is helpful with things like documentation and type inference, the types of closures are rarely documented since they’re anonymous, and they don’t cause the kinds of error-at-a-distance problems that inferring named function types can. </del> <ins> But we don’t have to. Why is this? Basically, it was chosen for ergonomic reasons. While specifying the full type for named functions is helpful with things like documentation and type inference, the full type signatures of closures are rarely documented since they’re anonymous, and they don’t cause the kinds of error-at-a-distance problems that inferring named function types can. </ins> <del> The second is that the syntax is similar, but a bit different. I’ve added spaces here for easier comparison: </del> <ins> The second is that the syntax is similar, but a bit different. I’ve added spaces here for easier comparison: </ins> ```rust fn  plus_one_v1   (x: i32) -> i32 { x + 1 }


# Closures and their environment <del> Closures are called such because they ‘close over their environment’. It looks like this: </del> <ins> The environment for a closure can include bindings from its enclosing scope in addition to parameters and local bindings. It looks like this: </ins> ```rust let num = 5;


it, while a `move` closure is self-contained. This means that you cannot generally return a non-`move` closure from a function, for example. <del> But before we talk about taking and returning closures, we should talk some more about the way that closures are implemented. As a systems language, Rust gives you tons of control over what your code does, and closures are no different. </del> <ins> But before we talk about taking and returning closures, we should talk some more about the way that closures are implemented. As a systems language, Rust gives you tons of control over what your code does, and closures are no different. </ins> # Closure implementation


#   some_closure(1) } ``` <del> Because `Fn` is a trait, we can bound our generic with it. In this case, our closure takes a `i32` as an argument and returns an `i32`, and so the generic bound we use is `Fn(i32) -> i32`. </del> <ins> Because `Fn` is a trait, we can bound our generic with it. In this case, our closure takes a `i32` as an argument and returns an `i32`, and so the generic bound we use is `Fn(i32) -> i32`. </ins> There’s one other key point here: because we’re bounding a generic with a trait, this will get monomorphized, and therefore, we’ll be doing static


The error also points out that the return type is expected to be a reference, but what we are trying to return is not. Further, we cannot directly assign a `'static` lifetime to an object. So we'll take a different approach and return <del> a "trait object" by `Box`ing up the `Fn`. This _almost_ works: </del> <ins> a ‘trait object’ by `Box`ing up the `Fn`. This _almost_ works: </ins> ```rust,ignore fn factory() -> Box<Fn(i32) -> i32> {


#[inline] fn last(self) -> Option<A::Item> { match self.state { <del> ChainState::Both => self.b.last().or(self.a.last()), </del> <ins> ChainState::Both => { // Must exhaust a before b. let a_last = self.a.last(); let b_last = self.b.last(); b_last.or(a_last) }, </ins> ChainState::Front => self.a.last(), ChainState::Back => self.b.last() }


talk about what you do want instead. There are three broad classes of things that are relevant here: iterators, <del> *iterator adapters*, and *consumers*. Here's some definitions: </del> <ins> *iterator adaptors*, and *consumers*. Here's some definitions: </ins> * *iterators* give you a sequence of values. <del> * *iterator adapters* operate on an iterator, producing a new iterator with a </del> <ins> * *iterator adaptors* operate on an iterator, producing a new iterator with a </ins> different output sequence. * *consumers* operate on an iterator, producing some final set of values.


These two basic iterators should serve you well. There are some more advanced iterators, including ones that are infinite. <del> That's enough about iterators. Iterator adapters are the last concept </del> <ins> That's enough about iterators. Iterator adaptors are the last concept </ins> we need to talk about with regards to iterators. Let's get to it! <del> ## Iterator adapters </del> <ins> ## Iterator adaptors </ins> <del> *Iterator adapters* take an iterator and modify it somehow, producing </del> <ins> *Iterator adaptors* take an iterator and modify it somehow, producing </ins> a new iterator. The simplest one is called `map`: ```rust,ignore


If you are trying to execute a closure on an iterator for its side effects, just use `for` instead. <del> There are tons of interesting iterator adapters. `take(n)` will return an </del> <ins> There are tons of interesting iterator adaptors. `take(n)` will return an </ins> iterator over the next `n` elements of the original iterator. Let's try it out with an infinite iterator:


This will give you a vector containing `6`, `12`, `18`, `24`, and `30`. <del> This is just a small taste of what iterators, iterator adapters, and consumers </del> <ins> This is just a small taste of what iterators, iterator adaptors, and consumers </ins> can help you with. There are a number of really useful iterators, and you can write your own as well. Iterators provide a safe, efficient way to manipulate all kinds of lists. They're a little unusual at first, but if you play with


#[stable(feature = "rust1", since = "1.0.0")] impl<T> Drop for IntoIter<T> { <ins> #[unsafe_destructor_blind_to_params] </ins> fn drop(&mut self) { // destroy the remaining elements for _x in self {}


<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. // This test ensures that vec.into_iter does not overconstrain element lifetime. pub fn main() { original_report(); revision_1(); revision_2(); } fn original_report() { drop(vec![&()].into_iter()) } fn revision_1() { // below is what above `vec!` expands into at time of this writing. drop(<[_]>::into_vec(::std::boxed::Box::new([&()])).into_iter()) } fn revision_2() { drop((match (Vec::new(), &()) { (mut v, b) => { v.push(b); v } }).into_iter()) } </ins>


///     use std::io::Cursor; ///     let mut buff = Cursor::new(vec![0; 15]); /// <del> ///     write_ten_bytes(&mut buff).unwrap(); </del> <ins> ///     write_ten_bytes_at_end(&mut buff).unwrap(); </ins> /// ///     assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// }


// option. This file may not be copied, modified, or distributed // except according to those terms. <del> //! A Unicode scalar value </del> <ins> //! Unicode scalar values </ins> //! //! This module provides the `CharExt` trait, as well as its //! implementation for the primitive `char` type, in order to allow


/// character, as `char`s. /// /// All characters are escaped with Rust syntax of the form `u{NNNN}` <del> /// where `NNNN` is the shortest hexadecimal representation of the code /// point. </del> <ins> /// where `NNNN` is the shortest hexadecimal representation. </ins> /// /// # Examples /// <ins> /// Basic usage: /// </ins> /// ``` /// for c in '❤'.escape_unicode() { ///     print!("{}", c);


/// /// # Examples /// <ins> /// Basic usage: /// </ins> /// ``` /// let n = 'ß'.len_utf16(); /// assert_eq!(n, 1);


/// /// # Examples /// <ins> /// Basic usage: /// </ins> /// ``` /// #![feature(decode_utf16)] ///


#[doc(primitive = "char")] // <del> /// A Unicode scalar value. </del> <ins> /// A character type. </ins> /// <del> /// A `char` represents a /// *[Unicode scalar /// value](http://www.unicode.org/glossary/#unicode_scalar_value)*, as it can /// contain any Unicode code point except high-surrogate and low-surrogate code /// points. </del> <ins> /// The `char` type represents a single character. More specifically, since /// 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode /// scalar value]', which is similar to, but not the same as, a '[Unicode code /// point]'. </ins> /// <del> /// As such, only values in the ranges [0x0,0xD7FF] and [0xE000,0x10FFFF] /// (inclusive) are allowed. A `char` can always be safely cast to a `u32`; /// however the converse is not always true due to the above range limits /// and, as such, should be performed via the `from_u32` function. </del> <ins> /// [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value /// [Unicode code point]: http://www.unicode.org/glossary/#code_point </ins> /// <del> /// *[See also the `std::char` module](char/index.html).* </del> <ins> /// This documentation describes a number of methods and trait implementations on the /// `char` type. For technical reasons, there is additional, separate /// documentation in [the `std::char` module](char/index.html) as well. </ins> /// <ins> /// # Representation /// /// `char` is always four bytes in size. This is a different representation than /// a given character would have as part of a [`String`], for example: /// /// ``` /// let v = vec!['h', 'e', 'l', 'l', 'o']; /// /// // five elements times four bytes for each element /// assert_eq!(20, v.len() * std::mem::size_of::<char>()); /// /// let s = String::from("hello"); /// /// // five elements times one byte per element /// assert_eq!(5, s.len() * std::mem::size_of::<u8>()); /// ``` /// /// [`String`]: string/struct.String.html /// /// As always, remember that a human intuition for 'character' may not map to /// Unicode's definitions. For example, emoji symbols such as '❤' are more than /// one byte; ❤ in particular is six: /// /// ``` /// let s = String::from("❤"); /// /// // six bytes times one byte for each element /// assert_eq!(6, s.len() * std::mem::size_of::<u8>()); /// ``` /// /// This also means it won't fit into a `char`, and so trying to create a /// literal with `let heart = '❤';` gives an error: /// /// ```text /// error: character literal may only contain one codepoint: '❤ /// let heart = '❤'; ///             ^~ /// ``` /// /// Another implication of this is that if you want to do per-`char`acter /// processing, it can end up using a lot more memory: /// /// ``` /// let s = String::from("love: ❤"); /// let v: Vec<char> = s.chars().collect(); /// /// assert_eq!(12, s.len() * std::mem::size_of::<u8>()); /// assert_eq!(32, v.len() * std::mem::size_of::<char>()); /// ``` /// /// Or may give you results you may not expect: /// /// ``` /// let s = String::from("❤"); /// /// let mut iter = s.chars(); /// /// // we get two chars out of a single ❤ /// assert_eq!(Some('u{2764}'), iter.next()); /// assert_eq!(Some('u{fe0f}'), iter.next()); /// assert_eq!(None, iter.next()); /// ``` </ins> mod prim_char { } #[doc(primitive = "unit")]


//! Like many traits, these are often used as bounds for generic functions, to //! support arguments of multiple types. //! <ins> //! - Impl the `As*` traits for reference-to-reference conversions //! - Impl the `Into` trait when you want to consume the value in the conversion //! - The `From` trait is the most flexible, usefull for values _and_ references conversions //! //! As a library writer, you should prefer implementing `From<T>` rather than //! `Into<U>`, as `From` provides greater flexibility and offer the equivalent `Into` //! implementation for free, thanks to a blanket implementation in the standard library. //! //! **Note: these traits must not fail**. If the conversion can fail, you must use a dedicated //! method which return an `Option<T>` or a `Result<T, E>`. //! //! # Generic impl //! //! - `AsRef` and `AsMut` auto-dereference if the inner type is a reference //! - `From<U> for T` implies `Into<T> for U` //! - `From` and `Into` are reflexive, which means that all types can `into()` //!   themselves and `from()` themselves //! </ins> //! See each trait for usage examples. #![stable(feature = "rust1", since = "1.0.0")]


/// /// [book]: ../../book/borrow-and-asref.html /// <ins> /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which /// return an `Option<T>` or a `Result<T, E>`. /// </ins> /// # Examples /// /// Both `String` and `&str` implement `AsRef<str>`:


/// let s = "hello".to_string(); /// is_hello(s); /// ``` <ins> /// /// # Generic Impls /// /// - `AsRef` auto-dereference if the inner type is a reference or a mutable /// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) /// </ins> #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRef<T: ?Sized> { /// Performs the conversion.


} /// A cheap, mutable reference-to-mutable reference conversion. <ins> /// /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which /// return an `Option<T>` or a `Result<T, E>`. /// /// # Generic Impls /// /// - `AsMut` auto-dereference if the inner type is a reference or a mutable /// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) /// </ins> #[stable(feature = "rust1", since = "1.0.0")] pub trait AsMut<T: ?Sized> { /// Performs the conversion.


/// A conversion that consumes `self`, which may or may not be expensive. /// <ins> /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which /// return an `Option<T>` or a `Result<T, E>`. /// /// Library writer should not implement directly this trait, but should prefer the implementation /// of the `From` trait, which offer greater flexibility and provide the equivalent `Into` /// implementation for free, thanks to a blanket implementation in the standard library. /// </ins> /// # Examples /// /// `String` implements `Into<Vec<u8>>`:


/// let s = "hello".to_string(); /// is_hello(s); /// ``` <ins> /// /// # Generic Impls /// /// - `From<T> for U` implies `Into<U> for T` /// - `into()` is reflexive, which means that `Into<T> for T` is implemented /// </ins> #[stable(feature = "rust1", since = "1.0.0")] pub trait Into<T>: Sized { /// Performs the conversion.


/// Construct `Self` via a conversion. /// <ins> /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which /// return an `Option<T>` or a `Result<T, E>`. /// </ins> /// # Examples /// /// `String` implements `From<&str>`:


/// /// assert_eq!(string, other_string); /// ``` <ins> /// # Generic impls /// /// - `From<T> for U` implies `Into<U> for T` /// - `from()` is reflexive, which means that `From<T> for T` is implemented /// </ins> #[stable(feature = "rust1", since = "1.0.0")] pub trait From<T>: Sized { /// Performs the conversion.


} } <ins> pub fn get_static_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: DefId, ty: Ty<'tcx>) -> ValueRef { if let Some(node_id) = ccx.tcx().map.as_local_node_id(did) { base::get_item_val(ccx, node_id) } else { base::get_extern_const(ccx, did, ty) } } </ins>


use middle::def_id::DefId; use trans::{adt, closure, debuginfo, expr, inline, machine}; use trans::base::{self, push_ctxt}; <ins> use trans::common::{self, type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt}; </ins> use trans::common::{CrateContext, C_integral, C_floating, C_bool, C_str_slice, C_bytes, val_ty}; <del> use trans::common::{type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt}; </del> use trans::common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, VariantInfo, C_uint}; use trans::common::{type_is_fat_ptr, Field, C_vector, C_array, C_null, ExprId, MethodCallKey}; use trans::declare;


} let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def()); if let Some(def::DefStatic(def_id, _)) = opt_def { <del> get_static_val(cx, def_id, ety) </del> <ins> common::get_static_val(cx, def_id, ety) </ins> } else { // If this isn't the address of a static, then keep going through // normal constant evaluation.


Ok(g) } } <del> fn get_static_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: DefId, ty: Ty<'tcx>) -> ValueRef { if let Some(node_id) = ccx.tcx().map.as_local_node_id(did) { base::get_item_val(ccx, node_id) } else { base::trans_external_path(ccx, did, ty) } } </del>


DatumBlock::new(bcx, datum.to_expr_datum()) } def::DefStatic(did, _) => { <del> // There are two things that may happen here: //  1) If the static item is defined in this crate, it will be //     translated using `get_item_val`, and we return a pointer to //     the result. //  2) If the static item is defined in another crate then we add //     (or reuse) a declaration of an external global, and return a //     pointer to that. </del> let const_ty = expr_ty(bcx, ref_expr); <del> // For external constants, we don't inline. let val = if let Some(node_id) = bcx.tcx().map.as_local_node_id(did) { // Case 1. // The LLVM global has the type of its initializer, // which may not be equal to the enum's type for // non-C-like enums. let val = base::get_item_val(bcx.ccx(), node_id); let pty = type_of::type_of(bcx.ccx(), const_ty).ptr_to(); PointerCast(bcx, val, pty) } else { // Case 2. base::get_extern_const(bcx.ccx(), did, const_ty) }; </del> <ins> let val = get_static_val(bcx.ccx(), did, const_ty); </ins> let lval = Lvalue::new("expr::trans_def"); DatumBlock::new(bcx, Datum::new(val, const_ty, LvalueExpr(lval))) }


tcx.sess.bug(&format!("using operand temp {:?} as lvalue", lvalue)), }, mir::Lvalue::Arg(index) => self.args[index as usize], <del> mir::Lvalue::Static(_def_id) => unimplemented!(), </del> <ins> mir::Lvalue::Static(def_id) => { let const_ty = self.mir.lvalue_ty(tcx, lvalue); LvalueRef::new(common::get_static_val(ccx, def_id, const_ty.to_ty(tcx)), const_ty) }, </ins> mir::Lvalue::ReturnPointer => { let return_ty = bcx.monomorphize(&self.mir.return_ty); let llval = fcx.get_ret_slot(bcx, return_ty, "return");


[rust]: https://www.rust-lang.org <del> “The Rust Programming Language” is split into eight sections. This introduction </del> <ins> “The Rust Programming Language” is split into sections. This introduction </ins> is the first. After this: * [Getting started][gs] - Set up your computer for Rust development. <del> * [Learn Rust][lr] - Learn Rust programming through small projects. * [Effective Rust][er] - Higher-level concepts for writing excellent Rust code. </del> <ins> * [Tutorial: Guessing Game][gg] - Learn some Rust with a small project. </ins> * [Syntax and Semantics][ss] - Each bit of Rust, broken down into small chunks. <ins> * [Effective Rust][er] - Higher-level concepts for writing excellent Rust code. </ins> * [Nightly Rust][nr] - Cutting-edge features that aren’t in stable builds yet. * [Glossary][gl] - A reference of terms used in the book. * [Bibliography][bi] - Background on Rust's influences, papers about Rust. [gs]: getting-started.html <del> [lr]: learn-rust.html </del> <ins> [gg]: guessing-game.html </ins> [er]: effective-rust.html [ss]: syntax-and-semantics.html [nr]: nightly-rust.html [gl]: glossary.html [bi]: bibliography.html <del> After reading this introduction, you’ll want to dive into either ‘Learn Rust’ or ‘Syntax and Semantics’, depending on your preference: ‘Learn Rust’ if you want to dive in with a project, or ‘Syntax and Semantics’ if you prefer to start small, and learn a single concept thoroughly before moving onto the next. Copious cross-linking connects these parts together. </del> ### Contributing The source files from which this book is generated can be found on


# Summary * [Getting Started](getting-started.md) <del> * [Learn Rust](learn-rust.md) * [Guessing Game](guessing-game.md) * [Dining Philosophers](dining-philosophers.md) * [Rust Inside Other Languages](rust-inside-other-languages.md) </del> <ins> * [Tutorial: Guessing Game](guessing-game.md) </ins> * [Syntax and Semantics](syntax-and-semantics.md) * [Variable Bindings](variable-bindings.md) * [Functions](functions.md)


<del> % Dining Philosophers For our second project, let’s look at a classic concurrency problem. It’s called ‘the dining philosophers’. It was originally conceived by Dijkstra in 1965, but we’ll use a lightly adapted version from [this paper][paper] by Tony Hoare in 1985. [paper]: http://www.usingcsp.com/cspbook.pdf > In ancient times, a wealthy philanthropist endowed a College to accommodate > five eminent philosophers. Each philosopher had a room in which they could > engage in their professional activity of thinking; there was also a common > dining room, furnished with a circular table, surrounded by five chairs, each > labelled by the name of the philosopher who was to sit in it. They sat > anticlockwise around the table. To the left of each philosopher there was > laid a golden fork, and in the center stood a large bowl of spaghetti, which > was constantly replenished. A philosopher was expected to spend most of > their time thinking; but when they felt hungry, they went to the dining > room, sat down in their own chair, picked up their own fork on their left, > and plunged it into the spaghetti. But such is the tangled nature of > spaghetti that a second fork is required to carry it to the mouth. The > philosopher therefore had also to pick up the fork on their right. When > they were finished they would put down both their forks, get up from their > chair, and continue thinking. Of course, a fork can be used by only one > philosopher at a time. If the other philosopher wants it, they just have > to wait until the fork is available again. This classic problem shows off a few different elements of concurrency. The reason is that it's actually slightly tricky to implement: a simple implementation can deadlock. For example, let's consider a simple algorithm that would solve this problem: 1. A philosopher picks up the fork on their left. 2. They then pick up the fork on their right. 3. They eat. 4. They return the forks. Now, let’s imagine this sequence of events: 1. Philosopher 1 begins the algorithm, picking up the fork on their left. 2. Philosopher 2 begins the algorithm, picking up the fork on their left. 3. Philosopher 3 begins the algorithm, picking up the fork on their left. 4. Philosopher 4 begins the algorithm, picking up the fork on their left. 5. Philosopher 5 begins the algorithm, picking up the fork on their left. 6. ... ? All the forks are taken, but nobody can eat! There are different ways to solve this problem. We’ll get to our solution in the tutorial itself. For now, let’s get started and create a new project with `cargo`: ```bash $ cd ~/projects $ cargo new dining_philosophers --bin $ cd dining_philosophers ``` Now we can start modeling the problem itself. We’ll start with the philosophers in `src/main.rs`: ```rust struct Philosopher { name: String, } impl Philosopher { fn new(name: &str) -> Philosopher { Philosopher { name: name.to_string(), } } } fn main() { let p1 = Philosopher::new("Judith Butler"); let p2 = Philosopher::new("Gilles Deleuze"); let p3 = Philosopher::new("Karl Marx"); let p4 = Philosopher::new("Emma Goldman"); let p5 = Philosopher::new("Michel Foucault"); } ``` Here, we make a [`struct`][struct] to represent a philosopher. For now, a name is all we need. We choose the [`String`][string] type for the name, rather than `&str`. Generally speaking, working with a type which owns its data is easier than working with one that uses references. [struct]: structs.html [string]: strings.html Let’s continue: ```rust # struct Philosopher { #     name: String, # } impl Philosopher { fn new(name: &str) -> Philosopher { Philosopher { name: name.to_string(), } } } ``` This `impl` block lets us define things on `Philosopher` structs. In this case, we define an ‘associated function’ called `new`. The first line looks like this: ```rust # struct Philosopher { #     name: String, # } # impl Philosopher { fn new(name: &str) -> Philosopher { #         Philosopher { #             name: name.to_string(), #         } #     } # } ``` We take one argument, a `name`, of type `&str`. This is a reference to another string. It returns an instance of our `Philosopher` struct. ```rust # struct Philosopher { #     name: String, # } # impl Philosopher { #    fn new(name: &str) -> Philosopher { Philosopher { name: name.to_string(), } #     } # } ``` This creates a new `Philosopher`, and sets its `name` to our `name` argument. Not just the argument itself, though, as we call `.to_string()` on it. This will create a copy of the string that our `&str` points to, and give us a new `String`, which is the type of the `name` field of `Philosopher`. Why not accept a `String` directly? It’s nicer to call. If we took a `String`, but our caller had a `&str`, they’d have to call this method themselves. The downside of this flexibility is that we _always_ make a copy. For this small program, that’s not particularly important, as we know we’ll just be using short strings anyway. One last thing you’ll notice: we just define a `Philosopher`, and seemingly don’t do anything with it. Rust is an ‘expression based’ language, which means that almost everything in Rust is an expression which returns a value. This is true of functions as well — the last expression is automatically returned. Since we create a new `Philosopher` as the last expression of this function, we end up returning it. This name, `new()`, isn’t anything special to Rust, but it is a convention for functions that create new instances of structs. Before we talk about why, let’s look at `main()` again: ```rust # struct Philosopher { #     name: String, # } # # impl Philosopher { #     fn new(name: &str) -> Philosopher { #         Philosopher { #             name: name.to_string(), #         } #     } # } # fn main() { let p1 = Philosopher::new("Judith Butler"); let p2 = Philosopher::new("Gilles Deleuze"); let p3 = Philosopher::new("Karl Marx"); let p4 = Philosopher::new("Emma Goldman"); let p5 = Philosopher::new("Michel Foucault"); } ``` Here, we create five variable bindings with five new philosophers. If we _didn’t_ define that `new()` function, it would look like this: ```rust # struct Philosopher { #     name: String, # } fn main() { let p1 = Philosopher { name: "Judith Butler".to_string() }; let p2 = Philosopher { name: "Gilles Deleuze".to_string() }; let p3 = Philosopher { name: "Karl Marx".to_string() }; let p4 = Philosopher { name: "Emma Goldman".to_string() }; let p5 = Philosopher { name: "Michel Foucault".to_string() }; } ``` That’s much noisier. Using `new` has other advantages too, but even in this simple case, it ends up being nicer to use. Now that we’ve got the basics in place, there’s a number of ways that we can tackle the broader problem here. I like to start from the end first: let’s set up a way for each philosopher to finish eating. As a tiny step, let’s make a method, and then loop through all the philosophers, calling it: ```rust struct Philosopher { name: String, } impl Philosopher { fn new(name: &str) -> Philosopher { Philosopher { name: name.to_string(), } } fn eat(&self) { println!("{} is done eating.", self.name); } } fn main() { let philosophers = vec![ Philosopher::new("Judith Butler"), Philosopher::new("Gilles Deleuze"), Philosopher::new("Karl Marx"), Philosopher::new("Emma Goldman"), Philosopher::new("Michel Foucault"), ]; for p in &philosophers { p.eat(); } } ``` Let’s look at `main()` first. Rather than have five individual variable bindings for our philosophers, we make a `Vec<T>` of them instead. `Vec<T>` is also called a ‘vector’, and it’s a growable array type. We then use a [`for`][for] loop to iterate through the vector, getting a reference to each philosopher in turn. [for]: loops.html#for In the body of the loop, we call `p.eat()`, which is defined above: ```rust,ignore fn eat(&self) { println!("{} is done eating.", self.name); } ``` In Rust, methods take an explicit `self` parameter. That’s why `eat()` is a method, but `new` is an associated function: `new()` has no `self`. For our first version of `eat()`, we just print out the name of the philosopher, and mention they’re done eating. Running this program should give you the following output: ```text Judith Butler is done eating. Gilles Deleuze is done eating. Karl Marx is done eating. Emma Goldman is done eating. Michel Foucault is done eating. ``` Easy enough, they’re all done! We haven’t actually implemented the real problem yet, though, so we’re not done yet! Next, we want to make our philosophers not just finish eating, but actually eat. Here’s the next version: ```rust use std::thread; use std::time::Duration; struct Philosopher { name: String, } impl Philosopher { fn new(name: &str) -> Philosopher { Philosopher { name: name.to_string(), } } fn eat(&self) { println!("{} is eating.", self.name); thread::sleep(Duration::from_millis(1000)); println!("{} is done eating.", self.name); } } fn main() { let philosophers = vec![ Philosopher::new("Judith Butler"), Philosopher::new("Gilles Deleuze"), Philosopher::new("Karl Marx"), Philosopher::new("Emma Goldman"), Philosopher::new("Michel Foucault"), ]; for p in &philosophers { p.eat(); } } ``` Just a few changes. Let’s break it down. ```rust,ignore use std::thread; ``` `use` brings names into scope. We’re going to start using the `thread` module from the standard library, and so we need to `use` it. ```rust,ignore fn eat(&self) { println!("{} is eating.", self.name); thread::sleep(Duration::from_millis(1000)); println!("{} is done eating.", self.name); } ``` We now print out two messages, with a `sleep` in the middle. This will simulate the time it takes a philosopher to eat. If you run this program, you should see each philosopher eat in turn: ```text Judith Butler is eating. Judith Butler is done eating. Gilles Deleuze is eating. Gilles Deleuze is done eating. Karl Marx is eating. Karl Marx is done eating. Emma Goldman is eating. Emma Goldman is done eating. Michel Foucault is eating. Michel Foucault is done eating. ``` Excellent! We’re getting there. There’s just one problem: we aren’t actually operating in a concurrent fashion, which is a core part of the problem! To make our philosophers eat concurrently, we need to make a small change. Here’s the next iteration: ```rust use std::thread; use std::time::Duration; struct Philosopher { name: String, } impl Philosopher { fn new(name: &str) -> Philosopher { Philosopher { name: name.to_string(), } } fn eat(&self) { println!("{} is eating.", self.name); thread::sleep(Duration::from_millis(1000)); println!("{} is done eating.", self.name); } } fn main() { let philosophers = vec![ Philosopher::new("Judith Butler"), Philosopher::new("Gilles Deleuze"), Philosopher::new("Karl Marx"), Philosopher::new("Emma Goldman"), Philosopher::new("Michel Foucault"), ]; let handles: Vec<_> = philosophers.into_iter().map(|p| { thread::spawn(move || { p.eat(); }) }).collect(); for h in handles { h.join().unwrap(); } } ``` All we’ve done is change the loop in `main()`, and added a second one! Here’s the first change: ```rust,ignore let handles: Vec<_> = philosophers.into_iter().map(|p| { thread::spawn(move || { p.eat(); }) }).collect(); ``` While this is only five lines, they’re a dense five. Let’s break it down. ```rust,ignore let handles: Vec<_> = ``` We introduce a new binding, called `handles`. We’ve given it this name because we are going to make some new threads, and that will return some handles to those threads that let us control their operation. We need to explicitly annotate the type here, though, due to an issue we’ll talk about later. The `_` is a type placeholder. We’re saying “`handles` is a vector of something, but you can figure out what that something is, Rust.” ```rust,ignore philosophers.into_iter().map(|p| { ``` We take our list of philosophers and call `into_iter()` on it. This creates an iterator that takes ownership of each philosopher. We need to do this to pass them to our threads. We take that iterator and call `map` on it, which takes a closure as an argument and calls that closure on each element in turn. ```rust,ignore thread::spawn(move || { p.eat(); }) ``` Here’s where the concurrency happens. The `thread::spawn` function takes a closure as an argument and executes that closure in a new thread. This closure needs an extra annotation, `move`, to indicate that the closure is going to take ownership of the values it’s capturing. In this case, it's the `p` variable of the `map` function. Inside the thread, all we do is call `eat()` on `p`. Also note that the call to `thread::spawn` lacks a trailing semicolon, making this an expression. This distinction is important, yielding the correct return value. For more details, read [Expressions vs. Statements][es]. [es]: functions.html#expressions-vs-statements ```rust,ignore }).collect(); ``` Finally, we take the result of all those `map` calls and collect them up. `collect()` will make them into a collection of some kind, which is why we needed to annotate the return type: we want a `Vec<T>`. The elements are the return values of the `thread::spawn` calls, which are handles to those threads. Whew! ```rust,ignore for h in handles { h.join().unwrap(); } ``` At the end of `main()`, we loop through the handles and call `join()` on them, which blocks execution until the thread has completed execution. This ensures that the threads complete their work before the program exits. If you run this program, you’ll see that the philosophers eat out of order! We have multi-threading! ```text Judith Butler is eating. Gilles Deleuze is eating. Karl Marx is eating. Emma Goldman is eating. Michel Foucault is eating. Judith Butler is done eating. Gilles Deleuze is done eating. Karl Marx is done eating. Emma Goldman is done eating. Michel Foucault is done eating. ``` But what about the forks? We haven’t modeled them at all yet. To do that, let’s make a new `struct`: ```rust use std::sync::Mutex; struct Table { forks: Vec<Mutex<()>>, } ``` This `Table` has a vector of `Mutex`es. A mutex is a way to control concurrency: only one thread can access the contents at once. This is exactly the property we need with our forks. We use an empty tuple, `()`, inside the mutex, since we’re not actually going to use the value, just hold onto it. Let’s modify the program to use the `Table`: ```rust use std::thread; use std::time::Duration; use std::sync::{Mutex, Arc}; struct Philosopher { name: String, left: usize, right: usize, } impl Philosopher { fn new(name: &str, left: usize, right: usize) -> Philosopher { Philosopher { name: name.to_string(), left: left, right: right, } } fn eat(&self, table: &Table) { let _left = table.forks[self.left].lock().unwrap(); thread::sleep(Duration::from_millis(150)); let _right = table.forks[self.right].lock().unwrap(); println!("{} is eating.", self.name); thread::sleep(Duration::from_millis(1000)); println!("{} is done eating.", self.name); } } struct Table { forks: Vec<Mutex<()>>, } fn main() { let table = Arc::new(Table { forks: vec![ Mutex::new(()), Mutex::new(()), Mutex::new(()), Mutex::new(()), Mutex::new(()), ]}); let philosophers = vec![ Philosopher::new("Judith Butler", 0, 1), Philosopher::new("Gilles Deleuze", 1, 2), Philosopher::new("Karl Marx", 2, 3), Philosopher::new("Emma Goldman", 3, 4), Philosopher::new("Michel Foucault", 0, 4), ]; let handles: Vec<_> = philosophers.into_iter().map(|p| { let table = table.clone(); thread::spawn(move || { p.eat(&table); }) }).collect(); for h in handles { h.join().unwrap(); } } ``` Lots of changes! However, with this iteration, we’ve got a working program. Let’s go over the details: ```rust,ignore use std::sync::{Mutex, Arc}; ``` We’re going to use another structure from the `std::sync` package: `Arc<T>`. We’ll talk more about it when we use it. ```rust,ignore struct Philosopher { name: String, left: usize, right: usize, } ``` We need to add two more fields to our `Philosopher`. Each philosopher is going to have two forks: the one on their left, and the one on their right. We’ll use the `usize` type to indicate them, as it’s the type that you index vectors with. These two values will be the indexes into the `forks` our `Table` has. ```rust,ignore fn new(name: &str, left: usize, right: usize) -> Philosopher { Philosopher { name: name.to_string(), left: left, right: right, } } ``` We now need to construct those `left` and `right` values, so we add them to `new()`. ```rust,ignore fn eat(&self, table: &Table) { let _left = table.forks[self.left].lock().unwrap(); thread::sleep(Duration::from_millis(150)); let _right = table.forks[self.right].lock().unwrap(); println!("{} is eating.", self.name); thread::sleep(Duration::from_millis(1000)); println!("{} is done eating.", self.name); } ``` We have three new lines. We’ve added an argument, `table`. We access the `Table`’s list of forks, and then use `self.left` and `self.right` to access the fork at that particular index. That gives us access to the `Mutex` at that index, and we call `lock()` on it. If the mutex is currently being accessed by someone else, we’ll block until it becomes available. We have also a call to `thread::sleep` between the moment the first fork is picked and the moment the second forked is picked, as the process of picking up the fork is not immediate. The call to `lock()` might fail, and if it does, we want to crash. In this case, the error that could happen is that the mutex is [‘poisoned’][poison], which is what happens when the thread panics while the lock is held. Since this shouldn’t happen, we just use `unwrap()`. [poison]: ../std/sync/struct.Mutex.html#poisoning One other odd thing about these lines: we’ve named the results `_left` and `_right`. What’s up with that underscore? Well, we aren’t planning on _using_ the value inside the lock. We just want to acquire it. As such, Rust will warn us that we never use the value. By using the underscore, we tell Rust that this is what we intended, and it won’t throw a warning. What about releasing the lock? Well, that will happen when `_left` and `_right` go out of scope, automatically. ```rust,ignore let table = Arc::new(Table { forks: vec![ Mutex::new(()), Mutex::new(()), Mutex::new(()), Mutex::new(()), Mutex::new(()), ]}); ``` Next, in `main()`, we make a new `Table` and wrap it in an `Arc<T>`. ‘arc’ stands for ‘atomic reference count’, and we need that to share our `Table` across multiple threads. As we share it, the reference count will go up, and when each thread ends, it will go back down. ```rust,ignore let philosophers = vec![ Philosopher::new("Judith Butler", 0, 1), Philosopher::new("Gilles Deleuze", 1, 2), Philosopher::new("Karl Marx", 2, 3), Philosopher::new("Emma Goldman", 3, 4), Philosopher::new("Michel Foucault", 0, 4), ]; ``` We need to pass in our `left` and `right` values to the constructors for our `Philosopher`s. But there’s one more detail here, and it’s _very_ important. If you look at the pattern, it’s all consistent until the very end. Monsieur Foucault should have `4, 0` as arguments, but instead, has `0, 4`. This is what prevents deadlock, actually: one of our philosophers is left handed! This is one way to solve the problem, and in my opinion, it’s the simplest. If you change the order of the parameters, you will be able to observe the deadlock taking place. ```rust,ignore let handles: Vec<_> = philosophers.into_iter().map(|p| { let table = table.clone(); thread::spawn(move || { p.eat(&table); }) }).collect(); ``` Finally, inside of our `map()`/`collect()` loop, we call `table.clone()`. The `clone()` method on `Arc<T>` is what bumps up the reference count, and when it goes out of scope, it decrements the count. This is needed so that we know how many references to `table` exist across our threads. If we didn’t have a count, we wouldn’t know how to deallocate it. You’ll notice we can introduce a new binding to `table` here, and it will shadow the old one. This is often used so that you don’t need to come up with two unique names. With this, our program works! Only two philosophers can eat at any one time, and so you’ll get some output like this: ```text Gilles Deleuze is eating. Emma Goldman is eating. Emma Goldman is done eating. Gilles Deleuze is done eating. Judith Butler is eating. Karl Marx is eating. Judith Butler is done eating. Michel Foucault is eating. Karl Marx is done eating. Michel Foucault is done eating. ``` Congrats! You’ve implemented a classic concurrency problem in Rust. </del>


% Guessing Game <del> For our first project, we’ll implement a classic beginner programming problem: the guessing game. Here’s how it works: Our program will generate a random integer between one and a hundred. It will then prompt us to enter a guess. Upon entering our guess, it will tell us if we’re too low or too high. Once we guess correctly, it will congratulate us. Sounds good? </del> <ins> Let’s learn some Rust! For our first project, we’ll implement a classic beginner programming problem: the guessing game. Here’s how it works: Our program will generate a random integer between one and a hundred. It will then prompt us to enter a guess. Upon entering our guess, it will tell us if we’re too low or too high. Once we guess correctly, it will congratulate us. Sounds good? Along the way, we’ll learn a little bit about Rust. The next section, ‘Syntax and Semantics’, will dive deeper into each part. </ins> # Set up


<del> % Rust Inside Other Languages For our third project, we’re going to choose something that shows off one of Rust’s greatest strengths: a lack of a substantial runtime. As organizations grow, they increasingly rely on a multitude of programming languages. Different programming languages have different strengths and weaknesses, and a polyglot stack lets you use a particular language where its strengths make sense and a different one where it’s weak. A very common area where many programming languages are weak is in runtime performance of programs. Often, using a language that is slower, but offers greater programmer productivity, is a worthwhile trade-off. To help mitigate this, they provide a way to write some of your system in C and then call that C code as though it were written in the higher-level language. This is called a ‘foreign function interface’, often shortened to ‘FFI’. Rust has support for FFI in both directions: it can call into C code easily, but crucially, it can also be called _into_ as easily as C. Combined with Rust’s lack of a garbage collector and low runtime requirements, this makes Rust a great candidate to embed inside of other languages when you need that extra oomph. There is a whole [chapter devoted to FFI][ffi] and its specifics elsewhere in the book, but in this chapter, we’ll examine this particular use-case of FFI, with examples in Ruby, Python, and JavaScript. [ffi]: ffi.html # The problem There are many different projects we could choose here, but we’re going to pick an example where Rust has a clear advantage over many other languages: numeric computing and threading. Many languages, for the sake of consistency, place numbers on the heap, rather than on the stack. Especially in languages that focus on object-oriented programming and use garbage collection, heap allocation is the default. Sometimes optimizations can stack allocate particular numbers, but rather than relying on an optimizer to do its job, we may want to ensure that we’re always using primitive number types rather than some sort of object type. Second, many languages have a ‘global interpreter lock’ (GIL), which limits concurrency in many situations. This is done in the name of safety, which is a positive effect, but it limits the amount of work that can be done at the same time, which is a big negative. To emphasize these two aspects, we’re going to create a little project that uses these two aspects heavily. Since the focus of the example is to embed Rust into other languages, rather than the problem itself, we’ll just use a toy example: > Start ten threads. Inside each thread, count from one to five million. After > all ten threads are finished, print out ‘done!’. I chose five million based on my particular computer. Here’s an example of this code in Ruby: ```ruby threads = [] 10.times do threads << Thread.new do count = 0 5_000_000.times do count += 1 end count end end threads.each do |t| puts "Thread finished with count=#{t.value}" end puts "done!" ``` Try running this example, and choose a number that runs for a few seconds. Depending on your computer’s hardware, you may have to increase or decrease the number. On my system, running this program takes `2.156` seconds. And, if I use some sort of process monitoring tool, like `top`, I can see that it only uses one core on my machine. That’s the GIL kicking in. While it’s true that this is a synthetic program, one can imagine many problems that are similar to this in the real world. For our purposes, spinning up a few busy threads represents some sort of parallel, expensive computation. # A Rust library Let’s rewrite this problem in Rust. First, let’s make a new project with Cargo: ```bash $ cargo new embed $ cd embed ``` This program is fairly easy to write in Rust: ```rust use std::thread; fn process() { let handles: Vec<_> = (0..10).map(|_| { thread::spawn(|| { let mut x = 0; for _ in 0..5_000_000 { x += 1 } x }) }).collect(); for h in handles { println!("Thread finished with count={}", h.join().map_err(|_| "Could not join a thread!").unwrap()); } } ``` Some of this should look familiar from previous examples. We spin up ten threads, collecting them into a `handles` vector. Inside of each thread, we loop five million times, and add one to `x` each time. Finally, we join on each thread. Right now, however, this is a Rust library, and it doesn’t expose anything that’s callable from C. If we tried to hook this up to another language right now, it wouldn’t work. We only need to make two small changes to fix this, though. The first is to modify the beginning of our code: ```rust,ignore #[no_mangle] pub extern fn process() { ``` We have to add a new attribute, `no_mangle`. When you create a Rust library, it changes the name of the function in the compiled output. The reasons for this are outside the scope of this tutorial, but in order for other languages to know how to call the function, we can’t do that. This attribute turns that behavior off. The other change is the `pub extern`. The `pub` means that this function should be callable from outside of this module, and the `extern` says that it should be able to be called from C. That’s it! Not a whole lot of change. The second thing we need to do is to change a setting in our `Cargo.toml`. Add this at the bottom: ```toml [lib] name = "embed" crate-type = ["dylib"] ``` This tells Rust that we want to compile our library into a standard dynamic library. By default, Rust compiles an ‘rlib’, a Rust-specific format. Let’s build the project now: ```bash $ cargo build --release Compiling embed v0.1.0 (file:///home/steve/src/embed) ``` We’ve chosen `cargo build --release`, which builds with optimizations on. We want this to be as fast as possible! You can find the output of the library in `target/release`: ```bash $ ls target/release/ build  deps  examples  libembed.so  native ``` That `libembed.so` is our ‘shared object’ library. We can use this file just like any shared object library written in C! As an aside, this may be `embed.dll` (Microsoft Windows) or `libembed.dylib` (Mac OS X), depending on your operating system. Now that we’ve got our Rust library built, let’s use it from our Ruby. # Ruby Open up an `embed.rb` file inside of our project, and do this: ```ruby require 'ffi' module Hello extend FFI::Library ffi_lib 'target/release/libembed.so' attach_function :process, [], :void end Hello.process puts 'done!' ``` Before we can run this, we need to install the `ffi` gem: ```bash $ gem install ffi # this may need sudo Fetching: ffi-1.9.8.gem (100%) Building native extensions.  This could take a while... Successfully installed ffi-1.9.8 Parsing documentation for ffi-1.9.8 Installing ri documentation for ffi-1.9.8 Done installing documentation for ffi after 0 seconds 1 gem installed ``` And finally, we can try running it: ```bash $ ruby embed.rb Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 Thread finished with count=5000000 done! done! $ ``` Whoa, that was fast! On my system, this took `0.086` seconds, rather than the two seconds the pure Ruby version took. Let’s break down this Ruby code: ```ruby require 'ffi' ``` We first need to require the `ffi` gem. This lets us interface with our Rust library like a C library. ```ruby module Hello extend FFI::Library ffi_lib 'target/release/libembed.so' ``` The `Hello` module is used to attach the native functions from the shared library. Inside, we `extend` the necessary `FFI::Library` module and then call `ffi_lib` to load up our shared object library. We just pass it the path that our library is stored, which, as we saw before, is `target/release/libembed.so`. ```ruby attach_function :process, [], :void ``` The `attach_function` method is provided by the FFI gem. It’s what connects our `process()` function in Rust to a Ruby function of the same name. Since `process()` takes no arguments, the second parameter is an empty array, and since it returns nothing, we pass `:void` as the final argument. ```ruby Hello.process ``` This is the actual call into Rust. The combination of our `module` and the call to `attach_function` sets this all up. It looks like a Ruby function but is actually Rust! ```ruby puts 'done!' ``` Finally, as per our project’s requirements, we print out `done!`. That’s it! As we’ve seen, bridging between the two languages is really easy, and buys us a lot of performance. Next, let’s try Python! # Python Create an `embed.py` file in this directory, and put this in it: ```python from ctypes import cdll lib = cdll.LoadLibrary("target/release/libembed.so") lib.process() print("done!") ``` Even easier! We use `cdll` from the `ctypes` module. A quick call to `LoadLibrary` later, and we can call `process()`. On my system, this takes `0.017` seconds. Speedy! # Node.js Node isn’t a language, but it’s currently the dominant implementation of server-side JavaScript. In order to do FFI with Node, we first need to install the library: ```bash $ npm install ffi ``` After that installs, we can use it: ```javascript var ffi = require('ffi'); var lib = ffi.Library('target/release/libembed', { 'process': ['void', []] }); lib.process(); console.log("done!"); ``` It looks more like the Ruby example than the Python example. We use the `ffi` module to get access to `ffi.Library()`, which loads up our shared object. We need to annotate the return type and argument types of the function, which are `void` for return and an empty array to signify no arguments. From there, we just call it and print the result. On my system, this takes a quick `0.092` seconds. # Conclusion As you can see, the basics of doing this are _very_ easy. Of course, there's a lot more that we could do here. Check out the [FFI][ffi] chapter for more details. </del>


``` ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType` ``` <ins> Note that this does not move `v` (unlike `transmute`), and may need a call to `mem::forget(v)` in case you want to avoid destructors being called. </ins> "##, E0152: r##"


#[stable(feature = "rust1", since = "1.0.0")] impl Ord for Ipv4Addr { fn cmp(&self, other: &Ipv4Addr) -> Ordering { <del> self.inner.s_addr.cmp(&other.inner.s_addr) </del> <ins> self.octets().cmp(&other.octets()) </ins> } }


#[stable(feature = "rust1", since = "1.0.0")] impl Ord for Ipv6Addr { fn cmp(&self, other: &Ipv6Addr) -> Ordering { <del> self.inner.s6_addr.cmp(&other.inner.s6_addr) </del> <ins> self.segments().cmp(&other.segments()) </ins> } }


let a = Ipv4Addr::new(127, 0, 0, 1); assert_eq!(Ipv4Addr::from(2130706433), a); } <ins> #[test] fn ord() { assert!(Ipv4Addr::new(100, 64, 3, 3) < Ipv4Addr::new(192, 0, 2, 2)); assert!("2001:db8:f00::1002".parse::<Ipv6Addr>().unwrap() < "2001:db8:f00::2001".parse::<Ipv6Addr>().unwrap()); } </ins> }


<ins> // Regression test for #29988 // compile-flags: -C no-prepopulate-passes // only-x86_64 // ignore-windows #[repr(C)] struct S { f1: i32, f2: i32, f3: i32, } extern { fn foo(s: S); } fn main() { let s = S { f1: 1, f2: 2, f3: 3 }; unsafe { // CHECK: load { i64, i32 }, { i64, i32 }* {{.*}}, align 4 // CHECK: call void @foo({ i64, i32 } {{.*}}) foo(s); } } </ins>


<ins> enum Bug<S> { Var = { let x: S = 0; //~ ERROR: mismatched types 0 }, } fn main() {} </ins>


<ins> error[E0308]: mismatched types --> $DIR/issue-67945-1.rs:3:20 | LL | enum Bug<S> { |          - this type parameter LL |     Var = { LL |         let x: S = 0; |                -   ^ expected type parameter `S`, found integer |                | |                expected due to this | = note: expected type parameter `S` found type `{integer}` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>


<ins> #![feature(type_ascription)] enum Bug<S> { Var = 0: S, //~^ ERROR: mismatched types //~| ERROR: mismatched types } fn main() {} </ins>


<ins> error[E0308]: mismatched types --> $DIR/issue-67945-2.rs:4:11 | LL | enum Bug<S> { |          - this type parameter LL |     Var = 0: S, |           ^ expected type parameter `S`, found integer | = note: expected type parameter `S` found type `{integer}` error[E0308]: mismatched types --> $DIR/issue-67945-2.rs:4:11 | LL | enum Bug<S> { |          - this type parameter LL |     Var = 0: S, |           ^^^^ expected `isize`, found type parameter `S` | = note:        expected type `isize` found type parameter `S` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


<ins> trait Foo {} impl<'a, T> Foo for &'a T {} struct Ctx<'a>(&'a ()) where &'a (): Foo, //~ ERROR: type annotations needed &'static (): Foo; fn main() {} </ins>


<ins> error[E0283]: type annotations needed --> $DIR/issue-34979.rs:6:13 | LL | trait Foo {} | --------- required by this bound in `Foo` ... LL |     &'a (): Foo, |             ^^^ cannot infer type for reference `&'a ()` | = note: cannot satisfy `&'a (): Foo` error: aborting due to previous error For more information about this error, try `rustc --explain E0283`. </ins>


fn consume(&mut self, amt: usize) { self.pos += amt as u64; } } <ins> // Non-resizing write implementation fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> { let pos = cmp::min(*pos_mut, slice.len() as u64); let amt = (&mut slice[(pos as usize)..]).write(buf)?; *pos_mut += amt as u64; Ok(amt) } // Resizing write implementation fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> { let pos: usize = (*pos_mut).try_into().map_err(|_| { Error::new(ErrorKind::InvalidInput, "cursor position exceeds maximum possible vector length") })?; // Make sure the internal buffer is as least as big as where we // currently are let len = vec.len(); if len < pos { // use `resize` so that the zero filling is as efficient as possible vec.resize(pos, 0); } // Figure out what bytes will be used to overwrite what's currently // there (left), and what will be appended on the end (right) { let space = vec.len() - pos; let (left, right) = buf.split_at(cmp::min(space, buf.len())); vec[pos..pos + left.len()].copy_from_slice(left); vec.extend_from_slice(right); } // Bump us forward *pos_mut = (pos + buf.len()) as u64; Ok(buf.len()) } </ins> #[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for Cursor<&'a mut [u8]> { #[inline] <del> fn write(&mut self, data: &[u8]) -> io::Result<usize> { let pos = cmp::min(self.pos, self.inner.len() as u64); let amt = (&mut self.inner[(pos as usize)..]).write(data)?; self.pos += amt as u64; Ok(amt) </del> <ins> fn write(&mut self, buf: &[u8]) -> io::Result<usize> { slice_write(&mut self.pos, self.inner, buf) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } #[unstable(feature = "cursor_mut_vec", issue = "30132")] impl<'a> Write for Cursor<&'a mut Vec<u8>> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { vec_write(&mut self.pos, self.inner, buf) </ins> } fn flush(&mut self) -> io::Result<()> { Ok(()) } }


#[stable(feature = "rust1", since = "1.0.0")] impl Write for Cursor<Vec<u8>> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { <del> let pos: usize = self.position().try_into().map_err(|_| { Error::new(ErrorKind::InvalidInput, "cursor position exceeds maximum possible vector length") })?; // Make sure the internal buffer is as least as big as where we // currently are let len = self.inner.len(); if len < pos { // use `resize` so that the zero filling is as efficient as possible self.inner.resize(pos, 0); } // Figure out what bytes will be used to overwrite what's currently // there (left), and what will be appended on the end (right) { let space = self.inner.len() - pos; let (left, right) = buf.split_at(cmp::min(space, buf.len())); self.inner[pos..pos + left.len()].copy_from_slice(left); self.inner.extend_from_slice(right); } // Bump us forward self.set_position((pos + buf.len()) as u64); Ok(buf.len()) </del> <ins> vec_write(&mut self.pos, &mut self.inner, buf) </ins> } fn flush(&mut self) -> io::Result<()> { Ok(()) } }


impl Write for Cursor<Box<[u8]>> { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result<usize> { <del> let pos = cmp::min(self.pos, self.inner.len() as u64); let amt = (&mut self.inner[(pos as usize)..]).write(buf)?; self.pos += amt as u64; Ok(amt) </del> <ins> slice_write(&mut self.pos, &mut self.inner, buf) </ins> } fn flush(&mut self) -> io::Result<()> { Ok(()) } }


} #[test] <ins> fn test_mem_mut_writer() { let mut vec = Vec::new(); let mut writer = Cursor::new(&mut vec); assert_eq!(writer.write(&[0]).unwrap(), 1); assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; assert_eq!(&writer.get_ref()[..], b); } #[test] </ins> fn test_box_slice_writer() { let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); assert_eq!(writer.position(), 0);


``` You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will <del> automatically add a `main()` wrapper around your code, and in the right place. For example: </del> <ins> automatically add a `main()` wrapper around your code, using heuristics to attempt to put it in the right place. For example: </ins> ```rust /// ```


`unused_attributes`, and `dead_code`. Small examples often trigger these lints. 3. If the example does not contain `extern crate`, then `extern crate <del> <mycrate>;` is inserted. 2. Finally, if the example does not contain `fn main`, the remainder of the text is wrapped in `fn main() { your_code }` Sometimes, this isn't enough, though. For example, all of these code samples </del> <ins> <mycrate>;` is inserted (note the lack of `#[macro_use]`). 4. Finally, if the example does not contain `fn main`, the remainder of the text is wrapped in `fn main() { your_code }`. This generated `fn main` can be a problem! If you have `extern crate` or a `mod` statements in the example code that are referred to by `use` statements, they will fail to resolve unless you include at least `fn main() {}` to inhibit step 4. `#[macro_use] extern crate` also does not work except at the crate root, so when testing macros an explicit `main` is always required. It doesn't have to clutter up your docs, though -- keep reading! Sometimes this algorithm isn't enough, though. For example, all of these code samples </ins> with `///` we've been talking about? The raw text: ```text


You’ll note three things: we need to add our own `extern crate` line, so that we can add the `#[macro_use]` attribute. Second, we’ll need to add our own <del> `main()` as well. Finally, a judicious use of `#` to comment out those two things, so they don’t show up in the output. </del> <ins> `main()` as well (for reasons discussed above). Finally, a judicious use of `#` to comment out those two things, so they don’t show up in the output. </ins> Another case where the use of `#` is handy is when you want to ignore error handling. Lets say you want the following,


// the merge has confused the heck out of josh in the past. // We pass `--no-verify` to avoid running git hooks like `./miri fmt` that could in turn // trigger auto-actions. <del> sh.write_file("rust-version", &commit)?; </del> <ins> sh.write_file("rust-version", format!("{commit}n"))?; </ins> const PREPARING_COMMIT_MESSAGE: &str = "Preparing for merge from rustc"; cmd!(sh, "git commit rust-version --no-verify -m {PREPARING_COMMIT_MESSAGE}") .run()


// interleaving, but wether UB happens can depend on whether a write occurs in the // future... let is_write = new_perm.initial_state.is_active() <del> || (new_perm.initial_state.is_resrved() && new_perm.protector.is_some()); </del> <ins> || (new_perm.initial_state.is_reserved() && new_perm.protector.is_some()); </ins> if is_write { // Need to get mutable access to alloc_extra. // (Cannot always do this as we can do read-only reborrowing on read-only allocations.)


matches!(self.inner, Active) } <del> pub fn is_resrved(self) -> bool { </del> <ins> pub fn is_reserved(self) -> bool { </ins> matches!(self.inner, Reserved { .. }) }


/// in an existing allocation, then returns Err containing the position /// where such allocation should be inserted fn find_offset(&self, offset: Size) -> Result<Position, Position> { <del> // We do a binary search. let mut left = 0usize; // inclusive let mut right = self.v.len(); // exclusive loop { if left == right { // No element contains the given offset. But the // position is where such element should be placed at. return Err(left); } let candidate = left.checked_add(right).unwrap() / 2; let elem = &self.v[candidate]; </del> <ins> self.v.binary_search_by(|elem| -> std::cmp::Ordering { </ins> if offset < elem.range.start { // We are too far right (offset is further left). <del> debug_assert!(candidate < right); // we are making progress right = candidate; </del> <ins> std::cmp::Ordering::Greater </ins> } else if offset >= elem.range.end() { // We are too far left (offset is further right). <del> debug_assert!(candidate >= left); // we are making progress left = candidate + 1; </del> <ins> std::cmp::Ordering::Less </ins> } else { // This is it! <del> return Ok(candidate); </del> <ins> std::cmp::Ordering::Equal </ins> } <del> } </del> <ins> }) </ins> } /// Determines whether a given access on `range` overlaps with


} ``` <ins> Your structure can still contain `&mut` pointers, which will let you do some kinds of mutation: ```rust struct Point { x: i32, y: i32, } struct PointRef<'a> { x: &'a mut i32, y: &'a mut i32, } fn main() { let mut point = Point { x: 0, y: 0 }; { let r = PointRef { x: &mut point.x, y: &mut point.y }; *r.x = 5; *r.y = 6; } assert_eq!(5, point.x); assert_eq!(6, point.y); } ``` </ins> # Update syntax A `struct` can include `..` to indicate that you want to use a copy of some


self } <ins> /// Configuration for the child process’s standard input (stdin) handle. /// /// See [`std::process::Command::stdin`]. pub fn stdin<T: Into<::std::process::Stdio>>(&mut self, cfg: T) -> &mut Self { self.cmd.stdin(cfg); self } /// Configuration for the child process’s standard output (stdout) handle. /// /// See [`std::process::Command::stdout`]. pub fn stdout<T: Into<::std::process::Stdio>>(&mut self, cfg: T) -> &mut Self { self.cmd.stdout(cfg); self } /// Configuration for the child process’s standard error (stderr) handle. /// /// See [`std::process::Command::stderr`]. pub fn stderr<T: Into<::std::process::Stdio>>(&mut self, cfg: T) -> &mut Self { self.cmd.stderr(cfg); self } </ins> /// Inspect what the underlying [`Command`] is up to the /// current construction. pub fn inspect<I>(&mut self, inspector: I) -> &mut Self


run-make/branch-protection-check-IBT/Makefile run-make/cat-and-grep-sanity-check/Makefile <del> run-make/emit-to-stdout/Makefile </del> run-make/extern-fn-reachable/Makefile run-make/incr-add-rust-src-component/Makefile run-make/issue-84395-lto-embed-bitcode/Makefile


ui/consts/issue-73976-monomorphic.rs ui/consts/issue-73976-polymorphic.rs ui/consts/issue-76064.rs <del> ui/consts/issue-77062-large-zst-array.rs </del> ui/consts/issue-78655.rs ui/consts/issue-79137-monomorphic.rs ui/consts/issue-79137-toogeneric.rs


<del> include ../tools.mk SRC=test.rs OUT=$(TMPDIR)/out all: asm llvm-ir dep-info mir llvm-bc obj metadata link multiple-types multiple-types-option-o asm: $(OUT) $(RUSTC) --emit asm=$(OUT)/$@ $(SRC) $(RUSTC) --emit asm=- $(SRC) | diff - $(OUT)/$@ llvm-ir: $(OUT) $(RUSTC) --emit llvm-ir=$(OUT)/$@ $(SRC) $(RUSTC) --emit llvm-ir=- $(SRC) | diff - $(OUT)/$@ dep-info: $(OUT) $(RUSTC) -Z dep-info-omit-d-target=yes --emit dep-info=$(OUT)/$@ $(SRC) $(RUSTC) --emit dep-info=- $(SRC) | diff - $(OUT)/$@ mir: $(OUT) $(RUSTC) --emit mir=$(OUT)/$@ $(SRC) $(RUSTC) --emit mir=- $(SRC) | diff - $(OUT)/$@ llvm-bc: $(OUT) $(RUSTC) --emit llvm-bc=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true diff $(OUT)/$@ emit-llvm-bc.stderr obj: $(OUT) $(RUSTC) --emit obj=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true diff $(OUT)/$@ emit-obj.stderr # For metadata output, a temporary directory will be created to hold the temporary # metadata file. But when output is stdout, the temporary directory will be located # in the same place as $(SRC), which is mounted as read-only in the tests. Thus as # a workaround, $(SRC) is copied to the test output directory $(OUT) and we compile # it there. metadata: $(OUT) cp $(SRC) $(OUT) (cd $(OUT); $(RUSTC) --emit metadata=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true) diff $(OUT)/$@ emit-metadata.stderr link: $(OUT) $(RUSTC) --emit link=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true diff $(OUT)/$@ emit-link.stderr multiple-types: $(OUT) $(RUSTC) --emit asm=- --emit llvm-ir=- --emit dep-info=- --emit mir=- $(SRC) 2>$(OUT)/$@ || true diff $(OUT)/$@ emit-multiple-types.stderr multiple-types-option-o: $(OUT) $(RUSTC) -o - --emit asm,llvm-ir,dep-info,mir $(SRC) 2>$(OUT)/$@ || true diff $(OUT)/$@ emit-multiple-types.stderr $(OUT): mkdir -p $(OUT) </del>


<ins> //! If `-o -` or `--emit KIND=-` is provided, output should be written to stdout //! instead. Binary output (`obj`, `llvm-bc`, `link` and `metadata`) //! being written this way will result in an error if stdout is a tty. //! Multiple output types going to stdout will trigger an error too, //! as they would all be mixed together. //! //! See <https://github.com/rust-lang/rust/pull/111626>. use std::fs::File; use run_make_support::{diff, run_in_tmpdir, rustc}; // Test emitting text outputs to stdout works correctly fn run_diff(name: &str, file_args: &[&str]) { rustc().emit(format!("{name}={name}")).input("test.rs").args(file_args).run(); let out = rustc().emit(format!("{name}=-")).input("test.rs").run().stdout_utf8(); diff().expected_file(name).actual_text("stdout", &out).run(); } // Test that emitting binary formats to a terminal gives the correct error fn run_terminal_err_diff(name: &str) { #[cfg(not(windows))] let terminal = File::create("/dev/ptmx").unwrap(); // FIXME: If this test fails and the compiler does print to the console, // then this will produce a lot of output. // We should spawn a new console instead to print stdout. #[cfg(windows)] let terminal = File::options().read(true).write(true).open(r".CONOUT$").unwrap(); let err = File::create(name).unwrap(); rustc().emit(format!("{name}=-")).input("test.rs").stdout(terminal).stderr(err).run_fail(); diff().expected_file(format!("emit-{name}.stderr")).actual_file(name).run(); } fn main() { run_in_tmpdir(|| { run_diff("asm", &[]); run_diff("llvm-ir", &[]); run_diff("dep-info", &["-Zdep-info-omit-d-target=yes"]); run_diff("mir", &[]); run_terminal_err_diff("llvm-bc"); run_terminal_err_diff("obj"); run_terminal_err_diff("metadata"); run_terminal_err_diff("link"); // Test error for emitting multiple types to stdout rustc() .input("test.rs") .emit("asm=-") .emit("llvm-ir=-") .emit("dep-info=-") .emit("mir=-") .stderr(File::create("multiple-types").unwrap()) .run_fail(); diff().expected_file("emit-multiple-types.stderr").actual_file("multiple-types").run(); // Same as above, but using `-o` rustc() .input("test.rs") .output("-") .emit("asm,llvm-ir,dep-info,mir") .stderr(File::create("multiple-types-option-o").unwrap()) .run_fail(); diff() .expected_file("emit-multiple-types.stderr") .actual_file("multiple-types-option-o") .run(); // Test that `-o -` redirected to a file works correctly (#26719) rustc().input("test.rs").output("-").stdout(File::create("out-stdout").unwrap()).run(); }); } </ins>


<del> //@ build-pass fn main() { let _ = &[(); usize::MAX]; } </del>


<ins> //@ build-pass pub static FOO: [(); usize::MAX] = [(); usize::MAX]; fn main() { let _ = &[(); usize::MAX]; } </ins>