Skip to content

Commit b8af02e

Browse files
committed
WIP on issue #1425: mostly infrastructure changes.
1 parent d8d7673 commit b8af02e

File tree

5 files changed

+314
-111
lines changed

5 files changed

+314
-111
lines changed

src/rustc/metadata/tydecode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
346346
ret ty::mk_res(st.tcx, def, inner, substs);
347347
}
348348
'X' {
349-
ret ty::mk_var(st.tcx, ty::ty_vid(parse_int(st) as uint));
349+
ret ty::mk_var(st.tcx, ty::tv_vid(parse_int(st) as uint));
350350
}
351351
'Y' { ret ty::mk_type(st.tcx); }
352352
'C' {

src/rustc/middle/ty.rs

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import middle::lint::{get_warning_level, vecs_not_implicitly_copyable,
1717
import syntax::ast::*;
1818
import syntax::print::pprust::*;
1919

20-
export ty_vid, region_vid, vid;
20+
export tv_vid, tvi_vid, region_vid, vid;
2121
export br_hashmap;
2222
export is_instantiable;
2323
export node_id_to_type;
@@ -302,11 +302,6 @@ enum closure_kind {
302302
ck_uniq,
303303
}
304304

305-
enum ty_var_kind {
306-
tvk_regular,
307-
tvk_integral,
308-
}
309-
310305
type fn_ty = {purity: ast::purity,
311306
proto: ast::proto,
312307
inputs: [arg],
@@ -372,9 +367,9 @@ enum sty {
372367
ty_res(def_id, t, substs),
373368
ty_tup([t]),
374369

375-
ty_var(ty_vid), // type variable during typechecking
376-
ty_var_integral(ty_vid), // type variable during typechecking, for
377-
// integral types only
370+
ty_var(tv_vid), // type variable during typechecking
371+
ty_var_integral(tvi_vid), // type variable during typechecking, for
372+
// integral types only
378373
ty_param(uint, def_id), // type parameter
379374
ty_self, // special, implicit `self` type parameter
380375
ty_constr(t, [@type_constr]),
@@ -429,19 +424,25 @@ enum param_bound {
429424
bound_iface(t),
430425
}
431426

432-
enum ty_vid = uint;
427+
enum tv_vid = uint;
428+
enum tvi_vid = uint;
433429
enum region_vid = uint;
434430

435431
iface vid {
436432
fn to_uint() -> uint;
437433
fn to_str() -> str;
438434
}
439435

440-
impl of vid for ty_vid {
436+
impl of vid for tv_vid {
441437
fn to_uint() -> uint { *self }
442438
fn to_str() -> str { #fmt["<V%u>", self.to_uint()] }
443439
}
444440

441+
impl of vid for tvi_vid {
442+
fn to_uint() -> uint { *self }
443+
fn to_str() -> str { #fmt["<V (integral) %u>", self.to_uint()] }
444+
}
445+
445446
impl of vid for region_vid {
446447
fn to_uint() -> uint { *self }
447448
fn to_str() -> str { #fmt["<R%u>", self.to_uint()] }
@@ -693,9 +694,11 @@ fn mk_res(cx: ctxt, did: ast::def_id,
693694
mk_t(cx, ty_res(did, inner, substs))
694695
}
695696

696-
fn mk_var(cx: ctxt, v: ty_vid) -> t { mk_t(cx, ty_var(v)) }
697+
fn mk_var(cx: ctxt, v: tv_vid) -> t { mk_t(cx, ty_var(v)) }
697698

698-
fn mk_var_integral(cx: ctxt, v: ty_vid) -> t { mk_t(cx, ty_var_integral(v)) }
699+
fn mk_var_integral(cx: ctxt, v: tvi_vid) -> t {
700+
mk_t(cx, ty_var_integral(v))
701+
}
699702

700703
fn mk_self(cx: ctxt) -> t { mk_t(cx, ty_self) }
701704

@@ -1911,29 +1914,6 @@ fn type_param(ty: t) -> option<uint> {
19111914
ret none;
19121915
}
19131916

1914-
// Returns a vec of all the type variables of kind `tvk` occurring in `ty`. It
1915-
// may contain duplicates.
1916-
fn vars_in_type(ty: t, tvk: ty_var_kind) -> [ty_vid] {
1917-
let mut rslt = [];
1918-
walk_ty(ty) {|ty|
1919-
alt get(ty).struct {
1920-
ty_var(v) {
1921-
alt tvk {
1922-
tvk_regular { rslt += [v]; }
1923-
_ { }
1924-
}
1925-
}
1926-
ty_var_integral(v) {
1927-
alt tvk {
1928-
tvk_integral { rslt += [v]; }
1929-
_ { }
1930-
}
1931-
}
1932-
_ { } }
1933-
}
1934-
rslt
1935-
}
1936-
19371917
// Returns the type and mutability of *t.
19381918
//
19391919
// The parameter `expl` indicates if this is an *explicit* dereference. Some
@@ -2229,13 +2209,21 @@ fn is_pred_ty(fty: t) -> bool {
22292209
is_fn_ty(fty) && type_is_bool(ty_fn_ret(fty))
22302210
}
22312211

2232-
fn ty_var_id(typ: t) -> ty_vid {
2212+
fn ty_var_id(typ: t) -> tv_vid {
22332213
alt get(typ).struct {
2234-
ty_var(vid) | ty_var_integral(vid) { ret vid; }
2214+
ty_var(vid) { ret vid; }
22352215
_ { #error("ty_var_id called on non-var ty"); fail; }
22362216
}
22372217
}
22382218

2219+
fn ty_var_integral_id(typ: t) -> tvi_vid {
2220+
alt get(typ).struct {
2221+
ty_var_integral(vid) { ret vid; }
2222+
_ { #error("ty_var_integral_id called on ty other than \
2223+
ty_var_integral");
2224+
fail; }
2225+
}
2226+
}
22392227

22402228
// Type accessors for AST nodes
22412229
fn block_ty(cx: ctxt, b: ast::blk) -> t {
@@ -2311,12 +2299,23 @@ fn method_idx(id: ast::ident, meths: [method]) -> option<uint> {
23112299
ret none;
23122300
}
23132301

2314-
fn occurs_check(tcx: ctxt, sp: span, vid: ty_vid, rt: t) {
2302+
fn occurs_check(tcx: ctxt, sp: span, vid: tv_vid, rt: t) {
2303+
2304+
// Returns a vec of all the type variables occurring in `ty`. It may
2305+
// contain duplicates. (Integral type vars aren't counted.)
2306+
fn vars_in_type(ty: t) -> [tv_vid] {
2307+
let mut rslt = [];
2308+
walk_ty(ty) {|ty|
2309+
alt get(ty).struct { ty_var(v) { rslt += [v]; } _ { } }
2310+
}
2311+
rslt
2312+
}
2313+
23152314
// Fast path
23162315
if !type_needs_infer(rt) { ret; }
23172316

23182317
// Occurs check!
2319-
if vec::contains(vars_in_type(rt, tvk_regular), vid) {
2318+
if vec::contains(vars_in_type(rt), vid) {
23202319
// Maybe this should be span_err -- however, there's an
23212320
// assertion later on that the type doesn't contain
23222321
// variables, so in this case we have to be sure to die.

src/rustc/middle/typeck.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ import pat_util::{pat_is_variant, pat_id_map};
5252
import middle::ty;
5353
import middle::ty::{arg, field, node_type_table, mk_nil,
5454
ty_param_bounds_and_ty, lookup_public_fields};
55-
import middle::ty::{ty_vid, region_vid, vid};
5655
import middle::typeck::infer::methods;
5756
import util::ppaux::{ty_to_str, tys_to_str, region_to_str,
5857
bound_region_to_str, vstore_to_str};

src/rustc/middle/typeck/check.rs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,15 @@ type parameter).
6969
import astconv::{ast_conv, ast_ty_to_ty};
7070
import collect::{methods}; // ccx.to_ty()
7171
import method::{methods}; // methods for method::lookup
72-
import middle::ty::tys_in_fn_ty;
72+
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};
77+
import typeck::infer::{root, to_str};
78+
import typeck::infer::{unify_methods}; // infcx.set()
79+
import typeck::infer::{min_8bit_tys, min_16bit_tys, min_32bit_tys,
80+
min_64bit_tys};
7681

7782
type fn_ctxt =
7883
// var_bindings, locals and next_var_id are shared
@@ -84,7 +89,7 @@ type fn_ctxt =
8489
indirect_ret_ty: option<ty::t>,
8590
purity: ast::purity,
8691
infcx: infer::infer_ctxt,
87-
locals: hashmap<ast::node_id, ty_vid>,
92+
locals: hashmap<ast::node_id, tv_vid>,
8893

8994
mut blocks: [ast::node_id], // stack of blocks in scope, may be empty
9095
in_scope_regions: isr_alist,
@@ -618,22 +623,49 @@ fn are_compatible(fcx: @fn_ctxt, expected: ty::t, actual: ty::t) -> bool {
618623
}
619624
}
620625

621-
// Local variable gathering. We gather up all locals and create variable IDs
622-
// for them before typechecking the function.
623-
type gather_result =
624-
{infcx: infer::infer_ctxt,
625-
locals: hashmap<ast::node_id, ty_vid>,
626-
ty_var_counter: @mut uint};
627-
628626
// AST fragment checking
629-
fn check_lit(ccx: @crate_ctxt, lit: @ast::lit) -> ty::t {
627+
fn check_lit(fcx: @fn_ctxt, lit: @ast::lit) -> ty::t {
628+
let tcx = fcx.ccx.tcx;
629+
630630
alt lit.node {
631-
ast::lit_str(_) { ty::mk_str(ccx.tcx) }
632-
ast::lit_int(_, t) { ty::mk_mach_int(ccx.tcx, t) }
633-
ast::lit_uint(_, t) { ty::mk_mach_uint(ccx.tcx, t) }
634-
ast::lit_float(_, t) { ty::mk_mach_float(ccx.tcx, t) }
635-
ast::lit_nil { ty::mk_nil(ccx.tcx) }
636-
ast::lit_bool(_) { ty::mk_bool(ccx.tcx) }
631+
ast::lit_str(_) { ty::mk_str(tcx) }
632+
ast::lit_int(v, t) {
633+
alt t {
634+
ty_char | ty_i8 | ty_i16 | ty_i32 | ty_i64 {
635+
// If it's a char or has an explicit suffix, give it the
636+
// appropriate integral type.
637+
ty::mk_mach_int(tcx, t)
638+
}
639+
ty_i {
640+
// Otherwise, an unsuffixed integer literal parses to a
641+
// `ty_i`. In that case, it could have any integral type,
642+
// so create an integral type variable for it.
643+
let vid = fcx.infcx.next_ty_var_integral_id();
644+
645+
// We need to sniff at the value `v` provided and figure
646+
// out how big of an int it is; that determines the set of
647+
// possibly types it could take on.
648+
let possible_types = alt v {
649+
0i64 to 127i64 { min_8bit_tys() }
650+
128i64 to 65535i64 { min_16bit_tys() }
651+
65536i64 to 4294967295i64 { min_32bit_tys() }
652+
_ { min_64bit_tys() }
653+
};
654+
655+
// Store the set of possible types
656+
fcx.infcx.set(fcx.infcx.tvib, vid,
657+
root(possible_types));
658+
ty::mk_var_integral(tcx, vid);
659+
660+
// FIXME: remove me when #1425 is finished.
661+
ty::mk_mach_int(tcx, t)
662+
}
663+
}
664+
}
665+
ast::lit_uint(_, t) { ty::mk_mach_uint(tcx, t) }
666+
ast::lit_float(_, t) { ty::mk_mach_float(tcx, t) }
667+
ast::lit_nil { ty::mk_nil(tcx) }
668+
ast::lit_bool(_) { ty::mk_bool(tcx) }
637669
}
638670
}
639671

@@ -1107,7 +1139,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
11071139
}
11081140

11091141
ast::expr_lit(lit) {
1110-
let typ = check_lit(fcx.ccx, lit);
1142+
let typ = check_lit(fcx, lit);
11111143
fcx.write_ty(id, typ);
11121144
}
11131145

@@ -2067,7 +2099,7 @@ fn self_ref(fcx: @fn_ctxt, id: ast::node_id) -> bool {
20672099
ast_util::is_self)
20682100
}
20692101

2070-
fn lookup_local(fcx: @fn_ctxt, sp: span, id: ast::node_id) -> ty_vid {
2102+
fn lookup_local(fcx: @fn_ctxt, sp: span, id: ast::node_id) -> tv_vid {
20712103
alt fcx.locals.find(id) {
20722104
some(x) { x }
20732105
_ {

0 commit comments

Comments
 (0)