├── .gitignore ├── Cargo.toml ├── README.md ├── libcore ├── Cargo.toml ├── any.rs ├── array.rs ├── borrow.rs ├── cell.rs ├── char.rs ├── char_private.rs ├── clone.rs ├── cmp.rs ├── convert.rs ├── default.rs ├── fmt │ ├── builders.rs │ ├── mod.rs │ ├── num.rs │ └── rt │ │ └── v1.rs ├── hash │ ├── mod.rs │ └── sip.rs ├── intrinsics.rs ├── iter │ ├── iterator.rs │ ├── mod.rs │ ├── range.rs │ ├── sources.rs │ └── traits.rs ├── iter_private.rs ├── lib.rs ├── macros.rs ├── marker.rs ├── mem.rs ├── nonzero.rs ├── num │ ├── bignum.rs │ ├── dec2flt │ │ ├── algorithm.rs │ │ ├── mod.rs │ │ ├── num.rs │ │ ├── parse.rs │ │ ├── rawfp.rs │ │ └── table.rs │ ├── diy_float.rs │ ├── f32.rs │ ├── f64.rs │ ├── float_macros.rs │ ├── flt2dec │ │ ├── decoder.rs │ │ ├── estimator.rs │ │ ├── mod.rs │ │ └── strategy │ │ │ ├── dragon.rs │ │ │ └── grisu.rs │ ├── i16.rs │ ├── i32.rs │ ├── i64.rs │ ├── i8.rs │ ├── int_macros.rs │ ├── isize.rs │ ├── mod.rs │ ├── u16.rs │ ├── u32.rs │ ├── u64.rs │ ├── u8.rs │ ├── uint_macros.rs │ ├── usize.rs │ └── wrapping.rs ├── ops.rs ├── option.rs ├── panicking.rs ├── prelude │ ├── mod.rs │ └── v1.rs ├── ptr.rs ├── raw.rs ├── result.rs ├── slice.rs ├── str │ ├── mod.rs │ └── pattern.rs ├── sync │ ├── atomic.rs │ └── mod.rs └── tuple.rs ├── libcyano ├── Cargo.toml ├── core.rs └── src │ ├── ffi.rs │ ├── lib.rs │ └── vec.rs └── src ├── cell.rs ├── codegen.rs ├── compiler.rs ├── head └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cyano" 3 | version = "0.1.0" 4 | authors = ["ticki "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cyano: An advanced Rust-to-JavaScript transpiler 2 | 3 | Cyano implements a transpiler converting Rust (MIR output) to JavaScript. It 4 | supports most of Rust's features, but still lacks of support for various Rust 5 | libraries. 6 | 7 | **This crate is highly Work-in-Process and not ready to use yet.** 8 | 9 | ## Roadmap 10 | 11 | - [x] Pointers/references 12 | - [x] `Box`es 13 | - [x] Functions 14 | - [x] Traits/generics 15 | - [x] Enums 16 | - [x] `match` 17 | - [x] JS library integration 18 | - [ ] `libcore` and `libstd` 19 | - [ ] Panicking 20 | - [ ] Custom destructors (`Drop` trait) 21 | - [ ] JS specific optimizations 22 | -------------------------------------------------------------------------------- /libcore/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["The Rust Project Developers"] 3 | name = "core" 4 | version = "0.0.0" 5 | 6 | [lib] 7 | name = "core" 8 | path = "lib.rs" 9 | test = false 10 | 11 | [[test]] 12 | name = "coretest" 13 | path = "../libcoretest/lib.rs" 14 | -------------------------------------------------------------------------------- /libcore/any.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! This module implements the `Any` trait, which enables dynamic typing 12 | //! of any `'static` type through runtime reflection. 13 | //! 14 | //! `Any` itself can be used to get a `TypeId`, and has more features when used 15 | //! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and 16 | //! `downcast_ref` methods, to test if the contained value is of a given type, 17 | //! and to get a reference to the inner value as a type. As `&mut Any`, there 18 | //! is also the `downcast_mut` method, for getting a mutable reference to the 19 | //! inner value. `Box` adds the `downcast` method, which attempts to 20 | //! convert to a `Box`. See the [`Box`] documentation for the full details. 21 | //! 22 | //! Note that &Any is limited to testing whether a value is of a specified 23 | //! concrete type, and cannot be used to test whether a type implements a trait. 24 | //! 25 | //! [`Box`]: ../../std/boxed/struct.Box.html 26 | //! 27 | //! # Examples 28 | //! 29 | //! Consider a situation where we want to log out a value passed to a function. 30 | //! We know the value we're working on implements Debug, but we don't know its 31 | //! concrete type. We want to give special treatment to certain types: in this 32 | //! case printing out the length of String values prior to their value. 33 | //! We don't know the concrete type of our value at compile time, so we need to 34 | //! use runtime reflection instead. 35 | //! 36 | //! ```rust 37 | //! use std::fmt::Debug; 38 | //! use std::any::Any; 39 | //! 40 | //! // Logger function for any type that implements Debug. 41 | //! fn log(value: &T) { 42 | //! let value_any = value as &Any; 43 | //! 44 | //! // try to convert our value to a String. If successful, we want to 45 | //! // output the String's length as well as its value. If not, it's a 46 | //! // different type: just print it out unadorned. 47 | //! match value_any.downcast_ref::() { 48 | //! Some(as_string) => { 49 | //! println!("String ({}): {}", as_string.len(), as_string); 50 | //! } 51 | //! None => { 52 | //! println!("{:?}", value); 53 | //! } 54 | //! } 55 | //! } 56 | //! 57 | //! // This function wants to log its parameter out prior to doing work with it. 58 | //! fn do_work(value: &T) { 59 | //! log(value); 60 | //! // ...do some other work 61 | //! } 62 | //! 63 | //! fn main() { 64 | //! let my_string = "Hello World".to_string(); 65 | //! do_work(&my_string); 66 | //! 67 | //! let my_i8: i8 = 100; 68 | //! do_work(&my_i8); 69 | //! } 70 | //! ``` 71 | 72 | #![stable(feature = "rust1", since = "1.0.0")] 73 | 74 | use fmt; 75 | use intrinsics; 76 | use marker::Reflect; 77 | 78 | /////////////////////////////////////////////////////////////////////////////// 79 | // Any trait 80 | /////////////////////////////////////////////////////////////////////////////// 81 | 82 | /// A type to emulate dynamic typing. 83 | /// 84 | /// Most types implement `Any`. However, any type which contains a non-`'static` reference does not. 85 | /// See the [module-level documentation][mod] for more details. 86 | /// 87 | /// [mod]: index.html 88 | #[stable(feature = "rust1", since = "1.0.0")] 89 | pub trait Any: Reflect + 'static { 90 | /// Gets the `TypeId` of `self`. 91 | /// 92 | /// # Examples 93 | /// 94 | /// ``` 95 | /// #![feature(get_type_id)] 96 | /// 97 | /// use std::any::{Any, TypeId}; 98 | /// 99 | /// fn is_string(s: &Any) -> bool { 100 | /// TypeId::of::() == s.get_type_id() 101 | /// } 102 | /// 103 | /// fn main() { 104 | /// assert_eq!(is_string(&0), false); 105 | /// assert_eq!(is_string(&"cookie monster".to_owned()), true); 106 | /// } 107 | /// ``` 108 | #[unstable(feature = "get_type_id", 109 | reason = "this method will likely be replaced by an associated static", 110 | issue = "27745")] 111 | fn get_type_id(&self) -> TypeId; 112 | } 113 | 114 | #[stable(feature = "rust1", since = "1.0.0")] 115 | impl Any for T { 116 | fn get_type_id(&self) -> TypeId { TypeId::of::() } 117 | } 118 | 119 | /////////////////////////////////////////////////////////////////////////////// 120 | // Extension methods for Any trait objects. 121 | /////////////////////////////////////////////////////////////////////////////// 122 | 123 | #[stable(feature = "rust1", since = "1.0.0")] 124 | impl fmt::Debug for Any { 125 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 126 | f.pad("Any") 127 | } 128 | } 129 | 130 | // Ensure that the result of e.g. joining a thread can be printed and 131 | // hence used with `unwrap`. May eventually no longer be needed if 132 | // dispatch works with upcasting. 133 | #[stable(feature = "rust1", since = "1.0.0")] 134 | impl fmt::Debug for Any + Send { 135 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 136 | f.pad("Any") 137 | } 138 | } 139 | 140 | impl Any { 141 | /// Returns true if the boxed type is the same as `T`. 142 | /// 143 | /// # Examples 144 | /// 145 | /// ``` 146 | /// use std::any::Any; 147 | /// 148 | /// fn is_string(s: &Any) { 149 | /// if s.is::() { 150 | /// println!("It's a string!"); 151 | /// } else { 152 | /// println!("Not a string..."); 153 | /// } 154 | /// } 155 | /// 156 | /// fn main() { 157 | /// is_string(&0); 158 | /// is_string(&"cookie monster".to_owned()); 159 | /// } 160 | /// ``` 161 | #[stable(feature = "rust1", since = "1.0.0")] 162 | #[inline] 163 | pub fn is(&self) -> bool { 164 | // Get TypeId of the type this function is instantiated with 165 | let t = TypeId::of::(); 166 | 167 | // Get TypeId of the type in the trait object 168 | let boxed = self.get_type_id(); 169 | 170 | // Compare both TypeIds on equality 171 | t == boxed 172 | } 173 | 174 | /// Returns some reference to the boxed value if it is of type `T`, or 175 | /// `None` if it isn't. 176 | /// 177 | /// # Examples 178 | /// 179 | /// ``` 180 | /// use std::any::Any; 181 | /// 182 | /// fn print_if_string(s: &Any) { 183 | /// if let Some(string) = s.downcast_ref::() { 184 | /// println!("It's a string({}): '{}'", string.len(), string); 185 | /// } else { 186 | /// println!("Not a string..."); 187 | /// } 188 | /// } 189 | /// 190 | /// fn main() { 191 | /// print_if_string(&0); 192 | /// print_if_string(&"cookie monster".to_owned()); 193 | /// } 194 | /// ``` 195 | #[stable(feature = "rust1", since = "1.0.0")] 196 | #[inline] 197 | pub fn downcast_ref(&self) -> Option<&T> { 198 | if self.is::() { 199 | unsafe { 200 | Some(&*(self as *const Any as *const T)) 201 | } 202 | } else { 203 | None 204 | } 205 | } 206 | 207 | /// Returns some mutable reference to the boxed value if it is of type `T`, or 208 | /// `None` if it isn't. 209 | /// 210 | /// # Examples 211 | /// 212 | /// ``` 213 | /// use std::any::Any; 214 | /// 215 | /// fn modify_if_u32(s: &mut Any) { 216 | /// if let Some(num) = s.downcast_mut::() { 217 | /// *num = 42; 218 | /// } 219 | /// } 220 | /// 221 | /// fn main() { 222 | /// let mut x = 10u32; 223 | /// let mut s = "starlord".to_owned(); 224 | /// 225 | /// modify_if_u32(&mut x); 226 | /// modify_if_u32(&mut s); 227 | /// 228 | /// assert_eq!(x, 42); 229 | /// assert_eq!(&s, "starlord"); 230 | /// } 231 | /// ``` 232 | #[stable(feature = "rust1", since = "1.0.0")] 233 | #[inline] 234 | pub fn downcast_mut(&mut self) -> Option<&mut T> { 235 | if self.is::() { 236 | unsafe { 237 | Some(&mut *(self as *mut Any as *mut T)) 238 | } 239 | } else { 240 | None 241 | } 242 | } 243 | } 244 | 245 | impl Any+Send { 246 | /// Forwards to the method defined on the type `Any`. 247 | /// 248 | /// # Examples 249 | /// 250 | /// ``` 251 | /// use std::any::Any; 252 | /// 253 | /// fn is_string(s: &(Any + Send)) { 254 | /// if s.is::() { 255 | /// println!("It's a string!"); 256 | /// } else { 257 | /// println!("Not a string..."); 258 | /// } 259 | /// } 260 | /// 261 | /// fn main() { 262 | /// is_string(&0); 263 | /// is_string(&"cookie monster".to_owned()); 264 | /// } 265 | /// ``` 266 | #[stable(feature = "rust1", since = "1.0.0")] 267 | #[inline] 268 | pub fn is(&self) -> bool { 269 | Any::is::(self) 270 | } 271 | 272 | /// Forwards to the method defined on the type `Any`. 273 | /// 274 | /// # Examples 275 | /// 276 | /// ``` 277 | /// use std::any::Any; 278 | /// 279 | /// fn print_if_string(s: &(Any + Send)) { 280 | /// if let Some(string) = s.downcast_ref::() { 281 | /// println!("It's a string({}): '{}'", string.len(), string); 282 | /// } else { 283 | /// println!("Not a string..."); 284 | /// } 285 | /// } 286 | /// 287 | /// fn main() { 288 | /// print_if_string(&0); 289 | /// print_if_string(&"cookie monster".to_owned()); 290 | /// } 291 | /// ``` 292 | #[stable(feature = "rust1", since = "1.0.0")] 293 | #[inline] 294 | pub fn downcast_ref(&self) -> Option<&T> { 295 | Any::downcast_ref::(self) 296 | } 297 | 298 | /// Forwards to the method defined on the type `Any`. 299 | /// 300 | /// # Examples 301 | /// 302 | /// ``` 303 | /// use std::any::Any; 304 | /// 305 | /// fn modify_if_u32(s: &mut (Any+ Send)) { 306 | /// if let Some(num) = s.downcast_mut::() { 307 | /// *num = 42; 308 | /// } 309 | /// } 310 | /// 311 | /// fn main() { 312 | /// let mut x = 10u32; 313 | /// let mut s = "starlord".to_owned(); 314 | /// 315 | /// modify_if_u32(&mut x); 316 | /// modify_if_u32(&mut s); 317 | /// 318 | /// assert_eq!(x, 42); 319 | /// assert_eq!(&s, "starlord"); 320 | /// } 321 | /// ``` 322 | #[stable(feature = "rust1", since = "1.0.0")] 323 | #[inline] 324 | pub fn downcast_mut(&mut self) -> Option<&mut T> { 325 | Any::downcast_mut::(self) 326 | } 327 | } 328 | 329 | 330 | /////////////////////////////////////////////////////////////////////////////// 331 | // TypeID and its methods 332 | /////////////////////////////////////////////////////////////////////////////// 333 | 334 | /// A `TypeId` represents a globally unique identifier for a type. 335 | /// 336 | /// Each `TypeId` is an opaque object which does not allow inspection of what's 337 | /// inside but does allow basic operations such as cloning, comparison, 338 | /// printing, and showing. 339 | /// 340 | /// A `TypeId` is currently only available for types which ascribe to `'static`, 341 | /// but this limitation may be removed in the future. 342 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 343 | #[stable(feature = "rust1", since = "1.0.0")] 344 | pub struct TypeId { 345 | t: u64, 346 | } 347 | 348 | impl TypeId { 349 | /// Returns the `TypeId` of the type this generic function has been 350 | /// instantiated with. 351 | /// 352 | /// # Examples 353 | /// 354 | /// ``` 355 | /// #![feature(get_type_id)] 356 | /// 357 | /// use std::any::{Any, TypeId}; 358 | /// 359 | /// fn is_string(s: &Any) -> bool { 360 | /// TypeId::of::() == s.get_type_id() 361 | /// } 362 | /// 363 | /// fn main() { 364 | /// assert_eq!(is_string(&0), false); 365 | /// assert_eq!(is_string(&"cookie monster".to_owned()), true); 366 | /// } 367 | /// ``` 368 | #[stable(feature = "rust1", since = "1.0.0")] 369 | pub fn of() -> TypeId { 370 | TypeId { 371 | t: unsafe { intrinsics::type_id::() }, 372 | } 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /libcore/array.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Implementations of things like `Eq` for fixed-length arrays 12 | //! up to a certain length. Eventually we should able to generalize 13 | //! to all lengths. 14 | //! 15 | //! *[See also the array primitive type](../../std/primitive.array.html).* 16 | 17 | #![unstable(feature = "fixed_size_array", 18 | reason = "traits and impls are better expressed through generic \ 19 | integer constants", 20 | issue = "27778")] 21 | 22 | use borrow::{Borrow, BorrowMut}; 23 | use cmp::Ordering; 24 | use fmt; 25 | use hash::{Hash, self}; 26 | use marker::Unsize; 27 | use slice::{Iter, IterMut}; 28 | 29 | /// Utility trait implemented only on arrays of fixed size 30 | /// 31 | /// This trait can be used to implement other traits on fixed-size arrays 32 | /// without causing much metadata bloat. 33 | /// 34 | /// The trait is marked unsafe in order to restrict implementors to fixed-size 35 | /// arrays. User of this trait can assume that implementors have the exact 36 | /// layout in memory of a fixed size array (for example, for unsafe 37 | /// initialization). 38 | /// 39 | /// Note that the traits AsRef and AsMut provide similar methods for types that 40 | /// may not be fixed-size arrays. Implementors should prefer those traits 41 | /// instead. 42 | pub unsafe trait FixedSizeArray { 43 | /// Converts the array to immutable slice 44 | fn as_slice(&self) -> &[T]; 45 | /// Converts the array to mutable slice 46 | fn as_mut_slice(&mut self) -> &mut [T]; 47 | } 48 | 49 | unsafe impl> FixedSizeArray for A { 50 | #[inline] 51 | fn as_slice(&self) -> &[T] { 52 | self 53 | } 54 | #[inline] 55 | fn as_mut_slice(&mut self) -> &mut [T] { 56 | self 57 | } 58 | } 59 | 60 | macro_rules! __impl_slice_eq1 { 61 | ($Lhs: ty, $Rhs: ty) => { 62 | __impl_slice_eq1! { $Lhs, $Rhs, Sized } 63 | }; 64 | ($Lhs: ty, $Rhs: ty, $Bound: ident) => { 65 | #[stable(feature = "rust1", since = "1.0.0")] 66 | impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq { 67 | #[inline] 68 | fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] } 69 | #[inline] 70 | fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] } 71 | } 72 | } 73 | } 74 | 75 | macro_rules! __impl_slice_eq2 { 76 | ($Lhs: ty, $Rhs: ty) => { 77 | __impl_slice_eq2! { $Lhs, $Rhs, Sized } 78 | }; 79 | ($Lhs: ty, $Rhs: ty, $Bound: ident) => { 80 | __impl_slice_eq1!($Lhs, $Rhs, $Bound); 81 | 82 | #[stable(feature = "rust1", since = "1.0.0")] 83 | impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq { 84 | #[inline] 85 | fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] } 86 | #[inline] 87 | fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] } 88 | } 89 | } 90 | } 91 | 92 | // macro for implementing n-ary tuple functions and operations 93 | macro_rules! array_impls { 94 | ($($N:expr)+) => { 95 | $( 96 | impl AsRef<[T]> for [T; $N] { 97 | #[inline] 98 | fn as_ref(&self) -> &[T] { 99 | &self[..] 100 | } 101 | } 102 | 103 | impl AsMut<[T]> for [T; $N] { 104 | #[inline] 105 | fn as_mut(&mut self) -> &mut [T] { 106 | &mut self[..] 107 | } 108 | } 109 | 110 | #[stable(feature = "array_borrow", since = "1.4.0")] 111 | impl Borrow<[T]> for [T; $N] { 112 | fn borrow(&self) -> &[T] { 113 | self 114 | } 115 | } 116 | 117 | #[stable(feature = "array_borrow", since = "1.4.0")] 118 | impl BorrowMut<[T]> for [T; $N] { 119 | fn borrow_mut(&mut self) -> &mut [T] { 120 | self 121 | } 122 | } 123 | 124 | #[stable(feature = "rust1", since = "1.0.0")] 125 | impl Clone for [T; $N] { 126 | fn clone(&self) -> [T; $N] { 127 | *self 128 | } 129 | } 130 | 131 | #[stable(feature = "rust1", since = "1.0.0")] 132 | impl Hash for [T; $N] { 133 | fn hash(&self, state: &mut H) { 134 | Hash::hash(&self[..], state) 135 | } 136 | } 137 | 138 | #[stable(feature = "rust1", since = "1.0.0")] 139 | impl fmt::Debug for [T; $N] { 140 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 141 | fmt::Debug::fmt(&&self[..], f) 142 | } 143 | } 144 | 145 | #[stable(feature = "rust1", since = "1.0.0")] 146 | impl<'a, T> IntoIterator for &'a [T; $N] { 147 | type Item = &'a T; 148 | type IntoIter = Iter<'a, T>; 149 | 150 | fn into_iter(self) -> Iter<'a, T> { 151 | self.iter() 152 | } 153 | } 154 | 155 | #[stable(feature = "rust1", since = "1.0.0")] 156 | impl<'a, T> IntoIterator for &'a mut [T; $N] { 157 | type Item = &'a mut T; 158 | type IntoIter = IterMut<'a, T>; 159 | 160 | fn into_iter(self) -> IterMut<'a, T> { 161 | self.iter_mut() 162 | } 163 | } 164 | 165 | // NOTE: some less important impls are omitted to reduce code bloat 166 | __impl_slice_eq1! { [A; $N], [B; $N] } 167 | __impl_slice_eq2! { [A; $N], [B] } 168 | __impl_slice_eq2! { [A; $N], &'b [B] } 169 | __impl_slice_eq2! { [A; $N], &'b mut [B] } 170 | // __impl_slice_eq2! { [A; $N], &'b [B; $N] } 171 | // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } 172 | 173 | #[stable(feature = "rust1", since = "1.0.0")] 174 | impl Eq for [T; $N] { } 175 | 176 | #[stable(feature = "rust1", since = "1.0.0")] 177 | impl PartialOrd for [T; $N] { 178 | #[inline] 179 | fn partial_cmp(&self, other: &[T; $N]) -> Option { 180 | PartialOrd::partial_cmp(&&self[..], &&other[..]) 181 | } 182 | #[inline] 183 | fn lt(&self, other: &[T; $N]) -> bool { 184 | PartialOrd::lt(&&self[..], &&other[..]) 185 | } 186 | #[inline] 187 | fn le(&self, other: &[T; $N]) -> bool { 188 | PartialOrd::le(&&self[..], &&other[..]) 189 | } 190 | #[inline] 191 | fn ge(&self, other: &[T; $N]) -> bool { 192 | PartialOrd::ge(&&self[..], &&other[..]) 193 | } 194 | #[inline] 195 | fn gt(&self, other: &[T; $N]) -> bool { 196 | PartialOrd::gt(&&self[..], &&other[..]) 197 | } 198 | } 199 | 200 | #[stable(feature = "rust1", since = "1.0.0")] 201 | impl Ord for [T; $N] { 202 | #[inline] 203 | fn cmp(&self, other: &[T; $N]) -> Ordering { 204 | Ord::cmp(&&self[..], &&other[..]) 205 | } 206 | } 207 | )+ 208 | } 209 | } 210 | 211 | array_impls! { 212 | 0 1 2 3 4 5 6 7 8 9 213 | 10 11 12 13 14 15 16 17 18 19 214 | 20 21 22 23 24 25 26 27 28 29 215 | 30 31 32 216 | } 217 | 218 | // The Default impls cannot be generated using the array_impls! macro because 219 | // they require array literals. 220 | 221 | macro_rules! array_impl_default { 222 | {$n:expr, $t:ident $($ts:ident)*} => { 223 | #[stable(since = "1.4.0", feature = "array_default")] 224 | impl Default for [T; $n] where T: Default { 225 | fn default() -> [T; $n] { 226 | [$t::default(), $($ts::default()),*] 227 | } 228 | } 229 | array_impl_default!{($n - 1), $($ts)*} 230 | }; 231 | {$n:expr,} => { 232 | #[stable(since = "1.4.0", feature = "array_default")] 233 | impl Default for [T; $n] { 234 | fn default() -> [T; $n] { [] } 235 | } 236 | }; 237 | } 238 | 239 | array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} 240 | -------------------------------------------------------------------------------- /libcore/borrow.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! A module for working with borrowed data. 12 | 13 | #![stable(feature = "rust1", since = "1.0.0")] 14 | 15 | /// A trait for borrowing data. 16 | /// 17 | /// In general, there may be several ways to "borrow" a piece of data. The 18 | /// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` 19 | /// (a mutable borrow). But types like `Vec` provide additional kinds of 20 | /// borrows: the borrowed slices `&[T]` and `&mut [T]`. 21 | /// 22 | /// When writing generic code, it is often desirable to abstract over all ways 23 | /// of borrowing data from a given type. That is the role of the `Borrow` 24 | /// trait: if `T: Borrow`, then `&U` can be borrowed from `&T`. A given 25 | /// type can be borrowed as multiple different types. In particular, `Vec: 26 | /// Borrow>` and `Vec: Borrow<[T]>`. 27 | /// 28 | /// If you are implementing `Borrow` and both `Self` and `Borrowed` implement 29 | /// `Hash`, `Eq`, and/or `Ord`, they must produce the same result. 30 | /// 31 | /// `Borrow` is very similar to, but different than, `AsRef`. See 32 | /// [the book][book] for more. 33 | /// 34 | /// [book]: ../../book/borrow-and-asref.html 35 | #[stable(feature = "rust1", since = "1.0.0")] 36 | pub trait Borrow { 37 | /// Immutably borrows from an owned value. 38 | /// 39 | /// # Examples 40 | /// 41 | /// ``` 42 | /// use std::borrow::Borrow; 43 | /// 44 | /// fn check>(s: T) { 45 | /// assert_eq!("Hello", s.borrow()); 46 | /// } 47 | /// 48 | /// let s = "Hello".to_string(); 49 | /// 50 | /// check(s); 51 | /// 52 | /// let s = "Hello"; 53 | /// 54 | /// check(s); 55 | /// ``` 56 | #[stable(feature = "rust1", since = "1.0.0")] 57 | fn borrow(&self) -> &Borrowed; 58 | } 59 | 60 | /// A trait for mutably borrowing data. 61 | /// 62 | /// Similar to `Borrow`, but for mutable borrows. 63 | #[stable(feature = "rust1", since = "1.0.0")] 64 | pub trait BorrowMut : Borrow { 65 | /// Mutably borrows from an owned value. 66 | /// 67 | /// # Examples 68 | /// 69 | /// ``` 70 | /// use std::borrow::BorrowMut; 71 | /// 72 | /// fn check>(mut v: T) { 73 | /// assert_eq!(&mut [1, 2, 3], v.borrow_mut()); 74 | /// } 75 | /// 76 | /// let v = vec![1, 2, 3]; 77 | /// 78 | /// check(v); 79 | /// ``` 80 | #[stable(feature = "rust1", since = "1.0.0")] 81 | fn borrow_mut(&mut self) -> &mut Borrowed; 82 | } 83 | 84 | #[stable(feature = "rust1", since = "1.0.0")] 85 | impl Borrow for T { 86 | fn borrow(&self) -> &T { self } 87 | } 88 | 89 | #[stable(feature = "rust1", since = "1.0.0")] 90 | impl BorrowMut for T { 91 | fn borrow_mut(&mut self) -> &mut T { self } 92 | } 93 | 94 | #[stable(feature = "rust1", since = "1.0.0")] 95 | impl<'a, T: ?Sized> Borrow for &'a T { 96 | fn borrow(&self) -> &T { &**self } 97 | } 98 | 99 | #[stable(feature = "rust1", since = "1.0.0")] 100 | impl<'a, T: ?Sized> Borrow for &'a mut T { 101 | fn borrow(&self) -> &T { &**self } 102 | } 103 | 104 | #[stable(feature = "rust1", since = "1.0.0")] 105 | impl<'a, T: ?Sized> BorrowMut for &'a mut T { 106 | fn borrow_mut(&mut self) -> &mut T { &mut **self } 107 | } 108 | -------------------------------------------------------------------------------- /libcore/char_private.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | // NOTE: The following code was generated by "src/etc/char_private.py", 12 | // do not edit directly! 13 | 14 | fn check(x: u16, singletons: &[u16], normal: &[u16]) -> bool { 15 | for &s in singletons { 16 | if x == s { 17 | return false; 18 | } else if x < s { 19 | break; 20 | } 21 | } 22 | for w in normal.chunks(2) { 23 | let start = w[0]; 24 | let len = w[1]; 25 | let difference = (x as i32) - (start as i32); 26 | if 0 <= difference { 27 | if difference < len as i32 { 28 | return false; 29 | } 30 | } else { 31 | break; 32 | } 33 | } 34 | true 35 | } 36 | 37 | pub fn is_printable(x: char) -> bool { 38 | let x = x as u32; 39 | let lower = x as u16; 40 | if x < 0x10000 { 41 | check(lower, SINGLETONS0, NORMAL0) 42 | } else if x < 0x20000 { 43 | check(lower, SINGLETONS1, NORMAL1) 44 | } else { 45 | if 0x20000 <= x && x < 0x2f800 { 46 | return false; 47 | } 48 | if 0x2fa1e <= x && x < 0xe0100 { 49 | return false; 50 | } 51 | if 0xe01f0 <= x && x < 0x110000 { 52 | return false; 53 | } 54 | true 55 | } 56 | } 57 | 58 | const SINGLETONS0: &'static [u16] = &[ 59 | 0xad, 60 | 0x378, 61 | 0x379, 62 | 0x38b, 63 | 0x38d, 64 | 0x3a2, 65 | 0x557, 66 | 0x558, 67 | 0x560, 68 | 0x588, 69 | 0x590, 70 | 0x61c, 71 | 0x61d, 72 | 0x6dd, 73 | 0x70e, 74 | 0x70f, 75 | 0x74b, 76 | 0x74c, 77 | 0x82e, 78 | 0x82f, 79 | 0x83f, 80 | 0x85c, 81 | 0x85d, 82 | 0x8a1, 83 | 0x8ff, 84 | 0x978, 85 | 0x980, 86 | 0x984, 87 | 0x98d, 88 | 0x98e, 89 | 0x991, 90 | 0x992, 91 | 0x9a9, 92 | 0x9b1, 93 | 0x9ba, 94 | 0x9bb, 95 | 0x9c5, 96 | 0x9c6, 97 | 0x9c9, 98 | 0x9ca, 99 | 0x9de, 100 | 0x9e4, 101 | 0x9e5, 102 | 0xa04, 103 | 0xa11, 104 | 0xa12, 105 | 0xa29, 106 | 0xa31, 107 | 0xa34, 108 | 0xa37, 109 | 0xa3a, 110 | 0xa3b, 111 | 0xa3d, 112 | 0xa49, 113 | 0xa4a, 114 | 0xa5d, 115 | 0xa84, 116 | 0xa8e, 117 | 0xa92, 118 | 0xaa9, 119 | 0xab1, 120 | 0xab4, 121 | 0xaba, 122 | 0xabb, 123 | 0xac6, 124 | 0xaca, 125 | 0xace, 126 | 0xacf, 127 | 0xae4, 128 | 0xae5, 129 | 0xb04, 130 | 0xb0d, 131 | 0xb0e, 132 | 0xb11, 133 | 0xb12, 134 | 0xb29, 135 | 0xb31, 136 | 0xb34, 137 | 0xb3a, 138 | 0xb3b, 139 | 0xb45, 140 | 0xb46, 141 | 0xb49, 142 | 0xb4a, 143 | 0xb5e, 144 | 0xb64, 145 | 0xb65, 146 | 0xb84, 147 | 0xb91, 148 | 0xb9b, 149 | 0xb9d, 150 | 0xbc9, 151 | 0xbce, 152 | 0xbcf, 153 | 0xc04, 154 | 0xc0d, 155 | 0xc11, 156 | 0xc29, 157 | 0xc34, 158 | 0xc45, 159 | 0xc49, 160 | 0xc57, 161 | 0xc64, 162 | 0xc65, 163 | 0xc80, 164 | 0xc81, 165 | 0xc84, 166 | 0xc8d, 167 | 0xc91, 168 | 0xca9, 169 | 0xcb4, 170 | 0xcba, 171 | 0xcbb, 172 | 0xcc5, 173 | 0xcc9, 174 | 0xcdf, 175 | 0xce4, 176 | 0xce5, 177 | 0xcf0, 178 | 0xd04, 179 | 0xd0d, 180 | 0xd11, 181 | 0xd3b, 182 | 0xd3c, 183 | 0xd45, 184 | 0xd49, 185 | 0xd64, 186 | 0xd65, 187 | 0xd80, 188 | 0xd81, 189 | 0xd84, 190 | 0xdb2, 191 | 0xdbc, 192 | 0xdbe, 193 | 0xdbf, 194 | 0xdd5, 195 | 0xdd7, 196 | 0xe83, 197 | 0xe85, 198 | 0xe86, 199 | 0xe89, 200 | 0xe8b, 201 | 0xe8c, 202 | 0xe98, 203 | 0xea0, 204 | 0xea4, 205 | 0xea6, 206 | 0xea8, 207 | 0xea9, 208 | 0xeac, 209 | 0xeba, 210 | 0xebe, 211 | 0xebf, 212 | 0xec5, 213 | 0xec7, 214 | 0xece, 215 | 0xecf, 216 | 0xeda, 217 | 0xedb, 218 | 0xf48, 219 | 0xf98, 220 | 0xfbd, 221 | 0xfcd, 222 | 0x10c6, 223 | 0x10ce, 224 | 0x10cf, 225 | 0x1249, 226 | 0x124e, 227 | 0x124f, 228 | 0x1257, 229 | 0x1259, 230 | 0x125e, 231 | 0x125f, 232 | 0x1289, 233 | 0x128e, 234 | 0x128f, 235 | 0x12b1, 236 | 0x12b6, 237 | 0x12b7, 238 | 0x12bf, 239 | 0x12c1, 240 | 0x12c6, 241 | 0x12c7, 242 | 0x12d7, 243 | 0x1311, 244 | 0x1316, 245 | 0x1317, 246 | 0x135b, 247 | 0x135c, 248 | 0x1680, 249 | 0x170d, 250 | 0x176d, 251 | 0x1771, 252 | 0x17de, 253 | 0x17df, 254 | 0x180e, 255 | 0x180f, 256 | 0x196e, 257 | 0x196f, 258 | 0x1a1c, 259 | 0x1a1d, 260 | 0x1a5f, 261 | 0x1a7d, 262 | 0x1a7e, 263 | 0x1f16, 264 | 0x1f17, 265 | 0x1f1e, 266 | 0x1f1f, 267 | 0x1f46, 268 | 0x1f47, 269 | 0x1f4e, 270 | 0x1f4f, 271 | 0x1f58, 272 | 0x1f5a, 273 | 0x1f5c, 274 | 0x1f5e, 275 | 0x1f7e, 276 | 0x1f7f, 277 | 0x1fb5, 278 | 0x1fc5, 279 | 0x1fd4, 280 | 0x1fd5, 281 | 0x1fdc, 282 | 0x1ff0, 283 | 0x1ff1, 284 | 0x1ff5, 285 | 0x2072, 286 | 0x2073, 287 | 0x208f, 288 | 0x2700, 289 | 0x2c2f, 290 | 0x2c5f, 291 | 0x2d26, 292 | 0x2d2e, 293 | 0x2d2f, 294 | 0x2da7, 295 | 0x2daf, 296 | 0x2db7, 297 | 0x2dbf, 298 | 0x2dc7, 299 | 0x2dcf, 300 | 0x2dd7, 301 | 0x2ddf, 302 | 0x2e9a, 303 | 0x3040, 304 | 0x3097, 305 | 0x3098, 306 | 0x318f, 307 | 0x321f, 308 | 0x32ff, 309 | 0xa78f, 310 | 0xa9ce, 311 | 0xaa4e, 312 | 0xaa4f, 313 | 0xaa5a, 314 | 0xaa5b, 315 | 0xab07, 316 | 0xab08, 317 | 0xab0f, 318 | 0xab10, 319 | 0xab27, 320 | 0xabee, 321 | 0xabef, 322 | 0xfa6e, 323 | 0xfa6f, 324 | 0xfb37, 325 | 0xfb3d, 326 | 0xfb3f, 327 | 0xfb42, 328 | 0xfb45, 329 | 0xfd90, 330 | 0xfd91, 331 | 0xfdfe, 332 | 0xfdff, 333 | 0xfe53, 334 | 0xfe67, 335 | 0xfe75, 336 | 0xffc8, 337 | 0xffc9, 338 | 0xffd0, 339 | 0xffd1, 340 | 0xffd8, 341 | 0xffd9, 342 | 0xffe7, 343 | 0xfffe, 344 | 0xffff, 345 | ]; 346 | const SINGLETONS1: &'static [u16] = &[ 347 | 0xc, 348 | 0x27, 349 | 0x3b, 350 | 0x3e, 351 | 0x4e, 352 | 0x4f, 353 | 0x31f, 354 | 0x39e, 355 | 0x49e, 356 | 0x49f, 357 | 0x806, 358 | 0x807, 359 | 0x809, 360 | 0x836, 361 | 0x83d, 362 | 0x83e, 363 | 0x856, 364 | 0xa04, 365 | 0xa14, 366 | 0xa18, 367 | 0xb56, 368 | 0xb57, 369 | 0x10bd, 370 | 0x1135, 371 | 0xd127, 372 | 0xd128, 373 | 0xd455, 374 | 0xd49d, 375 | 0xd4a0, 376 | 0xd4a1, 377 | 0xd4a3, 378 | 0xd4a4, 379 | 0xd4a7, 380 | 0xd4a8, 381 | 0xd4ad, 382 | 0xd4ba, 383 | 0xd4bc, 384 | 0xd4c4, 385 | 0xd506, 386 | 0xd50b, 387 | 0xd50c, 388 | 0xd515, 389 | 0xd51d, 390 | 0xd53a, 391 | 0xd53f, 392 | 0xd545, 393 | 0xd551, 394 | 0xd6a6, 395 | 0xd6a7, 396 | 0xd7cc, 397 | 0xd7cd, 398 | 0xee04, 399 | 0xee20, 400 | 0xee23, 401 | 0xee25, 402 | 0xee26, 403 | 0xee28, 404 | 0xee33, 405 | 0xee38, 406 | 0xee3a, 407 | 0xee48, 408 | 0xee4a, 409 | 0xee4c, 410 | 0xee50, 411 | 0xee53, 412 | 0xee55, 413 | 0xee56, 414 | 0xee58, 415 | 0xee5a, 416 | 0xee5c, 417 | 0xee5e, 418 | 0xee60, 419 | 0xee63, 420 | 0xee65, 421 | 0xee66, 422 | 0xee6b, 423 | 0xee73, 424 | 0xee78, 425 | 0xee7d, 426 | 0xee7f, 427 | 0xee8a, 428 | 0xeea4, 429 | 0xeeaa, 430 | 0xf0af, 431 | 0xf0b0, 432 | 0xf0bf, 433 | 0xf0c0, 434 | 0xf0d0, 435 | 0xf12f, 436 | 0xf336, 437 | 0xf3c5, 438 | 0xf43f, 439 | 0xf441, 440 | 0xf4f8, 441 | 0xf53e, 442 | 0xf53f, 443 | ]; 444 | const NORMAL0: &'static [u16] = &[ 445 | 0x0, 0x20, 446 | 0x7f, 0x22, 447 | 0x37f, 0x5, 448 | 0x528, 0x9, 449 | 0x58b, 0x4, 450 | 0x5c8, 0x8, 451 | 0x5eb, 0x5, 452 | 0x5f5, 0x11, 453 | 0x7b2, 0xe, 454 | 0x7fb, 0x5, 455 | 0x85f, 0x41, 456 | 0x8ad, 0x37, 457 | 0x9b3, 0x3, 458 | 0x9cf, 0x8, 459 | 0x9d8, 0x4, 460 | 0x9fc, 0x5, 461 | 0xa0b, 0x4, 462 | 0xa43, 0x4, 463 | 0xa4e, 0x3, 464 | 0xa52, 0x7, 465 | 0xa5f, 0x7, 466 | 0xa76, 0xb, 467 | 0xad1, 0xf, 468 | 0xaf2, 0xf, 469 | 0xb4e, 0x8, 470 | 0xb58, 0x4, 471 | 0xb78, 0xa, 472 | 0xb8b, 0x3, 473 | 0xb96, 0x3, 474 | 0xba0, 0x3, 475 | 0xba5, 0x3, 476 | 0xbab, 0x3, 477 | 0xbba, 0x4, 478 | 0xbc3, 0x3, 479 | 0xbd1, 0x6, 480 | 0xbd8, 0xe, 481 | 0xbfb, 0x6, 482 | 0xc3a, 0x3, 483 | 0xc4e, 0x7, 484 | 0xc5a, 0x6, 485 | 0xc70, 0x8, 486 | 0xcce, 0x7, 487 | 0xcd7, 0x7, 488 | 0xcf3, 0xf, 489 | 0xd4f, 0x8, 490 | 0xd58, 0x8, 491 | 0xd76, 0x3, 492 | 0xd97, 0x3, 493 | 0xdc7, 0x3, 494 | 0xdcb, 0x4, 495 | 0xde0, 0x12, 496 | 0xdf5, 0xc, 497 | 0xe3b, 0x4, 498 | 0xe5c, 0x25, 499 | 0xe8e, 0x6, 500 | 0xee0, 0x20, 501 | 0xf6d, 0x4, 502 | 0xfdb, 0x25, 503 | 0x10c8, 0x5, 504 | 0x137d, 0x3, 505 | 0x139a, 0x6, 506 | 0x13f5, 0xb, 507 | 0x169d, 0x3, 508 | 0x16f1, 0xf, 509 | 0x1715, 0xb, 510 | 0x1737, 0x9, 511 | 0x1754, 0xc, 512 | 0x1774, 0xc, 513 | 0x17ea, 0x6, 514 | 0x17fa, 0x6, 515 | 0x181a, 0x6, 516 | 0x1878, 0x8, 517 | 0x18ab, 0x5, 518 | 0x18f6, 0xa, 519 | 0x191d, 0x3, 520 | 0x192c, 0x4, 521 | 0x193c, 0x4, 522 | 0x1941, 0x3, 523 | 0x1975, 0xb, 524 | 0x19ac, 0x4, 525 | 0x19ca, 0x6, 526 | 0x19db, 0x3, 527 | 0x1a8a, 0x6, 528 | 0x1a9a, 0x6, 529 | 0x1aae, 0x52, 530 | 0x1b4c, 0x4, 531 | 0x1b7d, 0x3, 532 | 0x1bf4, 0x8, 533 | 0x1c38, 0x3, 534 | 0x1c4a, 0x3, 535 | 0x1c80, 0x40, 536 | 0x1cc8, 0x8, 537 | 0x1cf7, 0x9, 538 | 0x1de7, 0x15, 539 | 0x1fff, 0x11, 540 | 0x2028, 0x8, 541 | 0x205f, 0x11, 542 | 0x209d, 0x3, 543 | 0x20ba, 0x16, 544 | 0x20f1, 0xf, 545 | 0x218a, 0x6, 546 | 0x23f4, 0xc, 547 | 0x2427, 0x19, 548 | 0x244b, 0x15, 549 | 0x2b4d, 0x3, 550 | 0x2b5a, 0xa6, 551 | 0x2cf4, 0x5, 552 | 0x2d28, 0x5, 553 | 0x2d68, 0x7, 554 | 0x2d71, 0xe, 555 | 0x2d97, 0x9, 556 | 0x2e3c, 0x44, 557 | 0x2ef4, 0xc, 558 | 0x2fd6, 0x1a, 559 | 0x2ffc, 0x5, 560 | 0x3100, 0x5, 561 | 0x312e, 0x3, 562 | 0x31bb, 0x5, 563 | 0x31e4, 0xc, 564 | 0x3400, 0x19c0, 565 | 0x4e00, 0x5200, 566 | 0xa48d, 0x3, 567 | 0xa4c7, 0x9, 568 | 0xa62c, 0x14, 569 | 0xa698, 0x7, 570 | 0xa6f8, 0x8, 571 | 0xa794, 0xc, 572 | 0xa7ab, 0x4d, 573 | 0xa82c, 0x4, 574 | 0xa83a, 0x6, 575 | 0xa878, 0x8, 576 | 0xa8c5, 0x9, 577 | 0xa8da, 0x6, 578 | 0xa8fc, 0x4, 579 | 0xa954, 0xb, 580 | 0xa97d, 0x3, 581 | 0xa9da, 0x4, 582 | 0xa9e0, 0x20, 583 | 0xaa37, 0x9, 584 | 0xaa7c, 0x4, 585 | 0xaac3, 0x18, 586 | 0xaaf7, 0xa, 587 | 0xab17, 0x9, 588 | 0xab2f, 0x91, 589 | 0xabfa, 0x2bb6, 590 | 0xd7c7, 0x4, 591 | 0xd7fc, 0x2104, 592 | 0xfada, 0x26, 593 | 0xfb07, 0xc, 594 | 0xfb18, 0x5, 595 | 0xfbc2, 0x11, 596 | 0xfd40, 0x10, 597 | 0xfdc8, 0x28, 598 | 0xfe1a, 0x6, 599 | 0xfe27, 0x9, 600 | 0xfe6c, 0x4, 601 | 0xfefd, 0x4, 602 | 0xffbf, 0x3, 603 | 0xffdd, 0x3, 604 | 0xffef, 0xd, 605 | ]; 606 | const NORMAL1: &'static [u16] = &[ 607 | 0x5e, 0x22, 608 | 0xfb, 0x5, 609 | 0x103, 0x4, 610 | 0x134, 0x3, 611 | 0x18b, 0x5, 612 | 0x19c, 0x34, 613 | 0x1fe, 0x82, 614 | 0x29d, 0x3, 615 | 0x2d1, 0x2f, 616 | 0x324, 0xc, 617 | 0x34b, 0x35, 618 | 0x3c4, 0x4, 619 | 0x3d6, 0x2a, 620 | 0x4aa, 0x356, 621 | 0x839, 0x3, 622 | 0x860, 0xa0, 623 | 0x91c, 0x3, 624 | 0x93a, 0x5, 625 | 0x940, 0x40, 626 | 0x9b8, 0x6, 627 | 0x9c0, 0x40, 628 | 0xa07, 0x5, 629 | 0xa34, 0x4, 630 | 0xa3b, 0x4, 631 | 0xa48, 0x8, 632 | 0xa59, 0x7, 633 | 0xa80, 0x80, 634 | 0xb36, 0x3, 635 | 0xb73, 0x5, 636 | 0xb80, 0x80, 637 | 0xc49, 0x217, 638 | 0xe7f, 0x181, 639 | 0x104e, 0x4, 640 | 0x1070, 0x10, 641 | 0x10c2, 0xe, 642 | 0x10e9, 0x7, 643 | 0x10fa, 0x6, 644 | 0x1144, 0x3c, 645 | 0x11c9, 0x7, 646 | 0x11da, 0x4a6, 647 | 0x16b8, 0x8, 648 | 0x16ca, 0x936, 649 | 0x236f, 0x91, 650 | 0x2463, 0xd, 651 | 0x2474, 0xb8c, 652 | 0x342f, 0x33d1, 653 | 0x6a39, 0x4c7, 654 | 0x6f45, 0xb, 655 | 0x6f7f, 0x10, 656 | 0x6fa0, 0x4060, 657 | 0xb002, 0x1ffe, 658 | 0xd0f6, 0xa, 659 | 0xd173, 0x8, 660 | 0xd1de, 0x22, 661 | 0xd246, 0xba, 662 | 0xd357, 0x9, 663 | 0xd372, 0x8e, 664 | 0xd547, 0x3, 665 | 0xd800, 0x1600, 666 | 0xee3c, 0x6, 667 | 0xee43, 0x4, 668 | 0xee9c, 0x5, 669 | 0xeebc, 0x34, 670 | 0xeef2, 0x10e, 671 | 0xf02c, 0x4, 672 | 0xf094, 0xc, 673 | 0xf0e0, 0x20, 674 | 0xf10b, 0x5, 675 | 0xf16c, 0x4, 676 | 0xf19b, 0x4b, 677 | 0xf203, 0xd, 678 | 0xf23b, 0x5, 679 | 0xf249, 0x7, 680 | 0xf252, 0xae, 681 | 0xf321, 0xf, 682 | 0xf37d, 0x3, 683 | 0xf394, 0xc, 684 | 0xf3cb, 0x15, 685 | 0xf3f1, 0xf, 686 | 0xf4fd, 0x3, 687 | 0xf544, 0xc, 688 | 0xf568, 0x93, 689 | 0xf641, 0x4, 690 | 0xf650, 0x30, 691 | 0xf6c6, 0x3a, 692 | 0xf774, 0x88c, 693 | ]; 694 | -------------------------------------------------------------------------------- /libcore/clone.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The `Clone` trait for types that cannot be 'implicitly copied'. 12 | //! 13 | //! In Rust, some simple types are "implicitly copyable" and when you 14 | //! assign them or pass them as arguments, the receiver will get a copy, 15 | //! leaving the original value in place. These types do not require 16 | //! allocation to copy and do not have finalizers (i.e. they do not 17 | //! contain owned boxes or implement `Drop`), so the compiler considers 18 | //! them cheap and safe to copy. For other types copies must be made 19 | //! explicitly, by convention implementing the `Clone` trait and calling 20 | //! the `clone` method. 21 | //! 22 | //! Basic usage example: 23 | //! 24 | //! ``` 25 | //! let s = String::new(); // String type implements Clone 26 | //! let copy = s.clone(); // so we can clone it 27 | //! ``` 28 | //! 29 | //! To easily implement the Clone trait, you can also use 30 | //! `#[derive(Clone)]`. Example: 31 | //! 32 | //! ``` 33 | //! #[derive(Clone)] // we add the Clone trait to Morpheus struct 34 | //! struct Morpheus { 35 | //! blue_pill: f32, 36 | //! red_pill: i64, 37 | //! } 38 | //! 39 | //! fn main() { 40 | //! let f = Morpheus { blue_pill: 0.0, red_pill: 0 }; 41 | //! let copy = f.clone(); // and now we can clone it! 42 | //! } 43 | //! ``` 44 | 45 | #![stable(feature = "rust1", since = "1.0.0")] 46 | 47 | /// A common trait for the ability to explicitly duplicate an object. 48 | /// 49 | /// Differs from `Copy` in that `Copy` is implicit and extremely inexpensive, while 50 | /// `Clone` is always explicit and may or may not be expensive. In order to enforce 51 | /// these characteristics, Rust does not allow you to reimplement `Copy`, but you 52 | /// may reimplement `Clone` and run arbitrary code. 53 | /// 54 | /// Since `Clone` is more general than `Copy`, you can automatically make anything 55 | /// `Copy` be `Clone` as well. 56 | /// 57 | /// ## Derivable 58 | /// 59 | /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d 60 | /// implementation of `clone()` calls `clone()` on each field. 61 | /// 62 | /// ## How can I implement `Clone`? 63 | /// 64 | /// Types that are `Copy` should have a trivial implementation of `Clone`. More formally: 65 | /// if `T: Copy`, `x: T`, and `y: &T`, then `let x = y.clone();` is equivalent to `let x = *y;`. 66 | /// Manual implementations should be careful to uphold this invariant; however, unsafe code 67 | /// must not rely on it to ensure memory safety. 68 | /// 69 | /// An example is an array holding more than 32 elements of a type that is `Clone`; the standard 70 | /// library only implements `Clone` up until arrays of size 32. In this case, the implementation of 71 | /// `Clone` cannot be `derive`d, but can be implemented as: 72 | /// 73 | /// ``` 74 | /// #[derive(Copy)] 75 | /// struct Stats { 76 | /// frequencies: [i32; 100], 77 | /// } 78 | /// 79 | /// impl Clone for Stats { 80 | /// fn clone(&self) -> Stats { *self } 81 | /// } 82 | /// ``` 83 | #[stable(feature = "rust1", since = "1.0.0")] 84 | pub trait Clone : Sized { 85 | /// Returns a copy of the value. 86 | /// 87 | /// # Examples 88 | /// 89 | /// ``` 90 | /// let hello = "Hello"; // &str implements Clone 91 | /// 92 | /// assert_eq!("Hello", hello.clone()); 93 | /// ``` 94 | #[stable(feature = "rust1", since = "1.0.0")] 95 | fn clone(&self) -> Self; 96 | 97 | /// Performs copy-assignment from `source`. 98 | /// 99 | /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality, 100 | /// but can be overridden to reuse the resources of `a` to avoid unnecessary 101 | /// allocations. 102 | #[inline(always)] 103 | #[stable(feature = "rust1", since = "1.0.0")] 104 | fn clone_from(&mut self, source: &Self) { 105 | *self = source.clone() 106 | } 107 | } 108 | 109 | // FIXME(aburka): this method is used solely by #[derive] to 110 | // assert that every component of a type implements Clone. 111 | // 112 | // This should never be called by user code. 113 | #[doc(hidden)] 114 | #[inline(always)] 115 | #[unstable(feature = "derive_clone_copy", 116 | reason = "deriving hack, should not be public", 117 | issue = "0")] 118 | pub fn assert_receiver_is_clone(_: &T) {} 119 | 120 | #[stable(feature = "rust1", since = "1.0.0")] 121 | impl<'a, T: ?Sized> Clone for &'a T { 122 | /// Returns a shallow copy of the reference. 123 | #[inline] 124 | fn clone(&self) -> &'a T { *self } 125 | } 126 | 127 | macro_rules! clone_impl { 128 | ($t:ty) => { 129 | #[stable(feature = "rust1", since = "1.0.0")] 130 | impl Clone for $t { 131 | /// Returns a deep copy of the value. 132 | #[inline] 133 | fn clone(&self) -> $t { *self } 134 | } 135 | } 136 | } 137 | 138 | clone_impl! { isize } 139 | clone_impl! { i8 } 140 | clone_impl! { i16 } 141 | clone_impl! { i32 } 142 | clone_impl! { i64 } 143 | 144 | clone_impl! { usize } 145 | clone_impl! { u8 } 146 | clone_impl! { u16 } 147 | clone_impl! { u32 } 148 | clone_impl! { u64 } 149 | 150 | clone_impl! { f32 } 151 | clone_impl! { f64 } 152 | 153 | clone_impl! { () } 154 | clone_impl! { bool } 155 | clone_impl! { char } 156 | -------------------------------------------------------------------------------- /libcore/convert.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Traits for conversions between types. 12 | //! 13 | //! The traits in this module provide a general way to talk about conversions 14 | //! from one type to another. They follow the standard Rust conventions of 15 | //! `as`/`into`/`from`. 16 | //! 17 | //! Like many traits, these are often used as bounds for generic functions, to 18 | //! support arguments of multiple types. 19 | //! 20 | //! - Impl the `As*` traits for reference-to-reference conversions 21 | //! - Impl the `Into` trait when you want to consume the value in the conversion 22 | //! - The `From` trait is the most flexible, useful for value _and_ reference conversions 23 | //! - The `TryFrom` and `TryInto` traits behave like `From` and `Into`, but allow for the 24 | //! conversion to fail 25 | //! 26 | //! As a library author, you should prefer implementing `From` or `TryFrom` rather than 27 | //! `Into` or `TryInto`, as `From` and `TryFrom` provide greater flexibility and offer 28 | //! equivalent `Into` or `TryInto` implementations for free, thanks to a blanket implementation 29 | //! in the standard library. 30 | //! 31 | //! # Generic impl 32 | //! 33 | //! - `AsRef` and `AsMut` auto-dereference if the inner type is a reference 34 | //! - `From for T` implies `Into for U` 35 | //! - `TryFrom for T` implies `TryInto for U` 36 | //! - `From` and `Into` are reflexive, which means that all types can `into()` 37 | //! themselves and `from()` themselves 38 | //! 39 | //! See each trait for usage examples. 40 | 41 | #![stable(feature = "rust1", since = "1.0.0")] 42 | 43 | /// A cheap, reference-to-reference conversion. 44 | /// 45 | /// `AsRef` is very similar to, but different than, [`Borrow`]. See 46 | /// [the book][book] for more. 47 | /// 48 | /// [book]: ../../book/borrow-and-asref.html 49 | /// [`Borrow`]: ../../std/borrow/trait.Borrow.html 50 | /// 51 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which 52 | /// returns an [`Option`] or a [`Result`]. 53 | /// 54 | /// [`Option`]: ../../std/option/enum.Option.html 55 | /// [`Result`]: ../../std/result/enum.Result.html 56 | /// 57 | /// # Examples 58 | /// 59 | /// Both [`String`] and `&str` implement `AsRef`: 60 | /// 61 | /// [`String`]: ../../std/string/struct.String.html 62 | /// 63 | /// ``` 64 | /// fn is_hello>(s: T) { 65 | /// assert_eq!("hello", s.as_ref()); 66 | /// } 67 | /// 68 | /// let s = "hello"; 69 | /// is_hello(s); 70 | /// 71 | /// let s = "hello".to_string(); 72 | /// is_hello(s); 73 | /// ``` 74 | /// 75 | /// # Generic Impls 76 | /// 77 | /// - `AsRef` auto-dereferences if the inner type is a reference or a mutable 78 | /// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) 79 | /// 80 | #[stable(feature = "rust1", since = "1.0.0")] 81 | pub trait AsRef { 82 | /// Performs the conversion. 83 | #[stable(feature = "rust1", since = "1.0.0")] 84 | fn as_ref(&self) -> &T; 85 | } 86 | 87 | /// A cheap, mutable reference-to-mutable reference conversion. 88 | /// 89 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which 90 | /// returns an [`Option`] or a [`Result`]. 91 | /// 92 | /// [`Option`]: ../../std/option/enum.Option.html 93 | /// [`Result`]: ../../std/result/enum.Result.html 94 | /// 95 | /// # Generic Impls 96 | /// 97 | /// - `AsMut` auto-dereferences if the inner type is a reference or a mutable 98 | /// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) 99 | /// 100 | #[stable(feature = "rust1", since = "1.0.0")] 101 | pub trait AsMut { 102 | /// Performs the conversion. 103 | #[stable(feature = "rust1", since = "1.0.0")] 104 | fn as_mut(&mut self) -> &mut T; 105 | } 106 | 107 | /// A conversion that consumes `self`, which may or may not be expensive. 108 | /// 109 | /// **Note: this trait must not fail**. If the conversion can fail, use [`TryInto`] or a dedicated 110 | /// method which returns an [`Option`] or a [`Result`]. 111 | /// 112 | /// Library authors should not directly implement this trait, but should prefer implementing 113 | /// the [`From`][From] trait, which offers greater flexibility and provides an equivalent `Into` 114 | /// implementation for free, thanks to a blanket implementation in the standard library. 115 | /// 116 | /// # Examples 117 | /// 118 | /// [`String`] implements `Into>`: 119 | /// 120 | /// ``` 121 | /// fn is_hello>>(s: T) { 122 | /// let bytes = b"hello".to_vec(); 123 | /// assert_eq!(bytes, s.into()); 124 | /// } 125 | /// 126 | /// let s = "hello".to_string(); 127 | /// is_hello(s); 128 | /// ``` 129 | /// 130 | /// # Generic Impls 131 | /// 132 | /// - `[From][From] for U` implies `Into for T` 133 | /// - [`into()`] is reflexive, which means that `Into for T` is implemented 134 | /// 135 | /// [`TryInto`]: trait.TryInto.html 136 | /// [`Option`]: ../../std/option/enum.Option.html 137 | /// [`Result`]: ../../std/result/enum.Result.html 138 | /// [`String`]: ../../std/string/struct.String.html 139 | /// [From]: trait.From.html 140 | /// [`into()`]: trait.Into.html#tymethod.into 141 | #[stable(feature = "rust1", since = "1.0.0")] 142 | pub trait Into: Sized { 143 | /// Performs the conversion. 144 | #[stable(feature = "rust1", since = "1.0.0")] 145 | fn into(self) -> T; 146 | } 147 | 148 | /// Construct `Self` via a conversion. 149 | /// 150 | /// **Note: this trait must not fail**. If the conversion can fail, use [`TryFrom`] or a dedicated 151 | /// method which returns an [`Option`] or a [`Result`]. 152 | /// 153 | /// # Examples 154 | /// 155 | /// [`String`] implements `From<&str>`: 156 | /// 157 | /// ``` 158 | /// let string = "hello".to_string(); 159 | /// let other_string = String::from("hello"); 160 | /// 161 | /// assert_eq!(string, other_string); 162 | /// ``` 163 | /// # Generic impls 164 | /// 165 | /// - `From for U` implies `[Into] for T` 166 | /// - [`from()`] is reflexive, which means that `From for T` is implemented 167 | /// 168 | /// [`TryFrom`]: trait.TryFrom.html 169 | /// [`Option`]: ../../std/option/enum.Option.html 170 | /// [`Result`]: ../../std/result/enum.Result.html 171 | /// [`String`]: ../../std/string/struct.String.html 172 | /// [Into]: trait.Into.html 173 | /// [`from()`]: trait.From.html#tymethod.from 174 | #[stable(feature = "rust1", since = "1.0.0")] 175 | pub trait From: Sized { 176 | /// Performs the conversion. 177 | #[stable(feature = "rust1", since = "1.0.0")] 178 | fn from(T) -> Self; 179 | } 180 | 181 | /// An attempted conversion that consumes `self`, which may or may not be expensive. 182 | /// 183 | /// Library authors should not directly implement this trait, but should prefer implementing 184 | /// the [`TryFrom`] trait, which offers greater flexibility and provides an equivalent `TryInto` 185 | /// implementation for free, thanks to a blanket implementation in the standard library. 186 | /// 187 | /// [`TryFrom`]: trait.TryFrom.html 188 | #[unstable(feature = "try_from", issue = "33417")] 189 | pub trait TryInto: Sized { 190 | /// The type returned in the event of a conversion error. 191 | type Err; 192 | 193 | /// Performs the conversion. 194 | fn try_into(self) -> Result; 195 | } 196 | 197 | /// Attempt to construct `Self` via a conversion. 198 | #[unstable(feature = "try_from", issue = "33417")] 199 | pub trait TryFrom: Sized { 200 | /// The type returned in the event of a conversion error. 201 | type Err; 202 | 203 | /// Performs the conversion. 204 | fn try_from(T) -> Result; 205 | } 206 | 207 | //////////////////////////////////////////////////////////////////////////////// 208 | // GENERIC IMPLS 209 | //////////////////////////////////////////////////////////////////////////////// 210 | 211 | // As lifts over & 212 | #[stable(feature = "rust1", since = "1.0.0")] 213 | impl<'a, T: ?Sized, U: ?Sized> AsRef for &'a T where T: AsRef { 214 | fn as_ref(&self) -> &U { 215 | >::as_ref(*self) 216 | } 217 | } 218 | 219 | // As lifts over &mut 220 | #[stable(feature = "rust1", since = "1.0.0")] 221 | impl<'a, T: ?Sized, U: ?Sized> AsRef for &'a mut T where T: AsRef { 222 | fn as_ref(&self) -> &U { 223 | >::as_ref(*self) 224 | } 225 | } 226 | 227 | // FIXME (#23442): replace the above impls for &/&mut with the following more general one: 228 | // // As lifts over Deref 229 | // impl AsRef for D where D::Target: AsRef { 230 | // fn as_ref(&self) -> &U { 231 | // self.deref().as_ref() 232 | // } 233 | // } 234 | 235 | // AsMut lifts over &mut 236 | #[stable(feature = "rust1", since = "1.0.0")] 237 | impl<'a, T: ?Sized, U: ?Sized> AsMut for &'a mut T where T: AsMut { 238 | fn as_mut(&mut self) -> &mut U { 239 | (*self).as_mut() 240 | } 241 | } 242 | 243 | // FIXME (#23442): replace the above impl for &mut with the following more general one: 244 | // // AsMut lifts over DerefMut 245 | // impl AsMut for D where D::Target: AsMut { 246 | // fn as_mut(&mut self) -> &mut U { 247 | // self.deref_mut().as_mut() 248 | // } 249 | // } 250 | 251 | // From implies Into 252 | #[stable(feature = "rust1", since = "1.0.0")] 253 | impl Into for T where U: From { 254 | fn into(self) -> U { 255 | U::from(self) 256 | } 257 | } 258 | 259 | // From (and thus Into) is reflexive 260 | #[stable(feature = "rust1", since = "1.0.0")] 261 | impl From for T { 262 | fn from(t: T) -> T { t } 263 | } 264 | 265 | 266 | // TryFrom implies TryInto 267 | #[unstable(feature = "try_from", issue = "33417")] 268 | impl TryInto for T where U: TryFrom { 269 | type Err = U::Err; 270 | 271 | fn try_into(self) -> Result { 272 | U::try_from(self) 273 | } 274 | } 275 | 276 | //////////////////////////////////////////////////////////////////////////////// 277 | // CONCRETE IMPLS 278 | //////////////////////////////////////////////////////////////////////////////// 279 | 280 | #[stable(feature = "rust1", since = "1.0.0")] 281 | impl AsRef<[T]> for [T] { 282 | fn as_ref(&self) -> &[T] { 283 | self 284 | } 285 | } 286 | 287 | #[stable(feature = "rust1", since = "1.0.0")] 288 | impl AsMut<[T]> for [T] { 289 | fn as_mut(&mut self) -> &mut [T] { 290 | self 291 | } 292 | } 293 | 294 | #[stable(feature = "rust1", since = "1.0.0")] 295 | impl AsRef for str { 296 | #[inline] 297 | fn as_ref(&self) -> &str { 298 | self 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /libcore/default.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The `Default` trait for types which may have meaningful default values. 12 | 13 | #![stable(feature = "rust1", since = "1.0.0")] 14 | 15 | /// A trait for giving a type a useful default value. 16 | /// 17 | /// Sometimes, you want to fall back to some kind of default value, and 18 | /// don't particularly care what it is. This comes up often with `struct`s 19 | /// that define a set of options: 20 | /// 21 | /// ``` 22 | /// # #[allow(dead_code)] 23 | /// struct SomeOptions { 24 | /// foo: i32, 25 | /// bar: f32, 26 | /// } 27 | /// ``` 28 | /// 29 | /// How can we define some default values? You can use `Default`: 30 | /// 31 | /// ``` 32 | /// # #[allow(dead_code)] 33 | /// #[derive(Default)] 34 | /// struct SomeOptions { 35 | /// foo: i32, 36 | /// bar: f32, 37 | /// } 38 | /// 39 | /// fn main() { 40 | /// let options: SomeOptions = Default::default(); 41 | /// } 42 | /// ``` 43 | /// 44 | /// Now, you get all of the default values. Rust implements `Default` for various primitives types. 45 | /// 46 | /// If you want to override a particular option, but still retain the other defaults: 47 | /// 48 | /// ``` 49 | /// # #[allow(dead_code)] 50 | /// # #[derive(Default)] 51 | /// # struct SomeOptions { 52 | /// # foo: i32, 53 | /// # bar: f32, 54 | /// # } 55 | /// fn main() { 56 | /// let options = SomeOptions { foo: 42, ..Default::default() }; 57 | /// } 58 | /// ``` 59 | /// 60 | /// ## Derivable 61 | /// 62 | /// This trait can be used with `#[derive]` if all of the type's fields implement 63 | /// `Default`. When `derive`d, it will use the default value for each field's type. 64 | /// 65 | /// ## How can I implement `Default`? 66 | /// 67 | /// Provide an implementation for the `default()` method that returns the value of 68 | /// your type that should be the default: 69 | /// 70 | /// ``` 71 | /// # #![allow(dead_code)] 72 | /// enum Kind { 73 | /// A, 74 | /// B, 75 | /// C, 76 | /// } 77 | /// 78 | /// impl Default for Kind { 79 | /// fn default() -> Kind { Kind::A } 80 | /// } 81 | /// ``` 82 | /// 83 | /// # Examples 84 | /// 85 | /// ``` 86 | /// # #[allow(dead_code)] 87 | /// #[derive(Default)] 88 | /// struct SomeOptions { 89 | /// foo: i32, 90 | /// bar: f32, 91 | /// } 92 | /// ``` 93 | #[stable(feature = "rust1", since = "1.0.0")] 94 | pub trait Default: Sized { 95 | /// Returns the "default value" for a type. 96 | /// 97 | /// Default values are often some kind of initial value, identity value, or anything else that 98 | /// may make sense as a default. 99 | /// 100 | /// # Examples 101 | /// 102 | /// Using built-in default values: 103 | /// 104 | /// ``` 105 | /// let i: i8 = Default::default(); 106 | /// let (x, y): (Option, f64) = Default::default(); 107 | /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default(); 108 | /// ``` 109 | /// 110 | /// Making your own: 111 | /// 112 | /// ``` 113 | /// # #[allow(dead_code)] 114 | /// enum Kind { 115 | /// A, 116 | /// B, 117 | /// C, 118 | /// } 119 | /// 120 | /// impl Default for Kind { 121 | /// fn default() -> Kind { Kind::A } 122 | /// } 123 | /// ``` 124 | #[stable(feature = "rust1", since = "1.0.0")] 125 | fn default() -> Self; 126 | } 127 | 128 | macro_rules! default_impl { 129 | ($t:ty, $v:expr) => { 130 | #[stable(feature = "rust1", since = "1.0.0")] 131 | impl Default for $t { 132 | #[inline] 133 | fn default() -> $t { $v } 134 | } 135 | } 136 | } 137 | 138 | default_impl! { (), () } 139 | default_impl! { bool, false } 140 | default_impl! { char, '\x00' } 141 | 142 | default_impl! { usize, 0 } 143 | default_impl! { u8, 0 } 144 | default_impl! { u16, 0 } 145 | default_impl! { u32, 0 } 146 | default_impl! { u64, 0 } 147 | 148 | default_impl! { isize, 0 } 149 | default_impl! { i8, 0 } 150 | default_impl! { i16, 0 } 151 | default_impl! { i32, 0 } 152 | default_impl! { i64, 0 } 153 | 154 | default_impl! { f32, 0.0f32 } 155 | default_impl! { f64, 0.0f64 } 156 | -------------------------------------------------------------------------------- /libcore/fmt/builders.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | use fmt::{self, FlagV1}; 12 | 13 | struct PadAdapter<'a, 'b: 'a> { 14 | fmt: &'a mut fmt::Formatter<'b>, 15 | on_newline: bool, 16 | } 17 | 18 | impl<'a, 'b: 'a> PadAdapter<'a, 'b> { 19 | fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> { 20 | PadAdapter { 21 | fmt: fmt, 22 | on_newline: false, 23 | } 24 | } 25 | } 26 | 27 | impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> { 28 | fn write_str(&mut self, mut s: &str) -> fmt::Result { 29 | while !s.is_empty() { 30 | if self.on_newline { 31 | self.fmt.write_str(" ")?; 32 | } 33 | 34 | let split = match s.find('\n') { 35 | Some(pos) => { 36 | self.on_newline = true; 37 | pos + 1 38 | } 39 | None => { 40 | self.on_newline = false; 41 | s.len() 42 | } 43 | }; 44 | self.fmt.write_str(&s[..split])?; 45 | s = &s[split..]; 46 | } 47 | 48 | Ok(()) 49 | } 50 | } 51 | 52 | /// A struct to help with `fmt::Debug` implementations. 53 | /// 54 | /// Constructed by the `Formatter::debug_struct` method. 55 | #[must_use] 56 | #[allow(missing_debug_implementations)] 57 | #[stable(feature = "debug_builders", since = "1.2.0")] 58 | pub struct DebugStruct<'a, 'b: 'a> { 59 | fmt: &'a mut fmt::Formatter<'b>, 60 | result: fmt::Result, 61 | has_fields: bool, 62 | } 63 | 64 | pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, 65 | name: &str) 66 | -> DebugStruct<'a, 'b> { 67 | let result = fmt.write_str(name); 68 | DebugStruct { 69 | fmt: fmt, 70 | result: result, 71 | has_fields: false, 72 | } 73 | } 74 | 75 | impl<'a, 'b: 'a> DebugStruct<'a, 'b> { 76 | /// Adds a new field to the generated struct output. 77 | #[stable(feature = "debug_builders", since = "1.2.0")] 78 | pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> { 79 | self.result = self.result.and_then(|_| { 80 | let prefix = if self.has_fields { 81 | "," 82 | } else { 83 | " {" 84 | }; 85 | 86 | if self.is_pretty() { 87 | let mut writer = PadAdapter::new(self.fmt); 88 | fmt::write(&mut writer, 89 | format_args!("{}\n{}: {:#?}", prefix, name, value)) 90 | } else { 91 | write!(self.fmt, "{} {}: {:?}", prefix, name, value) 92 | } 93 | }); 94 | 95 | self.has_fields = true; 96 | self 97 | } 98 | 99 | /// Finishes output and returns any error encountered. 100 | #[stable(feature = "debug_builders", since = "1.2.0")] 101 | pub fn finish(&mut self) -> fmt::Result { 102 | if self.has_fields { 103 | self.result = self.result.and_then(|_| { 104 | if self.is_pretty() { 105 | self.fmt.write_str("\n}") 106 | } else { 107 | self.fmt.write_str(" }") 108 | } 109 | }); 110 | } 111 | self.result 112 | } 113 | 114 | fn is_pretty(&self) -> bool { 115 | self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 116 | } 117 | } 118 | 119 | /// A struct to help with `fmt::Debug` implementations. 120 | /// 121 | /// Constructed by the `Formatter::debug_tuple` method. 122 | #[must_use] 123 | #[allow(missing_debug_implementations)] 124 | #[stable(feature = "debug_builders", since = "1.2.0")] 125 | pub struct DebugTuple<'a, 'b: 'a> { 126 | fmt: &'a mut fmt::Formatter<'b>, 127 | result: fmt::Result, 128 | fields: usize, 129 | empty_name: bool, 130 | } 131 | 132 | pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> { 133 | let result = fmt.write_str(name); 134 | DebugTuple { 135 | fmt: fmt, 136 | result: result, 137 | fields: 0, 138 | empty_name: name.is_empty(), 139 | } 140 | } 141 | 142 | impl<'a, 'b: 'a> DebugTuple<'a, 'b> { 143 | /// Adds a new field to the generated tuple struct output. 144 | #[stable(feature = "debug_builders", since = "1.2.0")] 145 | pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> { 146 | self.result = self.result.and_then(|_| { 147 | let (prefix, space) = if self.fields > 0 { 148 | (",", " ") 149 | } else { 150 | ("(", "") 151 | }; 152 | 153 | if self.is_pretty() { 154 | let mut writer = PadAdapter::new(self.fmt); 155 | fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value)) 156 | } else { 157 | write!(self.fmt, "{}{}{:?}", prefix, space, value) 158 | } 159 | }); 160 | 161 | self.fields += 1; 162 | self 163 | } 164 | 165 | /// Finishes output and returns any error encountered. 166 | #[stable(feature = "debug_builders", since = "1.2.0")] 167 | pub fn finish(&mut self) -> fmt::Result { 168 | if self.fields > 0 { 169 | self.result = self.result.and_then(|_| { 170 | if self.is_pretty() { 171 | self.fmt.write_str("\n")?; 172 | } 173 | if self.fields == 1 && self.empty_name { 174 | self.fmt.write_str(",")?; 175 | } 176 | self.fmt.write_str(")") 177 | }); 178 | } 179 | self.result 180 | } 181 | 182 | fn is_pretty(&self) -> bool { 183 | self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 184 | } 185 | } 186 | 187 | struct DebugInner<'a, 'b: 'a> { 188 | fmt: &'a mut fmt::Formatter<'b>, 189 | result: fmt::Result, 190 | has_fields: bool, 191 | } 192 | 193 | impl<'a, 'b: 'a> DebugInner<'a, 'b> { 194 | fn entry(&mut self, entry: &fmt::Debug) { 195 | self.result = self.result.and_then(|_| { 196 | if self.is_pretty() { 197 | let mut writer = PadAdapter::new(self.fmt); 198 | let prefix = if self.has_fields { 199 | "," 200 | } else { 201 | "" 202 | }; 203 | fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry)) 204 | } else { 205 | let prefix = if self.has_fields { 206 | ", " 207 | } else { 208 | "" 209 | }; 210 | write!(self.fmt, "{}{:?}", prefix, entry) 211 | } 212 | }); 213 | 214 | self.has_fields = true; 215 | } 216 | 217 | pub fn finish(&mut self) { 218 | let prefix = if self.is_pretty() && self.has_fields { 219 | "\n" 220 | } else { 221 | "" 222 | }; 223 | self.result = self.result.and_then(|_| self.fmt.write_str(prefix)); 224 | } 225 | 226 | fn is_pretty(&self) -> bool { 227 | self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 228 | } 229 | } 230 | 231 | /// A struct to help with `fmt::Debug` implementations. 232 | /// 233 | /// Constructed by the `Formatter::debug_set` method. 234 | #[must_use] 235 | #[allow(missing_debug_implementations)] 236 | #[stable(feature = "debug_builders", since = "1.2.0")] 237 | pub struct DebugSet<'a, 'b: 'a> { 238 | inner: DebugInner<'a, 'b>, 239 | } 240 | 241 | pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> { 242 | let result = write!(fmt, "{{"); 243 | DebugSet { 244 | inner: DebugInner { 245 | fmt: fmt, 246 | result: result, 247 | has_fields: false, 248 | }, 249 | } 250 | } 251 | 252 | impl<'a, 'b: 'a> DebugSet<'a, 'b> { 253 | /// Adds a new entry to the set output. 254 | #[stable(feature = "debug_builders", since = "1.2.0")] 255 | pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> { 256 | self.inner.entry(entry); 257 | self 258 | } 259 | 260 | /// Adds the contents of an iterator of entries to the set output. 261 | #[stable(feature = "debug_builders", since = "1.2.0")] 262 | pub fn entries(&mut self, entries: I) -> &mut DebugSet<'a, 'b> 263 | where D: fmt::Debug, 264 | I: IntoIterator 265 | { 266 | for entry in entries { 267 | self.entry(&entry); 268 | } 269 | self 270 | } 271 | 272 | /// Finishes output and returns any error encountered. 273 | #[stable(feature = "debug_builders", since = "1.2.0")] 274 | pub fn finish(&mut self) -> fmt::Result { 275 | self.inner.finish(); 276 | self.inner.result.and_then(|_| self.inner.fmt.write_str("}")) 277 | } 278 | } 279 | 280 | /// A struct to help with `fmt::Debug` implementations. 281 | /// 282 | /// Constructed by the `Formatter::debug_list` method. 283 | #[must_use] 284 | #[allow(missing_debug_implementations)] 285 | #[stable(feature = "debug_builders", since = "1.2.0")] 286 | pub struct DebugList<'a, 'b: 'a> { 287 | inner: DebugInner<'a, 'b>, 288 | } 289 | 290 | pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> { 291 | let result = write!(fmt, "["); 292 | DebugList { 293 | inner: DebugInner { 294 | fmt: fmt, 295 | result: result, 296 | has_fields: false, 297 | }, 298 | } 299 | } 300 | 301 | impl<'a, 'b: 'a> DebugList<'a, 'b> { 302 | /// Adds a new entry to the list output. 303 | #[stable(feature = "debug_builders", since = "1.2.0")] 304 | pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> { 305 | self.inner.entry(entry); 306 | self 307 | } 308 | 309 | /// Adds the contents of an iterator of entries to the list output. 310 | #[stable(feature = "debug_builders", since = "1.2.0")] 311 | pub fn entries(&mut self, entries: I) -> &mut DebugList<'a, 'b> 312 | where D: fmt::Debug, 313 | I: IntoIterator 314 | { 315 | for entry in entries { 316 | self.entry(&entry); 317 | } 318 | self 319 | } 320 | 321 | /// Finishes output and returns any error encountered. 322 | #[stable(feature = "debug_builders", since = "1.2.0")] 323 | pub fn finish(&mut self) -> fmt::Result { 324 | self.inner.finish(); 325 | self.inner.result.and_then(|_| self.inner.fmt.write_str("]")) 326 | } 327 | } 328 | 329 | /// A struct to help with `fmt::Debug` implementations. 330 | /// 331 | /// Constructed by the `Formatter::debug_map` method. 332 | #[must_use] 333 | #[allow(missing_debug_implementations)] 334 | #[stable(feature = "debug_builders", since = "1.2.0")] 335 | pub struct DebugMap<'a, 'b: 'a> { 336 | fmt: &'a mut fmt::Formatter<'b>, 337 | result: fmt::Result, 338 | has_fields: bool, 339 | } 340 | 341 | pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { 342 | let result = write!(fmt, "{{"); 343 | DebugMap { 344 | fmt: fmt, 345 | result: result, 346 | has_fields: false, 347 | } 348 | } 349 | 350 | impl<'a, 'b: 'a> DebugMap<'a, 'b> { 351 | /// Adds a new entry to the map output. 352 | #[stable(feature = "debug_builders", since = "1.2.0")] 353 | pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> { 354 | self.result = self.result.and_then(|_| { 355 | if self.is_pretty() { 356 | let mut writer = PadAdapter::new(self.fmt); 357 | let prefix = if self.has_fields { 358 | "," 359 | } else { 360 | "" 361 | }; 362 | fmt::write(&mut writer, 363 | format_args!("{}\n{:#?}: {:#?}", prefix, key, value)) 364 | } else { 365 | let prefix = if self.has_fields { 366 | ", " 367 | } else { 368 | "" 369 | }; 370 | write!(self.fmt, "{}{:?}: {:?}", prefix, key, value) 371 | } 372 | }); 373 | 374 | self.has_fields = true; 375 | self 376 | } 377 | 378 | /// Adds the contents of an iterator of entries to the map output. 379 | #[stable(feature = "debug_builders", since = "1.2.0")] 380 | pub fn entries(&mut self, entries: I) -> &mut DebugMap<'a, 'b> 381 | where K: fmt::Debug, 382 | V: fmt::Debug, 383 | I: IntoIterator 384 | { 385 | for (k, v) in entries { 386 | self.entry(&k, &v); 387 | } 388 | self 389 | } 390 | 391 | /// Finishes output and returns any error encountered. 392 | #[stable(feature = "debug_builders", since = "1.2.0")] 393 | pub fn finish(&mut self) -> fmt::Result { 394 | let prefix = if self.is_pretty() && self.has_fields { 395 | "\n" 396 | } else { 397 | "" 398 | }; 399 | self.result.and_then(|_| write!(self.fmt, "{}}}", prefix)) 400 | } 401 | 402 | fn is_pretty(&self) -> bool { 403 | self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 404 | } 405 | } 406 | -------------------------------------------------------------------------------- /libcore/fmt/num.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Integer and floating-point number formatting 12 | 13 | #![allow(deprecated)] 14 | 15 | // FIXME: #6220 Implement floating point formatting 16 | 17 | use fmt; 18 | use num::Zero; 19 | use ops::{Div, Rem, Sub}; 20 | use str; 21 | use slice; 22 | use ptr; 23 | use mem; 24 | 25 | #[doc(hidden)] 26 | trait Int: Zero + PartialEq + PartialOrd + Div + Rem + 27 | Sub + Copy { 28 | fn from_u8(u: u8) -> Self; 29 | fn to_u8(&self) -> u8; 30 | fn to_u16(&self) -> u16; 31 | fn to_u32(&self) -> u32; 32 | fn to_u64(&self) -> u64; 33 | } 34 | 35 | macro_rules! doit { 36 | ($($t:ident)*) => ($(impl Int for $t { 37 | fn from_u8(u: u8) -> $t { u as $t } 38 | fn to_u8(&self) -> u8 { *self as u8 } 39 | fn to_u16(&self) -> u16 { *self as u16 } 40 | fn to_u32(&self) -> u32 { *self as u32 } 41 | fn to_u64(&self) -> u64 { *self as u64 } 42 | })*) 43 | } 44 | doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } 45 | 46 | /// A type that represents a specific radix 47 | #[doc(hidden)] 48 | trait GenericRadix { 49 | /// The number of digits. 50 | fn base(&self) -> u8; 51 | 52 | /// A radix-specific prefix string. 53 | fn prefix(&self) -> &'static str { 54 | "" 55 | } 56 | 57 | /// Converts an integer to corresponding radix digit. 58 | fn digit(&self, x: u8) -> u8; 59 | 60 | /// Format an integer using the radix using a formatter. 61 | fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { 62 | // The radix can be as low as 2, so we need a buffer of at least 64 63 | // characters for a base 2 number. 64 | let zero = T::zero(); 65 | let is_nonnegative = x >= zero; 66 | let mut buf = [0; 64]; 67 | let mut curr = buf.len(); 68 | let base = T::from_u8(self.base()); 69 | if is_nonnegative { 70 | // Accumulate each digit of the number from the least significant 71 | // to the most significant figure. 72 | for byte in buf.iter_mut().rev() { 73 | let n = x % base; // Get the current place value. 74 | x = x / base; // Deaccumulate the number. 75 | *byte = self.digit(n.to_u8()); // Store the digit in the buffer. 76 | curr -= 1; 77 | if x == zero { 78 | // No more digits left to accumulate. 79 | break 80 | }; 81 | } 82 | } else { 83 | // Do the same as above, but accounting for two's complement. 84 | for byte in buf.iter_mut().rev() { 85 | let n = zero - (x % base); // Get the current place value. 86 | x = x / base; // Deaccumulate the number. 87 | *byte = self.digit(n.to_u8()); // Store the digit in the buffer. 88 | curr -= 1; 89 | if x == zero { 90 | // No more digits left to accumulate. 91 | break 92 | }; 93 | } 94 | } 95 | let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) }; 96 | f.pad_integral(is_nonnegative, self.prefix(), buf) 97 | } 98 | } 99 | 100 | /// A binary (base 2) radix 101 | #[derive(Clone, PartialEq)] 102 | struct Binary; 103 | 104 | /// An octal (base 8) radix 105 | #[derive(Clone, PartialEq)] 106 | struct Octal; 107 | 108 | /// A decimal (base 10) radix 109 | #[derive(Clone, PartialEq)] 110 | struct Decimal; 111 | 112 | /// A hexadecimal (base 16) radix, formatted with lower-case characters 113 | #[derive(Clone, PartialEq)] 114 | struct LowerHex; 115 | 116 | /// A hexadecimal (base 16) radix, formatted with upper-case characters 117 | #[derive(Clone, PartialEq)] 118 | struct UpperHex; 119 | 120 | macro_rules! radix { 121 | ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => { 122 | impl GenericRadix for $T { 123 | fn base(&self) -> u8 { $base } 124 | fn prefix(&self) -> &'static str { $prefix } 125 | fn digit(&self, x: u8) -> u8 { 126 | match x { 127 | $($x => $conv,)+ 128 | x => panic!("number not in the range 0..{}: {}", self.base() - 1, x), 129 | } 130 | } 131 | } 132 | } 133 | } 134 | 135 | radix! { Binary, 2, "0b", x @ 0 ... 2 => b'0' + x } 136 | radix! { Octal, 8, "0o", x @ 0 ... 7 => b'0' + x } 137 | radix! { Decimal, 10, "", x @ 0 ... 9 => b'0' + x } 138 | radix! { LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x, 139 | x @ 10 ... 15 => b'a' + (x - 10) } 140 | radix! { UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x, 141 | x @ 10 ... 15 => b'A' + (x - 10) } 142 | 143 | macro_rules! int_base { 144 | ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { 145 | #[stable(feature = "rust1", since = "1.0.0")] 146 | impl fmt::$Trait for $T { 147 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 148 | $Radix.fmt_int(*self as $U, f) 149 | } 150 | } 151 | } 152 | } 153 | 154 | macro_rules! debug { 155 | ($T:ident) => { 156 | #[stable(feature = "rust1", since = "1.0.0")] 157 | impl fmt::Debug for $T { 158 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 159 | fmt::Display::fmt(self, f) 160 | } 161 | } 162 | } 163 | } 164 | 165 | macro_rules! integer { 166 | ($Int:ident, $Uint:ident) => { 167 | int_base! { Binary for $Int as $Uint -> Binary } 168 | int_base! { Octal for $Int as $Uint -> Octal } 169 | int_base! { LowerHex for $Int as $Uint -> LowerHex } 170 | int_base! { UpperHex for $Int as $Uint -> UpperHex } 171 | debug! { $Int } 172 | 173 | int_base! { Binary for $Uint as $Uint -> Binary } 174 | int_base! { Octal for $Uint as $Uint -> Octal } 175 | int_base! { LowerHex for $Uint as $Uint -> LowerHex } 176 | int_base! { UpperHex for $Uint as $Uint -> UpperHex } 177 | debug! { $Uint } 178 | } 179 | } 180 | integer! { isize, usize } 181 | integer! { i8, u8 } 182 | integer! { i16, u16 } 183 | integer! { i32, u32 } 184 | integer! { i64, u64 } 185 | 186 | const DEC_DIGITS_LUT: &'static[u8] = 187 | b"0001020304050607080910111213141516171819\ 188 | 2021222324252627282930313233343536373839\ 189 | 4041424344454647484950515253545556575859\ 190 | 6061626364656667686970717273747576777879\ 191 | 8081828384858687888990919293949596979899"; 192 | 193 | macro_rules! impl_Display { 194 | ($($t:ident),*: $conv_fn:ident) => ($( 195 | #[stable(feature = "rust1", since = "1.0.0")] 196 | impl fmt::Display for $t { 197 | #[allow(unused_comparisons)] 198 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 199 | let is_nonnegative = *self >= 0; 200 | let mut n = if is_nonnegative { 201 | self.$conv_fn() 202 | } else { 203 | // convert the negative num to positive by summing 1 to it's 2 complement 204 | (!self.$conv_fn()).wrapping_add(1) 205 | }; 206 | let mut buf: [u8; 20] = unsafe { mem::uninitialized() }; 207 | let mut curr = buf.len() as isize; 208 | let buf_ptr = buf.as_mut_ptr(); 209 | let lut_ptr = DEC_DIGITS_LUT.as_ptr(); 210 | 211 | unsafe { 212 | // eagerly decode 4 characters at a time 213 | if <$t>::max_value() as u64 >= 10000 { 214 | while n >= 10000 { 215 | let rem = (n % 10000) as isize; 216 | n /= 10000; 217 | 218 | let d1 = (rem / 100) << 1; 219 | let d2 = (rem % 100) << 1; 220 | curr -= 4; 221 | ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); 222 | ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2); 223 | } 224 | } 225 | 226 | // if we reach here numbers are <= 9999, so at most 4 chars long 227 | let mut n = n as isize; // possibly reduce 64bit math 228 | 229 | // decode 2 more chars, if > 2 chars 230 | if n >= 100 { 231 | let d1 = (n % 100) << 1; 232 | n /= 100; 233 | curr -= 2; 234 | ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); 235 | } 236 | 237 | // decode last 1 or 2 chars 238 | if n < 10 { 239 | curr -= 1; 240 | *buf_ptr.offset(curr) = (n as u8) + 48; 241 | } else { 242 | let d1 = n << 1; 243 | curr -= 2; 244 | ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); 245 | } 246 | } 247 | 248 | let buf_slice = unsafe { 249 | str::from_utf8_unchecked( 250 | slice::from_raw_parts(buf_ptr.offset(curr), buf.len() - curr as usize)) 251 | }; 252 | f.pad_integral(is_nonnegative, "", buf_slice) 253 | } 254 | })*); 255 | } 256 | 257 | impl_Display!(i8, u8, i16, u16, i32, u32: to_u32); 258 | impl_Display!(i64, u64: to_u64); 259 | #[cfg(target_pointer_width = "16")] 260 | impl_Display!(isize, usize: to_u16); 261 | #[cfg(target_pointer_width = "32")] 262 | impl_Display!(isize, usize: to_u32); 263 | #[cfg(target_pointer_width = "64")] 264 | impl_Display!(isize, usize: to_u64); 265 | -------------------------------------------------------------------------------- /libcore/fmt/rt/v1.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! This is an internal module used by the ifmt! runtime. These structures are 12 | //! emitted to static arrays to precompile format strings ahead of time. 13 | //! 14 | //! These definitions are similar to their `ct` equivalents, but differ in that 15 | //! these can be statically allocated and are slightly optimized for the runtime 16 | #![allow(missing_debug_implementations)] 17 | 18 | #[derive(Copy, Clone)] 19 | pub struct Argument { 20 | pub position: Position, 21 | pub format: FormatSpec, 22 | } 23 | 24 | #[derive(Copy, Clone)] 25 | pub struct FormatSpec { 26 | pub fill: char, 27 | pub align: Alignment, 28 | pub flags: u32, 29 | pub precision: Count, 30 | pub width: Count, 31 | } 32 | 33 | /// Possible alignments that can be requested as part of a formatting directive. 34 | #[derive(Copy, Clone, PartialEq)] 35 | pub enum Alignment { 36 | /// Indication that contents should be left-aligned. 37 | Left, 38 | /// Indication that contents should be right-aligned. 39 | Right, 40 | /// Indication that contents should be center-aligned. 41 | Center, 42 | /// No alignment was requested. 43 | Unknown, 44 | } 45 | 46 | #[derive(Copy, Clone)] 47 | pub enum Count { 48 | Is(usize), 49 | Param(usize), 50 | NextParam, 51 | Implied, 52 | } 53 | 54 | #[derive(Copy, Clone)] 55 | pub enum Position { 56 | Next, 57 | At(usize), 58 | } 59 | -------------------------------------------------------------------------------- /libcore/hash/sip.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! An implementation of SipHash. 12 | 13 | use marker::PhantomData; 14 | use ptr; 15 | 16 | /// An implementation of SipHash 1-3. 17 | /// 18 | /// See: https://131002.net/siphash/ 19 | #[unstable(feature = "sip_hash_13", issue = "34767")] 20 | #[derive(Debug, Clone, Default)] 21 | pub struct SipHasher13 { 22 | hasher: Hasher, 23 | } 24 | 25 | /// An implementation of SipHash 2-4. 26 | /// 27 | /// See: https://131002.net/siphash/ 28 | #[unstable(feature = "sip_hash_13", issue = "34767")] 29 | #[derive(Debug, Clone, Default)] 30 | pub struct SipHasher24 { 31 | hasher: Hasher, 32 | } 33 | 34 | /// An implementation of SipHash 2-4. 35 | /// 36 | /// See: https://131002.net/siphash/ 37 | /// 38 | /// This is currently the default hashing function used by standard library 39 | /// (eg. `collections::HashMap` uses it by default). 40 | /// 41 | /// SipHash is a general-purpose hashing function: it runs at a good 42 | /// speed (competitive with Spooky and City) and permits strong _keyed_ 43 | /// hashing. This lets you key your hashtables from a strong RNG, such as 44 | /// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html). 45 | /// 46 | /// Although the SipHash algorithm is considered to be generally strong, 47 | /// it is not intended for cryptographic purposes. As such, all 48 | /// cryptographic uses of this implementation are _strongly discouraged_. 49 | #[stable(feature = "rust1", since = "1.0.0")] 50 | #[derive(Debug, Clone, Default)] 51 | pub struct SipHasher(SipHasher24); 52 | 53 | #[derive(Debug)] 54 | struct Hasher { 55 | k0: u64, 56 | k1: u64, 57 | length: usize, // how many bytes we've processed 58 | state: State, // hash State 59 | tail: u64, // unprocessed bytes le 60 | ntail: usize, // how many bytes in tail are valid 61 | _marker: PhantomData, 62 | } 63 | 64 | #[derive(Debug, Clone, Copy)] 65 | struct State { 66 | // v0, v2 and v1, v3 show up in pairs in the algorithm, 67 | // and simd implementations of SipHash will use vectors 68 | // of v02 and v13. By placing them in this order in the struct, 69 | // the compiler can pick up on just a few simd optimizations by itself. 70 | v0: u64, 71 | v2: u64, 72 | v1: u64, 73 | v3: u64, 74 | } 75 | 76 | // sadly, these macro definitions can't appear later, 77 | // because they're needed in the following defs; 78 | // this design could be improved. 79 | 80 | macro_rules! u8to64_le { 81 | ($buf:expr, $i:expr) => 82 | ($buf[0+$i] as u64 | 83 | ($buf[1+$i] as u64) << 8 | 84 | ($buf[2+$i] as u64) << 16 | 85 | ($buf[3+$i] as u64) << 24 | 86 | ($buf[4+$i] as u64) << 32 | 87 | ($buf[5+$i] as u64) << 40 | 88 | ($buf[6+$i] as u64) << 48 | 89 | ($buf[7+$i] as u64) << 56); 90 | ($buf:expr, $i:expr, $len:expr) => 91 | ({ 92 | let mut t = 0; 93 | let mut out = 0; 94 | while t < $len { 95 | out |= ($buf[t+$i] as u64) << t*8; 96 | t += 1; 97 | } 98 | out 99 | }); 100 | } 101 | 102 | /// Load a full u64 word from a byte stream, in LE order. Use 103 | /// `copy_nonoverlapping` to let the compiler generate the most efficient way 104 | /// to load u64 from a possibly unaligned address. 105 | /// 106 | /// Unsafe because: unchecked indexing at i..i+8 107 | #[inline] 108 | unsafe fn load_u64_le(buf: &[u8], i: usize) -> u64 { 109 | debug_assert!(i + 8 <= buf.len()); 110 | let mut data = 0u64; 111 | ptr::copy_nonoverlapping(buf.get_unchecked(i), &mut data as *mut _ as *mut u8, 8); 112 | data.to_le() 113 | } 114 | 115 | macro_rules! rotl { 116 | ($x:expr, $b:expr) => 117 | (($x << $b) | ($x >> (64_i32.wrapping_sub($b)))) 118 | } 119 | 120 | macro_rules! compress { 121 | ($state:expr) => ({ 122 | compress!($state.v0, $state.v1, $state.v2, $state.v3) 123 | }); 124 | ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => 125 | ({ 126 | $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0; 127 | $v0 = rotl!($v0, 32); 128 | $v2 = $v2.wrapping_add($v3); $v3 = rotl!($v3, 16); $v3 ^= $v2; 129 | $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0; 130 | $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2; 131 | $v2 = rotl!($v2, 32); 132 | }); 133 | } 134 | 135 | impl SipHasher { 136 | /// Creates a new `SipHasher` with the two initial keys set to 0. 137 | #[inline] 138 | #[stable(feature = "rust1", since = "1.0.0")] 139 | pub fn new() -> SipHasher { 140 | SipHasher::new_with_keys(0, 0) 141 | } 142 | 143 | /// Creates a `SipHasher` that is keyed off the provided keys. 144 | #[inline] 145 | #[stable(feature = "rust1", since = "1.0.0")] 146 | pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher { 147 | SipHasher(SipHasher24::new_with_keys(key0, key1)) 148 | } 149 | } 150 | 151 | 152 | impl SipHasher13 { 153 | /// Creates a new `SipHasher13` with the two initial keys set to 0. 154 | #[inline] 155 | #[unstable(feature = "sip_hash_13", issue = "34767")] 156 | pub fn new() -> SipHasher13 { 157 | SipHasher13::new_with_keys(0, 0) 158 | } 159 | 160 | /// Creates a `SipHasher13` that is keyed off the provided keys. 161 | #[inline] 162 | #[unstable(feature = "sip_hash_13", issue = "34767")] 163 | pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 { 164 | SipHasher13 { 165 | hasher: Hasher::new_with_keys(key0, key1) 166 | } 167 | } 168 | } 169 | 170 | impl SipHasher24 { 171 | /// Creates a new `SipHasher24` with the two initial keys set to 0. 172 | #[inline] 173 | #[unstable(feature = "sip_hash_13", issue = "34767")] 174 | pub fn new() -> SipHasher24 { 175 | SipHasher24::new_with_keys(0, 0) 176 | } 177 | 178 | /// Creates a `SipHasher24` that is keyed off the provided keys. 179 | #[inline] 180 | #[unstable(feature = "sip_hash_13", issue = "34767")] 181 | pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 { 182 | SipHasher24 { 183 | hasher: Hasher::new_with_keys(key0, key1) 184 | } 185 | } 186 | } 187 | 188 | impl Hasher { 189 | #[inline] 190 | fn new_with_keys(key0: u64, key1: u64) -> Hasher { 191 | let mut state = Hasher { 192 | k0: key0, 193 | k1: key1, 194 | length: 0, 195 | state: State { 196 | v0: 0, 197 | v1: 0, 198 | v2: 0, 199 | v3: 0, 200 | }, 201 | tail: 0, 202 | ntail: 0, 203 | _marker: PhantomData, 204 | }; 205 | state.reset(); 206 | state 207 | } 208 | 209 | #[inline] 210 | fn reset(&mut self) { 211 | self.length = 0; 212 | self.state.v0 = self.k0 ^ 0x736f6d6570736575; 213 | self.state.v1 = self.k1 ^ 0x646f72616e646f6d; 214 | self.state.v2 = self.k0 ^ 0x6c7967656e657261; 215 | self.state.v3 = self.k1 ^ 0x7465646279746573; 216 | self.ntail = 0; 217 | } 218 | } 219 | 220 | #[stable(feature = "rust1", since = "1.0.0")] 221 | impl super::Hasher for SipHasher { 222 | #[inline] 223 | fn write(&mut self, msg: &[u8]) { 224 | self.0.write(msg) 225 | } 226 | 227 | #[inline] 228 | fn finish(&self) -> u64 { 229 | self.0.finish() 230 | } 231 | } 232 | 233 | #[unstable(feature = "sip_hash_13", issue = "34767")] 234 | impl super::Hasher for SipHasher13 { 235 | #[inline] 236 | fn write(&mut self, msg: &[u8]) { 237 | self.hasher.write(msg) 238 | } 239 | 240 | #[inline] 241 | fn finish(&self) -> u64 { 242 | self.hasher.finish() 243 | } 244 | } 245 | 246 | #[unstable(feature = "sip_hash_13", issue = "34767")] 247 | impl super::Hasher for SipHasher24 { 248 | #[inline] 249 | fn write(&mut self, msg: &[u8]) { 250 | self.hasher.write(msg) 251 | } 252 | 253 | #[inline] 254 | fn finish(&self) -> u64 { 255 | self.hasher.finish() 256 | } 257 | } 258 | 259 | impl super::Hasher for Hasher { 260 | #[inline] 261 | fn write(&mut self, msg: &[u8]) { 262 | let length = msg.len(); 263 | self.length += length; 264 | 265 | let mut needed = 0; 266 | 267 | if self.ntail != 0 { 268 | needed = 8 - self.ntail; 269 | if length < needed { 270 | self.tail |= u8to64_le!(msg, 0, length) << 8 * self.ntail; 271 | self.ntail += length; 272 | return 273 | } 274 | 275 | let m = self.tail | u8to64_le!(msg, 0, needed) << 8 * self.ntail; 276 | 277 | self.state.v3 ^= m; 278 | S::c_rounds(&mut self.state); 279 | self.state.v0 ^= m; 280 | 281 | self.ntail = 0; 282 | } 283 | 284 | // Buffered tail is now flushed, process new input. 285 | let len = length - needed; 286 | let left = len & 0x7; 287 | 288 | let mut i = needed; 289 | while i < len - left { 290 | let mi = unsafe { load_u64_le(msg, i) }; 291 | 292 | self.state.v3 ^= mi; 293 | S::c_rounds(&mut self.state); 294 | self.state.v0 ^= mi; 295 | 296 | i += 8; 297 | } 298 | 299 | self.tail = u8to64_le!(msg, i, left); 300 | self.ntail = left; 301 | } 302 | 303 | #[inline] 304 | fn finish(&self) -> u64 { 305 | let mut state = self.state; 306 | 307 | let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail; 308 | 309 | state.v3 ^= b; 310 | S::c_rounds(&mut state); 311 | state.v0 ^= b; 312 | 313 | state.v2 ^= 0xff; 314 | S::d_rounds(&mut state); 315 | 316 | state.v0 ^ state.v1 ^ state.v2 ^ state.v3 317 | } 318 | } 319 | 320 | impl Clone for Hasher { 321 | #[inline] 322 | fn clone(&self) -> Hasher { 323 | Hasher { 324 | k0: self.k0, 325 | k1: self.k1, 326 | length: self.length, 327 | state: self.state, 328 | tail: self.tail, 329 | ntail: self.ntail, 330 | _marker: self._marker, 331 | } 332 | } 333 | } 334 | 335 | impl Default for Hasher { 336 | #[inline] 337 | fn default() -> Hasher { 338 | Hasher::new_with_keys(0, 0) 339 | } 340 | } 341 | 342 | #[doc(hidden)] 343 | trait Sip { 344 | fn c_rounds(&mut State); 345 | fn d_rounds(&mut State); 346 | } 347 | 348 | #[derive(Debug, Clone, Default)] 349 | struct Sip13Rounds; 350 | 351 | impl Sip for Sip13Rounds { 352 | #[inline] 353 | fn c_rounds(state: &mut State) { 354 | compress!(state); 355 | } 356 | 357 | #[inline] 358 | fn d_rounds(state: &mut State) { 359 | compress!(state); 360 | compress!(state); 361 | compress!(state); 362 | } 363 | } 364 | 365 | #[derive(Debug, Clone, Default)] 366 | struct Sip24Rounds; 367 | 368 | impl Sip for Sip24Rounds { 369 | #[inline] 370 | fn c_rounds(state: &mut State) { 371 | compress!(state); 372 | compress!(state); 373 | } 374 | 375 | #[inline] 376 | fn d_rounds(state: &mut State) { 377 | compress!(state); 378 | compress!(state); 379 | compress!(state); 380 | compress!(state); 381 | } 382 | } 383 | -------------------------------------------------------------------------------- /libcore/iter/sources.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | use fmt; 12 | use marker; 13 | use usize; 14 | 15 | use super::FusedIterator; 16 | 17 | /// An iterator that repeats an element endlessly. 18 | /// 19 | /// This `struct` is created by the [`repeat()`] function. See its documentation for more. 20 | /// 21 | /// [`repeat()`]: fn.repeat.html 22 | #[derive(Clone, Debug)] 23 | #[stable(feature = "rust1", since = "1.0.0")] 24 | pub struct Repeat { 25 | element: A 26 | } 27 | 28 | #[stable(feature = "rust1", since = "1.0.0")] 29 | impl Iterator for Repeat { 30 | type Item = A; 31 | 32 | #[inline] 33 | fn next(&mut self) -> Option { Some(self.element.clone()) } 34 | #[inline] 35 | fn size_hint(&self) -> (usize, Option) { (usize::MAX, None) } 36 | } 37 | 38 | #[stable(feature = "rust1", since = "1.0.0")] 39 | impl DoubleEndedIterator for Repeat { 40 | #[inline] 41 | fn next_back(&mut self) -> Option { Some(self.element.clone()) } 42 | } 43 | 44 | #[unstable(feature = "fused", issue = "35602")] 45 | impl FusedIterator for Repeat {} 46 | 47 | /// Creates a new iterator that endlessly repeats a single element. 48 | /// 49 | /// The `repeat()` function repeats a single value over and over and over and 50 | /// over and over and 🔁. 51 | /// 52 | /// Infinite iterators like `repeat()` are often used with adapters like 53 | /// [`take()`], in order to make them finite. 54 | /// 55 | /// [`take()`]: trait.Iterator.html#method.take 56 | /// 57 | /// # Examples 58 | /// 59 | /// Basic usage: 60 | /// 61 | /// ``` 62 | /// use std::iter; 63 | /// 64 | /// // the number four 4ever: 65 | /// let mut fours = iter::repeat(4); 66 | /// 67 | /// assert_eq!(Some(4), fours.next()); 68 | /// assert_eq!(Some(4), fours.next()); 69 | /// assert_eq!(Some(4), fours.next()); 70 | /// assert_eq!(Some(4), fours.next()); 71 | /// assert_eq!(Some(4), fours.next()); 72 | /// 73 | /// // yup, still four 74 | /// assert_eq!(Some(4), fours.next()); 75 | /// ``` 76 | /// 77 | /// Going finite with [`take()`]: 78 | /// 79 | /// ``` 80 | /// use std::iter; 81 | /// 82 | /// // that last example was too many fours. Let's only have four fours. 83 | /// let mut four_fours = iter::repeat(4).take(4); 84 | /// 85 | /// assert_eq!(Some(4), four_fours.next()); 86 | /// assert_eq!(Some(4), four_fours.next()); 87 | /// assert_eq!(Some(4), four_fours.next()); 88 | /// assert_eq!(Some(4), four_fours.next()); 89 | /// 90 | /// // ... and now we're done 91 | /// assert_eq!(None, four_fours.next()); 92 | /// ``` 93 | #[inline] 94 | #[stable(feature = "rust1", since = "1.0.0")] 95 | pub fn repeat(elt: T) -> Repeat { 96 | Repeat{element: elt} 97 | } 98 | 99 | /// An iterator that yields nothing. 100 | /// 101 | /// This `struct` is created by the [`empty()`] function. See its documentation for more. 102 | /// 103 | /// [`empty()`]: fn.empty.html 104 | #[stable(feature = "iter_empty", since = "1.2.0")] 105 | pub struct Empty(marker::PhantomData); 106 | 107 | #[stable(feature = "core_impl_debug", since = "1.9.0")] 108 | impl fmt::Debug for Empty { 109 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 110 | f.pad("Empty") 111 | } 112 | } 113 | 114 | #[stable(feature = "iter_empty", since = "1.2.0")] 115 | impl Iterator for Empty { 116 | type Item = T; 117 | 118 | fn next(&mut self) -> Option { 119 | None 120 | } 121 | 122 | fn size_hint(&self) -> (usize, Option){ 123 | (0, Some(0)) 124 | } 125 | } 126 | 127 | #[stable(feature = "iter_empty", since = "1.2.0")] 128 | impl DoubleEndedIterator for Empty { 129 | fn next_back(&mut self) -> Option { 130 | None 131 | } 132 | } 133 | 134 | #[stable(feature = "iter_empty", since = "1.2.0")] 135 | impl ExactSizeIterator for Empty { 136 | fn len(&self) -> usize { 137 | 0 138 | } 139 | } 140 | 141 | #[unstable(feature = "fused", issue = "35602")] 142 | impl FusedIterator for Empty {} 143 | 144 | // not #[derive] because that adds a Clone bound on T, 145 | // which isn't necessary. 146 | #[stable(feature = "iter_empty", since = "1.2.0")] 147 | impl Clone for Empty { 148 | fn clone(&self) -> Empty { 149 | Empty(marker::PhantomData) 150 | } 151 | } 152 | 153 | // not #[derive] because that adds a Default bound on T, 154 | // which isn't necessary. 155 | #[stable(feature = "iter_empty", since = "1.2.0")] 156 | impl Default for Empty { 157 | fn default() -> Empty { 158 | Empty(marker::PhantomData) 159 | } 160 | } 161 | 162 | /// Creates an iterator that yields nothing. 163 | /// 164 | /// # Examples 165 | /// 166 | /// Basic usage: 167 | /// 168 | /// ``` 169 | /// use std::iter; 170 | /// 171 | /// // this could have been an iterator over i32, but alas, it's just not. 172 | /// let mut nope = iter::empty::(); 173 | /// 174 | /// assert_eq!(None, nope.next()); 175 | /// ``` 176 | #[stable(feature = "iter_empty", since = "1.2.0")] 177 | pub fn empty() -> Empty { 178 | Empty(marker::PhantomData) 179 | } 180 | 181 | /// An iterator that yields an element exactly once. 182 | /// 183 | /// This `struct` is created by the [`once()`] function. See its documentation for more. 184 | /// 185 | /// [`once()`]: fn.once.html 186 | #[derive(Clone, Debug)] 187 | #[stable(feature = "iter_once", since = "1.2.0")] 188 | pub struct Once { 189 | inner: ::option::IntoIter 190 | } 191 | 192 | #[stable(feature = "iter_once", since = "1.2.0")] 193 | impl Iterator for Once { 194 | type Item = T; 195 | 196 | fn next(&mut self) -> Option { 197 | self.inner.next() 198 | } 199 | 200 | fn size_hint(&self) -> (usize, Option) { 201 | self.inner.size_hint() 202 | } 203 | } 204 | 205 | #[stable(feature = "iter_once", since = "1.2.0")] 206 | impl DoubleEndedIterator for Once { 207 | fn next_back(&mut self) -> Option { 208 | self.inner.next_back() 209 | } 210 | } 211 | 212 | #[stable(feature = "iter_once", since = "1.2.0")] 213 | impl ExactSizeIterator for Once { 214 | fn len(&self) -> usize { 215 | self.inner.len() 216 | } 217 | } 218 | 219 | #[unstable(feature = "fused", issue = "35602")] 220 | impl FusedIterator for Once {} 221 | 222 | /// Creates an iterator that yields an element exactly once. 223 | /// 224 | /// This is commonly used to adapt a single value into a [`chain()`] of other 225 | /// kinds of iteration. Maybe you have an iterator that covers almost 226 | /// everything, but you need an extra special case. Maybe you have a function 227 | /// which works on iterators, but you only need to process one value. 228 | /// 229 | /// [`chain()`]: trait.Iterator.html#method.chain 230 | /// 231 | /// # Examples 232 | /// 233 | /// Basic usage: 234 | /// 235 | /// ``` 236 | /// use std::iter; 237 | /// 238 | /// // one is the loneliest number 239 | /// let mut one = iter::once(1); 240 | /// 241 | /// assert_eq!(Some(1), one.next()); 242 | /// 243 | /// // just one, that's all we get 244 | /// assert_eq!(None, one.next()); 245 | /// ``` 246 | /// 247 | /// Chaining together with another iterator. Let's say that we want to iterate 248 | /// over each file of the `.foo` directory, but also a configuration file, 249 | /// `.foorc`: 250 | /// 251 | /// ```no_run 252 | /// use std::iter; 253 | /// use std::fs; 254 | /// use std::path::PathBuf; 255 | /// 256 | /// let dirs = fs::read_dir(".foo").unwrap(); 257 | /// 258 | /// // we need to convert from an iterator of DirEntry-s to an iterator of 259 | /// // PathBufs, so we use map 260 | /// let dirs = dirs.map(|file| file.unwrap().path()); 261 | /// 262 | /// // now, our iterator just for our config file 263 | /// let config = iter::once(PathBuf::from(".foorc")); 264 | /// 265 | /// // chain the two iterators together into one big iterator 266 | /// let files = dirs.chain(config); 267 | /// 268 | /// // this will give us all of the files in .foo as well as .foorc 269 | /// for f in files { 270 | /// println!("{:?}", f); 271 | /// } 272 | /// ``` 273 | #[stable(feature = "iter_once", since = "1.2.0")] 274 | pub fn once(value: T) -> Once { 275 | Once { inner: Some(value).into_iter() } 276 | } 277 | -------------------------------------------------------------------------------- /libcore/iter_private.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | 12 | /// An iterator whose items are random accessible efficiently 13 | /// 14 | /// # Safety 15 | /// 16 | /// The iterator's .len() and size_hint() must be exact. 17 | /// 18 | /// .get_unchecked() must return distinct mutable references for distinct 19 | /// indices (if applicable), and must return a valid reference if index is in 20 | /// 0..self.len(). 21 | #[doc(hidden)] 22 | pub unsafe trait TrustedRandomAccess : ExactSizeIterator { 23 | unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libcore/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! # The Rust Core Library 12 | //! 13 | //! The Rust Core Library is the dependency-free[^free] foundation of [The 14 | //! Rust Standard Library](../std/index.html). It is the portable glue 15 | //! between the language and its libraries, defining the intrinsic and 16 | //! primitive building blocks of all Rust code. It links to no 17 | //! upstream libraries, no system libraries, and no libc. 18 | //! 19 | //! [^free]: Strictly speaking, there are some symbols which are needed but 20 | //! they aren't always necessary. 21 | //! 22 | //! The core library is *minimal*: it isn't even aware of heap allocation, 23 | //! nor does it provide concurrency or I/O. These things require 24 | //! platform integration, and this library is platform-agnostic. 25 | //! 26 | //! # How to use the core library 27 | //! 28 | //! Please note that all of these details are currently not considered stable. 29 | //! 30 | // FIXME: Fill me in with more detail when the interface settles 31 | //! This library is built on the assumption of a few existing symbols: 32 | //! 33 | //! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are 34 | //! often generated by LLVM. Additionally, this library can make explicit 35 | //! calls to these functions. Their signatures are the same as found in C. 36 | //! These functions are often provided by the system libc, but can also be 37 | //! provided by the [rlibc crate](https://crates.io/crates/rlibc). 38 | //! 39 | //! * `rust_begin_panic` - This function takes three arguments, a 40 | //! `fmt::Arguments`, a `&'static str`, and a `u32`. These three arguments 41 | //! dictate the panic message, the file at which panic was invoked, and the 42 | //! line. It is up to consumers of this core library to define this panic 43 | //! function; it is only required to never return. This requires a `lang` 44 | //! attribute named `panic_fmt`. 45 | //! 46 | //! * `rust_eh_personality` - is used by the failure mechanisms of the 47 | //! compiler. This is often mapped to GCC's personality function, but crates 48 | //! which do not trigger a panic can be assured that this function is never 49 | //! called. The `lang` attribute is called `eh_personality`. 50 | 51 | // Since libcore defines many fundamental lang items, all tests live in a 52 | // separate crate, libcoretest, to avoid bizarre issues. 53 | 54 | #![crate_name = "core"] 55 | #![stable(feature = "core", since = "1.6.0")] 56 | #![crate_type = "rlib"] 57 | #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", 58 | html_favicon_url = "https://doc.rust-lang.org/favicon.ico", 59 | html_root_url = "https://doc.rust-lang.org/nightly/", 60 | html_playground_url = "https://play.rust-lang.org/", 61 | issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", 62 | test(no_crate_inject, attr(deny(warnings))), 63 | test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] 64 | 65 | #![no_core] 66 | #![deny(missing_docs)] 67 | #![deny(missing_debug_implementations)] 68 | #![cfg_attr(not(stage0), deny(warnings))] 69 | 70 | #![feature(allow_internal_unstable)] 71 | #![feature(asm)] 72 | #![feature(associated_type_defaults)] 73 | #![feature(cfg_target_feature)] 74 | #![feature(concat_idents)] 75 | #![feature(const_fn)] 76 | #![feature(cfg_target_has_atomic)] 77 | #![feature(custom_attribute)] 78 | #![feature(fundamental)] 79 | #![feature(inclusive_range_syntax)] 80 | #![feature(intrinsics)] 81 | #![feature(lang_items)] 82 | #![feature(no_core)] 83 | #![feature(on_unimplemented)] 84 | #![feature(optin_builtin_traits)] 85 | #![feature(reflect)] 86 | #![feature(unwind_attributes)] 87 | #![feature(repr_simd, platform_intrinsics)] 88 | #![feature(rustc_attrs)] 89 | #![feature(specialization)] 90 | #![feature(staged_api)] 91 | #![feature(unboxed_closures)] 92 | #![feature(question_mark)] 93 | #![feature(never_type)] 94 | #![feature(prelude_import)] 95 | 96 | #[prelude_import] 97 | #[allow(unused)] 98 | use prelude::v1::*; 99 | 100 | #[macro_use] 101 | mod macros; 102 | 103 | #[path = "num/float_macros.rs"] 104 | #[macro_use] 105 | mod float_macros; 106 | 107 | #[path = "num/int_macros.rs"] 108 | #[macro_use] 109 | mod int_macros; 110 | 111 | #[path = "num/uint_macros.rs"] 112 | #[macro_use] 113 | mod uint_macros; 114 | 115 | #[path = "num/isize.rs"] pub mod isize; 116 | #[path = "num/i8.rs"] pub mod i8; 117 | #[path = "num/i16.rs"] pub mod i16; 118 | #[path = "num/i32.rs"] pub mod i32; 119 | #[path = "num/i64.rs"] pub mod i64; 120 | 121 | #[path = "num/usize.rs"] pub mod usize; 122 | #[path = "num/u8.rs"] pub mod u8; 123 | #[path = "num/u16.rs"] pub mod u16; 124 | #[path = "num/u32.rs"] pub mod u32; 125 | #[path = "num/u64.rs"] pub mod u64; 126 | 127 | #[path = "num/f32.rs"] pub mod f32; 128 | #[path = "num/f64.rs"] pub mod f64; 129 | 130 | #[macro_use] 131 | pub mod num; 132 | 133 | /* The libcore prelude, not as all-encompassing as the libstd prelude */ 134 | 135 | pub mod prelude; 136 | 137 | /* Core modules for ownership management */ 138 | 139 | pub mod intrinsics; 140 | pub mod mem; 141 | pub mod nonzero; 142 | pub mod ptr; 143 | 144 | /* Core language traits */ 145 | 146 | pub mod marker; 147 | pub mod ops; 148 | pub mod cmp; 149 | pub mod clone; 150 | pub mod default; 151 | pub mod convert; 152 | pub mod borrow; 153 | 154 | /* Core types and methods on primitives */ 155 | 156 | pub mod any; 157 | pub mod array; 158 | pub mod sync; 159 | pub mod cell; 160 | pub mod char; 161 | pub mod panicking; 162 | pub mod iter; 163 | pub mod option; 164 | pub mod raw; 165 | pub mod result; 166 | 167 | pub mod slice; 168 | pub mod str; 169 | pub mod hash; 170 | pub mod fmt; 171 | 172 | // note: does not need to be public 173 | mod char_private; 174 | mod iter_private; 175 | mod tuple; 176 | -------------------------------------------------------------------------------- /libcore/nonzero.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Exposes the NonZero lang item which provides optimization hints. 12 | #![unstable(feature = "nonzero", 13 | reason = "needs an RFC to flesh out the design", 14 | issue = "27730")] 15 | 16 | use ops::{CoerceUnsized, Deref}; 17 | 18 | /// Unsafe trait to indicate what types are usable with the NonZero struct 19 | pub unsafe trait Zeroable {} 20 | 21 | unsafe impl Zeroable for *const T {} 22 | unsafe impl Zeroable for *mut T {} 23 | unsafe impl Zeroable for isize {} 24 | unsafe impl Zeroable for usize {} 25 | unsafe impl Zeroable for i8 {} 26 | unsafe impl Zeroable for u8 {} 27 | unsafe impl Zeroable for i16 {} 28 | unsafe impl Zeroable for u16 {} 29 | unsafe impl Zeroable for i32 {} 30 | unsafe impl Zeroable for u32 {} 31 | unsafe impl Zeroable for i64 {} 32 | unsafe impl Zeroable for u64 {} 33 | 34 | /// A wrapper type for raw pointers and integers that will never be 35 | /// NULL or 0 that might allow certain optimizations. 36 | #[lang = "non_zero"] 37 | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] 38 | pub struct NonZero(T); 39 | 40 | impl NonZero { 41 | /// Creates an instance of NonZero with the provided value. 42 | /// You must indeed ensure that the value is actually "non-zero". 43 | #[inline(always)] 44 | pub const unsafe fn new(inner: T) -> NonZero { 45 | NonZero(inner) 46 | } 47 | } 48 | 49 | impl Deref for NonZero { 50 | type Target = T; 51 | 52 | #[inline] 53 | fn deref(&self) -> &T { 54 | let NonZero(ref inner) = *self; 55 | inner 56 | } 57 | } 58 | 59 | impl, U: Zeroable> CoerceUnsized> for NonZero {} 60 | -------------------------------------------------------------------------------- /libcore/num/dec2flt/num.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Utility functions for bignums that don't make too much sense to turn into methods. 12 | 13 | // FIXME This module's name is a bit unfortunate, since other modules also import `core::num`. 14 | 15 | use cmp::Ordering::{self, Less, Equal, Greater}; 16 | 17 | pub use num::bignum::Big32x40 as Big; 18 | 19 | /// Test whether truncating all bits less significant than `ones_place` introduces 20 | /// a relative error less, equal, or greater than 0.5 ULP. 21 | pub fn compare_with_half_ulp(f: &Big, ones_place: usize) -> Ordering { 22 | if ones_place == 0 { 23 | return Less; 24 | } 25 | let half_bit = ones_place - 1; 26 | if f.get_bit(half_bit) == 0 { 27 | // < 0.5 ULP 28 | return Less; 29 | } 30 | // If all remaining bits are zero, it's = 0.5 ULP, otherwise > 0.5 31 | // If there are no more bits (half_bit == 0), the below also correctly returns Equal. 32 | for i in 0..half_bit { 33 | if f.get_bit(i) == 1 { 34 | return Greater; 35 | } 36 | } 37 | Equal 38 | } 39 | 40 | /// Convert an ASCII string containing only decimal digits to a `u64`. 41 | /// 42 | /// Does not perform checks for overflow or invalid characters, so if the caller is not careful, 43 | /// the result is bogus and can panic (though it won't be `unsafe`). Additionally, empty strings 44 | /// are treated as zero. This function exists because 45 | /// 46 | /// 1. using `FromStr` on `&[u8]` requires `from_utf8_unchecked`, which is bad, and 47 | /// 2. piecing together the results of `integral.parse()` and `fractional.parse()` is 48 | /// more complicated than this entire function. 49 | pub fn from_str_unchecked<'a, T>(bytes: T) -> u64 where T : IntoIterator { 50 | let mut result = 0; 51 | for &c in bytes { 52 | result = result * 10 + (c - b'0') as u64; 53 | } 54 | result 55 | } 56 | 57 | /// Convert a string of ASCII digits into a bignum. 58 | /// 59 | /// Like `from_str_unchecked`, this function relies on the parser to weed out non-digits. 60 | pub fn digits_to_big(integral: &[u8], fractional: &[u8]) -> Big { 61 | let mut f = Big::from_small(0); 62 | for &c in integral.iter().chain(fractional) { 63 | let n = (c - b'0') as u32; 64 | f.mul_small(10); 65 | f.add_small(n); 66 | } 67 | f 68 | } 69 | 70 | /// Unwraps a bignum into a 64 bit integer. Panics if the number is too large. 71 | pub fn to_u64(x: &Big) -> u64 { 72 | assert!(x.bit_length() < 64); 73 | let d = x.digits(); 74 | if d.len() < 2 { 75 | d[0] as u64 76 | } else { 77 | (d[1] as u64) << 32 | d[0] as u64 78 | } 79 | } 80 | 81 | 82 | /// Extract a range of bits. 83 | 84 | /// Index 0 is the least significant bit and the range is half-open as usual. 85 | /// Panics if asked to extract more bits than fit into the return type. 86 | pub fn get_bits(x: &Big, start: usize, end: usize) -> u64 { 87 | assert!(end - start <= 64); 88 | let mut result: u64 = 0; 89 | for i in (start..end).rev() { 90 | result = result << 1 | x.get_bit(i) as u64; 91 | } 92 | result 93 | } 94 | -------------------------------------------------------------------------------- /libcore/num/dec2flt/parse.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Validating and decomposing a decimal string of the form: 12 | //! 13 | //! `(digits | digits? '.'? digits?) (('e' | 'E') ('+' | '-')? digits)?` 14 | //! 15 | //! In other words, standard floating-point syntax, with two exceptions: No sign, and no 16 | //! handling of "inf" and "NaN". These are handled by the driver function (super::dec2flt). 17 | //! 18 | //! Although recognizing valid inputs is relatively easy, this module also has to reject the 19 | //! countless invalid variations, never panic, and perform numerous checks that the other 20 | //! modules rely on to not panic (or overflow) in turn. 21 | //! To make matters worse, all that happens in a single pass over the input. 22 | //! So, be careful when modifying anything, and double-check with the other modules. 23 | use super::num; 24 | use self::ParseResult::{Valid, ShortcutToInf, ShortcutToZero, Invalid}; 25 | 26 | #[derive(Debug)] 27 | pub enum Sign { 28 | Positive, 29 | Negative, 30 | } 31 | 32 | #[derive(Debug, PartialEq, Eq)] 33 | /// The interesting parts of a decimal string. 34 | pub struct Decimal<'a> { 35 | pub integral: &'a [u8], 36 | pub fractional: &'a [u8], 37 | /// The decimal exponent, guaranteed to have fewer than 18 decimal digits. 38 | pub exp: i64, 39 | } 40 | 41 | impl<'a> Decimal<'a> { 42 | pub fn new(integral: &'a [u8], fractional: &'a [u8], exp: i64) -> Decimal<'a> { 43 | Decimal { integral: integral, fractional: fractional, exp: exp } 44 | } 45 | } 46 | 47 | #[derive(Debug, PartialEq, Eq)] 48 | pub enum ParseResult<'a> { 49 | Valid(Decimal<'a>), 50 | ShortcutToInf, 51 | ShortcutToZero, 52 | Invalid, 53 | } 54 | 55 | /// Check if the input string is a valid floating point number and if so, locate the integral 56 | /// part, the fractional part, and the exponent in it. Does not handle signs. 57 | pub fn parse_decimal(s: &str) -> ParseResult { 58 | if s.is_empty() { 59 | return Invalid; 60 | } 61 | 62 | let s = s.as_bytes(); 63 | let (integral, s) = eat_digits(s); 64 | 65 | match s.first() { 66 | None => Valid(Decimal::new(integral, b"", 0)), 67 | Some(&b'e') | Some(&b'E') => { 68 | if integral.is_empty() { 69 | return Invalid; // No digits before 'e' 70 | } 71 | 72 | parse_exp(integral, b"", &s[1..]) 73 | } 74 | Some(&b'.') => { 75 | let (fractional, s) = eat_digits(&s[1..]); 76 | if integral.is_empty() && fractional.is_empty() && s.is_empty() { 77 | return Invalid; 78 | } 79 | 80 | match s.first() { 81 | None => Valid(Decimal::new(integral, fractional, 0)), 82 | Some(&b'e') | Some(&b'E') => parse_exp(integral, fractional, &s[1..]), 83 | _ => Invalid, // Trailing junk after fractional part 84 | } 85 | } 86 | _ => Invalid, // Trailing junk after first digit string 87 | } 88 | } 89 | 90 | /// Carve off decimal digits up to the first non-digit character. 91 | fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) { 92 | let mut i = 0; 93 | while i < s.len() && b'0' <= s[i] && s[i] <= b'9' { 94 | i += 1; 95 | } 96 | (&s[..i], &s[i..]) 97 | } 98 | 99 | /// Exponent extraction and error checking. 100 | fn parse_exp<'a>(integral: &'a [u8], fractional: &'a [u8], rest: &'a [u8]) -> ParseResult<'a> { 101 | let (sign, rest) = match rest.first() { 102 | Some(&b'-') => (Sign::Negative, &rest[1..]), 103 | Some(&b'+') => (Sign::Positive, &rest[1..]), 104 | _ => (Sign::Positive, rest), 105 | }; 106 | let (mut number, trailing) = eat_digits(rest); 107 | if !trailing.is_empty() { 108 | return Invalid; // Trailing junk after exponent 109 | } 110 | if number.is_empty() { 111 | return Invalid; // Empty exponent 112 | } 113 | // At this point, we certainly have a valid string of digits. It may be too long to put into 114 | // an `i64`, but if it's that huge, the input is certainly zero or infinity. Since each zero 115 | // in the decimal digits only adjusts the exponent by +/- 1, at exp = 10^18 the input would 116 | // have to be 17 exabyte (!) of zeros to get even remotely close to being finite. 117 | // This is not exactly a use case we need to cater to. 118 | while number.first() == Some(&b'0') { 119 | number = &number[1..]; 120 | } 121 | if number.len() >= 18 { 122 | return match sign { 123 | Sign::Positive => ShortcutToInf, 124 | Sign::Negative => ShortcutToZero, 125 | }; 126 | } 127 | let abs_exp = num::from_str_unchecked(number); 128 | let e = match sign { 129 | Sign::Positive => abs_exp as i64, 130 | Sign::Negative => -(abs_exp as i64), 131 | }; 132 | Valid(Decimal::new(integral, fractional, e)) 133 | } 134 | -------------------------------------------------------------------------------- /libcore/num/diy_float.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Extended precision "soft float", for internal use only. 12 | 13 | // This module is only for dec2flt and flt2dec, and only public because of libcoretest. 14 | // It is not intended to ever be stabilized. 15 | #![doc(hidden)] 16 | #![unstable(feature = "core_private_diy_float", 17 | reason = "internal routines only exposed for testing", 18 | issue = "0")] 19 | 20 | /// A custom 64-bit floating point type, representing `f * 2^e`. 21 | #[derive(Copy, Clone, Debug)] 22 | #[doc(hidden)] 23 | pub struct Fp { 24 | /// The integer mantissa. 25 | pub f: u64, 26 | /// The exponent in base 2. 27 | pub e: i16, 28 | } 29 | 30 | impl Fp { 31 | /// Returns a correctly rounded product of itself and `other`. 32 | pub fn mul(&self, other: &Fp) -> Fp { 33 | const MASK: u64 = 0xffffffff; 34 | let a = self.f >> 32; 35 | let b = self.f & MASK; 36 | let c = other.f >> 32; 37 | let d = other.f & MASK; 38 | let ac = a * c; 39 | let bc = b * c; 40 | let ad = a * d; 41 | let bd = b * d; 42 | let tmp = (bd >> 32) + (ad & MASK) + (bc & MASK) + (1 << 31) /* round */; 43 | let f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); 44 | let e = self.e + other.e + 64; 45 | Fp { f: f, e: e } 46 | } 47 | 48 | /// Normalizes itself so that the resulting mantissa is at least `2^63`. 49 | pub fn normalize(&self) -> Fp { 50 | let mut f = self.f; 51 | let mut e = self.e; 52 | if f >> (64 - 32) == 0 { f <<= 32; e -= 32; } 53 | if f >> (64 - 16) == 0 { f <<= 16; e -= 16; } 54 | if f >> (64 - 8) == 0 { f <<= 8; e -= 8; } 55 | if f >> (64 - 4) == 0 { f <<= 4; e -= 4; } 56 | if f >> (64 - 2) == 0 { f <<= 2; e -= 2; } 57 | if f >> (64 - 1) == 0 { f <<= 1; e -= 1; } 58 | debug_assert!(f >= (1 >> 63)); 59 | Fp { f: f, e: e } 60 | } 61 | 62 | /// Normalizes itself to have the shared exponent. 63 | /// It can only decrease the exponent (and thus increase the mantissa). 64 | pub fn normalize_to(&self, e: i16) -> Fp { 65 | let edelta = self.e - e; 66 | assert!(edelta >= 0); 67 | let edelta = edelta as usize; 68 | assert_eq!(self.f << edelta >> edelta, self.f); 69 | Fp { f: self.f << edelta, e: e } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /libcore/num/f32.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Operations and constants for 32-bits floats (`f32` type) 12 | 13 | // FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353 14 | #![allow(overflowing_literals)] 15 | 16 | #![stable(feature = "rust1", since = "1.0.0")] 17 | 18 | use intrinsics; 19 | use mem; 20 | use num::Float; 21 | use num::FpCategory as Fp; 22 | 23 | /// The radix or base of the internal representation of `f32`. 24 | #[stable(feature = "rust1", since = "1.0.0")] 25 | pub const RADIX: u32 = 2; 26 | 27 | /// Number of significant digits in base 2. 28 | #[stable(feature = "rust1", since = "1.0.0")] 29 | pub const MANTISSA_DIGITS: u32 = 24; 30 | /// Approximate number of significant digits in base 10. 31 | #[stable(feature = "rust1", since = "1.0.0")] 32 | pub const DIGITS: u32 = 6; 33 | 34 | /// Difference between `1.0` and the next largest representable number. 35 | #[stable(feature = "rust1", since = "1.0.0")] 36 | pub const EPSILON: f32 = 1.19209290e-07_f32; 37 | 38 | /// Smallest finite `f32` value. 39 | #[stable(feature = "rust1", since = "1.0.0")] 40 | pub const MIN: f32 = -3.40282347e+38_f32; 41 | /// Smallest positive normal `f32` value. 42 | #[stable(feature = "rust1", since = "1.0.0")] 43 | pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32; 44 | /// Largest finite `f32` value. 45 | #[stable(feature = "rust1", since = "1.0.0")] 46 | pub const MAX: f32 = 3.40282347e+38_f32; 47 | 48 | /// One greater than the minimum possible normal power of 2 exponent. 49 | #[stable(feature = "rust1", since = "1.0.0")] 50 | pub const MIN_EXP: i32 = -125; 51 | /// Maximum possible power of 2 exponent. 52 | #[stable(feature = "rust1", since = "1.0.0")] 53 | pub const MAX_EXP: i32 = 128; 54 | 55 | /// Minimum possible normal power of 10 exponent. 56 | #[stable(feature = "rust1", since = "1.0.0")] 57 | pub const MIN_10_EXP: i32 = -37; 58 | /// Maximum possible power of 10 exponent. 59 | #[stable(feature = "rust1", since = "1.0.0")] 60 | pub const MAX_10_EXP: i32 = 38; 61 | 62 | /// Not a Number (NaN). 63 | #[stable(feature = "rust1", since = "1.0.0")] 64 | pub const NAN: f32 = 0.0_f32/0.0_f32; 65 | /// Infinity (∞). 66 | #[stable(feature = "rust1", since = "1.0.0")] 67 | pub const INFINITY: f32 = 1.0_f32/0.0_f32; 68 | /// Negative infinity (-∞). 69 | #[stable(feature = "rust1", since = "1.0.0")] 70 | pub const NEG_INFINITY: f32 = -1.0_f32/0.0_f32; 71 | 72 | /// Basic mathematical constants. 73 | #[stable(feature = "rust1", since = "1.0.0")] 74 | pub mod consts { 75 | // FIXME: replace with mathematical constants from cmath. 76 | 77 | /// Archimedes' constant (π) 78 | #[stable(feature = "rust1", since = "1.0.0")] 79 | pub const PI: f32 = 3.14159265358979323846264338327950288_f32; 80 | 81 | /// π/2 82 | #[stable(feature = "rust1", since = "1.0.0")] 83 | pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32; 84 | 85 | /// π/3 86 | #[stable(feature = "rust1", since = "1.0.0")] 87 | pub const FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32; 88 | 89 | /// π/4 90 | #[stable(feature = "rust1", since = "1.0.0")] 91 | pub const FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32; 92 | 93 | /// π/6 94 | #[stable(feature = "rust1", since = "1.0.0")] 95 | pub const FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32; 96 | 97 | /// π/8 98 | #[stable(feature = "rust1", since = "1.0.0")] 99 | pub const FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32; 100 | 101 | /// 1/π 102 | #[stable(feature = "rust1", since = "1.0.0")] 103 | pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32; 104 | 105 | /// 2/π 106 | #[stable(feature = "rust1", since = "1.0.0")] 107 | pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32; 108 | 109 | /// 2/sqrt(π) 110 | #[stable(feature = "rust1", since = "1.0.0")] 111 | pub const FRAC_2_SQRT_PI: f32 = 1.12837916709551257389615890312154517_f32; 112 | 113 | /// sqrt(2) 114 | #[stable(feature = "rust1", since = "1.0.0")] 115 | pub const SQRT_2: f32 = 1.41421356237309504880168872420969808_f32; 116 | 117 | /// 1/sqrt(2) 118 | #[stable(feature = "rust1", since = "1.0.0")] 119 | pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32; 120 | 121 | /// Euler's number (e) 122 | #[stable(feature = "rust1", since = "1.0.0")] 123 | pub const E: f32 = 2.71828182845904523536028747135266250_f32; 124 | 125 | /// log2(e) 126 | #[stable(feature = "rust1", since = "1.0.0")] 127 | pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32; 128 | 129 | /// log10(e) 130 | #[stable(feature = "rust1", since = "1.0.0")] 131 | pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32; 132 | 133 | /// ln(2) 134 | #[stable(feature = "rust1", since = "1.0.0")] 135 | pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32; 136 | 137 | /// ln(10) 138 | #[stable(feature = "rust1", since = "1.0.0")] 139 | pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32; 140 | } 141 | 142 | #[unstable(feature = "core_float", 143 | reason = "stable interface is via `impl f{32,64}` in later crates", 144 | issue = "32110")] 145 | impl Float for f32 { 146 | #[inline] 147 | fn nan() -> f32 { NAN } 148 | 149 | #[inline] 150 | fn infinity() -> f32 { INFINITY } 151 | 152 | #[inline] 153 | fn neg_infinity() -> f32 { NEG_INFINITY } 154 | 155 | #[inline] 156 | fn zero() -> f32 { 0.0 } 157 | 158 | #[inline] 159 | fn neg_zero() -> f32 { -0.0 } 160 | 161 | #[inline] 162 | fn one() -> f32 { 1.0 } 163 | 164 | /// Returns `true` if the number is NaN. 165 | #[inline] 166 | fn is_nan(self) -> bool { self != self } 167 | 168 | /// Returns `true` if the number is infinite. 169 | #[inline] 170 | fn is_infinite(self) -> bool { 171 | self == INFINITY || self == NEG_INFINITY 172 | } 173 | 174 | /// Returns `true` if the number is neither infinite or NaN. 175 | #[inline] 176 | fn is_finite(self) -> bool { 177 | !(self.is_nan() || self.is_infinite()) 178 | } 179 | 180 | /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. 181 | #[inline] 182 | fn is_normal(self) -> bool { 183 | self.classify() == Fp::Normal 184 | } 185 | 186 | /// Returns the floating point category of the number. If only one property 187 | /// is going to be tested, it is generally faster to use the specific 188 | /// predicate instead. 189 | fn classify(self) -> Fp { 190 | const EXP_MASK: u32 = 0x7f800000; 191 | const MAN_MASK: u32 = 0x007fffff; 192 | 193 | let bits: u32 = unsafe { mem::transmute(self) }; 194 | match (bits & MAN_MASK, bits & EXP_MASK) { 195 | (0, 0) => Fp::Zero, 196 | (_, 0) => Fp::Subnormal, 197 | (0, EXP_MASK) => Fp::Infinite, 198 | (_, EXP_MASK) => Fp::Nan, 199 | _ => Fp::Normal, 200 | } 201 | } 202 | 203 | /// Returns the mantissa, exponent and sign as integers. 204 | fn integer_decode(self) -> (u64, i16, i8) { 205 | let bits: u32 = unsafe { mem::transmute(self) }; 206 | let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; 207 | let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; 208 | let mantissa = if exponent == 0 { 209 | (bits & 0x7fffff) << 1 210 | } else { 211 | (bits & 0x7fffff) | 0x800000 212 | }; 213 | // Exponent bias + mantissa shift 214 | exponent -= 127 + 23; 215 | (mantissa as u64, exponent, sign) 216 | } 217 | 218 | /// Computes the absolute value of `self`. Returns `Float::nan()` if the 219 | /// number is `Float::nan()`. 220 | #[inline] 221 | fn abs(self) -> f32 { 222 | unsafe { intrinsics::fabsf32(self) } 223 | } 224 | 225 | /// Returns a number that represents the sign of `self`. 226 | /// 227 | /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` 228 | /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` 229 | /// - `Float::nan()` if the number is `Float::nan()` 230 | #[inline] 231 | fn signum(self) -> f32 { 232 | if self.is_nan() { 233 | NAN 234 | } else { 235 | unsafe { intrinsics::copysignf32(1.0, self) } 236 | } 237 | } 238 | 239 | /// Returns `true` if `self` is positive, including `+0.0` and 240 | /// `Float::infinity()`. 241 | #[inline] 242 | fn is_sign_positive(self) -> bool { 243 | self > 0.0 || (1.0 / self) == INFINITY 244 | } 245 | 246 | /// Returns `true` if `self` is negative, including `-0.0` and 247 | /// `Float::neg_infinity()`. 248 | #[inline] 249 | fn is_sign_negative(self) -> bool { 250 | self < 0.0 || (1.0 / self) == NEG_INFINITY 251 | } 252 | 253 | /// Returns the reciprocal (multiplicative inverse) of the number. 254 | #[inline] 255 | fn recip(self) -> f32 { 1.0 / self } 256 | 257 | #[inline] 258 | fn powi(self, n: i32) -> f32 { 259 | unsafe { intrinsics::powif32(self, n) } 260 | } 261 | 262 | /// Converts to degrees, assuming the number is in radians. 263 | #[inline] 264 | fn to_degrees(self) -> f32 { self * (180.0f32 / consts::PI) } 265 | 266 | /// Converts to radians, assuming the number is in degrees. 267 | #[inline] 268 | fn to_radians(self) -> f32 { 269 | let value: f32 = consts::PI; 270 | self * (value / 180.0f32) 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /libcore/num/f64.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Operations and constants for 64-bits floats (`f64` type) 12 | 13 | // FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353 14 | #![allow(overflowing_literals)] 15 | 16 | #![stable(feature = "rust1", since = "1.0.0")] 17 | 18 | use intrinsics; 19 | use mem; 20 | use num::FpCategory as Fp; 21 | use num::Float; 22 | 23 | /// The radix or base of the internal representation of `f64`. 24 | #[stable(feature = "rust1", since = "1.0.0")] 25 | pub const RADIX: u32 = 2; 26 | 27 | /// Number of significant digits in base 2. 28 | #[stable(feature = "rust1", since = "1.0.0")] 29 | pub const MANTISSA_DIGITS: u32 = 53; 30 | /// Approximate number of significant digits in base 10. 31 | #[stable(feature = "rust1", since = "1.0.0")] 32 | pub const DIGITS: u32 = 15; 33 | 34 | /// Difference between `1.0` and the next largest representable number. 35 | #[stable(feature = "rust1", since = "1.0.0")] 36 | pub const EPSILON: f64 = 2.2204460492503131e-16_f64; 37 | 38 | /// Smallest finite `f64` value. 39 | #[stable(feature = "rust1", since = "1.0.0")] 40 | pub const MIN: f64 = -1.7976931348623157e+308_f64; 41 | /// Smallest positive normal `f64` value. 42 | #[stable(feature = "rust1", since = "1.0.0")] 43 | pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64; 44 | /// Largest finite `f64` value. 45 | #[stable(feature = "rust1", since = "1.0.0")] 46 | pub const MAX: f64 = 1.7976931348623157e+308_f64; 47 | 48 | /// One greater than the minimum possible normal power of 2 exponent. 49 | #[stable(feature = "rust1", since = "1.0.0")] 50 | pub const MIN_EXP: i32 = -1021; 51 | /// Maximum possible power of 2 exponent. 52 | #[stable(feature = "rust1", since = "1.0.0")] 53 | pub const MAX_EXP: i32 = 1024; 54 | 55 | /// Minimum possible normal power of 10 exponent. 56 | #[stable(feature = "rust1", since = "1.0.0")] 57 | pub const MIN_10_EXP: i32 = -307; 58 | /// Maximum possible power of 10 exponent. 59 | #[stable(feature = "rust1", since = "1.0.0")] 60 | pub const MAX_10_EXP: i32 = 308; 61 | 62 | /// Not a Number (NaN). 63 | #[stable(feature = "rust1", since = "1.0.0")] 64 | pub const NAN: f64 = 0.0_f64/0.0_f64; 65 | /// Infinity (∞). 66 | #[stable(feature = "rust1", since = "1.0.0")] 67 | pub const INFINITY: f64 = 1.0_f64/0.0_f64; 68 | /// Negative infinity (-∞). 69 | #[stable(feature = "rust1", since = "1.0.0")] 70 | pub const NEG_INFINITY: f64 = -1.0_f64/0.0_f64; 71 | 72 | /// Basic mathematical constants. 73 | #[stable(feature = "rust1", since = "1.0.0")] 74 | pub mod consts { 75 | // FIXME: replace with mathematical constants from cmath. 76 | 77 | /// Archimedes' constant (π) 78 | #[stable(feature = "rust1", since = "1.0.0")] 79 | pub const PI: f64 = 3.14159265358979323846264338327950288_f64; 80 | 81 | /// π/2 82 | #[stable(feature = "rust1", since = "1.0.0")] 83 | pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64; 84 | 85 | /// π/3 86 | #[stable(feature = "rust1", since = "1.0.0")] 87 | pub const FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64; 88 | 89 | /// π/4 90 | #[stable(feature = "rust1", since = "1.0.0")] 91 | pub const FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64; 92 | 93 | /// π/6 94 | #[stable(feature = "rust1", since = "1.0.0")] 95 | pub const FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64; 96 | 97 | /// π/8 98 | #[stable(feature = "rust1", since = "1.0.0")] 99 | pub const FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64; 100 | 101 | /// 1/π 102 | #[stable(feature = "rust1", since = "1.0.0")] 103 | pub const FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64; 104 | 105 | /// 2/π 106 | #[stable(feature = "rust1", since = "1.0.0")] 107 | pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64; 108 | 109 | /// 2/sqrt(π) 110 | #[stable(feature = "rust1", since = "1.0.0")] 111 | pub const FRAC_2_SQRT_PI: f64 = 1.12837916709551257389615890312154517_f64; 112 | 113 | /// sqrt(2) 114 | #[stable(feature = "rust1", since = "1.0.0")] 115 | pub const SQRT_2: f64 = 1.41421356237309504880168872420969808_f64; 116 | 117 | /// 1/sqrt(2) 118 | #[stable(feature = "rust1", since = "1.0.0")] 119 | pub const FRAC_1_SQRT_2: f64 = 0.707106781186547524400844362104849039_f64; 120 | 121 | /// Euler's number (e) 122 | #[stable(feature = "rust1", since = "1.0.0")] 123 | pub const E: f64 = 2.71828182845904523536028747135266250_f64; 124 | 125 | /// log2(e) 126 | #[stable(feature = "rust1", since = "1.0.0")] 127 | pub const LOG2_E: f64 = 1.44269504088896340735992468100189214_f64; 128 | 129 | /// log10(e) 130 | #[stable(feature = "rust1", since = "1.0.0")] 131 | pub const LOG10_E: f64 = 0.434294481903251827651128918916605082_f64; 132 | 133 | /// ln(2) 134 | #[stable(feature = "rust1", since = "1.0.0")] 135 | pub const LN_2: f64 = 0.693147180559945309417232121458176568_f64; 136 | 137 | /// ln(10) 138 | #[stable(feature = "rust1", since = "1.0.0")] 139 | pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64; 140 | } 141 | 142 | #[unstable(feature = "core_float", 143 | reason = "stable interface is via `impl f{32,64}` in later crates", 144 | issue = "32110")] 145 | impl Float for f64 { 146 | #[inline] 147 | fn nan() -> f64 { NAN } 148 | 149 | #[inline] 150 | fn infinity() -> f64 { INFINITY } 151 | 152 | #[inline] 153 | fn neg_infinity() -> f64 { NEG_INFINITY } 154 | 155 | #[inline] 156 | fn zero() -> f64 { 0.0 } 157 | 158 | #[inline] 159 | fn neg_zero() -> f64 { -0.0 } 160 | 161 | #[inline] 162 | fn one() -> f64 { 1.0 } 163 | 164 | /// Returns `true` if the number is NaN. 165 | #[inline] 166 | fn is_nan(self) -> bool { self != self } 167 | 168 | /// Returns `true` if the number is infinite. 169 | #[inline] 170 | fn is_infinite(self) -> bool { 171 | self == INFINITY || self == NEG_INFINITY 172 | } 173 | 174 | /// Returns `true` if the number is neither infinite or NaN. 175 | #[inline] 176 | fn is_finite(self) -> bool { 177 | !(self.is_nan() || self.is_infinite()) 178 | } 179 | 180 | /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. 181 | #[inline] 182 | fn is_normal(self) -> bool { 183 | self.classify() == Fp::Normal 184 | } 185 | 186 | /// Returns the floating point category of the number. If only one property 187 | /// is going to be tested, it is generally faster to use the specific 188 | /// predicate instead. 189 | fn classify(self) -> Fp { 190 | const EXP_MASK: u64 = 0x7ff0000000000000; 191 | const MAN_MASK: u64 = 0x000fffffffffffff; 192 | 193 | let bits: u64 = unsafe { mem::transmute(self) }; 194 | match (bits & MAN_MASK, bits & EXP_MASK) { 195 | (0, 0) => Fp::Zero, 196 | (_, 0) => Fp::Subnormal, 197 | (0, EXP_MASK) => Fp::Infinite, 198 | (_, EXP_MASK) => Fp::Nan, 199 | _ => Fp::Normal, 200 | } 201 | } 202 | 203 | /// Returns the mantissa, exponent and sign as integers. 204 | fn integer_decode(self) -> (u64, i16, i8) { 205 | let bits: u64 = unsafe { mem::transmute(self) }; 206 | let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; 207 | let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; 208 | let mantissa = if exponent == 0 { 209 | (bits & 0xfffffffffffff) << 1 210 | } else { 211 | (bits & 0xfffffffffffff) | 0x10000000000000 212 | }; 213 | // Exponent bias + mantissa shift 214 | exponent -= 1023 + 52; 215 | (mantissa, exponent, sign) 216 | } 217 | 218 | /// Computes the absolute value of `self`. Returns `Float::nan()` if the 219 | /// number is `Float::nan()`. 220 | #[inline] 221 | fn abs(self) -> f64 { 222 | unsafe { intrinsics::fabsf64(self) } 223 | } 224 | 225 | /// Returns a number that represents the sign of `self`. 226 | /// 227 | /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` 228 | /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` 229 | /// - `Float::nan()` if the number is `Float::nan()` 230 | #[inline] 231 | fn signum(self) -> f64 { 232 | if self.is_nan() { 233 | NAN 234 | } else { 235 | unsafe { intrinsics::copysignf64(1.0, self) } 236 | } 237 | } 238 | 239 | /// Returns `true` if `self` is positive, including `+0.0` and 240 | /// `Float::infinity()`. 241 | #[inline] 242 | fn is_sign_positive(self) -> bool { 243 | self > 0.0 || (1.0 / self) == INFINITY 244 | } 245 | 246 | /// Returns `true` if `self` is negative, including `-0.0` and 247 | /// `Float::neg_infinity()`. 248 | #[inline] 249 | fn is_sign_negative(self) -> bool { 250 | self < 0.0 || (1.0 / self) == NEG_INFINITY 251 | } 252 | 253 | /// Returns the reciprocal (multiplicative inverse) of the number. 254 | #[inline] 255 | fn recip(self) -> f64 { 1.0 / self } 256 | 257 | #[inline] 258 | fn powi(self, n: i32) -> f64 { 259 | unsafe { intrinsics::powif64(self, n) } 260 | } 261 | 262 | /// Converts to degrees, assuming the number is in radians. 263 | #[inline] 264 | fn to_degrees(self) -> f64 { self * (180.0f64 / consts::PI) } 265 | 266 | /// Converts to radians, assuming the number is in degrees. 267 | #[inline] 268 | fn to_radians(self) -> f64 { 269 | let value: f64 = consts::PI; 270 | self * (value / 180.0) 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /libcore/num/float_macros.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | #![doc(hidden)] 12 | 13 | macro_rules! assert_approx_eq { 14 | ($a:expr, $b:expr) => ({ 15 | use num::Float; 16 | let (a, b) = (&$a, &$b); 17 | assert!((*a - *b).abs() < 1.0e-6, 18 | "{} is not approximately equal to {}", *a, *b); 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /libcore/num/flt2dec/decoder.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Decodes a floating-point value into individual parts and error ranges. 12 | 13 | use {f32, f64}; 14 | use num::FpCategory; 15 | use num::dec2flt::rawfp::RawFloat; 16 | 17 | /// Decoded unsigned finite value, such that: 18 | /// 19 | /// - The original value equals to `mant * 2^exp`. 20 | /// 21 | /// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will 22 | /// round to the original value. The range is inclusive only when 23 | /// `inclusive` is true. 24 | #[derive(Copy, Clone, Debug, PartialEq)] 25 | pub struct Decoded { 26 | /// The scaled mantissa. 27 | pub mant: u64, 28 | /// The lower error range. 29 | pub minus: u64, 30 | /// The upper error range. 31 | pub plus: u64, 32 | /// The shared exponent in base 2. 33 | pub exp: i16, 34 | /// True when the error range is inclusive. 35 | /// 36 | /// In IEEE 754, this is true when the original mantissa was even. 37 | pub inclusive: bool, 38 | } 39 | 40 | /// Decoded unsigned value. 41 | #[derive(Copy, Clone, Debug, PartialEq)] 42 | pub enum FullDecoded { 43 | /// Not-a-number. 44 | Nan, 45 | /// Infinities, either positive or negative. 46 | Infinite, 47 | /// Zero, either positive or negative. 48 | Zero, 49 | /// Finite numbers with further decoded fields. 50 | Finite(Decoded), 51 | } 52 | 53 | /// A floating point type which can be `decode`d. 54 | pub trait DecodableFloat: RawFloat + Copy { 55 | /// The minimum positive normalized value. 56 | fn min_pos_norm_value() -> Self; 57 | } 58 | 59 | impl DecodableFloat for f32 { 60 | fn min_pos_norm_value() -> Self { f32::MIN_POSITIVE } 61 | } 62 | 63 | impl DecodableFloat for f64 { 64 | fn min_pos_norm_value() -> Self { f64::MIN_POSITIVE } 65 | } 66 | 67 | /// Returns a sign (true when negative) and `FullDecoded` value 68 | /// from given floating point number. 69 | pub fn decode(v: T) -> (/*negative?*/ bool, FullDecoded) { 70 | let (mant, exp, sign) = v.integer_decode2(); 71 | let even = (mant & 1) == 0; 72 | let decoded = match v.classify() { 73 | FpCategory::Nan => FullDecoded::Nan, 74 | FpCategory::Infinite => FullDecoded::Infinite, 75 | FpCategory::Zero => FullDecoded::Zero, 76 | FpCategory::Subnormal => { 77 | // neighbors: (mant - 2, exp) -- (mant, exp) -- (mant + 2, exp) 78 | // Float::integer_decode always preserves the exponent, 79 | // so the mantissa is scaled for subnormals. 80 | FullDecoded::Finite(Decoded { mant: mant, minus: 1, plus: 1, 81 | exp: exp, inclusive: even }) 82 | } 83 | FpCategory::Normal => { 84 | let minnorm = ::min_pos_norm_value().integer_decode2(); 85 | if mant == minnorm.0 { 86 | // neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp) 87 | // where maxmant = minnormmant * 2 - 1 88 | FullDecoded::Finite(Decoded { mant: mant << 2, minus: 1, plus: 2, 89 | exp: exp - 2, inclusive: even }) 90 | } else { 91 | // neighbors: (mant - 1, exp) -- (mant, exp) -- (mant + 1, exp) 92 | FullDecoded::Finite(Decoded { mant: mant << 1, minus: 1, plus: 1, 93 | exp: exp - 1, inclusive: even }) 94 | } 95 | } 96 | }; 97 | (sign < 0, decoded) 98 | } 99 | 100 | -------------------------------------------------------------------------------- /libcore/num/flt2dec/estimator.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The exponent estimator. 12 | 13 | /// Finds `k_0` such that `10^(k_0-1) < mant * 2^exp <= 10^(k_0+1)`. 14 | /// 15 | /// This is used to approximate `k = ceil(log_10 (mant * 2^exp))`; 16 | /// the true `k` is either `k_0` or `k_0+1`. 17 | #[doc(hidden)] 18 | pub fn estimate_scaling_factor(mant: u64, exp: i16) -> i16 { 19 | // 2^(nbits-1) < mant <= 2^nbits if mant > 0 20 | let nbits = 64 - (mant - 1).leading_zeros() as i64; 21 | // 1292913986 = floor(2^32 * log_10 2) 22 | // therefore this always underestimates (or is exact), but not much. 23 | (((nbits + exp as i64) * 1292913986) >> 32) as i16 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libcore/num/i16.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 16-bit signed integer type. 12 | //! 13 | //! *[See also the `i16` primitive type](../../std/primitive.i16.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | int_module! { i16, 16 } 18 | -------------------------------------------------------------------------------- /libcore/num/i32.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 32-bit signed integer type. 12 | //! 13 | //! *[See also the `i32` primitive type](../../std/primitive.i32.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | int_module! { i32, 32 } 18 | -------------------------------------------------------------------------------- /libcore/num/i64.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 64-bit signed integer type. 12 | //! 13 | //! *[See also the `i64` primitive type](../../std/primitive.i64.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | int_module! { i64, 64 } 18 | -------------------------------------------------------------------------------- /libcore/num/i8.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 8-bit signed integer type. 12 | //! 13 | //! *[See also the `i8` primitive type](../../std/primitive.i8.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | int_module! { i8, 8 } 18 | -------------------------------------------------------------------------------- /libcore/num/int_macros.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | #![doc(hidden)] 12 | 13 | macro_rules! int_module { ($T:ident, $bits:expr) => ( 14 | 15 | /// The smallest value that can be represented by this integer type. 16 | #[stable(feature = "rust1", since = "1.0.0")] 17 | pub const MIN: $T = $T::min_value(); 18 | /// The largest value that can be represented by this integer type. 19 | #[stable(feature = "rust1", since = "1.0.0")] 20 | pub const MAX: $T = $T::max_value(); 21 | 22 | ) } 23 | -------------------------------------------------------------------------------- /libcore/num/isize.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The pointer-sized signed integer type. 12 | //! 13 | //! *[See also the `isize` primitive type](../../std/primitive.isize.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | #[cfg(target_pointer_width = "16")] 18 | int_module! { isize, 16 } 19 | #[cfg(target_pointer_width = "32")] 20 | int_module! { isize, 32 } 21 | #[cfg(target_pointer_width = "64")] 22 | int_module! { isize, 64 } 23 | -------------------------------------------------------------------------------- /libcore/num/u16.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 16-bit unsigned integer type. 12 | //! 13 | //! *[See also the `u16` primitive type](../../std/primitive.u16.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | uint_module! { u16, 16 } 18 | -------------------------------------------------------------------------------- /libcore/num/u32.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 32-bit unsigned integer type. 12 | //! 13 | //! *[See also the `u32` primitive type](../../std/primitive.u32.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | uint_module! { u32, 32 } 18 | -------------------------------------------------------------------------------- /libcore/num/u64.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 64-bit unsigned integer type. 12 | //! 13 | //! *[See also the `u64` primitive type](../../std/primitive.u64.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | uint_module! { u64, 64 } 18 | -------------------------------------------------------------------------------- /libcore/num/u8.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The 8-bit unsigned integer type. 12 | //! 13 | //! *[See also the `u8` primitive type](../../std/primitive.u8.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | uint_module! { u8, 8 } 18 | -------------------------------------------------------------------------------- /libcore/num/uint_macros.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | #![doc(hidden)] 12 | 13 | macro_rules! uint_module { ($T:ident, $bits:expr) => ( 14 | 15 | /// The smallest value that can be represented by this integer type. 16 | #[stable(feature = "rust1", since = "1.0.0")] 17 | pub const MIN: $T = $T::min_value(); 18 | /// The largest value that can be represented by this integer type. 19 | #[stable(feature = "rust1", since = "1.0.0")] 20 | pub const MAX: $T = $T::max_value(); 21 | 22 | ) } 23 | -------------------------------------------------------------------------------- /libcore/num/usize.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The pointer-sized unsigned integer type. 12 | //! 13 | //! *[See also the `usize` primitive type](../../std/primitive.usize.html).* 14 | 15 | #![stable(feature = "rust1", since = "1.0.0")] 16 | 17 | #[cfg(target_pointer_width = "16")] 18 | uint_module! { usize, 16 } 19 | #[cfg(target_pointer_width = "32")] 20 | uint_module! { usize, 32 } 21 | #[cfg(target_pointer_width = "64")] 22 | uint_module! { usize, 64 } 23 | -------------------------------------------------------------------------------- /libcore/num/wrapping.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | use super::Wrapping; 12 | 13 | use ops::*; 14 | 15 | macro_rules! sh_impl_signed { 16 | ($t:ident, $f:ident) => ( 17 | #[stable(feature = "rust1", since = "1.0.0")] 18 | impl Shl<$f> for Wrapping<$t> { 19 | type Output = Wrapping<$t>; 20 | 21 | #[inline(always)] 22 | fn shl(self, other: $f) -> Wrapping<$t> { 23 | if other < 0 { 24 | Wrapping(self.0.wrapping_shr((-other & self::shift_max::$t as $f) as u32)) 25 | } else { 26 | Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) 27 | } 28 | } 29 | } 30 | 31 | #[stable(feature = "wrapping_impls", since = "1.7.0")] 32 | impl ShlAssign<$f> for Wrapping<$t> { 33 | #[inline(always)] 34 | fn shl_assign(&mut self, other: $f) { 35 | *self = *self << other; 36 | } 37 | } 38 | 39 | #[stable(feature = "rust1", since = "1.0.0")] 40 | impl Shr<$f> for Wrapping<$t> { 41 | type Output = Wrapping<$t>; 42 | 43 | #[inline(always)] 44 | fn shr(self, other: $f) -> Wrapping<$t> { 45 | if other < 0 { 46 | Wrapping(self.0.wrapping_shl((-other & self::shift_max::$t as $f) as u32)) 47 | } else { 48 | Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) 49 | } 50 | } 51 | } 52 | 53 | #[stable(feature = "wrapping_impls", since = "1.7.0")] 54 | impl ShrAssign<$f> for Wrapping<$t> { 55 | #[inline(always)] 56 | fn shr_assign(&mut self, other: $f) { 57 | *self = *self >> other; 58 | } 59 | } 60 | ) 61 | } 62 | 63 | macro_rules! sh_impl_unsigned { 64 | ($t:ident, $f:ident) => ( 65 | #[stable(feature = "rust1", since = "1.0.0")] 66 | impl Shl<$f> for Wrapping<$t> { 67 | type Output = Wrapping<$t>; 68 | 69 | #[inline(always)] 70 | fn shl(self, other: $f) -> Wrapping<$t> { 71 | Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) 72 | } 73 | } 74 | 75 | #[stable(feature = "wrapping_impls", since = "1.7.0")] 76 | impl ShlAssign<$f> for Wrapping<$t> { 77 | #[inline(always)] 78 | fn shl_assign(&mut self, other: $f) { 79 | *self = *self << other; 80 | } 81 | } 82 | 83 | #[stable(feature = "rust1", since = "1.0.0")] 84 | impl Shr<$f> for Wrapping<$t> { 85 | type Output = Wrapping<$t>; 86 | 87 | #[inline(always)] 88 | fn shr(self, other: $f) -> Wrapping<$t> { 89 | Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) 90 | } 91 | } 92 | 93 | #[stable(feature = "wrapping_impls", since = "1.7.0")] 94 | impl ShrAssign<$f> for Wrapping<$t> { 95 | #[inline(always)] 96 | fn shr_assign(&mut self, other: $f) { 97 | *self = *self >> other; 98 | } 99 | } 100 | ) 101 | } 102 | 103 | // FIXME (#23545): uncomment the remaining impls 104 | macro_rules! sh_impl_all { 105 | ($($t:ident)*) => ($( 106 | //sh_impl_unsigned! { $t, u8 } 107 | //sh_impl_unsigned! { $t, u16 } 108 | //sh_impl_unsigned! { $t, u32 } 109 | //sh_impl_unsigned! { $t, u64 } 110 | sh_impl_unsigned! { $t, usize } 111 | 112 | //sh_impl_signed! { $t, i8 } 113 | //sh_impl_signed! { $t, i16 } 114 | //sh_impl_signed! { $t, i32 } 115 | //sh_impl_signed! { $t, i64 } 116 | //sh_impl_signed! { $t, isize } 117 | )*) 118 | } 119 | 120 | sh_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } 121 | 122 | // FIXME(30524): impl Op for Wrapping, impl OpAssign for Wrapping 123 | macro_rules! wrapping_impl { 124 | ($($t:ty)*) => ($( 125 | #[stable(feature = "rust1", since = "1.0.0")] 126 | impl Add for Wrapping<$t> { 127 | type Output = Wrapping<$t>; 128 | 129 | #[inline(always)] 130 | fn add(self, other: Wrapping<$t>) -> Wrapping<$t> { 131 | Wrapping(self.0.wrapping_add(other.0)) 132 | } 133 | } 134 | 135 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 136 | impl AddAssign for Wrapping<$t> { 137 | #[inline(always)] 138 | fn add_assign(&mut self, other: Wrapping<$t>) { 139 | *self = *self + other; 140 | } 141 | } 142 | 143 | #[stable(feature = "rust1", since = "1.0.0")] 144 | impl Sub for Wrapping<$t> { 145 | type Output = Wrapping<$t>; 146 | 147 | #[inline(always)] 148 | fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> { 149 | Wrapping(self.0.wrapping_sub(other.0)) 150 | } 151 | } 152 | 153 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 154 | impl SubAssign for Wrapping<$t> { 155 | #[inline(always)] 156 | fn sub_assign(&mut self, other: Wrapping<$t>) { 157 | *self = *self - other; 158 | } 159 | } 160 | 161 | #[stable(feature = "rust1", since = "1.0.0")] 162 | impl Mul for Wrapping<$t> { 163 | type Output = Wrapping<$t>; 164 | 165 | #[inline(always)] 166 | fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> { 167 | Wrapping(self.0.wrapping_mul(other.0)) 168 | } 169 | } 170 | 171 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 172 | impl MulAssign for Wrapping<$t> { 173 | #[inline(always)] 174 | fn mul_assign(&mut self, other: Wrapping<$t>) { 175 | *self = *self * other; 176 | } 177 | } 178 | 179 | #[stable(feature = "wrapping_div", since = "1.3.0")] 180 | impl Div for Wrapping<$t> { 181 | type Output = Wrapping<$t>; 182 | 183 | #[inline(always)] 184 | fn div(self, other: Wrapping<$t>) -> Wrapping<$t> { 185 | Wrapping(self.0.wrapping_div(other.0)) 186 | } 187 | } 188 | 189 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 190 | impl DivAssign for Wrapping<$t> { 191 | #[inline(always)] 192 | fn div_assign(&mut self, other: Wrapping<$t>) { 193 | *self = *self / other; 194 | } 195 | } 196 | 197 | #[stable(feature = "wrapping_impls", since = "1.7.0")] 198 | impl Rem for Wrapping<$t> { 199 | type Output = Wrapping<$t>; 200 | 201 | #[inline(always)] 202 | fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> { 203 | Wrapping(self.0.wrapping_rem(other.0)) 204 | } 205 | } 206 | 207 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 208 | impl RemAssign for Wrapping<$t> { 209 | #[inline(always)] 210 | fn rem_assign(&mut self, other: Wrapping<$t>) { 211 | *self = *self % other; 212 | } 213 | } 214 | 215 | #[stable(feature = "rust1", since = "1.0.0")] 216 | impl Not for Wrapping<$t> { 217 | type Output = Wrapping<$t>; 218 | 219 | #[inline(always)] 220 | fn not(self) -> Wrapping<$t> { 221 | Wrapping(!self.0) 222 | } 223 | } 224 | 225 | #[stable(feature = "rust1", since = "1.0.0")] 226 | impl BitXor for Wrapping<$t> { 227 | type Output = Wrapping<$t>; 228 | 229 | #[inline(always)] 230 | fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> { 231 | Wrapping(self.0 ^ other.0) 232 | } 233 | } 234 | 235 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 236 | impl BitXorAssign for Wrapping<$t> { 237 | #[inline(always)] 238 | fn bitxor_assign(&mut self, other: Wrapping<$t>) { 239 | *self = *self ^ other; 240 | } 241 | } 242 | 243 | #[stable(feature = "rust1", since = "1.0.0")] 244 | impl BitOr for Wrapping<$t> { 245 | type Output = Wrapping<$t>; 246 | 247 | #[inline(always)] 248 | fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> { 249 | Wrapping(self.0 | other.0) 250 | } 251 | } 252 | 253 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 254 | impl BitOrAssign for Wrapping<$t> { 255 | #[inline(always)] 256 | fn bitor_assign(&mut self, other: Wrapping<$t>) { 257 | *self = *self | other; 258 | } 259 | } 260 | 261 | #[stable(feature = "rust1", since = "1.0.0")] 262 | impl BitAnd for Wrapping<$t> { 263 | type Output = Wrapping<$t>; 264 | 265 | #[inline(always)] 266 | fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> { 267 | Wrapping(self.0 & other.0) 268 | } 269 | } 270 | 271 | #[stable(feature = "op_assign_traits", since = "1.8.0")] 272 | impl BitAndAssign for Wrapping<$t> { 273 | #[inline(always)] 274 | fn bitand_assign(&mut self, other: Wrapping<$t>) { 275 | *self = *self & other; 276 | } 277 | } 278 | 279 | #[stable(feature = "wrapping_neg", since = "1.10.0")] 280 | impl Neg for Wrapping<$t> { 281 | type Output = Self; 282 | #[inline(always)] 283 | fn neg(self) -> Self { 284 | Wrapping(0) - self 285 | } 286 | } 287 | )*) 288 | } 289 | 290 | wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } 291 | 292 | mod shift_max { 293 | #![allow(non_upper_case_globals)] 294 | 295 | #[cfg(target_pointer_width = "16")] 296 | mod platform { 297 | pub const usize: u32 = super::u16; 298 | pub const isize: u32 = super::i16; 299 | } 300 | 301 | #[cfg(target_pointer_width = "32")] 302 | mod platform { 303 | pub const usize: u32 = super::u32; 304 | pub const isize: u32 = super::i32; 305 | } 306 | 307 | #[cfg(target_pointer_width = "64")] 308 | mod platform { 309 | pub const usize: u32 = super::u64; 310 | pub const isize: u32 = super::i64; 311 | } 312 | 313 | pub const i8: u32 = (1 << 3) - 1; 314 | pub const i16: u32 = (1 << 4) - 1; 315 | pub const i32: u32 = (1 << 5) - 1; 316 | pub const i64: u32 = (1 << 6) - 1; 317 | pub use self::platform::isize; 318 | 319 | pub const u8: u32 = i8; 320 | pub const u16: u32 = i16; 321 | pub const u32: u32 = i32; 322 | pub const u64: u32 = i64; 323 | pub use self::platform::usize; 324 | } 325 | -------------------------------------------------------------------------------- /libcore/panicking.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Panic support for libcore 12 | //! 13 | //! The core library cannot define panicking, but it does *declare* panicking. This 14 | //! means that the functions inside of libcore are allowed to panic, but to be 15 | //! useful an upstream crate must define panicking for libcore to use. The current 16 | //! interface for panicking is: 17 | //! 18 | //! ```ignore 19 | //! fn panic_impl(fmt: fmt::Arguments, &(&'static str, u32)) -> !; 20 | //! ``` 21 | //! 22 | //! This definition allows for panicking with any general message, but it does not 23 | //! allow for failing with a `Box` value. The reason for this is that libcore 24 | //! is not allowed to allocate. 25 | //! 26 | //! This module contains a few other panicking functions, but these are just the 27 | //! necessary lang items for the compiler. All panics are funneled through this 28 | //! one function. Currently, the actual symbol is declared in the standard 29 | //! library, but the location of this may change over time. 30 | 31 | #![allow(dead_code, missing_docs)] 32 | #![unstable(feature = "core_panic", 33 | reason = "internal details of the implementation of the `panic!` \ 34 | and related macros", 35 | issue = "0")] 36 | 37 | use fmt; 38 | 39 | #[cold] #[inline(never)] // this is the slow path, always 40 | #[lang = "panic"] 41 | pub fn panic(expr_file_line: &(&'static str, &'static str, u32)) -> ! { 42 | // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially 43 | // reduce size overhead. The format_args! macro uses str's Display trait to 44 | // write expr, which calls Formatter::pad, which must accommodate string 45 | // truncation and padding (even though none is used here). Using 46 | // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the 47 | // output binary, saving up to a few kilobytes. 48 | let (expr, file, line) = *expr_file_line; 49 | panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line)) 50 | } 51 | 52 | #[cold] #[inline(never)] 53 | #[lang = "panic_bounds_check"] 54 | fn panic_bounds_check(file_line: &(&'static str, u32), 55 | index: usize, len: usize) -> ! { 56 | panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}", 57 | len, index), file_line) 58 | } 59 | 60 | #[cold] #[inline(never)] 61 | pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! { 62 | #[allow(improper_ctypes)] 63 | extern { 64 | #[lang = "panic_fmt"] 65 | #[unwind] 66 | fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: u32) -> !; 67 | } 68 | let (file, line) = *file_line; 69 | unsafe { panic_impl(fmt, file, line) } 70 | } 71 | -------------------------------------------------------------------------------- /libcore/prelude/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The libcore prelude 12 | 13 | #![stable(feature = "core_prelude", since = "1.4.0")] 14 | 15 | pub mod v1; 16 | -------------------------------------------------------------------------------- /libcore/prelude/v1.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! The core prelude 12 | //! 13 | //! This module is intended for users of libcore which do not link to libstd as 14 | //! well. This module is imported by default when `#![no_std]` is used in the 15 | //! same manner as the standard library's prelude. 16 | 17 | #![stable(feature = "core_prelude", since = "1.4.0")] 18 | 19 | // Reexported core operators 20 | #[stable(feature = "core_prelude", since = "1.4.0")] 21 | #[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync}; 22 | #[stable(feature = "core_prelude", since = "1.4.0")] 23 | #[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce}; 24 | 25 | // Reexported functions 26 | #[stable(feature = "core_prelude", since = "1.4.0")] 27 | #[doc(no_inline)] pub use mem::drop; 28 | 29 | // Reexported types and traits 30 | #[stable(feature = "core_prelude", since = "1.4.0")] 31 | #[doc(no_inline)] pub use clone::Clone; 32 | #[stable(feature = "core_prelude", since = "1.4.0")] 33 | #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; 34 | #[stable(feature = "core_prelude", since = "1.4.0")] 35 | #[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From}; 36 | #[stable(feature = "core_prelude", since = "1.4.0")] 37 | #[doc(no_inline)] pub use default::Default; 38 | #[stable(feature = "core_prelude", since = "1.4.0")] 39 | #[doc(no_inline)] pub use iter::{Iterator, Extend, IntoIterator}; 40 | #[stable(feature = "core_prelude", since = "1.4.0")] 41 | #[doc(no_inline)] pub use iter::{DoubleEndedIterator, ExactSizeIterator}; 42 | #[stable(feature = "core_prelude", since = "1.4.0")] 43 | #[doc(no_inline)] pub use option::Option::{self, Some, None}; 44 | #[stable(feature = "core_prelude", since = "1.4.0")] 45 | #[doc(no_inline)] pub use result::Result::{self, Ok, Err}; 46 | 47 | // Reexported extension traits for primitive types 48 | #[stable(feature = "core_prelude", since = "1.4.0")] 49 | #[doc(no_inline)] pub use slice::SliceExt; 50 | #[stable(feature = "core_prelude", since = "1.4.0")] 51 | #[doc(no_inline)] pub use str::StrExt; 52 | #[stable(feature = "core_prelude", since = "1.4.0")] 53 | #[doc(no_inline)] pub use char::CharExt; 54 | -------------------------------------------------------------------------------- /libcore/raw.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | #![allow(missing_docs)] 12 | #![unstable(feature = "raw", issue = "27751")] 13 | 14 | //! Contains struct definitions for the layout of compiler built-in types. 15 | //! 16 | //! They can be used as targets of transmutes in unsafe code for manipulating 17 | //! the raw representations directly. 18 | //! 19 | //! Their definition should always match the ABI defined in `rustc::back::abi`. 20 | 21 | /// The representation of a trait object like `&SomeTrait`. 22 | /// 23 | /// This struct has the same layout as types like `&SomeTrait` and 24 | /// `Box`. The [Trait Objects chapter of the 25 | /// Book][moreinfo] contains more details about the precise nature of 26 | /// these internals. 27 | /// 28 | /// [moreinfo]: ../../book/trait-objects.html#representation 29 | /// 30 | /// `TraitObject` is guaranteed to match layouts, but it is not the 31 | /// type of trait objects (e.g. the fields are not directly accessible 32 | /// on a `&SomeTrait`) nor does it control that layout (changing the 33 | /// definition will not change the layout of a `&SomeTrait`). It is 34 | /// only designed to be used by unsafe code that needs to manipulate 35 | /// the low-level details. 36 | /// 37 | /// There is no way to refer to all trait objects generically, so the only 38 | /// way to create values of this type is with functions like 39 | /// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true 40 | /// trait object from a `TraitObject` value is with `transmute`. 41 | /// 42 | /// [transmute]: ../intrinsics/fn.transmute.html 43 | /// 44 | /// Synthesizing a trait object with mismatched types—one where the 45 | /// vtable does not correspond to the type of the value to which the 46 | /// data pointer points—is highly likely to lead to undefined 47 | /// behavior. 48 | /// 49 | /// # Examples 50 | /// 51 | /// ``` 52 | /// #![feature(raw)] 53 | /// 54 | /// use std::{mem, raw}; 55 | /// 56 | /// // an example trait 57 | /// trait Foo { 58 | /// fn bar(&self) -> i32; 59 | /// } 60 | /// 61 | /// impl Foo for i32 { 62 | /// fn bar(&self) -> i32 { 63 | /// *self + 1 64 | /// } 65 | /// } 66 | /// 67 | /// let value: i32 = 123; 68 | /// 69 | /// // let the compiler make a trait object 70 | /// let object: &Foo = &value; 71 | /// 72 | /// // look at the raw representation 73 | /// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) }; 74 | /// 75 | /// // the data pointer is the address of `value` 76 | /// assert_eq!(raw_object.data as *const i32, &value as *const _); 77 | /// 78 | /// let other_value: i32 = 456; 79 | /// 80 | /// // construct a new object, pointing to a different `i32`, being 81 | /// // careful to use the `i32` vtable from `object` 82 | /// let synthesized: &Foo = unsafe { 83 | /// mem::transmute(raw::TraitObject { 84 | /// data: &other_value as *const _ as *mut (), 85 | /// vtable: raw_object.vtable, 86 | /// }) 87 | /// }; 88 | /// 89 | /// // it should work just as if we had constructed a trait object out of 90 | /// // `other_value` directly 91 | /// assert_eq!(synthesized.bar(), 457); 92 | /// ``` 93 | #[repr(C)] 94 | #[derive(Copy, Clone)] 95 | #[allow(missing_debug_implementations)] 96 | pub struct TraitObject { 97 | pub data: *mut (), 98 | pub vtable: *mut (), 99 | } 100 | -------------------------------------------------------------------------------- /libcore/sync/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Synchronization primitives 12 | 13 | #![stable(feature = "rust1", since = "1.0.0")] 14 | 15 | pub mod atomic; 16 | -------------------------------------------------------------------------------- /libcore/tuple.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | // See src/libstd/primitive_docs.rs for documentation. 12 | 13 | use cmp::*; 14 | use cmp::Ordering::*; 15 | 16 | // FIXME(#19630) Remove this work-around 17 | macro_rules! e { 18 | ($e:expr) => { $e } 19 | } 20 | 21 | // macro for implementing n-ary tuple functions and operations 22 | macro_rules! tuple_impls { 23 | ($( 24 | $Tuple:ident { 25 | $(($idx:tt) -> $T:ident)+ 26 | } 27 | )+) => { 28 | $( 29 | #[stable(feature = "rust1", since = "1.0.0")] 30 | impl<$($T:Clone),+> Clone for ($($T,)+) { 31 | fn clone(&self) -> ($($T,)+) { 32 | ($(e!(self.$idx.clone()),)+) 33 | } 34 | } 35 | 36 | #[stable(feature = "rust1", since = "1.0.0")] 37 | impl<$($T:PartialEq),+> PartialEq for ($($T,)+) { 38 | #[inline] 39 | fn eq(&self, other: &($($T,)+)) -> bool { 40 | e!($(self.$idx == other.$idx)&&+) 41 | } 42 | #[inline] 43 | fn ne(&self, other: &($($T,)+)) -> bool { 44 | e!($(self.$idx != other.$idx)||+) 45 | } 46 | } 47 | 48 | #[stable(feature = "rust1", since = "1.0.0")] 49 | impl<$($T:Eq),+> Eq for ($($T,)+) {} 50 | 51 | #[stable(feature = "rust1", since = "1.0.0")] 52 | impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) { 53 | #[inline] 54 | fn partial_cmp(&self, other: &($($T,)+)) -> Option { 55 | lexical_partial_cmp!($(self.$idx, other.$idx),+) 56 | } 57 | #[inline] 58 | fn lt(&self, other: &($($T,)+)) -> bool { 59 | lexical_ord!(lt, $(self.$idx, other.$idx),+) 60 | } 61 | #[inline] 62 | fn le(&self, other: &($($T,)+)) -> bool { 63 | lexical_ord!(le, $(self.$idx, other.$idx),+) 64 | } 65 | #[inline] 66 | fn ge(&self, other: &($($T,)+)) -> bool { 67 | lexical_ord!(ge, $(self.$idx, other.$idx),+) 68 | } 69 | #[inline] 70 | fn gt(&self, other: &($($T,)+)) -> bool { 71 | lexical_ord!(gt, $(self.$idx, other.$idx),+) 72 | } 73 | } 74 | 75 | #[stable(feature = "rust1", since = "1.0.0")] 76 | impl<$($T:Ord),+> Ord for ($($T,)+) { 77 | #[inline] 78 | fn cmp(&self, other: &($($T,)+)) -> Ordering { 79 | lexical_cmp!($(self.$idx, other.$idx),+) 80 | } 81 | } 82 | 83 | #[stable(feature = "rust1", since = "1.0.0")] 84 | impl<$($T:Default),+> Default for ($($T,)+) { 85 | #[inline] 86 | fn default() -> ($($T,)+) { 87 | ($({ let x: $T = Default::default(); x},)+) 88 | } 89 | } 90 | )+ 91 | } 92 | } 93 | 94 | // Constructs an expression that performs a lexical ordering using method $rel. 95 | // The values are interleaved, so the macro invocation for 96 | // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2, 97 | // a3, b3)` (and similarly for `lexical_cmp`) 98 | macro_rules! lexical_ord { 99 | ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => { 100 | if $a != $b { lexical_ord!($rel, $a, $b) } 101 | else { lexical_ord!($rel, $($rest_a, $rest_b),+) } 102 | }; 103 | ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) }; 104 | } 105 | 106 | macro_rules! lexical_partial_cmp { 107 | ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => { 108 | match ($a).partial_cmp(&$b) { 109 | Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+), 110 | ordering => ordering 111 | } 112 | }; 113 | ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) }; 114 | } 115 | 116 | macro_rules! lexical_cmp { 117 | ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => { 118 | match ($a).cmp(&$b) { 119 | Equal => lexical_cmp!($($rest_a, $rest_b),+), 120 | ordering => ordering 121 | } 122 | }; 123 | ($a:expr, $b:expr) => { ($a).cmp(&$b) }; 124 | } 125 | 126 | tuple_impls! { 127 | Tuple1 { 128 | (0) -> A 129 | } 130 | Tuple2 { 131 | (0) -> A 132 | (1) -> B 133 | } 134 | Tuple3 { 135 | (0) -> A 136 | (1) -> B 137 | (2) -> C 138 | } 139 | Tuple4 { 140 | (0) -> A 141 | (1) -> B 142 | (2) -> C 143 | (3) -> D 144 | } 145 | Tuple5 { 146 | (0) -> A 147 | (1) -> B 148 | (2) -> C 149 | (3) -> D 150 | (4) -> E 151 | } 152 | Tuple6 { 153 | (0) -> A 154 | (1) -> B 155 | (2) -> C 156 | (3) -> D 157 | (4) -> E 158 | (5) -> F 159 | } 160 | Tuple7 { 161 | (0) -> A 162 | (1) -> B 163 | (2) -> C 164 | (3) -> D 165 | (4) -> E 166 | (5) -> F 167 | (6) -> G 168 | } 169 | Tuple8 { 170 | (0) -> A 171 | (1) -> B 172 | (2) -> C 173 | (3) -> D 174 | (4) -> E 175 | (5) -> F 176 | (6) -> G 177 | (7) -> H 178 | } 179 | Tuple9 { 180 | (0) -> A 181 | (1) -> B 182 | (2) -> C 183 | (3) -> D 184 | (4) -> E 185 | (5) -> F 186 | (6) -> G 187 | (7) -> H 188 | (8) -> I 189 | } 190 | Tuple10 { 191 | (0) -> A 192 | (1) -> B 193 | (2) -> C 194 | (3) -> D 195 | (4) -> E 196 | (5) -> F 197 | (6) -> G 198 | (7) -> H 199 | (8) -> I 200 | (9) -> J 201 | } 202 | Tuple11 { 203 | (0) -> A 204 | (1) -> B 205 | (2) -> C 206 | (3) -> D 207 | (4) -> E 208 | (5) -> F 209 | (6) -> G 210 | (7) -> H 211 | (8) -> I 212 | (9) -> J 213 | (10) -> K 214 | } 215 | Tuple12 { 216 | (0) -> A 217 | (1) -> B 218 | (2) -> C 219 | (3) -> D 220 | (4) -> E 221 | (5) -> F 222 | (6) -> G 223 | (7) -> H 224 | (8) -> I 225 | (9) -> J 226 | (10) -> K 227 | (11) -> L 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /libcyano/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libcyano" 3 | version = "0.1.0" 4 | authors = ["ticki "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /libcyano/core.rs: -------------------------------------------------------------------------------- 1 | pub enum Option { 2 | Some(T), 3 | None, 4 | } 5 | 6 | #[macro_export] 7 | macro_rules! unreachable { 8 | () => { 9 | js!("alert('Cyano error: A codepath marked unreachable was reached.')"); 10 | 11 | loop {} 12 | }; 13 | } 14 | 15 | /* TODO 16 | 17 | #[lang = "eh_personality"] 18 | #[no_mangle] 19 | pub extern fn rust_eh_personality() {} 20 | 21 | #[lang = "eh_unwind_resume"] 22 | #[no_mangle] 23 | pub extern fn rust_eh_unwind_resume() {} 24 | 25 | #[lang = "panic_fmt"] 26 | #[no_mangle] 27 | pub extern fn rust_begin_panic(_msg: core::fmt::Arguments, _file: &'static str, _line: u32) -> ! { 28 | // TODO: Give the message here. 29 | js!("alert('Panic!')"); 30 | 31 | loop {} 32 | } 33 | 34 | */ 35 | -------------------------------------------------------------------------------- /libcyano/src/ffi.rs: -------------------------------------------------------------------------------- 1 | pub fn undefined() -> T { 2 | js!("return undefined"); 3 | 4 | unreachable!(); 5 | } 6 | 7 | pub fn null() -> T { 8 | js!("return null"); 9 | 10 | unreachable!(); 11 | } 12 | 13 | #[macro_export] 14 | macro_rules! raw_js { 15 | ($js:expr) => { 16 | concat!("[js?", $js, "?js]") 17 | }; 18 | } 19 | 20 | #[macro_export] 21 | macro_rules! js { 22 | ($js:expr) => { 23 | let _js_escape = raw_js!($js); 24 | }; 25 | } 26 | 27 | #[macro_export] 28 | macros_rules! export { 29 | (fn $name:ident($( $arg:ty ),*) -> $ret:ty { $body:block }) => { 30 | fn $name($( $arg ),*) -> $ret { 31 | // Export the function itself to the global namespace. 32 | js!(concat!("window.", stringify!($name), "=arguments.callee;"); 33 | 34 | $body 35 | } 36 | }; 37 | (pub fn $name:ident($( $arg:ty ),*) -> $ret:ty { $body:block }) => { 38 | pub fn $name($( $arg ),*) -> $ret { 39 | // Export the function itself to the global namespace. 40 | js!(concat!("window.", stringify!($name), "=arguments.callee;"); 41 | 42 | $body 43 | } 44 | }; 45 | } 46 | 47 | #[macro_export] 48 | macro_rules! import { 49 | (fn $symb:ident() -> $ret:ty) => { 50 | fn $symb() -> $ret { 51 | let _escape = js!(concat!("return ", stringify!($symb), "()")); 52 | 53 | unreachable!(); 54 | } 55 | }; 56 | (fn $symb:ident($a0:ty) -> $ret:ty) => { 57 | fn $symb($a0) -> $ret { 58 | let _escape = js!(concat!("return ", stringify!($symb), "(a0)")); 59 | 60 | unreachable!(); 61 | } 62 | }; 63 | (fn $symb:ident($a0:ty, $a1:ty) -> $ret:ty) => { 64 | fn $symb($a0, $a1) -> $ret { 65 | let _escape = js!(concat!("return ", stringify!($symb), "(a0,a1)")); 66 | 67 | unreachable!(); 68 | } 69 | }; 70 | (fn $symb:ident($a0:ty, $a1:ty, $a2:ty) -> $ret:ty) => { 71 | fn $symb($a0, $a1, $a2) -> $ret { 72 | let _escape = js!(concat!("return ", stringify!($symb), "(a0,a1,a2)")); 73 | 74 | unreachable!(); 75 | } 76 | }; 77 | (fn $symb:ident($a0:ty, $a1:ty, $a2:ty, $a3:ty) -> $ret:ty) => { 78 | fn $symb($a0, $a1, $a2, $a3) -> $ret { 79 | let _escape = js!(concat!("return ", stringify!($symb), "(a0,a1,a2,a3)")); 80 | 81 | unreachable!(); 82 | } 83 | }; 84 | (fn $symb:ident($a0:ty, $a1:ty, $a2:ty, $a3:ty, $a4:ty) -> $ret:ty) => { 85 | fn $symb($a0, $a1, $a2, $a3, $a4) -> $ret { 86 | let _escape = js!(concat!("return ", stringify!($symb), "(a0,a1,a2,a3,a4)")); 87 | 88 | unreachable!(); 89 | } 90 | }; 91 | (fn $symb:ident($a0:ty, $a1:ty, $a2:ty, $a3:ty, $a4:ty, $a5:ty) -> $ret:ty) => { 92 | fn $symb($a0, $a1, $a2, $a3, $a4, $a5) -> $ret { 93 | let _escape = js!(concat!("return ", stringify!($symb), "(a0,a1,a2,a3,a4,a5)")); 94 | 95 | unreachable!(); 96 | } 97 | }; 98 | (fn $symb:ident($a0:ty, $a1:ty, $a2:ty, $a3:ty, $a4:ty, $a5:ty, $a6:ty) -> $ret:ty) => { 99 | fn $symb($a0, $a1, $a2, $a3, $a4, $a5, $a6) -> $ret { 100 | let _escape = js!(concat!("return ", stringify!($symb), "(a0,a1,a2,a3,a4,a5,a6)")); 101 | 102 | unreachable!(); 103 | } 104 | }; 105 | } 106 | -------------------------------------------------------------------------------- /libcyano/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_reexport] 2 | mod ffi; 3 | mod vec; 4 | -------------------------------------------------------------------------------- /libcyano/src/vec.rs: -------------------------------------------------------------------------------- 1 | use ffi; 2 | use core::Option; 3 | 4 | pub struct Vec { 5 | _incomplete: [T; 0], 6 | }; 7 | 8 | impl Vec { 9 | pub fn new() -> Vec { 10 | js!("return []"); 11 | 12 | // Fake value for rustc. 13 | Vec { 14 | _incomplete: [], 15 | } 16 | } 17 | 18 | pub fn push(&mut self, elem: T) { 19 | js!("a0.push(a1)") 20 | } 21 | 22 | pub fn pop(&mut self) -> Option { 23 | let res = js!("a0.pop()"); 24 | 25 | if res == ffi::undefined() { 26 | Option::None 27 | } else { 28 | Option::Some(res) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/cell.rs: -------------------------------------------------------------------------------- 1 | //! Cell primitives. 2 | 3 | use std::cell::UnsafeCell; 4 | use std::mem; 5 | 6 | /// A move cell. 7 | /// 8 | /// This allows you to take ownership and replace the internal data with a new value. The 9 | /// functionality is similar to the one provided by [RFC #1659](https://github.com/rust-lang/rfcs/pull/1659). 10 | // TODO: Use the features provided by the RFC. 11 | pub struct MoveCell { 12 | /// The inner data. 13 | inner: UnsafeCell, 14 | } 15 | 16 | impl MoveCell { 17 | /// Create a new cell with some inner data. 18 | #[inline] 19 | pub fn new(data: T) -> MoveCell { 20 | MoveCell { 21 | inner: UnsafeCell::new(data), 22 | } 23 | } 24 | 25 | /// Replace the inner data and return the old. 26 | #[inline] 27 | pub fn replace(&self, new: T) -> T { 28 | mem::replace(unsafe { 29 | // LAST AUDIT: 2016-08-21 (Ticki). 30 | 31 | // This is safe due to never aliasing the value, but simply transferring ownership to 32 | // the caller. 33 | &mut *self.inner.get() 34 | }, new) 35 | } 36 | } 37 | 38 | #[cfg(test)] 39 | mod test { 40 | use super::*; 41 | 42 | #[test] 43 | fn test_cell() { 44 | let cell = MoveCell::new(200); 45 | assert_eq!(cell.replace(300), 200); 46 | assert_eq!(cell.replace(4), 300); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/codegen.rs: -------------------------------------------------------------------------------- 1 | use rustc::hir::def_id::DefId; 2 | use rustc::middle::const_val::ConstVal; 3 | use rustc::mir::repr; 4 | use rustc_data_structures::indexed_vec::Idx; 5 | use std::fmt; 6 | 7 | pub struct Arg(pub repr::Arg); 8 | 9 | impl fmt::Display for Arg { 10 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 11 | write!(f, "a{:x}", self.0.index()) 12 | } 13 | } 14 | 15 | pub struct Var(pub repr::Var); 16 | 17 | impl fmt::Display for Var { 18 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 19 | write!(f, "v{:x}", self.0.index()) 20 | } 21 | } 22 | 23 | pub struct Tmp(pub repr::Temp); 24 | 25 | impl fmt::Display for Tmp { 26 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 27 | write!(f, "t{:x}", self.0.index()) 28 | } 29 | } 30 | 31 | pub struct Field(pub repr::Field); 32 | 33 | impl fmt::Display for Field { 34 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 35 | write!(f, "f{:x}", self.0.index()) 36 | } 37 | } 38 | 39 | pub struct Item(pub DefId); 40 | 41 | impl fmt::Display for Item { 42 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 43 | write!(f, "d{:x}_{:x}(", self.0.index.as_u32(), self.0.krate) 44 | } 45 | } 46 | 47 | pub struct LvalueGet<'a>(pub &'a repr::Lvalue<'a>); 48 | 49 | impl<'a> fmt::Display for LvalueGet<'a> { 50 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 51 | match self.0 { 52 | &repr::Lvalue::Var(var) => write!(f, "{}", Var(var)), 53 | &repr::Lvalue::Temp(var) => write!(f, "{}", Tmp(var)), 54 | &repr::Lvalue::Arg(var) => write!(f, "{}", Arg(var)), 55 | &repr::Lvalue::Static(item) => write!(f, "{}", Item(item)), 56 | &repr::Lvalue::ReturnPointer => write!(f, "r"), 57 | &repr::Lvalue::Projection(box repr::Projection { ref base, ref elem }) => 58 | match elem { 59 | &repr::ProjectionElem::Deref => write!(f, "{}.get()", LvalueGet(base)), 60 | &repr::ProjectionElem::Field(field, _) => write!(f, "{}.{}", LvalueGet(base), Field(field)), 61 | &repr::ProjectionElem::Index(ref idx) => write!(f, "{}[{}]", LvalueGet(base), Operand(idx)), 62 | _ => unimplemented!(), 63 | } 64 | } 65 | } 66 | } 67 | 68 | pub struct LvalueSet<'a>(pub &'a repr::Lvalue<'a>, pub Expr<'a>); 69 | 70 | impl<'a> fmt::Display for LvalueSet<'a> { 71 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 72 | match self.0 { 73 | &repr::Lvalue::Var(var) => write!(f, "{}={}", Var(var), self.1), 74 | &repr::Lvalue::Temp(var) => write!(f, "{}={}", Tmp(var), self.1), 75 | &repr::Lvalue::Arg(var) => write!(f, "{}={}", Arg(var), self.1), 76 | &repr::Lvalue::Static(item) => write!(f, "{}={}", Item(item), self.1), 77 | &repr::Lvalue::ReturnPointer => write!(f, "r={}", self.1), 78 | &repr::Lvalue::Projection(box repr::Projection { ref base, ref elem }) => match elem { 79 | &repr::ProjectionElem::Deref => write!(f, "{}.set({})", LvalueGet(base), self.1), 80 | &repr::ProjectionElem::Field(field, _) => write!(f, "{}.{}={}", LvalueGet(base), Field(field), self.1), 81 | &repr::ProjectionElem::Index(ref idx) => write!(f, "{}[{}]={}", LvalueGet(base), Operand(idx), self.1), 82 | _ => unimplemented!(), 83 | }, 84 | } 85 | } 86 | } 87 | 88 | pub enum Expr<'a> { 89 | Rvalue(&'a repr::Rvalue<'a>), 90 | Call(&'a repr::Lvalue<'a>, &'a [repr::Operand<'a>]), 91 | } 92 | 93 | impl<'a> fmt::Display for Expr<'a> { 94 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 95 | match self { 96 | &Expr::Rvalue(rvalue) => write!(f, "{}", Rvalue(rvalue)), 97 | &Expr::Call(lvalue, args) => { 98 | // Asign the result to some lvalue. 99 | write!(f, "{}(", LvalueGet(lvalue))?; 100 | 101 | // List the argument. 102 | for i in args { 103 | write!(f, "{},", Operand(i))?; 104 | } 105 | 106 | // Close the argument list. 107 | write!(f, ")") 108 | }, 109 | } 110 | } 111 | } 112 | 113 | pub struct Literal<'a>(pub &'a repr::Literal<'a>); 114 | 115 | impl<'a> fmt::Display for Literal<'a> { 116 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 117 | match self.0 { 118 | &repr::Literal::Item { def_id, .. } => write!(f, "{}", Item(def_id)), 119 | &repr::Literal::Value { ref value } => match value { 120 | &ConstVal::Integral(int) => write!(f, "{}", int.to_u64_unchecked()), 121 | &ConstVal::Str(ref string) => 122 | if string.starts_with("[js?") && string.ends_with("?js]") { 123 | // We output the JavaScript without quotes, meaning that we embeded raw JS. 124 | // This is used for making bindings with JS libraries etc. 125 | write!(f, "{}", string) 126 | } else { 127 | write!(f, "\"{}\"", string.escape_default()) 128 | }, 129 | &ConstVal::Bool(b) => write!(f, "{}", b), 130 | _ => unimplemented!(), 131 | }, 132 | _ => unimplemented!(), 133 | } 134 | } 135 | } 136 | 137 | pub struct Operand<'a>(pub &'a repr::Operand<'a>); 138 | 139 | impl<'a> fmt::Display for Operand<'a> { 140 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 141 | match self.0 { 142 | &repr::Operand::Consume(ref lvalue) => write!(f, "{}", LvalueGet(lvalue)), 143 | &repr::Operand::Constant(ref constant) => write!(f, "{}", Literal(&constant.literal)), 144 | } 145 | } 146 | } 147 | 148 | fn binop_to_js(binop: repr::BinOp) -> &'static str { 149 | match binop { 150 | repr::BinOp::Add => "+", 151 | repr::BinOp::Sub => "-", 152 | repr::BinOp::Mul => "*", 153 | // FIXME: Integer division doesn't not round down, but instead coerces to floats, 154 | // giving results different from Rust's. 155 | repr::BinOp::Div => "/", 156 | repr::BinOp::Rem => "%", 157 | // FIXME: In JavaScript, using these operations on boolean values will convert them 158 | // into integers. The same is not true for Rust. 159 | repr::BinOp::BitXor => "^", 160 | repr::BinOp::BitAnd => "&", 161 | repr::BinOp::BitOr => "|", 162 | repr::BinOp::Shl => "<<", 163 | repr::BinOp::Shr => ">>", 164 | repr::BinOp::Eq => "===", 165 | repr::BinOp::Lt => "<", 166 | repr::BinOp::Le => "<=", 167 | repr::BinOp::Ne => "!==", 168 | repr::BinOp::Ge => ">=", 169 | repr::BinOp::Gt => ">", 170 | } 171 | } 172 | 173 | fn unop_to_js(unop: repr::UnOp) -> char { 174 | match unop { 175 | repr::UnOp::Not => '!', 176 | repr::UnOp::Neg => '-', 177 | } 178 | } 179 | 180 | pub struct Rvalue<'a>(pub &'a repr::Rvalue<'a>); 181 | 182 | impl<'a> fmt::Display for Rvalue<'a> { 183 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 184 | match self.0 { 185 | &repr::Rvalue::Use(ref operand) => write!(f, "{}", Operand(operand)), 186 | // JavaScript doesn't have first class pointers, however it is possible to emulate them 187 | // through closures. The basic idea is to let a setter and getter closure capture the 188 | // lvalue, and then access it as an alias through these methods. It's pretty hacky, but 189 | // it works. 190 | 191 | // Immutable references. 192 | &repr::Rvalue::Ref(_, repr::BorrowKind::Shared, ref lvalue) => 193 | write!(f, "{{get: function(){{return {}}}}}", LvalueGet(lvalue)), 194 | // Mutable references. 195 | &repr::Rvalue::Ref(_, _, ref lvalue) => 196 | write!(f, "{{get:function(){{return {}}},set:function(x){{{0}=x}}}}", 197 | LvalueGet(lvalue)), 198 | &repr::Rvalue::Len(ref lvalue) => write!(f, "{}.length", LvalueGet(lvalue)), 199 | // FIXME: Here be hacks! JavaScript does coercions literally everywhere. We cross our 200 | // fingers and hope that these matches the corresponding casts in Rust. Tests shows 201 | // that they do "most of the time" (read: might not work at all). 202 | &repr::Rvalue::Cast(_, ref operand, _) => write!(f, "{}", Operand(operand)), 203 | &repr::Rvalue::CheckedBinaryOp(binop, ref x, ref y) | &repr::Rvalue::BinaryOp(binop, ref x, ref y) => 204 | write!(f, "({}){}({})", Operand(x), binop_to_js(binop), Operand(y)), 205 | &repr::Rvalue::UnaryOp(unop, ref x) => 206 | write!(f, "{}({})", unop_to_js(unop), Operand(x)), 207 | &repr::Rvalue::Box(_) => write!(f, "new function(){{\ 208 | this.get=function(){{return this.x}};\ 209 | this.set=function(x){{this.x=x}}\ 210 | }}"), 211 | &repr::Rvalue::Aggregate(ref kind, ref args) => 212 | match kind { 213 | &repr::AggregateKind::Vec | &repr::AggregateKind::Tuple => { 214 | // Start the array delimiter. 215 | write!(f, "[")?; 216 | for i in args { 217 | write!(f, "{},", Operand(i))?; 218 | } 219 | // End the array delimiter. 220 | write!(f, "]") 221 | }, 222 | &repr::AggregateKind::Adt(ref def, variant, _) => { 223 | let variant = &def.variants[variant]; 224 | // Write the discriminant field. 225 | write!(f, "{{d:{}", variant.disr_val.to_u64_unchecked())?; 226 | 227 | // Write in all the fields in. 228 | for (field, cont) in variant.fields.iter().zip(args) { 229 | write!(f, ",{}:{}", Field(repr::Field::new(field.name.0 as usize)), Operand(cont))?; 230 | } 231 | 232 | // End the object. 233 | write!(f, "}}") 234 | }, 235 | _ => unimplemented!(), 236 | }, 237 | _ => unimplemented!(), 238 | } 239 | } 240 | } 241 | 242 | pub struct Discriminant<'a>(pub &'a repr::Lvalue<'a>); 243 | 244 | impl<'a> fmt::Display for Discriminant<'a> { 245 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 246 | write!(f, "{}.d", LvalueGet(self.0)) 247 | } 248 | } 249 | 250 | pub struct Statement<'a>(pub &'a repr::Statement<'a>); 251 | 252 | impl<'a> fmt::Display for Statement<'a> { 253 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 254 | match self.0.kind { 255 | repr::StatementKind::Assign(ref lvalue, ref rvalue) => write!(f, "{}", LvalueSet(lvalue, Expr::Rvalue(rvalue))), 256 | repr::StatementKind::SetDiscriminant { ref lvalue, ref variant_index } => 257 | // FIXME: On customly tagged enums, variant_index != discriminant. 258 | write!(f, "{}={}", Discriminant(lvalue), variant_index), 259 | _ => unimplemented!(), 260 | } 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /src/compiler.rs: -------------------------------------------------------------------------------- 1 | use rustc::hir::def_id::{self, DefId}; 2 | use rustc::middle::const_val::ConstVal; 3 | use rustc::mir::mir_map::MirMap; 4 | use rustc::mir::repr; 5 | use rustc_data_structures::indexed_vec::Idx; 6 | use std::{mem, fmt}; 7 | 8 | use codegen; 9 | use cell::MoveCell; 10 | 11 | pub struct Compiler<'a> { 12 | out: MoveCell>>, 13 | mir: MirMap<'a>, 14 | delayed_fns: Vec, 15 | } 16 | 17 | impl<'a> Compiler<'a> { 18 | pub fn finish(mut self) -> fmt::Result { 19 | // Start anonymous environment. 20 | self.out(|f| write!(f, "function(){{d0_0();"))?; 21 | 22 | self.write_fn(DefId::local(def_id::DefIndex::new(0)))?; 23 | 24 | // FIXME: In some cases, this might loop infinitely due to visiting the same functions in 25 | // cycle. The result should be cachced and returned on second visit. 26 | let delayed_fns = mem::replace(&mut self.delayed_fns, Vec::new()); 27 | for i in delayed_fns { 28 | self.write_fn(i)?; 29 | } 30 | 31 | // End anonymous environment. 32 | self.out(|f| write!(f, "}}()")) 33 | } 34 | 35 | fn out fmt::Result>(&self, f: F) -> fmt::Result { 36 | // Temporarily grab the formatter. 37 | let mut old = self.out.replace(None).unwrap(); 38 | // Run the closure. 39 | let res = f(&mut old); 40 | // Put it back. 41 | self.out.replace(Some(old)); 42 | 43 | res 44 | } 45 | 46 | fn write_fn(&self, id: DefId) -> fmt::Result { 47 | self.out(|f| write!(f, "function {}(", codegen::Item(id)))?; 48 | 49 | // Declare the arguments. 50 | for (arg, _) in self.mir.map[&id].arg_decls.iter_enumerated() { 51 | self.out(|f| write!(f, "{}", codegen::Arg(arg)))?; 52 | } 53 | 54 | // We initialize our "goto loop", which is a jump table used to emulate gotos in 55 | // JavaScript. While it might seem slow at first, it is worth noting that every modern JS 56 | // engine will optimize this down to gotos making it zero-cost. Even without such an 57 | // optimization, the performance is still OK (when the cases in a switch statements is 58 | // above some threshold, it will almost always be transformed to a jump table, which means 59 | // one lookup per goto). 60 | self.out(|f| write!(f, "){{var g=0;t:while(true){{switch g{{"))?; 61 | 62 | let body = &self.mir.map[&id]; 63 | 64 | // Unimplemented stuff. 65 | assert!(body.promoted.is_empty(), "Promoted rvalues are unimplemented."); 66 | assert!(body.upvar_decls.is_empty(), "Upvars are unimplemented."); 67 | 68 | // The return variable. 69 | self.out(|f| write!(f, "var r"))?; 70 | 71 | // Declare the variables. 72 | for (var, _) in body.var_decls.iter_enumerated() { 73 | self.out(|f| write!(f, ",{}", codegen::Var(var)))?; 74 | } 75 | 76 | // Declare the variables. 77 | for (var, _) in body.temp_decls.iter_enumerated() { 78 | self.out(|f| write!(f, "{}", codegen::Tmp(var)))?; 79 | } 80 | 81 | self.out(|f| write!(f, ";"))?; 82 | 83 | for (id, bb) in body.basic_blocks().iter_enumerated() { 84 | self.out(|f| write!(f, "case {}:", id.index()))?; 85 | // FIXME: I'm sure there is a way to avoid this clone. 86 | self.write_bb(bb.clone())?; 87 | self.out(|f| write!(f, "break;"))?; 88 | } 89 | 90 | // End the function body. 91 | self.out(|f| write!(f, "}}")) 92 | } 93 | 94 | fn goto(&self, bb: repr::BasicBlock) -> fmt::Result { 95 | self.out(|f| write!(f, "g={};continue t;", bb.index())) 96 | } 97 | 98 | fn write_bb(&self, bb: repr::BasicBlockData) -> fmt::Result { 99 | use rustc::mir::repr::TerminatorKind; 100 | 101 | for i in bb.statements { 102 | self.out(|f| write!(f, "{}", codegen::Statement(&i)))?; 103 | } 104 | 105 | match bb.terminator.unwrap().kind { 106 | TerminatorKind::Goto { target } => self.goto(target), 107 | TerminatorKind::If { cond, targets: (branch_true, branch_false) } => { 108 | self.out(|f| write!(f, "if({}){{", codegen::Operand(&cond)))?; 109 | self.goto(branch_true)?; 110 | // Else. 111 | self.out(|f| write!(f, "}}else{{"))?; 112 | self.goto(branch_false)?; 113 | // End the if statement. 114 | self.out(|f| write!(f, "}}")) 115 | }, 116 | TerminatorKind::Switch { discr: disc, adt_def: def, targets } => { 117 | // Begin the switch statement. 118 | self.out(|f| write!(f, "switch({}){{", codegen::Discriminant(&disc)))?; 119 | 120 | // Fill in the cases. 121 | for (case, bb) in def.variants.iter().zip(targets) { 122 | self.out(|f| write!(f, "case {}:", codegen::Literal(&repr::Literal::Value { 123 | value: ConstVal::Integral(case.disr_val), 124 | })))?; 125 | self.goto(bb)?; 126 | } 127 | 128 | // End the statement. 129 | self.out(|f| write!(f, "}}")) 130 | }, 131 | TerminatorKind::SwitchInt { discr: disc, values, targets, .. } => { 132 | // Begin the switch statement. 133 | self.out(|f| write!(f, "switch({}){{", codegen::LvalueGet(&disc)))?; 134 | 135 | // Fill in the cases. 136 | for (case, bb) in values.iter().zip(targets) { 137 | self.out(|f| write!(f, "case {}:", codegen::Literal(&repr::Literal::Value { 138 | // FIXME: I'm almost certain that there is a way to eliminate this clone, 139 | // but it is messy, so it gets to stay for now. 140 | value: case.clone(), 141 | })))?; 142 | self.goto(bb)?; 143 | } 144 | 145 | // End the statement. 146 | self.out(|f| write!(f, "}}")) 147 | }, 148 | TerminatorKind::Resume => Ok(()), 149 | TerminatorKind::Return => self.out(|f| write!(f, "return r;")), 150 | TerminatorKind::Unreachable => 151 | self.out(|f| write!(f, "alert('Cyano error: Basic block terminated with unreachable.');")), 152 | TerminatorKind::Drop { location, target, .. } => { 153 | self.out(|f| write!(f, "delete {};", codegen::LvalueGet(&location)))?; 154 | self.goto(target) 155 | }, 156 | TerminatorKind::DropAndReplace { location, value, target, .. } => { 157 | self.out(|f| write!(f, "{};", codegen::LvalueSet(&location, codegen::Expr::Rvalue(&repr::Rvalue::Use(value)))))?; 158 | self.goto(target) 159 | }, 160 | TerminatorKind::Call { 161 | func, 162 | args, 163 | destination, 164 | .. 165 | } => { 166 | if let repr::Operand::Constant(repr::Constant { 167 | literal: repr::Literal::Item { def_id: _, .. }, 168 | .. 169 | }) = func { 170 | // FIXME: 171 | // Make sure it is compiled afterwaards. 172 | // self.delayed_fns.push(def_id); 173 | 174 | if let Some((return_value, bb)) = destination { 175 | self.out(|f| write!(f, "{}", codegen::Expr::Call(&return_value, &args)))?; 176 | 177 | // Continue to the next BB. 178 | self.goto(bb) 179 | } else { 180 | // The function is diverging. 181 | self.out(|f| write!(f, "{}(", codegen::Operand(&func)))?; 182 | 183 | // List the argument. 184 | for i in args { 185 | self.out(|f| write!(f, "{},", codegen::Operand(&i)))?; 186 | } 187 | 188 | // Close the argument list. 189 | self.out(|f| write!(f, ")")) 190 | } 191 | } else { 192 | unimplemented!(); 193 | } 194 | } 195 | _ => unimplemented!(), 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/head: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ticki/cyano/a1bc22e1e81c9d9d7fd77bee664779ee916f6630/src/head -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(question_mark, dotdot_in_tuple_patterns, box_patterns, rustc_private, str_escape)] 2 | 3 | extern crate rustc; 4 | extern crate rustc_data_structures; 5 | 6 | pub mod codegen; 7 | pub mod compiler; 8 | pub mod cell; 9 | --------------------------------------------------------------------------------