]> git.lizzy.rs Git - rust.git/commitdiff
Allow constant struct fields and tuple indexing
authorAdolfo Ochagavía <aochagavia92@gmail.com>
Mon, 24 Nov 2014 11:46:02 +0000 (12:46 +0100)
committerAdolfo Ochagavía <aochagavia92@gmail.com>
Tue, 25 Nov 2014 09:25:14 +0000 (10:25 +0100)
src/librustc/middle/const_eval.rs

index 98ac7e413ca7c63213e2a1c9aae7c7f035a03ad3..7afbf9223514769044731ca44b82639b91a5c0b1 100644 (file)
@@ -567,6 +567,34 @@ macro_rules! define_casts(
             None => Ok(const_int(0i64))
         }
       }
+      ast::ExprTupField(ref base, index) => {
+        // Get the base tuple if it is constant
+        if let Some(&ast::ExprTup(ref fields)) = lookup_const(tcx, &**base).map(|s| &s.node) {
+            // Check that the given index is within bounds and evaluate its value
+            if fields.len() > index.node {
+                return eval_const_expr_partial(tcx, &*fields[index.node])
+            } else {
+                return Err("tuple index out of bounds".to_string())
+            }
+        }
+
+        Err("non-constant struct in constant expr".to_string())
+      }
+      ast::ExprField(ref base, field_name) => {
+        // Get the base expression if it is a struct and it is constant
+        if let Some(&ast::ExprStruct(_, ref fields, _)) = lookup_const(tcx, &**base)
+                                                            .map(|s| &s.node) {
+            // Check that the given field exists and evaluate it
+            if let Some(f) = fields.iter().find(|f|
+                                           f.ident.node.as_str() == field_name.node.as_str()) {
+                return eval_const_expr_partial(tcx, &*f.expr)
+            } else {
+                return Err("nonexistent struct field".to_string())
+            }
+        }
+
+        Err("non-constant struct in constant expr".to_string())
+      }
       _ => Err("unsupported constant expr".to_string())
     }
 }