Skip to content

Commit c1e3c0e

Browse files
committed
---
yaml --- r: 27899 b: refs/heads/try c: 457e78c h: refs/heads/master i: 27897: 096570f 27895: 8dd6062 v: v3
1 parent 40e41e8 commit c1e3c0e

File tree

10 files changed

+200
-71
lines changed

10 files changed

+200
-71
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
5-
refs/heads/try: 2b457c265482fee2ecb44e4c7a98da8b887756db
5+
refs/heads/try: 457e78cd538ed057a2546ced28688cec44dcf264
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df

branches/try/src/libsyntax/print/pprust.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,9 +1522,10 @@ fn print_pat(s: ps, &&pat: @ast::pat) {
15221522
s.ann.post(ann_node);
15231523
}
15241524
1525-
fn print_self_ty(s: ps, self_ty: ast::self_ty_) {
1525+
// Returns whether it printed anything
1526+
fn print_self_ty(s: ps, self_ty: ast::self_ty_) -> bool {
15261527
match self_ty {
1527-
ast::sty_static | ast::sty_by_ref => {}
1528+
ast::sty_static | ast::sty_by_ref => { return false; }
15281529
ast::sty_value => { word(s.s, ~"self"); }
15291530
ast::sty_region(m) => {
15301531
word(s.s, ~"&"); print_mutability(s, m); word(s.s, ~"self");
@@ -1536,6 +1537,7 @@ fn print_self_ty(s: ps, self_ty: ast::self_ty_) {
15361537
word(s.s, ~"~"); print_mutability(s, m); word(s.s, ~"self");
15371538
}
15381539
}
1540+
return true;
15391541
}
15401542

15411543
fn print_fn(s: ps, decl: ast::fn_decl, name: ast::ident,
@@ -1556,8 +1558,7 @@ fn print_fn_args(s: ps, decl: ast::fn_decl,
15561558
box(s, 0u, inconsistent);
15571559
let mut first = true;
15581560
for opt_self_ty.each |self_ty| {
1559-
first = false;
1560-
print_self_ty(s, self_ty);
1561+
first = !print_self_ty(s, self_ty);
15611562
}
15621563

15631564
for decl.inputs.each |arg| {
@@ -1780,8 +1781,7 @@ fn print_ty_fn(s: ps, opt_proto: option<ast::proto>,
17801781
box(s, 0u, inconsistent);
17811782
let mut first = true;
17821783
for opt_self_ty.each |self_ty| {
1783-
first = false;
1784-
print_self_ty(s, self_ty);
1784+
first = !print_self_ty(s, self_ty);
17851785
}
17861786
for decl.inputs.each |arg| {
17871787
if first { first = false; } else { word_space(s, ~","); }

branches/try/src/rustc/middle/astencode.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,9 @@ trait read_method_map_entry_helper {
412412
impl ebml::ebml_deserializer: read_method_map_entry_helper {
413413
fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry {
414414
let mme = deserialize_method_map_entry(self);
415-
{derefs: mme.derefs, origin: mme.origin.tr(xcx)}
415+
{derefs: mme.derefs,
416+
self_mode: mme.self_mode,
417+
origin: mme.origin.tr(xcx)}
416418
}
417419
}
418420

branches/try/src/rustc/middle/kind.rs

Lines changed: 51 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,51 @@ fn check_block(b: blk, cx: ctx, v: visit::vt<ctx>) {
215215

216216
fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
217217
debug!{"kind::check_expr(%s)", expr_to_str(e)};
218+
219+
// Handle any kind bounds on type parameters
220+
do option::iter(cx.tcx.node_type_substs.find(e.id)) |ts| {
221+
let bounds = match check e.node {
222+
expr_path(_) => {
223+
let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id));
224+
ty::lookup_item_type(cx.tcx, did).bounds
225+
}
226+
_ => {
227+
// Type substitions should only occur on paths and
228+
// method calls, so this needs to be a method call.
229+
match cx.method_map.get(e.id).origin {
230+
typeck::method_static(did) => {
231+
// n.b.: When we encode class/impl methods, the bounds
232+
// that we encode include both the class/impl bounds
233+
// and then the method bounds themselves...
234+
ty::lookup_item_type(cx.tcx, did).bounds
235+
}
236+
typeck::method_param({trait_id:trt_id,
237+
method_num:n_mth, _}) |
238+
typeck::method_trait(trt_id, n_mth) => {
239+
// ...trait methods bounds, in contrast, include only the
240+
// method bounds, so we must preprend the tps from the
241+
// trait itself. This ought to be harmonized.
242+
let trt_bounds =
243+
ty::lookup_item_type(cx.tcx, trt_id).bounds;
244+
let mth = ty::trait_methods(cx.tcx, trt_id)[n_mth];
245+
@(vec::append(*trt_bounds, *mth.tps))
246+
}
247+
}
248+
}
249+
};
250+
if vec::len(ts) != vec::len(*bounds) {
251+
// Fail earlier to make debugging easier
252+
fail fmt!("Internal error: in kind::check_expr, length \
253+
mismatch between actual and declared bounds: actual = \
254+
%s (%u tys), declared = %? (%u tys)",
255+
tys_to_str(cx.tcx, ts), ts.len(),
256+
*bounds, (*bounds).len());
257+
}
258+
do vec::iter2(ts, *bounds) |ty, bound| {
259+
check_bounds(cx, e.id, e.span, ty, bound)
260+
}
261+
}
262+
218263
match e.node {
219264
expr_assign(_, ex) |
220265
expr_unary(box(_), ex) | expr_unary(uniq(_), ex) |
@@ -266,45 +311,12 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
266311
i += 1u;
267312
}
268313
}
269-
expr_path(_) | expr_field(_, _, _) => {
270-
do option::iter(cx.tcx.node_type_substs.find(e.id)) |ts| {
271-
let bounds = match check e.node {
272-
expr_path(_) => {
273-
let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id));
274-
ty::lookup_item_type(cx.tcx, did).bounds
275-
}
276-
expr_field(base, _, _) => {
277-
match cx.method_map.get(e.id).origin {
278-
typeck::method_static(did) => {
279-
// n.b.: When we encode class/impl methods, the bounds
280-
// that we encode include both the class/impl bounds
281-
// and then the method bounds themselves...
282-
ty::lookup_item_type(cx.tcx, did).bounds
283-
}
284-
typeck::method_param({trait_id:trt_id,
285-
method_num:n_mth, _}) |
286-
typeck::method_trait(trt_id, n_mth) => {
287-
// ...trait methods bounds, in contrast, include only the
288-
// method bounds, so we must preprend the tps from the
289-
// trait itself. This ought to be harmonized.
290-
let trt_bounds =
291-
ty::lookup_item_type(cx.tcx, trt_id).bounds;
292-
let mth = ty::trait_methods(cx.tcx, trt_id)[n_mth];
293-
@(vec::append(*trt_bounds, *mth.tps))
294-
}
295-
}
296-
}
297-
};
298-
if vec::len(ts) != vec::len(*bounds) {
299-
// Fail earlier to make debugging easier
300-
fail fmt!{"Internal error: in kind::check_expr, length \
301-
mismatch between actual and declared bounds: actual = \
302-
%s (%u tys), declared = %? (%u tys)",
303-
tys_to_str(cx.tcx, ts), ts.len(), *bounds, (*bounds).len()};
304-
}
305-
do vec::iter2(ts, *bounds) |ty, bound| {
306-
check_bounds(cx, e.id, e.span, ty, bound)
307-
}
314+
expr_field(lhs, _, _) => {
315+
// If this is a method call with a by-val argument, we need
316+
// to check the copy
317+
match cx.method_map.find(e.id) {
318+
some({self_mode: by_copy, _}) => maybe_copy(cx, lhs),
319+
_ => ()
308320
}
309321
}
310322
expr_repeat(element, count_expr, _) => {

branches/try/src/rustc/middle/trans/base.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,7 @@ type lval_result = {bcx: block, val: ValueRef, kind: lval_kind};
19841984
enum callee_env {
19851985
null_env,
19861986
is_closure,
1987-
self_env(ValueRef, ty::t, option<ValueRef>),
1987+
self_env(ValueRef, ty::t, option<ValueRef>, ast::rmode),
19881988
}
19891989
type lval_maybe_callee = {bcx: block,
19901990
val: ValueRef,
@@ -2447,7 +2447,9 @@ fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef {
24472447
}
24482448
}
24492449

2450-
fn cast_self(cx: block, slf: val_self_pair) -> ValueRef {
2450+
// This shouldn't exist. We should cast self *once*, but right now this
2451+
// conflicts with default methods.
2452+
fn cast_self(cx: block, slf: val_self_data) -> ValueRef {
24512453
PointerCast(cx, slf.v, T_ptr(type_of(cx.ccx(), slf.t)))
24522454
}
24532455

@@ -3201,7 +3203,7 @@ fn trans_call_inner(
32013203
null_env => {
32023204
llvm::LLVMGetUndef(T_opaque_box_ptr(ccx))
32033205
}
3204-
self_env(e, _, _) => {
3206+
self_env(e, _, _, _) => {
32053207
PointerCast(bcx, e, T_opaque_box_ptr(ccx))
32063208
}
32073209
is_closure => {
@@ -3225,6 +3227,13 @@ fn trans_call_inner(
32253227

32263228
let llretslot = args_res.retslot;
32273229

3230+
// Now that the arguments have finished evaluating, we need to revoke
3231+
// the cleanup for the self argument, if it exists
3232+
match f_res.env {
3233+
self_env(e, _, _, ast::by_copy) => revoke_clean(bcx, e),
3234+
_ => (),
3235+
}
3236+
32283237
/* If the block is terminated,
32293238
then one or more of the args has
32303239
type _|_. Since that means it diverges, the code
@@ -4635,7 +4644,10 @@ fn create_llargs_for_fn_args(cx: fn_ctxt,
46354644
let mut arg_n = first_real_arg;
46364645
match ty_self {
46374646
impl_self(tt) => {
4638-
cx.llself = some({v: cx.llenv, t: tt});
4647+
cx.llself = some({v: cx.llenv, t: tt, is_owned: false});
4648+
}
4649+
impl_owned_self(tt) => {
4650+
cx.llself = some({v: cx.llenv, t: tt, is_owned: true});
46394651
}
46404652
no_self => ()
46414653
}
@@ -4662,6 +4674,21 @@ fn copy_args_to_allocas(fcx: fn_ctxt, bcx: block, args: ~[ast::arg],
46624674
tcx.sess.bug(~"someone forgot\
46634675
to document an invariant in copy_args_to_allocas!");
46644676
};
4677+
4678+
match fcx.llself {
4679+
some(copy slf) => {
4680+
// We really should do this regardless of whether self is owned,
4681+
// but it doesn't work right with default method impls yet.
4682+
if slf.is_owned {
4683+
let self_val = PointerCast(bcx, slf.v,
4684+
T_ptr(type_of(bcx.ccx(), slf.t)));
4685+
fcx.llself = some({v: self_val with slf});
4686+
add_clean(bcx, self_val, slf.t);
4687+
}
4688+
}
4689+
_ => {}
4690+
}
4691+
46654692
for vec::each(arg_tys) |arg| {
46664693
let id = args[arg_n].id;
46674694
let argval = match fcx.llargs.get(id) {
@@ -4705,7 +4732,7 @@ fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) {
47054732
Br(raw_block(fcx, false, fcx.llloadenv), lltop);
47064733
}
47074734

4708-
enum self_arg { impl_self(ty::t), no_self, }
4735+
enum self_arg { impl_self(ty::t), impl_owned_self(ty::t), no_self, }
47094736

47104737
// trans_closure: Builds an LLVM function out of a source function.
47114738
// If the function closes over its environment a closure will be
@@ -4897,7 +4924,7 @@ fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
48974924
}
48984925

48994926
// note we don't want to take *or* drop self.
4900-
fcx.llself = some({v: selfptr, t: rslt_ty});
4927+
fcx.llself = some({v: selfptr, t: rslt_ty, is_owned: false});
49014928

49024929
// Translate the body of the ctor
49034930
bcx = trans_block(bcx_top, body, ignore);

branches/try/src/rustc/middle/trans/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ type crate_ctxt = {
141141
mut do_not_commit_warning_issued: bool};
142142

143143
// Types used for llself.
144-
type val_self_pair = {v: ValueRef, t: ty::t};
144+
type val_self_data = {v: ValueRef, t: ty::t, is_owned: bool};
145145

146146
enum local_val { local_mem(ValueRef), local_imm(ValueRef), }
147147

@@ -177,7 +177,7 @@ type fn_ctxt = @{
177177
mut llreturn: BasicBlockRef,
178178
// The 'self' value currently in use in this function, if there
179179
// is one.
180-
mut llself: option<val_self_pair>,
180+
mut llself: option<val_self_data>,
181181
// The a value alloca'd for calls to upcalls.rust_personality. Used when
182182
// outputting the resume instruction.
183183
mut personality: option<ValueRef>,

branches/try/src/rustc/middle/trans/impl.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
3535
ast::sty_uniq(_) => {
3636
impl_self(ty::mk_imm_uniq(ccx.tcx, self_ty))
3737
}
38-
// XXX: Is this right at all?
3938
ast::sty_region(*) => {
4039
impl_self(ty::mk_imm_ptr(ccx.tcx, self_ty))
4140
}
4241
ast::sty_value => {
43-
ccx.sess.unimpl(~"by value self type not implemented");
42+
impl_owned_self(self_ty)
4443
}
4544
ast::sty_by_ref => { impl_self(self_ty) }
4645
};
@@ -54,18 +53,22 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
5453
}
5554
}
5655

57-
fn trans_self_arg(bcx: block, base: @ast::expr, derefs: uint) -> result {
56+
fn trans_self_arg(bcx: block, base: @ast::expr,
57+
mentry: typeck::method_map_entry) -> result {
5858
let _icx = bcx.insn_ctxt("impl::trans_self_arg");
5959
let basety = expr_ty(bcx, base);
60-
let m_by_ref = ast::expl(ast::by_ref);
60+
let mode = ast::expl(mentry.self_mode);
6161
let mut temp_cleanups = ~[];
62-
let result = trans_arg_expr(bcx, {mode: m_by_ref, ty: basety},
62+
let result = trans_arg_expr(bcx, {mode: mode, ty: basety},
6363
T_ptr(type_of::type_of(bcx.ccx(), basety)),
64-
base, temp_cleanups, none, derefs);
64+
base, temp_cleanups, none, mentry.derefs);
6565

6666
// by-ref self argument should not require cleanup in the case of
6767
// other arguments failing:
68-
assert temp_cleanups == ~[];
68+
//assert temp_cleanups == ~[];
69+
//do vec::iter(temp_cleanups) |c| {
70+
// revoke_clean(bcx, c)
71+
//}
6972

7073
return result;
7174
}
@@ -76,16 +79,19 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
7679
let _icx = bcx.insn_ctxt("impl::trans_method_callee");
7780
match mentry.origin {
7881
typeck::method_static(did) => {
79-
let {bcx, val} = trans_self_arg(bcx, self, mentry.derefs);
80-
{env: self_env(val, node_id_type(bcx, self.id), none)
82+
83+
84+
let {bcx, val} = trans_self_arg(bcx, self, mentry);
85+
{env: self_env(val, node_id_type(bcx, self.id), none,
86+
mentry.self_mode)
8187
with lval_static_fn(bcx, did, callee_id)}
8288
}
8389
typeck::method_param({trait_id:trait_id, method_num:off,
8490
param_num:p, bound_num:b}) => {
8591
match check bcx.fcx.param_substs {
8692
some(substs) => {
8793
let vtbl = find_vtable_in_fn_ctxt(substs, p, b);
88-
trans_monomorphized_callee(bcx, callee_id, self, mentry.derefs,
94+
trans_monomorphized_callee(bcx, callee_id, self, mentry,
8995
trait_id, off, vtbl)
9096
}
9197
}
@@ -184,7 +190,8 @@ fn method_ty_param_count(ccx: @crate_ctxt, m_id: ast::def_id,
184190
}
185191

186192
fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
187-
base: @ast::expr, derefs: uint,
193+
base: @ast::expr,
194+
mentry: typeck::method_map_entry,
188195
trait_id: ast::def_id, n_method: uint,
189196
vtbl: typeck::vtable_origin)
190197
-> lval_maybe_callee {
@@ -200,10 +207,11 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
200207
= vec::append(impl_substs,
201208
vec::tailn(node_substs,
202209
node_substs.len() - n_m_tps));
203-
let {bcx, val} = trans_self_arg(bcx, base, derefs);
210+
let {bcx, val} = trans_self_arg(bcx, base, mentry);
204211
let lval = lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
205212
some(sub_origins));
206-
{env: self_env(val, node_id_type(bcx, base.id), none),
213+
{env: self_env(val, node_id_type(bcx, base.id),
214+
none, mentry.self_mode),
207215
val: PointerCast(bcx, lval.val, T_ptr(type_of_fn_from_ty(
208216
ccx, node_id_type(bcx, callee_id))))
209217
with lval}
@@ -230,7 +238,9 @@ fn trans_trait_callee(bcx: block, val: ValueRef,
230238
let llbox = Load(bcx, GEPi(bcx, val, ~[0u, 1u]));
231239
// FIXME[impl] I doubt this is alignment-safe (#2534)
232240
let self = GEPi(bcx, llbox, ~[0u, abi::box_field_body]);
233-
let env = self_env(self, ty::mk_opaque_box(bcx.tcx()), some(llbox));
241+
let env = self_env(self, ty::mk_opaque_box(bcx.tcx()), some(llbox),
242+
// XXX: is this bogosity?
243+
ast::by_ref);
234244
let llfty = type_of::type_of_fn_from_ty(ccx, callee_ty);
235245
let vtable = PointerCast(bcx, vtable,
236246
T_ptr(T_array(T_ptr(llfty), n_method + 1u)));

branches/try/src/rustc/middle/typeck.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ type method_map_entry = {
113113
// number of derefs that are required on the receiver
114114
derefs: uint,
115115

116+
// the mode by which the self parameter needs to be passed
117+
self_mode: ast::rmode,
118+
116119
// method details being invoked
117120
origin: method_origin
118121
};

0 commit comments

Comments
 (0)