1use std::marker::PhantomData;
2
3pub use clause_filter::NoClauses;
4use clause_filter::*;
5pub use iterator::CallerBoundsIterator;
6use output_as::*;
7use polarity_filter::*;
8use self_ty_filter::*;
9use trait_filter::*;
10
11use crate::inherent::*;
12use crate::lang_items::SolverTraitLangItem;
13use crate::{Binder, ClauseKind, ClausePolarity, Interner, TraitClause, Upcast};
14
15#[must_use]
16pub struct CallerBoundsAccessor<I, Iter, CF>
17where
18 I: Interner,
19 Iter: Iterator<Item = I::Clause>,
20 CF: ClauseFilter,
21{
22 clauses: Iter,
23 clause_filter: CF,
24 cx: PhantomData<I>,
25}
26
27impl<I, Iter> CallerBoundsAccessor<I, Iter, NoClauses>
28where
29 I: Interner,
30 Iter: Iterator<Item = I::Clause>,
31{
32 #[inline]
33 pub fn new(clauses: Iter) -> Self {
34 Self { clauses, clause_filter: NoClauses, cx: PhantomData }
35 }
36}
37
38mod iterator {
39 use super::*;
40 use crate::param_env::output_as::OutputAs;
41
42 pub trait CallerBoundsIterator<I, Iter>
43 where
44 I: Interner,
45 Iter: Iterator<Item = I::Clause>,
46 {
47 type Item;
48 fn iter(self) -> impl Iterator<Item = Self::Item>;
50 }
51 impl<I, Iter> CallerBoundsIterator<I, Iter> for CallerBoundsAccessor<I, Iter, NonTraitClauses>
52 where
53 I: Interner,
54 Iter: Iterator<Item = I::Clause>,
55 {
56 type Item = I::Clause;
57
58 #[inline]
59 fn iter(self) -> impl Iterator<Item = Self::Item> {
60 self.clauses.filter(|&i| !#[allow(non_exhaustive_omitted_patterns)] match i.kind().skip_binder() {
ClauseKind::Trait(_) => true,
_ => false,
}matches!(i.kind().skip_binder(), ClauseKind::Trait(_)))
61 }
62 }
63
64 impl<I, Iter> CallerBoundsIterator<I, Iter> for CallerBoundsAccessor<I, Iter, AllClauses>
65 where
66 I: Interner,
67 Iter: Iterator<Item = I::Clause>,
68 {
69 type Item = I::Clause;
70
71 #[inline]
72 fn iter(self) -> impl Iterator<Item = Self::Item> {
73 self.clauses
74 }
75 }
76
77 #[inline]
78 fn filter_trait_clause_helper<I, P, S, T, O>(
79 filter: &TraitClauses<I, P, S, T, O>,
80 clause: TraitClause<I>,
81 ) -> bool
82 where
83 I: Interner,
84 P: PolarityFilter,
85 S: SelfTyFilter<I>,
86 T: TraitFilter<I>,
87 O: OutputAs<I>,
88 {
89 let TraitClauses { cx: _, polarity_filter, self_type_filter, trait_filter, output: _ } =
90 filter;
91 polarity_filter.allow_polarity(clause.polarity)
92 && self_type_filter.allow_self_ty(clause.self_ty())
93 && trait_filter.allow_clause(clause)
94 }
95
96 impl<I, Iter, P, S, T, O> CallerBoundsIterator<I, Iter>
97 for CallerBoundsAccessor<I, Iter, TraitClauses<I, P, S, T, O>>
98 where
99 I: Interner,
100 Iter: Iterator<Item = I::Clause>,
101 P: PolarityFilter,
102 S: SelfTyFilter<I>,
103 T: TraitFilter<I>,
104 O: OutputAs<I>,
105 {
106 type Item = O::Output;
107
108 #[inline]
109 fn iter(self) -> impl Iterator<Item = Self::Item> {
110 self.clauses.filter_map(move |clause| {
111 let kind = clause.kind();
112 match kind.skip_binder() {
113 ClauseKind::Trait(trait_clause)
114 if filter_trait_clause_helper(&self.clause_filter, trait_clause) =>
115 {
116 Some(O::construct_from_trait_clause(
117 kind.rebind(trait_clause),
118 self.clause_filter.cx,
119 ))
120 }
121 _ => None,
122 }
123 })
124 }
125 }
126}
127
128mod clause_filter {
129 use super::*;
130
131 pub trait ClauseFilter {}
132
133 pub struct NoClauses;
134 impl ClauseFilter for NoClauses {}
135
136 pub struct NonTraitClauses;
137 impl ClauseFilter for NonTraitClauses {}
138
139 pub struct TraitClauses<I, P, S, T, O> {
140 pub cx: I,
141 pub polarity_filter: P,
142 pub self_type_filter: S,
143 pub trait_filter: T,
144 pub output: O,
145 }
146
147 impl<I, P, S, T, O> ClauseFilter for TraitClauses<I, P, S, T, O> {}
148
149 pub struct AllClauses;
150 impl ClauseFilter for AllClauses {}
151
152 impl<I, Iter> CallerBoundsAccessor<I, Iter, NoClauses>
153 where
154 I: Interner,
155 Iter: Iterator<Item = I::Clause>,
156 {
157 #[inline]
158 pub fn non_trait_clauses(self) -> CallerBoundsAccessor<I, Iter, NonTraitClauses> {
159 CallerBoundsAccessor {
160 clauses: self.clauses,
161 clause_filter: NonTraitClauses,
162 cx: PhantomData,
163 }
164 }
165
166 #[inline]
167 pub fn trait_clauses(
168 self,
169 cx: I,
170 ) -> CallerBoundsAccessor<I, Iter, TraitClauses<I, (), (), (), OutputAsTraitClause>>
171 {
172 CallerBoundsAccessor {
173 clauses: self.clauses,
174 clause_filter: TraitClauses {
175 polarity_filter: (),
176 self_type_filter: (),
177 trait_filter: (),
178 output: OutputAsTraitClause,
179 cx,
180 },
181 cx: PhantomData,
182 }
183 }
184
185 #[inline]
187 pub fn all_clauses(self, _cx: I) -> CallerBoundsAccessor<I, Iter, AllClauses> {
189 CallerBoundsAccessor {
190 clauses: self.clauses,
191 clause_filter: AllClauses,
192 cx: PhantomData,
193 }
194 }
195 }
196}
197
198mod polarity_filter {
199 use super::*;
200
201 pub trait PolarityFilter {
202 fn allow_polarity(&self, p: ClausePolarity) -> bool;
203 }
204 impl PolarityFilter for () {
205 #[inline]
206 fn allow_polarity(&self, _p: ClausePolarity) -> bool {
207 true
208 }
209 }
210 impl PolarityFilter for ClausePolarity {
211 #[inline]
212 fn allow_polarity(&self, p: ClausePolarity) -> bool {
213 *self == p
214 }
215 }
216
217 impl<I, Iter, P, S, T, O> CallerBoundsAccessor<I, Iter, TraitClauses<I, P, S, T, O>>
218 where
219 I: Interner,
220 Iter: Iterator<Item = I::Clause>,
221 P: PolarityFilter,
222 S: SelfTyFilter<I>,
223 T: TraitFilter<I>,
224 O: OutputAs<I>,
225 {
226 #[inline]
227 pub fn with_polarity(
228 self,
229 polarity: ClausePolarity,
230 ) -> CallerBoundsAccessor<I, Iter, TraitClauses<I, ClausePolarity, S, T, O>> {
231 let CallerBoundsAccessor {
232 clauses: iter,
233 clause_filter:
234 TraitClauses { cx, polarity_filter: _, self_type_filter, trait_filter, output },
235 cx: PhantomData,
236 } = self;
237 CallerBoundsAccessor {
238 clauses: iter,
239 clause_filter: TraitClauses {
240 cx,
241 polarity_filter: polarity,
242 self_type_filter,
243 trait_filter,
244 output,
245 },
246 cx: PhantomData,
247 }
248 }
249 #[inline]
250 pub fn validate_self_ty<F: Fn(I::Ty) -> bool>(
251 self,
252 validate_fn: F,
253 ) -> CallerBoundsAccessor<I, Iter, TraitClauses<I, P, FilterFn<F>, T, O>> {
254 let CallerBoundsAccessor {
255 clauses: iter,
256 clause_filter:
257 TraitClauses { cx, polarity_filter, self_type_filter: _, trait_filter, output },
258 cx: PhantomData,
259 } = self;
260 CallerBoundsAccessor {
261 clauses: iter,
262 clause_filter: TraitClauses {
263 cx,
264 polarity_filter,
265 self_type_filter: FilterFn { f: validate_fn },
266 trait_filter,
267 output,
268 },
269 cx: PhantomData,
270 }
271 }
272 #[inline]
273 pub fn with_self_ty(
274 self,
275 desired_self_ty: I::Ty,
276 ) -> CallerBoundsAccessor<I, Iter, TraitClauses<I, P, FilterFn<impl Fn(I::Ty) -> bool>, T, O>>
277 {
278 self.validate_self_ty(move |actual_self_ty| actual_self_ty == desired_self_ty)
279 }
280 #[inline]
281 pub fn for_trait(
282 self,
283 def_id: I::TraitId,
284 ) -> CallerBoundsAccessor<I, Iter, TraitClauses<I, P, S, TraitWithId<I>, O>> {
285 let CallerBoundsAccessor {
286 clauses: iter,
287 clause_filter:
288 TraitClauses { polarity_filter, self_type_filter, trait_filter: _, output, cx },
289 cx: PhantomData,
290 } = self;
291 CallerBoundsAccessor {
292 clauses: iter,
293 clause_filter: TraitClauses {
294 polarity_filter,
295 self_type_filter,
296 trait_filter: TraitWithId(def_id),
297 output,
298 cx,
299 },
300 cx: PhantomData,
301 }
302 }
303 #[inline]
304 pub fn for_trait_lang_item(
305 self,
306 lang_item: SolverTraitLangItem,
307 ) -> CallerBoundsAccessor<I, Iter, TraitClauses<I, P, S, TraitWithId<I>, O>> {
308 let cx = self.clause_filter.cx;
309 self.for_trait(cx.require_trait_lang_item(lang_item))
310 }
311
312 #[inline]
313 pub fn interned(
314 self,
315 ) -> CallerBoundsAccessor<I, Iter, TraitClauses<I, P, S, T, OutputAsInternedClause>>
316 {
317 let CallerBoundsAccessor {
318 clauses: iter,
319 clause_filter:
320 TraitClauses { cx, polarity_filter, self_type_filter, trait_filter, output: _ },
321 cx: PhantomData,
322 } = self;
323 CallerBoundsAccessor {
324 clauses: iter,
325 clause_filter: TraitClauses {
326 cx,
327 polarity_filter,
328 self_type_filter,
329 trait_filter,
330 output: OutputAsInternedClause,
331 },
332 cx: PhantomData,
333 }
334 }
335 }
336}
337
338mod self_ty_filter {
339 use super::*;
340
341 pub trait SelfTyFilter<I>
342 where
343 I: Interner,
344 {
345 fn allow_self_ty(&self, ty: I::Ty) -> bool;
346 }
347
348 impl<I> SelfTyFilter<I> for ()
349 where
350 I: Interner,
351 {
352 #[inline]
353 fn allow_self_ty(&self, _ty: I::Ty) -> bool {
354 true
355 }
356 }
357
358 pub struct FilterFn<F> {
359 pub f: F,
360 }
361 impl<I, F> SelfTyFilter<I> for FilterFn<F>
362 where
363 I: Interner,
364 F: Fn(I::Ty) -> bool,
365 {
366 #[inline]
367 fn allow_self_ty(&self, ty: I::Ty) -> bool {
368 (self.f)(ty)
369 }
370 }
371}
372
373mod trait_filter {
374 use super::*;
375
376 pub trait TraitFilter<I>
377 where
378 I: Interner,
379 {
380 fn allow_clause(&self, clause: TraitClause<I>) -> bool;
381 }
382
383 impl<I> TraitFilter<I> for ()
384 where
385 I: Interner,
386 {
387 #[inline]
388 fn allow_clause(&self, _clause: TraitClause<I>) -> bool {
389 true
390 }
391 }
392
393 pub struct TraitWithId<I>(pub I::TraitId)
394 where
395 I: Interner;
396 impl<I> TraitFilter<I> for TraitWithId<I>
397 where
398 I: Interner,
399 {
400 #[inline]
401 fn allow_clause(&self, clause: TraitClause<I>) -> bool {
402 clause.def_id() == self.0
403 }
404 }
405}
406
407mod output_as {
408 use super::*;
409
410 pub trait OutputAs<I: Interner> {
411 type Output;
412 fn construct_from_trait_clause(tc: Binder<I, TraitClause<I>>, cx: I) -> Self::Output;
413 }
414
415 pub struct OutputAsInternedClause;
416 impl<I: Interner> OutputAs<I> for OutputAsInternedClause {
417 type Output = I::Clause;
418 fn construct_from_trait_clause(tc: Binder<I, TraitClause<I>>, cx: I) -> I::Clause {
419 tc.upcast(cx)
420 }
421 }
422
423 pub struct OutputAsTraitClause;
424 impl<I: Interner> OutputAs<I> for OutputAsTraitClause {
425 type Output = Binder<I, TraitClause<I>>;
426 fn construct_from_trait_clause(
427 tc: Binder<I, TraitClause<I>>,
428 _cx: I,
429 ) -> Binder<I, TraitClause<I>> {
430 tc
431 }
432 }
433}