rust/src/librustc_driver/lib.rs

615 lines
21 KiB
Rust
Raw Normal View History

// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Rust compiler.
//!
//! # Note
//!
//! This API is completely unstable and subject to change.
#![crate_name = "rustc_driver"]
#![experimental]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![feature(default_type_params, globs, macro_rules, phase, quote)]
#![feature(slicing_syntax, unsafe_destructor)]
#![feature(rustc_diagnostic_macros)]
2014-12-09 15:32:45 -06:00
#![feature(unboxed_closures)]
2015-01-02 07:15:20 -06:00
#![feature(associated_types)]
extern crate arena;
extern crate flate;
extern crate getopts;
extern crate graphviz;
extern crate libc;
extern crate rustc;
extern crate rustc_back;
extern crate rustc_borrowck;
extern crate rustc_resolve;
extern crate rustc_trans;
extern crate rustc_typeck;
extern crate serialize;
extern crate "rustc_llvm" as llvm;
2012-11-28 18:20:41 -06:00
#[cfg(stage0)]
#[phase(plugin, link)]
extern crate log;
#[cfg(not(stage0))]
#[macro_use]
extern crate log;
#[cfg(stage0)]
#[phase(plugin, link)]
extern crate syntax;
#[cfg(not(stage0))]
#[macro_use]
extern crate syntax;
pub use syntax::diagnostic;
use rustc_trans::back::link;
use rustc::session::{config, Session, build_session};
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
use rustc::session::config::{Input, PrintRequest};
use rustc::lint::Lint;
use rustc::lint;
use rustc::metadata;
use rustc::DIAGNOSTICS;
use std::cmp::Ordering::Equal;
use std::io;
2014-12-10 21:46:38 -06:00
use std::iter::repeat;
use std::os;
std: Second pass stabilization for `comm` This commit is a second pass stabilization for the `std::comm` module, performing the following actions: * The entire `std::comm` module was moved under `std::sync::mpsc`. This movement reflects that channels are just yet another synchronization primitive, and they don't necessarily deserve a special place outside of the other concurrency primitives that the standard library offers. * The `send` and `recv` methods have all been removed. * The `send_opt` and `recv_opt` methods have been renamed to `send` and `recv`. This means that all send/receive operations return a `Result` now indicating whether the operation was successful or not. * The error type of `send` is now a `SendError` to implement a custom error message and allow for `unwrap()`. The error type contains an `into_inner` method to extract the value. * The error type of `recv` is now `RecvError` for the same reasons as `send`. * The `TryRecvError` and `TrySendError` types have had public reexports removed of their variants and the variant names have been tweaked with enum namespacing rules. * The `Messages` iterator is renamed to `Iter` This functionality is now all `#[stable]`: * `Sender` * `SyncSender` * `Receiver` * `std::sync::mpsc` * `channel` * `sync_channel` * `Iter` * `Sender::send` * `Sender::clone` * `SyncSender::send` * `SyncSender::try_send` * `SyncSender::clone` * `Receiver::recv` * `Receiver::try_recv` * `Receiver::iter` * `SendError` * `RecvError` * `TrySendError::{mod, Full, Disconnected}` * `TryRecvError::{mod, Empty, Disconnected}` * `SendError::into_inner` * `TrySendError::into_inner` This is a breaking change due to the modification of where this module is located, as well as the changing of the semantics of `send` and `recv`. Most programs just need to rename imports of `std::comm` to `std::sync::mpsc` and add calls to `unwrap` after a send or a receive operation. [breaking-change]
2014-12-23 13:53:35 -06:00
use std::sync::mpsc::channel;
2014-12-06 20:34:37 -06:00
use std::thread;
use rustc::session::early_error;
use syntax::ast;
use syntax::parse;
use syntax::diagnostic::Emitter;
use syntax::diagnostics;
#[cfg(test)]
pub mod test;
pub mod driver;
pub mod pretty;
pub fn run(args: Vec<String>) -> int {
monitor(move |:| run_compiler(args.as_slice()));
0
}
static BUG_REPORT_URL: &'static str =
"http://doc.rust-lang.org/complement-bugreport.html";
fn run_compiler(args: &[String]) {
let matches = match handle_options(args.to_vec()) {
Some(matches) => matches,
None => return
};
let descriptions = diagnostics::registry::Registry::new(&DIAGNOSTICS);
match matches.opt_str("explain") {
Some(ref code) => {
match descriptions.find_description(code.index(&FullRange)) {
Some(ref description) => {
println!("{}", description);
}
None => {
early_error(format!("no extended information for {}", code).index(&FullRange));
}
}
return;
},
None => ()
}
let sopts = config::build_session_options(&matches);
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
let ofile = matches.opt_str("o").map(|o| Path::new(o));
let (input, input_file_path) = match matches.free.len() {
0u => {
if sopts.describe_lints {
let mut ls = lint::LintStore::new();
ls.register_builtin(None);
2014-06-18 19:26:14 -05:00
describe_lints(&ls, false);
return;
}
let sess = build_session(sopts, None, descriptions);
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
if print_crate_info(&sess, None, &odir, &ofile) {
return;
}
early_error("no input filename given");
}
1u => {
let ifile = matches.free[0].index(&FullRange);
if ifile == "-" {
let contents = io::stdin().read_to_end().unwrap();
let src = String::from_utf8(contents).unwrap();
(Input::Str(src), None)
} else {
(Input::File(Path::new(ifile)), Some(Path::new(ifile)))
}
}
_ => early_error("multiple input filenames provided")
};
let mut sess = build_session(sopts, input_file_path, descriptions);
let cfg = config::build_configuration(&sess);
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
if print_crate_info(&sess, Some(&input), &odir, &ofile) {
return
}
let pretty = matches.opt_default("pretty", "normal").map(|a| {
// stable pretty-print variants only
pretty::parse_pretty(&sess, a.as_slice(), false)
});
let pretty = if pretty.is_none() &&
2014-12-27 03:19:27 -06:00
sess.unstable_options() {
matches.opt_str("xpretty").map(|a| {
// extended with unstable pretty-print variants
pretty::parse_pretty(&sess, a.as_slice(), true)
})
} else {
pretty
};
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
match pretty.into_iter().next() {
pretty-printer: let users choose particular items to pretty print. With this change: * `--pretty variant=<node-id>` will print the item associated with `<node-id>` (where `<node-id>` is an integer for some node-id in the AST, and `variant` means one of {`normal`,`expanded`,...}). * `--pretty variant=<path-suffix>` will print all of the items that match the `<path-suffix>` (where `<path-suffix>` is a suffix of a path, and `variant` again means one of {`normal`,`expanded`,...}). Example 1: the suffix `typeck::check::check_struct` matches the item with the path `rustc::middle::typeck::check::check_struct` when compiling the `rustc` crate. Example 2: the suffix `and` matches `core::option::Option::and` and `core::result::Result::and` when compiling the `core` crate. Both of the `--pretty variant=...` modes will include the full path to the item in a comment that follows the item. Note that when multiple paths match, then either: 1. all matching items are printed, in series; this is what happens in the usual pretty-print variants, or 2. the compiler signals an error; this is what happens in flowgraph printing. ---- Some drive-by improvements: Heavily refactored the pretty-printing glue in driver.rs, introducing a couple local traits to avoid cut-and-pasting very code segments that differed only in how they accessed the `Session` or the `ast_map::Map`. (Note the previous code had three similar calls to `print_crate` which have all been unified in this revision; the addition of printing individual node-ids exacerbated the situation beyond tolerance.) We may want to consider promoting some of these traits, e.g. `SessionCarrier`, for use more generally elsewhere in the compiler; right now I have to double check how to access the `Session` depending on what context I am hacking in. Refactored `PpMode` to make the data directly reflect the fundamental difference in the categories (in terms of printing source-code with various annotations, versus printing a control-flow graph). (also, addressed review feedback.)
2014-08-07 11:22:24 -05:00
Some((ppm, opt_uii)) => {
pretty::pretty_print_input(sess, cfg, &input, ppm, opt_uii, ofile);
return;
}
pretty-printer: let users choose particular items to pretty print. With this change: * `--pretty variant=<node-id>` will print the item associated with `<node-id>` (where `<node-id>` is an integer for some node-id in the AST, and `variant` means one of {`normal`,`expanded`,...}). * `--pretty variant=<path-suffix>` will print all of the items that match the `<path-suffix>` (where `<path-suffix>` is a suffix of a path, and `variant` again means one of {`normal`,`expanded`,...}). Example 1: the suffix `typeck::check::check_struct` matches the item with the path `rustc::middle::typeck::check::check_struct` when compiling the `rustc` crate. Example 2: the suffix `and` matches `core::option::Option::and` and `core::result::Result::and` when compiling the `core` crate. Both of the `--pretty variant=...` modes will include the full path to the item in a comment that follows the item. Note that when multiple paths match, then either: 1. all matching items are printed, in series; this is what happens in the usual pretty-print variants, or 2. the compiler signals an error; this is what happens in flowgraph printing. ---- Some drive-by improvements: Heavily refactored the pretty-printing glue in driver.rs, introducing a couple local traits to avoid cut-and-pasting very code segments that differed only in how they accessed the `Session` or the `ast_map::Map`. (Note the previous code had three similar calls to `print_crate` which have all been unified in this revision; the addition of printing individual node-ids exacerbated the situation beyond tolerance.) We may want to consider promoting some of these traits, e.g. `SessionCarrier`, for use more generally elsewhere in the compiler; right now I have to double check how to access the `Session` depending on what context I am hacking in. Refactored `PpMode` to make the data directly reflect the fundamental difference in the categories (in terms of printing source-code with various annotations, versus printing a control-flow graph). (also, addressed review feedback.)
2014-08-07 11:22:24 -05:00
None => {/* continue */ }
}
if sess.unstable_options() {
sess.opts.show_span = matches.opt_str("show-span");
}
let r = matches.opt_strs("Z");
if r.contains(&("ls".to_string())) {
match input {
Input::File(ref ifile) => {
let mut stdout = io::stdout();
list_metadata(&sess, &(*ifile), &mut stdout).unwrap();
}
Input::Str(_) => {
early_error("can not list metadata for stdin");
}
}
return;
}
driver::compile_input(sess, cfg, &input, &odir, &ofile, None);
}
/// Returns a version string such as "0.12.0-dev".
pub fn release_str() -> Option<&'static str> {
option_env!("CFG_RELEASE")
}
/// Returns the full SHA1 hash of HEAD of the Git repo from which rustc was built.
pub fn commit_hash_str() -> Option<&'static str> {
option_env!("CFG_VER_HASH")
}
/// Returns the "commit date" of HEAD of the Git repo from which rustc was built as a static string.
pub fn commit_date_str() -> Option<&'static str> {
option_env!("CFG_VER_DATE")
}
/// Prints version information and returns None on success or an error
2014-11-08 09:47:51 -06:00
/// message on panic.
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
pub fn version(binary: &str, matches: &getopts::Matches) {
let verbose = matches.opt_present("verbose");
println!("{} {}", binary, option_env!("CFG_VERSION").unwrap_or("unknown version"));
if verbose {
fn unw(x: Option<&str>) -> &str { x.unwrap_or("unknown") }
println!("binary: {}", binary);
println!("commit-hash: {}", unw(commit_hash_str()));
println!("commit-date: {}", unw(commit_date_str()));
println!("host: {}", config::host_triple());
println!("release: {}", unw(release_str()));
}
}
fn usage(verbose: bool, include_unstable_options: bool) {
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
let groups = if verbose {
config::rustc_optgroups()
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
} else {
config::rustc_short_optgroups()
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
};
let groups : Vec<_> = groups.into_iter()
.filter(|x| include_unstable_options || x.is_stable())
.map(|x|x.opt_group)
.collect();
let message = format!("Usage: rustc [OPTIONS] INPUT");
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
let extra_help = if verbose {
""
} else {
"\n --help -v Print the full set of options rustc accepts"
};
println!("{}\n\
Additional help:
-C help Print codegen options
-W help Print 'lint' options and default settings
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
-Z help Print internal options for debugging rustc{}\n",
getopts::usage(message.as_slice(), groups.as_slice()),
extra_help);
}
2014-06-18 19:26:14 -05:00
fn describe_lints(lint_store: &lint::LintStore, loaded_plugins: bool) {
println!("
Available lint options:
-W <foo> Warn about <foo>
-A <foo> Allow <foo>
-D <foo> Deny <foo>
-F <foo> Forbid <foo> (deny, and deny all overrides)
");
fn sort_lints(lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
lints.sort_by(|x: &&Lint, y: &&Lint| {
match x.default_level.cmp(&y.default_level) {
// The sort doesn't case-fold but it's doubtful we care.
Equal => x.name.cmp(y.name),
r => r,
}
});
lints
}
fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
-> Vec<(&'static str, Vec<lint::LintId>)> {
let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect();
lints.sort_by(|&(x, _): &(&'static str, Vec<lint::LintId>),
&(y, _): &(&'static str, Vec<lint::LintId>)| {
x.cmp(y)
});
lints
}
2014-12-30 12:51:18 -06:00
let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints()
.iter().cloned().partition(|&(_, p)| p);
2014-06-18 19:26:14 -05:00
let plugin = sort_lints(plugin);
let builtin = sort_lints(builtin);
2014-12-30 12:51:18 -06:00
let (plugin_groups, builtin_groups): (Vec<_>, _) = lint_store.get_lint_groups()
.iter().cloned().partition(|&(_, _, p)| p);
let plugin_groups = sort_lint_groups(plugin_groups);
let builtin_groups = sort_lint_groups(builtin_groups);
2014-06-18 19:26:14 -05:00
let max_name_len = plugin.iter().chain(builtin.iter())
.map(|&s| s.name.width(true))
.max().unwrap_or(0);
let padded = |&: x: &str| {
2014-12-10 21:46:38 -06:00
let mut s = repeat(" ").take(max_name_len - x.chars().count())
.collect::<String>();
s.push_str(x);
s
};
println!("Lint checks provided by rustc:\n");
println!(" {} {:7.7} {}", padded("name"), "default", "meaning");
println!(" {} {:7.7} {}", padded("----"), "-------", "-------");
let print_lints = |&: lints: Vec<&Lint>| {
2014-09-14 22:27:36 -05:00
for lint in lints.into_iter() {
let name = lint.name_lower().replace("_", "-");
println!(" {} {:7.7} {}",
padded(name.index(&FullRange)), lint.default_level.as_str(), lint.desc);
}
println!("\n");
};
print_lints(builtin);
let max_name_len = plugin_groups.iter().chain(builtin_groups.iter())
.map(|&(s, _)| s.width(true))
.max().unwrap_or(0);
let padded = |&: x: &str| {
2014-12-10 21:46:38 -06:00
let mut s = repeat(" ").take(max_name_len - x.chars().count())
.collect::<String>();
s.push_str(x);
s
};
println!("Lint groups provided by rustc:\n");
println!(" {} {}", padded("name"), "sub-lints");
println!(" {} {}", padded("----"), "---------");
let print_lint_groups = |&: lints: Vec<(&'static str, Vec<lint::LintId>)>| {
2014-09-14 22:27:36 -05:00
for (name, to) in lints.into_iter() {
let name = name.chars().map(|x| x.to_lowercase())
.collect::<String>().replace("_", "-");
let desc = to.into_iter().map(|x| x.as_str().replace("_", "-"))
.collect::<Vec<String>>().connect(", ");
println!(" {} {}",
padded(name.index(&FullRange)), desc);
2014-06-18 19:26:14 -05:00
}
println!("\n");
};
print_lint_groups(builtin_groups);
match (loaded_plugins, plugin.len(), plugin_groups.len()) {
(false, 0, _) | (false, _, 0) => {
println!("Compiler plugins can provide additional lints and lint groups. To see a \
listing of these, re-run `rustc -W help` with a crate filename.");
}
(false, _, _) => panic!("didn't load lint plugins but got them anyway!"),
(true, 0, 0) => println!("This crate does not load any lint plugins or lint groups."),
(true, l, g) => {
if l > 0 {
println!("Lint checks provided by plugins loaded by this crate:\n");
print_lints(plugin);
}
if g > 0 {
println!("Lint groups provided by plugins loaded by this crate:\n");
print_lint_groups(plugin_groups);
}
2014-06-18 19:26:14 -05:00
}
}
}
fn describe_debug_flags() {
println!("\nAvailable debug options:\n");
let r = config::debugging_opts_map();
for tuple in r.iter() {
match *tuple {
(ref name, ref desc, _) => {
println!(" -Z {:>20} -- {}", *name, *desc);
}
}
}
}
fn describe_codegen_flags() {
println!("\nAvailable codegen options:\n");
for &(name, _, opt_type_desc, desc) in config::CG_OPTIONS.iter() {
let (width, extra) = match opt_type_desc {
Some(..) => (21, "=val"),
None => (25, "")
};
println!(" -C {:>width$}{} -- {}", name.replace("_", "-"),
extra, desc, width=width);
}
}
/// Process command line options. Emits messages as appropriate. If compilation
/// should continue, returns a getopts::Matches object parsed from args, otherwise
/// returns None.
pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
// Throw away the first argument, the name of the binary
2014-12-30 12:51:18 -06:00
let _binary = args.remove(0);
if args.is_empty() {
// user did not write `-v` nor `-Z unstable-options`, so do not
// include that extra information.
usage(false, false);
return None;
}
let matches =
match getopts::getopts(args.index(&FullRange), config::optgroups().index(&FullRange)) {
Ok(m) => m,
Err(f_stable_attempt) => {
// redo option parsing, including unstable options this time,
// in anticipation that the mishandled option was one of the
// unstable ones.
let all_groups : Vec<getopts::OptGroup>
= config::rustc_optgroups().into_iter().map(|x|x.opt_group).collect();
match getopts::getopts(args.as_slice(), all_groups.as_slice()) {
Ok(m_unstable) => {
let r = m_unstable.opt_strs("Z");
let include_unstable_options = r.iter().any(|x| *x == "unstable-options");
if include_unstable_options {
m_unstable
} else {
early_error(f_stable_attempt.to_string().as_slice());
}
}
Err(_) => {
// ignore the error from the unstable attempt; just
// pass the error we got from the first try.
early_error(f_stable_attempt.to_string().as_slice());
}
}
}
};
let r = matches.opt_strs("Z");
let include_unstable_options = r.iter().any(|x| *x == "unstable-options");
if matches.opt_present("h") || matches.opt_present("help") {
usage(matches.opt_present("verbose"), include_unstable_options);
return None;
}
// Don't handle -W help here, because we might first load plugins.
let r = matches.opt_strs("Z");
if r.iter().any(|x| *x == "help") {
describe_debug_flags();
return None;
}
let cg_flags = matches.opt_strs("C");
if cg_flags.iter().any(|x| *x == "help") {
describe_codegen_flags();
return None;
}
if cg_flags.contains(&"passes=list".to_string()) {
unsafe { ::llvm::LLVMRustPrintPasses(); }
return None;
}
if matches.opt_present("version") {
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
version("rustc", &matches);
return None;
}
Some(matches)
}
fn print_crate_info(sess: &Session,
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
input: Option<&Input>,
odir: &Option<Path>,
ofile: &Option<Path>)
-> bool {
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
if sess.opts.prints.len() == 0 { return false }
let attrs = input.map(|input| parse_crate_attrs(sess, input));
for req in sess.opts.prints.iter() {
match *req {
PrintRequest::Sysroot => println!("{}", sess.sysroot().display()),
PrintRequest::FileNames |
PrintRequest::CrateName => {
let input = match input {
Some(input) => input,
None => early_error("no input file provided"),
};
let attrs = attrs.as_ref().unwrap().as_slice();
let t_outputs = driver::build_output_filenames(input,
odir,
ofile,
attrs,
sess);
let id = link::find_crate_name(Some(sess), attrs.as_slice(),
input);
if *req == PrintRequest::CrateName {
println!("{}", id);
continue
}
let crate_types = driver::collect_crate_types(sess, attrs);
let metadata = driver::collect_crate_metadata(sess, attrs);
*sess.crate_metadata.borrow_mut() = metadata;
for &style in crate_types.iter() {
let fname = link::filename_for_input(sess, style,
id.as_slice(),
&t_outputs.with_extension(""));
println!("{}", fname.filename_display());
}
}
}
}
rustc: Start "stabilizing" some flags This commit shuffles around some CLI flags of the compiler to some more stable locations with some renamings. The changes made were: * The `-v` flag has been repurposes as the "verbose" flag. The version flag has been renamed to `-V`. * The `-h` screen has been split into two parts. Most top-level options (not all) show with `-h`, and the remaining options (generally obscure) can be shown with `--help -v` which is a "verbose help screen" * The `-V` flag (version flag now) has lost its argument as it is now requested with `rustc -vV` "verbose version". * The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir` and `llvm-bc` to emphasize that they are LLVM's IR/bytecode. * The `--emit` option has grown a new variant, `dep-info`, which subsumes the `--dep-info` CLI argument. The `--dep-info` flag is now deprecated. * The `--parse-only`, `--no-trans`, and `--no-analysis` flags have moved behind the `-Z` family of flags. * The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C` flag. * The `--print-file-name` and `--print-crate-name` flags were moved behind one global `--print` flag which now accepts one of `crate-name`, `file-names`, or `sysroot`. This global `--print` flag is intended to serve as a mechanism for learning various metadata about the compiler itself. No warnings are currently enabled to allow tools like Cargo to have time to migrate to the new flags before spraying warnings to all users.
2014-12-15 18:03:39 -06:00
return true;
}
fn parse_crate_attrs(sess: &Session, input: &Input) ->
Vec<ast::Attribute> {
let result = match *input {
Input::File(ref ifile) => {
parse::parse_crate_attrs_from_file(ifile,
Vec::new(),
&sess.parse_sess)
}
Input::Str(ref src) => {
parse::parse_crate_attrs_from_source_str(
driver::anon_src().to_string(),
src.to_string(),
Vec::new(),
&sess.parse_sess)
}
};
2014-09-14 22:27:36 -05:00
result.into_iter().collect()
}
pub fn list_metadata(sess: &Session, path: &Path,
out: &mut io::Writer) -> io::IoResult<()> {
metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx, path, out)
}
2014-11-08 09:47:51 -06:00
/// Run a procedure which will detect panics in the compiler and print nicer
/// error messages rather than just failing the test.
///
/// The diagnostic emitter yielded to the procedure should be used for reporting
/// errors of the compiler.
pub fn monitor<F:FnOnce()+Send>(f: F) {
static STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
let (tx, rx) = channel();
let w = io::ChanWriter::new(tx);
let mut r = io::ChanReader::new(rx);
let mut cfg = thread::Builder::new().name("rustc".to_string());
// FIXME: Hacks on hacks. If the env is trying to override the stack size
// then *don't* set it explicitly.
if os::getenv("RUST_MIN_STACK").is_none() {
2014-12-06 20:34:37 -06:00
cfg = cfg.stack_size(STACK_SIZE);
}
match cfg.spawn(move || { std::io::stdio::set_stderr(box w); f() }).join() {
Ok(()) => { /* fallthrough */ }
Err(value) => {
2014-12-26 15:04:27 -06:00
// Thread panicked without emitting a fatal diagnostic
if !value.is::<diagnostic::FatalError>() {
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
// a .span_bug or .bug call has already printed what
// it wants to print.
if !value.is::<diagnostic::ExplicitBug>() {
emitter.emit(
None,
"unexpected panic",
None,
diagnostic::Bug);
}
let xs = [
"the compiler unexpectedly panicked. this is a bug.".to_string(),
format!("we would appreciate a bug report: {}",
BUG_REPORT_URL),
2014-05-25 05:10:11 -05:00
"run with `RUST_BACKTRACE=1` for a backtrace".to_string(),
];
for note in xs.iter() {
emitter.emit(None, note.index(&FullRange), None, diagnostic::Note)
}
match r.read_to_string() {
Ok(s) => println!("{}", s),
Err(e) => {
emitter.emit(None,
format!("failed to read internal \
stderr: {}", e).index(&FullRange),
None,
diagnostic::Error)
}
}
}
// Panic so the process returns a failure code, but don't pollute the
2014-11-08 09:47:51 -06:00
// output with some unnecessary panic messages, we've already
// printed everything that we needed to.
io::stdio::set_stderr(box io::util::NullWriter);
panic!();
}
}
}
pub fn main() {
let args = std::os::args();
let result = run(args);
std::os::set_exit_status(result);
}