rust/src/librustc_driver/lib.rs

1028 lines
37 KiB
Rust
Raw Normal View History

2015-02-02 18:40:52 -06:00
// Copyright 2014-2015 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"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]
#![feature(box_syntax)]
#![feature(libc)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(set_stdio)]
#![feature(staged_api)]
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_passes;
2015-07-31 02:04:06 -05:00
extern crate rustc_front;
extern crate rustc_lint;
extern crate rustc_plugin;
extern crate rustc_privacy;
extern crate rustc_metadata;
extern crate rustc_mir;
extern crate rustc_resolve;
extern crate rustc_trans;
extern crate rustc_typeck;
extern crate serialize;
2015-03-24 20:13:54 -05:00
extern crate rustc_llvm as llvm;
2015-11-10 14:48:44 -06:00
#[macro_use]
extern crate log;
#[macro_use]
extern crate syntax;
extern crate syntax_ext;
use driver::CompileController;
use pretty::{PpMode, UserIdentifiedItem};
use rustc_resolve as resolve;
use rustc_trans::back::link;
use rustc_trans::save;
use rustc::session::{config, Session, build_session, CompileResult};
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
use rustc::middle::cstore::CrateStore;
use rustc::lint::Lint;
use rustc::lint;
use rustc_metadata::loader;
use rustc_metadata::cstore::CStore;
use rustc::util::common::time;
use std::cmp::max;
use std::cmp::Ordering::Equal;
use std::default::Default;
std: Add a new `env` module This is an implementation of [RFC 578][rfc] which adds a new `std::env` module to replace most of the functionality in the current `std::os` module. More details can be found in the RFC itself, but as a summary the following methods have all been deprecated: [rfc]: https://github.com/rust-lang/rfcs/pull/578 * `os::args_as_bytes` => `env::args` * `os::args` => `env::args` * `os::consts` => `env::consts` * `os::dll_filename` => no replacement, use `env::consts` directly * `os::page_size` => `env::page_size` * `os::make_absolute` => use `env::current_dir` + `join` instead * `os::getcwd` => `env::current_dir` * `os::change_dir` => `env::set_current_dir` * `os::homedir` => `env::home_dir` * `os::tmpdir` => `env::temp_dir` * `os::join_paths` => `env::join_paths` * `os::split_paths` => `env::split_paths` * `os::self_exe_name` => `env::current_exe` * `os::self_exe_path` => use `env::current_exe` + `pop` * `os::set_exit_status` => `env::set_exit_status` * `os::get_exit_status` => `env::get_exit_status` * `os::env` => `env::vars` * `os::env_as_bytes` => `env::vars` * `os::getenv` => `env::var` or `env::var_string` * `os::getenv_as_bytes` => `env::var` * `os::setenv` => `env::set_var` * `os::unsetenv` => `env::remove_var` Many function signatures have also been tweaked for various purposes, but the main changes were: * `Vec`-returning APIs now all return iterators instead * All APIs are now centered around `OsString` instead of `Vec<u8>` or `String`. There is currently on convenience API, `env::var_string`, which can be used to get the value of an environment variable as a unicode `String`. All old APIs are `#[deprecated]` in-place and will remain for some time to allow for migrations. The semantics of the APIs have been tweaked slightly with regard to dealing with invalid unicode (panic instead of replacement). The new `std::env` module is all contained within the `env` feature, so crates must add the following to access the new APIs: #![feature(env)] [breaking-change]
2015-01-27 14:20:58 -06:00
use std::env;
2015-03-11 17:24:14 -05:00
use std::io::{self, Read, Write};
use std::iter::repeat;
use std::path::PathBuf;
use std::process;
use std::rc::Rc;
2015-03-11 17:24:14 -05:00
use std::str;
use std::sync::{Arc, Mutex};
2014-12-06 20:34:37 -06:00
use std::thread;
use rustc::session::early_error;
use syntax::ast;
use syntax::parse;
use syntax::errors;
use syntax::errors::emitter::Emitter;
use syntax::diagnostics;
use syntax::parse::token;
#[cfg(test)]
pub mod test;
pub mod driver;
pub mod pretty;
pub mod target_features;
2015-11-10 14:48:44 -06:00
const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
md#bug-reports";
#[inline]
fn abort_msg(err_count: usize) -> String {
match err_count {
0 => "aborting with no errors (maybe a bug?)".to_owned(),
1 => "aborting due to previous error".to_owned(),
e => format!("aborting due to {} previous errors", e),
}
}
pub fn abort_on_err<T>(result: Result<T, usize>, sess: &Session) -> T {
match result {
Err(err_count) => {
sess.fatal(&abort_msg(err_count));
}
Ok(x) => x,
}
}
pub fn run(args: Vec<String>) -> isize {
monitor(move || {
let (result, session) = run_compiler(&args, &mut RustcDefaultCalls);
if let Err(err_count) = result {
if err_count > 0 {
match session {
Some(sess) => sess.fatal(&abort_msg(err_count)),
None => {
let mut emitter =
errors::emitter::BasicEmitter::stderr(errors::ColorConfig::Auto);
emitter.emit(None, &abort_msg(err_count), None, errors::Level::Fatal);
exit_on_err();
}
}
}
}
});
0
}
// Parse args and run the compiler. This is the primary entry point for rustc.
// See comments on CompilerCalls below for details about the callbacks argument.
pub fn run_compiler<'a>(args: &[String],
callbacks: &mut CompilerCalls<'a>)
-> (CompileResult, Option<Session>) {
macro_rules! do_or_return {($expr: expr, $sess: expr) => {
2015-02-02 18:40:52 -06:00
match $expr {
Compilation::Stop => return (Ok(()), $sess),
2015-02-02 18:40:52 -06:00
Compilation::Continue => {}
}
}}
let matches = match handle_options(args.to_vec()) {
Some(matches) => matches,
None => return (Ok(()), None),
};
let sopts = config::build_session_options(&matches);
let descriptions = diagnostics_registry();
do_or_return!(callbacks.early_callback(&matches,
&sopts,
&descriptions,
sopts.error_format),
None);
let (odir, ofile) = make_output(&matches);
let (input, input_file_path) = match make_input(&matches.free) {
Some((input, input_file_path)) => callbacks.some_input(input, input_file_path),
None => match callbacks.no_input(&matches, &sopts, &odir, &ofile, &descriptions) {
Some((input, input_file_path)) => (input, input_file_path),
None => return (Ok(()), None),
2015-11-10 14:48:44 -06:00
},
};
let cstore = Rc::new(CStore::new(token::get_ident_interner()));
let sess = build_session(sopts, input_file_path, descriptions, cstore.clone());
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let mut cfg = config::build_configuration(&sess);
target_features::add_configuration(&mut cfg, &sess);
do_or_return!(callbacks.late_callback(&matches, &sess, &input, &odir, &ofile), Some(sess));
// It is somewhat unfortunate that this is hardwired in - this is forced by
// the fact that pretty_print_input requires the session by value.
let pretty = callbacks.parse_pretty(&sess, &matches);
2015-02-02 18:40:52 -06:00
match pretty {
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, &cstore, cfg, &input, ppm, opt_uii, ofile);
return (Ok(()), None);
}
2015-11-10 14:48:44 -06:00
None => {
// continue
}
}
let plugins = sess.opts.debugging_opts.extra_plugins.clone();
let control = callbacks.build_controller(&sess);
(driver::compile_input(&sess, &cstore, cfg, &input, &odir, &ofile,
Some(plugins), control),
Some(sess))
}
// Extract output directory and file from matches.
fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) {
let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));
let ofile = matches.opt_str("o").map(|o| PathBuf::from(&o));
(odir, ofile)
}
// Extract input (string or file and optional path) from matches.
fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
if free_matches.len() == 1 {
let ifile = &free_matches[0][..];
if ifile == "-" {
2015-03-11 17:24:14 -05:00
let mut src = String::new();
io::stdin().read_to_string(&mut src).unwrap();
Some((Input::Str(src), None))
} else {
2015-11-10 14:48:44 -06:00
Some((Input::File(PathBuf::from(ifile)),
Some(PathBuf::from(ifile))))
}
} else {
None
}
}
2015-02-02 18:40:52 -06:00
// Whether to stop or continue compilation.
2015-03-30 08:38:44 -05:00
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2015-02-02 18:40:52 -06:00
pub enum Compilation {
Stop,
Continue,
}
impl Compilation {
pub fn and_then<F: FnOnce() -> Compilation>(self, next: F) -> Compilation {
match self {
Compilation::Stop => Compilation::Stop,
2015-11-10 14:48:44 -06:00
Compilation::Continue => next(),
2015-02-02 18:40:52 -06:00
}
}
}
// A trait for customising the compilation process. Offers a number of hooks for
// executing custom code or customising input.
pub trait CompilerCalls<'a> {
// Hook for a callback early in the process of handling arguments. This will
// be called straight after options have been parsed but before anything
2015-02-02 18:40:52 -06:00
// else (e.g., selecting input and output).
fn early_callback(&mut self,
2015-07-16 04:51:59 -05:00
_: &getopts::Matches,
_: &config::Options,
_: &diagnostics::registry::Registry,
_: ErrorOutputType)
-> Compilation {
Compilation::Continue
}
// Hook for a callback late in the process of handling arguments. This will
// be called just before actual compilation starts (and before build_controller
2015-02-02 18:40:52 -06:00
// is called), after all arguments etc. have been completely handled.
fn late_callback(&mut self,
2015-07-16 04:51:59 -05:00
_: &getopts::Matches,
_: &Session,
_: &Input,
_: &Option<PathBuf>,
_: &Option<PathBuf>)
-> Compilation {
Compilation::Continue
}
// Called after we extract the input from the arguments. Gives the implementer
// an opportunity to change the inputs or to add some custom input handling.
// The default behaviour is to simply pass through the inputs.
2015-11-10 14:48:44 -06:00
fn some_input(&mut self,
input: Input,
input_path: Option<PathBuf>)
-> (Input, Option<PathBuf>) {
(input, input_path)
}
// Called after we extract the input from the arguments if there is no valid
// input. Gives the implementer an opportunity to supply alternate input (by
// returning a Some value) or to add custom behaviour for this error such as
// emitting error messages. Returning None will cause compilation to stop
// at this point.
fn no_input(&mut self,
2015-07-16 04:51:59 -05:00
_: &getopts::Matches,
_: &config::Options,
_: &Option<PathBuf>,
_: &Option<PathBuf>,
_: &diagnostics::registry::Registry)
-> Option<(Input, Option<PathBuf>)> {
None
}
// Parse pretty printing information from the arguments. The implementer can
// choose to ignore this (the default will return None) which will skip pretty
// printing. If you do want to pretty print, it is recommended to use the
// implementation of this method from RustcDefaultCalls.
// FIXME, this is a terrible bit of API. Parsing of pretty printing stuff
// should be done as part of the framework and the implementor should customise
// handling of it. However, that is not possible atm because pretty printing
// essentially goes off and takes another path through the compiler which
// means the session is either moved or not depending on what parse_pretty
// returns (we could fix this by cloning, but it's another hack). The proper
// solution is to handle pretty printing as if it were a compiler extension,
// extending CompileController to make this work (see for example the treatment
// of save-analysis in RustcDefaultCalls::build_controller).
fn parse_pretty(&mut self,
_sess: &Session,
_matches: &getopts::Matches)
-> Option<(PpMode, Option<UserIdentifiedItem>)> {
None
}
2015-11-10 14:48:44 -06:00
// Create a CompilController struct for controlling the behaviour of
// compilation.
fn build_controller(&mut self, &Session) -> CompileController<'a>;
}
// CompilerCalls instance for a regular rustc build.
2015-03-30 08:38:44 -05:00
#[derive(Copy, Clone)]
pub struct RustcDefaultCalls;
fn handle_explain(code: &str,
descriptions: &diagnostics::registry::Registry,
output: ErrorOutputType) {
let normalised = if !code.starts_with("E") {
format!("E{0:0>4}", code)
} else {
code.to_string()
};
match descriptions.find_description(&normalised) {
Some(ref description) => {
// Slice off the leading newline and print.
print!("{}", &description[1..]);
}
None => {
early_error(output, &format!("no extended information for {}", code));
}
}
}
fn check_cfg(sopts: &config::Options,
output: ErrorOutputType) {
let mut emitter: Box<Emitter> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(errors::emitter::BasicEmitter::stderr(color_config))
}
config::ErrorOutputType::Json => Box::new(errors::json::JsonEmitter::basic()),
};
let mut saw_invalid_predicate = false;
for item in sopts.cfg.iter() {
match item.node {
ast::MetaList(ref pred, _) => {
saw_invalid_predicate = true;
emitter.emit(None,
&format!("invalid predicate in --cfg command line argument: `{}`",
pred),
None,
errors::Level::Fatal);
}
_ => {},
}
}
if saw_invalid_predicate {
panic!(errors::FatalError);
}
}
impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
fn early_callback(&mut self,
matches: &getopts::Matches,
sopts: &config::Options,
descriptions: &diagnostics::registry::Registry,
output: ErrorOutputType)
2015-02-02 18:40:52 -06:00
-> Compilation {
if let Some(ref code) = matches.opt_str("explain") {
handle_explain(code, descriptions, output);
return Compilation::Stop;
}
check_cfg(sopts, output);
Compilation::Continue
}
fn no_input(&mut self,
matches: &getopts::Matches,
sopts: &config::Options,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
descriptions: &diagnostics::registry::Registry)
-> Option<(Input, Option<PathBuf>)> {
match matches.free.len() {
0 => {
if sopts.describe_lints {
let mut ls = lint::LintStore::new();
rustc_lint::register_builtins(&mut ls, None);
describe_lints(&ls, false);
return None;
}
let cstore = Rc::new(CStore::new(token::get_ident_interner()));
let sess = build_session(sopts.clone(), None, descriptions.clone(),
cstore.clone());
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
2015-02-02 18:40:52 -06:00
let should_stop = RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile);
if should_stop == Compilation::Stop {
return None;
}
early_error(sopts.error_format, "no input filename given");
}
1 => panic!("make_input should have provided valid inputs"),
_ => early_error(sopts.error_format, "multiple input filenames provided"),
}
None
}
fn parse_pretty(&mut self,
sess: &Session,
matches: &getopts::Matches)
-> Option<(PpMode, Option<UserIdentifiedItem>)> {
let pretty = if sess.opts.debugging_opts.unstable_options {
matches.opt_default("pretty", "normal").map(|a| {
// stable pretty-print variants only
pretty::parse_pretty(sess, &a, false)
})
} else {
None
};
if pretty.is_none() && sess.unstable_options() {
matches.opt_str("unpretty").map(|a| {
// extended with unstable pretty-print variants
pretty::parse_pretty(sess, &a, true)
})
} else {
pretty
}
}
fn late_callback(&mut self,
matches: &getopts::Matches,
sess: &Session,
input: &Input,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>)
2015-02-02 18:40:52 -06:00
-> Compilation {
2015-11-10 14:48:44 -06:00
RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile)
.and_then(|| RustcDefaultCalls::list_metadata(sess, matches, input))
}
fn build_controller(&mut self, sess: &Session) -> CompileController<'a> {
let mut control = CompileController::basic();
2016-01-11 22:44:24 -06:00
if sess.opts.parse_only || sess.opts.debugging_opts.show_span.is_some() ||
sess.opts.debugging_opts.ast_json_noexpand {
2015-02-02 18:40:52 -06:00
control.after_parse.stop = Compilation::Stop;
}
if sess.opts.no_analysis || sess.opts.debugging_opts.ast_json {
2015-02-02 18:40:52 -06:00
control.after_write_deps.stop = Compilation::Stop;
}
if sess.opts.no_trans {
2015-02-02 18:40:52 -06:00
control.after_analysis.stop = Compilation::Stop;
}
if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
2015-02-02 18:40:52 -06:00
control.after_llvm.stop = Compilation::Stop;
}
if sess.opts.debugging_opts.save_analysis {
control.after_analysis.callback = box |state| {
2015-11-10 14:48:44 -06:00
time(state.session.time_passes(), "save analysis", || {
save::process_crate(state.tcx.unwrap(),
state.lcx.unwrap(),
state.krate.unwrap(),
state.analysis.unwrap(),
state.crate_name.unwrap(),
state.out_dir)
});
};
control.after_analysis.run_callback_on_error = true;
control.make_glob_map = resolve::MakeGlobMap::Yes;
}
control
}
}
impl RustcDefaultCalls {
2015-11-10 14:48:44 -06:00
pub fn list_metadata(sess: &Session, matches: &getopts::Matches, input: &Input) -> Compilation {
let r = matches.opt_strs("Z");
if r.contains(&("ls".to_string())) {
match input {
&Input::File(ref ifile) => {
let path = &(*ifile);
let mut v = Vec::new();
loader::list_file_metadata(&sess.target.target, path, &mut v)
2015-11-10 14:48:44 -06:00
.unwrap();
println!("{}", String::from_utf8(v).unwrap());
}
&Input::Str(_) => {
early_error(ErrorOutputType::default(), "cannot list metadata for stdin");
}
}
2015-02-02 18:40:52 -06:00
return Compilation::Stop;
}
2015-02-02 18:40:52 -06:00
return Compilation::Continue;
}
fn print_crate_info(sess: &Session,
input: Option<&Input>,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>)
2015-02-02 18:40:52 -06:00
-> Compilation {
if sess.opts.prints.is_empty() {
2015-02-02 18:40:52 -06:00
return Compilation::Continue;
}
let attrs = input.map(|input| parse_crate_attrs(sess, input));
for req in &sess.opts.prints {
match *req {
PrintRequest::Sysroot => println!("{}", sess.sysroot().display()),
PrintRequest::FileNames |
PrintRequest::CrateName => {
let input = match input {
Some(input) => input,
None => early_error(ErrorOutputType::default(), "no input file provided"),
};
let attrs = attrs.as_ref().unwrap();
2015-11-10 14:48:44 -06:00
let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess);
let id = link::find_crate_name(Some(sess), attrs, input);
if *req == PrintRequest::CrateName {
println!("{}", id);
2015-11-10 14:48:44 -06:00
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 {
2015-11-10 14:48:44 -06:00
let fname = link::filename_for_input(sess, style, &id, &t_outputs);
println!("{}",
fname.file_name()
.unwrap()
.to_string_lossy());
}
}
PrintRequest::Cfg => {
for cfg in config::build_configuration(sess) {
match cfg.node {
ast::MetaWord(ref word) => println!("{}", word),
ast::MetaNameValue(ref name, ref value) => {
println!("{}=\"{}\"", name, match value.node {
ast::LitKind::Str(ref s, _) => s,
_ => continue,
});
}
// Right now there are not and should not be any
// MetaList items in the configuration returned by
// `build_configuration`.
ast::MetaList(..) => {
panic!("MetaList encountered in default cfg")
}
}
}
}
}
}
2015-02-02 18:40:52 -06:00
return Compilation::Stop;
Preliminary feature staging This partially implements the feature staging described in the [release channel RFC][rc]. It does not yet fully conform to the RFC as written, but does accomplish its goals sufficiently for the 1.0 alpha release. It has three primary user-visible effects: * On the nightly channel, use of unstable APIs generates a warning. * On the beta channel, use of unstable APIs generates a warning. * On the beta channel, use of feature gates generates a warning. Code that does not trigger these warnings is considered 'stable', modulo pre-1.0 bugs. Disabling the warnings for unstable APIs continues to be done in the existing (i.e. old) style, via `#[allow(...)]`, not that specified in the RFC. I deem this marginally acceptable since any code that must do this is not using the stable dialect of Rust. Use of feature gates is itself gated with the new 'unstable_features' lint, on nightly set to 'allow', and on beta 'warn'. The attribute scheme used here corresponds to an older version of the RFC, with the `#[staged_api]` crate attribute toggling the staging behavior of the stability attributes, but the user impact is only in-tree so I'm not concerned about having to make design changes later (and I may ultimately prefer the scheme here after all, with the `#[staged_api]` crate attribute). Since the Rust codebase itself makes use of unstable features the compiler and build system to a midly elaborate dance to allow it to bootstrap while disobeying these lints (which would otherwise be errors because Rust builds with `-D warnings`). This patch includes one significant hack that causes a regression. Because the `format_args!` macro emits calls to unstable APIs it would trigger the lint. I added a hack to the lint to make it not trigger, but this in turn causes arguments to `println!` not to be checked for feature gates. I don't presently understand macro expansion well enough to fix. This is bug #20661. Closes #16678 [rc]: https://github.com/rust-lang/rfcs/blob/master/text/0507-release-channels.md
2015-01-06 08:26:08 -06:00
}
}
/// 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")
}
2015-06-26 12:32:27 -05:00
/// Prints version information
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");
2015-11-10 14:48:44 -06:00
println!("{} {}",
binary,
option_env!("CFG_VERSION").unwrap_or("unknown version"));
if verbose {
2015-11-10 14:48:44 -06:00
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
};
2015-11-10 14:48:44 -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"
};
2015-11-10 14:48:44 -06:00
println!("{}\nAdditional help:
-C help Print codegen options
2015-11-10 14:48:44 -06:00
-W help \
Print 'lint' options and default settings
-Z help Print internal \
options for debugging rustc{}\n",
getopts::usage(&message, &groups),
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>
2015-11-10 14:48:44 -06:00
-A <foo> \
Allow <foo>
-D <foo> Deny <foo>
2015-11-10 14:48:44 -06:00
-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)>)
2015-11-10 14:48:44 -06:00
-> 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()
2015-11-10 14:48:44 -06:00
.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()
2015-11-10 14:48:44 -06:00
.iter()
.cloned()
.partition(|&(_, _, p)| p);
let plugin_groups = sort_lint_groups(plugin_groups);
let builtin_groups = sort_lint_groups(builtin_groups);
2015-11-10 14:48:44 -06:00
let max_name_len = plugin.iter()
.chain(&builtin)
.map(|&s| s.name.chars().count())
.max()
.unwrap_or(0);
let padded = |x: &str| {
2015-11-10 14:48:44 -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>| {
for lint in lints {
let name = lint.name_lower().replace("_", "-");
println!(" {} {:7.7} {}",
2015-11-10 14:48:44 -06:00
padded(&name[..]),
lint.default_level.as_str(),
lint.desc);
}
println!("\n");
};
print_lints(builtin);
2016-01-06 00:42:19 -06:00
let max_name_len = max("warnings".len(),
plugin_groups.iter()
.chain(&builtin_groups)
.map(|&(s, _)| s.chars().count())
.max()
.unwrap_or(0));
let padded = |x: &str| {
2015-11-10 14:48:44 -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("----"), "---------");
println!(" {} {}", padded("warnings"), "all built-in lints");
let print_lint_groups = |lints: Vec<(&'static str, Vec<lint::LintId>)>| {
for (name, to) in lints {
let name = name.to_lowercase().replace("_", "-");
2015-11-10 14:48:44 -06:00
let desc = to.into_iter()
.map(|x| x.as_str().replace("_", "-"))
.collect::<Vec<String>>()
.join(", ");
println!(" {} {}", padded(&name[..]), 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");
print_flag_list("-Z", config::DB_OPTIONS);
}
fn describe_codegen_flags() {
println!("\nAvailable codegen options:\n");
print_flag_list("-C", config::CG_OPTIONS);
}
fn print_flag_list<T>(cmdline_opt: &str,
flag_list: &[(&'static str, T, Option<&'static str>, &'static str)]) {
2015-11-10 14:48:44 -06:00
let max_len = flag_list.iter()
.map(|&(name, _, opt_type_desc, _)| {
let extra_len = match opt_type_desc {
Some(..) => 4,
None => 0,
};
name.chars().count() + extra_len
})
.max()
.unwrap_or(0);
for &(name, _, opt_type_desc, desc) in flag_list {
let (width, extra) = match opt_type_desc {
Some(..) => (max_len - 4, "=val"),
2015-11-10 14:48:44 -06:00
None => (max_len, ""),
};
2015-11-10 14:48:44 -06:00
println!(" {} {:>width$}{} -- {}",
cmdline_opt,
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;
}
fn allows_unstable_options(matches: &getopts::Matches) -> bool {
let r = matches.opt_strs("Z");
r.iter().any(|x| *x == "unstable-options")
}
fn parse_all_options(args: &Vec<String>) -> getopts::Matches {
2015-11-10 14:48:44 -06:00
let all_groups: Vec<getopts::OptGroup> = config::rustc_optgroups()
.into_iter()
.map(|x| x.opt_group)
.collect();
match getopts::getopts(&args[..], &all_groups) {
Ok(m) => {
if !allows_unstable_options(&m) {
// If -Z unstable-options was not specified, verify that
// no unstable options were present.
for opt in config::rustc_optgroups().into_iter().filter(|x| !x.is_stable()) {
let opt_name = if !opt.opt_group.long_name.is_empty() {
&opt.opt_group.long_name
} else {
&opt.opt_group.short_name
};
if m.opt_present(opt_name) {
early_error(ErrorOutputType::default(),
2015-11-10 14:48:44 -06:00
&format!("use of unstable option '{}' requires -Z \
unstable-options",
opt_name));
}
}
}
m
}
Err(f) => early_error(ErrorOutputType::default(), &f.to_string()),
}
}
// As a speed optimization, first try to parse the command-line using just
// the stable options.
let matches = match getopts::getopts(&args[..], &config::optgroups()) {
Ok(ref m) if allows_unstable_options(m) => {
// If -Z unstable-options was specified, redo parsing with the
// unstable options to ensure that unstable options are defined
// in the returned getopts::Matches.
parse_all_options(&args)
}
Ok(m) => m,
Err(_) => {
// redo option parsing, including unstable options this time,
// in anticipation that the mishandled option was one of the
// unstable ones.
parse_all_options(&args)
}
};
if matches.opt_present("h") || matches.opt_present("help") {
2015-11-10 14:48:44 -06:00
usage(matches.opt_present("verbose"),
allows_unstable_options(&matches));
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()) {
2015-11-10 14:48:44 -06:00
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)
}
2015-11-10 14:48:44 -06:00
fn parse_crate_attrs(sess: &Session, input: &Input) -> Vec<ast::Attribute> {
let result = match *input {
Input::File(ref ifile) => {
2015-11-10 14:48:44 -06:00
parse::parse_crate_attrs_from_file(ifile, Vec::new(), &sess.parse_sess)
}
Input::Str(ref src) => {
2015-11-10 14:48:44 -06:00
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()
}
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.
2015-11-10 14:48:44 -06:00
pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
const STACK_SIZE: usize = 8 * 1024 * 1024; // 8MB
2015-03-11 17:24:14 -05:00
struct Sink(Arc<Mutex<Vec<u8>>>);
impl Write for Sink {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
Write::write(&mut *self.0.lock().unwrap(), data)
}
2015-11-10 14:48:44 -06:00
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
2015-03-11 17:24:14 -05:00
}
let data = Arc::new(Mutex::new(Vec::new()));
let err = Sink(data.clone());
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 env::var_os("RUST_MIN_STACK").is_none() {
2014-12-06 20:34:37 -06:00
cfg = cfg.stack_size(STACK_SIZE);
}
2015-11-10 14:48:44 -06:00
match cfg.spawn(move || {
io::set_panic(box err);
f()
})
.unwrap()
.join() {
Ok(()) => {
// fallthrough
}
Err(value) => {
2014-12-26 15:04:27 -06:00
// Thread panicked without emitting a fatal diagnostic
if !value.is::<errors::FatalError>() {
let mut emitter = errors::emitter::BasicEmitter::stderr(errors::ColorConfig::Auto);
// a .span_bug or .bug call has already printed what
// it wants to print.
if !value.is::<errors::ExplicitBug>() {
emitter.emit(None, "unexpected panic", None, errors::Level::Bug);
}
2015-11-10 14:48:44 -06:00
let xs = ["the compiler unexpectedly panicked. this is a bug.".to_string(),
format!("we would appreciate a bug report: {}", BUG_REPORT_URL)];
2015-01-31 11:20:46 -06:00
for note in &xs {
emitter.emit(None, &note[..], None, errors::Level::Note)
}
if let None = env::var_os("RUST_BACKTRACE") {
2015-11-10 14:48:44 -06:00
emitter.emit(None,
"run with `RUST_BACKTRACE=1` for a backtrace",
None,
errors::Level::Note);
}
2015-03-11 17:24:14 -05:00
println!("{}", str::from_utf8(&data.lock().unwrap()).unwrap());
}
exit_on_err();
}
}
}
fn exit_on_err() -> ! {
// Panic so the process returns a failure code, but don't pollute the
// output with some unnecessary panic messages, we've already
// printed everything that we needed to.
io::set_panic(box io::sink());
panic!();
}
pub fn diagnostics_registry() -> diagnostics::registry::Registry {
use syntax::diagnostics::registry::Registry;
let mut all_errors = Vec::new();
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 19:31:49 -06:00
all_errors.extend_from_slice(&rustc::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_typeck::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_borrowck::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_resolve::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_trans::DIAGNOSTICS);
Registry::new(&*all_errors)
}
pub fn main() {
let result = run(env::args().collect());
process::exit(result as i32);
}