Skip to content

Commit 7a253ea

Browse files
committed
Add an intermediate level of type/region variable resolution forcing
And change structurally_resolved_type() to force resolution of non-region variables.
1 parent 047e3c4 commit 7a253ea

File tree

5 files changed

+49
-24
lines changed

5 files changed

+49
-24
lines changed

src/rustc/middle/typeck/check.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ import rscope::{in_binding_rscope, region_scope, type_rscope};
7676
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::{force_level, force_none, force_non_region_vars_only,
80+
force_all};
7981

8082
type fn_ctxt =
8183
// var_bindings, locals and next_var_id are shared
@@ -1040,7 +1042,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
10401042
-> option<O> {
10411043
alt expected {
10421044
some(t) {
1043-
alt infer::resolve_shallow(fcx.infcx, t, false) {
1045+
alt infer::resolve_shallow(fcx.infcx, t, force_none) {
10441046
result::ok(t) { unpack(ty::get(t).struct) }
10451047
_ { none }
10461048
}
@@ -2184,7 +2186,8 @@ fn instantiate_path(fcx: @fn_ctxt,
21842186
// Resolves `typ` by a single level if `typ` is a type variable. If no
21852187
// resolution is possible, then an error is reported.
21862188
fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
2187-
alt infer::resolve_shallow(fcx.infcx, tp, false) {
2189+
alt infer::resolve_shallow(fcx.infcx, tp,
2190+
force_non_region_vars_only) {
21882191
result::ok(t_s) if !ty::type_is_var(t_s) { ret t_s; }
21892192
_ {
21902193
fcx.ccx.tcx.sess.span_fatal
@@ -2357,5 +2360,3 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::native_item) {
23572360
ty_to_str(ccx.tcx, fty)]});
23582361
}
23592362
}
2360-
2361-

src/rustc/middle/typeck/check/regionck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ fn visit_node(id: ast::node_id, span: span, rcx: rcx) -> bool {
115115
// is going to fail anyway, so just stop here and let typeck
116116
// report errors later on in the writeback phase.
117117
let ty0 = fcx.node_ty(id);
118-
let ty = alt infer::resolve_deep(fcx.infcx, ty0, false) {
118+
let ty = alt infer::resolve_deep(fcx.infcx, ty0, force_none) {
119119
result::err(_) { ret true; }
120120
result::ok(ty) { ty }
121121
};

src/rustc/middle/typeck/check/vtable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
168168

169169
fn fixup_ty(fcx: @fn_ctxt, sp: span, ty: ty::t) -> ty::t {
170170
let tcx = fcx.ccx.tcx;
171-
alt infer::resolve_deep(fcx.infcx, ty, true) {
171+
alt infer::resolve_deep(fcx.infcx, ty, force_all) {
172172
result::ok(new_type) { new_type }
173173
result::err(e) {
174174
tcx.sess.span_fatal(

src/rustc/middle/typeck/check/writeback.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export resolve_type_vars_in_expr;
1010
fn resolve_type_vars_in_type(fcx: @fn_ctxt, sp: span, typ: ty::t) ->
1111
option<ty::t> {
1212
if !ty::type_needs_infer(typ) { ret some(typ); }
13-
alt infer::resolve_deep(fcx.infcx, typ, true) {
13+
alt infer::resolve_deep(fcx.infcx, typ, force_all) {
1414
result::ok(new_type) { ret some(new_type); }
1515
result::err(e) {
1616
if !fcx.ccx.tcx.sess.has_errors() {
@@ -131,7 +131,7 @@ fn visit_pat(p: @ast::pat, wbcx: wb_ctxt, v: wb_vt) {
131131
fn visit_local(l: @ast::local, wbcx: wb_ctxt, v: wb_vt) {
132132
if !wbcx.success { ret; }
133133
let var_id = lookup_local(wbcx.fcx, l.span, l.node.id);
134-
alt infer::resolve_deep_var(wbcx.fcx.infcx, var_id, true) {
134+
alt infer::resolve_deep_var(wbcx.fcx.infcx, var_id, force_all) {
135135
result::ok(lty) {
136136
#debug["Type for local %s (id %d) resolved to %s",
137137
pat_to_str(l.node.pat), l.node.id,

src/rustc/middle/typeck/infer.rs

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ export fixup_err, fixup_err_to_str;
176176
export assignment;
177177
export root, to_str;
178178
export int_ty_set_all;
179+
export force_level, force_none, force_non_region_vars_only, force_all;
179180

180181
// Bitvector to represent sets of integral types
181182
enum int_ty_set = uint;
@@ -380,18 +381,19 @@ fn compare_tys(tcx: ty::ctxt, a: ty::t, b: ty::t) -> ures {
380381

381382
// See comment on the type `resolve_state` below
382383
fn resolve_shallow(cx: infer_ctxt, a: ty::t,
383-
force_vars: bool) -> fres<ty::t> {
384+
force_vars: force_level) -> fres<ty::t> {
384385
resolver(cx, false, force_vars).resolve(a)
385386
}
386387

387388
// See comment on the type `resolve_state` below
388389
fn resolve_deep_var(cx: infer_ctxt, vid: tv_vid,
389-
force_vars: bool) -> fres<ty::t> {
390+
force_vars: force_level) -> fres<ty::t> {
390391
resolver(cx, true, force_vars).resolve(ty::mk_var(cx.tcx, vid))
391392
}
392393

393394
// See comment on the type `resolve_state` below
394-
fn resolve_deep(cx: infer_ctxt, a: ty::t, force_vars: bool) -> fres<ty::t> {
395+
fn resolve_deep(cx: infer_ctxt, a: ty::t, force_vars: force_level)
396+
-> fres<ty::t> {
395397
resolver(cx, true, force_vars).resolve(a)
396398
}
397399

@@ -618,7 +620,7 @@ impl methods for infer_ctxt {
618620
}
619621

620622
fn resolve_type_vars_if_possible(typ: ty::t) -> ty::t {
621-
alt infer::resolve_deep(self, typ, false) {
623+
alt infer::resolve_deep(self, typ, force_none) {
622624
result::ok(new_type) { ret new_type; }
623625
result::err(_) { ret typ; }
624626
}
@@ -995,20 +997,34 @@ impl unify_methods for infer_ctxt {
995997
// A <: [B] and B <: int, then shallow resolution on A would yield
996998
// [B]. Deep resolution, on the other hand, would yield [int].
997999
//
998-
// But there is one more knob: the force_vars variable controls the
999-
// behavior in the face of unconstrained variables. If it is true,
1000-
// then unconstrained variables result in an error.
1000+
// But there is one more knob: the `force_level` variable controls
1001+
// the behavior in the face of unconstrained type and region
1002+
// variables.
1003+
1004+
enum force_level {
1005+
// Any unconstrained variables are OK.
1006+
force_none,
1007+
1008+
// Unconstrained region vars are OK; unconstrained ty vars and
1009+
// integral ty vars result in an error.
1010+
force_non_region_vars_only,
1011+
1012+
// Any unconstrained variables result in an error.
1013+
force_all,
1014+
}
1015+
10011016

10021017
type resolve_state = @{
10031018
infcx: infer_ctxt,
10041019
deep: bool,
1005-
force_vars: bool,
1020+
force_vars: force_level,
10061021
mut err: option<fixup_err>,
10071022
mut r_seen: [region_vid],
10081023
mut v_seen: [tv_vid]
10091024
};
10101025

1011-
fn resolver(infcx: infer_ctxt, deep: bool, fvars: bool) -> resolve_state {
1026+
fn resolver(infcx: infer_ctxt, deep: bool, fvars: force_level)
1027+
-> resolve_state {
10121028
@{infcx: infcx,
10131029
deep: deep,
10141030
force_vars: fvars,
@@ -1021,7 +1037,7 @@ impl methods for resolve_state {
10211037
fn resolve(typ: ty::t) -> fres<ty::t> {
10221038
self.err = none;
10231039

1024-
#debug["Resolving %s (deep=%b, force_vars=%b)",
1040+
#debug["Resolving %s (deep=%b, force_vars=%?)",
10251041
ty_to_str(self.infcx.tcx, typ),
10261042
self.deep,
10271043
self.force_vars];
@@ -1034,7 +1050,7 @@ impl methods for resolve_state {
10341050
assert vec::is_empty(self.v_seen) && vec::is_empty(self.r_seen);
10351051
alt self.err {
10361052
none {
1037-
#debug["Resolved to %s (deep=%b, force_vars=%b)",
1053+
#debug["Resolved to %s (deep=%b, force_vars=%?)",
10381054
ty_to_str(self.infcx.tcx, rty),
10391055
self.deep,
10401056
self.force_vars];
@@ -1095,8 +1111,11 @@ impl methods for resolve_state {
10951111
{ ub:_, lb:some(t) } { self.resolve_region(t) }
10961112
{ ub:some(t), lb:_ } { self.resolve_region(t) }
10971113
{ ub:none, lb:none } {
1098-
if self.force_vars {
1114+
alt self.force_vars {
1115+
force_all {
10991116
self.err = some(unresolved_region(rid));
1117+
}
1118+
_ { /* ok */ }
11001119
}
11011120
ty::re_var(rid)
11021121
}
@@ -1127,8 +1146,11 @@ impl methods for resolve_state {
11271146
{ ub:some(t), lb:_ } { self.resolve1(t) }
11281147
{ ub:_, lb:some(t) } { self.resolve1(t) }
11291148
{ ub:none, lb:none } {
1130-
if self.force_vars {
1149+
alt self.force_vars {
1150+
force_non_region_vars_only | force_all {
11311151
self.err = some(unresolved_ty(vid));
1152+
}
1153+
force_none { /* ok */ }
11321154
}
11331155
ty::mk_var(tcx, vid)
11341156
}
@@ -1146,21 +1168,23 @@ impl methods for resolve_state {
11461168
alt single_type_contained_in(self.infcx.tcx, pt) {
11471169
some(t) { t }
11481170
none {
1149-
if self.force_vars {
1171+
alt self.force_vars {
1172+
force_non_region_vars_only | force_all {
11501173
// As a last resort, default to int.
11511174
let ty = ty::mk_int(self.infcx.tcx);
11521175
self.infcx.set(
11531176
self.infcx.tvib, vid,
11541177
root(convert_integral_ty_to_int_ty_set(self.infcx.tcx,
11551178
ty)));
11561179
ty
1157-
} else {
1180+
}
1181+
force_none {
11581182
ty::mk_var_integral(self.infcx.tcx, vid)
1183+
}
11591184
}
11601185
}
11611186
}
11621187
}
1163-
11641188
}
11651189

11661190
// ______________________________________________________________________

0 commit comments

Comments
 (0)