about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-03-21 08:49:13 -0700
committerbors <bors@rust-lang.org>2013-03-21 08:49:13 -0700
commit56d288d0dc89ae8d284ffddf74f6be9d0f37362e (patch)
treedd80e056d5b30e46416b367ed9cf4fd9c0ba04ec /src
parentefb5f8734aec0e6e7325b32425716587f59203a3 (diff)
parent3f2d576a38854c1f6ffd21016e4c8a2822d64fee (diff)
downloadrust-56d288d0dc89ae8d284ffddf74f6be9d0f37362e.tar.gz
rust-56d288d0dc89ae8d284ffddf74f6be9d0f37362e.zip
auto merge of #5464 : luqmana/rust/const-pat, r=pcwalton
r? @pcwalton 
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/check_match.rs19
-rw-r--r--src/librustc/middle/const_eval.rs23
-rw-r--r--src/librustc/middle/mem_categorization.rs5
-rw-r--r--src/librustc/middle/pat_util.rs2
-rw-r--r--src/librustc/middle/resolve.rs11
-rw-r--r--src/librustc/middle/trans/_match.rs26
-rw-r--r--src/librustc/middle/typeck/check/_match.rs1
-rw-r--r--src/test/run-pass/cross-crate-const-pat.rs22
8 files changed, 93 insertions, 16 deletions
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 245872c39c6..24e94c7ca6d 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -528,6 +528,25 @@ pub fn specialize(cx: @MatchCheckCtxt,
             }
             pat_enum(_, args) => {
                 match cx.tcx.def_map.get(&pat_id) {
+                    def_const(did) => {
+                        let const_expr =
+                            lookup_const_by_id(cx.tcx, did).get();
+                        let e_v = eval_const_expr(cx.tcx, const_expr);
+                        let match_ = match ctor_id {
+                            val(ref v) => compare_const_vals(e_v, (*v)) == 0,
+                            range(ref c_lo, ref c_hi) => {
+                                compare_const_vals((*c_lo), e_v) >= 0 &&
+                                    compare_const_vals((*c_hi), e_v) <= 0
+                            }
+                            single => true,
+                            _ => fail!(~"type error")
+                        };
+                        if match_ {
+                            Some(vec::from_slice(r.tail()))
+                        } else {
+                            None
+                        }
+                    }
                     def_variant(_, id) if variant(id) == ctor_id => {
                         let args = match args {
                             Some(args) => args,
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 4888a01c6b9..ba6348bb1de 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -10,6 +10,8 @@
 
 use core::prelude::*;
 
+use metadata::csearch;
+use middle::astencode;
 use middle::resolve;
 use middle::ty;
 use middle;
@@ -19,6 +21,8 @@ use core::vec;
 use syntax::{ast, ast_map, ast_util, visit};
 use syntax::ast::*;
 
+use std::oldmap::HashMap;
+
 //
 // This pass classifies expressions by their constant-ness.
 //
@@ -187,7 +191,24 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
             Some(_) => None
         }
     } else {
-        None
+        let maps = astencode::Maps {
+            mutbl_map: HashMap(),
+            root_map: HashMap(),
+            last_use_map: HashMap(),
+            method_map: HashMap(),
+            vtable_map: HashMap(),
+            write_guard_map: HashMap(),
+            moves_map: HashMap(),
+            capture_map: HashMap()
+        };
+        match csearch::maybe_get_item_ast(tcx, def_id,
+            |a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) {
+            csearch::found(ast::ii_item(item)) => match item.node {
+                item_const(_, const_expr) => Some(const_expr),
+                _ => None
+            },
+            _ => None
+        }
     }
 }
 
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index fee3695002d..a471d91877a 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -916,6 +916,11 @@ pub impl mem_categorization_ctxt {
                         self.cat_pattern(cmt_field, *subpat, op);
                     }
                 }
+                Some(ast::def_const(*)) => {
+                    for subpats.each |subpat| {
+                        self.cat_pattern(cmt, *subpat, op);
+                    }
+                }
                 _ => {
                     self.tcx.sess.span_bug(
                         pat.span,
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 4522977a4ab..a25fddcad88 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -43,7 +43,7 @@ pub fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: @pat) -> bool {
 
 pub fn pat_is_const(dm: resolve::DefMap, pat: &pat) -> bool {
     match pat.node {
-        pat_ident(_, _, None) => {
+        pat_ident(_, _, None) | pat_enum(*) => {
             match dm.find(&pat.id) {
                 Some(def_const(*)) => true,
                 _ => false
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 2bba9a0df2e..f0e7ef0c589 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -4333,23 +4333,24 @@ pub impl Resolver {
                 }
 
                 pat_enum(path, _) => {
-                    // This must be an enum variant or struct.
+                    // This must be an enum variant, struct or const.
                     match self.resolve_path(path, ValueNS, false, visitor) {
                         Some(def @ def_variant(*)) |
-                                Some(def @ def_struct(*)) => {
+                        Some(def @ def_struct(*))  |
+                        Some(def @ def_const(*)) => {
                             self.record_def(pattern.id, def);
                         }
                         Some(_) => {
                             self.session.span_err(
                                 path.span,
-                                fmt!("not an enum variant or struct: %s",
+                                fmt!("not an enum variant, struct or const: %s",
                                      *self.session.str_of(
                                          *path.idents.last())));
                         }
                         None => {
                             self.session.span_err(path.span,
-                                                  ~"unresolved enum variant \
-                                                    or struct");
+                                                  ~"unresolved enum variant, \
+                                                    struct or const");
                         }
                     }
 
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 45fe40ca1f7..09f0a4f547a 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -502,6 +502,16 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
     let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()};
     do enter_match(bcx, tcx.def_map, m, col, val) |p| {
         match p.node {
+            ast::pat_enum(*) |
+            ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => {
+                let const_def = tcx.def_map.get(&p.id);
+                let const_def_id = ast_util::def_id_of_def(const_def);
+                if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
+                    Some(~[])
+                } else {
+                    None
+                }
+            }
             ast::pat_enum(_, ref subpats) => {
                 if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
                     match *subpats {
@@ -520,15 +530,6 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
                     None
                 }
             }
-            ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => {
-                let const_def = tcx.def_map.get(&p.id);
-                let const_def_id = ast_util::def_id_of_def(const_def);
-                if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
-                    Some(~[])
-                } else {
-                    None
-                }
-            }
             ast::pat_lit(l) => {
                 if opt_eq(tcx, &lit(ExprLit(l)), opt) {Some(~[])} else {None}
             }
@@ -806,6 +807,10 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] {
                         add_to_set(ccx.tcx, &mut found,
                                    variant_opt(bcx, cur.id));
                     }
+                    Some(ast::def_const(const_did)) => {
+                        add_to_set(ccx.tcx, &mut found,
+                                   lit(ConstLit(const_did)));
+                    }
                     _ => {}
                 }
             }
@@ -1782,6 +1787,9 @@ pub fn bind_irrefutable_pat(bcx: block,
                         }
                     }
                 }
+                Some(ast::def_const(*)) => {
+                    bcx = bind_irrefutable_pat(bcx, pat, val, make_copy, binding_mode);
+                }
                 _ => {
                     // Nothing to do here.
                 }
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 5e106668fc9..5dcbcbda35c 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -366,6 +366,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
         }
         fcx.write_ty(pat.id, b_ty);
       }
+      ast::pat_enum(*) |
       ast::pat_ident(*) if pat_is_const(tcx.def_map, pat) => {
         let const_did = ast_util::def_id_of_def(tcx.def_map.get(&pat.id));
         let const_tpt = ty::lookup_item_type(tcx, const_did);
diff --git a/src/test/run-pass/cross-crate-const-pat.rs b/src/test/run-pass/cross-crate-const-pat.rs
new file mode 100644
index 00000000000..0a0e2356f44
--- /dev/null
+++ b/src/test/run-pass/cross-crate-const-pat.rs
@@ -0,0 +1,22 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-fast
+// aux-build:cci_const.rs
+
+extern mod cci_const;
+
+fn main() {
+    let x = cci_const::uint_val;
+    match x {
+        cci_const::uint_val => {}
+        _ => {}
+    }
+}