Skip to content

Commit

Permalink
Add rustc --drawing to use Unicode line drawing characters for span o…
Browse files Browse the repository at this point in the history
…utput

I bet we can find other uses for these sorts of characters in clarifying type
errors, etc.

This is marked as a "stable" flag for consistency with --color. However we
should reconsider both of them as part of rust-lang#19051. For these features to be
conveniently available with Cargo, we may want to use environment variables or
a config file.
  • Loading branch information
kmcallister authored and LeoTestard committed Oct 7, 2015
1 parent 44fcecf commit 73ee491
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 64 deletions.
3 changes: 3 additions & 0 deletions man/rustc.1
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ always colorize output;
.B never
never colorize output.
.RE
.TP
\fB\-\-drawing\fR
Use drawing characters in diagnostic output

.SH CODEGEN OPTIONS

Expand Down
6 changes: 3 additions & 3 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use util::nodemap::FnvHashMap;

use std::cell::RefCell;
use std::cmp;
use std::default;
use std::mem;
use syntax::ast_util::{self, IdVisitingOperation};
use syntax::attr::{self, AttrMetaMethods};
Expand All @@ -46,7 +47,6 @@ use rustc_front::hir;
use rustc_front::util;
use rustc_front::visit as hir_visit;
use syntax::visit as ast_visit;
use syntax::diagnostic;

/// Information about the registered lints.
///
Expand Down Expand Up @@ -166,7 +166,7 @@ impl LintStore {
match (sess, from_plugin) {
// We load builtin lints first, so a duplicate is a compiler bug.
// Use early_error when handling -W help with no crate.
(None, _) => early_error(diagnostic::ColorConfig::Auto, &msg[..]),
(None, _) => early_error(default::Default::default(), &msg[..]),
(Some(sess), false) => sess.bug(&msg[..]),

// A duplicate name from a plugin is a user error.
Expand All @@ -190,7 +190,7 @@ impl LintStore {
match (sess, from_plugin) {
// We load builtin lints first, so a duplicate is a compiler bug.
// Use early_error when handling -W help with no crate.
(None, _) => early_error(diagnostic::ColorConfig::Auto, &msg[..]),
(None, _) => early_error(default::Default::default(), &msg[..]),
(Some(sess), false) => sess.bug(&msg[..]),

// A duplicate name from a plugin is a user error.
Expand Down
59 changes: 33 additions & 26 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use metadata::cstore;
use syntax::ast::{self, IntTy, UintTy};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::{ColorConfig, SpanHandler};
use syntax::diagnostic;
use syntax::diagnostic::{ColorConfig, EmitterConfig, SpanHandler};
use syntax::parse;
use syntax::parse::token::InternedString;
use syntax::feature_gate::UnstableFeatures;
Expand All @@ -37,6 +38,7 @@ use std::collections::HashMap;
use std::env;
use std::fmt;
use std::path::PathBuf;
use std::default;

use llvm;

Expand Down Expand Up @@ -106,7 +108,7 @@ pub struct Options {
pub debugging_opts: DebuggingOptions,
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>,
Expand Down Expand Up @@ -216,7 +218,7 @@ pub fn basic_options() -> Options {
debugging_opts: basic_debugging_options(),
prints: Vec::new(),
cg: basic_codegen_options(),
color: ColorConfig::Auto,
emit_cfg: default::Default::default(),
show_span: None,
externs: HashMap::new(),
crate_name: None,
Expand Down Expand Up @@ -284,7 +286,7 @@ macro_rules! options {
$struct_name { $($opt: $init),* }
}

pub fn $buildfn(matches: &getopts::Matches, color: ColorConfig) -> $struct_name
pub fn $buildfn(matches: &getopts::Matches, cfg: EmitterConfig) -> $struct_name
{
let mut op = $defaultfn();
for option in matches.opt_strs($prefix) {
Expand All @@ -298,17 +300,17 @@ macro_rules! options {
if !setter(&mut op, value) {
match (value, opt_type_desc) {
(Some(..), None) => {
early_error(color, &format!("{} option `{}` takes no \
early_error(cfg, &format!("{} option `{}` takes no \
value", $outputname, key))
}
(None, Some(type_desc)) => {
early_error(color, &format!("{0} option `{1}` requires \
early_error(cfg, &format!("{0} option `{1}` requires \
{2} ({3} {1}=<value>)",
$outputname, key,
type_desc, $prefix))
}
(Some(value), Some(type_desc)) => {
early_error(color, &format!("incorrect value `{}` for {} \
early_error(cfg, &format!("incorrect value `{}` for {} \
option `{}` - {} was expected",
value, $outputname,
key, type_desc))
Expand All @@ -320,7 +322,7 @@ macro_rules! options {
break;
}
if !found {
early_error(color, &format!("unknown {} option: `{}`",
early_error(cfg, &format!("unknown {} option: `{}`",
$outputname, key));
}
}
Expand Down Expand Up @@ -822,6 +824,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"),

opt::flagopt_u("", "pretty",
"Pretty-print the input instead of compiling;
Expand Down Expand Up @@ -853,24 +856,28 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
}

pub fn build_session_options(matches: &getopts::Matches) -> Options {
let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
let mut emit_cfg: diagnostic::EmitterConfig = default::Default::default();
emit_cfg.color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
Some("auto") => ColorConfig::Auto,
Some("always") => ColorConfig::Always,
Some("never") => ColorConfig::Never,

None => ColorConfig::Auto,

Some(arg) => {
early_error(ColorConfig::Auto,
early_error(emit_cfg,
&format!("argument for --color must be auto, always \
or never (instead was `{}`)",
arg))
}
};
if matches.opt_present("drawing") {
emit_cfg.drawing = true;
}

let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(color, &e[..]));
.unwrap_or_else(|e| early_error(emit_cfg, &e[..]));

let mut lint_opts = vec!();
let mut describe_lints = false;
Expand All @@ -887,11 +894,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {

let lint_cap = matches.opt_str("cap-lints").map(|cap| {
lint::Level::from_str(&cap).unwrap_or_else(|| {
early_error(color, &format!("unknown lint level: `{}`", cap))
early_error(emit_cfg, &format!("unknown lint level: `{}`", cap))
})
});

let debugging_opts = build_debugging_options(matches, color);
let debugging_opts = build_debugging_options(matches, emit_cfg);

let parse_only = debugging_opts.parse_only;
let no_trans = debugging_opts.no_trans;
Expand All @@ -916,7 +923,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
"link" => OutputType::Exe,
"dep-info" => OutputType::DepInfo,
part => {
early_error(color, &format!("unknown emission type: `{}`",
early_error(emit_cfg, &format!("unknown emission type: `{}`",
part))
}
};
Expand All @@ -929,15 +936,15 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
output_types.insert(OutputType::Exe, None);
}

let cg = build_codegen_options(matches, color);
let cg = build_codegen_options(matches, emit_cfg);

let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
let target = matches.opt_str("target").unwrap_or(
host_triple().to_string());
let opt_level = {
if matches.opt_present("O") {
if cg.opt_level.is_some() {
early_error(color, "-O and -C opt-level both provided");
early_error(emit_cfg, "-O and -C opt-level both provided");
}
Default
} else {
Expand All @@ -948,7 +955,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
Some(2) => Default,
Some(3) => Aggressive,
Some(arg) => {
early_error(color, &format!("optimization level needs to be \
early_error(emit_cfg, &format!("optimization level needs to be \
between 0-3 (instead was `{}`)",
arg));
}
Expand All @@ -959,7 +966,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let gc = debugging_opts.gc;
let debuginfo = if matches.opt_present("g") {
if cg.debuginfo.is_some() {
early_error(color, "-g and -C debuginfo both provided");
early_error(emit_cfg, "-g and -C debuginfo both provided");
}
FullDebugInfo
} else {
Expand All @@ -968,7 +975,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
Some(1) => LimitedDebugInfo,
Some(2) => FullDebugInfo,
Some(arg) => {
early_error(color, &format!("debug info level needs to be between \
early_error(emit_cfg, &format!("debug info level needs to be between \
0-2 (instead was `{}`)",
arg));
}
Expand All @@ -977,7 +984,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {

let mut search_paths = SearchPaths::new();
for s in &matches.opt_strs("L") {
search_paths.add_path(&s[..], color);
search_paths.add_path(&s[..], emit_cfg);
}

let libs = matches.opt_strs("l").into_iter().map(|s| {
Expand All @@ -989,7 +996,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
(Some(name), "framework") => (name, cstore::NativeFramework),
(Some(name), "static") => (name, cstore::NativeStatic),
(_, s) => {
early_error(color, &format!("unknown library kind `{}`, expected \
early_error(emit_cfg, &format!("unknown library kind `{}`, expected \
one of dylib, framework, or static",
s));
}
Expand All @@ -1006,13 +1013,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
"file-names" => PrintRequest::FileNames,
"sysroot" => PrintRequest::Sysroot,
req => {
early_error(color, &format!("unknown print request `{}`", req))
early_error(emit_cfg, &format!("unknown print request `{}`", req))
}
}
}).collect::<Vec<_>>();

if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
early_warn(color, "-C remark will not show source locations without \
early_warn(emit_cfg, "-C remark will not show source locations without \
--debuginfo");
}

Expand All @@ -1021,11 +1028,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let mut parts = arg.splitn(2, '=');
let name = match parts.next() {
Some(s) => s,
None => early_error(color, "--extern value must not be empty"),
None => early_error(emit_cfg, "--extern value must not be empty"),
};
let location = match parts.next() {
Some(s) => s,
None => early_error(color, "--extern value must be of the format `foo=bar`"),
None => early_error(emit_cfg, "--extern value must be of the format `foo=bar`"),
};

externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string());
Expand Down Expand Up @@ -1055,7 +1062,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
debugging_opts: debugging_opts,
prints: prints,
cg: cg,
color: color,
emit_cfg: emit_cfg,
show_span: None,
externs: externs,
crate_name: crate_name,
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ pub fn build_session(sopts: config::Options,

let codemap = codemap::CodeMap::new();
let diagnostic_handler =
diagnostic::Handler::new(sopts.color, Some(registry), can_print_warnings);
diagnostic::Handler::new(sopts.emit_cfg, Some(registry), can_print_warnings);
let span_diagnostic_handler =
diagnostic::SpanHandler::new(diagnostic_handler, codemap);

Expand Down Expand Up @@ -473,13 +473,13 @@ pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
diagnostic::expect(sess.diagnostic(), opt, msg)
}

pub fn early_error(color: diagnostic::ColorConfig, msg: &str) -> ! {
let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
pub fn early_error(cfg: diagnostic::EmitterConfig, msg: &str) -> ! {
let mut emitter = diagnostic::EmitterWriter::stderr(cfg, None);
emitter.emit(None, msg, None, diagnostic::Fatal);
panic!(diagnostic::FatalError);
}

pub fn early_warn(color: diagnostic::ColorConfig, msg: &str) {
let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
pub fn early_warn(cfg: diagnostic::EmitterConfig, msg: &str) {
let mut emitter = diagnostic::EmitterWriter::stderr(cfg, None);
emitter.emit(None, msg, None, diagnostic::Warning);
}
4 changes: 2 additions & 2 deletions src/librustc/session/search_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl SearchPaths {
SearchPaths { paths: Vec::new() }
}

pub fn add_path(&mut self, path: &str, color: diagnostic::ColorConfig) {
pub fn add_path(&mut self, path: &str, cfg: diagnostic::EmitterConfig) {
let (kind, path) = if path.starts_with("native=") {
(PathKind::Native, &path["native=".len()..])
} else if path.starts_with("crate=") {
Expand All @@ -53,7 +53,7 @@ impl SearchPaths {
(PathKind::All, path)
};
if path.is_empty() {
early_error(color, "empty search path given via `-L`");
early_error(cfg, "empty search path given via `-L`");
}
self.paths.push((kind, PathBuf::from(path)));
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ impl Target {
// this is 1. ugly, 2. error prone.


let handler = diagnostic::Handler::new(diagnostic::ColorConfig::Auto, None, true);
let handler = diagnostic::Handler::new(Default::default(), None, true);

let get_req_field = |name: &str| {
match obj.find(name)
Expand Down
Loading

0 comments on commit 73ee491

Please sign in to comment.