diff --git a/mk/clean.mk b/mk/clean.mk index bb79e2186ae15..ac34ac506bb17 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -65,7 +65,8 @@ clean-generic-$(2)-$(1): -name '*.def' -o \ -name '*.py' -o \ -name '*.pyc' -o \ - -name '*.bc' \ + -name '*.bc' -o \ + -name '*.rs' \ \) \ | xargs rm -f $(Q)find $(1) \ diff --git a/src/doc/reference.md b/src/doc/reference.md index 2ce21b47dfb13..949ffb9a5f063 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -677,8 +677,8 @@ apply to the crate as a whole. ``` A crate that contains a `main` function can be compiled to an executable. If a -`main` function is present, its return type must be [`unit`](#tuple-types) -and it must take no arguments. +`main` function is present, its return type must be `()` +("[unit](#tuple-types)") and it must take no arguments. # Items and attributes diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 9abab6e04e025..72013c533da51 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -14,8 +14,6 @@ //! and thus uses bitvectors. Your job is simply to specify the so-called //! GEN and KILL bits for each expression. -pub use self::EntryOrExit::*; - use middle::cfg; use middle::cfg::CFGIndex; use middle::ty; @@ -340,7 +338,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { } let indices = get_cfg_indices(id, &self.nodeid_to_index); for &cfgidx in indices { - if !self.each_bit_for_node(Entry, cfgidx, |i| f(i)) { + if !self.each_bit_for_node(EntryOrExit::Entry, cfgidx, |i| f(i)) { return false; } } @@ -363,8 +361,8 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let on_entry = &self.on_entry[start.. end]; let temp_bits; let slice = match e { - Entry => on_entry, - Exit => { + EntryOrExit::Entry => on_entry, + EntryOrExit::Exit => { let mut t = on_entry.to_vec(); self.apply_gen_kill(cfgidx, &mut t); temp_bits = t; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 67ced5d32594d..9db34eef91fd1 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -24,8 +24,7 @@ use middle::ty::{self, TypeAndMut, Ty, HasTypeFlags}; use middle::ty::fold::TypeFoldable; use std::fmt; -use syntax::abi; -use syntax::ast; +use syntax::{abi, ast_util}; use syntax::parse::token; use syntax::ast::CRATE_NODE_ID; use rustc_front::hir; @@ -774,55 +773,14 @@ impl<'tcx> fmt::Display for ty::TraitRef<'tcx> { } } -pub fn int_ty_to_string(t: ast::IntTy, val: Option) -> String { - let s = match t { - ast::TyIs => "isize", - ast::TyI8 => "i8", - ast::TyI16 => "i16", - ast::TyI32 => "i32", - ast::TyI64 => "i64" - }; - - match val { - // cast to a u64 so we can correctly print INT64_MIN. All integral types - // are parsed as u64, so we wouldn't want to print an extra negative - // sign. - Some(n) => format!("{}{}", n as u64, s), - None => s.to_string() - } -} - -pub fn uint_ty_to_string(t: ast::UintTy, val: Option) -> String { - let s = match t { - ast::TyUs => "usize", - ast::TyU8 => "u8", - ast::TyU16 => "u16", - ast::TyU32 => "u32", - ast::TyU64 => "u64" - }; - - match val { - Some(n) => format!("{}{}", n, s), - None => s.to_string() - } -} - - -pub fn float_ty_to_string(t: ast::FloatTy) -> String { - match t { - ast::TyF32 => "f32".to_string(), - ast::TyF64 => "f64".to_string(), - } -} - impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { TyBool => write!(f, "bool"), TyChar => write!(f, "char"), - TyInt(t) => write!(f, "{}", int_ty_to_string(t, None)), - TyUint(t) => write!(f, "{}", uint_ty_to_string(t, None)), - TyFloat(t) => write!(f, "{}", float_ty_to_string(t)), + TyInt(t) => write!(f, "{}", ast_util::int_ty_to_string(t)), + TyUint(t) => write!(f, "{}", ast_util::uint_ty_to_string(t)), + TyFloat(t) => write!(f, "{}", ast_util::float_ty_to_string(t)), TyBox(typ) => write!(f, "Box<{}>", typ), TyRawPtr(ref tm) => { write!(f, "*{} {}", match tm.mutbl { diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs index ade52bfde35e6..be963f30dc1e8 100644 --- a/src/librustc_borrowck/graphviz.rs +++ b/src/librustc_borrowck/graphviz.rs @@ -22,7 +22,6 @@ use borrowck::{BorrowckCtxt, LoanPath}; use dot; use rustc::middle::cfg::CFGIndex; use rustc::middle::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit}; -use rustc::middle::dataflow; use std::rc::Rc; use std::borrow::IntoCow; @@ -134,8 +133,8 @@ impl<'a, 'tcx> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 't fn graph_id(&'a self) -> dot::Id<'a> { self.inner.graph_id() } fn node_id(&'a self, n: &Node<'a>) -> dot::Id<'a> { self.inner.node_id(n) } fn node_label(&'a self, n: &Node<'a>) -> dot::LabelText<'a> { - let prefix = self.dataflow_for(dataflow::Entry, n); - let suffix = self.dataflow_for(dataflow::Exit, n); + let prefix = self.dataflow_for(EntryOrExit::Entry, n); + let suffix = self.dataflow_for(EntryOrExit::Exit, n); let inner_label = self.inner.node_label(n); inner_label .prefix_line(dot::LabelText::LabelStr(prefix.into_cow())) diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs index c09048d677e81..acb47516150cf 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_llvm/diagnostic.rs @@ -37,7 +37,6 @@ impl OptimizationDiagnosticKind { } } -#[derive(Copy, Clone)] pub struct OptimizationDiagnostic { pub kind: OptimizationDiagnosticKind, pub pass_name: *const c_char, @@ -94,7 +93,6 @@ impl InlineAsmDiagnostic { } } -#[derive(Copy, Clone)] pub enum Diagnostic { Optimization(OptimizationDiagnostic), InlineAsm(InlineAsmDiagnostic), diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index addac528aa25c..11b8a6a5faa14 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -46,7 +46,7 @@ use std::rc::Rc; use syntax; use syntax::util::interner::Interner; use syntax::codemap::Span; -use syntax::{ast, codemap}; +use syntax::{ast, ast_util, codemap}; use syntax::parse::token; @@ -932,26 +932,17 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (name, encoding) = match t.sty { ty::TyTuple(ref elements) if elements.is_empty() => - ("()".to_string(), DW_ATE_unsigned), - ty::TyBool => ("bool".to_string(), DW_ATE_boolean), - ty::TyChar => ("char".to_string(), DW_ATE_unsigned_char), - ty::TyInt(int_ty) => match int_ty { - ast::TyIs => ("isize".to_string(), DW_ATE_signed), - ast::TyI8 => ("i8".to_string(), DW_ATE_signed), - ast::TyI16 => ("i16".to_string(), DW_ATE_signed), - ast::TyI32 => ("i32".to_string(), DW_ATE_signed), - ast::TyI64 => ("i64".to_string(), DW_ATE_signed) + ("()", DW_ATE_unsigned), + ty::TyBool => ("bool", DW_ATE_boolean), + ty::TyChar => ("char", DW_ATE_unsigned_char), + ty::TyInt(int_ty) => { + (ast_util::int_ty_to_string(int_ty), DW_ATE_signed) }, - ty::TyUint(uint_ty) => match uint_ty { - ast::TyUs => ("usize".to_string(), DW_ATE_unsigned), - ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned), - ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned), - ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned), - ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned) + ty::TyUint(uint_ty) => { + (ast_util::uint_ty_to_string(uint_ty), DW_ATE_unsigned) }, - ty::TyFloat(float_ty) => match float_ty { - ast::TyF32 => ("f32".to_string(), DW_ATE_float), - ast::TyF64 => ("f64".to_string(), DW_ATE_float), + ty::TyFloat(float_ty) => { + (ast_util::float_ty_to_string(float_ty), DW_ATE_float) }, _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type") }; diff --git a/src/librustc_trans/trans/debuginfo/type_names.rs b/src/librustc_trans/trans/debuginfo/type_names.rs index c6b5ce436835f..6769c010435aa 100644 --- a/src/librustc_trans/trans/debuginfo/type_names.rs +++ b/src/librustc_trans/trans/debuginfo/type_names.rs @@ -19,7 +19,7 @@ use middle::subst::{self, Substs}; use middle::ty::{self, Ty}; use rustc_front::hir; -use syntax::ast; +use syntax::ast_util; // Compute the name of the type as it should be stored in debuginfo. Does not do // any caching, i.e. calling the function twice with the same type will also do @@ -41,21 +41,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, qualified: bool, output: &mut String) { match t.sty { - ty::TyBool => output.push_str("bool"), - ty::TyChar => output.push_str("char"), - ty::TyStr => output.push_str("str"), - ty::TyInt(ast::TyIs) => output.push_str("isize"), - ty::TyInt(ast::TyI8) => output.push_str("i8"), - ty::TyInt(ast::TyI16) => output.push_str("i16"), - ty::TyInt(ast::TyI32) => output.push_str("i32"), - ty::TyInt(ast::TyI64) => output.push_str("i64"), - ty::TyUint(ast::TyUs) => output.push_str("usize"), - ty::TyUint(ast::TyU8) => output.push_str("u8"), - ty::TyUint(ast::TyU16) => output.push_str("u16"), - ty::TyUint(ast::TyU32) => output.push_str("u32"), - ty::TyUint(ast::TyU64) => output.push_str("u64"), - ty::TyFloat(ast::TyF32) => output.push_str("f32"), - ty::TyFloat(ast::TyF64) => output.push_str("f64"), + ty::TyBool => output.push_str("bool"), + ty::TyChar => output.push_str("char"), + ty::TyStr => output.push_str("str"), + ty::TyInt(int_ty) => output.push_str(ast_util::int_ty_to_string(int_ty)), + ty::TyUint(uint_ty) => output.push_str(ast_util::uint_ty_to_string(uint_ty)), + ty::TyFloat(float_ty) => output.push_str(ast_util::float_ty_to_string(float_ty)), ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { push_item_name(cx, def.did, qualified, output); diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 597c517e859e2..d5a2de69c0271 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 df12952fc324f..73d53f974c1bc 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -16,21 +16,87 @@ 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`. This code: +/// +/// ```ignore +/// 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")] diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e4697a7fd9149..ab62c8d9421ae 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1258,7 +1258,7 @@ impl fmt::Debug for IntTy { impl fmt::Display for IntTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", ast_util::int_ty_to_string(*self, None)) + write!(f, "{}", ast_util::int_ty_to_string(*self)) } } @@ -1303,7 +1303,7 @@ impl fmt::Debug for UintTy { impl fmt::Display for UintTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", ast_util::uint_ty_to_string(*self, None)) + write!(f, "{}", ast_util::uint_ty_to_string(*self)) } } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 44334762d9022..489c61b83da75 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -111,26 +111,23 @@ pub fn is_path(e: P) -> bool { match e.node { ExprPath(..) => true, _ => false } } -/// Get a string representation of a signed int type, with its value. -/// We want to avoid "45int" and "-3int" in favor of "45" and "-3" -pub fn int_ty_to_string(t: IntTy, val: Option) -> String { - let s = match t { +pub fn int_ty_to_string(t: IntTy) -> &'static str { + match t { TyIs => "isize", TyI8 => "i8", TyI16 => "i16", TyI32 => "i32", TyI64 => "i64" - }; - - match val { - // cast to a u64 so we can correctly print INT64_MIN. All integral types - // are parsed as u64, so we wouldn't want to print an extra negative - // sign. - Some(n) => format!("{}{}", n as u64, s), - None => s.to_string() } } +pub fn int_val_to_string(t: IntTy, val: i64) -> String { + // cast to a u64 so we can correctly print INT64_MIN. All integral types + // are parsed as u64, so we wouldn't want to print an extra negative + // sign. + format!("{}{}", val as u64, int_ty_to_string(t)) +} + pub fn int_ty_max(t: IntTy) -> u64 { match t { TyI8 => 0x80, @@ -140,23 +137,20 @@ pub fn int_ty_max(t: IntTy) -> u64 { } } -/// Get a string representation of an unsigned int type, with its value. -/// We want to avoid "42u" in favor of "42us". "42uint" is right out. -pub fn uint_ty_to_string(t: UintTy, val: Option) -> String { - let s = match t { +pub fn uint_ty_to_string(t: UintTy) -> &'static str { + match t { TyUs => "usize", TyU8 => "u8", TyU16 => "u16", TyU32 => "u32", TyU64 => "u64" - }; - - match val { - Some(n) => format!("{}{}", n, s), - None => s.to_string() } } +pub fn uint_val_to_string(t: UintTy, val: u64) -> String { + format!("{}{}", val, uint_ty_to_string(t)) +} + pub fn uint_ty_max(t: UintTy) -> u64 { match t { TyU8 => 0xff, @@ -166,10 +160,10 @@ pub fn uint_ty_max(t: UintTy) -> u64 { } } -pub fn float_ty_to_string(t: FloatTy) -> String { +pub fn float_ty_to_string(t: FloatTy) -> &'static str { match t { - TyF32 => "f32".to_string(), - TyF64 => "f64".to_string(), + TyF32 => "f32", + TyF64 => "f64", } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e9c716017c0b3..6de86de9c54eb 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -651,15 +651,15 @@ pub trait PrintState<'a> { match t { ast::SignedIntLit(st, ast::Plus) => { word(self.writer(), - &ast_util::int_ty_to_string(st, Some(i as i64))) + &ast_util::int_val_to_string(st, i as i64)) } ast::SignedIntLit(st, ast::Minus) => { - let istr = ast_util::int_ty_to_string(st, Some(-(i as i64))); + let istr = ast_util::int_val_to_string(st, -(i as i64)); word(self.writer(), &format!("-{}", istr)) } ast::UnsignedIntLit(ut) => { - word(self.writer(), &ast_util::uint_ty_to_string(ut, Some(i))) + word(self.writer(), &ast_util::uint_val_to_string(ut, i)) } ast::UnsuffixedIntLit(ast::Plus) => { word(self.writer(), &format!("{}", i))