summary refs log tree commit diff
path: root/src/test/ui/nll/user-annotations/patterns.rs
blob: 53d97360c869e3b034ece137fc2143743e1d53ea (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Test that various patterns also enforce types.

#![feature(nll)]

fn variable_no_initializer() {
    let x = 22;
    let y: &'static u32;
    y = &x; //~ ERROR
}

fn tuple_no_initializer() {
    // FIXME(#47187): We are not propagating ascribed type through tuples.

    let x = 22;
    let (y, z): (&'static u32, &'static u32);
    y = &x;
}

fn ref_with_ascribed_static_type() -> u32 {
    // Check the behavior in some wacky cases.
    let x = 22;
    let y = &x; //~ ERROR
    let ref z: &'static u32 = y;
    **z
}

fn ref_with_ascribed_any_type() -> u32 {
    let x = 22;
    let y = &x;
    let ref z: &u32 = y;
    **z
}

struct Single<T> { value: T }

fn struct_no_initializer() {
    // FIXME(#47187): We are not propagating ascribed type through patterns.

    let x = 22;
    let Single { value: y }: Single<&'static u32>;
    y = &x;
}

fn variable_with_initializer() {
    let x = 22;
    let y: &'static u32 = &x; //~ ERROR
}

fn underscore_with_initializer() {
    let x = 22;
    let _: &'static u32 = &x; //~ ERROR

    let _: Vec<&'static String> = vec![&String::new()];
    //~^ ERROR borrowed value does not live long enough [E0597]

    let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44);
    //~^ ERROR borrowed value does not live long enough [E0597]

    let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44);
    //~^ ERROR borrowed value does not live long enough [E0597]
}

fn pair_underscores_with_initializer() {
    let x = 22;
    let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR
}

fn pair_variable_with_initializer() {
    let x = 22;
    let (y, _): (&'static u32, u32) = (&x, 44); //~ ERROR
}

fn struct_single_field_variable_with_initializer() {
    let x = 22;
    let Single { value: y }: Single<&'static u32> = Single { value: &x }; //~ ERROR
}

fn struct_single_field_underscore_with_initializer() {
    let x = 22;
    let Single { value: _ }: Single<&'static u32> = Single { value: &x }; //~ ERROR
}

struct Double<T> { value1: T, value2: T }

fn struct_double_field_underscore_with_initializer() {
    let x = 22;
    let Double { value1: _, value2: _ }: Double<&'static u32> = Double {
        value1: &x, //~ ERROR
        value2: &44,
    };
}

fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
    // The error in this test is inconsistency with
    // `static_to_a_to_static_through_tuple`, but "feels right" to
    // me. It occurs because we special case the single binding case
    // and force the type of `y` to be `&'a u32`, even though the
    // right-hand side has type `&'static u32`.

    let y: &'a u32 = &22;
    y //~ ERROR
}

fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
    // FIXME(#47187): The fact that this type-checks is perhaps surprising.
    // What happens is that the right-hand side is constrained to have
    // type `&'a u32`, which is possible, because it has type
    // `&'static u32`. The variable `y` is then forced to have type
    // `&'static u32`, but it is constrained only by the right-hand
    // side, not the ascribed type, and hence it passes.

    let (y, _z): (&'a u32, u32) = (&22, 44);
    y
}

fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
    let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
    y
}

fn main() { }