1
Fork 0

Auto merge of #116815 - Nilstrieb:more-funny-pretty-printers, r=compiler-errors

Remove lots of generics from `ty::print`

All of these generics mostly resolve to the same thing, which means we can remove them, greatly simplifying the types involved in pretty printing and unlocking another simplification (that is not performed in this PR): Using `&mut self` instead of passing `self` through the return type.

cc `@eddyb` you probably know why it's like this, just checking in and making sure I didn't do anything bad

r? oli-obk
This commit is contained in:
bors 2023-10-18 09:57:07 +00:00
commit e8b8c78d84
9 changed files with 214 additions and 310 deletions

View file

@ -3,7 +3,7 @@ use rustc_hir::def_id::CrateNum;
use rustc_hir::definitions::DisambiguatedDefPathData; use rustc_hir::definitions::DisambiguatedDefPathData;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, self,
print::{PrettyPrinter, Print, Printer}, print::{PrettyPrinter, Print, PrintError, Printer},
GenericArg, GenericArgKind, Ty, TyCtxt, GenericArg, GenericArgKind, Ty, TyCtxt,
}; };
use std::fmt::Write; use std::fmt::Write;
@ -14,23 +14,15 @@ struct AbsolutePathPrinter<'tcx> {
} }
impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
type Error = std::fmt::Error;
type Path = Self;
type Region = Self;
type Type = Self;
type DynExistential = Self;
type Const = Self;
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> { fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> {
Ok(self) Ok(self)
} }
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> {
match *ty.kind() { match *ty.kind() {
// Types without identity. // Types without identity.
ty::Bool ty::Bool
@ -68,18 +60,18 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
} }
} }
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> { fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self, PrintError> {
self.pretty_print_const(ct, false) self.pretty_print_const(ct, false)
} }
fn print_dyn_existential( fn print_dyn_existential(
self, self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> { ) -> Result<Self, PrintError> {
self.pretty_print_dyn_existential(predicates) self.pretty_print_dyn_existential(predicates)
} }
fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { fn path_crate(mut self, cnum: CrateNum) -> Result<Self, PrintError> {
self.path.push_str(self.tcx.crate_name(cnum).as_str()); self.path.push_str(self.tcx.crate_name(cnum).as_str());
Ok(self) Ok(self)
} }
@ -88,17 +80,17 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
self, self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self.pretty_path_qualified(self_ty, trait_ref) self.pretty_path_qualified(self_ty, trait_ref)
} }
fn path_append_impl( fn path_append_impl(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
_disambiguated_data: &DisambiguatedDefPathData, _disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self.pretty_path_append_impl( self.pretty_path_append_impl(
|mut cx| { |mut cx| {
cx = print_prefix(cx)?; cx = print_prefix(cx)?;
@ -114,9 +106,9 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
fn path_append( fn path_append(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = print_prefix(self)?; self = print_prefix(self)?;
write!(self.path, "::{}", disambiguated_data.data).unwrap(); write!(self.path, "::{}", disambiguated_data.data).unwrap();
@ -126,9 +118,9 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
fn path_generic_args( fn path_generic_args(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = print_prefix(self)?; self = print_prefix(self)?;
let args = let args =
args.iter().cloned().filter(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_))); args.iter().cloned().filter(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_)));
@ -144,9 +136,9 @@ impl<'tcx> PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
fn should_print_region(&self, _region: ty::Region<'_>) -> bool { fn should_print_region(&self, _region: ty::Region<'_>) -> bool {
false false
} }
fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error> fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, PrintError>
where where
T: Print<'tcx, Self, Output = Self, Error = Self::Error>, T: Print<'tcx, Self>,
{ {
if let Some(first) = elems.next() { if let Some(first) = elems.next() {
self = first.print(self)?; self = first.print(self)?;
@ -160,8 +152,8 @@ impl<'tcx> PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
fn generic_delimiters( fn generic_delimiters(
mut self, mut self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>, f: impl FnOnce(Self) -> Result<Self, PrintError>,
) -> Result<Self, Self::Error> { ) -> Result<Self, PrintError> {
write!(self, "<")?; write!(self, "<")?;
self = f(self)?; self = f(self)?;

View file

@ -67,7 +67,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_middle::dep_graph::DepContext; use rustc_middle::dep_graph::DepContext;
use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable, self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable,
@ -580,76 +580,68 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
struct AbsolutePathPrinter<'tcx> { struct AbsolutePathPrinter<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
segments: Vec<String>,
} }
struct NonTrivialPath;
impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
type Error = NonTrivialPath;
type Path = Vec<String>;
type Region = !;
type Type = !;
type DynExistential = !;
type Const = !;
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> { fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> {
Err(NonTrivialPath) Err(fmt::Error)
} }
fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { fn print_type(self, _ty: Ty<'tcx>) -> Result<Self, PrintError> {
Err(NonTrivialPath) Err(fmt::Error)
} }
fn print_dyn_existential( fn print_dyn_existential(
self, self,
_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> { ) -> Result<Self, PrintError> {
Err(NonTrivialPath) Err(fmt::Error)
} }
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> { fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self, PrintError> {
Err(NonTrivialPath) Err(fmt::Error)
} }
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { fn path_crate(mut self, cnum: CrateNum) -> Result<Self, PrintError> {
Ok(vec![self.tcx.crate_name(cnum).to_string()]) self.segments = vec![self.tcx.crate_name(cnum).to_string()];
Ok(self)
} }
fn path_qualified( fn path_qualified(
self, self,
_self_ty: Ty<'tcx>, _self_ty: Ty<'tcx>,
_trait_ref: Option<ty::TraitRef<'tcx>>, _trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
Err(NonTrivialPath) Err(fmt::Error)
} }
fn path_append_impl( fn path_append_impl(
self, self,
_print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, _print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
_disambiguated_data: &DisambiguatedDefPathData, _disambiguated_data: &DisambiguatedDefPathData,
_self_ty: Ty<'tcx>, _self_ty: Ty<'tcx>,
_trait_ref: Option<ty::TraitRef<'tcx>>, _trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
Err(NonTrivialPath) Err(fmt::Error)
} }
fn path_append( fn path_append(
self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let mut path = print_prefix(self)?; self = print_prefix(self)?;
path.push(disambiguated_data.to_string()); self.segments.push(disambiguated_data.to_string());
Ok(path) Ok(self)
} }
fn path_generic_args( fn path_generic_args(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
_args: &[GenericArg<'tcx>], _args: &[GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
print_prefix(self) print_prefix(self)
} }
} }
@ -659,12 +651,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// are from a local module we could have false positives, e.g. // are from a local module we could have false positives, e.g.
// let _ = [{struct Foo; Foo}, {struct Foo; Foo}]; // let _ = [{struct Foo; Foo}, {struct Foo; Foo}];
if did1.krate != did2.krate { if did1.krate != did2.krate {
let abs_path = let abs_path = |def_id| {
|def_id| AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]); AbsolutePathPrinter { tcx: self.tcx, segments: vec![] }
.print_def_path(def_id, &[])
.map(|p| p.segments)
};
// We compare strings because DefPath can be different // We compare strings because DefPath can be different
// for imported and non-imported crates // for imported and non-imported crates
let same_path = || -> Result<_, NonTrivialPath> { let same_path = || -> Result<_, PrintError> {
Ok(self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2) Ok(self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2)
|| abs_path(did1)? == abs_path(did2)?) || abs_path(did1)? == abs_path(did2)?)
}; };

View file

@ -28,7 +28,7 @@ pub struct Highlighted<'tcx, T> {
impl<'tcx, T> IntoDiagnosticArg for Highlighted<'tcx, T> impl<'tcx, T> IntoDiagnosticArg for Highlighted<'tcx, T>
where where
T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>, Error = fmt::Error, Output = FmtPrinter<'a, 'tcx>>, T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>,
{ {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
rustc_errors::DiagnosticArgValue::Str(self.to_string().into()) rustc_errors::DiagnosticArgValue::Str(self.to_string().into())
@ -43,7 +43,7 @@ impl<'tcx, T> Highlighted<'tcx, T> {
impl<'tcx, T> fmt::Display for Highlighted<'tcx, T> impl<'tcx, T> fmt::Display for Highlighted<'tcx, T>
where where
T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>, Error = fmt::Error, Output = FmtPrinter<'a, 'tcx>>, T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>,
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS); let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS);

View file

@ -31,7 +31,7 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::middle::stability; use rustc_middle::middle::stability;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::{with_no_trimmed_paths, PrintError};
use rustc_middle::ty::{self, print::Printer, GenericArg, RegisteredTools, Ty, TyCtxt}; use rustc_middle::ty::{self, print::Printer, GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_session::config::ExpectedValues; use rustc_session::config::ExpectedValues;
use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId}; use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId};
@ -1200,51 +1200,45 @@ impl<'tcx> LateContext<'tcx> {
/// } /// }
/// ``` /// ```
pub fn get_def_path(&self, def_id: DefId) -> Vec<Symbol> { pub fn get_def_path(&self, def_id: DefId) -> Vec<Symbol> {
pub struct AbsolutePathPrinter<'tcx> { struct AbsolutePathPrinter<'tcx> {
pub tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
path: Vec<Symbol>,
} }
impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
type Error = !;
type Path = Vec<Symbol>;
type Region = ();
type Type = ();
type DynExistential = ();
type Const = ();
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> { fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> {
Ok(()) Ok(self)
} }
fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { fn print_type(self, _ty: Ty<'tcx>) -> Result<Self, PrintError> {
Ok(()) Ok(self)
} }
fn print_dyn_existential( fn print_dyn_existential(
self, self,
_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> { ) -> Result<Self, PrintError> {
Ok(()) Ok(self)
} }
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> { fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self, PrintError> {
Ok(()) Ok(self)
} }
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { fn path_crate(mut self, cnum: CrateNum) -> Result<Self, PrintError> {
Ok(vec![self.tcx.crate_name(cnum)]) self.path = vec![self.tcx.crate_name(cnum)];
Ok(self)
} }
fn path_qualified( fn path_qualified(
self, mut self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
if trait_ref.is_none() { if trait_ref.is_none() {
if let ty::Adt(def, args) = self_ty.kind() { if let ty::Adt(def, args) = self_ty.kind() {
return self.print_def_path(def.did(), args); return self.print_def_path(def.did(), args);
@ -1253,24 +1247,25 @@ impl<'tcx> LateContext<'tcx> {
// This shouldn't ever be needed, but just in case: // This shouldn't ever be needed, but just in case:
with_no_trimmed_paths!({ with_no_trimmed_paths!({
Ok(vec![match trait_ref { self.path = vec![match trait_ref {
Some(trait_ref) => Symbol::intern(&format!("{trait_ref:?}")), Some(trait_ref) => Symbol::intern(&format!("{trait_ref:?}")),
None => Symbol::intern(&format!("<{self_ty}>")), None => Symbol::intern(&format!("<{self_ty}>")),
}]) }];
Ok(self)
}) })
} }
fn path_append_impl( fn path_append_impl(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
_disambiguated_data: &DisambiguatedDefPathData, _disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let mut path = print_prefix(self)?; let mut path = print_prefix(self)?;
// This shouldn't ever be needed, but just in case: // This shouldn't ever be needed, but just in case:
path.push(match trait_ref { path.path.push(match trait_ref {
Some(trait_ref) => { Some(trait_ref) => {
with_no_trimmed_paths!(Symbol::intern(&format!( with_no_trimmed_paths!(Symbol::intern(&format!(
"<impl {} for {}>", "<impl {} for {}>",
@ -1288,9 +1283,9 @@ impl<'tcx> LateContext<'tcx> {
fn path_append( fn path_append(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let mut path = print_prefix(self)?; let mut path = print_prefix(self)?;
// Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs.
@ -1298,20 +1293,23 @@ impl<'tcx> LateContext<'tcx> {
return Ok(path); return Ok(path);
} }
path.push(Symbol::intern(&disambiguated_data.data.to_string())); path.path.push(Symbol::intern(&disambiguated_data.data.to_string()));
Ok(path) Ok(path)
} }
fn path_generic_args( fn path_generic_args(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
_args: &[GenericArg<'tcx>], _args: &[GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
print_prefix(self) print_prefix(self)
} }
} }
AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]).unwrap() AbsolutePathPrinter { tcx: self.tcx, path: vec![] }
.print_def_path(def_id, &[])
.unwrap()
.path
} }
/// Returns the associated type `name` for `self_ty` as an implementation of `trait_id`. /// Returns the associated type `name` for `self_ty` as an implementation of `trait_id`.

View file

@ -10,13 +10,12 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
mod pretty; mod pretty;
pub use self::pretty::*; pub use self::pretty::*;
pub type PrintError = std::fmt::Error;
// FIXME(eddyb) false positive, the lifetime parameters are used with `P: Printer<...>`. // FIXME(eddyb) false positive, the lifetime parameters are used with `P: Printer<...>`.
#[allow(unused_lifetimes)] #[allow(unused_lifetimes)]
pub trait Print<'tcx, P> { pub trait Print<'tcx, P> {
type Output; fn print(&self, cx: P) -> Result<P, PrintError>;
type Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error>;
} }
/// Interface for outputting user-facing "type-system entities" /// Interface for outputting user-facing "type-system entities"
@ -29,21 +28,13 @@ pub trait Print<'tcx, P> {
// //
// FIXME(eddyb) find a better name; this is more general than "printing". // FIXME(eddyb) find a better name; this is more general than "printing".
pub trait Printer<'tcx>: Sized { pub trait Printer<'tcx>: Sized {
type Error;
type Path;
type Region;
type Type;
type DynExistential;
type Const;
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
fn print_def_path( fn print_def_path(
self, self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self.default_print_def_path(def_id, args) self.default_print_def_path(def_id, args)
} }
@ -53,48 +44,48 @@ pub trait Printer<'tcx>: Sized {
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self.default_print_impl_path(impl_def_id, args, self_ty, trait_ref) self.default_print_impl_path(impl_def_id, args, self_ty, trait_ref)
} }
fn print_region(self, region: ty::Region<'tcx>) -> Result<Self::Region, Self::Error>; fn print_region(self, region: ty::Region<'tcx>) -> Result<Self, PrintError>;
fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>; fn print_type(self, ty: Ty<'tcx>) -> Result<Self, PrintError>;
fn print_dyn_existential( fn print_dyn_existential(
self, self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error>; ) -> Result<Self, PrintError>;
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error>; fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self, PrintError>;
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error>; fn path_crate(self, cnum: CrateNum) -> Result<Self, PrintError>;
fn path_qualified( fn path_qualified(
self, self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error>; ) -> Result<Self, PrintError>;
fn path_append_impl( fn path_append_impl(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error>; ) -> Result<Self, PrintError>;
fn path_append( fn path_append(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error>; ) -> Result<Self, PrintError>;
fn path_generic_args( fn path_generic_args(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error>; ) -> Result<Self, PrintError>;
// Defaults (should not be overridden): // Defaults (should not be overridden):
@ -103,7 +94,7 @@ pub trait Printer<'tcx>: Sized {
self, self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let key = self.tcx().def_key(def_id); let key = self.tcx().def_key(def_id);
debug!(?key); debug!(?key);
@ -194,7 +185,7 @@ pub trait Printer<'tcx>: Sized {
_args: &'tcx [GenericArg<'tcx>], _args: &'tcx [GenericArg<'tcx>],
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
impl_trait_ref: Option<ty::TraitRef<'tcx>>, impl_trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
debug!( debug!(
"default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", "default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}",
impl_def_id, self_ty, impl_trait_ref impl_def_id, self_ty, impl_trait_ref
@ -295,34 +286,25 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
} }
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'tcx> { impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'tcx> {
type Output = P::Region; fn print(&self, cx: P) -> Result<P, PrintError> {
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_region(*self) cx.print_region(*self)
} }
} }
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> { impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
type Output = P::Type; fn print(&self, cx: P) -> Result<P, PrintError> {
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_type(*self) cx.print_type(*self)
} }
} }
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
type Output = P::DynExistential; fn print(&self, cx: P) -> Result<P, PrintError> {
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_dyn_existential(self) cx.print_dyn_existential(self)
} }
} }
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> { impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> {
type Output = P::Const; fn print(&self, cx: P) -> Result<P, PrintError> {
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_const(*self) cx.print_const(*self)
} }
} }

View file

@ -205,29 +205,19 @@ impl<'tcx> RegionHighlightMode<'tcx> {
} }
/// Trait for printers that pretty-print using `fmt::Write` to the printer. /// Trait for printers that pretty-print using `fmt::Write` to the printer.
pub trait PrettyPrinter<'tcx>: pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
> + fmt::Write
{
/// Like `print_def_path` but for value paths. /// Like `print_def_path` but for value paths.
fn print_value_path( fn print_value_path(
self, self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self.print_def_path(def_id, args) self.print_def_path(def_id, args)
} }
fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error> fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, PrintError>
where where
T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
{ {
value.as_ref().skip_binder().print(self) value.as_ref().skip_binder().print(self)
} }
@ -236,17 +226,17 @@ pub trait PrettyPrinter<'tcx>:
self, self,
value: &ty::Binder<'tcx, T>, value: &ty::Binder<'tcx, T>,
f: F, f: F,
) -> Result<Self, Self::Error> ) -> Result<Self, PrintError>
where where
T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
{ {
f(value.as_ref().skip_binder(), self) f(value.as_ref().skip_binder(), self)
} }
/// Prints comma-separated elements. /// Prints comma-separated elements.
fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error> fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, PrintError>
where where
T: Print<'tcx, Self, Output = Self, Error = Self::Error>, T: Print<'tcx, Self>,
{ {
if let Some(first) = elems.next() { if let Some(first) = elems.next() {
self = first.print(self)?; self = first.print(self)?;
@ -261,10 +251,10 @@ pub trait PrettyPrinter<'tcx>:
/// Prints `{f: t}` or `{f as t}` depending on the `cast` argument /// Prints `{f: t}` or `{f as t}` depending on the `cast` argument
fn typed_value( fn typed_value(
mut self, mut self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>, f: impl FnOnce(Self) -> Result<Self, PrintError>,
t: impl FnOnce(Self) -> Result<Self, Self::Error>, t: impl FnOnce(Self) -> Result<Self, PrintError>,
conversion: &str, conversion: &str,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
self.write_str("{")?; self.write_str("{")?;
self = f(self)?; self = f(self)?;
self.write_str(conversion)?; self.write_str(conversion)?;
@ -276,8 +266,8 @@ pub trait PrettyPrinter<'tcx>:
/// Prints `<...>` around what `f` prints. /// Prints `<...>` around what `f` prints.
fn generic_delimiters( fn generic_delimiters(
self, self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>, f: impl FnOnce(Self) -> Result<Self, PrintError>,
) -> Result<Self, Self::Error>; ) -> Result<Self, PrintError>;
/// Returns `true` if the region should be printed in /// Returns `true` if the region should be printed in
/// optional positions, e.g., `&'a T` or `dyn Tr + 'b`. /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
@ -291,7 +281,7 @@ pub trait PrettyPrinter<'tcx>:
/// If possible, this returns a global path resolving to `def_id` that is visible /// If possible, this returns a global path resolving to `def_id` that is visible
/// from at least one local module, and returns `true`. If the crate defining `def_id` is /// from at least one local module, and returns `true`. If the crate defining `def_id` is
/// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), Self::Error> { fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), PrintError> {
if NO_VISIBLE_PATH.with(|flag| flag.get()) { if NO_VISIBLE_PATH.with(|flag| flag.get()) {
return Ok((self, false)); return Ok((self, false));
} }
@ -305,10 +295,7 @@ pub trait PrettyPrinter<'tcx>:
// For enum variants, if they have an unique name, then we only print the name, otherwise we // For enum variants, if they have an unique name, then we only print the name, otherwise we
// print the enum name and the variant name. Otherwise, we do not print anything and let the // print the enum name and the variant name. Otherwise, we do not print anything and let the
// caller use the `print_def_path` fallback. // caller use the `print_def_path` fallback.
fn force_print_trimmed_def_path( fn force_print_trimmed_def_path(mut self, def_id: DefId) -> Result<(Self, bool), PrintError> {
mut self,
def_id: DefId,
) -> Result<(Self::Path, bool), Self::Error> {
let key = self.tcx().def_key(def_id); let key = self.tcx().def_key(def_id);
let visible_parent_map = self.tcx().visible_parent_map(()); let visible_parent_map = self.tcx().visible_parent_map(());
let kind = self.tcx().def_kind(def_id); let kind = self.tcx().def_kind(def_id);
@ -378,10 +365,7 @@ pub trait PrettyPrinter<'tcx>:
} }
/// Try to see if this path can be trimmed to a unique symbol name. /// Try to see if this path can be trimmed to a unique symbol name.
fn try_print_trimmed_def_path( fn try_print_trimmed_def_path(mut self, def_id: DefId) -> Result<(Self, bool), PrintError> {
mut self,
def_id: DefId,
) -> Result<(Self::Path, bool), Self::Error> {
if FORCE_TRIMMED_PATH.with(|flag| flag.get()) { if FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
let (s, trimmed) = self.force_print_trimmed_def_path(def_id)?; let (s, trimmed) = self.force_print_trimmed_def_path(def_id)?;
if trimmed { if trimmed {
@ -423,7 +407,7 @@ pub trait PrettyPrinter<'tcx>:
mut self, mut self,
def_id: DefId, def_id: DefId,
callers: &mut Vec<DefId>, callers: &mut Vec<DefId>,
) -> Result<(Self, bool), Self::Error> { ) -> Result<(Self, bool), PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
debug!("try_print_visible_def_path: def_id={:?}", def_id); debug!("try_print_visible_def_path: def_id={:?}", def_id);
@ -595,7 +579,7 @@ pub trait PrettyPrinter<'tcx>:
self, self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
if trait_ref.is_none() { if trait_ref.is_none() {
// Inherent impls. Try to print `Foo::bar` for an inherent // Inherent impls. Try to print `Foo::bar` for an inherent
// impl on `Foo`, but fallback to `<Foo>::bar` if self-type is // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
@ -629,10 +613,10 @@ pub trait PrettyPrinter<'tcx>:
fn pretty_path_append_impl( fn pretty_path_append_impl(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = print_prefix(self)?; self = print_prefix(self)?;
self.generic_delimiters(|mut cx| { self.generic_delimiters(|mut cx| {
@ -648,7 +632,7 @@ pub trait PrettyPrinter<'tcx>:
}) })
} }
fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
match *ty.kind() { match *ty.kind() {
@ -919,7 +903,7 @@ pub trait PrettyPrinter<'tcx>:
mut self, mut self,
def_id: DefId, def_id: DefId,
args: &'tcx ty::List<ty::GenericArg<'tcx>>, args: &'tcx ty::List<ty::GenericArg<'tcx>>,
) -> Result<Self::Type, Self::Error> { ) -> Result<Self, PrintError> {
let tcx = self.tcx(); let tcx = self.tcx();
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
@ -1189,7 +1173,7 @@ pub trait PrettyPrinter<'tcx>:
fn pretty_print_inherent_projection( fn pretty_print_inherent_projection(
self, self,
alias_ty: &ty::AliasTy<'tcx>, alias_ty: &ty::AliasTy<'tcx>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let def_key = self.tcx().def_key(alias_ty.def_id); let def_key = self.tcx().def_key(alias_ty.def_id);
self.path_generic_args( self.path_generic_args(
|cx| { |cx| {
@ -1213,7 +1197,7 @@ pub trait PrettyPrinter<'tcx>:
fn pretty_print_dyn_existential( fn pretty_print_dyn_existential(
mut self, mut self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> { ) -> Result<Self, PrintError> {
// Generate the main trait ref, including associated types. // Generate the main trait ref, including associated types.
let mut first = true; let mut first = true;
@ -1306,7 +1290,7 @@ pub trait PrettyPrinter<'tcx>:
inputs: &[Ty<'tcx>], inputs: &[Ty<'tcx>],
c_variadic: bool, c_variadic: bool,
output: Ty<'tcx>, output: Ty<'tcx>,
) -> Result<Self, Self::Error> { ) -> Result<Self, PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
p!("(", comma_sep(inputs.iter().copied())); p!("(", comma_sep(inputs.iter().copied()));
@ -1328,7 +1312,7 @@ pub trait PrettyPrinter<'tcx>:
mut self, mut self,
ct: ty::Const<'tcx>, ct: ty::Const<'tcx>,
print_ty: bool, print_ty: bool,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
if self.should_print_verbose() { if self.should_print_verbose() {
@ -1404,11 +1388,7 @@ pub trait PrettyPrinter<'tcx>:
Ok(self) Ok(self)
} }
fn pretty_print_const_scalar( fn pretty_print_const_scalar(self, scalar: Scalar, ty: Ty<'tcx>) -> Result<Self, PrintError> {
self,
scalar: Scalar,
ty: Ty<'tcx>,
) -> Result<Self::Const, Self::Error> {
match scalar { match scalar {
Scalar::Ptr(ptr, _size) => self.pretty_print_const_scalar_ptr(ptr, ty), Scalar::Ptr(ptr, _size) => self.pretty_print_const_scalar_ptr(ptr, ty),
Scalar::Int(int) => { Scalar::Int(int) => {
@ -1421,7 +1401,7 @@ pub trait PrettyPrinter<'tcx>:
mut self, mut self,
ptr: Pointer, ptr: Pointer,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
let (alloc_id, offset) = ptr.into_parts(); let (alloc_id, offset) = ptr.into_parts();
@ -1483,7 +1463,7 @@ pub trait PrettyPrinter<'tcx>:
int: ScalarInt, int: ScalarInt,
ty: Ty<'tcx>, ty: Ty<'tcx>,
print_ty: bool, print_ty: bool,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
match ty.kind() { match ty.kind() {
@ -1545,7 +1525,7 @@ pub trait PrettyPrinter<'tcx>:
self, self,
_: Pointer<Prov>, _: Pointer<Prov>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
self.typed_value( self.typed_value(
|mut this| { |mut this| {
this.write_str("&_")?; this.write_str("&_")?;
@ -1556,7 +1536,7 @@ pub trait PrettyPrinter<'tcx>:
) )
} }
fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> { fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self, PrintError> {
write!(self, "b\"{}\"", byte_str.escape_ascii())?; write!(self, "b\"{}\"", byte_str.escape_ascii())?;
Ok(self) Ok(self)
} }
@ -1566,7 +1546,7 @@ pub trait PrettyPrinter<'tcx>:
valtree: ty::ValTree<'tcx>, valtree: ty::ValTree<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
print_ty: bool, print_ty: bool,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
if self.should_print_verbose() { if self.should_print_verbose() {
@ -1689,7 +1669,7 @@ pub trait PrettyPrinter<'tcx>:
fn pretty_closure_as_impl( fn pretty_closure_as_impl(
mut self, mut self,
closure: ty::ClosureArgs<'tcx>, closure: ty::ClosureArgs<'tcx>,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
let sig = closure.sig(); let sig = closure.sig();
let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn); let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
@ -1862,14 +1842,6 @@ impl fmt::Write for FmtPrinter<'_, '_> {
} }
impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
type Error = fmt::Error;
type Path = Self;
type Region = Self;
type Type = Self;
type DynExistential = Self;
type Const = Self;
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
@ -1878,7 +1850,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
mut self, mut self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
define_scoped_cx!(self); define_scoped_cx!(self);
if args.is_empty() { if args.is_empty() {
@ -1933,11 +1905,11 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
self.default_print_def_path(def_id, args) self.default_print_def_path(def_id, args)
} }
fn print_region(self, region: ty::Region<'tcx>) -> Result<Self::Region, Self::Error> { fn print_region(self, region: ty::Region<'tcx>) -> Result<Self, PrintError> {
self.pretty_print_region(region) self.pretty_print_region(region)
} }
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> {
if self.type_length_limit.value_within_limit(self.printed_type_count) { if self.type_length_limit.value_within_limit(self.printed_type_count) {
self.printed_type_count += 1; self.printed_type_count += 1;
self.pretty_print_type(ty) self.pretty_print_type(ty)
@ -1951,15 +1923,15 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
fn print_dyn_existential( fn print_dyn_existential(
self, self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> { ) -> Result<Self, PrintError> {
self.pretty_print_dyn_existential(predicates) self.pretty_print_dyn_existential(predicates)
} }
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> { fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self, PrintError> {
self.pretty_print_const(ct, false) self.pretty_print_const(ct, false)
} }
fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { fn path_crate(mut self, cnum: CrateNum) -> Result<Self, PrintError> {
self.empty_path = true; self.empty_path = true;
if cnum == LOCAL_CRATE { if cnum == LOCAL_CRATE {
if self.tcx.sess.at_least_rust_2018() { if self.tcx.sess.at_least_rust_2018() {
@ -1980,7 +1952,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
mut self, mut self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = self.pretty_path_qualified(self_ty, trait_ref)?; self = self.pretty_path_qualified(self_ty, trait_ref)?;
self.empty_path = false; self.empty_path = false;
Ok(self) Ok(self)
@ -1988,11 +1960,11 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
fn path_append_impl( fn path_append_impl(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
_disambiguated_data: &DisambiguatedDefPathData, _disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = self.pretty_path_append_impl( self = self.pretty_path_append_impl(
|mut cx| { |mut cx| {
cx = print_prefix(cx)?; cx = print_prefix(cx)?;
@ -2011,9 +1983,9 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
fn path_append( fn path_append(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = print_prefix(self)?; self = print_prefix(self)?;
// Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs.
@ -2042,9 +2014,9 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
fn path_generic_args( fn path_generic_args(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = print_prefix(self)?; self = print_prefix(self)?;
let tcx = self.tcx; let tcx = self.tcx;
@ -2101,7 +2073,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
mut self, mut self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let was_in_value = std::mem::replace(&mut self.in_value, true); let was_in_value = std::mem::replace(&mut self.in_value, true);
self = self.print_def_path(def_id, args)?; self = self.print_def_path(def_id, args)?;
self.in_value = was_in_value; self.in_value = was_in_value;
@ -2109,30 +2081,30 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
Ok(self) Ok(self)
} }
fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error> fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, PrintError>
where where
T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
{ {
self.pretty_in_binder(value) self.pretty_in_binder(value)
} }
fn wrap_binder<T, C: FnOnce(&T, Self) -> Result<Self, Self::Error>>( fn wrap_binder<T, C: FnOnce(&T, Self) -> Result<Self, PrintError>>(
self, self,
value: &ty::Binder<'tcx, T>, value: &ty::Binder<'tcx, T>,
f: C, f: C,
) -> Result<Self, Self::Error> ) -> Result<Self, PrintError>
where where
T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
{ {
self.pretty_wrap_binder(value, f) self.pretty_wrap_binder(value, f)
} }
fn typed_value( fn typed_value(
mut self, mut self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>, f: impl FnOnce(Self) -> Result<Self, PrintError>,
t: impl FnOnce(Self) -> Result<Self, Self::Error>, t: impl FnOnce(Self) -> Result<Self, PrintError>,
conversion: &str, conversion: &str,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
self.write_str("{")?; self.write_str("{")?;
self = f(self)?; self = f(self)?;
self.write_str(conversion)?; self.write_str(conversion)?;
@ -2145,8 +2117,8 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
fn generic_delimiters( fn generic_delimiters(
mut self, mut self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>, f: impl FnOnce(Self) -> Result<Self, PrintError>,
) -> Result<Self, Self::Error> { ) -> Result<Self, PrintError> {
write!(self, "<")?; write!(self, "<")?;
let was_in_value = std::mem::replace(&mut self.in_value, false); let was_in_value = std::mem::replace(&mut self.in_value, false);
@ -2206,7 +2178,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
self, self,
p: Pointer<Prov>, p: Pointer<Prov>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<Self::Const, Self::Error> { ) -> Result<Self, PrintError> {
let print = |mut this: Self| { let print = |mut this: Self| {
define_scoped_cx!(this); define_scoped_cx!(this);
if this.print_alloc_ids { if this.print_alloc_ids {
@ -2371,7 +2343,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
value: &ty::Binder<'tcx, T>, value: &ty::Binder<'tcx, T>,
) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error> ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
where where
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
{ {
fn name_by_region_index( fn name_by_region_index(
index: usize, index: usize,
@ -2541,7 +2513,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error> pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
where where
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
{ {
let old_region_index = self.region_index; let old_region_index = self.region_index;
let (new, new_value, _) = self.name_all_regions(value)?; let (new, new_value, _) = self.name_all_regions(value)?;
@ -2557,7 +2529,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
f: C, f: C,
) -> Result<Self, fmt::Error> ) -> Result<Self, fmt::Error>
where where
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
{ {
let old_region_index = self.region_index; let old_region_index = self.region_index;
let (new, new_value, _) = self.name_all_regions(value)?; let (new, new_value, _) = self.name_all_regions(value)?;
@ -2622,24 +2594,19 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T> impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T>
where where
T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<TyCtxt<'tcx>>, T: Print<'tcx, P> + TypeFoldable<TyCtxt<'tcx>>,
{ {
type Output = P; fn print(&self, cx: P) -> Result<P, PrintError> {
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.in_binder(self) cx.in_binder(self)
} }
} }
impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<T, U> impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<T, U>
where where
T: Print<'tcx, P, Output = P, Error = P::Error>, T: Print<'tcx, P>,
U: Print<'tcx, P, Output = P, Error = P::Error>, U: Print<'tcx, P>,
{ {
type Output = P; fn print(&self, mut cx: P) -> Result<P, PrintError> {
type Error = P::Error;
fn print(&self, mut cx: P) -> Result<Self::Output, Self::Error> {
define_scoped_cx!(cx); define_scoped_cx!(cx);
p!(print(self.0), ": ", print(self.1)); p!(print(self.0), ": ", print(self.1));
Ok(cx) Ok(cx)
@ -2666,9 +2633,7 @@ macro_rules! forward_display_to_print {
macro_rules! define_print_and_forward_display { macro_rules! define_print_and_forward_display {
(($self:ident, $cx:ident): $($ty:ty $print:block)+) => { (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
$(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty { $(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
type Output = P; fn print(&$self, $cx: P) -> Result<P, PrintError> {
type Error = fmt::Error;
fn print(&$self, $cx: P) -> Result<Self::Output, Self::Error> {
#[allow(unused_mut)] #[allow(unused_mut)]
let mut $cx = $cx; let mut $cx = $cx;
define_scoped_cx!($cx); define_scoped_cx!($cx);

View file

@ -1,7 +1,7 @@
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_hir::def_id::CrateNum; use rustc_hir::def_id::CrateNum;
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::ty::print::{PrettyPrinter, Print, Printer}; use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_middle::ty::{GenericArg, GenericArgKind};
use rustc_middle::util::common::record_time; use rustc_middle::util::common::record_time;
@ -200,23 +200,15 @@ struct SymbolPrinter<'tcx> {
// symbol names should have their own printing machinery. // symbol names should have their own printing machinery.
impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> { impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
type Error = fmt::Error;
type Path = Self;
type Region = Self;
type Type = Self;
type DynExistential = Self;
type Const = Self;
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> { fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> {
Ok(self) Ok(self)
} }
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> {
match *ty.kind() { match *ty.kind() {
// Print all nominal types as paths (unlike `pretty_print_type`). // Print all nominal types as paths (unlike `pretty_print_type`).
ty::FnDef(def_id, args) ty::FnDef(def_id, args)
@ -250,7 +242,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
fn print_dyn_existential( fn print_dyn_existential(
mut self, mut self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> { ) -> Result<Self, PrintError> {
let mut first = true; let mut first = true;
for p in predicates { for p in predicates {
if !first { if !first {
@ -262,7 +254,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
Ok(self) Ok(self)
} }
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> { fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self, PrintError> {
// only print integers // only print integers
match (ct.kind(), ct.ty().kind()) { match (ct.kind(), ct.ty().kind()) {
(ty::ConstKind::Value(ty::ValTree::Leaf(scalar)), ty::Int(_) | ty::Uint(_)) => { (ty::ConstKind::Value(ty::ValTree::Leaf(scalar)), ty::Int(_) | ty::Uint(_)) => {
@ -280,7 +272,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
Ok(self) Ok(self)
} }
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { fn path_crate(self, cnum: CrateNum) -> Result<Self, PrintError> {
self.write_str(self.tcx.crate_name(cnum).as_str())?; self.write_str(self.tcx.crate_name(cnum).as_str())?;
Ok(self) Ok(self)
} }
@ -288,7 +280,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
self, self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
// Similar to `pretty_path_qualified`, but for the other // Similar to `pretty_path_qualified`, but for the other
// types that are printed as paths (see `print_type` above). // types that are printed as paths (see `print_type` above).
match self_ty.kind() { match self_ty.kind() {
@ -304,11 +296,11 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
fn path_append_impl( fn path_append_impl(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
_disambiguated_data: &DisambiguatedDefPathData, _disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self.pretty_path_append_impl( self.pretty_path_append_impl(
|mut cx| { |mut cx| {
cx = print_prefix(cx)?; cx = print_prefix(cx)?;
@ -328,9 +320,9 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
} }
fn path_append( fn path_append(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = print_prefix(self)?; self = print_prefix(self)?;
// Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs.
@ -351,9 +343,9 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
} }
fn path_generic_args( fn path_generic_args(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
self = print_prefix(self)?; self = print_prefix(self)?;
let args = let args =
@ -371,9 +363,9 @@ impl<'tcx> PrettyPrinter<'tcx> for &mut SymbolPrinter<'tcx> {
fn should_print_region(&self, _region: ty::Region<'_>) -> bool { fn should_print_region(&self, _region: ty::Region<'_>) -> bool {
false false
} }
fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error> fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, PrintError>
where where
T: Print<'tcx, Self, Output = Self, Error = Self::Error>, T: Print<'tcx, Self>,
{ {
if let Some(first) = elems.next() { if let Some(first) = elems.next() {
self = first.print(self)?; self = first.print(self)?;
@ -387,8 +379,8 @@ impl<'tcx> PrettyPrinter<'tcx> for &mut SymbolPrinter<'tcx> {
fn generic_delimiters( fn generic_delimiters(
mut self, mut self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>, f: impl FnOnce(Self) -> Result<Self, PrintError>,
) -> Result<Self, Self::Error> { ) -> Result<Self, PrintError> {
write!(self, "<")?; write!(self, "<")?;
let kept_within_component = mem::replace(&mut self.keep_within_component, true); let kept_within_component = mem::replace(&mut self.keep_within_component, true);

View file

@ -6,7 +6,7 @@ use rustc_hir::def::CtorKind;
use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::print::{Print, Printer}; use rustc_middle::ty::print::{Print, PrintError, Printer};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, TypeVisitableExt,
UintTy, UintTy,
@ -181,11 +181,11 @@ impl<'tcx> SymbolMangler<'tcx> {
fn path_append_ns<'a>( fn path_append_ns<'a>(
mut self: &'a mut Self, mut self: &'a mut Self,
print_prefix: impl FnOnce(&'a mut Self) -> Result<&'a mut Self, !>, print_prefix: impl FnOnce(&'a mut Self) -> Result<&'a mut Self, PrintError>,
ns: char, ns: char,
disambiguator: u64, disambiguator: u64,
name: &str, name: &str,
) -> Result<&'a mut Self, !> { ) -> Result<&'a mut Self, PrintError> {
self.push("N"); self.push("N");
self.out.push(ns); self.out.push(ns);
self = print_prefix(self)?; self = print_prefix(self)?;
@ -194,7 +194,7 @@ impl<'tcx> SymbolMangler<'tcx> {
Ok(self) Ok(self)
} }
fn print_backref(&mut self, i: usize) -> Result<&mut Self, !> { fn print_backref(&mut self, i: usize) -> Result<&mut Self, PrintError> {
self.push("B"); self.push("B");
self.push_integer_62((i - self.start_offset) as u64); self.push_integer_62((i - self.start_offset) as u64);
Ok(self) Ok(self)
@ -203,8 +203,8 @@ impl<'tcx> SymbolMangler<'tcx> {
fn in_binder<'a, T>( fn in_binder<'a, T>(
mut self: &'a mut Self, mut self: &'a mut Self,
value: &ty::Binder<'tcx, T>, value: &ty::Binder<'tcx, T>,
print_value: impl FnOnce(&'a mut Self, &T) -> Result<&'a mut Self, !>, print_value: impl FnOnce(&'a mut Self, &T) -> Result<&'a mut Self, PrintError>,
) -> Result<&'a mut Self, !> ) -> Result<&'a mut Self, PrintError>
where where
T: TypeVisitable<TyCtxt<'tcx>>, T: TypeVisitable<TyCtxt<'tcx>>,
{ {
@ -230,14 +230,6 @@ impl<'tcx> SymbolMangler<'tcx> {
} }
impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
type Error = !;
type Path = Self;
type Region = Self;
type Type = Self;
type DynExistential = Self;
type Const = Self;
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
@ -246,7 +238,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
mut self, mut self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
if let Some(&i) = self.paths.get(&(def_id, args)) { if let Some(&i) = self.paths.get(&(def_id, args)) {
return self.print_backref(i); return self.print_backref(i);
} }
@ -268,7 +260,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
mut self_ty: Ty<'tcx>, mut self_ty: Ty<'tcx>,
mut impl_trait_ref: Option<ty::TraitRef<'tcx>>, mut impl_trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let key = self.tcx.def_key(impl_def_id); let key = self.tcx.def_key(impl_def_id);
let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id }; let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id };
@ -321,7 +313,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
Ok(self) Ok(self)
} }
fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error> { fn print_region(self, region: ty::Region<'_>) -> Result<Self, PrintError> {
let i = match *region { let i = match *region {
// Erased lifetimes use the index 0, for a // Erased lifetimes use the index 0, for a
// shorter mangling of `L_`. // shorter mangling of `L_`.
@ -343,7 +335,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
Ok(self) Ok(self)
} }
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> {
// Basic types, never cached (single-character). // Basic types, never cached (single-character).
let basic_type = match ty.kind() { let basic_type = match ty.kind() {
ty::Bool => "b", ty::Bool => "b",
@ -498,7 +490,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
fn print_dyn_existential( fn print_dyn_existential(
mut self, mut self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> { ) -> Result<Self, PrintError> {
// Okay, so this is a bit tricky. Imagine we have a trait object like // Okay, so this is a bit tricky. Imagine we have a trait object like
// `dyn for<'a> Foo<'a, Bar = &'a ()>`. When we mangle this, the // `dyn for<'a> Foo<'a, Bar = &'a ()>`. When we mangle this, the
// output looks really close to the syntax, where the `Bar = &'a ()` bit // output looks really close to the syntax, where the `Bar = &'a ()` bit
@ -559,7 +551,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
Ok(self) Ok(self)
} }
fn print_const(mut self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> { fn print_const(mut self, ct: ty::Const<'tcx>) -> Result<Self, PrintError> {
// We only mangle a typed value if the const can be evaluated. // We only mangle a typed value if the const can be evaluated.
let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all()); let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all());
match ct.kind() { match ct.kind() {
@ -731,7 +723,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
Ok(self) Ok(self)
} }
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { fn path_crate(self, cnum: CrateNum) -> Result<Self, PrintError> {
self.push("C"); self.push("C");
let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id();
self.push_disambiguator(stable_crate_id.as_u64()); self.push_disambiguator(stable_crate_id.as_u64());
@ -744,7 +736,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
mut self, mut self,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
assert!(trait_ref.is_some()); assert!(trait_ref.is_some());
let trait_ref = trait_ref.unwrap(); let trait_ref = trait_ref.unwrap();
@ -755,20 +747,20 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
fn path_append_impl( fn path_append_impl(
self, self,
_: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, _: impl FnOnce(Self) -> Result<Self, PrintError>,
_: &DisambiguatedDefPathData, _: &DisambiguatedDefPathData,
_: Ty<'tcx>, _: Ty<'tcx>,
_: Option<ty::TraitRef<'tcx>>, _: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
// Inlined into `print_impl_path` // Inlined into `print_impl_path`
unreachable!() unreachable!()
} }
fn path_append( fn path_append(
self, self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
let ns = match disambiguated_data.data { let ns = match disambiguated_data.data {
// Extern block segments can be skipped, names from extern blocks // Extern block segments can be skipped, names from extern blocks
// are effectively living in their parent modules. // are effectively living in their parent modules.
@ -806,9 +798,9 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
fn path_generic_args( fn path_generic_args(
mut self, mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self::Path, Self::Error> { ) -> Result<Self, PrintError> {
// Don't print any regions if they're all erased. // Don't print any regions if they're all erased.
let print_regions = args.iter().any(|arg| match arg.unpack() { let print_regions = args.iter().any(|arg| match arg.unpack() {
GenericArgKind::Lifetime(r) => !r.is_erased(), GenericArgKind::Lifetime(r) => !r.is_erased(),

View file

@ -60,10 +60,7 @@ pub trait TypeErrCtxtExt<'tcx> {
suggest_increasing_limit: bool, suggest_increasing_limit: bool,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>
where where
T: fmt::Display T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
+ TypeFoldable<TyCtxt<'tcx>>
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
fn report_overflow_error<T>( fn report_overflow_error<T>(
&self, &self,
@ -73,10 +70,7 @@ pub trait TypeErrCtxtExt<'tcx> {
mutate: impl FnOnce(&mut Diagnostic), mutate: impl FnOnce(&mut Diagnostic),
) -> ! ) -> !
where where
T: fmt::Display T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
+ TypeFoldable<TyCtxt<'tcx>>
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed; fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed;
@ -227,10 +221,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
mutate: impl FnOnce(&mut Diagnostic), mutate: impl FnOnce(&mut Diagnostic),
) -> ! ) -> !
where where
T: fmt::Display T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
+ TypeFoldable<TyCtxt<'tcx>>
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
{ {
let mut err = self.build_overflow_error(predicate, span, suggest_increasing_limit); let mut err = self.build_overflow_error(predicate, span, suggest_increasing_limit);
mutate(&mut err); mutate(&mut err);
@ -247,10 +238,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
suggest_increasing_limit: bool, suggest_increasing_limit: bool,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>
where where
T: fmt::Display T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
+ TypeFoldable<TyCtxt<'tcx>>
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
{ {
let predicate = self.resolve_vars_if_possible(predicate.clone()); let predicate = self.resolve_vars_if_possible(predicate.clone());
let mut pred_str = predicate.to_string(); let mut pred_str = predicate.to_string();