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