File: edition-gate-macro.rs

package info (click to toggle)
rustc 1.88.0%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 934,128 kB
  • sloc: xml: 158,127; python: 36,062; javascript: 19,855; sh: 19,700; cpp: 18,947; ansic: 12,993; asm: 4,792; makefile: 690; lisp: 29; perl: 29; ruby: 19; sql: 11
file content (76 lines) | stat: -rw-r--r-- 2,318 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//@ revisions: edition2021 edition2024
//@ compile-flags: -Z lint-mir -Z validate-mir
//@ [edition2021] edition: 2021
//@ [edition2024] edition: 2024
//@ aux-build:macro-in-2021.rs
//@ aux-build:macro-in-2024.rs
//@ run-pass

#![allow(dead_code)]

use std::unreachable as never;
use std::cell::RefCell;
use std::convert::TryInto;

// Compiletest doesn't specify the needed --extern flags to make `extern crate` unneccessary
extern crate macro_in_2021;
extern crate macro_in_2024;

#[derive(Default)]
struct DropOrderCollector(RefCell<Vec<u32>>);

struct LoudDrop<'a>(&'a DropOrderCollector, u32);

impl Drop for LoudDrop<'_> {
    fn drop(&mut self) {
        println!("{}", self.1);
        self.0.0.borrow_mut().push(self.1);
    }
}

impl DropOrderCollector {
    fn print(&self, n: u32) {
        println!("{n}");
        self.0.borrow_mut().push(n)
    }
    fn some_loud(&self, n: u32) -> Option<LoudDrop> {
        Some(LoudDrop(self, n))
    }

    #[track_caller]
    fn validate(self) {
        assert!(
            self.0
                .into_inner()
                .into_iter()
                .enumerate()
                .all(|(idx, item)| idx + 1 == item.try_into().unwrap())
        );
    }
    fn with_macro_2021(self) {
        // Edition 2021 drop behaviour
        macro_in_2021::make_if!((let None = self.some_loud(2)) { never!() } {self.print(1) });
        macro_in_2021::make_if!(let (self.some_loud(4)) { never!() } { self.print(3) });
        self.validate();
    }
    fn with_macro_2024(self) {
        // Edition 2024 drop behaviour
        macro_in_2024::make_if!((let None = self.some_loud(1)) { never!() } { self.print(2) });
        macro_in_2024::make_if!(let (self.some_loud(3)) { never!() } { self.print(4) });
        self.validate();
    }
}

fn main() {
    // 2021 drop order if it's a 2021 macro creating the `if`
    // 2024 drop order if it's a 2024 macro creating the `if`

    // Compare this with edition-gate-macro-error.rs: We want to avoid exposing 2021 drop order,
    // because it can create bad MIR (issue #104843)
    // This test doesn't contain any let chains at all: it should be understood
    // in combination with `edition-gate-macro-error.rs`

    DropOrderCollector::default().with_macro_2021();
    DropOrderCollector::default().with_macro_2024();

}