Skip to content

Allow printing TraitRef and TraitPredicate with Infcx information #125262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use crate::traits::solve::{
ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
};
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData,
GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern,
Expand All @@ -52,7 +53,7 @@ use rustc_errors::{
Applicability, Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def::{DefKind, Namespace};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::definitions::Definitions;
use rustc_hir::intravisit::Visitor;
Expand Down Expand Up @@ -89,6 +90,18 @@ use std::ops::{Bound, Deref};
#[allow(rustc::usage_of_ty_tykind)]
impl<'tcx> Interner for TyCtxt<'tcx> {
type DefId = DefId;
fn print_def_path(defid: Self::DefId, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ty::tls::with(|tcx| {
with_no_trimmed_paths!({
// this namespace is..... not strictly correct lol
let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
cx.print_def_path(defid, &[])
})?;
f.write_str(&s)
})
})
}

type AdtDef = ty::AdtDef<'tcx>;

type GenericArgs = ty::GenericArgsRef<'tcx>;
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,17 @@ impl fmt::Debug for ty::LateParamRegion {
}
}

impl<'tcx> fmt::Debug for Ty<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
with_no_trimmed_paths!(self.kind().fmt(f))
}
}
impl<'tcx> ty::DebugWithInfcx<TyCtxt<'tcx>> for Ty<'tcx> {
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
this: WithInfcx<'_, Infcx, &Self>,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
this.data.fmt(f)
}
}
impl<'tcx> fmt::Debug for Ty<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
with_no_trimmed_paths!(fmt::Debug::fmt(self.kind(), f))
this.map(|ty| ty.kind()).fmt(f)
}
}

Expand Down Expand Up @@ -264,9 +264,12 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::RegionVid {
this: WithInfcx<'_, Infcx, &Self>,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match this.infcx.universe_of_lt(*this.data) {
Some(universe) => write!(f, "'?{}_{}", this.data.index(), universe.index()),
match this.infcx {
None => write!(f, "{:?}", this.data),
Some(infcx) => match infcx.universe_of_lt(*this.data) {
Some(universe) => write!(f, "'?{}_{}", this.data.index(), universe.index()),
None => write!(f, "'?{}_..", this.data.index()),
},
}
}
}
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_type_ir/src/const_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,18 @@ impl<I: Interner> DebugWithInfcx<I> for InferConst {
this: WithInfcx<'_, Infcx, &Self>,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match *this.data {
InferConst::Var(vid) => match this.infcx.universe_of_ct(vid) {
None => write!(f, "{:?}", this.data),
Some(universe) => write!(f, "?{}_{}c", vid.index(), universe.index()),
match this.infcx {
None => write!(f, "{:?}", this.data),
Some(infcx) => match *this.data {
InferConst::Var(vid) => match infcx.universe_of_ct(vid) {
None => write!(f, "?{}_..c", vid.index()),
Some(universe) => write!(f, "?{}_{}c", vid.index(), universe.index()),
},
InferConst::EffectVar(vid) => write!(f, "?{}e", vid.index()),
InferConst::Fresh(_) => {
unreachable!()
}
},
InferConst::EffectVar(vid) => write!(f, "?{}e", vid.index()),
InferConst::Fresh(_) => {
unreachable!()
}
}
}
}
Expand Down
50 changes: 27 additions & 23 deletions compiler/rustc_type_ir/src/debug.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,55 @@
use crate::{ConstVid, InferCtxtLike, Interner, TyVid, UniverseIndex};

use core::fmt;
use std::marker::PhantomData;

pub struct NoInfcx<I>(PhantomData<I>);

pub struct NoInfcx<I>(core::convert::Infallible, core::marker::PhantomData<I>);
impl<I: Interner> InferCtxtLike for NoInfcx<I> {
type Interner = I;

fn interner(&self) -> Self::Interner {
unreachable!()
match self.0 {}
}

fn universe_of_ty(&self, _ty: TyVid) -> Option<UniverseIndex> {
None
match self.0 {}
}

fn universe_of_lt(&self, _lt: I::InferRegion) -> Option<UniverseIndex> {
None
fn root_ty_var(&self, _vid: TyVid) -> TyVid {
match self.0 {}
}

fn universe_of_ct(&self, _ct: ConstVid) -> Option<UniverseIndex> {
None
fn probe_ty_var(&self, _vid: TyVid) -> Option<<Self::Interner as Interner>::Ty> {
match self.0 {}
}

fn root_ty_var(&self, vid: TyVid) -> TyVid {
vid
fn universe_of_lt(
&self,
_lt: <Self::Interner as Interner>::InferRegion,
) -> Option<UniverseIndex> {
match self.0 {}
}

fn probe_ty_var(&self, _vid: TyVid) -> Option<I::Ty> {
None
fn opportunistic_resolve_lt_var(
&self,
_vid: <Self::Interner as Interner>::InferRegion,
) -> Option<<Self::Interner as Interner>::Region> {
match self.0 {}
}

fn opportunistic_resolve_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
None
fn universe_of_ct(&self, _ct: ConstVid) -> Option<UniverseIndex> {
match self.0 {}
}

fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
vid
fn root_ct_var(&self, _vid: ConstVid) -> ConstVid {
match self.0 {}
}

fn probe_ct_var(&self, _vid: ConstVid) -> Option<I::Const> {
None
fn probe_ct_var(&self, _vid: ConstVid) -> Option<<Self::Interner as Interner>::Const> {
match self.0 {}
}

fn defining_opaque_types(&self) -> <Self::Interner as Interner>::DefiningOpaqueTypes {
Default::default()
match self.0 {}
}
}

Expand Down Expand Up @@ -96,7 +100,7 @@ impl<I: Interner, T: DebugWithInfcx<I>> DebugWithInfcx<I> for [T] {

pub struct WithInfcx<'a, Infcx: InferCtxtLike, T> {
pub data: T,
pub infcx: &'a Infcx,
pub infcx: Option<&'a Infcx>,
}

impl<Infcx: InferCtxtLike, T: Copy> Copy for WithInfcx<'_, Infcx, T> {}
Expand All @@ -109,13 +113,13 @@ impl<Infcx: InferCtxtLike, T: Clone> Clone for WithInfcx<'_, Infcx, T> {

impl<'a, I: Interner, T> WithInfcx<'a, NoInfcx<I>, T> {
pub fn with_no_infcx(data: T) -> Self {
Self { data, infcx: &NoInfcx(PhantomData) }
Self { data, infcx: None }
}
}

impl<'a, Infcx: InferCtxtLike, T> WithInfcx<'a, Infcx, T> {
pub fn new(data: T, infcx: &'a Infcx) -> Self {
Self { data, infcx }
Self { data, infcx: Some(infcx) }
}

pub fn wrap<U>(self, u: U) -> WithInfcx<'a, Infcx, U> {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub trait Interner:
+ IrPrint<FnSig<Self>>
{
type DefId: Copy + Debug + Hash + Eq;
fn print_def_path(defid: Self::DefId, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;

type AdtDef: Copy + Debug + Hash + Eq;

type GenericArgs: GenericArgs<Self>;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/ir_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ define_display_via_print!(
FnSig,
);

define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
define_debug_via_print!(ExistentialTraitRef, ExistentialProjection);
78 changes: 77 additions & 1 deletion compiler/rustc_type_ir/src/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,44 @@ pub struct TraitRef<I: Interner> {
_use_trait_ref_new_instead: (),
}

impl<I: Interner> fmt::Debug for TraitRef<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
WithInfcx::with_no_infcx(self).fmt(f)
}
}
impl<I: Interner> DebugWithInfcx<I> for TraitRef<I> {
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
this: WithInfcx<'_, Infcx, &Self>,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
// If we ever wind up with a malformed `TraitRef` it might be good to not ICE in its Debug impl(?)
if this.data.args.len() == 0 {
return f
.debug_tuple("TraitRef")
.field(&this.data.def_id)
.field(&this.data.args)
.finish();
}

write!(f, "({:?} as ", this.map(|trait_ref| trait_ref.args[0]))?;
I::print_def_path(this.data.def_id, f)?;

match this.data.args.len() {
0 => unreachable!(),
1 => write!(f, ")"), // the first arg is the self type
2 => write!(f, "<{:?}>)", this.map(|trait_ref| trait_ref.args[1])),
3.. => {
write!(f, "<{:?}", this.map(|trait_ref| trait_ref.args[1]))?;
for arg in &this.data.args[2..] {
let arg = this.wrap(arg);
write!(f, ", {:?}", arg)?;
}
write!(f, ">)")
}
}
}
}

impl<I: Interner> TraitRef<I> {
pub fn new(
interner: I,
Expand Down Expand Up @@ -114,8 +152,46 @@ impl<I: Interner> TraitPredicate<I> {

impl<I: Interner> fmt::Debug for TraitPredicate<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
WithInfcx::with_no_infcx(self).fmt(f)
}
}
impl<I: Interner> DebugWithInfcx<I> for TraitPredicate<I> {
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
this: WithInfcx<'_, Infcx, &Self>,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
// FIXME(effects) printing?
write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)

// If we ever wind up with a malformed `TraitRef` it might be good to not ICE in its Debug impl(?)
if this.data.trait_ref.args.len() == 0 {
return f
.debug_tuple("TraitPredicate")
.field(&this.data.trait_ref.def_id)
.field(&this.data.trait_ref.args)
.field(&this.data.polarity)
.finish();
}

write!(f, "({:?}: ", this.map(|pred| pred.trait_ref.args[0]))?;
match this.data.polarity {
PredicatePolarity::Positive => (),
PredicatePolarity::Negative => write!(f, "!")?,
};
I::print_def_path(this.data.trait_ref.def_id, f)?;

match this.data.trait_ref.args.len() {
0 => unreachable!(),
1 => write!(f, ")"), // the first arg is the self type
2 => write!(f, "<{:?}>)", this.map(|trait_ref| trait_ref.trait_ref.args[1])),
3.. => {
write!(f, "<{:?}", this.map(|trait_ref| trait_ref.trait_ref.args[1]))?;
for arg in &this.data.trait_ref.args[2..] {
let arg = this.wrap(arg);
write!(f, ", {:?}", arg)?;
}
write!(f, ">)")
}
}
}
}

Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_type_ir/src/ty_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,6 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
}
}

// This is manually implemented because a derive would require `I: Debug`
impl<I: Interner> fmt::Debug for TyKind<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
WithInfcx::with_no_infcx(self).fmt(f)
Expand Down Expand Up @@ -924,15 +923,18 @@ impl<I: Interner> DebugWithInfcx<I> for InferTy {
this: WithInfcx<'_, Infcx, &Self>,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
match this.data {
InferTy::TyVar(vid) => {
if let Some(universe) = this.infcx.universe_of_ty(*vid) {
write!(f, "?{}_{}t", vid.index(), universe.index())
} else {
write!(f, "{:?}", this.data)
match this.infcx {
None => write!(f, "{:?}", this.data),
Some(infcx) => match this.data {
InferTy::TyVar(vid) => {
if let Some(universe) = infcx.universe_of_ty(*vid) {
write!(f, "?{}_{}t", vid.index(), universe.index())
} else {
write!(f, "{}_..t", vid.index())
}
}
}
_ => write!(f, "{:?}", this.data),
_ => write!(f, "{:?}", this.data),
},
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/traits/cache-reached-depth-ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ fn test<X: ?Sized + Send>() {}

fn main() {
test::<A>();
//~^ ERROR evaluate(Binder { value: TraitPredicate(<A as std::marker::Send>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
//~^ ERROR evaluate(Binder { value: (A: std::marker::Send), bound_vars: [] }) = Ok(EvaluatedToOk)
}
2 changes: 1 addition & 1 deletion tests/ui/traits/cache-reached-depth-ice.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: evaluate(Binder { value: TraitPredicate(<A as std::marker::Send>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
error: evaluate(Binder { value: (A: std::marker::Send), bound_vars: [] }) = Ok(EvaluatedToOk)
--> $DIR/cache-reached-depth-ice.rs:43:5
|
LL | fn test<X: ?Sized + Send>() {}
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/traits/issue-83538-tainted-cache-after-cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ fn main() {
// Key is that Vec<First> is "ok" and Third<'_, Ty> is "ok modulo regions":

forward();
//~^ ERROR evaluate(Binder { value: TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
//~| ERROR evaluate(Binder { value: TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions)
//~^ ERROR evaluate(Binder { value: (std::vec::Vec<First, std::alloc::Global>: std::marker::Unpin), bound_vars: [] }) = Ok(EvaluatedToOk)
//~| ERROR evaluate(Binder { value: (Third<'?0, Ty>: std::marker::Unpin), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions)

reverse();
//~^ ERROR evaluate(Binder { value: TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
//~| ERROR evaluate(Binder { value: TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions)
//~^ ERROR evaluate(Binder { value: (std::vec::Vec<First, std::alloc::Global>: std::marker::Unpin), bound_vars: [] }) = Ok(EvaluatedToOk)
//~| ERROR evaluate(Binder { value: (Third<'?2, Ty>: std::marker::Unpin), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions)
}
Loading
Loading