This commit adds support for the compiler to distinguish between different forms
of lookup paths in the compiler itself. Issue #19767 has some background on this
topic, as well as some sample bugs which can occur if these lookup paths are not
separated.
This commits extends the existing command line flag `-L` with the same trailing
syntax as the `-l` flag. Each argument to `-L` can now have a trailing `:all`,
`:native`, `:crate`, or `:dependency`. This suffix indicates what form of lookup
path the compiler should add the argument to. The `dependency` lookup path is
used when looking up crate dependencies, the `crate` lookup path is used when
looking for immediate dependencies (`extern crate` statements), and the `native`
lookup path is used for probing for native libraries to insert into rlibs. Paths
with `all` are used for all of these purposes (the default).
The default compiler lookup path (the rustlib libdir) is by default added to all
of these paths. Additionally, the `RUST_PATH` lookup path is added to all of
these paths.
Closes #19767
pub use self::DebugInfoLevel::*;
use session::{early_error, Session};
+ use session::search_paths::SearchPaths;
use rustc_back::target::Target;
use lint;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use getopts;
- use std::cell::{RefCell};
use std::fmt;
use llvm;
// This was mutable for rustpkg, which updates search paths based on the
// parsed code. It remains mutable in case its replacements wants to use
// this.
- pub addl_lib_search_paths: RefCell<Vec<Path>>,
+ pub search_paths: SearchPaths,
pub libs: Vec<(String, cstore::NativeLibraryKind)>,
pub maybe_sysroot: Option<Path>,
pub target_triple: String,
lint_opts: Vec::new(),
describe_lints: false,
output_types: Vec::new(),
- addl_lib_search_paths: RefCell::new(Vec::new()),
+ search_paths: SearchPaths::new(),
maybe_sysroot: None,
target_triple: host_triple().to_string(),
cfg: Vec::new(),
PARSE_ONLY,
NO_TRANS,
NO_ANALYSIS,
- UNSTABLE_OPTIONS
+ UNSTABLE_OPTIONS,
+ PRINT_ENUM_SIZES
]
0
}
("no-analysis", "Parse and expand the source, but run no analysis and",
NO_TRANS),
("unstable-options", "Adds unstable command line options to rustc interface",
- UNSTABLE_OPTIONS)]
+ UNSTABLE_OPTIONS),
+ ("print-enum-sizes", "Print the size of enums and their variants", PRINT_ENUM_SIZES),
+ ]
}
#[deriving(Clone)]
}
};
- let addl_lib_search_paths = matches.opt_strs("L").iter().map(|s| {
- Path::new(s[])
- }).collect();
+ let mut search_paths = SearchPaths::new();
+ for s in matches.opt_strs("L").iter() {
+ search_paths.add_path(s[]);
+ }
let libs = matches.opt_strs("l").into_iter().map(|s| {
let mut parts = s.rsplitn(1, ':');
lint_opts: lint_opts,
describe_lints: describe_lints,
output_types: output_types,
- addl_lib_search_paths: RefCell::new(addl_lib_search_paths),
+ search_paths: search_paths,
maybe_sysroot: sysroot_opt,
target_triple: target,
cfg: cfg,
// except according to those terms.
+ use lint;
use metadata::cstore::CStore;
use metadata::filesearch;
- use lint;
+ use session::search_paths::PathKind;
use util::nodemap::NodeMap;
use syntax::ast::NodeId;
use std::cell::{Cell, RefCell};
pub mod config;
+ pub mod search_paths;
// Represents the data associated with a compilation
// session for a single crate.
pub fn show_span(&self) -> bool {
self.debugging_opt(config::SHOW_SPAN)
}
+ pub fn print_enum_sizes(&self) -> bool {
+ self.debugging_opt(config::PRINT_ENUM_SIZES)
+ }
pub fn sysroot<'a>(&'a self) -> &'a Path {
match self.opts.maybe_sysroot {
Some (ref sysroot) => sysroot,
.expect("missing sysroot and default_sysroot in Session")
}
}
- pub fn target_filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
+ pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
filesearch::FileSearch::new(self.sysroot(),
self.opts.target_triple[],
- &self.opts.addl_lib_search_paths)
+ &self.opts.search_paths,
+ kind)
}
- pub fn host_filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
+ pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
filesearch::FileSearch::new(
self.sysroot(),
config::host_triple(),
- &self.opts.addl_lib_search_paths)
+ &self.opts.search_paths,
+ kind)
}
}
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
emitter.emit(None, msg, None, diagnostic::Warning);
}
-
use rustc::session::Session;
use rustc::session::config::{mod, Input, OutputFilenames};
+ use rustc::session::search_paths::PathKind;
use rustc::lint;
use rustc::metadata::creader;
use rustc::middle::{stability, ty, reachable};
use std::io;
use std::io::fs;
use std::os;
-use arena::TypedArena;
use syntax::ast;
use syntax::ast_map;
use syntax::attr;
if stop_after_phase_2(&sess) { return; }
- let type_arena = TypedArena::new();
- let analysis = phase_3_run_analysis_passes(sess, ast_map, &type_arena, id);
+ let arenas = ty::CtxtArenas::new();
+ let analysis = phase_3_run_analysis_passes(sess, ast_map, &arenas, id);
phase_save_analysis(&analysis.ty_cx.sess, analysis.ty_cx.map.krate(), &analysis, outdir);
+
+ if log_enabled!(::log::INFO) {
+ println!("Pre-trans");
+ analysis.ty_cx.print_debug_stats();
+ }
+
if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
let (tcx, trans) = phase_4_translate_to_llvm(analysis);
+ if log_enabled!(::log::INFO) {
+ println!("Post-trans");
+ tcx.print_debug_stats();
+ }
+
// Discard interned strings as they are no longer required.
token::get_ident_interner().clear();
let mut _old_path = String::new();
if cfg!(windows) {
_old_path = os::getenv("PATH").unwrap_or(_old_path);
- let mut new_path = sess.host_filesearch().get_dylib_search_paths();
+ let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
new_path.extend(os::split_paths(_old_path[]).into_iter());
os::setenv("PATH", os::join_paths(new_path[]).unwrap());
}
/// structures carrying the results of the analysis.
pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
ast_map: ast_map::Map<'tcx>,
- type_arena: &'tcx TypedArena<ty::TyS<'tcx>>,
+ arenas: &'tcx ty::CtxtArenas<'tcx>,
name: String) -> ty::CrateAnalysis<'tcx> {
let time_passes = sess.time_passes();
let krate = ast_map.krate();
let lang_items = time(time_passes, "language item collection", (), |_|
middle::lang_items::collect_language_items(krate, &sess));
+ let make_glob_map = if save_analysis(&sess) {
+ resolve::MakeGlobMap::Yes
+ } else {
+ resolve::MakeGlobMap::No
+ };
let resolve::CrateMap {
def_map,
freevars,
export_map,
trait_map,
external_exports,
- last_private_map
+ last_private_map,
+ glob_map,
} =
time(time_passes, "resolution", (),
- |_| resolve::resolve_crate(&sess, &lang_items, krate));
+ |_| resolve::resolve_crate(&sess,
+ &ast_map,
+ &lang_items,
+ krate,
+ make_glob_map));
// Discard MTWT tables that aren't required past resolution.
syntax::ext::mtwt::clear_tables();
middle::check_static_recursion::check_crate(&sess, krate, &def_map, &ast_map));
let ty_cx = ty::mk_ctxt(sess,
- type_arena,
+ arenas,
def_map,
named_region_map,
ast_map,
public_items: public_items,
reachable: reachable_map,
name: name,
+ glob_map: glob_map,
}
}
+fn save_analysis(sess: &Session) -> bool {
+ (sess.opts.debugging_opts & config::SAVE_ANALYSIS) != 0
+}
+
pub fn phase_save_analysis(sess: &Session,
krate: &ast::Crate,
analysis: &ty::CrateAnalysis,
odir: &Option<Path>) {
- if (sess.opts.debugging_opts & config::SAVE_ANALYSIS) == 0 {
+ if !save_analysis(sess) {
return;
}
time(sess.time_passes(), "save analysis", krate, |krate|
trans: &trans::CrateTranslation,
outputs: &OutputFilenames) {
let old_path = os::getenv("PATH").unwrap_or_else(||String::new());
- let mut new_path = sess.host_filesearch().get_tools_search_paths();
+ let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths();
new_path.extend(os::split_paths(old_path[]).into_iter());
os::setenv("PATH", os::join_paths(new_path[]).unwrap());
use rustc_driver::driver;
use rustc::session::{mod, config};
+ use rustc::session::search_paths::SearchPaths;
use rustc::middle::{privacy, ty};
use rustc::lint;
use rustc_trans::back::link;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
-use arena::TypedArena;
use visit_ast::RustdocVisitor;
use clean;
pub type Externs = HashMap<String, Vec<String>>;
- pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, externs: Externs,
+ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
cpath: &Path, triple: Option<String>)
-> (clean::Crate, CrateAnalysis) {
let sessopts = config::Options {
maybe_sysroot: None,
- addl_lib_search_paths: RefCell::new(libs),
+ search_paths: search_paths,
crate_types: vec!(config::CrateTypeRlib),
lint_opts: vec!((warning_lint, lint::Allow)),
externs: externs,
let mut forest = ast_map::Forest::new(krate);
let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
- let type_arena = TypedArena::new();
+ let arenas = ty::CtxtArenas::new();
let ty::CrateAnalysis {
exported_items, public_items, ty_cx, ..
- } = driver::phase_3_run_analysis_passes(sess, ast_map, &type_arena, name);
+ } = driver::phase_3_run_analysis_passes(sess, ast_map, &arenas, name);
let ctxt = DocContext {
krate: ty_cx.map.krate(),