diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index df3a40c2289..5fe1a5f7233 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -130,8 +130,8 @@ pub enum input { } pub fn phase_1_parse_input(sess: Session, cfg: ast::CrateConfig, input: &input) - -> @ast::Crate { - time(sess.time_passes(), ~"parsing", || { + -> ast::Crate { + time(sess.time_passes(), ~"parsing", (), |_| { match *input { file_input(ref file) => { parse::parse_crate_from_file(&(*file), cfg.clone(), sess.parse_sess) @@ -153,11 +153,11 @@ pub fn phase_1_parse_input(sess: Session, cfg: ast::CrateConfig, input: &input) /// standard library and prelude. pub fn phase_2_configure_and_expand(sess: Session, cfg: ast::CrateConfig, - mut crate: @ast::Crate) -> @ast::Crate { + mut crate: ast::Crate) -> ast::Crate { let time_passes = sess.time_passes(); *sess.building_library = session::building_library(sess.opts.crate_type, - crate, sess.opts.test); + &crate, sess.opts.test); // strip before expansion to allow macros to depend on @@ -167,29 +167,29 @@ pub fn phase_2_configure_and_expand(sess: Session, // mod bar { macro_rules! baz!(() => {{}}) } // // baz! should not use this definition unless foo is enabled. - crate = time(time_passes, ~"std macros injection", || + crate = time(time_passes, ~"std macros injection", crate, |crate| syntax::ext::expand::inject_std_macros(sess.parse_sess, cfg.clone(), crate)); - crate = time(time_passes, ~"configuration 1", || + crate = time(time_passes, ~"configuration 1", crate, |crate| front::config::strip_unconfigured_items(crate)); - crate = time(time_passes, ~"expansion", || + crate = time(time_passes, ~"expansion", crate, |crate| syntax::ext::expand::expand_crate(sess.parse_sess, cfg.clone(), crate)); // strip again, in case expansion added anything with a #[cfg]. - crate = time(time_passes, ~"configuration 2", || + crate = time(time_passes, ~"configuration 2", crate, |crate| front::config::strip_unconfigured_items(crate)); - crate = time(time_passes, ~"maybe building test harness", || + crate = time(time_passes, ~"maybe building test harness", crate, |crate| front::test::modify_for_testing(sess, crate)); - crate = time(time_passes, ~"std injection", || + crate = time(time_passes, ~"std injection", crate, |crate| front::std_inject::maybe_inject_libstd_ref(sess, crate)); - crate = time(time_passes, ~"assigning node ids", || + crate = time(time_passes, ~"assigning node ids", crate, |crate| front::assign_node_ids::assign_node_ids(sess, crate)); return crate; @@ -207,21 +207,21 @@ pub struct CrateAnalysis { /// miscellaneous analysis passes on the crate. Return various /// structures carrying the results of the analysis. pub fn phase_3_run_analysis_passes(sess: Session, - crate: @ast::Crate) -> CrateAnalysis { + crate: &ast::Crate) -> CrateAnalysis { let time_passes = sess.time_passes(); - let ast_map = time(time_passes, ~"ast indexing", || + let ast_map = time(time_passes, ~"ast indexing", (), |_| syntax::ast_map::map_crate(sess.diagnostic(), crate)); - time(time_passes, ~"external crate/lib resolution", || + 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.is_static, token::get_ident_interner())); - let lang_items = time(time_passes, ~"language item collection", || + let lang_items = time(time_passes, ~"language item collection", (), |_| middle::lang_items::collect_language_items(crate, sess)); let middle::resolve::CrateMap { @@ -229,19 +229,19 @@ pub fn phase_3_run_analysis_passes(sess: Session, exp_map2: exp_map2, trait_map: trait_map } = - time(time_passes, ~"resolution", || + time(time_passes, ~"resolution", (), |_| middle::resolve::resolve_crate(sess, lang_items, crate)); - time(time_passes, ~"looking for entry point", - || middle::entry::find_entry_point(sess, crate, ast_map)); + time(time_passes, ~"looking for entry point", (), + |_| middle::entry::find_entry_point(sess, crate, ast_map)); - let freevars = time(time_passes, ~"freevar finding", || + let freevars = time(time_passes, ~"freevar finding", (), |_| freevars::annotate_freevars(def_map, crate)); - let region_map = time(time_passes, ~"region resolution", || + let region_map = time(time_passes, ~"region resolution", (), |_| middle::region::resolve_crate(sess, def_map, crate)); - let rp_set = time(time_passes, ~"region parameterization inference", || + let rp_set = time(time_passes, ~"region parameterization inference", (), |_| middle::region::determine_rp_in_crate(sess, ast_map, def_map, crate)); let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, @@ -252,53 +252,53 @@ pub fn phase_3_run_analysis_passes(sess: Session, ty_cx, trait_map, crate); // These next two const passes can probably be merged - time(time_passes, ~"const marking", || + time(time_passes, ~"const marking", (), |_| middle::const_eval::process_crate(crate, ty_cx)); - time(time_passes, ~"const checking", || + time(time_passes, ~"const checking", (), |_| middle::check_const::check_crate(sess, crate, ast_map, def_map, method_map, ty_cx)); let exported_items = - time(time_passes, ~"privacy checking", || + time(time_passes, ~"privacy checking", (), |_| middle::privacy::check_crate(ty_cx, &method_map, &exp_map2, crate)); - time(time_passes, ~"effect checking", || + time(time_passes, ~"effect checking", (), |_| middle::effect::check_crate(ty_cx, method_map, crate)); - time(time_passes, ~"loop checking", || + time(time_passes, ~"loop checking", (), |_| middle::check_loop::check_crate(ty_cx, crate)); - time(time_passes, ~"stack checking", || + time(time_passes, ~"stack checking", (), |_| middle::stack_check::stack_check_crate(ty_cx, crate)); let middle::moves::MoveMaps {moves_map, moved_variables_set, capture_map} = - time(time_passes, ~"compute moves", || + time(time_passes, ~"compute moves", (), |_| middle::moves::compute_moves(ty_cx, method_map, crate)); - time(time_passes, ~"match checking", || + time(time_passes, ~"match checking", (), |_| middle::check_match::check_crate(ty_cx, method_map, moves_map, crate)); - time(time_passes, ~"liveness checking", || + time(time_passes, ~"liveness checking", (), |_| middle::liveness::check_crate(ty_cx, method_map, capture_map, crate)); let (root_map, write_guard_map) = - time(time_passes, ~"borrow checking", || + time(time_passes, ~"borrow checking", (), |_| middle::borrowck::check_crate(ty_cx, method_map, moves_map, moved_variables_set, capture_map, crate)); - time(time_passes, ~"kind checking", || + time(time_passes, ~"kind checking", (), |_| kind::check_crate(ty_cx, method_map, crate)); let reachable_map = - time(time_passes, ~"reachability checking", || + time(time_passes, ~"reachability checking", (), |_| reachable::find_reachable(ty_cx, method_map, crate)); - time(time_passes, ~"lint checking", || + time(time_passes, ~"lint checking", (), |_| lint::check_crate(ty_cx, crate)); CrateAnalysis { @@ -325,10 +325,10 @@ pub struct CrateTranslation { /// Run the translation phase to LLVM, after which the AST and analysis can /// be discarded. pub fn phase_4_translate_to_llvm(sess: Session, - crate: @ast::Crate, + crate: ast::Crate, analysis: &CrateAnalysis, outputs: &OutputFilenames) -> CrateTranslation { - time(sess.time_passes(), ~"translation", || + time(sess.time_passes(), ~"translation", crate, |crate| trans::base::trans_crate(sess, crate, analysis, &outputs.obj_filename)) } @@ -349,7 +349,7 @@ pub fn phase_5_run_llvm_passes(sess: Session, let output_type = link::output_type_assembly; let asm_filename = outputs.obj_filename.with_filetype("s"); - time(sess.time_passes(), ~"LLVM passes", || + time(sess.time_passes(), ~"LLVM passes", (), |_| link::write::run_passes(sess, trans.context, trans.module, @@ -363,7 +363,7 @@ pub fn phase_5_run_llvm_passes(sess: Session, os::remove_file(&asm_filename); } } else { - time(sess.time_passes(), ~"LLVM passes", || + time(sess.time_passes(), ~"LLVM passes", (), |_| link::write::run_passes(sess, trans.context, trans.module, @@ -377,7 +377,7 @@ pub fn phase_5_run_llvm_passes(sess: Session, pub fn phase_6_link_output(sess: Session, trans: &CrateTranslation, outputs: &OutputFilenames) { - time(sess.time_passes(), ~"linking", || + time(sess.time_passes(), ~"linking", (), |_| link::link_binary(sess, &outputs.obj_filename, &outputs.out_filename, @@ -430,7 +430,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input, if stop_after_phase_1(sess) { return; } phase_2_configure_and_expand(sess, cfg, crate) }; - let analysis = phase_3_run_analysis_passes(sess, expanded_crate); + let analysis = phase_3_run_analysis_passes(sess, &expanded_crate); if stop_after_phase_3(sess) { return; } let outputs = build_output_filenames(input, outdir, output, [], sess); let trans = phase_4_translate_to_llvm(sess, expanded_crate, @@ -535,7 +535,7 @@ pub fn pretty_print_input(sess: Session, } as @pprust::pp_ann } PpmTyped => { - let analysis = phase_3_run_analysis_passes(sess, crate); + let analysis = phase_3_run_analysis_passes(sess, &crate); @TypedAnnotation { analysis: analysis } as @pprust::pp_ann @@ -548,7 +548,7 @@ pub fn pretty_print_input(sess: Session, pprust::print_crate(sess.codemap, token::get_ident_interner(), sess.span_diagnostic, - crate, + &crate, source_name(input), rdr, io::stdout(), diff --git a/src/librustc/front/assign_node_ids.rs b/src/librustc/front/assign_node_ids.rs index fc1b034de97..3d0b32fcee0 100644 --- a/src/librustc/front/assign_node_ids.rs +++ b/src/librustc/front/assign_node_ids.rs @@ -24,9 +24,9 @@ impl ast_fold for NodeIdAssigner { } } -pub fn assign_node_ids(sess: Session, crate: @ast::Crate) -> @ast::Crate { +pub fn assign_node_ids(sess: Session, crate: ast::Crate) -> ast::Crate { let fold = NodeIdAssigner { sess: sess, }; - @fold.fold_crate(crate) + fold.fold_crate(crate) } diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index efaebcca011..b99e154853e 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -18,9 +18,10 @@ struct Context<'self> { // Support conditional compilation by transforming the AST, stripping out // any items that do not belong in the current configuration -pub fn strip_unconfigured_items(crate: @ast::Crate) -> @ast::Crate { +pub fn strip_unconfigured_items(crate: ast::Crate) -> ast::Crate { + let config = crate.config.clone(); do strip_items(crate) |attrs| { - in_cfg(crate.config, attrs) + in_cfg(config, attrs) } } @@ -40,13 +41,13 @@ impl<'self> fold::ast_fold for Context<'self> { } } -pub fn strip_items(crate: &ast::Crate, +pub fn strip_items(crate: ast::Crate, in_cfg: &fn(attrs: &[ast::Attribute]) -> bool) - -> @ast::Crate { + -> ast::Crate { let ctxt = Context { in_cfg: in_cfg, }; - @ctxt.fold_crate(crate) + ctxt.fold_crate(crate) } fn filter_item(cx: &Context, item: @ast::item) -> Option<@ast::item> { diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index ad5575f14a7..2253f151ddf 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -22,9 +22,9 @@ use syntax::opt_vec; static STD_VERSION: &'static str = "0.9-pre"; -pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::Crate) - -> @ast::Crate { - if use_std(crate) { +pub fn maybe_inject_libstd_ref(sess: Session, crate: ast::Crate) + -> ast::Crate { + if use_std(&crate) { inject_libstd_ref(sess, crate) } else { crate @@ -51,7 +51,7 @@ struct StandardLibraryInjector { } impl fold::ast_fold for StandardLibraryInjector { - fn fold_crate(&self, crate: &ast::Crate) -> ast::Crate { + fn fold_crate(&self, crate: ast::Crate) -> ast::Crate { let version = STD_VERSION.to_managed(); let vi1 = ast::view_item { node: ast::view_item_extern_mod(self.sess.ident_of("std"), @@ -77,10 +77,9 @@ impl fold::ast_fold for StandardLibraryInjector { new_module = self.fold_mod(&new_module); } - // FIXME #2543: Bad copy. ast::Crate { module: new_module, - ..(*crate).clone() + ..crate } } @@ -133,9 +132,9 @@ impl fold::ast_fold for StandardLibraryInjector { } } -fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate { +fn inject_libstd_ref(sess: Session, crate: ast::Crate) -> ast::Crate { let fold = StandardLibraryInjector { sess: sess, }; - @fold.fold_crate(crate) + fold.fold_crate(crate) } diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 4ac398d351f..254116bd507 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -37,17 +37,17 @@ struct Test { struct TestCtxt { sess: session::Session, - crate: @ast::Crate, path: ~[ast::Ident], ext_cx: @ExtCtxt, - testfns: ~[Test] + testfns: ~[Test], + is_extra: bool, + config: ast::CrateConfig, } // Traverse the crate, collecting all the test functions, eliding any // existing main functions, and synthesizing a main test harness pub fn modify_for_testing(sess: session::Session, - crate: @ast::Crate) - -> @ast::Crate { + crate: ast::Crate) -> ast::Crate { // We generate the test harness when building in the 'test' // configuration, either with the '--test' or '--cfg test' // command line options. @@ -65,7 +65,7 @@ struct TestHarnessGenerator { } impl fold::ast_fold for TestHarnessGenerator { - fn fold_crate(&self, c: &ast::Crate) -> ast::Crate { + fn fold_crate(&self, c: ast::Crate) -> ast::Crate { let folded = fold::noop_fold_crate(c, self); // Add a special __test module to the crate that will contain code @@ -141,14 +141,15 @@ impl fold::ast_fold for TestHarnessGenerator { } } -fn generate_test_harness(sess: session::Session, crate: @ast::Crate) - -> @ast::Crate { +fn generate_test_harness(sess: session::Session, crate: ast::Crate) + -> ast::Crate { let cx: @mut TestCtxt = @mut TestCtxt { sess: sess, - crate: crate, ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone()), path: ~[], - testfns: ~[] + testfns: ~[], + is_extra: is_extra(&crate), + config: crate.config.clone(), }; let ext_cx = cx.ext_cx; @@ -163,12 +164,12 @@ fn generate_test_harness(sess: session::Session, crate: @ast::Crate) let fold = TestHarnessGenerator { cx: cx }; - let res = @fold.fold_crate(&*crate); + let res = fold.fold_crate(crate); ext_cx.bt_pop(); return res; } -fn strip_test_functions(crate: &ast::Crate) -> @ast::Crate { +fn strip_test_functions(crate: ast::Crate) -> ast::Crate { // When not compiling with --test we should not compile the // #[test] functions do config::strip_items(crate) |attrs| { @@ -234,7 +235,7 @@ fn is_ignored(cx: @mut TestCtxt, i: @ast::item) -> bool { do i.attrs.iter().any |attr| { // check ignore(cfg(foo, bar)) "ignore" == attr.name() && match attr.meta_item_list() { - Some(ref cfgs) => attr::test_cfg(cx.crate.config, cfgs.iter().map(|x| *x)), + Some(ref cfgs) => attr::test_cfg(cx.config, cfgs.iter().map(|x| *x)), None => true } } @@ -273,7 +274,7 @@ mod __test { fn mk_std(cx: &TestCtxt) -> ast::view_item { let id_extra = cx.sess.ident_of("extra"); - let vi = if is_extra(cx) { + let vi = if cx.is_extra { ast::view_item_use( ~[@nospan(ast::view_path_simple(id_extra, path_node(~[id_extra]), @@ -371,8 +372,8 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item { )).unwrap() } -fn is_extra(cx: &TestCtxt) -> bool { - let items = attr::find_linkage_metas(cx.crate.attrs); +fn is_extra(crate: &ast::Crate) -> bool { + let items = attr::find_linkage_metas(crate.attrs); match attr::last_meta_item_value_str_by_name(items, "name") { Some(s) if "extra" == s => true, _ => false diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 331bd25e359..3c6ebc9311d 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -135,7 +135,7 @@ pub type LintDict = HashMap<&'static str, LintSpec>; enum AttributedNode<'self> { Item(@ast::item), Method(&'self ast::method), - Crate(@ast::Crate), + Crate(&'self ast::Crate), } #[deriving(Eq)] @@ -1565,7 +1565,7 @@ impl Visitor<@mut Context> for LintCheckVisitor { } } -pub fn check_crate(tcx: ty::ctxt, crate: @ast::Crate) { +pub fn check_crate(tcx: ty::ctxt, crate: &ast::Crate) { let cx = @mut Context { dict: @get_lint_dict(), curr: SmallIntMap::new(), diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 07ec4bc27fb..718f8005b74 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -268,7 +268,7 @@ impl ReachableContext { // Step 1: Mark all public symbols, and add all public symbols that might // be inlined to a worklist. - fn mark_public_symbols(&self, crate: @Crate) { + fn mark_public_symbols(&self, crate: &Crate) { let reachable_symbols = self.reachable_symbols; let worklist = self.worklist; @@ -429,7 +429,7 @@ impl ReachableContext { pub fn find_reachable(tcx: ty::ctxt, method_map: typeck::method_map, - crate: @Crate) + crate: &Crate) -> @mut HashSet { // XXX(pcwalton): We only need to mark symbols that are exported. But this // is more complicated than just looking at whether the symbol is `pub`, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index a01f4f04246..1bc4f18cce9 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -37,7 +37,6 @@ use syntax::opt_vec::OptVec; use syntax::visit; use syntax::visit::Visitor; -use std::str; use std::uint; use std::hashmap::{HashMap, HashSet}; use std::util; @@ -803,8 +802,7 @@ pub fn namespace_error_to_str(ns: NamespaceError) -> &'static str { pub fn Resolver(session: Session, lang_items: LanguageItems, - crate: @Crate) - -> Resolver { + crate_span: Span) -> Resolver { let graph_root = @mut NameBindings(); graph_root.define_module(Public, @@ -812,14 +810,13 @@ pub fn Resolver(session: Session, Some(DefId { crate: 0, node: 0 }), NormalModuleKind, false, - crate.span); + crate_span); let current_module = graph_root.get_module(); let this = Resolver { session: @session, lang_items: lang_items, - crate: crate, // The outermost module has def ID 0; this is not reflected in the // AST. @@ -862,7 +859,6 @@ pub fn Resolver(session: Session, pub struct Resolver { session: @Session, lang_items: LanguageItems, - crate: @Crate, intr: @ident_interner, @@ -959,8 +955,8 @@ impl<'self> Visitor<()> for UnusedImportCheckVisitor<'self> { impl Resolver { /// The main name resolution procedure. - pub fn resolve(&mut self) { - self.build_reduced_graph(); + pub fn resolve(&mut self, crate: &ast::Crate) { + self.build_reduced_graph(crate); self.session.abort_if_errors(); self.resolve_imports(); @@ -969,10 +965,10 @@ impl Resolver { self.record_exports(); self.session.abort_if_errors(); - self.resolve_crate(); + self.resolve_crate(crate); self.session.abort_if_errors(); - self.check_for_unused_imports(); + self.check_for_unused_imports(crate); } // @@ -983,12 +979,12 @@ impl Resolver { // /// Constructs the reduced graph for the entire crate. - pub fn build_reduced_graph(&mut self) { + pub fn build_reduced_graph(&mut self, crate: &ast::Crate) { let initial_parent = ModuleReducedGraphParent(self.graph_root.get_module()); let mut visitor = BuildReducedGraphVisitor { resolver: self, }; - visit::walk_crate(&mut visitor, self.crate, initial_parent); + visit::walk_crate(&mut visitor, crate, initial_parent); } /// Returns the current module tracked by the reduced graph parent. @@ -3554,10 +3550,10 @@ impl Resolver { return None; } - pub fn resolve_crate(&mut self) { + pub fn resolve_crate(&mut self, crate: &ast::Crate) { debug!("(resolving crate) starting"); - visit::walk_crate(self, self.crate, ()); + visit::walk_crate(self, crate, ()); } pub fn resolve_item(&mut self, item: @item) { @@ -4986,40 +4982,6 @@ impl Resolver { } } - pub fn name_exists_in_scope_struct(&mut self, name: &str) -> bool { - let this = &mut *self; - - let mut i = this.type_ribs.len(); - while i != 0 { - i -= 1; - match this.type_ribs[i].kind { - MethodRibKind(node_id, _) => - for item in this.crate.module.items.iter() { - if item.id == node_id { - match item.node { - item_struct(class_def, _) => { - for field in class_def.fields.iter() { - match field.node.kind { - unnamed_field => {}, - named_field(ident, _) => { - if str::eq_slice(this.session.str_of(ident), - name) { - return true - } - } - } - } - } - _ => {} - } - } - }, - _ => {} - } - } - return false; - } - pub fn resolve_expr(&mut self, expr: @Expr) { // First, record candidate traits for this expression if it could // result in the invocation of a method call. @@ -5060,47 +5022,38 @@ impl Resolver { } None => { let wrong_name = self.path_idents_to_str(path); - if self.name_exists_in_scope_struct(wrong_name) { - self.resolve_error(expr.span, - fmt!("unresolved name `%s`. \ - Did you mean `self.%s`?", - wrong_name, - wrong_name)); - } - else { - // Be helpful if the name refers to a struct - // (The pattern matching def_tys where the id is in self.structs - // matches on regular structs while excluding tuple- and enum-like - // structs, which wouldn't result in this error.) - match self.with_no_errors(|this| - this.resolve_path(expr.id, path, TypeNS, false)) { - Some(DefTy(struct_id)) - if self.structs.contains(&struct_id) => { - self.resolve_error(expr.span, - fmt!("`%s` is a structure name, but this expression \ - uses it like a function name", wrong_name)); + // Be helpful if the name refers to a struct + // (The pattern matching def_tys where the id is in self.structs + // matches on regular structs while excluding tuple- and enum-like + // structs, which wouldn't result in this error.) + match self.with_no_errors(|this| + this.resolve_path(expr.id, path, TypeNS, false)) { + Some(DefTy(struct_id)) + if self.structs.contains(&struct_id) => { + self.resolve_error(expr.span, + fmt!("`%s` is a structure name, but this expression \ + uses it like a function name", wrong_name)); - self.session.span_note(expr.span, fmt!("Did you mean to write: \ - `%s { /* fields */ }`?", wrong_name)); + self.session.span_note(expr.span, fmt!("Did you mean to write: \ + `%s { /* fields */ }`?", wrong_name)); - } - _ => - // limit search to 5 to reduce the number - // of stupid suggestions - match self.find_best_match_for_name(wrong_name, 5) { - Some(m) => { - self.resolve_error(expr.span, - fmt!("unresolved name `%s`. \ - Did you mean `%s`?", - wrong_name, m)); - } - None => { - self.resolve_error(expr.span, - fmt!("unresolved name `%s`.", - wrong_name)); - } - } } + _ => + // limit search to 5 to reduce the number + // of stupid suggestions + match self.find_best_match_for_name(wrong_name, 5) { + Some(m) => { + self.resolve_error(expr.span, + fmt!("unresolved name `%s`. \ + Did you mean `%s`?", + wrong_name, m)); + } + None => { + self.resolve_error(expr.span, + fmt!("unresolved name `%s`.", + wrong_name)); + } + } } } } @@ -5431,9 +5384,9 @@ impl Resolver { // resolve data structures. // - pub fn check_for_unused_imports(&self) { + pub fn check_for_unused_imports(&self, crate: &ast::Crate) { let mut visitor = UnusedImportCheckVisitor{ resolver: self }; - visit::walk_crate(&mut visitor, self.crate, ()); + visit::walk_crate(&mut visitor, crate, ()); } pub fn check_for_item_unused_imports(&self, vi: &view_item) { @@ -5549,10 +5502,10 @@ pub struct CrateMap { /// Entry point to crate resolution. pub fn resolve_crate(session: Session, lang_items: LanguageItems, - crate: @Crate) + crate: &Crate) -> CrateMap { - let mut resolver = Resolver(session, lang_items, crate); - resolver.resolve(); + let mut resolver = Resolver(session, lang_items, crate.span); + resolver.resolve(crate); CrateMap { def_map: resolver.def_map, exp_map2: resolver.export_map2, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 3f021881b27..983708183d8 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3075,16 +3075,17 @@ pub fn write_abi_version(ccx: &mut CrateContext) { } pub fn trans_crate(sess: session::Session, - crate: &ast::Crate, + crate: ast::Crate, analysis: &CrateAnalysis, output: &Path) -> CrateTranslation { // Before we touch LLVM, make sure that multithreading is enabled. if unsafe { !llvm::LLVMRustStartMultithreading() } { - //sess.bug("couldn't enable multi-threaded LLVM"); + sess.bug("couldn't enable multi-threaded LLVM"); } let mut symbol_hasher = hash::default_state(); - let link_meta = link::build_link_meta(sess, crate, output, &mut symbol_hasher); + let link_meta = link::build_link_meta(sess, &crate, output, + &mut symbol_hasher); // Append ".rc" to crate name as LLVM module identifier. // @@ -3107,7 +3108,7 @@ pub fn trans_crate(sess: session::Session, analysis.reachable); if ccx.sess.opts.debuginfo { - debuginfo::initialize(ccx, crate); + debuginfo::initialize(ccx, &crate); } { @@ -3144,7 +3145,7 @@ pub fn trans_crate(sess: session::Session, } // Translate the metadata. - write_metadata(ccx, crate); + write_metadata(ccx, &crate); if ccx.sess.trans_stats() { io::println("--- trans stats ---"); println!("n_static_tydescs: {}", ccx.stats.n_static_tydescs); diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 45a65f954a3..fbd3088902f 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -447,17 +447,17 @@ pub fn check_crate(tcx: ty::ctxt, tcx: tcx }; - time(time_passes, ~"type collecting", || + time(time_passes, ~"type collecting", (), |_| collect::collect_item_types(ccx, crate)); // this ensures that later parts of type checking can assume that items // have valid types and not error tcx.sess.abort_if_errors(); - time(time_passes, ~"coherence checking", || + time(time_passes, ~"coherence checking", (), |_| coherence::check_coherence(ccx, crate)); - time(time_passes, ~"type checking", || + time(time_passes, ~"type checking", (), |_| check::check_item_types(ccx, crate)); check_for_entry_fn(ccx); diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index bd7ca3a5529..3ffbbdd8358 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -17,10 +17,10 @@ use syntax::visit::Visitor; use std::hashmap::HashSet; use extra; -pub fn time(do_it: bool, what: ~str, thunk: &fn() -> T) -> T { - if !do_it { return thunk(); } +pub fn time(do_it: bool, what: ~str, u: U, f: &fn(U) -> T) -> T { + if !do_it { return f(u); } let start = extra::time::precise_time_s(); - let rv = thunk(); + let rv = f(u); let end = extra::time::precise_time_s(); println!("time: {:3.3f} s\t{}", end - start, what); rv diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8a7bb1f9346..ff60241056c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -24,7 +24,7 @@ use clean; use clean::Clean; pub struct DocContext { - crate: @ast::Crate, + crate: ast::Crate, tycx: middle::ty::ctxt, sess: driver::session::Session } @@ -60,7 +60,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: ~[Path]) -> DocContext { let mut crate = phase_1_parse_input(sess, cfg.clone(), &input); crate = phase_2_configure_and_expand(sess, cfg, crate); - let analysis = phase_3_run_analysis_passes(sess, crate); + let analysis = phase_3_run_analysis_passes(sess, &crate); debug!("crate: %?", crate); DocContext { crate: crate, tycx: analysis.ty_cx, sess: sess } @@ -75,7 +75,7 @@ pub fn run_core (libs: ~[Path], path: &Path) -> clean::Crate { local_data::set(super::ctxtkey, ctxt); let v = @mut RustdocVisitor::new(); - v.visit(ctxt.crate); + v.visit(&ctxt.crate); v.clean() } diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index ae6c36b8861..ebf939c8bea 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -161,7 +161,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str], let mut to_run = ~[]; // statements to run (emitted back into code) let new_locals = @mut ~[]; // new locals being defined let mut result = None; // resultant expression (to print via pp) - do find_main(crate, sess) |blk| { + do find_main(&crate, sess) |blk| { // Fish out all the view items, be sure to record 'extern mod' items // differently beause they must appear before all 'use' statements for vi in blk.view_items.iter() { @@ -241,11 +241,11 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str], let crate = driver::phase_1_parse_input(sess, cfg.clone(), &dinput); let expanded_crate = driver::phase_2_configure_and_expand(sess, cfg, crate); - let analysis = driver::phase_3_run_analysis_passes(sess, expanded_crate); + let analysis = driver::phase_3_run_analysis_passes(sess, &expanded_crate); // Once we're typechecked, record the types of all local variables defined // in this input - do find_main(crate, sess) |blk| { + do find_main(&expanded_crate, sess) |blk| { program.register_new_vars(blk, analysis.ty_cx); } @@ -264,7 +264,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str], let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input); let expanded_crate = driver::phase_2_configure_and_expand(sess, cfg, crate); - let analysis = driver::phase_3_run_analysis_passes(sess, expanded_crate); + let analysis = driver::phase_3_run_analysis_passes(sess, &expanded_crate); let trans = driver::phase_4_translate_to_llvm(sess, expanded_crate, &analysis, outputs); driver::phase_5_run_llvm_passes(sess, &trans, outputs); @@ -283,14 +283,14 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str], // return (program, jit::consume_engine()); - fn parse_input(sess: session::Session, input: &str) -> @ast::Crate { + fn parse_input(sess: session::Session, input: &str) -> ast::Crate { let code = fmt!("fn main() {\n %s \n}", input); let input = driver::str_input(code.to_managed()); let cfg = driver::build_configuration(sess); driver::phase_1_parse_input(sess, cfg.clone(), &input) } - fn find_main(crate: @ast::Crate, sess: session::Session, + fn find_main(crate: &ast::Crate, sess: session::Session, f: &fn(&ast::Block)) { for item in crate.module.items.iter() { match item.node { @@ -358,7 +358,7 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option { println(fmt!("compiling %s...", src_filename)); let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input); let expanded_crate = driver::phase_2_configure_and_expand(sess, cfg, crate); - let analysis = driver::phase_3_run_analysis_passes(sess, expanded_crate); + let analysis = driver::phase_3_run_analysis_passes(sess, &expanded_crate); let trans = driver::phase_4_translate_to_llvm(sess, expanded_crate, &analysis, outputs); driver::phase_5_run_llvm_passes(sess, &trans, outputs); true diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index e4f88081239..2945b75128e 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -85,7 +85,7 @@ struct PkgScript<'self> { /// The config for compiling the custom build script cfg: ast::CrateConfig, /// The crate for the custom build script - crate: @ast::Crate, + crate: Option, /// Directory in which to store build output build_dir: Path } @@ -125,7 +125,7 @@ impl<'self> PkgScript<'self> { input: script, sess: sess, cfg: cfg, - crate: crate, + crate: Some(crate), build_dir: work_dir } } @@ -134,12 +134,13 @@ impl<'self> PkgScript<'self> { /// is the command to pass to it (e.g., "build", "clean", "install") /// Returns a pair of an exit code and list of configs (obtained by /// calling the package script's configs() function if it exists - fn run_custom(&self, exec: &mut workcache::Exec, sysroot: &Path) -> (~[~str], ExitCode) { + fn run_custom(&mut self, exec: &mut workcache::Exec, + sysroot: &Path) -> (~[~str], ExitCode) { let sess = self.sess; debug!("Working directory = %s", self.build_dir.to_str()); // Collect together any user-defined commands in the package script - let crate = util::ready_crate(sess, self.crate); + let crate = util::ready_crate(sess, self.crate.take_unwrap()); debug!("Building output filenames with script name %s", driver::source_name(&driver::file_input(self.input.clone()))); let exe = self.build_dir.push(~"pkg" + util::exe_suffix()); @@ -419,10 +420,10 @@ impl CtxMethods for BuildContext { let sub_id = pkgid.clone(); declare_package_script_dependency(prep, &*pkg_src); do prep.exec |exec| { - let pscript = PkgScript::parse(@sub_sysroot.clone(), - package_script_path_clone.clone(), - &sub_ws, - &sub_id); + let mut pscript = PkgScript::parse(@sub_sysroot.clone(), + package_script_path_clone.clone(), + &sub_ws, + &sub_id); pscript.run_custom(exec, &sub_sysroot) } diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index b30ad6f2c92..af80abdac38 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -68,7 +68,6 @@ struct ListenerFn { struct ReadyCtx { sess: session::Session, - crate: @ast::Crate, ext_cx: @ExtCtxt, path: ~[ast::Ident], fns: ~[ListenerFn] @@ -151,10 +150,9 @@ impl fold::ast_fold for CrateSetup { /// Generate/filter main function, add the list of commands, etc. pub fn ready_crate(sess: session::Session, - crate: @ast::Crate) -> @ast::Crate { + crate: ast::Crate) -> ast::Crate { let ctx = @mut ReadyCtx { sess: sess, - crate: crate, ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone()), path: ~[], fns: ~[] @@ -162,7 +160,7 @@ pub fn ready_crate(sess: session::Session, let fold = CrateSetup { ctx: ctx, }; - @fold.fold_crate(crate) + fold.fold_crate(crate) } pub fn compile_input(context: &BuildContext, @@ -262,7 +260,7 @@ pub fn compile_input(context: &BuildContext, let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input); crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate); - find_and_install_dependencies(context, pkg_id, sess, exec, crate, + find_and_install_dependencies(context, pkg_id, sess, exec, &crate, |p| { debug!("a dependency: %s", p.to_str()); // Pass the directory containing a dependency @@ -289,10 +287,7 @@ pub fn compile_input(context: &BuildContext, pkg_id.path.to_str().to_managed())]; debug!("link options: %?", link_options); - crate = @ast::Crate { - attrs: ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))], - .. (*crate).clone() - } + crate.attrs = ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))]; } debug!("calling compile_crate_from_input, workspace = %s, @@ -334,7 +329,7 @@ pub fn compile_crate_from_input(input: &Path, sess: session::Session, // Returns None if one of the flags that suppresses compilation output was // given - crate: @ast::Crate) -> Option { + crate: ast::Crate) -> Option { debug!("Calling build_output_filenames with %s, building library? %?", out_dir.to_str(), sess.building_library); @@ -352,7 +347,7 @@ pub fn compile_crate_from_input(input: &Path, for lib in sess.opts.addl_lib_search_paths.iter() { debug!("an additional library: %s", lib.to_str()); } - let analysis = driver::phase_3_run_analysis_passes(sess, crate); + let analysis = driver::phase_3_run_analysis_passes(sess, &crate); if driver::stop_after_phase_3(sess) { return None; } let translation = driver::phase_4_translate_to_llvm(sess, crate, &analysis, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index c62ebb9254e..0ca4f4fa1cd 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1143,8 +1143,8 @@ impl ast_fold for Injector { // program (ick). This should run before cfg stripping. pub fn inject_std_macros(parse_sess: @mut parse::ParseSess, cfg: ast::CrateConfig, - c: @Crate) - -> @Crate { + c: Crate) + -> Crate { let sm = match parse_item_from_source_str(@"", std_macros(), cfg.clone(), @@ -1157,7 +1157,7 @@ pub fn inject_std_macros(parse_sess: @mut parse::ParseSess, let injector = @Injector { sm: sm, } as @ast_fold; - @injector.fold_crate(c) + injector.fold_crate(c) } struct NoOpFolder { @@ -1214,7 +1214,7 @@ impl ast_fold for MacroExpander { pub fn expand_crate(parse_sess: @mut parse::ParseSess, cfg: ast::CrateConfig, - c: &Crate) -> @Crate { + c: Crate) -> Crate { // adding *another* layer of indirection here so that the block // visitor can swap out one exts table for another for the duration // of the block. The cleaner alternative would be to thread the @@ -1227,7 +1227,7 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess, cx: cx, } as @ast_fold; - let ret = @expander.fold_crate(c); + let ret = expander.fold_crate(c); parse_sess.span_diagnostic.handler().abort_if_errors(); return ret; } @@ -1534,7 +1534,7 @@ mod test { let a2_name = gensym("a2"); let renamer = new_rename_folder(ast::Ident{name:a_name,ctxt:EMPTY_CTXT}, a2_name); - let renamed_ast = renamer.fold_crate(item_ast); + let renamed_ast = renamer.fold_crate(item_ast.clone()); let varrefs = @mut ~[]; visit::walk_crate(&mut new_path_finder(varrefs), &renamed_ast, ()); match varrefs { @@ -1557,12 +1557,12 @@ mod test { } } - fn fake_print_crate(crate: @ast::Crate) { + fn fake_print_crate(crate: &ast::Crate) { let s = pprust::rust_printer(std::io::stderr(),get_ident_interner()); pprust::print_crate_(s, crate); } - fn expand_crate_str(crate_str: @str) -> @ast::Crate { + fn expand_crate_str(crate_str: @str) -> ast::Crate { let (crate_ast,ps) = string_to_crate_and_sess(crate_str); // the cfg argument actually does matter, here... expand_crate(ps,~[],crate_ast) @@ -1658,10 +1658,10 @@ mod test { let cr = expand_crate_str(teststr.to_managed()); // find the bindings: let bindings = @mut ~[]; - visit::walk_crate(&mut new_name_finder(bindings),cr,()); + visit::walk_crate(&mut new_name_finder(bindings),&cr,()); // find the varrefs: let varrefs = @mut ~[]; - visit::walk_crate(&mut new_path_finder(varrefs),cr,()); + visit::walk_crate(&mut new_path_finder(varrefs),&cr,()); // must be one check clause for each binding: assert_eq!(bindings.len(),bound_connections.len()); for (binding_idx,shouldmatch) in bound_connections.iter().enumerate() { @@ -1721,7 +1721,7 @@ foo_module!() let cr = expand_crate_str(crate_str); // find the xx binding let bindings = @mut ~[]; - visit::walk_crate(&mut new_name_finder(bindings), cr, ()); + visit::walk_crate(&mut new_name_finder(bindings), &cr, ()); let cxbinds : ~[&ast::Ident] = bindings.iter().filter(|b|{@"xx" == (ident_to_str(*b))}).collect(); let cxbind = match cxbinds { @@ -1731,7 +1731,7 @@ foo_module!() let resolved_binding = mtwt_resolve(*cxbind); // find all the xx varrefs: let varrefs = @mut ~[]; - visit::walk_crate(&mut new_path_finder(varrefs), cr, ()); + visit::walk_crate(&mut new_path_finder(varrefs), &cr, ()); // the xx binding should bind all of the xx varrefs: for (idx,v) in varrefs.iter().filter(|p|{ p.segments.len() == 1 && (@"xx" == (ident_to_str(&p.segments[0].identifier))) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index a25f267c458..b823ff726ac 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -16,7 +16,7 @@ use opt_vec::OptVec; // We may eventually want to be able to fold over type parameters, too. pub trait ast_fold { - fn fold_crate(&self, c: &Crate) -> Crate { + fn fold_crate(&self, c: Crate) -> Crate { noop_fold_crate(c, self) } @@ -691,7 +691,7 @@ pub fn noop_fold_mod(m: &_mod, folder: &T) -> _mod { } } -pub fn noop_fold_crate(c: &Crate, folder: &T) -> Crate { +pub fn noop_fold_crate(c: Crate, folder: &T) -> Crate { let fold_meta_item = |x| fold_meta_item_(x, folder); let fold_attribute = |x| fold_attribute_(x, folder); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 37f2f8345cd..a492a2283e3 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -73,7 +73,7 @@ pub fn parse_crate_from_file( input: &Path, cfg: ast::CrateConfig, sess: @mut ParseSess -) -> @ast::Crate { +) -> ast::Crate { new_parser_from_file(sess, /*bad*/ cfg.clone(), input).parse_crate_mod() // why is there no p.abort_if_errors here? } @@ -83,7 +83,7 @@ pub fn parse_crate_from_source_str( source: @str, cfg: ast::CrateConfig, sess: @mut ParseSess -) -> @ast::Crate { +) -> ast::Crate { let p = new_parser_from_source_str(sess, /*bad*/ cfg.clone(), name, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6c905c252c1..5a68e32a533 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5140,7 +5140,7 @@ impl Parser { // Parses a source module as a crate. This is the main // entry point for the parser. - pub fn parse_crate_mod(&self) -> @Crate { + pub fn parse_crate_mod(&self) -> Crate { let lo = self.span.lo; // parse the crate's inner attrs, maybe (oops) one // of the attrs of an item: @@ -5149,7 +5149,7 @@ impl Parser { // parse the items inside the crate: let m = self.parse_mod_items(token::EOF, first_item_outer_attrs); - @ast::Crate { + ast::Crate { module: m, attrs: inner, config: self.cfg.clone(), diff --git a/src/libsyntax/syntax b/src/libsyntax/syntax new file mode 100755 index 00000000000..942ee88bd0e Binary files /dev/null and b/src/libsyntax/syntax differ diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 23396c06a9a..59a6f0adeb4 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -47,14 +47,14 @@ fn with_error_checking_parse(s: @str, f: &fn(&mut Parser) -> T) -> T { } // parse a string, return a crate. -pub fn string_to_crate (source_str : @str) -> @ast::Crate { +pub fn string_to_crate (source_str : @str) -> ast::Crate { do with_error_checking_parse(source_str) |p| { p.parse_crate_mod() } } // parse a string, return a crate and the ParseSess -pub fn string_to_crate_and_sess (source_str : @str) -> (@ast::Crate,@mut ParseSess) { +pub fn string_to_crate_and_sess (source_str : @str) -> (ast::Crate,@mut ParseSess) { let (p,ps) = string_to_parser_and_sess(source_str); (p.parse_crate_mod(),ps) }