Skip to content

Commit 782552c

Browse files
committed
---
yaml --- r: 12607 b: refs/heads/master c: 30d5638 h: refs/heads/master i: 12605: d939f00 12603: 7007fca 12599: 26cb576 12591: c05c061 12575: 2d81b91 12543: 9ffd073 v: v3
1 parent 2ef2f62 commit 782552c

File tree

10 files changed

+147
-91
lines changed

10 files changed

+147
-91
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 0d3658bb43455fc1d52662dca17789e689914879
2+
refs/heads/master: 30d563839eb496fcc20c333a3eda2cee16966534
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/etc/indenter

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ my $indent = 0;
66
while (<>) {
77
if (/^rust: ">>/) {
88
$indent += 1;
9-
} elsif (/^rust: "<</) {
10-
$indent -= 1;
119
}
1210

1311
printf "%03d %s%s", $indent, (" " x $indent), $_;
12+
13+
if (/^rust: "<</) {
14+
$indent -= 1;
15+
}
1416
}
1517

trunk/src/rustc/middle/infer.rs

Lines changed: 64 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,19 @@ fn compare_tys(tcx: ty::ctxt, a: ty::t, b: ty::t) -> ures {
9292
mk_eqty(infcx, a, b)
9393
}
9494

95-
// Resolves one level of type structure but not any type variables
96-
// that may be nested within.
97-
fn resolve_shallow(cx: infer_ctxt, a: ty::t) -> fres<ty::t> {
98-
resolver(cx, false, false).resolve(a)
95+
// See comment on the type `resolve_state` below
96+
fn resolve_shallow(cx: infer_ctxt, a: ty::t,
97+
force_vars: bool) -> fres<ty::t> {
98+
resolver(cx, false, force_vars).resolve(a)
9999
}
100100

101-
// see resolve_deep()
101+
// See comment on the type `resolve_state` below
102102
fn resolve_deep_var(cx: infer_ctxt, vid: ty_vid,
103103
force_vars: bool) -> fres<ty::t> {
104104
resolver(cx, true, force_vars).resolve(ty::mk_var(cx.tcx, vid))
105105
}
106106

107-
// Resolves all levels of type structure. If `force_vars` is true,
108-
// then we will resolve unconstrained type/region variables to
109-
// something arbitrary. Otherwise, we preserve them as variables.
107+
// See comment on the type `resolve_state` below
110108
fn resolve_deep(cx: infer_ctxt, a: ty::t, force_vars: bool) -> fres<ty::t> {
111109
resolver(cx, true, force_vars).resolve(a)
112110
}
@@ -556,8 +554,12 @@ impl unify_methods for infer_ctxt {
556554
}
557555

558556
fn eq_regions(a: ty::region, b: ty::region) -> ures {
559-
self.sub_regions(a, b).then {||
560-
self.sub_regions(b, a)
557+
#debug["eq_regions(%s, %s)",
558+
a.to_str(self), b.to_str(self)];
559+
indent {||
560+
self.sub_regions(a, b).then {||
561+
self.sub_regions(b, a)
562+
}
561563
}
562564
}
563565
}
@@ -599,16 +601,20 @@ impl methods for resolve_state {
599601
fn resolve(typ: ty::t) -> fres<ty::t> {
600602
self.err = none;
601603

604+
#debug["Resolving %s (deep=%b, force_vars=%b)",
605+
ty_to_str(self.infcx.tcx, typ),
606+
self.deep,
607+
self.force_vars];
608+
602609
// n.b. This is a hokey mess because the current fold doesn't
603610
// allow us to pass back errors in any useful way.
604611

605612
assert vec::is_empty(self.v_seen) && vec::is_empty(self.r_seen);
606-
let rty = self.resolve1(typ);
613+
let rty = indent {|| self.resolve1(typ) };
607614
assert vec::is_empty(self.v_seen) && vec::is_empty(self.r_seen);
608615
alt self.err {
609616
none {
610-
#debug["Resolved %s to %s (deep=%b, force_vars=%b)",
611-
ty_to_str(self.infcx.tcx, typ),
617+
#debug["Resolved to %s (deep=%b, force_vars=%b)",
612618
ty_to_str(self.infcx.tcx, rty),
613619
self.deep,
614620
self.force_vars];
@@ -619,25 +625,32 @@ impl methods for resolve_state {
619625
}
620626

621627
fn resolve1(typ: ty::t) -> ty::t {
622-
let tb = ty::get(typ);
623-
alt tb.struct {
624-
ty::ty_var(vid) { self.resolve_ty_var(vid) }
625-
_ if !tb.has_regions && !self.deep { typ }
626-
_ {
627-
ty::fold_regions_and_ty(
628-
self.infcx.tcx, typ,
629-
{ |r| self.resolve_region(r) },
630-
{ |t| self.resolve_if_deep(t) },
631-
{ |t| self.resolve_if_deep(t) })
632-
}
633-
}
628+
#debug("Resolve1(%s)", typ.to_str(self.infcx));
629+
indent(fn&() -> ty::t {
630+
if !ty::get(typ).has_vars { ret typ; }
631+
632+
let tb = ty::get(typ);
633+
alt tb.struct {
634+
ty::ty_var(vid) { self.resolve_ty_var(vid) }
635+
_ if !tb.has_regions && !self.deep { typ }
636+
_ {
637+
ty::fold_regions_and_ty(
638+
self.infcx.tcx, typ,
639+
{ |r| self.resolve_region(r) },
640+
{ |t| self.resolve_if_deep(t) },
641+
{ |t| self.resolve_if_deep(t) })
642+
}
643+
}
644+
})
634645
}
635646

636647
fn resolve_if_deep(typ: ty::t) -> ty::t {
648+
#debug("Resolve_if_deep(%s)", typ.to_str(self.infcx));
637649
if !self.deep {typ} else {self.resolve1(typ)}
638650
}
639651

640652
fn resolve_region(orig: ty::region) -> ty::region {
653+
#debug("Resolve_region(%s)", orig.to_str(self.infcx));
641654
alt orig {
642655
ty::re_var(rid) { self.resolve_region_var(rid) }
643656
_ { orig }
@@ -650,16 +663,15 @@ impl methods for resolve_state {
650663
ret ty::re_var(rid);
651664
} else {
652665
vec::push(self.r_seen, rid);
653-
let r = self.resolve_var(
654-
self.infcx.rb,
655-
{|_t| false },
656-
rid,
657-
{||
658-
if self.force_vars {ty::re_static}
659-
else {ty::re_var(rid)}
660-
});
666+
let {root:_, bounds} = self.infcx.get(self.infcx.rb, rid);
667+
let r1 = alt bounds {
668+
{ ub:_, lb:some(t) } { self.resolve_region(t) }
669+
{ ub:some(t), lb:_ } { self.resolve_region(t) }
670+
{ ub:none, lb:none } if self.force_vars { ty::re_static }
671+
{ ub:none, lb:none } { ty::re_var(rid) }
672+
};
661673
vec::pop(self.r_seen);
662-
ret r;
674+
ret r1;
663675
}
664676
}
665677

@@ -670,43 +682,25 @@ impl methods for resolve_state {
670682
} else {
671683
vec::push(self.v_seen, vid);
672684
let tcx = self.infcx.tcx;
673-
let t0 = self.resolve_var(
674-
self.infcx.vb,
675-
{|t| type_is_bot(t) },
676-
vid,
677-
{||
678-
if self.force_vars {ty::mk_bot(tcx)}
679-
else {ty::mk_var(tcx, vid)}
680-
});
681-
let t1 = self.resolve1(t0);
685+
686+
// Nonobvious: prefer the most specific type
687+
// (i.e., the lower bound) to the more general
688+
// one. More general types in Rust (e.g., fn())
689+
// tend to carry more restrictions or higher
690+
// perf. penalties, so it pays to know more.
691+
692+
let {root:_, bounds} = self.infcx.get(self.infcx.vb, vid);
693+
let t1 = alt bounds {
694+
{ ub:_, lb:some(t) } if !type_is_bot(t) { self.resolve1(t) }
695+
{ ub:some(t), lb:_ } { self.resolve1(t) }
696+
{ ub:_, lb:some(t) } { self.resolve1(t) }
697+
{ ub:none, lb:none } if self.force_vars { ty::mk_bot(tcx) }
698+
{ ub:none, lb:none } { ty::mk_var(tcx, vid) }
699+
};
682700
vec::pop(self.v_seen);
683701
ret t1;
684702
}
685703
}
686-
687-
fn resolve_var<V: copy vid, T:copy to_str>(
688-
vb: vals_and_bindings<V, T>, bot_guard: fn(T)->bool,
689-
vid: V, unbound: fn() -> T) -> T {
690-
691-
let {root:_, bounds} = self.infcx.get(vb, vid);
692-
693-
#debug["resolve_var(%s) bounds=%s",
694-
vid.to_str(),
695-
bounds.to_str(self.infcx)];
696-
697-
// Nonobvious: prefer the most specific type
698-
// (i.e., the lower bound) to the more general
699-
// one. More general types in Rust (e.g., fn())
700-
// tend to carry more restrictions or higher
701-
// perf. penalties, so it pays to know more.
702-
703-
alt bounds {
704-
{ ub:_, lb:some(t) } if !bot_guard(t) { t }
705-
{ ub:some(t), lb:_ } { t }
706-
{ ub:_, lb:some(t) } { t }
707-
{ ub:none, lb:none } { unbound() }
708-
}
709-
}
710704
}
711705

712706
// ______________________________________________________________________
@@ -958,8 +952,9 @@ fn super_substs<C:combine>(
958952
ok(none)
959953
}
960954
(some(a), some(b)) {
961-
infcx.eq_regions(a, b);
962-
ok(some(a))
955+
infcx.eq_regions(a, b).then {||
956+
ok(some(a))
957+
}
963958
}
964959
(_, _) {
965960
// If these two substitutions are for the same type (and

trunk/src/rustc/middle/ty.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,26 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
483483
has_vars |= t.has_vars;
484484
has_regions |= t.has_regions;
485485
}
486-
alt st {
487-
ty_estr(vstore_slice(_)) {
486+
fn derive_rflags(&has_vars: bool, &has_regions: bool, r: region) {
488487
has_regions = true;
488+
alt r {
489+
ty::re_var(_) { has_vars = true; }
490+
_ { }
491+
}
492+
}
493+
fn derive_sflags(&has_params: bool, &has_vars: bool, &has_regions: bool,
494+
substs: substs) {
495+
for substs.tps.each {|tt|
496+
derive_flags(has_params, has_vars, has_regions, tt);
497+
}
498+
substs.self_r.iter { |r| derive_rflags(has_vars, has_regions, r) }
499+
}
500+
alt st {
501+
ty_estr(vstore_slice(r)) {
502+
derive_rflags(has_vars, has_regions, r);
489503
}
490-
ty_evec(mt, vstore_slice(_)) {
491-
has_regions = true;
504+
ty_evec(mt, vstore_slice(r)) {
505+
derive_rflags(has_vars, has_regions, r);
492506
derive_flags(has_params, has_vars, has_regions, mt.ty);
493507
}
494508
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
@@ -497,10 +511,7 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
497511
ty_param(_, _) { has_params = true; }
498512
ty_var(_) | ty_self(_) { has_vars = true; }
499513
ty_enum(_, substs) | ty_class(_, substs) {
500-
for substs.tps.each {|tt|
501-
derive_flags(has_params, has_vars, has_regions, tt);
502-
}
503-
substs.self_r.iter { |_i| has_regions = true; }
514+
derive_sflags(has_params, has_vars, has_regions, substs);
504515
}
505516
ty_iface(_, tys) {
506517
for tys.each {|tt|
@@ -511,11 +522,7 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
511522
derive_flags(has_params, has_vars, has_regions, m.ty);
512523
}
513524
ty_rptr(r, m) {
514-
alt r {
515-
ty::re_var(_) { has_vars = true; }
516-
_ { }
517-
}
518-
has_regions = true;
525+
derive_rflags(has_vars, has_regions, r);
519526
derive_flags(has_params, has_vars, has_regions, m.ty);
520527
}
521528
ty_rec(flds) {
@@ -535,9 +542,7 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
535542
}
536543
ty_res(_, tt, substs) {
537544
derive_flags(has_params, has_vars, has_regions, tt);
538-
for substs.tps.each {|tt|
539-
derive_flags(has_params, has_vars, has_regions, tt);
540-
}
545+
derive_sflags(has_params, has_vars, has_regions, substs);
541546
}
542547
ty_constr(tt, _) {
543548
derive_flags(has_params, has_vars, has_regions, tt);
@@ -933,10 +938,11 @@ fn subst(cx: ctxt,
933938
substs: substs,
934939
typ: t) -> t {
935940

936-
if substs_is_noop(substs) { ret typ; }
937941
#debug["subst(substs=%s, typ=%s)",
938942
substs_to_str(cx, substs),
939943
ty_to_str(cx, typ)];
944+
945+
if substs_is_noop(substs) { ret typ; }
940946
let r = do_subst(cx, substs, typ);
941947
#debug[" r = %s", ty_to_str(cx, r)];
942948
ret r;

trunk/src/rustc/middle/typeck.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ fn instantiate_path(fcx: @fn_ctxt,
258258

259259
// Type tests
260260
fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
261-
alt infer::resolve_shallow(fcx.infcx, tp) {
261+
alt infer::resolve_shallow(fcx.infcx, tp, true) {
262262
// note: the bot type doesn't count as resolved; it's what we use when
263263
// there is no information about a variable.
264264
result::ok(t_s) if !ty::type_is_bot(t_s) { ret t_s; }
@@ -1348,7 +1348,7 @@ mod collect {
13481348
constraints: []})
13491349
};
13501350
let tpt = {bounds: ty_param_bounds(ccx, ty_params),
1351-
rp: ast::rp_none,
1351+
rp: rp,
13521352
ty: result_ty};
13531353
tcx.tcache.insert(local_def(variant.node.id), tpt);
13541354
write_ty_to_tcx(tcx, variant.node.id, result_ty);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
enum ast/& {
2+
num(uint),
3+
add(&ast, &ast)
4+
}
5+
6+
fn mk_add_bad1(x: &a.ast, y: &b.ast) -> ast/&a {
7+
add(x, y) //! ERROR mismatched types: expected `&a.ast/&a` but found `&b.ast/&b`
8+
}
9+
10+
fn main() {
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
enum ast/& {
2+
num(uint),
3+
add(&ast, &ast)
4+
}
5+
6+
fn mk_add_bad2(x: &a.ast, y: &a.ast, z: &ast) -> ast {
7+
add(x, y) //! ERROR mismatched types: expected `ast/&` but found `ast/&a`
8+
}
9+
10+
fn main() {
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
enum ast/& {
2+
num(uint),
3+
add(&ast, &ast)
4+
}
5+
6+
fn mk_add_ok(x: &ast, y: &ast) -> ast {
7+
add(x, y)
8+
}
9+
10+
fn main() {
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
enum ast/& {
2+
num(uint),
3+
add(&ast, &ast)
4+
}
5+
6+
fn mk_add_ok(x: &a.ast, y: &a.ast, z: &ast) -> ast/&a {
7+
add(x, y)
8+
}
9+
10+
fn main() {
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
enum roption/& {
2+
a, b(&uint)
3+
}
4+
5+
fn mk(cond: bool, ptr: &uint) -> roption {
6+
if cond {a} else {b(ptr)}
7+
}
8+
9+
fn main() {}

0 commit comments

Comments
 (0)