Rollup merge of #77190 - jakevossen5:master, r=eddyb

updated p! macro to accept literals

Closes #70948

Huge thanks @eddyb for helping me out!
This commit is contained in:
Yuki Okushi 2020-10-04 11:44:59 +09:00 committed by GitHub
commit 44ce38ac9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -28,6 +28,9 @@ use std::ops::{Deref, DerefMut};
use super::*;
macro_rules! p {
(@$lit:literal) => {
write!(scoped_cx!(), $lit)?
};
(@write($($data:expr),+)) => {
write!(scoped_cx!(), $($data),+)?
};
@ -37,8 +40,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 {
@ -478,7 +481,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 +498,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 +512,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 +528,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 +558,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 +570,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,7 +600,7 @@ 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);
@ -608,7 +611,7 @@ pub trait PrettyPrinter<'tcx>:
let mut first = true;
let mut is_sized = false;
p!(write("impl"));
p!("impl");
for predicate in bounds.predicates {
// Note: We can't use `to_opt_poly_trait_ref` here as `predicate`
// may contain unbound variables. We therefore do this manually.
@ -634,21 +637,21 @@ 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);
@ -661,7 +664,7 @@ pub trait PrettyPrinter<'tcx>:
p!(print_def_path(did, substs));
if substs.as_generator().is_valid() {
// Search for the first inference variable
p!(write(" upvar_tys=("));
p!(" upvar_tys=(");
let mut uninferred_ty =
substs.as_generator().upvar_tys().filter(|ty| ty.is_ty_infer());
if uninferred_ty.next().is_some() {
@ -669,15 +672,15 @@ pub trait PrettyPrinter<'tcx>:
} else {
self = self.comma_sep(substs.as_generator().upvar_tys())?;
}
p!(write(")"));
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,7 +693,7 @@ 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)));
@ -707,40 +710,40 @@ pub trait PrettyPrinter<'tcx>:
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)"));
p!(" closure_substs=(unavailable)");
} else {
p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
p!(
write(" closure_sig_as_fn_ptr_ty="),
" closure_sig_as_fn_ptr_ty=",
print(substs.as_closure().sig_as_fn_ptr_ty())
);
p!(write(" upvar_tys=("));
p!(" upvar_tys=(");
self = self.comma_sep(substs.as_closure().upvar_tys())?;
p!(write(")"));
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 +850,7 @@ pub trait PrettyPrinter<'tcx>:
for (_, def_id) in auto_traits {
if !first {
p!(write(" + "));
p!(" + ");
}
first = false;
@ -865,16 +868,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 +948,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)
}
@ -987,17 +990,17 @@ pub trait PrettyPrinter<'tcx>:
{
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::Raw { data: 0, .. }, ty::Bool) => p!("false"),
(Scalar::Raw { data: 1, .. }, ty::Bool) => p!("true"),
// Float
(Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F32)) => {
p!(write("{}f32", Single::from_bits(data)))
@ -1093,13 +1096,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 +1115,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);
}
@ -1149,7 +1152,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 +1176,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 +1197,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 +1227,7 @@ pub trait PrettyPrinter<'tcx>:
// fallback
p!(write("{:?}", ct));
if print_ty {
p!(write(": "), print(ty));
p!(": ", print(ty));
}
Ok(self)
}
@ -1637,7 +1640,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 +1706,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 +1719,7 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
}
}
p!(write("'_"));
p!("'_");
Ok(self)
}
@ -1847,7 +1850,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)
}
}
@ -1945,7 +1948,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 +1984,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 +1993,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 +2019,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 +2037,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 +2054,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 +2062,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")
}
}
}