mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-25 14:13:38 +00:00
Disallow rebinding / matching against consts in alts
As per Issue #1193. Closes #1193. I had to rename a few variables ("info" and "epsilon") to avoid clashing with in-scope constants, which is responsible for all the changes other than resolve and issue-1193.rs.
This commit is contained in:
parent
1e51196f33
commit
b0074c5a92
@ -51,10 +51,10 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> str {
|
||||
if (frac < epsilon && !exact) || digits == 0u { ret accum; }
|
||||
accum += ".";
|
||||
let mut i = digits;
|
||||
let mut epsilon = 1. / pow_with_uint(10u, i);
|
||||
while i > 0u && (frac >= epsilon || exact) {
|
||||
let mut epsilon_prime = 1. / pow_with_uint(10u, i);
|
||||
while i > 0u && (frac >= epsilon_prime || exact) {
|
||||
frac *= 10.0;
|
||||
epsilon *= 10.0;
|
||||
epsilon_prime *= 10.0;
|
||||
let digit = frac as uint;
|
||||
accum += uint::str(digit);
|
||||
frac -= digit as float;
|
||||
|
@ -34,9 +34,8 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
|
||||
some(normal({expander: exp, span: exp_sp})) {
|
||||
let expanded = exp(cx, pth.span, args, body);
|
||||
|
||||
let info = {call_site: s,
|
||||
callie: {name: extname, span: exp_sp}};
|
||||
cx.bt_push(expanded_from(info));
|
||||
cx.bt_push(expanded_from({call_site: s,
|
||||
callie: {name: extname, span: exp_sp}}));
|
||||
//keep going, outside-in
|
||||
let fully_expanded = fld.fold_expr(expanded).node;
|
||||
cx.bt_pop();
|
||||
|
@ -500,19 +500,23 @@ fn resolve_names(e: @env, c: @ast::crate) {
|
||||
}
|
||||
_ {
|
||||
e.sess.span_err(p.span,
|
||||
"not a enum variant: " +
|
||||
"not an enum variant: " +
|
||||
ast_util::path_name(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Here we determine whether a given pat_ident binds a new
|
||||
variable a refers to a nullary enum. */
|
||||
variable or refers to a nullary enum. */
|
||||
ast::pat_ident(p, none) {
|
||||
alt lookup_in_scope(*e, sc, p.span, path_to_ident(p),
|
||||
ns_val, false) {
|
||||
some(fnd@ast::def_variant(_,_)) {
|
||||
e.def_map.insert(pat.id, fnd);
|
||||
}
|
||||
some(fnd@ast::def_const(_)) {
|
||||
e.sess.span_err(p.span, "Sorry, rebinding or matching \
|
||||
against symbolic constants is not allowed.");
|
||||
}
|
||||
// Binds a var -- nothing needs to be done
|
||||
_ {}
|
||||
}
|
||||
@ -1446,16 +1450,16 @@ fn list_search<T: copy, U: copy>(ls: list<T>, f: fn(T) -> option<U>)
|
||||
|
||||
fn lookup_in_local_mod(e: env, node_id: node_id, sp: span, id: ident,
|
||||
ns: namespace, dr: dir) -> option<def> {
|
||||
let info = alt e.mod_map.find(node_id) {
|
||||
let inf = alt e.mod_map.find(node_id) {
|
||||
some(x) { x }
|
||||
none { e.sess.span_bug(sp, #fmt("lookup_in_local_mod: \
|
||||
module %d not in mod_map", node_id)); }
|
||||
};
|
||||
if dr == outside && !is_exported(e, id, info) {
|
||||
// if we're in a native mod, then dr==inside, so info.m is some _mod
|
||||
if dr == outside && !is_exported(e, id, inf) {
|
||||
// if we're in a native mod, then dr==inside, so inf.m is some _mod
|
||||
ret none; // name is not visible
|
||||
}
|
||||
alt info.index.find(id) {
|
||||
alt inf.index.find(id) {
|
||||
none { }
|
||||
some(lst) {
|
||||
let found = list_search(lst, bind lookup_in_mie(e, _, ns));
|
||||
@ -1465,7 +1469,7 @@ fn lookup_in_local_mod(e: env, node_id: node_id, sp: span, id: ident,
|
||||
}
|
||||
}
|
||||
// not local or explicitly imported; try globs:
|
||||
ret lookup_glob_in_mod(e, info, sp, id, ns, outside);
|
||||
ret lookup_glob_in_mod(e, inf, sp, id, ns, outside);
|
||||
}
|
||||
|
||||
fn lookup_in_globs(e: env, globs: [glob_imp_def], sp: span, id: ident,
|
||||
|
@ -371,19 +371,19 @@ fn get_tydesc(ccx: @crate_ctxt, t: ty::t,
|
||||
&static_ti: option<@tydesc_info>) -> ValueRef {
|
||||
assert !ty::type_has_params(t);
|
||||
// Otherwise, generate a tydesc if necessary, and return it.
|
||||
let info = get_static_tydesc(ccx, t);
|
||||
static_ti = some(info);
|
||||
info.tydesc
|
||||
let inf = get_static_tydesc(ccx, t);
|
||||
static_ti = some(inf);
|
||||
inf.tydesc
|
||||
}
|
||||
|
||||
fn get_static_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
|
||||
alt ccx.tydescs.find(t) {
|
||||
some(info) { ret info; }
|
||||
some(inf) { ret inf; }
|
||||
none {
|
||||
ccx.stats.n_static_tydescs += 1u;
|
||||
let info = declare_tydesc(ccx, t);
|
||||
ccx.tydescs.insert(t, info);
|
||||
ret info;
|
||||
let inf = declare_tydesc(ccx, t);
|
||||
ccx.tydescs.insert(t, inf);
|
||||
ret inf;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -455,7 +455,7 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
|
||||
let gvar = str::as_c_str(name, {|buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
|
||||
});
|
||||
let info =
|
||||
let inf =
|
||||
@{ty: t,
|
||||
tydesc: gvar,
|
||||
size: llsize,
|
||||
@ -464,7 +464,7 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
|
||||
mut drop_glue: none,
|
||||
mut free_glue: none};
|
||||
log(debug, "--- declare_tydesc " + ty_to_str(ccx.tcx, t));
|
||||
ret info;
|
||||
ret inf;
|
||||
}
|
||||
|
||||
type glue_helper = fn@(block, ValueRef, ty::t);
|
||||
@ -2870,8 +2870,8 @@ fn need_invoke(bcx: block) -> bool {
|
||||
let mut cur = bcx;
|
||||
loop {
|
||||
alt cur.kind {
|
||||
block_scope(info) {
|
||||
for info.cleanups.each {|cleanup|
|
||||
block_scope(inf) {
|
||||
for inf.cleanups.each {|cleanup|
|
||||
alt cleanup {
|
||||
clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) {
|
||||
if cleanup_type == normal_exit_and_unwind {
|
||||
@ -2892,8 +2892,8 @@ fn need_invoke(bcx: block) -> bool {
|
||||
|
||||
fn have_cached_lpad(bcx: block) -> bool {
|
||||
let mut res = false;
|
||||
in_lpad_scope_cx(bcx) {|info|
|
||||
alt info.landing_pad {
|
||||
in_lpad_scope_cx(bcx) {|inf|
|
||||
alt inf.landing_pad {
|
||||
some(_) { res = true; }
|
||||
none { res = false; }
|
||||
}
|
||||
@ -2905,9 +2905,9 @@ fn in_lpad_scope_cx(bcx: block, f: fn(scope_info)) {
|
||||
let mut bcx = bcx;
|
||||
loop {
|
||||
alt bcx.kind {
|
||||
block_scope(info) {
|
||||
if info.cleanups.len() > 0u || bcx.parent == parent_none {
|
||||
f(info); ret;
|
||||
block_scope(inf) {
|
||||
if inf.cleanups.len() > 0u || bcx.parent == parent_none {
|
||||
f(inf); ret;
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
@ -2920,13 +2920,13 @@ fn get_landing_pad(bcx: block) -> BasicBlockRef {
|
||||
let _icx = bcx.insn_ctxt("get_landing_pad");
|
||||
|
||||
let mut cached = none, pad_bcx = bcx; // Guaranteed to be set below
|
||||
in_lpad_scope_cx(bcx) {|info|
|
||||
in_lpad_scope_cx(bcx) {|inf|
|
||||
// If there is a valid landing pad still around, use it
|
||||
alt info.landing_pad {
|
||||
alt inf.landing_pad {
|
||||
some(target) { cached = some(target); }
|
||||
none {
|
||||
pad_bcx = sub_block(bcx, "unwind");
|
||||
info.landing_pad = some(pad_bcx.llbb);
|
||||
inf.landing_pad = some(pad_bcx.llbb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3792,8 +3792,8 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
|
||||
let mut done = false;
|
||||
loop {
|
||||
alt cur.kind {
|
||||
block_scope(info) if info.cleanups.len() > 0u {
|
||||
option::iter(vec::find(info.cleanup_paths,
|
||||
block_scope(inf) if inf.cleanups.len() > 0u {
|
||||
option::iter(vec::find(inf.cleanup_paths,
|
||||
{|cp| cp.target == leave})) {|cp|
|
||||
Br(bcx, cp.dest);
|
||||
done = true;
|
||||
@ -3801,7 +3801,7 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
|
||||
if done { ret; }
|
||||
let sub_cx = sub_block(bcx, "cleanup");
|
||||
Br(bcx, sub_cx.llbb);
|
||||
info.cleanup_paths += [{target: leave, dest: sub_cx.llbb}];
|
||||
inf.cleanup_paths += [{target: leave, dest: sub_cx.llbb}];
|
||||
bcx = trans_block_cleanups_(sub_cx, cur, is_lpad);
|
||||
}
|
||||
_ {}
|
||||
|
@ -381,7 +381,7 @@ fn in_scope_cx(cx: block, f: fn(scope_info)) {
|
||||
let mut cur = cx;
|
||||
loop {
|
||||
alt cur.kind {
|
||||
block_scope(info) { f(info); ret; }
|
||||
block_scope(inf) { f(inf); ret; }
|
||||
_ {}
|
||||
}
|
||||
cur = block_parent(cur);
|
||||
|
@ -514,16 +514,16 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
|
||||
// to each variant shape). As we do so, build up the header.
|
||||
|
||||
let mut header = [];
|
||||
let mut info = [];
|
||||
let mut inf = [];
|
||||
let header_sz = 2u16 * ccx.shape_cx.next_tag_id;
|
||||
let data_sz = vec::len(data) as u16;
|
||||
|
||||
let mut info_sz = 0u16;
|
||||
let mut inf_sz = 0u16;
|
||||
for ccx.shape_cx.tag_order.each {|did_|
|
||||
let did = did_; // Satisfy alias checker.
|
||||
let num_variants = vec::len(*ty::enum_variants(ccx.tcx, did)) as u16;
|
||||
add_u16(header, header_sz + info_sz);
|
||||
info_sz += 2u16 * (num_variants + 2u16) + 3u16;
|
||||
add_u16(header, header_sz + inf_sz);
|
||||
inf_sz += 2u16 * (num_variants + 2u16) + 3u16;
|
||||
}
|
||||
|
||||
// Construct the info tables, which contain offsets to the shape of each
|
||||
@ -535,11 +535,11 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
|
||||
for ccx.shape_cx.tag_order.each {|did_|
|
||||
let did = did_; // Satisfy alias checker.
|
||||
let variants = ty::enum_variants(ccx.tcx, did);
|
||||
add_u16(info, vec::len(*variants) as u16);
|
||||
add_u16(inf, vec::len(*variants) as u16);
|
||||
|
||||
// Construct the largest-variants table.
|
||||
add_u16(info,
|
||||
header_sz + info_sz + data_sz + (vec::len(lv_table) as u16));
|
||||
add_u16(inf,
|
||||
header_sz + inf_sz + data_sz + (vec::len(lv_table) as u16));
|
||||
|
||||
let lv = largest_variants(ccx, did);
|
||||
add_u16(lv_table, vec::len(lv) as u16);
|
||||
@ -555,22 +555,22 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
|
||||
let size_align = if dynamic { {size: 0u16, align: 0u8} }
|
||||
else { compute_static_enum_size(ccx, lv, did) };
|
||||
// Write in the static size and alignment of the enum.
|
||||
add_u16(info, size_align.size);
|
||||
info += [size_align.align];
|
||||
add_u16(inf, size_align.size);
|
||||
inf += [size_align.align];
|
||||
|
||||
// Now write in the offset of each variant.
|
||||
for vec::each(*variants) {|_v|
|
||||
add_u16(info, header_sz + info_sz + offsets[i]);
|
||||
add_u16(inf, header_sz + inf_sz + offsets[i]);
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
||||
assert (i == vec::len(offsets));
|
||||
assert (header_sz == vec::len(header) as u16);
|
||||
assert (info_sz == vec::len(info) as u16);
|
||||
assert (inf_sz == vec::len(inf) as u16);
|
||||
assert (data_sz == vec::len(data) as u16);
|
||||
|
||||
header += info;
|
||||
header += inf;
|
||||
header += data;
|
||||
header += lv_table;
|
||||
|
||||
|
14
src/test/compile-fail/issue-1193.rs
Normal file
14
src/test/compile-fail/issue-1193.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// error-pattern: Sorry, rebinding or matching against symbolic
|
||||
mod foo {
|
||||
type t = u8;
|
||||
|
||||
const a : t = 0u8;
|
||||
const b : t = 1u8;
|
||||
|
||||
fn bar(v: t) -> bool {
|
||||
alt v {
|
||||
a { ret true; }
|
||||
b { ret false; }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user