File: promote-not.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg2-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 893,176 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; lisp: 29; perl: 29; ruby: 19; sql: 11
file content (100 lines) | stat: -rw-r--r-- 4,269 bytes parent folder | download | duplicates (10)
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
// ignore-tidy-linelength
// Test various things that we do not want to promote.
#![allow(unconditional_panic)]

use std::cell::Cell;
use std::mem::ManuallyDrop;

// We do not promote mutable references.
static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]); //~ ERROR temporary value dropped while borrowed

static mut TEST2: &'static mut [i32] = {
    let x = &mut [1,2,3]; //~ ERROR temporary value dropped while borrowed
    x
};

// We do not promote fn calls in `fn`, including `const fn`.
pub const fn promote_cal(b: bool) -> i32 {
    const fn foo() { [()][42] }

    if b {
        let _x: &'static () = &foo(); //~ ERROR temporary value dropped while borrowed
    }
    13
}

// We do not promote union field accesses in `fn`.
union U { x: i32, y: i32 }
pub const fn promote_union() {
    let _x: &'static i32 = &unsafe { U { x: 0 }.x }; //~ ERROR temporary value dropped while borrowed
}

// We do not promote union field accesses in `const`, either.
const TEST_UNION: () = {
    let _x: &'static i32 = &unsafe { U { x: 0 }.x }; //~ ERROR temporary value dropped while borrowed
};

// In a `const`, we do not promote things with interior mutability. Not even if we "project it away".
const TEST_INTERIOR_MUT: () = {
    // The "0." case is already ruled out by not permitting any interior mutability in `const`.
    let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed
};

// This gets accepted by the "outer scope" rule, not promotion.
const TEST_DROP_OUTER_SCOPE: &String = &String::new();
// To demonstrate that, we can rewrite it as follows. If this was promotion it would still work.
const TEST_DROP_NOT_PROMOTE: &String = {
    let x = &String::new(); //~ ERROR destructor of `String` cannot be evaluated at compile-time
    // The "dropped while borrowed" error seems to be suppressed, but the key point is that this
    // fails to compile.
    x
};


// We do not promote function calls in `const` initializers in dead code.
const fn mk_panic() -> u32 { panic!() }
const fn mk_false() -> bool { false }
const Y: () = {
    if mk_false() {
        let _x: &'static u32 = &mk_panic(); //~ ERROR temporary value dropped while borrowed
    }
};

fn main() {
    // We must not promote things with interior mutability. Not even if we "project it away".
    let _val: &'static _ = &(Cell::new(1), 2).0; //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed

    // No promotion of fallible operations.
    let _val: &'static _ = &(1/0); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(1/(1-1)); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &((1+1)/(1-1)); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(i32::MIN/-1); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(i32::MIN/(0-1)); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(-128i8/-1); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(1%0); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(1%(1-1)); //~ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &([1,2,3][4]+1); //~ ERROR temporary value dropped while borrowed

    // No promotion of temporaries that need to be dropped.
    const TEST_DROP: String = String::new();
    let _val: &'static _ = &TEST_DROP;
    //~^ ERROR temporary value dropped while borrowed
    let _val: &'static _ = &&TEST_DROP;
    //~^ ERROR temporary value dropped while borrowed
    //~| ERROR temporary value dropped while borrowed
    let _val: &'static _ = &(&TEST_DROP,);
    //~^ ERROR temporary value dropped while borrowed
    //~| ERROR temporary value dropped while borrowed
    let _val: &'static _ = &[&TEST_DROP; 1];
    //~^ ERROR temporary value dropped while borrowed
    //~| ERROR temporary value dropped while borrowed

    // Make sure there is no value-based reasoning for unions.
    union UnionWithCell {
        f1: i32,
        f2: ManuallyDrop<Cell<i32>>,
    }
    let x: &'static _ = &UnionWithCell { f1: 0 };
    //~^ ERROR temporary value dropped while borrowed
}