rustc: Implement a new resolve pass behind a compile flag

This commit is contained in:
Patrick Walton 2012-05-22 10:54:12 -07:00
parent 0b1edb7f0e
commit f093d374ed
42 changed files with 4336 additions and 163 deletions

View file

@ -27,8 +27,8 @@ io::println(comm::recv(p));
import either::either;
import libc::size_t;
export port::{};
export chan::{};
export port;
export chan;
export send;
export recv;
export peek;

View file

@ -200,6 +200,7 @@ impl extensions<A:copy> for dvec<A> {
}
}
/*
#[doc = "
Append all elements of an iterable.
@ -222,6 +223,7 @@ impl extensions<A:copy> for dvec<A> {
v
}
}
*/
#[doc = "
Gets a copy of the current contents.
@ -267,7 +269,28 @@ impl extensions<A:copy> for dvec<A> {
}
#[doc = "Returns the last element, failing if the vector is empty"]
#[inline(always)]
fn last() -> A {
self.get_elt(self.len() - 1u)
self.check_not_borrowed();
let length = self.len();
if length == 0u {
fail "attempt to retrieve the last element of an empty vector";
}
ret self.data[length - 1u];
}
#[doc="Iterates over the elements in reverse order"]
#[inline(always)]
fn reach(f: fn(A) -> bool) {
let length = self.len();
let mut i = 0u;
while i < length {
if !f(self.get_elt(i)) {
break;
}
i += 1u;
}
}
}

View file

@ -14,7 +14,6 @@ io::println(#fmt(\"fib(5000) = %?\", delayed_fib.get()))
import either::either;
export future;
export future::{};
export from_value;
export from_port;
export from_fn;

View file

@ -6,6 +6,7 @@ avoid needing a single global lock."]
import arc::methods;
import dvec::dvec;
import dvec::{extensions};
import sys::methods;
export port;
export chan;

View file

@ -24,6 +24,7 @@ spawn {||
import result::result;
import dvec::extensions;
import dvec_iter::extensions;
export task;
export task_result;
@ -31,7 +32,7 @@ export notification;
export sched_mode;
export sched_opts;
export task_opts;
export builder::{};
export builder;
export default_task_opts;
export get_opts;

View file

@ -8,6 +8,7 @@ import io;
import io::{reader_util, writer_util};
import map;
import map::hashmap;
import core::vec::extensions;
export json;
export error;

View file

@ -102,6 +102,11 @@ pure fn append<T: copy>(l: @list<T>, m: @list<T>) -> @list<T> {
}
}
#[doc = "Push an element to the front of a list"]
fn push<T: copy>(&l: list<T>, v: T) {
l = cons(v, @l);
}
#[doc = "Iterate over a list"]
fn iter<T>(l: @list<T>, f: fn(T)) {
let mut cur = l;

View file

@ -4,6 +4,7 @@ import comm::send;
import comm::recv;
import future_spawn = future::spawn;
import future::future;
import core::vec::extensions;
export map, mapi, alli, any, mapi_factory;

View file

@ -3,6 +3,7 @@
import core::option;
import option::{none, some};
import rand;
import core::rand::extensions;
fn mkdtemp(prefix: str, suffix: str) -> option<str> {
let r = rand::rng();

View file

@ -7,7 +7,7 @@ The I/O task runs in its own single-threaded scheduler. By using the
"];
export iotask::{};
export iotask;
export spawn_iotask;
export interact;
export exit;

View file

@ -572,6 +572,13 @@ fn walk_pat(pat: @pat, it: fn(@pat)) {
}
}
fn view_path_id(p: @view_path) -> node_id {
alt p.node {
view_path_simple(_, _, id) | view_path_glob(_, id) |
view_path_list(_, _, id) { id }
}
}
// Local Variables:
// mode: rust
// fill-column: 78;

View file

@ -4,6 +4,9 @@ export filename;
export filemap;
export span;
export file_substr;
export fss_none;
export fss_internal;
export fss_external;
export codemap;
export expn_info;
export expn_info_;

View file

@ -18,8 +18,8 @@ import common::parser_common;
import ast::node_id;
import util::interner;
// FIXME (#1935): resolve badness
import lexer::*;//{string_reader_as_reader, tt_reader_as_reader,
//reader, string_reader, tt_reader};
import lexer::{string_reader_as_reader, tt_reader_as_reader, reader,
string_reader, tt_reader};
import diagnostic::{span_handler, mk_span_handler, mk_handler, emitter};
type parse_sess = @{

View file

@ -1,7 +1,8 @@
/*
Predicates on exprs and stmts that the pretty-printer and parser use
*/
import ast_util::*;
import ast_util::operator_prec;
fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
alt e.node {

View file

@ -5,18 +5,21 @@ import token::{can_begin_expr, is_ident, is_plain_ident};
import codemap::{span,fss_none};
import util::interner;
import ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec};
import ast::*;
import lexer::reader;
import prec::{as_prec, token_to_binop};
import attr::parser_attr;
import common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed,
seq_sep_none, token_to_str};
import common::*;//{parser_common};
seq_sep_none, token_to_str, parser_common};
import dvec::{dvec, extensions};
import vec::{push};
import ast::*;
export file_type;
export parser;
export parse_expr;
export parse_pat;
export CRATE_FILE;
export SOURCE_FILE;
// FIXME (#1893): #ast expects to find this here but it's actually
// defined in `parse` Fixing this will be easier when we have export

View file

@ -1,4 +1,3 @@
import parse::classify::*;
import parse::comments;
import parse::lexer;
import codemap::codemap;
@ -8,6 +7,7 @@ import pp::{break_offset, word, printer,
import diagnostic;
import ast_util::operator_prec;
import dvec::{dvec, extensions};
import parse::classify::*;
// The ps is stored here to prevent recursive type.
enum ann_node {

View file

@ -13,6 +13,7 @@ import std::getopts;
import io::{reader_util, writer_util};
import getopts::{optopt, optmulti, optflag, optflagopt, opt_present};
import back::{x86, x86_64};
import std::map::hashmap;
enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified,
ppm_expanded_identified }
@ -107,7 +108,7 @@ fn parse_input(sess: session, cfg: ast::crate_cfg, input: input)
}
}
fn time<T>(do_it: bool, what: str, thunk: fn@() -> T) -> T {
fn time<T>(do_it: bool, what: str, thunk: fn() -> T) -> T {
if !do_it { ret thunk(); }
let start = std::time::precise_time_s();
let rv = thunk();
@ -137,105 +138,99 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
sess.building_library = session::building_library(
sess.opts.crate_type, crate, sess.opts.test);
crate = time(time_passes, "configuration", |copy crate| {
front::config::strip_unconfigured_items(crate)
});
crate = time(time_passes, "configuration", ||
front::config::strip_unconfigured_items(crate));
crate = time(time_passes, "maybe building test harness", |copy crate| {
front::test::modify_for_testing(sess, crate)
});
crate = time(time_passes, "maybe building test harness", ||
front::test::modify_for_testing(sess, crate));
crate = time(time_passes, "expansion", |copy crate| {
syntax::ext::expand::expand_crate(
sess.parse_sess, sess.opts.cfg, crate)
});
crate = time(time_passes, "expansion", ||
syntax::ext::expand::expand_crate(sess.parse_sess, sess.opts.cfg,
crate));
if upto == cu_expand { ret {crate: crate, tcx: none}; }
crate = time(time_passes, "intrinsic injection", |copy crate| {
front::intrinsic_inject::inject_intrinsic(sess, crate)
});
crate = time(time_passes, "intrinsic injection", ||
front::intrinsic_inject::inject_intrinsic(sess, crate));
crate = time(time_passes, "core injection", |copy crate| {
front::core_inject::maybe_inject_libcore_ref(sess, crate)
});
crate = time(time_passes, "core injection", ||
front::core_inject::maybe_inject_libcore_ref(sess, crate));
time(time_passes, "building warning settings table", |copy crate| {
lint::build_settings_crate(sess, crate)
});
time(time_passes, "building warning settings table", ||
lint::build_settings_crate(sess, crate));
let ast_map = time(time_passes, "ast indexing", |copy crate| {
syntax::ast_map::map_crate(sess.diagnostic(), *crate)
});
let ast_map = time(time_passes, "ast indexing", ||
syntax::ast_map::map_crate(sess.diagnostic(), *crate));
time(time_passes, "external crate/lib resolution", |copy crate| {
creader::read_crates(
sess.diagnostic(), *crate, sess.cstore,
sess.filesearch,
session::sess_os_to_meta_os(sess.targ_cfg.os),
sess.opts.static)
});
time(time_passes, "external crate/lib resolution", ||
creader::read_crates(sess.diagnostic(), *crate, sess.cstore,
sess.filesearch,
session::sess_os_to_meta_os(sess.targ_cfg.os),
sess.opts.static));
let { def_map, exp_map, impl_map
} = time(time_passes, "resolution", |copy crate| {
resolve::resolve_crate(sess, ast_map, crate)
});
let mut def_map;
let mut impl_map;
let mut exp_map;
if sess.fast_resolve() {
let { def_map: fast_dm, exp_map: fast_em, impl_map: fast_im } =
time(time_passes, "fast resolution", ||
middle::resolve3::resolve_crate(sess, ast_map, crate));
let freevars = time(time_passes, "freevar finding", |copy crate| {
freevars::annotate_freevars(def_map, crate)
});
def_map = fast_dm;
impl_map = fast_im;
exp_map = fast_em;
} else {
let { def_map: normal_dm, exp_map: normal_em, impl_map: normal_im } =
time(time_passes, "resolution", ||
resolve::resolve_crate(sess, ast_map, crate));
let region_map = time(time_passes, "region resolution", |copy crate| {
middle::region::resolve_crate(sess, def_map, crate)
});
def_map = normal_dm;
impl_map = normal_im;
exp_map = normal_em;
}
let freevars = time(time_passes, "freevar finding", ||
freevars::annotate_freevars(def_map, crate));
let region_map = time(time_passes, "region resolution", ||
middle::region::resolve_crate(sess, def_map, crate));
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, region_map);
let ( method_map, vtable_map
) = time(time_passes, "typechecking", |copy crate| {
typeck::check_crate(ty_cx, impl_map, crate)
});
let (method_map, vtable_map) = time(time_passes, "typechecking", ||
typeck::check_crate(ty_cx,
impl_map,
crate));
time(time_passes, "const checking", |copy crate| {
middle::check_const::check_crate(
sess, crate, ast_map, def_map, method_map, ty_cx)
});
time(time_passes, "const checking", ||
middle::check_const::check_crate(sess, crate, ast_map, def_map,
method_map, ty_cx));
if upto == cu_typeck { ret {crate: crate, tcx: some(ty_cx)}; }
time(time_passes, "block-use checking", |copy crate| {
middle::block_use::check_crate(ty_cx, crate)
});
time(time_passes, "block-use checking", ||
middle::block_use::check_crate(ty_cx, crate));
time(time_passes, "loop checking", |copy crate| {
middle::check_loop::check_crate(ty_cx, crate)
});
time(time_passes, "loop checking", ||
middle::check_loop::check_crate(ty_cx, crate));
time(time_passes, "alt checking", |copy crate| {
middle::check_alt::check_crate(ty_cx, crate)
});
time(time_passes, "alt checking", ||
middle::check_alt::check_crate(ty_cx, crate));
let last_use_map = time(time_passes, "liveness checking", |copy crate| {
middle::liveness::check_crate(ty_cx, method_map, crate)
});
let last_use_map = time(time_passes, "liveness checking", ||
middle::liveness::check_crate(ty_cx, method_map, crate));
time(time_passes, "typestate checking", |copy crate| {
middle::tstate::ck::check_crate(ty_cx, crate)
});
time(time_passes, "typestate checking", ||
middle::tstate::ck::check_crate(ty_cx, crate));
let ( root_map, mutbl_map
) = time(time_passes, "borrow checking", |copy crate| {
let (root_map, mutbl_map) = time(time_passes, "borrow checking", ||
middle::borrowck::check_crate(ty_cx, method_map,
last_use_map, crate)
});
last_use_map, crate));
time(time_passes, "kind checking", |copy crate| {
kind::check_crate(ty_cx, method_map, last_use_map, crate)
});
time(time_passes, "kind checking", ||
kind::check_crate(ty_cx, method_map, last_use_map, crate));
time(time_passes, "lint checking", |copy crate| {
lint::check_crate(ty_cx, crate)
});
time(time_passes, "lint checking", || lint::check_crate(ty_cx, crate));
if upto == cu_no_trans { ret {crate: crate, tcx: some(ty_cx)}; }
let outputs = option::get(outputs);
@ -245,14 +240,12 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
impl_map: impl_map, method_map: method_map,
vtable_map: vtable_map};
let (llmod, link_meta) = time(time_passes, "translation", |copy crate| {
let (llmod, link_meta) = time(time_passes, "translation", ||
trans::base::trans_crate(sess, crate, ty_cx, outputs.obj_filename,
exp_map, maps)
});
exp_map, maps));
time(time_passes, "LLVM passes", || {
link::write::run_passes(sess, llmod, outputs.obj_filename)
});
time(time_passes, "LLVM passes", ||
link::write::run_passes(sess, llmod, outputs.obj_filename));
let stop_after_codegen =
sess.opts.output_type != link::output_type_exe ||
@ -260,10 +253,9 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
if stop_after_codegen { ret {crate: crate, tcx: some(ty_cx)}; }
time(time_passes, "linking", || {
link::link_binary(sess, outputs.obj_filename,
outputs.out_filename, link_meta)
});
time(time_passes, "linking", ||
link::link_binary(sess, outputs.obj_filename,
outputs.out_filename, link_meta));
ret {crate: crate, tcx: some(ty_cx)};
}

View file

@ -35,6 +35,7 @@ const trace: uint = 128u;
// FIXME (#2377): This exists to transition to a Rust crate runtime
// It should be removed
const no_rt: uint = 256u;
const fast_resolve: uint = 512u;
fn debugging_opts_map() -> ~[(str, str, uint)] {
~[("ppregions", "prettyprint regions with \
@ -47,7 +48,8 @@ fn debugging_opts_map() -> ~[(str, str, uint)] {
("no-asm-comments", "omit comments when using -S", no_asm_comments),
("no-verify", "skip LLVM verification", no_verify),
("trace", "emit trace logs", trace),
("no-rt", "do not link to the runtime", no_rt)
("no-rt", "do not link to the runtime", no_rt),
("fast-resolve", "use fast name resolution", fast_resolve)
]
}
@ -162,6 +164,7 @@ impl session for session {
fn no_asm_comments() -> bool { self.debugging_opt(no_asm_comments) }
fn no_verify() -> bool { self.debugging_opt(no_verify) }
fn trace() -> bool { self.debugging_opt(trace) }
fn fast_resolve() -> bool { self.debugging_opt(fast_resolve) }
}
#[doc = "Some reasonable defaults"]

View file

@ -22,6 +22,7 @@ export lookup_method_purity;
export get_enum_variants;
export get_impls_for_mod;
export get_iface_methods;
export each_path;
export get_type;
export get_impl_iface;
export get_impl_method;
@ -81,6 +82,13 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
ret result;
}
#[doc="Iterates over all the paths in the given crate."]
fn each_path(cstore: cstore::cstore, cnum: ast::crate_num,
f: fn(decoder::path_entry) -> bool) {
let crate_data = cstore::get_crate_data(cstore, cnum);
decoder::each_path(crate_data, f);
}
fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
let cstore = tcx.cstore;
let cdata = cstore::get_crate_data(cstore, def.crate);

View file

@ -6,7 +6,7 @@ import std::map::hashmap;
import syntax::{ast, attr};
import syntax::ast_util::new_def_hash;
export cstore::{};
export cstore;
export cnum_map;
export crate_metadata;
export mk_cstore;

View file

@ -1,7 +1,7 @@
// Decoding metadata from a single crate's metadata
import std::{ebml, map};
import std::map::hashmap;
import std::map::{hashmap, str_hash};
import io::writer_util;
import syntax::{ast, ast_util};
import syntax::attr;
@ -37,6 +37,12 @@ export get_crate_vers;
export get_impls_for_mod;
export get_iface_methods;
export get_crate_module_paths;
export def_like;
export dl_def;
export dl_impl;
export dl_field;
export path_entry;
export each_path;
export get_item_path;
export maybe_find_item; // sketchy
export item_type; // sketchy
@ -116,6 +122,7 @@ fn item_parent_item(d: ebml::doc) -> option<ast::def_id> {
found
}
// XXX: This has nothing to do with classes.
fn class_member_id(d: ebml::doc, cdata: cmd) -> ast::def_id {
let tagdoc = ebml::get_doc(d, tag_def_id);
ret translate_def_id(cdata, parse_def_id(ebml::doc_data(tagdoc)));
@ -257,31 +264,39 @@ fn lookup_item_name(data: @~[u8], id: ast::node_id) -> ast::ident {
item_name(lookup_item(id, data))
}
fn lookup_def(cnum: ast::crate_num, data: @~[u8], did_: ast::def_id) ->
ast::def {
let item = lookup_item(did_.node, data);
fn item_to_def_like(item: ebml::doc, did: ast::def_id, cnum: ast::crate_num)
-> def_like {
let fam_ch = item_family(item);
let did = {crate: cnum, node: did_.node};
// We treat references to enums as references to types.
alt check fam_ch {
'c' { ast::def_const(did) }
'C' { ast::def_class(did) }
'u' { ast::def_fn(did, ast::unsafe_fn) }
'f' { ast::def_fn(did, ast::impure_fn) }
'p' { ast::def_fn(did, ast::pure_fn) }
'y' { ast::def_ty(did) }
't' { ast::def_ty(did) }
'm' { ast::def_mod(did) }
'n' { ast::def_foreign_mod(did) }
alt fam_ch {
'c' { dl_def(ast::def_const(did)) }
'C' { dl_def(ast::def_class(did)) }
'u' { dl_def(ast::def_fn(did, ast::unsafe_fn)) }
'f' { dl_def(ast::def_fn(did, ast::impure_fn)) }
'p' { dl_def(ast::def_fn(did, ast::pure_fn)) }
'y' { dl_def(ast::def_ty(did)) }
't' { dl_def(ast::def_ty(did)) }
'm' { dl_def(ast::def_mod(did)) }
'n' { dl_def(ast::def_foreign_mod(did)) }
'v' {
let mut tid = option::get(item_parent_item(item));
tid = {crate: cnum, node: tid.node};
ast::def_variant(tid, did)
dl_def(ast::def_variant(tid, did))
}
'I' { ast::def_ty(did) }
'I' { dl_def(ast::def_ty(did)) }
'i' { dl_impl(did) }
'g' | 'j' { dl_field }
ch { fail #fmt("unexpected family code: '%c'", ch) }
}
}
fn lookup_def(cnum: ast::crate_num, data: @~[u8], did_: ast::def_id) ->
ast::def {
let item = lookup_item(did_.node, data);
let did = {crate: cnum, node: did_.node};
// We treat references to enums as references to types.
ret def_like_to_def(item_to_def_like(item, did, cnum));
}
fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> ty::ty_param_bounds_and_ty {
@ -356,6 +371,104 @@ fn get_symbol(data: @~[u8], id: ast::node_id) -> str {
ret item_symbol(lookup_item(id, data));
}
// Something that a name can resolve to.
enum def_like {
dl_def(ast::def),
dl_impl(ast::def_id),
dl_field
}
fn def_like_to_def(def_like: def_like) -> ast::def {
alt def_like {
dl_def(def) { ret def; }
dl_impl(*) { fail "found impl in def_like_to_def"; }
dl_field { fail "found field in def_like_to_def"; }
}
}
// A path.
class path_entry {
// The full path, separated by '::'.
let path_string: str;
// The definition, implementation, or field that this path corresponds to.
let def_like: def_like;
new(path_string: str, def_like: def_like) {
self.path_string = path_string;
self.def_like = def_like;
}
}
#[doc="Iterates over all the paths in the given crate."]
fn each_path(cdata: cmd, f: fn(path_entry) -> bool) {
let root = ebml::doc(cdata.data);
let items = ebml::get_doc(root, tag_items);
let items_data = ebml::get_doc(items, tag_items_data);
let mut broken = false;
// First, go through all the explicit items.
do ebml::tagged_docs(items_data, tag_items_data_item) |item_doc| {
if !broken {
let name = ast_map::path_to_str_with_sep(item_path(item_doc),
"::");
if name != "" {
// Extract the def ID.
let def_id = class_member_id(item_doc, cdata);
// Construct the def for this item.
#debug("(each_path) yielding explicit item: %s", name);
let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
// Hand the information off to the iteratee.
let this_path_entry = path_entry(name, def_like);
if !f(this_path_entry) {
broken = true; // XXX: This is awful.
}
}
}
}
// If broken, stop here.
if broken {
ret;
}
// Next, go through all the paths. We will find items that we didn't know
// about before (reexports in particular).
let outer_paths = ebml::get_doc(root, tag_paths);
let inner_paths = ebml::get_doc(outer_paths, tag_paths);
do ebml::tagged_docs(inner_paths, tag_paths_data_item) |path_doc| {
if !broken {
let path = item_name(path_doc);
// Extract the def ID.
let def_id = class_member_id(path_doc, cdata);
// Get the item.
alt maybe_find_item(def_id.node, items) {
none {
#debug("(each_path) ignoring implicit item: %s",
*path);
}
some(item_doc) {
// Construct the def for this item.
let def_like = item_to_def_like(item_doc, def_id,
cdata.cnum);
// Hand the information off to the iteratee.
#debug("(each_path) yielding implicit item: %s",
*path);
let this_path_entry = path_entry(*path, def_like);
if (!f(this_path_entry)) {
broken = true; // XXX: This is awful.
}
}
}
}
}
}
fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path {
item_path(lookup_item(id, cdata.data))
}
@ -441,10 +554,12 @@ fn item_impl_methods(cdata: cmd, item: ebml::doc, base_tps: uint)
rslt
}
fn get_impls_for_mod(cdata: cmd, m_id: ast::node_id,
fn get_impls_for_mod(cdata: cmd,
m_id: ast::node_id,
name: option<ast::ident>,
get_cdata: fn(ast::crate_num) -> cmd)
-> @~[@_impl] {
-> @~[@_impl] {
let data = cdata.data;
let mod_item = lookup_item(m_id, data);
let mut result = ~[];

View file

@ -385,9 +385,13 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
encode_def_id(ebml_w, local_def(id));
encode_family(ebml_w, 'm');
encode_name(ebml_w, name);
#debug("(encoding info for module) encoding info for module ID %d", id);
let impls = ecx.impl_map(id);
for impls.each |i| {
let (ident, did) = i;
#debug("(encoding info for module) ... encoding impl %s (%?), \
exported? %?",
*ident, did, ast_util::is_exported(ident, md));
if ast_util::is_exported(ident, md) {
ebml_w.start_tag(tag_mod_impl);
alt ecx.tcx.items.find(did.node) {

View file

@ -8,7 +8,9 @@ import std::map::{map,hashmap,int_hash,hash_from_strs};
import std::smallintmap::{map,smallintmap};
import io::writer_util;
import syntax::print::pprust::expr_to_str;
export lint, ctypes, unused_imports;
export lint, ctypes, unused_imports, while_true, path_statement, old_vecs;
export unrecognized_warning, non_implicitly_copyable_typarams;
export vecs_not_implicitly_copyable, implicit_copies;
export level, ignore, warn, error;
export lookup_lint, lint_dict, get_lint_dict;
export get_warning_level, get_warning_settings_level;

View file

@ -283,7 +283,7 @@ class ir_maps {
some(var) {var}
none {
self.tcx.sess.span_bug(
span, "No variable registered for this id");
span, #fmt("No variable registered for id %d", node_id));
}
}
}

3946
src/rustc/middle/resolve3.rs Normal file

File diff suppressed because it is too large Load diff

View file

@ -39,14 +39,16 @@ import link::{mangle_internal_name_by_type_only,
mangle_exported_name};
import metadata::{csearch, cstore, encoder};
import metadata::common::link_meta;
import util::ppaux;
import util::ppaux::{ty_to_str, ty_to_short_str};
import syntax::diagnostic::expect;
import common::*;
import build::*;
import shape::*;
import type_of::*;
import common::*;
import type_of::type_of; // Issue #1873
import common::result;
import syntax::ast_map::{path, path_mod, path_name};
import std::smallintmap;
@ -511,7 +513,7 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
mut drop_glue: none,
mut free_glue: none,
mut visit_glue: none};
log(debug, "--- declare_tydesc " + ty_to_str(ccx.tcx, t));
log(debug, "--- declare_tydesc " + ppaux::ty_to_str(ccx.tcx, t));
ret inf;
}
@ -1106,14 +1108,14 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue TAKE %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn = declare_generic_glue
(ccx, ti.ty, T_glue_fn(ccx), "take");
ti.take_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_take_glue, "take");
#debug("--- lazily_emit_tydesc_glue TAKE %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_drop_glue {
@ -1121,14 +1123,14 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue DROP %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "drop");
ti.drop_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_drop_glue, "drop");
#debug("--- lazily_emit_tydesc_glue DROP %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_free_glue {
@ -1136,14 +1138,14 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue FREE %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "free");
ti.free_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_free_glue, "free");
#debug("--- lazily_emit_tydesc_glue FREE %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_visit_glue {
@ -1151,14 +1153,14 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue VISIT %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "visit");
ti.visit_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_visit_glue, "visit");
#debug("--- lazily_emit_tydesc_glue VISIT %s",
ty_to_str(ccx.tcx, ti.ty));
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
}
@ -1383,7 +1385,7 @@ fn copy_val_no_check(bcx: block, action: copy_action, dst: ValueRef,
ret take_ty(bcx, dst, t);
}
ccx.sess.bug("unexpected type in trans::copy_val_no_check: " +
ty_to_str(ccx.tcx, t));
ppaux::ty_to_str(ccx.tcx, t));
}
@ -1422,7 +1424,7 @@ fn move_val(cx: block, action: copy_action, dst: ValueRef,
ret cx;
}
cx.sess().bug("unexpected type in trans::move_val: " +
ty_to_str(tcx, t));
ppaux::ty_to_str(tcx, t));
}
fn store_temp_expr(cx: block, action: copy_action, dst: ValueRef,
@ -1810,7 +1812,7 @@ fn autoderef(cx: block, e_id: ast::node_id,
let mut derefs = 0u;
while derefs < max {
#debug["autoderef(e_id=%d, v1=%s, t1=%s, derefs=%u)",
e_id, val_str(ccx.tn, v1), ty_to_str(ccx.tcx, t1),
e_id, val_str(ccx.tn, v1), ppaux::ty_to_str(ccx.tcx, t1),
derefs];
// root the autoderef'd value, if necessary:
@ -2140,7 +2142,6 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id,
for real_substs.each() |s| { assert !ty::type_has_params(s); }
for substs.each() |s| { assert !ty::type_has_params(s); }
let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len());
let hash_id = make_mono_id(ccx, fn_id, substs, vtables, some(param_uses));
if vec::any(hash_id.params,
@ -2156,6 +2157,8 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id,
alt ccx.monomorphized.find(hash_id) {
some(val) {
#debug["leaving monomorphic fn %s",
ty::item_path_str(ccx.tcx, fn_id)];
ret {val: val, must_cast: must_cast};
}
none {}
@ -2286,6 +2289,8 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id,
}
};
ccx.monomorphizing.insert(fn_id, depth);
#debug["leaving monomorphic fn %s", ty::item_path_str(ccx.tcx, fn_id)];
{val: lldecl, must_cast: must_cast}
}
@ -3056,7 +3061,7 @@ fn adapt_borrowed_value(lv: lval_result,
_ {
bcx.tcx().sess.span_bug(
e.span, #fmt["cannot borrow a value of type %s",
ty_to_str(bcx.tcx(), e_ty)]);
ppaux::ty_to_str(bcx.tcx(), e_ty)]);
}
}
}
@ -3517,7 +3522,7 @@ fn add_root_cleanup(bcx: block, scope_id: ast::node_id,
#debug["add_root_cleanup(bcx=%s, scope_id=%d, root_loc=%s, ty=%s)",
bcx.to_str(), scope_id, val_str(bcx.ccx().tn, root_loc),
ty_to_str(bcx.ccx().tcx, ty)];
ppaux::ty_to_str(bcx.ccx().tcx, ty)];
let bcx_scope = find_bcx_for_scope(bcx, scope_id);
add_clean_temp_mem(bcx_scope, root_loc, ty);
@ -3614,7 +3619,8 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
alt check ty::get(expr_ty(bcx, e)).struct {
ty::ty_fn({proto, _}) {
#debug("translating fn_block %s with type %s",
expr_to_str(e), ty_to_str(tcx, expr_ty(bcx, e)));
expr_to_str(e),
ppaux::ty_to_str(tcx, expr_ty(bcx, e)));
ret closure::trans_expr_fn(bcx, proto, decl, body,
e.id, cap_clause, none, dest);
}
@ -3754,7 +3760,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
let ptr_ty = expr_ty(bcx, e);
let ptr_ptr_val = alloc_ty(bcx, ptr_ty);
#debug["ptr_ty = %s", ty_to_str(tcx, ptr_ty)];
#debug["ptr_ty = %s", ppaux::ty_to_str(tcx, ptr_ty)];
#debug["ptr_ptr_val = %s", val_str(ccx.tn, ptr_ptr_val)];
let void_ty = ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx),
@ -3947,7 +3953,7 @@ fn trans_fail_expr(bcx: block, sp_opt: option<span>,
} else {
bcx.sess().span_bug(
expr.span, "fail called with unsupported type " +
ty_to_str(tcx, e_ty));
ppaux::ty_to_str(tcx, e_ty));
}
}
_ { ret trans_fail(bcx, sp_opt, "explicit failure"); }
@ -4345,7 +4351,7 @@ fn alloc_ty(bcx: block, t: ty::t) -> ValueRef {
let _icx = bcx.insn_ctxt("alloc_ty");
let ccx = bcx.ccx();
let llty = type_of(ccx, t);
if ty::type_has_params(t) { log(error, ty_to_str(ccx.tcx, t)); }
if ty::type_has_params(t) { log(error, ppaux::ty_to_str(ccx.tcx, t)); }
assert !ty::type_has_params(t);
let val = alloca(bcx, llty);
ret val;

View file

@ -264,6 +264,9 @@ fn store_environment(bcx: block,
bcx = move_val(bcx, INIT, bound_data, src, ty);
}
env_ref(val, ty, owned) {
#debug["> storing %s into %s",
val_str(bcx.ccx().tn, val),
val_str(bcx.ccx().tn, bound_data)];
Store(bcx, val, bound_data);
}
env_ref(val, ty, owned_imm) {
@ -298,6 +301,8 @@ fn build_closure(bcx0: block,
#debug["Building closure: captured variable %?", cap_var];
let lv = trans_local_var(bcx, cap_var.def);
let nid = ast_util::def_id_of_def(cap_var.def).node;
#debug["Node id is %s",
syntax::ast_map::node_id_to_str(bcx.ccx().tcx.items, nid)];
let mut ty = node_id_type(bcx, nid);
alt cap_var.mode {
capture::cap_ref {

View file

@ -9,8 +9,7 @@ import lib::llvm::{ llvm, TypeRef, ValueRef,
ModuleRef, CallConv, Attribute,
StructRetAttribute, ByValAttribute,
SequentiallyConsistent, Acquire, Release,
Xchg, Add, Sub
};
Xchg };
import syntax::{ast, ast_util};
import back::{link, abi};
import common::*;
@ -830,42 +829,42 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
Store(bcx, old, fcx.llretptr);
}
"atomic_add" {
let old = AtomicRMW(bcx, Add,
let old = AtomicRMW(bcx, lib::llvm::Add,
get_param(decl, first_real_arg),
get_param(decl, first_real_arg + 1u),
SequentiallyConsistent);
Store(bcx, old, fcx.llretptr);
}
"atomic_add_acq" {
let old = AtomicRMW(bcx, Add,
let old = AtomicRMW(bcx, lib::llvm::Add,
get_param(decl, first_real_arg),
get_param(decl, first_real_arg + 1u),
Acquire);
Store(bcx, old, fcx.llretptr);
}
"atomic_add_rel" {
let old = AtomicRMW(bcx, Add,
let old = AtomicRMW(bcx, lib::llvm::Add,
get_param(decl, first_real_arg),
get_param(decl, first_real_arg + 1u),
Release);
Store(bcx, old, fcx.llretptr);
}
"atomic_sub" {
let old = AtomicRMW(bcx, Sub,
let old = AtomicRMW(bcx, lib::llvm::Sub,
get_param(decl, first_real_arg),
get_param(decl, first_real_arg + 1u),
SequentiallyConsistent);
Store(bcx, old, fcx.llretptr);
}
"atomic_sub_acq" {
let old = AtomicRMW(bcx, Sub,
let old = AtomicRMW(bcx, lib::llvm::Sub,
get_param(decl, first_real_arg),
get_param(decl, first_real_arg + 1u),
Acquire);
Store(bcx, old, fcx.llretptr);
}
"atomic_sub_rel" {
let old = AtomicRMW(bcx, Sub,
let old = AtomicRMW(bcx, lib::llvm::Sub,
get_param(decl, first_real_arg),
get_param(decl, first_real_arg + 1u),
Release);

View file

@ -81,6 +81,18 @@ fn traverse_public_mod(cx: ctx, m: _mod) {
if !traverse_exports(cx, m.view_items) {
// No exports, so every local item is exported
for vec::each(m.items) |item| { traverse_public_item(cx, item); }
} else {
// Make impls always reachable.
for vec::each(m.items) |item| {
alt item.node {
item_impl(*) {
traverse_public_item(cx, item);
}
_ {
// Nothing to do.
}
}
}
}
}

View file

@ -5,8 +5,6 @@ import lib::llvm::llvm;
import driver::session::session;
import std::map::hashmap;
import ty::*;
export type_of;
export type_of_dtor;
export type_of_explicit_args;
@ -174,7 +172,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
alt ty::get(t).struct {
ty::ty_class(did, ts) {
// Only instance vars are record fields at runtime.
let fields = lookup_class_fields(cx.tcx, did);
let fields = ty::lookup_class_fields(cx.tcx, did);
let mut tys = do vec::map(fields) |f| {
let t = ty::lookup_field_type(cx.tcx, did, f.id, ts);
type_of(cx, t)

View file

@ -11,11 +11,11 @@ import syntax::codemap::span;
import metadata::csearch;
import util::ppaux::region_to_str;
import util::ppaux::vstore_to_str;
import util::ppaux::{ty_to_str, tys_to_str, ty_constr_to_str};
import middle::lint::{get_warning_level, vecs_not_implicitly_copyable,
ignore};
import syntax::ast::*;
import syntax::print::pprust::*;
import util::ppaux::{ty_to_str, tys_to_str, ty_constr_to_str};
export tv_vid, tvi_vid, region_vid, vid;
export br_hashmap;
@ -105,7 +105,10 @@ export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
export ty_var, mk_var, type_is_var;
export ty_var_integral, mk_var_integral, type_is_var_integral;
export ty_self, mk_self, type_has_self;
export ty_class;
export region, bound_region, encl_region;
export re_bound, re_free, re_scope, re_static, re_var;
export br_self, br_anon, br_named;
export get, type_has_params, type_needs_infer, type_has_regions;
export type_has_resources, type_id;
export tbox_has_flag;
@ -2528,6 +2531,7 @@ fn iface_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
fn impl_iface(cx: ctxt, id: ast::def_id) -> option<t> {
if id.crate == ast::local_crate {
#debug("(impl_iface) searching for iface impl %?", id);
alt cx.items.find(id.node) {
some(ast_map::node_item(@{node: ast::item_impl(
_, _, some(@{id: id, _}), _, _), _}, _)) {
@ -2537,11 +2541,16 @@ fn impl_iface(cx: ctxt, id: ast::def_id) -> option<t> {
_},_)) {
alt cx.def_map.find(id.node) {
some(def_ty(iface_id)) {
some(node_id_to_type(cx, id.node))
// XXX: Doesn't work cross-crate.
#debug("(impl_iface) found iface id %?", iface_id);
some(node_id_to_type(cx, iface_id.node))
}
_ {
cx.sess.bug("impl_iface: iface ref isn't in iface map \
and isn't bound to a def_ty");
some(x) {
cx.sess.bug(#fmt("impl_iface: iface ref is in iface map \
but is bound to %?", x));
}
none {
none
}
}
}

View file

@ -53,8 +53,6 @@ import middle::ty;
import middle::ty::{arg, field, node_type_table, mk_nil,
ty_param_bounds_and_ty, lookup_public_fields};
import middle::typeck::infer::methods;
import util::ppaux::{ty_to_str, tys_to_str, region_to_str,
bound_region_to_str, vstore_to_str};
import std::smallintmap;
import std::smallintmap::map;
import std::map;
@ -62,6 +60,8 @@ import std::map::{hashmap, int_hash};
import std::serialization::{serialize_uint, deserialize_uint};
import vec::each;
import syntax::print::pprust::*;
import util::ppaux::{ty_to_str, tys_to_str, region_to_str,
bound_region_to_str, vstore_to_str};
import util::common::{indent, indenter};
import std::list;
import list::{list, nil, cons};

View file

@ -74,6 +74,8 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
alt check ty::get(ity).struct {
ty::ty_iface(idid, substs) {
if iface_id == idid {
#debug("(checking vtable) @0 relating ty to iface ty
with did %?", idid);
relate_iface_tys(fcx, sp, iface_ty, ity);
ret vtable_param(n, n_bound);
}
@ -86,6 +88,9 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
}
ty::ty_iface(did, substs) if iface_id == did {
#debug("(checking vtable) @1 relating ty to iface ty with did %?",
did);
relate_iface_tys(fcx, sp, iface_ty, ty);
if !allow_unsafe {
for vec::each(*ty::iface_methods(tcx, did)) |m| {
@ -134,6 +139,10 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
}
// check that desired iface type unifies
#debug("(checking vtable) @2 relating iface ty %s to \
of_ty %s",
fcx.infcx.ty_to_str(iface_ty),
fcx.infcx.ty_to_str(of_ty));
let of_ty = ty::subst(tcx, substs, of_ty);
relate_iface_tys(fcx, sp, iface_ty, of_ty);
@ -186,6 +195,8 @@ fn connect_iface_tps(fcx: @fn_ctxt, sp: span, impl_tys: ~[ty::t],
let tcx = fcx.ccx.tcx;
let ity = option::get(ty::impl_iface(tcx, impl_did));
let iface_ty = ty::subst_tps(tcx, impl_tys, ity);
#debug("(connect iface tps) iface type is %?, impl did is %?",
ty::get(iface_ty).struct, impl_did);
alt check ty::get(iface_ty).struct {
ty::ty_iface(_, substs) {
vec::iter2(substs.tps, iface_tys,

View file

@ -52,6 +52,7 @@ mod middle {
}
mod ty;
mod resolve;
mod resolve3;
mod typeck {
mod check {
mod alt;

View file

@ -24,7 +24,7 @@ import rustc::middle::resolve;
export ctxt;
export ctxt_handler;
export srv::{};
export srv;
export from_str;
export from_file;
export exec;

View file

@ -1,3 +1,5 @@
// xfail-test
import to_str::*;
import to_str::to_str;
@ -45,4 +47,4 @@ fn print_out<T: to_str>(thing: T, expected: str) {
fn main() {
let nyan : to_str = cat(0u, 2, "nyan") as to_str;
print_out(nyan, "nyan");
}
}

View file

@ -1,3 +1,5 @@
// xfail-test
use std;
import std::map::{map, hashmap, int_hash};

View file

@ -1,4 +1,6 @@
// xfail-test
// xfail-fast
use std;
import std::map::*;

View file

@ -1,3 +1,5 @@
// xfail-test
use std;
import std::map::*;
import vec::*;
@ -116,4 +118,4 @@ fn main() {
assert(nyan.meow_count() == 10u);
assert(bite_everything(nyan as bitey));
assert(scratched_something(nyan as scratchy));
}
}

View file

@ -1,3 +1,6 @@
// xfail-test
// xfail-fast
// (Not sure why, though -- FIXME (tjc)
import to_str::*;
import to_str::to_str;

View file

@ -1,8 +1,10 @@
// Test that a glob-export functions as an import
// when referenced within its own local scope.
// Modified to not use export since it's going away. --pcw
mod foo {
export bar::*;
import bar::*;
mod bar {
const a : int = 10;
}

View file

@ -1,8 +1,11 @@
// Test that a glob-export functions as an explicit
// named export when referenced from outside its scope.
// Modified to not use export since it's going away. --pcw
mod foo {
export bar::*;
import bar::*;
export a;
mod bar {
const a : int = 10;
}