Skip to content

Commit e640a66

Browse files
committed
Make most forms of explicit self work. By-value not implemented. Work on #2585.
1 parent 4c16ff5 commit e640a66

File tree

9 files changed

+86
-83
lines changed

9 files changed

+86
-83
lines changed

src/libsyntax/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ enum self_ty_ {
600600
sty_static, // no self: static method
601601
sty_by_ref, // old by-reference self: ``
602602
sty_value, // by-value self: `self`
603-
sty_region(@region, mutability), // by-region self: `&self`
603+
sty_region(mutability), // by-region self: `&self`
604604
sty_box(mutability), // by-managed-pointer self: `@self`
605605
sty_uniq(mutability) // by-unique-pointer self: `~self`
606606
}

src/libsyntax/parse/parser.rs

+1-23
Original file line numberDiff line numberDiff line change
@@ -2300,29 +2300,7 @@ class parser {
23002300
self.bump();
23012301
let mutability = self.parse_mutability();
23022302
self.expect_self_ident();
2303-
2304-
// Parse an explicit region, if possible.
2305-
let region_name;
2306-
match copy self.token {
2307-
token::BINOP(token::SLASH) => {
2308-
self.bump();
2309-
match copy self.token {
2310-
token::IDENT(sid, false) => {
2311-
self.bump();
2312-
region_name = some(self.get_str(sid));
2313-
}
2314-
_ => {
2315-
region_name = none;
2316-
}
2317-
}
2318-
}
2319-
_ => {
2320-
region_name = none;
2321-
}
2322-
}
2323-
2324-
let region = self.region_from_name(region_name);
2325-
self_ty = sty_region(region, mutability);
2303+
self_ty = sty_region(mutability);
23262304
} else {
23272305
self_ty = sty_by_ref;
23282306
}

src/rustc/metadata/decoder.rs

+1-16
Original file line numberDiff line numberDiff line change
@@ -598,22 +598,7 @@ fn get_self_ty(item: ebml::doc) -> ast::self_ty_ {
598598
'v' => { return ast::sty_value; }
599599
'@' => { return ast::sty_box(get_mutability(string[1])); }
600600
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
601-
'&' => {
602-
let mutability = get_mutability(string[1]);
603-
604-
let region;
605-
let region_doc =
606-
ebml::get_doc(self_type_doc,
607-
tag_item_trait_method_self_ty_region);
608-
let region_string = str::from_bytes(ebml::doc_data(region_doc));
609-
if region_string == ~"" {
610-
region = ast::re_anon;
611-
} else {
612-
region = ast::re_named(@region_string);
613-
}
614-
615-
return ast::sty_region(@{ id: 0, node: region }, mutability);
616-
}
601+
'&' => { return ast::sty_region(get_mutability(string[1])); }
617602
_ => {
618603
fail fmt!{"unknown self type code: `%c`", self_ty_kind as char};
619604
}

src/rustc/metadata/encoder.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ fn encode_self_type(ebml_w: ebml::writer, self_type: ast::self_ty_) {
500500
sty_static => { ch = 's' as u8; }
501501
sty_by_ref => { ch = 'r' as u8; }
502502
sty_value => { ch = 'v' as u8; }
503-
sty_region(_, _) => { ch = '&' as u8; }
503+
sty_region(_) => { ch = '&' as u8; }
504504
sty_box(_) => { ch = '@' as u8; }
505505
sty_uniq(_) => { ch = '~' as u8; }
506506
}
@@ -509,27 +509,17 @@ fn encode_self_type(ebml_w: ebml::writer, self_type: ast::self_ty_) {
509509
// Encode mutability.
510510
match self_type {
511511
sty_static | sty_by_ref | sty_value => { /* No-op. */ }
512-
sty_region(_, m_imm) | sty_box(m_imm) | sty_uniq(m_imm) => {
512+
sty_region(m_imm) | sty_box(m_imm) | sty_uniq(m_imm) => {
513513
ebml_w.writer.write(&[ 'i' as u8 ]);
514514
}
515-
sty_region(_, m_mutbl) | sty_box(m_mutbl) | sty_uniq(m_mutbl) => {
515+
sty_region(m_mutbl) | sty_box(m_mutbl) | sty_uniq(m_mutbl) => {
516516
ebml_w.writer.write(&[ 'm' as u8 ]);
517517
}
518-
sty_region(_, m_const) | sty_box(m_const) | sty_uniq(m_const) => {
518+
sty_region(m_const) | sty_box(m_const) | sty_uniq(m_const) => {
519519
ebml_w.writer.write(&[ 'c' as u8 ]);
520520
}
521521
}
522522

523-
// Encode the region.
524-
match self_type {
525-
sty_region(region, _) => {
526-
encode_region(ebml_w, *region);
527-
}
528-
sty_static | sty_by_ref | sty_value | sty_box(*) | sty_uniq(*) => {
529-
// Nothing to do.
530-
}
531-
}
532-
533523
ebml_w.end_tag();
534524
}
535525

src/rustc/middle/trans/impl.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,23 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
2626
for vec::each(methods) |m| {
2727
if m.tps.len() == 0u {
2828
let llfn = get_item_val(ccx, m.id);
29+
let self_ty = ty::node_id_to_type(ccx.tcx, m.self_id);
2930
let self_arg = match m.self_ty.node {
3031
ast::sty_static => { no_self }
31-
_ => { impl_self(ty::node_id_to_type(ccx.tcx, m.self_id)) }
32+
ast::sty_box(_) => {
33+
impl_self(ty::mk_imm_box(ccx.tcx, self_ty))
34+
}
35+
ast::sty_uniq(_) => {
36+
impl_self(ty::mk_imm_uniq(ccx.tcx, self_ty))
37+
}
38+
// XXX: Is this right at all?
39+
ast::sty_region(*) => {
40+
impl_self(ty::mk_imm_ptr(ccx.tcx, self_ty))
41+
}
42+
ast::sty_value => {
43+
ccx.sess.unimpl(~"by value self type not implemented");
44+
}
45+
ast::sty_by_ref => { impl_self(self_ty) }
3246
};
3347

3448
trans_fn(ccx,

src/rustc/middle/typeck/check.rs

+30-10
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import std::map::str_hash;
8080
type self_info = {
8181
self_ty: ty::t,
8282
node_id: ast::node_id,
83+
explicit_self: ast::self_ty_
8384
};
8485

8586
type fn_ctxt_ =
@@ -367,14 +368,20 @@ fn check_fn(ccx: @crate_ctxt,
367368

368369
fn check_method(ccx: @crate_ctxt, method: @ast::method,
369370
self_info: self_info) {
371+
370372
check_bare_fn(ccx, method.decl, method.body, method.id, some(self_info));
371373
}
372374

373-
fn check_class_member(ccx: @crate_ctxt, class_t: self_info,
375+
fn check_class_member(ccx: @crate_ctxt, self_ty: ty::t,
376+
node_id: ast::node_id,
374377
cm: @ast::class_member) {
375378
match cm.node {
376379
ast::instance_var(_,t,_,_,_) => (),
377-
ast::class_method(m) => check_method(ccx, m, class_t)
380+
ast::class_method(m) => {
381+
let class_t = {self_ty: self_ty, node_id: node_id,
382+
explicit_self: m.self_ty.node};
383+
check_method(ccx, m, class_t)
384+
}
378385
}
379386
}
380387

@@ -404,9 +411,11 @@ fn check_no_duplicate_fields(tcx: ty::ctxt, fields:
404411
fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
405412
id: ast::node_id, span: span) {
406413
let tcx = ccx.tcx;
407-
let class_t = {self_ty: ty::node_id_to_type(tcx, id), node_id: id};
414+
let self_ty = ty::node_id_to_type(tcx, id);
408415

409416
do option::iter(struct_def.ctor) |ctor| {
417+
let class_t = {self_ty: self_ty, node_id: id,
418+
explicit_self: ast::sty_by_ref};
410419
// typecheck the ctor
411420
check_bare_fn(ccx, ctor.node.dec,
412421
ctor.node.body, ctor.node.id,
@@ -416,6 +425,8 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
416425
}
417426

418427
do option::iter(struct_def.dtor) |dtor| {
428+
let class_t = {self_ty: self_ty, node_id: id,
429+
explicit_self: ast::sty_by_ref};
419430
// typecheck the dtor
420431
check_bare_fn(ccx, ast_util::dtor_dec(),
421432
dtor.node.body, dtor.node.id,
@@ -426,7 +437,7 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
426437

427438
// typecheck the members
428439
for struct_def.members.each |m| {
429-
check_class_member(ccx, class_t, m);
440+
check_class_member(ccx, self_ty, id, m);
430441
}
431442
// Check that there's at least one field
432443
let (fields,_) = split_class_items(struct_def.members);
@@ -450,9 +461,12 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
450461
let rp = ccx.tcx.region_paramd_items.contains_key(it.id);
451462
debug!{"item_impl %s with id %d rp %b",
452463
*it.ident, it.id, rp};
453-
let self_info = {self_ty: ccx.to_ty(rscope::type_rscope(rp), ty),
454-
node_id: it.id };
455-
for ms.each |m| { check_method(ccx, m, self_info);}
464+
let self_ty = ccx.to_ty(rscope::type_rscope(rp), ty);
465+
for ms.each |m| {
466+
let self_info = {self_ty: self_ty, node_id: it.id,
467+
explicit_self: m.self_ty.node };
468+
check_method(ccx, m, self_info)
469+
}
456470
}
457471
ast::item_trait(_, _, trait_methods) => {
458472
for trait_methods.each |trait_method| {
@@ -463,7 +477,8 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
463477
}
464478
provided(m) => {
465479
let self_info = {self_ty: ty::mk_self(ccx.tcx),
466-
node_id: it.id};
480+
node_id: it.id,
481+
explicit_self: m.self_ty.node};
467482
check_method(ccx, m, self_info);
468483
}
469484
}
@@ -742,7 +757,8 @@ fn check_expr(fcx: @fn_ctxt, expr: @ast::expr,
742757
// declared on the impl declaration e.g., `impl<A,B> for ~[(A,B)]`
743758
// would return ($0, $1) where $0 and $1 are freshly instantiated type
744759
// variables.
745-
fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty {
760+
fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id, require_rp: bool)
761+
-> ty_param_substs_and_ty {
746762
let tcx = fcx.ccx.tcx;
747763

748764
let {n_tps, rp, raw_ty} = if did.crate == ast::local_crate {
@@ -778,6 +794,7 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty {
778794
raw_ty: ity.ty}
779795
};
780796

797+
let rp = rp || require_rp;
781798
let self_r = if rp {some(fcx.infcx.next_region_var_nb())} else {none};
782799
let tps = fcx.infcx.next_ty_vars(n_tps);
783800

@@ -2216,7 +2233,10 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
22162233
ast::def_self(_) => {
22172234
match fcx.self_info {
22182235
some(self_info) => {
2219-
return no_params(self_info.self_ty);
2236+
let self_region = fcx.in_scope_regions.find(ty::br_self);
2237+
return no_params(method::transform_self_type_for_method(
2238+
fcx.tcx(), self_region,
2239+
self_info.self_ty, self_info.explicit_self));
22202240
}
22212241
none => {
22222242
fcx.ccx.tcx.sess.span_bug(sp, ~"def_self with no self_info");

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

+21-16
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,30 @@ type candidate = {
2020
entry: method_map_entry
2121
};
2222

23-
fn transform_self_type_for_method(fcx: @fn_ctxt,
24-
impl_ty: ty::t,
25-
method_info: MethodInfo)
23+
fn transform_self_type_for_method
24+
(tcx: ty::ctxt,
25+
self_region: option<ty::region>,
26+
impl_ty: ty::t,
27+
self_type: ast::self_ty_)
2628
-> ty::t {
27-
match method_info.self_type {
29+
match self_type {
2830
sty_static => {
29-
fcx.tcx().sess.bug(~"calling transform_self_type_for_method on \
30-
static method");
31+
tcx.sess.bug(~"calling transform_self_type_for_method on \
32+
static method");
3133
}
3234
sty_by_ref | sty_value => {
3335
impl_ty
3436
}
35-
sty_region(r, mutability) => {
36-
// XXX: dummy_sp is unfortunate here.
37-
let region = ast_region_to_region(fcx, fcx, dummy_sp(), r);
38-
mk_rptr(fcx.ccx.tcx, region, { ty: impl_ty, mutbl: mutability })
37+
sty_region(mutability) => {
38+
mk_rptr(tcx,
39+
self_region.expect(~"self region missing for &self param"),
40+
{ ty: impl_ty, mutbl: mutability })
3941
}
4042
sty_box(mutability) => {
41-
mk_box(fcx.ccx.tcx, { ty: impl_ty, mutbl: mutability })
43+
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
4244
}
4345
sty_uniq(mutability) => {
44-
mk_uniq(fcx.ccx.tcx, { ty: impl_ty, mutbl: mutability })
46+
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
4547
}
4648
}
4749
}
@@ -368,14 +370,17 @@ class lookup {
368370
// Check whether this impl has a method with the right name.
369371
for im.methods.find(|m| m.ident == self.m_name).each |m| {
370372

373+
let need_rp = match m.self_type { ast::sty_region(_) => true,
374+
_ => false };
375+
371376
// determine the `self` of the impl with fresh
372377
// variables for each parameter:
373378
let {substs: impl_substs, ty: impl_ty} =
374-
impl_self_ty(self.fcx, im.did);
379+
impl_self_ty(self.fcx, im.did, need_rp);
375380

376-
let impl_ty = transform_self_type_for_method(self.fcx,
377-
impl_ty,
378-
*m);
381+
let impl_ty = transform_self_type_for_method(
382+
self.tcx(), impl_substs.self_r,
383+
impl_ty, m.self_type);
379384

380385
// Depending on our argument, we find potential
381386
// matches either by checking subtypability or

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

+12-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ fn replace_bound_regions_in_fn_ty(
2222

2323
let mut all_tys = ty::tys_in_fn_ty(fn_ty);
2424

25+
match self_info {
26+
some({explicit_self: ast::sty_region(m), _}) => {
27+
let region = ty::re_bound(ty::br_self);
28+
let ty = ty::mk_rptr(tcx, region,
29+
{ ty: ty::mk_self(tcx), mutbl: m });
30+
vec::push(all_tys, ty);
31+
}
32+
_ => {}
33+
}
34+
35+
2536
for self_ty.each |t| { vec::push(all_tys, t) }
2637

2738
debug!{"replace_bound_regions_in_fn_ty(self_info.self_ty=%?, fn_ty=%s, \
@@ -50,7 +61,7 @@ fn replace_bound_regions_in_fn_ty(
5061
// Glue updated self_ty back together with its original node_id.
5162
let new_self_info = match self_info {
5263
some(s) => match check t_self {
53-
some(t) => some({self_ty: t, node_id: s.node_id})
64+
some(t) => some({self_ty: t with s})
5465
// this 'none' case shouldn't happen
5566
},
5667
none => none

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ fn lookup_vtable(fcx: @fn_ctxt, sp: span, ty: ty::t, trait_ty: ty::t,
146146
// check whether the type unifies with the type
147147
// that the impl is for, and continue if not
148148
let {substs: substs, ty: for_ty} =
149-
impl_self_ty(fcx, im.did);
149+
impl_self_ty(fcx, im.did, false);
150150
let im_bs = ty::lookup_item_type(tcx, im.did).bounds;
151151
match fcx.mk_subty(ty, for_ty) {
152152
result::err(_) => again,

0 commit comments

Comments
 (0)