Skip to content

Commit 73ee491

Browse files
kmcallisterLeoTestard
authored andcommitted
Add rustc --drawing to use Unicode line drawing characters for span output
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.
1 parent 44fcecf commit 73ee491

File tree

13 files changed

+167
-64
lines changed

13 files changed

+167
-64
lines changed

man/rustc.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ always colorize output;
139139
.B never
140140
never colorize output.
141141
.RE
142+
.TP
143+
\fB\-\-drawing\fR
144+
Use drawing characters in diagnostic output
142145

143146
.SH CODEGEN OPTIONS
144147

src/librustc/lint/context.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use util::nodemap::FnvHashMap;
3636

3737
use std::cell::RefCell;
3838
use std::cmp;
39+
use std::default;
3940
use std::mem;
4041
use syntax::ast_util::{self, IdVisitingOperation};
4142
use syntax::attr::{self, AttrMetaMethods};
@@ -46,7 +47,6 @@ use rustc_front::hir;
4647
use rustc_front::util;
4748
use rustc_front::visit as hir_visit;
4849
use syntax::visit as ast_visit;
49-
use syntax::diagnostic;
5050

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

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

196196
// A duplicate name from a plugin is a user error.

src/librustc/session/config.rs

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use metadata::cstore;
2727
use syntax::ast::{self, IntTy, UintTy};
2828
use syntax::attr;
2929
use syntax::attr::AttrMetaMethods;
30-
use syntax::diagnostic::{ColorConfig, SpanHandler};
30+
use syntax::diagnostic;
31+
use syntax::diagnostic::{ColorConfig, EmitterConfig, SpanHandler};
3132
use syntax::parse;
3233
use syntax::parse::token::InternedString;
3334
use syntax::feature_gate::UnstableFeatures;
@@ -37,6 +38,7 @@ use std::collections::HashMap;
3738
use std::env;
3839
use std::fmt;
3940
use std::path::PathBuf;
41+
use std::default;
4042

4143
use llvm;
4244

@@ -106,7 +108,7 @@ pub struct Options {
106108
pub debugging_opts: DebuggingOptions,
107109
pub prints: Vec<PrintRequest>,
108110
pub cg: CodegenOptions,
109-
pub color: ColorConfig,
111+
pub emit_cfg: diagnostic::EmitterConfig,
110112
pub show_span: Option<String>,
111113
pub externs: HashMap<String, Vec<String>>,
112114
pub crate_name: Option<String>,
@@ -216,7 +218,7 @@ pub fn basic_options() -> Options {
216218
debugging_opts: basic_debugging_options(),
217219
prints: Vec::new(),
218220
cg: basic_codegen_options(),
219-
color: ColorConfig::Auto,
221+
emit_cfg: default::Default::default(),
220222
show_span: None,
221223
externs: HashMap::new(),
222224
crate_name: None,
@@ -284,7 +286,7 @@ macro_rules! options {
284286
$struct_name { $($opt: $init),* }
285287
}
286288

287-
pub fn $buildfn(matches: &getopts::Matches, color: ColorConfig) -> $struct_name
289+
pub fn $buildfn(matches: &getopts::Matches, cfg: EmitterConfig) -> $struct_name
288290
{
289291
let mut op = $defaultfn();
290292
for option in matches.opt_strs($prefix) {
@@ -298,17 +300,17 @@ macro_rules! options {
298300
if !setter(&mut op, value) {
299301
match (value, opt_type_desc) {
300302
(Some(..), None) => {
301-
early_error(color, &format!("{} option `{}` takes no \
303+
early_error(cfg, &format!("{} option `{}` takes no \
302304
value", $outputname, key))
303305
}
304306
(None, Some(type_desc)) => {
305-
early_error(color, &format!("{0} option `{1}` requires \
307+
early_error(cfg, &format!("{0} option `{1}` requires \
306308
{2} ({3} {1}=<value>)",
307309
$outputname, key,
308310
type_desc, $prefix))
309311
}
310312
(Some(value), Some(type_desc)) => {
311-
early_error(color, &format!("incorrect value `{}` for {} \
313+
early_error(cfg, &format!("incorrect value `{}` for {} \
312314
option `{}` - {} was expected",
313315
value, $outputname,
314316
key, type_desc))
@@ -320,7 +322,7 @@ macro_rules! options {
320322
break;
321323
}
322324
if !found {
323-
early_error(color, &format!("unknown {} option: `{}`",
325+
early_error(cfg, &format!("unknown {} option: `{}`",
324326
$outputname, key));
325327
}
326328
}
@@ -822,6 +824,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
822824
auto = colorize, if output goes to a tty (default);
823825
always = always colorize output;
824826
never = never colorize output", "auto|always|never"),
827+
opt::flag("", "drawing", "Use drawing characters in diagnostic output"),
825828

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

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

861865
None => ColorConfig::Auto,
862866

863867
Some(arg) => {
864-
early_error(ColorConfig::Auto,
868+
early_error(emit_cfg,
865869
&format!("argument for --color must be auto, always \
866870
or never (instead was `{}`)",
867871
arg))
868872
}
869873
};
874+
if matches.opt_present("drawing") {
875+
emit_cfg.drawing = true;
876+
}
870877

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

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

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

894-
let debugging_opts = build_debugging_options(matches, color);
901+
let debugging_opts = build_debugging_options(matches, emit_cfg);
895902

896903
let parse_only = debugging_opts.parse_only;
897904
let no_trans = debugging_opts.no_trans;
@@ -916,7 +923,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
916923
"link" => OutputType::Exe,
917924
"dep-info" => OutputType::DepInfo,
918925
part => {
919-
early_error(color, &format!("unknown emission type: `{}`",
926+
early_error(emit_cfg, &format!("unknown emission type: `{}`",
920927
part))
921928
}
922929
};
@@ -929,15 +936,15 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
929936
output_types.insert(OutputType::Exe, None);
930937
}
931938

932-
let cg = build_codegen_options(matches, color);
939+
let cg = build_codegen_options(matches, emit_cfg);
933940

934941
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
935942
let target = matches.opt_str("target").unwrap_or(
936943
host_triple().to_string());
937944
let opt_level = {
938945
if matches.opt_present("O") {
939946
if cg.opt_level.is_some() {
940-
early_error(color, "-O and -C opt-level both provided");
947+
early_error(emit_cfg, "-O and -C opt-level both provided");
941948
}
942949
Default
943950
} else {
@@ -948,7 +955,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
948955
Some(2) => Default,
949956
Some(3) => Aggressive,
950957
Some(arg) => {
951-
early_error(color, &format!("optimization level needs to be \
958+
early_error(emit_cfg, &format!("optimization level needs to be \
952959
between 0-3 (instead was `{}`)",
953960
arg));
954961
}
@@ -959,7 +966,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
959966
let gc = debugging_opts.gc;
960967
let debuginfo = if matches.opt_present("g") {
961968
if cg.debuginfo.is_some() {
962-
early_error(color, "-g and -C debuginfo both provided");
969+
early_error(emit_cfg, "-g and -C debuginfo both provided");
963970
}
964971
FullDebugInfo
965972
} else {
@@ -968,7 +975,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
968975
Some(1) => LimitedDebugInfo,
969976
Some(2) => FullDebugInfo,
970977
Some(arg) => {
971-
early_error(color, &format!("debug info level needs to be between \
978+
early_error(emit_cfg, &format!("debug info level needs to be between \
972979
0-2 (instead was `{}`)",
973980
arg));
974981
}
@@ -977,7 +984,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
977984

978985
let mut search_paths = SearchPaths::new();
979986
for s in &matches.opt_strs("L") {
980-
search_paths.add_path(&s[..], color);
987+
search_paths.add_path(&s[..], emit_cfg);
981988
}
982989

983990
let libs = matches.opt_strs("l").into_iter().map(|s| {
@@ -989,7 +996,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
989996
(Some(name), "framework") => (name, cstore::NativeFramework),
990997
(Some(name), "static") => (name, cstore::NativeStatic),
991998
(_, s) => {
992-
early_error(color, &format!("unknown library kind `{}`, expected \
999+
early_error(emit_cfg, &format!("unknown library kind `{}`, expected \
9931000
one of dylib, framework, or static",
9941001
s));
9951002
}
@@ -1006,13 +1013,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10061013
"file-names" => PrintRequest::FileNames,
10071014
"sysroot" => PrintRequest::Sysroot,
10081015
req => {
1009-
early_error(color, &format!("unknown print request `{}`", req))
1016+
early_error(emit_cfg, &format!("unknown print request `{}`", req))
10101017
}
10111018
}
10121019
}).collect::<Vec<_>>();
10131020

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

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

10311038
externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string());
@@ -1055,7 +1062,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10551062
debugging_opts: debugging_opts,
10561063
prints: prints,
10571064
cg: cg,
1058-
color: color,
1065+
emit_cfg: emit_cfg,
10591066
show_span: None,
10601067
externs: externs,
10611068
crate_name: crate_name,

src/librustc/session/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ pub fn build_session(sopts: config::Options,
394394

395395
let codemap = codemap::CodeMap::new();
396396
let diagnostic_handler =
397-
diagnostic::Handler::new(sopts.color, Some(registry), can_print_warnings);
397+
diagnostic::Handler::new(sopts.emit_cfg, Some(registry), can_print_warnings);
398398
let span_diagnostic_handler =
399399
diagnostic::SpanHandler::new(diagnostic_handler, codemap);
400400

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

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

482-
pub fn early_warn(color: diagnostic::ColorConfig, msg: &str) {
483-
let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
482+
pub fn early_warn(cfg: diagnostic::EmitterConfig, msg: &str) {
483+
let mut emitter = diagnostic::EmitterWriter::stderr(cfg, None);
484484
emitter.emit(None, msg, None, diagnostic::Warning);
485485
}

src/librustc/session/search_paths.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl SearchPaths {
3838
SearchPaths { paths: Vec::new() }
3939
}
4040

41-
pub fn add_path(&mut self, path: &str, color: diagnostic::ColorConfig) {
41+
pub fn add_path(&mut self, path: &str, cfg: diagnostic::EmitterConfig) {
4242
let (kind, path) = if path.starts_with("native=") {
4343
(PathKind::Native, &path["native=".len()..])
4444
} else if path.starts_with("crate=") {
@@ -53,7 +53,7 @@ impl SearchPaths {
5353
(PathKind::All, path)
5454
};
5555
if path.is_empty() {
56-
early_error(color, "empty search path given via `-L`");
56+
early_error(cfg, "empty search path given via `-L`");
5757
}
5858
self.paths.push((kind, PathBuf::from(path)));
5959
}

src/librustc_back/target/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl Target {
250250
// this is 1. ugly, 2. error prone.
251251

252252

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

255255
let get_req_field = |name: &str| {
256256
match obj.find(name)

0 commit comments

Comments
 (0)