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:
Tim Chevalier 2012-04-19 16:19:53 -07:00
parent 1e51196f33
commit b0074c5a92
7 changed files with 65 additions and 48 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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,

View File

@ -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);
}
_ {}

View File

@ -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);

View File

@ -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;

View 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; }
}
}
}