Skip to content

Commit 77e6573

Browse files
committed
Further work on integer literal suffix inference (#1425)
In this commit: * Change the lit_int_unsuffixed AST node to not carry a type, since it doesn't need one * Don't print "(unsuffixed)" when pretty-printing unsuffixed integer literals * Just print "I" instead of "(integral)" for integral type variables * Set up trans to use the information that will be gathered during typeck to construct the appropriate constants for unsuffixed int literals * Add logic for handling int_ty_sets in typeck::infer * Clean up unnecessary code in typeck::infer * Add missing mk_ functions to middle::ty * Add ty_var_integral to a few of the type utility functions it was missing from in middle::ty
1 parent d953462 commit 77e6573

File tree

12 files changed

+201
-143
lines changed

12 files changed

+201
-143
lines changed

src/libsyntax/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ enum lit_ {
402402
lit_str(@str),
403403
lit_int(i64, int_ty),
404404
lit_uint(u64, uint_ty),
405-
lit_int_unsuffixed(i64, int_ty),
405+
lit_int_unsuffixed(i64),
406406
lit_float(@str, float_ty),
407407
lit_nil,
408408
lit_bool(bool),

src/libsyntax/parse/classify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn ends_in_lit_int(ex: @ast::expr) -> bool {
5454
ast::expr_lit(node) {
5555
alt node {
5656
@{node: ast::lit_int(_, ast::ty_i), _} |
57-
@{node: ast::lit_int_unsuffixed(_, ast::ty_i), _}
57+
@{node: ast::lit_int_unsuffixed(_), _}
5858
{ true }
5959
_ { false }
6060
}

src/libsyntax/parse/lexer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ fn scan_number(c: char, rdr: reader) -> token::token {
285285

286286
#debug["lexing %s as an unsuffixed integer literal",
287287
num_str];
288-
ret token::LIT_INT_UNSUFFIXED(parsed as i64, ast::ty_i);
288+
ret token::LIT_INT_UNSUFFIXED(parsed as i64);
289289
}
290290
}
291291

src/libsyntax/parse/parser.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ class parser {
501501
let lo = self.span.lo;
502502
self.bump();
503503
alt copy self.token {
504-
token::LIT_INT_UNSUFFIXED(num, _) {
504+
token::LIT_INT_UNSUFFIXED(num) {
505505
self.bump();
506506
some(mac_var(num as uint))
507507
}
@@ -534,7 +534,7 @@ class parser {
534534
token::UNDERSCORE {
535535
self.bump(); some(vstore_fixed(none))
536536
}
537-
token::LIT_INT_UNSUFFIXED(i, _) if i >= 0i64 {
537+
token::LIT_INT_UNSUFFIXED(i) if i >= 0i64 {
538538
self.bump(); some(vstore_fixed(some(i as uint)))
539539
}
540540
token::BINOP(token::AND) {
@@ -553,7 +553,7 @@ class parser {
553553
alt tok {
554554
token::LIT_INT(i, it) { lit_int(i, it) }
555555
token::LIT_UINT(u, ut) { lit_uint(u, ut) }
556-
token::LIT_INT_UNSUFFIXED(i, it) { lit_int_unsuffixed(i, it) }
556+
token::LIT_INT_UNSUFFIXED(i) { lit_int_unsuffixed(i) }
557557
token::LIT_FLOAT(s, ft) { lit_float(self.get_str(s), ft) }
558558
token::LIT_STR(s) { lit_str(self.get_str(s)) }
559559
token::LPAREN { self.expect(token::RPAREN); lit_nil }

src/libsyntax/parse/token.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ enum token {
5757
/* Literals */
5858
LIT_INT(i64, ast::int_ty),
5959
LIT_UINT(u64, ast::uint_ty),
60-
LIT_INT_UNSUFFIXED(i64, ast::int_ty),
60+
LIT_INT_UNSUFFIXED(i64),
6161
LIT_FLOAT(str_num, ast::float_ty),
6262
LIT_STR(str_num),
6363

@@ -129,8 +129,8 @@ fn to_str(in: interner<@str>, t: token) -> str {
129129
LIT_UINT(u, t) {
130130
uint::to_str(u as uint, 10u) + ast_util::uint_ty_to_str(t)
131131
}
132-
LIT_INT_UNSUFFIXED(i, t) {
133-
int::to_str(i as int, 10u) + ast_util::int_ty_to_str(t)
132+
LIT_INT_UNSUFFIXED(i) {
133+
int::to_str(i as int, 10u)
134134
}
135135
LIT_FLOAT(s, t) {
136136
*interner::get(in, s) +
@@ -160,7 +160,7 @@ pure fn can_begin_expr(t: token) -> bool {
160160
TILDE { true }
161161
LIT_INT(_, _) { true }
162162
LIT_UINT(_, _) { true }
163-
LIT_INT_UNSUFFIXED(_, _) { true }
163+
LIT_INT_UNSUFFIXED(_) { true }
164164
LIT_FLOAT(_, _) { true }
165165
LIT_STR(_) { true }
166166
POUND { true }
@@ -178,7 +178,7 @@ fn is_lit(t: token) -> bool {
178178
alt t {
179179
LIT_INT(_, _) { true }
180180
LIT_UINT(_, _) { true }
181-
LIT_INT_UNSUFFIXED(_, _) { true }
181+
LIT_INT_UNSUFFIXED(_) { true }
182182
LIT_FLOAT(_, _) { true }
183183
LIT_STR(_) { true }
184184
_ { false }

src/libsyntax/print/pprust.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,15 +1628,11 @@ fn print_literal(s: ps, &&lit: @ast::lit) {
16281628
u64::to_str(u, 10u)
16291629
+ ast_util::uint_ty_to_str(t));
16301630
}
1631-
ast::lit_int_unsuffixed(i, t) {
1631+
ast::lit_int_unsuffixed(i) {
16321632
if i < 0_i64 {
1633-
word(s.s,
1634-
"-" + u64::to_str(-i as u64, 10u)
1635-
+ ast_util::int_ty_to_str(t));
1633+
word(s.s, "-" + u64::to_str(-i as u64, 10u));
16361634
} else {
1637-
word(s.s,
1638-
u64::to_str(i as u64, 10u)
1639-
+ ast_util::int_ty_to_str(t));
1635+
word(s.s, u64::to_str(i as u64, 10u));
16401636
}
16411637
}
16421638
ast::lit_float(f, t) {

src/rustc/metadata/tyencode.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,9 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
278278
w.write_uint(id.to_uint());
279279
}
280280
ty::ty_var_integral(id) {
281-
// TODO: should we have a different character for these? (Issue #1425)
282281
w.write_char('X');
282+
w.write_char('I');
283283
w.write_uint(id.to_uint());
284-
w.write_str("(integral)");
285284
}
286285
ty::ty_param(id, did) {
287286
w.write_char('p');

src/rustc/middle/const_eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fn lit_to_const(lit: @lit) -> const_val {
111111
lit_str(s) { const_str(*s) }
112112
lit_int(n, _) { const_int(n) }
113113
lit_uint(n, _) { const_uint(n) }
114-
lit_int_unsuffixed(n, _) { const_int(n) }
114+
lit_int_unsuffixed(n) { const_int(n) }
115115
lit_float(n, _) { const_float(option::get(float::from_str(*n)) as f64) }
116116
lit_nil { const_int(0i64) }
117117
lit_bool(b) { const_int(b as i64) }

src/rustc/middle/trans/base.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,15 +1473,25 @@ fn store_temp_expr(cx: block, action: copy_action, dst: ValueRef,
14731473
ret move_val(cx, action, dst, src, t);
14741474
}
14751475

1476-
fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef {
1476+
fn trans_crate_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
1477+
-> ValueRef {
14771478
let _icx = cx.insn_ctxt("trans_crate_lit");
14781479
alt lit.node {
14791480
ast::lit_int(i, t) { C_integral(T_int_ty(cx, t), i as u64, True) }
14801481
ast::lit_uint(u, t) { C_integral(T_uint_ty(cx, t), u, False) }
1481-
ast::lit_int_unsuffixed(i, t) {
1482-
// FIXME (#1425): should we be using cx.fcx.infcx to figure out what
1483-
// to actually generate from this?
1484-
C_integral(T_int_ty(cx, t), i as u64, True)
1482+
ast::lit_int_unsuffixed(i) {
1483+
let lit_int_ty = ty::node_id_to_type(cx.tcx, e.id);
1484+
alt ty::get(lit_int_ty).struct {
1485+
ty::ty_int(t) {
1486+
C_integral(T_int_ty(cx, t), i as u64, True)
1487+
}
1488+
ty::ty_uint(t) {
1489+
C_integral(T_uint_ty(cx, t), i as u64, False)
1490+
}
1491+
_ { cx.sess.span_bug(lit.span,
1492+
"integer literal doesn't have a type");
1493+
}
1494+
}
14851495
}
14861496
ast::lit_float(fs, t) { C_floating(*fs, T_float_ty(cx, t)) }
14871497
ast::lit_bool(b) { C_bool(b) }
@@ -1492,13 +1502,13 @@ fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef {
14921502
}
14931503
}
14941504

1495-
fn trans_lit(cx: block, lit: ast::lit, dest: dest) -> block {
1505+
fn trans_lit(cx: block, e: @ast::expr, lit: ast::lit, dest: dest) -> block {
14961506
let _icx = cx.insn_ctxt("trans_lit");
14971507
if dest == ignore { ret cx; }
14981508
alt lit.node {
14991509
ast::lit_str(s) { tvec::trans_estr(cx, s, ast::vstore_uniq, dest) }
15001510
_ {
1501-
store_in_dest(cx, trans_crate_lit(cx.ccx(), lit), dest)
1511+
store_in_dest(cx, trans_crate_lit(cx.ccx(), e, lit), dest)
15021512
}
15031513
}
15041514
}
@@ -3584,7 +3594,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
35843594
}
35853595
ast::expr_tup(args) { ret trans_tup(bcx, args, dest); }
35863596
ast::expr_vstore(e, v) { ret tvec::trans_vstore(bcx, e, v, dest); }
3587-
ast::expr_lit(lit) { ret trans_lit(bcx, *lit, dest); }
3597+
ast::expr_lit(lit) { ret trans_lit(bcx, e, *lit, dest); }
35883598
ast::expr_vec(args, _) {
35893599
ret tvec::trans_evec(bcx, args, ast::vstore_uniq, e.id, dest);
35903600
}
@@ -4684,7 +4694,7 @@ fn trans_enum_variant(ccx: @crate_ctxt, enum_id: ast::node_id,
46844694
fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
46854695
let _icx = cx.insn_ctxt("trans_const_expr");
46864696
alt e.node {
4687-
ast::expr_lit(lit) { ret trans_crate_lit(cx, *lit); }
4697+
ast::expr_lit(lit) { ret trans_crate_lit(cx, e, *lit); }
46884698
ast::expr_binary(b, e1, e2) {
46894699
let te1 = trans_const_expr(cx, e1);
46904700
let te2 = trans_const_expr(cx, e2);

src/rustc/middle/ty.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export ty_float, mk_float, mk_mach_float, type_is_fp;
8484
export ty_fn, fn_ty, mk_fn;
8585
export ty_fn_proto, ty_fn_ret, ty_fn_ret_style, tys_in_fn_ty;
8686
export ty_int, mk_int, mk_mach_int, mk_char;
87+
export mk_i8, mk_u8, mk_i16, mk_u16, mk_i32, mk_u32, mk_i64, mk_u64;
8788
export ty_str, mk_str, type_is_str;
8889
export ty_vec, mk_vec, type_is_vec;
8990
export ty_estr, mk_estr;
@@ -416,7 +417,8 @@ enum type_err {
416417
terr_vstores_differ(terr_vstore_kind, vstore, vstore),
417418
terr_in_field(@type_err, ast::ident),
418419
terr_sorts(t, t),
419-
terr_self_substs
420+
terr_self_substs,
421+
terr_no_integral_type,
420422
}
421423

422424
enum param_bound {
@@ -442,7 +444,7 @@ impl of vid for tv_vid {
442444

443445
impl of vid for tvi_vid {
444446
fn to_uint() -> uint { *self }
445-
fn to_str() -> str { #fmt["<V (integral) %u>", self.to_uint()] }
447+
fn to_str() -> str { #fmt["<VI%u>", self.to_uint()] }
446448
}
447449

448450
impl of vid for region_vid {
@@ -619,12 +621,26 @@ fn mk_bool(cx: ctxt) -> t { mk_t(cx, ty_bool) }
619621

620622
fn mk_int(cx: ctxt) -> t { mk_t(cx, ty_int(ast::ty_i)) }
621623

624+
fn mk_i8(cx: ctxt) -> t { mk_t(cx, ty_int(ast::ty_i8)) }
625+
626+
fn mk_i16(cx: ctxt) -> t { mk_t(cx, ty_int(ast::ty_i16)) }
627+
628+
fn mk_i32(cx: ctxt) -> t { mk_t(cx, ty_int(ast::ty_i32)) }
629+
630+
fn mk_i64(cx: ctxt) -> t { mk_t(cx, ty_int(ast::ty_i64)) }
631+
622632
fn mk_float(cx: ctxt) -> t { mk_t(cx, ty_float(ast::ty_f)) }
623633

624634
fn mk_uint(cx: ctxt) -> t { mk_t(cx, ty_uint(ast::ty_u)) }
625635

626636
fn mk_u8(cx: ctxt) -> t { mk_t(cx, ty_uint(ast::ty_u8)) }
627637

638+
fn mk_u16(cx: ctxt) -> t { mk_t(cx, ty_uint(ast::ty_u16)) }
639+
640+
fn mk_u32(cx: ctxt) -> t { mk_t(cx, ty_uint(ast::ty_u32)) }
641+
642+
fn mk_u64(cx: ctxt) -> t { mk_t(cx, ty_uint(ast::ty_u64)) }
643+
628644
fn mk_mach_int(cx: ctxt, tm: ast::int_ty) -> t { mk_t(cx, ty_int(tm)) }
629645

630646
fn mk_mach_uint(cx: ctxt, tm: ast::uint_ty) -> t { mk_t(cx, ty_uint(tm)) }
@@ -1188,7 +1204,7 @@ pure fn type_is_unique(ty: t) -> bool {
11881204
pure fn type_is_scalar(ty: t) -> bool {
11891205
alt get(ty).struct {
11901206
ty_nil | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
1191-
ty_type | ty_ptr(_) | ty_rptr(_, _) { true }
1207+
ty_var_integral(_) | ty_type | ty_ptr(_) | ty_rptr(_, _) { true }
11921208
_ { false }
11931209
}
11941210
}
@@ -1827,7 +1843,7 @@ fn type_structurally_contains_uniques(cx: ctxt, ty: t) -> bool {
18271843

18281844
fn type_is_integral(ty: t) -> bool {
18291845
alt get(ty).struct {
1830-
ty_int(_) | ty_uint(_) | ty_bool { true }
1846+
ty_var_integral(_) | ty_int(_) | ty_uint(_) | ty_bool { true }
18311847
_ { false }
18321848
}
18331849
}
@@ -2531,6 +2547,10 @@ fn type_err_to_str(cx: ctxt, err: type_err) -> str {
25312547
terr_self_substs {
25322548
ret "inconsistent self substitution"; // XXX this is more of a bug
25332549
}
2550+
terr_no_integral_type {
2551+
ret "couldn't determine an appropriate integral type for integer \
2552+
literal";
2553+
}
25342554
}
25352555
}
25362556

@@ -2966,7 +2986,7 @@ fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool {
29662986
fn tycat(ty: t) -> int {
29672987
alt get(ty).struct {
29682988
ty_bool { tycat_bool }
2969-
ty_int(_) | ty_uint(_) { tycat_int }
2989+
ty_int(_) | ty_uint(_) | ty_var_integral(_) { tycat_int }
29702990
ty_float(_) { tycat_float }
29712991
ty_estr(_) | ty_str { tycat_str }
29722992
ty_evec(_, _) | ty_vec(_) { tycat_vec }

src/rustc/middle/typeck/check.rs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,9 @@ import middle::ty::{tv_vid, vid};
7373
import regionmanip::{replace_bound_regions_in_fn_ty, region_of};
7474
import rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope};
7575
import rscope::{in_binding_rscope, region_scope, type_rscope};
76-
import syntax::ast::{ty_char, ty_i8, ty_i16, ty_i32, ty_i64, ty_i};
76+
import syntax::ast::{ty_char, ty_i};
7777
import typeck::infer::{root, to_str};
7878
import typeck::infer::{unify_methods}; // infcx.set()
79-
import typeck::infer::{min_8bit_tys, min_16bit_tys, min_32bit_tys,
80-
min_64bit_tys};
8179

8280
type fn_ctxt =
8381
// var_bindings, locals and next_var_id are shared
@@ -623,29 +621,13 @@ fn check_lit(fcx: @fn_ctxt, lit: @ast::lit) -> ty::t {
623621
ast::lit_str(_) { ty::mk_str(tcx) }
624622
ast::lit_int(_, t) { ty::mk_mach_int(tcx, t) }
625623
ast::lit_uint(_, t) { ty::mk_mach_uint(tcx, t) }
626-
ast::lit_int_unsuffixed(v, t) {
624+
ast::lit_int_unsuffixed(v) {
627625
// An unsuffixed integer literal could have any integral type,
628626
// so we create an integral type variable for it.
629-
let vid = fcx.infcx.next_ty_var_integral_id();
630-
631-
// We need to sniff at the value `v` and figure out how big of
632-
// an int it is; that determines the range of possible types
633-
// that the integral type variable could take on.
634-
let possible_types = alt v {
635-
0i64 to 127i64 { min_8bit_tys() }
636-
128i64 to 65535i64 { min_16bit_tys() }
637-
65536i64 to 4294967295i64 { min_32bit_tys() }
638-
_ { min_64bit_tys() }
639-
};
640-
641-
// Store the set of possible types and return the integral
642-
// type variable.
643-
fcx.infcx.set(fcx.infcx.tvib, vid,
644-
root(possible_types));
645-
ty::mk_var_integral(tcx, vid);
627+
ty::mk_var_integral(tcx, fcx.infcx.next_ty_var_integral_id());
646628

647629
// FIXME: remove me when #1425 is finished.
648-
ty::mk_mach_int(tcx, t)
630+
ty::mk_mach_int(tcx, ty_i)
649631
}
650632
ast::lit_float(_, t) { ty::mk_mach_float(tcx, t) }
651633
ast::lit_nil { ty::mk_nil(tcx) }

0 commit comments

Comments
 (0)