1use crate::prelude::*;
2#[cfg(creusot)]
3use core::convert::Infallible;
4#[cfg(feature = "nightly")]
5use core::marker::Tuple;
6use core::ops::*;
7
8#[cfg(feature = "nightly")]
15pub trait FnOnceExt<Args: Tuple> {
16 type Output;
17
18 #[logic(prophetic)]
19 fn precondition(self, a: Args) -> bool;
20
21 #[logic(prophetic)]
22 fn postcondition_once(self, a: Args, res: Self::Output) -> bool;
23}
24
25#[cfg(not(feature = "nightly"))]
26pub trait FnOnceExt<Args> {
27 type Output;
28}
29
30#[cfg(feature = "nightly")]
33pub trait FnMutExt<Args: Tuple>: FnOnceExt<Args> {
34 #[logic(prophetic)]
35 fn postcondition_mut(self, _: Args, _: Self, _: Self::Output) -> bool;
36
37 #[logic(prophetic)]
38 fn hist_inv(self, _: Self) -> bool;
39
40 #[logic(law)]
41 #[requires(self.postcondition_mut(args, res_state, res))]
42 #[ensures(
43 #[trigger(self.postcondition_mut(args, res_state, res))]
44 #[trigger(self.hist_inv(res_state))]
45 self.hist_inv(res_state))]
46 fn postcondition_mut_hist_inv(self, args: Args, res_state: Self, res: Self::Output);
47
48 #[logic(law)]
49 #[ensures(#[trigger(self.hist_inv(self))] self.hist_inv(self))]
50 fn hist_inv_refl(self);
51
52 #[logic(law)]
53 #[requires(self.hist_inv(b))]
54 #[requires(b.hist_inv(c))]
55 #[ensures(
56 #[trigger(self.hist_inv(b), b.hist_inv(c))]
57 #[trigger(self.hist_inv(b), self.hist_inv(c))]
58 #[trigger(b.hist_inv(c), self.hist_inv(c))]
59 self.hist_inv(c))]
60 fn hist_inv_trans(self, b: Self, c: Self);
61
62 #[logic(law)]
63 #[ensures(#[trigger(self.postcondition_once(args, res))]
64 self.postcondition_once(args, res) ==
65 exists<res_state: Self> self.postcondition_mut(args, res_state, res) && resolve(res_state))]
66 fn fn_mut_once(self, args: Args, res: Self::Output);
67}
68
69#[cfg(not(feature = "nightly"))]
70pub trait FnMutExt<Args>: FnOnceExt<Args> {}
71
72#[cfg(feature = "nightly")]
75pub trait FnExt<Args: Tuple>: FnMutExt<Args> {
76 #[logic(prophetic)]
77 fn postcondition(self, _: Args, _: Self::Output) -> bool;
78
79 #[logic(law)]
80 #[ensures(#[trigger(self.postcondition_mut(args, res_state, res))]
81 self.postcondition_mut(args, res_state, res) == (self.postcondition(args, res) && self == res_state))]
82 fn fn_mut(self, args: Args, res_state: Self, res: Self::Output);
83
84 #[logic(law)]
85 #[ensures(#[trigger(self.postcondition_once(args, res))]
86 self.postcondition_once(args, res) == (self.postcondition(args, res) && resolve(self)))]
87 fn fn_once(self, args: Args, res: Self::Output);
88
89 #[logic(law)]
90 #[ensures(#[trigger(self.hist_inv(res_state))] self.hist_inv(res_state) == (self == res_state))]
91 fn fn_hist_inv(self, res_state: Self);
92}
93
94#[cfg(not(feature = "nightly"))]
97pub trait FnExt<Args>: FnMutExt<Args> {}
98
99#[cfg(feature = "nightly")]
100impl<Args: Tuple, F: ?Sized + FnOnce<Args>> FnOnceExt<Args> for F {
101 type Output = <Self as FnOnce<Args>>::Output;
102
103 #[logic(open, prophetic)]
104 #[allow(unused_variables)]
105 #[intrinsic("precondition")]
106 fn precondition(self, args: Args) -> bool {
107 dead
108 }
109
110 #[logic(open, prophetic)]
111 #[allow(unused_variables)]
112 #[intrinsic("postcondition_once")]
113 fn postcondition_once(self, args: Args, result: Self::Output) -> bool {
114 dead
115 }
116}
117
118#[cfg(feature = "nightly")]
119impl<Args: Tuple, F: ?Sized + FnMut<Args>> FnMutExt<Args> for F {
120 #[logic(open, prophetic)]
121 #[allow(unused_variables)]
122 #[intrinsic("postcondition_mut")]
123 fn postcondition_mut(self, args: Args, result_state: Self, result: Self::Output) -> bool {
124 dead
125 }
126
127 #[logic(open, prophetic)]
128 #[allow(unused_variables)]
129 #[intrinsic("hist_inv")]
130 fn hist_inv(self, result_state: Self) -> bool {
131 dead
132 }
133
134 #[trusted]
135 #[logic(law)]
136 #[requires(self.postcondition_mut(args, res_state, res))]
137 #[ensures(
138 #[trigger(self.postcondition_mut(args, res_state, res))]
139 #[trigger(self.hist_inv(res_state))]
140 self.hist_inv(res_state))]
141 fn postcondition_mut_hist_inv(self, args: Args, res_state: Self, res: Self::Output) {}
142
143 #[trusted]
144 #[logic(law)]
145 #[ensures(#[trigger(self.hist_inv(self))] self.hist_inv(self))]
146 fn hist_inv_refl(self) {}
147
148 #[trusted]
149 #[logic(law)]
150 #[requires(self.hist_inv(b))]
151 #[requires(b.hist_inv(c))]
152 #[ensures(
153 #[trigger(self.hist_inv(b), b.hist_inv(c))]
154 #[trigger(self.hist_inv(b), self.hist_inv(c))]
155 #[trigger(b.hist_inv(c), self.hist_inv(c))]
156 self.hist_inv(c))]
157 fn hist_inv_trans(self, b: Self, c: Self) {}
158
159 #[logic(law)]
160 #[trusted]
161 #[ensures(#[trigger(self.postcondition_once(args, res))]
162 self.postcondition_once(args, res) ==
163 exists<res_state: Self> self.postcondition_mut(args, res_state, res) && resolve(res_state))]
164 fn fn_mut_once(self, args: Args, res: Self::Output) {}
165}
166
167#[cfg(feature = "nightly")]
168impl<Args: Tuple, F: ?Sized + Fn<Args>> FnExt<Args> for F {
169 #[logic(open, prophetic)]
170 #[allow(unused_variables)]
171 #[intrinsic("postcondition")]
172 fn postcondition(self, args: Args, result: Self::Output) -> bool {
173 dead
174 }
175
176 #[logic(law)]
177 #[trusted]
178 #[ensures(#[trigger(self.postcondition_mut(args, res_state, res))]
179 self.postcondition_mut(args, res_state, res) == (self.postcondition(args, res) && self == res_state))]
180 fn fn_mut(self, args: Args, res_state: Self, res: Self::Output) {}
181
182 #[logic(law)]
183 #[trusted]
184 #[ensures(#[trigger(self.postcondition_once(args, res))]
185 self.postcondition_once(args, res) == (self.postcondition(args, res) && resolve(self)))]
186 fn fn_once(self, args: Args, res: Self::Output) {}
187
188 #[logic(law)]
189 #[trusted]
190 #[ensures(#[trigger(self.hist_inv(res_state))] self.hist_inv(res_state) == (self == res_state))]
191 fn fn_hist_inv(self, res_state: Self) {}
192}
193
194extern_spec! {
195 mod core {
196 mod ops {
197 trait FnOnce<Args> where Args: Tuple {
198 #[requires(self.precondition(arg))]
199 #[ensures(self.postcondition_once(arg, result))]
200 fn call_once(self, arg: Args) -> Self::Output;
201 }
202
203 trait FnMut<Args> where Args: Tuple {
204 #[requires((*self).precondition(arg))]
205 #[ensures((*self).postcondition_mut(arg, ^self, result))]
206 fn call_mut(&mut self, arg: Args) -> Self::Output;
207 }
208
209 trait Fn<Args> where Args: Tuple {
210 #[requires((*self).precondition(arg))]
211 #[ensures((*self).postcondition(arg, result))]
212 fn call(&self, arg: Args) -> Self::Output;
213 }
214
215 trait Deref {
216 #[check(ghost)]
217 #[requires(false)]
218 fn deref(&self) -> &Self::Target;
219 }
220
221 trait DerefMut {
222 #[check(ghost)]
223 #[requires(false)]
224 fn deref_mut(&mut self) -> &mut Self::Target;
225 }
226 }
227 }
228
229 impl<'a, T> Deref for &'a T {
230 #[check(ghost)]
231 #[ensures(*result == **self)]
232 fn deref<'b>(&'b self) -> &'b T {
233 *self
234 }
235 }
236
237 impl<'a, T> Deref for &'a mut T {
238 #[check(ghost)]
239 #[ensures(*result == **self)]
240 fn deref<'b>(&'b self) -> &'b T {
241 *self
242 }
243 }
244
245 impl<'a, T> DerefMut for &'a mut T {
246 #[check(ghost)]
247 #[ensures(*result == **self)]
248 #[ensures(^result == *^self)]
249 #[ensures(^*self == ^^self)]
250 fn deref_mut<'b>(&'b mut self) -> &'b mut T {
251 *self
252 }
253 }
254}
255
256impl<T: DeepModel> DeepModel for Bound<T> {
257 type DeepModelTy = Bound<T::DeepModelTy>;
258
259 #[logic(open)]
260 fn deep_model(self) -> Self::DeepModelTy {
261 match self {
262 Bound::Included(b) => Bound::Included(b.deep_model()),
263 Bound::Excluded(b) => Bound::Excluded(b.deep_model()),
264 Bound::Unbounded => Bound::Unbounded,
265 }
266 }
267}
268
269pub trait RangeBounds<T: ?Sized + DeepModel<DeepModelTy: OrdLogic>>:
271 core::ops::RangeBounds<T>
272{
273 #[logic]
274 fn start_bound_logic(&self) -> Bound<&T>;
275
276 #[logic]
277 fn end_bound_logic(&self) -> Bound<&T>;
278}
279
280#[logic(open)]
282pub fn between<T: OrdLogic>(lo: Bound<T>, item: T, hi: Bound<T>) -> bool {
283 lower_bound(lo, item) && upper_bound(item, hi)
284}
285
286#[logic(open)]
288pub fn lower_bound<T: OrdLogic>(lo: Bound<T>, item: T) -> bool {
289 pearlite! {
290 match lo {
291 Bound::Included(lo) => lo <= item,
292 Bound::Excluded(lo) => lo < item,
293 Bound::Unbounded => true,
294 }
295 }
296}
297
298#[logic(open)]
300pub fn upper_bound<T: OrdLogic>(item: T, hi: Bound<T>) -> bool {
301 pearlite! {
302 match hi {
303 Bound::Included(hi) => item <= hi,
304 Bound::Excluded(lo) => lo < item,
305 Bound::Unbounded => true,
306 }
307 }
308}
309
310extern_spec! {
311 mod core {
312 mod ops {
313 trait RangeBounds<T>
314 where
315 Self: RangeBounds<T>,
316 T: ?Sized + DeepModel,
317 T::DeepModelTy: OrdLogic,
318 {
319 #[ensures(result == self.start_bound_logic())]
320 fn start_bound(&self) -> Bound<&T>;
321
322 #[ensures(result == self.end_bound_logic())]
323 fn end_bound(&self) -> Bound<&T>;
324
325 #[ensures(result == between(self.start_bound_logic().deep_model(), item.deep_model(), self.end_bound_logic().deep_model()))]
326 fn contains<U>(&self, item: &U) -> bool
327 where
328 T: PartialOrd<U>,
329 U: ?Sized + PartialOrd<T> + DeepModel<DeepModelTy = T::DeepModelTy>;
330
331 #[ensures(result == !exists<item: T::DeepModelTy> between(self.start_bound_logic().deep_model(), item, self.end_bound_logic().deep_model()))]
332 fn is_empty(&self) -> bool
333 where T: PartialOrd;
334 }
335 }
336 }
337
338 impl<T: Copy> Bound<&T> {
339 #[erasure]
340 #[ensures(result == match self {
341 Bound::Unbounded => Bound::Unbounded,
342 Bound::Included(x) => Bound::Included(*x),
343 Bound::Excluded(x) => Bound::Excluded(*x),
344 })]
345 fn copied(self) -> Bound<T> {
346 match self {
347 Bound::Unbounded => Bound::Unbounded,
348 Bound::Included(x) => Bound::Included(*x),
349 Bound::Excluded(x) => Bound::Excluded(*x),
350 }
351 }
352 }
353}
354
355impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeFull {
356 #[logic(open)]
357 fn start_bound_logic(&self) -> Bound<&T> {
358 Bound::Unbounded
359 }
360
361 #[logic(open)]
362 fn end_bound_logic(&self) -> Bound<&T> {
363 Bound::Unbounded
364 }
365}
366
367impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeFrom<T> {
368 #[logic(open)]
369 fn start_bound_logic(&self) -> Bound<&T> {
370 Bound::Included(&self.start)
371 }
372
373 #[logic(open)]
374 fn end_bound_logic(&self) -> Bound<&T> {
375 Bound::Unbounded
376 }
377}
378
379impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeTo<T> {
380 #[logic(open)]
381 fn start_bound_logic(&self) -> Bound<&T> {
382 Bound::Unbounded
383 }
384
385 #[logic(open)]
386 fn end_bound_logic(&self) -> Bound<&T> {
387 Bound::Excluded(&self.end)
388 }
389}
390
391impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for Range<T> {
392 #[logic(open)]
393 fn start_bound_logic(&self) -> Bound<&T> {
394 Bound::Included(&self.start)
395 }
396
397 #[logic(open)]
398 fn end_bound_logic(&self) -> Bound<&T> {
399 Bound::Excluded(&self.end)
400 }
401}
402
403impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeInclusive<T> {
404 #[logic(open)]
405 fn start_bound_logic(&self) -> Bound<&T> {
406 Bound::Included(&self.start_log())
407 }
408
409 #[logic(opaque)]
410 fn end_bound_logic(&self) -> Bound<&T> {
411 dead
412 }
413}
414
415impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeToInclusive<T> {
416 #[logic(open)]
417 fn start_bound_logic(&self) -> Bound<&T> {
418 Bound::Unbounded
419 }
420
421 #[logic(open)]
422 fn end_bound_logic(&self) -> Bound<&T> {
423 Bound::Included(&self.end)
424 }
425}
426
427impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for (Bound<T>, Bound<T>) {
428 #[logic(open)]
429 fn start_bound_logic(&self) -> Bound<&T> {
430 match *self {
431 (Bound::Included(ref start), _) => Bound::Included(start),
432 (Bound::Excluded(ref start), _) => Bound::Excluded(start),
433 (Bound::Unbounded, _) => Bound::Unbounded,
434 }
435 }
436
437 #[logic(open)]
438 fn end_bound_logic(&self) -> Bound<&T> {
439 match *self {
440 (_, Bound::Included(ref end)) => Bound::Included(end),
441 (_, Bound::Excluded(ref end)) => Bound::Excluded(end),
442 (_, Bound::Unbounded) => Bound::Unbounded,
443 }
444 }
445}
446
447impl<'a, T: ?Sized + 'a + DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T>
448 for (Bound<&'a T>, Bound<&'a T>)
449{
450 #[logic(open)]
451 fn start_bound_logic(&self) -> Bound<&T> {
452 self.0
453 }
454
455 #[logic(open)]
456 fn end_bound_logic(&self) -> Bound<&T> {
457 self.1
458 }
459}
460
461impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeFrom<&T> {
462 #[logic(open)]
463 fn start_bound_logic(&self) -> Bound<&T> {
464 Bound::Included(self.start)
465 }
466
467 #[logic(open)]
468 fn end_bound_logic(&self) -> Bound<&T> {
469 Bound::Unbounded
470 }
471}
472
473impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeTo<&T> {
474 #[logic(open)]
475 fn start_bound_logic(&self) -> Bound<&T> {
476 Bound::Unbounded
477 }
478
479 #[logic(open)]
480 fn end_bound_logic(&self) -> Bound<&T> {
481 Bound::Excluded(self.end)
482 }
483}
484
485impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for Range<&T> {
486 #[logic(open)]
487 fn start_bound_logic(&self) -> Bound<&T> {
488 Bound::Included(self.start)
489 }
490
491 #[logic(open)]
492 fn end_bound_logic(&self) -> Bound<&T> {
493 Bound::Excluded(self.end)
494 }
495}
496
497impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeInclusive<&T> {
499 #[logic(open)]
500 fn start_bound_logic(&self) -> Bound<&T> {
501 Bound::Included(&self.start_log())
502 }
503
504 #[logic(open)]
505 fn end_bound_logic(&self) -> Bound<&T> {
506 Bound::Included(&self.end_log())
507 }
508}
509
510impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for RangeToInclusive<&T> {
511 #[logic(open)]
512 fn start_bound_logic(&self) -> Bound<&T> {
513 Bound::Unbounded
514 }
515
516 #[logic(open)]
517 fn end_bound_logic(&self) -> Bound<&T> {
518 Bound::Included(self.end)
519 }
520}
521
522#[cfg(feature = "nightly")]
523impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for core::range::Range<T> {
524 #[logic(open)]
525 fn start_bound_logic(&self) -> Bound<&T> {
526 Bound::Included(&self.start)
527 }
528
529 #[logic(open)]
530 fn end_bound_logic(&self) -> Bound<&T> {
531 Bound::Excluded(&self.end)
532 }
533}
534
535#[cfg(feature = "nightly")]
536impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for core::range::Range<&T> {
537 #[logic(open)]
538 fn start_bound_logic(&self) -> Bound<&T> {
539 Bound::Included(self.start)
540 }
541
542 #[logic(open)]
543 fn end_bound_logic(&self) -> Bound<&T> {
544 Bound::Excluded(self.end)
545 }
546}
547
548#[cfg(feature = "nightly")]
549impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for core::range::RangeFrom<T> {
550 #[logic(open)]
551 fn start_bound_logic(&self) -> Bound<&T> {
552 Bound::Included(&self.start)
553 }
554
555 #[logic(open)]
556 fn end_bound_logic(&self) -> Bound<&T> {
557 Bound::Unbounded
558 }
559}
560
561#[cfg(feature = "nightly")]
562impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for core::range::RangeFrom<&T> {
563 #[logic(open)]
564 fn start_bound_logic(&self) -> Bound<&T> {
565 Bound::Included(self.start)
566 }
567
568 #[logic(open)]
569 fn end_bound_logic(&self) -> Bound<&T> {
570 Bound::Unbounded
571 }
572}
573
574#[cfg(feature = "nightly")]
575impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for core::range::RangeInclusive<T> {
576 #[logic(open)]
577 fn start_bound_logic(&self) -> Bound<&T> {
578 Bound::Included(&self.start)
579 }
580
581 #[logic(open)]
582 fn end_bound_logic(&self) -> Bound<&T> {
583 Bound::Included(&self.last)
584 }
585}
586
587#[cfg(feature = "nightly")]
588impl<T: DeepModel<DeepModelTy: OrdLogic>> RangeBounds<T> for core::range::RangeInclusive<&T> {
589 #[logic(open)]
590 fn start_bound_logic(&self) -> Bound<&T> {
591 Bound::Included(self.start)
592 }
593
594 #[logic(open)]
595 fn end_bound_logic(&self) -> Bound<&T> {
596 Bound::Included(self.last)
597 }
598}
599
600pub trait RangeInclusiveExt<Idx> {
601 #[logic]
602 fn new_log(start: Idx, end: Idx) -> Self
603 where
604 Idx: DeepModel,
605 Idx::DeepModelTy: OrdLogic;
606
607 #[logic]
608 fn start_log(self) -> Idx;
609
610 #[logic]
611 fn end_log(self) -> Idx;
612
613 #[logic]
614 fn is_empty_log(self) -> bool
615 where
616 Idx: DeepModel,
617 Idx::DeepModelTy: OrdLogic;
618}
619
620impl<Idx> RangeInclusiveExt<Idx> for RangeInclusive<Idx> {
621 #[logic(opaque)]
622 #[trusted]
623 #[ensures(start == result.start_log())]
624 #[ensures(end == result.end_log())]
625 #[ensures(start.deep_model() <= end.deep_model() ==> !result.is_empty_log())]
626 fn new_log(start: Idx, end: Idx) -> Self
627 where
628 Idx: DeepModel,
629 Idx::DeepModelTy: OrdLogic,
630 {
631 dead
632 }
633
634 #[logic(opaque)]
635 fn start_log(self) -> Idx {
636 dead
637 }
638
639 #[logic(opaque)]
640 fn end_log(self) -> Idx {
641 dead
642 }
643
644 #[logic(opaque)]
645 #[trusted]
646 #[ensures(!result ==> self.start_log().deep_model() <= self.end_log().deep_model())]
647 fn is_empty_log(self) -> bool
648 where
649 Idx: DeepModel,
650 Idx::DeepModelTy: OrdLogic,
651 {
652 dead
653 }
654}
655
656extern_spec! {
657 impl<Idx> RangeInclusive<Idx> {
658 #[ensures(result.start_log() == start)]
659 #[ensures(result.end_log() == end)]
660 #[ensures(start.deep_model() <= end.deep_model() ==> !result.is_empty_log())]
661 fn new(start: Idx, end: Idx) -> Self
662 where Idx: DeepModel, Idx::DeepModelTy: OrdLogic;
663
664 #[ensures(*result == self.start_log())]
665 fn start(&self) -> &Idx;
666
667 #[ensures(*result == self.end_log())]
668 fn end(&self) -> &Idx;
669 }
670
671 impl<Idx: PartialOrd<Idx> + DeepModel> RangeInclusive<Idx>
672 where Idx::DeepModelTy: OrdLogic
673 {
674 #[ensures(result == self.is_empty_log())]
675 fn is_empty(&self) -> bool;
676 }
677}
678
679extern_spec! {
680 mod core {
681 mod ops {
682 trait FromResidual<R> where Self: Sized {
683 #[requires(true)]
684 fn from_residual(residual: R) -> Self;
685 }
686 }
687 }
688
689 impl<T> Try for Option<T> {
690 #[ensures(result == Some(output))]
691 fn from_output(output: T) -> Self {
692 Some(output)
693 }
694
695 #[ensures(match self {
696 Some(v) => result == ControlFlow::Continue(v),
697 None => result == ControlFlow::Break(None)
698 })]
699 fn branch(self) -> ControlFlow<Option<Infallible>, T> {
700 match self {
701 Some(v) => ControlFlow::Continue(v),
702 None => ControlFlow::Break(None),
703 }
704 }
705 }
706
707 impl<T> FromResidual<Option<Infallible>> for Option<T> {
708 #[ensures(result == None)]
709 fn from_residual(residual: Option<Infallible>) -> Self {
710 match residual {
711 None => None,
712 }
713 }
714 }
715
716 impl<T, E> Try for Result<T, E> {
717 #[ensures(result == Ok(output))]
718 fn from_output(output: T) -> Self {
719 Ok(output)
720 }
721
722 #[ensures(match self {
723 Ok(v) => result == ControlFlow::Continue(v),
724 Err(e) => result == ControlFlow::Break(Err(e))
725 })]
726 fn branch(self) -> ControlFlow<Result<Infallible, E>, T> {
727 match self {
728 Ok(v) => ControlFlow::Continue(v),
729 Err(e) => ControlFlow::Break(Err(e)),
730 }
731 }
732 }
733
734 impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {
735 #[ensures(match (result, residual) {
736 (Err(result), Err(residual)) => F::from.postcondition((residual,), result),
737 _ => false,
738 })]
739 fn from_residual(residual: Result<Infallible, E>) -> Self {
740 match residual {
741 Err(e) => Err(core::convert::From::from(e)),
742 }
743 }
744 }
745}
746
747#[cfg(creusot)]
749#[allow(dead_code)]
750#[ensures(FromResidual::from_residual.postcondition((r,), result))]
751#[intrinsic("residual_into_try_type")]
752#[creusot::extern_spec]
753fn residual_into_try_type<R: Residual<O>, O>(r: R) -> <R as Residual<O>>::TryType {
754 FromResidual::from_residual(r)
755}
756
757#[cfg(not(feature = "nightly"))]
759mod impls {
760 use crate::std::ops::*;
761
762 impl<O, F: FnOnce() -> O> FnOnceExt<()> for F {
763 type Output = O;
764 }
765 impl<O, F: FnMut() -> O> FnMutExt<()> for F {}
766 impl<O, F: Fn() -> O> FnExt<()> for F {}
767
768 macro_rules! impl_fn {
769 ( $( $tuple:tt ),+ ) => {
770 impl<$($tuple),+, O, F: FnOnce($($tuple),+) -> O> FnOnceExt<($($tuple),+,)> for F {
771 type Output = O;
772 }
773 impl<$($tuple),+, O, F: FnMut($($tuple),+) -> O> FnMutExt<($($tuple),+,)> for F {}
774 impl<$($tuple),+, O, F: Fn($($tuple),+) -> O> FnExt<($($tuple),+,)> for F {}
775 };
776 }
777
778 impl_fn! { A1 }
779 impl_fn! { A1, A2 }
780 impl_fn! { A1, A2, A3 }
781 impl_fn! { A1, A2, A3, A4 }
782 impl_fn! { A1, A2, A3, A4, A5 }
783 impl_fn! { A1, A2, A3, A4, A5, A6 }
784 impl_fn! { A1, A2, A3, A4, A5, A6, A7 }
785 impl_fn! { A1, A2, A3, A4, A5, A6, A7, A8 }
786 impl_fn! { A1, A2, A3, A4, A5, A6, A7, A8, A9 }
787}