1use std::fmt::Debug;
2
3use rustc_hir::def_id::DefId;
4use rustc_middle::ty::{self, Ty, TyVid, Upcast};
5use thin_vec::{ThinVec, thin_vec};
6
7use super::{ObligationCause, PredicateObligation, PredicateObligations};
8use crate::infer::InferCtxt;
9use crate::traits::Obligation;
10
11#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for ScrubbedTraitError<'tcx> {
#[inline]
fn clone(&self) -> ScrubbedTraitError<'tcx> {
match self {
ScrubbedTraitError::TrueError => ScrubbedTraitError::TrueError,
ScrubbedTraitError::Ambiguity => ScrubbedTraitError::Ambiguity,
ScrubbedTraitError::Cycle(__self_0) =>
ScrubbedTraitError::Cycle(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ScrubbedTraitError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ScrubbedTraitError::TrueError =>
::core::fmt::Formatter::write_str(f, "TrueError"),
ScrubbedTraitError::Ambiguity =>
::core::fmt::Formatter::write_str(f, "Ambiguity"),
ScrubbedTraitError::Cycle(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Cycle",
&__self_0),
}
}
}Debug)]
18pub enum ScrubbedTraitError<'tcx> {
19 TrueError,
21 Ambiguity,
23 Cycle(PredicateObligations<'tcx>),
26}
27
28impl<'tcx> ScrubbedTraitError<'tcx> {
29 pub fn is_true_error(&self) -> bool {
30 match self {
31 ScrubbedTraitError::TrueError => true,
32 ScrubbedTraitError::Ambiguity | ScrubbedTraitError::Cycle(_) => false,
33 }
34 }
35}
36
37#[derive(#[automatically_derived]
impl<E: ::core::fmt::Debug> ::core::fmt::Debug for TraitErrors<E> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
TraitErrors::HasErrors(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"HasErrors", &__self_0),
TraitErrors::NoErrors =>
::core::fmt::Formatter::write_str(f, "NoErrors"),
}
}
}Debug, #[automatically_derived]
impl<E: ::core::clone::Clone> ::core::clone::Clone for TraitErrors<E> {
#[inline]
fn clone(&self) -> TraitErrors<E> {
match self {
TraitErrors::HasErrors(__self_0) =>
TraitErrors::HasErrors(::core::clone::Clone::clone(__self_0)),
TraitErrors::NoErrors => TraitErrors::NoErrors,
}
}
}Clone)]
38#[must_use]
39pub enum TraitErrors<E> {
40 HasErrors(ThinVec<E>),
41 NoErrors,
42}
43
44impl<E> TraitErrors<E> {
45 #[inline]
46 pub fn from_iter(iter: impl ExactSizeIterator<Item = E>) -> TraitErrors<E> {
47 if iter.len() == 0 { TraitErrors::NoErrors } else { TraitErrors::HasErrors(iter.collect()) }
48 }
49
50 #[inline]
51 pub fn has_errors(&self) -> bool {
52 #[allow(non_exhaustive_omitted_patterns)] match self {
TraitErrors::HasErrors(_) => true,
_ => false,
}matches!(self, TraitErrors::HasErrors(_))
53 }
54
55 #[inline]
56 pub fn no_errors(&self) -> bool {
57 #[allow(non_exhaustive_omitted_patterns)] match self {
TraitErrors::NoErrors => true,
_ => false,
}matches!(self, TraitErrors::NoErrors)
58 }
59
60 #[inline]
61 pub fn as_slice(&self) -> &[E] {
62 match self {
63 TraitErrors::HasErrors(errors) => errors.as_slice(),
64 TraitErrors::NoErrors => &[],
65 }
66 }
67
68 #[inline]
69 pub fn as_mut_slice(&mut self) -> &mut [E] {
70 match self {
71 TraitErrors::HasErrors(errors) => errors.as_mut_slice(),
72 TraitErrors::NoErrors => &mut [],
73 }
74 }
75
76 #[inline]
77 pub fn into_thin_vec(self) -> ThinVec<E> {
78 match self {
79 TraitErrors::HasErrors(errors) => errors,
80 TraitErrors::NoErrors => ThinVec::new(),
81 }
82 }
83
84 #[cold]
85 pub fn push(&mut self, err: E) {
86 match self {
87 TraitErrors::HasErrors(errors) => errors.push(err),
88 TraitErrors::NoErrors => *self = TraitErrors::HasErrors({
let len = [()].len();
let mut vec = ::thin_vec::ThinVec::with_capacity(len);
vec.push(err);
vec
}thin_vec![err]),
89 }
90 }
91
92 #[inline]
93 pub fn len(&self) -> usize {
94 match self {
95 TraitErrors::HasErrors(errors) => errors.len(),
96 TraitErrors::NoErrors => 0,
97 }
98 }
99}
100
101impl<E> IntoIterator for TraitErrors<E> {
102 type Item = E;
103 type IntoIter = thin_vec::IntoIter<E>;
104
105 #[inline]
106 fn into_iter(self) -> Self::IntoIter {
107 self.into_thin_vec().into_iter()
108 }
109}
110
111impl<'a, E> IntoIterator for &'a TraitErrors<E> {
112 type Item = &'a E;
113 type IntoIter = std::slice::Iter<'a, E>;
114
115 #[inline]
116 fn into_iter(self) -> Self::IntoIter {
117 self.as_slice().iter()
118 }
119}
120
121pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
122 fn register_bound(
126 &mut self,
127 infcx: &InferCtxt<'tcx>,
128 param_env: ty::ParamEnv<'tcx>,
129 ty: Ty<'tcx>,
130 def_id: DefId,
131 cause: ObligationCause<'tcx>,
132 ) {
133 let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
134 self.register_predicate_obligation(
135 infcx,
136 Obligation {
137 cause,
138 recursion_depth: 0,
139 param_env,
140 predicate: trait_ref.upcast(infcx.tcx),
141 },
142 );
143 }
144
145 fn register_predicate_obligation(
146 &mut self,
147 infcx: &InferCtxt<'tcx>,
148 obligation: PredicateObligation<'tcx>,
149 );
150
151 fn register_predicate_obligations(
152 &mut self,
153 infcx: &InferCtxt<'tcx>,
154 obligations: PredicateObligations<'tcx>,
155 ) {
156 for obligation in obligations {
157 self.register_predicate_obligation(infcx, obligation);
158 }
159 }
160
161 #[must_use]
170 fn try_evaluate_obligations(&mut self, infcx: &InferCtxt<'tcx>) -> TraitErrors<E>;
171
172 fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> TraitErrors<E>;
173
174 #[must_use]
183 fn evaluate_obligations_error_on_ambiguity(
184 &mut self,
185 infcx: &InferCtxt<'tcx>,
186 ) -> TraitErrors<E> {
187 let errors = self.try_evaluate_obligations(infcx);
188 if errors.has_errors() {
189 return errors;
190 }
191
192 self.collect_remaining_errors(infcx)
193 }
194
195 fn has_pending_obligations(&self) -> bool;
196
197 fn pending_obligations(&self) -> PredicateObligations<'tcx>;
198
199 fn pending_obligations_potentially_referencing_sub_root(
204 &self,
205 _infcx: &InferCtxt<'tcx>,
206 _sub_root: TyVid,
207 ) -> PredicateObligations<'tcx> {
208 self.pending_obligations()
209 }
210
211 fn pending_obligations_potentially_referencing_float_infer(
216 &self,
217 _infcx: &InferCtxt<'tcx>,
218 ) -> PredicateObligations<'tcx> {
219 self.pending_obligations()
220 }
221
222 fn drain_stalled_obligations_for_coroutines(
226 &mut self,
227 infcx: &InferCtxt<'tcx>,
228 ) -> PredicateObligations<'tcx>;
229}
230
231pub trait FromSolverError<'tcx, E>: Debug + 'tcx {
232 fn from_solver_error(infcx: &InferCtxt<'tcx>, error: E) -> Self;
233}