Auto merge of #30105 - faineance:master, r=nrc

Issue: #30058
Updated for:
 - Stmt
 - BinOp_
 - UnOp
 - UintTy, IntTy and FloatTy
 - Lit
 - Generics

A possible inconsistancy?
The `Stmt` methods are on the spanned varient:
```rust
pub type Stmt = Spanned<Stmt_>;

impl Stmt {
    pub fn id(s: &Stmt) -> Option<NodeId> {
        match s.node {
          StmtDecl(_, id) => Some(id),
          StmtExpr(_, id) => Some(id),
          StmtSemi(_, id) => Some(id),
          StmtMac(..) => None,
      }
  }
}
```
Whilst the methods for BinOp are on the non spanned version.
````rust
impl BinOp_ {
    pub fn to_string(op: BinOp_) -> &'static str { ... }
    pub fn lazy(b: BinOp_) -> bool { ... }

    pub fn is_shift(b: BinOp_) -> bool { ... }
    pub fn is_comparison(b: BinOp_) -> bool { ... }
    /// Returns `true` if the binary operator takes its arguments by value
    pub fn is_by_value(b: BinOp_) -> bool { ... }

}
pub type BinOp = Spanned<BinOp_>;
````
r? @Manishearth
This commit is contained in:
bors 2015-12-15 01:18:01 +00:00
commit 8f031bf962
10 changed files with 191 additions and 192 deletions

View File

@ -24,7 +24,7 @@ use middle::ty::{self, TypeAndMut, Ty, HasTypeFlags};
use middle::ty::fold::TypeFoldable;
use std::fmt;
use syntax::{abi, ast_util};
use syntax::{abi};
use syntax::parse::token;
use syntax::ast::CRATE_NODE_ID;
use rustc_front::hir;
@ -778,9 +778,9 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
match *self {
TyBool => write!(f, "bool"),
TyChar => write!(f, "char"),
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)),
TyInt(t) => write!(f, "{}", t.ty_to_string()),
TyUint(t) => write!(f, "{}", t.ty_to_string()),
TyFloat(t) => write!(f, "{}", t.ty_to_string()),
TyBox(typ) => write!(f, "Box<{}>", typ),
TyRawPtr(ref tm) => {
write!(f, "*{} {}", match tm.mutbl {

View File

@ -46,7 +46,7 @@ use std::rc::Rc;
use syntax;
use syntax::util::interner::Interner;
use syntax::codemap::Span;
use syntax::{ast, ast_util, codemap};
use syntax::{ast, codemap};
use syntax::parse::token;
@ -936,13 +936,13 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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)
(int_ty.ty_to_string(), DW_ATE_signed)
},
ty::TyUint(uint_ty) => {
(ast_util::uint_ty_to_string(uint_ty), DW_ATE_unsigned)
(uint_ty.ty_to_string(), DW_ATE_unsigned)
},
ty::TyFloat(float_ty) => {
(ast_util::float_ty_to_string(float_ty), DW_ATE_float)
(float_ty.ty_to_string(), DW_ATE_float)
},
_ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
};

View File

@ -19,7 +19,6 @@ use middle::subst::{self, Substs};
use middle::ty::{self, Ty};
use rustc_front::hir;
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
@ -44,9 +43,9 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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::TyInt(int_ty) => output.push_str(int_ty.ty_to_string()),
ty::TyUint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
ty::TyFloat(float_ty) => output.push_str(float_ty.ty_to_string()),
ty::TyStruct(def, substs) |
ty::TyEnum(def, substs) => {
push_item_name(cx, def.did, qualified, output);

View File

@ -83,7 +83,7 @@ use trans::type_::Type;
use rustc_front;
use rustc_front::hir;
use syntax::{ast, ast_util, codemap};
use syntax::{ast, codemap};
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::parse::token;
@ -2622,7 +2622,7 @@ fn expr_kind(tcx: &ty::ctxt, expr: &hir::Expr) -> ExprKind {
ExprKind::RvalueDps
}
hir::ExprLit(ref lit) if ast_util::lit_is_str(&**lit) => {
hir::ExprLit(ref lit) if lit.node.is_str() => {
ExprKind::RvalueDps
}

View File

@ -48,7 +48,6 @@ pub use self::PathParameters::*;
use attr::ThinAttributes;
use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
use abi::Abi;
use ast_util;
use ext::base;
use ext::tt::macro_parser;
use owned_slice::OwnedSlice;
@ -427,6 +426,19 @@ impl Generics {
}
}
impl Default for Generics {
fn default() -> Generics {
Generics {
lifetimes: Vec::new(),
ty_params: OwnedSlice::empty(),
where_clause: WhereClause {
id: DUMMY_NODE_ID,
predicates: Vec::new(),
}
}
}
}
/// A `where` clause in a definition
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereClause {
@ -657,6 +669,57 @@ pub enum BinOp_ {
BiGt,
}
impl BinOp_ {
pub fn to_string(&self) -> &'static str {
match *self {
BiAdd => "+",
BiSub => "-",
BiMul => "*",
BiDiv => "/",
BiRem => "%",
BiAnd => "&&",
BiOr => "||",
BiBitXor => "^",
BiBitAnd => "&",
BiBitOr => "|",
BiShl => "<<",
BiShr => ">>",
BiEq => "==",
BiLt => "<",
BiLe => "<=",
BiNe => "!=",
BiGe => ">=",
BiGt => ">"
}
}
pub fn lazy(&self) -> bool {
match *self {
BiAnd | BiOr => true,
_ => false
}
}
pub fn is_shift(&self) -> bool {
match *self {
BiShl | BiShr => true,
_ => false
}
}
pub fn is_comparison(&self) -> bool {
match *self {
BiEq | BiLt | BiLe | BiNe | BiGt | BiGe =>
true,
BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem |
BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr =>
false,
}
}
/// Returns `true` if the binary operator takes its arguments by value
pub fn is_by_value(&self) -> bool {
!BinOp_::is_comparison(self)
}
}
pub type BinOp = Spanned<BinOp_>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@ -669,13 +732,31 @@ pub enum UnOp {
UnNeg
}
impl UnOp {
/// Returns `true` if the unary operator takes its argument by value
pub fn is_by_value(u: UnOp) -> bool {
match u {
UnNeg | UnNot => true,
_ => false,
}
}
pub fn to_string(op: UnOp) -> &'static str {
match op {
UnDeref => "*",
UnNot => "!",
UnNeg => "-",
}
}
}
/// A statement
pub type Stmt = Spanned<Stmt_>;
impl fmt::Debug for Stmt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "stmt({}: {})",
ast_util::stmt_id(self)
self.node.id()
.map_or(Cow::Borrowed("<macro>"),|id|Cow::Owned(id.to_string())),
pprust::stmt_to_string(self))
}
@ -697,6 +778,15 @@ pub enum Stmt_ {
}
impl Stmt_ {
pub fn id(&self) -> Option<NodeId> {
match *self {
StmtDecl(_, id) => Some(id),
StmtExpr(_, id) => Some(id),
StmtSemi(_, id) => Some(id),
StmtMac(..) => None,
}
}
pub fn attrs(&self) -> &[Attribute] {
match *self {
StmtDecl(ref d, _) => d.attrs(),
@ -1226,6 +1316,16 @@ pub enum Lit_ {
LitBool(bool),
}
impl Lit_ {
/// Returns true if this literal is a string and false otherwise.
pub fn is_str(&self) -> bool {
match *self {
LitStr(..) => true,
_ => false,
}
}
}
// NB: If you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@ -1301,11 +1401,37 @@ 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))
write!(f, "{}", self.ty_to_string())
}
}
impl IntTy {
pub fn ty_to_string(&self) -> &'static str {
match *self {
TyIs => "isize",
TyI8 => "i8",
TyI16 => "i16",
TyI32 => "i32",
TyI64 => "i64"
}
}
pub fn val_to_string(&self, 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, self.ty_to_string())
}
pub fn ty_max(&self) -> u64 {
match *self {
TyI8 => 0x80,
TyI16 => 0x8000,
TyIs | TyI32 => 0x80000000, // actually ni about TyIs
TyI64 => 0x8000000000000000
}
}
pub fn bit_width(&self) -> Option<usize> {
Some(match *self {
TyIs => return None,
@ -1327,6 +1453,29 @@ pub enum UintTy {
}
impl UintTy {
pub fn ty_to_string(&self) -> &'static str {
match *self {
TyUs => "usize",
TyU8 => "u8",
TyU16 => "u16",
TyU32 => "u32",
TyU64 => "u64"
}
}
pub fn val_to_string(&self, val: u64) -> String {
format!("{}{}", val, self.ty_to_string())
}
pub fn ty_max(&self) -> u64 {
match *self {
TyU8 => 0xff,
TyU16 => 0xffff,
TyUs | TyU32 => 0xffffffff, // actually ni about TyUs
TyU64 => 0xffffffffffffffff
}
}
pub fn bit_width(&self) -> Option<usize> {
Some(match *self {
TyUs => return None,
@ -1346,7 +1495,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))
write!(f, "{}", self.ty_to_string())
}
}
@ -1364,11 +1513,18 @@ impl fmt::Debug for FloatTy {
impl fmt::Display for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", ast_util::float_ty_to_string(*self))
write!(f, "{}", self.ty_to_string())
}
}
impl FloatTy {
pub fn ty_to_string(&self) -> &'static str {
match *self {
TyF32 => "f32",
TyF64 => "f64",
}
}
pub fn bit_width(&self) -> usize {
match *self {
TyF32 => 32,

View File

@ -10,7 +10,6 @@
use ast::*;
use ast;
use ast_util;
use codemap;
use codemap::Span;
use owned_slice::OwnedSlice;
@ -28,144 +27,10 @@ pub fn path_name_i(idents: &[Ident]) -> String {
idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
}
pub fn stmt_id(s: &Stmt) -> Option<NodeId> {
match s.node {
StmtDecl(_, id) => Some(id),
StmtExpr(_, id) => Some(id),
StmtSemi(_, id) => Some(id),
StmtMac(..) => None,
}
}
pub fn binop_to_string(op: BinOp_) -> &'static str {
match op {
BiAdd => "+",
BiSub => "-",
BiMul => "*",
BiDiv => "/",
BiRem => "%",
BiAnd => "&&",
BiOr => "||",
BiBitXor => "^",
BiBitAnd => "&",
BiBitOr => "|",
BiShl => "<<",
BiShr => ">>",
BiEq => "==",
BiLt => "<",
BiLe => "<=",
BiNe => "!=",
BiGe => ">=",
BiGt => ">"
}
}
pub fn lazy_binop(b: BinOp_) -> bool {
match b {
BiAnd => true,
BiOr => true,
_ => false
}
}
pub fn is_shift_binop(b: BinOp_) -> bool {
match b {
BiShl => true,
BiShr => true,
_ => false
}
}
pub fn is_comparison_binop(b: BinOp_) -> bool {
match b {
BiEq | BiLt | BiLe | BiNe | BiGt | BiGe =>
true,
BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem |
BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr =>
false,
}
}
/// Returns `true` if the binary operator takes its arguments by value
pub fn is_by_value_binop(b: BinOp_) -> bool {
!is_comparison_binop(b)
}
/// Returns `true` if the unary operator takes its argument by value
pub fn is_by_value_unop(u: UnOp) -> bool {
match u {
UnNeg | UnNot => true,
_ => false,
}
}
pub fn unop_to_string(op: UnOp) -> &'static str {
match op {
UnDeref => "*",
UnNot => "!",
UnNeg => "-",
}
}
pub fn is_path(e: P<Expr>) -> bool {
match e.node { ExprPath(..) => true, _ => false }
}
pub fn int_ty_to_string(t: IntTy) -> &'static str {
match t {
TyIs => "isize",
TyI8 => "i8",
TyI16 => "i16",
TyI32 => "i32",
TyI64 => "i64"
}
}
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,
TyI16 => 0x8000,
TyIs | TyI32 => 0x80000000, // actually ni about TyIs
TyI64 => 0x8000000000000000
}
}
pub fn uint_ty_to_string(t: UintTy) -> &'static str {
match t {
TyUs => "usize",
TyU8 => "u8",
TyU16 => "u16",
TyU32 => "u32",
TyU64 => "u64"
}
}
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,
TyU16 => 0xffff,
TyUs | TyU32 => 0xffffffff, // actually ni about TyUs
TyU64 => 0xffffffffffffffff
}
}
pub fn float_ty_to_string(t: FloatTy) -> &'static str {
match t {
TyF32 => "f32",
TyF64 => "f64",
}
}
// convert a span and an identifier to the corresponding
// 1-segment path
@ -236,17 +101,6 @@ pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
}
}
pub fn empty_generics() -> Generics {
Generics {
lifetimes: Vec::new(),
ty_params: OwnedSlice::empty(),
where_clause: WhereClause {
id: DUMMY_NODE_ID,
predicates: Vec::new(),
}
}
}
// ______________________________________________________________________
// Enumerating the IDs which appear in an AST
@ -351,7 +205,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
fn visit_stmt(&mut self, statement: &Stmt) {
self.operation
.visit_id(ast_util::stmt_id(statement).expect("attempted to visit unexpanded stmt"));
.visit_id(statement.node.id().expect("attempted to visit unexpanded stmt"));
visit::walk_stmt(self, statement)
}
@ -519,14 +373,6 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo
})
}
/// Returns true if this literal is a string and false otherwise.
pub fn lit_is_str(lit: &Lit) -> bool {
match lit.node {
LitStr(..) => true,
_ => false,
}
}
#[cfg(test)]
mod tests {
use ast::*;

View File

@ -11,7 +11,6 @@
use abi;
use ast::{Ident, Generics, Expr};
use ast;
use ast_util;
use attr;
use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
use ext::base::ExtCtxt;
@ -991,7 +990,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
name,
inputs,
output,
ast_util::empty_generics(),
Generics::default(),
body)
}
@ -1029,7 +1028,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn item_enum(&self, span: Span, name: Ident,
enum_definition: ast::EnumDef) -> P<ast::Item> {
self.item_enum_poly(span, name, enum_definition,
ast_util::empty_generics())
Generics::default())
}
fn item_struct(&self, span: Span, name: Ident,
@ -1038,7 +1037,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
span,
name,
struct_def,
ast_util::empty_generics()
Generics::default()
)
}
@ -1086,7 +1085,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> P<ast::Item> {
self.item_ty_poly(span, name, ty, ast_util::empty_generics())
self.item_ty_poly(span, name, ty, Generics::default())
}
fn attribute(&self, sp: Span, mi: P<ast::MetaItem>) -> ast::Attribute {

View File

@ -2872,7 +2872,7 @@ impl<'a> Parser<'a> {
fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) {
debug_assert!(outer_op.is_comparison());
match lhs.node {
ExprBinary(op, _, _) if ast_util::is_comparison_binop(op.node) => {
ExprBinary(op, _, _) if op.node.is_comparison() => {
// respan to include both operators
let op_span = mk_sp(op.span.lo, self.span.hi);
self.span_err(op_span,
@ -4000,7 +4000,7 @@ impl<'a> Parser<'a> {
}
})
} else {
Ok(ast_util::empty_generics())
Ok(ast::Generics::default())
}
}

View File

@ -15,7 +15,6 @@ use ast::{self, TokenTree};
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
use ast::Attribute;
use attr::ThinAttributesExt;
use ast_util;
use util::parser::AssocOp;
use attr;
use owned_slice::OwnedSlice;
@ -649,15 +648,15 @@ pub trait PrintState<'a> {
match t {
ast::SignedIntLit(st, ast::Plus) => {
word(self.writer(),
&ast_util::int_val_to_string(st, i as i64))
&st.val_to_string(i as i64))
}
ast::SignedIntLit(st, ast::Minus) => {
let istr = ast_util::int_val_to_string(st, -(i as i64));
let istr = st.val_to_string(-(i as i64));
word(self.writer(),
&format!("-{}", istr))
}
ast::UnsignedIntLit(ut) => {
word(self.writer(), &ast_util::uint_val_to_string(ut, i))
word(self.writer(), &ut.val_to_string(i))
}
ast::UnsuffixedIntLit(ast::Plus) => {
word(self.writer(), &format!("{}", i))
@ -672,7 +671,7 @@ pub trait PrintState<'a> {
&format!(
"{}{}",
&f,
&ast_util::float_ty_to_string(t)))
t.ty_to_string()))
}
ast::LitFloatUnsuffixed(ref f) => word(self.writer(), &f[..]),
ast::LitBool(val) => {
@ -1528,7 +1527,7 @@ impl<'a> State<'a> {
pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
try!(self.head(""));
let generics = ast_util::empty_generics();
let generics = ast::Generics::default();
try!(self.print_struct(&v.node.data, &generics, v.node.name, v.span, false));
match v.node.disr_expr {
Some(ref d) => {
@ -1948,7 +1947,7 @@ impl<'a> State<'a> {
try!(self.print_expr(lhs));
}
try!(space(&mut self.s));
try!(self.word_space(ast_util::binop_to_string(op.node)));
try!(self.word_space(op.node.to_string()));
if self.check_expr_bin_needs_paren(rhs, op) {
self.print_expr_maybe_paren(rhs)
} else {
@ -1959,7 +1958,7 @@ impl<'a> State<'a> {
fn print_expr_unary(&mut self,
op: ast::UnOp,
expr: &ast::Expr) -> io::Result<()> {
try!(word(&mut self.s, ast_util::unop_to_string(op)));
try!(word(&mut self.s, ast::UnOp::to_string(op)));
self.print_expr_maybe_paren(expr)
}
@ -2151,7 +2150,7 @@ impl<'a> State<'a> {
ast::ExprAssignOp(op, ref lhs, ref rhs) => {
try!(self.print_expr(&**lhs));
try!(space(&mut self.s));
try!(word(&mut self.s, ast_util::binop_to_string(op.node)));
try!(word(&mut self.s, op.node.to_string()));
try!(self.word_space("="));
try!(self.print_expr(&**rhs));
}
@ -3159,7 +3158,7 @@ mod tests {
output: ast::DefaultReturn(codemap::DUMMY_SP),
variadic: false
};
let generics = ast_util::empty_generics();
let generics = ast::Generics::default();
assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal,
ast::Constness::NotConst,
abba_ident,

View File

@ -500,7 +500,7 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> {
let main = ast::ItemFn(ecx.fn_decl(vec![], main_ret_ty),
ast::Unsafety::Normal,
ast::Constness::NotConst,
::abi::Rust, empty_generics(), main_body);
::abi::Rust, ast::Generics::default(), main_body);
let main = P(ast::Item {
ident: token::str_to_ident("main"),
attrs: vec![main_attr],