提交 3333b0f1 编写于 作者: N Niko Matsakis

Add a (currently unused) "transformed self type" pointer into ty::method

上级 0a0525e3
......@@ -162,6 +162,7 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
pub static tag_item_method_tps: uint = 0x7b;
pub static tag_item_method_fty: uint = 0x7c;
pub static tag_item_method_transformed_self_ty: uint = 0x7d;
pub struct LinkMeta {
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))
}
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,
tcx: ty::ctxt, cdata: cmd) -> ty::t {
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 def_id = item_def_id(method_doc, cdata);
let name = item_name(intr, method_doc);
let bounds = item_ty_param_bounds(method_doc, tcx, cdata,
tag_item_method_tps);
let bounds =
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 vis = item_visibility(method_doc);
let self_ty = get_self_ty(method_doc);
ty::method {
ident: name,
tps: bounds,
transformed_self_ty: transformed_self_ty,
fty: fty,
self_ty: self_ty,
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 ty_method = ty::method {
ident: name,
tps: bounds,
transformed_self_ty: transformed_self_ty,
fty: fty,
self_ty: self_ty,
vis: ast::public,
......
......@@ -230,6 +230,17 @@ fn encode_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) {
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,
ebml_w: writer::Encoder,
typ: &ty::BareFnTy)
......@@ -570,6 +581,7 @@ fn encode_method_ty_fields(ecx: @EncodeContext,
encode_name(ecx, ebml_w, method_ty.ident);
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.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_visibility(ebml_w, method_ty.vis);
encode_self_type(ebml_w, method_ty.self_ty);
......
......@@ -71,6 +71,7 @@ pub struct field {
pub struct method {
ident: ast::ident,
tps: @~[param_bounds],
transformed_self_ty: Option<ty::t>,
fty: BareFnTy,
self_ty: ast::self_ty_,
vis: ast::visibility,
......
......@@ -544,6 +544,29 @@ pub fn bound_lifetimes<AC:AstConv>(
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>(
self: &AC,
rscope: &RS,
......@@ -551,6 +574,20 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
abi: AbiSet,
lifetimes: &OptVec<ast::Lifetime>,
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");
......@@ -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 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 output_ty = match decl.output.node {
ast::ty_infer => self.ty_infer(decl.output.span),
_ => ast_ty_to_ty(self, &rb, decl.output)
};
ty::BareFnTy {
purity: purity,
abis: abi,
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
inputs: input_tys,
output: output_ty}
return (opt_transformed_self_ty,
ty::BareFnTy {
purity: purity,
abis: abi,
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
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| {
let ty_method = @match m {
&ast::required(ref m) => {
ty_method_of_trait_method(ccx, region_paramd, generics,
&m.id, &m.ident, &m.self_ty,
&m.generics, &m.purity, &m.decl)
ty_method_of_trait_method(
ccx, trait_id, region_paramd, generics,
&m.id, &m.ident, &m.self_ty,
&m.generics, &m.purity, &m.decl)
}
&ast::provided(ref m) => {
ty_method_of_trait_method(ccx, region_paramd, generics,
&m.id, &m.ident, &m.self_ty,
&m.generics, &m.purity, &m.decl)
ty_method_of_trait_method(
ccx, trait_id, region_paramd, generics,
&m.id, &m.ident, &m.self_ty,
&m.generics, &m.purity, &m.decl)
}
};
......@@ -316,6 +318,7 @@ fn make_static_method_ty(ccx: &CrateCtxt,
}
fn ty_method_of_trait_method(self: &CrateCtxt,
trait_id: ast::node_id,
trait_rp: Option<ty::region_variance>,
trait_generics: &ast::Generics,
m_id: &ast::node_id,
......@@ -325,16 +328,16 @@ fn ty_method_of_trait_method(self: &CrateCtxt,
m_purity: &ast::purity,
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 (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 {
ident: *m_ident,
tps: ty_param_bounds(self, m_generics),
fty: astconv::ty_of_bare_fn(self,
&rscope,
*m_purity,
AbiSet::Rust(),
&m_generics.lifetimes,
m_decl),
transformed_self_ty: transformed_self_ty,
fty: fty,
self_ty: m_self_ty.node,
// assume public, because this is only invoked on trait methods
vis: ast::public,
......@@ -607,6 +610,7 @@ pub struct ConvertedMethod {
pub fn convert_methods(ccx: &CrateCtxt,
ms: &[@ast::method],
rp: Option<ty::region_variance>,
untransformed_rcvr_ty: ty::t,
rcvr_bounds: @~[ty::param_bounds],
rcvr_generics: &ast::Generics,
rcvr_visibility: ast::visibility)
......@@ -615,8 +619,9 @@ pub fn convert_methods(ccx: &CrateCtxt,
let tcx = ccx.tcx;
return vec::map(ms, |m| {
let bounds = ty_param_bounds(ccx, &m.generics);
let mty = @ty_of_method(ccx, *m, rp, rcvr_generics,
rcvr_visibility, &m.generics);
let mty = @ty_of_method(
ccx, *m, rp, untransformed_rcvr_ty,
rcvr_generics, rcvr_visibility, &m.generics);
let fty = ty::mk_bare_fn(tcx, copy mty.fty);
tcx.tcache.insert(
local_def(m.id),
......@@ -637,6 +642,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
fn ty_of_method(ccx: &CrateCtxt,
m: @ast::method,
rp: Option<ty::region_variance>,
untransformed_rcvr_ty: ty::t,
rcvr_generics: &ast::Generics,
rcvr_visibility: ast::visibility,
method_generics: &ast::Generics) -> ty::method
......@@ -644,15 +650,16 @@ fn ty_of_method(ccx: &CrateCtxt,
let rscope = MethodRscope::new(m.self_ty.node,
rp,
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 {
ident: m.ident,
tps: ty_param_bounds(ccx, &m.generics),
fty: astconv::ty_of_bare_fn(ccx,
&rscope,
m.purity,
ast::RustAbi,
&method_generics.lifetimes,
&m.decl),
transformed_self_ty: transformed_self_ty,
fty: fty,
self_ty: m.self_ty.node,
vis: m.vis.inherit_from(rcvr_visibility),
def_id: local_def(m.id)
......@@ -715,7 +722,7 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
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);
for opt_trait_ref.each |t| {
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) =
split_trait_methods(*trait_methods);
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);
}
ast::item_struct(struct_def, ref generics) => {
......
......@@ -15,7 +15,7 @@ struct Foo {
}
pub impl Foo {
fn foo(&'a self) {}
fn foo<'a>(&'a self) {}
}
pub fn main() {}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册