• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(
2     clippy::bool_to_int_with_if,
3     clippy::diverging_sub_expression,
4     clippy::if_same_then_else,
5     clippy::ifs_same_cond,
6     clippy::items_after_statements,
7     clippy::let_and_return,
8     clippy::match_bool,
9     clippy::never_loop,
10     clippy::overly_complex_bool_expr,
11     clippy::redundant_closure_call,
12     clippy::redundant_pattern_matching,
13     clippy::too_many_lines,
14     clippy::unit_arg,
15     clippy::while_immutable_condition,
16     clippy::zero_ptr,
17     irrefutable_let_patterns
18 )]
19 
20 use self::Enum::Generic;
21 use anyhow::{anyhow, ensure, Chain, Error, Result};
22 use std::fmt::{self, Debug};
23 use std::iter;
24 use std::marker::{PhantomData, PhantomData as P};
25 use std::mem;
26 use std::ops::Add;
27 use std::ptr;
28 
29 struct S;
30 
31 impl<T> Add<T> for S {
32     type Output = bool;
add(self, rhs: T) -> Self::Output33     fn add(self, rhs: T) -> Self::Output {
34         let _ = rhs;
35         false
36     }
37 }
38 
39 trait Trait: Sized {
40     const V: usize = 0;
t(self, i: i32) -> i3241     fn t(self, i: i32) -> i32 {
42         i
43     }
44 }
45 
46 impl<T> Trait for T {}
47 
48 enum Enum<T: ?Sized> {
49     #[allow(dead_code)]
50     Thing(PhantomData<T>),
51     Generic,
52 }
53 
54 impl<T: ?Sized> PartialEq for Enum<T> {
eq(&self, rhs: &Self) -> bool55     fn eq(&self, rhs: &Self) -> bool {
56         mem::discriminant(self) == mem::discriminant(rhs)
57     }
58 }
59 
60 impl<T: ?Sized> Debug for Enum<T> {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result61     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
62         formatter.write_str("Generic")
63     }
64 }
65 
66 #[track_caller]
assert_err<T: Debug>(result: impl FnOnce() -> Result<T>, expected: &'static str)67 fn assert_err<T: Debug>(result: impl FnOnce() -> Result<T>, expected: &'static str) {
68     let actual = result().unwrap_err().to_string();
69 
70     // In general different rustc versions will format the interpolated lhs and
71     // rhs $:expr fragment with insignificant differences in whitespace or
72     // punctuation, so we check the message in full against nightly and do just
73     // a cursory test on older toolchains.
74     if rustversion::cfg!(nightly) && !cfg!(miri) {
75         assert_eq!(actual, expected);
76     } else {
77         assert_eq!(actual.contains(" vs "), expected.contains(" vs "));
78     }
79 }
80 
81 #[test]
test_recursion()82 fn test_recursion() {
83     // Must not blow the default #[recursion_limit], which is 128.
84     #[rustfmt::skip]
85     let test = || Ok(ensure!(
86         false | false | false | false | false | false | false | false | false |
87         false | false | false | false | false | false | false | false | false |
88         false | false | false | false | false | false | false | false | false |
89         false | false | false | false | false | false | false | false | false |
90         false | false | false | false | false | false | false | false | false |
91         false | false | false | false | false | false | false | false | false |
92         false | false | false | false | false | false | false | false | false
93     ));
94 
95     test().unwrap_err();
96 }
97 
98 #[test]
test_low_precedence_control_flow()99 fn test_low_precedence_control_flow() {
100     #[allow(unreachable_code)]
101     let test = || {
102         let val = loop {
103             // Break has lower precedence than the comparison operators so the
104             // expression here is `S + (break (1 == 1))`. It would be bad if the
105             // ensure macro partitioned this input into `(S + break 1) == (1)`
106             // because that means a different thing than what was written.
107             ensure!(S + break 1 == 1);
108         };
109         Ok(val)
110     };
111 
112     assert!(test().unwrap());
113 }
114 
115 #[test]
test_low_precedence_binary_operator()116 fn test_low_precedence_binary_operator() {
117     // Must not partition as `false == (true && false)`.
118     let test = || Ok(ensure!(false == true && false));
119     assert_err(test, "Condition failed: `false == true && false`");
120 
121     // But outside the root level, it is fine.
122     let test = || Ok(ensure!(while false == true && false {} < ()));
123     assert_err(
124         test,
125         "Condition failed: `while false == true && false {} < ()` (() vs ())",
126     );
127 }
128 
129 #[test]
test_closure()130 fn test_closure() {
131     // Must not partition as `(S + move) || (1 == 1)` by treating move as an
132     // identifier, nor as `(S + move || 1) == (1)` by misinterpreting the
133     // closure precedence.
134     let test = || Ok(ensure!(S + move || 1 == 1));
135     assert_err(test, "Condition failed: `S + (move || 1 == 1)`");
136 
137     let test = || Ok(ensure!(S + || 1 == 1));
138     assert_err(test, "Condition failed: `S + (|| 1 == 1)`");
139 
140     // Must not partition as `S + ((move | ()) | 1) == 1` by treating those
141     // pipes as bitwise-or.
142     let test = || Ok(ensure!(S + move |()| 1 == 1));
143     assert_err(test, "Condition failed: `S + (move |()| 1 == 1)`");
144 
145     let test = || Ok(ensure!(S + |()| 1 == 1));
146     assert_err(test, "Condition failed: `S + (|()| 1 == 1)`");
147 }
148 
149 #[test]
test_unary()150 fn test_unary() {
151     let mut x = &1;
152     let test = || Ok(ensure!(*x == 2));
153     assert_err(test, "Condition failed: `*x == 2` (1 vs 2)");
154 
155     let test = || Ok(ensure!(!x == 1));
156     assert_err(test, "Condition failed: `!x == 1` (-2 vs 1)");
157 
158     let test = || Ok(ensure!(-x == 1));
159     assert_err(test, "Condition failed: `-x == 1` (-1 vs 1)");
160 
161     let test = || Ok(ensure!(&x == &&2));
162     assert_err(test, "Condition failed: `&x == &&2` (1 vs 2)");
163 
164     let test = || Ok(ensure!(&mut x == *&&mut &2));
165     assert_err(test, "Condition failed: `&mut x == *&&mut &2` (1 vs 2)");
166 }
167 
168 #[test]
test_if()169 fn test_if() {
170     #[rustfmt::skip]
171     let test = || Ok(ensure!(if false {}.t(1) == 2));
172     assert_err(test, "Condition failed: `if false {}.t(1) == 2` (1 vs 2)");
173 
174     #[rustfmt::skip]
175     let test = || Ok(ensure!(if false {} else {}.t(1) == 2));
176     assert_err(
177         test,
178         "Condition failed: `if false {} else {}.t(1) == 2` (1 vs 2)",
179     );
180 
181     #[rustfmt::skip]
182     let test = || Ok(ensure!(if false {} else if false {}.t(1) == 2));
183     assert_err(
184         test,
185         "Condition failed: `if false {} else if false {}.t(1) == 2` (1 vs 2)",
186     );
187 
188     #[rustfmt::skip]
189     let test = || Ok(ensure!(if let 1 = 2 {}.t(1) == 2));
190     assert_err(
191         test,
192         "Condition failed: `if let 1 = 2 {}.t(1) == 2` (1 vs 2)",
193     );
194 
195     #[rustfmt::skip]
196     let test = || Ok(ensure!(if let 1 | 2 = 2 {}.t(1) == 2));
197     assert_err(
198         test,
199         "Condition failed: `if let 1 | 2 = 2 {}.t(1) == 2` (1 vs 2)",
200     );
201 
202     #[rustfmt::skip]
203     let test = || Ok(ensure!(if let | 1 | 2 = 2 {}.t(1) == 2));
204     assert_err(
205         test,
206         "Condition failed: `if let 1 | 2 = 2 {}.t(1) == 2` (1 vs 2)",
207     );
208 }
209 
210 #[test]
test_loop()211 fn test_loop() {
212     #[rustfmt::skip]
213     let test = || Ok(ensure!(1 + loop { break 1 } == 1));
214     assert_err(
215         test,
216         "Condition failed: `1 + loop { break 1 } == 1` (2 vs 1)",
217     );
218 
219     #[rustfmt::skip]
220     let test = || Ok(ensure!(1 + 'a: loop { break 'a 1 } == 1));
221     assert_err(
222         test,
223         "Condition failed: `1 + 'a: loop { break 'a 1 } == 1` (2 vs 1)",
224     );
225 
226     #[rustfmt::skip]
227     let test = || Ok(ensure!(while false {}.t(1) == 2));
228     assert_err(
229         test,
230         "Condition failed: `while false {}.t(1) == 2` (1 vs 2)",
231     );
232 
233     #[rustfmt::skip]
234     let test = || Ok(ensure!(while let None = Some(1) {}.t(1) == 2));
235     assert_err(
236         test,
237         "Condition failed: `while let None = Some(1) {}.t(1) == 2` (1 vs 2)",
238     );
239 
240     #[rustfmt::skip]
241     let test = || Ok(ensure!(for _x in iter::once(0) {}.t(1) == 2));
242     assert_err(
243         test,
244         "Condition failed: `for _x in iter::once(0) {}.t(1) == 2` (1 vs 2)",
245     );
246 
247     #[rustfmt::skip]
248     let test = || Ok(ensure!(for | _x in iter::once(0) {}.t(1) == 2));
249     assert_err(
250         test,
251         "Condition failed: `for _x in iter::once(0) {}.t(1) == 2` (1 vs 2)",
252     );
253 
254     #[rustfmt::skip]
255     let test = || Ok(ensure!(for true | false in iter::empty() {}.t(1) == 2));
256     assert_err(
257         test,
258         "Condition failed: `for true | false in iter::empty() {}.t(1) == 2` (1 vs 2)",
259     );
260 }
261 
262 #[test]
test_match()263 fn test_match() {
264     #[rustfmt::skip]
265     let test = || Ok(ensure!(match 1 == 1 { true => 1, false => 0 } == 2));
266     assert_err(
267         test,
268         "Condition failed: `match 1 == 1 { true => 1, false => 0, } == 2` (1 vs 2)",
269     );
270 }
271 
272 #[test]
test_atom()273 fn test_atom() {
274     let test = || Ok(ensure!([false, false].len() > 3));
275     assert_err(
276         test,
277         "Condition failed: `[false, false].len() > 3` (2 vs 3)",
278     );
279 
280     #[rustfmt::skip]
281     let test = || Ok(ensure!({ let x = 1; x } >= 3));
282     assert_err(test, "Condition failed: `{ let x = 1; x } >= 3` (1 vs 3)");
283 
284     let test = || Ok(ensure!(S + async { 1 } == true));
285     assert_err(
286         test,
287         "Condition failed: `S + async { 1 } == true` (false vs true)",
288     );
289 
290     let test = || Ok(ensure!(S + async move { 1 } == true));
291     assert_err(
292         test,
293         "Condition failed: `S + async move { 1 } == true` (false vs true)",
294     );
295 
296     let x = &1;
297     let test = || Ok(ensure!(S + unsafe { ptr::read(x) } == true));
298     assert_err(
299         test,
300         "Condition failed: `S + unsafe { ptr::read(x) } == true` (false vs true)",
301     );
302 }
303 
304 #[test]
test_path()305 fn test_path() {
306     let test = || Ok(ensure!(crate::S.t(1) == 2));
307     assert_err(test, "Condition failed: `crate::S.t(1) == 2` (1 vs 2)");
308 
309     let test = || Ok(ensure!(::anyhow::Error::root_cause.t(1) == 2));
310     assert_err(
311         test,
312         "Condition failed: `::anyhow::Error::root_cause.t(1) == 2` (1 vs 2)",
313     );
314 
315     let test = || Ok(ensure!(Error::msg::<&str>.t(1) == 2));
316     assert_err(
317         test,
318         "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
319     );
320 
321     #[rustfmt::skip]
322     let test = || Ok(ensure!(Error::msg::<&str,>.t(1) == 2));
323     assert_err(
324         test,
325         "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
326     );
327 
328     let test = || Ok(ensure!(Error::msg::<<str as ToOwned>::Owned>.t(1) == 2));
329     assert_err(
330         test,
331         "Condition failed: `Error::msg::<<str as ToOwned>::Owned>.t(1) == 2` (1 vs 2)",
332     );
333 
334     let test = || Ok(ensure!(Chain::<'static>::new.t(1) == 2));
335     assert_err(
336         test,
337         "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
338     );
339 
340     #[rustfmt::skip]
341     let test = || Ok(ensure!(Chain::<'static,>::new.t(1) == 2));
342     assert_err(
343         test,
344         "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
345     );
346 
347     fn f<const I: isize>() {}
348     let test = || Ok(ensure!(f::<1>() != ()));
349     assert_err(test, "Condition failed: `f::<1>() != ()` (() vs ())");
350     let test = || Ok(ensure!(f::<-1>() != ()));
351     assert_err(test, "Condition failed: `f::<-1>() != ()` (() vs ())");
352 
353     fn g<T, const I: isize>() {}
354     let test = || Ok(ensure!(g::<u8, 1>() != ()));
355     assert_err(test, "Condition failed: `g::<u8, 1>() != ()` (() vs ())");
356     let test = || Ok(ensure!(g::<u8, -1>() != ()));
357     assert_err(test, "Condition failed: `g::<u8, -1>() != ()` (() vs ())");
358 
359     #[derive(PartialOrd, PartialEq, Debug)]
360     enum E<'a, T> {
361         #[allow(dead_code)]
362         T(&'a T),
363         U,
364     }
365 
366     #[rustfmt::skip]
367     let test = || Ok(ensure!(E::U::<>>E::U::<u8>));
368     assert_err(test, "Condition failed: `E::U::<> > E::U::<u8>` (U vs U)");
369 
370     #[rustfmt::skip]
371     let test = || Ok(ensure!(E::U::<u8>>E::U));
372     assert_err(test, "Condition failed: `E::U::<u8> > E::U` (U vs U)");
373 
374     #[rustfmt::skip]
375     let test = || Ok(ensure!(E::U::<u8,>>E::U));
376     assert_err(test, "Condition failed: `E::U::<u8> > E::U` (U vs U)");
377 
378     let test = || Ok(ensure!(Generic::<dyn Debug + Sync> != Generic));
379     assert_err(
380         test,
381         "Condition failed: `Generic::<dyn Debug + Sync> != Generic` (Generic vs Generic)",
382     );
383 
384     let test = || Ok(ensure!(Generic::<dyn Fn() + Sync> != Generic));
385     assert_err(
386         test,
387         "Condition failed: `Generic::<dyn Fn() + Sync> != Generic` (Generic vs Generic)",
388     );
389 
390     #[rustfmt::skip]
391     let test = || {
392         Ok(ensure!(
393             Generic::<dyn Fn::() + ::std::marker::Sync> != Generic
394         ))
395     };
396     assert_err(
397         test,
398         "Condition failed: `Generic::<dyn Fn() + ::std::marker::Sync> != Generic` (Generic vs Generic)",
399     );
400 }
401 
402 #[test]
test_macro()403 fn test_macro() {
404     let test = || Ok(ensure!(anyhow!("...").to_string().len() <= 1));
405     assert_err(
406         test,
407         "Condition failed: `anyhow!(\"...\").to_string().len() <= 1` (3 vs 1)",
408     );
409 
410     let test = || Ok(ensure!(vec![1].len() < 1));
411     assert_err(test, "Condition failed: `vec![1].len() < 1` (1 vs 1)");
412 
413     let test = || Ok(ensure!(stringify! {} != ""));
414     assert_err(
415         test,
416         "Condition failed: `stringify! {} != \"\"` (\"\" vs \"\")",
417     );
418 }
419 
420 #[test]
test_trailer()421 fn test_trailer() {
422     let test = || Ok(ensure!((|| 1)() == 2));
423     assert_err(test, "Condition failed: `(|| 1)() == 2` (1 vs 2)");
424 
425     let test = || Ok(ensure!(b"hmm"[1] == b'c'));
426     assert_err(test, "Condition failed: `b\"hmm\"[1] == b'c'` (109 vs 99)");
427 
428     let test = || Ok(ensure!(PhantomData::<u8> {} != PhantomData));
429     assert_err(
430         test,
431         "Condition failed: `PhantomData::<u8> {} != PhantomData` (PhantomData<u8> vs PhantomData<u8>)",
432     );
433 
434     let result = Ok::<_, Error>(1);
435     let test = || Ok(ensure!(result? == 2));
436     assert_err(test, "Condition failed: `result? == 2` (1 vs 2)");
437 
438     let test = || Ok(ensure!((2, 3).1 == 2));
439     assert_err(test, "Condition failed: `(2, 3).1 == 2` (3 vs 2)");
440 
441     #[rustfmt::skip]
442     let test = || Ok(ensure!((2, (3, 4)). 1.1 == 2));
443     assert_err(test, "Condition failed: `(2, (3, 4)).1.1 == 2` (4 vs 2)");
444 
445     let err = anyhow!("");
446     let test = || Ok(ensure!(err.is::<&str>() == false));
447     assert_err(
448         test,
449         "Condition failed: `err.is::<&str>() == false` (true vs false)",
450     );
451 
452     let test = || Ok(ensure!(err.is::<<str as ToOwned>::Owned>() == true));
453     assert_err(
454         test,
455         "Condition failed: `err.is::<<str as ToOwned>::Owned>() == true` (false vs true)",
456     );
457 }
458 
459 #[test]
test_whitespace()460 fn test_whitespace() {
461     #[derive(Debug)]
462     pub struct Point {
463         pub x: i32,
464         pub y: i32,
465     }
466 
467     let point = Point { x: 0, y: 0 };
468     let test = || Ok(ensure!("" == format!("{:#?}", point)));
469     assert_err(
470         test,
471         "Condition failed: `\"\" == format!(\"{:#?}\", point)`",
472     );
473 }
474 
475 #[test]
test_too_long()476 fn test_too_long() {
477     let test = || Ok(ensure!("" == "x".repeat(10)));
478     assert_err(
479         test,
480         "Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")",
481     );
482 
483     let test = || Ok(ensure!("" == "x".repeat(80)));
484     assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`");
485 }
486 
487 #[test]
test_as()488 fn test_as() {
489     let test = || Ok(ensure!('\0' as u8 > 1));
490     assert_err(test, "Condition failed: `'\\0' as u8 > 1` (0 vs 1)");
491 
492     let test = || Ok(ensure!('\0' as ::std::primitive::u8 > 1));
493     assert_err(
494         test,
495         "Condition failed: `'\\0' as ::std::primitive::u8 > 1` (0 vs 1)",
496     );
497 
498     let test = || Ok(ensure!(&[0] as &[i32] == [1]));
499     assert_err(
500         test,
501         "Condition failed: `&[0] as &[i32] == [1]` ([0] vs [1])",
502     );
503 
504     let test = || Ok(ensure!(0 as *const () as *mut _ == 1 as *mut ()));
505     assert_err(
506         test,
507         "Condition failed: `0 as *const () as *mut _ == 1 as *mut ()` (0x0 vs 0x1)",
508     );
509 
510     let s = "";
511     let test = || Ok(ensure!(s as &str != s));
512     assert_err(test, "Condition failed: `s as &str != s` (\"\" vs \"\")");
513 
514     let test = || Ok(ensure!(&s as &&str != &s));
515     assert_err(test, "Condition failed: `&s as &&str != &s` (\"\" vs \"\")");
516 
517     let test = || Ok(ensure!(s as &'static str != s));
518     assert_err(
519         test,
520         "Condition failed: `s as &'static str != s` (\"\" vs \"\")",
521     );
522 
523     let test = || Ok(ensure!(&s as &&'static str != &s));
524     assert_err(
525         test,
526         "Condition failed: `&s as &&'static str != &s` (\"\" vs \"\")",
527     );
528 
529     let m: &mut str = Default::default();
530     let test = || Ok(ensure!(m as &mut str != s));
531     assert_err(
532         test,
533         "Condition failed: `m as &mut str != s` (\"\" vs \"\")",
534     );
535 
536     let test = || Ok(ensure!(&m as &&mut str != &s));
537     assert_err(
538         test,
539         "Condition failed: `&m as &&mut str != &s` (\"\" vs \"\")",
540     );
541 
542     let test = || Ok(ensure!(&m as &&'static mut str != &s));
543     assert_err(
544         test,
545         "Condition failed: `&m as &&'static mut str != &s` (\"\" vs \"\")",
546     );
547 
548     let f = || {};
549     let test = || Ok(ensure!(f as fn() as usize * 0 != 0));
550     assert_err(
551         test,
552         "Condition failed: `f as fn() as usize * 0 != 0` (0 vs 0)",
553     );
554 
555     let test = || Ok(ensure!(f as fn() -> () as usize * 0 != 0));
556     assert_err(
557         test,
558         "Condition failed: `f as fn() -> () as usize * 0 != 0` (0 vs 0)",
559     );
560 
561     let test = || Ok(ensure!(f as for<'a> fn() as usize * 0 != 0));
562     assert_err(
563         test,
564         "Condition failed: `f as for<'a> fn() as usize * 0 != 0` (0 vs 0)",
565     );
566 
567     let test = || Ok(ensure!(f as unsafe fn() as usize * 0 != 0));
568     assert_err(
569         test,
570         "Condition failed: `f as unsafe fn() as usize * 0 != 0` (0 vs 0)",
571     );
572 
573     #[rustfmt::skip]
574     let test = || Ok(ensure!(f as extern "Rust" fn() as usize * 0 != 0));
575     assert_err(
576         test,
577         "Condition failed: `f as extern \"Rust\" fn() as usize * 0 != 0` (0 vs 0)",
578     );
579 
580     extern "C" fn extern_fn() {}
581     #[rustfmt::skip]
582     let test = || Ok(ensure!(extern_fn as extern fn() as usize * 0 != 0));
583     assert_err(
584         test,
585         "Condition failed: `extern_fn as extern fn() as usize * 0 != 0` (0 vs 0)",
586     );
587 
588     let f = || -> ! { panic!() };
589     let test = || Ok(ensure!(f as fn() -> ! as usize * 0 != 0));
590     assert_err(
591         test,
592         "Condition failed: `f as fn() -> ! as usize * 0 != 0` (0 vs 0)",
593     );
594 
595     trait EqDebug<T>: PartialEq<T> + Debug {
596         type Assoc;
597     }
598 
599     impl<S, T> EqDebug<T> for S
600     where
601         S: PartialEq<T> + Debug,
602     {
603         type Assoc = bool;
604     }
605 
606     let test = || Ok(ensure!(&0 as &dyn EqDebug<i32, Assoc = bool> != &0));
607     assert_err(
608         test,
609         "Condition failed: `&0 as &dyn EqDebug<i32, Assoc = bool> != &0` (0 vs 0)",
610     );
611 
612     let test = || {
613         Ok(ensure!(
614             PhantomData as PhantomData<<i32 as ToOwned>::Owned> != PhantomData
615         ))
616     };
617     assert_err(
618         test,
619         "Condition failed: `PhantomData as PhantomData<<i32 as ToOwned>::Owned> != PhantomData` (PhantomData<i32> vs PhantomData<i32>)",
620     );
621 
622     macro_rules! int {
623         (...) => {
624             u8
625         };
626     }
627 
628     let test = || Ok(ensure!(0 as int!(...) != 0));
629     assert_err(test, "Condition failed: `0 as int!(...) != 0` (0 vs 0)");
630 
631     let test = || Ok(ensure!(0 as int![...] != 0));
632     assert_err(test, "Condition failed: `0 as int![...] != 0` (0 vs 0)");
633 
634     let test = || Ok(ensure!(0 as int! {...} != 0));
635     assert_err(test, "Condition failed: `0 as int! { ... } != 0` (0 vs 0)");
636 }
637 
638 #[test]
test_pat()639 fn test_pat() {
640     let test = || Ok(ensure!(if let ref mut _x @ 0 = 0 { 0 } else { 1 } == 1));
641     assert_err(
642         test,
643         "Condition failed: `if let ref mut _x @ 0 = 0 { 0 } else { 1 } == 1` (0 vs 1)",
644     );
645 
646     let test = || Ok(ensure!(if let -1..=1 = 0 { 0 } else { 1 } == 1));
647     assert_err(
648         test,
649         "Condition failed: `if let -1..=1 = 0 { 0 } else { 1 } == 1` (0 vs 1)",
650     );
651 
652     let test = || Ok(ensure!(if let &0 = &0 { 0 } else { 1 } == 1));
653     assert_err(
654         test,
655         "Condition failed: `if let &0 = &0 { 0 } else { 1 } == 1` (0 vs 1)",
656     );
657 
658     let test = || Ok(ensure!(if let &&0 = &&0 { 0 } else { 1 } == 1));
659     assert_err(
660         test,
661         "Condition failed: `if let &&0 = &&0 { 0 } else { 1 } == 1` (0 vs 1)",
662     );
663 
664     let test = || Ok(ensure!(if let &mut 0 = &mut 0 { 0 } else { 1 } == 1));
665     assert_err(
666         test,
667         "Condition failed: `if let &mut 0 = &mut 0 { 0 } else { 1 } == 1` (0 vs 1)",
668     );
669 
670     let test = || Ok(ensure!(if let &&mut 0 = &&mut 0 { 0 } else { 1 } == 1));
671     assert_err(
672         test,
673         "Condition failed: `if let &&mut 0 = &&mut 0 { 0 } else { 1 } == 1` (0 vs 1)",
674     );
675 
676     let test = || Ok(ensure!(if let (0, 1) = (0, 1) { 0 } else { 1 } == 1));
677     assert_err(
678         test,
679         "Condition failed: `if let (0, 1) = (0, 1) { 0 } else { 1 } == 1` (0 vs 1)",
680     );
681 
682     let test = || Ok(ensure!(if let [0] = b"\0" { 0 } else { 1 } == 1));
683     assert_err(
684         test,
685         "Condition failed: `if let [0] = b\"\\0\" { 0 } else { 1 } == 1` (0 vs 1)",
686     );
687 
688     let p = PhantomData::<u8>;
689     let test = || Ok(ensure!(if let P::<u8> {} = p { 0 } else { 1 } == 1));
690     assert_err(
691         test,
692         "Condition failed: `if let P::<u8> {} = p { 0 } else { 1 } == 1` (0 vs 1)",
693     );
694 
695     let test = || Ok(ensure!(if let ::std::marker::PhantomData = p {} != ()));
696     assert_err(
697         test,
698         "Condition failed: `if let ::std::marker::PhantomData = p {} != ()` (() vs ())",
699     );
700 
701     let test = || Ok(ensure!(if let <S as Trait>::V = 0 { 0 } else { 1 } == 1));
702     assert_err(
703         test,
704         "Condition failed: `if let <S as Trait>::V = 0 { 0 } else { 1 } == 1` (0 vs 1)",
705     );
706 
707     let test = || Ok(ensure!(for _ in iter::once(()) {} != ()));
708     assert_err(
709         test,
710         "Condition failed: `for _ in iter::once(()) {} != ()` (() vs ())",
711     );
712 
713     let test = || Ok(ensure!(if let stringify!(x) = "x" { 0 } else { 1 } == 1));
714     assert_err(
715         test,
716         "Condition failed: `if let stringify!(x) = \"x\" { 0 } else { 1 } == 1` (0 vs 1)",
717     );
718 }
719