use middle::cstore::CrateStore;
use middle::dependency_format;
use session::search_paths::PathKind;
-use session::config::{DebugInfoLevel, PanicStrategy};
+use session::config::DebugInfoLevel;
use ty::tls;
-use util::nodemap::{NodeMap, FnvHashMap};
+use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
use util::common::duration_to_secs_str;
use mir::transform as mir_pass;
use syntax::feature_gate::AttributeType;
use syntax_pos::{Span, MultiSpan};
+use rustc_back::PanicStrategy;
use rustc_back::target::Target;
use rustc_data_structures::flock;
use llvm;
use std::collections::HashMap;
use std::env;
use std::ffi::CString;
+use std::io::Write;
use std::rc::Rc;
use std::fmt;
use std::time::Duration;
pub working_dir: PathBuf,
pub lint_store: RefCell<lint::LintStore>,
pub lints: RefCell<NodeMap<Vec<(lint::LintId, Span, String)>>>,
+ /// Set of (span, message) tuples tracking lint (sub)diagnostics that have
+ /// been set once, but should not be set again, in order to avoid
+ /// redundantly verbose output (Issue #24690).
+ pub one_time_diagnostics: RefCell<FnvHashSet<(Span, String)>>,
pub plugin_llvm_passes: RefCell<Vec<String>>,
pub mir_passes: RefCell<mir_pass::Passes>,
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
pub incr_comp_hashes_time: Cell<Duration>,
// The number of incr. comp. hash computations performed
pub incr_comp_hashes_count: Cell<u64>,
+ // The number of bytes hashed when computing ICH values
+ pub incr_comp_bytes_hashed: Cell<u64>,
// The accumulated time spent on computing symbol hashes
pub symbol_hash_time: Cell<Duration>,
}
pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
&self.parse_sess.span_diagnostic
}
+
+ /// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
+ /// deduplicates on span and message for this `Session`.
+ //
+ // FIXME: if the need arises for one-time diagnostics other than
+ // `span_note`, we almost certainly want to generalize this
+ // "check/insert-into the one-time diagnostics map, then set message if
+ // it's not already there" code to accomodate all of them
+ pub fn diag_span_note_once<'a, 'b>(&'a self,
+ diag_builder: &'b mut DiagnosticBuilder<'a>,
+ span: Span, message: &str) {
+ let span_message = (span, message.to_owned());
+ let fresh = self.one_time_diagnostics.borrow_mut().insert(span_message);
+ if fresh {
+ diag_builder.span_note(span, &message);
+ }
+ }
+
pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
self.parse_sess.codemap()
}
pub fn lto(&self) -> bool {
self.opts.cg.lto
}
+ /// Returns the panic strategy for this compile session. If the user explicitly selected one
+ /// using '-C panic', use that, otherwise use the panic strategy defined by the target.
+ pub fn panic_strategy(&self) -> PanicStrategy {
+ self.opts.cg.panic.unwrap_or(self.target.target.options.panic_strategy)
+ }
pub fn no_landing_pads(&self) -> bool {
- self.opts.debugging_opts.no_landing_pads ||
- self.opts.cg.panic == PanicStrategy::Abort
+ self.opts.debugging_opts.no_landing_pads || self.panic_strategy() == PanicStrategy::Abort
}
pub fn unstable_options(&self) -> bool {
self.opts.debugging_opts.unstable_options
duration_to_secs_str(self.perf_stats.incr_comp_hashes_time.get()));
println!("Total number of incr. comp. hashes computed: {}",
self.perf_stats.incr_comp_hashes_count.get());
+ println!("Total number of bytes hashed for incr. comp.: {}",
+ self.perf_stats.incr_comp_bytes_hashed.get());
+ println!("Average bytes hashed per incr. comp. HIR node: {}",
+ self.perf_stats.incr_comp_bytes_hashed.get() /
+ self.perf_stats.incr_comp_hashes_count.get());
println!("Total time spent computing symbol hashes: {}",
duration_to_secs_str(self.perf_stats.symbol_hash_time.get()));
}
local_crate_source_file,
registry,
cstore,
- Rc::new(codemap::CodeMap::new()))
+ Rc::new(codemap::CodeMap::new()),
+ None)
}
pub fn build_session_with_codemap(sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
registry: errors::registry::Registry,
cstore: Rc<for<'a> CrateStore<'a>>,
- codemap: Rc<codemap::CodeMap>)
+ codemap: Rc<codemap::CodeMap>,
+ emitter_dest: Option<Box<Write + Send>>)
-> Session {
// FIXME: This is not general enough to make the warning lint completely override
// normal diagnostic warnings, since the warning lint can also be denied and changed
.unwrap_or(true);
let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug;
- let emitter: Box<Emitter> = match sopts.error_format {
- config::ErrorOutputType::HumanReadable(color_config) => {
+ let emitter: Box<Emitter> = match (sopts.error_format, emitter_dest) {
+ (config::ErrorOutputType::HumanReadable(color_config), None) => {
Box::new(EmitterWriter::stderr(color_config,
Some(codemap.clone())))
}
- config::ErrorOutputType::Json => {
+ (config::ErrorOutputType::HumanReadable(_), Some(dst)) => {
+ Box::new(EmitterWriter::new(dst,
+ Some(codemap.clone())))
+ }
+ (config::ErrorOutputType::Json, None) => {
Box::new(JsonEmitter::stderr(Some(registry), codemap.clone()))
}
+ (config::ErrorOutputType::Json, Some(dst)) => {
+ Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone()))
+ }
};
let diagnostic_handler =
working_dir: env::current_dir().unwrap(),
lint_store: RefCell::new(lint::LintStore::new()),
lints: RefCell::new(NodeMap()),
+ one_time_diagnostics: RefCell::new(FnvHashSet()),
plugin_llvm_passes: RefCell::new(Vec::new()),
mir_passes: RefCell::new(mir_pass::Passes::new()),
plugin_attributes: RefCell::new(Vec::new()),
svh_time: Cell::new(Duration::from_secs(0)),
incr_comp_hashes_time: Cell::new(Duration::from_secs(0)),
incr_comp_hashes_count: Cell::new(0),
+ incr_comp_bytes_hashed: Cell::new(0),
symbol_hash_time: Cell::new(Duration::from_secs(0)),
}
};