1
Fork 0

Make ty::print::Printer take &mut self instead of self

This simplifies the code by removing all the `self` assignments and
makes the flow of data clearer - always into the printer.
Especially in v0 mangling, which already used  `&mut self` in some
places, it gets a lot more uniform.
This commit is contained in:
Nilstrieb 2023-10-17 19:46:14 +02:00
parent 45a45c6e60
commit 5acf26b97e
17 changed files with 615 additions and 592 deletions

View file

@ -470,7 +470,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
} }
ty.print(printer).unwrap().into_buffer() ty.print(&mut printer).unwrap();
printer.into_buffer()
} }
/// Returns the name of the provided `Ty` (that must be a reference)'s region with a /// Returns the name of the provided `Ty` (that must be a reference)'s region with a
@ -492,7 +493,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
bug!("ty for annotation of borrow region is not a reference"); bug!("ty for annotation of borrow region is not a reference");
}; };
region.print(printer).unwrap().into_buffer() region.print(&mut printer).unwrap();
printer.into_buffer()
} }
} }

View file

@ -107,10 +107,10 @@ impl<Prov: Provenance> std::fmt::Display for ImmTy<'_, Prov> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// Helper function for printing a scalar to a FmtPrinter /// Helper function for printing a scalar to a FmtPrinter
fn p<'a, 'tcx, Prov: Provenance>( fn p<'a, 'tcx, Prov: Provenance>(
cx: FmtPrinter<'a, 'tcx>, cx: &mut FmtPrinter<'a, 'tcx>,
s: Scalar<Prov>, s: Scalar<Prov>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<FmtPrinter<'a, 'tcx>, std::fmt::Error> { ) -> Result<(), std::fmt::Error> {
match s { match s {
Scalar::Int(int) => cx.pretty_print_const_scalar_int(int, ty, true), Scalar::Int(int) => cx.pretty_print_const_scalar_int(int, ty, true),
Scalar::Ptr(ptr, _sz) => { Scalar::Ptr(ptr, _sz) => {
@ -125,8 +125,9 @@ impl<Prov: Provenance> std::fmt::Display for ImmTy<'_, Prov> {
match self.imm { match self.imm {
Immediate::Scalar(s) => { Immediate::Scalar(s) => {
if let Some(ty) = tcx.lift(self.layout.ty) { if let Some(ty) = tcx.lift(self.layout.ty) {
let cx = FmtPrinter::new(tcx, Namespace::ValueNS); let s =
f.write_str(&p(cx, s, ty)?.into_buffer())?; FmtPrinter::print_string(tcx, Namespace::ValueNS, |cx| p(cx, s, ty))?;
f.write_str(&s)?;
return Ok(()); return Ok(());
} }
write!(f, "{:x}: {}", s, self.layout.ty) write!(f, "{:x}: {}", s, self.layout.ty)

View file

@ -18,11 +18,11 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> { fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
Ok(self) Ok(())
} }
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> { fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
match *ty.kind() { match *ty.kind() {
// Types without identity. // Types without identity.
ty::Bool ty::Bool
@ -43,7 +43,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
// Placeholders (all printed as `_` to uniformize them). // Placeholders (all printed as `_` to uniformize them).
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => { ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => {
write!(self, "_")?; write!(self, "_")?;
Ok(self) Ok(())
} }
// Types with identity (print the module path). // Types with identity (print the module path).
@ -60,44 +60,44 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
} }
} }
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self, PrintError> { fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
self.pretty_print_const(ct, false) self.pretty_print_const(ct, false)
} }
fn print_dyn_existential( fn print_dyn_existential(
self, &mut self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
self.pretty_print_dyn_existential(predicates) self.pretty_print_dyn_existential(predicates)
} }
fn path_crate(mut self, cnum: CrateNum) -> Result<Self, PrintError> { fn path_crate(&mut self, cnum: CrateNum) -> Result<(), 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(())
} }
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, PrintError> { ) -> Result<(), 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, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), 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, PrintError> { ) -> Result<(), PrintError> {
self.pretty_path_append_impl( self.pretty_path_append_impl(
|mut cx| { |cx| {
cx = print_prefix(cx)?; print_prefix(cx)?;
cx.path.push_str("::"); cx.path.push_str("::");
Ok(cx) Ok(())
}, },
self_ty, self_ty,
trait_ref, trait_ref,
@ -105,29 +105,29 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
} }
fn path_append( fn path_append(
mut self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
self = print_prefix(self)?; print_prefix(self)?;
write!(self.path, "::{}", disambiguated_data.data).unwrap(); write!(self.path, "::{}", disambiguated_data.data).unwrap();
Ok(self) Ok(())
} }
fn path_generic_args( fn path_generic_args(
mut self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
self = print_prefix(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(_)));
if args.clone().next().is_some() { if args.clone().next().is_some() {
self.generic_delimiters(|cx| cx.comma_sep(args)) self.generic_delimiters(|cx| cx.comma_sep(args))
} else { } else {
Ok(self) Ok(())
} }
} }
} }
@ -136,31 +136,31 @@ 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, PrintError> fn comma_sep<T>(&mut self, mut elems: impl Iterator<Item = T>) -> Result<(), PrintError>
where where
T: Print<'tcx, Self>, T: Print<'tcx, Self>,
{ {
if let Some(first) = elems.next() { if let Some(first) = elems.next() {
self = first.print(self)?; first.print(self)?;
for elem in elems { for elem in elems {
self.path.push_str(", "); self.path.push_str(", ");
self = elem.print(self)?; elem.print(self)?;
} }
} }
Ok(self) Ok(())
} }
fn generic_delimiters( fn generic_delimiters(
mut self, &mut self,
f: impl FnOnce(Self) -> Result<Self, PrintError>, f: impl FnOnce(&mut Self) -> Result<(), PrintError>,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
write!(self, "<")?; write!(self, "<")?;
self = f(self)?; f(self)?;
write!(self, ">")?; write!(self, ">")?;
Ok(self) Ok(())
} }
fn should_print_verbose(&self) -> bool { fn should_print_verbose(&self) -> bool {
@ -177,5 +177,7 @@ impl Write for AbsolutePathPrinter<'_> {
} }
pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> String { pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> String {
AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path let mut printer = AbsolutePathPrinter { tcx, path: String::new() };
printer.print_type(ty).unwrap();
printer.path
} }

View file

@ -588,60 +588,60 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> { fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
Err(fmt::Error) Err(fmt::Error)
} }
fn print_type(self, _ty: Ty<'tcx>) -> Result<Self, PrintError> { fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> {
Err(fmt::Error) Err(fmt::Error)
} }
fn print_dyn_existential( fn print_dyn_existential(
self, &mut self,
_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
Err(fmt::Error) Err(fmt::Error)
} }
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self, PrintError> { fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> {
Err(fmt::Error) Err(fmt::Error)
} }
fn path_crate(mut self, cnum: CrateNum) -> Result<Self, PrintError> { fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError> {
self.segments = vec![self.tcx.crate_name(cnum).to_string()]; self.segments = vec![self.tcx.crate_name(cnum).to_string()];
Ok(self) Ok(())
} }
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, PrintError> { ) -> Result<(), PrintError> {
Err(fmt::Error) Err(fmt::Error)
} }
fn path_append_impl( fn path_append_impl(
self, &mut self,
_print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, _print_prefix: impl FnOnce(&mut Self) -> Result<(), 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, PrintError> { ) -> Result<(), PrintError> {
Err(fmt::Error) Err(fmt::Error)
} }
fn path_append( fn path_append(
mut self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
self = print_prefix(self)?; print_prefix(self)?;
self.segments.push(disambiguated_data.to_string()); self.segments.push(disambiguated_data.to_string());
Ok(self) Ok(())
} }
fn path_generic_args( fn path_generic_args(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
_args: &[GenericArg<'tcx>], _args: &[GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
print_prefix(self) print_prefix(self)
} }
} }
@ -652,9 +652,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// 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 = |def_id| { let abs_path = |def_id| {
AbsolutePathPrinter { tcx: self.tcx, segments: vec![] } let mut printer = AbsolutePathPrinter { tcx: self.tcx, segments: vec![] };
.print_def_path(def_id, &[]) printer.print_def_path(def_id, &[]).map(|_| printer.segments)
.map(|p| p.segments)
}; };
// We compare strings because DefPath can be different // We compare strings because DefPath can be different
@ -1058,7 +1057,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let get_lifetimes = |sig| { let get_lifetimes = |sig| {
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS) let (sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS)
.name_all_regions(sig) .name_all_regions(sig)
.unwrap(); .unwrap();
let lts: Vec<String> = reg.into_values().map(|kind| kind.to_string()).collect(); let lts: Vec<String> = reg.into_values().map(|kind| kind.to_string()).collect();

View file

@ -200,12 +200,15 @@ fn ty_to_string<'tcx>(
ty: Ty<'tcx>, ty: Ty<'tcx>,
called_method_def_id: Option<DefId>, called_method_def_id: Option<DefId>,
) -> String { ) -> String {
let printer = fmt_printer(infcx, Namespace::TypeNS); let mut printer = fmt_printer(infcx, Namespace::TypeNS);
let ty = infcx.resolve_vars_if_possible(ty); let ty = infcx.resolve_vars_if_possible(ty);
match (ty.kind(), called_method_def_id) { match (ty.kind(), called_method_def_id) {
// We don't want the regular output for `fn`s because it includes its path in // We don't want the regular output for `fn`s because it includes its path in
// invalid pseudo-syntax, we want the `fn`-pointer output instead. // invalid pseudo-syntax, we want the `fn`-pointer output instead.
(ty::FnDef(..), _) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(), (ty::FnDef(..), _) => {
ty.fn_sig(infcx.tcx).print(&mut printer).unwrap();
printer.into_buffer()
}
(_, Some(def_id)) (_, Some(def_id))
if ty.is_ty_or_numeric_infer() if ty.is_ty_or_numeric_infer()
&& infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) => && infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) =>
@ -218,7 +221,10 @@ fn ty_to_string<'tcx>(
// //
// We do have to hide the `extern "rust-call"` ABI in that case though, // We do have to hide the `extern "rust-call"` ABI in that case though,
// which is too much of a bother for now. // which is too much of a bother for now.
_ => ty.print(printer).unwrap().into_buffer(), _ => {
ty.print(&mut printer).unwrap();
printer.into_buffer()
}
} }
} }
@ -285,8 +291,9 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(highlight) = highlight { if let Some(highlight) = highlight {
printer.region_highlight_mode = highlight; printer.region_highlight_mode = highlight;
} }
ty.print(&mut printer).unwrap();
InferenceDiagnosticsData { InferenceDiagnosticsData {
name: ty.print(printer).unwrap().into_buffer(), name: printer.into_buffer(),
span: None, span: None,
kind: UnderspecifiedArgKind::Type { prefix: ty.prefix_string(self.tcx) }, kind: UnderspecifiedArgKind::Type { prefix: ty.prefix_string(self.tcx) },
parent: None, parent: None,
@ -312,8 +319,9 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(highlight) = highlight { if let Some(highlight) = highlight {
printer.region_highlight_mode = highlight; printer.region_highlight_mode = highlight;
} }
ct.print(&mut printer).unwrap();
InferenceDiagnosticsData { InferenceDiagnosticsData {
name: ct.print(printer).unwrap().into_buffer(), name: printer.into_buffer(),
span: Some(origin.span), span: Some(origin.span),
kind: UnderspecifiedArgKind::Const { is_parameter: false }, kind: UnderspecifiedArgKind::Const { is_parameter: false },
parent: None, parent: None,
@ -329,8 +337,9 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(highlight) = highlight { if let Some(highlight) = highlight {
printer.region_highlight_mode = highlight; printer.region_highlight_mode = highlight;
} }
ct.print(&mut printer).unwrap();
InferenceDiagnosticsData { InferenceDiagnosticsData {
name: ct.print(printer).unwrap().into_buffer(), name: printer.into_buffer(),
span: None, span: None,
kind: UnderspecifiedArgKind::Const { is_parameter: false }, kind: UnderspecifiedArgKind::Const { is_parameter: false },
parent: None, parent: None,
@ -487,7 +496,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
{ {
"Vec<_>".to_string() "Vec<_>".to_string()
} else { } else {
fmt_printer(self, Namespace::TypeNS) let mut printer = fmt_printer(self, Namespace::TypeNS);
printer
.comma_sep(generic_args.iter().copied().map(|arg| { .comma_sep(generic_args.iter().copied().map(|arg| {
if arg.is_suggestable(self.tcx, true) { if arg.is_suggestable(self.tcx, true) {
return arg; return arg;
@ -512,8 +522,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.into(), .into(),
} }
})) }))
.unwrap() .unwrap();
.into_buffer() printer.into_buffer()
}; };
if !have_turbofish { if !have_turbofish {
@ -525,8 +535,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => { InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
let printer = fmt_printer(self, Namespace::ValueNS); let mut printer = fmt_printer(self, Namespace::ValueNS);
let def_path = printer.print_def_path(def_id, args).unwrap().into_buffer(); printer.print_def_path(def_id, args).unwrap();
let def_path = printer.into_buffer();
// We only care about whether we have to add `&` or `&mut ` for now. // We only care about whether we have to add `&` or `&mut ` for now.
// This is the case if the last adjustment is a borrow and the // This is the case if the last adjustment is a borrow and the

View file

@ -49,8 +49,8 @@ where
let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS); let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS);
printer.region_highlight_mode = self.highlight; printer.region_highlight_mode = self.highlight;
let s = self.value.print(printer)?.into_buffer(); self.value.print(&mut printer)?;
f.write_str(&s) f.write_str(&printer.into_buffer())
} }
} }

View file

@ -763,9 +763,9 @@ fn foo(&self) -> Self::T { String::new() }
} }
pub fn format_generic_args(&self, args: &[ty::GenericArg<'tcx>]) -> String { pub fn format_generic_args(&self, args: &[ty::GenericArg<'tcx>]) -> String {
FmtPrinter::new(self.tcx, hir::def::Namespace::TypeNS) FmtPrinter::print_string(self.tcx, hir::def::Namespace::TypeNS, |cx| {
.path_generic_args(Ok, args) cx.path_generic_args(|_| Ok(()), args)
})
.expect("could not write to `String`.") .expect("could not write to `String`.")
.into_buffer()
} }
} }

View file

@ -1210,35 +1210,35 @@ impl<'tcx> LateContext<'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> { fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
Ok(self) Ok(())
} }
fn print_type(self, _ty: Ty<'tcx>) -> Result<Self, PrintError> { fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> {
Ok(self) Ok(())
} }
fn print_dyn_existential( fn print_dyn_existential(
self, &mut self,
_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
Ok(self) Ok(())
} }
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self, PrintError> { fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> {
Ok(self) Ok(())
} }
fn path_crate(mut self, cnum: CrateNum) -> Result<Self, PrintError> { fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError> {
self.path = vec![self.tcx.crate_name(cnum)]; self.path = vec![self.tcx.crate_name(cnum)];
Ok(self) Ok(())
} }
fn path_qualified( fn path_qualified(
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, PrintError> { ) -> Result<(), 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);
@ -1251,21 +1251,21 @@ impl<'tcx> LateContext<'tcx> {
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) Ok(())
}) })
} }
fn path_append_impl( fn path_append_impl(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), 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, PrintError> { ) -> Result<(), PrintError> {
let mut path = print_prefix(self)?; print_prefix(self)?;
// This shouldn't ever be needed, but just in case: // This shouldn't ever be needed, but just in case:
path.path.push(match trait_ref { self.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 {}>",
@ -1278,38 +1278,37 @@ impl<'tcx> LateContext<'tcx> {
} }
}); });
Ok(path) Ok(())
} }
fn path_append( fn path_append(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
let mut path = print_prefix(self)?; print_prefix(self)?;
// Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs.
if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data { if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data {
return Ok(path); return Ok(());
} }
path.path.push(Symbol::intern(&disambiguated_data.data.to_string())); self.path.push(Symbol::intern(&disambiguated_data.data.to_string()));
Ok(path) Ok(())
} }
fn path_generic_args( fn path_generic_args(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
_args: &[GenericArg<'tcx>], _args: &[GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
print_prefix(self) print_prefix(self)
} }
} }
AbsolutePathPrinter { tcx: self.tcx, path: vec![] } let mut printer = AbsolutePathPrinter { tcx: self.tcx, path: vec![] };
.print_def_path(def_id, &[]) printer.print_def_path(def_id, &[]).unwrap();
.unwrap() printer.path
.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

@ -998,9 +998,9 @@ impl<'tcx> Debug for Rvalue<'tcx> {
ty::tls::with(|tcx| { ty::tls::with(|tcx| {
let variant_def = &tcx.adt_def(adt_did).variant(variant); let variant_def = &tcx.adt_def(adt_did).variant(variant);
let args = tcx.lift(args).expect("could not lift for printing"); let args = tcx.lift(args).expect("could not lift for printing");
let name = FmtPrinter::new(tcx, Namespace::ValueNS) let name = FmtPrinter::print_string(tcx, Namespace::ValueNS, |cx| {
.print_def_path(variant_def.def_id, args)? cx.print_def_path(variant_def.def_id, args)
.into_buffer(); })?;
match variant_def.ctor_kind() { match variant_def.ctor_kind() {
Some(CtorKind::Const) => fmt.write_str(&name), Some(CtorKind::Const) => fmt.write_str(&name),
@ -1740,7 +1740,7 @@ fn pretty_print_const_value_tcx<'tcx>(
let args = tcx.lift(args).unwrap(); let args = tcx.lift(args).unwrap();
let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
cx.print_alloc_ids = true; cx.print_alloc_ids = true;
let cx = cx.print_value_path(variant_def.def_id, args)?; cx.print_value_path(variant_def.def_id, args)?;
fmt.write_str(&cx.into_buffer())?; fmt.write_str(&cx.into_buffer())?;
match variant_def.ctor_kind() { match variant_def.ctor_kind() {
@ -1775,14 +1775,14 @@ fn pretty_print_const_value_tcx<'tcx>(
let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
cx.print_alloc_ids = true; cx.print_alloc_ids = true;
let ty = tcx.lift(ty).unwrap(); let ty = tcx.lift(ty).unwrap();
cx = cx.pretty_print_const_scalar(scalar, ty)?; cx.pretty_print_const_scalar(scalar, ty)?;
fmt.write_str(&cx.into_buffer())?; fmt.write_str(&cx.into_buffer())?;
return Ok(()); return Ok(());
} }
(ConstValue::ZeroSized, ty::FnDef(d, s)) => { (ConstValue::ZeroSized, ty::FnDef(d, s)) => {
let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
cx.print_alloc_ids = true; cx.print_alloc_ids = true;
let cx = cx.print_value_path(*d, s)?; cx.print_value_path(*d, s)?;
fmt.write_str(&cx.into_buffer())?; fmt.write_str(&cx.into_buffer())?;
return Ok(()); return Ok(());
} }

View file

@ -315,26 +315,25 @@ impl<'tcx> Ty<'tcx> {
impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxt<'tcx> {
pub fn ty_string_with_limit(self, ty: Ty<'tcx>, length_limit: usize) -> String { pub fn ty_string_with_limit(self, ty: Ty<'tcx>, length_limit: usize) -> String {
let mut type_limit = 50; let mut type_limit = 50;
let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
.pretty_print_type(ty) cx.pretty_print_type(ty)
.expect("could not write to `String`") })
.into_buffer(); .expect("could not write to `String`");
if regular.len() <= length_limit { if regular.len() <= length_limit {
return regular; return regular;
} }
let mut short; let mut short;
loop { loop {
// Look for the longest properly trimmed path that still fits in length_limit. // Look for the longest properly trimmed path that still fits in length_limit.
short = with_forced_trimmed_paths!( short = with_forced_trimmed_paths!({
FmtPrinter::new_with_limit( let mut cx = FmtPrinter::new_with_limit(
self, self,
hir::def::Namespace::TypeNS, hir::def::Namespace::TypeNS,
rustc_session::Limit(type_limit), rustc_session::Limit(type_limit),
)
.pretty_print_type(ty)
.expect("could not write to `String`")
.into_buffer()
); );
cx.pretty_print_type(ty).expect("could not write to `String`");
cx.into_buffer()
});
if short.len() <= length_limit || type_limit == 0 { if short.len() <= length_limit || type_limit == 0 {
break; break;
} }
@ -344,10 +343,10 @@ impl<'tcx> TyCtxt<'tcx> {
} }
pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
.pretty_print_type(ty) cx.pretty_print_type(ty)
.expect("could not write to `String`") })
.into_buffer(); .expect("could not write to `String`");
if !self.sess.opts.unstable_opts.write_long_types_to_disk { if !self.sess.opts.unstable_opts.write_long_types_to_disk {
return (regular, None); return (regular, None);

View file

@ -298,9 +298,9 @@ fn fmt_instance(
ty::tls::with(|tcx| { ty::tls::with(|tcx| {
let args = tcx.lift(instance.args).expect("could not lift for printing"); let args = tcx.lift(instance.args).expect("could not lift for printing");
let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length) let mut cx = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length);
.print_def_path(instance.def_id(), args)? cx.print_def_path(instance.def_id(), args)?;
.into_buffer(); let s = cx.into_buffer();
f.write_str(&s) f.write_str(&s)
})?; })?;

View file

@ -15,7 +15,7 @@ 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> {
fn print(&self, cx: P) -> Result<P, PrintError>; fn print(&self, cx: &mut P) -> Result<(), PrintError>;
} }
/// Interface for outputting user-facing "type-system entities" /// Interface for outputting user-facing "type-system entities"
@ -31,70 +31,70 @@ pub trait Printer<'tcx>: Sized {
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
fn print_def_path( fn print_def_path(
self, &mut self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
self.default_print_def_path(def_id, args) self.default_print_def_path(def_id, args)
} }
fn print_impl_path( fn print_impl_path(
self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
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, PrintError> { ) -> Result<(), 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, PrintError>; fn print_region(&mut self, region: ty::Region<'tcx>) -> Result<(), PrintError>;
fn print_type(self, ty: Ty<'tcx>) -> Result<Self, PrintError>; fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError>;
fn print_dyn_existential( fn print_dyn_existential(
self, &mut self,
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Result<Self, PrintError>; ) -> Result<(), PrintError>;
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self, PrintError>; fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError>;
fn path_crate(self, cnum: CrateNum) -> Result<Self, PrintError>; fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError>;
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, PrintError>; ) -> Result<(), PrintError>;
fn path_append_impl( fn path_append_impl(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), 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, PrintError>; ) -> Result<(), PrintError>;
fn path_append( fn path_append(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self, PrintError>; ) -> Result<(), PrintError>;
fn path_generic_args( fn path_generic_args(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self, PrintError>; ) -> Result<(), PrintError>;
// Defaults (should not be overridden): // Defaults (should not be overridden):
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn default_print_def_path( fn default_print_def_path(
self, &mut self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
let key = self.tcx().def_key(def_id); let key = self.tcx().def_key(def_id);
debug!(?key); debug!(?key);
@ -161,7 +161,7 @@ pub trait Printer<'tcx>: Sized {
} }
self.path_append( self.path_append(
|cx: Self| { |cx: &mut Self| {
if trait_qualify_parent { if trait_qualify_parent {
let trait_ref = ty::TraitRef::new( let trait_ref = ty::TraitRef::new(
cx.tcx(), cx.tcx(),
@ -180,12 +180,12 @@ pub trait Printer<'tcx>: Sized {
} }
fn default_print_impl_path( fn default_print_impl_path(
self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
_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, PrintError> { ) -> Result<(), 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
@ -286,25 +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> {
fn print(&self, cx: P) -> Result<P, PrintError> { fn print(&self, cx: &mut P) -> Result<(), PrintError> {
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> {
fn print(&self, cx: P) -> Result<P, PrintError> { fn print(&self, cx: &mut P) -> Result<(), PrintError> {
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>> {
fn print(&self, cx: P) -> Result<P, PrintError> { fn print(&self, cx: &mut P) -> Result<(), PrintError> {
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> {
fn print(&self, cx: P) -> Result<P, PrintError> { fn print(&self, cx: &mut P) -> Result<(), PrintError> {
cx.print_const(*self) cx.print_const(*self)
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -22,11 +22,10 @@ impl fmt::Debug for ty::TraitDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| { ty::tls::with(|tcx| {
with_no_trimmed_paths!({ with_no_trimmed_paths!({
f.write_str( let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
&FmtPrinter::new(tcx, Namespace::TypeNS) cx.print_def_path(self.def_id, &[])
.print_def_path(self.def_id, &[])? })?;
.into_buffer(), f.write_str(&s)
)
}) })
}) })
} }
@ -36,11 +35,10 @@ impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| { ty::tls::with(|tcx| {
with_no_trimmed_paths!({ with_no_trimmed_paths!({
f.write_str( let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
&FmtPrinter::new(tcx, Namespace::TypeNS) cx.print_def_path(self.did(), &[])
.print_def_path(self.did(), &[])? })?;
.into_buffer(), f.write_str(&s)
)
}) })
}) })
} }
@ -350,8 +348,7 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::Const<'tcx> {
let ConstKind::Value(valtree) = lifted.kind() else { let ConstKind::Value(valtree) = lifted.kind() else {
bug!("we checked that this is a valtree") bug!("we checked that this is a valtree")
}; };
let cx = FmtPrinter::new(tcx, Namespace::ValueNS); let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
let cx =
cx.pretty_print_const_valtree(valtree, lifted.ty(), /*print_ty*/ true)?; cx.pretty_print_const_valtree(valtree, lifted.ty(), /*print_ty*/ true)?;
f.write_str(&cx.into_buffer()) f.write_str(&cx.into_buffer())
}); });

View file

@ -199,16 +199,16 @@ struct SymbolPrinter<'tcx> {
// `PrettyPrinter` aka pretty printing of e.g. types in paths, // `PrettyPrinter` aka pretty printing of e.g. types in paths,
// 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 SymbolPrinter<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn print_region(self, _region: ty::Region<'_>) -> Result<Self, PrintError> { fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
Ok(self) Ok(())
} }
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> { fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), 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)
@ -220,17 +220,17 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
// -Zverbose flag, so we cannot reuse it here. // -Zverbose flag, so we cannot reuse it here.
ty::Array(ty, size) => { ty::Array(ty, size) => {
self.write_str("[")?; self.write_str("[")?;
self = self.print_type(ty)?; self.print_type(ty)?;
self.write_str("; ")?; self.write_str("; ")?;
if let Some(size) = size.try_to_target_usize(self.tcx()) { if let Some(size) = size.try_to_target_usize(self.tcx()) {
write!(self, "{size}")? write!(self, "{size}")?
} else if let ty::ConstKind::Param(param) = size.kind() { } else if let ty::ConstKind::Param(param) = size.kind() {
self = param.print(self)? param.print(self)?
} else { } else {
self.write_str("_")? self.write_str("_")?
} }
self.write_str("]")?; self.write_str("]")?;
Ok(self) Ok(())
} }
ty::Alias(ty::Inherent, _) => panic!("unexpected inherent projection"), ty::Alias(ty::Inherent, _) => panic!("unexpected inherent projection"),
@ -240,21 +240,21 @@ 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, PrintError> { ) -> Result<(), PrintError> {
let mut first = true; let mut first = true;
for p in predicates { for p in predicates {
if !first { if !first {
write!(self, "+")?; write!(self, "+")?;
} }
first = false; first = false;
self = p.print(self)?; p.print(self)?;
} }
Ok(self) Ok(())
} }
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self, PrintError> { fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), 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(_)) => {
@ -269,18 +269,18 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
} }
_ => self.write_str("_")?, _ => self.write_str("_")?,
} }
Ok(self) Ok(())
} }
fn path_crate(self, cnum: CrateNum) -> Result<Self, PrintError> { fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError> {
self.write_str(self.tcx.crate_name(cnum).as_str())?; self.write_str(self.tcx.crate_name(cnum).as_str())?;
Ok(self) Ok(())
} }
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, PrintError> { ) -> Result<(), 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() {
@ -295,15 +295,15 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
} }
fn path_append_impl( fn path_append_impl(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), 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, PrintError> { ) -> Result<(), PrintError> {
self.pretty_path_append_impl( self.pretty_path_append_impl(
|mut cx| { |cx| {
cx = print_prefix(cx)?; print_prefix(cx)?;
if cx.keep_within_component { if cx.keep_within_component {
// HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
@ -312,22 +312,22 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
cx.path.finalize_pending_component(); cx.path.finalize_pending_component();
} }
Ok(cx) Ok(())
}, },
self_ty, self_ty,
trait_ref, trait_ref,
) )
} }
fn path_append( fn path_append(
mut self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
self = print_prefix(self)?; print_prefix(self)?;
// Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs.
if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data { if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data {
return Ok(self); return Ok(());
} }
if self.keep_within_component { if self.keep_within_component {
@ -339,14 +339,14 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
write!(self, "{}", disambiguated_data.data)?; write!(self, "{}", disambiguated_data.data)?;
Ok(self) Ok(())
} }
fn path_generic_args( fn path_generic_args(
mut self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
self = print_prefix(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(_)));
@ -354,42 +354,42 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
if args.clone().next().is_some() { if args.clone().next().is_some() {
self.generic_delimiters(|cx| cx.comma_sep(args)) self.generic_delimiters(|cx| cx.comma_sep(args))
} else { } else {
Ok(self) Ok(())
} }
} }
} }
impl<'tcx> PrettyPrinter<'tcx> for &mut SymbolPrinter<'tcx> { impl<'tcx> PrettyPrinter<'tcx> for 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, PrintError> fn comma_sep<T>(&mut self, mut elems: impl Iterator<Item = T>) -> Result<(), PrintError>
where where
T: Print<'tcx, Self>, T: Print<'tcx, Self>,
{ {
if let Some(first) = elems.next() { if let Some(first) = elems.next() {
self = first.print(self)?; first.print(self)?;
for elem in elems { for elem in elems {
self.write_str(",")?; self.write_str(",")?;
self = elem.print(self)?; elem.print(self)?;
} }
} }
Ok(self) Ok(())
} }
fn generic_delimiters( fn generic_delimiters(
mut self, &mut self,
f: impl FnOnce(Self) -> Result<Self, PrintError>, f: impl FnOnce(&mut Self) -> Result<(), PrintError>,
) -> Result<Self, PrintError> { ) -> Result<(), 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);
self = f(self)?; f(self)?;
self.keep_within_component = kept_within_component; self.keep_within_component = kept_within_component;
write!(self, ">")?; write!(self, ">")?;
Ok(self) Ok(())
} }
} }

View file

@ -30,7 +30,7 @@ pub(super) fn mangle<'tcx>(
let args = tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), instance.args); let args = tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), instance.args);
let prefix = "_R"; let prefix = "_R";
let mut cx = &mut SymbolMangler { let mut cx: SymbolMangler<'_> = SymbolMangler {
tcx, tcx,
start_offset: prefix.len(), start_offset: prefix.len(),
paths: FxHashMap::default(), paths: FxHashMap::default(),
@ -49,13 +49,13 @@ pub(super) fn mangle<'tcx>(
_ => None, _ => None,
}; };
cx = if let Some(shim_kind) = shim_kind { if let Some(shim_kind) = shim_kind {
cx.path_append_ns(|cx| cx.print_def_path(def_id, args), 'S', 0, shim_kind).unwrap() cx.path_append_ns(|cx| cx.print_def_path(def_id, args), 'S', 0, shim_kind).unwrap()
} else { } else {
cx.print_def_path(def_id, args).unwrap() cx.print_def_path(def_id, args).unwrap()
}; };
if let Some(instantiating_crate) = instantiating_crate { if let Some(instantiating_crate) = instantiating_crate {
cx = cx.print_def_path(instantiating_crate.as_def_id(), &[]).unwrap(); cx.print_def_path(instantiating_crate.as_def_id(), &[]).unwrap();
} }
std::mem::take(&mut cx.out) std::mem::take(&mut cx.out)
} }
@ -65,7 +65,7 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
trait_ref: ty::PolyExistentialTraitRef<'tcx>, trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> String { ) -> String {
// FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`. // FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`.
let mut cx = &mut SymbolMangler { let mut cx = SymbolMangler {
tcx, tcx,
start_offset: 0, start_offset: 0,
paths: FxHashMap::default(), paths: FxHashMap::default(),
@ -74,7 +74,7 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
binders: vec![], binders: vec![],
out: String::new(), out: String::new(),
}; };
cx = cx.print_def_path(trait_ref.def_id(), &[]).unwrap(); cx.print_def_path(trait_ref.def_id(), &[]).unwrap();
std::mem::take(&mut cx.out) std::mem::take(&mut cx.out)
} }
@ -179,32 +179,32 @@ impl<'tcx> SymbolMangler<'tcx> {
self.push(ident); self.push(ident);
} }
fn path_append_ns<'a>( fn path_append_ns(
mut self: &'a mut Self, &mut self,
print_prefix: impl FnOnce(&'a mut Self) -> Result<&'a mut Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
ns: char, ns: char,
disambiguator: u64, disambiguator: u64,
name: &str, name: &str,
) -> Result<&'a mut Self, PrintError> { ) -> Result<(), PrintError> {
self.push("N"); self.push("N");
self.out.push(ns); self.out.push(ns);
self = print_prefix(self)?; print_prefix(self)?;
self.push_disambiguator(disambiguator as u64); self.push_disambiguator(disambiguator as u64);
self.push_ident(name); self.push_ident(name);
Ok(self) Ok(())
} }
fn print_backref(&mut self, i: usize) -> Result<&mut Self, PrintError> { fn print_backref(&mut self, i: usize) -> Result<(), 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(())
} }
fn in_binder<'a, T>( fn in_binder<T>(
mut self: &'a mut Self, &mut self,
value: &ty::Binder<'tcx, T>, value: &ty::Binder<'tcx, T>,
print_value: impl FnOnce(&'a mut Self, &T) -> Result<&'a mut Self, PrintError>, print_value: impl FnOnce(&mut Self, &T) -> Result<(), PrintError>,
) -> Result<&'a mut Self, PrintError> ) -> Result<(), PrintError>
where where
T: TypeVisitable<TyCtxt<'tcx>>, T: TypeVisitable<TyCtxt<'tcx>>,
{ {
@ -222,45 +222,45 @@ impl<'tcx> SymbolMangler<'tcx> {
lifetime_depths.end += lifetimes; lifetime_depths.end += lifetimes;
self.binders.push(BinderLevel { lifetime_depths }); self.binders.push(BinderLevel { lifetime_depths });
self = print_value(self, value.as_ref().skip_binder())?; print_value(self, value.as_ref().skip_binder())?;
self.binders.pop(); self.binders.pop();
Ok(self) Ok(())
} }
} }
impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn print_def_path( fn print_def_path(
mut self, &mut self,
def_id: DefId, def_id: DefId,
args: &'tcx [GenericArg<'tcx>], args: &'tcx [GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), 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);
} }
let start = self.out.len(); let start = self.out.len();
self = self.default_print_def_path(def_id, args)?; self.default_print_def_path(def_id, args)?;
// Only cache paths that do not refer to an enclosing // Only cache paths that do not refer to an enclosing
// binder (which would change depending on context). // binder (which would change depending on context).
if !args.iter().any(|k| k.has_escaping_bound_vars()) { if !args.iter().any(|k| k.has_escaping_bound_vars()) {
self.paths.insert((def_id, args), start); self.paths.insert((def_id, args), start);
} }
Ok(self) Ok(())
} }
fn print_impl_path( fn print_impl_path(
mut self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
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, PrintError> { ) -> Result<(), 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 };
@ -288,7 +288,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
// Encode impl generic params if the substitutions contain parameters (implying // Encode impl generic params if the substitutions contain parameters (implying
// polymorphization is enabled) and this isn't an inherent impl. // polymorphization is enabled) and this isn't an inherent impl.
if impl_trait_ref.is_some() && args.iter().any(|a| a.has_non_region_param()) { if impl_trait_ref.is_some() && args.iter().any(|a| a.has_non_region_param()) {
self = self.path_generic_args( self.path_generic_args(
|this| { |this| {
this.path_append_ns( this.path_append_ns(
|cx| cx.print_def_path(parent_def_id, &[]), |cx| cx.print_def_path(parent_def_id, &[]),
@ -301,19 +301,19 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
)?; )?;
} else { } else {
self.push_disambiguator(key.disambiguated_data.disambiguator as u64); self.push_disambiguator(key.disambiguated_data.disambiguator as u64);
self = self.print_def_path(parent_def_id, &[])?; self.print_def_path(parent_def_id, &[])?;
} }
self = self_ty.print(self)?; self_ty.print(self)?;
if let Some(trait_ref) = impl_trait_ref { if let Some(trait_ref) = impl_trait_ref {
self = self.print_def_path(trait_ref.def_id, trait_ref.args)?; self.print_def_path(trait_ref.def_id, trait_ref.args)?;
} }
Ok(self) Ok(())
} }
fn print_region(self, region: ty::Region<'_>) -> Result<Self, PrintError> { fn print_region(&mut self, region: ty::Region<'_>) -> Result<(), 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_`.
@ -332,10 +332,10 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
}; };
self.push("L"); self.push("L");
self.push_integer_62(i as u64); self.push_integer_62(i as u64);
Ok(self) Ok(())
} }
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self, PrintError> { fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), 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",
@ -365,7 +365,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
}; };
if !basic_type.is_empty() { if !basic_type.is_empty() {
self.push(basic_type); self.push(basic_type);
return Ok(self); return Ok(());
} }
if let Some(&i) = self.types.get(&ty) { if let Some(&i) = self.types.get(&ty) {
@ -391,9 +391,9 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
hir::Mutability::Mut => "Q", hir::Mutability::Mut => "Q",
}); });
if !r.is_erased() { if !r.is_erased() {
self = r.print(self)?; r.print(self)?;
} }
self = ty.print(self)?; ty.print(self)?;
} }
ty::RawPtr(mt) => { ty::RawPtr(mt) => {
@ -401,23 +401,23 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
hir::Mutability::Not => "P", hir::Mutability::Not => "P",
hir::Mutability::Mut => "O", hir::Mutability::Mut => "O",
}); });
self = mt.ty.print(self)?; mt.ty.print(self)?;
} }
ty::Array(ty, len) => { ty::Array(ty, len) => {
self.push("A"); self.push("A");
self = ty.print(self)?; ty.print(self)?;
self = self.print_const(len)?; self.print_const(len)?;
} }
ty::Slice(ty) => { ty::Slice(ty) => {
self.push("S"); self.push("S");
self = ty.print(self)?; ty.print(self)?;
} }
ty::Tuple(tys) => { ty::Tuple(tys) => {
self.push("T"); self.push("T");
for ty in tys.iter() { for ty in tys.iter() {
self = ty.print(self)?; ty.print(self)?;
} }
self.push("E"); self.push("E");
} }
@ -428,15 +428,15 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
| ty::Closure(def_id, args) | ty::Closure(def_id, args)
| ty::Coroutine(def_id, args, _) => { | ty::Coroutine(def_id, args, _) => {
self = self.print_def_path(def_id, args)?; self.print_def_path(def_id, args)?;
} }
ty::Foreign(def_id) => { ty::Foreign(def_id) => {
self = self.print_def_path(def_id, &[])?; self.print_def_path(def_id, &[])?;
} }
ty::FnPtr(sig) => { ty::FnPtr(sig) => {
self.push("F"); self.push("F");
self = self.in_binder(&sig, |mut cx, sig| { self.in_binder(&sig, |cx, sig| {
if sig.unsafety == hir::Unsafety::Unsafe { if sig.unsafety == hir::Unsafety::Unsafe {
cx.push("U"); cx.push("U");
} }
@ -454,7 +454,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
} }
} }
for &ty in sig.inputs() { for &ty in sig.inputs() {
cx = ty.print(cx)?; ty.print(cx)?;
} }
if sig.c_variadic { if sig.c_variadic {
cx.push("v"); cx.push("v");
@ -470,8 +470,8 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
// FIXME(dyn-star): need to update v0 mangling docs // FIXME(dyn-star): need to update v0 mangling docs
ty::DynStar => "D*", ty::DynStar => "D*",
}); });
self = self.print_dyn_existential(predicates)?; self.print_dyn_existential(predicates)?;
self = r.print(self)?; r.print(self)?;
} }
ty::Alias(ty::Inherent, _) => bug!("symbol_names: unexpected inherent projection"), ty::Alias(ty::Inherent, _) => bug!("symbol_names: unexpected inherent projection"),
@ -484,13 +484,13 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
if !ty.has_escaping_bound_vars() { if !ty.has_escaping_bound_vars() {
self.types.insert(ty, start); self.types.insert(ty, start);
} }
Ok(self) Ok(())
} }
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, PrintError> { ) -> Result<(), 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
@ -517,7 +517,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
// [<Trait> [{<Projection>}]] [{<Auto>}] // [<Trait> [{<Projection>}]] [{<Auto>}]
// Since any predicates after the first one shouldn't change the binders, // Since any predicates after the first one shouldn't change the binders,
// just put them all in the binders of the first. // just put them all in the binders of the first.
self = self.in_binder(&predicates[0], |mut cx, _| { self.in_binder(&predicates[0], |cx, _| {
for predicate in predicates.iter() { for predicate in predicates.iter() {
// It would be nice to be able to validate bound vars here, but // It would be nice to be able to validate bound vars here, but
// projections can actually include bound vars from super traits // projections can actually include bound vars from super traits
@ -528,30 +528,30 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
// Use a type that can't appear in defaults of type parameters. // Use a type that can't appear in defaults of type parameters.
let dummy_self = Ty::new_fresh(cx.tcx, 0); let dummy_self = Ty::new_fresh(cx.tcx, 0);
let trait_ref = trait_ref.with_self_ty(cx.tcx, dummy_self); let trait_ref = trait_ref.with_self_ty(cx.tcx, dummy_self);
cx = cx.print_def_path(trait_ref.def_id, trait_ref.args)?; cx.print_def_path(trait_ref.def_id, trait_ref.args)?;
} }
ty::ExistentialPredicate::Projection(projection) => { ty::ExistentialPredicate::Projection(projection) => {
let name = cx.tcx.associated_item(projection.def_id).name; let name = cx.tcx.associated_item(projection.def_id).name;
cx.push("p"); cx.push("p");
cx.push_ident(name.as_str()); cx.push_ident(name.as_str());
cx = match projection.term.unpack() { match projection.term.unpack() {
ty::TermKind::Ty(ty) => ty.print(cx), ty::TermKind::Ty(ty) => ty.print(cx),
ty::TermKind::Const(c) => c.print(cx), ty::TermKind::Const(c) => c.print(cx),
}?; }?;
} }
ty::ExistentialPredicate::AutoTrait(def_id) => { ty::ExistentialPredicate::AutoTrait(def_id) => {
cx = cx.print_def_path(*def_id, &[])?; cx.print_def_path(*def_id, &[])?;
} }
} }
} }
Ok(cx) Ok(())
})?; })?;
self.push("E"); self.push("E");
Ok(self) Ok(())
} }
fn print_const(mut self, ct: ty::Const<'tcx>) -> Result<Self, PrintError> { fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), 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() {
@ -570,12 +570,13 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
| ty::ConstKind::Error(_) => { | ty::ConstKind::Error(_) => {
// Never cached (single-character). // Never cached (single-character).
self.push("p"); self.push("p");
return Ok(self); return Ok(());
} }
} }
if let Some(&i) = self.consts.get(&ct) { if let Some(&i) = self.consts.get(&ct) {
return self.print_backref(i); self.print_backref(i)?;
return Ok(());
} }
let start = self.out.len(); let start = self.out.len();
@ -583,7 +584,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
match ty.kind() { match ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => { ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
self = ty.print(self)?; ty.print(self)?;
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all()); let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all());
@ -645,7 +646,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
.ty; .ty;
// FIXME(const_generics): add an assert that we only do this for valtrees. // FIXME(const_generics): add an assert that we only do this for valtrees.
let dereferenced_const = self.tcx.mk_ct_from_kind(ct.kind(), pointee_ty); let dereferenced_const = self.tcx.mk_ct_from_kind(ct.kind(), pointee_ty);
self = dereferenced_const.print(self)?; dereferenced_const.print(self)?;
} }
} }
} }
@ -654,22 +655,22 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
let contents = self.tcx.destructure_const(ct); let contents = self.tcx.destructure_const(ct);
let fields = contents.fields.iter().copied(); let fields = contents.fields.iter().copied();
let print_field_list = |mut this: Self| { let print_field_list = |this: &mut Self| {
for field in fields.clone() { for field in fields.clone() {
this = field.print(this)?; field.print(this)?;
} }
this.push("E"); this.push("E");
Ok(this) Ok(())
}; };
match *ct.ty().kind() { match *ct.ty().kind() {
ty::Array(..) | ty::Slice(_) => { ty::Array(..) | ty::Slice(_) => {
self.push("A"); self.push("A");
self = print_field_list(self)?; print_field_list(self)?;
} }
ty::Tuple(..) => { ty::Tuple(..) => {
self.push("T"); self.push("T");
self = print_field_list(self)?; print_field_list(self)?;
} }
ty::Adt(def, args) => { ty::Adt(def, args) => {
let variant_idx = let variant_idx =
@ -677,7 +678,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
let variant_def = &def.variant(variant_idx); let variant_def = &def.variant(variant_idx);
self.push("V"); self.push("V");
self = self.print_def_path(variant_def.def_id, args)?; self.print_def_path(variant_def.def_id, args)?;
match variant_def.ctor_kind() { match variant_def.ctor_kind() {
Some(CtorKind::Const) => { Some(CtorKind::Const) => {
@ -685,7 +686,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
} }
Some(CtorKind::Fn) => { Some(CtorKind::Fn) => {
self.push("T"); self.push("T");
self = print_field_list(self)?; print_field_list(self)?;
} }
None => { None => {
self.push("S"); self.push("S");
@ -701,7 +702,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
); );
self.push_ident(field_name.unwrap_or(kw::Empty).as_str()); self.push_ident(field_name.unwrap_or(kw::Empty).as_str());
self = field.print(self)?; field.print(self)?;
} }
self.push("E"); self.push("E");
} }
@ -720,47 +721,47 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
if !ct.has_escaping_bound_vars() { if !ct.has_escaping_bound_vars() {
self.consts.insert(ct, start); self.consts.insert(ct, start);
} }
Ok(self) Ok(())
} }
fn path_crate(self, cnum: CrateNum) -> Result<Self, PrintError> { fn path_crate(&mut self, cnum: CrateNum) -> Result<(), 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());
let name = self.tcx.crate_name(cnum); let name = self.tcx.crate_name(cnum);
self.push_ident(name.as_str()); self.push_ident(name.as_str());
Ok(self) Ok(())
} }
fn path_qualified( fn path_qualified(
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, PrintError> { ) -> Result<(), PrintError> {
assert!(trait_ref.is_some()); assert!(trait_ref.is_some());
let trait_ref = trait_ref.unwrap(); let trait_ref = trait_ref.unwrap();
self.push("Y"); self.push("Y");
self = self_ty.print(self)?; self_ty.print(self)?;
self.print_def_path(trait_ref.def_id, trait_ref.args) self.print_def_path(trait_ref.def_id, trait_ref.args)
} }
fn path_append_impl( fn path_append_impl(
self, &mut self,
_: impl FnOnce(Self) -> Result<Self, PrintError>, _: impl FnOnce(&mut Self) -> Result<(), PrintError>,
_: &DisambiguatedDefPathData, _: &DisambiguatedDefPathData,
_: Ty<'tcx>, _: Ty<'tcx>,
_: Option<ty::TraitRef<'tcx>>, _: Option<ty::TraitRef<'tcx>>,
) -> Result<Self, PrintError> { ) -> Result<(), PrintError> {
// Inlined into `print_impl_path` // Inlined into `print_impl_path`
unreachable!() unreachable!()
} }
fn path_append( fn path_append(
self, &mut self,
print_prefix: impl FnOnce(Self) -> Result<Self, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
disambiguated_data: &DisambiguatedDefPathData, disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self, PrintError> { ) -> Result<(), 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.
@ -797,10 +798,10 @@ 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, PrintError>, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> Result<Self, PrintError> { ) -> Result<(), 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(),
@ -816,23 +817,23 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
} }
self.push("I"); self.push("I");
self = print_prefix(self)?; print_prefix(self)?;
for arg in args { for arg in args {
match arg.unpack() { match arg.unpack() {
GenericArgKind::Lifetime(lt) => { GenericArgKind::Lifetime(lt) => {
self = lt.print(self)?; lt.print(self)?;
} }
GenericArgKind::Type(ty) => { GenericArgKind::Type(ty) => {
self = ty.print(self)?; ty.print(self)?;
} }
GenericArgKind::Const(c) => { GenericArgKind::Const(c) => {
self.push("K"); self.push("K");
self = c.print(self)?; c.print(self)?;
} }
} }
} }
self.push("E"); self.push("E");
Ok(self) Ok(())
} }
} }

View file

@ -246,14 +246,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if pred_str.len() > 50 { if pred_str.len() > 50 {
// We don't need to save the type to a file, we will be talking about this type already // We don't need to save the type to a file, we will be talking about this type already
// in a separate note when we explain the obligation, so it will be available that way. // in a separate note when we explain the obligation, so it will be available that way.
pred_str = predicate let mut cx: FmtPrinter<'_, '_> =
.print(FmtPrinter::new_with_limit( FmtPrinter::new_with_limit(self.tcx, Namespace::TypeNS, rustc_session::Limit(6));
self.tcx, predicate.print(&mut cx).unwrap();
Namespace::TypeNS, pred_str = cx.into_buffer();
rustc_session::Limit(6),
))
.unwrap()
.into_buffer();
} }
let mut err = struct_span_err!( let mut err = struct_span_err!(
self.tcx.sess, self.tcx.sess,
@ -1408,17 +1404,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term) self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term)
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
with_forced_trimmed_paths!(format!( let mut cx = FmtPrinter::new_with_limit(
"type mismatch resolving `{}`",
self.resolve_vars_if_possible(predicate)
.print(FmtPrinter::new_with_limit(
self.tcx, self.tcx,
Namespace::TypeNS, Namespace::TypeNS,
rustc_session::Limit(10), rustc_session::Limit(10),
)) );
.unwrap() with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", {
.into_buffer() self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
)) cx.into_buffer()
}))
}); });
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}"); let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
@ -1463,14 +1457,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty.span, ty.span,
with_forced_trimmed_paths!(Cow::from(format!( with_forced_trimmed_paths!(Cow::from(format!(
"type mismatch resolving `{}`", "type mismatch resolving `{}`",
self.resolve_vars_if_possible(predicate) {
.print(FmtPrinter::new_with_limit( let mut cx = FmtPrinter::new_with_limit(
self.tcx, self.tcx,
Namespace::TypeNS, Namespace::TypeNS,
rustc_session::Limit(5), rustc_session::Limit(5),
)) );
.unwrap() self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
.into_buffer() cx.into_buffer()
}
))), ))),
)), )),
_ => None, _ => None,