]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_middle/src/ty/print/pretty.rs
New upstream version 1.49.0~beta.4+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / print / pretty.rs
index 7b5cf681f38fb60efde2996f0eca594d81707319..1e4fd0921ee0fd4b380f502b9aaa952e7fdbed9a 100644 (file)
@@ -1,12 +1,9 @@
 use crate::middle::cstore::{ExternCrate, ExternCrateSource};
 use crate::mir::interpret::{AllocId, ConstValue, GlobalAlloc, Pointer, Scalar};
-use crate::ty::layout::IntegerExt;
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
-use crate::ty::{self, ConstInt, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Ty, TyCtxt, TypeFoldable};
 use rustc_apfloat::ieee::{Double, Single};
-use rustc_apfloat::Float;
 use rustc_ast as ast;
-use rustc_attr::{SignedInt, UnsignedInt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
@@ -15,19 +12,23 @@ use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathD
 use rustc_hir::ItemKind;
 use rustc_session::config::TrimmedDefPaths;
 use rustc_span::symbol::{kw, Ident, Symbol};
-use rustc_target::abi::{Integer, Size};
+use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
 
 use std::cell::Cell;
 use std::char;
 use std::collections::BTreeMap;
+use std::convert::TryFrom;
 use std::fmt::{self, Write as _};
-use std::ops::{Deref, DerefMut};
+use std::ops::{ControlFlow, Deref, DerefMut};
 
 // `pretty` is a separate module only for organization.
 use super::*;
 
 macro_rules! p {
+    (@$lit:literal) => {
+        write!(scoped_cx!(), $lit)?
+    };
     (@write($($data:expr),+)) => {
         write!(scoped_cx!(), $($data),+)?
     };
@@ -37,8 +38,8 @@ macro_rules! p {
     (@$method:ident($($arg:expr),*)) => {
         scoped_cx!() = scoped_cx!().$method($($arg),*)?
     };
-    ($($kind:ident $data:tt),+) => {{
-        $(p!(@$kind $data);)+
+    ($($elem:tt $(($($args:tt)*))?),+) => {{
+        $(p!(@ $elem $(($($args)*))?);)+
     }};
 }
 macro_rules! define_scoped_cx {
@@ -62,7 +63,7 @@ thread_local! {
 /// Avoids running any queries during any prints that occur
 /// during the closure. This may alter the appearance of some
 /// types (e.g. forcing verbose printing for opaque types).
-/// This method is used during some queries (e.g. `predicates_of`
+/// This method is used during some queries (e.g. `explicit_item_bounds`
 /// for opaque types), to ensure that any debug printing that
 /// occurs during the query computation does not end up recursively
 /// calling the same query.
@@ -478,7 +479,7 @@ pub trait PrettyPrinter<'tcx>:
 
             p!(print(self_ty));
             if let Some(trait_ref) = trait_ref {
-                p!(write(" as "), print(trait_ref.print_only_trait_path()));
+                p!(" as ", print(trait_ref.print_only_trait_path()));
             }
             Ok(cx)
         })
@@ -495,9 +496,9 @@ pub trait PrettyPrinter<'tcx>:
         self.generic_delimiters(|mut cx| {
             define_scoped_cx!(cx);
 
-            p!(write("impl "));
+            p!("impl ");
             if let Some(trait_ref) = trait_ref {
-                p!(print(trait_ref.print_only_trait_path()), write(" for "));
+                p!(print(trait_ref.print_only_trait_path()), " for ");
             }
             p!(print(self_ty));
 
@@ -509,8 +510,8 @@ pub trait PrettyPrinter<'tcx>:
         define_scoped_cx!(self);
 
         match *ty.kind() {
-            ty::Bool => p!(write("bool")),
-            ty::Char => p!(write("char")),
+            ty::Bool => p!("bool"),
+            ty::Char => p!("char"),
             ty::Int(t) => p!(write("{}", t.name_str())),
             ty::Uint(t) => p!(write("{}", t.name_str())),
             ty::Float(t) => p!(write("{}", t.name_str())),
@@ -525,23 +526,23 @@ pub trait PrettyPrinter<'tcx>:
                 p!(print(tm.ty))
             }
             ty::Ref(r, ty, mutbl) => {
-                p!(write("&"));
+                p!("&");
                 if self.region_should_not_be_omitted(r) {
-                    p!(print(r), write(" "));
+                    p!(print(r), " ");
                 }
                 p!(print(ty::TypeAndMut { ty, mutbl }))
             }
-            ty::Never => p!(write("!")),
+            ty::Never => p!("!"),
             ty::Tuple(ref tys) => {
-                p!(write("("), comma_sep(tys.iter()));
+                p!("(", comma_sep(tys.iter()));
                 if tys.len() == 1 {
-                    p!(write(","));
+                    p!(",");
                 }
-                p!(write(")"))
+                p!(")")
             }
             ty::FnDef(def_id, substs) => {
                 let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
-                p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}"));
+                p!(print(sig), " {{", print_value_path(def_id, substs), "}}");
             }
             ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
             ty::Infer(infer_ty) => {
@@ -555,7 +556,7 @@ pub trait PrettyPrinter<'tcx>:
                     p!(write("{}", infer_ty))
                 }
             }
-            ty::Error(_) => p!(write("[type error]")),
+            ty::Error(_) => p!("[type error]"),
             ty::Param(ref param_ty) => p!(write("{}", param_ty)),
             ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
                 ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?,
@@ -567,11 +568,11 @@ pub trait PrettyPrinter<'tcx>:
             ty::Dynamic(data, r) => {
                 let print_r = self.region_should_not_be_omitted(r);
                 if print_r {
-                    p!(write("("));
+                    p!("(");
                 }
-                p!(write("dyn "), print(data));
+                p!("dyn ", print(data));
                 if print_r {
-                    p!(write(" + "), print(r), write(")"));
+                    p!(" + ", print(r), ")");
                 }
             }
             ty::Foreign(def_id) => {
@@ -597,27 +598,27 @@ pub trait PrettyPrinter<'tcx>:
                         p!(write("{}", name));
                         // FIXME(eddyb) print this with `print_def_path`.
                         if !substs.is_empty() {
-                            p!(write("::"));
+                            p!("::");
                             p!(generic_delimiters(|cx| cx.comma_sep(substs.iter())));
                         }
                         return Ok(self);
                     }
                     // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
                     // by looking up the projections associated with the def_id.
-                    let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs);
+                    let bounds = self.tcx().explicit_item_bounds(def_id);
 
                     let mut first = true;
                     let mut is_sized = false;
-                    p!(write("impl"));
-                    for predicate in bounds.predicates {
+                    p!("impl");
+                    for (predicate, _) in bounds {
+                        let predicate = predicate.subst(self.tcx(), substs);
                         // Note: We can't use `to_opt_poly_trait_ref` here as `predicate`
                         // may contain unbound variables. We therefore do this manually.
                         //
                         // FIXME(lcnr): Find out why exactly this is the case :)
-                        if let ty::PredicateAtom::Trait(pred, _) =
-                            predicate.bound_atom(self.tcx()).skip_binder()
-                        {
-                            let trait_ref = ty::Binder::bind(pred.trait_ref);
+                        let bound_predicate = predicate.bound_atom_with_opt_escaping(self.tcx());
+                        if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() {
+                            let trait_ref = bound_predicate.rebind(pred.trait_ref);
                             // Don't print +Sized, but rather +?Sized if absent.
                             if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
                                 is_sized = true;
@@ -634,50 +635,45 @@ pub trait PrettyPrinter<'tcx>:
                     if !is_sized {
                         p!(write("{}?Sized", if first { " " } else { "+" }));
                     } else if first {
-                        p!(write(" Sized"));
+                        p!(" Sized");
                     }
                     Ok(self)
                 })?);
             }
-            ty::Str => p!(write("str")),
+            ty::Str => p!("str"),
             ty::Generator(did, substs, movability) => {
                 p!(write("["));
                 match movability {
                     hir::Movability::Movable => {}
-                    hir::Movability::Static => p!(write("static ")),
+                    hir::Movability::Static => p!("static "),
                 }
 
                 if !self.tcx().sess.verbose() {
-                    p!(write("generator"));
+                    p!("generator");
                     // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
                         let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
                         let span = self.tcx().hir().span(hir_id);
                         p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
                     } else {
-                        p!(write("@{}", self.tcx().def_path_str(did)));
+                        p!(write("@"), print_def_path(did, substs));
                     }
                 } else {
                     p!(print_def_path(did, substs));
-                    if substs.as_generator().is_valid() {
-                        // Search for the first inference variable
-                        p!(write(" upvar_tys=("));
-                        let mut uninferred_ty =
-                            substs.as_generator().upvar_tys().filter(|ty| ty.is_ty_infer());
-                        if uninferred_ty.next().is_some() {
-                            p!(write("unavailable"));
-                        } else {
-                            self = self.comma_sep(substs.as_generator().upvar_tys())?;
-                        }
-                        p!(write(")"));
+                    p!(" upvar_tys=(");
+                    if !substs.as_generator().is_valid() {
+                        p!("unavailable");
+                    } else {
+                        self = self.comma_sep(substs.as_generator().upvar_tys())?;
                     }
+                    p!(")");
                 }
 
                 if substs.as_generator().is_valid() {
-                    p!(write(" "), print(substs.as_generator().witness()));
+                    p!(" ", print(substs.as_generator().witness()));
                 }
 
-                p!(write("]"));
+                p!("]")
             }
             ty::GeneratorWitness(types) => {
                 p!(in_binder(&types));
@@ -690,57 +686,50 @@ pub trait PrettyPrinter<'tcx>:
                     if let Some(did) = did.as_local() {
                         let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
                         if self.tcx().sess.opts.debugging_opts.span_free_formats {
-                            p!(write("@"), print_def_path(did.to_def_id(), substs));
+                            p!("@", print_def_path(did.to_def_id(), substs));
                         } else {
                             let span = self.tcx().hir().span(hir_id);
                             p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
                         }
                     } else {
-                        p!(write("@{}", self.tcx().def_path_str(did)));
+                        p!(write("@"), print_def_path(did, substs));
                     }
                 } else {
                     p!(print_def_path(did, substs));
-                    if substs.as_closure().is_valid() {
-                        // Search for the first inference variable
-                        let mut uninferred_ty =
-                            substs.as_closure().upvar_tys().filter(|ty| ty.is_ty_infer());
-                        if uninferred_ty.next().is_some() {
-                            // If the upvar substs contain an inference variable we haven't
-                            // finished capture analysis.
-                            p!(write(" closure_substs=(unavailable)"));
-                        } else {
-                            p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
-                            p!(
-                                write(" closure_sig_as_fn_ptr_ty="),
-                                print(substs.as_closure().sig_as_fn_ptr_ty())
-                            );
-                            p!(write(" upvar_tys=("));
-                            self = self.comma_sep(substs.as_closure().upvar_tys())?;
-                            p!(write(")"));
-                        }
+                    if !substs.as_closure().is_valid() {
+                        p!(" closure_substs=(unavailable)");
+                    } else {
+                        p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
+                        p!(
+                            " closure_sig_as_fn_ptr_ty=",
+                            print(substs.as_closure().sig_as_fn_ptr_ty())
+                        );
+                        p!(" upvar_tys=(");
+                        self = self.comma_sep(substs.as_closure().upvar_tys())?;
+                        p!(")");
                     }
                 }
-                p!(write("]"));
+                p!("]");
             }
             ty::Array(ty, sz) => {
-                p!(write("["), print(ty), write("; "));
+                p!("[", print(ty), "; ");
                 if self.tcx().sess.verbose() {
                     p!(write("{:?}", sz));
                 } else if let ty::ConstKind::Unevaluated(..) = sz.val {
                     // Do not try to evaluate unevaluated constants. If we are const evaluating an
                     // array length anon const, rustc will (with debug assertions) print the
                     // constant's path. Which will end up here again.
-                    p!(write("_"));
+                    p!("_");
                 } else if let Some(n) = sz.val.try_to_bits(self.tcx().data_layout.pointer_size) {
                     p!(write("{}", n));
                 } else if let ty::ConstKind::Param(param) = sz.val {
                     p!(write("{}", param));
                 } else {
-                    p!(write("_"));
+                    p!("_");
                 }
-                p!(write("]"))
+                p!("]")
             }
-            ty::Slice(ty) => p!(write("["), print(ty), write("]")),
+            ty::Slice(ty) => p!("[", print(ty), "]"),
         }
 
         Ok(self)
@@ -847,7 +836,7 @@ pub trait PrettyPrinter<'tcx>:
 
         for (_, def_id) in auto_traits {
             if !first {
-                p!(write(" + "));
+                p!(" + ");
             }
             first = false;
 
@@ -865,16 +854,16 @@ pub trait PrettyPrinter<'tcx>:
     ) -> Result<Self, Self::Error> {
         define_scoped_cx!(self);
 
-        p!(write("("), comma_sep(inputs.iter().copied()));
+        p!("(", comma_sep(inputs.iter().copied()));
         if c_variadic {
             if !inputs.is_empty() {
-                p!(write(", "));
+                p!(", ");
             }
-            p!(write("..."));
+            p!("...");
         }
-        p!(write(")"));
+        p!(")");
         if !output.is_unit() {
-            p!(write(" -> "), print(output));
+            p!(" -> ", print(output));
         }
 
         Ok(self)
@@ -945,7 +934,7 @@ pub trait PrettyPrinter<'tcx>:
                 self.pretty_print_bound_var(debruijn, bound_var)?
             }
             ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
-            ty::ConstKind::Error(_) => p!(write("[const error]")),
+            ty::ConstKind::Error(_) => p!("[const error]"),
         };
         Ok(self)
     }
@@ -969,11 +958,7 @@ pub trait PrettyPrinter<'tcx>:
                             ty::Array(
                                 ty::TyS { kind: ty::Uint(ast::UintTy::U8), .. },
                                 ty::Const {
-                                    val:
-                                        ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw {
-                                            data,
-                                            ..
-                                        })),
+                                    val: ty::ConstKind::Value(ConstValue::Scalar(int)),
                                     ..
                                 },
                             ),
@@ -983,45 +968,42 @@ pub trait PrettyPrinter<'tcx>:
                 ),
             ) => match self.tcx().get_global_alloc(ptr.alloc_id) {
                 Some(GlobalAlloc::Memory(alloc)) => {
-                    if let Ok(byte_str) = alloc.get_bytes(&self.tcx(), ptr, Size::from_bytes(*data))
-                    {
+                    let bytes = int.assert_bits(self.tcx().data_layout.pointer_size);
+                    let size = Size::from_bytes(bytes);
+                    if let Ok(byte_str) = alloc.get_bytes(&self.tcx(), ptr, size) {
                         p!(pretty_print_byte_str(byte_str))
                     } else {
-                        p!(write("<too short allocation>"))
+                        p!("<too short allocation>")
                     }
                 }
                 // FIXME: for statics and functions, we could in principle print more detail.
                 Some(GlobalAlloc::Static(def_id)) => p!(write("<static({:?})>", def_id)),
-                Some(GlobalAlloc::Function(_)) => p!(write("<function>")),
-                None => p!(write("<dangling pointer>")),
+                Some(GlobalAlloc::Function(_)) => p!("<function>"),
+                None => p!("<dangling pointer>"),
             },
             // Bool
-            (Scalar::Raw { data: 0, .. }, ty::Bool) => p!(write("false")),
-            (Scalar::Raw { data: 1, .. }, ty::Bool) => p!(write("true")),
+            (Scalar::Int(int), ty::Bool) if int == ScalarInt::FALSE => p!("false"),
+            (Scalar::Int(int), ty::Bool) if int == ScalarInt::TRUE => p!("true"),
             // Float
-            (Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F32)) => {
-                p!(write("{}f32", Single::from_bits(data)))
+            (Scalar::Int(int), ty::Float(ast::FloatTy::F32)) => {
+                p!(write("{}f32", Single::try_from(int).unwrap()))
             }
-            (Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F64)) => {
-                p!(write("{}f64", Double::from_bits(data)))
+            (Scalar::Int(int), ty::Float(ast::FloatTy::F64)) => {
+                p!(write("{}f64", Double::try_from(int).unwrap()))
             }
             // Int
-            (Scalar::Raw { data, .. }, ty::Uint(ui)) => {
-                let size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
-                let int = ConstInt::new(data, size, false, ty.is_ptr_sized_integral());
-                if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) }
-            }
-            (Scalar::Raw { data, .. }, ty::Int(i)) => {
-                let size = Integer::from_attr(&self.tcx(), SignedInt(*i)).size();
-                let int = ConstInt::new(data, size, true, ty.is_ptr_sized_integral());
+            (Scalar::Int(int), ty::Uint(_) | ty::Int(_)) => {
+                let int =
+                    ConstInt::new(int, matches!(ty.kind(), ty::Int(_)), ty.is_ptr_sized_integral());
                 if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) }
             }
             // Char
-            (Scalar::Raw { data, .. }, ty::Char) if char::from_u32(data as u32).is_some() => {
-                p!(write("{:?}", char::from_u32(data as u32).unwrap()))
+            (Scalar::Int(int), ty::Char) if char::try_from(int).is_ok() => {
+                p!(write("{:?}", char::try_from(int).unwrap()))
             }
             // Raw pointers
-            (Scalar::Raw { data, .. }, ty::RawPtr(_)) => {
+            (Scalar::Int(int), ty::RawPtr(_)) => {
+                let data = int.assert_bits(self.tcx().data_layout.pointer_size);
                 self = self.typed_value(
                     |mut this| {
                         write!(this, "0x{:x}", data)?;
@@ -1043,14 +1025,16 @@ pub trait PrettyPrinter<'tcx>:
                 )?;
             }
             // For function type zsts just printing the path is enough
-            (Scalar::Raw { size: 0, .. }, ty::FnDef(d, s)) => p!(print_value_path(*d, s)),
+            (Scalar::Int(int), ty::FnDef(d, s)) if int == ScalarInt::ZST => {
+                p!(print_value_path(*d, s))
+            }
             // Nontrivial types with scalar bit representation
-            (Scalar::Raw { data, size }, _) => {
+            (Scalar::Int(int), _) => {
                 let print = |mut this: Self| {
-                    if size == 0 {
+                    if int.size() == Size::ZERO {
                         write!(this, "transmute(())")?;
                     } else {
-                        write!(this, "transmute(0x{:01$x})", data, size as usize * 2)?;
+                        write!(this, "transmute(0x{:x})", int)?;
                     }
                     Ok(this)
                 };
@@ -1093,13 +1077,13 @@ pub trait PrettyPrinter<'tcx>:
 
     fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> {
         define_scoped_cx!(self);
-        p!(write("b\""));
+        p!("b\"");
         for &c in byte_str {
             for e in std::ascii::escape_default(c) {
                 self.write_char(e as char)?;
             }
         }
-        p!(write("\""));
+        p!("\"");
         Ok(self)
     }
 
@@ -1112,7 +1096,7 @@ pub trait PrettyPrinter<'tcx>:
         define_scoped_cx!(self);
 
         if self.tcx().sess.verbose() {
-            p!(write("ConstValue({:?}: ", ct), print(ty), write(")"));
+            p!(write("ConstValue({:?}: ", ct), print(ty), ")");
             return Ok(self);
         }
 
@@ -1138,7 +1122,7 @@ pub trait PrettyPrinter<'tcx>:
                 // relocations (we have an active `str` reference here). We don't use this
                 // result to affect interpreter execution.
                 let slice = data.inspect_with_uninit_and_ptr_outside_interpreter(start..end);
-                let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
+                let s = std::str::from_utf8(slice).expect("non utf8 str from miri");
                 p!(write("{:?}", s));
                 Ok(self)
             }
@@ -1149,7 +1133,7 @@ pub trait PrettyPrinter<'tcx>:
                 let ptr = Pointer::new(AllocId(0), offset);
 
                 let byte_str = alloc.get_bytes(&self.tcx(), ptr, n).unwrap();
-                p!(write("*"));
+                p!("*");
                 p!(pretty_print_byte_str(byte_str));
                 Ok(self)
             }
@@ -1173,14 +1157,14 @@ pub trait PrettyPrinter<'tcx>:
 
                 match *ty.kind() {
                     ty::Array(..) => {
-                        p!(write("["), comma_sep(fields), write("]"));
+                        p!("[", comma_sep(fields), "]");
                     }
                     ty::Tuple(..) => {
-                        p!(write("("), comma_sep(fields));
+                        p!("(", comma_sep(fields));
                         if contents.fields.len() == 1 {
-                            p!(write(","));
+                            p!(",");
                         }
-                        p!(write(")"));
+                        p!(")");
                     }
                     ty::Adt(def, substs) if def.variants.is_empty() => {
                         p!(print_value_path(def.did, substs));
@@ -1194,19 +1178,19 @@ pub trait PrettyPrinter<'tcx>:
                         match variant_def.ctor_kind {
                             CtorKind::Const => {}
                             CtorKind::Fn => {
-                                p!(write("("), comma_sep(fields), write(")"));
+                                p!("(", comma_sep(fields), ")");
                             }
                             CtorKind::Fictive => {
-                                p!(write(" {{ "));
+                                p!(" {{ ");
                                 let mut first = true;
                                 for (field_def, field) in variant_def.fields.iter().zip(fields) {
                                     if !first {
-                                        p!(write(", "));
+                                        p!(", ");
                                     }
                                     p!(write("{}: ", field_def.ident), print(field));
                                     first = false;
                                 }
-                                p!(write(" }}"));
+                                p!(" }}");
                             }
                         }
                     }
@@ -1224,7 +1208,7 @@ pub trait PrettyPrinter<'tcx>:
                 // fallback
                 p!(write("{:?}", ct));
                 if print_ty {
-                    p!(write(": "), print(ty));
+                    p!(": ", print(ty));
                 }
                 Ok(self)
             }
@@ -1637,7 +1621,7 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
             if this.print_alloc_ids {
                 p!(write("{:?}", p));
             } else {
-                p!(write("&_"));
+                p!("&_");
             }
             Ok(this)
         };
@@ -1703,11 +1687,11 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
             ty::ReVar(_) => {}
             ty::ReErased => {}
             ty::ReStatic => {
-                p!(write("'static"));
+                p!("'static");
                 return Ok(self);
             }
             ty::ReEmpty(ty::UniverseIndex::ROOT) => {
-                p!(write("'<empty>"));
+                p!("'<empty>");
                 return Ok(self);
             }
             ty::ReEmpty(ui) => {
@@ -1716,7 +1700,7 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
             }
         }
 
-        p!(write("'_"));
+        p!("'_");
 
         Ok(self)
     }
@@ -1812,7 +1796,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
     {
         struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
         impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
-            fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
+            fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<()> {
                 if let ty::ReLateBound(_, ty::BrNamed(_, name)) = *r {
                     self.0.insert(name);
                 }
@@ -1847,7 +1831,7 @@ where
     type Error = P::Error;
     fn print(&self, mut cx: P) -> Result<Self::Output, Self::Error> {
         define_scoped_cx!(cx);
-        p!(print(self.0), write(": "), print(self.1));
+        p!(print(self.0), ": ", print(self.1));
         Ok(cx)
     }
 }
@@ -1857,7 +1841,7 @@ macro_rules! forward_display_to_print {
         $(impl fmt::Display for $ty {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 ty::tls::with(|tcx| {
-                    tcx.lift(self)
+                    tcx.lift(*self)
                         .expect("could not lift for printing")
                         .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
                     Ok(())
@@ -1945,7 +1929,7 @@ define_print_and_forward_display! {
     (self, cx):
 
     &'tcx ty::List<Ty<'tcx>> {
-        p!(write("{{"), comma_sep(self.iter()), write("}}"))
+        p!("{{", comma_sep(self.iter()), "}}")
     }
 
     ty::TypeAndMut<'tcx> {
@@ -1981,7 +1965,7 @@ define_print_and_forward_display! {
             p!(write("extern {} ", self.abi));
         }
 
-        p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
+        p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
     }
 
     ty::InferTy {
@@ -1990,7 +1974,7 @@ define_print_and_forward_display! {
             return Ok(cx);
         }
         match *self {
-            ty::TyVar(_) => p!(write("_")),
+            ty::TyVar(_) => p!("_"),
             ty::IntVar(_) => p!(write("{}", "{integer}")),
             ty::FloatVar(_) => p!(write("{}", "{float}")),
             ty::FreshTy(v) => p!(write("FreshTy({})", v)),
@@ -2016,16 +2000,16 @@ define_print_and_forward_display! {
     }
 
     ty::SubtypePredicate<'tcx> {
-        p!(print(self.a), write(" <: "), print(self.b))
+        p!(print(self.a), " <: ", print(self.b))
     }
 
     ty::TraitPredicate<'tcx> {
-        p!(print(self.trait_ref.self_ty()), write(": "),
+        p!(print(self.trait_ref.self_ty()), ": ",
            print(self.trait_ref.print_only_trait_path()))
     }
 
     ty::ProjectionPredicate<'tcx> {
-        p!(print(self.projection_ty), write(" == "), print(self.ty))
+        p!(print(self.projection_ty), " == ", print(self.ty))
     }
 
     ty::ProjectionTy<'tcx> {
@@ -2034,9 +2018,9 @@ define_print_and_forward_display! {
 
     ty::ClosureKind {
         match *self {
-            ty::ClosureKind::Fn => p!(write("Fn")),
-            ty::ClosureKind::FnMut => p!(write("FnMut")),
-            ty::ClosureKind::FnOnce => p!(write("FnOnce")),
+            ty::ClosureKind::Fn => p!("Fn"),
+            ty::ClosureKind::FnMut => p!("FnMut"),
+            ty::ClosureKind::FnOnce => p!("FnOnce"),
         }
     }
 
@@ -2051,7 +2035,7 @@ define_print_and_forward_display! {
         match *self {
             ty::PredicateAtom::Trait(ref data, constness) => {
                 if let hir::Constness::Const = constness {
-                    p!(write("const "));
+                    p!("const ");
                 }
                 p!(print(data))
             }
@@ -2059,33 +2043,23 @@ define_print_and_forward_display! {
             ty::PredicateAtom::RegionOutlives(predicate) => p!(print(predicate)),
             ty::PredicateAtom::TypeOutlives(predicate) => p!(print(predicate)),
             ty::PredicateAtom::Projection(predicate) => p!(print(predicate)),
-            ty::PredicateAtom::WellFormed(arg) => p!(print(arg), write(" well-formed")),
+            ty::PredicateAtom::WellFormed(arg) => p!(print(arg), " well-formed"),
             ty::PredicateAtom::ObjectSafe(trait_def_id) => {
-                p!(write("the trait `"),
-                print_def_path(trait_def_id, &[]),
-                write("` is object-safe"))
+                p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
             }
             ty::PredicateAtom::ClosureKind(closure_def_id, _closure_substs, kind) => {
-                p!(write("the closure `"),
+                p!("the closure `",
                 print_value_path(closure_def_id, &[]),
                 write("` implements the trait `{}`", kind))
             }
             ty::PredicateAtom::ConstEvaluatable(def, substs) => {
-                p!(write("the constant `"),
-                print_value_path(def.did, substs),
-                write("` can be evaluated"))
+                p!("the constant `", print_value_path(def.did, substs), "` can be evaluated")
             }
             ty::PredicateAtom::ConstEquate(c1, c2) => {
-                p!(write("the constant `"),
-                print(c1),
-                write("` equals `"),
-                print(c2),
-                write("`"))
+                p!("the constant `", print(c1), "` equals `", print(c2), "`")
             }
             ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
-                p!(write("the type `"),
-                print(ty),
-                write("` is found in the environment"))
+                p!("the type `", print(ty), "` is found in the environment")
             }
         }
     }