@@ -14,8 +14,7 @@ use middle::ty;
14
14
use util:: ppaux;
15
15
16
16
use syntax:: ast;
17
- use syntax:: visit:: Visitor ;
18
- use syntax:: visit;
17
+ use syntax:: visit:: { mod, Visitor } ;
19
18
20
19
struct CheckCrateVisitor < ' a , ' tcx : ' a > {
21
20
tcx : & ' a ty:: ctxt < ' tcx > ,
@@ -36,24 +35,39 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
36
35
{
37
36
self . with_const ( true , f) ;
38
37
}
39
- fn outside_const < F > ( & mut self , f : F ) where
40
- F : FnOnce ( & mut CheckCrateVisitor < ' a , ' tcx > ) ,
41
- {
42
- self . with_const ( false , f) ;
43
- }
44
38
}
45
39
46
40
impl < ' a , ' tcx , ' v > Visitor < ' v > for CheckCrateVisitor < ' a , ' tcx > {
47
41
fn visit_item ( & mut self , i : & ast:: Item ) {
48
- check_item ( self , i) ;
42
+ match i. node {
43
+ ast:: ItemStatic ( _, _, ref ex) |
44
+ ast:: ItemConst ( _, ref ex) => {
45
+ self . inside_const ( |v| v. visit_expr ( & * * ex) ) ;
46
+ }
47
+ ast:: ItemEnum ( ref enum_definition, _) => {
48
+ self . inside_const ( |v| {
49
+ for var in enum_definition. variants . iter ( ) {
50
+ if let Some ( ref ex) = var. node . disr_expr {
51
+ v. visit_expr ( & * * ex) ;
52
+ }
53
+ }
54
+ } ) ;
55
+ }
56
+ _ => self . with_const ( false , |v| visit:: walk_item ( v, i) )
57
+ }
49
58
}
50
59
fn visit_pat ( & mut self , p : & ast:: Pat ) {
51
- check_pat ( self , p) ;
60
+ let is_const = match p. node {
61
+ ast:: PatLit ( _) | ast:: PatRange ( ..) => true ,
62
+ _ => false
63
+ } ;
64
+ self . with_const ( is_const, |v| visit:: walk_pat ( v, p) )
52
65
}
53
66
fn visit_expr ( & mut self , ex : & ast:: Expr ) {
54
- if check_expr ( self , ex ) {
55
- visit :: walk_expr ( self , ex) ;
67
+ if self . in_const {
68
+ check_expr ( self , ex) ;
56
69
}
70
+ visit:: walk_expr ( self , ex) ;
57
71
}
58
72
}
59
73
@@ -63,40 +77,12 @@ pub fn check_crate(tcx: &ty::ctxt) {
63
77
tcx. sess . abort_if_errors ( ) ;
64
78
}
65
79
66
- fn check_item ( v : & mut CheckCrateVisitor , it : & ast:: Item ) {
67
- match it. node {
68
- ast:: ItemStatic ( _, _, ref ex) |
69
- ast:: ItemConst ( _, ref ex) => {
70
- v. inside_const ( |v| v. visit_expr ( & * * ex) ) ;
71
- }
72
- ast:: ItemEnum ( ref enum_definition, _) => {
73
- for var in ( * enum_definition) . variants . iter ( ) {
74
- for ex in var. node . disr_expr . iter ( ) {
75
- v. inside_const ( |v| v. visit_expr ( & * * ex) ) ;
76
- }
77
- }
78
- }
79
- _ => v. outside_const ( |v| visit:: walk_item ( v, it) )
80
- }
81
- }
82
-
83
- fn check_pat ( v : & mut CheckCrateVisitor , p : & ast:: Pat ) {
84
- let is_const = match p. node {
85
- ast:: PatLit ( _) | ast:: PatRange ( ..) => true ,
86
- _ => false
87
- } ;
88
- v. with_const ( is_const, |v| visit:: walk_pat ( v, p) )
89
- }
90
-
91
- fn check_expr ( v : & mut CheckCrateVisitor , e : & ast:: Expr ) -> bool {
92
- if !v. in_const { return true }
93
-
80
+ fn check_expr ( v : & mut CheckCrateVisitor , e : & ast:: Expr ) {
94
81
match e. node {
95
82
ast:: ExprUnary ( ast:: UnDeref , _) => { }
96
83
ast:: ExprUnary ( ast:: UnUniq , _) => {
97
84
span_err ! ( v. tcx. sess, e. span, E0010 ,
98
85
"cannot do allocations in constant expressions" ) ;
99
- return false ;
100
86
}
101
87
ast:: ExprBinary ( ..) | ast:: ExprUnary ( ..) => {
102
88
let method_call = ty:: MethodCall :: expr ( e. id ) ;
@@ -135,29 +121,22 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
135
121
"paths in constants may only refer to items without \
136
122
type parameters") ;
137
123
}
138
- match v. tcx . def_map . borrow ( ) . get ( & e. id ) {
139
- Some ( & DefStatic ( ..) ) |
140
- Some ( & DefConst ( ..) ) |
141
- Some ( & DefFn ( ..) ) |
142
- Some ( & DefVariant ( _, _, _) ) |
143
- Some ( & DefStruct ( _) ) => { }
124
+ match v. tcx . def_map . borrow ( ) [ e. id ] {
125
+ DefStatic ( ..) | DefConst ( ..) |
126
+ DefFn ( ..) | DefStruct ( _) |
127
+ DefVariant ( _, _, _) => { }
144
128
145
- Some ( & def) => {
129
+ def => {
146
130
debug ! ( "(checking const) found bad def: {}" , def) ;
147
131
span_err ! ( v. tcx. sess, e. span, E0014 ,
148
132
"paths in constants may only refer to constants \
149
133
or functions") ;
150
134
}
151
- None => {
152
- v. tcx . sess . span_bug ( e. span , "unbound path in const?!" ) ;
153
- }
154
135
}
155
136
}
156
137
ast:: ExprCall ( ref callee, _) => {
157
- match v. tcx . def_map . borrow ( ) . get ( & callee. id ) {
158
- Some ( & DefStruct ( ..) ) |
159
- Some ( & DefVariant ( ..) ) => { } // OK.
160
-
138
+ match v. tcx . def_map . borrow ( ) [ callee. id ] {
139
+ DefStruct ( ..) | DefVariant ( ..) => { } // OK.
161
140
_ => {
162
141
span_err ! ( v. tcx. sess, e. span, E0015 ,
163
142
"function calls in constants are limited to \
@@ -173,9 +152,9 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
173
152
"blocks in constants are limited to items and \
174
153
tail expressions") ;
175
154
match stmt. node {
176
- ast:: StmtDecl ( ref span , _) => {
177
- match span . node {
178
- ast:: DeclLocal ( _) => block_span_err ( span . span ) ,
155
+ ast:: StmtDecl ( ref decl , _) => {
156
+ match decl . node {
157
+ ast:: DeclLocal ( _) => block_span_err ( decl . span ) ,
179
158
180
159
// Item statements are allowed
181
160
ast:: DeclItem ( _) => { }
@@ -189,9 +168,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
189
168
}
190
169
}
191
170
}
192
- match block. expr {
193
- Some ( ref expr) => { check_expr ( v, & * * expr) ; }
194
- None => { }
171
+ if let Some ( ref expr) = block. expr {
172
+ check_expr ( v, & * * expr) ;
195
173
}
196
174
}
197
175
ast:: ExprVec ( _) |
@@ -215,11 +193,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
215
193
}
216
194
}
217
195
218
- _ => {
219
- span_err ! ( v. tcx. sess, e. span, E0019 ,
220
- "constant contains unimplemented expression type" ) ;
221
- return false ;
222
- }
196
+ _ => span_err ! ( v. tcx. sess, e. span, E0019 ,
197
+ "constant contains unimplemented expression type" )
223
198
}
224
- true
225
199
}
0 commit comments