10
10
11
11
//! See docs in build/expr/mod.rs
12
12
13
- use build:: { BlockAnd , BlockAndExtension , Builder } ;
14
- use build:: ForGuard :: { OutsideGuard , RefWithinGuard } ;
15
13
use build:: expr:: category:: Category ;
14
+ use build:: ForGuard :: { OutsideGuard , RefWithinGuard } ;
15
+ use build:: { BlockAnd , BlockAndExtension , Builder } ;
16
16
use hair:: * ;
17
- use rustc:: mir:: * ;
18
17
use rustc:: mir:: interpret:: EvalErrorKind :: BoundsCheck ;
18
+ use rustc:: mir:: * ;
19
19
20
20
use rustc_data_structures:: indexed_vec:: Idx ;
21
21
22
22
impl < ' a , ' gcx , ' tcx > Builder < ' a , ' gcx , ' tcx > {
23
23
/// Compile `expr`, yielding a place that we can move from etc.
24
- pub fn as_place < M > ( & mut self ,
25
- block : BasicBlock ,
26
- expr : M )
27
- -> BlockAnd < Place < ' tcx > >
28
- where M : Mirror < ' tcx , Output =Expr < ' tcx > >
24
+ pub fn as_place < M > ( & mut self , block : BasicBlock , expr : M ) -> BlockAnd < Place < ' tcx > >
25
+ where
26
+ M : Mirror < ' tcx , Output = Expr < ' tcx > > ,
29
27
{
30
28
let expr = self . hir . mirror ( expr) ;
31
29
self . expr_as_place ( block, expr, Mutability :: Mut )
@@ -36,36 +34,40 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
36
34
/// place. The place itself may or may not be mutable:
37
35
/// * If this expr is a place expr like a.b, then we will return that place.
38
36
/// * Otherwise, a temporary is created: in that event, it will be an immutable temporary.
39
- pub fn as_read_only_place < M > ( & mut self ,
40
- block : BasicBlock ,
41
- expr : M )
42
- -> BlockAnd < Place < ' tcx > >
43
- where M : Mirror < ' tcx , Output =Expr < ' tcx > >
37
+ pub fn as_read_only_place < M > ( & mut self , block : BasicBlock , expr : M ) -> BlockAnd < Place < ' tcx > >
38
+ where
39
+ M : Mirror < ' tcx , Output = Expr < ' tcx > > ,
44
40
{
45
41
let expr = self . hir . mirror ( expr) ;
46
42
self . expr_as_place ( block, expr, Mutability :: Not )
47
43
}
48
44
49
- fn expr_as_place ( & mut self ,
50
- mut block : BasicBlock ,
51
- expr : Expr < ' tcx > ,
52
- mutability : Mutability )
53
- -> BlockAnd < Place < ' tcx > > {
54
- debug ! ( "expr_as_place(block={:?}, expr={:?}, mutability={:?})" , block, expr, mutability) ;
45
+ fn expr_as_place (
46
+ & mut self ,
47
+ mut block : BasicBlock ,
48
+ expr : Expr < ' tcx > ,
49
+ mutability : Mutability ,
50
+ ) -> BlockAnd < Place < ' tcx > > {
51
+ debug ! (
52
+ "expr_as_place(block={:?}, expr={:?}, mutability={:?})" ,
53
+ block, expr, mutability
54
+ ) ;
55
55
56
56
let this = self ;
57
57
let expr_span = expr. span ;
58
58
let source_info = this. source_info ( expr_span) ;
59
59
match expr. kind {
60
- ExprKind :: Scope { region_scope, lint_level, value } => {
61
- this. in_scope ( ( region_scope, source_info) , lint_level, block, |this| {
62
- if mutability == Mutability :: Not {
63
- this. as_read_only_place ( block, value)
64
- } else {
65
- this. as_place ( block, value)
66
- }
67
- } )
68
- }
60
+ ExprKind :: Scope {
61
+ region_scope,
62
+ lint_level,
63
+ value,
64
+ } => this. in_scope ( ( region_scope, source_info) , lint_level, block, |this| {
65
+ if mutability == Mutability :: Not {
66
+ this. as_read_only_place ( block, value)
67
+ } else {
68
+ this. as_place ( block, value)
69
+ }
70
+ } ) ,
69
71
ExprKind :: Field { lhs, name } => {
70
72
let place = unpack ! ( block = this. as_place( block, lhs) ) ;
71
73
let place = place. field ( name, expr. ty ) ;
@@ -86,29 +88,40 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
86
88
let idx = unpack ! ( block = this. as_temp( block, None , index, Mutability :: Mut ) ) ;
87
89
88
90
// bounds check:
89
- let ( len, lt) = ( this. temp ( usize_ty. clone ( ) , expr_span) ,
90
- this. temp ( bool_ty, expr_span) ) ;
91
- this. cfg . push_assign ( block, source_info, // len = len(slice)
92
- & len, Rvalue :: Len ( slice. clone ( ) ) ) ;
93
- this. cfg . push_assign ( block, source_info, // lt = idx < len
94
- & lt, Rvalue :: BinaryOp ( BinOp :: Lt ,
95
- Operand :: Copy ( Place :: Local ( idx) ) ,
96
- Operand :: Copy ( len. clone ( ) ) ) ) ;
91
+ let ( len, lt) = (
92
+ this. temp ( usize_ty. clone ( ) , expr_span) ,
93
+ this. temp ( bool_ty, expr_span) ,
94
+ ) ;
95
+ this. cfg . push_assign (
96
+ block,
97
+ source_info, // len = len(slice)
98
+ & len,
99
+ Rvalue :: Len ( slice. clone ( ) ) ,
100
+ ) ;
101
+ this. cfg . push_assign (
102
+ block,
103
+ source_info, // lt = idx < len
104
+ & lt,
105
+ Rvalue :: BinaryOp (
106
+ BinOp :: Lt ,
107
+ Operand :: Copy ( Place :: Local ( idx) ) ,
108
+ Operand :: Copy ( len. clone ( ) ) ,
109
+ ) ,
110
+ ) ;
97
111
98
112
let msg = BoundsCheck {
99
113
len : Operand :: Move ( len) ,
100
- index : Operand :: Copy ( Place :: Local ( idx) )
114
+ index : Operand :: Copy ( Place :: Local ( idx) ) ,
101
115
} ;
102
- let success = this. assert ( block, Operand :: Move ( lt) , true ,
103
- msg, expr_span) ;
116
+ let success = this. assert ( block, Operand :: Move ( lt) , true , msg, expr_span) ;
104
117
success. and ( slice. index ( idx) )
105
118
}
106
- ExprKind :: SelfRef => {
107
- block. and ( Place :: Local ( Local :: new ( 1 ) ) )
108
- }
119
+ ExprKind :: SelfRef => block. and ( Place :: Local ( Local :: new ( 1 ) ) ) ,
109
120
ExprKind :: VarRef { id } => {
110
- let place = if this. is_bound_var_in_guard ( id) &&
111
- this. hir . tcx ( ) . all_pat_vars_are_implicit_refs_within_guards ( )
121
+ let place = if this. is_bound_var_in_guard ( id) && this
122
+ . hir
123
+ . tcx ( )
124
+ . all_pat_vars_are_implicit_refs_within_guards ( )
112
125
{
113
126
let index = this. var_local_id ( id, RefWithinGuard ) ;
114
127
Place :: Local ( index) . deref ( )
@@ -118,47 +131,48 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
118
131
} ;
119
132
block. and ( place)
120
133
}
121
- ExprKind :: StaticRef { id } => {
122
- block. and ( Place :: Static ( Box :: new ( Static { def_id : id, ty : expr. ty } ) ) )
123
- }
134
+ ExprKind :: StaticRef { id } => block. and ( Place :: Static ( Box :: new ( Static {
135
+ def_id : id,
136
+ ty : expr. ty ,
137
+ } ) ) ) ,
124
138
125
- ExprKind :: Array { .. } |
126
- ExprKind :: Tuple { .. } |
127
- ExprKind :: Adt { .. } |
128
- ExprKind :: Closure { .. } |
129
- ExprKind :: Unary { .. } |
130
- ExprKind :: Binary { .. } |
131
- ExprKind :: LogicalOp { .. } |
132
- ExprKind :: Box { .. } |
133
- ExprKind :: Cast { .. } |
134
- ExprKind :: Use { .. } |
135
- ExprKind :: NeverToAny { .. } |
136
- ExprKind :: ReifyFnPointer { .. } |
137
- ExprKind :: ClosureFnPointer { .. } |
138
- ExprKind :: UnsafeFnPointer { .. } |
139
- ExprKind :: Unsize { .. } |
140
- ExprKind :: Repeat { .. } |
141
- ExprKind :: Borrow { .. } |
142
- ExprKind :: If { .. } |
143
- ExprKind :: Match { .. } |
144
- ExprKind :: Loop { .. } |
145
- ExprKind :: Block { .. } |
146
- ExprKind :: Assign { .. } |
147
- ExprKind :: AssignOp { .. } |
148
- ExprKind :: Break { .. } |
149
- ExprKind :: Continue { .. } |
150
- ExprKind :: Return { .. } |
151
- ExprKind :: Literal { .. } |
152
- ExprKind :: InlineAsm { .. } |
153
- ExprKind :: Yield { .. } |
154
- ExprKind :: Call { .. } => {
139
+ ExprKind :: Array { .. }
140
+ | ExprKind :: Tuple { .. }
141
+ | ExprKind :: Adt { .. }
142
+ | ExprKind :: Closure { .. }
143
+ | ExprKind :: Unary { .. }
144
+ | ExprKind :: Binary { .. }
145
+ | ExprKind :: LogicalOp { .. }
146
+ | ExprKind :: Box { .. }
147
+ | ExprKind :: Cast { .. }
148
+ | ExprKind :: Use { .. }
149
+ | ExprKind :: NeverToAny { .. }
150
+ | ExprKind :: ReifyFnPointer { .. }
151
+ | ExprKind :: ClosureFnPointer { .. }
152
+ | ExprKind :: UnsafeFnPointer { .. }
153
+ | ExprKind :: Unsize { .. }
154
+ | ExprKind :: Repeat { .. }
155
+ | ExprKind :: Borrow { .. }
156
+ | ExprKind :: If { .. }
157
+ | ExprKind :: Match { .. }
158
+ | ExprKind :: Loop { .. }
159
+ | ExprKind :: Block { .. }
160
+ | ExprKind :: Assign { .. }
161
+ | ExprKind :: AssignOp { .. }
162
+ | ExprKind :: Break { .. }
163
+ | ExprKind :: Continue { .. }
164
+ | ExprKind :: Return { .. }
165
+ | ExprKind :: Literal { .. }
166
+ | ExprKind :: InlineAsm { .. }
167
+ | ExprKind :: Yield { .. }
168
+ | ExprKind :: Call { .. } => {
155
169
// these are not places, so we need to make a temporary.
156
170
debug_assert ! ( match Category :: of( & expr. kind) {
157
171
Some ( Category :: Place ) => false ,
158
172
_ => true ,
159
173
} ) ;
160
- let temp = unpack ! (
161
- block = this. as_temp( block, expr. temp_lifetime, expr, mutability) ) ;
174
+ let temp =
175
+ unpack ! ( block = this. as_temp( block, expr. temp_lifetime, expr, mutability) ) ;
162
176
block. and ( Place :: Local ( temp) )
163
177
}
164
178
}
0 commit comments