commit
56d288d0dc
@ -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,
|
||||
|
@ -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 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -916,6 +916,11 @@ fn cat_pattern(&self,
|
||||
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,
|
||||
|
@ -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
|
||||
|
@ -4333,23 +4333,24 @@ struct in scope",
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ fn add_to_set(tcx: ty::ctxt, set: &mut ~[Opt], +val: 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.
|
||||
}
|
||||
|
@ -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);
|
||||
|
22
src/test/run-pass/cross-crate-const-pat.rs
Normal file
22
src/test/run-pass/cross-crate-const-pat.rs
Normal file
@ -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 => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user