rustc: Split diagnostics into "span diagnostics" and "diagnostics".

The former contain a codemap (which is per-crate), and the latter don't. This
will be useful in order to allow more than one crate to be compiled in one run
of the compiler.
This commit is contained in:
Patrick Walton 2012-01-24 21:42:54 -08:00
parent 4d096a8c86
commit 9ecd5ee81d
9 changed files with 118 additions and 84 deletions

View File

@ -100,10 +100,11 @@ fn load_link(mis: [@ast::meta_item]) -> (option::t<str>,
fn load_pkg(filename: str) -> option::t<pkg> {
let cm = codemap::new_codemap();
let handler = diagnostic::mk_handler(none);
let sess = @{
cm: cm,
mutable next_id: 1,
diagnostic: diagnostic::mk_handler(cm, none),
span_diagnostic: diagnostic::mk_span_handler(handler, cm),
mutable chpos: 0u,
mutable byte_pos: 0u
};

View File

@ -5,51 +5,82 @@ import codemap::span;
export emitter, emit;
export level, fatal, error, warning, note;
export handler, mk_handler;
export span_handler, handler, mk_span_handler, mk_handler;
export codemap_span_handler, codemap_handler;
export ice_msg;
type emitter = fn@(cmsp: option<(codemap::codemap, span)>,
msg: str, lvl: level);
iface handler {
iface span_handler {
fn span_fatal(sp: span, msg: str) -> !;
fn fatal(msg: str) -> !;
fn span_err(sp: span, msg: str);
fn err(msg: str);
fn has_errors() -> bool;
fn abort_if_errors();
fn span_warn(sp: span, msg: str);
fn warn(msg: str);
fn span_note(sp: span, msg: str);
fn note(msg: str);
fn span_bug(sp: span, msg: str) -> !;
fn bug(msg: str) -> !;
fn span_unimpl(sp: span, msg: str) -> !;
fn unimpl(msg: str) -> !;
fn handler() -> handler;
}
type codemap_t = @{
cm: codemap::codemap,
iface handler {
fn fatal(msg: str) -> !;
fn err(msg: str);
fn bump_err_count();
fn has_errors() -> bool;
fn abort_if_errors();
fn warn(msg: str);
fn note(msg: str);
fn bug(msg: str) -> !;
fn unimpl(msg: str) -> !;
fn emit(cmsp: option<(codemap::codemap, span)>, msg: str, lvl: level);
}
type handler_t = @{
mutable err_count: uint,
emit: emitter
_emit: emitter
};
impl codemap_handler of handler for codemap_t {
type codemap_t = @{
handler: handler,
cm: codemap::codemap
};
impl codemap_span_handler of span_handler for codemap_t {
fn span_fatal(sp: span, msg: str) -> ! {
self.emit(some((self.cm, sp)), msg, fatal);
fail;
}
fn fatal(msg: str) -> ! {
self.emit(none, msg, fatal);
self.handler.emit(some((self.cm, sp)), msg, fatal);
fail;
}
fn span_err(sp: span, msg: str) {
self.emit(some((self.cm, sp)), msg, error);
self.err_count += 1u;
self.handler.emit(some((self.cm, sp)), msg, error);
self.handler.bump_err_count();
}
fn span_warn(sp: span, msg: str) {
self.handler.emit(some((self.cm, sp)), msg, warning);
}
fn span_note(sp: span, msg: str) {
self.handler.emit(some((self.cm, sp)), msg, note);
}
fn span_bug(sp: span, msg: str) -> ! {
self.span_fatal(sp, ice_msg(msg));
}
fn span_unimpl(sp: span, msg: str) -> ! {
self.span_bug(sp, "unimplemented " + msg);
}
fn handler() -> handler {
self.handler
}
}
impl codemap_handler of handler for handler_t {
fn fatal(msg: str) -> ! {
self._emit(none, msg, fatal);
fail;
}
fn err(msg: str) {
self.emit(none, msg, error);
self._emit(none, msg, error);
}
fn bump_err_count() {
self.err_count += 1u;
}
fn has_errors() -> bool { self.err_count > 0u }
@ -58,36 +89,30 @@ impl codemap_handler of handler for codemap_t {
self.fatal("aborting due to previous errors");
}
}
fn span_warn(sp: span, msg: str) {
self.emit(some((self.cm, sp)), msg, warning);
}
fn warn(msg: str) {
self.emit(none, msg, warning);
}
fn span_note(sp: span, msg: str) {
self.emit(some((self.cm, sp)), msg, note);
self._emit(none, msg, warning);
}
fn note(msg: str) {
self.emit(none, msg, note);
}
fn span_bug(sp: span, msg: str) -> ! {
self.span_fatal(sp, ice_msg(msg));
self._emit(none, msg, note);
}
fn bug(msg: str) -> ! {
self.fatal(ice_msg(msg));
}
fn span_unimpl(sp: span, msg: str) -> ! {
self.span_bug(sp, "unimplemented " + msg);
}
fn unimpl(msg: str) -> ! { self.bug("unimplemented " + msg); }
fn emit(cmsp: option<(codemap::codemap, span)>, msg: str, lvl: level) {
self._emit(cmsp, msg, lvl);
}
}
fn ice_msg(msg: str) -> str {
#fmt["internal compiler error %s", msg]
}
fn mk_handler(cm: codemap::codemap,
emitter: option<emitter>) -> handler {
fn mk_span_handler(handler: handler, cm: codemap::codemap) -> span_handler {
@{ handler: handler, cm: cm } as span_handler
}
fn mk_handler(emitter: option<emitter>) -> handler {
let emit = alt emitter {
some(e) { e }
@ -101,9 +126,8 @@ fn mk_handler(cm: codemap::codemap,
};
@{
cm: cm,
mutable err_count: 0u,
emit: emit
_emit: emit
} as handler
}

View File

@ -299,7 +299,7 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
}
ppm_expanded | ppm_normal {}
}
pprust::print_crate(sess.codemap, sess.diagnostic, crate, input,
pprust::print_crate(sess.codemap, sess.span_diagnostic, crate, input,
io::string_reader(src), io::stdout(), ann);
}
@ -481,21 +481,23 @@ fn build_session(sopts: @session::options, input: str,
sopts.addl_lib_search_paths);
let codemap = codemap::new_codemap();
let diagnostic_handler =
diagnostic::mk_handler(codemap, some(demitter));
diagnostic::mk_handler(some(demitter));
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, codemap);
@{targ_cfg: target_cfg,
opts: sopts,
cstore: cstore,
parse_sess: @{
cm: codemap,
mutable next_id: 1,
diagnostic: diagnostic_handler,
span_diagnostic: span_diagnostic_handler,
mutable chpos: 0u,
mutable byte_pos: 0u
},
codemap: codemap,
// For a library crate, this is always none
mutable main_fn: none,
diagnostic: diagnostic_handler,
span_diagnostic: span_diagnostic_handler,
filesearch: filesearch,
mutable building_library: false,
working_dir: fs::dirname(input)}

View File

@ -60,53 +60,53 @@ type session = @{targ_cfg: @config,
codemap: codemap::codemap,
// For a library crate, this is always none
mutable main_fn: option::t<node_id>,
diagnostic: diagnostic::handler,
span_diagnostic: diagnostic::span_handler,
filesearch: filesearch::filesearch,
mutable building_library: bool,
working_dir: str};
impl session for session {
fn span_fatal(sp: span, msg: str) -> ! {
self.diagnostic.span_fatal(sp, msg)
self.span_diagnostic.span_fatal(sp, msg)
}
fn fatal(msg: str) -> ! {
self.diagnostic.fatal(msg)
self.span_diagnostic.handler().fatal(msg)
}
fn span_err(sp: span, msg: str) {
self.diagnostic.span_err(sp, msg)
self.span_diagnostic.span_err(sp, msg)
}
fn err(msg: str) {
self.diagnostic.err(msg)
self.span_diagnostic.handler().err(msg)
}
fn has_errors() -> bool {
self.diagnostic.has_errors()
self.span_diagnostic.handler().has_errors()
}
fn abort_if_errors() {
self.diagnostic.abort_if_errors()
self.span_diagnostic.handler().abort_if_errors()
}
fn span_warn(sp: span, msg: str) {
self.diagnostic.span_warn(sp, msg)
self.span_diagnostic.span_warn(sp, msg)
}
fn warn(msg: str) {
self.diagnostic.warn(msg)
self.span_diagnostic.handler().warn(msg)
}
fn span_note(sp: span, msg: str) {
self.diagnostic.span_note(sp, msg)
self.span_diagnostic.span_note(sp, msg)
}
fn note(msg: str) {
self.diagnostic.note(msg)
self.span_diagnostic.handler().note(msg)
}
fn span_bug(sp: span, msg: str) -> ! {
self.diagnostic.span_bug(sp, msg)
self.span_diagnostic.span_bug(sp, msg)
}
fn bug(msg: str) -> ! {
self.diagnostic.bug(msg)
self.span_diagnostic.handler().bug(msg)
}
fn span_unimpl(sp: span, msg: str) -> ! {
self.diagnostic.span_unimpl(sp, msg)
self.span_diagnostic.span_unimpl(sp, msg)
}
fn unimpl(msg: str) -> ! {
self.diagnostic.unimpl(msg)
self.span_diagnostic.handler().unimpl(msg)
}
fn next_node_id() -> ast::node_id {
ret syntax::parse::parser::next_node_id(self.parse_sess);

View File

@ -10,7 +10,7 @@ import driver::diagnostic;
type reader = @{
cm: codemap::codemap,
diagnostic: diagnostic::handler,
span_diagnostic: diagnostic::span_handler,
src: str,
len: uint,
mutable col: uint,
@ -49,17 +49,18 @@ impl reader for reader {
} else { self.curr = -1 as char; }
}
fn fatal(m: str) -> ! {
self.diagnostic.span_fatal(
self.span_diagnostic.span_fatal(
ast_util::mk_sp(self.chpos, self.chpos),
m)
}
}
fn new_reader(cm: codemap::codemap,
diagnostic: diagnostic::handler,
span_diagnostic: diagnostic::span_handler,
src: str, filemap: codemap::filemap,
itr: @interner::interner<str>) -> reader {
let r = @{cm: cm, diagnostic: diagnostic,
let r = @{cm: cm,
span_diagnostic: span_diagnostic,
src: src, len: str::byte_len(src),
mutable col: 0u, mutable pos: 0u, mutable curr: -1 as char,
mutable chpos: filemap.start_pos.ch, mutable strs: [],
@ -667,13 +668,13 @@ fn is_lit(t: token::token) -> bool {
type lit = {lit: str, pos: uint};
fn gather_comments_and_literals(cm: codemap::codemap,
diagnostic: diagnostic::handler,
span_diagnostic: diagnostic::span_handler,
path: str,
srdr: io::reader) ->
{cmnts: [cmnt], lits: [lit]} {
let src = str::unsafe_from_bytes(srdr.read_whole_stream());
let itr = @interner::mk::<str>(str::hash, str::eq);
let rdr = new_reader(cm, diagnostic, src,
let rdr = new_reader(cm, span_diagnostic, src,
codemap::new_filemap(path, 0u, 0u), itr);
let comments: [cmnt] = [];
let literals: [lit] = [];

View File

@ -24,7 +24,7 @@ enum file_type { CRATE_FILE, SOURCE_FILE, }
type parse_sess = @{
cm: codemap::codemap,
mutable next_id: node_id,
diagnostic: diagnostic::handler,
span_diagnostic: diagnostic::span_handler,
// these two must be kept up to date
mutable chpos: uint,
mutable byte_pos: uint
@ -78,13 +78,13 @@ impl parser for parser {
ret self.buffer[distance - 1u].tok;
}
fn fatal(m: str) -> ! {
self.sess.diagnostic.span_fatal(self.span, m)
self.sess.span_diagnostic.span_fatal(self.span, m)
}
fn span_fatal(sp: span, m: str) -> ! {
self.sess.diagnostic.span_fatal(sp, m)
self.sess.span_diagnostic.span_fatal(sp, m)
}
fn warn(m: str) {
self.sess.diagnostic.span_warn(self.span, m)
self.sess.span_diagnostic.span_warn(self.span, m)
}
fn get_str(i: token::str_num) -> str {
interner::get(*self.reader.interner, i)
@ -101,14 +101,14 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str,
src
}
result::err(e) {
sess.diagnostic.fatal(e)
sess.span_diagnostic.handler().fatal(e)
}
};
let filemap = codemap::new_filemap(path, sess.chpos, sess.byte_pos);
sess.cm.files += [filemap];
let itr = @interner::mk(str::hash, str::eq);
let rdr = lexer::new_reader(sess.cm, sess.diagnostic,
src, filemap, itr);
let rdr = lexer::new_reader(sess.cm, sess.span_diagnostic, src, filemap,
itr);
ret new_parser(sess, cfg, rdr, ftype);
}
@ -118,8 +118,8 @@ fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
let filemap = codemap::new_filemap(name, sess.chpos, sess.byte_pos);
sess.cm.files += [filemap];
let itr = @interner::mk(str::hash, str::eq);
let rdr = lexer::new_reader(sess.cm, sess.diagnostic,
source, filemap, itr);
let rdr = lexer::new_reader(sess.cm, sess.span_diagnostic, source,
filemap, itr);
ret new_parser(sess, cfg, rdr, ftype);
}
@ -2628,7 +2628,8 @@ fn parse_crate_from_file(input: str, cfg: ast::crate_cfg, sess: parse_sess) ->
} else if str::ends_with(input, ".rs") {
parse_crate_from_source_file(input, cfg, sess)
} else {
sess.diagnostic.fatal("unknown input file type: " + input)
sess.span_diagnostic.handler().fatal("unknown input file type: " +
input)
}
}

View File

@ -60,11 +60,12 @@ const default_columns: uint = 78u;
// Requires you to pass an input filename and reader so that
// it can scan the input text for comments and literals to
// copy forward.
fn print_crate(cm: codemap, diagnostic: diagnostic::handler,
fn print_crate(cm: codemap, span_diagnostic: diagnostic::span_handler,
crate: @ast::crate, filename: str, in: io::reader,
out: io::writer, ann: pp_ann) {
let boxes: [pp::breaks] = [];
let r = lexer::gather_comments_and_literals(cm, diagnostic, filename, in);
let r = lexer::gather_comments_and_literals(cm, span_diagnostic, filename,
in);
let s =
@{s: pp::mk_printer(out, default_columns),
cm: some(cm),

View File

@ -259,10 +259,11 @@ fn check_variants_T<T: copy>(
let crate2 = @replacer(crate, i, things[j], cx.mode);
// It would be best to test the *crate* for stability, but testing the
// string for stability is easier and ok for now.
let handler = diagnostic::mk_handler(none);
let str3 =
as_str(bind pprust::print_crate(
codemap,
diagnostic::mk_handler(codemap, none),
diagnostic::mk_span_handler(handler, codemap),
crate2,
filename,
io::string_reader(""), _,
@ -416,10 +417,11 @@ fn check_compiling(filename: str) -> happiness {
fn parse_and_print(code: str) -> str {
let filename = "tmp.rs";
let cm = codemap::new_codemap();
let handler = diagnostic::mk_handler(none);
let sess = @{
cm: cm,
mutable next_id: 0,
diagnostic: diagnostic::mk_handler(cm, none),
span_diagnostic: diagnostic::mk_span_handler(handler, cm),
mutable chpos: 0u,
mutable byte_pos: 0u
};
@ -427,7 +429,7 @@ fn parse_and_print(code: str) -> str {
let crate = parser::parse_crate_from_source_str(
filename, code, [], sess);
ret as_str(bind pprust::print_crate(sess.cm,
sess.diagnostic,
sess.span_diagnostic,
crate,
filename,
io::string_reader(code), _,
@ -565,10 +567,11 @@ fn check_variants(files: [str], cx: context) {
log(error, "check_variants: " + file);
let cm = codemap::new_codemap();
let handler = diagnostic::mk_handler(none);
let sess = @{
cm: cm,
mutable next_id: 0,
diagnostic: diagnostic::mk_handler(cm, none),
span_diagnostic: diagnostic::mk_span_handler(handler, cm),
mutable chpos: 0u,
mutable byte_pos: 0u
};
@ -578,7 +581,7 @@ fn check_variants(files: [str], cx: context) {
s, [], sess);
#error("%s",
as_str(bind pprust::print_crate(sess.cm,
sess.diagnostic,
sess.span_diagnostic,
crate,
file,
io::string_reader(s), _,

View File

@ -9,10 +9,11 @@ export from_file, from_str;
fn new_parse_sess() -> parser::parse_sess {
let cm = codemap::new_codemap();
let handler = diagnostic::mk_handler(none);
let sess = @{
cm: cm,
mutable next_id: 1,
diagnostic: diagnostic::mk_handler(cm, none),
span_diagnostic: diagnostic::mk_span_handler(handler, cm),
mutable chpos: 0u,
mutable byte_pos: 0u
};