about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-12-01 01:05:59 +0800
committerkennytm <kennytm@gmail.com>2018-12-01 02:03:43 +0800
commitbdb901c865e024161b2e8b9428235f82235df070 (patch)
tree31a3f2ad649d24afbf964584e4283fb3d9aec0d5 /src/libsyntax
parentce00a8dd4d795f47a38a207af861a2cffcee7256 (diff)
parent64cd645d14407d312c7ed3a10efd9b3a99271884 (diff)
downloadrust-bdb901c865e024161b2e8b9428235f82235df070.tar.gz
rust-bdb901c865e024161b2e8b9428235f82235df070.zip
Rollup merge of #56336 - nnethercote:clean-up-pp, r=nikomatsakis
Clean up and streamline the pretty-printer

Some minor improvements.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/libsyntax/print/pp.rs309
-rw-r--r--src/libsyntax/print/pprust.rs106
3 files changed, 216 insertions, 201 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 506199b60ad..f13bb7df0b4 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2791,7 +2791,7 @@ impl<'a> Parser<'a> {
                             s.print_usize(float.trunc() as usize)?;
                             s.pclose()?;
                             s.s.word(".")?;
-                            s.s.word(fstr.splitn(2, ".").last().unwrap())
+                            s.s.word(fstr.splitn(2, ".").last().unwrap().to_string())
                         });
                         err.span_suggestion_with_applicability(
                             lo.to(self.prev_span),
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 086de35d531..aaed56da29d 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -140,13 +140,14 @@
 //! calculation, SCAN will write "infinity" to the size and let PRINT consume
 //! it.
 //!
-//! In this implementation (following the paper, again) the SCAN process is
-//! the method called `Printer::pretty_print`, and the 'PRINT' process is the method
-//! called `Printer::print`.
+//! In this implementation (following the paper, again) the SCAN process is the
+//! methods called `Printer::pretty_print_*`, and the 'PRINT' process is the
+//! method called `Printer::print`.
 
 use std::collections::VecDeque;
 use std::fmt;
 use std::io;
+use std::borrow::Cow;
 
 /// How to break. Described in more detail in the module docs.
 #[derive(Clone, Copy, PartialEq)]
@@ -169,7 +170,10 @@ pub struct BeginToken {
 
 #[derive(Clone)]
 pub enum Token {
-    String(String, isize),
+    // In practice a string token contains either a `&'static str` or a
+    // `String`. `Cow` is overkill for this because we never modify the data,
+    // but it's more convenient than rolling our own more specialized type.
+    String(Cow<'static, str>, isize),
     Break(BreakToken),
     Begin(BeginToken),
     End,
@@ -309,84 +313,86 @@ impl<'a> Printer<'a> {
     pub fn last_token(&mut self) -> Token {
         self.buf[self.right].token.clone()
     }
-    /// be very careful with this!
+
+    /// Be very careful with this!
     pub fn replace_last_token(&mut self, t: Token) {
         self.buf[self.right].token = t;
     }
-    pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
-        debug!("pp Vec<{},{}>", self.left, self.right);
-        match token {
-          Token::Eof => {
-            if !self.scan_stack.is_empty() {
-                self.check_stack(0);
-                self.advance_left()?;
-            }
-            self.indent(0);
-            Ok(())
-          }
-          Token::Begin(b) => {
-            if self.scan_stack.is_empty() {
-                self.left_total = 1;
-                self.right_total = 1;
-                self.left = 0;
-                self.right = 0;
-            } else {
-                self.advance_right();
-            }
-            debug!("pp Begin({})/buffer Vec<{},{}>",
-                   b.offset, self.left, self.right);
-            self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
-            let right = self.right;
-            self.scan_push(right);
-            Ok(())
-          }
-          Token::End => {
-            if self.scan_stack.is_empty() {
-                debug!("pp End/print Vec<{},{}>", self.left, self.right);
-                self.print(token, 0)
-            } else {
-                debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
-                self.advance_right();
-                self.buf[self.right] = BufEntry { token: token, size: -1 };
-                let right = self.right;
-                self.scan_push(right);
-                Ok(())
-            }
-          }
-          Token::Break(b) => {
-            if self.scan_stack.is_empty() {
-                self.left_total = 1;
-                self.right_total = 1;
-                self.left = 0;
-                self.right = 0;
-            } else {
-                self.advance_right();
-            }
-            debug!("pp Break({})/buffer Vec<{},{}>",
-                   b.offset, self.left, self.right);
+
+    fn pretty_print_eof(&mut self) -> io::Result<()> {
+        if !self.scan_stack.is_empty() {
             self.check_stack(0);
+            self.advance_left()?;
+        }
+        self.indent(0);
+        Ok(())
+    }
+
+    fn pretty_print_begin(&mut self, b: BeginToken) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            self.left_total = 1;
+            self.right_total = 1;
+            self.left = 0;
+            self.right = 0;
+        } else {
+            self.advance_right();
+        }
+        debug!("pp Begin({})/buffer Vec<{},{}>",
+               b.offset, self.left, self.right);
+        self.buf[self.right] = BufEntry { token: Token::Begin(b), size: -self.right_total };
+        let right = self.right;
+        self.scan_push(right);
+        Ok(())
+    }
+
+    fn pretty_print_end(&mut self) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            debug!("pp End/print Vec<{},{}>", self.left, self.right);
+            self.print_end()
+        } else {
+            debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
+            self.advance_right();
+            self.buf[self.right] = BufEntry { token: Token::End, size: -1 };
             let right = self.right;
             self.scan_push(right);
-            self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
-            self.right_total += b.blank_space;
             Ok(())
-          }
-          Token::String(s, len) => {
-            if self.scan_stack.is_empty() {
-                debug!("pp String('{}')/print Vec<{},{}>",
-                       s, self.left, self.right);
-                self.print(Token::String(s, len), len)
-            } else {
-                debug!("pp String('{}')/buffer Vec<{},{}>",
-                       s, self.left, self.right);
-                self.advance_right();
-                self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
-                self.right_total += len;
-                self.check_stream()
-            }
-          }
         }
     }
+
+    fn pretty_print_break(&mut self, b: BreakToken) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            self.left_total = 1;
+            self.right_total = 1;
+            self.left = 0;
+            self.right = 0;
+        } else {
+            self.advance_right();
+        }
+        debug!("pp Break({})/buffer Vec<{},{}>",
+               b.offset, self.left, self.right);
+        self.check_stack(0);
+        let right = self.right;
+        self.scan_push(right);
+        self.buf[self.right] = BufEntry { token: Token::Break(b), size: -self.right_total };
+        self.right_total += b.blank_space;
+        Ok(())
+    }
+
+    fn pretty_print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            debug!("pp String('{}')/print Vec<{},{}>",
+                   s, self.left, self.right);
+            self.print_string(s, len)
+        } else {
+            debug!("pp String('{}')/buffer Vec<{},{}>",
+                   s, self.left, self.right);
+            self.advance_right();
+            self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
+            self.right_total += len;
+            self.check_stream()
+        }
+    }
+
     pub fn check_stream(&mut self) -> io::Result<()> {
         debug!("check_stream Vec<{}, {}> with left_total={}, right_total={}",
                self.left, self.right, self.left_total, self.right_total);
@@ -405,19 +411,24 @@ impl<'a> Printer<'a> {
         }
         Ok(())
     }
+
     pub fn scan_push(&mut self, x: usize) {
         debug!("scan_push {}", x);
         self.scan_stack.push_front(x);
     }
+
     pub fn scan_pop(&mut self) -> usize {
         self.scan_stack.pop_front().unwrap()
     }
+
     pub fn scan_top(&mut self) -> usize {
         *self.scan_stack.front().unwrap()
     }
+
     pub fn scan_pop_bottom(&mut self) -> usize {
         self.scan_stack.pop_back().unwrap()
     }
+
     pub fn advance_right(&mut self) {
         self.right += 1;
         self.right %= self.buf_max_len;
@@ -427,6 +438,7 @@ impl<'a> Printer<'a> {
         }
         assert_ne!(self.right, self.left);
     }
+
     pub fn advance_left(&mut self) -> io::Result<()> {
         debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right,
                self.left, self.buf[self.left].size);
@@ -461,6 +473,7 @@ impl<'a> Printer<'a> {
 
         Ok(())
     }
+
     pub fn check_stack(&mut self, k: isize) {
         if !self.scan_stack.is_empty() {
             let x = self.scan_top();
@@ -488,6 +501,7 @@ impl<'a> Printer<'a> {
             }
         }
     }
+
     pub fn print_newline(&mut self, amount: isize) -> io::Result<()> {
         debug!("NEWLINE {}", amount);
         let ret = write!(self.out, "\n");
@@ -495,10 +509,12 @@ impl<'a> Printer<'a> {
         self.indent(amount);
         ret
     }
+
     pub fn indent(&mut self, amount: isize) {
         debug!("INDENT {}", amount);
         self.pending_indentation += amount;
     }
+
     pub fn get_top(&mut self) -> PrintStackElem {
         match self.print_stack.last() {
             Some(el) => *el,
@@ -508,62 +524,50 @@ impl<'a> Printer<'a> {
             }
         }
     }
-    pub fn print_str(&mut self, s: &str) -> io::Result<()> {
-        while self.pending_indentation > 0 {
-            write!(self.out, " ")?;
-            self.pending_indentation -= 1;
+
+    pub fn print_begin(&mut self, b: BeginToken, l: isize) -> io::Result<()> {
+        if l > self.space {
+            let col = self.margin - self.space + b.offset;
+            debug!("print Begin -> push broken block at col {}", col);
+            self.print_stack.push(PrintStackElem {
+                offset: col,
+                pbreak: PrintStackBreak::Broken(b.breaks)
+            });
+        } else {
+            debug!("print Begin -> push fitting block");
+            self.print_stack.push(PrintStackElem {
+                offset: 0,
+                pbreak: PrintStackBreak::Fits
+            });
         }
-        write!(self.out, "{}", s)
+        Ok(())
     }
-    pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
-        debug!("print {} {} (remaining line space={})", token, l,
-               self.space);
-        debug!("{}", buf_str(&self.buf,
-                             self.left,
-                             self.right,
-                             6));
-        match token {
-          Token::Begin(b) => {
-            if l > self.space {
-                let col = self.margin - self.space + b.offset;
-                debug!("print Begin -> push broken block at col {}", col);
-                self.print_stack.push(PrintStackElem {
-                    offset: col,
-                    pbreak: PrintStackBreak::Broken(b.breaks)
-                });
-            } else {
-                debug!("print Begin -> push fitting block");
-                self.print_stack.push(PrintStackElem {
-                    offset: 0,
-                    pbreak: PrintStackBreak::Fits
-                });
-            }
-            Ok(())
-          }
-          Token::End => {
-            debug!("print End -> pop End");
-            let print_stack = &mut self.print_stack;
-            assert!(!print_stack.is_empty());
-            print_stack.pop().unwrap();
-            Ok(())
-          }
-          Token::Break(b) => {
-            let top = self.get_top();
-            match top.pbreak {
-              PrintStackBreak::Fits => {
+
+    pub fn print_end(&mut self) -> io::Result<()> {
+        debug!("print End -> pop End");
+        let print_stack = &mut self.print_stack;
+        assert!(!print_stack.is_empty());
+        print_stack.pop().unwrap();
+        Ok(())
+    }
+
+    pub fn print_break(&mut self, b: BreakToken, l: isize) -> io::Result<()> {
+        let top = self.get_top();
+        match top.pbreak {
+            PrintStackBreak::Fits => {
                 debug!("print Break({}) in fitting block", b.blank_space);
                 self.space -= b.blank_space;
                 self.indent(b.blank_space);
                 Ok(())
-              }
-              PrintStackBreak::Broken(Breaks::Consistent) => {
+            }
+            PrintStackBreak::Broken(Breaks::Consistent) => {
                 debug!("print Break({}+{}) in consistent block",
                        top.offset, b.offset);
                 let ret = self.print_newline(top.offset + b.offset);
                 self.space = self.margin - (top.offset + b.offset);
                 ret
-              }
-              PrintStackBreak::Broken(Breaks::Inconsistent) => {
+            }
+            PrintStackBreak::Broken(Breaks::Inconsistent) => {
                 if l > self.space {
                     debug!("print Break({}+{}) w/ newline in inconsistent",
                            top.offset, b.offset);
@@ -577,20 +581,37 @@ impl<'a> Printer<'a> {
                     self.space -= b.blank_space;
                     Ok(())
                 }
-              }
             }
-          }
-          Token::String(ref s, len) => {
-            debug!("print String({})", s);
-            assert_eq!(l, len);
-            // assert!(l <= space);
-            self.space -= len;
-            self.print_str(s)
-          }
-          Token::Eof => {
-            // Eof should never get here.
-            panic!();
-          }
+        }
+    }
+
+    pub fn print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
+        debug!("print String({})", s);
+        // assert!(len <= space);
+        self.space -= len;
+        while self.pending_indentation > 0 {
+            write!(self.out, " ")?;
+            self.pending_indentation -= 1;
+        }
+        write!(self.out, "{}", s)
+    }
+
+    pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
+        debug!("print {} {} (remaining line space={})", token, l,
+               self.space);
+        debug!("{}", buf_str(&self.buf,
+                             self.left,
+                             self.right,
+                             6));
+        match token {
+            Token::Begin(b) => self.print_begin(b, l),
+            Token::End => self.print_end(),
+            Token::Break(b) => self.print_break(b, l),
+            Token::String(s, len) => {
+                assert_eq!(len, l);
+                self.print_string(s, len)
+            }
+            Token::Eof => panic!(), // Eof should never get here.
         }
     }
 
@@ -598,10 +619,10 @@ impl<'a> Printer<'a> {
 
     /// "raw box"
     pub fn rbox(&mut self, indent: usize, b: Breaks) -> io::Result<()> {
-        self.pretty_print(Token::Begin(BeginToken {
+        self.pretty_print_begin(BeginToken {
             offset: indent as isize,
             breaks: b
-        }))
+        })
     }
 
     /// Inconsistent breaking box
@@ -615,30 +636,24 @@ impl<'a> Printer<'a> {
     }
 
     pub fn break_offset(&mut self, n: usize, off: isize) -> io::Result<()> {
-        self.pretty_print(Token::Break(BreakToken {
+        self.pretty_print_break(BreakToken {
             offset: off,
             blank_space: n as isize
-        }))
+        })
     }
 
     pub fn end(&mut self) -> io::Result<()> {
-        self.pretty_print(Token::End)
+        self.pretty_print_end()
     }
 
     pub fn eof(&mut self) -> io::Result<()> {
-        self.pretty_print(Token::Eof)
-    }
-
-    pub fn word(&mut self, wrd: &str) -> io::Result<()> {
-        self.pretty_print(Token::String(wrd.to_string(), wrd.len() as isize))
-    }
-
-    pub fn huge_word(&mut self, wrd: &str) -> io::Result<()> {
-        self.pretty_print(Token::String(wrd.to_string(), SIZE_INFINITY))
+        self.pretty_print_eof()
     }
 
-    pub fn zero_word(&mut self, wrd: &str) -> io::Result<()> {
-        self.pretty_print(Token::String(wrd.to_string(), 0))
+    pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) -> io::Result<()> {
+        let s = wrd.into();
+        let len = s.len() as isize;
+        self.pretty_print_string(s, len)
     }
 
     fn spaces(&mut self, n: usize) -> io::Result<()> {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index ce7708cc42e..14ad4b5c6f8 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -29,6 +29,7 @@ use syntax_pos::{DUMMY_SP, FileName};
 use tokenstream::{self, TokenStream, TokenTree};
 
 use std::ascii;
+use std::borrow::Cow;
 use std::io::{self, Write, Read};
 use std::iter::Peekable;
 use std::vec;
@@ -444,7 +445,7 @@ pub trait PrintState<'a> {
     fn cur_lit(&mut self) -> Option<&comments::Literal>;
     fn bump_lit(&mut self) -> Option<comments::Literal>;
 
-    fn word_space(&mut self, w: &str) -> io::Result<()> {
+    fn word_space<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
         self.writer().word(w)?;
         self.writer().space()
     }
@@ -539,7 +540,7 @@ pub trait PrintState<'a> {
             comments::Mixed => {
                 assert_eq!(cmnt.lines.len(), 1);
                 self.writer().zerobreak()?;
-                self.writer().word(&cmnt.lines[0])?;
+                self.writer().word(cmnt.lines[0].clone())?;
                 self.writer().zerobreak()
             }
             comments::Isolated => {
@@ -548,7 +549,7 @@ pub trait PrintState<'a> {
                     // Don't print empty lines because they will end up as trailing
                     // whitespace
                     if !line.is_empty() {
-                        self.writer().word(&line[..])?;
+                        self.writer().word(line.clone())?;
                     }
                     self.writer().hardbreak()?;
                 }
@@ -559,13 +560,13 @@ pub trait PrintState<'a> {
                     self.writer().word(" ")?;
                 }
                 if cmnt.lines.len() == 1 {
-                    self.writer().word(&cmnt.lines[0])?;
+                    self.writer().word(cmnt.lines[0].clone())?;
                     self.writer().hardbreak()
                 } else {
                     self.ibox(0)?;
                     for line in &cmnt.lines {
                         if !line.is_empty() {
-                            self.writer().word(&line[..])?;
+                            self.writer().word(line.clone())?;
                         }
                         self.writer().hardbreak()?;
                     }
@@ -610,7 +611,7 @@ pub trait PrintState<'a> {
     fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
         self.maybe_print_comment(lit.span.lo())?;
         if let Some(ltrl) = self.next_lit(lit.span.lo()) {
-            return self.writer().word(&ltrl.lit);
+            return self.writer().word(ltrl.lit.clone());
         }
         match lit.node {
             ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style),
@@ -618,31 +619,31 @@ pub trait PrintState<'a> {
                 let mut res = String::from("b'");
                 res.extend(ascii::escape_default(byte).map(|c| c as char));
                 res.push('\'');
-                self.writer().word(&res[..])
+                self.writer().word(res)
             }
             ast::LitKind::Char(ch) => {
                 let mut res = String::from("'");
                 res.extend(ch.escape_default());
                 res.push('\'');
-                self.writer().word(&res[..])
+                self.writer().word(res)
             }
             ast::LitKind::Int(i, t) => {
                 match t {
                     ast::LitIntType::Signed(st) => {
-                        self.writer().word(&st.val_to_string(i as i128))
+                        self.writer().word(st.val_to_string(i as i128))
                     }
                     ast::LitIntType::Unsigned(ut) => {
-                        self.writer().word(&ut.val_to_string(i))
+                        self.writer().word(ut.val_to_string(i))
                     }
                     ast::LitIntType::Unsuffixed => {
-                        self.writer().word(&i.to_string())
+                        self.writer().word(i.to_string())
                     }
                 }
             }
             ast::LitKind::Float(ref f, t) => {
-                self.writer().word(&format!("{}{}", &f, t.ty_to_string()))
+                self.writer().word(format!("{}{}", &f, t.ty_to_string()))
             }
-            ast::LitKind::FloatUnsuffixed(ref f) => self.writer().word(&f.as_str()),
+            ast::LitKind::FloatUnsuffixed(ref f) => self.writer().word(f.as_str().get()),
             ast::LitKind::Bool(val) => {
                 if val { self.writer().word("true") } else { self.writer().word("false") }
             }
@@ -652,7 +653,7 @@ pub trait PrintState<'a> {
                     escaped.extend(ascii::escape_default(ch)
                                          .map(|c| c as char));
                 }
-                self.writer().word(&format!("b\"{}\"", escaped))
+                self.writer().word(format!("b\"{}\"", escaped))
             }
         }
     }
@@ -669,7 +670,7 @@ pub trait PrintState<'a> {
                          string=st))
             }
         };
-        self.writer().word(&st[..])
+        self.writer().word(st)
     }
 
     fn print_inner_attributes(&mut self,
@@ -727,7 +728,7 @@ pub trait PrintState<'a> {
             if segment.ident.name != keywords::CrateRoot.name() &&
                segment.ident.name != keywords::DollarCrate.name()
             {
-                self.writer().word(&segment.ident.as_str())?;
+                self.writer().word(segment.ident.as_str().get())?;
             } else if segment.ident.name == keywords::DollarCrate.name() {
                 self.print_dollar_crate(segment.ident.span.ctxt())?;
             }
@@ -746,7 +747,7 @@ pub trait PrintState<'a> {
         }
         self.maybe_print_comment(attr.span.lo())?;
         if attr.is_sugared_doc {
-            self.writer().word(&attr.value_str().unwrap().as_str())?;
+            self.writer().word(attr.value_str().unwrap().as_str().get())?;
             self.writer().hardbreak()
         } else {
             match attr.style {
@@ -807,7 +808,7 @@ pub trait PrintState<'a> {
     fn print_tt(&mut self, tt: tokenstream::TokenTree) -> io::Result<()> {
         match tt {
             TokenTree::Token(_, ref tk) => {
-                self.writer().word(&token_to_string(tk))?;
+                self.writer().word(token_to_string(tk))?;
                 match *tk {
                     parse::token::DocComment(..) => {
                         self.writer().hardbreak()
@@ -816,11 +817,11 @@ pub trait PrintState<'a> {
                 }
             }
             TokenTree::Delimited(_, ref delimed) => {
-                self.writer().word(&token_to_string(&delimed.open_token()))?;
+                self.writer().word(token_to_string(&delimed.open_token()))?;
                 self.writer().space()?;
                 self.print_tts(delimed.stream())?;
                 self.writer().space()?;
-                self.writer().word(&token_to_string(&delimed.close_token()))
+                self.writer().word(token_to_string(&delimed.close_token()))
             },
         }
     }
@@ -889,12 +890,13 @@ impl<'a> State<'a> {
         self.s.cbox(u)
     }
 
-    pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
+    pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
         self.s.word(w)?;
         self.nbsp()
     }
 
-    pub fn head(&mut self, w: &str) -> io::Result<()> {
+    pub fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
+        let w = w.into();
         // outer-box is consistent
         self.cbox(INDENT_UNIT)?;
         // head-box is inconsistent
@@ -956,7 +958,7 @@ impl<'a> State<'a> {
     pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
         self.s.word("/*")?;
         self.s.space()?;
-        self.s.word(&text[..])?;
+        self.s.word(text)?;
         self.s.space()?;
         self.s.word("*/")
     }
@@ -1129,7 +1131,7 @@ impl<'a> State<'a> {
                 self.end() // end the outer fn box
             }
             ast::ForeignItemKind::Static(ref t, m) => {
-                self.head(&visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"))?;
                 if m {
                     self.word_space("mut")?;
                 }
@@ -1141,7 +1143,7 @@ impl<'a> State<'a> {
                 self.end() // end the outer cbox
             }
             ast::ForeignItemKind::Ty => {
-                self.head(&visibility_qualified(&item.vis, "type"))?;
+                self.head(visibility_qualified(&item.vis, "type"))?;
                 self.print_ident(item.ident)?;
                 self.s.word(";")?;
                 self.end()?; // end the head-ibox
@@ -1164,7 +1166,7 @@ impl<'a> State<'a> {
                               vis: &ast::Visibility)
                               -> io::Result<()>
     {
-        self.s.word(&visibility_qualified(vis, ""))?;
+        self.s.word(visibility_qualified(vis, ""))?;
         self.word_space("const")?;
         self.print_ident(ident)?;
         self.word_space(":")?;
@@ -1203,7 +1205,7 @@ impl<'a> State<'a> {
         self.ann.pre(self, AnnNode::Item(item))?;
         match item.node {
             ast::ItemKind::ExternCrate(orig_name) => {
-                self.head(&visibility_qualified(&item.vis, "extern crate"))?;
+                self.head(visibility_qualified(&item.vis, "extern crate"))?;
                 if let Some(orig_name) = orig_name {
                     self.print_name(orig_name)?;
                     self.s.space()?;
@@ -1216,14 +1218,14 @@ impl<'a> State<'a> {
                 self.end()?; // end outer head-block
             }
             ast::ItemKind::Use(ref tree) => {
-                self.head(&visibility_qualified(&item.vis, "use"))?;
+                self.head(visibility_qualified(&item.vis, "use"))?;
                 self.print_use_tree(tree)?;
                 self.s.word(";")?;
                 self.end()?; // end inner head-block
                 self.end()?; // end outer head-block
             }
             ast::ItemKind::Static(ref ty, m, ref expr) => {
-                self.head(&visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"))?;
                 if m == ast::Mutability::Mutable {
                     self.word_space("mut")?;
                 }
@@ -1239,7 +1241,7 @@ impl<'a> State<'a> {
                 self.end()?; // end the outer cbox
             }
             ast::ItemKind::Const(ref ty, ref expr) => {
-                self.head(&visibility_qualified(&item.vis, "const"))?;
+                self.head(visibility_qualified(&item.vis, "const"))?;
                 self.print_ident(item.ident)?;
                 self.word_space(":")?;
                 self.print_type(ty)?;
@@ -1264,7 +1266,7 @@ impl<'a> State<'a> {
                 self.print_block_with_attrs(body, &item.attrs)?;
             }
             ast::ItemKind::Mod(ref _mod) => {
-                self.head(&visibility_qualified(&item.vis, "mod"))?;
+                self.head(visibility_qualified(&item.vis, "mod"))?;
                 self.print_ident(item.ident)?;
 
                 if _mod.inline || self.is_expanded {
@@ -1281,18 +1283,18 @@ impl<'a> State<'a> {
             }
             ast::ItemKind::ForeignMod(ref nmod) => {
                 self.head("extern")?;
-                self.word_nbsp(&nmod.abi.to_string())?;
+                self.word_nbsp(nmod.abi.to_string())?;
                 self.bopen()?;
                 self.print_foreign_mod(nmod, &item.attrs)?;
                 self.bclose(item.span)?;
             }
             ast::ItemKind::GlobalAsm(ref ga) => {
-                self.head(&visibility_qualified(&item.vis, "global_asm!"))?;
-                self.s.word(&ga.asm.as_str())?;
+                self.head(visibility_qualified(&item.vis, "global_asm!"))?;
+                self.s.word(ga.asm.as_str().get())?;
                 self.end()?;
             }
             ast::ItemKind::Ty(ref ty, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "type"))?;
+                self.head(visibility_qualified(&item.vis, "type"))?;
                 self.print_ident(item.ident)?;
                 self.print_generic_params(&generics.params)?;
                 self.end()?; // end the inner ibox
@@ -1305,7 +1307,7 @@ impl<'a> State<'a> {
                 self.end()?; // end the outer ibox
             }
             ast::ItemKind::Existential(ref bounds, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "existential type"))?;
+                self.head(visibility_qualified(&item.vis, "existential type"))?;
                 self.print_ident(item.ident)?;
                 self.print_generic_params(&generics.params)?;
                 self.end()?; // end the inner ibox
@@ -1326,11 +1328,11 @@ impl<'a> State<'a> {
                 )?;
             }
             ast::ItemKind::Struct(ref struct_def, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "struct"))?;
+                self.head(visibility_qualified(&item.vis, "struct"))?;
                 self.print_struct(struct_def, generics, item.ident, item.span, true)?;
             }
             ast::ItemKind::Union(ref struct_def, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "union"))?;
+                self.head(visibility_qualified(&item.vis, "union"))?;
                 self.print_struct(struct_def, generics, item.ident, item.span, true)?;
             }
             ast::ItemKind::Impl(unsafety,
@@ -1479,7 +1481,7 @@ impl<'a> State<'a> {
                           generics: &ast::Generics, ident: ast::Ident,
                           span: syntax_pos::Span,
                           visibility: &ast::Visibility) -> io::Result<()> {
-        self.head(&visibility_qualified(visibility, "enum"))?;
+        self.head(visibility_qualified(visibility, "enum"))?;
         self.print_ident(ident)?;
         self.print_generic_params(&generics.params)?;
         self.print_where_clause(&generics.where_clause)?;
@@ -1514,9 +1516,9 @@ impl<'a> State<'a> {
             ast::VisibilityKind::Restricted { ref path, .. } => {
                 let path = to_string(|s| s.print_path(path, false, 0));
                 if path == "self" || path == "super" {
-                    self.word_nbsp(&format!("pub({})", path))
+                    self.word_nbsp(format!("pub({})", path))
                 } else {
-                    self.word_nbsp(&format!("pub(in {})", path))
+                    self.word_nbsp(format!("pub(in {})", path))
                 }
             }
             ast::VisibilityKind::Inherited => Ok(())
@@ -2415,19 +2417,19 @@ impl<'a> State<'a> {
 
     pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
         if ident.is_raw_guess() {
-            self.s.word(&format!("r#{}", ident))?;
+            self.s.word(format!("r#{}", ident))?;
         } else {
-            self.s.word(&ident.as_str())?;
+            self.s.word(ident.as_str().get())?;
         }
         self.ann.post(self, AnnNode::Ident(&ident))
     }
 
     pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
-        self.s.word(&i.to_string())
+        self.s.word(i.to_string())
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
-        self.s.word(&name.as_str())?;
+        self.s.word(name.as_str().get())?;
         self.ann.post(self, AnnNode::Name(&name))
     }
 
@@ -2851,10 +2853,8 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_type_bounds(&mut self,
-                        prefix: &str,
-                        bounds: &[ast::GenericBound])
-                        -> io::Result<()> {
+    pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound])
+                             -> io::Result<()> {
         if !bounds.is_empty() {
             self.s.word(prefix)?;
             let mut first = true;
@@ -3146,7 +3146,7 @@ impl<'a> State<'a> {
             Some(Abi::Rust) => Ok(()),
             Some(abi) => {
                 self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
+                self.word_nbsp(abi.to_string())
             }
             None => Ok(())
         }
@@ -3157,7 +3157,7 @@ impl<'a> State<'a> {
         match opt_abi {
             Some(abi) => {
                 self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
+                self.word_nbsp(abi.to_string())
             }
             None => Ok(())
         }
@@ -3166,7 +3166,7 @@ impl<'a> State<'a> {
     pub fn print_fn_header_info(&mut self,
                                 header: ast::FnHeader,
                                 vis: &ast::Visibility) -> io::Result<()> {
-        self.s.word(&visibility_qualified(vis, ""))?;
+        self.s.word(visibility_qualified(vis, ""))?;
 
         match header.constness.node {
             ast::Constness::NotConst => {}
@@ -3178,7 +3178,7 @@ impl<'a> State<'a> {
 
         if header.abi != Abi::Rust {
             self.word_nbsp("extern")?;
-            self.word_nbsp(&header.abi.to_string())?;
+            self.word_nbsp(header.abi.to_string())?;
         }
 
         self.s.word("fn")