Skip to content

Commit 37894a6

Browse files
committed
---
yaml --- r: 12774 b: refs/heads/master c: b4d1f1b h: refs/heads/master v: v3
1 parent 8cecde3 commit 37894a6

28 files changed

+500
-541
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: c23d6a50d786e926d001423f36dc43fe480acbae
2+
refs/heads/master: b4d1f1b2c11db370a2ef82646a4fdc091699e7b6
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/rustc/driver/driver.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,9 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
188188
bind middle::check_alt::check_crate(ty_cx, crate));
189189
time(time_passes, "typestate checking",
190190
bind middle::tstate::ck::check_crate(ty_cx, crate));
191-
let _root_map = time(
191+
let (_root_map, mutbl_map) = time(
192192
time_passes, "borrow checking",
193193
bind middle::borrowck::check_crate(ty_cx, method_map, crate));
194-
let mutbl_map =
195-
time(time_passes, "mutability checking",
196-
bind middle::mutbl::check_crate(ty_cx, crate));
197194
time(time_passes, "region checking",
198195
bind middle::regionck::check_crate(ty_cx, crate));
199196
let (copy_map, ref_map) =

trunk/src/rustc/middle/alias.rs

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import syntax::{ast, ast_util};
32
import ast::{ident, fn_ident, node_id};
43
import syntax::codemap::span;
@@ -640,11 +639,141 @@ fn pattern_roots(tcx: ty::ctxt, mutbl: option<unsafe_ty>, pat: @ast::pat)
640639
ret set;
641640
}
642641

643-
// Wraps the expr_root in mutbl.rs to also handle roots that exist through
644-
// return-by-reference
642+
enum deref_t { unbox(bool), field, index, }
643+
644+
type deref = @{mutbl: bool, kind: deref_t, outer_t: ty::t};
645+
645646
fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
646647
-> {ex: @ast::expr, mutbl: option<unsafe_ty>} {
647-
let base_root = mutbl::expr_root_(cx.tcx, none, ex, autoderef);
648+
649+
fn maybe_auto_unbox(tcx: ty::ctxt, t: ty::t) -> {t: ty::t, ds: [deref]} {
650+
let mut ds = [], t = t;
651+
loop {
652+
alt ty::get(t).struct {
653+
ty::ty_box(mt) | ty::ty_uniq(mt) | ty::ty_rptr(_, mt) {
654+
ds += [@{mutbl: mt.mutbl == ast::m_mutbl,
655+
kind: unbox(false),
656+
outer_t: t}];
657+
t = mt.ty;
658+
}
659+
ty::ty_res(_, inner, substs) {
660+
ds += [@{mutbl: false, kind: unbox(false), outer_t: t}];
661+
t = ty::subst(tcx, substs, inner);
662+
}
663+
ty::ty_enum(did, substs) {
664+
let variants = ty::enum_variants(tcx, did);
665+
if vec::len(*variants) != 1u ||
666+
vec::len(variants[0].args) != 1u {
667+
break;
668+
}
669+
ds += [@{mutbl: false, kind: unbox(false), outer_t: t}];
670+
t = ty::subst(tcx, substs, variants[0].args[0]);
671+
}
672+
_ { break; }
673+
}
674+
}
675+
ret {t: t, ds: ds};
676+
}
677+
678+
fn expr_root_(tcx: ty::ctxt, ctor_self: option<node_id>,
679+
ex: @ast::expr, autoderef: bool) -> {ex: @ast::expr,
680+
ds: @[deref]} {
681+
let mut ds: [deref] = [], ex = ex;
682+
loop {
683+
alt copy ex.node {
684+
ast::expr_field(base, ident, _) {
685+
let auto_unbox =
686+
maybe_auto_unbox(tcx, ty::expr_ty(tcx, base));
687+
let mut is_mutbl = false;
688+
alt ty::get(auto_unbox.t).struct {
689+
ty::ty_rec(fields) {
690+
for fields.each {|fld|
691+
if str::eq(ident, fld.ident) {
692+
is_mutbl = fld.mt.mutbl == ast::m_mutbl;
693+
break;
694+
}
695+
}
696+
}
697+
ty::ty_class(did, _) {
698+
util::common::log_expr(*base);
699+
let in_self = alt ctor_self {
700+
some(selfid) {
701+
alt tcx.def_map.find(base.id) {
702+
some(ast::def_self(slfid)) { slfid == selfid }
703+
_ { false }
704+
}
705+
}
706+
none { false }
707+
};
708+
for ty::lookup_class_fields(tcx, did).each {|fld|
709+
if str::eq(ident, fld.ident) {
710+
is_mutbl = fld.mutability == ast::class_mutable
711+
|| in_self; // all fields can be mutated
712+
// in the ctor
713+
break;
714+
}
715+
}
716+
}
717+
_ {}
718+
}
719+
ds += [@{mutbl:is_mutbl, kind:field, outer_t:auto_unbox.t}];
720+
ds += auto_unbox.ds;
721+
ex = base;
722+
}
723+
ast::expr_index(base, _) {
724+
let auto_unbox =
725+
maybe_auto_unbox(tcx, ty::expr_ty(tcx, base));
726+
alt ty::get(auto_unbox.t).struct {
727+
ty::ty_evec(mt, _) |
728+
ty::ty_vec(mt) {
729+
ds +=
730+
[@{mutbl: mt.mutbl == ast::m_mutbl,
731+
kind: index,
732+
outer_t: auto_unbox.t}];
733+
}
734+
ty::ty_estr(_) |
735+
ty::ty_str {
736+
ds += [@{mutbl:false, kind:index, outer_t:auto_unbox.t}];
737+
}
738+
_ { break; }
739+
}
740+
ds += auto_unbox.ds;
741+
ex = base;
742+
}
743+
ast::expr_unary(op, base) {
744+
if op == ast::deref {
745+
let base_t = ty::expr_ty(tcx, base);
746+
let mut is_mutbl = false, ptr = false;
747+
alt ty::get(base_t).struct {
748+
ty::ty_box(mt) { is_mutbl = mt.mutbl==ast::m_mutbl; }
749+
ty::ty_uniq(mt) { is_mutbl = mt.mutbl==ast::m_mutbl; }
750+
ty::ty_res(_, _, _) { }
751+
ty::ty_enum(_, _) { }
752+
ty::ty_ptr(mt) | ty::ty_rptr(_, mt) {
753+
is_mutbl = mt.mutbl==ast::m_mutbl;
754+
ptr = true;
755+
}
756+
_ {
757+
tcx.sess.span_bug(
758+
base.span,
759+
"ill-typed base expression in deref"); }
760+
}
761+
ds += [@{mutbl: is_mutbl, kind: unbox(ptr && is_mutbl),
762+
outer_t: base_t}];
763+
ex = base;
764+
} else { break; }
765+
}
766+
_ { break; }
767+
}
768+
}
769+
if autoderef {
770+
let auto_unbox = maybe_auto_unbox(tcx, ty::expr_ty(tcx, ex));
771+
ds += auto_unbox.ds;
772+
}
773+
ret {ex: ex, ds: @ds};
774+
}
775+
776+
let base_root = expr_root_(cx.tcx, none, ex, autoderef);
648777
let mut unsafe_ty = none;
649778
for vec::each(*base_root.ds) {|d|
650779
if d.mutbl { unsafe_ty = some(contains(d.outer_t)); break; }

0 commit comments

Comments
 (0)