Skip to content

Commit 5167f7e

Browse files
committed
Allow formatting TraitRef and TraitPredicate with an Infcx
1 parent d8e01c0 commit 5167f7e

File tree

4 files changed

+94
-2
lines changed

4 files changed

+94
-2
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
pub mod tls;
66

7+
use hir::def::Namespace;
78
pub use rustc_type_ir::lift::Lift;
89

910
use crate::arena::Arena;
@@ -27,6 +28,7 @@ use crate::traits::solve::{
2728
ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
2829
};
2930
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
31+
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
3032
use crate::ty::{
3133
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData,
3234
GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern,
@@ -89,6 +91,18 @@ use std::ops::{Bound, Deref};
8991
#[allow(rustc::usage_of_ty_tykind)]
9092
impl<'tcx> Interner for TyCtxt<'tcx> {
9193
type DefId = DefId;
94+
fn print_def_path(defid: Self::DefId, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95+
ty::tls::with(|tcx| {
96+
with_no_trimmed_paths!({
97+
// this namespace is..... not strictly correct lol
98+
let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
99+
cx.print_def_path(defid, &[])
100+
})?;
101+
f.write_str(&s)
102+
})
103+
})
104+
}
105+
92106
type AdtDef = ty::AdtDef<'tcx>;
93107

94108
type GenericArgs = ty::GenericArgsRef<'tcx>;

compiler/rustc_type_ir/src/interner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub trait Interner:
2929
+ IrPrint<FnSig<Self>>
3030
{
3131
type DefId: Copy + Debug + Hash + Eq;
32+
fn print_def_path(defid: Self::DefId, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
33+
3234
type AdtDef: Copy + Debug + Hash + Eq;
3335

3436
type GenericArgs: GenericArgs<Self>;

compiler/rustc_type_ir/src/ir_print.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ define_display_via_print!(
4848
FnSig,
4949
);
5050

51-
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
51+
define_debug_via_print!(ExistentialTraitRef, ExistentialProjection);

compiler/rustc_type_ir/src/predicate.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,44 @@ pub struct TraitRef<I: Interner> {
4040
_use_trait_ref_new_instead: (),
4141
}
4242

43+
impl<I: Interner> fmt::Debug for TraitRef<I> {
44+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45+
WithInfcx::with_no_infcx(self).fmt(f)
46+
}
47+
}
48+
impl<I: Interner> DebugWithInfcx<I> for TraitRef<I> {
49+
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
50+
this: WithInfcx<'_, Infcx, &Self>,
51+
f: &mut fmt::Formatter<'_>,
52+
) -> fmt::Result {
53+
// If we ever wind up with a malformed `TraitRef` it might be good to not ICE in its Debug impl(?)
54+
if this.data.args.len() == 0 {
55+
return f
56+
.debug_tuple("TraitRef")
57+
.field(&this.data.def_id)
58+
.field(&this.data.args)
59+
.finish();
60+
}
61+
62+
write!(f, "({:?} as ", this.map(|trait_ref| trait_ref.args[0]))?;
63+
I::print_def_path(this.data.def_id, f)?;
64+
65+
match this.data.args.len() {
66+
0 => unreachable!(),
67+
1 => write!(f, ")"), // the first arg is the self type
68+
2 => write!(f, "<{:?}>)", this.map(|trait_ref| trait_ref.args[1])),
69+
3.. => {
70+
write!(f, "<{:?}", this.map(|trait_ref| trait_ref.args[1]))?;
71+
for arg in &this.data.args[2..] {
72+
let arg = this.wrap(arg);
73+
write!(f, ", {:?}", arg)?;
74+
}
75+
write!(f, ">)")
76+
}
77+
}
78+
}
79+
}
80+
4381
impl<I: Interner> TraitRef<I> {
4482
pub fn new(
4583
interner: I,
@@ -114,8 +152,46 @@ impl<I: Interner> TraitPredicate<I> {
114152

115153
impl<I: Interner> fmt::Debug for TraitPredicate<I> {
116154
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155+
WithInfcx::with_no_infcx(self).fmt(f)
156+
}
157+
}
158+
impl<I: Interner> DebugWithInfcx<I> for TraitPredicate<I> {
159+
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
160+
this: WithInfcx<'_, Infcx, &Self>,
161+
f: &mut fmt::Formatter<'_>,
162+
) -> fmt::Result {
117163
// FIXME(effects) printing?
118-
write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
164+
165+
// If we ever wind up with a malformed `TraitRef` it might be good to not ICE in its Debug impl(?)
166+
if this.data.trait_ref.args.len() == 0 {
167+
return f
168+
.debug_tuple("TraitPredicate")
169+
.field(&this.data.trait_ref.def_id)
170+
.field(&this.data.trait_ref.args)
171+
.field(&this.data.polarity)
172+
.finish();
173+
}
174+
175+
write!(f, "({:?}: ", this.map(|pred| pred.trait_ref.args[0]))?;
176+
match this.data.polarity {
177+
PredicatePolarity::Positive => (),
178+
PredicatePolarity::Negative => write!(f, "!")?,
179+
};
180+
I::print_def_path(this.data.trait_ref.def_id, f)?;
181+
182+
match this.data.trait_ref.args.len() {
183+
0 => unreachable!(),
184+
1 => write!(f, ")"), // the first arg is the self type
185+
2 => write!(f, "<{:?}>)", this.map(|trait_ref| trait_ref.trait_ref.args[1])),
186+
3.. => {
187+
write!(f, "<{:?}", this.map(|trait_ref| trait_ref.trait_ref.args[1]))?;
188+
for arg in &this.data.trait_ref.args[2..] {
189+
let arg = this.wrap(arg);
190+
write!(f, ", {:?}", arg)?;
191+
}
192+
write!(f, ">)")
193+
}
194+
}
119195
}
120196
}
121197

0 commit comments

Comments
 (0)