diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 66333884475..6e98ebc6976 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -197,6 +197,9 @@ pub enum Expr {
     Tuple {
         exprs: Vec<ExprId>,
     },
+    Array {
+        exprs: Vec<ExprId>,
+    },
     Literal(Literal),
 }
 
@@ -312,7 +315,7 @@ impl Expr {
             | Expr::UnaryOp { expr, .. } => {
                 f(*expr);
             }
-            Expr::Tuple { exprs } => {
+            Expr::Tuple { exprs } | Expr::Array { exprs } => {
                 for expr in exprs {
                     f(*expr);
                 }
@@ -649,6 +652,10 @@ impl ExprCollector {
                 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
                 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
             }
+            ast::ExprKind::ArrayExpr(e) => {
+                let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
+                self.alloc_expr(Expr::Array { exprs }, syntax_ptr)
+            }
             ast::ExprKind::Literal(e) => {
                 let child = if let Some(child) = e.literal_expr() {
                     child
@@ -691,7 +698,6 @@ impl ExprCollector {
             // TODO implement HIR for these:
             ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
             ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
-            ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
             ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
         }
     }
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 85d4dc05ce8..676ed3ac994 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -227,6 +227,9 @@ pub enum Ty {
     /// A tuple type.  For example, `(i32, bool)`.
     Tuple(Arc<[Ty]>),
 
+    /// A array type.  For example, `[i32]`.
+    Array(Arc<[Ty]>),
+
     // The projection of an associated type.  For example,
     // `<T as Trait<..>>::N`.pub
     // Projection(ProjectionTy),
@@ -414,6 +417,16 @@ impl fmt::Display for Ty {
                         .to_fmt(f)
                 }
             }
+            Ty::Array(ts) => {
+                if ts.len() == 1 {
+                    write!(f, "[{},]", ts[0])
+                } else {
+                    join(ts.iter())
+                        .surround_with("[", "]")
+                        .separator(", ")
+                        .to_fmt(f)
+                }
+            }
             Ty::FnPtr(sig) => {
                 join(sig.input.iter())
                     .surround_with("fn(", ")")
@@ -1101,7 +1114,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                 }
 
                 Ty::Tuple(Arc::from(ty_vec))
-            }
+            },
+            Expr::Array { exprs } => {
+                let mut ty_vec = Vec::with_capacity(exprs.len());
+                for arg in exprs.iter() {
+                    ty_vec.push(self.infer_expr(*arg, &Expectation::none()));
+                }
+
+                Ty::Array(Arc::from(ty_vec))
+            },
             Expr::Literal(lit) => match lit {
                 Literal::Bool(..) => Ty::Bool,
                 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared),