2015-07-31 00:04:06 -07:00
|
|
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
pub use self::AnnNode::*;
|
|
|
|
|
2016-02-05 13:13:36 +01:00
|
|
|
use syntax::abi::Abi;
|
2015-07-31 00:04:06 -07:00
|
|
|
use syntax::ast;
|
2016-06-21 18:08:13 -04:00
|
|
|
use syntax::codemap::{CodeMap, Spanned};
|
2017-01-17 01:14:53 +00:00
|
|
|
use syntax::parse::ParseSess;
|
2015-07-31 00:04:06 -07:00
|
|
|
use syntax::parse::lexer::comments;
|
2017-06-24 21:22:42 -06:00
|
|
|
use syntax::print::pp::{self, Breaks};
|
2015-07-31 00:04:06 -07:00
|
|
|
use syntax::print::pp::Breaks::{Consistent, Inconsistent};
|
2017-06-25 06:38:13 -06:00
|
|
|
use syntax::print::pprust::PrintState;
|
2015-07-31 00:04:06 -07:00
|
|
|
use syntax::ptr::P;
|
2016-12-27 10:00:18 +02:00
|
|
|
use syntax::symbol::keywords;
|
2017-08-14 18:27:20 -04:00
|
|
|
use syntax::util::parser::{self, AssocOp, Fixity};
|
2016-06-21 18:08:13 -04:00
|
|
|
use syntax_pos::{self, BytePos};
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
use hir;
|
2017-01-10 22:13:53 +01:00
|
|
|
use hir::{PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier, RangeEnd};
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-01-09 17:46:11 +02:00
|
|
|
use std::cell::Cell;
|
2015-07-31 00:04:06 -07:00
|
|
|
use std::io::{self, Write, Read};
|
2017-06-25 06:38:13 -06:00
|
|
|
use std::iter::Peekable;
|
|
|
|
use std::vec;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
pub enum AnnNode<'a> {
|
|
|
|
NodeName(&'a ast::Name),
|
|
|
|
NodeBlock(&'a hir::Block),
|
|
|
|
NodeItem(&'a hir::Item),
|
|
|
|
NodeSubItem(ast::NodeId),
|
|
|
|
NodeExpr(&'a hir::Expr),
|
|
|
|
NodePat(&'a hir::Pat),
|
|
|
|
}
|
|
|
|
|
2016-12-27 10:00:18 +02:00
|
|
|
pub enum Nested {
|
|
|
|
Item(hir::ItemId),
|
|
|
|
TraitItem(hir::TraitItemId),
|
|
|
|
ImplItem(hir::ImplItemId),
|
|
|
|
Body(hir::BodyId),
|
|
|
|
BodyArgPat(hir::BodyId, usize)
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
pub trait PpAnn {
|
2016-12-27 10:00:18 +02:00
|
|
|
fn nested(&self, _state: &mut State, _nested: Nested) -> io::Result<()> {
|
|
|
|
Ok(())
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> {
|
|
|
|
Ok(())
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct NoAnn;
|
|
|
|
impl PpAnn for NoAnn {}
|
2016-12-27 10:00:18 +02:00
|
|
|
pub const NO_ANN: &'static PpAnn = &NoAnn;
|
|
|
|
|
|
|
|
impl PpAnn for hir::Crate {
|
|
|
|
fn nested(&self, state: &mut State, nested: Nested) -> io::Result<()> {
|
|
|
|
match nested {
|
|
|
|
Nested::Item(id) => state.print_item(self.item(id.id)),
|
|
|
|
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
|
|
|
|
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
|
|
|
|
Nested::Body(id) => state.print_expr(&self.body(id).value),
|
|
|
|
Nested::BodyArgPat(id, i) => state.print_pat(&self.body(id).arguments[i].pat)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
pub struct State<'a> {
|
|
|
|
pub s: pp::Printer<'a>,
|
|
|
|
cm: Option<&'a CodeMap>,
|
2015-09-14 21:58:20 +12:00
|
|
|
comments: Option<Vec<comments::Comment>>,
|
2017-06-25 06:38:13 -06:00
|
|
|
literals: Peekable<vec::IntoIter<comments::Literal>>,
|
|
|
|
cur_cmnt: usize,
|
2015-07-31 00:04:06 -07:00
|
|
|
boxes: Vec<pp::Breaks>,
|
2015-09-28 08:23:31 +13:00
|
|
|
ann: &'a (PpAnn + 'a),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2015-09-14 21:58:20 +12:00
|
|
|
impl<'a> PrintState<'a> for State<'a> {
|
|
|
|
fn writer(&mut self) -> &mut pp::Printer<'a> {
|
|
|
|
&mut self.s
|
|
|
|
}
|
|
|
|
|
|
|
|
fn boxes(&mut self) -> &mut Vec<pp::Breaks> {
|
|
|
|
&mut self.boxes
|
|
|
|
}
|
|
|
|
|
|
|
|
fn comments(&mut self) -> &mut Option<Vec<comments::Comment>> {
|
|
|
|
&mut self.comments
|
|
|
|
}
|
|
|
|
|
2017-06-25 06:38:13 -06:00
|
|
|
fn cur_cmnt(&mut self) -> &mut usize {
|
|
|
|
&mut self.cur_cmnt
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
|
2017-06-25 06:38:13 -06:00
|
|
|
fn cur_lit(&mut self) -> Option<&comments::Literal> {
|
|
|
|
self.literals.peek()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn bump_lit(&mut self) -> Option<comments::Literal> {
|
|
|
|
self.literals.next()
|
2015-09-14 21:58:20 +12:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
#[allow(non_upper_case_globals)]
|
|
|
|
pub const indent_unit: usize = 4;
|
|
|
|
|
|
|
|
#[allow(non_upper_case_globals)]
|
|
|
|
pub const default_columns: usize = 78;
|
|
|
|
|
|
|
|
|
|
|
|
/// Requires you to pass an input filename and reader so that
|
|
|
|
/// it can scan the input text for comments and literals to
|
|
|
|
/// copy forward.
|
|
|
|
pub fn print_crate<'a>(cm: &'a CodeMap,
|
2017-01-17 01:14:53 +00:00
|
|
|
sess: &ParseSess,
|
2015-07-31 00:04:06 -07:00
|
|
|
krate: &hir::Crate,
|
|
|
|
filename: String,
|
|
|
|
input: &mut Read,
|
2015-09-28 08:23:31 +13:00
|
|
|
out: Box<Write + 'a>,
|
2015-07-31 00:04:06 -07:00
|
|
|
ann: &'a PpAnn,
|
2015-09-28 08:23:31 +13:00
|
|
|
is_expanded: bool)
|
|
|
|
-> io::Result<()> {
|
2017-01-17 01:14:53 +00:00
|
|
|
let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
// When printing the AST, we sometimes need to inject `#[no_std]` here.
|
|
|
|
// Since you can't compile the HIR, it's not necessary.
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
s.print_mod(&krate.module, &krate.attrs)?;
|
|
|
|
s.print_remaining_comments()?;
|
2017-06-24 21:22:42 -06:00
|
|
|
s.s.eof()
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> State<'a> {
|
|
|
|
pub fn new_from_input(cm: &'a CodeMap,
|
2017-01-17 01:14:53 +00:00
|
|
|
sess: &ParseSess,
|
2015-07-31 00:04:06 -07:00
|
|
|
filename: String,
|
|
|
|
input: &mut Read,
|
2015-09-28 08:23:31 +13:00
|
|
|
out: Box<Write + 'a>,
|
2015-07-31 00:04:06 -07:00
|
|
|
ann: &'a PpAnn,
|
2016-12-27 10:00:18 +02:00
|
|
|
is_expanded: bool)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> State<'a> {
|
2017-01-17 01:14:53 +00:00
|
|
|
let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input);
|
2015-09-28 08:23:31 +13:00
|
|
|
|
|
|
|
State::new(cm,
|
|
|
|
out,
|
|
|
|
ann,
|
|
|
|
Some(cmnts),
|
|
|
|
// If the code is post expansion, don't use the table of
|
|
|
|
// literals, since it doesn't correspond with the literals
|
|
|
|
// in the AST anymore.
|
|
|
|
if is_expanded {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(lits)
|
2016-12-27 10:00:18 +02:00
|
|
|
})
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new(cm: &'a CodeMap,
|
2015-09-28 08:23:31 +13:00
|
|
|
out: Box<Write + 'a>,
|
2015-07-31 00:04:06 -07:00
|
|
|
ann: &'a PpAnn,
|
|
|
|
comments: Option<Vec<comments::Comment>>,
|
2016-12-27 10:00:18 +02:00
|
|
|
literals: Option<Vec<comments::Literal>>)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> State<'a> {
|
2015-07-31 00:04:06 -07:00
|
|
|
State {
|
|
|
|
s: pp::mk_printer(out, default_columns),
|
|
|
|
cm: Some(cm),
|
2015-09-14 21:58:20 +12:00
|
|
|
comments: comments.clone(),
|
2017-06-25 06:38:13 -06:00
|
|
|
literals: literals.unwrap_or_default().into_iter().peekable(),
|
|
|
|
cur_cmnt: 0,
|
2015-07-31 00:04:06 -07:00
|
|
|
boxes: Vec::new(),
|
2017-07-03 11:19:51 -07:00
|
|
|
ann,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-27 10:00:18 +02:00
|
|
|
pub fn to_string<F>(ann: &PpAnn, f: F) -> String
|
2015-09-28 08:23:31 +13:00
|
|
|
where F: FnOnce(&mut State) -> io::Result<()>
|
2015-07-31 00:04:06 -07:00
|
|
|
{
|
|
|
|
let mut wr = Vec::new();
|
|
|
|
{
|
2016-12-27 10:00:18 +02:00
|
|
|
let mut printer = State {
|
|
|
|
s: pp::mk_printer(Box::new(&mut wr), default_columns),
|
|
|
|
cm: None,
|
|
|
|
comments: None,
|
2017-06-25 06:38:13 -06:00
|
|
|
literals: vec![].into_iter().peekable(),
|
|
|
|
cur_cmnt: 0,
|
2016-12-27 10:00:18 +02:00
|
|
|
boxes: Vec::new(),
|
2017-07-03 11:19:51 -07:00
|
|
|
ann,
|
2016-12-27 10:00:18 +02:00
|
|
|
};
|
2015-07-31 00:04:06 -07:00
|
|
|
f(&mut printer).unwrap();
|
2017-06-24 21:22:42 -06:00
|
|
|
printer.s.eof().unwrap();
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
String::from_utf8(wr).unwrap()
|
|
|
|
}
|
|
|
|
|
2016-12-27 10:00:18 +02:00
|
|
|
pub fn visibility_qualified(vis: &hir::Visibility, w: &str) -> String {
|
|
|
|
to_string(NO_ANN, |s| {
|
|
|
|
s.print_visibility(vis)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
s.s.word(w)
|
2015-07-31 00:04:06 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> State<'a> {
|
|
|
|
pub fn cbox(&mut self, u: usize) -> io::Result<()> {
|
|
|
|
self.boxes.push(pp::Breaks::Consistent);
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.cbox(u)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn nbsp(&mut self) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(" ")
|
2015-09-28 08:23:31 +13:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(w)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.nbsp()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn head(&mut self, w: &str) -> io::Result<()> {
|
|
|
|
// outer-box is consistent
|
2016-03-22 22:01:37 -05:00
|
|
|
self.cbox(indent_unit)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
// head-box is inconsistent
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(w.len() + 1)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
// keyword that starts the head
|
|
|
|
if !w.is_empty() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_nbsp(w)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn bopen(&mut self) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("{")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end() // close the head-box
|
|
|
|
}
|
|
|
|
|
2016-06-21 18:08:13 -04:00
|
|
|
pub fn bclose_(&mut self, span: syntax_pos::Span, indented: usize) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
self.bclose_maybe_open(span, indented, true)
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn bclose_maybe_open(&mut self,
|
2016-06-21 18:08:13 -04:00
|
|
|
span: syntax_pos::Span,
|
2015-09-28 08:23:31 +13:00
|
|
|
indented: usize,
|
|
|
|
close_box: bool)
|
|
|
|
-> io::Result<()> {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(span.hi())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.break_offset_if_not_bol(1, -(indented as isize))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("}")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if close_box {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // close the outer-box
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2016-06-21 18:08:13 -04:00
|
|
|
pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
self.bclose_(span, indent_unit)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn in_cbox(&self) -> bool {
|
|
|
|
match self.boxes.last() {
|
|
|
|
Some(&last_box) => last_box == pp::Breaks::Consistent,
|
2015-09-28 08:23:31 +13:00
|
|
|
None => false,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn space_if_not_bol(&mut self) -> io::Result<()> {
|
2015-09-28 08:23:31 +13:00
|
|
|
if !self.is_bol() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-09-28 08:23:31 +13:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
Ok(())
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
if !self.is_bol() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.break_offset(n, off)
|
2015-07-31 00:04:06 -07:00
|
|
|
} else {
|
|
|
|
if off != 0 && self.s.last_token().is_hardbreak_tok() {
|
|
|
|
// We do something pretty sketchy here: tuck the nonzero
|
|
|
|
// offset-adjustment we were going to deposit along with the
|
|
|
|
// break into the previous hardbreak.
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.replace_last_token(pp::Printer::hardbreak_tok_offset(off));
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Synthesizes a comment that was not textually present in the original source
|
|
|
|
// file.
|
|
|
|
pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("/*")?;
|
|
|
|
self.s.space()?;
|
|
|
|
self.s.word(&text[..])?;
|
|
|
|
self.s.space()?;
|
|
|
|
self.s.word("*/")
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn commasep_cmnt<T, F, G>(&mut self,
|
|
|
|
b: Breaks,
|
|
|
|
elts: &[T],
|
|
|
|
mut op: F,
|
2015-09-28 08:23:31 +13:00
|
|
|
mut get_span: G)
|
|
|
|
-> io::Result<()>
|
|
|
|
where F: FnMut(&mut State, &T) -> io::Result<()>,
|
2016-06-21 18:08:13 -04:00
|
|
|
G: FnMut(&T) -> syntax_pos::Span
|
2015-07-31 00:04:06 -07:00
|
|
|
{
|
2016-03-22 22:01:37 -05:00
|
|
|
self.rbox(0, b)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
let len = elts.len();
|
|
|
|
let mut i = 0;
|
|
|
|
for elt in elts {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(get_span(elt).hi())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
op(self, elt)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
i += 1;
|
|
|
|
if i < len {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi()))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
2016-10-28 21:16:44 +11:00
|
|
|
pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) -> io::Result<()> {
|
2016-02-08 22:50:21 +01:00
|
|
|
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_inner_attributes(attrs)?;
|
2016-12-21 12:32:59 +02:00
|
|
|
for &item_id in &_mod.item_ids {
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Item(item_id))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_foreign_mod(&mut self,
|
|
|
|
nmod: &hir::ForeignMod,
|
|
|
|
attrs: &[ast::Attribute])
|
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_inner_attributes(attrs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
for item in &nmod.items {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_foreign_item(item)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2017-01-09 17:46:11 +02:00
|
|
|
pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
|
|
|
|
if !lifetime.is_elided() {
|
|
|
|
self.print_lifetime(lifetime)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.nbsp()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(ty.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(0)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match ty.node {
|
2016-09-20 02:14:46 +02:00
|
|
|
hir::TySlice(ref ty) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("[")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_type(&ty)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("]")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::TyPtr(ref mt) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("*")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match mt.mutbl {
|
2016-03-22 22:01:37 -05:00
|
|
|
hir::MutMutable => self.word_nbsp("mut")?,
|
|
|
|
hir::MutImmutable => self.word_nbsp("const")?,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_type(&mt.ty)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::TyRptr(ref lifetime, ref mt) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("&")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_opt_lifetime(lifetime)?;
|
|
|
|
self.print_mt(mt)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-08-02 15:56:20 +08:00
|
|
|
hir::TyNever => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("!")?;
|
2016-05-10 00:03:59 +08:00
|
|
|
},
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::TyTup(ref elts) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if elts.len() == 1 {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.pclose()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::TyBareFn(ref f) => {
|
|
|
|
let generics = hir::Generics {
|
|
|
|
lifetimes: f.lifetimes.clone(),
|
2015-12-19 04:20:11 +03:00
|
|
|
ty_params: hir::HirVec::new(),
|
2015-07-31 00:04:06 -07:00
|
|
|
where_clause: hir::WhereClause {
|
|
|
|
id: ast::DUMMY_NODE_ID,
|
2015-12-17 20:41:28 +03:00
|
|
|
predicates: hir::HirVec::new(),
|
2015-07-31 00:04:06 -07:00
|
|
|
},
|
2016-08-10 19:39:12 +02:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2015-07-31 00:04:06 -07:00
|
|
|
};
|
2017-09-27 00:43:37 +02:00
|
|
|
self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics,
|
|
|
|
&f.arg_names[..])?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
hir::TyPath(ref qpath) => {
|
|
|
|
self.print_qpath(qpath, false)?
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-01-24 17:17:06 +02:00
|
|
|
hir::TyTraitObject(ref bounds, ref lifetime) => {
|
|
|
|
let mut first = true;
|
|
|
|
for bound in bounds {
|
|
|
|
self.nbsp()?;
|
|
|
|
if first {
|
|
|
|
first = false;
|
|
|
|
} else {
|
|
|
|
self.word_space("+")?;
|
|
|
|
}
|
|
|
|
self.print_poly_trait_ref(bound)?;
|
|
|
|
}
|
|
|
|
if !lifetime.is_elided() {
|
|
|
|
self.word_space("+")?;
|
|
|
|
self.print_lifetime(lifetime)?;
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-08-01 04:25:32 +03:00
|
|
|
hir::TyImplTrait(ref bounds) => {
|
|
|
|
self.print_bounds("impl ", &bounds[..])?;
|
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::TyArray(ref ty, v) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("[")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_type(&ty)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("; ")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(v))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("]")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::TyTypeof(e) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("typeof(")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(e))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(")")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::TyInfer => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("_")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-03-28 18:56:29 -07:00
|
|
|
hir::TyErr => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("?")?;
|
2017-03-28 18:56:29 -07:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(item.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_outer_attributes(&item.attrs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match item.node {
|
2016-12-20 22:46:11 +02:00
|
|
|
hir::ForeignItemFn(ref decl, ref arg_names, ref generics) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("")?;
|
|
|
|
self.print_fn(decl,
|
2016-03-22 17:58:45 -05:00
|
|
|
hir::Unsafety::Normal,
|
|
|
|
hir::Constness::NotConst,
|
|
|
|
Abi::Rust,
|
|
|
|
Some(item.name),
|
|
|
|
generics,
|
2016-12-20 22:46:11 +02:00
|
|
|
&item.vis,
|
|
|
|
arg_names,
|
|
|
|
None)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end head-ibox
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end() // end the outer fn box
|
|
|
|
}
|
|
|
|
hir::ForeignItemStatic(ref t, m) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "static"))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if m {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("mut")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(item.name)?;
|
|
|
|
self.word_space(":")?;
|
|
|
|
self.print_type(&t)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end the head-ibox
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end() // end the outer cbox
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_associated_const(&mut self,
|
2015-09-20 04:50:30 +03:00
|
|
|
name: ast::Name,
|
2015-07-31 00:04:06 -07:00
|
|
|
ty: &hir::Ty,
|
2016-12-21 12:32:59 +02:00
|
|
|
default: Option<hir::BodyId>,
|
2016-03-25 06:08:11 +00:00
|
|
|
vis: &hir::Visibility)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(&visibility_qualified(vis, ""))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("const")?;
|
|
|
|
self.print_name(name)?;
|
|
|
|
self.word_space(":")?;
|
|
|
|
self.print_type(ty)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if let Some(expr) = default {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(expr))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_associated_type(&mut self,
|
2015-09-20 04:50:30 +03:00
|
|
|
name: ast::Name,
|
2015-07-31 00:04:06 -07:00
|
|
|
bounds: Option<&hir::TyParamBounds>,
|
|
|
|
ty: Option<&hir::Ty>)
|
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("type")?;
|
|
|
|
self.print_name(name)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if let Some(bounds) = bounds {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_bounds(":", bounds)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
if let Some(ty) = ty {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_type(ty)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Pretty-print an item
|
|
|
|
pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(item.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_outer_attributes(&item.attrs)?;
|
|
|
|
self.ann.pre(self, NodeItem(item))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match item.node {
|
|
|
|
hir::ItemExternCrate(ref optional_path) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "extern crate"))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if let Some(p) = *optional_path {
|
|
|
|
let val = p.as_str();
|
|
|
|
if val.contains("-") {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_string(&val, ast::StrStyle::Cooked)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
} else {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(p)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
|
|
|
self.s.word("as")?;
|
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(item.name)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end inner head-block
|
|
|
|
self.end()?; // end outer head-block
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-11-24 06:11:31 +02:00
|
|
|
hir::ItemUse(ref path, kind) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "use"))?;
|
2016-11-24 06:11:31 +02:00
|
|
|
self.print_path(path, false)?;
|
|
|
|
|
|
|
|
match kind {
|
|
|
|
hir::UseKind::Single => {
|
|
|
|
if path.segments.last().unwrap().name != item.name {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-11-24 06:11:31 +02:00
|
|
|
self.word_space("as")?;
|
|
|
|
self.print_name(item.name)?;
|
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2016-11-24 06:11:31 +02:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
hir::UseKind::Glob => self.s.word("::*;")?,
|
|
|
|
hir::UseKind::ListStem => self.s.word("::{};")?
|
2016-11-24 06:11:31 +02:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end inner head-block
|
|
|
|
self.end()?; // end outer head-block
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::ItemStatic(ref ty, m, expr) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "static"))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if m == hir::MutMutable {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("mut")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(item.name)?;
|
|
|
|
self.word_space(":")?;
|
|
|
|
self.print_type(&ty)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end the head-ibox
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(expr))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end the outer cbox
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::ItemConst(ref ty, expr) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "const"))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(item.name)?;
|
|
|
|
self.word_space(":")?;
|
|
|
|
self.print_type(&ty)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end the head-ibox
|
|
|
|
|
|
|
|
self.word_space("=")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(expr))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end the outer cbox
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, body) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("")?;
|
|
|
|
self.print_fn(decl,
|
2016-03-22 17:58:45 -05:00
|
|
|
unsafety,
|
|
|
|
constness,
|
|
|
|
abi,
|
|
|
|
Some(item.name),
|
|
|
|
typarams,
|
2016-12-20 22:46:11 +02:00
|
|
|
&item.vis,
|
|
|
|
&[],
|
|
|
|
Some(body))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(" ")?;
|
2016-10-26 02:27:14 +03:00
|
|
|
self.end()?; // need to close a box
|
|
|
|
self.end()?; // need to close a box
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(body))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ItemMod(ref _mod) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "mod"))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(item.name)?;
|
|
|
|
self.nbsp()?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.print_mod(_mod, &item.attrs)?;
|
|
|
|
self.bclose(item.span)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ItemForeignMod(ref nmod) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("extern")?;
|
|
|
|
self.word_nbsp(&nmod.abi.to_string())?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.print_foreign_mod(nmod, &item.attrs)?;
|
|
|
|
self.bclose(item.span)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-03-15 21:27:40 -05:00
|
|
|
hir::ItemGlobalAsm(ref ga) => {
|
|
|
|
self.head(&visibility_qualified(&item.vis, "global asm"))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(&ga.asm.as_str())?;
|
2017-03-15 21:27:40 -05:00
|
|
|
self.end()?
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::ItemTy(ref ty, ref params) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(indent_unit)?;
|
|
|
|
self.ibox(0)?;
|
2016-03-25 06:08:11 +00:00
|
|
|
self.word_nbsp(&visibility_qualified(&item.vis, "type"))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(item.name)?;
|
|
|
|
self.print_generics(params)?;
|
|
|
|
self.end()?; // end the inner ibox
|
|
|
|
|
|
|
|
self.print_where_clause(¶ms.where_clause)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_type(&ty)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // end the outer ibox
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ItemEnum(ref enum_definition, ref params) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.print_enum_def(enum_definition, params, item.name, item.span, &item.vis)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ItemStruct(ref struct_def, ref generics) => {
|
2016-03-25 06:08:11 +00:00
|
|
|
self.head(&visibility_qualified(&item.vis, "struct"))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_struct(struct_def, generics, item.name, item.span, true)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-08-06 21:36:28 +03:00
|
|
|
hir::ItemUnion(ref struct_def, ref generics) => {
|
|
|
|
self.head(&visibility_qualified(&item.vis, "union"))?;
|
|
|
|
self.print_struct(struct_def, generics, item.name, item.span, true)?;
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::ItemDefaultImpl(unsafety, ref trait_ref) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("")?;
|
2016-03-25 06:08:11 +00:00
|
|
|
self.print_visibility(&item.vis)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_unsafety(unsafety)?;
|
|
|
|
self.word_nbsp("impl")?;
|
|
|
|
self.print_trait_ref(trait_ref)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("for")?;
|
|
|
|
self.word_space("..")?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.bclose(item.span)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ItemImpl(unsafety,
|
|
|
|
polarity,
|
2016-11-18 17:14:42 +01:00
|
|
|
defaultness,
|
2015-07-31 00:04:06 -07:00
|
|
|
ref generics,
|
|
|
|
ref opt_trait,
|
|
|
|
ref ty,
|
|
|
|
ref impl_items) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("")?;
|
2016-03-25 06:08:11 +00:00
|
|
|
self.print_visibility(&item.vis)?;
|
2016-11-18 17:14:42 +01:00
|
|
|
self.print_defaultness(defaultness)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_unsafety(unsafety)?;
|
|
|
|
self.word_nbsp("impl")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
if generics.is_parameterized() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_generics(generics)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
match polarity {
|
|
|
|
hir::ImplPolarity::Negative => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("!")?;
|
2015-09-28 08:23:31 +13:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
match opt_trait {
|
|
|
|
&Some(ref t) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_trait_ref(t)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("for")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
&None => {}
|
|
|
|
}
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_type(&ty)?;
|
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bopen()?;
|
|
|
|
self.print_inner_attributes(&item.attrs)?;
|
2016-11-10 09:47:00 -05:00
|
|
|
for impl_item in impl_items {
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::ImplItem(impl_item.id))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bclose(item.span)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("")?;
|
2016-03-25 06:08:11 +00:00
|
|
|
self.print_visibility(&item.vis)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_unsafety(unsafety)?;
|
|
|
|
self.word_nbsp("trait")?;
|
|
|
|
self.print_name(item.name)?;
|
|
|
|
self.print_generics(generics)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
|
|
|
for b in bounds.iter() {
|
|
|
|
if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("for ?")?;
|
|
|
|
self.print_trait_ref(&ptr.trait_ref)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
} else {
|
|
|
|
real_bounds.push(b.clone());
|
|
|
|
}
|
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_bounds(":", &real_bounds[..])?;
|
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(" ")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bopen()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
for trait_item in trait_items {
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::TraitItem(trait_item.id))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bclose(item.span)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.ann.post(self, NodeItem(item))
|
|
|
|
}
|
|
|
|
|
2016-10-30 08:04:52 +02:00
|
|
|
pub fn print_trait_ref(&mut self, t: &hir::TraitRef) -> io::Result<()> {
|
2016-10-27 05:17:42 +03:00
|
|
|
self.print_path(&t.path, false)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_formal_lifetime_list(&mut self, lifetimes: &[hir::LifetimeDef]) -> io::Result<()> {
|
|
|
|
if !lifetimes.is_empty() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("for<")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
let mut comma = false;
|
|
|
|
for lifetime_def in lifetimes {
|
|
|
|
if comma {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(",")?
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_lifetime_def(lifetime_def)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
comma = true;
|
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(">")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_formal_lifetime_list(&t.bound_lifetimes)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_trait_ref(&t.trait_ref)
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_enum_def(&mut self,
|
|
|
|
enum_definition: &hir::EnumDef,
|
|
|
|
generics: &hir::Generics,
|
|
|
|
name: ast::Name,
|
2016-06-21 18:08:13 -04:00
|
|
|
span: syntax_pos::Span,
|
2016-03-25 06:08:11 +00:00
|
|
|
visibility: &hir::Visibility)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head(&visibility_qualified(visibility, "enum"))?;
|
|
|
|
self.print_name(name)?;
|
|
|
|
self.print_generics(generics)?;
|
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_variants(&enum_definition.variants, span)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_variants(&mut self,
|
2015-12-07 17:17:41 +03:00
|
|
|
variants: &[hir::Variant],
|
2016-06-21 18:08:13 -04:00
|
|
|
span: syntax_pos::Span)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bopen()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
for v in variants {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(v.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_outer_attributes(&v.node.attrs)?;
|
|
|
|
self.ibox(indent_unit)?;
|
|
|
|
self.print_variant(v)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?;
|
|
|
|
self.maybe_print_trailing_comment(v.span, None)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
self.bclose(span)
|
|
|
|
}
|
|
|
|
|
2016-03-25 06:08:11 +00:00
|
|
|
pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
|
|
|
|
match *vis {
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::Public => self.word_nbsp("pub"),
|
2016-04-02 20:24:02 +00:00
|
|
|
hir::Visibility::Crate => self.word_nbsp("pub(crate)"),
|
2016-12-27 10:00:18 +02:00
|
|
|
hir::Visibility::Restricted { ref path, .. } => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("pub(")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.print_path(path, false)?;
|
|
|
|
self.word_nbsp(")")
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
hir::Inherited => Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-18 17:14:42 +01:00
|
|
|
pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {
|
2016-11-21 18:39:25 +00:00
|
|
|
match defaultness {
|
|
|
|
hir::Defaultness::Default { .. } => self.word_nbsp("default")?,
|
|
|
|
hir::Defaultness::Final => (),
|
2016-11-18 17:14:42 +01:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
pub fn print_struct(&mut self,
|
2015-10-08 03:20:57 +03:00
|
|
|
struct_def: &hir::VariantData,
|
2015-07-31 00:04:06 -07:00
|
|
|
generics: &hir::Generics,
|
2015-09-20 04:50:30 +03:00
|
|
|
name: ast::Name,
|
2016-06-21 18:08:13 -04:00
|
|
|
span: syntax_pos::Span,
|
2015-10-02 00:03:22 +03:00
|
|
|
print_finalizer: bool)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(name)?;
|
|
|
|
self.print_generics(generics)?;
|
2015-10-08 23:45:46 +03:00
|
|
|
if !struct_def.is_struct() {
|
|
|
|
if struct_def.is_tuple() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep(Inconsistent, struct_def.fields(), |s, field| {
|
2017-07-31 23:04:34 +03:00
|
|
|
s.maybe_print_comment(field.span.lo())?;
|
2016-06-17 10:05:19 +01:00
|
|
|
s.print_outer_attributes(&field.attrs)?;
|
|
|
|
s.print_visibility(&field.vis)?;
|
2016-02-27 11:34:29 +03:00
|
|
|
s.print_type(&field.ty)
|
2016-03-22 22:01:37 -05:00
|
|
|
})?;
|
|
|
|
self.pclose()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
2015-10-02 00:03:22 +03:00
|
|
|
if print_finalizer {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2015-10-02 00:03:22 +03:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end() // close the outer-box
|
|
|
|
} else {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_where_clause(&generics.where_clause)?;
|
|
|
|
self.nbsp()?;
|
|
|
|
self.bopen()?;
|
|
|
|
self.hardbreak_if_not_bol()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2015-10-08 23:45:46 +03:00
|
|
|
for field in struct_def.fields() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(field.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_outer_attributes(&field.attrs)?;
|
2016-03-25 06:08:11 +00:00
|
|
|
self.print_visibility(&field.vis)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(field.name)?;
|
|
|
|
self.word_nbsp(":")?;
|
|
|
|
self.print_type(&field.ty)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
self.bclose(span)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("")?;
|
2016-03-29 09:32:58 +03:00
|
|
|
let generics = hir::Generics::empty();
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?;
|
2016-12-21 12:32:59 +02:00
|
|
|
if let Some(d) = v.node.disr_expr {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-12-21 12:32:59 +02:00
|
|
|
self.word_space("=")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(d))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
Ok(())
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
pub fn print_method_sig(&mut self,
|
2015-09-20 04:50:30 +03:00
|
|
|
name: ast::Name,
|
2015-07-31 00:04:06 -07:00
|
|
|
m: &hir::MethodSig,
|
2017-09-25 17:24:20 -04:00
|
|
|
generics: &hir::Generics,
|
2016-12-20 22:46:11 +02:00
|
|
|
vis: &hir::Visibility,
|
|
|
|
arg_names: &[Spanned<ast::Name>],
|
|
|
|
body_id: Option<hir::BodyId>)
|
2015-07-31 00:04:06 -07:00
|
|
|
-> io::Result<()> {
|
|
|
|
self.print_fn(&m.decl,
|
|
|
|
m.unsafety,
|
|
|
|
m.constness,
|
|
|
|
m.abi,
|
2015-09-20 04:50:30 +03:00
|
|
|
Some(name),
|
2017-09-25 17:24:20 -04:00
|
|
|
generics,
|
2016-12-20 22:46:11 +02:00
|
|
|
vis,
|
|
|
|
arg_names,
|
|
|
|
body_id)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ann.pre(self, NodeSubItem(ti.id))?;
|
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(ti.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_outer_attributes(&ti.attrs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match ti.node {
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::TraitItemKind::Const(ref ty, default) => {
|
|
|
|
self.print_associated_const(ti.name, &ty, default, &hir::Inherited)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-20 22:46:11 +02:00
|
|
|
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref arg_names)) => {
|
2017-09-25 18:36:28 -04:00
|
|
|
self.print_method_sig(ti.name, sig, &ti.generics, &hir::Inherited, arg_names,
|
|
|
|
None)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2016-12-20 22:46:11 +02:00
|
|
|
}
|
|
|
|
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
|
|
|
|
self.head("")?;
|
2017-09-25 18:36:28 -04:00
|
|
|
self.print_method_sig(ti.name, sig, &ti.generics, &hir::Inherited, &[],
|
|
|
|
Some(body))?;
|
2016-12-20 22:46:11 +02:00
|
|
|
self.nbsp()?;
|
|
|
|
self.end()?; // need to close a box
|
|
|
|
self.end()?; // need to close a box
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(body))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-04 04:21:06 +02:00
|
|
|
hir::TraitItemKind::Type(ref bounds, ref default) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_associated_type(ti.name,
|
2016-03-22 17:58:45 -05:00
|
|
|
Some(bounds),
|
|
|
|
default.as_ref().map(|ty| &**ty))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.ann.post(self, NodeSubItem(ti.id))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ann.pre(self, NodeSubItem(ii.id))?;
|
|
|
|
self.hardbreak_if_not_bol()?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(ii.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_outer_attributes(&ii.attrs)?;
|
2016-11-18 17:14:42 +01:00
|
|
|
self.print_defaultness(ii.defaultness)?;
|
2016-03-13 22:55:26 -07:00
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
match ii.node {
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::ImplItemKind::Const(ref ty, expr) => {
|
|
|
|
self.print_associated_const(ii.name, &ty, Some(expr), &ii.vis)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::ImplItemKind::Method(ref sig, body) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("")?;
|
2017-09-25 17:24:20 -04:00
|
|
|
self.print_method_sig(ii.name, sig, &ii.generics, &ii.vis, &[], Some(body))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.nbsp()?;
|
2016-10-26 02:27:14 +03:00
|
|
|
self.end()?; // need to close a box
|
|
|
|
self.end()?; // need to close a box
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(body))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2015-11-12 15:57:51 +01:00
|
|
|
hir::ImplItemKind::Type(ref ty) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_associated_type(ii.name, None, Some(ty))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.ann.post(self, NodeSubItem(ii.id))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(st.span.lo())?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match st.node {
|
|
|
|
hir::StmtDecl(ref decl, _) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_decl(&decl)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::StmtExpr(ref expr, _) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.print_expr(&expr)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::StmtSemi(ref expr, _) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.print_expr(&expr)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if stmt_ends_with_semi(&st.node) {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(";")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
self.maybe_print_trailing_comment(st.span, None)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_block(&mut self, blk: &hir::Block) -> io::Result<()> {
|
|
|
|
self.print_block_with_attrs(blk, &[])
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_block_unclosed(&mut self, blk: &hir::Block) -> io::Result<()> {
|
|
|
|
self.print_block_unclosed_indent(blk, indent_unit)
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_block_unclosed_indent(&mut self,
|
|
|
|
blk: &hir::Block,
|
|
|
|
indented: usize)
|
|
|
|
-> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_block_maybe_unclosed(blk, indented, &[], false)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_block_with_attrs(&mut self,
|
|
|
|
blk: &hir::Block,
|
2015-09-28 08:23:31 +13:00
|
|
|
attrs: &[ast::Attribute])
|
|
|
|
-> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_block_maybe_unclosed(&mut self,
|
|
|
|
blk: &hir::Block,
|
|
|
|
indented: usize,
|
2015-09-14 21:58:20 +12:00
|
|
|
attrs: &[ast::Attribute],
|
2015-09-28 08:23:31 +13:00
|
|
|
close_box: bool)
|
|
|
|
-> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
match blk.rules {
|
2016-03-22 22:01:37 -05:00
|
|
|
hir::UnsafeBlock(..) => self.word_space("unsafe")?,
|
|
|
|
hir::PushUnsafeBlock(..) => self.word_space("push_unsafe")?,
|
|
|
|
hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe")?,
|
2015-09-29 13:46:01 +13:00
|
|
|
hir::DefaultBlock => (),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(blk.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ann.pre(self, NodeBlock(blk))?;
|
|
|
|
self.bopen()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_inner_attributes(attrs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
for st in &blk.stmts {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_stmt(st)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
match blk.expr {
|
|
|
|
Some(ref expr) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.print_expr(&expr)?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
_ => (),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bclose_maybe_open(blk.span, indented, close_box)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.ann.post(self, NodeBlock(blk))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> {
|
|
|
|
match els {
|
|
|
|
Some(_else) => {
|
|
|
|
match _else.node {
|
|
|
|
// "another else-if"
|
|
|
|
hir::ExprIf(ref i, ref then, ref e) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.cbox(indent_unit - 1)?;
|
|
|
|
self.ibox(0)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(" else if ")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_as_cond(&i)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2017-03-09 09:53:00 -05:00
|
|
|
self.print_expr(&then)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_else(e.as_ref().map(|e| &**e))
|
|
|
|
}
|
|
|
|
// "final else"
|
|
|
|
hir::ExprBlock(ref b) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.cbox(indent_unit - 1)?;
|
|
|
|
self.ibox(0)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(" else ")?;
|
2016-02-08 22:50:21 +01:00
|
|
|
self.print_block(&b)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
// BLEAH, constraints would be great here
|
|
|
|
_ => {
|
|
|
|
panic!("print_if saw if with weird alternative");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
_ => Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_if(&mut self,
|
|
|
|
test: &hir::Expr,
|
2017-03-09 09:53:00 -05:00
|
|
|
blk: &hir::Expr,
|
2015-09-28 08:23:31 +13:00
|
|
|
elseopt: Option<&hir::Expr>)
|
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("if")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_as_cond(test)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2017-03-09 09:53:00 -05:00
|
|
|
self.print_expr(blk)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_else(elseopt)
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_if_let(&mut self,
|
|
|
|
pat: &hir::Pat,
|
|
|
|
expr: &hir::Expr,
|
|
|
|
blk: &hir::Block,
|
|
|
|
elseopt: Option<&hir::Expr>)
|
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("if let")?;
|
|
|
|
self.print_pat(pat)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_as_cond(expr)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_block(blk)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_else(elseopt)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-28 21:16:44 +11:00
|
|
|
fn print_call_post(&mut self, args: &[hir::Expr]) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
|
|
|
self.commasep_exprs(Inconsistent, args)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
|
2017-08-14 18:27:20 -04:00
|
|
|
pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) -> io::Result<()> {
|
|
|
|
let needs_par = expr_precedence(expr) < prec;
|
|
|
|
if needs_par {
|
|
|
|
self.popen()?;
|
|
|
|
}
|
|
|
|
self.print_expr(expr)?;
|
|
|
|
if needs_par {
|
|
|
|
self.pclose()?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
|
|
|
|
/// `if cond { ... }`.
|
|
|
|
pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) -> io::Result<()> {
|
|
|
|
let needs_par = match expr.node {
|
|
|
|
// These cases need parens due to the parse error observed in #26461: `if return {}`
|
|
|
|
// parses as the erroneous construct `if (return {})`, not `if (return) {}`.
|
|
|
|
hir::ExprClosure(..) |
|
|
|
|
hir::ExprRet(..) |
|
|
|
|
hir::ExprBreak(..) => true,
|
|
|
|
|
|
|
|
_ => contains_exterior_struct_lit(expr),
|
|
|
|
};
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
if needs_par {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr(expr)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if needs_par {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.pclose()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2016-10-28 21:16:44 +11:00
|
|
|
fn print_expr_vec(&mut self, exprs: &[hir::Expr]) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(indent_unit)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("[")?;
|
2016-10-28 21:16:44 +11:00
|
|
|
self.commasep_exprs(Inconsistent, exprs)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("]")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
2016-12-21 12:32:59 +02:00
|
|
|
fn print_expr_repeat(&mut self, element: &hir::Expr, count: hir::BodyId) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(indent_unit)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("[")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr(element)?;
|
|
|
|
self.word_space(";")?;
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(count))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("]")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_struct(&mut self,
|
2016-10-27 05:17:42 +03:00
|
|
|
qpath: &hir::QPath,
|
2015-07-31 00:04:06 -07:00
|
|
|
fields: &[hir::Field],
|
2015-09-28 08:23:31 +13:00
|
|
|
wth: &Option<P<hir::Expr>>)
|
|
|
|
-> io::Result<()> {
|
2016-10-27 05:17:42 +03:00
|
|
|
self.print_qpath(qpath, true)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("{")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.commasep_cmnt(Consistent,
|
2016-03-22 17:58:45 -05:00
|
|
|
&fields[..],
|
|
|
|
|s, field| {
|
|
|
|
s.ibox(indent_unit)?;
|
2016-10-27 03:15:13 +03:00
|
|
|
if !field.is_shorthand {
|
|
|
|
s.print_name(field.name.node)?;
|
|
|
|
s.word_space(":")?;
|
|
|
|
}
|
2016-03-22 17:58:45 -05:00
|
|
|
s.print_expr(&field.expr)?;
|
|
|
|
s.end()
|
|
|
|
},
|
|
|
|
|f| f.span)?;
|
2015-09-10 22:46:52 +03:00
|
|
|
match *wth {
|
|
|
|
Some(ref expr) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(indent_unit)?;
|
2015-09-10 22:46:52 +03:00
|
|
|
if !fields.is_empty() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("..")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr(&expr)?;
|
|
|
|
self.end()?;
|
2015-09-10 22:46:52 +03:00
|
|
|
}
|
|
|
|
_ => if !fields.is_empty() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?
|
2015-09-28 08:23:31 +13:00
|
|
|
},
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("}")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2016-10-28 21:16:44 +11:00
|
|
|
fn print_expr_tup(&mut self, exprs: &[hir::Expr]) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
2016-10-28 21:16:44 +11:00
|
|
|
self.commasep_exprs(Inconsistent, exprs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if exprs.len() == 1 {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
|
2016-10-28 21:16:44 +11:00
|
|
|
fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) -> io::Result<()> {
|
2017-08-14 18:27:20 -04:00
|
|
|
let prec =
|
|
|
|
match func.node {
|
|
|
|
hir::ExprField(..) |
|
|
|
|
hir::ExprTupField(..) => parser::PREC_FORCE_PAREN,
|
|
|
|
_ => parser::PREC_POSTFIX,
|
|
|
|
};
|
|
|
|
|
|
|
|
self.print_expr_maybe_paren(func, prec)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_call_post(args)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_method_call(&mut self,
|
2017-07-07 15:57:51 +03:00
|
|
|
segment: &hir::PathSegment,
|
2016-10-28 21:16:44 +11:00
|
|
|
args: &[hir::Expr])
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
let base_args = &args[1..];
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(".")?;
|
2017-07-07 15:57:51 +03:00
|
|
|
self.print_name(segment.name)?;
|
2017-09-21 23:24:26 +03:00
|
|
|
|
|
|
|
segment.with_parameters(|parameters| {
|
|
|
|
if !parameters.lifetimes.is_empty() ||
|
|
|
|
!parameters.types.is_empty() ||
|
|
|
|
!parameters.bindings.is_empty()
|
|
|
|
{
|
|
|
|
self.print_path_parameters(¶meters, segment.infer_types, true)
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
})?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_call_post(base_args)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_binary(&mut self,
|
|
|
|
op: hir::BinOp,
|
|
|
|
lhs: &hir::Expr,
|
2015-09-28 08:23:31 +13:00
|
|
|
rhs: &hir::Expr)
|
|
|
|
-> io::Result<()> {
|
2017-08-14 18:27:20 -04:00
|
|
|
let assoc_op = bin_op_to_assoc_op(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),
|
|
|
|
};
|
|
|
|
|
|
|
|
self.print_expr_maybe_paren(lhs, left_prec)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-29 09:32:58 +03:00
|
|
|
self.word_space(op.node.as_str())?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(rhs, right_prec)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(op.as_str())?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_expr_addr_of(&mut self,
|
|
|
|
mutability: hir::Mutability,
|
2015-09-28 08:23:31 +13:00
|
|
|
expr: &hir::Expr)
|
|
|
|
-> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("&")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_mutability(mutability)?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(expr.span.lo())?;
|
2017-01-03 20:24:53 +01:00
|
|
|
self.print_outer_attributes(&expr.attrs)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(indent_unit)?;
|
|
|
|
self.ann.pre(self, NodeExpr(expr))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match expr.node {
|
2015-09-24 18:00:08 +03:00
|
|
|
hir::ExprBox(ref expr) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("box")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-09-20 02:14:46 +02:00
|
|
|
hir::ExprArray(ref exprs) => {
|
2016-10-28 21:16:44 +11:00
|
|
|
self.print_expr_vec(exprs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::ExprRepeat(ref element, count) => {
|
|
|
|
self.print_expr_repeat(&element, count)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
hir::ExprStruct(ref qpath, ref fields, ref wth) => {
|
|
|
|
self.print_expr_struct(qpath, &fields[..], wth)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprTup(ref exprs) => {
|
2016-10-28 21:16:44 +11:00
|
|
|
self.print_expr_tup(exprs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprCall(ref func, ref args) => {
|
2016-10-28 21:16:44 +11:00
|
|
|
self.print_expr_call(&func, args)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-07-07 15:57:51 +03:00
|
|
|
hir::ExprMethodCall(ref segment, _, ref args) => {
|
|
|
|
self.print_expr_method_call(segment, args)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprBinary(op, ref lhs, ref rhs) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr_binary(op, &lhs, &rhs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprUnary(op, ref expr) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr_unary(op, &expr)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprAddrOf(m, ref expr) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr_addr_of(m, &expr)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprLit(ref lit) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_literal(&lit)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprCast(ref expr, ref ty) => {
|
2017-08-14 18:27:20 -04:00
|
|
|
let prec = AssocOp::As.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(&expr, prec)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("as")?;
|
|
|
|
self.print_type(&ty)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2015-12-03 05:37:48 +03:00
|
|
|
hir::ExprType(ref expr, ref ty) => {
|
2017-08-14 18:27:20 -04:00
|
|
|
let prec = AssocOp::Colon.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(&expr, prec)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
|
|
|
self.print_type(&ty)?;
|
2015-12-03 05:37:48 +03:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::ExprIf(ref test, ref blk, ref elseopt) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-05-02 18:22:03 +02:00
|
|
|
hir::ExprWhile(ref test, ref blk, opt_sp_name) => {
|
|
|
|
if let Some(sp_name) = opt_sp_name {
|
|
|
|
self.print_name(sp_name.node)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("while")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_as_cond(&test)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_block(&blk)?;
|
2015-07-31 00:04:06 -07: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
|
|
|
hir::ExprLoop(ref blk, opt_sp_name, _) => {
|
2016-05-02 18:22:03 +02:00
|
|
|
if let Some(sp_name) = opt_sp_name {
|
|
|
|
self.print_name(sp_name.node)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.head("loop")?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_block(&blk)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprMatch(ref expr, ref arms, _) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.cbox(indent_unit)?;
|
|
|
|
self.ibox(4)?;
|
|
|
|
self.word_nbsp("match")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_as_cond(&expr)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bopen()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
for arm in arms {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_arm(arm)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.bclose_(expr.span, indent_unit)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-07-10 20:06:39 +02:00
|
|
|
hir::ExprClosure(capture_clause, ref decl, body, _fn_decl_span, _gen) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_capture_clause(capture_clause)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-12-20 22:46:11 +02:00
|
|
|
self.print_closure_args(&decl, body)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-10-26 02:27:14 +03:00
|
|
|
// this is a bare expression
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Body(body))?;
|
2016-10-26 02:27:14 +03:00
|
|
|
self.end()?; // need to close a box
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
// a box will be closed by print_expr, but we didn't want an overall
|
|
|
|
// wrapper so we closed the corresponding opening. so create an
|
|
|
|
// empty box to satisfy the close.
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(0)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprBlock(ref blk) => {
|
|
|
|
// containing cbox, will be closed by print-block at }
|
2016-03-22 22:01:37 -05:00
|
|
|
self.cbox(indent_unit)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
// head-box, will be closed by print-block after {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(0)?;
|
|
|
|
self.print_block(&blk)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprAssign(ref lhs, ref rhs) => {
|
2017-08-14 18:27:20 -04:00
|
|
|
let prec = AssocOp::Assign.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(&lhs, prec + 1)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(&rhs, prec)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprAssignOp(op, ref lhs, ref rhs) => {
|
2017-08-14 18:27:20 -04:00
|
|
|
let prec = AssocOp::Assign.precedence() as i8;
|
|
|
|
self.print_expr_maybe_paren(&lhs, prec + 1)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
|
|
|
self.s.word(op.node.as_str())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(&rhs, prec)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2015-09-20 14:00:18 +03:00
|
|
|
hir::ExprField(ref expr, name) => {
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(".")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(name.node)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprTupField(ref expr, id) => {
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(".")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_usize(id.node)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::ExprIndex(ref expr, ref index) => {
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("[")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr(&index)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("]")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
hir::ExprPath(ref qpath) => {
|
|
|
|
self.print_qpath(qpath, true)?
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-02-15 14:52:27 -08:00
|
|
|
hir::ExprBreak(label, ref opt_expr) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("break")?;
|
|
|
|
self.s.space()?;
|
2017-02-15 14:52:27 -08:00
|
|
|
if let Some(label_ident) = label.ident {
|
|
|
|
self.print_name(label_ident.node.name)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07: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 {
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 15:15:06 -07:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-02-15 14:52:27 -08:00
|
|
|
hir::ExprAgain(label) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("continue")?;
|
|
|
|
self.s.space()?;
|
2017-02-15 14:52:27 -08:00
|
|
|
if let Some(label_ident) = label.ident {
|
|
|
|
self.print_name(label_ident.node.name)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
hir::ExprRet(ref result) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("return")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match *result {
|
|
|
|
Some(ref expr) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(" ")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
_ => (),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
2016-03-09 22:17:02 +02:00
|
|
|
hir::ExprInlineAsm(ref a, ref outputs, ref inputs) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("asm!")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
2016-11-16 10:52:37 +00:00
|
|
|
self.print_string(&a.asm.as_str(), a.asm_str_style)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-03-09 22:17:02 +02:00
|
|
|
let mut out_idx = 0;
|
2016-03-22 22:01:37 -05: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 => {
|
|
|
|
s.print_string(&format!("+{}", ch.as_str()),
|
|
|
|
ast::StrStyle::Cooked)?
|
2015-11-05 21:17:59 +00:00
|
|
|
}
|
2016-11-16 10:52:37 +00:00
|
|
|
_ => s.print_string(&constraint, ast::StrStyle::Cooked)?,
|
2015-11-05 21:17:59 +00:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
s.popen()?;
|
|
|
|
s.print_expr(&outputs[out_idx])?;
|
|
|
|
s.pclose()?;
|
2016-03-09 22:17:02 +02:00
|
|
|
out_idx += 1;
|
2015-11-05 21:17:59 +00:00
|
|
|
Ok(())
|
2016-03-22 22:01:37 -05:00
|
|
|
})?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-03-09 22:17:02 +02:00
|
|
|
let mut in_idx = 0;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.commasep(Inconsistent, &a.inputs, |s, co| {
|
2016-11-16 10:52:37 +00:00
|
|
|
s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
s.popen()?;
|
|
|
|
s.print_expr(&inputs[in_idx])?;
|
|
|
|
s.pclose()?;
|
2016-03-09 22:17:02 +02:00
|
|
|
in_idx += 1;
|
2015-11-05 21:17:59 +00:00
|
|
|
Ok(())
|
2016-03-22 22:01:37 -05:00
|
|
|
})?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.commasep(Inconsistent, &a.clobbers, |s, co| {
|
2016-11-16 10:52:37 +00:00
|
|
|
s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
|
2015-11-05 21:17:59 +00:00
|
|
|
Ok(())
|
2016-03-22 22:01:37 -05:00
|
|
|
})?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2015-11-05 21:17:59 +00:00
|
|
|
let mut options = vec![];
|
2015-07-31 00:04:06 -07: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 {
|
2015-07-31 00:04:06 -07:00
|
|
|
options.push("intel");
|
|
|
|
}
|
|
|
|
|
|
|
|
if !options.is_empty() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
|
|
|
self.commasep(Inconsistent, &options, |s, &co| {
|
|
|
|
s.print_string(co, ast::StrStyle::Cooked)?;
|
2015-11-05 21:17:59 +00:00
|
|
|
Ok(())
|
2016-03-22 22:01:37 -05:00
|
|
|
})?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.pclose()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-07-10 21:11:31 +02:00
|
|
|
hir::ExprYield(ref expr) => {
|
2017-09-03 12:42:28 +02:00
|
|
|
self.word_space("yield")?;
|
2017-08-14 18:27:20 -04:00
|
|
|
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
|
2016-12-26 14:34:03 +01:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ann.post(self, NodeExpr(expr))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_local_decl(&mut self, loc: &hir::Local) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_pat(&loc.pat)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if let Some(ref ty) = loc.ty {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(":")?;
|
|
|
|
self.print_type(&ty)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_decl(&mut self, decl: &hir::Decl) -> io::Result<()> {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(decl.span.lo())?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match decl.node {
|
|
|
|
hir::DeclLocal(ref loc) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.ibox(indent_unit)?;
|
|
|
|
self.word_nbsp("let")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(indent_unit)?;
|
|
|
|
self.print_local_decl(&loc)?;
|
|
|
|
self.end()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if let Some(ref init) = loc.init {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.nbsp()?;
|
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_expr(&init)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::DeclItem(item) => {
|
2016-12-27 10:00:18 +02:00
|
|
|
self.ann.nested(self, Nested::Item(item))
|
2015-11-17 17:32:12 -05:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(&i.to_string())
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(&name.as_str())?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.ann.post(self, NodeName(&name))
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_local_decl(loc)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("in")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_expr(coll)
|
|
|
|
}
|
|
|
|
|
2016-12-27 10:00:18 +02:00
|
|
|
pub fn print_path(&mut self,
|
|
|
|
path: &hir::Path,
|
|
|
|
colons_before_params: bool)
|
|
|
|
-> io::Result<()> {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(path.span.lo())?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-12-05 03:51:11 +00:00
|
|
|
for (i, segment) in path.segments.iter().enumerate() {
|
|
|
|
if i > 0 {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("::")?
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-25 20:34:49 +03:00
|
|
|
if segment.name != keywords::CrateRoot.name() &&
|
|
|
|
segment.name != keywords::DollarCrate.name() {
|
2017-09-21 23:24:26 +03:00
|
|
|
self.print_name(segment.name)?;
|
|
|
|
segment.with_parameters(|parameters| {
|
|
|
|
self.print_path_parameters(parameters,
|
|
|
|
segment.infer_types,
|
|
|
|
colons_before_params)
|
|
|
|
})?;
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2016-12-27 10:00:18 +02:00
|
|
|
pub fn print_qpath(&mut self,
|
|
|
|
qpath: &hir::QPath,
|
|
|
|
colons_before_params: bool)
|
|
|
|
-> io::Result<()> {
|
2016-10-27 05:17:42 +03:00
|
|
|
match *qpath {
|
|
|
|
hir::QPath::Resolved(None, ref path) => {
|
|
|
|
self.print_path(path, colons_before_params)
|
|
|
|
}
|
|
|
|
hir::QPath::Resolved(Some(ref qself), ref path) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("<")?;
|
2016-10-27 05:17:42 +03:00
|
|
|
self.print_type(qself)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-10-27 05:17:42 +03:00
|
|
|
self.word_space("as")?;
|
|
|
|
|
2016-12-05 03:51:11 +00:00
|
|
|
for (i, segment) in path.segments[..path.segments.len() - 1].iter().enumerate() {
|
|
|
|
if i > 0 {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("::")?
|
2016-10-27 05:17:42 +03:00
|
|
|
}
|
2017-06-25 20:34:49 +03:00
|
|
|
if segment.name != keywords::CrateRoot.name() &&
|
|
|
|
segment.name != keywords::DollarCrate.name() {
|
2016-12-05 03:51:11 +00:00
|
|
|
self.print_name(segment.name)?;
|
2017-09-21 23:24:26 +03:00
|
|
|
segment.with_parameters(|parameters| {
|
|
|
|
self.print_path_parameters(parameters,
|
|
|
|
segment.infer_types,
|
|
|
|
colons_before_params)
|
|
|
|
})?;
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
}
|
|
|
|
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(">")?;
|
|
|
|
self.s.word("::")?;
|
2016-10-27 05:17:42 +03:00
|
|
|
let item_segment = path.segments.last().unwrap();
|
|
|
|
self.print_name(item_segment.name)?;
|
2017-09-21 23:24:26 +03:00
|
|
|
item_segment.with_parameters(|parameters| {
|
|
|
|
self.print_path_parameters(parameters,
|
|
|
|
item_segment.infer_types,
|
|
|
|
colons_before_params)
|
|
|
|
})
|
2016-10-27 05:17:42 +03:00
|
|
|
}
|
|
|
|
hir::QPath::TypeRelative(ref qself, ref item_segment) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("<")?;
|
2016-10-27 05:17:42 +03:00
|
|
|
self.print_type(qself)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(">")?;
|
|
|
|
self.s.word("::")?;
|
2016-10-27 05:17:42 +03:00
|
|
|
self.print_name(item_segment.name)?;
|
2017-09-21 23:24:26 +03:00
|
|
|
item_segment.with_parameters(|parameters| {
|
|
|
|
self.print_path_parameters(parameters,
|
|
|
|
item_segment.infer_types,
|
|
|
|
colons_before_params)
|
|
|
|
})
|
2016-10-27 05:17:42 +03:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_path_parameters(&mut self,
|
|
|
|
parameters: &hir::PathParameters,
|
2017-09-21 23:24:26 +03:00
|
|
|
infer_types: bool,
|
2015-07-31 00:04:06 -07:00
|
|
|
colons_before_params: bool)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2017-07-29 01:13:40 +03:00
|
|
|
if parameters.parenthesized {
|
|
|
|
self.s.word("(")?;
|
|
|
|
self.commasep(Inconsistent, parameters.inputs(), |s, ty| s.print_type(&ty))?;
|
|
|
|
self.s.word(")")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-07-29 01:13:40 +03:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.word_space("->")?;
|
|
|
|
self.print_type(¶meters.bindings[0].ty)?;
|
|
|
|
} else {
|
|
|
|
let start = if colons_before_params { "::<" } else { "<" };
|
|
|
|
let empty = Cell::new(true);
|
|
|
|
let start_or_comma = |this: &mut Self| {
|
|
|
|
if empty.get() {
|
|
|
|
empty.set(false);
|
|
|
|
this.s.word(start)
|
|
|
|
} else {
|
|
|
|
this.word_space(",")
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-07-29 01:13:40 +03:00
|
|
|
};
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-07-29 01:13:40 +03:00
|
|
|
if !parameters.lifetimes.iter().all(|lt| lt.is_elided()) {
|
|
|
|
for lifetime in ¶meters.lifetimes {
|
2017-01-09 17:46:11 +02:00
|
|
|
start_or_comma(self)?;
|
2017-07-29 01:13:40 +03:00
|
|
|
self.print_lifetime(lifetime)?;
|
2016-10-17 06:02:23 +03:00
|
|
|
}
|
2017-07-29 01:13:40 +03:00
|
|
|
}
|
2016-10-17 06:02:23 +03:00
|
|
|
|
2017-07-29 01:13:40 +03:00
|
|
|
if !parameters.types.is_empty() {
|
|
|
|
start_or_comma(self)?;
|
|
|
|
self.commasep(Inconsistent, ¶meters.types, |s, ty| s.print_type(&ty))?;
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-07-29 01:13:40 +03:00
|
|
|
// FIXME(eddyb) This would leak into error messages, e.g.:
|
|
|
|
// "non-exhaustive patterns: `Some::<..>(_)` not covered".
|
2017-09-21 23:24:26 +03:00
|
|
|
if infer_types && false {
|
2017-07-29 01:13:40 +03:00
|
|
|
start_or_comma(self)?;
|
|
|
|
self.s.word("..")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2017-07-29 01:13:40 +03:00
|
|
|
for binding in parameters.bindings.iter() {
|
|
|
|
start_or_comma(self)?;
|
|
|
|
self.print_name(binding.name)?;
|
|
|
|
self.s.space()?;
|
|
|
|
self.word_space("=")?;
|
|
|
|
self.print_type(&binding.ty)?;
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-07-29 01:13:40 +03:00
|
|
|
if !empty.get() {
|
|
|
|
self.s.word(">")?
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(pat.span.lo())?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ann.pre(self, NodePat(pat))?;
|
2015-11-05 21:17:59 +00:00
|
|
|
// Pat isn't normalized, but the beauty of it
|
|
|
|
// is that it doesn't matter
|
2015-07-31 00:04:06 -07:00
|
|
|
match pat.node {
|
2017-06-24 21:22:42 -06:00
|
|
|
PatKind::Wild => self.s.word("_")?,
|
2016-11-25 13:21:19 +02:00
|
|
|
PatKind::Binding(binding_mode, _, ref path1, ref sub) => {
|
2015-07-31 00:04:06 -07:00
|
|
|
match binding_mode {
|
2017-07-21 19:29:43 -04:00
|
|
|
hir::BindingAnnotation::Ref => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_nbsp("ref")?;
|
2017-07-21 19:29:43 -04:00
|
|
|
self.print_mutability(hir::MutImmutable)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-07-21 19:29:43 -04:00
|
|
|
hir::BindingAnnotation::RefMut => {
|
|
|
|
self.word_nbsp("ref")?;
|
|
|
|
self.print_mutability(hir::MutMutable)?;
|
|
|
|
}
|
|
|
|
hir::BindingAnnotation::Unannotated => {}
|
|
|
|
hir::BindingAnnotation::Mutable => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_nbsp("mut")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
self.print_name(path1.node)?;
|
2016-06-13 22:43:30 -07:00
|
|
|
if let Some(ref p) = *sub {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("@")?;
|
2016-06-13 22:43:30 -07:00
|
|
|
self.print_pat(&p)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
PatKind::TupleStruct(ref qpath, ref elts, ddpos) => {
|
|
|
|
self.print_qpath(qpath, true)?;
|
2016-03-06 15:54:44 +03:00
|
|
|
self.popen()?;
|
|
|
|
if let Some(ddpos) = ddpos {
|
|
|
|
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?;
|
|
|
|
if ddpos != 0 {
|
|
|
|
self.word_space(",")?;
|
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("..")?;
|
2016-03-06 15:54:44 +03:00
|
|
|
if ddpos != elts.len() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2016-03-06 15:54:44 +03:00
|
|
|
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
} else {
|
2016-08-27 06:50:17 -07:00
|
|
|
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-08-27 06:50:17 -07:00
|
|
|
self.pclose()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
PatKind::Path(ref qpath) => {
|
|
|
|
self.print_qpath(qpath, true)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
PatKind::Struct(ref qpath, ref fields, etc) => {
|
|
|
|
self.print_qpath(qpath, true)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.nbsp()?;
|
|
|
|
self.word_space("{")?;
|
|
|
|
self.commasep_cmnt(Consistent,
|
2016-03-22 17:58:45 -05:00
|
|
|
&fields[..],
|
|
|
|
|s, f| {
|
|
|
|
s.cbox(indent_unit)?;
|
|
|
|
if !f.node.is_shorthand {
|
|
|
|
s.print_name(f.node.name)?;
|
|
|
|
s.word_nbsp(":")?;
|
|
|
|
}
|
|
|
|
s.print_pat(&f.node.pat)?;
|
|
|
|
s.end()
|
|
|
|
},
|
|
|
|
|f| f.node.pat.span)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if etc {
|
2015-09-28 08:23:31 +13:00
|
|
|
if !fields.is_empty() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(",")?;
|
2015-09-28 08:23:31 +13:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("..")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
|
|
|
self.s.word("}")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
PatKind::Tuple(ref elts, ddpos) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
2016-03-06 15:54:44 +03:00
|
|
|
if let Some(ddpos) = ddpos {
|
|
|
|
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?;
|
|
|
|
if ddpos != 0 {
|
|
|
|
self.word_space(",")?;
|
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("..")?;
|
2016-03-06 15:54:44 +03:00
|
|
|
if ddpos != elts.len() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2016-03-06 15:54:44 +03:00
|
|
|
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?;
|
|
|
|
if elts.len() == 1 {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2016-03-06 15:54:44 +03:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.pclose()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-02-14 15:25:12 +03:00
|
|
|
PatKind::Box(ref inner) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("box ")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_pat(&inner)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-02-14 15:25:12 +03:00
|
|
|
PatKind::Ref(ref inner, mutbl) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("&")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if mutbl == hir::MutMutable {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("mut ")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_pat(&inner)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
PatKind::Lit(ref e) => self.print_expr(&e)?,
|
2017-01-10 22:13:53 +01:00
|
|
|
PatKind::Range(ref begin, ref end, ref end_kind) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr(&begin)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2017-01-10 22:13:53 +01:00
|
|
|
match *end_kind {
|
2017-06-24 21:22:42 -06:00
|
|
|
RangeEnd::Included => self.s.word("...")?,
|
|
|
|
RangeEnd::Excluded => self.s.word("..")?,
|
2017-01-10 22:13:53 +01:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_expr(&end)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-09-20 02:14:46 +02:00
|
|
|
PatKind::Slice(ref before, ref slice, ref after) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("[")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p))?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if let Some(ref p) = *slice {
|
2015-09-28 08:23:31 +13:00
|
|
|
if !before.is_empty() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(",")?;
|
2015-09-28 08:23:31 +13:00
|
|
|
}
|
2016-02-14 15:25:12 +03:00
|
|
|
if p.node != PatKind::Wild {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_pat(&p)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("..")?;
|
2015-09-28 08:23:31 +13:00
|
|
|
if !after.is_empty() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(",")?;
|
2015-09-28 08:23:31 +13:00
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("]")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.ann.post(self, NodePat(pat))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
|
|
|
|
// I have no idea why this check is necessary, but here it
|
|
|
|
// is :(
|
|
|
|
if arm.attrs.is_empty() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.cbox(indent_unit)?;
|
|
|
|
self.ibox(0)?;
|
|
|
|
self.print_outer_attributes(&arm.attrs)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
let mut first = true;
|
|
|
|
for p in &arm.pats {
|
|
|
|
if first {
|
|
|
|
first = false;
|
|
|
|
} else {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("|")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_pat(&p)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if let Some(ref e) = arm.guard {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("if")?;
|
|
|
|
self.print_expr(&e)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=>")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
match arm.body.node {
|
|
|
|
hir::ExprBlock(ref blk) => {
|
|
|
|
// the block will close the pattern's ibox
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_block_unclosed_indent(&blk, indent_unit)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
// If it is a user-provided unsafe block, print a comma after it
|
|
|
|
if let hir::UnsafeBlock(hir::UserProvided) = blk.rules {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?; // close the ibox for the pattern
|
|
|
|
self.print_expr(&arm.body)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(",")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.end() // close enclosing cbox
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_fn(&mut self,
|
|
|
|
decl: &hir::FnDecl,
|
|
|
|
unsafety: hir::Unsafety,
|
|
|
|
constness: hir::Constness,
|
2016-02-05 13:13:36 +01:00
|
|
|
abi: Abi,
|
2015-09-20 04:50:30 +03:00
|
|
|
name: Option<ast::Name>,
|
2015-07-31 00:04:06 -07:00
|
|
|
generics: &hir::Generics,
|
2016-12-20 22:46:11 +02:00
|
|
|
vis: &hir::Visibility,
|
|
|
|
arg_names: &[Spanned<ast::Name>],
|
|
|
|
body_id: Option<hir::BodyId>)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_fn_header_info(unsafety, constness, abi, vis)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
if let Some(name) = name {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.nbsp()?;
|
|
|
|
self.print_name(name)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_generics(generics)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.popen()?;
|
2016-12-20 22:46:11 +02:00
|
|
|
let mut i = 0;
|
|
|
|
// Make sure we aren't supplied *both* `arg_names` and `body_id`.
|
|
|
|
assert!(arg_names.is_empty() || body_id.is_none());
|
|
|
|
self.commasep(Inconsistent, &decl.inputs, |s, ty| {
|
|
|
|
s.ibox(indent_unit)?;
|
|
|
|
if let Some(name) = arg_names.get(i) {
|
2017-06-24 21:22:42 -06:00
|
|
|
s.s.word(&name.node.as_str())?;
|
|
|
|
s.s.word(":")?;
|
|
|
|
s.s.space()?;
|
2016-12-27 10:00:18 +02:00
|
|
|
} else if let Some(body_id) = body_id {
|
|
|
|
s.ann.nested(s, Nested::BodyArgPat(body_id, i))?;
|
2017-06-24 21:22:42 -06:00
|
|
|
s.s.word(":")?;
|
|
|
|
s.s.space()?;
|
2016-12-20 22:46:11 +02:00
|
|
|
}
|
|
|
|
i += 1;
|
|
|
|
s.print_type(ty)?;
|
|
|
|
s.end()
|
|
|
|
})?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if decl.variadic {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(", ...")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.pclose()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2016-12-20 22:46:11 +02:00
|
|
|
self.print_fn_output(decl)?;
|
|
|
|
self.print_where_clause(&generics.where_clause)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2016-12-20 22:46:11 +02:00
|
|
|
fn print_closure_args(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) -> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("|")?;
|
2016-12-20 22:46:11 +02:00
|
|
|
let mut i = 0;
|
|
|
|
self.commasep(Inconsistent, &decl.inputs, |s, ty| {
|
|
|
|
s.ibox(indent_unit)?;
|
|
|
|
|
2016-12-27 10:00:18 +02:00
|
|
|
s.ann.nested(s, Nested::BodyArgPat(body_id, i))?;
|
2016-12-20 22:46:11 +02:00
|
|
|
i += 1;
|
|
|
|
|
|
|
|
if ty.node != hir::TyInfer {
|
2017-06-24 21:22:42 -06:00
|
|
|
s.s.word(":")?;
|
|
|
|
s.s.space()?;
|
2016-12-20 22:46:11 +02:00
|
|
|
s.print_type(ty)?;
|
|
|
|
}
|
|
|
|
s.end()
|
|
|
|
})?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("|")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
if let hir::DefaultReturn(..) = decl.output {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.word_space("->")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match decl.output {
|
|
|
|
hir::Return(ref ty) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_type(&ty)?;
|
2017-07-31 23:04:34 +03:00
|
|
|
self.maybe_print_comment(ty.span.lo())
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
hir::DefaultReturn(..) => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
match capture_clause {
|
|
|
|
hir::CaptureByValue => self.word_space("move"),
|
|
|
|
hir::CaptureByRef => Ok(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
if !bounds.is_empty() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(prefix)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
let mut first = true;
|
|
|
|
for bound in bounds {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.nbsp()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if first {
|
|
|
|
first = false;
|
|
|
|
} else {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("+")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
match *bound {
|
2015-07-31 00:04:06 -07:00
|
|
|
TraitTyParamBound(ref tref, TraitBoundModifier::None) => {
|
|
|
|
self.print_poly_trait_ref(tref)
|
|
|
|
}
|
|
|
|
TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("?")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.print_poly_trait_ref(tref)
|
|
|
|
}
|
|
|
|
RegionTyParamBound(ref lt) => {
|
|
|
|
self.print_lifetime(lt)
|
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
}?
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
|
2017-09-19 16:36:54 -07:00
|
|
|
self.print_name(lifetime.name.name())
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_lifetime(&lifetime.lifetime)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
let mut sep = ":";
|
|
|
|
for v in &lifetime.bounds {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(sep)?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_lifetime(v)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
sep = "+";
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_generics(&mut self, generics: &hir::Generics) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
let total = generics.lifetimes.len() + generics.ty_params.len();
|
|
|
|
if total == 0 {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("<")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
let mut ints = Vec::new();
|
|
|
|
for i in 0..total {
|
|
|
|
ints.push(i);
|
|
|
|
}
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.commasep(Inconsistent, &ints[..], |s, &idx| {
|
2015-11-05 21:17:59 +00:00
|
|
|
if idx < generics.lifetimes.len() {
|
|
|
|
let lifetime = &generics.lifetimes[idx];
|
|
|
|
s.print_lifetime_def(lifetime)
|
|
|
|
} else {
|
|
|
|
let idx = idx - generics.lifetimes.len();
|
|
|
|
let param = &generics.ty_params[idx];
|
|
|
|
s.print_ty_param(param)
|
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
})?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(">")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_ty_param(&mut self, param: &hir::TyParam) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_name(param.name)?;
|
|
|
|
self.print_bounds(":", ¶m.bounds)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match param.default {
|
|
|
|
Some(ref default) => {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
2016-02-08 22:50:21 +01:00
|
|
|
self.print_type(&default)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
_ => Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
if where_clause.predicates.is_empty() {
|
2015-11-05 21:17:59 +00:00
|
|
|
return Ok(());
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("where")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
for (i, predicate) in where_clause.predicates.iter().enumerate() {
|
|
|
|
if i != 0 {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space(",")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
match predicate {
|
|
|
|
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bound_lifetimes,
|
|
|
|
ref bounded_ty,
|
|
|
|
ref bounds,
|
|
|
|
..}) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_formal_lifetime_list(bound_lifetimes)?;
|
|
|
|
self.print_type(&bounded_ty)?;
|
|
|
|
self.print_bounds(":", bounds)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
&hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
|
|
|
|
ref bounds,
|
|
|
|
..}) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_lifetime(lifetime)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(":")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
for (i, bound) in bounds.iter().enumerate() {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_lifetime(bound)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
if i != 0 {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(":")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-16 21:32:13 +03:00
|
|
|
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref lhs_ty,
|
|
|
|
ref rhs_ty,
|
|
|
|
..}) => {
|
|
|
|
self.print_type(lhs_ty)?;
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.space()?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_space("=")?;
|
2017-01-16 21:32:13 +03:00
|
|
|
self.print_type(rhs_ty)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn print_mutability(&mut self, mutbl: hir::Mutability) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
match mutbl {
|
|
|
|
hir::MutMutable => self.word_nbsp("mut"),
|
|
|
|
hir::MutImmutable => Ok(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_mt(&mut self, mt: &hir::MutTy) -> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_mutability(mt.mutbl)?;
|
2016-02-08 22:50:21 +01:00
|
|
|
self.print_type(&mt.ty)
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_fn_output(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
|
|
|
|
if let hir::DefaultReturn(..) = decl.output {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.space_if_not_bol()?;
|
|
|
|
self.ibox(indent_unit)?;
|
|
|
|
self.word_space("->")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
match decl.output {
|
|
|
|
hir::DefaultReturn(..) => unreachable!(),
|
2016-03-22 22:01:37 -05:00
|
|
|
hir::Return(ref ty) => self.print_type(&ty)?,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
self.end()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
match decl.output {
|
2017-07-31 23:04:34 +03:00
|
|
|
hir::Return(ref output) => self.maybe_print_comment(output.span.lo()),
|
2015-09-28 08:23:31 +13:00
|
|
|
_ => Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_ty_fn(&mut self,
|
2016-02-05 13:13:36 +01:00
|
|
|
abi: Abi,
|
2015-07-31 00:04:06 -07:00
|
|
|
unsafety: hir::Unsafety,
|
|
|
|
decl: &hir::FnDecl,
|
2015-09-23 20:04:49 +03:00
|
|
|
name: Option<ast::Name>,
|
2017-09-27 00:43:37 +02:00
|
|
|
generics: &hir::Generics,
|
|
|
|
arg_names: &[Spanned<ast::Name>])
|
2015-07-31 00:04:06 -07:00
|
|
|
-> io::Result<()> {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.ibox(indent_unit)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("for")?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_generics(generics)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
let generics = hir::Generics {
|
2015-12-17 20:41:28 +03:00
|
|
|
lifetimes: hir::HirVec::new(),
|
2015-12-19 04:20:11 +03:00
|
|
|
ty_params: hir::HirVec::new(),
|
2015-07-31 00:04:06 -07:00
|
|
|
where_clause: hir::WhereClause {
|
|
|
|
id: ast::DUMMY_NODE_ID,
|
2015-12-17 20:41:28 +03:00
|
|
|
predicates: hir::HirVec::new(),
|
2015-07-31 00:04:06 -07:00
|
|
|
},
|
2016-08-10 19:39:12 +02:00
|
|
|
span: syntax_pos::DUMMY_SP,
|
2015-07-31 00:04:06 -07:00
|
|
|
};
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_fn(decl,
|
2016-03-22 17:58:45 -05:00
|
|
|
unsafety,
|
|
|
|
hir::Constness::NotConst,
|
|
|
|
abi,
|
|
|
|
name,
|
|
|
|
&generics,
|
2016-12-20 22:46:11 +02:00
|
|
|
&hir::Inherited,
|
2017-09-27 00:43:37 +02:00
|
|
|
arg_names,
|
2016-12-20 22:46:11 +02:00
|
|
|
None)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
2015-09-28 08:23:31 +13:00
|
|
|
pub fn maybe_print_trailing_comment(&mut self,
|
2016-06-21 18:08:13 -04:00
|
|
|
span: syntax_pos::Span,
|
2015-07-31 00:04:06 -07:00
|
|
|
next_pos: Option<BytePos>)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
let cm = match self.cm {
|
|
|
|
Some(cm) => cm,
|
2015-09-28 08:23:31 +13:00
|
|
|
_ => return Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
};
|
2016-06-13 22:43:30 -07:00
|
|
|
if let Some(ref cmnt) = self.next_comment() {
|
|
|
|
if (*cmnt).style != comments::Trailing {
|
|
|
|
return Ok(());
|
|
|
|
}
|
2017-07-31 23:04:34 +03:00
|
|
|
let span_line = cm.lookup_char_pos(span.hi());
|
2016-06-13 22:43:30 -07:00
|
|
|
let comment_line = cm.lookup_char_pos((*cmnt).pos);
|
|
|
|
let mut next = (*cmnt).pos + BytePos(1);
|
|
|
|
if let Some(p) = next_pos {
|
|
|
|
next = p;
|
|
|
|
}
|
2017-07-31 23:04:34 +03:00
|
|
|
if span.hi() < (*cmnt).pos && (*cmnt).pos < next &&
|
2016-06-13 22:43:30 -07:00
|
|
|
span_line.line == comment_line.line {
|
|
|
|
self.print_comment(cmnt)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_remaining_comments(&mut self) -> io::Result<()> {
|
|
|
|
// If there aren't any remaining comments, then we need to manually
|
|
|
|
// make sure there is a line break at the end.
|
|
|
|
if self.next_comment().is_none() {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.hardbreak()?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
loop {
|
|
|
|
match self.next_comment() {
|
|
|
|
Some(ref cmnt) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_comment(cmnt)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
_ => break,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
|
2016-02-05 13:13:36 +01:00
|
|
|
opt_abi: Option<Abi>)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
match opt_abi {
|
2016-02-05 13:13:36 +01:00
|
|
|
Some(Abi::Rust) => Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
Some(abi) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_nbsp("extern")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.word_nbsp(&abi.to_string())
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
None => Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-05 13:13:36 +01:00
|
|
|
pub fn print_extern_opt_abi(&mut self, opt_abi: Option<Abi>) -> io::Result<()> {
|
2015-07-31 00:04:06 -07:00
|
|
|
match opt_abi {
|
|
|
|
Some(abi) => {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_nbsp("extern")?;
|
2015-07-31 00:04:06 -07:00
|
|
|
self.word_nbsp(&abi.to_string())
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
None => Ok(()),
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_fn_header_info(&mut self,
|
|
|
|
unsafety: hir::Unsafety,
|
|
|
|
constness: hir::Constness,
|
2016-02-05 13:13:36 +01:00
|
|
|
abi: Abi,
|
2016-03-25 06:08:11 +00:00
|
|
|
vis: &hir::Visibility)
|
2015-09-28 08:23:31 +13:00
|
|
|
-> io::Result<()> {
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word(&visibility_qualified(vis, ""))?;
|
2016-03-22 22:01:37 -05:00
|
|
|
self.print_unsafety(unsafety)?;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
|
|
|
match constness {
|
|
|
|
hir::Constness::NotConst => {}
|
2016-03-22 22:01:37 -05:00
|
|
|
hir::Constness::Const => self.word_nbsp("const")?,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2016-02-05 13:13:36 +01:00
|
|
|
if abi != Abi::Rust {
|
2016-03-22 22:01:37 -05:00
|
|
|
self.word_nbsp("extern")?;
|
|
|
|
self.word_nbsp(&abi.to_string())?;
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
2017-06-24 21:22:42 -06:00
|
|
|
self.s.word("fn")
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_unsafety(&mut self, s: hir::Unsafety) -> io::Result<()> {
|
|
|
|
match s {
|
|
|
|
hir::Unsafety::Normal => Ok(()),
|
|
|
|
hir::Unsafety::Unsafe => self.word_nbsp("unsafe"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dup'ed from parse::classify, but adapted for the HIR.
|
|
|
|
/// Does this expression require a semicolon to be treated
|
|
|
|
/// as a statement? The negation of this: 'can this expression
|
|
|
|
/// be used as a statement without a semicolon' -- is used
|
|
|
|
/// as an early-bail-out in the parser so that, for instance,
|
|
|
|
/// if true {...} else {...}
|
|
|
|
/// |x| 5
|
|
|
|
/// isn't parsed as (if true {...} else {...} | x) | 5
|
|
|
|
fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
|
|
|
|
match e.node {
|
2015-09-28 08:23:31 +13:00
|
|
|
hir::ExprIf(..) |
|
|
|
|
hir::ExprMatch(..) |
|
|
|
|
hir::ExprBlock(_) |
|
|
|
|
hir::ExprWhile(..) |
|
|
|
|
hir::ExprLoop(..) => false,
|
|
|
|
_ => true,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// this statement requires a semicolon after it.
|
|
|
|
/// note that in one case (stmt_semi), we've already
|
|
|
|
/// seen the semicolon, and thus don't need another.
|
|
|
|
fn stmt_ends_with_semi(stmt: &hir::Stmt_) -> bool {
|
|
|
|
match *stmt {
|
|
|
|
hir::StmtDecl(ref d, _) => {
|
|
|
|
match d.node {
|
|
|
|
hir::DeclLocal(_) => true,
|
2015-09-28 08:23:31 +13:00
|
|
|
hir::DeclItem(_) => false,
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
2015-09-28 08:23:31 +13:00
|
|
|
hir::StmtExpr(ref e, _) => {
|
2016-02-08 22:50:21 +01:00
|
|
|
expr_requires_semi_to_be_stmt(&e)
|
2015-09-28 08:23:31 +13:00
|
|
|
}
|
|
|
|
hir::StmtSemi(..) => {
|
|
|
|
false
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
}
|
|
|
|
}
|
2017-08-14 18:27:20 -04:00
|
|
|
|
|
|
|
|
|
|
|
fn expr_precedence(expr: &hir::Expr) -> i8 {
|
|
|
|
use syntax::util::parser::*;
|
|
|
|
|
|
|
|
match expr.node {
|
|
|
|
hir::ExprClosure(..) => PREC_CLOSURE,
|
|
|
|
|
|
|
|
hir::ExprBreak(..) |
|
|
|
|
hir::ExprAgain(..) |
|
|
|
|
hir::ExprRet(..) |
|
|
|
|
hir::ExprYield(..) => PREC_JUMP,
|
|
|
|
|
|
|
|
// Binop-like expr kinds, handled by `AssocOp`.
|
|
|
|
hir::ExprBinary(op, _, _) => bin_op_to_assoc_op(op.node).precedence() as i8,
|
|
|
|
|
|
|
|
hir::ExprCast(..) => AssocOp::As.precedence() as i8,
|
|
|
|
hir::ExprType(..) => AssocOp::Colon.precedence() as i8,
|
|
|
|
|
|
|
|
hir::ExprAssign(..) |
|
|
|
|
hir::ExprAssignOp(..) => AssocOp::Assign.precedence() as i8,
|
|
|
|
|
|
|
|
// Unary, prefix
|
|
|
|
hir::ExprBox(..) |
|
|
|
|
hir::ExprAddrOf(..) |
|
|
|
|
hir::ExprUnary(..) => PREC_PREFIX,
|
|
|
|
|
|
|
|
// Unary, postfix
|
|
|
|
hir::ExprCall(..) |
|
|
|
|
hir::ExprMethodCall(..) |
|
|
|
|
hir::ExprField(..) |
|
|
|
|
hir::ExprTupField(..) |
|
|
|
|
hir::ExprIndex(..) |
|
|
|
|
hir::ExprInlineAsm(..) => PREC_POSTFIX,
|
|
|
|
|
|
|
|
// Never need parens
|
|
|
|
hir::ExprArray(..) |
|
|
|
|
hir::ExprRepeat(..) |
|
|
|
|
hir::ExprTup(..) |
|
|
|
|
hir::ExprLit(..) |
|
|
|
|
hir::ExprPath(..) |
|
2017-09-07 10:28:31 -04:00
|
|
|
hir::ExprIf(..) |
|
|
|
|
hir::ExprWhile(..) |
|
|
|
|
hir::ExprLoop(..) |
|
|
|
|
hir::ExprMatch(..) |
|
|
|
|
hir::ExprBlock(..) |
|
2017-08-14 18:27:20 -04:00
|
|
|
hir::ExprStruct(..) => PREC_PAREN,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn bin_op_to_assoc_op(op: hir::BinOp_) -> AssocOp {
|
|
|
|
use hir::BinOp_::*;
|
|
|
|
match op {
|
|
|
|
BiAdd => AssocOp::Add,
|
|
|
|
BiSub => AssocOp::Subtract,
|
|
|
|
BiMul => AssocOp::Multiply,
|
|
|
|
BiDiv => AssocOp::Divide,
|
|
|
|
BiRem => AssocOp::Modulus,
|
|
|
|
|
|
|
|
BiAnd => AssocOp::LAnd,
|
|
|
|
BiOr => AssocOp::LOr,
|
|
|
|
|
|
|
|
BiBitXor => AssocOp::BitXor,
|
|
|
|
BiBitAnd => AssocOp::BitAnd,
|
|
|
|
BiBitOr => AssocOp::BitOr,
|
|
|
|
BiShl => AssocOp::ShiftLeft,
|
|
|
|
BiShr => AssocOp::ShiftRight,
|
|
|
|
|
|
|
|
BiEq => AssocOp::Equal,
|
|
|
|
BiLt => AssocOp::Less,
|
|
|
|
BiLe => AssocOp::LessEqual,
|
|
|
|
BiNe => AssocOp::NotEqual,
|
|
|
|
BiGe => AssocOp::GreaterEqual,
|
|
|
|
BiGt => AssocOp::Greater,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Expressions that syntactically contain an "exterior" struct literal i.e. not surrounded by any
|
|
|
|
/// parens or other delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
|
|
|
|
/// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
|
|
|
|
fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
|
|
|
|
match value.node {
|
|
|
|
hir::ExprStruct(..) => true,
|
|
|
|
|
|
|
|
hir::ExprAssign(ref lhs, ref rhs) |
|
|
|
|
hir::ExprAssignOp(_, ref lhs, ref rhs) |
|
|
|
|
hir::ExprBinary(_, ref lhs, ref rhs) => {
|
|
|
|
// X { y: 1 } + X { y: 2 }
|
|
|
|
contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
|
|
|
|
}
|
|
|
|
hir::ExprUnary(_, ref x) |
|
|
|
|
hir::ExprCast(ref x, _) |
|
|
|
|
hir::ExprType(ref x, _) |
|
|
|
|
hir::ExprField(ref x, _) |
|
|
|
|
hir::ExprTupField(ref x, _) |
|
|
|
|
hir::ExprIndex(ref x, _) => {
|
|
|
|
// &X { y: 1 }, X { y: 1 }.y
|
|
|
|
contains_exterior_struct_lit(&x)
|
|
|
|
}
|
|
|
|
|
|
|
|
hir::ExprMethodCall(.., ref exprs) => {
|
|
|
|
// X { y: 1 }.bar(...)
|
|
|
|
contains_exterior_struct_lit(&exprs[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|