2019-02-07 02:33:01 +09:00
|
|
|
use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
|
|
|
|
use crate::ast::{SelfKind, GenericBound, TraitBoundModifier};
|
|
|
|
use crate::ast::{Attribute, MacDelimiter, GenericArg};
|
|
|
|
use crate::util::parser::{self, AssocOp, Fixity};
|
2019-10-11 14:39:52 +02:00
|
|
|
use crate::util::comments;
|
2019-02-07 02:33:01 +09:00
|
|
|
use crate::attr;
|
|
|
|
use crate::source_map::{self, SourceMap, Spanned};
|
2019-10-11 12:46:32 +02:00
|
|
|
use crate::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind};
|
2019-02-07 02:33:01 +09:00
|
|
|
use crate::print::pp::{self, Breaks};
|
|
|
|
use crate::print::pp::Breaks::{Consistent, Inconsistent};
|
|
|
|
use crate::ptr::P;
|
2019-10-11 13:17:20 +02:00
|
|
|
use crate::util::classify;
|
2019-10-14 10:08:26 +02:00
|
|
|
use crate::sess::ParseSess;
|
2019-05-11 17:41:37 +03:00
|
|
|
use crate::symbol::{kw, sym};
|
2019-02-07 02:33:01 +09:00
|
|
|
use crate::tokenstream::{self, TokenStream, TokenTree};
|
|
|
|
|
2016-06-21 18:08:13 -04:00
|
|
|
use syntax_pos::{self, BytePos};
|
2019-08-04 17:59:06 -04:00
|
|
|
use syntax_pos::{FileName, Span};
|
2012-12-23 17:41:37 -05:00
|
|
|
|
2018-11-29 11:36:58 +11:00
|
|
|
use std::borrow::Cow;
|
2013-05-24 19:35:29 -07:00
|
|
|
|
2019-08-02 00:26:40 +03:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests;
|
|
|
|
|
2019-07-14 16:09:39 +03:00
|
|
|
pub enum MacHeader<'a> {
|
|
|
|
Path(&'a ast::Path),
|
|
|
|
Keyword(&'static str),
|
|
|
|
}
|
|
|
|
|
2014-03-16 20:58:11 +02:00
|
|
|
pub enum AnnNode<'a> {
|
2018-08-22 22:05:19 +01:00
|
|
|
Ident(&'a ast::Ident),
|
|
|
|
Name(&'a ast::Name),
|
|
|
|
Block(&'a ast::Block),
|
|
|
|
Item(&'a ast::Item),
|
|
|
|
SubItem(ast::NodeId),
|
|
|
|
Expr(&'a ast::Expr),
|
|
|
|
Pat(&'a ast::Pat),
|
2019-07-14 21:17:37 +01:00
|
|
|
Crate(&'a ast::Crate),
|
2011-07-05 11:48:19 +02:00
|
|
|
}
|
2013-08-29 15:24:33 -07:00
|
|
|
|
2014-01-09 15:05:33 +02:00
|
|
|
pub trait PpAnn {
|
2019-06-24 14:15:11 -04:00
|
|
|
fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { }
|
|
|
|
fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { }
|
2013-08-29 15:24:33 -07:00
|
|
|
}
|
|
|
|
|
2015-03-30 09:38:59 -04:00
|
|
|
#[derive(Copy, Clone)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub struct NoAnn;
|
2011-07-05 11:48:19 +02:00
|
|
|
|
2014-01-09 15:05:33 +02:00
|
|
|
impl PpAnn for NoAnn {}
|
2013-08-29 15:24:33 -07:00
|
|
|
|
2019-07-05 18:29:15 -04:00
|
|
|
pub struct Comments<'a> {
|
|
|
|
cm: &'a SourceMap,
|
|
|
|
comments: Vec<comments::Comment>,
|
|
|
|
current: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Comments<'a> {
|
|
|
|
pub fn new(
|
|
|
|
cm: &'a SourceMap,
|
|
|
|
sess: &ParseSess,
|
|
|
|
filename: FileName,
|
|
|
|
input: String,
|
|
|
|
) -> Comments<'a> {
|
|
|
|
let comments = comments::gather_comments(sess, filename, input);
|
|
|
|
Comments {
|
|
|
|
cm,
|
|
|
|
comments,
|
|
|
|
current: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn next(&self) -> Option<comments::Comment> {
|
|
|
|
self.comments.get(self.current).cloned()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn trailing_comment(
|
|
|
|
&mut self,
|
|
|
|
span: syntax_pos::Span,
|
|
|
|
next_pos: Option<BytePos>,
|
|
|
|
) -> Option<comments::Comment> {
|
|
|
|
if let Some(cmnt) = self.next() {
|
|
|
|
if cmnt.style != comments::Trailing { return None; }
|
|
|
|
let span_line = self.cm.lookup_char_pos(span.hi());
|
|
|
|
let comment_line = self.cm.lookup_char_pos(cmnt.pos);
|
|
|
|
let next = next_pos.unwrap_or_else(|| cmnt.pos + BytePos(1));
|
|
|
|
if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line {
|
|
|
|
return Some(cmnt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-17 22:27:37 -07:00
|
|
|
pub struct State<'a> {
|
2019-07-05 19:10:18 -04:00
|
|
|
pub s: pp::Printer,
|
2019-07-05 18:29:15 -04:00
|
|
|
comments: Option<Comments<'a>>,
|
2018-07-10 21:06:26 +02:00
|
|
|
ann: &'a (dyn PpAnn+'a),
|
2018-07-12 23:35:40 +02:00
|
|
|
is_expanded: bool
|
2013-02-04 14:02:01 -08:00
|
|
|
}
|
2011-07-05 11:48:19 +02:00
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate const INDENT_UNIT: usize = 4;
|
2011-07-05 11:48:19 +02:00
|
|
|
|
2014-06-09 13:12:30 -07:00
|
|
|
/// Requires you to pass an input filename and reader so that
|
2019-05-09 19:04:04 +03:00
|
|
|
/// it can scan the input text for comments to copy forward.
|
2018-08-18 12:13:35 +02:00
|
|
|
pub fn print_crate<'a>(cm: &'a SourceMap,
|
2017-01-17 01:14:53 +00:00
|
|
|
sess: &ParseSess,
|
2014-03-17 22:27:37 -07:00
|
|
|
krate: &ast::Crate,
|
2017-12-14 08:09:19 +01:00
|
|
|
filename: FileName,
|
2019-07-05 17:12:11 -04:00
|
|
|
input: String,
|
2018-07-10 21:06:26 +02:00
|
|
|
ann: &'a dyn PpAnn,
|
2019-07-05 17:48:21 -04:00
|
|
|
is_expanded: bool) -> String {
|
2019-07-05 18:32:04 -04:00
|
|
|
let mut s = State {
|
2019-07-05 19:10:18 -04:00
|
|
|
s: pp::mk_printer(),
|
2019-07-05 18:32:04 -04:00
|
|
|
comments: Some(Comments::new(cm, sess, filename, input)),
|
|
|
|
ann,
|
|
|
|
is_expanded,
|
|
|
|
};
|
2017-01-17 01:14:53 +00:00
|
|
|
|
2019-07-18 22:29:07 +03:00
|
|
|
if is_expanded && sess.injected_crate_name.try_get().is_some() {
|
2015-02-05 17:04:11 -08:00
|
|
|
// We need to print `#![no_std]` (and its feature gate) so that
|
|
|
|
// compiling pretty-printed source won't inject libstd again.
|
2019-09-06 03:56:45 +01:00
|
|
|
// However, we don't want these attributes in the AST because
|
2015-02-05 17:04:11 -08:00
|
|
|
// of the feature gate, so we fake them up here.
|
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
// `#![feature(prelude_import)]`
|
2019-08-11 02:20:18 +03:00
|
|
|
let pi_nested = attr::mk_nested_word_item(ast::Ident::with_dummy_span(sym::prelude_import));
|
|
|
|
let list = attr::mk_list_item(ast::Ident::with_dummy_span(sym::feature), vec![pi_nested]);
|
2019-07-30 14:18:19 -04:00
|
|
|
let fake_attr = attr::mk_attr_inner(list);
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_attribute(&fake_attr);
|
2015-02-05 17:04:11 -08:00
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
// Currently, in Rust 2018 we don't have `extern crate std;` at the crate
|
2019-08-25 22:36:13 +01:00
|
|
|
// root, so this is not needed, and actually breaks things.
|
|
|
|
if sess.edition == syntax_pos::edition::Edition::Edition2015 {
|
2019-09-06 03:56:45 +01:00
|
|
|
// `#![no_std]`
|
2019-08-25 22:36:13 +01:00
|
|
|
let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std));
|
|
|
|
let fake_attr = attr::mk_attr_inner(no_std_meta);
|
|
|
|
s.print_attribute(&fake_attr);
|
|
|
|
}
|
2015-02-05 17:04:11 -08:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_mod(&krate.module, &krate.attrs);
|
|
|
|
s.print_remaining_comments();
|
2019-07-14 21:17:37 +01:00
|
|
|
s.ann.post(&mut s, AnnNode::Crate(krate));
|
2019-07-05 19:10:18 -04:00
|
|
|
s.s.eof()
|
2012-02-21 15:34:26 -08:00
|
|
|
}
|
|
|
|
|
2014-12-08 13:28:32 -05:00
|
|
|
pub fn to_string<F>(f: F) -> String where
|
2019-06-24 14:15:11 -04:00
|
|
|
F: FnOnce(&mut State<'_>),
|
2014-12-08 13:28:32 -05:00
|
|
|
{
|
2019-07-05 19:10:18 -04:00
|
|
|
let mut printer = State {
|
|
|
|
s: pp::mk_printer(),
|
|
|
|
comments: None,
|
|
|
|
ann: &NoAnn,
|
|
|
|
is_expanded: false
|
|
|
|
};
|
|
|
|
f(&mut printer);
|
|
|
|
printer.s.eof()
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2019-08-25 20:41:52 +03:00
|
|
|
// This makes comma-separated lists look slightly nicer,
|
|
|
|
// and also addresses a specific regression described in issue #63896.
|
|
|
|
fn tt_prepend_space(tt: &TokenTree) -> bool {
|
|
|
|
match tt {
|
|
|
|
TokenTree::Token(token) => match token.kind {
|
|
|
|
token::Comma => false,
|
|
|
|
_ => true,
|
|
|
|
}
|
|
|
|
_ => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-25 07:51:55 -06:00
|
|
|
fn binop_to_string(op: BinOpToken) -> &'static str {
|
2014-10-28 11:05:28 +11:00
|
|
|
match op {
|
|
|
|
token::Plus => "+",
|
|
|
|
token::Minus => "-",
|
|
|
|
token::Star => "*",
|
|
|
|
token::Slash => "/",
|
|
|
|
token::Percent => "%",
|
|
|
|
token::Caret => "^",
|
|
|
|
token::And => "&",
|
|
|
|
token::Or => "|",
|
|
|
|
token::Shl => "<<",
|
|
|
|
token::Shr => ">>",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-19 19:56:45 +03:00
|
|
|
pub fn literal_to_string(lit: token::Lit) -> String {
|
|
|
|
let token::Lit { kind, symbol, suffix } = lit;
|
2019-05-19 01:04:26 +03:00
|
|
|
let mut out = match kind {
|
|
|
|
token::Byte => format!("b'{}'", symbol),
|
|
|
|
token::Char => format!("'{}'", symbol),
|
|
|
|
token::Str => format!("\"{}\"", symbol),
|
|
|
|
token::StrRaw(n) => format!("r{delim}\"{string}\"{delim}",
|
|
|
|
delim="#".repeat(n as usize),
|
|
|
|
string=symbol),
|
|
|
|
token::ByteStr => format!("b\"{}\"", symbol),
|
|
|
|
token::ByteStrRaw(n) => format!("br{delim}\"{string}\"{delim}",
|
|
|
|
delim="#".repeat(n as usize),
|
|
|
|
string=symbol),
|
2019-06-07 12:53:33 +03:00
|
|
|
token::Integer |
|
|
|
|
token::Float |
|
|
|
|
token::Bool |
|
|
|
|
token::Err => symbol.to_string(),
|
2019-05-09 19:04:04 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(suffix) = suffix {
|
|
|
|
out.push_str(&suffix.as_str())
|
|
|
|
}
|
|
|
|
|
|
|
|
out
|
|
|
|
}
|
|
|
|
|
2019-07-11 12:34:57 +03:00
|
|
|
/// Print an ident from AST, `$crate` is converted into its respective crate name.
|
2019-07-13 19:11:07 +03:00
|
|
|
pub fn ast_ident_to_string(ident: ast::Ident, is_raw: bool) -> String {
|
2019-07-11 12:34:57 +03:00
|
|
|
ident_to_string(ident.name, is_raw, Some(ident.span))
|
2019-07-04 02:37:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// AST pretty-printer is used as a fallback for turning AST structures into token streams for
|
|
|
|
// proc macros. Additionally, proc macros may stringify their input and expect it survive the
|
|
|
|
// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
|
|
|
|
// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
|
|
|
|
// hygiene data, most importantly name of the crate it refers to.
|
|
|
|
// As a result we print `$crate` as `crate` if it refers to the local crate
|
|
|
|
// and as `::other_crate_name` if it refers to some other crate.
|
|
|
|
// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
|
|
|
|
// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
|
|
|
|
// so we should not perform this lossy conversion if the top level call to the pretty-printer was
|
|
|
|
// done for a token stream or a single token.
|
2019-07-11 12:34:57 +03:00
|
|
|
fn ident_to_string(name: ast::Name, is_raw: bool, convert_dollar_crate: Option<Span>) -> String {
|
2019-07-04 02:37:34 +03:00
|
|
|
if is_raw {
|
|
|
|
format!("r#{}", name)
|
|
|
|
} else {
|
|
|
|
if name == kw::DollarCrate {
|
|
|
|
if let Some(span) = convert_dollar_crate {
|
|
|
|
let converted = span.ctxt().dollar_crate_name();
|
|
|
|
return if converted.is_path_segment_keyword() {
|
|
|
|
converted.to_string()
|
|
|
|
} else {
|
|
|
|
format!("::{}", converted)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
name.to_string()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-11 12:34:57 +03:00
|
|
|
/// Print the token kind precisely, without converting `$crate` into its respective crate name.
|
2019-06-08 22:38:23 +03:00
|
|
|
pub fn token_kind_to_string(tok: &TokenKind) -> String {
|
2019-07-04 02:37:34 +03:00
|
|
|
token_kind_to_string_ext(tok, None)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>) -> String {
|
2014-10-28 11:05:28 +11:00
|
|
|
match *tok {
|
2014-12-10 19:46:38 -08: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 11:05:28 +11:00
|
|
|
token::BinOpEq(op) => format!("{}=", binop_to_string(op)),
|
|
|
|
|
|
|
|
/* Structural symbols */
|
2014-12-10 19:46:38 -08: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(),
|
2014-12-10 19:46:38 -08: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 20:05:39 +02:00
|
|
|
token::OpenDelim(token::NoDelim) |
|
2016-07-19 13:00:45 -07:00
|
|
|
token::CloseDelim(token::NoDelim) => " ".to_string(),
|
2014-12-10 19:46:38 -08:00
|
|
|
token::Pound => "#".to_string(),
|
|
|
|
token::Dollar => "$".to_string(),
|
|
|
|
token::Question => "?".to_string(),
|
2018-05-14 00:01:56 +03:00
|
|
|
token::SingleQuote => "'".to_string(),
|
2014-10-28 11:05:28 +11:00
|
|
|
|
|
|
|
/* Literals */
|
2019-05-19 01:04:26 +03:00
|
|
|
token::Literal(lit) => literal_to_string(lit),
|
2014-10-28 11:05:28 +11:00
|
|
|
|
|
|
|
/* Name components */
|
2019-07-11 12:34:57 +03:00
|
|
|
token::Ident(s, is_raw) => ident_to_string(s, is_raw, convert_dollar_crate),
|
2015-07-28 18:07:20 +02:00
|
|
|
token::Lifetime(s) => s.to_string(),
|
2014-10-28 11:05:28 +11:00
|
|
|
|
|
|
|
/* Other */
|
2015-07-28 18:07:20 +02:00
|
|
|
token::DocComment(s) => s.to_string(),
|
2014-12-10 19:46:38 -08:00
|
|
|
token::Eof => "<eof>".to_string(),
|
|
|
|
token::Whitespace => " ".to_string(),
|
|
|
|
token::Comment => "/* */".to_string(),
|
2015-07-28 18:07:20 +02:00
|
|
|
token::Shebang(s) => format!("/* shebang: {}*/", s),
|
2019-07-30 12:31:41 +03:00
|
|
|
token::Unknown(s) => s.to_string(),
|
2014-10-28 11:05:28 +11:00
|
|
|
|
2019-02-15 09:10:02 +11:00
|
|
|
token::Interpolated(ref nt) => nonterminal_to_string(nt),
|
2019-02-15 08:31:44 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-11 12:34:57 +03:00
|
|
|
/// Print the token precisely, without converting `$crate` into its respective crate name.
|
2019-06-08 22:38:23 +03:00
|
|
|
pub fn token_to_string(token: &Token) -> String {
|
2019-07-04 02:37:34 +03:00
|
|
|
token_to_string_ext(token, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
|
|
|
|
let convert_dollar_crate = if convert_dollar_crate { Some(token.span) } else { None };
|
|
|
|
token_kind_to_string_ext(&token.kind, convert_dollar_crate)
|
2019-06-08 22:38:23 +03:00
|
|
|
}
|
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
|
2019-02-15 08:31:44 +11:00
|
|
|
match *nt {
|
|
|
|
token::NtExpr(ref e) => expr_to_string(e),
|
2019-08-18 01:10:56 +03:00
|
|
|
token::NtMeta(ref e) => attr_item_to_string(e),
|
2019-02-15 08:31:44 +11:00
|
|
|
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),
|
2019-07-11 12:34:57 +03:00
|
|
|
token::NtIdent(e, is_raw) => ast_ident_to_string(e, is_raw),
|
2019-07-04 02:37:34 +03:00
|
|
|
token::NtLifetime(e) => e.to_string(),
|
2019-02-15 08:31:44 +11:00
|
|
|
token::NtLiteral(ref e) => expr_to_string(e),
|
|
|
|
token::NtTT(ref tree) => tt_to_string(tree.clone()),
|
|
|
|
token::NtImplItem(ref e) => impl_item_to_string(e),
|
|
|
|
token::NtTraitItem(ref e) => trait_item_to_string(e),
|
|
|
|
token::NtVis(ref e) => vis_to_string(e),
|
|
|
|
token::NtForeignItem(ref e) => foreign_item_to_string(e),
|
2014-10-28 11:05:28 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-21 03:39:03 -07: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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_type(ty))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2018-06-14 12:08:58 +01:00
|
|
|
pub fn bounds_to_string(bounds: &[ast::GenericBound]) -> String {
|
2018-05-28 15:23:16 +01:00
|
|
|
to_string(|s| s.print_type_bounds("", bounds))
|
2014-11-20 15:05:29 -05:00
|
|
|
}
|
|
|
|
|
2014-06-21 03:39:03 -07: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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_pat(pat))
|
2014-06-21 03:39:03 -07: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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_expr(e))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2017-02-21 05:05:59 +00:00
|
|
|
pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
|
2019-07-04 02:37:34 +03:00
|
|
|
to_string(|s| s.print_tt(tt, false))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2019-08-31 20:08:06 +03:00
|
|
|
pub fn tts_to_string(tokens: TokenStream) -> String {
|
2019-07-11 03:16:19 +03:00
|
|
|
to_string(|s| s.print_tts(tokens, false))
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 03:39:03 -07: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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_stmt(stmt))
|
2014-06-21 03:39:03 -07: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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_item(i))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2019-07-05 16:00:38 -04:00
|
|
|
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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_impl_item(i))
|
2015-03-19 17:01:15 +00:00
|
|
|
}
|
|
|
|
|
2019-07-05 16:00:38 -04:00
|
|
|
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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_trait_item(i))
|
2015-03-19 17:01:46 +00:00
|
|
|
}
|
|
|
|
|
2018-05-27 20:07:09 +01:00
|
|
|
pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String {
|
2017-10-16 21:07:26 +02:00
|
|
|
to_string(|s| s.print_generic_params(generic_params))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn path_to_string(p: &ast::Path) -> String {
|
2018-03-10 02:02:39 +03:00
|
|
|
to_string(|s| s.print_path(p, false, 0))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2017-05-30 10:37:11 +12:00
|
|
|
pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
|
|
|
|
to_string(|s| s.print_path_segment(p, false))
|
|
|
|
}
|
|
|
|
|
2016-04-25 02:04:01 +10:00
|
|
|
pub fn vis_to_string(v: &ast::Visibility) -> String {
|
|
|
|
to_string(|s| s.print_visibility(v))
|
|
|
|
}
|
|
|
|
|
2019-07-05 16:00:38 -04:00
|
|
|
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 15:06:49 -05:00
|
|
|
to_string(|s| {
|
2019-09-06 03:56:45 +01:00
|
|
|
// Containing cbox, will be closed by `print_block` at `}`.
|
2019-06-24 14:15:11 -04:00
|
|
|
s.cbox(INDENT_UNIT);
|
2019-09-06 03:56:45 +01:00
|
|
|
// Head-ibox, will be closed by `print_block` after `{`.
|
2019-06-24 14:15:11 -04:00
|
|
|
s.ibox(0);
|
2014-06-21 03:39:03 -07:00
|
|
|
s.print_block(blk)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-08-19 18:58:14 -07:00
|
|
|
pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
|
|
|
|
to_string(|s| s.print_meta_list_item(li))
|
|
|
|
}
|
|
|
|
|
2019-08-18 01:10:56 +03:00
|
|
|
fn attr_item_to_string(ai: &ast::AttrItem) -> String {
|
|
|
|
to_string(|s| s.print_attr_item(ai, ai.path.span))
|
2014-06-21 03:39:03 -07: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 15:06:49 -05:00
|
|
|
to_string(|s| s.print_attribute(attr))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2019-08-27 13:24:32 +02:00
|
|
|
pub fn param_to_string(arg: &ast::Param) -> String {
|
|
|
|
to_string(|s| s.print_param(arg, false))
|
2014-06-21 03:39:03 -07:00
|
|
|
}
|
|
|
|
|
2019-07-05 16:00:38 -04:00
|
|
|
fn foreign_item_to_string(arg: &ast::ForeignItem) -> String {
|
2018-03-10 18:16:26 -08:00
|
|
|
to_string(|s| s.print_foreign_item(arg))
|
|
|
|
}
|
|
|
|
|
2019-07-05 16:00:38 -04:00
|
|
|
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-29 17:39:21 -08:00
|
|
|
}
|
2011-05-28 19:16:18 -07:00
|
|
|
|
2019-07-09 09:26:50 -04:00
|
|
|
impl std::ops::Deref for State<'_> {
|
|
|
|
type Target = pp::Printer;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.s
|
2012-11-04 20:41:00 -08:00
|
|
|
}
|
2019-07-09 09:26:50 -04:00
|
|
|
}
|
2011-05-28 19:16:18 -07:00
|
|
|
|
2019-07-09 09:26:50 -04:00
|
|
|
impl std::ops::DerefMut for State<'_> {
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
|
&mut self.s
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-07-09 09:26:50 -04:00
|
|
|
}
|
2011-05-28 19:16:18 -07:00
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut {
|
2019-07-09 09:26:50 -04:00
|
|
|
fn comments(&mut self) -> &mut Option<Comments<'a>>;
|
2019-07-13 19:11:07 +03:00
|
|
|
fn print_ident(&mut self, ident: ast::Ident);
|
|
|
|
fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool);
|
2011-05-28 19:16:18 -07:00
|
|
|
|
2019-07-14 01:05:52 +00:00
|
|
|
fn strsep<T, F>(&mut self, sep: &'static str, space_before: bool,
|
|
|
|
b: Breaks, elts: &[T], mut op: F)
|
2019-06-24 14:15:11 -04:00
|
|
|
where F: FnMut(&mut Self, &T),
|
2015-09-14 21:58:20 +12:00
|
|
|
{
|
2019-06-24 14:15:11 -04:00
|
|
|
self.rbox(0, b);
|
2019-07-14 01:05:52 +00:00
|
|
|
if let Some((first, rest)) = elts.split_first() {
|
|
|
|
op(self, first);
|
|
|
|
for elt in rest {
|
|
|
|
if space_before {
|
|
|
|
self.space();
|
2018-10-19 15:40:07 +01:00
|
|
|
}
|
|
|
|
self.word_space(sep);
|
2019-07-14 01:05:52 +00:00
|
|
|
op(self, elt);
|
2018-10-19 15:40:07 +01:00
|
|
|
}
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
2019-07-14 01:05:52 +00:00
|
|
|
fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], op: F)
|
2018-10-19 15:40:07 +01:00
|
|
|
where F: FnMut(&mut Self, &T),
|
|
|
|
{
|
2019-07-14 01:05:52 +00:00
|
|
|
self.strsep(",", false, b, elts, op)
|
2018-10-19 15:40:07 +01:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn maybe_print_comment(&mut self, pos: BytePos) {
|
2016-10-12 20:54:41 +03:00
|
|
|
while let Some(ref cmnt) = self.next_comment() {
|
|
|
|
if cmnt.pos < pos {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_comment(cmnt);
|
2016-10-12 20:54:41 +03:00
|
|
|
} else {
|
|
|
|
break
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_comment(&mut self,
|
2019-06-24 14:15:11 -04:00
|
|
|
cmnt: &comments::Comment) {
|
|
|
|
match cmnt.style {
|
2015-09-14 21:58:20 +12:00
|
|
|
comments::Mixed => {
|
|
|
|
assert_eq!(cmnt.lines.len(), 1);
|
2019-07-09 09:51:56 -04:00
|
|
|
self.zerobreak();
|
|
|
|
self.word(cmnt.lines[0].clone());
|
|
|
|
self.zerobreak()
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
comments::Isolated => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.hardbreak_if_not_bol();
|
2015-09-14 21:58:20 +12:00
|
|
|
for line in &cmnt.lines {
|
|
|
|
// Don't print empty lines because they will end up as trailing
|
2019-09-06 03:56:45 +01:00
|
|
|
// whitespace.
|
2015-09-14 21:58:20 +12:00
|
|
|
if !line.is_empty() {
|
2019-07-09 09:51:56 -04:00
|
|
|
self.word(line.clone());
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-07-09 09:51:56 -04:00
|
|
|
self.hardbreak();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
}
|
|
|
|
comments::Trailing => {
|
2019-07-09 09:51:56 -04:00
|
|
|
if !self.is_beginning_of_line() {
|
|
|
|
self.word(" ");
|
2016-10-12 20:54:41 +03:00
|
|
|
}
|
2015-09-14 21:58:20 +12:00
|
|
|
if cmnt.lines.len() == 1 {
|
2019-07-09 09:51:56 -04:00
|
|
|
self.word(cmnt.lines[0].clone());
|
|
|
|
self.hardbreak()
|
2015-09-14 21:58:20 +12:00
|
|
|
} else {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(0);
|
2015-09-14 21:58:20 +12:00
|
|
|
for line in &cmnt.lines {
|
|
|
|
if !line.is_empty() {
|
2019-07-09 09:51:56 -04:00
|
|
|
self.word(line.clone());
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-07-09 09:51:56 -04:00
|
|
|
self.hardbreak();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
}
|
|
|
|
comments::BlankLine => {
|
|
|
|
// We need to do at least one, possibly two hardbreaks.
|
2019-07-09 09:51:56 -04:00
|
|
|
let twice = match self.last_token() {
|
2019-07-05 09:58:34 -04:00
|
|
|
pp::Token::String(s) => ";" == s,
|
2019-07-07 10:51:18 -04:00
|
|
|
pp::Token::Begin(_) => true,
|
|
|
|
pp::Token::End => true,
|
2015-09-14 21:58:20 +12:00
|
|
|
_ => false
|
|
|
|
};
|
2019-07-07 10:51:18 -04:00
|
|
|
if twice {
|
2019-07-09 09:51:56 -04:00
|
|
|
self.hardbreak();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-07-09 09:51:56 -04:00
|
|
|
self.hardbreak();
|
2017-06-25 06:38:13 -06:00
|
|
|
}
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-07-05 18:29:15 -04:00
|
|
|
if let Some(cm) = self.comments() {
|
|
|
|
cm.current += 1;
|
|
|
|
}
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
fn next_comment(&mut self) -> Option<comments::Comment> {
|
2019-07-05 18:29:15 -04:00
|
|
|
self.comments().as_mut().and_then(|c| c.next())
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_literal(&mut self, lit: &ast::Lit) {
|
|
|
|
self.maybe_print_comment(lit.span.lo());
|
2019-07-09 09:51:56 -04:00
|
|
|
self.word(lit.token.to_string())
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_string(&mut self, st: &str,
|
2019-06-24 14:15:11 -04:00
|
|
|
style: ast::StrStyle) {
|
2015-09-14 21:58:20 +12:00
|
|
|
let st = match style {
|
2016-02-09 18:01:08 +01:00
|
|
|
ast::StrStyle::Cooked => {
|
2018-05-06 10:55:10 +09:00
|
|
|
(format!("\"{}\"", st.escape_debug()))
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2016-02-09 18:01:08 +01:00
|
|
|
ast::StrStyle::Raw(n) => {
|
2015-09-14 21:58:20 +12:00
|
|
|
(format!("r{delim}\"{string}\"{delim}",
|
2018-04-01 13:48:15 +09:00
|
|
|
delim="#".repeat(n as usize),
|
2015-09-14 21:58:20 +12:00
|
|
|
string=st))
|
|
|
|
}
|
|
|
|
};
|
2019-07-09 09:51:56 -04:00
|
|
|
self.word(st)
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_inner_attributes(&mut self,
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[ast::Attribute]) {
|
2015-11-03 17:39:51 +01:00
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_inner_attributes_no_trailing_hardbreak(&mut self,
|
|
|
|
attrs: &[ast::Attribute])
|
2019-06-24 14:15:11 -04:00
|
|
|
{
|
2015-11-03 17:39:51 +01:00
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, false)
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_outer_attributes(&mut self,
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[ast::Attribute]) {
|
2015-11-03 17:39:51 +01:00
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Outer, false, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_inner_attributes_inline(&mut self,
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[ast::Attribute]) {
|
2015-11-03 17:39:51 +01:00
|
|
|
self.print_either_attributes(attrs, ast::AttrStyle::Inner, true, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_outer_attributes_inline(&mut self,
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[ast::Attribute]) {
|
2015-11-03 17:39:51 +01:00
|
|
|
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,
|
2019-06-24 14:15:11 -04:00
|
|
|
trailing_hardbreak: bool) {
|
2015-09-14 21:58:20 +12:00
|
|
|
let mut count = 0;
|
|
|
|
for attr in attrs {
|
2016-11-14 12:00:25 +00:00
|
|
|
if attr.style == kind {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_attribute_inline(attr, is_inline);
|
2016-06-16 21:16:55 +01:00
|
|
|
if is_inline {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.nbsp();
|
2016-06-16 21:16:55 +01:00
|
|
|
}
|
|
|
|
count += 1;
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
}
|
2015-11-03 17:39:51 +01:00
|
|
|
if count > 0 && trailing_hardbreak && !is_inline {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.hardbreak_if_not_bol();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_attribute(&mut self, attr: &ast::Attribute) {
|
2015-11-03 17:39:51 +01:00
|
|
|
self.print_attribute_inline(attr, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_attribute_inline(&mut self, attr: &ast::Attribute,
|
2019-06-24 14:15:11 -04:00
|
|
|
is_inline: bool) {
|
2015-11-03 17:39:51 +01:00
|
|
|
if !is_inline {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.hardbreak_if_not_bol();
|
2015-11-03 17:39:51 +01:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.maybe_print_comment(attr.span.lo());
|
2019-10-24 06:33:12 +11:00
|
|
|
match attr.kind {
|
|
|
|
ast::AttrKind::Normal(ref item) => {
|
|
|
|
match attr.style {
|
|
|
|
ast::AttrStyle::Inner => self.word("#!["),
|
|
|
|
ast::AttrStyle::Outer => self.word("#["),
|
|
|
|
}
|
|
|
|
self.print_attr_item(&item, attr.span);
|
|
|
|
self.word("]");
|
|
|
|
}
|
|
|
|
ast::AttrKind::DocComment(comment) => {
|
|
|
|
self.word(comment.to_string());
|
|
|
|
self.hardbreak()
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-08-18 01:10:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
|
|
|
|
self.ibox(0);
|
|
|
|
match item.tokens.trees().next() {
|
|
|
|
Some(TokenTree::Delimited(_, delim, tts)) => {
|
|
|
|
self.print_mac_common(
|
|
|
|
Some(MacHeader::Path(&item.path)), false, None, delim, tts, true, span
|
|
|
|
);
|
|
|
|
}
|
|
|
|
tree => {
|
|
|
|
self.print_path(&item.path, false, 0);
|
|
|
|
if tree.is_some() {
|
|
|
|
self.space();
|
|
|
|
self.print_tts(item.tokens.clone(), true);
|
2019-07-13 21:01:04 +03:00
|
|
|
}
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2019-08-18 01:10:56 +03:00
|
|
|
self.end();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) {
|
2019-03-03 20:56:24 +03:00
|
|
|
match item {
|
|
|
|
ast::NestedMetaItem::MetaItem(ref mi) => {
|
2016-08-19 18:58:14 -07:00
|
|
|
self.print_meta_item(mi)
|
|
|
|
},
|
2019-03-03 20:56:24 +03:00
|
|
|
ast::NestedMetaItem::Literal(ref lit) => {
|
2016-08-19 18:58:14 -07:00
|
|
|
self.print_literal(lit)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_meta_item(&mut self, item: &ast::MetaItem) {
|
|
|
|
self.ibox(INDENT_UNIT);
|
2019-09-26 18:04:05 +01:00
|
|
|
match item.kind {
|
2019-07-13 19:11:07 +03:00
|
|
|
ast::MetaItemKind::Word => self.print_path(&item.path, false, 0),
|
2016-11-15 07:37:10 +00:00
|
|
|
ast::MetaItemKind::NameValue(ref value) => {
|
2019-07-13 19:11:07 +03:00
|
|
|
self.print_path(&item.path, false, 0);
|
2019-07-09 09:51:56 -04:00
|
|
|
self.space();
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("=");
|
|
|
|
self.print_literal(value);
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2016-11-15 07:37:10 +00:00
|
|
|
ast::MetaItemKind::List(ref items) => {
|
2019-07-13 19:11:07 +03:00
|
|
|
self.print_path(&item.path, false, 0);
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
2016-12-29 13:57:01 -08:00
|
|
|
self.commasep(Consistent,
|
2016-03-22 17:58:45 -05:00
|
|
|
&items[..],
|
2019-06-24 14:15:11 -04:00
|
|
|
|s, i| s.print_meta_list_item(i));
|
|
|
|
self.pclose();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2015-11-03 17:39:51 +01: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.
|
2019-07-04 02:37:34 +03:00
|
|
|
fn print_tt(&mut self, tt: tokenstream::TokenTree, convert_dollar_crate: bool) {
|
2017-03-03 09:23:59 +00:00
|
|
|
match tt {
|
2019-06-04 20:42:43 +03:00
|
|
|
TokenTree::Token(ref token) => {
|
2019-07-09 09:51:56 -04:00
|
|
|
self.word(token_to_string_ext(&token, convert_dollar_crate));
|
2019-06-04 20:42:43 +03:00
|
|
|
match token.kind {
|
|
|
|
token::DocComment(..) => {
|
2019-07-09 09:51:56 -04:00
|
|
|
self.hardbreak()
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
_ => {}
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-13 23:08:29 +03:00
|
|
|
TokenTree::Delimited(dspan, delim, tts) => {
|
|
|
|
self.print_mac_common(
|
|
|
|
None, false, None, delim, tts, convert_dollar_crate, dspan.entire()
|
|
|
|
);
|
|
|
|
}
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-11 03:16:19 +03:00
|
|
|
fn print_tts(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) {
|
2017-03-03 09:23:59 +00:00
|
|
|
for (i, tt) in tts.into_trees().enumerate() {
|
2019-08-25 20:41:52 +03:00
|
|
|
if i != 0 && tt_prepend_space(&tt) {
|
2019-07-09 09:51:56 -04:00
|
|
|
self.space();
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
2019-07-04 02:37:34 +03:00
|
|
|
self.print_tt(tt, convert_dollar_crate);
|
2017-03-03 09:23:59 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-14 21:58:20 +12:00
|
|
|
|
2019-07-13 19:11:07 +03:00
|
|
|
fn print_mac_common(
|
|
|
|
&mut self,
|
2019-07-14 16:09:39 +03:00
|
|
|
header: Option<MacHeader<'_>>,
|
2019-07-13 19:11:07 +03:00
|
|
|
has_bang: bool,
|
2019-07-13 20:35:46 +03:00
|
|
|
ident: Option<ast::Ident>,
|
2019-07-13 23:08:29 +03:00
|
|
|
delim: DelimToken,
|
2019-07-13 19:11:07 +03:00
|
|
|
tts: TokenStream,
|
2019-07-13 23:08:29 +03:00
|
|
|
convert_dollar_crate: bool,
|
2019-07-13 19:11:07 +03:00
|
|
|
span: Span,
|
|
|
|
) {
|
2019-07-14 00:11:59 +03:00
|
|
|
if delim == DelimToken::Brace {
|
|
|
|
self.cbox(INDENT_UNIT);
|
|
|
|
}
|
2019-07-14 16:09:39 +03:00
|
|
|
match header {
|
|
|
|
Some(MacHeader::Path(path)) => self.print_path(path, false, 0),
|
|
|
|
Some(MacHeader::Keyword(kw)) => self.word(kw),
|
|
|
|
None => {}
|
2019-07-13 23:08:29 +03:00
|
|
|
}
|
2019-07-13 19:11:07 +03:00
|
|
|
if has_bang {
|
|
|
|
self.word("!");
|
|
|
|
}
|
2019-07-13 20:35:46 +03:00
|
|
|
if let Some(ident) = ident {
|
2019-07-14 00:11:59 +03:00
|
|
|
self.nbsp();
|
2019-07-13 20:35:46 +03:00
|
|
|
self.print_ident(ident);
|
|
|
|
}
|
2019-07-13 19:11:07 +03:00
|
|
|
match delim {
|
2019-07-13 23:08:29 +03:00
|
|
|
DelimToken::Brace => {
|
2019-07-14 16:09:39 +03:00
|
|
|
if header.is_some() || has_bang || ident.is_some() {
|
2019-07-14 00:11:59 +03:00
|
|
|
self.nbsp();
|
|
|
|
}
|
|
|
|
self.word("{");
|
|
|
|
if !tts.is_empty() {
|
|
|
|
self.space();
|
|
|
|
}
|
2019-07-13 19:11:07 +03:00
|
|
|
}
|
2019-07-14 00:11:59 +03:00
|
|
|
_ => self.word(token_kind_to_string(&token::OpenDelim(delim))),
|
2019-07-13 19:11:07 +03:00
|
|
|
}
|
2019-07-13 23:11:04 +03:00
|
|
|
self.ibox(0);
|
2019-07-13 23:08:29 +03:00
|
|
|
self.print_tts(tts, convert_dollar_crate);
|
2019-07-13 23:11:04 +03:00
|
|
|
self.end();
|
2019-07-13 19:11:07 +03:00
|
|
|
match delim {
|
2019-07-13 23:08:29 +03:00
|
|
|
DelimToken::Brace => self.bclose(span),
|
2019-07-14 00:11:59 +03:00
|
|
|
_ => self.word(token_kind_to_string(&token::CloseDelim(delim))),
|
2019-07-13 19:11:07 +03:00
|
|
|
}
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
2011-08-02 15:25:06 -07:00
|
|
|
|
2019-07-13 19:11:07 +03:00
|
|
|
fn print_path(&mut self, path: &ast::Path, colons_before_params: bool, depth: usize) {
|
|
|
|
self.maybe_print_comment(path.span.lo());
|
|
|
|
|
|
|
|
for (i, segment) in path.segments[..path.segments.len() - depth].iter().enumerate() {
|
|
|
|
if i > 0 {
|
|
|
|
self.word("::")
|
|
|
|
}
|
|
|
|
self.print_path_segment(segment, colons_before_params);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_path_segment(&mut self, segment: &ast::PathSegment, colons_before_params: bool) {
|
|
|
|
if segment.ident.name != kw::PathRoot {
|
|
|
|
self.print_ident(segment.ident);
|
|
|
|
if let Some(ref args) = segment.args {
|
|
|
|
self.print_generic_args(args, colons_before_params);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) {
|
2018-11-29 11:36:58 +11:00
|
|
|
let w = w.into();
|
2019-09-06 03:56:45 +01:00
|
|
|
// Outer-box is consistent.
|
2019-06-24 14:15:11 -04:00
|
|
|
self.cbox(INDENT_UNIT);
|
2019-09-06 03:56:45 +01:00
|
|
|
// Head-box is inconsistent.
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(w.len() + 1);
|
2019-09-06 03:56:45 +01:00
|
|
|
// Keyword that starts the head.
|
2014-03-16 20:58:11 +02:00
|
|
|
if !w.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp(w);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2012-04-19 14:46:11 -07:00
|
|
|
|
2019-07-13 19:11:07 +03:00
|
|
|
fn bopen(&mut self) {
|
|
|
|
self.word("{");
|
2019-09-06 03:56:45 +01:00
|
|
|
self.end(); // Close the head-box.
|
2013-12-27 14:11:01 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2019-07-13 19:11:07 +03:00
|
|
|
fn bclose_maybe_open(&mut self, span: syntax_pos::Span, close_box: bool) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.maybe_print_comment(span.hi());
|
2019-07-09 09:30:08 -04:00
|
|
|
self.break_offset_if_not_bol(1, -(INDENT_UNIT as isize));
|
2019-07-13 19:11:07 +03:00
|
|
|
self.word("}");
|
2014-03-16 20:58:11 +02:00
|
|
|
if close_box {
|
2019-09-06 03:56:45 +01:00
|
|
|
self.end(); // Close the outer-box.
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2019-07-13 19:11:07 +03:00
|
|
|
|
|
|
|
fn bclose(&mut self, span: syntax_pos::Span) {
|
2019-07-09 09:30:08 -04:00
|
|
|
self.bclose_maybe_open(span, true)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2014-01-29 17:39:21 -08:00
|
|
|
|
2019-07-13 19:11:07 +03:00
|
|
|
fn break_offset_if_not_bol(&mut self, n: usize, off: isize) {
|
|
|
|
if !self.is_beginning_of_line() {
|
|
|
|
self.break_offset(n, off)
|
2014-03-16 20:58:11 +02:00
|
|
|
} else {
|
2019-07-13 19:11:07 +03:00
|
|
|
if off != 0 && self.last_token().is_hardbreak_tok() {
|
2014-03-16 20:58:11 +02:00
|
|
|
// We do something pretty sketchy here: tuck the nonzero
|
|
|
|
// offset-adjustment we were going to deposit along with the
|
|
|
|
// break into the previous hardbreak.
|
2019-07-13 19:11:07 +03:00
|
|
|
self.replace_last_token(pp::Printer::hardbreak_tok_offset(off));
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2014-01-29 17:39:21 -08:00
|
|
|
}
|
2019-07-13 19:11:07 +03:00
|
|
|
}
|
2011-03-17 17:39:47 -07:00
|
|
|
|
2019-07-13 19:11:07 +03:00
|
|
|
impl<'a> PrintState<'a> for State<'a> {
|
|
|
|
fn comments(&mut self) -> &mut Option<Comments<'a>> {
|
|
|
|
&mut self.comments
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_ident(&mut self, ident: ast::Ident) {
|
|
|
|
self.s.word(ast_ident_to_string(ident, ident.is_raw_guess()));
|
|
|
|
self.ann.post(self, AnnNode::Ident(&ident))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool) {
|
|
|
|
if colons_before_params {
|
|
|
|
self.s.word("::")
|
|
|
|
}
|
|
|
|
|
|
|
|
match *args {
|
|
|
|
ast::GenericArgs::AngleBracketed(ref data) => {
|
|
|
|
self.s.word("<");
|
|
|
|
|
|
|
|
self.commasep(Inconsistent, &data.args, |s, generic_arg| {
|
|
|
|
s.print_generic_arg(generic_arg)
|
|
|
|
});
|
|
|
|
|
|
|
|
let mut comma = data.args.len() != 0;
|
|
|
|
|
|
|
|
for constraint in data.constraints.iter() {
|
|
|
|
if comma {
|
|
|
|
self.word_space(",")
|
|
|
|
}
|
|
|
|
self.print_ident(constraint.ident);
|
|
|
|
self.s.space();
|
|
|
|
match constraint.kind {
|
|
|
|
ast::AssocTyConstraintKind::Equality { ref ty } => {
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_type(ty);
|
|
|
|
}
|
|
|
|
ast::AssocTyConstraintKind::Bound { ref bounds } => {
|
|
|
|
self.print_type_bounds(":", &*bounds);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
comma = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.s.word(">")
|
|
|
|
}
|
|
|
|
|
|
|
|
ast::GenericArgs::Parenthesized(ref data) => {
|
|
|
|
self.s.word("(");
|
|
|
|
self.commasep(
|
|
|
|
Inconsistent,
|
|
|
|
&data.inputs,
|
|
|
|
|s, ty| s.print_type(ty));
|
|
|
|
self.s.word(")");
|
|
|
|
|
|
|
|
if let Some(ref ty) = data.output {
|
|
|
|
self.space_if_not_bol();
|
|
|
|
self.word_space("->");
|
|
|
|
self.print_type(ty);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> State<'a> {
|
2014-03-16 20:58:11 +02:00
|
|
|
// Synthesizes a comment that was not textually present in the original source
|
|
|
|
// file.
|
2019-06-24 14:15:11 -04:00
|
|
|
pub fn synth_comment(&mut self, text: String) {
|
|
|
|
self.s.word("/*");
|
|
|
|
self.s.space();
|
|
|
|
self.s.word(text);
|
|
|
|
self.s.space();
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("*/")
|
2014-01-29 17:39:21 -08:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn commasep_cmnt<T, F, G>(&mut self,
|
2014-12-08 13:28:32 -05:00
|
|
|
b: Breaks,
|
|
|
|
elts: &[T],
|
|
|
|
mut op: F,
|
2019-06-24 14:15:11 -04:00
|
|
|
mut get_span: G) where
|
|
|
|
F: FnMut(&mut State<'_>, &T),
|
2016-06-21 18:08:13 -04:00
|
|
|
G: FnMut(&T) -> syntax_pos::Span,
|
2014-12-08 13:28:32 -05:00
|
|
|
{
|
2019-06-24 14:15:11 -04:00
|
|
|
self.rbox(0, b);
|
2014-03-16 20:58:11 +02:00
|
|
|
let len = elts.len();
|
2017-05-16 09:21:30 +02:00
|
|
|
let mut i = 0;
|
|
|
|
for elt in elts {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.maybe_print_comment(get_span(elt).hi());
|
|
|
|
op(self, elt);
|
2017-05-16 09:21:30 +02:00
|
|
|
i += 1;
|
2014-03-16 20:58:11 +02:00
|
|
|
if i < len {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(",");
|
2016-12-29 13:57:01 -08:00
|
|
|
self.maybe_print_trailing_comment(get_span(elt),
|
2019-06-24 14:15:11 -04:00
|
|
|
Some(get_span(&elts[i]).hi()));
|
|
|
|
self.space_if_not_bol();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2011-07-26 15:37:36 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn commasep_exprs(&mut self, b: Breaks,
|
2019-09-06 03:56:45 +01:00
|
|
|
exprs: &[P<ast::Expr>]) {
|
2017-05-12 20:05:39 +02:00
|
|
|
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span)
|
2012-03-08 18:10:07 -08:00
|
|
|
}
|
|
|
|
|
2019-10-10 10:26:10 +02:00
|
|
|
pub fn print_mod(
|
|
|
|
&mut self,
|
|
|
|
_mod: &ast::Mod,
|
|
|
|
attrs: &[ast::Attribute],
|
|
|
|
) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_inner_attributes(attrs);
|
2015-01-31 12:20:46 -05:00
|
|
|
for item in &_mod.items {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_item(item);
|
2014-01-09 15:05:33 +02:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
2019-09-06 03:56:45 +01:00
|
|
|
attrs: &[ast::Attribute]) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_inner_attributes(attrs);
|
2015-01-31 12:20:46 -05:00
|
|
|
for item in &nmod.items {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_foreign_item(item);
|
2014-01-09 15:05:33 +02:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn print_opt_lifetime(&mut self, lifetime: &Option<ast::Lifetime>) {
|
2018-05-30 16:49:39 +01:00
|
|
|
if let Some(lt) = *lifetime {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_lifetime(lt);
|
|
|
|
self.nbsp();
|
2013-02-18 17:45:56 -08:00
|
|
|
}
|
2011-03-04 07:22:43 +01:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_generic_arg(&mut self, generic_arg: &GenericArg) {
|
2018-05-16 12:57:45 +01:00
|
|
|
match generic_arg {
|
2018-05-30 16:49:39 +01:00
|
|
|
GenericArg::Lifetime(lt) => self.print_lifetime(*lt),
|
2018-05-27 20:07:09 +01:00
|
|
|
GenericArg::Type(ty) => self.print_type(ty),
|
2019-02-05 16:50:16 +01:00
|
|
|
GenericArg::Const(ct) => self.print_expr(&ct.value),
|
2018-02-08 08:58:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn print_type(&mut self, ty: &ast::Ty) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.maybe_print_comment(ty.span.lo());
|
|
|
|
self.ibox(0);
|
2019-09-26 17:25:31 +01:00
|
|
|
match ty.kind {
|
2016-09-20 16:54:24 +02:00
|
|
|
ast::TyKind::Slice(ref ty) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("[");
|
|
|
|
self.print_type(ty);
|
|
|
|
self.s.word("]");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Ptr(ref mt) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("*");
|
2014-06-25 12:47:34 -07:00
|
|
|
match mt.mutbl {
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::Mutability::Mutable => self.word_nbsp("mut"),
|
|
|
|
ast::Mutability::Immutable => self.word_nbsp("const"),
|
2014-06-25 12:47:34 -07:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type(&mt.ty);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Rptr(ref lifetime, ref mt) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("&");
|
|
|
|
self.print_opt_lifetime(lifetime);
|
|
|
|
self.print_mt(mt);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-08-02 15:56:20 +08:00
|
|
|
ast::TyKind::Never => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("!");
|
2016-05-10 00:03:59 +08:00
|
|
|
},
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Tup(ref elts) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
2016-12-29 13:57:01 -08:00
|
|
|
self.commasep(Inconsistent, &elts[..],
|
2019-06-24 14:15:11 -04:00
|
|
|
|s, ty| s.print_type(ty));
|
2014-03-16 20:58:11 +02:00
|
|
|
if elts.len() == 1 {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(",");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.pclose();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Paren(ref typ) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
|
|
|
self.print_type(typ);
|
|
|
|
self.pclose();
|
2014-06-11 12:14:38 -07:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::BareFn(ref f) => {
|
2016-12-29 13:57:01 -08:00
|
|
|
self.print_ty_fn(f.abi,
|
2016-03-22 17:58:45 -05:00
|
|
|
f.unsafety,
|
|
|
|
&f.decl,
|
|
|
|
None,
|
2019-06-24 14:15:11 -04:00
|
|
|
&f.generic_params);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Path(None, ref path) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(path, false, 0);
|
2015-01-31 21:20:24 +02:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Path(Some(ref qself), ref path) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_qpath(path, qself, false)
|
2014-11-20 15:05:29 -05:00
|
|
|
}
|
2017-10-10 17:33:19 +03:00
|
|
|
ast::TyKind::TraitObject(ref bounds, syntax) => {
|
2017-12-19 23:40:17 +03:00
|
|
|
let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" };
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type_bounds(prefix, &bounds[..]);
|
2014-11-07 06:53:45 -05:00
|
|
|
}
|
2018-06-18 16:23:13 +02:00
|
|
|
ast::TyKind::ImplTrait(_, ref bounds) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type_bounds("impl", &bounds[..]);
|
2016-08-01 04:25:32 +03:00
|
|
|
}
|
2018-05-17 21:28:50 +03:00
|
|
|
ast::TyKind::Array(ref ty, ref length) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("[");
|
|
|
|
self.print_type(ty);
|
|
|
|
self.s.word("; ");
|
|
|
|
self.print_expr(&length.value);
|
|
|
|
self.s.word("]");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Typeof(ref e) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("typeof(");
|
|
|
|
self.print_expr(&e.value);
|
|
|
|
self.s.word(")");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Infer => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("_");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-03-28 18:56:29 -07:00
|
|
|
ast::TyKind::Err => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
|
|
|
self.s.word("/*ERROR*/");
|
|
|
|
self.pclose();
|
2017-03-28 18:56:29 -07:00
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
ast::TyKind::ImplicitSelf => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("Self");
|
2016-03-06 15:54:44 +03:00
|
|
|
}
|
2016-02-08 16:53:21 +01:00
|
|
|
ast::TyKind::Mac(ref m) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_mac(m);
|
2015-07-25 21:30:35 -07:00
|
|
|
}
|
2018-11-30 15:53:44 +00:00
|
|
|
ast::TyKind::CVarArgs => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("...");
|
2018-11-30 15:53:44 +00:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2013-12-01 00:00:39 +02:00
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_foreign_item(&mut self,
|
2019-06-24 14:15:11 -04:00
|
|
|
item: &ast::ForeignItem) {
|
|
|
|
self.hardbreak_if_not_bol();
|
|
|
|
self.maybe_print_comment(item.span.lo());
|
|
|
|
self.print_outer_attributes(&item.attrs);
|
2019-09-26 17:58:14 +01:00
|
|
|
match item.kind {
|
2016-02-09 11:31:19 +01:00
|
|
|
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("");
|
2019-05-29 04:10:49 +03:00
|
|
|
self.print_fn(decl, ast::FnHeader::default(),
|
2018-05-16 22:55:18 -07:00
|
|
|
Some(item.ident),
|
2019-06-24 14:15:11 -04:00
|
|
|
generics, &item.vis);
|
|
|
|
self.end(); // end head-ibox
|
|
|
|
self.s.word(";");
|
|
|
|
self.end(); // end the outer fn box
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-09 11:31:19 +01:00
|
|
|
ast::ForeignItemKind::Static(ref t, m) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "static"));
|
2019-04-21 15:29:58 +03:00
|
|
|
if m == ast::Mutability::Mutable {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("mut");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(item.ident);
|
|
|
|
self.word_space(":");
|
|
|
|
self.print_type(t);
|
|
|
|
self.s.word(";");
|
|
|
|
self.end(); // end the head-ibox
|
|
|
|
self.end(); // end the outer cbox
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-09-03 19:53:58 +01:00
|
|
|
ast::ForeignItemKind::Ty => {
|
2019-06-24 14:15:11 -04:00
|
|
|
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
|
2017-09-03 19:53:58 +01:00
|
|
|
}
|
2018-03-10 18:16:26 -08:00
|
|
|
ast::ForeignItemKind::Macro(ref m) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_mac(m);
|
2019-08-15 02:13:53 +03:00
|
|
|
match m.delim {
|
2019-06-24 14:15:11 -04:00
|
|
|
MacDelimiter::Brace => {},
|
2018-05-22 08:01:21 -07:00
|
|
|
_ => self.s.word(";")
|
|
|
|
}
|
2018-03-10 18:16:26 -08:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2013-02-10 23:15:45 -08:00
|
|
|
|
2015-03-15 19:35:25 -06: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-15 19:35:25 -06:00
|
|
|
{
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(visibility_qualified(vis, ""));
|
|
|
|
self.word_space("const");
|
|
|
|
self.print_ident(ident);
|
|
|
|
self.word_space(":");
|
|
|
|
self.print_type(ty);
|
2015-03-15 19:35:25 -06:00
|
|
|
if let Some(expr) = default {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_expr(expr);
|
2015-03-15 19:35:25 -06:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")
|
2015-03-15 19:35:25 -06:00
|
|
|
}
|
|
|
|
|
2015-03-10 12:28:44 +02:00
|
|
|
fn print_associated_type(&mut self,
|
|
|
|
ident: ast::Ident,
|
2018-06-14 12:08:58 +01:00
|
|
|
bounds: Option<&ast::GenericBounds>,
|
2015-03-10 12:28:44 +02:00
|
|
|
ty: Option<&ast::Ty>)
|
2019-06-24 14:15:11 -04:00
|
|
|
{
|
|
|
|
self.word_space("type");
|
|
|
|
self.print_ident(ident);
|
2015-03-10 12:28:44 +02:00
|
|
|
if let Some(bounds) = bounds {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type_bounds(":", bounds);
|
2015-03-10 12:28:44 +02:00
|
|
|
}
|
|
|
|
if let Some(ty) = ty {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_type(ty);
|
2015-03-10 12:28:44 +02:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")
|
2014-08-05 19:44:21 -07:00
|
|
|
}
|
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
/// Pretty-prints an item.
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_item(&mut self, item: &ast::Item) {
|
|
|
|
self.hardbreak_if_not_bol();
|
|
|
|
self.maybe_print_comment(item.span.lo());
|
|
|
|
self.print_outer_attributes(&item.attrs);
|
|
|
|
self.ann.pre(self, AnnNode::Item(item));
|
2019-09-26 17:51:36 +01:00
|
|
|
match item.kind {
|
2018-03-09 18:51:48 +03:00
|
|
|
ast::ItemKind::ExternCrate(orig_name) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "extern crate"));
|
2018-03-09 18:51:48 +03:00
|
|
|
if let Some(orig_name) = orig_name {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_name(orig_name);
|
|
|
|
self.s.space();
|
|
|
|
self.s.word("as");
|
|
|
|
self.s.space();
|
2015-01-13 17:30:17 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(item.ident);
|
|
|
|
self.s.word(";");
|
|
|
|
self.end(); // end inner head-block
|
|
|
|
self.end(); // end outer head-block
|
2015-01-13 17:30:17 +02:00
|
|
|
}
|
2017-09-26 23:04:00 +02:00
|
|
|
ast::ItemKind::Use(ref tree) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "use"));
|
|
|
|
self.print_use_tree(tree);
|
|
|
|
self.s.word(";");
|
|
|
|
self.end(); // end inner head-block
|
|
|
|
self.end(); // end outer head-block
|
2015-01-13 17:30:17 +02:00
|
|
|
}
|
2016-02-09 11:36:51 +01:00
|
|
|
ast::ItemKind::Static(ref ty, m, ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "static"));
|
2016-02-09 17:44:47 +01:00
|
|
|
if m == ast::Mutability::Mutable {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("mut");
|
2013-03-04 16:11:30 -08:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(item.ident);
|
|
|
|
self.word_space(":");
|
|
|
|
self.print_type(ty);
|
|
|
|
self.s.space();
|
|
|
|
self.end(); // end the head-ibox
|
2014-03-16 20:58:11 +02:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("=");
|
|
|
|
self.print_expr(expr);
|
|
|
|
self.s.word(";");
|
|
|
|
self.end(); // end the outer cbox
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-09 11:36:51 +01:00
|
|
|
ast::ItemKind::Const(ref ty, ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "const"));
|
|
|
|
self.print_ident(item.ident);
|
|
|
|
self.word_space(":");
|
|
|
|
self.print_type(ty);
|
|
|
|
self.s.space();
|
|
|
|
self.end(); // end the head-ibox
|
|
|
|
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_expr(expr);
|
|
|
|
self.s.word(";");
|
|
|
|
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 08:17:01 -07:00
|
|
|
}
|
2019-11-07 13:33:37 +01:00
|
|
|
ast::ItemKind::Fn(ref sig, ref param_names, ref body) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("");
|
2016-12-29 13:57:01 -08:00
|
|
|
self.print_fn(
|
2019-11-07 13:33:37 +01:00
|
|
|
&sig.decl,
|
|
|
|
sig.header,
|
2015-03-11 08:38:27 +02:00
|
|
|
Some(item.ident),
|
2019-03-13 23:37:02 +00:00
|
|
|
param_names,
|
2016-03-23 10:17:34 +00:00
|
|
|
&item.vis
|
2019-06-24 14:15:11 -04:00
|
|
|
);
|
|
|
|
self.s.word(" ");
|
|
|
|
self.print_block_with_attrs(body, &item.attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-09 11:36:51 +01:00
|
|
|
ast::ItemKind::Mod(ref _mod) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "mod"));
|
|
|
|
self.print_ident(item.ident);
|
2018-07-11 15:19:32 +02:00
|
|
|
|
2018-07-12 23:35:40 +02:00
|
|
|
if _mod.inline || self.is_expanded {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.nbsp();
|
|
|
|
self.bopen();
|
|
|
|
self.print_mod(_mod, &item.attrs);
|
|
|
|
self.bclose(item.span);
|
2018-07-11 15:19:32 +02:00
|
|
|
} else {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(";");
|
|
|
|
self.end(); // end inner head-block
|
|
|
|
self.end(); // end outer head-block
|
2018-07-11 15:19:32 +02:00
|
|
|
}
|
|
|
|
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-09 11:36:51 +01:00
|
|
|
ast::ItemKind::ForeignMod(ref nmod) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("extern");
|
2019-10-27 23:14:35 +01:00
|
|
|
self.print_abi(nmod.abi);
|
2019-06-24 14:15:11 -04:00
|
|
|
self.bopen();
|
|
|
|
self.print_foreign_mod(nmod, &item.attrs);
|
|
|
|
self.bclose(item.span);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-03-15 21:27:40 -05:00
|
|
|
ast::ItemKind::GlobalAsm(ref ga) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "global_asm!"));
|
2019-10-22 08:31:37 +11:00
|
|
|
self.s.word(ga.asm.to_string());
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2017-03-15 21:27:40 -05:00
|
|
|
}
|
2019-08-02 11:02:08 +01:00
|
|
|
ast::ItemKind::TyAlias(ref ty, ref generics) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "type"));
|
|
|
|
self.print_ident(item.ident);
|
|
|
|
self.print_generic_params(&generics.params);
|
|
|
|
self.end(); // end the inner ibox
|
|
|
|
|
|
|
|
self.print_where_clause(&generics.where_clause);
|
|
|
|
self.s.space();
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_type(ty);
|
|
|
|
self.s.word(";");
|
|
|
|
self.end(); // end the outer ibox
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-09 11:36:51 +01:00
|
|
|
ast::ItemKind::Enum(ref enum_definition, ref params) => {
|
2016-12-29 13:57:01 -08:00
|
|
|
self.print_enum_def(
|
2014-03-16 20:58:11 +02:00
|
|
|
enum_definition,
|
|
|
|
params,
|
|
|
|
item.ident,
|
|
|
|
item.span,
|
2016-03-23 10:17:34 +00:00
|
|
|
&item.vis
|
2019-06-24 14:15:11 -04:00
|
|
|
);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-09 11:36:51 +01:00
|
|
|
ast::ItemKind::Struct(ref struct_def, ref generics) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "struct"));
|
|
|
|
self.print_struct(struct_def, generics, item.ident, item.span, true);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-08-29 05:04:31 +00:00
|
|
|
ast::ItemKind::Union(ref struct_def, ref generics) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head(visibility_qualified(&item.vis, "union"));
|
|
|
|
self.print_struct(struct_def, generics, item.ident, item.span, true);
|
2016-08-29 05:04:31 +00:00
|
|
|
}
|
2016-02-09 11:36:51 +01:00
|
|
|
ast::ItemKind::Impl(unsafety,
|
2014-12-28 23:33:18 +01:00
|
|
|
polarity,
|
2016-11-18 17:14:42 +01:00
|
|
|
defaultness,
|
2014-12-10 06:15:06 -05:00
|
|
|
ref generics,
|
2014-08-04 13:56:56 -07:00
|
|
|
ref opt_trait,
|
|
|
|
ref ty,
|
|
|
|
ref impl_items) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("");
|
|
|
|
self.print_visibility(&item.vis);
|
|
|
|
self.print_defaultness(defaultness);
|
|
|
|
self.print_unsafety(unsafety);
|
|
|
|
self.word_nbsp("impl");
|
2014-12-10 06:15:06 -05:00
|
|
|
|
2018-05-26 23:21:08 +01:00
|
|
|
if !generics.params.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_generic_params(&generics.params);
|
|
|
|
self.s.space();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2013-03-27 06:16:28 -04:00
|
|
|
|
2017-05-13 21:40:06 +02:00
|
|
|
if polarity == ast::ImplPolarity::Negative {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("!");
|
2014-12-28 23:33:18 +01:00
|
|
|
}
|
|
|
|
|
2016-07-03 14:38:37 -07:00
|
|
|
if let Some(ref t) = *opt_trait {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_trait_ref(t);
|
|
|
|
self.s.space();
|
|
|
|
self.word_space("for");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2012-08-08 17:14:25 -07:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type(ty);
|
|
|
|
self.print_where_clause(&generics.where_clause);
|
2012-08-08 14:17:52 -07:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.bopen();
|
|
|
|
self.print_inner_attributes(&item.attrs);
|
2015-01-31 12:20:46 -05:00
|
|
|
for impl_item in impl_items {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_impl_item(impl_item);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.bclose(item.span);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-10-12 09:51:31 -03:00
|
|
|
ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("");
|
|
|
|
self.print_visibility(&item.vis);
|
|
|
|
self.print_unsafety(unsafety);
|
|
|
|
self.print_is_auto(is_auto);
|
|
|
|
self.word_nbsp("trait");
|
|
|
|
self.print_ident(item.ident);
|
|
|
|
self.print_generic_params(&generics.params);
|
2014-12-24 22:34:57 +13:00
|
|
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
2015-02-13 07:33:44 +00:00
|
|
|
for b in bounds.iter() {
|
2018-06-14 12:23:46 +01:00
|
|
|
if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("for ?");
|
|
|
|
self.print_trait_ref(&ptr.trait_ref);
|
2014-12-24 22:34:57 +13:00
|
|
|
} else {
|
2015-02-13 07:33:44 +00:00
|
|
|
real_bounds.push(b.clone());
|
2014-12-24 22:34:57 +13:00
|
|
|
}
|
2014-04-03 13:38:45 +13:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type_bounds(":", &real_bounds[..]);
|
|
|
|
self.print_where_clause(&generics.where_clause);
|
|
|
|
self.s.word(" ");
|
|
|
|
self.bopen();
|
2015-03-10 12:28:44 +02:00
|
|
|
for trait_item in trait_items {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_trait_item(trait_item);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.bclose(item.span);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-10-02 12:27:45 +00:00
|
|
|
ast::ItemKind::TraitAlias(ref generics, ref bounds) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("");
|
|
|
|
self.print_visibility(&item.vis);
|
|
|
|
self.word_nbsp("trait");
|
|
|
|
self.print_ident(item.ident);
|
|
|
|
self.print_generic_params(&generics.params);
|
2017-10-02 12:27:45 +00:00
|
|
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
|
|
|
// FIXME(durka) this seems to be some quite outdated syntax
|
|
|
|
for b in bounds.iter() {
|
2018-06-14 12:23:46 +01:00
|
|
|
if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("for ?");
|
|
|
|
self.print_trait_ref(&ptr.trait_ref);
|
2017-10-02 12:27:45 +00:00
|
|
|
} else {
|
|
|
|
real_bounds.push(b.clone());
|
|
|
|
}
|
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.nbsp();
|
|
|
|
self.print_type_bounds("=", &real_bounds[..]);
|
|
|
|
self.print_where_clause(&generics.where_clause);
|
|
|
|
self.s.word(";");
|
2017-10-02 12:27:45 +00:00
|
|
|
}
|
2018-05-22 08:01:21 -07:00
|
|
|
ast::ItemKind::Mac(ref mac) => {
|
2019-07-13 20:35:46 +03:00
|
|
|
self.print_mac(mac);
|
2019-08-15 02:13:53 +03:00
|
|
|
match mac.delim {
|
2019-07-13 20:35:46 +03:00
|
|
|
MacDelimiter::Brace => {}
|
|
|
|
_ => self.s.word(";"),
|
2018-05-22 08:01:21 -07:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-07-13 20:35:46 +03:00
|
|
|
ast::ItemKind::MacroDef(ref macro_def) => {
|
2019-07-14 20:16:16 +01:00
|
|
|
let (kw, has_bang) = if macro_def.legacy {
|
|
|
|
("macro_rules", true)
|
|
|
|
} else {
|
|
|
|
self.print_visibility(&item.vis);
|
|
|
|
("macro", false)
|
|
|
|
};
|
2019-07-13 20:35:46 +03:00
|
|
|
self.print_mac_common(
|
2019-07-14 16:09:39 +03:00
|
|
|
Some(MacHeader::Keyword(kw)),
|
|
|
|
has_bang,
|
2019-07-13 23:08:29 +03:00
|
|
|
Some(item.ident),
|
|
|
|
DelimToken::Brace,
|
|
|
|
macro_def.stream(),
|
|
|
|
true,
|
|
|
|
item.span,
|
2019-07-13 20:35:46 +03:00
|
|
|
);
|
2017-03-05 05:15:58 +00:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-08-22 22:05:19 +01:00
|
|
|
self.ann.post(self, AnnNode::Item(item))
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_trait_ref(&mut self, t: &ast::TraitRef) {
|
2018-03-10 02:02:39 +03:00
|
|
|
self.print_path(&t.path, false, 0)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2017-10-16 21:07:26 +02:00
|
|
|
fn print_formal_generic_params(
|
|
|
|
&mut self,
|
2018-05-27 20:07:09 +01:00
|
|
|
generic_params: &[ast::GenericParam]
|
2019-06-24 14:15:11 -04:00
|
|
|
) {
|
2017-10-16 21:07:26 +02:00
|
|
|
if !generic_params.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("for");
|
|
|
|
self.print_generic_params(generic_params);
|
|
|
|
self.nbsp();
|
2014-11-07 06:53:45 -05:00
|
|
|
}
|
2015-02-09 16:49:27 +13:00
|
|
|
}
|
2014-11-07 06:53:45 -05:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
|
|
|
|
self.print_formal_generic_params(&t.bound_generic_params);
|
2014-11-07 06:53:45 -05:00
|
|
|
self.print_trait_ref(&t.trait_ref)
|
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
|
2014-03-16 20:58:11 +02:00
|
|
|
generics: &ast::Generics, ident: ast::Ident,
|
2016-06-21 18:08:13 -04:00
|
|
|
span: syntax_pos::Span,
|
2019-06-24 14:15:11 -04:00
|
|
|
visibility: &ast::Visibility) {
|
|
|
|
self.head(visibility_qualified(visibility, "enum"));
|
|
|
|
self.print_ident(ident);
|
|
|
|
self.print_generic_params(&generics.params);
|
|
|
|
self.print_where_clause(&generics.where_clause);
|
|
|
|
self.s.space();
|
2015-02-18 15:58:07 -08:00
|
|
|
self.print_variants(&enum_definition.variants, span)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_variants(&mut self,
|
2016-02-11 23:33:09 +03:00
|
|
|
variants: &[ast::Variant],
|
2019-06-24 14:15:11 -04:00
|
|
|
span: syntax_pos::Span) {
|
|
|
|
self.bopen();
|
2015-01-31 12:20:46 -05:00
|
|
|
for v in variants {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.space_if_not_bol();
|
|
|
|
self.maybe_print_comment(v.span.lo());
|
2019-08-13 21:40:21 -03:00
|
|
|
self.print_outer_attributes(&v.attrs);
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(INDENT_UNIT);
|
|
|
|
self.print_variant(v);
|
|
|
|
self.s.word(",");
|
|
|
|
self.end();
|
|
|
|
self.maybe_print_trailing_comment(v.span, None);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
self.bclose(span)
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_visibility(&mut self, vis: &ast::Visibility) {
|
2018-01-29 14:12:09 +09:00
|
|
|
match vis.node {
|
|
|
|
ast::VisibilityKind::Public => self.word_nbsp("pub"),
|
|
|
|
ast::VisibilityKind::Crate(sugar) => match sugar {
|
2017-10-19 14:43:47 -07:00
|
|
|
ast::CrateSugar::PubCrate => self.word_nbsp("pub(crate)"),
|
|
|
|
ast::CrateSugar::JustCrate => self.word_nbsp("crate")
|
|
|
|
}
|
2018-01-29 14:12:09 +09:00
|
|
|
ast::VisibilityKind::Restricted { ref path, .. } => {
|
2018-03-10 02:02:39 +03:00
|
|
|
let path = to_string(|s| s.print_path(path, false, 0));
|
2017-04-02 04:46:33 +00:00
|
|
|
if path == "self" || path == "super" {
|
2018-11-29 11:36:58 +11:00
|
|
|
self.word_nbsp(format!("pub({})", path))
|
2017-04-02 04:46:33 +00:00
|
|
|
} else {
|
2018-11-29 11:36:58 +11:00
|
|
|
self.word_nbsp(format!("pub(in {})", path))
|
2017-04-02 04:46:33 +00:00
|
|
|
}
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::VisibilityKind::Inherited => {}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_defaultness(&mut self, defaultness: ast::Defaultness) {
|
2018-07-03 19:38:14 +02:00
|
|
|
if let ast::Defaultness::Default = defaultness {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp("default");
|
2016-11-18 17:14:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_struct(&mut self,
|
2015-10-08 03:20:57 +03:00
|
|
|
struct_def: &ast::VariantData,
|
2014-03-16 20:58:11 +02:00
|
|
|
generics: &ast::Generics,
|
|
|
|
ident: ast::Ident,
|
2016-06-21 18:08:13 -04:00
|
|
|
span: syntax_pos::Span,
|
2019-06-24 14:15:11 -04:00
|
|
|
print_finalizer: bool) {
|
|
|
|
self.print_ident(ident);
|
|
|
|
self.print_generic_params(&generics.params);
|
2019-03-24 00:06:58 +03:00
|
|
|
match struct_def {
|
|
|
|
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
|
|
|
|
if let ast::VariantData::Tuple(..) = struct_def {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
2019-03-24 00:06:58 +03:00
|
|
|
self.commasep(
|
|
|
|
Inconsistent, struct_def.fields(),
|
|
|
|
|s, field| {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.maybe_print_comment(field.span.lo());
|
|
|
|
s.print_outer_attributes(&field.attrs);
|
|
|
|
s.print_visibility(&field.vis);
|
2019-03-24 00:06:58 +03:00
|
|
|
s.print_type(&field.ty)
|
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
);
|
|
|
|
self.pclose();
|
2019-03-24 00:06:58 +03:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_where_clause(&generics.where_clause);
|
2019-03-24 00:06:58 +03:00
|
|
|
if print_finalizer {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(";");
|
2019-03-24 00:06:58 +03:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2019-09-06 03:56:45 +01:00
|
|
|
self.end(); // Close the outer-box.
|
2015-10-01 18:47:27 +03:00
|
|
|
}
|
2019-03-24 00:06:58 +03:00
|
|
|
ast::VariantData::Struct(..) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_where_clause(&generics.where_clause);
|
|
|
|
self.nbsp();
|
|
|
|
self.bopen();
|
|
|
|
self.hardbreak_if_not_bol();
|
2012-09-21 18:10:45 -07:00
|
|
|
|
2019-03-24 00:06:58 +03:00
|
|
|
for field in struct_def.fields() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.hardbreak_if_not_bol();
|
|
|
|
self.maybe_print_comment(field.span.lo());
|
|
|
|
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);
|
|
|
|
self.s.word(",");
|
2019-03-24 00:06:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
self.bclose(span)
|
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2012-09-21 18:10:45 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_variant(&mut self, v: &ast::Variant) {
|
|
|
|
self.head("");
|
2015-11-28 19:02:07 +00:00
|
|
|
let generics = ast::Generics::default();
|
2019-08-13 21:40:21 -03:00
|
|
|
self.print_struct(&v.data, &generics, v.ident, v.span, false);
|
|
|
|
match v.disr_expr {
|
2014-05-16 00:16:13 -07:00
|
|
|
Some(ref d) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("=");
|
2018-05-17 21:28:50 +03:00
|
|
|
self.print_expr(&d.value)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
_ => {}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_method_sig(&mut self,
|
2015-03-11 08:38:27 +02:00
|
|
|
ident: ast::Ident,
|
2017-09-21 22:18:47 -04:00
|
|
|
generics: &ast::Generics,
|
2019-11-07 13:11:59 +01:00
|
|
|
m: &ast::FnSig,
|
2016-03-23 10:17:34 +00:00
|
|
|
vis: &ast::Visibility)
|
2019-06-24 14:15:11 -04:00
|
|
|
{
|
2015-03-11 08:38:27 +02:00
|
|
|
self.print_fn(&m.decl,
|
2019-05-29 04:10:49 +03:00
|
|
|
m.header,
|
2015-03-11 08:38:27 +02:00
|
|
|
Some(ident),
|
2017-09-21 22:18:47 -04:00
|
|
|
&generics,
|
2015-03-11 08:38:27 +02:00
|
|
|
vis)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_trait_item(&mut self, ti: &ast::TraitItem)
|
2019-06-24 14:15:11 -04:00
|
|
|
{
|
|
|
|
self.ann.pre(self, AnnNode::SubItem(ti.id));
|
|
|
|
self.hardbreak_if_not_bol();
|
|
|
|
self.maybe_print_comment(ti.span.lo());
|
|
|
|
self.print_outer_attributes(&ti.attrs);
|
2019-09-26 17:07:54 +01:00
|
|
|
match ti.kind {
|
2016-02-09 17:54:11 +01:00
|
|
|
ast::TraitItemKind::Const(ref ty, ref default) => {
|
2018-01-29 14:12:09 +09:00
|
|
|
self.print_associated_const(
|
|
|
|
ti.ident,
|
|
|
|
ty,
|
|
|
|
default.as_ref().map(|expr| &**expr),
|
2018-08-18 12:14:03 +02:00
|
|
|
&source_map::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
2019-06-24 14:15:11 -04:00
|
|
|
);
|
2015-03-15 19:35:25 -06:00
|
|
|
}
|
2016-02-09 17:54:11 +01:00
|
|
|
ast::TraitItemKind::Method(ref sig, ref body) => {
|
2015-03-11 23:38:58 +02:00
|
|
|
if body.is_some() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("");
|
2015-03-11 23:38:58 +02:00
|
|
|
}
|
2018-01-29 14:12:09 +09:00
|
|
|
self.print_method_sig(
|
|
|
|
ti.ident,
|
|
|
|
&ti.generics,
|
|
|
|
sig,
|
2018-08-18 12:14:03 +02:00
|
|
|
&source_map::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
2019-06-24 14:15:11 -04:00
|
|
|
);
|
2015-03-11 23:38:58 +02:00
|
|
|
if let Some(ref body) = *body {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.nbsp();
|
|
|
|
self.print_block_with_attrs(body, &ti.attrs);
|
2015-03-11 23:38:58 +02:00
|
|
|
} else {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(";");
|
2015-03-11 23:38:58 +02:00
|
|
|
}
|
2015-03-10 12:28:44 +02:00
|
|
|
}
|
2016-02-09 17:54:11 +01:00
|
|
|
ast::TraitItemKind::Type(ref bounds, ref default) => {
|
2016-12-29 13:57:01 -08:00
|
|
|
self.print_associated_type(ti.ident, Some(bounds),
|
2019-06-24 14:15:11 -04:00
|
|
|
default.as_ref().map(|ty| &**ty));
|
2015-03-10 12:28:44 +02:00
|
|
|
}
|
2018-05-22 08:01:21 -07:00
|
|
|
ast::TraitItemKind::Macro(ref mac) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_mac(mac);
|
2019-08-15 02:13:53 +03:00
|
|
|
match mac.delim {
|
2018-05-22 08:01:21 -07:00
|
|
|
MacDelimiter::Brace => {}
|
2019-06-24 14:15:11 -04:00
|
|
|
_ => self.s.word(";"),
|
2018-05-22 08:01:21 -07:00
|
|
|
}
|
2016-06-11 02:00:07 +01:00
|
|
|
}
|
2014-08-04 13:56:56 -07:00
|
|
|
}
|
2018-08-22 22:05:19 +01:00
|
|
|
self.ann.post(self, AnnNode::SubItem(ti.id))
|
2014-08-04 13:56:56 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_impl_item(&mut self, ii: &ast::ImplItem) {
|
|
|
|
self.ann.pre(self, AnnNode::SubItem(ii.id));
|
|
|
|
self.hardbreak_if_not_bol();
|
|
|
|
self.maybe_print_comment(ii.span.lo());
|
|
|
|
self.print_outer_attributes(&ii.attrs);
|
|
|
|
self.print_defaultness(ii.defaultness);
|
2019-09-26 16:38:13 +01:00
|
|
|
match ii.kind {
|
2015-11-13 14:15:04 +01:00
|
|
|
ast::ImplItemKind::Const(ref ty, ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_associated_const(ii.ident, ty, Some(expr), &ii.vis);
|
2015-03-15 19:35:25 -06:00
|
|
|
}
|
2015-11-13 14:15:04 +01:00
|
|
|
ast::ImplItemKind::Method(ref sig, ref body) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("");
|
|
|
|
self.print_method_sig(ii.ident, &ii.generics, sig, &ii.vis);
|
|
|
|
self.nbsp();
|
|
|
|
self.print_block_with_attrs(body, &ii.attrs);
|
2015-03-10 12:28:44 +02:00
|
|
|
}
|
2019-08-02 20:59:07 +01:00
|
|
|
ast::ImplItemKind::TyAlias(ref ty) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_associated_type(ii.ident, None, Some(ty));
|
2015-03-10 12:28:44 +02:00
|
|
|
}
|
2018-05-22 08:01:21 -07:00
|
|
|
ast::ImplItemKind::Macro(ref mac) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_mac(mac);
|
2019-08-15 02:13:53 +03:00
|
|
|
match mac.delim {
|
2018-05-22 08:01:21 -07:00
|
|
|
MacDelimiter::Brace => {}
|
2019-06-24 14:15:11 -04:00
|
|
|
_ => self.s.word(";"),
|
2018-05-22 08:01:21 -07:00
|
|
|
}
|
2014-07-11 21:22:11 -07:00
|
|
|
}
|
|
|
|
}
|
2018-08-22 22:05:19 +01:00
|
|
|
self.ann.post(self, AnnNode::SubItem(ii.id))
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_stmt(&mut self, st: &ast::Stmt) {
|
|
|
|
self.maybe_print_comment(st.span.lo());
|
2019-09-26 17:34:50 +01:00
|
|
|
match st.kind {
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Local(ref loc) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_outer_attributes(&loc.attrs);
|
|
|
|
self.space_if_not_bol();
|
|
|
|
self.ibox(INDENT_UNIT);
|
|
|
|
self.word_nbsp("let");
|
|
|
|
|
|
|
|
self.ibox(INDENT_UNIT);
|
|
|
|
self.print_local_decl(loc);
|
|
|
|
self.end();
|
2016-06-17 02:30:01 +00:00
|
|
|
if let Some(ref init) = loc.init {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.nbsp();
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_expr(init);
|
2016-06-17 02:30:01 +00:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(";");
|
|
|
|
self.end();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::StmtKind::Item(ref item) => self.print_item(item),
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Expr(ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.space_if_not_bol();
|
|
|
|
self.print_expr_outer_attr_style(expr, false);
|
2019-10-11 13:17:20 +02:00
|
|
|
if classify::expr_requires_semi_to_be_stmt(expr) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(";");
|
2016-06-24 11:39:18 +00:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Semi(ref expr) => {
|
2019-09-11 22:05:26 -04:00
|
|
|
match expr.kind {
|
|
|
|
// Filter out empty `Tup` exprs created for the `redundant_semicolon`
|
|
|
|
// lint, as they shouldn't be visible and interact poorly
|
|
|
|
// with proc macros.
|
|
|
|
ast::ExprKind::Tup(ref exprs) if exprs.is_empty()
|
|
|
|
&& expr.attrs.is_empty() => (),
|
|
|
|
_ => {
|
|
|
|
self.space_if_not_bol();
|
|
|
|
self.print_expr_outer_attr_style(expr, false);
|
|
|
|
self.s.word(";");
|
|
|
|
}
|
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-06-17 02:30:01 +00:00
|
|
|
ast::StmtKind::Mac(ref mac) => {
|
|
|
|
let (ref mac, style, ref attrs) = **mac;
|
2019-06-24 14:15:11 -04:00
|
|
|
self.space_if_not_bol();
|
|
|
|
self.print_outer_attributes(attrs);
|
|
|
|
self.print_mac(mac);
|
2016-07-05 11:21:25 +00:00
|
|
|
if style == ast::MacStmtStyle::Semicolon {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(";");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2012-06-30 11:54:54 +01:00
|
|
|
}
|
2011-06-16 13:00:19 -07:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
self.maybe_print_trailing_comment(st.span, None)
|
2011-06-16 13:00:19 -07:00
|
|
|
}
|
2011-07-08 16:35:09 -07:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_block(&mut self, blk: &ast::Block) {
|
2014-03-16 20:58:11 +02:00
|
|
|
self.print_block_with_attrs(blk, &[])
|
|
|
|
}
|
2012-08-13 21:13:41 -04:00
|
|
|
|
2019-07-09 09:30:08 -04:00
|
|
|
crate fn print_block_unclosed_indent(&mut self, blk: &ast::Block) {
|
|
|
|
self.print_block_maybe_unclosed(blk, &[], false)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2011-08-15 14:42:33 -07:00
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_block_with_attrs(&mut self,
|
2014-03-16 20:58:11 +02:00
|
|
|
blk: &ast::Block,
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[ast::Attribute]) {
|
2019-07-09 09:30:08 -04:00
|
|
|
self.print_block_maybe_unclosed(blk, attrs, true)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2012-01-15 17:23:59 -08:00
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_block_maybe_unclosed(&mut self,
|
2013-07-19 07:38:55 +02:00
|
|
|
blk: &ast::Block,
|
2013-07-19 21:51:37 +10:00
|
|
|
attrs: &[ast::Attribute],
|
2019-06-24 14:15:11 -04:00
|
|
|
close_box: bool) {
|
2014-03-16 20:58:11 +02:00
|
|
|
match blk.rules {
|
2019-06-24 14:15:11 -04:00
|
|
|
BlockCheckMode::Unsafe(..) => self.word_space("unsafe"),
|
2016-02-08 12:44:45 +01:00
|
|
|
BlockCheckMode::Default => ()
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.maybe_print_comment(blk.span.lo());
|
|
|
|
self.ann.pre(self, AnnNode::Block(blk));
|
|
|
|
self.bopen();
|
2014-03-16 20:58:11 +02:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_inner_attributes(attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
|
2016-06-24 11:39:18 +00:00
|
|
|
for (i, st) in blk.stmts.iter().enumerate() {
|
2019-09-26 17:34:50 +01:00
|
|
|
match st.kind {
|
2016-06-26 02:19:34 +00:00
|
|
|
ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.maybe_print_comment(st.span.lo());
|
|
|
|
self.space_if_not_bol();
|
|
|
|
self.print_expr_outer_attr_style(expr, false);
|
|
|
|
self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()));
|
2016-06-24 11:39:18 +00:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
_ => self.print_stmt(st),
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2016-06-24 11:39:18 +00:00
|
|
|
|
2019-07-09 09:30:08 -04:00
|
|
|
self.bclose_maybe_open(blk.span, close_box);
|
2018-08-22 22:05:19 +01:00
|
|
|
self.ann.post(self, AnnNode::Block(blk))
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2011-03-04 07:22:43 +01:00
|
|
|
|
2019-08-28 01:15:33 +02:00
|
|
|
/// Print a `let pat = scrutinee` expression.
|
|
|
|
crate fn print_let(&mut self, pat: &ast::Pat, scrutinee: &ast::Expr) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("let ");
|
2019-05-15 16:05:58 +02:00
|
|
|
|
2019-08-28 01:15:33 +02:00
|
|
|
self.print_pat(pat);
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
2019-05-15 16:05:58 +02:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("=");
|
2019-06-18 01:28:20 +02:00
|
|
|
self.print_expr_cond_paren(
|
|
|
|
scrutinee,
|
|
|
|
Self::cond_needs_par(scrutinee)
|
|
|
|
|| parser::needs_par_as_let_scrutinee(scrutinee.precedence().order())
|
|
|
|
)
|
2019-05-15 16:05:58 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_else(&mut self, els: Option<&ast::Expr>) {
|
2019-09-26 14:39:48 +01:00
|
|
|
if let Some(_else) = els {
|
|
|
|
match _else.kind {
|
|
|
|
// Another `else if` block.
|
|
|
|
ast::ExprKind::If(ref i, ref then, ref e) => {
|
|
|
|
self.cbox(INDENT_UNIT - 1);
|
|
|
|
self.ibox(0);
|
|
|
|
self.s.word(" else if ");
|
|
|
|
self.print_expr_as_cond(i);
|
|
|
|
self.s.space();
|
|
|
|
self.print_block(then);
|
|
|
|
self.print_else(e.as_ref().map(|e| &**e))
|
|
|
|
}
|
|
|
|
// Final `else` block.
|
|
|
|
ast::ExprKind::Block(ref b, _) => {
|
|
|
|
self.cbox(INDENT_UNIT - 1);
|
|
|
|
self.ibox(0);
|
|
|
|
self.s.word(" else ");
|
|
|
|
self.print_block(b)
|
|
|
|
}
|
|
|
|
// Constraints would be great here!
|
|
|
|
_ => {
|
|
|
|
panic!("print_if saw if with weird alternative");
|
2014-01-29 17:39:21 -08:00
|
|
|
}
|
2011-06-16 14:08:17 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
|
2019-06-24 14:15:11 -04:00
|
|
|
elseopt: Option<&ast::Expr>) {
|
|
|
|
self.head("if");
|
2019-05-15 16:05:58 +02:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_as_cond(test);
|
|
|
|
self.s.space();
|
2011-07-08 16:35:09 -07:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_block(blk);
|
2014-08-24 18:04:29 -07:00
|
|
|
self.print_else(elseopt)
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_mac(&mut self, m: &ast::Mac) {
|
2019-07-13 23:08:29 +03:00
|
|
|
self.print_mac_common(
|
2019-08-15 02:13:53 +03:00
|
|
|
Some(MacHeader::Path(&m.path)),
|
2019-07-14 16:09:39 +03:00
|
|
|
true,
|
|
|
|
None,
|
2019-08-15 02:13:53 +03:00
|
|
|
m.delim.to_token(),
|
|
|
|
m.stream(),
|
2019-07-14 16:09:39 +03:00
|
|
|
true,
|
|
|
|
m.span,
|
2019-07-13 23:08:29 +03:00
|
|
|
);
|
2012-09-11 21:25:01 -07:00
|
|
|
}
|
2012-11-30 11:18:25 -08:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_call_post(&mut self, args: &[P<ast::Expr>]) {
|
|
|
|
self.popen();
|
|
|
|
self.commasep_exprs(Inconsistent, args);
|
2014-03-16 20:58:11 +02:00
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) {
|
2019-06-18 01:28:20 +02:00
|
|
|
self.print_expr_cond_paren(expr, expr.precedence().order() < prec)
|
2015-08-06 19:55:27 +12:00
|
|
|
}
|
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
|
2017-07-20 16:53:56 -04:00
|
|
|
/// `if cond { ... }`.
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_expr_as_cond(&mut self, expr: &ast::Expr) {
|
2019-06-18 01:28:20 +02:00
|
|
|
self.print_expr_cond_paren(expr, Self::cond_needs_par(expr))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Does `expr` need parenthesis when printed in a condition position?
|
|
|
|
fn cond_needs_par(expr: &ast::Expr) -> bool {
|
2019-09-26 14:39:48 +01:00
|
|
|
match expr.kind {
|
2017-07-20 16:53:56 -04:00
|
|
|
// 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),
|
2019-06-18 01:28:20 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-20 16:53:56 -04:00
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
/// Prints `expr` or `(expr)` when `needs_par` holds.
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) {
|
2014-04-17 05:33:58 +09:00
|
|
|
if needs_par {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
2014-04-17 05:33:58 +09:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr(expr);
|
2014-04-17 05:33:58 +09:00
|
|
|
if needs_par {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.pclose();
|
2014-04-17 05:33:58 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-03 17:39:51 +01:00
|
|
|
fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>],
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[Attribute]) {
|
|
|
|
self.ibox(INDENT_UNIT);
|
|
|
|
self.s.word("[");
|
|
|
|
self.print_inner_attributes_inline(attrs);
|
|
|
|
self.commasep_exprs(Inconsistent, &exprs[..]);
|
|
|
|
self.s.word("]");
|
|
|
|
self.end();
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_repeat(&mut self,
|
|
|
|
element: &ast::Expr,
|
2018-05-17 21:28:50 +03:00
|
|
|
count: &ast::AnonConst,
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[Attribute]) {
|
|
|
|
self.ibox(INDENT_UNIT);
|
|
|
|
self.s.word("[");
|
|
|
|
self.print_inner_attributes_inline(attrs);
|
|
|
|
self.print_expr(element);
|
|
|
|
self.word_space(";");
|
|
|
|
self.print_expr(&count.value);
|
|
|
|
self.s.word("]");
|
|
|
|
self.end();
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_struct(&mut self,
|
|
|
|
path: &ast::Path,
|
|
|
|
fields: &[ast::Field],
|
2015-11-03 17:39:51 +01:00
|
|
|
wth: &Option<P<ast::Expr>>,
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[Attribute]) {
|
|
|
|
self.print_path(path, true, 0);
|
|
|
|
self.s.word("{");
|
|
|
|
self.print_inner_attributes_inline(attrs);
|
2016-12-29 13:57:01 -08:00
|
|
|
self.commasep_cmnt(
|
2015-09-10 22:46:52 +03:00
|
|
|
Consistent,
|
|
|
|
&fields[..],
|
|
|
|
|s, field| {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.ibox(INDENT_UNIT);
|
2016-10-27 03:15:13 +03:00
|
|
|
if !field.is_shorthand {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_ident(field.ident);
|
|
|
|
s.word_space(":");
|
2016-10-27 03:15:13 +03:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_expr(&field.expr);
|
|
|
|
s.end();
|
2015-09-10 22:46:52 +03:00
|
|
|
},
|
2019-06-24 14:15:11 -04:00
|
|
|
|f| f.span);
|
2015-09-10 22:46:52 +03:00
|
|
|
match *wth {
|
|
|
|
Some(ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(INDENT_UNIT);
|
2015-09-10 22:46:52 +03:00
|
|
|
if !fields.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(",");
|
|
|
|
self.s.space();
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("..");
|
|
|
|
self.print_expr(expr);
|
|
|
|
self.end();
|
2015-09-10 22:46:52 +03:00
|
|
|
}
|
|
|
|
_ => if !fields.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(",")
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("}");
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
|
2015-11-03 17:39:51 +01:00
|
|
|
fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>],
|
2019-06-24 14:15:11 -04:00
|
|
|
attrs: &[Attribute]) {
|
|
|
|
self.popen();
|
|
|
|
self.print_inner_attributes_inline(attrs);
|
|
|
|
self.commasep_exprs(Inconsistent, &exprs[..]);
|
2015-01-13 21:16:56 -08:00
|
|
|
if exprs.len() == 1 {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(",");
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_call(&mut self,
|
|
|
|
func: &ast::Expr,
|
2019-06-24 14:15:11 -04:00
|
|
|
args: &[P<ast::Expr>]) {
|
2017-07-20 16:53:56 -04:00
|
|
|
let prec =
|
2019-09-26 14:39:48 +01:00
|
|
|
match func.kind {
|
2018-04-01 21:48:39 +03:00
|
|
|
ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
|
2017-07-20 16:53:56 -04:00
|
|
|
_ => parser::PREC_POSTFIX,
|
|
|
|
};
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(func, prec);
|
2015-01-13 21:16:56 -08:00
|
|
|
self.print_call_post(args)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_method_call(&mut self,
|
2017-07-07 02:39:55 +03:00
|
|
|
segment: &ast::PathSegment,
|
2019-06-24 14:15:11 -04:00
|
|
|
args: &[P<ast::Expr>]) {
|
2015-01-17 16:15:52 -08:00
|
|
|
let base_args = &args[1..];
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
|
|
|
|
self.s.word(".");
|
|
|
|
self.print_ident(segment.ident);
|
2018-02-23 17:48:54 +00:00
|
|
|
if let Some(ref args) = segment.args {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_generic_args(args, true);
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
self.print_call_post(base_args)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_binary(&mut self,
|
|
|
|
op: ast::BinOp,
|
|
|
|
lhs: &ast::Expr,
|
2019-06-24 14:15:11 -04:00
|
|
|
rhs: &ast::Expr) {
|
2017-07-20 16:53:56 -04: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),
|
|
|
|
};
|
|
|
|
|
2019-09-26 14:39:48 +01:00
|
|
|
let left_prec = match (&lhs.kind, op.node) {
|
2017-11-05 09:28:00 -08:00
|
|
|
// 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,
|
2019-06-18 01:28:20 +02:00
|
|
|
// We are given `(let _ = a) OP b`.
|
|
|
|
//
|
|
|
|
// - When `OP <= LAnd` we should print `let _ = a OP b` to avoid redundant parens
|
|
|
|
// as the parser will interpret this as `(let _ = a) OP b`.
|
|
|
|
//
|
|
|
|
// - Otherwise, e.g. when we have `(let a = b) < c` in AST,
|
|
|
|
// parens are required since the parser would interpret `let a = b < c` as
|
|
|
|
// `let a = (b < c)`. To achieve this, we force parens.
|
|
|
|
(&ast::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(prec) => {
|
|
|
|
parser::PREC_FORCE_PAREN
|
|
|
|
}
|
2017-11-05 09:28:00 -08:00
|
|
|
_ => left_prec,
|
|
|
|
};
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(lhs, left_prec);
|
|
|
|
self.s.space();
|
|
|
|
self.word_space(op.node.to_string());
|
2017-07-20 16:53:56 -04:00
|
|
|
self.print_expr_maybe_paren(rhs, right_prec)
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_unary(&mut self,
|
|
|
|
op: ast::UnOp,
|
2019-06-24 14:15:11 -04:00
|
|
|
expr: &ast::Expr) {
|
|
|
|
self.s.word(ast::UnOp::to_string(op));
|
2017-07-20 16:53:56 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_addr_of(&mut self,
|
|
|
|
mutability: ast::Mutability,
|
2019-06-24 14:15:11 -04:00
|
|
|
expr: &ast::Expr) {
|
|
|
|
self.s.word("&");
|
|
|
|
self.print_mutability(mutability);
|
2017-07-20 16:53:56 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn print_expr(&mut self, expr: &ast::Expr) {
|
2015-11-03 17:39:51 +01:00
|
|
|
self.print_expr_outer_attr_style(expr, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_outer_attr_style(&mut self,
|
|
|
|
expr: &ast::Expr,
|
2019-06-24 14:15:11 -04:00
|
|
|
is_inline: bool) {
|
|
|
|
self.maybe_print_comment(expr.span.lo());
|
2015-11-03 17:39:51 +01:00
|
|
|
|
2016-06-18 04:01:57 +00:00
|
|
|
let attrs = &expr.attrs;
|
2015-11-03 17:39:51 +01:00
|
|
|
if is_inline {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_outer_attributes_inline(attrs);
|
2015-11-03 17:39:51 +01:00
|
|
|
} else {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_outer_attributes(attrs);
|
2015-11-03 17:39:51 +01:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(INDENT_UNIT);
|
|
|
|
self.ann.pre(self, AnnNode::Expr(expr));
|
2019-09-26 14:39:48 +01:00
|
|
|
match expr.kind {
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Box(ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("box");
|
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX);
|
2015-09-24 18:00:08 +03:00
|
|
|
}
|
2017-01-15 23:36:10 -08:00
|
|
|
ast::ExprKind::Array(ref exprs) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_vec(&exprs[..], attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Repeat(ref element, ref count) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_repeat(element, count, attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Struct(ref path, ref fields, ref wth) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_struct(path, &fields[..], wth, attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Tup(ref exprs) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_tup(&exprs[..], attrs);
|
2012-07-10 10:37:05 -07:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Call(ref func, ref args) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_call(func, &args[..]);
|
2012-08-09 19:31:47 -04:00
|
|
|
}
|
2017-07-07 02:39:55 +03:00
|
|
|
ast::ExprKind::MethodCall(ref segment, ref args) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_method_call(segment, &args[..]);
|
2013-10-28 15:22:49 -07:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_binary(op, lhs, rhs);
|
2013-10-28 15:22:49 -07:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Unary(op, ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_unary(op, expr);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::AddrOf(m, ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_addr_of(m, expr);
|
2015-01-13 21:16:56 -08:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Lit(ref lit) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_literal(lit);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Cast(ref expr, ref ty) => {
|
2017-07-20 16:53:56 -04:00
|
|
|
let prec = AssocOp::As.precedence() as i8;
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(expr, prec);
|
|
|
|
self.s.space();
|
|
|
|
self.word_space("as");
|
|
|
|
self.print_type(ty);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Type(ref expr, ref ty) => {
|
2017-07-20 16:53:56 -04:00
|
|
|
let prec = AssocOp::Colon.precedence() as i8;
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(expr, prec);
|
|
|
|
self.word_space(":");
|
|
|
|
self.print_type(ty);
|
2015-02-01 09:59:46 +02:00
|
|
|
}
|
2019-08-28 01:15:33 +02:00
|
|
|
ast::ExprKind::Let(ref pat, ref scrutinee) => {
|
|
|
|
self.print_let(pat, scrutinee);
|
2019-05-15 16:05:58 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::If(ref test, ref blk, ref elseopt) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_if(test, blk, elseopt.as_ref().map(|e| &**e));
|
2014-08-24 18:04:29 -07:00
|
|
|
}
|
2018-01-16 01:44:32 +03:00
|
|
|
ast::ExprKind::While(ref test, ref blk, opt_label) => {
|
|
|
|
if let Some(label) = opt_label {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(label.ident);
|
|
|
|
self.word_space(":");
|
2014-07-25 20:12:51 -04:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("while");
|
|
|
|
self.print_expr_as_cond(test);
|
|
|
|
self.s.space();
|
|
|
|
self.print_block_with_attrs(blk, attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-01-16 01:44:32 +03:00
|
|
|
ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => {
|
|
|
|
if let Some(label) = opt_label {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(label.ident);
|
|
|
|
self.word_space(":");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("for");
|
|
|
|
self.print_pat(pat);
|
|
|
|
self.s.space();
|
|
|
|
self.word_space("in");
|
|
|
|
self.print_expr_as_cond(iter);
|
|
|
|
self.s.space();
|
|
|
|
self.print_block_with_attrs(blk, attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-01-16 01:44:32 +03:00
|
|
|
ast::ExprKind::Loop(ref blk, opt_label) => {
|
|
|
|
if let Some(label) = opt_label {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(label.ident);
|
|
|
|
self.word_space(":");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("loop");
|
|
|
|
self.s.space();
|
|
|
|
self.print_block_with_attrs(blk, attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Match(ref expr, ref arms) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.cbox(INDENT_UNIT);
|
2019-07-09 09:49:37 -04:00
|
|
|
self.ibox(INDENT_UNIT);
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp("match");
|
|
|
|
self.print_expr_as_cond(expr);
|
|
|
|
self.s.space();
|
|
|
|
self.bopen();
|
|
|
|
self.print_inner_attributes_no_trailing_hardbreak(attrs);
|
2015-01-31 12:20:46 -05:00
|
|
|
for arm in arms {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_arm(arm);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-07-09 07:38:31 -04:00
|
|
|
self.bclose(expr.span);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-06-06 15:50:59 -07:00
|
|
|
ast::ExprKind::Closure(
|
2019-05-29 04:10:49 +03:00
|
|
|
capture_clause, asyncness, movability, ref decl, ref body, _) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_movability(movability);
|
|
|
|
self.print_asyncness(asyncness);
|
|
|
|
self.print_capture_clause(capture_clause);
|
2014-07-23 12:43:29 -07:00
|
|
|
|
2019-08-27 13:24:32 +02:00
|
|
|
self.print_fn_block_params(decl);
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.print_expr(body);
|
|
|
|
self.end(); // need to close a box
|
2016-06-23 09:51:18 +00:00
|
|
|
|
2014-03-16 20:58:11 +02: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.
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(0);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-04-16 05:44:39 +02:00
|
|
|
ast::ExprKind::Block(ref blk, opt_label) => {
|
|
|
|
if let Some(label) = opt_label {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(label.ident);
|
|
|
|
self.word_space(":");
|
2018-04-16 05:44:39 +02:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
// containing cbox, will be closed by print-block at }
|
2019-06-24 14:15:11 -04:00
|
|
|
self.cbox(INDENT_UNIT);
|
2014-03-16 20:58:11 +02:00
|
|
|
// head-box, will be closed by print-block after {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(0);
|
|
|
|
self.print_block_with_attrs(blk, attrs);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-06-06 15:50:59 -07:00
|
|
|
ast::ExprKind::Async(capture_clause, _, ref blk) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp("async");
|
|
|
|
self.print_capture_clause(capture_clause);
|
|
|
|
self.s.space();
|
2018-10-02 21:43:05 -07:00
|
|
|
// cbox/ibox in analogy to the `ExprKind::Block` arm above
|
2019-06-24 14:15:11 -04:00
|
|
|
self.cbox(INDENT_UNIT);
|
|
|
|
self.ibox(0);
|
|
|
|
self.print_block_with_attrs(blk, attrs);
|
2018-06-06 15:50:59 -07:00
|
|
|
}
|
2019-07-02 06:30:21 +02:00
|
|
|
ast::ExprKind::Await(ref expr) => {
|
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
|
|
|
self.s.word(".await");
|
2019-04-18 12:55:23 -07:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Assign(ref lhs, ref rhs) => {
|
2017-07-20 16:53:56 -04:00
|
|
|
let prec = AssocOp::Assign.precedence() as i8;
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(lhs, prec + 1);
|
|
|
|
self.s.space();
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_expr_maybe_paren(rhs, prec);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
|
2017-07-20 16:53:56 -04:00
|
|
|
let prec = AssocOp::Assign.precedence() as i8;
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(lhs, prec + 1);
|
|
|
|
self.s.space();
|
|
|
|
self.s.word(op.node.to_string());
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_expr_maybe_paren(rhs, prec);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-03-18 16:47:09 +03:00
|
|
|
ast::ExprKind::Field(ref expr, ident) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
|
|
|
self.s.word(".");
|
|
|
|
self.print_ident(ident);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Index(ref expr, ref index) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
|
|
|
self.s.word("[");
|
|
|
|
self.print_expr(index);
|
|
|
|
self.s.word("]");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-11 12:52:39 -05:00
|
|
|
ast::ExprKind::Range(ref start, ref end, limits) => {
|
2017-07-20 16:53:56 -04: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 20:05:39 +02:00
|
|
|
if let Some(ref e) = *start {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(e, fake_prec);
|
2014-09-15 20:48:58 +12:00
|
|
|
}
|
2016-01-13 01:23:31 -05:00
|
|
|
if limits == ast::RangeLimits::HalfOpen {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("..");
|
2016-01-13 01:23:31 -05:00
|
|
|
} else {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("..=");
|
2016-01-13 01:23:31 -05:00
|
|
|
}
|
2017-05-12 20:05:39 +02:00
|
|
|
if let Some(ref e) = *end {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(e, fake_prec);
|
2014-09-15 20:48:58 +12:00
|
|
|
}
|
2014-12-13 18:41:02 +13:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Path(None, ref path) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(path, true, 0)
|
2015-02-17 19:29:13 +02:00
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Path(Some(ref qself), ref path) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_qpath(path, qself, true)
|
2015-02-17 19:29:13 +02:00
|
|
|
}
|
2018-01-16 01:44:32 +03:00
|
|
|
ast::ExprKind::Break(opt_label, ref opt_expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("break");
|
|
|
|
self.s.space();
|
2018-01-16 01:44:32 +03:00
|
|
|
if let Some(label) = opt_label {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(label.ident);
|
|
|
|
self.s.space();
|
2014-03-16 20:58:11 +02: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 15:15:06 -07:00
|
|
|
if let Some(ref expr) = *opt_expr {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
|
|
|
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 15:15:06 -07:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-01-16 01:44:32 +03:00
|
|
|
ast::ExprKind::Continue(opt_label) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("continue");
|
|
|
|
self.s.space();
|
2018-01-16 01:44:32 +03:00
|
|
|
if let Some(label) = opt_label {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(label.ident);
|
|
|
|
self.s.space()
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Ret(ref result) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("return");
|
2017-05-12 20:05:39 +02:00
|
|
|
if let Some(ref expr) = *result {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(" ");
|
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::InlineAsm(ref a) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("asm!");
|
|
|
|
self.popen();
|
|
|
|
self.print_string(&a.asm.as_str(), a.asm_str_style);
|
|
|
|
self.word_space(":");
|
2014-04-17 17:35:40 +09:00
|
|
|
|
2016-12-29 13:57:01 -08: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 10:42:53 -07:00
|
|
|
match ch.next() {
|
|
|
|
Some('=') if out.is_rw => {
|
2016-12-29 13:57:01 -08:00
|
|
|
s.print_string(&format!("+{}", ch.as_str()),
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::StrStyle::Cooked)
|
2014-08-19 20:39:26 +01:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
_ => s.print_string(&constraint, ast::StrStyle::Cooked)
|
2014-08-19 20:39:26 +01:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
s.popen();
|
|
|
|
s.print_expr(&out.expr);
|
|
|
|
s.pclose();
|
|
|
|
});
|
|
|
|
self.s.space();
|
|
|
|
self.word_space(":");
|
2016-12-29 13:57:01 -08:00
|
|
|
|
|
|
|
self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_string(&co.as_str(), ast::StrStyle::Cooked);
|
|
|
|
s.popen();
|
|
|
|
s.print_expr(o);
|
|
|
|
s.pclose();
|
|
|
|
});
|
|
|
|
self.s.space();
|
|
|
|
self.word_space(":");
|
2014-04-17 17:35:40 +09:00
|
|
|
|
2016-12-29 13:57:01 -08:00
|
|
|
self.commasep(Inconsistent, &a.clobbers,
|
2014-11-30 11:56:31 +09:00
|
|
|
|s, co| {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_string(&co.as_str(), ast::StrStyle::Cooked);
|
|
|
|
});
|
2014-12-17 22:02:50 +09:00
|
|
|
|
2016-10-29 22:54:04 +01:00
|
|
|
let mut options = vec![];
|
2014-12-17 22:02:50 +09:00
|
|
|
if a.volatile {
|
|
|
|
options.push("volatile");
|
|
|
|
}
|
|
|
|
if a.alignstack {
|
|
|
|
options.push("alignstack");
|
|
|
|
}
|
2015-09-21 11:45:04 +02:00
|
|
|
if a.dialect == ast::AsmDialect::Intel {
|
2014-12-17 22:02:50 +09:00
|
|
|
options.push("intel");
|
|
|
|
}
|
|
|
|
|
2015-03-24 16:54:09 -07:00
|
|
|
if !options.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space(":");
|
2016-12-29 13:57:01 -08:00
|
|
|
self.commasep(Inconsistent, &options,
|
2016-03-22 17:58:45 -05:00
|
|
|
|s, &co| {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_string(co, ast::StrStyle::Cooked);
|
|
|
|
});
|
2014-12-17 22:02:50 +09:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.pclose();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::ExprKind::Mac(ref m) => self.print_mac(m),
|
2016-02-08 16:05:05 +01:00
|
|
|
ast::ExprKind::Paren(ref e) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
|
|
|
self.print_inner_attributes_inline(attrs);
|
|
|
|
self.print_expr(e);
|
|
|
|
self.pclose();
|
2016-02-28 17:38:48 -05:00
|
|
|
},
|
2016-12-26 14:34:03 +01:00
|
|
|
ast::ExprKind::Yield(ref e) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("yield");
|
2016-12-26 14:34:03 +01:00
|
|
|
match *e {
|
|
|
|
Some(ref expr) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
2016-12-26 14:34:03 +01:00
|
|
|
}
|
|
|
|
_ => ()
|
|
|
|
}
|
|
|
|
}
|
2016-02-28 17:38:48 -05:00
|
|
|
ast::ExprKind::Try(ref e) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr_maybe_paren(e, parser::PREC_POSTFIX);
|
|
|
|
self.s.word("?")
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2018-07-21 18:47:02 -07:00
|
|
|
ast::ExprKind::TryBlock(ref blk) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.head("try");
|
|
|
|
self.s.space();
|
|
|
|
self.print_block_with_attrs(blk, attrs)
|
2017-02-17 15:12:47 -08:00
|
|
|
}
|
2018-12-17 04:57:32 +03:00
|
|
|
ast::ExprKind::Err => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
|
|
|
self.s.word("/*ERROR*/");
|
|
|
|
self.pclose()
|
2018-12-17 04:57:32 +03:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ann.post(self, AnnNode::Expr(expr));
|
|
|
|
self.end();
|
2011-08-10 12:51:50 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_local_decl(&mut self, loc: &ast::Local) {
|
|
|
|
self.print_pat(&loc.pat);
|
2015-01-02 20:55:31 +09:00
|
|
|
if let Some(ref ty) = loc.ty {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space(":");
|
|
|
|
self.print_type(ty);
|
2011-03-04 07:22:43 +01:00
|
|
|
}
|
|
|
|
}
|
2011-03-24 16:33:20 +01:00
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn print_usize(&mut self, i: usize) {
|
2018-11-29 11:36:58 +11:00
|
|
|
self.s.word(i.to_string())
|
2014-08-10 15:54:33 +12:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_name(&mut self, name: ast::Name) {
|
2019-10-22 08:31:37 +11:00
|
|
|
self.s.word(name.to_string());
|
2018-08-22 22:05:19 +01:00
|
|
|
self.ann.post(self, AnnNode::Name(&name))
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2013-08-07 09:47:28 -07:00
|
|
|
|
2015-01-13 06:02:56 +02:00
|
|
|
fn print_qpath(&mut self,
|
2015-02-17 19:29:13 +02:00
|
|
|
path: &ast::Path,
|
|
|
|
qself: &ast::QSelf,
|
2015-01-13 06:02:56 +02:00
|
|
|
colons_before_params: bool)
|
|
|
|
{
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("<");
|
|
|
|
self.print_type(&qself.ty);
|
2015-02-24 12:12:14 +02:00
|
|
|
if qself.position > 0 {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("as");
|
2015-02-24 12:12:14 +02:00
|
|
|
let depth = path.segments.len() - qself.position;
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(path, false, depth);
|
2015-02-24 12:12:14 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(">");
|
|
|
|
self.s.word("::");
|
2015-02-17 19:29:13 +02:00
|
|
|
let item_segment = path.segments.last().unwrap();
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(item_segment.ident);
|
2018-02-23 17:48:54 +00:00
|
|
|
match item_segment.args {
|
|
|
|
Some(ref args) => self.print_generic_args(args, colons_before_params),
|
2019-06-24 14:15:11 -04:00
|
|
|
None => {},
|
2016-12-10 06:45:58 +00:00
|
|
|
}
|
2015-01-13 06:02:56 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_pat(&mut self, pat: &ast::Pat) {
|
|
|
|
self.maybe_print_comment(pat.span.lo());
|
|
|
|
self.ann.pre(self, AnnNode::Pat(pat));
|
2014-03-16 20:58:11 +02:00
|
|
|
/* Pat isn't normalized, but the beauty of it
|
|
|
|
is that it doesn't matter */
|
2019-09-26 16:18:31 +01:00
|
|
|
match pat.kind {
|
2019-06-24 14:15:11 -04:00
|
|
|
PatKind::Wild => self.s.word("_"),
|
2018-03-18 16:47:09 +03:00
|
|
|
PatKind::Ident(binding_mode, ident, ref sub) => {
|
2014-03-16 20:58:11 +02:00
|
|
|
match binding_mode {
|
2015-12-18 14:23:01 +01:00
|
|
|
ast::BindingMode::ByRef(mutbl) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp("ref");
|
|
|
|
self.print_mutability(mutbl);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-09 17:44:47 +01:00
|
|
|
ast::BindingMode::ByValue(ast::Mutability::Immutable) => {}
|
|
|
|
ast::BindingMode::ByValue(ast::Mutability::Mutable) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp("mut");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(ident);
|
2016-06-13 22:43:30 -07:00
|
|
|
if let Some(ref p) = *sub {
|
2019-10-14 18:12:04 +02:00
|
|
|
self.s.space();
|
|
|
|
self.s.word_space("@");
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_pat(p);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2019-07-09 09:12:14 +02:00
|
|
|
PatKind::TupleStruct(ref path, ref elts) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(path, true, 0);
|
|
|
|
self.popen();
|
2019-07-09 09:12:14 +02:00
|
|
|
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
|
2019-06-24 14:15:11 -04:00
|
|
|
self.pclose();
|
2013-11-07 19:25:39 -08:00
|
|
|
}
|
2018-10-19 15:40:07 +01:00
|
|
|
PatKind::Or(ref pats) => {
|
2019-07-14 01:05:52 +00:00
|
|
|
self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(p));
|
2018-10-19 15:40:07 +01:00
|
|
|
}
|
2016-06-11 18:47:47 +03:00
|
|
|
PatKind::Path(None, ref path) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(path, true, 0);
|
2016-02-13 15:51:27 +03:00
|
|
|
}
|
2016-06-11 18:47:47 +03:00
|
|
|
PatKind::Path(Some(ref qself), ref path) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_qpath(path, qself, false);
|
2015-03-25 10:53:28 -06:00
|
|
|
}
|
2016-02-11 21:16:33 +03:00
|
|
|
PatKind::Struct(ref path, ref fields, etc) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(path, true, 0);
|
|
|
|
self.nbsp();
|
|
|
|
self.word_space("{");
|
2016-12-29 13:57:01 -08:00
|
|
|
self.commasep_cmnt(
|
2015-02-18 14:48:57 -05:00
|
|
|
Consistent, &fields[..],
|
2014-03-16 20:58:11 +02:00
|
|
|
|s, f| {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.cbox(INDENT_UNIT);
|
2019-08-15 02:35:36 +03:00
|
|
|
if !f.is_shorthand {
|
|
|
|
s.print_ident(f.ident);
|
2019-06-24 14:15:11 -04:00
|
|
|
s.word_nbsp(":");
|
2014-10-27 00:11:26 -07:00
|
|
|
}
|
2019-08-15 02:35:36 +03:00
|
|
|
s.print_pat(&f.pat);
|
2019-06-24 14:15:11 -04:00
|
|
|
s.end();
|
2014-03-16 20:58:11 +02:00
|
|
|
},
|
2019-08-15 02:35:36 +03:00
|
|
|
|f| f.pat.span);
|
2014-03-16 20:58:11 +02:00
|
|
|
if etc {
|
2019-06-24 14:15:11 -04:00
|
|
|
if !fields.is_empty() { self.word_space(","); }
|
|
|
|
self.s.word("..");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.s.word("}");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-07-09 09:12:14 +02:00
|
|
|
PatKind::Tuple(ref elts) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
2019-07-09 09:12:14 +02:00
|
|
|
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
|
|
|
|
if elts.len() == 1 {
|
|
|
|
self.s.word(",");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.pclose();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-11 21:16:33 +03:00
|
|
|
PatKind::Box(ref inner) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("box ");
|
|
|
|
self.print_pat(inner);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-02-11 21:16:33 +03:00
|
|
|
PatKind::Ref(ref inner, mutbl) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("&");
|
2016-02-09 17:44:47 +01:00
|
|
|
if mutbl == ast::Mutability::Mutable {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("mut ");
|
2014-12-05 15:56:25 -08:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_pat(inner);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
PatKind::Lit(ref e) => self.print_expr(&**e),
|
2018-05-28 19:32:03 -07:00
|
|
|
PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr(begin);
|
|
|
|
self.s.space();
|
2017-01-10 22:13:53 +01:00
|
|
|
match *end_kind {
|
2019-06-24 14:15:11 -04:00
|
|
|
RangeEnd::Included(RangeSyntax::DotDotDot) => self.s.word("..."),
|
|
|
|
RangeEnd::Included(RangeSyntax::DotDotEq) => self.s.word("..="),
|
|
|
|
RangeEnd::Excluded => self.s.word(".."),
|
2017-01-10 22:13:53 +01:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr(end);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-07-09 09:12:14 +02:00
|
|
|
PatKind::Slice(ref elts) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("[");
|
2019-07-09 09:12:14 +02:00
|
|
|
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("]");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-07-07 00:26:55 +02:00
|
|
|
PatKind::Rest => self.s.word(".."),
|
2018-02-24 15:27:06 +03:00
|
|
|
PatKind::Paren(ref inner) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
|
|
|
self.print_pat(inner);
|
|
|
|
self.pclose();
|
2018-02-24 15:27:06 +03:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
PatKind::Mac(ref m) => self.print_mac(m),
|
2013-02-27 03:58:46 +09:00
|
|
|
}
|
2018-08-22 22:05:19 +01:00
|
|
|
self.ann.post(self, AnnNode::Pat(pat))
|
2013-12-27 14:11:01 -08:00
|
|
|
}
|
2011-03-04 07:22:43 +01:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_arm(&mut self, arm: &ast::Arm) {
|
2019-09-06 03:56:45 +01:00
|
|
|
// Note, I have no idea why this check is necessary, but here it is.
|
2014-07-27 18:05:07 -07:00
|
|
|
if arm.attrs.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
}
|
|
|
|
self.cbox(INDENT_UNIT);
|
|
|
|
self.ibox(0);
|
2019-08-28 01:15:33 +02:00
|
|
|
self.maybe_print_comment(arm.pat.span.lo());
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_outer_attributes(&arm.attrs);
|
2019-08-28 01:15:33 +02:00
|
|
|
self.print_pat(&arm.pat);
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
2019-06-23 11:32:16 +02:00
|
|
|
if let Some(ref e) = arm.guard {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("if");
|
|
|
|
self.print_expr(e);
|
|
|
|
self.s.space();
|
2014-07-27 18:05:07 -07:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("=>");
|
2014-07-27 18:05:07 -07:00
|
|
|
|
2019-09-26 14:39:48 +01:00
|
|
|
match arm.body.kind {
|
2018-04-16 05:44:39 +02:00
|
|
|
ast::ExprKind::Block(ref blk, opt_label) => {
|
|
|
|
if let Some(label) = opt_label {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_ident(label.ident);
|
|
|
|
self.word_space(":");
|
2018-04-16 05:44:39 +02:00
|
|
|
}
|
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
// The block will close the pattern's ibox.
|
2019-07-09 09:30:08 -04:00
|
|
|
self.print_block_unclosed_indent(blk);
|
2014-11-22 16:24:58 +01:00
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
// If it is a user-provided unsafe block, print a comma after it.
|
2016-02-08 12:44:45 +01:00
|
|
|
if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(",");
|
2014-11-22 16:24:58 +01:00
|
|
|
}
|
2014-07-27 18:05:07 -07:00
|
|
|
}
|
|
|
|
_ => {
|
2019-09-06 03:56:45 +01:00
|
|
|
self.end(); // Close the ibox for the pattern.
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_expr(&arm.body);
|
|
|
|
self.s.word(",");
|
2014-07-27 18:05:07 -07:00
|
|
|
}
|
|
|
|
}
|
2019-09-06 03:56:45 +01:00
|
|
|
self.end(); // Close enclosing cbox.
|
2014-07-27 18:05:07 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) {
|
2016-03-06 15:54:44 +03:00
|
|
|
match explicit_self.node {
|
|
|
|
SelfKind::Value(m) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_mutability(m);
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("self")
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
SelfKind::Region(ref lt, m) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("&");
|
|
|
|
self.print_opt_lifetime(lt);
|
|
|
|
self.print_mutability(m);
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("self")
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
SelfKind::Explicit(ref typ, m) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_mutability(m);
|
|
|
|
self.s.word("self");
|
|
|
|
self.word_space(":");
|
2017-05-12 20:05:39 +02:00
|
|
|
self.print_type(typ)
|
2014-05-06 16:37:32 -07:00
|
|
|
}
|
2013-03-09 19:43:53 -05:00
|
|
|
}
|
2012-08-17 16:14:57 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_fn(&mut self,
|
2014-03-16 20:58:11 +02:00
|
|
|
decl: &ast::FnDecl,
|
2019-05-29 04:10:49 +03:00
|
|
|
header: ast::FnHeader,
|
2015-03-11 08:38:27 +02:00
|
|
|
name: Option<ast::Ident>,
|
2014-03-16 20:58:11 +02:00
|
|
|
generics: &ast::Generics,
|
2019-06-24 14:15:11 -04:00
|
|
|
vis: &ast::Visibility) {
|
|
|
|
self.print_fn_header_info(header, vis);
|
2015-03-11 08:38:27 +02:00
|
|
|
|
|
|
|
if let Some(name) = name {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.nbsp();
|
|
|
|
self.print_ident(name);
|
2015-03-11 08:38:27 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_generic_params(&generics.params);
|
2019-08-27 13:24:32 +02:00
|
|
|
self.print_fn_params_and_ret(decl);
|
2015-03-13 21:54:29 -07:00
|
|
|
self.print_where_clause(&generics.where_clause)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-08-27 13:24:32 +02:00
|
|
|
crate fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.popen();
|
2019-08-27 13:24:32 +02:00
|
|
|
self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, false));
|
2019-06-24 14:15:11 -04:00
|
|
|
self.pclose();
|
2011-12-30 13:32:42 -08:00
|
|
|
|
2014-11-09 16:14:15 +01:00
|
|
|
self.print_fn_output(decl)
|
2013-10-25 01:56:34 -04:00
|
|
|
}
|
2012-02-22 11:16:25 +01:00
|
|
|
|
2019-08-27 13:24:32 +02:00
|
|
|
crate fn print_fn_block_params(&mut self, decl: &ast::FnDecl) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("|");
|
2019-08-27 13:24:32 +02:00
|
|
|
self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, true));
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("|");
|
2014-03-16 20:58:11 +02:00
|
|
|
|
2016-02-08 15:04:11 +01:00
|
|
|
if let ast::FunctionRetTy::Default(..) = decl.output {
|
2019-06-24 14:15:11 -04:00
|
|
|
return;
|
2012-09-07 18:53:14 -07:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.space_if_not_bol();
|
|
|
|
self.word_space("->");
|
2014-11-09 16:14:15 +01:00
|
|
|
match decl.output {
|
2016-02-08 15:04:11 +01:00
|
|
|
ast::FunctionRetTy::Ty(ref ty) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type(ty);
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(ty.span.lo())
|
2014-11-09 16:14:15 +01:00
|
|
|
}
|
2016-02-08 15:04:11 +01:00
|
|
|
ast::FunctionRetTy::Default(..) => unreachable!(),
|
2014-11-09 16:14:15 +01:00
|
|
|
}
|
2011-03-24 16:33:20 +01:00
|
|
|
}
|
2011-03-04 07:22:43 +01:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_movability(&mut self, movability: ast::Movability) {
|
2017-10-07 16:36:28 +02:00
|
|
|
match movability {
|
|
|
|
ast::Movability::Static => self.word_space("static"),
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::Movability::Movable => {},
|
2017-10-07 16:36:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_asyncness(&mut self, asyncness: ast::IsAsync) {
|
2018-06-06 15:50:59 -07:00
|
|
|
if asyncness.is_async() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp("async");
|
2018-06-06 15:50:59 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy) {
|
2014-07-23 12:43:29 -07:00
|
|
|
match capture_clause {
|
2016-02-08 15:27:08 +01:00
|
|
|
ast::CaptureBy::Value => self.word_space("move"),
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::CaptureBy::Ref => {},
|
2014-07-23 12:43:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound]) {
|
2014-08-27 21:46:52 -04:00
|
|
|
if !bounds.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(prefix);
|
2014-03-16 20:58:11 +02:00
|
|
|
let mut first = true;
|
2015-01-31 12:20:46 -05:00
|
|
|
for bound in bounds {
|
2017-12-19 23:40:17 +03:00
|
|
|
if !(first && prefix.is_empty()) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.nbsp();
|
2017-12-19 23:40:17 +03:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
if first {
|
|
|
|
first = false;
|
|
|
|
} else {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space("+");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2013-10-28 15:22:49 -07:00
|
|
|
|
2017-12-19 23:40:17 +03:00
|
|
|
match bound {
|
2018-06-14 12:23:46 +01:00
|
|
|
GenericBound::Trait(tref, modifier) => {
|
2017-12-19 23:40:17 +03:00
|
|
|
if modifier == &TraitBoundModifier::Maybe {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("?");
|
2017-12-19 23:40:17 +03:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_poly_trait_ref(tref);
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
GenericBound::Outlives(lt) => self.print_lifetime(*lt),
|
2017-12-19 23:40:17 +03:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2013-10-28 15:22:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_lifetime(&mut self, lifetime: ast::Lifetime) {
|
2017-03-25 21:14:18 +00:00
|
|
|
self.print_name(lifetime.ident.name)
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2013-10-28 15:22:49 -07:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_lifetime_bounds(
|
|
|
|
&mut self, lifetime: ast::Lifetime, bounds: &ast::GenericBounds) {
|
|
|
|
self.print_lifetime(lifetime);
|
2016-06-29 21:53:01 +09:00
|
|
|
if !bounds.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(": ");
|
2016-06-29 21:53:01 +09:00
|
|
|
for (i, bound) in bounds.iter().enumerate() {
|
|
|
|
if i != 0 {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(" + ");
|
2016-06-29 21:53:01 +09:00
|
|
|
}
|
2018-05-28 15:23:16 +01:00
|
|
|
match bound {
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt),
|
2018-05-28 15:23:16 +01:00
|
|
|
_ => panic!(),
|
|
|
|
}
|
2016-06-29 21:53:01 +09:00
|
|
|
}
|
2014-08-05 22:59:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) {
|
2017-10-16 21:07:26 +02:00
|
|
|
if generic_params.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
return;
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("<");
|
2014-08-27 21:46:52 -04:00
|
|
|
|
2017-10-16 21:07:26 +02:00
|
|
|
self.commasep(Inconsistent, &generic_params, |s, param| {
|
2019-08-02 08:36:08 +02:00
|
|
|
s.print_outer_attributes_inline(¶m.attrs);
|
|
|
|
|
2018-05-26 19:16:21 +01:00
|
|
|
match param.kind {
|
2018-05-30 16:49:39 +01:00
|
|
|
ast::GenericParamKind::Lifetime => {
|
|
|
|
let lt = ast::Lifetime { id: param.id, ident: param.ident };
|
|
|
|
s.print_lifetime_bounds(lt, ¶m.bounds)
|
2019-02-05 16:50:16 +01:00
|
|
|
}
|
2018-05-28 13:33:28 +01:00
|
|
|
ast::GenericParamKind::Type { ref default } => {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.print_ident(param.ident);
|
|
|
|
s.print_type_bounds(":", ¶m.bounds);
|
2019-08-02 08:36:08 +02:00
|
|
|
if let Some(ref default) = default {
|
|
|
|
s.s.space();
|
|
|
|
s.word_space("=");
|
|
|
|
s.print_type(default)
|
2018-05-26 19:16:21 +01:00
|
|
|
}
|
|
|
|
}
|
2019-02-05 16:50:16 +01:00
|
|
|
ast::GenericParamKind::Const { ref ty } => {
|
2019-06-24 14:15:11 -04:00
|
|
|
s.word_space("const");
|
|
|
|
s.print_ident(param.ident);
|
|
|
|
s.s.space();
|
|
|
|
s.word_space(":");
|
|
|
|
s.print_type(ty);
|
2019-02-05 16:50:16 +01:00
|
|
|
s.print_type_bounds(":", ¶m.bounds)
|
|
|
|
}
|
2014-08-11 09:32:26 -07:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
});
|
2014-08-11 09:32:26 -07:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word(">");
|
2011-08-02 21:26:54 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
|
2015-03-24 16:53:34 -07:00
|
|
|
if where_clause.predicates.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
return;
|
2014-08-11 09:32:26 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("where");
|
2014-08-11 09:32:26 -07:00
|
|
|
|
2015-03-13 21:54:29 -07:00
|
|
|
for (i, predicate) in where_clause.predicates.iter().enumerate() {
|
2014-08-11 09:32:26 -07:00
|
|
|
if i != 0 {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_space(",");
|
2014-08-11 09:32:26 -07:00
|
|
|
}
|
|
|
|
|
2015-11-17 23:24:49 +09:00
|
|
|
match *predicate {
|
2017-10-16 21:07:26 +02:00
|
|
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
|
|
|
ref bound_generic_params,
|
|
|
|
ref bounded_ty,
|
|
|
|
ref bounds,
|
|
|
|
..
|
|
|
|
}) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_formal_generic_params(bound_generic_params);
|
|
|
|
self.print_type(bounded_ty);
|
|
|
|
self.print_type_bounds(":", bounds);
|
2014-11-29 17:08:30 +13:00
|
|
|
}
|
2015-11-17 23:24:49 +09:00
|
|
|
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
|
|
|
|
ref bounds,
|
|
|
|
..}) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_lifetime_bounds(*lifetime, bounds);
|
2014-12-20 02:29:19 -08:00
|
|
|
}
|
2017-01-16 21:32:13 +03:00
|
|
|
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref lhs_ty,
|
|
|
|
ref rhs_ty,
|
|
|
|
..}) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type(lhs_ty);
|
|
|
|
self.s.space();
|
|
|
|
self.word_space("=");
|
|
|
|
self.print_type(rhs_ty);
|
2014-11-29 17:08:30 +13:00
|
|
|
}
|
|
|
|
}
|
2014-08-11 09:32:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_use_tree(&mut self, tree: &ast::UseTree) {
|
2017-09-26 23:04:00 +02:00
|
|
|
match tree.kind {
|
2018-06-13 11:44:06 -05:00
|
|
|
ast::UseTreeKind::Simple(rename, ..) => {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(&tree.prefix, false, 0);
|
2018-03-09 18:58:44 +03:00
|
|
|
if let Some(rename) = rename {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.space();
|
|
|
|
self.word_space("as");
|
|
|
|
self.print_ident(rename);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
}
|
2017-09-26 23:04:00 +02:00
|
|
|
ast::UseTreeKind::Glob => {
|
|
|
|
if !tree.prefix.segments.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(&tree.prefix, false, 0);
|
|
|
|
self.s.word("::");
|
2017-09-26 23:04:00 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("*");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-09-26 23:04:00 +02:00
|
|
|
ast::UseTreeKind::Nested(ref items) => {
|
|
|
|
if tree.prefix.segments.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("{");
|
2014-03-16 20:58:11 +02:00
|
|
|
} else {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_path(&tree.prefix, false, 0);
|
|
|
|
self.s.word("::{");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-09-26 23:04:00 +02:00
|
|
|
self.commasep(Inconsistent, &items[..], |this, &(ref tree, _)| {
|
|
|
|
this.print_use_tree(tree)
|
2019-06-24 14:15:11 -04:00
|
|
|
});
|
|
|
|
self.s.word("}");
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2014-02-01 11:24:42 -08:00
|
|
|
}
|
2011-06-21 14:23:16 -07:00
|
|
|
}
|
2011-06-14 18:53:12 -07:00
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
|
2014-03-16 20:58:11 +02:00
|
|
|
match mutbl {
|
2016-02-09 17:44:47 +01:00
|
|
|
ast::Mutability::Mutable => self.word_nbsp("mut"),
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::Mutability::Immutable => {},
|
2013-01-30 17:20:02 -08:00
|
|
|
}
|
2011-03-04 07:22:43 +01:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_mt(&mut self, mt: &ast::MutTy) {
|
|
|
|
self.print_mutability(mt.mutbl);
|
2016-02-08 23:55:55 +01:00
|
|
|
self.print_type(&mt.ty)
|
2011-03-24 16:33:20 +01:00
|
|
|
}
|
2011-03-04 07:22:43 +01:00
|
|
|
|
2019-08-27 13:24:32 +02:00
|
|
|
crate fn print_param(&mut self, input: &ast::Param, is_closure: bool) {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.ibox(INDENT_UNIT);
|
2019-08-02 09:34:49 +02:00
|
|
|
|
|
|
|
self.print_outer_attributes_inline(&input.attrs);
|
|
|
|
|
2019-09-26 17:25:31 +01:00
|
|
|
match input.ty.kind {
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::TyKind::Infer if is_closure => self.print_pat(&input.pat),
|
2014-03-16 20:58:11 +02:00
|
|
|
_ => {
|
2016-05-08 21:18:21 +03:00
|
|
|
if let Some(eself) = input.to_self() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_explicit_self(&eself);
|
2016-05-08 21:18:21 +03:00
|
|
|
} else {
|
2019-09-26 16:18:31 +01:00
|
|
|
let invalid = if let PatKind::Ident(_, ident, _) = input.pat.kind {
|
2019-05-11 17:41:37 +03:00
|
|
|
ident.name == kw::Invalid
|
2016-03-06 15:54:44 +03:00
|
|
|
} else {
|
|
|
|
false
|
|
|
|
};
|
2016-05-08 21:18:21 +03:00
|
|
|
if !invalid {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_pat(&input.pat);
|
|
|
|
self.s.word(":");
|
|
|
|
self.s.space();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type(&input.ty);
|
2014-01-09 15:05:33 +02:00
|
|
|
}
|
2012-11-06 18:41:06 -08:00
|
|
|
}
|
2012-05-04 12:33:04 -07:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_fn_output(&mut self, decl: &ast::FnDecl) {
|
2016-02-08 15:04:11 +01:00
|
|
|
if let ast::FunctionRetTy::Default(..) = decl.output {
|
2019-06-24 14:15:11 -04:00
|
|
|
return;
|
2014-09-05 21:27:47 -07:00
|
|
|
}
|
2014-11-09 16:14:15 +01:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.space_if_not_bol();
|
|
|
|
self.ibox(INDENT_UNIT);
|
|
|
|
self.word_space("->");
|
2014-11-09 16:14:15 +01:00
|
|
|
match decl.output {
|
2016-02-08 15:04:11 +01:00
|
|
|
ast::FunctionRetTy::Default(..) => unreachable!(),
|
|
|
|
ast::FunctionRetTy::Ty(ref ty) =>
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_type(ty),
|
2014-11-09 16:14:15 +01:00
|
|
|
}
|
2019-06-24 14:15:11 -04:00
|
|
|
self.end();
|
2014-11-09 16:14:15 +01:00
|
|
|
|
|
|
|
match decl.output {
|
2017-07-31 23:04:34 +03:00
|
|
|
ast::FunctionRetTy::Ty(ref output) => self.maybe_print_comment(output.span.lo()),
|
2019-06-24 14:15:11 -04:00
|
|
|
_ => {}
|
2014-11-09 16:14:15 +01:00
|
|
|
}
|
2014-09-05 21:27:47 -07:00
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_ty_fn(&mut self,
|
2019-10-27 23:14:35 +01:00
|
|
|
abi: ast::Abi,
|
2014-12-09 10:36:46 -05:00
|
|
|
unsafety: ast::Unsafety,
|
2014-03-16 20:58:11 +02:00
|
|
|
decl: &ast::FnDecl,
|
2015-03-11 08:38:27 +02:00
|
|
|
name: Option<ast::Ident>,
|
2018-07-27 16:50:28 +02:00
|
|
|
generic_params: &[ast::GenericParam])
|
2019-06-24 14:15:11 -04:00
|
|
|
{
|
|
|
|
self.ibox(INDENT_UNIT);
|
2017-10-16 21:07:26 +02:00
|
|
|
if !generic_params.is_empty() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.word("for");
|
|
|
|
self.print_generic_params(generic_params);
|
2015-03-18 11:54:06 -07:00
|
|
|
}
|
|
|
|
let generics = ast::Generics {
|
2017-10-16 21:07:26 +02:00
|
|
|
params: Vec::new(),
|
2015-03-18 11:54:06 -07:00
|
|
|
where_clause: ast::WhereClause {
|
|
|
|
predicates: Vec::new(),
|
2017-07-27 13:37:35 +09:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2015-03-18 11:54:06 -07:00
|
|
|
},
|
2016-08-10 19:39:12 +02:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2015-03-18 11:54:06 -07:00
|
|
|
};
|
2016-12-29 13:57:01 -08:00
|
|
|
self.print_fn(decl,
|
2019-05-29 04:10:49 +03:00
|
|
|
ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
|
2016-03-22 17:58:45 -05:00
|
|
|
name,
|
|
|
|
&generics,
|
2019-06-24 14:15:11 -04:00
|
|
|
&source_map::dummy_spanned(ast::VisibilityKind::Inherited));
|
|
|
|
self.end();
|
2014-01-29 17:39:21 -08:00
|
|
|
}
|
2014-03-16 20:58:11 +02:00
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span,
|
2014-03-16 20:58:11 +02:00
|
|
|
next_pos: Option<BytePos>)
|
2019-07-05 18:29:15 -04:00
|
|
|
{
|
|
|
|
if let Some(cmnts) = self.comments() {
|
|
|
|
if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) {
|
|
|
|
self.print_comment(&cmnt);
|
2014-01-29 17:39:21 -08:00
|
|
|
}
|
2011-03-24 16:33:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_remaining_comments(&mut self) {
|
2014-03-16 20:58:11 +02: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() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.s.hardbreak();
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2017-05-12 20:05:39 +02:00
|
|
|
while let Some(ref cmnt) = self.next_comment() {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_comment(cmnt);
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2011-07-05 11:48:19 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 12:12:56 -04:00
|
|
|
crate fn print_fn_header_info(&mut self,
|
2019-05-29 04:10:49 +03:00
|
|
|
header: ast::FnHeader,
|
2019-06-24 14:15:11 -04:00
|
|
|
vis: &ast::Visibility) {
|
|
|
|
self.s.word(visibility_qualified(vis, ""));
|
2014-05-07 16:33:43 -07:00
|
|
|
|
2018-05-16 22:55:18 -07:00
|
|
|
match header.constness.node {
|
2015-02-25 22:05:07 +02:00
|
|
|
ast::Constness::NotConst => {}
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::Constness::Const => self.word_nbsp("const")
|
2015-02-25 22:05:07 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
self.print_asyncness(header.asyncness.node);
|
|
|
|
self.print_unsafety(header.unsafety);
|
2015-10-24 16:52:07 +08:00
|
|
|
|
2019-10-27 23:14:35 +01:00
|
|
|
if header.abi.symbol != sym::Rust {
|
2019-06-24 14:15:11 -04:00
|
|
|
self.word_nbsp("extern");
|
2019-10-27 23:14:35 +01:00
|
|
|
self.print_abi(header.abi);
|
2013-03-13 22:25:28 -04:00
|
|
|
}
|
|
|
|
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("fn")
|
2012-05-24 23:44:58 -07:00
|
|
|
}
|
|
|
|
|
2019-10-27 23:14:35 +01:00
|
|
|
fn print_abi(&mut self, abi: ast::Abi) {
|
|
|
|
self.word_nbsp(format!("\"{}\"", abi.symbol));
|
|
|
|
}
|
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_unsafety(&mut self, s: ast::Unsafety) {
|
2014-04-06 18:04:40 -07:00
|
|
|
match s {
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::Unsafety::Normal => {},
|
2014-12-09 10:36:46 -05:00
|
|
|
ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
|
2014-03-16 20:58:11 +02:00
|
|
|
}
|
2012-05-24 23:44:58 -07:00
|
|
|
}
|
2017-10-12 09:51:31 -03:00
|
|
|
|
2019-06-24 14:15:11 -04:00
|
|
|
crate fn print_is_auto(&mut self, s: ast::IsAuto) {
|
2017-10-12 09:51:31 -03:00
|
|
|
match s {
|
|
|
|
ast::IsAuto::Yes => self.word_nbsp("auto"),
|
2019-06-24 14:15:11 -04:00
|
|
|
ast::IsAuto::No => {}
|
2017-10-12 09:51:31 -03:00
|
|
|
}
|
|
|
|
}
|
2012-11-04 20:41:00 -08:00
|
|
|
}
|