Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Diagnostic registry prototype #11460

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/librustc/diag_db.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
desc_diag!(A0003, "

Your borrowed pointer doesn't live long enough, dude.

"),
27 changes: 27 additions & 0 deletions src/librustc/diag_db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.

//! The diagnostic database.
//!
//! Extended information about Rust diagnostics is included in the
//! diag_db.md file and can be loaded at runtime with the `load`
//! function.

use syntax::diag_db::DiagnosticDb;

/// Load the database of extended diagnostic descriptions
pub fn load() -> DiagnosticDb {
DiagnosticDb::new(~[load_raw, ::syntax::diag_db::load_raw])
}

pub fn load_raw() -> ~[(&'static str, &'static str, &'static str)] {
~[include!("diag_db.md")]
}

36 changes: 36 additions & 0 deletions src/librustc/diag_index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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.

//! The diagnostic registry
//!
//! All diagnostic codes must be registered here. To add a new
//! diagnostic code just go to the end of the file and add a new
//! line with a code that is one greater than the previous.

reg_diag!(A0000)
reg_diag!(A0001)
reg_diag!(A0002)
reg_diag!(A0003)
reg_diag!(A0004)
reg_diag!(A0005)
reg_diag!(A0006)
reg_diag!(A0007)
reg_diag!(A0008)
reg_diag!(A0009)
reg_diag!(A0010)
reg_diag!(A0011)
reg_diag!(A0012)
reg_diag!(A0013)
reg_diag!(A0014)
reg_diag!(A0015)
reg_diag!(A0016)
reg_diag!(A0017)
reg_diag!(A0018)
reg_diag!(A0019)
7 changes: 5 additions & 2 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use back::link;
use back::{arm, x86, x86_64, mips};
use diag_db;
use driver::session::{Aggressive, OutputExecutable};
use driver::session::{Session, Session_, No, Less, Default};
use driver::session;
Expand Down Expand Up @@ -126,7 +127,7 @@ pub fn build_configuration(sess: Session) ->
fn parse_cfgspecs(cfgspecs: ~[~str], demitter: @diagnostic::Emitter)
-> ast::CrateConfig {
cfgspecs.move_iter().map(|s| {
let sess = parse::new_parse_sess(Some(demitter));
let sess = parse::new_parse_sess(Some(demitter), diag_db::load());
parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess)
}).collect::<ast::CrateConfig>()
}
Expand Down Expand Up @@ -884,7 +885,7 @@ pub fn build_session(sopts: @session::options, demitter: @diagnostic::Emitter)
-> Session {
let codemap = @codemap::CodeMap::new();
let diagnostic_handler =
diagnostic::mk_handler(Some(demitter));
diagnostic::mk_handler(Some(demitter), diag_db::load());
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, codemap);
build_session_(sopts, codemap, demitter, span_diagnostic_handler)
Expand Down Expand Up @@ -983,6 +984,8 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
in <dir>", "DIR"),
optflag("", "parse-only",
"Parse only; do not compile, assemble, or link"),
optopt("", "explain",
"Provide a detailed explanation of an error message", "ERRCODE"),
optflagopt("", "pretty",
"Pretty-print the input instead of compiling;
valid types are: normal (un-annotated source),
Expand Down
18 changes: 18 additions & 0 deletions src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,27 @@ impl Session_ {
pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
self.span_diagnostic.span_fatal(sp, msg)
}
pub fn span_fatal_with_diagnostic_code(&self, sp: Span, code: &str, msg: &str) -> ! {
self.span_diagnostic.span_fatal_with_diagnostic_code(sp, code, msg)
}
pub fn fatal(&self, msg: &str) -> ! {
self.span_diagnostic.handler().fatal(msg)
}
pub fn fatal_with_diagnostic_code(&self, code: &str, msg: &str) -> ! {
self.span_diagnostic.handler().fatal_with_diagnostic_code(code, msg)
}
pub fn span_err(&self, sp: Span, msg: &str) {
self.span_diagnostic.span_err(sp, msg)
}
pub fn span_err_with_diagnostic_code(&self, sp: Span, code: &str, msg: &str) {
self.span_diagnostic.span_err_with_diagnostic_code(sp, code, msg)
}
pub fn err(&self, msg: &str) {
self.span_diagnostic.handler().err(msg)
}
pub fn err_with_diagnostic_code(&self, code: &str, msg: &str) {
self.span_diagnostic.handler().err_with_diagnostic_code(code, msg)
}
pub fn err_count(&self) -> uint {
self.span_diagnostic.handler().err_count()
}
Expand All @@ -246,9 +258,15 @@ impl Session_ {
pub fn span_warn(&self, sp: Span, msg: &str) {
self.span_diagnostic.span_warn(sp, msg)
}
pub fn span_warn_with_diagnostic_code(&self, sp: Span, code: &str, msg: &str) {
self.span_diagnostic.span_warn_with_diagnostic_code(sp, code, msg)
}
pub fn warn(&self, msg: &str) {
self.span_diagnostic.handler().warn(msg)
}
pub fn warn_with_diagnostic_code(&self, code: &str, msg: &str) {
self.span_diagnostic.handler().warn_with_diagnostic_code(code, msg)
}
pub fn span_note(&self, sp: Span, msg: &str) {
self.span_diagnostic.span_note(sp, msg)
}
Expand Down
27 changes: 27 additions & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ use syntax::codemap;
use syntax::diagnostic::Emitter;
use syntax::diagnostic;
use syntax::parse;
use syntax::diag_db::{explain_diagnostic, explain_diag_help};

// Define the diagnostic macros
#[path = "../libsyntax/diag_macros.rs"]
pub mod diag_macros;
// The index of all diagnostic codes used by this crate. This must be defined
// lexically before any diagnostics are used.
pub mod diag_index;

pub mod middle {
pub mod trans;
Expand Down Expand Up @@ -227,6 +235,21 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
return;
}

match matches.opt_str("explain") {
Some(ref code) if code == &~"help" => {
explain_diag_help();
return;
},
Some(code) => {
if !explain_diagnostic(&diag_db::load(), code) {
d::early_error(demitter,
format!("no extended information about code {}", code));
}
return;
}
None => ()
}

// Display the available lint options if "-W help" or only "-W" is given.
let lint_flags = vec::append(matches.opt_strs("W"),
matches.opt_strs("warn"));
Expand Down Expand Up @@ -464,3 +487,7 @@ pub fn main_args(args: &[~str]) -> int {
monitor(proc(demitter) run_compiler(owned_args, demitter));
0
}

// The database of extended diagnostic descriptions. Must come lexically
// after all uses of diagnostics. See `diag_macros` for why.
pub mod diag_db;
3 changes: 2 additions & 1 deletion src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1460,7 +1460,8 @@ impl fake_ext_ctxt for fake_session {

#[cfg(test)]
fn mk_ctxt() -> @fake_ext_ctxt {
@parse::new_parse_sess(None) as @fake_ext_ctxt
use diag_db;
@parse::new_parse_sess(None, diag_db::load()) as @fake_ext_ctxt
}

#[cfg(test)]
Expand Down
48 changes: 21 additions & 27 deletions src/librustc/middle/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,10 @@ impl<'a> CheckLoanCtxt<'a> {

match (new_loan.mutbl, old_loan.mutbl) {
(MutableMutability, MutableMutability) => {
self.bccx.span_err(
new_loan.span,
format!("cannot borrow `{}` as mutable \
span_err!(self.bccx, new_loan.span, A0012,
"cannot borrow `{}` as mutable \
more than once at a time",
self.bccx.loan_path_to_str(new_loan.loan_path)));
self.bccx.loan_path_to_str(new_loan.loan_path));
self.bccx.span_note(
old_loan.span,
format!("previous borrow of `{}` as mutable occurs here",
Expand All @@ -239,13 +238,12 @@ impl<'a> CheckLoanCtxt<'a> {
}

_ => {
self.bccx.span_err(
new_loan.span,
format!("cannot borrow `{}` as {} because \
span_err!(self.bccx, new_loan.span, A0013,
"cannot borrow `{}` as {} because \
it is also borrowed as {}",
self.bccx.loan_path_to_str(new_loan.loan_path),
self.bccx.mut_to_str(new_loan.mutbl),
self.bccx.mut_to_str(old_loan.mutbl)));
self.bccx.loan_path_to_str(new_loan.loan_path),
self.bccx.mut_to_str(new_loan.mutbl),
self.bccx.mut_to_str(old_loan.mutbl));
self.bccx.span_note(
old_loan.span,
format!("previous borrow of `{}` occurs here",
Expand Down Expand Up @@ -332,11 +330,10 @@ impl<'a> CheckLoanCtxt<'a> {
}

// Otherwise, just a plain error.
self.bccx.span_err(
expr.span,
format!("cannot assign to {} {}",
cmt.mutbl.to_user_str(),
self.bccx.cmt_to_str(cmt)));
span_err!(self.bccx, expr.span, A0014,
"cannot assign to {} {}",
cmt.mutbl.to_user_str(),
self.bccx.cmt_to_str(cmt));
return;

fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
Expand Down Expand Up @@ -602,10 +599,9 @@ impl<'a> CheckLoanCtxt<'a> {
expr: &ast::Expr,
loan_path: &LoanPath,
loan: &Loan) {
self.bccx.span_err(
expr.span,
format!("cannot assign to `{}` because it is borrowed",
self.bccx.loan_path_to_str(loan_path)));
span_err!(self.bccx, expr.span, A0015,
"cannot assign to `{}` because it is borrowed",
self.bccx.loan_path_to_str(loan_path));
self.bccx.span_note(
loan.span,
format!("borrow of `{}` occurs here",
Expand All @@ -630,11 +626,10 @@ impl<'a> CheckLoanCtxt<'a> {
match self.analyze_move_out_from(id, move_path) {
MoveOk => {}
MoveWhileBorrowed(loan_path, loan_span) => {
self.bccx.span_err(
span,
format!("cannot move out of `{}` \
span_err!(self.bccx, span, A0016,
"cannot move out of `{}` \
because it is borrowed",
self.bccx.loan_path_to_str(move_path)));
self.bccx.loan_path_to_str(move_path));
self.bccx.span_note(
loan_span,
format!("borrow of `{}` occurs here",
Expand Down Expand Up @@ -727,11 +722,10 @@ fn check_loans_in_fn<'a>(this: &mut CheckLoanCtxt<'a>,
match move_err {
MoveOk => {}
MoveWhileBorrowed(loan_path, loan_span) => {
this.bccx.span_err(
cap_var.span,
format!("cannot move `{}` into closure \
span_err!(this.bccx, cap_var.span, A0017,
"cannot move `{}` into closure \
because it is borrowed",
this.bccx.loan_path_to_str(move_path)));
this.bccx.loan_path_to_str(move_path));
this.bccx.span_note(
loan_span,
format!("borrow of `{}` occurs here",
Expand Down
14 changes: 6 additions & 8 deletions src/librustc/middle/borrowck/gather_loans/gather_moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,9 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
mc::cat_stack_upvar(..) |
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {
bccx.span_err(
cmt0.span,
format!("cannot move out of {}",
bccx.cmt_to_str(cmt)));
span_err!(bccx, cmt0.span, A0018,
"cannot move out of {}",
bccx.cmt_to_str(cmt));
false
}

Expand Down Expand Up @@ -143,11 +142,10 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
match ty::get(b.ty).sty {
ty::ty_struct(did, _) | ty::ty_enum(did, _) => {
if ty::has_dtor(bccx.tcx, did) {
bccx.span_err(
cmt0.span,
format!("cannot move out of type `{}`, \
span_err!(bccx, cmt0.span, A0019,
"cannot move out of type `{}`, \
which defines the `Drop` trait",
b.ty.user_string(bccx.tcx)));
b.ty.user_string(bccx.tcx));
false
} else {
check_is_legal_to_move_from(bccx, cmt0, b)
Expand Down
Loading