Auto merge of #148324 - Zalathar:rollup-yp35ktq, r=Zalathar · rust-lang/rust@51f5892 (original) (raw)

1

1

`//! Random access inspection of the results of a dataflow analysis.

`

2

2

``

3

``

`-

use std::borrow::Cow;

`

4

3

`use std::cmp::Ordering;

`

5

``

`-

use std::ops::{Deref, DerefMut};

`

``

4

`+

use std::ops::Deref;

`

6

5

``

7

6

`#[cfg(debug_assertions)]

`

8

7

`use rustc_index::bit_set::DenseBitSet;

`

9

8

`use rustc_middle::mir::{self, BasicBlock, Location};

`

10

9

``

11

10

`use super::{Analysis, Direction, Effect, EffectIndex, Results};

`

12

11

``

13

``

`` -

/// Some ResultsCursors want to own an Analysis, and some want to borrow an Analysis, either

``

14

``

`` -

/// mutable or immutably. This type allows all of the above. It's similar to Cow, but Cow

``

15

``

`-

/// doesn't allow mutable borrowing.

`

16

``

`-

enum CowMut<'a, T> {

`

17

``

`-

BorrowedMut(&'a mut T),

`

``

12

`` +

/// This is like Cow, but it lacks the T: ToOwned bound and doesn't support

``

``

13

`` +

/// to_owned/into_owned.

``

``

14

`+

enum SimpleCow<'a, T> {

`

``

15

`+

Borrowed(&'a T),

`

18

16

`Owned(T),

`

19

17

`}

`

20

18

``

21

``

`-

impl Deref for CowMut<'_, T> {

`

``

19

`+

impl Deref for SimpleCow<'_, T> {

`

22

20

`type Target = T;

`

23

21

``

24

22

`fn deref(&self) -> &T {

`

25

23

`match self {

`

26

``

`-

CowMut::BorrowedMut(borrowed) => borrowed,

`

27

``

`-

CowMut::Owned(owned) => owned,

`

28

``

`-

}

`

29

``

`-

}

`

30

``

`-

}

`

31

``

-

32

``

`-

impl DerefMut for CowMut<'_, T> {

`

33

``

`-

fn deref_mut(&mut self) -> &mut T {

`

34

``

`-

match self {

`

35

``

`-

CowMut::BorrowedMut(borrowed) => borrowed,

`

36

``

`-

CowMut::Owned(owned) => owned,

`

``

24

`+

SimpleCow::Borrowed(borrowed) => borrowed,

`

``

25

`+

SimpleCow::Owned(owned) => owned,

`

37

26

`}

`

38

27

`}

`

39

28

`}

`

`@@ -53,8 +42,7 @@ where

`

53

42

`A: Analysis<'tcx>,

`

54

43

`{

`

55

44

`body: &'mir mir::Body<'tcx>,

`

56

``

`-

analysis: CowMut<'mir, A>,

`

57

``

`-

results: Cow<'mir, Results<A::Domain>>,

`

``

45

`+

results: SimpleCow<'mir, Results<'tcx, A>>,

`

58

46

`state: A::Domain,

`

59

47

``

60

48

`pos: CursorPosition,

`

`@@ -82,15 +70,10 @@ where

`

82

70

`self.body

`

83

71

`}

`

84

72

``

85

``

`-

fn new(

`

86

``

`-

body: &'mir mir::Body<'tcx>,

`

87

``

`-

analysis: CowMut<'mir, A>,

`

88

``

`-

results: Cow<'mir, Results<A::Domain>>,

`

89

``

`-

) -> Self {

`

90

``

`-

let bottom_value = analysis.bottom_value(body);

`

``

73

`+

fn new(body: &'mir mir::Body<'tcx>, results: SimpleCow<'mir, Results<'tcx, A>>) -> Self {

`

``

74

`+

let bottom_value = results.analysis.bottom_value(body);

`

91

75

`ResultsCursor {

`

92

76

` body,

`

93

``

`-

analysis,

`

94

77

` results,

`

95

78

``

96

79

`` // Initialize to the bottom_value and set state_needs_reset to tell the cursor that

``

`@@ -106,21 +89,13 @@ where

`

106

89

`}

`

107

90

``

108

91

`/// Returns a new cursor that takes ownership of and inspects analysis results.

`

109

``

`-

pub fn new_owning(

`

110

``

`-

body: &'mir mir::Body<'tcx>,

`

111

``

`-

analysis: A,

`

112

``

`-

results: Results<A::Domain>,

`

113

``

`-

) -> Self {

`

114

``

`-

Self::new(body, CowMut::Owned(analysis), Cow::Owned(results))

`

``

92

`+

pub fn new_owning(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {

`

``

93

`+

Self::new(body, SimpleCow::Owned(results))

`

115

94

`}

`

116

95

``

117

96

`/// Returns a new cursor that borrows and inspects analysis results.

`

118

``

`-

pub fn new_borrowing(

`

119

``

`-

body: &'mir mir::Body<'tcx>,

`

120

``

`-

analysis: &'mir mut A,

`

121

``

`-

results: &'mir Results<A::Domain>,

`

122

``

`-

) -> Self {

`

123

``

`-

Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results))

`

``

97

`+

pub fn new_borrowing(body: &'mir mir::Body<'tcx>, results: &'mir Results<'tcx, A>) -> Self {

`

``

98

`+

Self::new(body, SimpleCow::Borrowed(results))

`

124

99

`}

`

125

100

``

126

101

`` /// Allows inspection of unreachable basic blocks even with debug_assertions enabled.

``

`@@ -132,7 +107,7 @@ where

`

132

107

``

133

108

`` /// Returns the Analysis used to generate the underlying Results.

``

134

109

`pub fn analysis(&self) -> &A {

`

135

``

`-

&self.analysis

`

``

110

`+

&self.results.analysis

`

136

111

`}

`

137

112

``

138

113

`/// Resets the cursor to hold the entry set for the given basic block.

`

`@@ -144,7 +119,7 @@ where

`

144

119

`#[cfg(debug_assertions)]

`

145

120

`assert!(self.reachable_blocks.contains(block));

`

146

121

``

147

``

`-

self.state.clone_from(&self.results[block]);

`

``

122

`+

self.state.clone_from(&self.results.entry_states[block]);

`

148

123

`self.pos = CursorPosition::block_entry(block);

`

149

124

`self.state_needs_reset = false;

`

150

125

`}

`

`@@ -236,7 +211,7 @@ where

`

236

211

`let target_effect_index = effect.at_index(target.statement_index);

`

237

212

``

238

213

`A::Direction::apply_effects_in_range(

`

239

``

`-

&mut *self.analysis,

`

``

214

`+

&self.results.analysis,

`

240

215

`&mut self.state,

`

241

216

` target.block,

`

242

217

` block_data,

`

`@@ -251,8 +226,8 @@ where

`

251

226

`///

`

252

227

`/// This can be used, e.g., to apply the call return effect directly to the cursor without

`

253

228

`/// creating an extra copy of the dataflow state.

`

254

``

`-

pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {

`

255

``

`-

f(&mut self.analysis, &mut self.state);

`

``

229

`+

pub fn apply_custom_effect(&mut self, f: impl FnOnce(&A, &mut A::Domain)) {

`

``

230

`+

f(&self.results.analysis, &mut self.state);

`

256

231

`self.state_needs_reset = true;

`

257

232

`}

`

258

233

`}

`