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