2014-07-27 11:50:46 +00:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-04 00:48:01 +00:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2014-11-06 08:05:53 +00:00
|
|
|
pub use self::AnnNode::*;
|
|
|
|
|
2016-02-05 12:13:36 +00:00
|
|
|
use abi::{self, Abi};
|
2017-09-21 10:13:26 +00:00
|
|
|
use ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
|
2016-03-06 12:54:44 +00:00
|
|
|
use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
2015-11-15 16:17:50 +00:00
|
|
|
use ast::Attribute;
|
2017-07-20 20:53:56 +00:00
|
|
|
use util::parser::{self, AssocOp, Fixity};
|
2015-02-06 01:04:11 +00:00
|
|
|
use attr;
|
2016-06-21 22:08:13 +00:00
|
|
|
use codemap::{self, CodeMap};
|
|
|
|
use syntax_pos::{self, BytePos};
|
2016-11-16 08:21:52 +00:00
|
|
|
use parse::token::{self, BinOpToken, Token};
|
2014-05-21 23:57:31 +00:00
|
|
|
use parse::lexer::comments;
|
2017-01-17 01:14:53 +00:00
|
|
|
use parse::{self, ParseSess};
|
2017-06-25 03:22:42 +00:00
|
|
|
use print::pp::{self, Breaks};
|
2015-01-14 05:12:39 +00:00
|
|
|
use print::pp::Breaks::{Consistent, Inconsistent};
|
2014-09-13 16:06:01 +00:00
|
|
|
use ptr::P;
|
2015-02-06 01:04:11 +00:00
|
|
|
use std_inject;
|
2016-11-16 08:21:52 +00:00
|
|
|
use symbol::{Symbol, keywords};
|
2017-01-17 22:54:51 +00:00
|
|
|
use syntax_pos::DUMMY_SP;
|
2017-03-03 09:23:59 +00:00
|
|
|
use tokenstream::{self, TokenStream, TokenTree};
|
2012-12-23 22:41:37 +00:00
|
|
|
|
2015-04-17 02:54:05 +00:00
|
|
|
use std::ascii;
|
2015-02-27 05:00:43 +00:00
|
|
|
use std::io::{self, Write, Read};
|
2017-06-25 12:38:13 +00:00
|
|
|
use std::iter::{self, Peekable};
|
|
|
|
use std::vec;
|
2013-05-25 02:35:29 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub enum AnnNode<'a> {
|
2014-08-11 12:01:37 +00:00
|
|
|
NodeIdent(&'a ast::Ident),
|
|
|
|
NodeName(&'a ast::Name),
|
2014-03-16 18:58:11 +00:00
|
|
|
NodeBlock(&'a ast::Block),
|
|
|
|
NodeItem(&'a ast::Item),
|
2015-03-24 01:52:55 +00:00
|
|
|
NodeSubItem(ast::NodeId),
|
2014-03-16 18:58:11 +00:00
|
|
|
NodeExpr(&'a ast::Expr),
|
|
|
|
NodePat(&'a ast::Pat),
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
2013-08-29 22:24:33 +00:00
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
pub trait PpAnn {
|
2015-02-27 05:00:43 +00:00
|
|
|
fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
|
|
|
|
fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
|
2013-08-29 22:24:33 +00:00
|
|
|
}
|
|
|
|
|
2015-03-30 13:38:59 +00:00
|
|
|
#[derive(Copy, Clone)]
|
2014-01-09 13:05:33 +00:00
|
|
|
pub struct NoAnn;
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
impl PpAnn for NoAnn {}
|
2013-08-29 22:24:33 +00:00
|
|
|
|
2014-03-18 05:27:37 +00:00
|
|
|
pub struct State<'a> {
|
2015-02-27 05:00:43 +00:00
|
|
|
pub s: pp::Printer<'a>,
|
2014-03-16 18:58:11 +00:00
|
|
|
cm: Option<&'a CodeMap>,
|
2014-02-28 21:09:09 +00:00
|
|
|
comments: Option<Vec<comments::Comment> >,
|
2017-06-25 12:38:13 +00:00
|
|
|
literals: Peekable<vec::IntoIter<comments::Literal>>,
|
|
|
|
cur_cmnt: usize,
|
2014-03-27 17:31:00 +00:00
|
|
|
boxes: Vec<pp::Breaks>,
|
2014-11-20 20:08:02 +00:00
|
|
|
ann: &'a (PpAnn+'a),
|
2013-02-04 22:02:01 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2017-06-25 13:51:55 +00:00
|
|
|
fn rust_printer<'a>(writer: Box<Write+'a>, ann: &'a PpAnn) -> State<'a> {
|
2014-02-06 22:38:33 +00:00
|
|
|
State {
|
2015-11-03 16:39:51 +00:00
|
|
|
s: pp::mk_printer(writer, DEFAULT_COLUMNS),
|
2014-01-09 13:05:33 +00:00
|
|
|
cm: None,
|
|
|
|
comments: None,
|
2017-06-25 12:38:13 +00:00
|
|
|
literals: vec![].into_iter().peekable(),
|
|
|
|
cur_cmnt: 0,
|
2014-03-27 17:31:00 +00:00
|
|
|
boxes: Vec::new(),
|
2017-08-07 05:54:09 +00:00
|
|
|
ann,
|
2014-02-06 22:38:33 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
pub const INDENT_UNIT: usize = 4;
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
pub const DEFAULT_COLUMNS: usize = 78;
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-06-09 20:12:30 +00:00
|
|
|
/// Requires you to pass an input filename and reader so that
|
|
|
|
/// it can scan the input text for comments and literals to
|
|
|
|
/// copy forward.
|
2014-03-18 05:27:37 +00:00
|
|
|
pub fn print_crate<'a>(cm: &'a CodeMap,
|
2017-01-17 01:14:53 +00:00
|
|
|
sess: &ParseSess,
|
2014-03-18 05:27:37 +00:00
|
|
|
krate: &ast::Crate,
|
2014-05-22 23:57:53 +00:00
|
|
|
filename: String,
|
2015-02-27 05:00:43 +00:00
|
|
|
input: &mut Read,
|
|
|
|
out: Box<Write+'a>,
|
2014-03-18 05:27:37 +00:00
|
|
|
ann: &'a PpAnn,
|
2015-02-27 05:00:43 +00:00
|
|
|
is_expanded: bool) -> io::Result<()> {
|
2017-01-17 01:14:53 +00:00
|
|
|
let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);
|
|
|
|
|
2016-09-28 22:28:19 +00:00
|
|
|
if is_expanded && !std_inject::injected_crate_name(krate).is_none() {
|
2015-02-06 01:04:11 +00:00
|
|
|
// We need to print `#![no_std]` (and its feature gate) so that
|
|
|
|
// compiling pretty-printed source won't inject libstd again.
|
|
|
|
// However we don't want these attributes in the AST because
|
|
|
|
// of the feature gate, so we fake them up here.
|
|
|
|
|
2015-12-03 01:31:49 +00:00
|
|
|
// #![feature(prelude_import)]
|
2016-11-16 08:21:52 +00:00
|
|
|
let prelude_import_meta = attr::mk_list_word_item(Symbol::intern("prelude_import"));
|
|
|
|
let list = attr::mk_list_item(Symbol::intern("feature"), vec![prelude_import_meta]);
|
2017-01-17 22:54:51 +00:00
|
|
|
let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), list);
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_attribute(&fake_attr)?;
|
2015-02-06 01:04:11 +00:00
|
|
|
|
|
|
|
// #![no_std]
|
2016-11-16 08:21:52 +00:00
|
|
|
let no_std_meta = attr::mk_word_item(Symbol::intern("no_std"));
|
2017-01-17 22:54:51 +00:00
|
|
|
let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), no_std_meta);
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_attribute(&fake_attr)?;
|
2015-02-06 01:04:11 +00:00
|
|
|
}
|
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_mod(&krate.module, &krate.attrs)?;
|
|
|
|
s.print_remaining_comments()?;
|
2017-06-25 03:22:42 +00:00
|
|
|
s.s.eof()
|
2012-02-21 23:34:26 +00:00
|
|
|
}
|
|
|
|
|
2014-08-07 09:25:31 +00:00
|
|
|
impl<'a> State<'a> {
|
|
|
|
pub fn new_from_input(cm: &'a CodeMap,
|
2017-01-17 01:14:53 +00:00
|
|
|
sess: &ParseSess,
|
2014-08-07 09:25:31 +00:00
|
|
|
filename: String,
|
2015-02-27 05:00:43 +00:00
|
|
|
input: &mut Read,
|
|
|
|
out: Box<Write+'a>,
|
2014-08-07 09:25:31 +00:00
|
|
|
ann: &'a PpAnn,
|
|
|
|
is_expanded: bool) -> State<'a> {
|
2017-01-17 01:14:53 +00:00
|
|
|
let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input);
|
2014-08-07 09:25:31 +00:00
|
|
|
|
|
|
|
State::new(
|
|
|
|
cm,
|
|
|
|
out,
|
|
|
|
ann,
|
|
|
|
Some(cmnts),
|
|
|
|
// If the code is post expansion, don't use the table of
|
|
|
|
// literals, since it doesn't correspond with the literals
|
|
|
|
// in the AST anymore.
|
|
|
|
if is_expanded { None } else { Some(lits) })
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new(cm: &'a CodeMap,
|
2015-02-27 05:00:43 +00:00
|
|
|
out: Box<Write+'a>,
|
2014-08-07 09:25:31 +00:00
|
|
|
ann: &'a PpAnn,
|
|
|
|
comments: Option<Vec<comments::Comment>>,
|
|
|
|
literals: Option<Vec<comments::Literal>>) -> State<'a> {
|
|
|
|
State {
|
2015-11-03 16:39:51 +00:00
|
|
|
s: pp::mk_printer(out, DEFAULT_COLUMNS),
|
2014-08-07 09:25:31 +00:00
|
|
|
cm: Some(cm),
|
2017-08-07 05:54:09 +00:00
|
|
|
comments,
|
2017-06-25 12:38:13 +00:00
|
|
|
literals: literals.unwrap_or_default().into_iter().peekable(),
|
|
|
|
cur_cmnt: 0,
|
2014-08-07 09:25:31 +00:00
|
|
|
boxes: Vec::new(),
|
2017-08-07 05:54:09 +00:00
|
|
|
ann,
|
2014-08-07 09:25:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-08 18:28:32 +00:00
|
|
|
pub fn to_string<F>(f: F) -> String where
|
2015-02-27 05:00:43 +00:00
|
|
|
F: FnOnce(&mut State) -> io::Result<()>,
|
2014-12-08 18:28:32 +00:00
|
|
|
{
|
2015-04-17 02:54:05 +00:00
|
|
|
let mut wr = Vec::new();
|
|
|
|
{
|
2017-06-25 13:51:55 +00:00
|
|
|
let ann = NoAnn;
|
|
|
|
let mut printer = rust_printer(Box::new(&mut wr), &ann);
|
2015-04-17 02:54:05 +00:00
|
|
|
f(&mut printer).unwrap();
|
2017-06-25 03:22:42 +00:00
|
|
|
printer.s.eof().unwrap();
|
2015-04-17 02:54:05 +00:00
|
|
|
}
|
|
|
|
String::from_utf8(wr).unwrap()
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2017-06-25 13:51:55 +00:00
|
|
|
fn binop_to_string(op: BinOpToken) -> &'static str {
|
2014-10-28 00:05:28 +00:00
|
|
|
match op {
|
|
|
|
token::Plus => "+",
|
|
|
|
token::Minus => "-",
|
|
|
|
token::Star => "*",
|
|
|
|
token::Slash => "/",
|
|
|
|
token::Percent => "%",
|
|
|
|
token::Caret => "^",
|
|
|
|
token::And => "&",
|
|
|
|
token::Or => "|",
|
|
|
|
token::Shl => "<<",
|
|
|
|
token::Shr => ">>",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn token_to_string(tok: &Token) -> String {
|
|
|
|
match *tok {
|
2014-12-11 03:46:38 +00:00
|
|
|
token::Eq => "=".to_string(),
|
|
|
|
token::Lt => "<".to_string(),
|
|
|
|
token::Le => "<=".to_string(),
|
|
|
|
token::EqEq => "==".to_string(),
|
|
|
|
token::Ne => "!=".to_string(),
|
|
|
|
token::Ge => ">=".to_string(),
|
|
|
|
token::Gt => ">".to_string(),
|
|
|
|
token::Not => "!".to_string(),
|
|
|
|
token::Tilde => "~".to_string(),
|
|
|
|
token::OrOr => "||".to_string(),
|
|
|
|
token::AndAnd => "&&".to_string(),
|
|
|
|
token::BinOp(op) => binop_to_string(op).to_string(),
|
2014-10-28 00:05:28 +00:00
|
|
|
token::BinOpEq(op) => format!("{}=", binop_to_string(op)),
|
|
|
|
|
|
|
|
/* Structural symbols */
|
2014-12-11 03:46:38 +00:00
|
|
|
token::At => "@".to_string(),
|
|
|
|
token::Dot => ".".to_string(),
|
|
|
|
token::DotDot => "..".to_string(),
|
|
|
|
token::DotDotDot => "...".to_string(),
|
2017-09-19 05:40:04 +00:00
|
|
|
token::DotDotEq => "..=".to_string(),
|
|
|
|
token::DotEq => ".=".to_string(),
|
2014-12-11 03:46:38 +00:00
|
|
|
token::Comma => ",".to_string(),
|
|
|
|
token::Semi => ";".to_string(),
|
|
|
|
token::Colon => ":".to_string(),
|
|
|
|
token::ModSep => "::".to_string(),
|
|
|
|
token::RArrow => "->".to_string(),
|
|
|
|
token::LArrow => "<-".to_string(),
|
|
|
|
token::FatArrow => "=>".to_string(),
|
|
|
|
token::OpenDelim(token::Paren) => "(".to_string(),
|
|
|
|
token::CloseDelim(token::Paren) => ")".to_string(),
|
|
|
|
token::OpenDelim(token::Bracket) => "[".to_string(),
|
|
|
|
token::CloseDelim(token::Bracket) => "]".to_string(),
|
|
|
|
token::OpenDelim(token::Brace) => "{".to_string(),
|
|
|
|
token::CloseDelim(token::Brace) => "}".to_string(),
|
2017-05-12 18:05:39 +00:00
|
|
|
token::OpenDelim(token::NoDelim) |
|
2016-07-19 20:00:45 +00:00
|
|
|
token::CloseDelim(token::NoDelim) => " ".to_string(),
|
2014-12-11 03:46:38 +00:00
|
|
|
token::Pound => "#".to_string(),
|
|
|
|
token::Dollar => "$".to_string(),
|
|
|
|
token::Question => "?".to_string(),
|
2014-10-28 00:05:28 +00:00
|
|
|
|
|
|
|
/* Literals */
|
2014-11-19 04:48:38 +00:00
|
|
|
token::Literal(lit, suf) => {
|
|
|
|
let mut out = match lit {
|
2015-07-28 16:07:20 +00:00
|
|
|
token::Byte(b) => format!("b'{}'", b),
|
|
|
|
token::Char(c) => format!("'{}'", c),
|
2017-05-12 18:05:39 +00:00
|
|
|
token::Float(c) |
|
2015-07-28 16:07:20 +00:00
|
|
|
token::Integer(c) => c.to_string(),
|
|
|
|
token::Str_(s) => format!("\"{}\"", s),
|
2014-11-19 04:48:38 +00:00
|
|
|
token::StrRaw(s, n) => format!("r{delim}\"{string}\"{delim}",
|
2014-12-11 03:46:38 +00:00
|
|
|
delim=repeat("#", n),
|
2015-07-28 16:07:20 +00:00
|
|
|
string=s),
|
2015-09-03 07:54:53 +00:00
|
|
|
token::ByteStr(v) => format!("b\"{}\"", v),
|
|
|
|
token::ByteStrRaw(s, n) => format!("br{delim}\"{string}\"{delim}",
|
2014-12-11 03:46:38 +00:00
|
|
|
delim=repeat("#", n),
|
2015-07-28 16:07:20 +00:00
|
|
|
string=s),
|
2014-11-19 04:48:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(s) = suf {
|
2015-07-28 16:07:20 +00:00
|
|
|
out.push_str(&s.as_str())
|
2014-11-19 04:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
out
|
|
|
|
}
|
2014-10-28 00:05:28 +00:00
|
|
|
|
|
|
|
/* Name components */
|
2016-04-16 01:12:02 +00:00
|
|
|
token::Ident(s) => s.to_string(),
|
2015-07-28 16:07:20 +00:00
|
|
|
token::Lifetime(s) => s.to_string(),
|
2014-12-11 03:46:38 +00:00
|
|
|
token::Underscore => "_".to_string(),
|
2014-10-28 00:05:28 +00:00
|
|
|
|
|
|
|
/* Other */
|
2015-07-28 16:07:20 +00:00
|
|
|
token::DocComment(s) => s.to_string(),
|
2014-12-11 03:46:38 +00:00
|
|
|
token::Eof => "<eof>".to_string(),
|
|
|
|
token::Whitespace => " ".to_string(),
|
|
|
|
token::Comment => "/* */".to_string(),
|
2015-07-28 16:07:20 +00:00
|
|
|
token::Shebang(s) => format!("/* shebang: {}*/", s),
|
2014-10-28 00:05:28 +00:00
|
|
|
|
2017-03-29 01:55:01 +00:00
|
|
|
token::Interpolated(ref nt) => match nt.0 {
|
2017-05-12 18:05:39 +00:00
|
|
|
token::NtExpr(ref e) => expr_to_string(e),
|
|
|
|
token::NtMeta(ref e) => meta_item_to_string(e),
|
|
|
|
token::NtTy(ref e) => ty_to_string(e),
|
|
|
|
token::NtPath(ref e) => path_to_string(e),
|
|
|
|
token::NtItem(ref e) => item_to_string(e),
|
|
|
|
token::NtBlock(ref e) => block_to_string(e),
|
|
|
|
token::NtStmt(ref e) => stmt_to_string(e),
|
|
|
|
token::NtPat(ref e) => pat_to_string(e),
|
2016-04-16 01:12:02 +00:00
|
|
|
token::NtIdent(ref e) => ident_to_string(e.node),
|
2017-02-21 05:05:59 +00:00
|
|
|
token::NtTT(ref tree) => tt_to_string(tree.clone()),
|
2017-05-12 18:05:39 +00:00
|
|
|
token::NtArm(ref e) => arm_to_string(e),
|
|
|
|
token::NtImplItem(ref e) => impl_item_to_string(e),
|
|
|
|
token::NtTraitItem(ref e) => trait_item_to_string(e),
|
|
|
|
token::NtGenerics(ref e) => generics_to_string(e),
|
|
|
|
token::NtWhereClause(ref e) => where_clause_to_string(e),
|
|
|
|
token::NtArg(ref e) => arg_to_string(e),
|
|
|
|
token::NtVis(ref e) => vis_to_string(e),
|
2014-10-28 00:05:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn ty_to_string(ty: &ast::Ty) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_type(ty))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-11-20 20:05:29 +00:00
|
|
|
pub fn bounds_to_string(bounds: &[ast::TyParamBound]) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_bounds("", bounds))
|
2014-11-20 20:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn pat_to_string(pat: &ast::Pat) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_pat(pat))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-07-28 01:05:07 +00:00
|
|
|
pub fn arm_to_string(arm: &ast::Arm) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_arm(arm))
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn expr_to_string(e: &ast::Expr) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_expr(e))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_lifetime(e))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 05:05:59 +00:00
|
|
|
pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_tt(tt))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2016-06-20 15:49:33 +00:00
|
|
|
pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String {
|
2017-02-21 05:05:59 +00:00
|
|
|
to_string(|s| s.print_tts(tts.iter().cloned().collect()))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2017-03-03 09:23:59 +00:00
|
|
|
pub fn tokens_to_string(tokens: TokenStream) -> String {
|
|
|
|
to_string(|s| s.print_tts(tokens))
|
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_stmt(stmt))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 19:18:37 +00:00
|
|
|
pub fn attr_to_string(attr: &ast::Attribute) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_attribute(attr))
|
2015-04-13 17:22:15 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn item_to_string(i: &ast::Item) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_item(i))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 17:01:15 +00:00
|
|
|
pub fn impl_item_to_string(i: &ast::ImplItem) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_impl_item(i))
|
2015-03-19 17:01:15 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 17:01:46 +00:00
|
|
|
pub fn trait_item_to_string(i: &ast::TraitItem) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_trait_item(i))
|
2015-03-19 17:01:46 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn generics_to_string(generics: &ast::Generics) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_generics(generics))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2015-03-14 04:54:29 +00:00
|
|
|
pub fn where_clause_to_string(i: &ast::WhereClause) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_where_clause(i))
|
2015-03-14 04:54:29 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_fn_block_args(p))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn path_to_string(p: &ast::Path) -> String {
|
2016-12-05 03:51:11 +00:00
|
|
|
to_string(|s| s.print_path(p, false, 0, false))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2017-05-29 22:37:11 +00:00
|
|
|
pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
|
|
|
|
to_string(|s| s.print_path_segment(p, false))
|
|
|
|
}
|
|
|
|
|
2015-09-24 20:05:02 +00:00
|
|
|
pub fn ident_to_string(id: ast::Ident) -> String {
|
|
|
|
to_string(|s| s.print_ident(id))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2016-04-24 16:04:01 +00:00
|
|
|
pub fn vis_to_string(v: &ast::Visibility) -> String {
|
|
|
|
to_string(|s| s.print_visibility(v))
|
|
|
|
}
|
|
|
|
|
2015-02-25 20:05:07 +00:00
|
|
|
pub fn fun_to_string(decl: &ast::FnDecl,
|
|
|
|
unsafety: ast::Unsafety,
|
|
|
|
constness: ast::Constness,
|
|
|
|
name: ast::Ident,
|
|
|
|
generics: &ast::Generics)
|
|
|
|
-> String {
|
2015-05-05 12:47:04 +00:00
|
|
|
to_string(|s| {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.head("")?;
|
|
|
|
s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name),
|
|
|
|
generics, &ast::Visibility::Inherited)?;
|
|
|
|
s.end()?; // Close the head box
|
2014-06-21 10:39:03 +00:00
|
|
|
s.end() // Close the outer box
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn block_to_string(blk: &ast::Block) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| {
|
2014-06-21 10:39:03 +00:00
|
|
|
// containing cbox, will be closed by print-block at }
|
2016-12-29 21:57:01 +00:00
|
|
|
s.cbox(INDENT_UNIT)?;
|
2014-06-21 10:39:03 +00:00
|
|
|
// head-ibox, will be closed by print-block after {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.ibox(0)?;
|
2014-06-21 10:39:03 +00:00
|
|
|
s.print_block(blk)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-08-20 01:58:14 +00:00
|
|
|
pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
|
|
|
|
to_string(|s| s.print_meta_list_item(li))
|
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_meta_item(mi))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn attribute_to_string(attr: &ast::Attribute) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_attribute(attr))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn lit_to_string(l: &ast::Lit) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_literal(l))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn variant_to_string(var: &ast::Variant) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_variant(var))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn arg_to_string(arg: &ast::Arg) -> String {
|
2016-01-21 18:44:36 +00:00
|
|
|
to_string(|s| s.print_arg(arg, false))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-07-12 04:22:11 +00:00
|
|
|
pub fn mac_to_string(arg: &ast::Mac) -> String {
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
to_string(|s| s.print_mac(arg, ::parse::token::Paren))
|
2014-07-12 04:22:11 +00:00
|
|
|
}
|
|
|
|
|
2016-03-23 10:17:34 +00:00
|
|
|
pub fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
|
2017-04-02 04:46:33 +00:00
|
|
|
format!("{}{}", to_string(|s| s.print_visibility(vis)), s)
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2015-09-14 09:58:20 +00:00
|
|
|
pub trait PrintState<'a> {
|
|
|
|
fn writer(&mut self) -> &mut pp::Printer<'a>;
|
|
|
|
fn boxes(&mut self) -> &mut Vec<pp::Breaks>;
|
|
|
|
fn comments(&mut self) -> &mut Option<Vec<comments::Comment>>;
|
2017-06-25 12:38:13 +00:00
|
|
|
fn cur_cmnt(&mut self) -> &mut usize;
|
|
|
|
fn cur_lit(&mut self) -> Option<&comments::Literal>;
|
|
|
|
fn bump_lit(&mut self) -> Option<comments::Literal>;
|
2015-09-14 09:58:20 +00:00
|
|
|
|
|
|
|
fn word_space(&mut self, w: &str) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(w)?;
|
|
|
|
self.writer().space()
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
fn popen(&mut self) -> io::Result<()> { self.writer().word("(") }
|
2015-09-14 09:58:20 +00:00
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
fn pclose(&mut self) -> io::Result<()> { self.writer().word(")") }
|
2015-09-14 09:58:20 +00:00
|
|
|
|
|
|
|
fn is_begin(&mut self) -> bool {
|
|
|
|
match self.writer().last_token() {
|
|
|
|
pp::Token::Begin(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2015-09-14 09:58:20 +00:00
|
|
|
fn is_end(&mut self) -> bool {
|
|
|
|
match self.writer().last_token() {
|
|
|
|
pp::Token::End => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// is this the beginning of a line?
|
|
|
|
fn is_bol(&mut self) -> bool {
|
|
|
|
self.writer().last_token().is_eof() || self.writer().last_token().is_hardbreak_tok()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn hardbreak_if_not_bol(&mut self) -> io::Result<()> {
|
|
|
|
if !self.is_bol() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().hardbreak()?
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// "raw box"
|
2015-09-14 09:58:20 +00:00
|
|
|
fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> {
|
|
|
|
self.boxes().push(b);
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().rbox(u, b)
|
2012-11-05 04:41:00 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2015-09-14 09:58:20 +00:00
|
|
|
fn ibox(&mut self, u: usize) -> io::Result<()> {
|
|
|
|
self.boxes().push(pp::Breaks::Inconsistent);
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().ibox(u)
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2015-09-14 09:58:20 +00:00
|
|
|
fn end(&mut self) -> io::Result<()> {
|
|
|
|
self.boxes().pop().unwrap();
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().end()
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2015-09-14 09:58:20 +00:00
|
|
|
fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()>
|
|
|
|
where F: FnMut(&mut Self, &T) -> io::Result<()>,
|
|
|
|
{
|
2016-12-29 21:57:01 +00:00
|
|
|
self.rbox(0, b)?;
|
2015-09-14 09:58:20 +00:00
|
|
|
let mut first = true;
|
|
|
|
for elt in elts {
|
2016-12-29 21:57:01 +00:00
|
|
|
if first { first = false; } else { self.word_space(",")?; }
|
|
|
|
op(self, elt)?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> {
|
2017-06-25 12:38:13 +00:00
|
|
|
while let Some(ltrl) = self.cur_lit().cloned() {
|
|
|
|
if ltrl.pos > pos { break; }
|
2015-09-14 09:58:20 +00:00
|
|
|
|
2017-06-25 12:38:13 +00:00
|
|
|
// we don't need the value here since we're forced to clone cur_lit
|
|
|
|
// due to lack of NLL.
|
|
|
|
self.bump_lit();
|
|
|
|
if ltrl.pos == pos {
|
|
|
|
return Some(ltrl);
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-25 12:38:13 +00:00
|
|
|
None
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> {
|
2016-10-12 17:54:41 +00:00
|
|
|
while let Some(ref cmnt) = self.next_comment() {
|
|
|
|
if cmnt.pos < pos {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_comment(cmnt)?;
|
2016-10-12 17:54:41 +00:00
|
|
|
} else {
|
|
|
|
break
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_comment(&mut self,
|
|
|
|
cmnt: &comments::Comment) -> io::Result<()> {
|
2017-06-25 12:38:13 +00:00
|
|
|
let r = match cmnt.style {
|
2015-09-14 09:58:20 +00:00
|
|
|
comments::Mixed => {
|
|
|
|
assert_eq!(cmnt.lines.len(), 1);
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().zerobreak()?;
|
|
|
|
self.writer().word(&cmnt.lines[0])?;
|
|
|
|
self.writer().zerobreak()
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
comments::Isolated => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2015-09-14 09:58:20 +00:00
|
|
|
for line in &cmnt.lines {
|
|
|
|
// Don't print empty lines because they will end up as trailing
|
|
|
|
// whitespace
|
|
|
|
if !line.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&line[..])?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().hardbreak()?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
comments::Trailing => {
|
2016-10-12 17:54:41 +00:00
|
|
|
if !self.is_bol() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(" ")?;
|
2016-10-12 17:54:41 +00:00
|
|
|
}
|
2015-09-14 09:58:20 +00:00
|
|
|
if cmnt.lines.len() == 1 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&cmnt.lines[0])?;
|
|
|
|
self.writer().hardbreak()
|
2015-09-14 09:58:20 +00:00
|
|
|
} else {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(0)?;
|
2015-09-14 09:58:20 +00:00
|
|
|
for line in &cmnt.lines {
|
|
|
|
if !line.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&line[..])?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().hardbreak()?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
comments::BlankLine => {
|
|
|
|
// We need to do at least one, possibly two hardbreaks.
|
|
|
|
let is_semi = match self.writer().last_token() {
|
|
|
|
pp::Token::String(s, _) => ";" == s,
|
|
|
|
_ => false
|
|
|
|
};
|
|
|
|
if is_semi || self.is_begin() || self.is_end() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().hardbreak()?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().hardbreak()
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2017-06-25 12:38:13 +00:00
|
|
|
};
|
|
|
|
match r {
|
|
|
|
Ok(()) => {
|
|
|
|
*self.cur_cmnt() = *self.cur_cmnt() + 1;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
Err(e) => Err(e),
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn next_comment(&mut self) -> Option<comments::Comment> {
|
2017-06-25 12:38:13 +00:00
|
|
|
let cur_cmnt = *self.cur_cmnt();
|
2015-09-14 09:58:20 +00:00
|
|
|
match *self.comments() {
|
|
|
|
Some(ref cmnts) => {
|
|
|
|
if cur_cmnt < cmnts.len() {
|
|
|
|
Some(cmnts[cur_cmnt].clone())
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(lit.span.lo())?;
|
|
|
|
if let Some(ltrl) = self.next_lit(lit.span.lo()) {
|
2017-06-25 12:38:13 +00:00
|
|
|
return self.writer().word(<rl.lit);
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
match lit.node {
|
2016-11-16 10:52:37 +00:00
|
|
|
ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style),
|
2016-02-08 16:06:20 +00:00
|
|
|
ast::LitKind::Byte(byte) => {
|
2015-09-14 09:58:20 +00:00
|
|
|
let mut res = String::from("b'");
|
|
|
|
res.extend(ascii::escape_default(byte).map(|c| c as char));
|
|
|
|
res.push('\'');
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&res[..])
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-02-08 16:06:20 +00:00
|
|
|
ast::LitKind::Char(ch) => {
|
2015-09-14 09:58:20 +00:00
|
|
|
let mut res = String::from("'");
|
|
|
|
res.extend(ch.escape_default());
|
|
|
|
res.push('\'');
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&res[..])
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-02-08 16:06:20 +00:00
|
|
|
ast::LitKind::Int(i, t) => {
|
2015-09-14 09:58:20 +00:00
|
|
|
match t {
|
2016-02-08 16:16:23 +00:00
|
|
|
ast::LitIntType::Signed(st) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&st.val_to_string(i as i128))
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-02-08 16:16:23 +00:00
|
|
|
ast::LitIntType::Unsigned(ut) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&ut.val_to_string(i))
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-02-08 16:16:23 +00:00
|
|
|
ast::LitIntType::Unsuffixed => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&format!("{}", i))
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-02-08 16:06:20 +00:00
|
|
|
ast::LitKind::Float(ref f, t) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&format!("{}{}", &f, t.ty_to_string()))
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
ast::LitKind::FloatUnsuffixed(ref f) => self.writer().word(&f.as_str()),
|
2016-02-08 16:06:20 +00:00
|
|
|
ast::LitKind::Bool(val) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
if val { self.writer().word("true") } else { self.writer().word("false") }
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-02-08 16:06:20 +00:00
|
|
|
ast::LitKind::ByteStr(ref v) => {
|
2015-09-14 09:58:20 +00:00
|
|
|
let mut escaped: String = String::new();
|
|
|
|
for &ch in v.iter() {
|
|
|
|
escaped.extend(ascii::escape_default(ch)
|
|
|
|
.map(|c| c as char));
|
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&format!("b\"{}\"", escaped))
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_string(&mut self, st: &str,
|
|
|
|
style: ast::StrStyle) -> io::Result<()> {
|
|
|
|
let st = match style {
|
2016-02-09 17:01:08 +00:00
|
|
|
ast::StrStyle::Cooked => {
|
2017-05-03 17:54:03 +00:00
|
|
|
(format!("\"{}\"", parse::escape_default(st)))
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-02-09 17:01:08 +00:00
|
|
|
ast::StrStyle::Raw(n) => {
|
2015-09-14 09:58:20 +00:00
|
|
|
(format!("r{delim}\"{string}\"{delim}",
|
|
|
|
delim=repeat("#", n),
|
|
|
|
string=st))
|
|
|
|
}
|
|
|
|
};
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&st[..])
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_inner_attributes(&mut self,
|
2015-11-03 16:39:51 +00:00
|
|
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_inner_attributes_no_trailing_hardbreak(&mut self,
|
|
|
|
attrs: &[ast::Attribute])
|
|
|
|
-> io::Result<()> {
|
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, false)
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_outer_attributes(&mut self,
|
|
|
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
2015-11-03 16:39:51 +00:00
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Outer, false, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_inner_attributes_inline(&mut self,
|
|
|
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Inner, true, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_outer_attributes_inline(&mut self,
|
|
|
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Outer, true, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_either_attributes(&mut self,
|
|
|
|
attrs: &[ast::Attribute],
|
|
|
|
kind: ast::AttrStyle,
|
|
|
|
is_inline: bool,
|
|
|
|
trailing_hardbreak: bool) -> io::Result<()> {
|
2015-09-14 09:58:20 +00:00
|
|
|
let mut count = 0;
|
|
|
|
for attr in attrs {
|
2016-11-14 12:00:25 +00:00
|
|
|
if attr.style == kind {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_attribute_inline(attr, is_inline)?;
|
2016-06-16 20:16:55 +00:00
|
|
|
if is_inline {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.nbsp()?;
|
2016-06-16 20:16:55 +00:00
|
|
|
}
|
|
|
|
count += 1;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-03 16:39:51 +00:00
|
|
|
if count > 0 && trailing_hardbreak && !is_inline {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> {
|
2015-11-03 16:39:51 +00:00
|
|
|
self.print_attribute_inline(attr, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_attribute_inline(&mut self, attr: &ast::Attribute,
|
|
|
|
is_inline: bool) -> io::Result<()> {
|
|
|
|
if !is_inline {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2015-11-03 16:39:51 +00:00
|
|
|
}
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(attr.span.lo())?;
|
2016-11-14 12:00:25 +00:00
|
|
|
if attr.is_sugared_doc {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&attr.value_str().unwrap().as_str())?;
|
|
|
|
self.writer().hardbreak()
|
2015-09-14 09:58:20 +00:00
|
|
|
} else {
|
2016-11-14 12:00:25 +00:00
|
|
|
match attr.style {
|
2017-06-25 03:22:42 +00:00
|
|
|
ast::AttrStyle::Inner => self.writer().word("#![")?,
|
|
|
|
ast::AttrStyle::Outer => self.writer().word("#[")?,
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2017-03-03 09:23:59 +00:00
|
|
|
if let Some(mi) = attr.meta() {
|
|
|
|
self.print_meta_item(&mi)?
|
|
|
|
} else {
|
|
|
|
for (i, segment) in attr.path.segments.iter().enumerate() {
|
|
|
|
if i > 0 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word("::")?
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
if segment.identifier.name != keywords::CrateRoot.name() &&
|
2017-06-25 17:34:49 +00:00
|
|
|
segment.identifier.name != keywords::DollarCrate.name() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&segment.identifier.name.as_str())?;
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().space()?;
|
2017-03-03 09:23:59 +00:00
|
|
|
self.print_tts(attr.tokens.clone())?;
|
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word("]")
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-20 01:58:14 +00:00
|
|
|
fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) -> io::Result<()> {
|
|
|
|
match item.node {
|
|
|
|
ast::NestedMetaItemKind::MetaItem(ref mi) => {
|
|
|
|
self.print_meta_item(mi)
|
|
|
|
},
|
|
|
|
ast::NestedMetaItemKind::Literal(ref lit) => {
|
|
|
|
self.print_literal(lit)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-14 09:58:20 +00:00
|
|
|
fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
2015-09-14 09:58:20 +00:00
|
|
|
match item.node {
|
2016-11-15 07:37:10 +00:00
|
|
|
ast::MetaItemKind::Word => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&item.name.as_str())?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-11-15 07:37:10 +00:00
|
|
|
ast::MetaItemKind::NameValue(ref value) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(&item.name.as_str())?;
|
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_literal(value)?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
2016-11-15 07:37:10 +00:00
|
|
|
ast::MetaItemKind::List(ref items) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&item.name.as_str())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep(Consistent,
|
2016-03-22 22:58:45 +00:00
|
|
|
&items[..],
|
2017-05-12 18:05:39 +00:00
|
|
|
|s, i| s.print_meta_list_item(i))?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
2015-11-03 16:39:51 +00:00
|
|
|
|
2017-03-03 09:23:59 +00:00
|
|
|
/// This doesn't deserve to be called "pretty" printing, but it should be
|
|
|
|
/// meaning-preserving. A quick hack that might help would be to look at the
|
|
|
|
/// spans embedded in the TTs to decide where to put spaces and newlines.
|
|
|
|
/// But it'd be better to parse these according to the grammar of the
|
|
|
|
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
|
|
|
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
|
|
|
/// expression arguments as expressions). It can be done! I think.
|
|
|
|
fn print_tt(&mut self, tt: tokenstream::TokenTree) -> io::Result<()> {
|
|
|
|
match tt {
|
|
|
|
TokenTree::Token(_, ref tk) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&token_to_string(tk))?;
|
2017-03-03 09:23:59 +00:00
|
|
|
match *tk {
|
|
|
|
parse::token::DocComment(..) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().hardbreak()
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TokenTree::Delimited(_, ref delimed) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().word(&token_to_string(&delimed.open_token()))?;
|
|
|
|
self.writer().space()?;
|
2017-03-03 09:23:59 +00:00
|
|
|
self.print_tts(delimed.stream())?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().space()?;
|
|
|
|
self.writer().word(&token_to_string(&delimed.close_token()))
|
2017-03-03 09:23:59 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_tts(&mut self, tts: tokenstream::TokenStream) -> io::Result<()> {
|
|
|
|
self.ibox(0)?;
|
|
|
|
for (i, tt) in tts.into_trees().enumerate() {
|
|
|
|
if i != 0 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.writer().space()?;
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
self.print_tt(tt)?;
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
fn space_if_not_bol(&mut self) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
if !self.is_bol() { self.writer().space()?; }
|
2015-11-03 16:39:51 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
fn nbsp(&mut self) -> io::Result<()> { self.writer().word(" ") }
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> PrintState<'a> for State<'a> {
|
|
|
|
fn writer(&mut self) -> &mut pp::Printer<'a> {
|
|
|
|
&mut self.s
|
|
|
|
}
|
|
|
|
|
|
|
|
fn boxes(&mut self) -> &mut Vec<pp::Breaks> {
|
|
|
|
&mut self.boxes
|
|
|
|
}
|
|
|
|
|
|
|
|
fn comments(&mut self) -> &mut Option<Vec<comments::Comment>> {
|
|
|
|
&mut self.comments
|
|
|
|
}
|
|
|
|
|
2017-06-25 12:38:13 +00:00
|
|
|
fn cur_cmnt(&mut self) -> &mut usize {
|
|
|
|
&mut self.cur_cmnt
|
|
|
|
}
|
|
|
|
|
|
|
|
fn cur_lit(&mut self) -> Option<&comments::Literal> {
|
|
|
|
self.literals.peek()
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-08-02 22:25:06 +00:00
|
|
|
|
2017-06-25 12:38:13 +00:00
|
|
|
fn bump_lit(&mut self) -> Option<comments::Literal> {
|
|
|
|
self.literals.next()
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
}
|
2011-08-02 22:25:06 +00:00
|
|
|
|
2015-09-14 09:58:20 +00:00
|
|
|
impl<'a> State<'a> {
|
|
|
|
pub fn cbox(&mut self, u: usize) -> io::Result<()> {
|
|
|
|
self.boxes.push(pp::Breaks::Consistent);
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.cbox(u)
|
2015-09-14 09:58:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(w)?;
|
2015-09-14 09:58:20 +00:00
|
|
|
self.nbsp()
|
|
|
|
}
|
2011-06-20 14:45:05 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn head(&mut self, w: &str) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
// outer-box is consistent
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
// head-box is inconsistent
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(w.len() + 1)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
// keyword that starts the head
|
|
|
|
if !w.is_empty() {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_nbsp(w)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2012-04-19 21:46:11 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn bopen(&mut self) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("{")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end() // close the head-box
|
2013-12-27 22:11:01 +00:00
|
|
|
}
|
2011-06-15 18:19:50 +00:00
|
|
|
|
2016-06-21 22:08:13 +00:00
|
|
|
pub fn bclose_(&mut self, span: syntax_pos::Span,
|
2015-02-27 05:00:43 +00:00
|
|
|
indented: usize) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
self.bclose_maybe_open(span, indented, true)
|
|
|
|
}
|
2016-06-21 22:08:13 +00:00
|
|
|
pub fn bclose_maybe_open(&mut self, span: syntax_pos::Span,
|
2015-12-23 16:51:03 +00:00
|
|
|
indented: usize, close_box: bool) -> io::Result<()> {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(span.hi())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.break_offset_if_not_bol(1, -(indented as isize))?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("}")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
if close_box {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // close the outer-box
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2016-06-21 22:08:13 +00:00
|
|
|
pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
|
2015-11-03 16:39:51 +00:00
|
|
|
self.bclose_(span, INDENT_UNIT)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
|
2014-03-27 17:31:00 +00:00
|
|
|
pub fn in_cbox(&self) -> bool {
|
|
|
|
match self.boxes.last() {
|
2015-01-14 05:12:39 +00:00
|
|
|
Some(&last_box) => last_box == pp::Breaks::Consistent,
|
2014-03-16 18:58:11 +00:00
|
|
|
None => false
|
|
|
|
}
|
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2015-01-17 23:33:05 +00:00
|
|
|
pub fn break_offset_if_not_bol(&mut self, n: usize,
|
2015-02-27 05:00:43 +00:00
|
|
|
off: isize) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
if !self.is_bol() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.break_offset(n, off)
|
2014-03-16 18:58:11 +00:00
|
|
|
} else {
|
|
|
|
if off != 0 && self.s.last_token().is_hardbreak_tok() {
|
|
|
|
// We do something pretty sketchy here: tuck the nonzero
|
|
|
|
// offset-adjustment we were going to deposit along with the
|
|
|
|
// break into the previous hardbreak.
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.replace_last_token(pp::Printer::hardbreak_tok_offset(off));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2011-03-18 00:39:47 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// Synthesizes a comment that was not textually present in the original source
|
|
|
|
// file.
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("/*")?;
|
|
|
|
self.s.space()?;
|
|
|
|
self.s.word(&text[..])?;
|
|
|
|
self.s.space()?;
|
|
|
|
self.s.word("*/")
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-12-08 18:28:32 +00:00
|
|
|
pub fn commasep_cmnt<T, F, G>(&mut self,
|
|
|
|
b: Breaks,
|
|
|
|
elts: &[T],
|
|
|
|
mut op: F,
|
2015-02-27 05:00:43 +00:00
|
|
|
mut get_span: G) -> io::Result<()> where
|
|
|
|
F: FnMut(&mut State, &T) -> io::Result<()>,
|
2016-06-21 22:08:13 +00:00
|
|
|
G: FnMut(&T) -> syntax_pos::Span,
|
2014-12-08 18:28:32 +00:00
|
|
|
{
|
2016-12-29 21:57:01 +00:00
|
|
|
self.rbox(0, b)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
let len = elts.len();
|
2017-05-16 07:21:30 +00:00
|
|
|
let mut i = 0;
|
|
|
|
for elt in elts {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(get_span(elt).hi())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
op(self, elt)?;
|
2017-05-16 07:21:30 +00:00
|
|
|
i += 1;
|
2014-03-16 18:58:11 +00:00
|
|
|
if i < len {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.maybe_print_trailing_comment(get_span(elt),
|
2017-07-31 20:04:34 +00:00
|
|
|
Some(get_span(&elts[i]).hi()))?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.end()
|
2011-07-26 22:37:36 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn commasep_exprs(&mut self, b: Breaks,
|
2015-02-27 05:00:43 +00:00
|
|
|
exprs: &[P<ast::Expr>]) -> io::Result<()> {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span)
|
2012-03-09 02:10:07 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_mod(&mut self, _mod: &ast::Mod,
|
2015-02-27 05:00:43 +00:00
|
|
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_inner_attributes(attrs)?;
|
2015-01-31 17:20:46 +00:00
|
|
|
for item in &_mod.items {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_item(item)?;
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
2015-02-27 05:00:43 +00:00
|
|
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_inner_attributes(attrs)?;
|
2015-01-31 17:20:46 +00:00
|
|
|
for item in &nmod.items {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_foreign_item(item)?;
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_opt_lifetime(&mut self,
|
2015-02-27 05:00:43 +00:00
|
|
|
lifetime: &Option<ast::Lifetime>) -> io::Result<()> {
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(l) = *lifetime {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_lifetime(&l)?;
|
|
|
|
self.nbsp()?;
|
2013-02-19 01:45:56 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
2011-03-04 06:22:43 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(ty.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(0)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
match ty.node {
|
2016-09-20 14:54:24 +00:00
|
|
|
ast::TyKind::Slice(ref ty) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("[")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("]")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Ptr(ref mt) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("*")?;
|
2014-06-25 19:47:34 +00:00
|
|
|
match mt.mutbl {
|
2016-12-29 21:57:01 +00:00
|
|
|
ast::Mutability::Mutable => self.word_nbsp("mut")?,
|
|
|
|
ast::Mutability::Immutable => self.word_nbsp("const")?,
|
2014-06-25 19:47:34 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_type(&mt.ty)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Rptr(ref lifetime, ref mt) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("&")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_opt_lifetime(lifetime)?;
|
|
|
|
self.print_mt(mt)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-08-02 07:56:20 +00:00
|
|
|
ast::TyKind::Never => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("!")?;
|
2016-05-09 16:03:59 +00:00
|
|
|
},
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Tup(ref elts) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep(Inconsistent, &elts[..],
|
2017-05-12 18:05:39 +00:00
|
|
|
|s, ty| s.print_type(ty))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
if elts.len() == 1 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Paren(ref typ) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(typ)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2014-06-11 19:14:38 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::BareFn(ref f) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
let generics = ast::Generics {
|
|
|
|
lifetimes: f.lifetimes.clone(),
|
2017-01-16 22:54:59 +00:00
|
|
|
ty_params: Vec::new(),
|
2014-08-11 16:32:26 +00:00
|
|
|
where_clause: ast::WhereClause {
|
|
|
|
id: ast::DUMMY_NODE_ID,
|
|
|
|
predicates: Vec::new(),
|
2017-07-27 04:37:35 +00:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2014-08-11 16:32:26 +00:00
|
|
|
},
|
2016-08-10 17:39:12 +00:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2014-03-16 18:58:11 +00:00
|
|
|
};
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ty_fn(f.abi,
|
2016-03-22 22:58:45 +00:00
|
|
|
f.unsafety,
|
|
|
|
&f.decl,
|
|
|
|
None,
|
2016-12-29 21:57:01 +00:00
|
|
|
&generics)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Path(None, ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, false, 0, false)?;
|
2015-01-31 19:20:24 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Path(Some(ref qself), ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_qpath(path, qself, false)?
|
2014-11-20 20:05:29 +00:00
|
|
|
}
|
2017-10-10 14:33:19 +00:00
|
|
|
ast::TyKind::TraitObject(ref bounds, syntax) => {
|
|
|
|
let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn " } else { "" };
|
|
|
|
self.print_bounds(prefix, &bounds[..])?;
|
2014-11-07 11:53:45 +00:00
|
|
|
}
|
2016-08-01 01:25:32 +00:00
|
|
|
ast::TyKind::ImplTrait(ref bounds) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_bounds("impl ", &bounds[..])?;
|
2016-08-01 01:25:32 +00:00
|
|
|
}
|
2016-09-20 14:54:24 +00:00
|
|
|
ast::TyKind::Array(ref ty, ref v) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("[")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("; ")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(v)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("]")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Typeof(ref e) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("typeof(")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(e)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(")")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Infer => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("_")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-03-29 01:56:29 +00:00
|
|
|
ast::TyKind::Err => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("?")?;
|
2017-03-29 01:56:29 +00:00
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
ast::TyKind::ImplicitSelf => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("Self")?;
|
2016-03-06 12:54:44 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
ast::TyKind::Mac(ref m) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_mac(m, token::Paren)?;
|
2015-07-26 04:30:35 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
2013-11-30 22:00:39 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_foreign_item(&mut self,
|
2015-02-27 05:00:43 +00:00
|
|
|
item: &ast::ForeignItem) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(item.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&item.attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
match item.node {
|
2016-02-09 10:31:19 +00:00
|
|
|
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
|
|
|
self.print_fn(decl, ast::Unsafety::Normal,
|
2016-03-22 22:58:45 +00:00
|
|
|
ast::Constness::NotConst,
|
|
|
|
Abi::Rust, Some(item.ident),
|
2016-12-29 21:57:01 +00:00
|
|
|
generics, &item.vis)?;
|
|
|
|
self.end()?; // end head-ibox
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end() // end the outer fn box
|
|
|
|
}
|
2016-02-09 10:31:19 +00:00
|
|
|
ast::ForeignItemKind::Static(ref t, m) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "static"))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
if m {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("mut")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.word_space(":")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(t)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end the head-ibox
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end() // end the outer cbox
|
|
|
|
}
|
2017-09-03 18:53:58 +00:00
|
|
|
ast::ForeignItemKind::Ty => {
|
|
|
|
self.head(&visibility_qualified(&item.vis, "type"))?;
|
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.s.word(";")?;
|
|
|
|
self.end()?; // end the head-ibox
|
|
|
|
self.end() // end the outer cbox
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2013-02-11 07:15:45 +00:00
|
|
|
|
2015-03-16 01:35:25 +00:00
|
|
|
fn print_associated_const(&mut self,
|
|
|
|
ident: ast::Ident,
|
|
|
|
ty: &ast::Ty,
|
|
|
|
default: Option<&ast::Expr>,
|
2016-03-23 10:17:34 +00:00
|
|
|
vis: &ast::Visibility)
|
2015-03-16 01:35:25 +00:00
|
|
|
-> io::Result<()>
|
|
|
|
{
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(&visibility_qualified(vis, ""))?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("const")?;
|
|
|
|
self.print_ident(ident)?;
|
|
|
|
self.word_space(":")?;
|
|
|
|
self.print_type(ty)?;
|
2015-03-16 01:35:25 +00:00
|
|
|
if let Some(expr) = default {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_expr(expr)?;
|
2015-03-16 01:35:25 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")
|
2015-03-16 01:35:25 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 10:28:44 +00:00
|
|
|
fn print_associated_type(&mut self,
|
|
|
|
ident: ast::Ident,
|
|
|
|
bounds: Option<&ast::TyParamBounds>,
|
|
|
|
ty: Option<&ast::Ty>)
|
|
|
|
-> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("type")?;
|
|
|
|
self.print_ident(ident)?;
|
2015-03-10 10:28:44 +00:00
|
|
|
if let Some(bounds) = bounds {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_bounds(":", bounds)?;
|
2015-03-10 10:28:44 +00:00
|
|
|
}
|
|
|
|
if let Some(ty) = ty {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_type(ty)?;
|
2015-03-10 10:28:44 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")
|
2014-08-06 02:44:21 +00:00
|
|
|
}
|
|
|
|
|
2014-07-12 04:22:11 +00:00
|
|
|
/// Pretty-print an item
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(item.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&item.attrs)?;
|
|
|
|
self.ann.pre(self, NodeItem(item))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
match item.node {
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::ExternCrate(ref optional_path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "extern crate"))?;
|
2015-03-19 22:39:03 +00:00
|
|
|
if let Some(p) = *optional_path {
|
2015-07-28 16:07:20 +00:00
|
|
|
let val = p.as_str();
|
2017-05-12 18:05:39 +00:00
|
|
|
if val.contains('-') {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_string(&val, ast::StrStyle::Cooked)?;
|
2015-03-19 22:39:03 +00:00
|
|
|
} else {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_name(p)?;
|
2015-03-19 22:39:03 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
|
|
|
self.s.word("as")?;
|
|
|
|
self.s.space()?;
|
2015-01-13 15:30:17 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(item.ident)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end inner head-block
|
|
|
|
self.end()?; // end outer head-block
|
2015-01-13 15:30:17 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Use(ref vp) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "use"))?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_view_path(vp)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end inner head-block
|
|
|
|
self.end()?; // end outer head-block
|
2015-01-13 15:30:17 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Static(ref ty, m, ref expr) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "static"))?;
|
2016-02-09 16:44:47 +00:00
|
|
|
if m == ast::Mutability::Mutable {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("mut")?;
|
2013-03-05 00:11:30 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.word_space(":")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end the head-ibox
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(expr)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end the outer cbox
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Const(ref ty, ref expr) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "const"))?;
|
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.word_space(":")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end the head-ibox
|
|
|
|
|
|
|
|
self.word_space("=")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(expr)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end the outer cbox
|
rustc: Add `const` globals to the language
This change is an implementation of [RFC 69][rfc] which adds a third kind of
global to the language, `const`. This global is most similar to what the old
`static` was, and if you're unsure about what to use then you should use a
`const`.
The semantics of these three kinds of globals are:
* A `const` does not represent a memory location, but only a value. Constants
are translated as rvalues, which means that their values are directly inlined
at usage location (similar to a #define in C/C++). Constant values are, well,
constant, and can not be modified. Any "modification" is actually a
modification to a local value on the stack rather than the actual constant
itself.
Almost all values are allowed inside constants, whether they have interior
mutability or not. There are a few minor restrictions listed in the RFC, but
they should in general not come up too often.
* A `static` now always represents a memory location (unconditionally). Any
references to the same `static` are actually a reference to the same memory
location. Only values whose types ascribe to `Sync` are allowed in a `static`.
This restriction is in place because many threads may access a `static`
concurrently. Lifting this restriction (and allowing unsafe access) is a
future extension not implemented at this time.
* A `static mut` continues to always represent a memory location. All references
to a `static mut` continue to be `unsafe`.
This is a large breaking change, and many programs will need to be updated
accordingly. A summary of the breaking changes is:
* Statics may no longer be used in patterns. Statics now always represent a
memory location, which can sometimes be modified. To fix code, repurpose the
matched-on-`static` to a `const`.
static FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
change this code to:
const FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
* Statics may no longer refer to other statics by value. Due to statics being
able to change at runtime, allowing them to reference one another could
possibly lead to confusing semantics. If you are in this situation, use a
constant initializer instead. Note, however, that statics may reference other
statics by address, however.
* Statics may no longer be used in constant expressions, such as array lengths.
This is due to the same restrictions as listed above. Use a `const` instead.
[breaking-change]
[rfc]: https://github.com/rust-lang/rfcs/pull/246
2014-10-06 15:17:01 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Fn(ref decl, unsafety, constness, abi, ref typarams, ref body) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
|
|
|
self.print_fn(
|
2015-03-11 06:38:27 +00:00
|
|
|
decl,
|
|
|
|
unsafety,
|
2016-08-10 23:20:12 +00:00
|
|
|
constness.node,
|
2014-03-16 18:58:11 +00:00
|
|
|
abi,
|
2015-03-11 06:38:27 +00:00
|
|
|
Some(item.ident),
|
2014-03-16 18:58:11 +00:00
|
|
|
typarams,
|
2016-03-23 10:17:34 +00:00
|
|
|
&item.vis
|
2016-12-29 21:57:01 +00:00
|
|
|
)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(" ")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_with_attrs(body, &item.attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Mod(ref _mod) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "mod"))?;
|
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.nbsp()?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.print_mod(_mod, &item.attrs)?;
|
|
|
|
self.bclose(item.span)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::ForeignMod(ref nmod) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("extern")?;
|
|
|
|
self.word_nbsp(&nmod.abi.to_string())?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.print_foreign_mod(nmod, &item.attrs)?;
|
|
|
|
self.bclose(item.span)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-03-16 02:27:40 +00:00
|
|
|
ast::ItemKind::GlobalAsm(ref ga) => {
|
|
|
|
self.head(&visibility_qualified(&item.vis, "global_asm!"))?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(&ga.asm.as_str())?;
|
2017-03-16 02:27:40 +00:00
|
|
|
self.end()?;
|
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Ty(ref ty, ref params) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
|
|
|
self.ibox(0)?;
|
|
|
|
self.word_nbsp(&visibility_qualified(&item.vis, "type"))?;
|
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.print_generics(params)?;
|
|
|
|
self.end()?; // end the inner ibox
|
|
|
|
|
|
|
|
self.print_where_clause(¶ms.where_clause)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // end the outer ibox
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Enum(ref enum_definition, ref params) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_enum_def(
|
2014-03-16 18:58:11 +00:00
|
|
|
enum_definition,
|
|
|
|
params,
|
|
|
|
item.ident,
|
|
|
|
item.span,
|
2016-03-23 10:17:34 +00:00
|
|
|
&item.vis
|
2016-12-29 21:57:01 +00:00
|
|
|
)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Struct(ref struct_def, ref generics) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "struct"))?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_struct(struct_def, generics, item.ident, item.span, true)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-08-29 05:04:31 +00:00
|
|
|
ast::ItemKind::Union(ref struct_def, ref generics) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "union"))?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_struct(struct_def, generics, item.ident, item.span, true)?;
|
2016-08-29 05:04:31 +00:00
|
|
|
}
|
2017-10-09 16:59:20 +00:00
|
|
|
ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
|
|
|
self.print_visibility(&item.vis)?;
|
|
|
|
self.print_unsafety(unsafety)?;
|
|
|
|
self.word_nbsp("impl")?;
|
|
|
|
self.print_trait_ref(trait_ref)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("for")?;
|
|
|
|
self.word_space("..")?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.bclose(item.span)?;
|
2015-01-22 21:14:52 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Impl(unsafety,
|
2014-12-28 22:33:18 +00:00
|
|
|
polarity,
|
2016-11-18 16:14:42 +00:00
|
|
|
defaultness,
|
2014-12-10 11:15:06 +00:00
|
|
|
ref generics,
|
2014-08-04 20:56:56 +00:00
|
|
|
ref opt_trait,
|
|
|
|
ref ty,
|
|
|
|
ref impl_items) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
|
|
|
self.print_visibility(&item.vis)?;
|
2016-11-18 16:14:42 +00:00
|
|
|
self.print_defaultness(defaultness)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_unsafety(unsafety)?;
|
|
|
|
self.word_nbsp("impl")?;
|
2014-12-10 11:15:06 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
if generics.is_parameterized() {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_generics(generics)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-03-27 10:16:28 +00:00
|
|
|
|
2017-05-13 19:40:06 +00:00
|
|
|
if polarity == ast::ImplPolarity::Negative {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("!")?;
|
2014-12-28 22:33:18 +00:00
|
|
|
}
|
|
|
|
|
2016-07-03 21:38:37 +00:00
|
|
|
if let Some(ref t) = *opt_trait {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_trait_ref(t)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("for")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-08-09 00:14:25 +00:00
|
|
|
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2012-08-08 21:17:52 +00:00
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bopen()?;
|
|
|
|
self.print_inner_attributes(&item.attrs)?;
|
2015-01-31 17:20:46 +00:00
|
|
|
for impl_item in impl_items {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_impl_item(impl_item)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bclose(item.span)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-10-12 12:51:31 +00:00
|
|
|
ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
|
|
|
self.print_visibility(&item.vis)?;
|
|
|
|
self.print_unsafety(unsafety)?;
|
2017-11-03 18:13:02 +00:00
|
|
|
self.print_is_auto(is_auto)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_nbsp("trait")?;
|
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.print_generics(generics)?;
|
2014-12-24 09:34:57 +00:00
|
|
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
2015-02-13 07:33:44 +00:00
|
|
|
for b in bounds.iter() {
|
|
|
|
if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("for ?")?;
|
|
|
|
self.print_trait_ref(&ptr.trait_ref)?;
|
2014-12-24 09:34:57 +00:00
|
|
|
} else {
|
2015-02-13 07:33:44 +00:00
|
|
|
real_bounds.push(b.clone());
|
2014-12-24 09:34:57 +00:00
|
|
|
}
|
2014-04-03 00:38:45 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_bounds(":", &real_bounds[..])?;
|
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(" ")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bopen()?;
|
2015-03-10 10:28:44 +00:00
|
|
|
for trait_item in trait_items {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_trait_item(trait_item)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bclose(item.span)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(&node.path, false, 0, false)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("! ")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.cbox(INDENT_UNIT)?;
|
|
|
|
self.popen()?;
|
2017-02-21 05:05:59 +00:00
|
|
|
self.print_tts(node.stream())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-03-01 23:48:16 +00:00
|
|
|
ast::ItemKind::MacroDef(ref tts) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("macro_rules! ")?;
|
2017-03-05 05:15:58 +00:00
|
|
|
self.print_ident(item.ident)?;
|
|
|
|
self.cbox(INDENT_UNIT)?;
|
|
|
|
self.popen()?;
|
2017-03-17 21:58:48 +00:00
|
|
|
self.print_tts(tts.stream())?;
|
2017-03-05 05:15:58 +00:00
|
|
|
self.pclose()?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2017-03-05 05:15:58 +00:00
|
|
|
self.end()?;
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
self.ann.post(self, NodeItem(item))
|
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
|
2016-12-05 03:51:11 +00:00
|
|
|
self.print_path(&t.path, false, 0, false)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> {
|
2015-02-09 03:49:27 +00:00
|
|
|
if !lifetimes.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("for<")?;
|
2014-12-14 03:11:04 +00:00
|
|
|
let mut comma = false;
|
2015-02-09 03:49:27 +00:00
|
|
|
for lifetime_def in lifetimes {
|
2014-12-14 03:11:04 +00:00
|
|
|
if comma {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(",")?
|
2014-12-14 03:11:04 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
|
|
|
self.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)?;
|
2014-12-14 03:11:04 +00:00
|
|
|
comma = true;
|
2014-11-07 11:53:45 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(">")?;
|
2014-11-07 11:53:45 +00:00
|
|
|
}
|
2015-02-09 03:49:27 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
2014-11-07 11:53:45 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_formal_lifetime_list(&t.bound_lifetimes)?;
|
2014-11-07 11:53:45 +00:00
|
|
|
self.print_trait_ref(&t.trait_ref)
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
|
|
|
|
generics: &ast::Generics, ident: ast::Ident,
|
2016-06-21 22:08:13 +00:00
|
|
|
span: syntax_pos::Span,
|
2016-03-23 10:17:34 +00:00
|
|
|
visibility: &ast::Visibility) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head(&visibility_qualified(visibility, "enum"))?;
|
|
|
|
self.print_ident(ident)?;
|
|
|
|
self.print_generics(generics)?;
|
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2015-02-18 23:58:07 +00:00
|
|
|
self.print_variants(&enum_definition.variants, span)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_variants(&mut self,
|
2016-02-11 20:33:09 +00:00
|
|
|
variants: &[ast::Variant],
|
2016-06-21 22:08:13 +00:00
|
|
|
span: syntax_pos::Span) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bopen()?;
|
2015-01-31 17:20:46 +00:00
|
|
|
for v in variants {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(v.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&v.node.attrs)?;
|
|
|
|
self.ibox(INDENT_UNIT)?;
|
|
|
|
self.print_variant(v)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?;
|
|
|
|
self.maybe_print_trailing_comment(v.span, None)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
self.bclose(span)
|
|
|
|
}
|
|
|
|
|
2016-03-23 10:17:34 +00:00
|
|
|
pub fn print_visibility(&mut self, vis: &ast::Visibility) -> io::Result<()> {
|
|
|
|
match *vis {
|
2016-02-09 16:57:49 +00:00
|
|
|
ast::Visibility::Public => self.word_nbsp("pub"),
|
2017-10-19 21:43:47 +00:00
|
|
|
ast::Visibility::Crate(_, sugar) => match sugar {
|
|
|
|
ast::CrateSugar::PubCrate => self.word_nbsp("pub(crate)"),
|
|
|
|
ast::CrateSugar::JustCrate => self.word_nbsp("crate")
|
|
|
|
}
|
2016-12-05 03:51:11 +00:00
|
|
|
ast::Visibility::Restricted { ref path, .. } => {
|
|
|
|
let path = to_string(|s| s.print_path(path, false, 0, true));
|
2017-04-02 04:46:33 +00:00
|
|
|
if path == "self" || path == "super" {
|
|
|
|
self.word_nbsp(&format!("pub({})", path))
|
|
|
|
} else {
|
|
|
|
self.word_nbsp(&format!("pub(in {})", path))
|
|
|
|
}
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
2016-02-09 16:57:49 +00:00
|
|
|
ast::Visibility::Inherited => Ok(())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-18 16:14:42 +00:00
|
|
|
pub fn print_defaultness(&mut self, defatulness: ast::Defaultness) -> io::Result<()> {
|
|
|
|
if let ast::Defaultness::Default = defatulness {
|
|
|
|
try!(self.word_nbsp("default"));
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_struct(&mut self,
|
2015-10-08 00:20:57 +00:00
|
|
|
struct_def: &ast::VariantData,
|
2014-03-16 18:58:11 +00:00
|
|
|
generics: &ast::Generics,
|
|
|
|
ident: ast::Ident,
|
2016-06-21 22:08:13 +00:00
|
|
|
span: syntax_pos::Span,
|
2015-10-01 15:47:27 +00:00
|
|
|
print_finalizer: bool) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(ident)?;
|
|
|
|
self.print_generics(generics)?;
|
2015-10-08 20:45:46 +00:00
|
|
|
if !struct_def.is_struct() {
|
|
|
|
if struct_def.is_tuple() {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep(
|
2015-10-08 20:45:46 +00:00
|
|
|
Inconsistent, struct_def.fields(),
|
2014-03-16 18:58:11 +00:00
|
|
|
|s, field| {
|
2017-07-31 20:04:34 +00:00
|
|
|
s.maybe_print_comment(field.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_outer_attributes(&field.attrs)?;
|
|
|
|
s.print_visibility(&field.vis)?;
|
2016-04-06 08:19:10 +00:00
|
|
|
s.print_type(&field.ty)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
)?;
|
|
|
|
self.pclose()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2015-10-01 15:47:27 +00:00
|
|
|
if print_finalizer {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2015-10-01 15:47:27 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end() // close the outer-box
|
|
|
|
} else {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
|
|
|
self.nbsp()?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.hardbreak_if_not_bol()?;
|
2012-09-22 01:10:45 +00:00
|
|
|
|
2015-10-08 20:45:46 +00:00
|
|
|
for field in struct_def.fields() {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(field.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&field.attrs)?;
|
|
|
|
self.print_visibility(&field.vis)?;
|
|
|
|
self.print_ident(field.ident.unwrap())?;
|
|
|
|
self.word_nbsp(":")?;
|
|
|
|
self.print_type(&field.ty)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-09-22 01:10:45 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
self.bclose(span)
|
|
|
|
}
|
2012-09-22 01:10:45 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
2015-11-28 19:02:07 +00:00
|
|
|
let generics = ast::Generics::default();
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
match v.node.disr_expr {
|
2014-05-16 07:16:13 +00:00
|
|
|
Some(ref d) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(d)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-11 06:38:27 +00:00
|
|
|
pub fn print_method_sig(&mut self,
|
|
|
|
ident: ast::Ident,
|
2017-09-22 02:18:47 +00:00
|
|
|
generics: &ast::Generics,
|
2015-03-11 06:38:27 +00:00
|
|
|
m: &ast::MethodSig,
|
2016-03-23 10:17:34 +00:00
|
|
|
vis: &ast::Visibility)
|
2015-03-11 06:38:27 +00:00
|
|
|
-> io::Result<()> {
|
|
|
|
self.print_fn(&m.decl,
|
|
|
|
m.unsafety,
|
2016-08-10 23:20:12 +00:00
|
|
|
m.constness.node,
|
2015-03-11 06:38:27 +00:00
|
|
|
m.abi,
|
|
|
|
Some(ident),
|
2017-09-22 02:18:47 +00:00
|
|
|
&generics,
|
2015-03-11 06:38:27 +00:00
|
|
|
vis)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 10:28:44 +00:00
|
|
|
pub fn print_trait_item(&mut self, ti: &ast::TraitItem)
|
|
|
|
-> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ann.pre(self, NodeSubItem(ti.id))?;
|
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(ti.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&ti.attrs)?;
|
2015-03-10 10:28:44 +00:00
|
|
|
match ti.node {
|
2016-02-09 16:54:11 +00:00
|
|
|
ast::TraitItemKind::Const(ref ty, ref default) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_associated_const(ti.ident, ty,
|
2016-03-22 22:58:45 +00:00
|
|
|
default.as_ref().map(|expr| &**expr),
|
2016-12-29 21:57:01 +00:00
|
|
|
&ast::Visibility::Inherited)?;
|
2015-03-16 01:35:25 +00:00
|
|
|
}
|
2016-02-09 16:54:11 +00:00
|
|
|
ast::TraitItemKind::Method(ref sig, ref body) => {
|
2015-03-11 21:38:58 +00:00
|
|
|
if body.is_some() {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
2015-03-11 21:38:58 +00:00
|
|
|
}
|
2017-09-22 02:18:47 +00:00
|
|
|
self.print_method_sig(ti.ident, &ti.generics, sig, &ast::Visibility::Inherited)?;
|
2015-03-11 21:38:58 +00:00
|
|
|
if let Some(ref body) = *body {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.nbsp()?;
|
|
|
|
self.print_block_with_attrs(body, &ti.attrs)?;
|
2015-03-11 21:38:58 +00:00
|
|
|
} else {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2015-03-11 21:38:58 +00:00
|
|
|
}
|
2015-03-10 10:28:44 +00:00
|
|
|
}
|
2016-02-09 16:54:11 +00:00
|
|
|
ast::TraitItemKind::Type(ref bounds, ref default) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_associated_type(ti.ident, Some(bounds),
|
|
|
|
default.as_ref().map(|ty| &**ty))?;
|
2015-03-10 10:28:44 +00:00
|
|
|
}
|
2016-06-11 01:00:07 +00:00
|
|
|
ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
|
|
|
|
// code copied from ItemKind::Mac:
|
2016-12-05 03:51:11 +00:00
|
|
|
self.print_path(&node.path, false, 0, false)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("! ")?;
|
2016-06-11 01:00:07 +00:00
|
|
|
self.cbox(INDENT_UNIT)?;
|
|
|
|
self.popen()?;
|
2017-02-21 05:05:59 +00:00
|
|
|
self.print_tts(node.stream())?;
|
2016-06-11 01:00:07 +00:00
|
|
|
self.pclose()?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-06-11 01:00:07 +00:00
|
|
|
self.end()?
|
|
|
|
}
|
2014-08-04 20:56:56 +00:00
|
|
|
}
|
2015-03-24 01:52:55 +00:00
|
|
|
self.ann.post(self, NodeSubItem(ti.id))
|
2014-08-04 20:56:56 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ann.pre(self, NodeSubItem(ii.id))?;
|
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(ii.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&ii.attrs)?;
|
2016-11-18 16:14:42 +00:00
|
|
|
self.print_defaultness(ii.defaultness)?;
|
2015-03-10 10:28:44 +00:00
|
|
|
match ii.node {
|
2015-11-13 13:15:04 +00:00
|
|
|
ast::ImplItemKind::Const(ref ty, ref expr) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_associated_const(ii.ident, ty, Some(expr), &ii.vis)?;
|
2015-03-16 01:35:25 +00:00
|
|
|
}
|
2015-11-13 13:15:04 +00:00
|
|
|
ast::ImplItemKind::Method(ref sig, ref body) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
2017-09-22 02:18:47 +00:00
|
|
|
self.print_method_sig(ii.ident, &ii.generics, sig, &ii.vis)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.nbsp()?;
|
|
|
|
self.print_block_with_attrs(body, &ii.attrs)?;
|
2015-03-10 10:28:44 +00:00
|
|
|
}
|
2015-11-13 13:15:04 +00:00
|
|
|
ast::ImplItemKind::Type(ref ty) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_associated_type(ii.ident, None, Some(ty))?;
|
2015-03-10 10:28:44 +00:00
|
|
|
}
|
2015-11-13 13:15:04 +00:00
|
|
|
ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => {
|
2016-02-09 10:36:51 +00:00
|
|
|
// code copied from ItemKind::Mac:
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(&node.path, false, 0, false)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("! ")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT)?;
|
|
|
|
self.popen()?;
|
2017-02-21 05:05:59 +00:00
|
|
|
self.print_tts(node.stream())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?
|
2014-07-12 04:22:11 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-24 01:52:55 +00:00
|
|
|
self.ann.post(self, NodeSubItem(ii.id))
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(st.span.lo())?;
|
2014-03-16 18:58:11 +00:00
|
|
|
match st.node {
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Local(ref loc) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&loc.attrs)?;
|
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.ibox(INDENT_UNIT)?;
|
|
|
|
self.word_nbsp("let")?;
|
|
|
|
|
|
|
|
self.ibox(INDENT_UNIT)?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_local_decl(loc)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?;
|
2016-06-17 02:30:01 +00:00
|
|
|
if let Some(ref init) = loc.init {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.nbsp()?;
|
|
|
|
self.word_space("=")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(init)?;
|
2016-06-17 02:30:01 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-06-17 02:30:01 +00:00
|
|
|
self.end()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-05-12 18:05:39 +00:00
|
|
|
ast::StmtKind::Item(ref item) => self.print_item(item)?,
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Expr(ref expr) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_outer_attr_style(expr, false)?;
|
2016-06-24 11:39:18 +00:00
|
|
|
if parse::classify::expr_requires_semi_to_be_stmt(expr) {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2016-06-24 11:39:18 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Semi(ref expr) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_outer_attr_style(expr, false)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Mac(ref mac) => {
|
|
|
|
let (ref mac, style, ref attrs) = **mac;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_outer_attributes(attrs)?;
|
2014-11-14 17:18:10 +00:00
|
|
|
let delim = match style {
|
2016-02-09 10:56:59 +00:00
|
|
|
ast::MacStmtStyle::Braces => token::Brace,
|
2014-11-14 17:18:10 +00:00
|
|
|
_ => token::Paren
|
|
|
|
};
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_mac(mac, delim)?;
|
2016-07-05 11:21:25 +00:00
|
|
|
if style == ast::MacStmtStyle::Semicolon {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(";")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-06-30 10:54:54 +00:00
|
|
|
}
|
2011-06-16 20:00:19 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
self.maybe_print_trailing_comment(st.span, None)
|
2011-06-16 20:00:19 +00:00
|
|
|
}
|
2011-07-08 23:35:09 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_block(&mut self, blk: &ast::Block) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
self.print_block_with_attrs(blk, &[])
|
|
|
|
}
|
2012-08-14 01:13:41 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> io::Result<()> {
|
2015-11-03 16:39:51 +00:00
|
|
|
self.print_block_unclosed_indent(blk, INDENT_UNIT)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_block_unclosed_with_attrs(&mut self, blk: &ast::Block,
|
|
|
|
attrs: &[ast::Attribute])
|
|
|
|
-> io::Result<()> {
|
|
|
|
self.print_block_maybe_unclosed(blk, INDENT_UNIT, attrs, false)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-01-16 01:23:59 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
|
2015-02-27 05:00:43 +00:00
|
|
|
indented: usize) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
self.print_block_maybe_unclosed(blk, indented, &[], false)
|
|
|
|
}
|
2011-08-15 21:42:33 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block_with_attrs(&mut self,
|
|
|
|
blk: &ast::Block,
|
2015-02-27 05:00:43 +00:00
|
|
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
2015-11-03 16:39:51 +00:00
|
|
|
self.print_block_maybe_unclosed(blk, INDENT_UNIT, attrs, true)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-01-16 01:23:59 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block_maybe_unclosed(&mut self,
|
2013-07-19 05:38:55 +00:00
|
|
|
blk: &ast::Block,
|
2015-01-17 23:33:05 +00:00
|
|
|
indented: usize,
|
2013-07-19 11:51:37 +00:00
|
|
|
attrs: &[ast::Attribute],
|
2015-02-27 05:00:43 +00:00
|
|
|
close_box: bool) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
match blk.rules {
|
2016-12-29 21:57:01 +00:00
|
|
|
BlockCheckMode::Unsafe(..) => self.word_space("unsafe")?,
|
2016-02-08 11:44:45 +00:00
|
|
|
BlockCheckMode::Default => ()
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(blk.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ann.pre(self, NodeBlock(blk))?;
|
|
|
|
self.bopen()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_inner_attributes(attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2016-06-24 11:39:18 +00:00
|
|
|
for (i, st) in blk.stmts.iter().enumerate() {
|
|
|
|
match st.node {
|
2016-06-26 02:19:34 +00:00
|
|
|
ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(st.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_outer_attr_style(expr, false)?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()))?;
|
2016-06-24 11:39:18 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
_ => self.print_stmt(st)?,
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-24 11:39:18 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bclose_maybe_open(blk.span, indented, close_box)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.ann.post(self, NodeBlock(blk))
|
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> {
|
2012-08-06 19:34:08 +00:00
|
|
|
match els {
|
2014-01-30 01:39:21 +00:00
|
|
|
Some(_else) => {
|
|
|
|
match _else.node {
|
|
|
|
// "another else-if"
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::If(ref i, ref then, ref e) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT - 1)?;
|
|
|
|
self.ibox(0)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(" else if ")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(i)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block(then)?;
|
2014-09-13 16:06:01 +00:00
|
|
|
self.print_else(e.as_ref().map(|e| &**e))
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-08-25 01:04:29 +00:00
|
|
|
// "another else-if-let"
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::IfLet(ref pat, ref expr, ref then, ref e) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT - 1)?;
|
|
|
|
self.ibox(0)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(" else if let ")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(pat)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(expr)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block(then)?;
|
2014-08-25 01:04:29 +00:00
|
|
|
self.print_else(e.as_ref().map(|e| &**e))
|
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
// "final else"
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Block(ref b) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT - 1)?;
|
|
|
|
self.ibox(0)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(" else ")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block(b)
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
|
|
|
// BLEAH, constraints would be great here
|
|
|
|
_ => {
|
2014-10-09 19:17:22 +00:00
|
|
|
panic!("print_if saw if with weird alternative");
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-16 21:08:17 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => Ok(())
|
2011-06-16 21:08:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
|
2015-02-27 05:00:43 +00:00
|
|
|
elseopt: Option<&ast::Expr>) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("if")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(test)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_block(blk)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.print_else(elseopt)
|
2011-07-08 23:35:09 +00:00
|
|
|
}
|
|
|
|
|
2014-08-25 01:04:29 +00:00
|
|
|
pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block,
|
2015-02-27 05:00:43 +00:00
|
|
|
elseopt: Option<&ast::Expr>) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("if let")?;
|
|
|
|
self.print_pat(pat)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(expr)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_block(blk)?;
|
2014-08-25 01:04:29 +00:00
|
|
|
self.print_else(elseopt)
|
|
|
|
}
|
|
|
|
|
2014-11-14 17:18:10 +00:00
|
|
|
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(&m.node.path, false, 0, false)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("!")?;
|
2015-09-20 20:15:37 +00:00
|
|
|
match delim {
|
2016-12-29 21:57:01 +00:00
|
|
|
token::Paren => self.popen()?,
|
2017-06-25 03:22:42 +00:00
|
|
|
token::Bracket => self.s.word("[")?,
|
2015-11-03 16:39:51 +00:00
|
|
|
token::Brace => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("")?;
|
|
|
|
self.bopen()?;
|
2015-11-03 16:39:51 +00:00
|
|
|
}
|
2016-07-19 20:00:45 +00:00
|
|
|
token::NoDelim => {}
|
2015-09-20 20:15:37 +00:00
|
|
|
}
|
2017-02-21 05:05:59 +00:00
|
|
|
self.print_tts(m.node.stream())?;
|
2015-09-20 20:15:37 +00:00
|
|
|
match delim {
|
|
|
|
token::Paren => self.pclose(),
|
2017-06-25 03:22:42 +00:00
|
|
|
token::Bracket => self.s.word("]"),
|
2015-09-20 20:15:37 +00:00
|
|
|
token::Brace => self.bclose(m.span),
|
2016-07-19 20:00:45 +00:00
|
|
|
token::NoDelim => Ok(()),
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-09-12 04:25:01 +00:00
|
|
|
}
|
2012-11-30 19:18:25 +00:00
|
|
|
|
2012-07-23 23:39:18 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep_exprs(Inconsistent, args)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
|
2017-07-20 20:53:56 +00:00
|
|
|
pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) -> io::Result<()> {
|
|
|
|
let needs_par = parser::expr_precedence(expr) < prec;
|
|
|
|
if needs_par {
|
|
|
|
self.popen()?;
|
2015-08-06 07:55:27 +00:00
|
|
|
}
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr(expr)?;
|
|
|
|
if needs_par {
|
|
|
|
self.pclose()?;
|
|
|
|
}
|
|
|
|
Ok(())
|
2015-08-06 07:55:27 +00:00
|
|
|
}
|
|
|
|
|
2017-07-20 20:53:56 +00:00
|
|
|
/// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
|
|
|
|
/// `if cond { ... }`.
|
|
|
|
pub fn print_expr_as_cond(&mut self, expr: &ast::Expr) -> io::Result<()> {
|
|
|
|
let needs_par = match expr.node {
|
|
|
|
// These cases need parens due to the parse error observed in #26461: `if return {}`
|
|
|
|
// parses as the erroneous construct `if (return {})`, not `if (return) {}`.
|
|
|
|
ast::ExprKind::Closure(..) |
|
|
|
|
ast::ExprKind::Ret(..) |
|
|
|
|
ast::ExprKind::Break(..) => true,
|
|
|
|
|
|
|
|
_ => parser::contains_exterior_struct_lit(expr),
|
|
|
|
};
|
|
|
|
|
2014-04-16 20:33:58 +00:00
|
|
|
if needs_par {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
2014-04-16 20:33:58 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_expr(expr)?;
|
2014-04-16 20:33:58 +00:00
|
|
|
if needs_par {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2014-04-16 20:33:58 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-09-24 15:00:08 +00:00
|
|
|
fn print_expr_in_place(&mut self,
|
|
|
|
place: &ast::Expr,
|
|
|
|
expr: &ast::Expr) -> io::Result<()> {
|
2017-07-20 20:53:56 +00:00
|
|
|
let prec = AssocOp::Inplace.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(place, prec + 1)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("<-")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, prec)
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>],
|
|
|
|
attrs: &[Attribute]) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("[")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_inner_attributes_inline(attrs)?;
|
|
|
|
self.commasep_exprs(Inconsistent, &exprs[..])?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("]")?;
|
2015-01-14 05:16:56 +00:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_repeat(&mut self,
|
|
|
|
element: &ast::Expr,
|
2015-11-03 16:39:51 +00:00
|
|
|
count: &ast::Expr,
|
|
|
|
attrs: &[Attribute]) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("[")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_inner_attributes_inline(attrs)?;
|
|
|
|
self.print_expr(element)?;
|
|
|
|
self.word_space(";")?;
|
|
|
|
self.print_expr(count)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("]")?;
|
2015-01-14 05:16:56 +00:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_struct(&mut self,
|
|
|
|
path: &ast::Path,
|
|
|
|
fields: &[ast::Field],
|
2015-11-03 16:39:51 +00:00
|
|
|
wth: &Option<P<ast::Expr>>,
|
|
|
|
attrs: &[Attribute]) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, true, 0, false)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("{")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_inner_attributes_inline(attrs)?;
|
|
|
|
self.commasep_cmnt(
|
2015-09-10 19:46:52 +00:00
|
|
|
Consistent,
|
|
|
|
&fields[..],
|
|
|
|
|s, field| {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.ibox(INDENT_UNIT)?;
|
2016-10-27 00:15:13 +00:00
|
|
|
if !field.is_shorthand {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_ident(field.ident.node)?;
|
|
|
|
s.word_space(":")?;
|
2016-10-27 00:15:13 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_expr(&field.expr)?;
|
2015-09-10 19:46:52 +00:00
|
|
|
s.end()
|
|
|
|
},
|
2016-12-29 21:57:01 +00:00
|
|
|
|f| f.span)?;
|
2015-09-10 19:46:52 +00:00
|
|
|
match *wth {
|
|
|
|
Some(ref expr) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
2015-09-10 19:46:52 +00:00
|
|
|
if !fields.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
|
|
|
self.s.space()?;
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("..")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(expr)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?;
|
2015-09-10 19:46:52 +00:00
|
|
|
}
|
|
|
|
_ => if !fields.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("}")?;
|
2015-01-14 05:16:56 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>],
|
|
|
|
attrs: &[Attribute]) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.print_inner_attributes_inline(attrs)?;
|
|
|
|
self.commasep_exprs(Inconsistent, &exprs[..])?;
|
2015-01-14 05:16:56 +00:00
|
|
|
if exprs.len() == 1 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_call(&mut self,
|
|
|
|
func: &ast::Expr,
|
2015-02-27 05:00:43 +00:00
|
|
|
args: &[P<ast::Expr>]) -> io::Result<()> {
|
2017-07-20 20:53:56 +00:00
|
|
|
let prec =
|
|
|
|
match func.node {
|
|
|
|
ast::ExprKind::Field(..) |
|
|
|
|
ast::ExprKind::TupField(..) => parser::PREC_FORCE_PAREN,
|
|
|
|
_ => parser::PREC_POSTFIX,
|
|
|
|
};
|
|
|
|
|
|
|
|
self.print_expr_maybe_paren(func, prec)?;
|
2015-01-14 05:16:56 +00:00
|
|
|
self.print_call_post(args)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_method_call(&mut self,
|
2017-07-06 23:39:55 +00:00
|
|
|
segment: &ast::PathSegment,
|
2015-02-27 05:00:43 +00:00
|
|
|
args: &[P<ast::Expr>]) -> io::Result<()> {
|
2015-01-18 00:15:52 +00:00
|
|
|
let base_args = &args[1..];
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(".")?;
|
2017-07-06 23:39:55 +00:00
|
|
|
self.print_ident(segment.identifier)?;
|
|
|
|
if let Some(ref parameters) = segment.parameters {
|
|
|
|
self.print_path_parameters(parameters, true)?;
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
|
|
|
self.print_call_post(base_args)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_binary(&mut self,
|
|
|
|
op: ast::BinOp,
|
|
|
|
lhs: &ast::Expr,
|
2015-02-27 05:00:43 +00:00
|
|
|
rhs: &ast::Expr) -> io::Result<()> {
|
2017-07-20 20:53:56 +00:00
|
|
|
let assoc_op = AssocOp::from_ast_binop(op.node);
|
|
|
|
let prec = assoc_op.precedence() as i8;
|
|
|
|
let fixity = assoc_op.fixity();
|
|
|
|
|
|
|
|
let (left_prec, right_prec) = match fixity {
|
|
|
|
Fixity::Left => (prec, prec + 1),
|
|
|
|
Fixity::Right => (prec + 1, prec),
|
|
|
|
Fixity::None => (prec + 1, prec + 1),
|
|
|
|
};
|
|
|
|
|
2017-11-05 17:28:00 +00:00
|
|
|
let left_prec = match (&lhs.node, op.node) {
|
|
|
|
// These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
|
|
|
|
// the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
|
|
|
|
// of `(x as i32) < ...`. We need to convince it _not_ to do that.
|
|
|
|
(&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt) |
|
|
|
|
(&ast::ExprKind::Cast { .. }, ast::BinOpKind::Shl) => parser::PREC_FORCE_PAREN,
|
|
|
|
_ => left_prec,
|
|
|
|
};
|
|
|
|
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(lhs, left_prec)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(op.node.to_string())?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(rhs, right_prec)
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_unary(&mut self,
|
|
|
|
op: ast::UnOp,
|
2015-02-27 05:00:43 +00:00
|
|
|
expr: &ast::Expr) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(ast::UnOp::to_string(op))?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_addr_of(&mut self,
|
|
|
|
mutability: ast::Mutability,
|
2015-02-27 05:00:43 +00:00
|
|
|
expr: &ast::Expr) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("&")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_mutability(mutability)?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_expr(&mut self, expr: &ast::Expr) -> io::Result<()> {
|
2015-11-03 16:39:51 +00:00
|
|
|
self.print_expr_outer_attr_style(expr, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_outer_attr_style(&mut self,
|
|
|
|
expr: &ast::Expr,
|
|
|
|
is_inline: bool) -> io::Result<()> {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(expr.span.lo())?;
|
2015-11-03 16:39:51 +00:00
|
|
|
|
2016-06-18 04:01:57 +00:00
|
|
|
let attrs = &expr.attrs;
|
2015-11-03 16:39:51 +00:00
|
|
|
if is_inline {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes_inline(attrs)?;
|
2015-11-03 16:39:51 +00:00
|
|
|
} else {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(attrs)?;
|
2015-11-03 16:39:51 +00:00
|
|
|
}
|
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
|
|
|
self.ann.pre(self, NodeExpr(expr))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
match expr.node {
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Box(ref expr) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("box")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)?;
|
2015-09-24 15:00:08 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::InPlace(ref place, ref expr) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_expr_in_place(place, expr)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-01-16 07:36:10 +00:00
|
|
|
ast::ExprKind::Array(ref exprs) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_expr_vec(&exprs[..], attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Repeat(ref element, ref count) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_repeat(element, count, attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Struct(ref path, ref fields, ref wth) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_expr_struct(path, &fields[..], wth, attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Tup(ref exprs) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_expr_tup(&exprs[..], attrs)?;
|
2012-07-10 17:37:05 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Call(ref func, ref args) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_call(func, &args[..])?;
|
2012-08-09 23:31:47 +00:00
|
|
|
}
|
2017-07-06 23:39:55 +00:00
|
|
|
ast::ExprKind::MethodCall(ref segment, ref args) => {
|
|
|
|
self.print_expr_method_call(segment, &args[..])?;
|
2013-10-28 22:22:49 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_binary(op, lhs, rhs)?;
|
2013-10-28 22:22:49 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Unary(op, ref expr) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_unary(op, expr)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::AddrOf(m, ref expr) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr_addr_of(m, expr)?;
|
2015-01-14 05:16:56 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Lit(ref lit) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_literal(lit)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Cast(ref expr, ref ty) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
let prec = AssocOp::As.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(expr, prec)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("as")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Type(ref expr, ref ty) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
let prec = AssocOp::Colon.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(expr, prec)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(":")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2015-02-01 07:59:46 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::If(ref test, ref blk, ref elseopt) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_if(test, blk, elseopt.as_ref().map(|e| &**e))?;
|
2014-08-25 01:04:29 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::IfLet(ref pat, ref expr, ref blk, ref elseopt) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_if_let(pat, expr, blk, elseopt.as_ref().map(|e| &**e))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::While(ref test, ref blk, opt_ident) => {
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(ident) = opt_ident {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(ident.node)?;
|
|
|
|
self.word_space(":")?;
|
2014-07-26 00:12:51 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("while")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(test)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_with_attrs(blk, attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::WhileLet(ref pat, ref expr, ref blk, opt_ident) => {
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(ident) = opt_ident {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(ident.node)?;
|
|
|
|
self.word_space(":")?;
|
2014-10-03 02:45:46 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("while let")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(pat)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(expr)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_with_attrs(blk, attrs)?;
|
2014-10-03 02:45:46 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_ident) => {
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(ident) = opt_ident {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(ident.node)?;
|
|
|
|
self.word_space(":")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("for")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(pat)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("in")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(iter)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_with_attrs(blk, attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Loop(ref blk, opt_ident) => {
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(ident) = opt_ident {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(ident.node)?;
|
|
|
|
self.word_space(":")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.head("loop")?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_with_attrs(blk, attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Match(ref expr, ref arms) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT)?;
|
|
|
|
self.ibox(4)?;
|
|
|
|
self.word_nbsp("match")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_as_cond(expr)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bopen()?;
|
|
|
|
self.print_inner_attributes_no_trailing_hardbreak(attrs)?;
|
2015-01-31 17:20:46 +00:00
|
|
|
for arm in arms {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_arm(arm)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.bclose_(expr.span, INDENT_UNIT)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-04-20 18:44:07 +00:00
|
|
|
ast::ExprKind::Closure(capture_clause, ref decl, ref body, _) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_capture_clause(capture_clause)?;
|
2014-07-23 19:43:29 +00:00
|
|
|
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_fn_block_args(decl)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_expr(body)?;
|
|
|
|
self.end()?; // need to close a box
|
2016-06-23 09:51:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// a box will be closed by print_expr, but we didn't want an overall
|
|
|
|
// wrapper so we closed the corresponding opening. so create an
|
|
|
|
// empty box to satisfy the close.
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(0)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Block(ref blk) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
// containing cbox, will be closed by print-block at }
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
// head-box, will be closed by print-block after {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(0)?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_with_attrs(blk, attrs)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Assign(ref lhs, ref rhs) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
let prec = AssocOp::Assign.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(lhs, prec + 1)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(rhs, prec)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
let prec = AssocOp::Assign.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(lhs, prec + 1)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
|
|
|
self.s.word(op.node.to_string())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(rhs, prec)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Field(ref expr, id) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(".")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(id.node)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::TupField(ref expr, id) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(".")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_usize(id.node)?;
|
2014-08-10 03:54:33 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Index(ref expr, ref index) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("[")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(index)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("]")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-11 17:52:39 +00:00
|
|
|
ast::ExprKind::Range(ref start, ref end, limits) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
// Special case for `Range`. `AssocOp` claims that `Range` has higher precedence
|
|
|
|
// than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`.
|
|
|
|
// Here we use a fake precedence value so that any child with lower precedence than
|
|
|
|
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
|
|
|
|
let fake_prec = AssocOp::LOr.precedence() as i8;
|
2017-05-12 18:05:39 +00:00
|
|
|
if let Some(ref e) = *start {
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(e, fake_prec)?;
|
2014-09-15 08:48:58 +00:00
|
|
|
}
|
2016-01-13 06:23:31 +00:00
|
|
|
if limits == ast::RangeLimits::HalfOpen {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("..")?;
|
2016-01-13 06:23:31 +00:00
|
|
|
} else {
|
2017-11-03 17:17:44 +00:00
|
|
|
self.s.word("..=")?;
|
2016-01-13 06:23:31 +00:00
|
|
|
}
|
2017-05-12 18:05:39 +00:00
|
|
|
if let Some(ref e) = *end {
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(e, fake_prec)?;
|
2014-09-15 08:48:58 +00:00
|
|
|
}
|
2014-12-13 05:41:02 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Path(None, ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, true, 0, false)?
|
2015-02-17 17:29:13 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Path(Some(ref qself), ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_qpath(path, qself, true)?
|
2015-02-17 17:29:13 +00:00
|
|
|
}
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
ast::ExprKind::Break(opt_ident, ref opt_expr) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("break")?;
|
|
|
|
self.s.space()?;
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(ident) = opt_ident {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(ident.node)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
if let Some(ref expr) = *opt_expr {
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-06-17 02:34:18 +00:00
|
|
|
ast::ExprKind::Continue(opt_ident) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("continue")?;
|
|
|
|
self.s.space()?;
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(ident) = opt_ident {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(ident.node)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Ret(ref result) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("return")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
if let Some(ref expr) = *result {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(" ")?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::InlineAsm(ref a) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("asm!")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.print_string(&a.asm.as_str(), a.asm_str_style)?;
|
|
|
|
self.word_space(":")?;
|
2014-04-17 08:35:40 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(Inconsistent, &a.outputs, |s, out| {
|
2016-11-16 10:52:37 +00:00
|
|
|
let constraint = out.constraint.as_str();
|
|
|
|
let mut ch = constraint.chars();
|
2016-04-07 17:42:53 +00:00
|
|
|
match ch.next() {
|
|
|
|
Some('=') if out.is_rw => {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_string(&format!("+{}", ch.as_str()),
|
|
|
|
ast::StrStyle::Cooked)?
|
2014-08-19 19:39:26 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
_ => s.print_string(&constraint, ast::StrStyle::Cooked)?
|
2014-08-19 19:39:26 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
s.popen()?;
|
|
|
|
s.print_expr(&out.expr)?;
|
|
|
|
s.pclose()?;
|
2014-04-17 08:35:40 +00:00
|
|
|
Ok(())
|
2016-12-29 21:57:01 +00:00
|
|
|
})?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(":")?;
|
|
|
|
|
|
|
|
self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| {
|
|
|
|
s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
|
|
|
|
s.popen()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
s.print_expr(o)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
s.pclose()?;
|
2014-04-17 08:35:40 +00:00
|
|
|
Ok(())
|
2016-12-29 21:57:01 +00:00
|
|
|
})?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(":")?;
|
2014-04-17 08:35:40 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(Inconsistent, &a.clobbers,
|
2014-11-30 02:56:31 +00:00
|
|
|
|s, co| {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
|
2014-11-30 02:56:31 +00:00
|
|
|
Ok(())
|
2016-12-29 21:57:01 +00:00
|
|
|
})?;
|
2014-12-17 13:02:50 +00:00
|
|
|
|
2016-10-29 21:54:04 +00:00
|
|
|
let mut options = vec![];
|
2014-12-17 13:02:50 +00:00
|
|
|
if a.volatile {
|
|
|
|
options.push("volatile");
|
|
|
|
}
|
|
|
|
if a.alignstack {
|
|
|
|
options.push("alignstack");
|
|
|
|
}
|
2015-09-21 09:45:04 +00:00
|
|
|
if a.dialect == ast::AsmDialect::Intel {
|
2014-12-17 13:02:50 +00:00
|
|
|
options.push("intel");
|
|
|
|
}
|
|
|
|
|
2015-03-24 23:54:09 +00:00
|
|
|
if !options.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(":")?;
|
|
|
|
self.commasep(Inconsistent, &options,
|
2016-03-22 22:58:45 +00:00
|
|
|
|s, &co| {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_string(co, ast::StrStyle::Cooked)?;
|
2016-03-22 22:58:45 +00:00
|
|
|
Ok(())
|
2016-12-29 21:57:01 +00:00
|
|
|
})?;
|
2014-12-17 13:02:50 +00:00
|
|
|
}
|
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
ast::ExprKind::Mac(ref m) => self.print_mac(m, token::Paren)?,
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Paren(ref e) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.print_inner_attributes_inline(attrs)?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(e)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2016-02-28 22:38:48 +00:00
|
|
|
},
|
2016-12-26 13:34:03 +00:00
|
|
|
ast::ExprKind::Yield(ref e) => {
|
2017-07-13 04:29:26 +00:00
|
|
|
self.s.word("yield")?;
|
2016-12-26 13:34:03 +00:00
|
|
|
match *e {
|
|
|
|
Some(ref expr) => {
|
2017-07-13 04:29:26 +00:00
|
|
|
self.s.space()?;
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
|
2016-12-26 13:34:03 +00:00
|
|
|
}
|
|
|
|
_ => ()
|
|
|
|
}
|
|
|
|
}
|
2016-02-28 22:38:48 +00:00
|
|
|
ast::ExprKind::Try(ref e) => {
|
2017-07-20 20:53:56 +00:00
|
|
|
self.print_expr_maybe_paren(e, parser::PREC_POSTFIX)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("?")?
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-02-17 23:12:47 +00:00
|
|
|
ast::ExprKind::Catch(ref blk) => {
|
2017-03-03 22:41:07 +00:00
|
|
|
self.head("do catch")?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_with_attrs(blk, attrs)?
|
2017-02-17 23:12:47 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ann.post(self, NodeExpr(expr))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end()
|
2011-08-10 19:51:50 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_pat(&loc.pat)?;
|
2015-01-02 11:55:31 +00:00
|
|
|
if let Some(ref ty) = loc.ty {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(":")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2011-03-04 06:22:43 +00:00
|
|
|
}
|
2015-01-02 11:55:31 +00:00
|
|
|
Ok(())
|
2011-03-04 06:22:43 +00:00
|
|
|
}
|
2011-03-24 15:33:20 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(&ident.name.as_str())?;
|
2014-08-11 12:01:37 +00:00
|
|
|
self.ann.post(self, NodeIdent(&ident))
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(&i.to_string())
|
2014-08-10 03:54:33 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(&name.as_str())?;
|
2014-08-11 12:01:37 +00:00
|
|
|
self.ann.post(self, NodeName(&name))
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-08-07 16:47:28 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_for_decl(&mut self, loc: &ast::Local,
|
2015-02-27 05:00:43 +00:00
|
|
|
coll: &ast::Expr) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_local_decl(loc)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("in")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.print_expr(coll)
|
|
|
|
}
|
2013-08-07 16:47:28 +00:00
|
|
|
|
2014-11-20 20:08:48 +00:00
|
|
|
fn print_path(&mut self,
|
|
|
|
path: &ast::Path,
|
2015-01-31 19:20:24 +00:00
|
|
|
colons_before_params: bool,
|
2016-12-05 03:51:11 +00:00
|
|
|
depth: usize,
|
|
|
|
defaults_to_global: bool)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()>
|
2014-11-20 20:08:48 +00:00
|
|
|
{
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(path.span.lo())?;
|
2013-08-07 16:47:28 +00:00
|
|
|
|
2016-12-05 03:51:11 +00:00
|
|
|
let mut segments = path.segments[..path.segments.len()-depth].iter();
|
|
|
|
if defaults_to_global && path.is_global() {
|
|
|
|
segments.next();
|
|
|
|
}
|
|
|
|
for (i, segment) in segments.enumerate() {
|
|
|
|
if i > 0 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("::")?
|
2013-08-07 16:47:28 +00:00
|
|
|
}
|
2017-05-29 22:37:11 +00:00
|
|
|
self.print_path_segment(segment, colons_before_params)?;
|
2014-11-04 02:52:52 +00:00
|
|
|
}
|
|
|
|
|
2014-11-20 20:08:48 +00:00
|
|
|
Ok(())
|
2014-11-04 02:52:52 +00:00
|
|
|
}
|
|
|
|
|
2017-05-29 22:37:11 +00:00
|
|
|
fn print_path_segment(&mut self,
|
|
|
|
segment: &ast::PathSegment,
|
|
|
|
colons_before_params: bool)
|
|
|
|
-> io::Result<()>
|
|
|
|
{
|
|
|
|
if segment.identifier.name != keywords::CrateRoot.name() &&
|
2017-06-25 17:34:49 +00:00
|
|
|
segment.identifier.name != keywords::DollarCrate.name() {
|
2017-05-29 22:37:11 +00:00
|
|
|
self.print_ident(segment.identifier)?;
|
|
|
|
if let Some(ref parameters) = segment.parameters {
|
|
|
|
self.print_path_parameters(parameters, colons_before_params)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-01-13 04:02:56 +00:00
|
|
|
fn print_qpath(&mut self,
|
2015-02-17 17:29:13 +00:00
|
|
|
path: &ast::Path,
|
|
|
|
qself: &ast::QSelf,
|
2015-01-13 04:02:56 +00:00
|
|
|
colons_before_params: bool)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()>
|
2015-01-13 04:02:56 +00:00
|
|
|
{
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("<")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_type(&qself.ty)?;
|
2015-02-24 10:12:14 +00:00
|
|
|
if qself.position > 0 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("as")?;
|
2015-02-24 10:12:14 +00:00
|
|
|
let depth = path.segments.len() - qself.position;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_path(path, false, depth, false)?;
|
2015-02-24 10:12:14 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(">")?;
|
|
|
|
self.s.word("::")?;
|
2015-02-17 17:29:13 +00:00
|
|
|
let item_segment = path.segments.last().unwrap();
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(item_segment.identifier)?;
|
2016-12-10 06:45:58 +00:00
|
|
|
match item_segment.parameters {
|
|
|
|
Some(ref parameters) => self.print_path_parameters(parameters, colons_before_params),
|
|
|
|
None => Ok(()),
|
|
|
|
}
|
2015-01-13 04:02:56 +00:00
|
|
|
}
|
|
|
|
|
2014-11-04 02:52:52 +00:00
|
|
|
fn print_path_parameters(&mut self,
|
|
|
|
parameters: &ast::PathParameters,
|
|
|
|
colons_before_params: bool)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()>
|
2014-11-04 02:52:52 +00:00
|
|
|
{
|
|
|
|
if colons_before_params {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("::")?
|
2014-11-04 02:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
match *parameters {
|
2015-12-22 15:56:13 +00:00
|
|
|
ast::PathParameters::AngleBracketed(ref data) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("<")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
|
|
|
|
let mut comma = false;
|
2015-01-31 17:20:46 +00:00
|
|
|
for lifetime in &data.lifetimes {
|
2014-03-16 18:58:11 +00:00
|
|
|
if comma {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(",")?
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_lifetime(lifetime)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
comma = true;
|
2013-11-09 03:25:22 +00:00
|
|
|
}
|
2013-02-28 00:41:02 +00:00
|
|
|
|
2014-11-04 02:52:52 +00:00
|
|
|
if !data.types.is_empty() {
|
2014-03-16 18:58:11 +00:00
|
|
|
if comma {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(",")?
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(
|
2014-03-16 18:58:11 +00:00
|
|
|
Inconsistent,
|
2015-02-18 23:58:07 +00:00
|
|
|
&data.types,
|
2017-05-12 18:05:39 +00:00
|
|
|
|s, ty| s.print_type(ty))?;
|
2014-11-29 04:08:30 +00:00
|
|
|
comma = true;
|
|
|
|
}
|
|
|
|
|
2015-06-11 12:56:07 +00:00
|
|
|
for binding in data.bindings.iter() {
|
2014-11-29 04:08:30 +00:00
|
|
|
if comma {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(",")?
|
2014-11-29 04:08:30 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(binding.ident)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_type(&binding.ty)?;
|
2014-11-29 04:08:30 +00:00
|
|
|
comma = true;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(">")?
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-03-22 16:20:22 +00:00
|
|
|
|
2015-12-22 15:56:13 +00:00
|
|
|
ast::PathParameters::Parenthesized(ref data) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("(")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(
|
2014-11-04 02:52:52 +00:00
|
|
|
Inconsistent,
|
2015-02-18 23:58:07 +00:00
|
|
|
&data.inputs,
|
2017-05-12 18:05:39 +00:00
|
|
|
|s, ty| s.print_type(ty))?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(")")?;
|
2014-11-04 02:52:52 +00:00
|
|
|
|
2016-10-18 02:00:20 +00:00
|
|
|
if let Some(ref ty) = data.output {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.word_space("->")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2014-11-04 02:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
2014-03-22 16:20:22 +00:00
|
|
|
}
|
2014-11-04 02:52:52 +00:00
|
|
|
|
|
|
|
Ok(())
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(pat.span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ann.pre(self, NodePat(pat))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
/* Pat isn't normalized, but the beauty of it
|
|
|
|
is that it doesn't matter */
|
|
|
|
match pat.node {
|
2017-06-25 03:22:42 +00:00
|
|
|
PatKind::Wild => self.s.word("_")?,
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Ident(binding_mode, ref path1, ref sub) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
match binding_mode {
|
2015-12-18 13:23:01 +00:00
|
|
|
ast::BindingMode::ByRef(mutbl) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_nbsp("ref")?;
|
|
|
|
self.print_mutability(mutbl)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-09 16:44:47 +00:00
|
|
|
ast::BindingMode::ByValue(ast::Mutability::Immutable) => {}
|
|
|
|
ast::BindingMode::ByValue(ast::Mutability::Mutable) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_nbsp("mut")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_ident(path1.node)?;
|
2016-06-14 05:43:30 +00:00
|
|
|
if let Some(ref p) = *sub {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("@")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(p)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
PatKind::TupleStruct(ref path, ref elts, ddpos) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, true, 0, false)?;
|
|
|
|
self.popen()?;
|
2016-03-06 12:54:44 +00:00
|
|
|
if let Some(ddpos) = ddpos {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?;
|
2016-03-06 12:54:44 +00:00
|
|
|
if ddpos != 0 {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(",")?;
|
2016-03-06 12:54:44 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("..")?;
|
2016-03-06 12:54:44 +00:00
|
|
|
if ddpos != elts.len() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
} else {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?;
|
2013-11-08 03:25:39 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2013-11-08 03:25:39 +00:00
|
|
|
}
|
2016-06-11 15:47:47 +00:00
|
|
|
PatKind::Path(None, ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, true, 0, false)?;
|
2016-02-13 12:51:27 +00:00
|
|
|
}
|
2016-06-11 15:47:47 +00:00
|
|
|
PatKind::Path(Some(ref qself), ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_qpath(path, qself, false)?;
|
2015-03-25 16:53:28 +00:00
|
|
|
}
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Struct(ref path, ref fields, etc) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, true, 0, false)?;
|
|
|
|
self.nbsp()?;
|
|
|
|
self.word_space("{")?;
|
|
|
|
self.commasep_cmnt(
|
2015-02-18 19:48:57 +00:00
|
|
|
Consistent, &fields[..],
|
2014-03-16 18:58:11 +00:00
|
|
|
|s, f| {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.cbox(INDENT_UNIT)?;
|
2014-10-27 07:11:26 +00:00
|
|
|
if !f.node.is_shorthand {
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_ident(f.node.ident)?;
|
|
|
|
s.word_nbsp(":")?;
|
2014-10-27 07:11:26 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_pat(&f.node.pat)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
s.end()
|
|
|
|
},
|
2016-12-29 21:57:01 +00:00
|
|
|
|f| f.node.pat.span)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
if etc {
|
2016-12-29 21:57:01 +00:00
|
|
|
if !fields.is_empty() { self.word_space(",")?; }
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("..")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
|
|
|
self.s.word("}")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
PatKind::Tuple(ref elts, ddpos) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
2016-03-06 12:54:44 +00:00
|
|
|
if let Some(ddpos) = ddpos {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?;
|
2016-03-06 12:54:44 +00:00
|
|
|
if ddpos != 0 {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(",")?;
|
2016-03-06 12:54:44 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("..")?;
|
2016-03-06 12:54:44 +00:00
|
|
|
if ddpos != elts.len() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?;
|
2016-03-06 12:54:44 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?;
|
2016-03-06 12:54:44 +00:00
|
|
|
if elts.len() == 1 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2016-03-06 12:54:44 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Box(ref inner) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("box ")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(inner)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Ref(ref inner, mutbl) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("&")?;
|
2016-02-09 16:44:47 +00:00
|
|
|
if mutbl == ast::Mutability::Mutable {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("mut ")?;
|
2014-12-05 23:56:25 +00:00
|
|
|
}
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(inner)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
PatKind::Lit(ref e) => self.print_expr(&**e)?,
|
2017-01-10 21:13:53 +00:00
|
|
|
PatKind::Range(ref begin, ref end, ref end_kind) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(begin)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2017-01-10 21:13:53 +00:00
|
|
|
match *end_kind {
|
2017-09-21 10:13:26 +00:00
|
|
|
RangeEnd::Included(RangeSyntax::DotDotDot) => self.s.word("...")?,
|
|
|
|
RangeEnd::Included(RangeSyntax::DotDotEq) => self.s.word("..=")?,
|
2017-06-25 03:22:42 +00:00
|
|
|
RangeEnd::Excluded => self.s.word("..")?,
|
2017-01-10 21:13:53 +00:00
|
|
|
}
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(end)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-09-20 14:54:24 +00:00
|
|
|
PatKind::Slice(ref before, ref slice, ref after) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("[")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(Inconsistent,
|
2015-02-18 19:48:57 +00:00
|
|
|
&before[..],
|
2017-05-12 18:05:39 +00:00
|
|
|
|s, p| s.print_pat(p))?;
|
2015-01-31 17:20:46 +00:00
|
|
|
if let Some(ref p) = *slice {
|
2016-12-29 21:57:01 +00:00
|
|
|
if !before.is_empty() { self.word_space(",")?; }
|
2016-02-11 18:16:33 +00:00
|
|
|
if p.node != PatKind::Wild {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(p)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("..")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
if !after.is_empty() { self.word_space(",")?; }
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(Inconsistent,
|
2015-02-18 19:48:57 +00:00
|
|
|
&after[..],
|
2017-05-12 18:05:39 +00:00
|
|
|
|s, p| s.print_pat(p))?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("]")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
PatKind::Mac(ref m) => self.print_mac(m, token::Paren)?,
|
2013-02-26 18:58:46 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
self.ann.post(self, NodePat(pat))
|
2013-12-27 22:11:01 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> {
|
2014-07-28 01:05:07 +00:00
|
|
|
// I have no idea why this check is necessary, but here it
|
|
|
|
// is :(
|
|
|
|
if arm.attrs.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.cbox(INDENT_UNIT)?;
|
|
|
|
self.ibox(0)?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(arm.pats[0].span.lo())?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes(&arm.attrs)?;
|
2014-07-28 01:05:07 +00:00
|
|
|
let mut first = true;
|
2015-01-31 17:20:46 +00:00
|
|
|
for p in &arm.pats {
|
2014-07-28 01:05:07 +00:00
|
|
|
if first {
|
|
|
|
first = false;
|
|
|
|
} else {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("|")?;
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_pat(p)?;
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2014-11-22 15:24:58 +00:00
|
|
|
if let Some(ref e) = arm.guard {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("if")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_expr(e)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=>")?;
|
2014-07-28 01:05:07 +00:00
|
|
|
|
|
|
|
match arm.body.node {
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::Block(ref blk) => {
|
2014-07-28 01:05:07 +00:00
|
|
|
// the block will close the pattern's ibox
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_block_unclosed_indent(blk, INDENT_UNIT)?;
|
2014-11-22 15:24:58 +00:00
|
|
|
|
|
|
|
// If it is a user-provided unsafe block, print a comma after it
|
2016-02-08 11:44:45 +00:00
|
|
|
if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2014-11-22 15:24:58 +00:00
|
|
|
}
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
|
|
|
_ => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?; // close the ibox for the pattern
|
|
|
|
self.print_expr(&arm.body)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(",")?;
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.end() // close enclosing cbox
|
|
|
|
}
|
|
|
|
|
2016-03-06 12:54:44 +00:00
|
|
|
fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) -> io::Result<()> {
|
|
|
|
match explicit_self.node {
|
|
|
|
SelfKind::Value(m) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_mutability(m)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("self")
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
SelfKind::Region(ref lt, m) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("&")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_opt_lifetime(lt)?;
|
|
|
|
self.print_mutability(m)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("self")
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
SelfKind::Explicit(ref typ, m) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_mutability(m)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("self")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(":")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(typ)
|
2014-05-06 23:37:32 +00:00
|
|
|
}
|
2013-03-10 00:43:53 +00:00
|
|
|
}
|
2012-08-17 23:14:57 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_fn(&mut self,
|
|
|
|
decl: &ast::FnDecl,
|
2015-03-11 06:38:27 +00:00
|
|
|
unsafety: ast::Unsafety,
|
2015-02-25 20:05:07 +00:00
|
|
|
constness: ast::Constness,
|
2014-04-02 08:19:41 +00:00
|
|
|
abi: abi::Abi,
|
2015-03-11 06:38:27 +00:00
|
|
|
name: Option<ast::Ident>,
|
2014-03-16 18:58:11 +00:00
|
|
|
generics: &ast::Generics,
|
2016-03-23 10:17:34 +00:00
|
|
|
vis: &ast::Visibility) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_fn_header_info(unsafety, constness, abi, vis)?;
|
2015-03-11 06:38:27 +00:00
|
|
|
|
|
|
|
if let Some(name) = name {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.nbsp()?;
|
|
|
|
self.print_ident(name)?;
|
2015-03-11 06:38:27 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_generics(generics)?;
|
|
|
|
self.print_fn_args_and_ret(decl)?;
|
2015-03-14 04:54:29 +00:00
|
|
|
self.print_where_clause(&generics.where_clause)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
2016-03-06 12:54:44 +00:00
|
|
|
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?;
|
2014-03-16 18:58:11 +00:00
|
|
|
if decl.variadic {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(", ...")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.pclose()?;
|
2011-12-30 21:32:42 +00:00
|
|
|
|
2014-11-09 15:14:15 +00:00
|
|
|
self.print_fn_output(decl)
|
2013-10-25 05:56:34 +00:00
|
|
|
}
|
2012-02-22 10:16:25 +00:00
|
|
|
|
2014-07-30 05:08:39 +00:00
|
|
|
pub fn print_fn_block_args(
|
|
|
|
&mut self,
|
2015-02-03 16:34:05 +00:00
|
|
|
decl: &ast::FnDecl)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("|")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("|")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2016-02-08 14:04:11 +00:00
|
|
|
if let ast::FunctionRetTy::Default(..) = decl.output {
|
2015-01-18 13:49:19 +00:00
|
|
|
return Ok(());
|
2012-09-08 01:53:14 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.word_space("->")?;
|
2014-11-09 15:14:15 +00:00
|
|
|
match decl.output {
|
2016-02-08 14:04:11 +00:00
|
|
|
ast::FunctionRetTy::Ty(ref ty) => {
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?;
|
2017-07-31 20:04:34 +00:00
|
|
|
self.maybe_print_comment(ty.span.lo())
|
2014-11-09 15:14:15 +00:00
|
|
|
}
|
2016-02-08 14:04:11 +00:00
|
|
|
ast::FunctionRetTy::Default(..) => unreachable!(),
|
2014-11-09 15:14:15 +00:00
|
|
|
}
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2016-02-08 14:27:08 +00:00
|
|
|
pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2014-07-23 19:43:29 +00:00
|
|
|
match capture_clause {
|
2016-02-08 14:27:08 +00:00
|
|
|
ast::CaptureBy::Value => self.word_space("move"),
|
|
|
|
ast::CaptureBy::Ref => Ok(()),
|
2014-07-23 19:43:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-02 16:47:11 +00:00
|
|
|
pub fn print_bounds(&mut self,
|
2014-08-28 01:46:52 +00:00
|
|
|
prefix: &str,
|
2014-11-20 20:05:29 +00:00
|
|
|
bounds: &[ast::TyParamBound])
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2014-08-28 01:46:52 +00:00
|
|
|
if !bounds.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(prefix)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
let mut first = true;
|
2015-01-31 17:20:46 +00:00
|
|
|
for bound in bounds {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.nbsp()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
if first {
|
|
|
|
first = false;
|
|
|
|
} else {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("+")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-10-28 22:22:49 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
(match *bound {
|
2014-12-24 06:38:10 +00:00
|
|
|
TraitTyParamBound(ref tref, TraitBoundModifier::None) => {
|
|
|
|
self.print_poly_trait_ref(tref)
|
|
|
|
}
|
|
|
|
TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("?")?;
|
2014-11-07 11:53:45 +00:00
|
|
|
self.print_poly_trait_ref(tref)
|
2014-08-28 01:46:52 +00:00
|
|
|
}
|
|
|
|
RegionTyParamBound(ref lt) => {
|
|
|
|
self.print_lifetime(lt)
|
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
})?
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Ok(())
|
2013-10-28 22:22:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_lifetime(&mut self,
|
2014-08-06 02:59:24 +00:00
|
|
|
lifetime: &ast::Lifetime)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()>
|
2014-08-06 02:59:24 +00:00
|
|
|
{
|
2017-03-25 21:14:18 +00:00
|
|
|
self.print_name(lifetime.ident.name)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-10-28 22:22:49 +00:00
|
|
|
|
2016-06-29 12:53:01 +00:00
|
|
|
pub fn print_lifetime_bounds(&mut self,
|
|
|
|
lifetime: &ast::Lifetime,
|
|
|
|
bounds: &[ast::Lifetime])
|
|
|
|
-> io::Result<()>
|
2014-08-06 02:59:24 +00:00
|
|
|
{
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_lifetime(lifetime)?;
|
2016-06-29 12:53:01 +00:00
|
|
|
if !bounds.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(": ")?;
|
2016-06-29 12:53:01 +00:00
|
|
|
for (i, bound) in bounds.iter().enumerate() {
|
|
|
|
if i != 0 {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(" + ")?;
|
2016-06-29 12:53:01 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_lifetime(bound)?;
|
2016-06-29 12:53:01 +00:00
|
|
|
}
|
2014-08-06 02:59:24 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-08-28 01:46:52 +00:00
|
|
|
pub fn print_generics(&mut self,
|
|
|
|
generics: &ast::Generics)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()>
|
2014-08-28 01:46:52 +00:00
|
|
|
{
|
|
|
|
let total = generics.lifetimes.len() + generics.ty_params.len();
|
|
|
|
if total == 0 {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("<")?;
|
2014-08-28 01:46:52 +00:00
|
|
|
|
2014-08-11 16:32:26 +00:00
|
|
|
let mut ints = Vec::new();
|
2015-01-28 01:01:48 +00:00
|
|
|
for i in 0..total {
|
2014-08-11 16:32:26 +00:00
|
|
|
ints.push(i);
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(Inconsistent, &ints[..], |s, &idx| {
|
2014-08-28 01:46:52 +00:00
|
|
|
if idx < generics.lifetimes.len() {
|
2016-06-29 12:53:01 +00:00
|
|
|
let lifetime_def = &generics.lifetimes[idx];
|
2016-12-29 21:57:01 +00:00
|
|
|
s.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
2016-06-29 12:53:01 +00:00
|
|
|
s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
|
2014-08-11 16:32:26 +00:00
|
|
|
} else {
|
2014-08-28 01:46:52 +00:00
|
|
|
let idx = idx - generics.lifetimes.len();
|
2014-11-24 04:56:34 +00:00
|
|
|
let param = &generics.ty_params[idx];
|
2014-10-28 18:48:52 +00:00
|
|
|
s.print_ty_param(param)
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
})?;
|
2014-08-11 16:32:26 +00:00
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(">")?;
|
2014-08-28 01:46:52 +00:00
|
|
|
Ok(())
|
2011-08-03 04:26:54 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_outer_attributes_inline(¶m.attrs)?;
|
|
|
|
self.print_ident(param.ident)?;
|
|
|
|
self.print_bounds(":", ¶m.bounds)?;
|
2014-10-28 18:48:52 +00:00
|
|
|
match param.default {
|
|
|
|
Some(ref default) => {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(default)
|
2014-10-28 18:48:52 +00:00
|
|
|
}
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-14 04:54:29 +00:00
|
|
|
pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2015-03-24 23:53:34 +00:00
|
|
|
if where_clause.predicates.is_empty() {
|
2014-08-11 16:32:26 +00:00
|
|
|
return Ok(())
|
|
|
|
}
|
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("where")?;
|
2014-08-11 16:32:26 +00:00
|
|
|
|
2015-03-14 04:54:29 +00:00
|
|
|
for (i, predicate) in where_clause.predicates.iter().enumerate() {
|
2014-08-11 16:32:26 +00:00
|
|
|
if i != 0 {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space(",")?;
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
|
|
|
|
2015-11-17 14:24:49 +00:00
|
|
|
match *predicate {
|
|
|
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bound_lifetimes,
|
|
|
|
ref bounded_ty,
|
|
|
|
ref bounds,
|
|
|
|
..}) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_formal_lifetime_list(bound_lifetimes)?;
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(bounded_ty)?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_bounds(":", bounds)?;
|
2014-11-29 04:08:30 +00:00
|
|
|
}
|
2015-11-17 14:24:49 +00:00
|
|
|
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
|
|
|
|
ref bounds,
|
|
|
|
..}) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_lifetime_bounds(lifetime, bounds)?;
|
2014-12-20 10:29:19 +00:00
|
|
|
}
|
2017-01-16 18:32:13 +00:00
|
|
|
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref lhs_ty,
|
|
|
|
ref rhs_ty,
|
|
|
|
..}) => {
|
|
|
|
self.print_type(lhs_ty)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("=")?;
|
2017-01-16 18:32:13 +00:00
|
|
|
self.print_type(rhs_ty)?;
|
2014-11-29 04:08:30 +00:00
|
|
|
}
|
|
|
|
}
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
match vp.node {
|
2015-01-13 15:30:17 +00:00
|
|
|
ast::ViewPathSimple(ident, ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, false, 0, true)?;
|
2014-08-13 02:25:05 +00:00
|
|
|
|
|
|
|
if path.segments.last().unwrap().identifier.name !=
|
|
|
|
ident.name {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_space("as")?;
|
|
|
|
self.print_ident(ident)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-08-13 02:25:05 +00:00
|
|
|
|
|
|
|
Ok(())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-02-15 05:50:03 +00:00
|
|
|
|
2015-01-13 15:30:17 +00:00
|
|
|
ast::ViewPathGlob(ref path) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, false, 0, true)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("::*")
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2015-01-13 15:30:17 +00:00
|
|
|
ast::ViewPathList(ref path, ref idents) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
if path.segments.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("{")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
} else {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_path(path, false, 0, true)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("::{")?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.commasep(Inconsistent, &idents[..], |s, w| {
|
|
|
|
s.print_ident(w.node.name)?;
|
2016-08-12 09:01:22 +00:00
|
|
|
if let Some(ident) = w.node.rename {
|
2017-06-25 03:22:42 +00:00
|
|
|
s.s.space()?;
|
2016-12-29 21:57:01 +00:00
|
|
|
s.word_space("as")?;
|
|
|
|
s.print_ident(ident)?;
|
2014-07-17 22:56:56 +00:00
|
|
|
}
|
2016-08-12 09:01:22 +00:00
|
|
|
Ok(())
|
2016-12-29 21:57:01 +00:00
|
|
|
})?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("}")
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-02-01 19:24:42 +00:00
|
|
|
}
|
2011-06-21 21:23:16 +00:00
|
|
|
}
|
2011-06-15 01:53:12 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_mutability(&mut self,
|
2015-02-27 05:00:43 +00:00
|
|
|
mutbl: ast::Mutability) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
match mutbl {
|
2016-02-09 16:44:47 +00:00
|
|
|
ast::Mutability::Mutable => self.word_nbsp("mut"),
|
|
|
|
ast::Mutability::Immutable => Ok(()),
|
2013-01-31 01:20:02 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_mutability(mt.mutbl)?;
|
2016-02-08 22:55:55 +00:00
|
|
|
self.print_type(&mt.ty)
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2016-01-21 18:44:36 +00:00
|
|
|
pub fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) -> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
match input.ty.node {
|
2016-12-29 21:57:01 +00:00
|
|
|
ast::TyKind::Infer if is_closure => self.print_pat(&input.pat)?,
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => {
|
2016-05-08 18:18:21 +00:00
|
|
|
if let Some(eself) = input.to_self() {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_explicit_self(&eself)?;
|
2016-05-08 18:18:21 +00:00
|
|
|
} else {
|
2016-03-06 12:54:44 +00:00
|
|
|
let invalid = if let PatKind::Ident(_, ident, _) = input.pat.node {
|
|
|
|
ident.node.name == keywords::Invalid.name()
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
};
|
2016-05-08 18:18:21 +00:00
|
|
|
if !invalid {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_pat(&input.pat)?;
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(":")?;
|
|
|
|
self.s.space()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_type(&input.ty)?;
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2012-11-07 02:41:06 +00:00
|
|
|
}
|
2012-05-04 19:33:04 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> io::Result<()> {
|
2016-02-08 14:04:11 +00:00
|
|
|
if let ast::FunctionRetTy::Default(..) = decl.output {
|
2015-01-18 13:49:19 +00:00
|
|
|
return Ok(());
|
2014-09-06 04:27:47 +00:00
|
|
|
}
|
2014-11-09 15:14:15 +00:00
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.ibox(INDENT_UNIT)?;
|
|
|
|
self.word_space("->")?;
|
2014-11-09 15:14:15 +00:00
|
|
|
match decl.output {
|
2016-02-08 14:04:11 +00:00
|
|
|
ast::FunctionRetTy::Default(..) => unreachable!(),
|
|
|
|
ast::FunctionRetTy::Ty(ref ty) =>
|
2017-05-12 18:05:39 +00:00
|
|
|
self.print_type(ty)?
|
2014-11-09 15:14:15 +00:00
|
|
|
}
|
2016-12-29 21:57:01 +00:00
|
|
|
self.end()?;
|
2014-11-09 15:14:15 +00:00
|
|
|
|
|
|
|
match decl.output {
|
2017-07-31 20:04:34 +00:00
|
|
|
ast::FunctionRetTy::Ty(ref output) => self.maybe_print_comment(output.span.lo()),
|
2014-11-09 15:14:15 +00:00
|
|
|
_ => Ok(())
|
|
|
|
}
|
2014-09-06 04:27:47 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_ty_fn(&mut self,
|
2015-01-24 20:06:31 +00:00
|
|
|
abi: abi::Abi,
|
2014-12-09 15:36:46 +00:00
|
|
|
unsafety: ast::Unsafety,
|
2014-03-16 18:58:11 +00:00
|
|
|
decl: &ast::FnDecl,
|
2015-03-11 06:38:27 +00:00
|
|
|
name: Option<ast::Ident>,
|
2016-03-06 12:54:44 +00:00
|
|
|
generics: &ast::Generics)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.ibox(INDENT_UNIT)?;
|
2015-03-24 23:54:09 +00:00
|
|
|
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("for")?;
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_generics(generics)?;
|
2015-03-18 18:54:06 +00:00
|
|
|
}
|
|
|
|
let generics = ast::Generics {
|
|
|
|
lifetimes: Vec::new(),
|
2017-01-16 22:54:59 +00:00
|
|
|
ty_params: Vec::new(),
|
2015-03-18 18:54:06 +00:00
|
|
|
where_clause: ast::WhereClause {
|
|
|
|
id: ast::DUMMY_NODE_ID,
|
|
|
|
predicates: Vec::new(),
|
2017-07-27 04:37:35 +00:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2015-03-18 18:54:06 +00:00
|
|
|
},
|
2016-08-10 17:39:12 +00:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2015-03-18 18:54:06 +00:00
|
|
|
};
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_fn(decl,
|
2016-03-22 22:58:45 +00:00
|
|
|
unsafety,
|
|
|
|
ast::Constness::NotConst,
|
|
|
|
abi,
|
|
|
|
name,
|
|
|
|
&generics,
|
2016-12-29 21:57:01 +00:00
|
|
|
&ast::Visibility::Inherited)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end()
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2016-06-21 22:08:13 +00:00
|
|
|
pub fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span,
|
2014-03-16 18:58:11 +00:00
|
|
|
next_pos: Option<BytePos>)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
let cm = match self.cm {
|
|
|
|
Some(cm) => cm,
|
|
|
|
_ => return Ok(())
|
|
|
|
};
|
2016-06-14 05:43:30 +00:00
|
|
|
if let Some(ref cmnt) = self.next_comment() {
|
2016-10-12 17:54:41 +00:00
|
|
|
if cmnt.style != comments::Trailing { return Ok(()) }
|
2017-07-31 20:04:34 +00:00
|
|
|
let span_line = cm.lookup_char_pos(span.hi());
|
2016-10-12 17:54:41 +00:00
|
|
|
let comment_line = cm.lookup_char_pos(cmnt.pos);
|
|
|
|
let next = next_pos.unwrap_or(cmnt.pos + BytePos(1));
|
2017-07-31 20:04:34 +00:00
|
|
|
if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line {
|
2016-06-14 05:43:30 +00:00
|
|
|
self.print_comment(cmnt)?;
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_remaining_comments(&mut self) -> io::Result<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
// If there aren't any remaining comments, then we need to manually
|
|
|
|
// make sure there is a line break at the end.
|
|
|
|
if self.next_comment().is_none() {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.hardbreak()?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2017-05-12 18:05:39 +00:00
|
|
|
while let Some(ref cmnt) = self.next_comment() {
|
|
|
|
self.print_comment(cmnt)?;
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-02 08:19:41 +00:00
|
|
|
pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
|
2016-02-05 12:13:36 +00:00
|
|
|
opt_abi: Option<Abi>)
|
2015-02-27 05:00:43 +00:00
|
|
|
-> io::Result<()> {
|
2014-04-02 08:19:41 +00:00
|
|
|
match opt_abi {
|
2016-02-05 12:13:36 +00:00
|
|
|
Some(Abi::Rust) => Ok(()),
|
2014-04-02 08:19:41 +00:00
|
|
|
Some(abi) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_nbsp("extern")?;
|
2015-02-18 23:58:07 +00:00
|
|
|
self.word_nbsp(&abi.to_string())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-04-02 08:19:41 +00:00
|
|
|
None => Ok(())
|
2013-10-29 22:06:13 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-10-29 22:06:13 +00:00
|
|
|
|
2014-04-02 08:19:41 +00:00
|
|
|
pub fn print_extern_opt_abi(&mut self,
|
2016-02-05 12:13:36 +00:00
|
|
|
opt_abi: Option<Abi>) -> io::Result<()> {
|
2014-04-02 08:19:41 +00:00
|
|
|
match opt_abi {
|
|
|
|
Some(abi) => {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_nbsp("extern")?;
|
2015-02-18 23:58:07 +00:00
|
|
|
self.word_nbsp(&abi.to_string())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
None => Ok(())
|
2013-03-14 02:25:28 +00:00
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2013-02-01 01:12:29 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_fn_header_info(&mut self,
|
2015-03-11 06:38:27 +00:00
|
|
|
unsafety: ast::Unsafety,
|
2015-02-25 20:05:07 +00:00
|
|
|
constness: ast::Constness,
|
2016-02-05 12:13:36 +00:00
|
|
|
abi: Abi,
|
2016-03-23 10:17:34 +00:00
|
|
|
vis: &ast::Visibility) -> io::Result<()> {
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word(&visibility_qualified(vis, ""))?;
|
2014-05-07 23:33:43 +00:00
|
|
|
|
2015-02-25 20:05:07 +00:00
|
|
|
match constness {
|
|
|
|
ast::Constness::NotConst => {}
|
2016-12-29 21:57:01 +00:00
|
|
|
ast::Constness::Const => self.word_nbsp("const")?
|
2015-02-25 20:05:07 +00:00
|
|
|
}
|
|
|
|
|
2016-12-29 21:57:01 +00:00
|
|
|
self.print_unsafety(unsafety)?;
|
2015-10-24 08:52:07 +00:00
|
|
|
|
2016-02-05 12:13:36 +00:00
|
|
|
if abi != Abi::Rust {
|
2016-12-29 21:57:01 +00:00
|
|
|
self.word_nbsp("extern")?;
|
|
|
|
self.word_nbsp(&abi.to_string())?;
|
2013-03-14 02:25:28 +00:00
|
|
|
}
|
|
|
|
|
2017-06-25 03:22:42 +00:00
|
|
|
self.s.word("fn")
|
2012-05-25 06:44:58 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 05:00:43 +00:00
|
|
|
pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> {
|
2014-04-07 01:04:40 +00:00
|
|
|
match s {
|
2014-12-09 15:36:46 +00:00
|
|
|
ast::Unsafety::Normal => Ok(()),
|
|
|
|
ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-05-25 06:44:58 +00:00
|
|
|
}
|
2017-10-12 12:51:31 +00:00
|
|
|
|
|
|
|
pub fn print_is_auto(&mut self, s: ast::IsAuto) -> io::Result<()> {
|
|
|
|
match s {
|
|
|
|
ast::IsAuto::Yes => self.word_nbsp("auto"),
|
|
|
|
ast::IsAuto::No => Ok(()),
|
|
|
|
}
|
|
|
|
}
|
2012-11-05 04:41:00 +00:00
|
|
|
}
|
|
|
|
|
2015-01-17 23:33:05 +00:00
|
|
|
fn repeat(s: &str, n: usize) -> String { iter::repeat(s).take(n).collect() }
|
2014-12-11 03:46:38 +00:00
|
|
|
|
2013-01-24 22:10:38 +00:00
|
|
|
#[cfg(test)]
|
2015-04-24 15:30:41 +00:00
|
|
|
mod tests {
|
2013-02-25 19:11:21 +00:00
|
|
|
use super::*;
|
|
|
|
|
2013-01-24 22:10:38 +00:00
|
|
|
use ast;
|
2013-02-25 19:11:21 +00:00
|
|
|
use codemap;
|
2016-06-22 16:50:19 +00:00
|
|
|
use syntax_pos;
|
2013-01-24 22:10:38 +00:00
|
|
|
|
|
|
|
#[test]
|
2014-06-21 10:39:03 +00:00
|
|
|
fn test_fun_to_string() {
|
2016-11-17 14:04:36 +00:00
|
|
|
let abba_ident = ast::Ident::from_str("abba");
|
2013-01-24 22:10:38 +00:00
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
let decl = ast::FnDecl {
|
2014-02-28 21:09:09 +00:00
|
|
|
inputs: Vec::new(),
|
2016-06-21 22:08:13 +00:00
|
|
|
output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP),
|
2013-10-25 05:56:34 +00:00
|
|
|
variadic: false
|
2013-01-24 22:10:38 +00:00
|
|
|
};
|
2015-11-28 19:02:07 +00:00
|
|
|
let generics = ast::Generics::default();
|
2015-02-25 20:05:07 +00:00
|
|
|
assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal,
|
|
|
|
ast::Constness::NotConst,
|
2016-03-06 12:54:44 +00:00
|
|
|
abba_ident, &generics),
|
2014-11-28 00:52:53 +00:00
|
|
|
"fn abba()");
|
2013-01-24 22:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2014-06-21 10:39:03 +00:00
|
|
|
fn test_variant_to_string() {
|
2016-11-17 14:04:36 +00:00
|
|
|
let ident = ast::Ident::from_str("principal_skinner");
|
2013-01-24 22:10:38 +00:00
|
|
|
|
2016-06-22 16:50:19 +00:00
|
|
|
let var = codemap::respan(syntax_pos::DUMMY_SP, ast::Variant_ {
|
2013-01-24 22:10:38 +00:00
|
|
|
name: ident,
|
2014-02-28 21:09:09 +00:00
|
|
|
attrs: Vec::new(),
|
2013-01-24 22:10:38 +00:00
|
|
|
// making this up as I go.... ?
|
2015-10-25 15:33:51 +00:00
|
|
|
data: ast::VariantData::Unit(ast::DUMMY_NODE_ID),
|
2013-01-24 22:10:38 +00:00
|
|
|
disr_expr: None,
|
|
|
|
});
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
let varstr = variant_to_string(&var);
|
2015-09-16 17:01:15 +00:00
|
|
|
assert_eq!(varstr, "principal_skinner");
|
2013-01-24 22:10:38 +00:00
|
|
|
}
|
|
|
|
}
|