Support path as array length

Fixes #29.
diff --git a/src/expr.rs b/src/expr.rs
index 821e264..20e0555 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -352,11 +352,13 @@
 
     named!(pub expr -> Expr, do_parse!(
         mut e: alt!(
-            expr_lit // needs to be before expr_struct
+            expr_lit // must be before expr_struct
             |
-            expr_struct // needs to be before expr_path
+            expr_struct // must be before expr_path
             |
-            expr_paren // needs to be before expr_tup
+            expr_paren // must be before expr_tup
+            |
+            expr_mac // must be before expr_path
             |
             expr_box
             |
@@ -390,8 +392,6 @@
             |
             expr_ret
             |
-            expr_mac
-            |
             expr_repeat
         ) >>
         many0!(alt!(
diff --git a/src/ty.rs b/src/ty.rs
index dd81fac..b8aee5a 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -6,7 +6,7 @@
     /// A variable-length array (`[T]`)
     Slice(Box<Ty>),
     /// A fixed length array (`[T; n]`)
-    Array(Box<Ty>, usize),
+    Array(Box<Ty>, ArrayLen),
     /// A raw pointer (`*const T` or `*mut T`)
     Ptr(Box<MutTy>),
     /// A reference (`&'a T` or `&'a mut T`)
@@ -36,6 +36,15 @@
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
+pub enum ArrayLen {
+    /// As in `[T; 0]`.
+    Usize(usize),
+    /// As in `[T; LEN]` or `[T; helper::LEN as usize]`. The boolean indicates
+    /// whether the path is followed by `as usize`.
+    Path(Path, bool),
+}
+
+#[derive(Debug, Clone, Eq, PartialEq)]
 pub struct MutTy {
     pub ty: Ty,
     pub mutability: Mutability,
@@ -203,7 +212,7 @@
     named!(pub ty -> Ty, alt!(
         ty_vec
         |
-        ty_fixed_length_vec
+        ty_array
         |
         ty_ptr
         |
@@ -229,13 +238,23 @@
         (Ty::Slice(Box::new(elem)))
     ));
 
-    named!(ty_fixed_length_vec -> Ty, do_parse!(
+    named!(ty_array -> Ty, do_parse!(
         punct!("[") >>
         elem: ty >>
         punct!(";") >>
-        len: int >>
+        len: array_len >>
         punct!("]") >>
-        (Ty::Array(Box::new(elem), len.0 as usize))
+        (Ty::Array(Box::new(elem), len))
+    ));
+
+    named!(array_len -> ArrayLen, alt!(
+        map!(int, |(i, _)| ArrayLen::Usize(i as usize))
+        |
+        do_parse!(
+            path: path >>
+            as_usize: option!(tuple!(keyword!("as"), keyword!("usize"))) >>
+            (ArrayLen::Path(path, as_usize.is_some()))
+        )
     ));
 
     named!(ty_ptr -> Ty, do_parse!(
@@ -431,11 +450,11 @@
                     inner.to_tokens(tokens);
                     tokens.append("]");
                 }
-                Ty::Array(ref inner, len) => {
+                Ty::Array(ref inner, ref len) => {
                     tokens.append("[");
                     inner.to_tokens(tokens);
                     tokens.append(";");
-                    tokens.append(&len.to_string());
+                    len.to_tokens(tokens);
                     tokens.append("]");
                 }
                 Ty::Ptr(ref target) => {
@@ -508,6 +527,21 @@
         }
     }
 
+    impl ToTokens for ArrayLen {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            match *self {
+                ArrayLen::Usize(len) => tokens.append(&len.to_string()),
+                ArrayLen::Path(ref path, as_usize) => {
+                    path.to_tokens(tokens);
+                    if as_usize {
+                        tokens.append("as");
+                        tokens.append("usize");
+                    }
+                }
+            }
+        }
+    }
+
     impl ToTokens for Mutability {
         fn to_tokens(&self, tokens: &mut Tokens) {
             if let Mutability::Mutable = *self {