summaryrefslogtreecommitdiffstats
path: root/tests/ui/polymorphization/const_parameters/closures.rs
blob: 2f41beeb9691a36b82db1e849e7fc010019308ea (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
// build-fail
// compile-flags:-Zpolymorphize=on
#![feature(generic_const_exprs, rustc_attrs)]
//~^ WARN the feature `generic_const_exprs` is incomplete

// This test checks that the polymorphization analysis correctly detects unused const
// parameters in closures.

// Function doesn't have any generic parameters to be unused.
#[rustc_polymorphize_error]
pub fn no_parameters() {
    let _ = || {};
}

// Function has an unused generic parameter in parent and closure.
#[rustc_polymorphize_error]
pub fn unused<const T: usize>() -> usize {
    //~^ ERROR item has unused generic parameters
    let add_one = |x: usize| x + 1;
    //~^ ERROR item has unused generic parameters
    add_one(3)
}

// Function has an unused generic parameter in closure, but not in parent.
#[rustc_polymorphize_error]
pub fn used_parent<const T: usize>() -> usize {
    let x: usize = T;
    let add_one = |x: usize| x + 1;
    //~^ ERROR item has unused generic parameters
    x + add_one(3)
}

// Function uses generic parameter in value of a binding in closure.
#[rustc_polymorphize_error]
pub fn used_binding<const T: usize>() -> usize {
    let x = || {
        let y: usize = T;
        y
    };

    x()
}

// Closure uses a value as an upvar, which used the generic parameter.
#[rustc_polymorphize_error]
pub fn unused_upvar<const T: usize>() -> usize {
    let x: usize = T;
    let y = || x;
    //~^ ERROR item has unused generic parameters
    y()
}

// Closure uses generic parameter in substitutions to another function.
#[rustc_polymorphize_error]
pub fn used_substs<const T: usize>() -> usize {
    let x = || unused::<T>();
    x()
}

fn main() {
    no_parameters();
    let _ = unused::<1>();
    let _ = used_parent::<1>();
    let _ = used_binding::<1>();
    let _ = unused_upvar::<1>();
    let _ = used_substs::<1>();
}