@@ -14,8 +14,7 @@ use middle::ty;
1414use util:: ppaux;
1515
1616use syntax:: ast;
17- use syntax:: visit:: Visitor ;
18- use syntax:: visit;
17+ use syntax:: visit:: { mod, Visitor } ;
1918
2019struct CheckCrateVisitor < ' a , ' tcx : ' a > {
2120 tcx : & ' a ty:: ctxt < ' tcx > ,
@@ -36,24 +35,39 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
3635 {
3736 self . with_const ( true , f) ;
3837 }
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- }
4438}
4539
4640impl < ' a , ' tcx , ' v > Visitor < ' v > for CheckCrateVisitor < ' a , ' tcx > {
4741 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+ }
4958 }
5059 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) )
5265 }
5366 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) ;
5669 }
70+ visit:: walk_expr ( self , ex) ;
5771 }
5872}
5973
@@ -63,40 +77,12 @@ pub fn check_crate(tcx: &ty::ctxt) {
6377 tcx. sess . abort_if_errors ( ) ;
6478}
6579
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 ) {
9481 match e. node {
9582 ast:: ExprUnary ( ast:: UnDeref , _) => { }
9683 ast:: ExprUnary ( ast:: UnUniq , _) => {
9784 span_err ! ( v. tcx. sess, e. span, E0010 ,
9885 "cannot do allocations in constant expressions" ) ;
99- return false ;
10086 }
10187 ast:: ExprBinary ( ..) | ast:: ExprUnary ( ..) => {
10288 let method_call = ty:: MethodCall :: expr ( e. id ) ;
@@ -135,29 +121,22 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
135121 "paths in constants may only refer to items without \
136122 type parameters") ;
137123 }
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 ( _, _, _) => { }
144128
145- Some ( & def) => {
129+ def => {
146130 debug ! ( "(checking const) found bad def: {}" , def) ;
147131 span_err ! ( v. tcx. sess, e. span, E0014 ,
148132 "paths in constants may only refer to constants \
149133 or functions") ;
150134 }
151- None => {
152- v. tcx . sess . span_bug ( e. span , "unbound path in const?!" ) ;
153- }
154135 }
155136 }
156137 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.
161140 _ => {
162141 span_err ! ( v. tcx. sess, e. span, E0015 ,
163142 "function calls in constants are limited to \
@@ -173,9 +152,9 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
173152 "blocks in constants are limited to items and \
174153 tail expressions") ;
175154 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 ) ,
179158
180159 // Item statements are allowed
181160 ast:: DeclItem ( _) => { }
@@ -189,9 +168,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
189168 }
190169 }
191170 }
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) ;
195173 }
196174 }
197175 ast:: ExprVec ( _) |
@@ -215,11 +193,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
215193 }
216194 }
217195
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" )
223198 }
224- true
225199}
0 commit comments