mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Add a (currently unused) "transformed self type" pointer into ty::method
This commit is contained in:
parent
0a0525e366
commit
3333b0f117
@ -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_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 type param_bounds = @~[param_bound];
|
||||
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 @@ pub fn ensure_trait_methods(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 @@ pub fn ensure_trait_methods(ccx: &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 @@ pub fn convert_methods(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() {}
|
Loading…
Reference in New Issue
Block a user