Skip to content

Commit

Permalink
Add scaffolding for assigning alpha-numeric codes to rustc diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Wieczorek committed Jul 10, 2014
1 parent 7ab9bfa commit 9b9cce2
Show file tree
Hide file tree
Showing 25 changed files with 466 additions and 84 deletions.
18 changes: 18 additions & 0 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -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.
"##)
8 changes: 6 additions & 2 deletions src/librustc/driver/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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]
Expand All @@ -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")));
}
Expand All @@ -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());
Expand Down
13 changes: 12 additions & 1 deletion src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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};
Expand All @@ -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};
Expand Down Expand Up @@ -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 &registrar in registrars.iter() {
registrar(&mut registry);
}
Expand Down
35 changes: 27 additions & 8 deletions src/librustc/driver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use std::task::TaskBuilder;
use syntax::ast;
use syntax::parse;
use syntax::diagnostic::Emitter;
use syntax::diagnostics;

use getopts;

Expand All @@ -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 {
Expand All @@ -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));
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -429,14 +446,15 @@ 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.
if !value.is::<diagnostic::ExplicitBug>() {
emitter.emit(
None,
"unexpected failure",
None,
diagnostic::Bug);
}

Expand All @@ -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() {
Expand All @@ -457,6 +475,7 @@ fn monitor(f: proc():Send) {
format!("failed to read internal \
stderr: {}",
e).as_slice(),
None,
diagnostic::Error)
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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);

Expand Down
5 changes: 5 additions & 0 deletions src/librustc/front/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
}
}
}
Expand Down Expand Up @@ -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"));
}
9 changes: 8 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,21 @@ 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;
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;
Expand Down Expand Up @@ -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.
//
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/typeck/infer/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)


let codemap = syntax::codemap::CodeMap::new();
let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto);
let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto, None);
let span_diagnostic_handler =
syntax::diagnostic::mk_span_handler(diagnostic_handler, codemap);

Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub fn run(input: &str,


let codemap = CodeMap::new();
let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto);
let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None);
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, codemap);

Expand Down Expand Up @@ -150,7 +150,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
};
io::util::copy(&mut p, &mut err).unwrap();
});
let emitter = diagnostic::EmitterWriter::new(box w2);
let emitter = diagnostic::EmitterWriter::new(box w2, None);

// Compile the code
let codemap = CodeMap::new();
Expand Down
Loading

5 comments on commit 9b9cce2

@bors
Copy link
Contributor

@bors bors commented on 9b9cce2 Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 9b9cce2 Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging jakub-/rust/diagnostics = 9b9cce2 into auto

@bors
Copy link
Contributor

@bors bors commented on 9b9cce2 Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jakub-/rust/diagnostics = 9b9cce2 merged ok, testing candidate = 0e80dbe

@bors
Copy link
Contributor

@bors bors commented on 9b9cce2 Jul 11, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 0e80dbe

Please sign in to comment.