parent
dd9693f211
commit
58a81a68ed
@ -497,7 +497,7 @@ fn build_session(sopts: @session::options) -> session::session {
|
||||
sopts.target_triple,
|
||||
sopts.addl_lib_search_paths);
|
||||
ret session::session(target_cfg, sopts, cstore,
|
||||
@{cm: codemap::new_codemap(), mutable next_id: 0},
|
||||
@{cm: codemap::new_codemap(), mutable next_id: 1},
|
||||
none, 0u, filesearch, false);
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,15 @@
|
||||
|
||||
import syntax::ast;
|
||||
import middle::ty;
|
||||
import option;
|
||||
import option::{some, none};
|
||||
import driver::session;
|
||||
|
||||
export get_symbol;
|
||||
export get_type_param_count;
|
||||
export lookup_defs;
|
||||
export get_tag_variants;
|
||||
export get_impls_for_mod;
|
||||
export get_impl_methods;
|
||||
export get_type;
|
||||
|
||||
fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
|
||||
@ -56,15 +58,38 @@ fn get_tag_variants(tcx: ty::ctxt, def: ast::def_id) -> [ty::variant_info] {
|
||||
let cstore = tcx.sess.get_cstore();
|
||||
let cnum = def.crate;
|
||||
let cdata = cstore::get_crate_data(cstore, cnum).data;
|
||||
let resolver = bind translate_def_id(tcx.sess, cnum, _);
|
||||
let resolver = bind translate_def_id(cstore, cnum, _);
|
||||
ret decoder::get_tag_variants(cdata, def, tcx, resolver)
|
||||
}
|
||||
|
||||
fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
|
||||
name: option::t<ast::ident>)
|
||||
-> [@middle::resolve::_impl] {
|
||||
let cdata = cstore::get_crate_data(cstore, def.crate).data;
|
||||
let result = [];
|
||||
for did in decoder::get_impls_for_mod(cdata, def.node, def.crate) {
|
||||
let nm = decoder::lookup_item_name(cdata, did.node);
|
||||
if alt name { some(n) { n == nm } none. { true } } {
|
||||
result += [@{did: did,
|
||||
ident: nm,
|
||||
methods: decoder::lookup_impl_methods(
|
||||
cdata, did.node, did.crate)}];
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn get_impl_methods(cstore: cstore::cstore, def: ast::def_id)
|
||||
-> [@middle::resolve::method_info] {
|
||||
let cdata = cstore::get_crate_data(cstore, def.crate).data;
|
||||
decoder::lookup_impl_methods(cdata, def.node, def.crate)
|
||||
}
|
||||
|
||||
fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_kinds_and_ty {
|
||||
let cstore = tcx.sess.get_cstore();
|
||||
let cnum = def.crate;
|
||||
let cdata = cstore::get_crate_data(cstore, cnum).data;
|
||||
let resolver = bind translate_def_id(tcx.sess, cnum, _);
|
||||
let resolver = bind translate_def_id(cstore, cnum, _);
|
||||
decoder::get_type(cdata, def, tcx, resolver)
|
||||
}
|
||||
|
||||
@ -73,7 +98,7 @@ fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_kinds_and_ty {
|
||||
// external crates - if those types further refer to types in other crates
|
||||
// then we must translate the crate number from that encoded in the external
|
||||
// crate to the correct local crate number.
|
||||
fn translate_def_id(sess: session::session, searched_crate: ast::crate_num,
|
||||
fn translate_def_id(cstore: cstore::cstore, searched_crate: ast::crate_num,
|
||||
def_id: ast::def_id) -> ast::def_id {
|
||||
|
||||
let ext_cnum = def_id.crate;
|
||||
@ -82,13 +107,12 @@ fn translate_def_id(sess: session::session, searched_crate: ast::crate_num,
|
||||
assert (searched_crate != ast::local_crate);
|
||||
assert (ext_cnum != ast::local_crate);
|
||||
|
||||
let cstore = sess.get_cstore();
|
||||
let cmeta = cstore::get_crate_data(cstore, searched_crate);
|
||||
|
||||
let local_cnum =
|
||||
alt cmeta.cnum_map.find(ext_cnum) {
|
||||
option::some(n) { n }
|
||||
option::none. { sess.bug("didn't find a crate in the cnum_map") }
|
||||
option::none. { fail "didn't find a crate in the cnum_map"; }
|
||||
};
|
||||
|
||||
ret {crate: local_cnum, node: node_id};
|
||||
|
@ -16,6 +16,7 @@ export get_type;
|
||||
export get_type_param_count;
|
||||
export get_type_param_kinds;
|
||||
export lookup_def;
|
||||
export lookup_item_name;
|
||||
export resolve_path;
|
||||
export get_crate_attributes;
|
||||
export list_crate_metadata;
|
||||
@ -23,7 +24,8 @@ export crate_dep;
|
||||
export get_crate_deps;
|
||||
export get_crate_hash;
|
||||
export external_resolver;
|
||||
|
||||
export get_impls_for_mod;
|
||||
export lookup_impl_methods;
|
||||
// A function that takes a def_id relative to the crate being searched and
|
||||
// returns a def_id relative to the compilation environment, i.e. if we hit a
|
||||
// def_id for an item defined in another crate, somebody needs to figure out
|
||||
@ -130,6 +132,15 @@ fn item_ty_param_kinds(item: ebml::doc) -> [ast::kind] {
|
||||
ret ks;
|
||||
}
|
||||
|
||||
fn item_ty_param_count(item: ebml::doc) -> uint {
|
||||
let n = 0u;
|
||||
let tp = tag_items_data_item_ty_param_kinds;
|
||||
ebml::tagged_docs(item, tp) {|p|
|
||||
n += ebml::vint_at(ebml::doc_data(p), 0u).val;
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
fn tag_variant_ids(item: ebml::doc, this_cnum: ast::crate_num) ->
|
||||
[ast::def_id] {
|
||||
let ids: [ast::def_id] = [];
|
||||
@ -159,6 +170,15 @@ fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] {
|
||||
ret result;
|
||||
}
|
||||
|
||||
fn item_name(item: ebml::doc) -> ast::ident {
|
||||
let name = ebml::get_doc(item, tag_paths_data_name);
|
||||
str::unsafe_from_bytes(ebml::doc_data(name))
|
||||
}
|
||||
|
||||
fn lookup_item_name(data: @[u8], id: ast::node_id) -> ast::ident {
|
||||
item_name(lookup_item(id, data))
|
||||
}
|
||||
|
||||
// FIXME doesn't yet handle renamed re-exported externals
|
||||
fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
|
||||
ast::def {
|
||||
@ -205,7 +225,7 @@ fn get_type(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
|
||||
}
|
||||
|
||||
fn get_type_param_count(data: @[u8], id: ast::node_id) -> uint {
|
||||
ret vec::len(get_type_param_kinds(data, id));
|
||||
item_ty_param_count(lookup_item(id, data))
|
||||
}
|
||||
|
||||
fn get_type_param_kinds(data: @[u8], id: ast::node_id) -> [ast::kind] {
|
||||
@ -243,6 +263,31 @@ fn get_tag_variants(_data: @[u8], def: ast::def_id, tcx: ty::ctxt,
|
||||
ret infos;
|
||||
}
|
||||
|
||||
fn get_impls_for_mod(data: @[u8], node: ast::node_id, cnum: ast::crate_num)
|
||||
-> [ast::def_id] {
|
||||
let mod_item = lookup_item(node, data), result = [];
|
||||
ebml::tagged_docs(mod_item, tag_mod_impl) {|doc|
|
||||
let did = parse_def_id(ebml::doc_data(doc));
|
||||
result += [{crate: cnum with did}];
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn lookup_impl_methods(data: @[u8], node: ast::node_id, cnum: ast::crate_num)
|
||||
-> [@middle::resolve::method_info] {
|
||||
let impl_item = lookup_item(node, data), rslt = [];
|
||||
let base_tps = item_ty_param_count(impl_item);
|
||||
ebml::tagged_docs(impl_item, tag_impl_method) {|doc|
|
||||
let m_did = parse_def_id(ebml::doc_data(doc));
|
||||
let mth_item = lookup_item(m_did.node, data);
|
||||
rslt += [@{did: {crate: cnum, node: m_did.node},
|
||||
n_tps: item_ty_param_count(mth_item) - base_tps,
|
||||
ident: item_name(mth_item)}];
|
||||
}
|
||||
rslt
|
||||
}
|
||||
|
||||
|
||||
fn family_has_type_params(fam_ch: u8) -> bool {
|
||||
ret alt fam_ch as char {
|
||||
'c' { false }
|
||||
@ -258,6 +303,7 @@ fn family_has_type_params(fam_ch: u8) -> bool {
|
||||
'm' { false }
|
||||
'n' { false }
|
||||
'v' { true }
|
||||
'i' { true }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -249,6 +249,26 @@ fn encode_tag_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_info_for_mod(ebml_w: ebml::writer, md: _mod,
|
||||
id: node_id) {
|
||||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(id));
|
||||
encode_family(ebml_w, 'm' as u8);
|
||||
for i in md.items {
|
||||
alt i.node {
|
||||
item_impl(_, _, _) {
|
||||
if ast_util::is_exported(i.ident, md) {
|
||||
ebml::start_tag(ebml_w, tag_mod_impl);
|
||||
ebml_w.writer.write(str::bytes(def_to_str(local_def(i.id))));
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
&index: [entry<int>]) {
|
||||
alt item.node {
|
||||
@ -280,20 +300,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
item_mod(m) {
|
||||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'm' as u8);
|
||||
for i in m.items {
|
||||
alt i.node {
|
||||
item_impl(_, _, _) {
|
||||
ebml::start_tag(ebml_w, tag_mod_impl);
|
||||
ebml_w.writer.write(str::bytes(def_to_str(local_def(i.id))));
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
ebml::end_tag(ebml_w);
|
||||
encode_info_for_mod(ebml_w, m, item.id);
|
||||
}
|
||||
item_native_mod(_) {
|
||||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
@ -363,9 +370,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
item_impl(tps, _, methods) {
|
||||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'I' as u8);
|
||||
encode_family(ebml_w, 'i' as u8);
|
||||
encode_type_param_kinds(ebml_w, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
for m in methods {
|
||||
ebml::start_tag(ebml_w, tag_impl_method);
|
||||
ebml_w.writer.write(str::bytes(def_to_str(local_def(m.node.id))));
|
||||
@ -377,10 +385,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
index += [{val: m.node.id, pos: ebml_w.writer.tell()}];
|
||||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(m.node.id));
|
||||
encode_family(ebml_w, 'i' as u8);
|
||||
encode_family(ebml_w, 'f' as u8);
|
||||
encode_inlineness(ebml_w, 'n' as u8);
|
||||
encode_type_param_kinds(ebml_w, tps + m.node.tps);
|
||||
encode_type(ecx, ebml_w,
|
||||
node_id_to_monotype(ecx.ccx.tcx, m.node.id));
|
||||
encode_name(ebml_w, m.node.ident);
|
||||
encode_symbol(ecx, ebml_w, m.node.id);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
@ -415,10 +425,12 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer) ->
|
||||
[entry<int>] {
|
||||
fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
||||
crate_mod: _mod) -> [entry<int>] {
|
||||
let index: [entry<int>] = [];
|
||||
ebml::start_tag(ebml_w, tag_items_data);
|
||||
index += [{val: crate_node_id, pos: ebml_w.writer.tell()}];
|
||||
encode_info_for_mod(ebml_w, crate_mod, crate_node_id);
|
||||
ecx.ccx.ast_map.items {|key, val|
|
||||
alt val {
|
||||
middle::ast_map::node_item(i) {
|
||||
@ -658,7 +670,7 @@ fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str {
|
||||
// Encode and index the items.
|
||||
|
||||
ebml::start_tag(ebml_w, tag_items);
|
||||
let items_index = encode_info_for_items(ecx, ebml_w);
|
||||
let items_index = encode_info_for_items(ecx, ebml_w, crate.node.module);
|
||||
let items_buckets = create_index(items_index, hash_node_id);
|
||||
encode_index(ebml_w, items_buckets, write_int);
|
||||
ebml::end_tag(ebml_w);
|
||||
|
@ -8,6 +8,7 @@ tag ast_node {
|
||||
node_item(@item);
|
||||
node_obj_ctor(@item);
|
||||
node_native_item(@native_item);
|
||||
node_method(@method);
|
||||
node_expr(@expr);
|
||||
// Locals are numbered, because the alias analysis needs to know in which
|
||||
// order they are introduced.
|
||||
@ -63,6 +64,9 @@ fn map_item(cx: ctx, i: @item) {
|
||||
cx.map.insert(i.id, node_item(i));
|
||||
alt i.node {
|
||||
item_obj(_, _, ctor_id) { cx.map.insert(ctor_id, node_obj_ctor(i)); }
|
||||
item_impl(_, _, ms) {
|
||||
for m in ms { cx.map.insert(m.node.id, node_method(m)); }
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ import option::{some, none, is_none, is_some};
|
||||
import syntax::print::pprust::*;
|
||||
|
||||
export resolve_crate;
|
||||
export def_map, ext_map, exp_map, impl_map, iscopes;
|
||||
export def_map, ext_map, exp_map, impl_map;
|
||||
export _impl, iscopes, method_info;
|
||||
|
||||
// Resolving happens in two passes. The first pass collects defids of all
|
||||
// (internal) imports and modules, so that they can be looked up when needed,
|
||||
@ -47,7 +48,7 @@ tag import_state {
|
||||
resolved(option::t<def>, /* value */
|
||||
option::t<def>, /* type */
|
||||
option::t<def>, /* module */
|
||||
@[@ast::item],
|
||||
@[@_impl], /* impls */
|
||||
/* used for reporting unused import warning */
|
||||
ast::ident, codemap::span);
|
||||
}
|
||||
@ -106,6 +107,7 @@ type def_map = hashmap<node_id, def>;
|
||||
type ext_map = hashmap<def_id, [ident]>;
|
||||
type exp_map = hashmap<str, def>;
|
||||
type impl_map = hashmap<node_id, iscopes>;
|
||||
type impl_cache = hashmap<def_id, @[@_impl]>;
|
||||
|
||||
type env =
|
||||
{cstore: cstore::cstore,
|
||||
@ -117,6 +119,7 @@ type env =
|
||||
block_map: hashmap<ast::node_id, [glob_imp_def]>,
|
||||
ext_map: ext_map,
|
||||
impl_map: impl_map,
|
||||
impl_cache: impl_cache,
|
||||
ext_cache: ext_hash,
|
||||
used_imports: {mutable track: bool,
|
||||
mutable data: [ast::node_id]},
|
||||
@ -144,6 +147,7 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
|
||||
block_map: new_int_hash(),
|
||||
ext_map: new_def_hash(),
|
||||
impl_map: new_int_hash(),
|
||||
impl_cache: new_def_hash(),
|
||||
ext_cache: new_ext_hash(),
|
||||
used_imports: {mutable track: false, mutable data: []},
|
||||
mutable reported: [],
|
||||
@ -489,7 +493,7 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
|
||||
ids: [ast::ident], sp: codemap::span, sc: scopes) {
|
||||
fn register(e: env, id: node_id, cx: ctxt, sp: codemap::span,
|
||||
name: ast::ident, lookup: block(namespace) -> option::t<def>,
|
||||
impls: [@ast::item]) {
|
||||
impls: [@_impl]) {
|
||||
let val = lookup(ns_value), typ = lookup(ns_type),
|
||||
md = lookup(ns_module);
|
||||
if is_none(val) && is_none(typ) && is_none(md) &&
|
||||
@ -1058,7 +1062,7 @@ fn lookup_in_mod(e: env, m: def, sp: span, name: ident, ns: namespace,
|
||||
if !is_none(cached) { ret cached; }
|
||||
let path = [name];
|
||||
if defid.node != ast::crate_node_id {
|
||||
path = e.ext_map.get(defid) + path;
|
||||
path = e.ext_map.get(defid) + path;
|
||||
}
|
||||
let fnd = lookup_external(e, defid.crate, path, ns);
|
||||
if !is_none(fnd) {
|
||||
@ -1631,6 +1635,10 @@ fn check_exports(e: @env) {
|
||||
|
||||
// Impl resolution
|
||||
|
||||
type method_info = {did: def_id, n_tps: uint, ident: ast::ident};
|
||||
type _impl = {did: def_id, ident: ast::ident, methods: [@method_info]};
|
||||
type iscopes = list<@[@_impl]>;
|
||||
|
||||
fn resolve_impls(e: @env, c: @ast::crate) {
|
||||
visit::visit_crate(*c, nil, visit::mk_vt(@{
|
||||
visit_block: bind visit_block_with_impl_scope(e, _, _, _),
|
||||
@ -1641,21 +1649,25 @@ fn resolve_impls(e: @env, c: @ast::crate) {
|
||||
}
|
||||
|
||||
fn find_impls_in_view_item(e: env, vi: @ast::view_item,
|
||||
&impls: [@ast::item], sc: iscopes) {
|
||||
&impls: [@_impl], sc: iscopes) {
|
||||
alt vi.node {
|
||||
ast::view_item_import(_, pt, id) {
|
||||
ast::view_item_import(name, pt, id) {
|
||||
let found = [];
|
||||
if vec::len(*pt) == 1u {
|
||||
list::iter(sc) {|level|
|
||||
if vec::len(found) > 0u { ret; }
|
||||
for imp in *level {
|
||||
if imp.ident == pt[0] { found += [imp]; }
|
||||
if imp.ident == pt[0] {
|
||||
found += [@{ident: name with *imp}];
|
||||
}
|
||||
}
|
||||
if vec::len(found) > 0u { impls += found; }
|
||||
}
|
||||
} else {
|
||||
alt e.imports.get(id) {
|
||||
resolved(_, _, _, is, _, _) { impls += *is; }
|
||||
resolved(_, _, _, is, _, _) {
|
||||
for i in *is { impls += [@{ident: name with *i}]; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1680,38 +1692,51 @@ fn find_impls_in_view_item(e: env, vi: @ast::view_item,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_impls_in_item(i: @ast::item, &impls: [@ast::item],
|
||||
fn find_impls_in_item(i: @ast::item, &impls: [@_impl],
|
||||
name: option::t<ident>,
|
||||
ck_exports: option::t<ast::_mod>) {
|
||||
alt i.node {
|
||||
ast::item_impl(_, _, _) {
|
||||
ast::item_impl(_, _, mthds) {
|
||||
if alt name { some(n) { n == i.ident } _ { true } } &&
|
||||
alt ck_exports { some(m) { is_exported(i.ident, m) } _ { true } } {
|
||||
impls += [i];
|
||||
impls += [@{did: local_def(i.id),
|
||||
ident: i.ident,
|
||||
methods: vec::map({|m| @{did: local_def(m.node.id),
|
||||
n_tps: vec::len(m.node.tps),
|
||||
ident: m.node.ident}},
|
||||
mthds)}];
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME[impl] external importing of impls
|
||||
fn find_impls_in_mod(e: env, m: def, &impls: [@ast::item],
|
||||
// FIXME[impl] we should probably cache this
|
||||
fn find_impls_in_mod(e: env, m: def, &impls: [@_impl],
|
||||
name: option::t<ident>) {
|
||||
alt m {
|
||||
ast::def_mod(defid) {
|
||||
if defid.crate == ast::local_crate {
|
||||
let md = option::get(e.mod_map.get(defid.node).m);
|
||||
for i in md.items {
|
||||
find_impls_in_item(i, impls, name, some(md));
|
||||
alt e.impl_cache.find(defid) {
|
||||
some(v) { impls += *v; }
|
||||
none. {
|
||||
let found = [];
|
||||
if defid.crate == ast::local_crate {
|
||||
let md = option::get(e.mod_map.get(defid.node).m);
|
||||
for i in md.items {
|
||||
find_impls_in_item(i, found, name, some(md));
|
||||
}
|
||||
} else {
|
||||
found = csearch::get_impls_for_mod(e.cstore, defid, name);
|
||||
}
|
||||
impls += found;
|
||||
e.impl_cache.insert(defid, @found);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
|
||||
type iscopes = list<@[@ast::item]>;
|
||||
|
||||
fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
|
||||
v: vt<iscopes>) {
|
||||
let impls = [];
|
||||
|
@ -1463,33 +1463,36 @@ fn check_expr_with(fcx: @fn_ctxt, expr: @ast::expr, expected: ty::t) -> bool {
|
||||
// FIXME[impl] notice/resolve conflicts
|
||||
fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
|
||||
name: ast::ident, ty: ty::t)
|
||||
-> option::t<{method: @ast::method, ids: [int]}> {
|
||||
-> option::t<{method: @resolve::method_info, ids: [int]}> {
|
||||
let result = none;
|
||||
std::list::iter(isc) {|impls|
|
||||
for im in *impls {
|
||||
alt im.node {
|
||||
ast::item_impl(tps, slf, mthds) {
|
||||
let self_ty = ast_ty_to_ty_crate(fcx.ccx, slf);
|
||||
let tp_count = vec::len(tps);
|
||||
let {ids, ty: self_ty} = if tp_count > 0u {
|
||||
bind_params_in_type(ast_util::dummy_sp(), fcx.ccx.tcx,
|
||||
bind next_ty_var_id(fcx), self_ty,
|
||||
tp_count)
|
||||
} else { {ids: [], ty: self_ty} };
|
||||
// FIXME[impl] Don't unify in the current fcx, use
|
||||
// scratch context
|
||||
alt unify::unify(fcx, ty, self_ty) {
|
||||
ures_ok(_) {
|
||||
for m in mthds {
|
||||
if m.node.ident == name {
|
||||
result = some({method: m, ids: ids});
|
||||
ret;
|
||||
}
|
||||
}
|
||||
for @{did, methods, _} in *impls {
|
||||
let (n_tps, self_ty) = if did.crate == ast::local_crate {
|
||||
alt fcx.ccx.tcx.items.get(did.node) {
|
||||
ast_map::node_item(@{node: ast::item_impl(tps, st, _), _}) {
|
||||
(vec::len(tps), ast_ty_to_ty_crate(fcx.ccx, st))
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
} else {
|
||||
let tpt = csearch::get_type(fcx.ccx.tcx, did);
|
||||
(vec::len(tpt.kinds), tpt.ty)
|
||||
};
|
||||
let {ids, ty: self_ty} = if n_tps > 0u {
|
||||
bind_params_in_type(ast_util::dummy_sp(), fcx.ccx.tcx,
|
||||
bind next_ty_var_id(fcx), self_ty, n_tps)
|
||||
} else { {ids: [], ty: self_ty} };
|
||||
// FIXME[impl] Don't unify in the current fcx, use
|
||||
// scratch context
|
||||
alt unify::unify(fcx, ty, self_ty) {
|
||||
ures_ok(_) {
|
||||
for m in methods {
|
||||
if m.ident == name {
|
||||
result = some({method: m, ids: ids});
|
||||
ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2129,20 +2132,26 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||
let iscope = fcx.ccx.impl_map.get(expr.id);
|
||||
alt lookup_method(fcx, iscope, field, base_t) {
|
||||
some({method, ids}) {
|
||||
let mt = ty_of_method(fcx.ccx.tcx, m_check, method), ids = ids;
|
||||
let fty = ty::mk_fn(fcx.ccx.tcx, mt.proto, mt.inputs,
|
||||
mt.output, mt.cf, mt.constrs);
|
||||
let tp_count = vec::len(method.node.tps);
|
||||
if tp_count > 0u {
|
||||
let fty = if method.did.crate == ast::local_crate {
|
||||
alt tcx.items.get(method.did.node) {
|
||||
ast_map::node_method(m) {
|
||||
let mt = ty_of_method(tcx, m_check, m);
|
||||
ty::mk_fn(tcx, mt.proto, mt.inputs,
|
||||
mt.output, mt.cf, mt.constrs)
|
||||
}
|
||||
}
|
||||
} else { csearch::get_type(tcx, method.did).ty };
|
||||
let ids = ids;
|
||||
if method.n_tps > 0u {
|
||||
let b = bind_params_in_type(expr.span, tcx,
|
||||
bind next_ty_var_id(fcx),
|
||||
fty, tp_count);
|
||||
fty, method.n_tps);
|
||||
ids += b.ids;
|
||||
fty = b.ty;
|
||||
}
|
||||
let substs = vec::map(ids, {|id| ty::mk_var(tcx, id)});
|
||||
write::ty_fixup(fcx, id, {substs: some(substs), ty: fty});
|
||||
fcx.ccx.method_map.insert(id, local_def(method.node.id));
|
||||
fcx.ccx.method_map.insert(id, method.did);
|
||||
}
|
||||
_ {
|
||||
base_t = do_autoderef(fcx, expr.span, base_t);
|
||||
|
Loading…
x
Reference in New Issue
Block a user