Add a (currently unused) "transformed self type" pointer into ty::method
This commit is contained in:
parent
0a0525e366
commit
3333b0f117
7 changed files with 144 additions and 31 deletions
|
@ -162,6 +162,7 @@ pub static tag_link_args_arg: uint = 0x7a;
|
||||||
|
|
||||||
pub static tag_item_method_tps: uint = 0x7b;
|
pub static tag_item_method_tps: uint = 0x7b;
|
||||||
pub static tag_item_method_fty: uint = 0x7c;
|
pub static tag_item_method_fty: uint = 0x7c;
|
||||||
|
pub static tag_item_method_transformed_self_ty: uint = 0x7d;
|
||||||
|
|
||||||
pub struct LinkMeta {
|
pub struct LinkMeta {
|
||||||
name: @str,
|
name: @str,
|
||||||
|
|
|
@ -236,6 +236,16 @@ fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy {
|
||||||
|_, did| translate_def_id(cdata, did))
|
|_, did| translate_def_id(cdata, did))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn doc_transformed_self_ty(doc: ebml::Doc,
|
||||||
|
tcx: ty::ctxt,
|
||||||
|
cdata: cmd) -> Option<ty::t>
|
||||||
|
{
|
||||||
|
do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| {
|
||||||
|
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
|
||||||
|
|_, did| translate_def_id(cdata, did))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn item_type(item_id: ast::def_id, item: ebml::Doc,
|
pub fn item_type(item_id: ast::def_id, item: ebml::Doc,
|
||||||
tcx: ty::ctxt, cdata: cmd) -> ty::t {
|
tcx: ty::ctxt, cdata: cmd) -> ty::t {
|
||||||
let t = doc_type(item, tcx, cdata);
|
let t = doc_type(item, tcx, cdata);
|
||||||
|
@ -716,14 +726,17 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
||||||
let method_doc = lookup_item(id, cdata.data);
|
let method_doc = lookup_item(id, cdata.data);
|
||||||
let def_id = item_def_id(method_doc, cdata);
|
let def_id = item_def_id(method_doc, cdata);
|
||||||
let name = item_name(intr, method_doc);
|
let name = item_name(intr, method_doc);
|
||||||
let bounds = item_ty_param_bounds(method_doc, tcx, cdata,
|
let bounds =
|
||||||
tag_item_method_tps);
|
item_ty_param_bounds(method_doc, tcx, cdata,
|
||||||
|
tag_item_method_tps);
|
||||||
|
let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
|
||||||
let fty = doc_method_fty(method_doc, tcx, cdata);
|
let fty = doc_method_fty(method_doc, tcx, cdata);
|
||||||
let vis = item_visibility(method_doc);
|
let vis = item_visibility(method_doc);
|
||||||
let self_ty = get_self_ty(method_doc);
|
let self_ty = get_self_ty(method_doc);
|
||||||
ty::method {
|
ty::method {
|
||||||
ident: name,
|
ident: name,
|
||||||
tps: bounds,
|
tps: bounds,
|
||||||
|
transformed_self_ty: transformed_self_ty,
|
||||||
fty: fty,
|
fty: fty,
|
||||||
self_ty: self_ty,
|
self_ty: self_ty,
|
||||||
vis: vis,
|
vis: vis,
|
||||||
|
@ -767,10 +780,12 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let transformed_self_ty = doc_transformed_self_ty(mth, tcx, cdata);
|
||||||
let self_ty = get_self_ty(mth);
|
let self_ty = get_self_ty(mth);
|
||||||
let ty_method = ty::method {
|
let ty_method = ty::method {
|
||||||
ident: name,
|
ident: name,
|
||||||
tps: bounds,
|
tps: bounds,
|
||||||
|
transformed_self_ty: transformed_self_ty,
|
||||||
fty: fty,
|
fty: fty,
|
||||||
self_ty: self_ty,
|
self_ty: self_ty,
|
||||||
vis: ast::public,
|
vis: ast::public,
|
||||||
|
|
|
@ -230,6 +230,17 @@ fn encode_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) {
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encode_transformed_self_ty(ecx: @EncodeContext,
|
||||||
|
ebml_w: writer::Encoder,
|
||||||
|
opt_typ: Option<ty::t>)
|
||||||
|
{
|
||||||
|
for opt_typ.each |&typ| {
|
||||||
|
ebml_w.start_tag(tag_item_method_transformed_self_ty);
|
||||||
|
write_type(ecx, ebml_w, typ);
|
||||||
|
ebml_w.end_tag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_method_fty(ecx: @EncodeContext,
|
fn encode_method_fty(ecx: @EncodeContext,
|
||||||
ebml_w: writer::Encoder,
|
ebml_w: writer::Encoder,
|
||||||
typ: &ty::BareFnTy)
|
typ: &ty::BareFnTy)
|
||||||
|
@ -570,6 +581,7 @@ fn encode_method_ty_fields(ecx: @EncodeContext,
|
||||||
encode_name(ecx, ebml_w, method_ty.ident);
|
encode_name(ecx, ebml_w, method_ty.ident);
|
||||||
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
|
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
|
||||||
tag_item_method_tps);
|
tag_item_method_tps);
|
||||||
|
encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
|
||||||
encode_method_fty(ecx, ebml_w, &method_ty.fty);
|
encode_method_fty(ecx, ebml_w, &method_ty.fty);
|
||||||
encode_visibility(ebml_w, method_ty.vis);
|
encode_visibility(ebml_w, method_ty.vis);
|
||||||
encode_self_type(ebml_w, method_ty.self_ty);
|
encode_self_type(ebml_w, method_ty.self_ty);
|
||||||
|
|
|
@ -71,6 +71,7 @@ pub type param_bounds = @~[param_bound];
|
||||||
pub struct method {
|
pub struct method {
|
||||||
ident: ast::ident,
|
ident: ast::ident,
|
||||||
tps: @~[param_bounds],
|
tps: @~[param_bounds],
|
||||||
|
transformed_self_ty: Option<ty::t>,
|
||||||
fty: BareFnTy,
|
fty: BareFnTy,
|
||||||
self_ty: ast::self_ty_,
|
self_ty: ast::self_ty_,
|
||||||
vis: ast::visibility,
|
vis: ast::visibility,
|
||||||
|
|
|
@ -544,6 +544,29 @@ pub fn bound_lifetimes<AC:AstConv>(
|
||||||
bound_lifetime_names
|
bound_lifetime_names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SelfInfo {
|
||||||
|
untransformed_self_ty: ty::t,
|
||||||
|
self_transform: ast::self_ty
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + Durable>(
|
||||||
|
self: &AC,
|
||||||
|
rscope: &RS,
|
||||||
|
purity: ast::purity,
|
||||||
|
lifetimes: &OptVec<ast::Lifetime>,
|
||||||
|
untransformed_self_ty: ty::t,
|
||||||
|
self_transform: ast::self_ty,
|
||||||
|
decl: &ast::fn_decl) -> (Option<ty::t>, ty::BareFnTy)
|
||||||
|
{
|
||||||
|
let self_info = SelfInfo {
|
||||||
|
untransformed_self_ty: untransformed_self_ty,
|
||||||
|
self_transform: self_transform
|
||||||
|
};
|
||||||
|
let (a, b) = ty_of_method_or_bare_fn(
|
||||||
|
self, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
|
||||||
|
(a.get(), b)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
|
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
|
||||||
self: &AC,
|
self: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
|
@ -551,6 +574,20 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
|
||||||
abi: AbiSet,
|
abi: AbiSet,
|
||||||
lifetimes: &OptVec<ast::Lifetime>,
|
lifetimes: &OptVec<ast::Lifetime>,
|
||||||
decl: &ast::fn_decl) -> ty::BareFnTy
|
decl: &ast::fn_decl) -> ty::BareFnTy
|
||||||
|
{
|
||||||
|
let (_, b) = ty_of_method_or_bare_fn(
|
||||||
|
self, rscope, purity, abi, lifetimes, None, decl);
|
||||||
|
b
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
|
||||||
|
self: &AC,
|
||||||
|
rscope: &RS,
|
||||||
|
purity: ast::purity,
|
||||||
|
abi: AbiSet,
|
||||||
|
lifetimes: &OptVec<ast::Lifetime>,
|
||||||
|
opt_self_info: Option<&SelfInfo>,
|
||||||
|
decl: &ast::fn_decl) -> (Option<Option<ty::t>>, ty::BareFnTy)
|
||||||
{
|
{
|
||||||
debug!("ty_of_bare_fn");
|
debug!("ty_of_bare_fn");
|
||||||
|
|
||||||
|
@ -559,18 +596,56 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
|
||||||
let bound_lifetime_names = bound_lifetimes(self, lifetimes);
|
let bound_lifetime_names = bound_lifetimes(self, lifetimes);
|
||||||
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
|
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
|
||||||
|
|
||||||
|
let opt_transformed_self_ty = opt_self_info.map(|&self_info| {
|
||||||
|
transform_self_ty(self, &rb, self_info)
|
||||||
|
});
|
||||||
|
|
||||||
let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
|
let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
|
||||||
|
|
||||||
let output_ty = match decl.output.node {
|
let output_ty = match decl.output.node {
|
||||||
ast::ty_infer => self.ty_infer(decl.output.span),
|
ast::ty_infer => self.ty_infer(decl.output.span),
|
||||||
_ => ast_ty_to_ty(self, &rb, decl.output)
|
_ => ast_ty_to_ty(self, &rb, decl.output)
|
||||||
};
|
};
|
||||||
|
|
||||||
ty::BareFnTy {
|
return (opt_transformed_self_ty,
|
||||||
purity: purity,
|
ty::BareFnTy {
|
||||||
abis: abi,
|
purity: purity,
|
||||||
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
|
abis: abi,
|
||||||
inputs: input_tys,
|
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
|
||||||
output: output_ty}
|
inputs: input_tys,
|
||||||
|
output: output_ty}
|
||||||
|
});
|
||||||
|
|
||||||
|
fn transform_self_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
|
||||||
|
self: &AC,
|
||||||
|
rscope: &RS,
|
||||||
|
self_info: &SelfInfo) -> Option<ty::t>
|
||||||
|
{
|
||||||
|
match self_info.self_transform.node {
|
||||||
|
ast::sty_static => None,
|
||||||
|
ast::sty_value => {
|
||||||
|
Some(self_info.untransformed_self_ty)
|
||||||
|
}
|
||||||
|
ast::sty_region(lifetime, mutability) => {
|
||||||
|
let region =
|
||||||
|
ast_region_to_region(self, rscope,
|
||||||
|
self_info.self_transform.span,
|
||||||
|
lifetime);
|
||||||
|
Some(ty::mk_rptr(self.tcx(), region,
|
||||||
|
ty::mt {ty: self_info.untransformed_self_ty,
|
||||||
|
mutbl: mutability}))
|
||||||
|
}
|
||||||
|
ast::sty_box(mutability) => {
|
||||||
|
Some(ty::mk_box(self.tcx(),
|
||||||
|
ty::mt {ty: self_info.untransformed_self_ty,
|
||||||
|
mutbl: mutability}))
|
||||||
|
}
|
||||||
|
ast::sty_uniq(mutability) => {
|
||||||
|
Some(ty::mk_uniq(self.tcx(),
|
||||||
|
ty::mt {ty: self_info.untransformed_self_ty,
|
||||||
|
mutbl: mutability}))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,15 +237,17 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
|
||||||
for ms.each |m| {
|
for ms.each |m| {
|
||||||
let ty_method = @match m {
|
let ty_method = @match m {
|
||||||
&ast::required(ref m) => {
|
&ast::required(ref m) => {
|
||||||
ty_method_of_trait_method(ccx, region_paramd, generics,
|
ty_method_of_trait_method(
|
||||||
&m.id, &m.ident, &m.self_ty,
|
ccx, trait_id, region_paramd, generics,
|
||||||
&m.generics, &m.purity, &m.decl)
|
&m.id, &m.ident, &m.self_ty,
|
||||||
|
&m.generics, &m.purity, &m.decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
&ast::provided(ref m) => {
|
&ast::provided(ref m) => {
|
||||||
ty_method_of_trait_method(ccx, region_paramd, generics,
|
ty_method_of_trait_method(
|
||||||
&m.id, &m.ident, &m.self_ty,
|
ccx, trait_id, region_paramd, generics,
|
||||||
&m.generics, &m.purity, &m.decl)
|
&m.id, &m.ident, &m.self_ty,
|
||||||
|
&m.generics, &m.purity, &m.decl)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -316,6 +318,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_method_of_trait_method(self: &CrateCtxt,
|
fn ty_method_of_trait_method(self: &CrateCtxt,
|
||||||
|
trait_id: ast::node_id,
|
||||||
trait_rp: Option<ty::region_variance>,
|
trait_rp: Option<ty::region_variance>,
|
||||||
trait_generics: &ast::Generics,
|
trait_generics: &ast::Generics,
|
||||||
m_id: &ast::node_id,
|
m_id: &ast::node_id,
|
||||||
|
@ -325,16 +328,16 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
|
||||||
m_purity: &ast::purity,
|
m_purity: &ast::purity,
|
||||||
m_decl: &ast::fn_decl) -> ty::method
|
m_decl: &ast::fn_decl) -> ty::method
|
||||||
{
|
{
|
||||||
|
let trait_self_ty = ty::mk_self(self.tcx, local_def(trait_id));
|
||||||
let rscope = MethodRscope::new(m_self_ty.node, trait_rp, trait_generics);
|
let rscope = MethodRscope::new(m_self_ty.node, trait_rp, trait_generics);
|
||||||
|
let (transformed_self_ty, fty) =
|
||||||
|
astconv::ty_of_method(self, &rscope, *m_purity, &m_generics.lifetimes,
|
||||||
|
trait_self_ty, *m_self_ty, m_decl);
|
||||||
ty::method {
|
ty::method {
|
||||||
ident: *m_ident,
|
ident: *m_ident,
|
||||||
tps: ty_param_bounds(self, m_generics),
|
tps: ty_param_bounds(self, m_generics),
|
||||||
fty: astconv::ty_of_bare_fn(self,
|
transformed_self_ty: transformed_self_ty,
|
||||||
&rscope,
|
fty: fty,
|
||||||
*m_purity,
|
|
||||||
AbiSet::Rust(),
|
|
||||||
&m_generics.lifetimes,
|
|
||||||
m_decl),
|
|
||||||
self_ty: m_self_ty.node,
|
self_ty: m_self_ty.node,
|
||||||
// assume public, because this is only invoked on trait methods
|
// assume public, because this is only invoked on trait methods
|
||||||
vis: ast::public,
|
vis: ast::public,
|
||||||
|
@ -607,6 +610,7 @@ pub struct ConvertedMethod {
|
||||||
pub fn convert_methods(ccx: &CrateCtxt,
|
pub fn convert_methods(ccx: &CrateCtxt,
|
||||||
ms: &[@ast::method],
|
ms: &[@ast::method],
|
||||||
rp: Option<ty::region_variance>,
|
rp: Option<ty::region_variance>,
|
||||||
|
untransformed_rcvr_ty: ty::t,
|
||||||
rcvr_bounds: @~[ty::param_bounds],
|
rcvr_bounds: @~[ty::param_bounds],
|
||||||
rcvr_generics: &ast::Generics,
|
rcvr_generics: &ast::Generics,
|
||||||
rcvr_visibility: ast::visibility)
|
rcvr_visibility: ast::visibility)
|
||||||
|
@ -615,8 +619,9 @@ pub fn convert_methods(ccx: &CrateCtxt,
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
return vec::map(ms, |m| {
|
return vec::map(ms, |m| {
|
||||||
let bounds = ty_param_bounds(ccx, &m.generics);
|
let bounds = ty_param_bounds(ccx, &m.generics);
|
||||||
let mty = @ty_of_method(ccx, *m, rp, rcvr_generics,
|
let mty = @ty_of_method(
|
||||||
rcvr_visibility, &m.generics);
|
ccx, *m, rp, untransformed_rcvr_ty,
|
||||||
|
rcvr_generics, rcvr_visibility, &m.generics);
|
||||||
let fty = ty::mk_bare_fn(tcx, copy mty.fty);
|
let fty = ty::mk_bare_fn(tcx, copy mty.fty);
|
||||||
tcx.tcache.insert(
|
tcx.tcache.insert(
|
||||||
local_def(m.id),
|
local_def(m.id),
|
||||||
|
@ -637,6 +642,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
|
||||||
fn ty_of_method(ccx: &CrateCtxt,
|
fn ty_of_method(ccx: &CrateCtxt,
|
||||||
m: @ast::method,
|
m: @ast::method,
|
||||||
rp: Option<ty::region_variance>,
|
rp: Option<ty::region_variance>,
|
||||||
|
untransformed_rcvr_ty: ty::t,
|
||||||
rcvr_generics: &ast::Generics,
|
rcvr_generics: &ast::Generics,
|
||||||
rcvr_visibility: ast::visibility,
|
rcvr_visibility: ast::visibility,
|
||||||
method_generics: &ast::Generics) -> ty::method
|
method_generics: &ast::Generics) -> ty::method
|
||||||
|
@ -644,15 +650,16 @@ pub fn convert_methods(ccx: &CrateCtxt,
|
||||||
let rscope = MethodRscope::new(m.self_ty.node,
|
let rscope = MethodRscope::new(m.self_ty.node,
|
||||||
rp,
|
rp,
|
||||||
rcvr_generics);
|
rcvr_generics);
|
||||||
|
let (transformed_self_ty, fty) =
|
||||||
|
astconv::ty_of_method(ccx, &rscope, m.purity,
|
||||||
|
&method_generics.lifetimes,
|
||||||
|
untransformed_rcvr_ty,
|
||||||
|
m.self_ty, &m.decl);
|
||||||
ty::method {
|
ty::method {
|
||||||
ident: m.ident,
|
ident: m.ident,
|
||||||
tps: ty_param_bounds(ccx, &m.generics),
|
tps: ty_param_bounds(ccx, &m.generics),
|
||||||
fty: astconv::ty_of_bare_fn(ccx,
|
transformed_self_ty: transformed_self_ty,
|
||||||
&rscope,
|
fty: fty,
|
||||||
m.purity,
|
|
||||||
ast::RustAbi,
|
|
||||||
&method_generics.lifetimes,
|
|
||||||
&m.decl),
|
|
||||||
self_ty: m.self_ty.node,
|
self_ty: m.self_ty.node,
|
||||||
vis: m.vis.inherit_from(rcvr_visibility),
|
vis: m.vis.inherit_from(rcvr_visibility),
|
||||||
def_id: local_def(m.id)
|
def_id: local_def(m.id)
|
||||||
|
@ -715,7 +722,7 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
|
||||||
it.vis
|
it.vis
|
||||||
};
|
};
|
||||||
|
|
||||||
let cms = convert_methods(ccx, *ms, rp, i_bounds, generics,
|
let cms = convert_methods(ccx, *ms, rp, selfty, i_bounds, generics,
|
||||||
parent_visibility);
|
parent_visibility);
|
||||||
for opt_trait_ref.each |t| {
|
for opt_trait_ref.each |t| {
|
||||||
check_methods_against_trait(ccx, generics, rp, selfty, *t, cms);
|
check_methods_against_trait(ccx, generics, rp, selfty, *t, cms);
|
||||||
|
@ -732,7 +739,9 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
|
||||||
let (_, provided_methods) =
|
let (_, provided_methods) =
|
||||||
split_trait_methods(*trait_methods);
|
split_trait_methods(*trait_methods);
|
||||||
let (bounds, _) = mk_substs(ccx, generics, rp);
|
let (bounds, _) = mk_substs(ccx, generics, rp);
|
||||||
let _ = convert_methods(ccx, provided_methods, rp, bounds, generics,
|
let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
|
||||||
|
let _ = convert_methods(ccx, provided_methods, rp,
|
||||||
|
untransformed_rcvr_ty, bounds, generics,
|
||||||
it.vis);
|
it.vis);
|
||||||
}
|
}
|
||||||
ast::item_struct(struct_def, ref generics) => {
|
ast::item_struct(struct_def, ref generics) => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl Foo {
|
pub impl Foo {
|
||||||
fn foo(&'a self) {}
|
fn foo<'a>(&'a self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {}
|
pub fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue