From 10c6737ecf8446f053a0423f7e19fd7c72dcadc1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 23 Nov 2015 16:56:07 -0500 Subject: [PATCH 1/3] Fix up docs for char Part of https://github.com/rust-lang/rust/issues/29333 --- src/librustc_unicode/char.rs | 11 +++-- src/libstd/primitive_docs.rs | 83 +++++++++++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 597c517e859..d5a2de69c02 100644 --- a/src/librustc_unicode/char.rs +++ b/src/librustc_unicode/char.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A Unicode scalar value +//! Unicode scalar values //! //! This module provides the `CharExt` trait, as well as its //! implementation for the primitive `char` type, in order to allow @@ -244,11 +244,12 @@ impl char { /// character, as `char`s. /// /// All characters are escaped with Rust syntax of the form `\\u{NNNN}` - /// where `NNNN` is the shortest hexadecimal representation of the code - /// point. + /// where `NNNN` is the shortest hexadecimal representation. /// /// # Examples /// + /// Basic usage: + /// /// ``` /// for c in '❤'.escape_unicode() { /// print!("{}", c); @@ -384,6 +385,8 @@ impl char { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let n = 'ß'.len_utf16(); /// assert_eq!(n, 1); @@ -858,6 +861,8 @@ pub struct DecodeUtf16 /// /// # Examples /// +/// Basic usage: +/// /// ``` /// #![feature(decode_utf16)] /// diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index df12952fc32..aec8b6b1b22 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -16,21 +16,82 @@ mod prim_bool { } #[doc(primitive = "char")] // -/// A Unicode scalar value. +/// A character type. /// -/// A `char` represents a -/// *[Unicode scalar -/// value](http://www.unicode.org/glossary/#unicode_scalar_value)*, as it can -/// contain any Unicode code point except high-surrogate and low-surrogate code -/// points. +/// The `char` type represents a single character. More specifically, since +/// 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode +/// scalar value]', which is similar to, but not the same as, a '[Unicode code +/// point]'. /// -/// As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\] -/// (inclusive) are allowed. A `char` can always be safely cast to a `u32`; -/// however the converse is not always true due to the above range limits -/// and, as such, should be performed via the `from_u32` function. +/// [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value +/// [Unicode code point]: http://www.unicode.org/glossary/#code_point /// -/// *[See also the `std::char` module](char/index.html).* +/// This documentation describes a number of methods and trait implementations on the +/// `char` type. For technical reasons, there is additional, separate +/// documentation in [the `std::char` module](char/index.html) as well. /// +/// # Representation +/// +/// `char` is always four bytes in size. This is a different representation than +/// a given character would have as part of a [`String`], for example: +/// +/// ``` +/// let v = vec!['h', 'e', 'l', 'l', 'o']; +/// +/// // five elements times four bytes for each element +/// assert_eq!(20, v.len() * std::mem::size_of::()); +/// +/// let s = String::from("hello"); +/// +/// // five elements times one byte per element +/// assert_eq!(5, s.len() * std::mem::size_of::()); +/// ``` +/// +/// [`String`]: string/struct.String.html +/// +/// As always, remember that a human intuition for 'character' may not map to +/// Unicode's definitions. For example, emoji symbols such as '❤️' are more than +/// one byte; ❤️ in particular is six: +/// +/// ``` +/// let s = String::from("❤️"); +/// +/// // six bytes times one byte for each element +/// assert_eq!(6, s.len() * std::mem::size_of::()); +/// ``` +/// +/// This also means it won't fit into a `char`, and so trying to create a +/// literal with `let heart = '❤️';` gives an error: +/// +/// ```text +/// error: character literal may only contain one codepoint: '❤ +/// let heart = '❤️'; +/// ^~ +/// ``` +/// +/// Another implication of this is that if you want to do per-`char`acter +/// processing, it can end up using a lot more memory: +/// +/// ``` +/// let s = String::from("love: ❤️"); +/// let v: Vec = s.chars().collect(); +/// +/// assert_eq!(12, s.len() * std::mem::size_of::()); +/// assert_eq!(32, v.len() * std::mem::size_of::()); +/// ``` +/// +/// Or may give you results you may not expect: +/// +/// ``` +/// let s = String::from("❤️"); +/// +/// let mut iter = s.chars(); +/// +/// // we get two chars out of a single ❤️ +/// assert_eq!(Some('\u{2764}'), iter.next()); +/// assert_eq!(Some('\u{fe0f}'), iter.next()); +/// assert_eq!(None, iter.next()); +/// ``` mod prim_char { } #[doc(primitive = "unit")] From 5aa45071db5d00137702e8dbde4af943dcff5de0 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 24 Nov 2015 21:58:18 +0100 Subject: [PATCH 2/3] Add cargo instructions for dinning_philosopher project At this point of the book, reader have likely use `cargo new --bin`, likely 2 times, once if they are lazy. This remind them of the `cargo` syntax. I was myself unsure whether it was `cargo create`, `cargo new`, and whether it would initialize in current working directory or needed a target. --- src/doc/book/dining-philosophers.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/doc/book/dining-philosophers.md b/src/doc/book/dining-philosophers.md index 50d758c3a10..ace0fbc821a 100644 --- a/src/doc/book/dining-philosophers.md +++ b/src/doc/book/dining-philosophers.md @@ -45,8 +45,17 @@ Now, let’s imagine this sequence of events: 6. ... ? All the forks are taken, but nobody can eat! There are different ways to solve this problem. We’ll get to our solution in -the tutorial itself. For now, let’s get started modeling the problem itself. -We’ll start with the philosophers: +the tutorial itself. For now, let’s get started and create a new project with +`cargo`: + +```bash +$ cd ~/projects +$ cargo new dining_philosophers --bin +$ cd dining_philosophers +``` + +Now we can start modeling the problem itself. We’ll start with the philosophers +in `src/main.rs`: ```rust struct Philosopher { From 0fc1f9a2edda6c08fb0857e780b49102420a4179 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Tue, 24 Nov 2015 16:40:25 -0500 Subject: [PATCH 3/3] Add overflow check to `arc::Weak::upgrade` Closes #30031. --- src/liballoc/arc.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index dba9b71c61c..45a47ae075e 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -637,6 +637,11 @@ impl Weak { return None } + // See comments in `Arc::clone` for why we do this (for `mem::forget`). + if n > MAX_REFCOUNT { + unsafe { abort(); } + } + // Relaxed is valid for the same reason it is on Arc's Clone impl let old = inner.strong.compare_and_swap(n, n + 1, Relaxed); if old == n {