Skip to content

Commit 3333b0f

Browse files
committed
Add a (currently unused) "transformed self type" pointer into ty::method
1 parent 0a0525e commit 3333b0f

File tree

7 files changed

+144
-31
lines changed

7 files changed

+144
-31
lines changed

src/librustc/metadata/common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ pub static tag_link_args_arg: uint = 0x7a;
162162

163163
pub static tag_item_method_tps: uint = 0x7b;
164164
pub static tag_item_method_fty: uint = 0x7c;
165+
pub static tag_item_method_transformed_self_ty: uint = 0x7d;
165166

166167
pub struct LinkMeta {
167168
name: @str,

src/librustc/metadata/decoder.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,16 @@ fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy {
236236
|_, did| translate_def_id(cdata, did))
237237
}
238238
239+
fn doc_transformed_self_ty(doc: ebml::Doc,
240+
tcx: ty::ctxt,
241+
cdata: cmd) -> Option<ty::t>
242+
{
243+
do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| {
244+
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
245+
|_, did| translate_def_id(cdata, did))
246+
}
247+
}
248+
239249
pub fn item_type(item_id: ast::def_id, item: ebml::Doc,
240250
tcx: ty::ctxt, cdata: cmd) -> ty::t {
241251
let t = doc_type(item, tcx, cdata);
@@ -716,14 +726,17 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
716726
let method_doc = lookup_item(id, cdata.data);
717727
let def_id = item_def_id(method_doc, cdata);
718728
let name = item_name(intr, method_doc);
719-
let bounds = item_ty_param_bounds(method_doc, tcx, cdata,
720-
tag_item_method_tps);
729+
let bounds =
730+
item_ty_param_bounds(method_doc, tcx, cdata,
731+
tag_item_method_tps);
732+
let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
721733
let fty = doc_method_fty(method_doc, tcx, cdata);
722734
let vis = item_visibility(method_doc);
723735
let self_ty = get_self_ty(method_doc);
724736
ty::method {
725737
ident: name,
726738
tps: bounds,
739+
transformed_self_ty: transformed_self_ty,
727740
fty: fty,
728741
self_ty: self_ty,
729742
vis: vis,
@@ -767,10 +780,12 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
767780
}
768781
};
769782

783+
let transformed_self_ty = doc_transformed_self_ty(mth, tcx, cdata);
770784
let self_ty = get_self_ty(mth);
771785
let ty_method = ty::method {
772786
ident: name,
773787
tps: bounds,
788+
transformed_self_ty: transformed_self_ty,
774789
fty: fty,
775790
self_ty: self_ty,
776791
vis: ast::public,

src/librustc/metadata/encoder.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,17 @@ fn encode_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) {
230230
ebml_w.end_tag();
231231
}
232232

233+
fn encode_transformed_self_ty(ecx: @EncodeContext,
234+
ebml_w: writer::Encoder,
235+
opt_typ: Option<ty::t>)
236+
{
237+
for opt_typ.each |&typ| {
238+
ebml_w.start_tag(tag_item_method_transformed_self_ty);
239+
write_type(ecx, ebml_w, typ);
240+
ebml_w.end_tag();
241+
}
242+
}
243+
233244
fn encode_method_fty(ecx: @EncodeContext,
234245
ebml_w: writer::Encoder,
235246
typ: &ty::BareFnTy)
@@ -570,6 +581,7 @@ fn encode_method_ty_fields(ecx: @EncodeContext,
570581
encode_name(ecx, ebml_w, method_ty.ident);
571582
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
572583
tag_item_method_tps);
584+
encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
573585
encode_method_fty(ecx, ebml_w, &method_ty.fty);
574586
encode_visibility(ebml_w, method_ty.vis);
575587
encode_self_type(ebml_w, method_ty.self_ty);

src/librustc/middle/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub type param_bounds = @~[param_bound];
7171
pub struct method {
7272
ident: ast::ident,
7373
tps: @~[param_bounds],
74+
transformed_self_ty: Option<ty::t>,
7475
fty: BareFnTy,
7576
self_ty: ast::self_ty_,
7677
vis: ast::visibility,

src/librustc/middle/typeck/astconv.rs

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -544,13 +544,50 @@ pub fn bound_lifetimes<AC:AstConv>(
544544
bound_lifetime_names
545545
}
546546

547+
struct SelfInfo {
548+
untransformed_self_ty: ty::t,
549+
self_transform: ast::self_ty
550+
}
551+
552+
pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + Durable>(
553+
self: &AC,
554+
rscope: &RS,
555+
purity: ast::purity,
556+
lifetimes: &OptVec<ast::Lifetime>,
557+
untransformed_self_ty: ty::t,
558+
self_transform: ast::self_ty,
559+
decl: &ast::fn_decl) -> (Option<ty::t>, ty::BareFnTy)
560+
{
561+
let self_info = SelfInfo {
562+
untransformed_self_ty: untransformed_self_ty,
563+
self_transform: self_transform
564+
};
565+
let (a, b) = ty_of_method_or_bare_fn(
566+
self, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
567+
(a.get(), b)
568+
}
569+
547570
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
548571
self: &AC,
549572
rscope: &RS,
550573
purity: ast::purity,
551574
abi: AbiSet,
552575
lifetimes: &OptVec<ast::Lifetime>,
553576
decl: &ast::fn_decl) -> ty::BareFnTy
577+
{
578+
let (_, b) = ty_of_method_or_bare_fn(
579+
self, rscope, purity, abi, lifetimes, None, decl);
580+
b
581+
}
582+
583+
fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
584+
self: &AC,
585+
rscope: &RS,
586+
purity: ast::purity,
587+
abi: AbiSet,
588+
lifetimes: &OptVec<ast::Lifetime>,
589+
opt_self_info: Option<&SelfInfo>,
590+
decl: &ast::fn_decl) -> (Option<Option<ty::t>>, ty::BareFnTy)
554591
{
555592
debug!("ty_of_bare_fn");
556593

@@ -559,18 +596,56 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
559596
let bound_lifetime_names = bound_lifetimes(self, lifetimes);
560597
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
561598

599+
let opt_transformed_self_ty = opt_self_info.map(|&self_info| {
600+
transform_self_ty(self, &rb, self_info)
601+
});
602+
562603
let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
604+
563605
let output_ty = match decl.output.node {
564606
ast::ty_infer => self.ty_infer(decl.output.span),
565607
_ => ast_ty_to_ty(self, &rb, decl.output)
566608
};
567609

568-
ty::BareFnTy {
569-
purity: purity,
570-
abis: abi,
571-
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
572-
inputs: input_tys,
573-
output: output_ty}
610+
return (opt_transformed_self_ty,
611+
ty::BareFnTy {
612+
purity: purity,
613+
abis: abi,
614+
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
615+
inputs: input_tys,
616+
output: output_ty}
617+
});
618+
619+
fn transform_self_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
620+
self: &AC,
621+
rscope: &RS,
622+
self_info: &SelfInfo) -> Option<ty::t>
623+
{
624+
match self_info.self_transform.node {
625+
ast::sty_static => None,
626+
ast::sty_value => {
627+
Some(self_info.untransformed_self_ty)
628+
}
629+
ast::sty_region(lifetime, mutability) => {
630+
let region =
631+
ast_region_to_region(self, rscope,
632+
self_info.self_transform.span,
633+
lifetime);
634+
Some(ty::mk_rptr(self.tcx(), region,
635+
ty::mt {ty: self_info.untransformed_self_ty,
636+
mutbl: mutability}))
637+
}
638+
ast::sty_box(mutability) => {
639+
Some(ty::mk_box(self.tcx(),
640+
ty::mt {ty: self_info.untransformed_self_ty,
641+
mutbl: mutability}))
642+
}
643+
ast::sty_uniq(mutability) => {
644+
Some(ty::mk_uniq(self.tcx(),
645+
ty::mt {ty: self_info.untransformed_self_ty,
646+
mutbl: mutability}))
647+
}
648+
}
574649
}
575650
}
576651

src/librustc/middle/typeck/collect.rs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,17 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
237237
for ms.each |m| {
238238
let ty_method = @match m {
239239
&ast::required(ref m) => {
240-
ty_method_of_trait_method(ccx, region_paramd, generics,
241-
&m.id, &m.ident, &m.self_ty,
242-
&m.generics, &m.purity, &m.decl)
240+
ty_method_of_trait_method(
241+
ccx, trait_id, region_paramd, generics,
242+
&m.id, &m.ident, &m.self_ty,
243+
&m.generics, &m.purity, &m.decl)
243244
}
244245

245246
&ast::provided(ref m) => {
246-
ty_method_of_trait_method(ccx, region_paramd, generics,
247-
&m.id, &m.ident, &m.self_ty,
248-
&m.generics, &m.purity, &m.decl)
247+
ty_method_of_trait_method(
248+
ccx, trait_id, region_paramd, generics,
249+
&m.id, &m.ident, &m.self_ty,
250+
&m.generics, &m.purity, &m.decl)
249251
}
250252
};
251253

@@ -316,6 +318,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
316318
}
317319

318320
fn ty_method_of_trait_method(self: &CrateCtxt,
321+
trait_id: ast::node_id,
319322
trait_rp: Option<ty::region_variance>,
320323
trait_generics: &ast::Generics,
321324
m_id: &ast::node_id,
@@ -325,16 +328,16 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
325328
m_purity: &ast::purity,
326329
m_decl: &ast::fn_decl) -> ty::method
327330
{
331+
let trait_self_ty = ty::mk_self(self.tcx, local_def(trait_id));
328332
let rscope = MethodRscope::new(m_self_ty.node, trait_rp, trait_generics);
333+
let (transformed_self_ty, fty) =
334+
astconv::ty_of_method(self, &rscope, *m_purity, &m_generics.lifetimes,
335+
trait_self_ty, *m_self_ty, m_decl);
329336
ty::method {
330337
ident: *m_ident,
331338
tps: ty_param_bounds(self, m_generics),
332-
fty: astconv::ty_of_bare_fn(self,
333-
&rscope,
334-
*m_purity,
335-
AbiSet::Rust(),
336-
&m_generics.lifetimes,
337-
m_decl),
339+
transformed_self_ty: transformed_self_ty,
340+
fty: fty,
338341
self_ty: m_self_ty.node,
339342
// assume public, because this is only invoked on trait methods
340343
vis: ast::public,
@@ -607,6 +610,7 @@ pub struct ConvertedMethod {
607610
pub fn convert_methods(ccx: &CrateCtxt,
608611
ms: &[@ast::method],
609612
rp: Option<ty::region_variance>,
613+
untransformed_rcvr_ty: ty::t,
610614
rcvr_bounds: @~[ty::param_bounds],
611615
rcvr_generics: &ast::Generics,
612616
rcvr_visibility: ast::visibility)
@@ -615,8 +619,9 @@ pub fn convert_methods(ccx: &CrateCtxt,
615619
let tcx = ccx.tcx;
616620
return vec::map(ms, |m| {
617621
let bounds = ty_param_bounds(ccx, &m.generics);
618-
let mty = @ty_of_method(ccx, *m, rp, rcvr_generics,
619-
rcvr_visibility, &m.generics);
622+
let mty = @ty_of_method(
623+
ccx, *m, rp, untransformed_rcvr_ty,
624+
rcvr_generics, rcvr_visibility, &m.generics);
620625
let fty = ty::mk_bare_fn(tcx, copy mty.fty);
621626
tcx.tcache.insert(
622627
local_def(m.id),
@@ -637,22 +642,24 @@ pub fn convert_methods(ccx: &CrateCtxt,
637642
fn ty_of_method(ccx: &CrateCtxt,
638643
m: @ast::method,
639644
rp: Option<ty::region_variance>,
645+
untransformed_rcvr_ty: ty::t,
640646
rcvr_generics: &ast::Generics,
641647
rcvr_visibility: ast::visibility,
642648
method_generics: &ast::Generics) -> ty::method
643649
{
644650
let rscope = MethodRscope::new(m.self_ty.node,
645651
rp,
646652
rcvr_generics);
653+
let (transformed_self_ty, fty) =
654+
astconv::ty_of_method(ccx, &rscope, m.purity,
655+
&method_generics.lifetimes,
656+
untransformed_rcvr_ty,
657+
m.self_ty, &m.decl);
647658
ty::method {
648659
ident: m.ident,
649660
tps: ty_param_bounds(ccx, &m.generics),
650-
fty: astconv::ty_of_bare_fn(ccx,
651-
&rscope,
652-
m.purity,
653-
ast::RustAbi,
654-
&method_generics.lifetimes,
655-
&m.decl),
661+
transformed_self_ty: transformed_self_ty,
662+
fty: fty,
656663
self_ty: m.self_ty.node,
657664
vis: m.vis.inherit_from(rcvr_visibility),
658665
def_id: local_def(m.id)
@@ -715,7 +722,7 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
715722
it.vis
716723
};
717724

718-
let cms = convert_methods(ccx, *ms, rp, i_bounds, generics,
725+
let cms = convert_methods(ccx, *ms, rp, selfty, i_bounds, generics,
719726
parent_visibility);
720727
for opt_trait_ref.each |t| {
721728
check_methods_against_trait(ccx, generics, rp, selfty, *t, cms);
@@ -732,7 +739,9 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
732739
let (_, provided_methods) =
733740
split_trait_methods(*trait_methods);
734741
let (bounds, _) = mk_substs(ccx, generics, rp);
735-
let _ = convert_methods(ccx, provided_methods, rp, bounds, generics,
742+
let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
743+
let _ = convert_methods(ccx, provided_methods, rp,
744+
untransformed_rcvr_ty, bounds, generics,
736745
it.vis);
737746
}
738747
ast::item_struct(struct_def, ref generics) => {

src/test/run-pass/regions-expl-self.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct Foo {
1515
}
1616

1717
pub impl Foo {
18-
fn foo(&'a self) {}
18+
fn foo<'a>(&'a self) {}
1919
}
2020

2121
pub fn main() {}

0 commit comments

Comments
 (0)