]> git.proxmox.com Git - rustc.git/blobdiff - src/librustc/session/mod.rs
Imported Upstream version 1.4.0+dfsg1
[rustc.git] / src / librustc / session / mod.rs
index c1c5518887577d83462db5a07e032c48012f497e..ff732ee7b9d80c60099da78a70c3c65adec28c11 100644 (file)
@@ -8,12 +8,12 @@
 // 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;
@@ -24,11 +24,13 @@ use syntax::parse;
 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;
@@ -45,57 +47,109 @@ pub struct Session {
     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 {
@@ -124,6 +178,13 @@ impl Session {
     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)
     }
@@ -137,7 +198,7 @@ impl Session {
         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 {
@@ -145,6 +206,11 @@ impl Session {
             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)
     }
@@ -171,22 +237,29 @@ impl Session {
         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 }
@@ -219,6 +292,9 @@ impl Session {
     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,
@@ -228,7 +304,7 @@ impl Session {
     }
     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)
     }
@@ -248,7 +324,8 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
         !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| {
@@ -280,9 +357,9 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
     }
 
     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
@@ -302,7 +379,7 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
 }
 
 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
@@ -317,15 +394,15 @@ pub fn build_session(sopts: config::Options,
 
     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()) {
@@ -336,7 +413,7 @@ pub fn build_session_(sopts: config::Options,
     }
     };
     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())
@@ -373,14 +450,19 @@ pub fn build_session_(sopts: config::Options,
         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
 }
 
@@ -391,13 +473,13 @@ pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
     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);
 }