Auto merge of #49969 - mark-i-m:allocator_fmt, r=estebank

Various rustfmt and commenting changes

These are factored out of #49320

There aren't actually any changes in functionality, just rustfmt and doccomments.
This commit is contained in:
bors
2018-04-18 03:35:55 +00:00
3 changed files with 739 additions and 644 deletions
+79 -69
View File
@@ -11,12 +11,12 @@
use rustc::middle::allocator::AllocatorKind;
use rustc_errors;
use syntax::abi::Abi;
use syntax::ast::{Crate, Attribute, LitKind, StrStyle};
use syntax::ast::{Unsafety, Constness, Generics, Mutability, Ty, Mac, Arg};
use syntax::ast::{self, Ident, Item, ItemKind, TyKind, VisibilityKind, Expr};
use syntax::ast::{Attribute, Crate, LitKind, StrStyle};
use syntax::ast::{Arg, Constness, Generics, Mac, Mutability, Ty, Unsafety};
use syntax::ast::{self, Expr, Ident, Item, ItemKind, TyKind, VisibilityKind};
use syntax::attr;
use syntax::codemap::{dummy_spanned, respan};
use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute};
use syntax::codemap::{ExpnInfo, MacroAttribute, NameAndSpan};
use syntax::ext::base::ExtCtxt;
use syntax::ext::base::Resolver;
use syntax::ext::build::AstBuilder;
@@ -31,10 +31,12 @@
use {AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
pub fn modify(sess: &ParseSess,
resolver: &mut Resolver,
krate: Crate,
handler: &rustc_errors::Handler) -> ast::Crate {
pub fn modify(
sess: &ParseSess,
resolver: &mut Resolver,
krate: Crate,
handler: &rustc_errors::Handler,
) -> ast::Crate {
ExpandAllocatorDirectives {
handler,
sess,
@@ -55,20 +57,24 @@ fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
let name = if attr::contains_name(&item.attrs, "global_allocator") {
"global_allocator"
} else {
return fold::noop_fold_item(item, self)
return fold::noop_fold_item(item, self);
};
match item.node {
ItemKind::Static(..) => {}
_ => {
self.handler.span_err(item.span, "allocators must be statics");
return SmallVector::one(item)
self.handler
.span_err(item.span, "allocators must be statics");
return SmallVector::one(item);
}
}
if self.found {
self.handler.span_err(item.span, "cannot define more than one \
#[global_allocator]");
return SmallVector::one(item)
self.handler.span_err(
item.span,
"cannot define more than one \
#[global_allocator]",
);
return SmallVector::one(item);
}
self.found = true;
@@ -80,7 +86,7 @@ fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
span: None,
allow_internal_unstable: true,
allow_internal_unsafe: false,
}
},
});
let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
let ecfg = ExpansionConfig::default(name.to_string());
@@ -91,10 +97,7 @@ fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
core: Ident::from_str("core"),
cx: ExtCtxt::new(self.sess, ecfg, self.resolver),
};
let super_path = f.cx.path(f.span, vec![
Ident::from_str("super"),
f.global,
]);
let super_path = f.cx.path(f.span, vec![Ident::from_str("super"), f.global]);
let mut items = vec![
f.cx.item_extern_crate(f.span, f.core),
f.cx.item_use_simple(
@@ -114,7 +117,7 @@ fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
let mut ret = SmallVector::new();
ret.push(item);
ret.push(module);
return ret
return ret;
}
fn fold_mac(&mut self, mac: Mac) -> Mac {
@@ -139,30 +142,39 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> P<Item> {
i += 1;
name
};
let args = method.inputs.iter().map(|ty| {
self.arg_ty(ty, &mut abi_args, mk)
}).collect();
let args = method
.inputs
.iter()
.map(|ty| self.arg_ty(ty, &mut abi_args, mk))
.collect();
let result = self.call_allocator(method.name, args);
let (output_ty, output_expr) = self.ret_ty(&method.output, result);
let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)),
Unsafety::Unsafe,
dummy_spanned(Constness::NotConst),
Abi::Rust,
Generics::default(),
self.cx.block_expr(output_expr));
self.cx.item(self.span,
Ident::from_str(&self.kind.fn_name(method.name)),
self.attrs(),
kind)
let kind = ItemKind::Fn(
self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)),
Unsafety::Unsafe,
dummy_spanned(Constness::NotConst),
Abi::Rust,
Generics::default(),
self.cx.block_expr(output_expr),
);
self.cx.item(
self.span,
Ident::from_str(&self.kind.fn_name(method.name)),
self.attrs(),
kind,
)
}
fn call_allocator(&self, method: &str, mut args: Vec<P<Expr>>) -> P<Expr> {
let method = self.cx.path(self.span, vec![
self.core,
Ident::from_str("alloc"),
Ident::from_str("GlobalAlloc"),
Ident::from_str(method),
]);
let method = self.cx.path(
self.span,
vec![
self.core,
Ident::from_str("alloc"),
Ident::from_str("GlobalAlloc"),
Ident::from_str(method),
],
);
let method = self.cx.expr_path(method);
let allocator = self.cx.path_ident(self.span, self.global);
let allocator = self.cx.expr_path(allocator);
@@ -189,10 +201,12 @@ fn attrs(&self) -> Vec<Attribute> {
]
}
fn arg_ty(&self,
ty: &AllocatorTy,
args: &mut Vec<Arg>,
ident: &mut FnMut() -> Ident) -> P<Expr> {
fn arg_ty(
&self,
ty: &AllocatorTy,
args: &mut Vec<Arg>,
ident: &mut FnMut() -> Ident,
) -> P<Expr> {
match *ty {
AllocatorTy::Layout => {
let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
@@ -202,18 +216,19 @@ fn arg_ty(&self,
args.push(self.cx.arg(self.span, size, ty_usize.clone()));
args.push(self.cx.arg(self.span, align, ty_usize));
let layout_new = self.cx.path(self.span, vec![
self.core,
Ident::from_str("alloc"),
Ident::from_str("Layout"),
Ident::from_str("from_size_align_unchecked"),
]);
let layout_new = self.cx.path(
self.span,
vec![
self.core,
Ident::from_str("alloc"),
Ident::from_str("Layout"),
Ident::from_str("from_size_align_unchecked"),
],
);
let layout_new = self.cx.expr_path(layout_new);
let size = self.cx.expr_ident(self.span, size);
let align = self.cx.expr_ident(self.span, align);
let layout = self.cx.expr_call(self.span,
layout_new,
vec![size, align]);
let layout = self.cx.expr_call(self.span, layout_new, vec![size, align]);
layout
}
@@ -230,9 +245,7 @@ fn arg_ty(&self,
self.cx.expr_ident(self.span, ident)
}
AllocatorTy::ResultPtr |
AllocatorTy::Bang |
AllocatorTy::Unit => {
AllocatorTy::ResultPtr | AllocatorTy::Bang | AllocatorTy::Unit => {
panic!("can't convert AllocatorTy to an argument")
}
}
@@ -249,17 +262,11 @@ fn ret_ty(&self, ty: &AllocatorTy, expr: P<Expr>) -> (P<Ty>, P<Expr>) {
(self.ptr_u8(), expr)
}
AllocatorTy::Bang => {
(self.cx.ty(self.span, TyKind::Never), expr)
}
AllocatorTy::Bang => (self.cx.ty(self.span, TyKind::Never), expr),
AllocatorTy::Unit => {
(self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr)
}
AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr),
AllocatorTy::Layout |
AllocatorTy::Usize |
AllocatorTy::Ptr => {
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
panic!("can't convert AllocatorTy to an output")
}
}
@@ -277,11 +284,14 @@ fn ptr_u8(&self) -> P<Ty> {
}
fn ptr_opaque(&self) -> P<Ty> {
let opaque = self.cx.path(self.span, vec![
self.core,
Ident::from_str("alloc"),
Ident::from_str("Opaque"),
]);
let opaque = self.cx.path(
self.span,
vec![
self.core,
Ident::from_str("alloc"),
Ident::from_str("Opaque"),
],
);
let ty_opaque = self.cx.ty_path(opaque);
self.cx.ty_ptr(self.span, ty_opaque, Mutability::Mutable)
}
+606 -522
View File
@@ -14,17 +14,17 @@
use rustc::ich::Fingerprint;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_mir as mir;
use rustc::session::{Session, CompileResult, CrateDisambiguator};
use rustc::session::{CompileResult, CrateDisambiguator, Session};
use rustc::session::CompileIncomplete;
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
use rustc::session::search_paths::PathKind;
use rustc::lint;
use rustc::middle::{self, stability, reachable, resolve_lifetime};
use rustc::middle::{self, reachable, resolve_lifetime, stability};
use rustc::middle::cstore::CrateStore;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt, Resolutions, AllArenas};
use rustc::ty::{self, AllArenas, Resolutions, TyCtxt};
use rustc::traits;
use rustc::util::common::{ErrorReported, time, install_panic_hook};
use rustc::util::common::{install_panic_hook, time, ErrorReported};
use rustc_allocator as allocator;
use rustc_borrowck as borrowck;
use rustc_incremental;
@@ -37,14 +37,14 @@
use rustc_privacy;
use rustc_plugin::registry::Registry;
use rustc_plugin as plugin;
use rustc_passes::{self, ast_validation, loops, rvalue_promotion, hir_stats};
use rustc_passes::{self, ast_validation, hir_stats, loops, rvalue_promotion};
use super::Compilation;
use serialize::json;
use std::any::Any;
use std::env;
use std::ffi::{OsString, OsStr};
use std::ffi::{OsStr, OsString};
use std::fs;
use std::io::{self, Write};
use std::iter;
@@ -64,15 +64,17 @@
use profile;
pub fn compile_input(trans: Box<TransCrate>,
sess: &Session,
cstore: &CStore,
input_path: &Option<PathBuf>,
input: &Input,
outdir: &Option<PathBuf>,
output: &Option<PathBuf>,
addl_plugins: Option<Vec<String>>,
control: &CompileController) -> CompileResult {
pub fn compile_input(
trans: Box<TransCrate>,
sess: &Session,
cstore: &CStore,
input_path: &Option<PathBuf>,
input: &Input,
outdir: &Option<PathBuf>,
output: &Option<PathBuf>,
addl_plugins: Option<Vec<String>>,
control: &CompileController,
) -> CompileResult {
macro_rules! controller_entry_point {
($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
let state = &mut $make_state;
@@ -106,16 +108,9 @@ macro_rules! controller_entry_point {
};
let (krate, registry) = {
let mut compile_state = CompileState::state_after_parse(input,
sess,
outdir,
output,
krate,
&cstore);
controller_entry_point!(after_parse,
sess,
compile_state,
Ok(()));
let mut compile_state =
CompileState::state_after_parse(input, sess, outdir, output, krate, &cstore);
controller_entry_point!(after_parse, sess, compile_state, Ok(()));
(compile_state.krate.unwrap(), compile_state.registry)
};
@@ -125,7 +120,13 @@ macro_rules! controller_entry_point {
::rustc_trans_utils::link::find_crate_name(Some(sess), &krate.attrs, input);
install_panic_hook();
let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
let ExpansionResult {
expanded_crate,
defs,
analysis,
resolutions,
mut hir_forest,
} = {
phase_2_configure_and_expand(
sess,
&cstore,
@@ -136,11 +137,17 @@ macro_rules! controller_entry_point {
control.make_glob_map,
|expanded_crate| {
let mut state = CompileState::state_after_expand(
input, sess, outdir, output, &cstore, expanded_crate, &crate_name,
input,
sess,
outdir,
output,
&cstore,
expanded_crate,
&crate_name,
);
controller_entry_point!(after_expand, sess, state, Ok(()));
Ok(())
}
},
)?
};
@@ -152,24 +159,28 @@ macro_rules! controller_entry_point {
if output_contains_path(&output_paths, input_path) {
sess.err(&format!(
"the input file \"{}\" would be overwritten by the generated \
executable",
input_path.display()));
executable",
input_path.display()
));
return Err(CompileIncomplete::Stopped);
}
if let Some(dir_path) = output_conflicts_with_dir(&output_paths) {
sess.err(&format!(
"the generated executable for the input file \"{}\" conflicts with the \
existing directory \"{}\"",
input_path.display(), dir_path.display()));
existing directory \"{}\"",
input_path.display(),
dir_path.display()
));
return Err(CompileIncomplete::Stopped);
}
}
}
write_out_deps(sess, &outputs, &output_paths);
if sess.opts.output_types.contains_key(&OutputType::DepInfo) &&
sess.opts.output_types.len() == 1 {
return Ok(())
if sess.opts.output_types.contains_key(&OutputType::DepInfo)
&& sess.opts.output_types.len() == 1
{
return Ok(());
}
if let &Some(ref dir) = outdir {
@@ -182,28 +193,32 @@ macro_rules! controller_entry_point {
let arenas = AllArenas::new();
// Construct the HIR map
let hir_map = time(sess,
"indexing hir",
|| hir_map::map_crate(sess, cstore, &mut hir_forest, &defs));
let hir_map = time(sess, "indexing hir", || {
hir_map::map_crate(sess, cstore, &mut hir_forest, &defs)
});
{
hir_map.dep_graph.assert_ignored();
controller_entry_point!(after_hir_lowering,
sess,
CompileState::state_after_hir_lowering(input,
sess,
outdir,
output,
&arenas,
&cstore,
&hir_map,
&analysis,
&resolutions,
&expanded_crate,
&hir_map.krate(),
&outputs,
&crate_name),
Ok(()));
controller_entry_point!(
after_hir_lowering,
sess,
CompileState::state_after_hir_lowering(
input,
sess,
outdir,
output,
&arenas,
&cstore,
&hir_map,
&analysis,
&resolutions,
&expanded_crate,
&hir_map.krate(),
&outputs,
&crate_name
),
Ok(())
);
}
let opt_crate = if control.keep_ast {
@@ -213,60 +228,64 @@ macro_rules! controller_entry_point {
None
};
phase_3_run_analysis_passes(&*trans,
control,
sess,
cstore,
hir_map,
analysis,
resolutions,
&arenas,
&crate_name,
&outputs,
|tcx, analysis, rx, result| {
{
// Eventually, we will want to track plugins.
tcx.dep_graph.with_ignore(|| {
let mut state = CompileState::state_after_analysis(input,
sess,
outdir,
output,
opt_crate,
tcx.hir.krate(),
&analysis,
tcx,
&crate_name);
(control.after_analysis.callback)(&mut state);
});
phase_3_run_analysis_passes(
&*trans,
control,
sess,
cstore,
hir_map,
analysis,
resolutions,
&arenas,
&crate_name,
&outputs,
|tcx, analysis, rx, result| {
{
// Eventually, we will want to track plugins.
tcx.dep_graph.with_ignore(|| {
let mut state = CompileState::state_after_analysis(
input,
sess,
outdir,
output,
opt_crate,
tcx.hir.krate(),
&analysis,
tcx,
&crate_name,
);
(control.after_analysis.callback)(&mut state);
});
if control.after_analysis.stop == Compilation::Stop {
return result.and_then(|_| Err(CompileIncomplete::Stopped));
if control.after_analysis.stop == Compilation::Stop {
return result.and_then(|_| Err(CompileIncomplete::Stopped));
}
}
}
result?;
result?;
if log_enabled!(::log::Level::Info) {
println!("Pre-trans");
tcx.print_debug_stats();
}
let ongoing_trans = phase_4_translate_to_llvm(&*trans, tcx, rx);
if log_enabled!(::log::Level::Info) {
println!("Post-trans");
tcx.print_debug_stats();
}
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, &outputs) {
sess.err(&format!("could not emit MIR: {}", e));
sess.abort_if_errors();
if log_enabled!(::log::Level::Info) {
println!("Pre-trans");
tcx.print_debug_stats();
}
}
Ok((outputs.clone(), ongoing_trans, tcx.dep_graph.clone()))
})??
let ongoing_trans = phase_4_translate_to_llvm(&*trans, tcx, rx);
if log_enabled!(::log::Level::Info) {
println!("Post-trans");
tcx.print_debug_stats();
}
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, &outputs) {
sess.err(&format!("could not emit MIR: {}", e));
sess.abort_if_errors();
}
}
Ok((outputs.clone(), ongoing_trans, tcx.dep_graph.clone()))
},
)??
};
if sess.opts.debugging_opts.print_type_sizes {
@@ -391,10 +410,7 @@ pub struct CompileState<'a, 'tcx: 'a> {
}
impl<'a, 'tcx> CompileState<'a, 'tcx> {
fn empty(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>)
-> Self {
fn empty(input: &'a Input, session: &'tcx Session, out_dir: &'a Option<PathBuf>) -> Self {
CompileState {
input,
session,
@@ -415,13 +431,14 @@ fn empty(input: &'a Input,
}
}
fn state_after_parse(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
krate: ast::Crate,
cstore: &'tcx CStore)
-> Self {
fn state_after_parse(
input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
krate: ast::Crate,
cstore: &'tcx CStore,
) -> Self {
CompileState {
// Initialize the registry before moving `krate`
registry: Some(Registry::new(&session, krate.span)),
@@ -432,14 +449,15 @@ fn state_after_parse(input: &'a Input,
}
}
fn state_after_expand(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
cstore: &'tcx CStore,
expanded_crate: &'a ast::Crate,
crate_name: &'a str)
-> Self {
fn state_after_expand(
input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
cstore: &'tcx CStore,
expanded_crate: &'a ast::Crate,
crate_name: &'a str,
) -> Self {
CompileState {
crate_name: Some(crate_name),
cstore: Some(cstore),
@@ -449,20 +467,21 @@ fn state_after_expand(input: &'a Input,
}
}
fn state_after_hir_lowering(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
arenas: &'tcx AllArenas<'tcx>,
cstore: &'tcx CStore,
hir_map: &'a hir_map::Map<'tcx>,
analysis: &'a ty::CrateAnalysis,
resolutions: &'a Resolutions,
krate: &'a ast::Crate,
hir_crate: &'a hir::Crate,
output_filenames: &'a OutputFilenames,
crate_name: &'a str)
-> Self {
fn state_after_hir_lowering(
input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
arenas: &'tcx AllArenas<'tcx>,
cstore: &'tcx CStore,
hir_map: &'a hir_map::Map<'tcx>,
analysis: &'a ty::CrateAnalysis,
resolutions: &'a Resolutions,
krate: &'a ast::Crate,
hir_crate: &'a hir::Crate,
output_filenames: &'a OutputFilenames,
crate_name: &'a str,
) -> Self {
CompileState {
crate_name: Some(crate_name),
arenas: Some(arenas),
@@ -478,16 +497,17 @@ fn state_after_hir_lowering(input: &'a Input,
}
}
fn state_after_analysis(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
krate: Option<&'a ast::Crate>,
hir_crate: &'a hir::Crate,
analysis: &'a ty::CrateAnalysis,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_name: &'a str)
-> Self {
fn state_after_analysis(
input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
krate: Option<&'a ast::Crate>,
hir_crate: &'a hir::Crate,
analysis: &'a ty::CrateAnalysis,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_name: &'a str,
) -> Self {
CompileState {
analysis: Some(analysis),
tcx: Some(tcx),
@@ -499,11 +519,12 @@ fn state_after_analysis(input: &'a Input,
}
}
fn state_when_compilation_done(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>)
-> Self {
fn state_when_compilation_done(
input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
out_file: &'a Option<PathBuf>,
) -> Self {
CompileState {
out_file: out_file.as_ref().map(|s| &**s),
..CompileState::empty(input, session, out_dir)
@@ -511,27 +532,24 @@ fn state_when_compilation_done(input: &'a Input,
}
}
pub fn phase_1_parse_input<'a>(control: &CompileController,
sess: &'a Session,
input: &Input)
-> PResult<'a, ast::Crate> {
sess.diagnostic().set_continue_after_error(control.continue_parse_after_error);
pub fn phase_1_parse_input<'a>(
control: &CompileController,
sess: &'a Session,
input: &Input,
) -> PResult<'a, ast::Crate> {
sess.diagnostic()
.set_continue_after_error(control.continue_parse_after_error);
if sess.profile_queries() {
profile::begin(sess);
}
let krate = time(sess, "parsing", || {
match *input {
Input::File(ref file) => {
parse::parse_crate_from_file(file, &sess.parse_sess)
}
Input::Str { ref input, ref name } => {
parse::parse_crate_from_source_str(name.clone(),
input.clone(),
&sess.parse_sess)
}
}
let krate = time(sess, "parsing", || match *input {
Input::File(ref file) => parse::parse_crate_from_file(file, &sess.parse_sess),
Input::Str {
ref input,
ref name,
} => parse::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess),
})?;
sess.diagnostic().set_continue_after_error(true);
@@ -541,7 +559,10 @@ pub fn phase_1_parse_input<'a>(control: &CompileController,
}
if sess.opts.debugging_opts.input_stats {
println!("Lines of code: {}", sess.codemap().count_lines());
println!(
"Lines of code: {}",
sess.codemap().count_lines()
);
println!("Pre-expansion node count: {}", count_nodes(&krate));
}
@@ -586,16 +607,19 @@ pub struct InnerExpansionResult<'a> {
/// standard library and prelude, and name resolution.
///
/// Returns `None` if we're aborting after handling -W help.
pub fn phase_2_configure_and_expand<F>(sess: &Session,
cstore: &CStore,
krate: ast::Crate,
registry: Option<Registry>,
crate_name: &str,
addl_plugins: Option<Vec<String>>,
make_glob_map: MakeGlobMap,
after_expand: F)
-> Result<ExpansionResult, CompileIncomplete>
where F: FnOnce(&ast::Crate) -> CompileResult {
pub fn phase_2_configure_and_expand<F>(
sess: &Session,
cstore: &CStore,
krate: ast::Crate,
registry: Option<Registry>,
crate_name: &str,
addl_plugins: Option<Vec<String>>,
make_glob_map: MakeGlobMap,
after_expand: F,
) -> Result<ExpansionResult, CompileIncomplete>
where
F: FnOnce(&ast::Crate) -> CompileResult,
{
// Currently, we ignore the name resolution data structures for the purposes of dependency
// tracking. Instead we will run name resolution and include its output in the hash of each
// item, much like we do for macro expansion. In other words, the hash reflects not just
@@ -603,52 +627,72 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
// this back at some point.
let mut crate_loader = CrateLoader::new(sess, &cstore, &crate_name);
let resolver_arenas = Resolver::arenas();
let result = phase_2_configure_and_expand_inner(sess, cstore, krate, registry, crate_name,
addl_plugins, make_glob_map, &resolver_arenas,
&mut crate_loader, after_expand);
let result = phase_2_configure_and_expand_inner(
sess,
cstore,
krate,
registry,
crate_name,
addl_plugins,
make_glob_map,
&resolver_arenas,
&mut crate_loader,
after_expand,
);
match result {
Ok(InnerExpansionResult {expanded_crate, resolver, hir_forest}) => {
Ok(ExpansionResult {
expanded_crate,
defs: resolver.definitions,
hir_forest,
resolutions: Resolutions {
freevars: resolver.freevars,
export_map: resolver.export_map,
trait_map: resolver.trait_map,
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
maybe_unused_extern_crates: resolver.maybe_unused_extern_crates,
},
Ok(InnerExpansionResult {
expanded_crate,
resolver,
hir_forest,
}) => Ok(ExpansionResult {
expanded_crate,
defs: resolver.definitions,
hir_forest,
resolutions: Resolutions {
freevars: resolver.freevars,
export_map: resolver.export_map,
trait_map: resolver.trait_map,
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
maybe_unused_extern_crates: resolver.maybe_unused_extern_crates,
},
analysis: ty::CrateAnalysis {
access_levels: Lrc::new(AccessLevels::default()),
name: crate_name.to_string(),
glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
analysis: ty::CrateAnalysis {
access_levels: Lrc::new(AccessLevels::default()),
name: crate_name.to_string(),
glob_map: if resolver.make_glob_map {
Some(resolver.glob_map)
} else {
None
},
})
}
Err(x) => Err(x)
},
}),
Err(x) => Err(x),
}
}
/// Same as phase_2_configure_and_expand, but doesn't let you keep the resolver
/// around
pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
cstore: &'a CStore,
krate: ast::Crate,
registry: Option<Registry>,
crate_name: &str,
addl_plugins: Option<Vec<String>>,
make_glob_map: MakeGlobMap,
resolver_arenas: &'a ResolverArenas<'a>,
crate_loader: &'a mut CrateLoader,
after_expand: F)
-> Result<InnerExpansionResult<'a>, CompileIncomplete>
where F: FnOnce(&ast::Crate) -> CompileResult,
pub fn phase_2_configure_and_expand_inner<'a, F>(
sess: &'a Session,
cstore: &'a CStore,
krate: ast::Crate,
registry: Option<Registry>,
crate_name: &str,
addl_plugins: Option<Vec<String>>,
make_glob_map: MakeGlobMap,
resolver_arenas: &'a ResolverArenas<'a>,
crate_loader: &'a mut CrateLoader,
after_expand: F,
) -> Result<InnerExpansionResult<'a>, CompileIncomplete>
where
F: FnOnce(&ast::Crate) -> CompileResult,
{
let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess,
sess.opts.test,
sess.opts.debugging_opts.edition);
let (mut krate, features) = syntax::config::features(
krate,
&sess.parse_sess,
sess.opts.test,
sess.opts.debugging_opts.edition,
);
// these need to be set "early" so that expansion sees `quote` if enabled.
sess.init_features(features);
@@ -657,17 +701,16 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
let disambiguator = compute_crate_disambiguator(sess);
sess.crate_disambiguator.set(disambiguator);
rustc_incremental::prepare_session_directory(
sess,
&crate_name,
disambiguator,
);
rustc_incremental::prepare_session_directory(sess, &crate_name, disambiguator);
if sess.opts.incremental.is_some() {
time(sess, "garbage collect incremental cache directory", || {
if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
warn!("Error while trying to garbage collect incremental \
compilation cache directory: {}", e);
warn!(
"Error while trying to garbage collect incremental \
compilation cache directory: {}",
e
);
}
});
}
@@ -690,23 +733,31 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
let mut addl_plugins = Some(addl_plugins);
let registrars = time(sess, "plugin loading", || {
plugin::load::load_plugins(sess,
&cstore,
&krate,
crate_name,
addl_plugins.take().unwrap())
plugin::load::load_plugins(
sess,
&cstore,
&krate,
crate_name,
addl_plugins.take().unwrap(),
)
});
let mut registry = registry.unwrap_or(Registry::new(sess, krate.span));
time(sess, "plugin registration", || {
if sess.features_untracked().rustc_diagnostic_macros {
registry.register_macro("__diagnostic_used",
diagnostics::plugin::expand_diagnostic_used);
registry.register_macro("__register_diagnostic",
diagnostics::plugin::expand_register_diagnostic);
registry.register_macro("__build_diagnostic_array",
diagnostics::plugin::expand_build_diagnostic_array);
registry.register_macro(
"__diagnostic_used",
diagnostics::plugin::expand_diagnostic_used,
);
registry.register_macro(
"__register_diagnostic",
diagnostics::plugin::expand_register_diagnostic,
);
registry.register_macro(
"__build_diagnostic_array",
diagnostics::plugin::expand_build_diagnostic_array,
);
}
for registrar in registrars {
@@ -716,8 +767,15 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
});
let whitelisted_legacy_custom_derives = registry.take_whitelisted_custom_derives();
let Registry { syntax_exts, early_lint_passes, late_lint_passes, lint_groups,
llvm_passes, attributes, .. } = registry;
let Registry {
syntax_exts,
early_lint_passes,
late_lint_passes,
lint_groups,
llvm_passes,
attributes,
..
} = registry;
sess.track_errors(|| {
let mut ls = sess.lint_store.borrow_mut();
@@ -742,16 +800,19 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
return Err(CompileIncomplete::Stopped);
}
let mut resolver = Resolver::new(sess,
cstore,
&krate,
crate_name,
make_glob_map,
crate_loader,
&resolver_arenas);
let mut resolver = Resolver::new(
sess,
cstore,
&krate,
crate_name,
make_glob_map,
crate_loader,
&resolver_arenas,
);
resolver.whitelisted_legacy_custom_derives = whitelisted_legacy_custom_derives;
syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features_untracked().quote);
// Expand all macros
krate = time(sess, "expansion", || {
// Windows dlls do not have rpaths, so they don't know how to find their
// dependencies. It's up to us to tell the system where to find all the
@@ -769,18 +830,23 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
let mut old_path = OsString::new();
if cfg!(windows) {
old_path = env::var_os("PATH").unwrap_or(old_path);
let mut new_path = sess.host_filesearch(PathKind::All)
.get_dylib_search_paths();
let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
for path in env::split_paths(&old_path) {
if !new_path.contains(&path) {
new_path.push(path);
}
}
env::set_var("PATH",
&env::join_paths(new_path.iter()
.filter(|p| env::join_paths(iter::once(p)).is_ok()))
.unwrap());
env::set_var(
"PATH",
&env::join_paths(
new_path
.iter()
.filter(|p| env::join_paths(iter::once(p)).is_ok()),
).unwrap(),
);
}
// Create the config for macro expansion
let features = sess.features_untracked();
let cfg = syntax::ext::expand::ExpansionConfig {
features: Some(&features),
@@ -793,16 +859,23 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
let mut ecx = ExtCtxt::new(&sess.parse_sess, cfg, &mut resolver);
let err_count = ecx.parse_sess.span_diagnostic.err_count();
// Expand macros now!
let krate = time(sess, "expand crate", || {
ecx.monotonic_expander().expand_crate(krate)
});
// The rest is error reporting
time(sess, "check unused macros", || {
ecx.check_unused_macros();
});
let mut missing_fragment_specifiers: Vec<_> =
ecx.parse_sess.missing_fragment_specifiers.borrow().iter().cloned().collect();
let mut missing_fragment_specifiers: Vec<_> = ecx.parse_sess
.missing_fragment_specifiers
.borrow()
.iter()
.cloned()
.collect();
missing_fragment_specifiers.sort();
for span in missing_fragment_specifiers {
let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
@@ -819,12 +892,14 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
});
krate = time(sess, "maybe building test harness", || {
syntax::test::modify_for_testing(&sess.parse_sess,
&mut resolver,
sess.opts.test,
krate,
sess.diagnostic(),
&sess.features_untracked())
syntax::test::modify_for_testing(
&sess.parse_sess,
&mut resolver,
sess.opts.test,
krate,
sess.diagnostic(),
&sess.features_untracked(),
)
});
// If we're actually rustdoc then there's no need to actually compile
@@ -842,21 +917,20 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
let num_crate_types = crate_types.len();
let is_proc_macro_crate = crate_types.contains(&config::CrateTypeProcMacro);
let is_test_crate = sess.opts.test;
syntax_ext::proc_macro_registrar::modify(&sess.parse_sess,
&mut resolver,
krate,
is_proc_macro_crate,
is_test_crate,
num_crate_types,
sess.diagnostic())
syntax_ext::proc_macro_registrar::modify(
&sess.parse_sess,
&mut resolver,
krate,
is_proc_macro_crate,
is_test_crate,
num_crate_types,
sess.diagnostic(),
)
});
}
krate = time(sess, "creating allocators", || {
allocator::expand::modify(&sess.parse_sess,
&mut resolver,
krate,
sess.diagnostic())
allocator::expand::modify(&sess.parse_sess, &mut resolver, krate, sess.diagnostic())
});
after_expand(&krate)?;
@@ -873,9 +947,9 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
println!("{}", json::as_json(&krate));
}
time(sess,
"AST validation",
|| ast_validation::check_crate(sess, &krate));
time(sess, "AST validation", || {
ast_validation::check_crate(sess, &krate)
});
time(sess, "name resolution", || -> CompileResult {
resolver.resolve_crate(&krate);
@@ -885,11 +959,13 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
// Needs to go *after* expansion to be able to check the results of macro expansion.
time(sess, "complete gated feature checking", || {
sess.track_errors(|| {
syntax::feature_gate::check_crate(&krate,
&sess.parse_sess,
&sess.features_untracked(),
&attributes,
sess.opts.unstable_features);
syntax::feature_gate::check_crate(
&krate,
&sess.parse_sess,
&sess.features_untracked(),
&attributes,
sess.opts.unstable_features,
);
})
})?;
@@ -905,11 +981,12 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
None => DepGraph::new_disabled(),
Some(future) => {
let prev_graph = time(sess, "blocked while dep-graph loading finishes", || {
future.open()
.unwrap_or_else(|e| rustc_incremental::LoadResult::Error {
message: format!("could not decode incremental cache: {:?}", e)
})
.open(sess)
future
.open()
.unwrap_or_else(|e| rustc_incremental::LoadResult::Error {
message: format!("could not decode incremental cache: {:?}", e),
})
.open(sess)
});
DepGraph::new(prev_graph)
}
@@ -924,9 +1001,9 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
hir_map::Forest::new(hir_crate, &dep_graph)
});
time(sess,
"early lint checks",
|| lint::check_ast_crate(sess, &krate));
time(sess, "early lint checks", || {
lint::check_ast_crate(sess, &krate)
});
// Discard hygiene data, which isn't required after lowering to HIR.
if !sess.opts.debugging_opts.keep_hygiene_data {
@@ -965,39 +1042,43 @@ pub fn default_provide_extern(providers: &mut ty::maps::Providers) {
/// Run the resolution, typechecking, region checking and other
/// miscellaneous analysis passes on the crate. Return various
/// structures carrying the results of the analysis.
pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate,
control: &CompileController,
sess: &'tcx Session,
cstore: &'tcx CrateStore,
hir_map: hir_map::Map<'tcx>,
mut analysis: ty::CrateAnalysis,
resolutions: Resolutions,
arenas: &'tcx AllArenas<'tcx>,
name: &str,
output_filenames: &OutputFilenames,
f: F)
-> Result<R, CompileIncomplete>
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
ty::CrateAnalysis,
mpsc::Receiver<Box<Any + Send>>,
CompileResult) -> R
pub fn phase_3_run_analysis_passes<'tcx, F, R>(
trans: &TransCrate,
control: &CompileController,
sess: &'tcx Session,
cstore: &'tcx CrateStore,
hir_map: hir_map::Map<'tcx>,
mut analysis: ty::CrateAnalysis,
resolutions: Resolutions,
arenas: &'tcx AllArenas<'tcx>,
name: &str,
output_filenames: &OutputFilenames,
f: F,
) -> Result<R, CompileIncomplete>
where
F: for<'a> FnOnce(
TyCtxt<'a, 'tcx, 'tcx>,
ty::CrateAnalysis,
mpsc::Receiver<Box<Any + Send>>,
CompileResult,
) -> R,
{
let query_result_on_disk_cache = time(sess,
"load query result cache",
|| rustc_incremental::load_query_result_cache(sess));
let query_result_on_disk_cache = time(sess, "load query result cache", || {
rustc_incremental::load_query_result_cache(sess)
});
time(sess,
"looking for entry point",
|| middle::entry::find_entry_point(sess, &hir_map, name));
time(sess, "looking for entry point", || {
middle::entry::find_entry_point(sess, &hir_map, name)
});
sess.plugin_registrar_fn.set(time(sess, "looking for plugin registrar", || {
plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map)
}));
sess.derive_registrar_fn.set(derive_registrar::find(&hir_map));
sess.plugin_registrar_fn
.set(time(sess, "looking for plugin registrar", || {
plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map)
}));
sess.derive_registrar_fn
.set(derive_registrar::find(&hir_map));
time(sess,
"loop checking",
|| loops::check_crate(sess, &hir_map));
time(sess, "loop checking", || loops::check_crate(sess, &hir_map));
let mut local_providers = ty::maps::Providers::default();
default_provide(&mut local_providers);
@@ -1011,115 +1092,113 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate,
let (tx, rx) = mpsc::channel();
TyCtxt::create_and_enter(sess,
cstore,
local_providers,
extern_providers,
arenas,
resolutions,
hir_map,
query_result_on_disk_cache,
name,
tx,
output_filenames,
|tcx| {
// Do some initialization of the DepGraph that can only be done with the
// tcx available.
rustc_incremental::dep_graph_tcx_init(tcx);
TyCtxt::create_and_enter(
sess,
cstore,
local_providers,
extern_providers,
arenas,
resolutions,
hir_map,
query_result_on_disk_cache,
name,
tx,
output_filenames,
|tcx| {
// Do some initialization of the DepGraph that can only be done with the
// tcx available.
rustc_incremental::dep_graph_tcx_init(tcx);
time(sess, "attribute checking", || {
hir::check_attr::check_crate(tcx)
});
time(sess, "attribute checking", || {
hir::check_attr::check_crate(tcx)
});
time(sess,
"stability checking",
|| stability::check_unstable_api_usage(tcx));
time(sess, "stability checking", || {
stability::check_unstable_api_usage(tcx)
});
// passes are timed inside typeck
match typeck::check_crate(tcx) {
Ok(x) => x,
Err(x) => {
f(tcx, analysis, rx, Err(x));
return Err(x);
// passes are timed inside typeck
match typeck::check_crate(tcx) {
Ok(x) => x,
Err(x) => {
f(tcx, analysis, rx, Err(x));
return Err(x);
}
}
}
time(sess,
"rvalue promotion",
|| rvalue_promotion::check_crate(tcx));
time(sess, "rvalue promotion", || {
rvalue_promotion::check_crate(tcx)
});
analysis.access_levels =
time(sess, "privacy checking", || rustc_privacy::check_crate(tcx));
analysis.access_levels =
time(sess, "privacy checking", || rustc_privacy::check_crate(tcx));
time(sess,
"intrinsic checking",
|| middle::intrinsicck::check_crate(tcx));
time(sess, "intrinsic checking", || {
middle::intrinsicck::check_crate(tcx)
});
time(sess,
"match checking",
|| mir::matchck_crate(tcx));
time(sess, "match checking", || mir::matchck_crate(tcx));
// this must run before MIR dump, because
// "not all control paths return a value" is reported here.
//
// maybe move the check to a MIR pass?
time(sess,
"liveness checking",
|| middle::liveness::check_crate(tcx));
// this must run before MIR dump, because
// "not all control paths return a value" is reported here.
//
// maybe move the check to a MIR pass?
time(sess, "liveness checking", || {
middle::liveness::check_crate(tcx)
});
time(sess,
"borrow checking",
|| borrowck::check_crate(tcx));
time(sess, "borrow checking", || borrowck::check_crate(tcx));
time(sess,
"MIR borrow checking",
|| for def_id in tcx.body_owners() { tcx.mir_borrowck(def_id); });
time(sess, "MIR borrow checking", || {
for def_id in tcx.body_owners() {
tcx.mir_borrowck(def_id);
}
});
time(sess,
"MIR effect checking",
|| for def_id in tcx.body_owners() {
mir::transform::check_unsafety::check_unsafety(tcx, def_id)
});
// Avoid overwhelming user with errors if type checking failed.
// I'm not sure how helpful this is, to be honest, but it avoids
// a
// lot of annoying errors in the compile-fail tests (basically,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
if sess.err_count() > 0 {
return Ok(f(tcx, analysis, rx, sess.compile_status()));
}
time(sess, "MIR effect checking", || {
for def_id in tcx.body_owners() {
mir::transform::check_unsafety::check_unsafety(tcx, def_id)
}
});
// Avoid overwhelming user with errors if type checking failed.
// I'm not sure how helpful this is, to be honest, but it avoids
// a
// lot of annoying errors in the compile-fail tests (basically,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
if sess.err_count() > 0 {
return Ok(f(tcx, analysis, rx, sess.compile_status()));
}
time(sess, "death checking", || middle::dead::check_crate(tcx));
time(sess, "death checking", || middle::dead::check_crate(tcx));
time(sess, "unused lib feature checking", || {
stability::check_unused_or_stable_features(tcx)
});
time(sess, "unused lib feature checking", || {
stability::check_unused_or_stable_features(tcx)
});
time(sess, "lint checking", || lint::check_crate(tcx));
time(sess, "lint checking", || lint::check_crate(tcx));
time(sess,
"dumping chalk-like clauses",
|| rustc_traits::lowering::dump_program_clauses(tcx));
time(sess, "dumping chalk-like clauses", || {
rustc_traits::lowering::dump_program_clauses(tcx)
});
return Ok(f(tcx, analysis, rx, tcx.sess.compile_status()));
})
return Ok(f(tcx, analysis, rx, tcx.sess.compile_status()));
},
)
}
/// Run the translation phase to LLVM, after which the AST and analysis can
/// be discarded.
pub fn phase_4_translate_to_llvm<'a, 'tcx>(trans: &TransCrate,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
rx: mpsc::Receiver<Box<Any + Send>>)
-> Box<Any> {
time(tcx.sess,
"resolving dependency formats",
|| ::rustc::middle::dependency_format::calculate(tcx));
pub fn phase_4_translate_to_llvm<'a, 'tcx>(
trans: &TransCrate,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
rx: mpsc::Receiver<Box<Any + Send>>,
) -> Box<Any> {
time(tcx.sess, "resolving dependency formats", || {
::rustc::middle::dependency_format::calculate(tcx)
});
let translation =
time(tcx.sess, "translation", move || {
trans.trans_crate(tcx, rx)
});
let translation = time(tcx.sess, "translation", move || trans.trans_crate(tcx, rx));
if tcx.sess.profile_queries() {
profile::dump(&tcx.sess, "profile_queries".to_string())
}
@@ -1134,27 +1213,27 @@ fn escape_dep_filename(filename: &FileName) -> String {
}
// Returns all the paths that correspond to generated files.
fn generated_output_paths(sess: &Session,
outputs: &OutputFilenames,
exact_name: bool,
crate_name: &str) -> Vec<PathBuf> {
fn generated_output_paths(
sess: &Session,
outputs: &OutputFilenames,
exact_name: bool,
crate_name: &str,
) -> Vec<PathBuf> {
let mut out_filenames = Vec::new();
for output_type in sess.opts.output_types.keys() {
let file = outputs.path(*output_type);
match *output_type {
// If the filename has been overridden using `-o`, it will not be modified
// by appending `.rlib`, `.exe`, etc., so we can skip this transformation.
OutputType::Exe if !exact_name => {
for crate_type in sess.crate_types.borrow().iter() {
let p = ::rustc_trans_utils::link::filename_for_input(
sess,
*crate_type,
crate_name,
outputs
);
out_filenames.push(p);
}
}
OutputType::Exe if !exact_name => for crate_type in sess.crate_types.borrow().iter() {
let p = ::rustc_trans_utils::link::filename_for_input(
sess,
*crate_type,
crate_name,
outputs,
);
out_filenames.push(p);
},
OutputType::DepInfo if sess.opts.debugging_opts.dep_info_omit_d_target => {
// Don't add the dep-info output when omitting it from dep-info targets
}
@@ -1169,24 +1248,28 @@ fn generated_output_paths(sess: &Session,
// Runs `f` on every output file path and returns the first non-None result, or None if `f`
// returns None for every file path.
fn check_output<F, T>(output_paths: &Vec<PathBuf>, f: F) -> Option<T>
where F: Fn(&PathBuf) -> Option<T> {
for output_path in output_paths {
if let Some(result) = f(output_path) {
return Some(result);
}
}
None
where
F: Fn(&PathBuf) -> Option<T>,
{
for output_path in output_paths {
if let Some(result) = f(output_path) {
return Some(result);
}
}
None
}
pub fn output_contains_path(output_paths: &Vec<PathBuf>, input_path: &PathBuf) -> bool {
let input_path = input_path.canonicalize().ok();
if input_path.is_none() {
return false
return false;
}
let check = |output_path: &PathBuf| {
if output_path.canonicalize().ok() == input_path {
Some(())
} else { None }
} else {
None
}
};
check_output(output_paths, check).is_some()
}
@@ -1195,100 +1278,92 @@ pub fn output_conflicts_with_dir(output_paths: &Vec<PathBuf>) -> Option<PathBuf>
let check = |output_path: &PathBuf| {
if output_path.is_dir() {
Some(output_path.clone())
} else { None }
} else {
None
}
};
check_output(output_paths, check)
}
fn write_out_deps(sess: &Session,
outputs: &OutputFilenames,
out_filenames: &Vec<PathBuf>) {
fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &Vec<PathBuf>) {
// Write out dependency rules to the dep-info file if requested
if !sess.opts.output_types.contains_key(&OutputType::DepInfo) {
return;
}
let deps_filename = outputs.path(OutputType::DepInfo);
let result =
(|| -> io::Result<()> {
// Build a list of files used to compile the output and
// write Makefile-compatible dependency rules
let files: Vec<String> = sess.codemap()
.files()
.iter()
.filter(|fmap| fmap.is_real_file())
.filter(|fmap| !fmap.is_imported())
.map(|fmap| escape_dep_filename(&fmap.name))
.collect();
let mut file = fs::File::create(&deps_filename)?;
for path in out_filenames {
write!(file, "{}: {}\n\n", path.display(), files.join(" "))?;
}
let result = (|| -> io::Result<()> {
// Build a list of files used to compile the output and
// write Makefile-compatible dependency rules
let files: Vec<String> = sess.codemap()
.files()
.iter()
.filter(|fmap| fmap.is_real_file())
.filter(|fmap| !fmap.is_imported())
.map(|fmap| escape_dep_filename(&fmap.name))
.collect();
let mut file = fs::File::create(&deps_filename)?;
for path in out_filenames {
write!(file, "{}: {}\n\n", path.display(), files.join(" "))?;
}
// Emit a fake target for each input file to the compilation. This
// prevents `make` from spitting out an error if a file is later
// deleted. For more info see #28735
for path in files {
writeln!(file, "{}:", path)?;
}
Ok(())
})();
// Emit a fake target for each input file to the compilation. This
// prevents `make` from spitting out an error if a file is later
// deleted. For more info see #28735
for path in files {
writeln!(file, "{}:", path)?;
}
Ok(())
})();
match result {
Ok(()) => {}
Err(e) => {
sess.fatal(&format!("error writing dependencies to `{}`: {}",
deps_filename.display(),
e));
sess.fatal(&format!(
"error writing dependencies to `{}`: {}",
deps_filename.display(),
e
));
}
}
}
pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<config::CrateType> {
// Unconditionally collect crate types from attributes to make them used
let attr_types: Vec<config::CrateType> =
attrs.iter()
.filter_map(|a| {
if a.check_name("crate_type") {
match a.value_str() {
Some(ref n) if *n == "rlib" => {
Some(config::CrateTypeRlib)
}
Some(ref n) if *n == "dylib" => {
Some(config::CrateTypeDylib)
}
Some(ref n) if *n == "cdylib" => {
Some(config::CrateTypeCdylib)
}
Some(ref n) if *n == "lib" => {
Some(config::default_lib_output())
}
Some(ref n) if *n == "staticlib" => {
Some(config::CrateTypeStaticlib)
}
Some(ref n) if *n == "proc-macro" => {
Some(config::CrateTypeProcMacro)
}
Some(ref n) if *n == "bin" => Some(config::CrateTypeExecutable),
Some(_) => {
session.buffer_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
ast::CRATE_NODE_ID,
a.span,
"invalid `crate_type` value");
None
}
_ => {
session.struct_span_err(a.span, "`crate_type` requires a value")
.note("for example: `#![crate_type=\"lib\"]`")
.emit();
None
}
}
} else {
None
}
})
.collect();
let attr_types: Vec<config::CrateType> = attrs
.iter()
.filter_map(|a| {
if a.check_name("crate_type") {
match a.value_str() {
Some(ref n) if *n == "rlib" => Some(config::CrateTypeRlib),
Some(ref n) if *n == "dylib" => Some(config::CrateTypeDylib),
Some(ref n) if *n == "cdylib" => Some(config::CrateTypeCdylib),
Some(ref n) if *n == "lib" => Some(config::default_lib_output()),
Some(ref n) if *n == "staticlib" => Some(config::CrateTypeStaticlib),
Some(ref n) if *n == "proc-macro" => Some(config::CrateTypeProcMacro),
Some(ref n) if *n == "bin" => Some(config::CrateTypeExecutable),
Some(_) => {
session.buffer_lint(
lint::builtin::UNKNOWN_CRATE_TYPES,
ast::CRATE_NODE_ID,
a.span,
"invalid `crate_type` value",
);
None
}
_ => {
session
.struct_span_err(a.span, "`crate_type` requires a value")
.note("for example: `#![crate_type=\"lib\"]`")
.emit();
None
}
}
} else {
None
}
})
.collect();
// If we're generating a test executable, then ignore all other output
// styles at all other locations
@@ -1303,7 +1378,9 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
if base.is_empty() {
base.extend(attr_types);
if base.is_empty() {
base.push(::rustc_trans_utils::link::default_output_for_target(session));
base.push(::rustc_trans_utils::link::default_output_for_target(
session,
));
}
base.sort();
base.dedup();
@@ -1314,9 +1391,10 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
let res = !::rustc_trans_utils::link::invalid_output_for_target(session, *crate_type);
if !res {
session.warn(&format!("dropping unsupported crate type `{}` for target `{}`",
*crate_type,
session.opts.target_triple));
session.warn(&format!(
"dropping unsupported crate type `{}` for target `{}`",
*crate_type, session.opts.target_triple
));
}
res
@@ -1351,19 +1429,22 @@ pub fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
// Also incorporate crate type, so that we don't get symbol conflicts when
// linking against a library of the same name, if this is an executable.
let is_exe = session.crate_types.borrow().contains(&config::CrateTypeExecutable);
let is_exe = session
.crate_types
.borrow()
.contains(&config::CrateTypeExecutable);
hasher.write(if is_exe { b"exe" } else { b"lib" });
CrateDisambiguator::from(hasher.finish())
}
pub fn build_output_filenames(input: &Input,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
attrs: &[ast::Attribute],
sess: &Session)
-> OutputFilenames {
pub fn build_output_filenames(
input: &Input,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
attrs: &[ast::Attribute],
sess: &Session,
) -> OutputFilenames {
match *ofile {
None => {
// "-" as input file will cause the parser to read from stdin so we
@@ -1376,10 +1457,10 @@ pub fn build_output_filenames(input: &Input,
// If a crate name is present, we use it as the link name
let stem = sess.opts
.crate_name
.clone()
.or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string()))
.unwrap_or(input.filestem());
.crate_name
.clone()
.or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string()))
.unwrap_or(input.filestem());
OutputFilenames {
out_directory: dirpath,
@@ -1392,13 +1473,15 @@ pub fn build_output_filenames(input: &Input,
Some(ref out_file) => {
let unnamed_output_types = sess.opts
.output_types
.values()
.filter(|a| a.is_none())
.count();
.output_types
.values()
.filter(|a| a.is_none())
.count();
let ofile = if unnamed_output_types > 1 {
sess.warn("due to multiple output types requested, the explicitly specified \
output file name will be adapted for each output type");
sess.warn(
"due to multiple output types requested, the explicitly specified \
output file name will be adapted for each output type",
);
None
} else {
Some(out_file.clone())
@@ -1414,11 +1497,12 @@ pub fn build_output_filenames(input: &Input,
OutputFilenames {
out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(),
out_filestem: out_file.file_stem()
.unwrap_or(OsStr::new(""))
.to_str()
.unwrap()
.to_string(),
out_filestem: out_file
.file_stem()
.unwrap_or(OsStr::new(""))
.to_str()
.unwrap()
.to_string(),
single_output_file: ofile,
extra: sess.opts.cg.extra_filename.clone(),
outputs: sess.opts.output_types.clone(),
+54 -53
View File
@@ -962,38 +962,38 @@ enum TypeParameters<'a, 'b> {
RibKind<'a>),
}
// The rib kind controls the translation of local
// definitions (`Def::Local`) to upvars (`Def::Upvar`).
/// The rib kind controls the translation of local
/// definitions (`Def::Local`) to upvars (`Def::Upvar`).
#[derive(Copy, Clone, Debug)]
enum RibKind<'a> {
// No translation needs to be applied.
/// No translation needs to be applied.
NormalRibKind,
// We passed through a closure scope at the given node ID.
// Translate upvars as appropriate.
/// We passed through a closure scope at the given node ID.
/// Translate upvars as appropriate.
ClosureRibKind(NodeId /* func id */),
// We passed through an impl or trait and are now in one of its
// methods or associated types. Allow references to ty params that impl or trait
// binds. Disallow any other upvars (including other ty params that are
// upvars).
/// We passed through an impl or trait and are now in one of its
/// methods or associated types. Allow references to ty params that impl or trait
/// binds. Disallow any other upvars (including other ty params that are
/// upvars).
TraitOrImplItemRibKind,
// We passed through an item scope. Disallow upvars.
/// We passed through an item scope. Disallow upvars.
ItemRibKind,
// We're in a constant item. Can't refer to dynamic stuff.
/// We're in a constant item. Can't refer to dynamic stuff.
ConstantItemRibKind,
// We passed through a module.
/// We passed through a module.
ModuleRibKind(Module<'a>),
// We passed through a `macro_rules!` statement
/// We passed through a `macro_rules!` statement
MacroDefinition(DefId),
// All bindings in this rib are type parameters that can't be used
// from the default of a type parameter because they're not declared
// before said type parameter. Also see the `visit_generics` override.
/// All bindings in this rib are type parameters that can't be used
/// from the default of a type parameter because they're not declared
/// before said type parameter. Also see the `visit_generics` override.
ForwardTyParamBanRibKind,
}
@@ -1198,7 +1198,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
// Records a possibly-private value, type, or module definition.
/// Records a possibly-private value, type, or module definition.
#[derive(Clone, Debug)]
pub struct NameBinding<'a> {
kind: NameBindingKind<'a>,
@@ -1408,36 +1408,36 @@ pub struct Resolver<'a> {
prelude: Option<Module<'a>>,
// n.b. This is used only for better diagnostics, not name resolution itself.
/// n.b. This is used only for better diagnostics, not name resolution itself.
has_self: FxHashSet<DefId>,
// Names of fields of an item `DefId` accessible with dot syntax.
// Used for hints during error reporting.
/// Names of fields of an item `DefId` accessible with dot syntax.
/// Used for hints during error reporting.
field_names: FxHashMap<DefId, Vec<Name>>,
// All imports known to succeed or fail.
/// All imports known to succeed or fail.
determined_imports: Vec<&'a ImportDirective<'a>>,
// All non-determined imports.
/// All non-determined imports.
indeterminate_imports: Vec<&'a ImportDirective<'a>>,
// The module that represents the current item scope.
/// The module that represents the current item scope.
current_module: Module<'a>,
// The current set of local scopes for types and values.
// FIXME #4948: Reuse ribs to avoid allocation.
/// The current set of local scopes for types and values.
/// FIXME #4948: Reuse ribs to avoid allocation.
ribs: PerNS<Vec<Rib<'a>>>,
// The current set of local scopes, for labels.
/// The current set of local scopes, for labels.
label_ribs: Vec<Rib<'a>>,
// The trait that the current context can refer to.
/// The trait that the current context can refer to.
current_trait_ref: Option<(Module<'a>, TraitRef)>,
// The current self type if inside an impl (used for better errors).
/// The current self type if inside an impl (used for better errors).
current_self_type: Option<Ty>,
// The idents for the primitive types.
/// The idents for the primitive types.
primitive_type_table: PrimitiveTypeTable,
def_map: DefMap,
@@ -1446,20 +1446,20 @@ pub struct Resolver<'a> {
pub export_map: ExportMap,
pub trait_map: TraitMap,
// A map from nodes to anonymous modules.
// Anonymous modules are pseudo-modules that are implicitly created around items
// contained within blocks.
//
// For example, if we have this:
//
// fn f() {
// fn g() {
// ...
// }
// }
//
// There will be an anonymous module created around `g` with the ID of the
// entry block for `f`.
/// A map from nodes to anonymous modules.
/// Anonymous modules are pseudo-modules that are implicitly created around items
/// contained within blocks.
///
/// For example, if we have this:
///
/// fn f() {
/// fn g() {
/// ...
/// }
/// }
///
/// There will be an anonymous module created around `g` with the ID of the
/// entry block for `f`.
block_map: NodeMap<Module<'a>>,
module_map: FxHashMap<DefId, Module<'a>>,
extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
@@ -1487,7 +1487,8 @@ pub struct Resolver<'a> {
arenas: &'a ResolverArenas<'a>,
dummy_binding: &'a NameBinding<'a>,
use_extern_macros: bool, // true if `#![feature(use_extern_macros)]`
/// true if `#![feature(use_extern_macros)]`
use_extern_macros: bool,
crate_loader: &'a mut CrateLoader,
macro_names: FxHashSet<Ident>,
@@ -1501,29 +1502,29 @@ pub struct Resolver<'a> {
pub whitelisted_legacy_custom_derives: Vec<Name>,
pub found_unresolved_macro: bool,
// List of crate local macros that we need to warn about as being unused.
// Right now this only includes macro_rules! macros, and macros 2.0.
/// List of crate local macros that we need to warn about as being unused.
/// Right now this only includes macro_rules! macros, and macros 2.0.
unused_macros: FxHashSet<DefId>,
// Maps the `Mark` of an expansion to its containing module or block.
/// Maps the `Mark` of an expansion to its containing module or block.
invocations: FxHashMap<Mark, &'a InvocationData<'a>>,
// Avoid duplicated errors for "name already defined".
/// Avoid duplicated errors for "name already defined".
name_already_seen: FxHashMap<Name, Span>,
// If `#![feature(proc_macro)]` is set
/// If `#![feature(proc_macro)]` is set
proc_macro_enabled: bool,
// A set of procedural macros imported by `#[macro_use]` that have already been warned about
/// A set of procedural macros imported by `#[macro_use]` that have already been warned about
warned_proc_macros: FxHashSet<Name>,
potentially_unused_imports: Vec<&'a ImportDirective<'a>>,
// This table maps struct IDs into struct constructor IDs,
// it's not used during normal resolution, only for better error reporting.
/// This table maps struct IDs into struct constructor IDs,
/// it's not used during normal resolution, only for better error reporting.
struct_constructors: DefIdMap<(Def, ty::Visibility)>,
// Only used for better errors on `fn(): fn()`
/// Only used for better errors on `fn(): fn()`
current_type_ascription: Vec<Span>,
injected_crate: Option<Module<'a>>,