Skip to content

Commit 99d0fee

Browse files
Rollup merge of rust-lang#126075 - compiler-errors:remove-debugwithinfcx, r=lcnr
Remove `DebugWithInfcx` machinery This PR removes `DebugWithInfcx` after having a lot of second thoughts about it due to recent type system uplifting work. We could add it back later if we want, but I don't think the amount of boilerplate in the complier and the existence of (kindof) hacks like `NoInfcx` currently justify the existence of `DebugWithInfcx`, especially since it's not even being used anywhere in the compiler currently. The motivation for `DebugWithInfcx` is that we want to be able to print infcx-aware information, such as universe information[^1] (though if there are other usages that I'm overlooking, please let me know). I think there are probably more tailored solutions that can specifically be employed in places where this infcx-aware printing is necessary. For example, one way of achieving this is by implementing a custom `FmtPrinter` which overloads `ty_infer_name` (perhaps also extending it to have overrideable stubs for printing placeholders too) to print the `?u.i` name for an infer var. This will necessitate uplifting `Print` from `rustc_middle::ty::print`, but this seems a bit more extensible and reusable than `DebugWithInfcx`. One of the problems w/ `DebugWithInfcx` is its opt-in-ness. Even if a compiler dev adds a new `debug!(ty)` in a context where there is an `infcx` we can access, they have to *opt-in* to using `DebugWithInfcx` with something like `debug!(infcx.with(ty))`. This feels to me like it risks a lot of boilerplate, and very easy to just forget adding it at all, especially in cases like `#[instrument]`. A second problem is the `NoInfcx` type itself. It's necessary to have this dummy infcx implementation since we often want to print types outside of the scope of a valid `Infcx`. Right now, `NoInfcx` is only *partially* a valid implementation of `InferCtxtLike`, except for the methods that we specifically need for `DebugWithInfcx`. As I work on uplifting the trait solver, I actually want to add a lot more methods to `InferCtxtLike` and having to add `unreachable!("this should never be called")` stubs for uplifted methods like `next_ty_var` is quite annoying. In reality, I actually only *really* care about the second problem -- we could, perhaps, instead just try to get rid of `NoInfcx` and just just duplicate `Debug` and `DebugWithInfcx` for most types. If we're okay with duplicating all these implementations (though most of them would just be trivial `#[derive(Debug, DebugWithInfcx)]`), I'd be okay with that too 🤔 r? `@BoxyUwU` `@lcnr` would like to know your thoughts -- happy to discuss this further, mainly trying to bring this problem up [^1]: Which in my experience is only really necessary when we're debugging things like generalizer bugs.
2 parents ee45f5b + 0fc18e3 commit 99d0fee

17 files changed

+105
-477
lines changed

Diff for: compiler/rustc_middle/src/ty/list.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::flags::FlagComputation;
2-
use super::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, TyCtxt, TypeFlags, WithInfcx};
2+
use super::{DebruijnIndex, TypeFlags};
33
use crate::arena::Arena;
44
use rustc_data_structures::aligned::{align_of, Aligned};
55
use rustc_serialize::{Encodable, Encoder};
@@ -162,14 +162,6 @@ impl<H, T: fmt::Debug> fmt::Debug for RawList<H, T> {
162162
(**self).fmt(f)
163163
}
164164
}
165-
impl<'tcx, H, T: DebugWithInfcx<TyCtxt<'tcx>>> DebugWithInfcx<TyCtxt<'tcx>> for RawList<H, T> {
166-
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
167-
this: WithInfcx<'_, Infcx, &Self>,
168-
f: &mut core::fmt::Formatter<'_>,
169-
) -> core::fmt::Result {
170-
fmt::Debug::fmt(&this.map(|this| this.as_slice()), f)
171-
}
172-
}
173165

174166
impl<H, S: Encoder, T: Encodable<S>> Encodable<S> for RawList<H, T> {
175167
#[inline]

Diff for: compiler/rustc_middle/src/ty/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ use rustc_span::{ExpnId, ExpnKind, Span};
6161
use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx};
6262
pub use rustc_target::abi::{ReprFlags, ReprOptions};
6363
pub use rustc_type_ir::relate::VarianceDiagInfo;
64-
pub use rustc_type_ir::{DebugWithInfcx, InferCtxtLike, WithInfcx};
6564
use tracing::{debug, instrument};
6665
pub use vtable::*;
6766

Diff for: compiler/rustc_middle/src/ty/structural_impls.rs

+15-88
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_ast_ir::visit::VisitorResult;
1313
use rustc_hir::def::Namespace;
1414
use rustc_span::source_map::Spanned;
1515
use rustc_target::abi::TyAndLayout;
16-
use rustc_type_ir::{ConstKind, DebugWithInfcx, InferCtxtLike, WithInfcx};
16+
use rustc_type_ir::ConstKind;
1717

1818
use std::fmt::{self, Debug};
1919

@@ -83,14 +83,6 @@ impl fmt::Debug for ty::LateParamRegion {
8383
}
8484
}
8585

86-
impl<'tcx> ty::DebugWithInfcx<TyCtxt<'tcx>> for Ty<'tcx> {
87-
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
88-
this: WithInfcx<'_, Infcx, &Self>,
89-
f: &mut core::fmt::Formatter<'_>,
90-
) -> core::fmt::Result {
91-
this.data.fmt(f)
92-
}
93-
}
9486
impl<'tcx> fmt::Debug for Ty<'tcx> {
9587
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9688
with_no_trimmed_paths!(fmt::Debug::fmt(self.kind(), f))
@@ -121,91 +113,46 @@ impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
121113
}
122114
}
123115

124-
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for Pattern<'tcx> {
125-
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
126-
this: WithInfcx<'_, Infcx, &Self>,
127-
f: &mut core::fmt::Formatter<'_>,
128-
) -> core::fmt::Result {
129-
match &**this.data {
130-
ty::PatternKind::Range { start, end, include_end } => f
131-
.debug_struct("Pattern::Range")
132-
.field("start", start)
133-
.field("end", end)
134-
.field("include_end", include_end)
135-
.finish(),
136-
}
137-
}
138-
}
139-
140116
impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> {
141117
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142-
WithInfcx::with_no_infcx(self).fmt(f)
143-
}
144-
}
145-
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::consts::Expr<'tcx> {
146-
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
147-
this: WithInfcx<'_, Infcx, &Self>,
148-
f: &mut core::fmt::Formatter<'_>,
149-
) -> core::fmt::Result {
150-
match this.data.kind {
118+
match self.kind {
151119
ty::ExprKind::Binop(op) => {
152-
let (lhs_ty, rhs_ty, lhs, rhs) = this.data.binop_args();
153-
write!(
154-
f,
155-
"({op:?}: ({:?}: {:?}), ({:?}: {:?}))",
156-
&this.wrap(lhs),
157-
&this.wrap(lhs_ty),
158-
&this.wrap(rhs),
159-
&this.wrap(rhs_ty),
160-
)
120+
let (lhs_ty, rhs_ty, lhs, rhs) = self.binop_args();
121+
write!(f, "({op:?}: ({:?}: {:?}), ({:?}: {:?}))", lhs, lhs_ty, rhs, rhs_ty,)
161122
}
162123
ty::ExprKind::UnOp(op) => {
163-
let (rhs_ty, rhs) = this.data.unop_args();
164-
write!(f, "({op:?}: ({:?}: {:?}))", &this.wrap(rhs), &this.wrap(rhs_ty))
124+
let (rhs_ty, rhs) = self.unop_args();
125+
write!(f, "({op:?}: ({:?}: {:?}))", rhs, rhs_ty)
165126
}
166127
ty::ExprKind::FunctionCall => {
167-
let (func_ty, func, args) = this.data.call_args();
128+
let (func_ty, func, args) = self.call_args();
168129
let args = args.collect::<Vec<_>>();
169-
write!(f, "({:?}: {:?})(", &this.wrap(func), &this.wrap(func_ty))?;
130+
write!(f, "({:?}: {:?})(", func, func_ty)?;
170131
for arg in args.iter().rev().skip(1).rev() {
171-
write!(f, "{:?}, ", &this.wrap(arg))?;
132+
write!(f, "{:?}, ", arg)?;
172133
}
173134
if let Some(arg) = args.last() {
174-
write!(f, "{:?}", &this.wrap(arg))?;
135+
write!(f, "{:?}", arg)?;
175136
}
176137

177138
write!(f, ")")
178139
}
179140
ty::ExprKind::Cast(kind) => {
180-
let (value_ty, value, to_ty) = this.data.cast_args();
181-
write!(
182-
f,
183-
"({kind:?}: ({:?}: {:?}), {:?})",
184-
&this.wrap(value),
185-
&this.wrap(value_ty),
186-
&this.wrap(to_ty)
187-
)
141+
let (value_ty, value, to_ty) = self.cast_args();
142+
write!(f, "({kind:?}: ({:?}: {:?}), {:?})", value, value_ty, to_ty)
188143
}
189144
}
190145
}
191146
}
192147

193148
impl<'tcx> fmt::Debug for ty::Const<'tcx> {
194149
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195-
WithInfcx::with_no_infcx(self).fmt(f)
196-
}
197-
}
198-
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::Const<'tcx> {
199-
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
200-
this: WithInfcx<'_, Infcx, &Self>,
201-
f: &mut core::fmt::Formatter<'_>,
202-
) -> core::fmt::Result {
203150
// If this is a value, we spend some effort to make it look nice.
204-
if let ConstKind::Value(_, _) = this.data.kind() {
151+
if let ConstKind::Value(_, _) = self.kind() {
205152
return ty::tls::with(move |tcx| {
206153
// Somehow trying to lift the valtree results in lifetime errors, so we lift the
207154
// entire constant.
208-
let lifted = tcx.lift(*this.data).unwrap();
155+
let lifted = tcx.lift(*self).unwrap();
209156
let ConstKind::Value(ty, valtree) = lifted.kind() else {
210157
bug!("we checked that this is a valtree")
211158
};
@@ -215,7 +162,7 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::Const<'tcx> {
215162
});
216163
}
217164
// Fall back to something verbose.
218-
write!(f, "{kind:?}", kind = &this.map(|data| data.kind()))
165+
write!(f, "{:?}", self.kind())
219166
}
220167
}
221168

@@ -247,32 +194,12 @@ impl<'tcx> fmt::Debug for GenericArg<'tcx> {
247194
}
248195
}
249196
}
250-
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for GenericArg<'tcx> {
251-
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
252-
this: WithInfcx<'_, Infcx, &Self>,
253-
f: &mut core::fmt::Formatter<'_>,
254-
) -> core::fmt::Result {
255-
match this.data.unpack() {
256-
GenericArgKind::Lifetime(lt) => write!(f, "{:?}", &this.wrap(lt)),
257-
GenericArgKind::Const(ct) => write!(f, "{:?}", &this.wrap(ct)),
258-
GenericArgKind::Type(ty) => write!(f, "{:?}", &this.wrap(ty)),
259-
}
260-
}
261-
}
262197

263198
impl<'tcx> fmt::Debug for Region<'tcx> {
264199
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265200
write!(f, "{:?}", self.kind())
266201
}
267202
}
268-
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for Region<'tcx> {
269-
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
270-
this: WithInfcx<'_, Infcx, &Self>,
271-
f: &mut core::fmt::Formatter<'_>,
272-
) -> core::fmt::Result {
273-
write!(f, "{:?}", &this.map(|data| data.kind()))
274-
}
275-
}
276203

277204
///////////////////////////////////////////////////////////////////////////
278205
// Atomic structs

Diff for: compiler/rustc_type_ir/src/binder.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
88
use rustc_serialize::Decodable;
99
use tracing::debug;
1010

11-
use crate::debug::{DebugWithInfcx, WithInfcx};
1211
use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
1312
use crate::inherent::*;
1413
use crate::lift::Lift;
1514
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
16-
use crate::{self as ty, InferCtxtLike, Interner, SsoHashSet};
15+
use crate::{self as ty, Interner, SsoHashSet};
1716

1817
/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
1918
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
@@ -56,18 +55,6 @@ where
5655
}
5756
}
5857

59-
impl<I: Interner, T: DebugWithInfcx<I>> DebugWithInfcx<I> for ty::Binder<I, T> {
60-
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
61-
this: WithInfcx<'_, Infcx, &Self>,
62-
f: &mut core::fmt::Formatter<'_>,
63-
) -> core::fmt::Result {
64-
f.debug_tuple("Binder")
65-
.field(&this.map(|data| data.as_ref().skip_binder()))
66-
.field(&this.data.bound_vars())
67-
.finish()
68-
}
69-
}
70-
7158
macro_rules! impl_binder_encode_decode {
7259
($($t:ty),+ $(,)?) => {
7360
$(

Diff for: compiler/rustc_type_ir/src/const_kind.rs

+8-42
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
55
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
66
use std::fmt;
77

8-
use crate::{self as ty, DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx};
8+
use crate::{self as ty, DebruijnIndex, Interner};
99

1010
use self::ConstKind::*;
1111

@@ -61,28 +61,19 @@ impl<I: Interner> PartialEq for ConstKind<I> {
6161

6262
impl<I: Interner> fmt::Debug for ConstKind<I> {
6363
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64-
WithInfcx::with_no_infcx(self).fmt(f)
65-
}
66-
}
67-
68-
impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
69-
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
70-
this: WithInfcx<'_, Infcx, &Self>,
71-
f: &mut core::fmt::Formatter<'_>,
72-
) -> core::fmt::Result {
7364
use ConstKind::*;
7465

75-
match this.data {
66+
match self {
7667
Param(param) => write!(f, "{param:?}"),
77-
Infer(var) => write!(f, "{:?}", &this.wrap(var)),
68+
Infer(var) => write!(f, "{:?}", &var),
7869
Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var),
7970
Placeholder(placeholder) => write!(f, "{placeholder:?}"),
8071
Unevaluated(uv) => {
81-
write!(f, "{:?}", &this.wrap(uv))
72+
write!(f, "{:?}", &uv)
8273
}
83-
Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &this.wrap(ty)),
74+
Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &ty),
8475
Error(_) => write!(f, "{{const error}}"),
85-
Expr(expr) => write!(f, "{:?}", &this.wrap(expr)),
76+
Expr(expr) => write!(f, "{:?}", &expr),
8677
}
8778
}
8879
}
@@ -112,17 +103,9 @@ impl<I: Interner> UnevaluatedConst<I> {
112103

113104
impl<I: Interner> fmt::Debug for UnevaluatedConst<I> {
114105
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115-
WithInfcx::with_no_infcx(self).fmt(f)
116-
}
117-
}
118-
impl<I: Interner> DebugWithInfcx<I> for UnevaluatedConst<I> {
119-
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
120-
this: WithInfcx<'_, Infcx, &Self>,
121-
f: &mut core::fmt::Formatter<'_>,
122-
) -> core::fmt::Result {
123106
f.debug_struct("UnevaluatedConst")
124-
.field("def", &this.data.def)
125-
.field("args", &this.wrap(this.data.args))
107+
.field("def", &self.def)
108+
.field("args", &self.args)
126109
.finish()
127110
}
128111
}
@@ -175,23 +158,6 @@ impl fmt::Debug for InferConst {
175158
}
176159
}
177160
}
178-
impl<I: Interner> DebugWithInfcx<I> for InferConst {
179-
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
180-
this: WithInfcx<'_, Infcx, &Self>,
181-
f: &mut core::fmt::Formatter<'_>,
182-
) -> core::fmt::Result {
183-
match *this.data {
184-
InferConst::Var(vid) => match this.infcx.universe_of_ct(vid) {
185-
None => write!(f, "{:?}", this.data),
186-
Some(universe) => write!(f, "?{}_{}c", vid.index(), universe.index()),
187-
},
188-
InferConst::EffectVar(vid) => write!(f, "?{}e", vid.index()),
189-
InferConst::Fresh(_) => {
190-
unreachable!()
191-
}
192-
}
193-
}
194-
}
195161

196162
#[cfg(feature = "nightly")]
197163
impl<CTX> HashStable<CTX> for InferConst {

0 commit comments

Comments
 (0)