diff options
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/diagnostics.rs | 18 | ||||
| -rw-r--r-- | src/librustc/driver/config.rs | 8 | ||||
| -rw-r--r-- | src/librustc/driver/driver.rs | 13 | ||||
| -rw-r--r-- | src/librustc/driver/mod.rs | 35 | ||||
| -rw-r--r-- | src/librustc/driver/session.rs | 9 | ||||
| -rw-r--r-- | src/librustc/front/feature_gate.rs | 5 | ||||
| -rw-r--r-- | src/librustc/lib.rs | 9 | ||||
| -rw-r--r-- | src/librustc/middle/check_match.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/typeck/infer/test.rs | 1 |
9 files changed, 85 insertions, 15 deletions
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs new file mode 100644 index 00000000000..0499795f890 --- /dev/null +++ b/src/librustc/diagnostics.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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. + +register_diagnostic!(E0001, r##" + This error suggests that the expression arm corresponding to the noted pattern + will never be reached as for all possible values of the expression being matched, + one of the preceeding patterns will match. + + This means that perhaps some of the preceeding patterns are too general, this + one is too specific or the ordering is incorrect. +"##) diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index 9daaa2792eb..b726c50afe9 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -532,6 +532,7 @@ pub fn optgroups() -> Vec<getopts::OptGroup> { optopt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"), optopt( "", "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"), optflag("", "parse-only", "Parse only; do not compile, assemble, or link"), + optopt("", "explain", "Provide a detailed explanation of an error message", "OPT"), optflagopt("", "pretty", "Pretty-print the input instead of compiling; valid types are: `normal` (un-annotated source), @@ -807,6 +808,7 @@ mod test { use getopts::getopts; use syntax::attr; use syntax::attr::AttrMetaMethods; + use syntax::diagnostics; // When the user supplies --test we should implicitly supply --cfg test #[test] @@ -816,8 +818,9 @@ mod test { Ok(m) => m, Err(f) => fail!("test_switch_implies_cfg_test: {}", f) }; + let registry = diagnostics::registry::Registry::new([]); let sessopts = build_session_options(matches); - let sess = build_session(sessopts, None); + let sess = build_session(sessopts, None, registry); let cfg = build_configuration(&sess); assert!((attr::contains_name(cfg.as_slice(), "test"))); } @@ -834,8 +837,9 @@ mod test { fail!("test_switch_implies_cfg_test_unless_cfg_test: {}", f) } }; + let registry = diagnostics::registry::Registry::new([]); let sessopts = build_session_options(matches); - let sess = build_session(sessopts, None); + let sess = build_session(sessopts, None, registry); let cfg = build_configuration(&sess); let mut test_items = cfg.iter().filter(|m| m.name().equiv(&("test"))); assert!(test_items.next().is_some()); diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 6a016edcd28..8173e2ab582 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -16,6 +16,7 @@ use driver::{PpmFlowGraph, PpmExpanded, PpmExpandedIdentified, PpmTyped}; use driver::{PpmIdentified}; use front; use lib::llvm::{ContextRef, ModuleRef}; +use lint; use metadata::common::LinkMeta; use metadata::creader; use middle::cfg; @@ -26,7 +27,7 @@ use middle; use plugin::load::Plugins; use plugin::registry::Registry; use plugin; -use lint; + use util::common::time; use util::ppaux; use util::nodemap::{NodeSet}; @@ -41,6 +42,7 @@ use std::io::MemReader; use syntax::ast; use syntax::attr; use syntax::attr::{AttrMetaMethods}; +use syntax::diagnostics; use syntax::parse; use syntax::parse::token; use syntax::print::{pp, pprust}; @@ -213,6 +215,15 @@ pub fn phase_2_configure_and_expand(sess: &Session, let mut registry = Registry::new(&krate); time(time_passes, "plugin registration", (), |_| { + if sess.features.rustc_diagnostic_macros.get() { + 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 ®istrar in registrars.iter() { registrar(&mut registry); } diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs index ad0d8cac1e3..2614c9ebf98 100644 --- a/src/librustc/driver/mod.rs +++ b/src/librustc/driver/mod.rs @@ -26,6 +26,7 @@ use std::task::TaskBuilder; use syntax::ast; use syntax::parse; use syntax::diagnostic::Emitter; +use syntax::diagnostics; use getopts; @@ -49,8 +50,24 @@ fn run_compiler(args: &[String]) { Some(matches) => matches, None => return }; - let sopts = config::build_session_options(&matches); + let descriptions = diagnostics::registry::Registry::new(super::DIAGNOSTICS); + match matches.opt_str("explain") { + Some(ref code) => { + match descriptions.find_description(code.as_slice()) { + Some(ref description) => { + println!("{}", description); + } + None => { + early_error(format!("no extended information for {}", code).as_slice()); + } + } + return; + }, + None => () + } + + let sopts = config::build_session_options(&matches); let (input, input_file_path) = match matches.free.len() { 0u => { if sopts.describe_lints { @@ -75,7 +92,7 @@ fn run_compiler(args: &[String]) { _ => early_error("multiple input filenames provided") }; - let sess = build_session(sopts, input_file_path); + let sess = build_session(sopts, input_file_path, descriptions); let cfg = config::build_configuration(&sess); let odir = matches.opt_str("out-dir").map(|o| Path::new(o)); let ofile = matches.opt_str("o").map(|o| Path::new(o)); @@ -383,14 +400,14 @@ fn parse_crate_attrs(sess: &Session, input: &Input) -> } pub fn early_error(msg: &str) -> ! { - let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto); - emitter.emit(None, msg, diagnostic::Fatal); + let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None); + emitter.emit(None, msg, None, diagnostic::Fatal); fail!(diagnostic::FatalError); } pub fn early_warn(msg: &str) { - let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto); - emitter.emit(None, msg, diagnostic::Warning); + let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None); + emitter.emit(None, msg, None, diagnostic::Warning); } pub fn list_metadata(sess: &Session, path: &Path, @@ -429,7 +446,7 @@ fn monitor(f: proc():Send) { Err(value) => { // Task failed without emitting a fatal diagnostic if !value.is::<diagnostic::FatalError>() { - let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto); + let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None); // a .span_bug or .bug call has already printed what // it wants to print. @@ -437,6 +454,7 @@ fn monitor(f: proc():Send) { emitter.emit( None, "unexpected failure", + None, diagnostic::Bug); } @@ -447,7 +465,7 @@ fn monitor(f: proc():Send) { "run with `RUST_BACKTRACE=1` for a backtrace".to_string(), ]; for note in xs.iter() { - emitter.emit(None, note.as_slice(), diagnostic::Note) + emitter.emit(None, note.as_slice(), None, diagnostic::Note) } match r.read_to_string() { @@ -457,6 +475,7 @@ fn monitor(f: proc():Send) { format!("failed to read internal \ stderr: {}", e).as_slice(), + None, diagnostic::Error) } } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 50f61f8f06a..8669a733f61 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -20,6 +20,7 @@ use util::nodemap::NodeMap; use syntax::ast::NodeId; use syntax::codemap::Span; use syntax::diagnostic; +use syntax::diagnostics; use syntax::parse; use syntax::parse::token; use syntax::parse::ParseSess; @@ -65,6 +66,9 @@ impl Session { pub fn span_err(&self, sp: Span, msg: &str) { self.diagnostic().span_err(sp, msg) } + pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) { + self.diagnostic().span_err_with_code(sp, msg, code) + } pub fn err(&self, msg: &str) { self.diagnostic().handler().err(msg) } @@ -197,11 +201,12 @@ impl Session { } pub fn build_session(sopts: config::Options, - local_crate_source_file: Option<Path>) + local_crate_source_file: Option<Path>, + registry: diagnostics::registry::Registry) -> Session { let codemap = codemap::CodeMap::new(); let diagnostic_handler = - diagnostic::default_handler(sopts.color); + diagnostic::default_handler(sopts.color, Some(registry)); let span_diagnostic_handler = diagnostic::mk_span_handler(diagnostic_handler, codemap); diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs index 931f0312f57..8b92166388d 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/librustc/front/feature_gate.rs @@ -66,6 +66,8 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ ("quad_precision_float", Removed), + ("rustc_diagnostic_macros", Active), + // A temporary feature gate used to enable parser extensions needed // to bootstrap fix for #5723. ("issue_5723_bootstrap", Active), @@ -93,6 +95,7 @@ pub struct Features { pub default_type_params: Cell<bool>, pub issue_5723_bootstrap: Cell<bool>, pub overloaded_calls: Cell<bool>, + pub rustc_diagnostic_macros: Cell<bool> } impl Features { @@ -101,6 +104,7 @@ impl Features { default_type_params: Cell::new(false), issue_5723_bootstrap: Cell::new(false), overloaded_calls: Cell::new(false), + rustc_diagnostic_macros: Cell::new(false) } } } @@ -425,4 +429,5 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { sess.features.default_type_params.set(cx.has_feature("default_type_params")); sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap")); sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls")); + sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros")); } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 6e28d0cce32..97ea425df99 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -32,6 +32,9 @@ This API is completely unstable and subject to change. #![feature(macro_rules, globs, struct_variant, managed_boxes, quote)] #![feature(default_type_params, phase, unsafe_destructor)] +#![allow(unknown_features)] // NOTE: Remove after next snapshot +#![feature(rustc_diagnostic_macros)] + extern crate arena; extern crate debug; extern crate flate; @@ -39,9 +42,11 @@ extern crate getopts; extern crate graphviz; extern crate libc; extern crate serialize; -extern crate syntax; extern crate time; #[phase(plugin, link)] extern crate log; +#[phase(plugin, link)] extern crate syntax; + +mod diagnostics; pub mod middle { pub mod def; @@ -127,6 +132,8 @@ pub mod lib { pub mod llvmdeps; } +__build_diagnostic_array!(DIAGNOSTICS) + // A private module so that macro-expanded idents like // `::rustc::lint::Lint` will also work in `rustc` itself. // diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 599f5f4024f..f31c247abd3 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -194,7 +194,7 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) { let v = vec!(*pat); match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) { - NotUseful => cx.tcx.sess.span_err(pat.span, "unreachable pattern"), + NotUseful => span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern"), Useful => (), UsefulWithWitness(_) => unreachable!() } diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs index e66dcd118c9..c06e40fce14 100644 --- a/src/librustc/middle/typeck/infer/test.rs +++ b/src/librustc/middle/typeck/infer/test.rs @@ -78,6 +78,7 @@ impl Emitter for ExpectErrorEmitter { fn emit(&mut self, _cmsp: Option<(&codemap::CodeMap, Span)>, msg: &str, + _: Option<&str>, lvl: Level) { remove_message(self, msg, lvl); |
