@@ -32,6 +32,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
3232use rustc_errors:: ErrorGuaranteed ;
3333use rustc_middle:: query:: Providers ;
3434use rustc_middle:: span_bug;
35+ use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
3536use rustc_middle:: ty:: fold:: TypeFoldable ;
3637use rustc_middle:: ty:: visit:: { TypeVisitable , TypeVisitableExt } ;
3738use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFolder , TypeSuperVisitable , Upcast } ;
@@ -70,7 +71,7 @@ pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, Placeh
7071
7172pub use rustc_infer:: traits:: * ;
7273
73- /// A trait error without most of its information removed. This is the error
74+ /// A trait error with most of its information removed. This is the error
7475/// returned by an [`ObligationCtxt`] by default, and suitable if you just
7576/// want to see if a predicate holds, and don't particularly care about the
7677/// error itself (except for if it's an ambiguity or true error).
@@ -142,6 +143,43 @@ impl<'tcx> Debug for FulfillmentError<'tcx> {
142143 }
143144}
144145
146+ #[ derive( Clone ) ]
147+ pub enum FulfillmentErrorCode < ' tcx > {
148+ /// Inherently impossible to fulfill; this trait is implemented if and only
149+ /// if it is already implemented.
150+ Cycle ( Vec < PredicateObligation < ' tcx > > ) ,
151+ Select ( SelectionError < ' tcx > ) ,
152+ Project ( MismatchedProjectionTypes < ' tcx > ) ,
153+ Subtype ( ExpectedFound < Ty < ' tcx > > , TypeError < ' tcx > ) , // always comes from a SubtypePredicate
154+ ConstEquate ( ExpectedFound < ty:: Const < ' tcx > > , TypeError < ' tcx > ) ,
155+ Ambiguity {
156+ /// Overflow is only `Some(suggest_recursion_limit)` when using the next generation
157+ /// trait solver `-Znext-solver`. With the old solver overflow is eagerly handled by
158+ /// emitting a fatal error instead.
159+ overflow : Option < bool > ,
160+ } ,
161+ }
162+
163+ impl < ' tcx > Debug for FulfillmentErrorCode < ' tcx > {
164+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
165+ match * self {
166+ FulfillmentErrorCode :: Select ( ref e) => write ! ( f, "{e:?}" ) ,
167+ FulfillmentErrorCode :: Project ( ref e) => write ! ( f, "{e:?}" ) ,
168+ FulfillmentErrorCode :: Subtype ( ref a, ref b) => {
169+ write ! ( f, "CodeSubtypeError({a:?}, {b:?})" )
170+ }
171+ FulfillmentErrorCode :: ConstEquate ( ref a, ref b) => {
172+ write ! ( f, "CodeConstEquateError({a:?}, {b:?})" )
173+ }
174+ FulfillmentErrorCode :: Ambiguity { overflow : None } => write ! ( f, "Ambiguity" ) ,
175+ FulfillmentErrorCode :: Ambiguity { overflow : Some ( suggest_increasing_limit) } => {
176+ write ! ( f, "Overflow({suggest_increasing_limit})" )
177+ }
178+ FulfillmentErrorCode :: Cycle ( ref cycle) => write ! ( f, "Cycle({cycle:?})" ) ,
179+ }
180+ }
181+ }
182+
145183/// Whether to skip the leak check, as part of a future compatibility warning step.
146184///
147185/// The "default" for skip-leak-check corresponds to the current
0 commit comments