Skip to content
Closed
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
3 changes: 3 additions & 0 deletions man/rustc.1
Original file line number Diff line number Diff line change
@@ -100,6 +100,9 @@ Configure coloring of output:
auto = colorize, if output goes to a tty (default);
always = always colorize output;
never = never colorize output
.TP
\fB\-\-drawing\fR
Use drawing characters in diagnostic output

.SH CODEGEN OPTIONS

1 change: 1 addition & 0 deletions src/etc/zsh/_rust
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ _rustc_opts_switches=(
{-V,--verbose}'[use verbose output]'
-O'[Equivalent to -C opt-level=2]'
--test'[Build a test harness]'
--drawing'[Use drawing characters in diagnostic output]'
)


37 changes: 21 additions & 16 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
@@ -29,14 +29,16 @@ use syntax::ast;
use syntax::ast::{IntTy, UintTy};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
use syntax::diagnostic;
use syntax::diagnostic::{ColorConfig, SpanHandler};
use syntax::parse;
use syntax::parse::token::InternedString;

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use getopts;
use std::fmt;
use std::default;

use llvm;

@@ -104,7 +106,7 @@ pub struct Options {
pub write_dependency_info: (bool, Option<Path>),
pub prints: Vec<PrintRequest>,
pub cg: CodegenOptions,
pub color: ColorConfig,
pub emit_cfg: diagnostic::EmitterConfig,
pub show_span: Option<String>,
pub externs: HashMap<String, Vec<String>>,
pub crate_name: Option<String>,
@@ -228,7 +230,7 @@ pub fn basic_options() -> Options {
write_dependency_info: (false, None),
prints: Vec::new(),
cg: basic_codegen_options(),
color: Auto,
emit_cfg: default::Default::default(),
show_span: None,
externs: HashMap::new(),
crate_name: None,
@@ -793,6 +795,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
auto = colorize, if output goes to a tty (default);
always = always colorize output;
never = never colorize output", "auto|always|never"),
opt::flag("", "drawing", "Use drawing characters in diagnostic output"),

// DEPRECATED
opt::flag("", "print-crate-name", "Output the crate name and exit"),
@@ -1072,19 +1075,21 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
--debuginfo");
}

let color = match matches.opt_str("color").as_ref().map(|s| &s[]) {
Some("auto") => Auto,
Some("always") => Always,
Some("never") => Never,

None => Auto,

Some(arg) => {
early_error(&format!("argument for --color must be auto, always \
or never (instead was `{}`)",
arg)[])
}
let mut emit_cfg: diagnostic::EmitterConfig = default::Default::default();
if let Some(arg) = matches.opt_str("color").as_ref() {
emit_cfg.color = match &arg[] {
"auto" => ColorConfig::Auto,
"always" => ColorConfig::Always,
"never" => ColorConfig::Never,
_ => {
early_error(&format!("argument for --color must be auto, always \
or never (instead was `{}`)", arg)[]);
}
};
};
if matches.opt_present("drawing") {
emit_cfg.drawing = true;
}

let mut externs = HashMap::new();
for arg in matches.opt_strs("extern").iter() {
@@ -1126,7 +1131,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
write_dependency_info: write_dependency_info,
prints: prints,
cg: cg,
color: color,
emit_cfg: emit_cfg,
show_span: None,
externs: externs,
crate_name: crate_name,
13 changes: 8 additions & 5 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ use rustc_back::target::Target;

use std::os;
use std::cell::{Cell, RefCell};
use std::default::Default;

pub mod config;
pub mod search_paths;
@@ -291,7 +292,7 @@ pub fn build_session(sopts: config::Options,
-> Session {
let codemap = codemap::CodeMap::new();
let diagnostic_handler =
diagnostic::default_handler(sopts.color, Some(registry));
diagnostic::default_handler(sopts.emit_cfg, Some(registry));
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, codemap);

@@ -365,13 +366,15 @@ pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
diagnostic::expect(sess.diagnostic(), opt, msg)
}

pub fn fallback_emitter() -> diagnostic::EmitterWriter {
diagnostic::EmitterWriter::stderr(Default::default(), None)
}

pub fn early_error(msg: &str) -> ! {
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
emitter.emit(None, msg, None, diagnostic::Fatal);
fallback_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);
emitter.emit(None, msg, None, diagnostic::Warning);
fallback_emitter().emit(None, msg, None, diagnostic::Warning);
}
2 changes: 1 addition & 1 deletion src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
@@ -222,7 +222,7 @@ impl Target {
// this is 1. ugly, 2. error prone.


let handler = diagnostic::default_handler(diagnostic::Auto, None);
let handler = diagnostic::default_handler(Default::default(), None);

let get_req_field = |&: name: &str| {
match obj.find(name)
4 changes: 2 additions & 2 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ use std::os;
use std::sync::mpsc::channel;
use std::thread;

use rustc::session::early_error;
use rustc::session::{early_error, fallback_emitter};

use syntax::ast;
use syntax::parse;
@@ -616,7 +616,7 @@ pub fn monitor<F:FnOnce()+Send>(f: F) {
Err(value) => {
// Thread panicked without emitting a fatal diagnostic
if !value.is::<diagnostic::FatalError>() {
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
let mut emitter = fallback_emitter();

// a .span_bug or .bug call has already printed what
// it wants to print.
3 changes: 2 additions & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ use syntax::{ast, ast_map, codemap, diagnostic};

use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::default::Default;

use visit_ast::RustdocVisitor;
use clean;
@@ -103,7 +104,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
};

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

3 changes: 2 additions & 1 deletion src/librustdoc/test.rs
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ use std::os;
use std::str;
use std::thread::Thread;
use std::thunk::Thunk;
use std::default::Default;

use std::collections::{HashSet, HashMap};
use testing;
@@ -58,7 +59,7 @@ pub fn run(input: &str,
};

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

86 changes: 68 additions & 18 deletions src/libsyntax/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@

pub use self::Level::*;
pub use self::RenderSpan::*;
pub use self::ColorConfig::*;
use self::Destination::*;

use codemap::{COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span};
@@ -22,6 +21,7 @@ use std::fmt;
use std::io;
use std::iter::range;
use std::string::String;
use std::default::Default;
use term::WriterWrapper;
use term;

@@ -61,6 +61,49 @@ pub enum ColorConfig {
Never
}

#[derive(Clone, Copy)]
pub struct EmitterConfig {
pub color: ColorConfig,
pub drawing: bool,
}

impl Default for EmitterConfig {
fn default() -> EmitterConfig {
EmitterConfig {
color: ColorConfig::Auto,
drawing: false,
}
}
}

#[derive(Clone, Copy)]
struct SpanFormat {
single: char,
begin: char,
middle: char,
end: char,
}

impl EmitterConfig {
#[inline]
fn span_format(&self) -> SpanFormat {
match self.drawing {
false => SpanFormat {
single: '^',
begin: '^',
middle: '~',
end: '~',
},
true => SpanFormat {
single: '\u{25B2}', // BLACK UP-POINTING TRIANGLE
begin: '\u{2517}', // BOX DRAWINGS HEAVY UP AND RIGHT
middle: '\u{2501}', // BOX DRAWINGS HEAVY HORIZONTAL
end: '\u{251B}', // BOX DRAWINGS HEAVY UP AND LEFT
},
}
}
}

pub trait Emitter {
fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
msg: &str, code: Option<&str>, lvl: Level);
@@ -213,9 +256,9 @@ pub fn mk_span_handler(handler: Handler, cm: codemap::CodeMap) -> SpanHandler {
}
}

pub fn default_handler(color_config: ColorConfig,
pub fn default_handler(cfg: EmitterConfig,
registry: Option<diagnostics::registry::Registry>) -> Handler {
mk_handler(box EmitterWriter::stderr(color_config, registry))
mk_handler(box EmitterWriter::stderr(cfg, registry))
}

pub fn mk_handler(e: Box<Emitter + Send>) -> Handler {
@@ -321,7 +364,8 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,

pub struct EmitterWriter {
dst: Destination,
registry: Option<diagnostics::registry::Registry>
registry: Option<diagnostics::registry::Registry>,
cfg: EmitterConfig,
}

enum Destination {
@@ -330,30 +374,30 @@ enum Destination {
}

impl EmitterWriter {
pub fn stderr(color_config: ColorConfig,
pub fn stderr(cfg: EmitterConfig,
registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
let stderr = io::stderr();

let use_color = match color_config {
Always => true,
Never => false,
Auto => stderr.get_ref().isatty()
let use_color = match cfg.color {
ColorConfig::Always => true,
ColorConfig::Never => false,
ColorConfig::Auto => stderr.get_ref().isatty()
};

if use_color {
let dst = match term::stderr() {
Some(t) => Terminal(t),
None => Raw(box stderr),
};
EmitterWriter { dst: dst, registry: registry }
EmitterWriter { dst: dst, registry: registry, cfg: cfg }
} else {
EmitterWriter { dst: Raw(box stderr), registry: registry }
EmitterWriter { dst: Raw(box stderr), registry: registry, cfg: cfg }
}
}

pub fn new(dst: Box<Writer + Send>,
registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
EmitterWriter { dst: Raw(dst), registry: registry }
EmitterWriter { dst: Raw(dst), registry: registry, cfg: Default::default() }
}
}

@@ -498,14 +542,20 @@ fn highlight_lines(err: &mut EmitterWriter,
}

try!(write!(&mut err.dst, "{}", s));
let mut s = String::from_str("^");
let fmt = err.cfg.span_format();
let mut s = String::new();

let hi = cm.lookup_char_pos(sp.hi);
if hi.col != lo.col {
// the ^ already takes up one space
let num_squigglies = hi.col.to_uint() - lo.col.to_uint() - 1u;
let len = hi.col.to_uint() - lo.col.to_uint();
if len <= 1 {
s.push(fmt.single);
} else {
s.push(fmt.begin);
let num_squigglies = len - 2u;
for _ in range(0, num_squigglies) {
s.push('~');
s.push(fmt.middle);
}
s.push(fmt.end);
}
try!(print_maybe_styled(err,
&format!("{}\n", s)[],
@@ -556,7 +606,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
for _ in range(0, skip) {
s.push(' ');
}
s.push('^');
s.push(w.cfg.span_format().single);
s.push('\n');
print_maybe_styled(w,
&s[],
6 changes: 4 additions & 2 deletions src/libsyntax/parse/mod.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@

use ast;
use codemap::{Span, CodeMap, FileMap};
use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto};
use diagnostic::{SpanHandler, mk_span_handler, default_handler};
use parse::attr::ParserAttr;
use parse::parser::Parser;
use ptr::P;
@@ -21,6 +21,7 @@ use std::cell::{Cell, RefCell};
use std::io::File;
use std::rc::Rc;
use std::num::Int;
use std::default::Default;
use std::str;
use std::iter;

@@ -45,7 +46,8 @@ pub struct ParseSess {

pub fn new_parse_sess() -> ParseSess {
ParseSess {
span_diagnostic: mk_span_handler(default_handler(Auto, None), CodeMap::new()),
span_diagnostic: mk_span_handler(default_handler(Default::default(), None),
CodeMap::new()),
included_mod_stack: RefCell::new(Vec::new()),
node_id: Cell::new(1),
}
18 changes: 18 additions & 0 deletions src/test/compile-fail/drawing-spans-one-char.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2015 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.

// compile-flags:--drawing
// error-pattern: ▲

#![deny(warnings)]

fn main() {
let x = 3;
}
18 changes: 18 additions & 0 deletions src/test/compile-fail/drawing-spans.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2015 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.

// compile-flags:--drawing
// error-pattern: ┗━━━━┛

#![deny(warnings)]

fn main() {
let foobar = 3;
}