summaryrefslogtreecommitdiffstats
path: root/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.rs
blob: c319c63eda267bd2132808f45a3ac70ac8911c01 (plain)
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Regression test for ICE #116473.
// The ICE occurs when arguments are specified on an enum variant
// (which is illegal) and the variant and its preceding path are
// located at different places such as in different macros or
// different expansions of the same macro (i.e. when the macro
// calls itself recursively)

enum Enum<T1, T2> {  VariantA { _v1: T1, _v2: T2 }, VariantB }

type EnumUnit = Enum<(), ()>;

// Recursive macro call using a tt metavariable for variant
macro_rules! recursive_tt {
    () => (recursive_tt!(VariantB));
    ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
    //~^ ERROR type arguments are not allowed on this type
    //~| ERROR mismatched types
}


// Recursive macro call using an ident metavariable for variant
// (the behaviour is different for tt and ident)
macro_rules! recursive_ident {
    () => (recursive_ident!(VariantB));
    ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
    //~^ ERROR type arguments are not allowed on this type
    //~| ERROR mismatched types
}


// Mested macro calls (i.e. one calling another) using a tt
// metavariable for variant
macro_rules! nested1_tt {
    () => (nested2_tt!(VariantB));
}

macro_rules! nested2_tt {
    ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
    //~^ ERROR type arguments are not allowed on this type
    //~| ERROR mismatched types
}


// Mested macro calls using an ident metavariable for variant
// (the behaviour is different for tt and ident)
macro_rules! nested1_ident {
    () => (nested2_ident!(VariantB));
}

macro_rules! nested2_ident {
    ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
    //~^ ERROR type arguments are not allowed on this type
    //~| ERROR mismatched types
}


// Mested macro calls when args are passed as metavariable
// instead of the enum variant
macro_rules! nested1_tt_args_in_first_macro {
    () => (nested2_tt_args_in_first_macro!(i32, u32));
}

macro_rules! nested2_tt_args_in_first_macro {
    ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
    //~^ ERROR type arguments are not allowed on this type
    //~| ERROR mismatched types
            = 5 { true } else { false });
}

// Mested macro calls when args are passed as metavariable
// instead of the enum variant
macro_rules! nested1_ident_args_in_first_macro {
    () => (nested2_ident_args_in_first_macro!(i32, u32));
}

macro_rules! nested2_ident_args_in_first_macro {
    ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
    //~^ ERROR type arguments are not allowed on this type
    //~| ERROR mismatched types
        = 5 { true } else { false });
}

fn main() {
    // Macro cases
    recursive_tt!();
    recursive_ident!();
    nested1_tt!();
    nested1_ident!();
    nested1_tt_args_in_first_macro!();
    nested1_ident_args_in_first_macro!();

    // Regular, non-macro case
    if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false };
    //~^ ERROR type arguments are not allowed on this type
    //~| ERROR mismatched types
}