// option. This file may not be copied, modified, or distributed
// except according to those terms.
-
use lint;
use metadata::cstore::CStore;
use metadata::filesearch;
+use middle::dependency_format;
use session::search_paths::PathKind;
-use util::nodemap::NodeMap;
+use util::nodemap::{NodeMap, FnvHashMap};
use syntax::ast::NodeId;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::parse::ParseSess;
use syntax::{ast, codemap};
+use syntax::feature_gate::AttributeType;
use rustc_back::target::Target;
-use std::env;
+use std::path::{Path, PathBuf};
use std::cell::{Cell, RefCell};
+use std::env;
pub mod config;
pub mod search_paths;
pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
pub entry_type: Cell<Option<config::EntryFnType>>,
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
- pub default_sysroot: Option<Path>,
- // The name of the root source file of the crate, in the local file system. The path is always
- // expected to be absolute. `None` means that there is no source file.
- pub local_crate_source_file: Option<Path>,
- pub working_dir: Path,
+ pub default_sysroot: Option<PathBuf>,
+ // The name of the root source file of the crate, in the local file system.
+ // The path is always expected to be absolute. `None` means that there is no
+ // source file.
+ pub local_crate_source_file: Option<PathBuf>,
+ pub working_dir: PathBuf,
pub lint_store: RefCell<lint::LintStore>,
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
+ pub plugin_llvm_passes: RefCell<Vec<String>>,
+ pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
pub crate_types: RefCell<Vec<config::CrateType>>,
+ pub dependency_formats: RefCell<dependency_format::Dependencies>,
pub crate_metadata: RefCell<Vec<String>>,
pub features: RefCell<feature_gate::Features>,
+ pub delayed_span_bug: RefCell<Option<(codemap::Span, String)>>,
+
/// The maximum recursion limit for potentially infinitely recursive
/// operations such as auto-dereference and monomorphization.
- pub recursion_limit: Cell<uint>,
+ pub recursion_limit: Cell<usize>,
- pub can_print_warnings: bool
+ pub can_print_warnings: bool,
+
+ /// The metadata::creader module may inject an allocator dependency if it
+ /// didn't already find one, and this tracks what was injected.
+ pub injected_allocator: Cell<Option<ast::CrateNum>>,
+
+ next_node_id: Cell<ast::NodeId>,
}
impl Session {
pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
- self.diagnostic().span_fatal(sp, msg)
+ if self.opts.treat_err_as_bug {
+ self.span_bug(sp, msg);
+ }
+ panic!(self.diagnostic().span_fatal(sp, msg))
}
pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> ! {
- self.diagnostic().span_fatal_with_code(sp, msg, code)
+ if self.opts.treat_err_as_bug {
+ self.span_bug(sp, msg);
+ }
+ panic!(self.diagnostic().span_fatal_with_code(sp, msg, code))
}
pub fn fatal(&self, msg: &str) -> ! {
+ if self.opts.treat_err_as_bug {
+ self.bug(msg);
+ }
self.diagnostic().handler().fatal(msg)
}
+ pub fn span_err_or_warn(&self, is_warning: bool, sp: Span, msg: &str) {
+ if is_warning {
+ self.span_warn(sp, msg);
+ } else {
+ self.span_err(sp, msg);
+ }
+ }
pub fn span_err(&self, sp: Span, msg: &str) {
+ if self.opts.treat_err_as_bug {
+ self.span_bug(sp, msg);
+ }
match split_msg_into_multilines(msg) {
Some(msg) => self.diagnostic().span_err(sp, &msg[..]),
None => self.diagnostic().span_err(sp, msg)
}
}
+ pub fn note_rfc_1214(&self, span: Span) {
+ self.span_note(
+ span,
+ &format!("this warning results from recent bug fixes and clarifications; \
+ it will become a HARD ERROR in the next release. \
+ See RFC 1214 for details."));
+ }
pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+ if self.opts.treat_err_as_bug {
+ self.span_bug(sp, msg);
+ }
match split_msg_into_multilines(msg) {
Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code),
None => self.diagnostic().span_err_with_code(sp, msg, code)
}
}
pub fn err(&self, msg: &str) {
+ if self.opts.treat_err_as_bug {
+ self.bug(msg);
+ }
self.diagnostic().handler().err(msg)
}
- pub fn err_count(&self) -> uint {
+ pub fn err_count(&self) -> usize {
self.diagnostic().handler().err_count()
}
pub fn has_errors(&self) -> bool {
self.diagnostic().handler().has_errors()
}
pub fn abort_if_errors(&self) {
- self.diagnostic().handler().abort_if_errors()
+ self.diagnostic().handler().abort_if_errors();
+
+ let delayed_bug = self.delayed_span_bug.borrow();
+ match *delayed_bug {
+ Some((span, ref errmsg)) => {
+ self.diagnostic().span_bug(span, errmsg);
+ },
+ _ => {}
+ }
}
pub fn span_warn(&self, sp: Span, msg: &str) {
if self.can_print_warnings {
pub fn span_end_note(&self, sp: Span, msg: &str) {
self.diagnostic().span_end_note(sp, msg)
}
+
+ /// Prints out a message with a suggested edit of the code.
+ ///
+ /// See `diagnostic::RenderSpan::Suggestion` for more information.
+ pub fn span_suggestion(&self, sp: Span, msg: &str, suggestion: String) {
+ self.diagnostic().span_suggestion(sp, msg, suggestion)
+ }
pub fn span_help(&self, sp: Span, msg: &str) {
self.diagnostic().span_help(sp, msg)
}
self.diagnostic().handler().note(msg)
}
pub fn help(&self, msg: &str) {
- self.diagnostic().handler().note(msg)
+ self.diagnostic().handler().help(msg)
}
pub fn opt_span_bug(&self, opt_sp: Option<Span>, msg: &str) -> ! {
match opt_sp {
None => self.bug(msg),
}
}
+ /// Delay a span_bug() call until abort_if_errors()
+ pub fn delay_span_bug(&self, sp: Span, msg: &str) {
+ let mut delayed = self.delayed_span_bug.borrow_mut();
+ *delayed = Some((sp, msg.to_string()));
+ }
pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
self.diagnostic().span_bug(sp, msg)
}
lints.insert(id, vec!((lint_id, sp, msg)));
}
pub fn next_node_id(&self) -> ast::NodeId {
- self.parse_sess.next_node_id()
+ self.reserve_node_ids(1)
}
pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
- self.parse_sess.reserve_node_ids(count)
+ let id = self.next_node_id.get();
+
+ match id.checked_add(count) {
+ Some(next) => self.next_node_id.set(next),
+ None => self.bug("Input too large, ran out of node ids!")
+ }
+
+ id
}
pub fn diagnostic<'a>(&'a self) -> &'a diagnostic::SpanHandler {
&self.parse_sess.span_diagnostic
}
pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
- &self.parse_sess.span_diagnostic.cm
+ self.parse_sess.codemap()
}
// This exists to help with refactoring to eliminate impossible
// cases later on
pub fn impossible_case(&self, sp: Span, msg: &str) -> ! {
self.span_bug(sp,
- &format!("impossible case reached: {}", msg)[]);
+ &format!("impossible case reached: {}", msg));
}
pub fn verbose(&self) -> bool { self.opts.debugging_opts.verbose }
pub fn time_passes(&self) -> bool { self.opts.debugging_opts.time_passes }
pub fn print_enum_sizes(&self) -> bool {
self.opts.debugging_opts.print_enum_sizes
}
+ pub fn nonzeroing_move_hints(&self) -> bool {
+ self.opts.debugging_opts.enable_nonzeroing_move_hints
+ }
pub fn sysroot<'a>(&'a self) -> &'a Path {
match self.opts.maybe_sysroot {
Some (ref sysroot) => sysroot,
}
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
filesearch::FileSearch::new(self.sysroot(),
- &self.opts.target_triple[],
+ &self.opts.target_triple,
&self.opts.search_paths,
kind)
}
!msg.contains("if and else have incompatible types") &&
!msg.contains("if may be missing an else clause") &&
!msg.contains("match arms have incompatible types") &&
- !msg.contains("structure constructor specifies a structure of type") {
+ !msg.contains("structure constructor specifies a structure of type") &&
+ !msg.contains("has an incompatible type for trait") {
return None
}
let first = msg.match_indices("expected").filter(|s| {
}
let mut tail = &msg[head..];
- let third = tail.find_str("(values differ")
- .or(tail.find_str("(lifetime"))
- .or(tail.find_str("(cyclic type of infinite size"));
+ let third = tail.find("(values differ")
+ .or(tail.find("(lifetime"))
+ .or(tail.find("(cyclic type of infinite size"));
// Insert `\n` before any remaining messages which match.
if let Some(pos) = third {
// The end of the message may just be wrapped in `()` without
}
pub fn build_session(sopts: config::Options,
- local_crate_source_file: Option<Path>,
+ local_crate_source_file: Option<PathBuf>,
registry: diagnostics::registry::Registry)
-> Session {
// FIXME: This is not general enough to make the warning lint completely override
let codemap = codemap::CodeMap::new();
let diagnostic_handler =
- diagnostic::default_handler(sopts.color, Some(registry), can_print_warnings);
+ diagnostic::Handler::new(sopts.color, Some(registry), can_print_warnings);
let span_diagnostic_handler =
- diagnostic::mk_span_handler(diagnostic_handler, codemap);
+ diagnostic::SpanHandler::new(diagnostic_handler, codemap);
build_session_(sopts, local_crate_source_file, span_diagnostic_handler)
}
pub fn build_session_(sopts: config::Options,
- local_crate_source_file: Option<Path>,
+ local_crate_source_file: Option<PathBuf>,
span_diagnostic: diagnostic::SpanHandler)
-> Session {
let host = match Target::search(config::host_triple()) {
}
};
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
- let p_s = parse::new_parse_sess_special_handler(span_diagnostic);
+ let p_s = parse::ParseSess::with_span_handler(span_diagnostic);
let default_sysroot = match sopts.maybe_sysroot {
Some(_) => None,
None => Some(filesearch::get_or_default_sysroot())
working_dir: env::current_dir().unwrap(),
lint_store: RefCell::new(lint::LintStore::new()),
lints: RefCell::new(NodeMap()),
+ plugin_llvm_passes: RefCell::new(Vec::new()),
+ plugin_attributes: RefCell::new(Vec::new()),
crate_types: RefCell::new(Vec::new()),
+ dependency_formats: RefCell::new(FnvHashMap()),
crate_metadata: RefCell::new(Vec::new()),
+ delayed_span_bug: RefCell::new(None),
features: RefCell::new(feature_gate::Features::new()),
recursion_limit: Cell::new(64),
- can_print_warnings: can_print_warnings
+ can_print_warnings: can_print_warnings,
+ next_node_id: Cell::new(1),
+ injected_allocator: Cell::new(None),
};
- sess.lint_store.borrow_mut().register_builtin(Some(&sess));
sess
}
diagnostic::expect(sess.diagnostic(), opt, msg)
}
-pub fn early_error(msg: &str) -> ! {
- let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
+pub fn early_error(color: diagnostic::ColorConfig, msg: &str) -> ! {
+ let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
emitter.emit(None, msg, None, diagnostic::Fatal);
panic!(diagnostic::FatalError);
}
-pub fn early_warn(msg: &str) {
- let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
+pub fn early_warn(color: diagnostic::ColorConfig, msg: &str) {
+ let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
emitter.emit(None, msg, None, diagnostic::Warning);
}