diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 7fb66ea97f26b..b4f95b915eb8d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -44,7 +44,7 @@ use serialize::json; use std::any::Any; use std::env; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::fs; use std::io::{self, Write}; use std::iter; @@ -1021,6 +1021,7 @@ where .cloned() .collect(); missing_fragment_specifiers.sort(); + for span in missing_fragment_specifiers { let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER; let msg = "missing fragment specifier"; @@ -1472,7 +1473,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa .collect(); let mut file = fs::File::create(&deps_filename)?; for path in out_filenames { - write!(file, "{}: {}\n\n", path.display(), files.join(" "))?; + writeln!(file, "{}: {}\n", path.display(), files.join(" "))?; } // Emit a fake target for each input file to the compilation. This @@ -1484,15 +1485,12 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa Ok(()) })(); - match result { - Ok(()) => {} - Err(e) => { - sess.fatal(&format!( - "error writing dependencies to `{}`: {}", - deps_filename.display(), - e - )); - } + if let Err(e) = result { + sess.fatal(&format!( + "error writing dependencies to `{}`: {}", + deps_filename.display(), + e + )); } } @@ -1520,6 +1518,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Vec { + None => { session .struct_span_err(a.span, "`crate_type` requires a value") .note("for example: `#![crate_type=\"lib\"]`") @@ -1581,25 +1580,26 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec CrateDisambiguator { @@ -1650,17 +1650,14 @@ pub fn build_output_filenames( // "-" as input file will cause the parser to read from stdin so we // have to make up a name // We want to toss everything after the final '.' - let dirpath = match *odir { - Some(ref d) => d.clone(), - None => PathBuf::new(), - }; + let dirpath = (*odir).as_ref().cloned().unwrap_or_default(); // If a crate name is present, we use it as the link name let stem = sess.opts .crate_name .clone() .or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string())) - .unwrap_or(input.filestem()); + .unwrap_or_else(|| input.filestem()); OutputFilenames { out_directory: dirpath, @@ -1693,13 +1690,11 @@ pub fn build_output_filenames( sess.warn("ignoring -C extra-filename flag due to -o flag"); } - let cur_dir = Path::new(""); - OutputFilenames { - out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(), + out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), out_filestem: out_file .file_stem() - .unwrap_or(OsStr::new("")) + .unwrap_or_default() .to_str() .unwrap() .to_string(), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 0514bd20c985a..276b7290c2ef0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -89,6 +89,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use serialize::json::ToJson; use std::any::Any; +use std::borrow::Cow; use std::cmp::max; use std::default::Default; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; @@ -136,9 +137,7 @@ pub mod target_features { codegen_backend: &dyn CodegenBackend) { let tf = Symbol::intern("target_feature"); - for feat in codegen_backend.target_features(sess) { - cfg.insert((tf, Some(feat))); - } + cfg.extend(codegen_backend.target_features(sess).into_iter().map(|feat| (tf, Some(feat)))); if sess.crt_static_feature() { cfg.insert((tf, Some(Symbol::intern("crt-static")))); @@ -152,21 +151,14 @@ pub const EXIT_SUCCESS: isize = 0; /// Exit status code used for compilation failures and invalid flags. pub const EXIT_FAILURE: isize = 1; -const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ - md#bug-reports"; - -const ICE_REPORT_COMPILER_FLAGS: &'static [&'static str] = &[ - "Z", - "C", - "crate-type", -]; -const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &'static [&'static str] = &[ - "metadata", - "extra-filename", -]; -const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &'static [&'static str] = &[ - "incremental", -]; +const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ + md#bug-reports"; + +const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["Z", "C", "crate-type"]; + +const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"]; + +const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"]; pub fn abort_on_err(result: Result, sess: &Session) -> T { match result { @@ -195,14 +187,16 @@ pub fn run(run_compiler: F) -> isize } None => { let emitter = - errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, - None, - true, - false); + errors::emitter::EmitterWriter::stderr( + errors::ColorConfig::Auto, + None, + true, + false + ); let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); handler.emit(&MultiSpan::new(), - "aborting due to previous error(s)", - errors::Level::Fatal); + "aborting due to previous error(s)", + errors::Level::Fatal); panic::resume_unwind(Box::new(errors::FatalErrorMarker)); } } @@ -224,15 +218,10 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box { // available for future dynamic libraries opened. This is currently used by // loading LLVM and then making its symbols available for other dynamic // libraries. - let lib = match DynamicLibrary::open_global_now(path) { - Ok(lib) => lib, - Err(err) => { - let err = format!("couldn't load codegen backend {:?}: {:?}", - path, - err); - early_error(ErrorOutputType::default(), &err); - } - }; + let lib = DynamicLibrary::open_global_now(path).unwrap_or_else(|err| { + let err = format!("couldn't load codegen backend {:?}: {:?}", path, err); + early_error(ErrorOutputType::default(), &err); + }); unsafe { match lib.symbol("__rustc_codegen_backend") { Ok(f) => { @@ -328,37 +317,30 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { let sysroot = sysroot_candidates.iter() .map(|sysroot| { let libdir = filesearch::relative_target_lib_path(&sysroot, &target); - sysroot.join(libdir) - .with_file_name(option_env!("CFG_CODEGEN_BACKENDS_DIR") - .unwrap_or("codegen-backends")) + sysroot.join(libdir).with_file_name( + option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends")) }) .filter(|f| { info!("codegen backend candidate: {}", f.display()); f.exists() }) .next(); - let sysroot = match sysroot { - Some(path) => path, - None => { - let candidates = sysroot_candidates.iter() - .map(|p| p.display().to_string()) - .collect::>() - .join("\n* "); - let err = format!("failed to find a `codegen-backends` folder \ - in the sysroot candidates:\n* {}", candidates); - early_error(ErrorOutputType::default(), &err); - } - }; + let sysroot = sysroot.unwrap_or_else(|| { + let candidates = sysroot_candidates.iter() + .map(|p| p.display().to_string()) + .collect::>() + .join("\n* "); + let err = format!("failed to find a `codegen-backends` folder \ + in the sysroot candidates:\n* {}", candidates); + early_error(ErrorOutputType::default(), &err); + }); info!("probing {} for a codegen backend", sysroot.display()); - let d = match sysroot.read_dir() { - Ok(d) => d, - Err(e) => { - let err = format!("failed to load default codegen backend, couldn't \ - read `{}`: {}", sysroot.display(), e); - early_error(ErrorOutputType::default(), &err); - } - }; + let d = sysroot.read_dir().unwrap_or_else(|e| { + let err = format!("failed to load default codegen backend, couldn't \ + read `{}`: {}", sysroot.display(), e); + early_error(ErrorOutputType::default(), &err); + }); let mut file: Option = None; @@ -378,8 +360,8 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { } if let Some(ref prev) = file { let err = format!("duplicate codegen backends found\n\ - first: {}\n\ - second: {}\n\ + first: {}\n\ + second: {}\n\ ", prev.display(), path.display()); early_error(ErrorOutputType::default(), &err); } @@ -391,7 +373,7 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { None => { let err = format!("failed to load default codegen backend for `{}`, \ no appropriate codegen dylib found in `{}`", - backend_name, sysroot.display()); + backend_name, sysroot.display()); early_error(ErrorOutputType::default(), &err); } } @@ -578,7 +560,7 @@ pub fn set_sigpipe_handler() { unsafe { // Set the SIGPIPE signal handler, so that an EPIPE // will cause rustc to terminate, as expected. - assert!(libc::signal(libc::SIGPIPE, libc::SIG_DFL) != libc::SIG_ERR); + assert_ne!(libc::signal(libc::SIGPIPE, libc::SIG_DFL), libc::SIG_ERR); } } @@ -996,7 +978,7 @@ impl RustcDefaultCalls { input: &Input) -> Compilation { let r = matches.opt_strs("Z"); - if r.contains(&("ls".to_string())) { + if r.iter().any(|s| *s == "ls") { match input { &Input::File(ref ifile) => { let path = &(*ifile); @@ -1015,7 +997,7 @@ impl RustcDefaultCalls { return Compilation::Stop; } - return Compilation::Continue; + Compilation::Continue } @@ -1028,7 +1010,7 @@ impl RustcDefaultCalls { use rustc::session::config::PrintRequest::*; // PrintRequest::NativeStaticLibs is special - printed during linking // (empty iterator returns true) - if sess.opts.prints.iter().all(|&p| p==PrintRequest::NativeStaticLibs) { + if sess.opts.prints.iter().all(|&p| p == PrintRequest::NativeStaticLibs) { return Compilation::Continue; } @@ -1055,10 +1037,8 @@ impl RustcDefaultCalls { Sysroot => println!("{}", sess.sysroot().display()), TargetSpec => println!("{}", sess.target.target.to_json().pretty()), FileNames | CrateName => { - let input = match input { - Some(input) => input, - None => early_error(ErrorOutputType::default(), "no input file provided"), - }; + let input = input.unwrap_or_else(|| + early_error(ErrorOutputType::default(), "no input file provided")); let attrs = attrs.as_ref().unwrap(); let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess); let id = rustc_codegen_utils::link::find_crate_name(Some(sess), attrs, input); @@ -1074,18 +1054,14 @@ impl RustcDefaultCalls { &id, &t_outputs ); - println!("{}", - fname.file_name() - .unwrap() - .to_string_lossy()); + println!("{}", fname.file_name().unwrap().to_string_lossy()); } } Cfg => { let allow_unstable_cfg = UnstableFeatures::from_environment() .is_nightly_build(); - let mut cfgs = Vec::new(); - for &(name, ref value) in sess.parse_sess.config.iter() { + let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| { let gated_cfg = GatedCfg::gate(&ast::MetaItem { ident: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)), node: ast::MetaItemKind::Word, @@ -1104,16 +1080,16 @@ impl RustcDefaultCalls { let value = value.as_ref().map(|s| s.as_ref()); if name != "target_feature" || value != Some("crt-static") { if !allow_unstable_cfg && gated_cfg.is_some() { - continue; + return None } } - cfgs.push(if let Some(value) = value { - format!("{}=\"{}\"", name, value) + if let Some(value) = value { + Some(format!("{}=\"{}\"", name, value)) } else { - name.to_string() - }); - } + Some(name.to_string()) + } + }).collect::>(); cfgs.sort(); for cfg in cfgs { @@ -1150,9 +1126,8 @@ fn commit_date_str() -> Option<&'static str> { pub fn version(binary: &str, matches: &getopts::Matches) { let verbose = matches.opt_present("verbose"); - println!("{} {}", - binary, - option_env!("CFG_VERSION").unwrap_or("unknown version")); + println!("{} {}", binary, option_env!("CFG_VERSION").unwrap_or("unknown version")); + if verbose { fn unw(x: Option<&str>) -> &str { x.unwrap_or("unknown") @@ -1176,7 +1151,7 @@ fn usage(verbose: bool, include_unstable_options: bool) { for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) { (option.apply)(&mut options); } - let message = "Usage: rustc [OPTIONS] INPUT".to_string(); + let message = "Usage: rustc [OPTIONS] INPUT"; let nightly_help = if nightly_options::is_nightly_build() { "\n -Z help Print internal options for debugging rustc" } else { @@ -1191,7 +1166,7 @@ fn usage(verbose: bool, include_unstable_options: bool) { -C help Print codegen options -W help \ Print 'lint' options and default settings{}{}\n", - options.usage(&message), + options.usage(message), nightly_help, verbose_help); } @@ -1273,8 +1248,6 @@ Available lint options: print_lints(builtin); - - let max_name_len = max("warnings".len(), plugin_groups.iter() .chain(&builtin_groups) @@ -1407,10 +1380,8 @@ pub fn handle_options(args: &[String]) -> Option { for option in config::rustc_optgroups() { (option.apply)(&mut options); } - let matches = match options.parse(args) { - Ok(m) => m, - Err(f) => early_error(ErrorOutputType::default(), &f.to_string()), - }; + let matches = options.parse(args).unwrap_or_else(|f| + early_error(ErrorOutputType::default(), &f.to_string())); // For all options we just parsed, we check a few aspects: // @@ -1452,6 +1423,7 @@ pub fn handle_options(args: &[String]) -> Option { } let cg_flags = matches.opt_strs("C"); + if cg_flags.iter().any(|x| *x == "help") { describe_codegen_flags(); return None; @@ -1462,7 +1434,7 @@ pub fn handle_options(args: &[String]) -> Option { "the --no-stack-check flag is deprecated and does nothing"); } - if cg_flags.contains(&"passes=list".to_string()) { + if cg_flags.iter().any(|x| *x == "passes=list") { get_codegen_sysroot("llvm")().print_passes(); return None; } @@ -1500,7 +1472,7 @@ pub fn in_named_rustc_thread(name: String, f: F) -> Result(name: String, f: F) -> Result Option<(Vec, bool)> { } } - if result.len() > 0 { + if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None @@ -1680,25 +1652,25 @@ pub fn monitor(f: F) -> Result<(), CompilationFail errors::Level::Bug); } - let mut xs = vec![ - "the compiler unexpectedly panicked. this is a bug.".to_string(), - format!("we would appreciate a bug report: {}", BUG_REPORT_URL), + let mut xs: Vec> = vec![ + "the compiler unexpectedly panicked. this is a bug.".into(), + format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(), format!("rustc {} running on {}", option_env!("CFG_VERSION").unwrap_or("unknown_version"), - config::host_triple()), + config::host_triple()).into(), ]; if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { - xs.push(format!("compiler flags: {}", flags.join(" "))); + xs.push(format!("compiler flags: {}", flags.join(" ")).into()); if excluded_cargo_defaults { - xs.push("some of the compiler flags provided by cargo are hidden".to_string()); + xs.push("some of the compiler flags provided by cargo are hidden".into()); } } for note in &xs { handler.emit(&MultiSpan::new(), - ¬e, + note, errors::Level::Note); } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 7e395f1e9a92f..b4f6d10b1f829 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -167,10 +167,10 @@ pub fn parse_pretty(sess: &Session, impl PpSourceMode { /// Constructs a `PrinterSupport` object and passes it to `f`. fn call_with_pp_support<'tcx, A, F>(&self, - sess: &'tcx Session, - hir_map: Option<&hir_map::Map<'tcx>>, - f: F) - -> A + sess: &'tcx Session, + hir_map: Option<&hir_map::Map<'tcx>>, + f: F) + -> A where F: FnOnce(&dyn PrinterSupport) -> A { match *self { @@ -198,17 +198,18 @@ impl PpSourceMode { _ => panic!("Should use call_with_pp_support_hir"), } } - fn call_with_pp_support_hir<'tcx, A, F>(&self, - sess: &'tcx Session, - cstore: &'tcx CStore, - hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, - resolutions: &Resolutions, - arenas: &'tcx AllArenas<'tcx>, - output_filenames: &OutputFilenames, - id: &str, - f: F) - -> A + fn call_with_pp_support_hir<'tcx, A, F>( + &self, + sess: &'tcx Session, + cstore: &'tcx CStore, + hir_map: &hir_map::Map<'tcx>, + analysis: &ty::CrateAnalysis, + resolutions: &Resolutions, + arenas: &'tcx AllArenas<'tcx>, + output_filenames: &OutputFilenames, + id: &str, + f: F + ) -> A where F: FnOnce(&dyn HirPrinterSupport, &hir::Crate) -> A { match *self { @@ -855,7 +856,7 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, break n.body(); } let parent = tcx.hir.get_parent_node(node_id); - assert!(node_id != parent); + assert_ne!(node_id, parent); node_id = parent; } } @@ -952,18 +953,17 @@ pub fn print_after_parsing(sess: &Session, // Silently ignores an identified node. let out: &mut dyn Write = &mut out; s.call_with_pp_support(sess, None, move |annotation| { - debug!("pretty printing source code {:?}", s); - let sess = annotation.sess(); - pprust::print_crate(sess.source_map(), - &sess.parse_sess, - krate, - src_name, - &mut rdr, - box out, - annotation.pp_ann(), - false) - }) - .unwrap() + debug!("pretty printing source code {:?}", s); + let sess = annotation.sess(); + pprust::print_crate(sess.source_map(), + &sess.parse_sess, + krate, + src_name, + &mut rdr, + box out, + annotation.pp_ann(), + false) + }).unwrap() } else { unreachable!(); }; diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs index 2ec85e1c27f1d..d334a9476ce24 100644 --- a/src/librustc_driver/profile/mod.rs +++ b/src/librustc_driver/profile/mod.rs @@ -23,7 +23,7 @@ pub fn begin(sess: &Session) { use std::sync::mpsc::{channel}; let (tx, rx) = channel(); if profq_set_chan(sess, tx) { - thread::spawn(move||profile_queries_thread(rx)); + thread::spawn(move || profile_queries_thread(rx)); } } @@ -34,11 +34,12 @@ pub fn begin(sess: &Session) { pub fn dump(sess: &Session, path: String) { use std::sync::mpsc::{channel}; let (tx, rx) = channel(); - let params = ProfQDumpParams{ - path, ack:tx, + let params = ProfQDumpParams { + path, + ack: tx, // FIXME: Add another compiler flag to toggle whether this log // is written; false for now - dump_profq_msg_log:true, + dump_profq_msg_log: true, }; profq_msg(sess, ProfileQueriesMsg::Dump(params)); let _ = rx.recv().unwrap(); @@ -63,20 +64,20 @@ struct StackFrame { } fn total_duration(traces: &[trace::Rec]) -> Duration { - let mut sum : Duration = Duration::new(0,0); + let mut sum : Duration = Duration::new(0, 0); for t in traces.iter() { sum += t.dur_total; } return sum } // profiling thread; retains state (in local variables) and dump traces, upon request. -fn profile_queries_thread(r:Receiver) { +fn profile_queries_thread(r: Receiver) { use self::trace::*; use std::fs::File; use std::time::{Instant}; - let mut profq_msgs : Vec = vec![]; - let mut frame : StackFrame = StackFrame{ parse_st:ParseState::Clear, traces:vec![] }; - let mut stack : Vec = vec![]; + let mut profq_msgs: Vec = vec![]; + let mut frame: StackFrame = StackFrame { parse_st: ParseState::Clear, traces: vec![] }; + let mut stack: Vec = vec![]; loop { let msg = r.recv(); if let Err(_recv_err) = msg { @@ -90,7 +91,7 @@ fn profile_queries_thread(r:Receiver) { match msg { ProfileQueriesMsg::Halt => return, ProfileQueriesMsg::Dump(params) => { - assert!(stack.len() == 0); + assert!(stack.is_empty()); assert!(frame.parse_st == ParseState::Clear); { // write log of all messages @@ -109,17 +110,14 @@ fn profile_queries_thread(r:Receiver) { let counts_path = format!("{}.counts.txt", params.path); let mut counts_file = File::create(&counts_path).unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, - "\n\n", - "profile_queries.css").unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, "\n").unwrap(); + writeln!(html_file, "\n\n").unwrap(); trace::write_traces(&mut html_file, &mut counts_file, &frame.traces); - write!(html_file, "\n\n").unwrap(); + writeln!(html_file, "\n").unwrap(); let ack_path = format!("{}.ack", params.path); let ack_file = File::create(&ack_path).unwrap(); @@ -141,10 +139,10 @@ fn profile_queries_thread(r:Receiver) { // Parse State: Clear (ParseState::Clear, - ProfileQueriesMsg::QueryBegin(span,querymsg)) => { + ProfileQueriesMsg::QueryBegin(span, querymsg)) => { let start = Instant::now(); frame.parse_st = ParseState::HaveQuery - (Query{span:span, msg:querymsg}, start) + (Query { span, msg: querymsg }, start) }, (ParseState::Clear, ProfileQueriesMsg::CacheHit) => { @@ -287,8 +285,6 @@ fn profile_queries_thread(r:Receiver) { frame = StackFrame{parse_st:ParseState::Clear, traces:vec![]}; }, - // - // // Parse errors: (ParseState::HaveQuery(q,_), @@ -310,7 +306,6 @@ fn profile_queries_thread(r:Receiver) { unreachable!() }, } - } } } diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index e329b037d22aa..9589ae2a8dbe0 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -43,18 +43,18 @@ pub struct QueryMetric { pub dur_total: Duration, } +fn cons(s: &str) -> String { + let first = s.split(|d| d == '(' || d == '{').next(); + assert!(first.is_some() && first != Some("")); + first.unwrap().to_owned() +} + pub fn cons_of_query_msg(q: &trace::Query) -> String { - let s = format!("{:?}", q.msg); - let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect(); - assert!(cons.len() > 0 && cons[0] != ""); - cons[0].to_string() + cons(&format!("{:?}", q.msg)) } pub fn cons_of_key(k: &DepNode) -> String { - let s = format!("{:?}", k); - let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect(); - assert!(cons.len() > 0 && cons[0] != ""); - cons[0].to_string() + cons(&format!("{:?}", k)) } // First return value is text; second return value is a CSS class @@ -84,35 +84,33 @@ pub fn html_of_effect(eff: &Effect) -> (String, String) { // First return value is text; second return value is a CSS class fn html_of_duration(_start: &Instant, dur: &Duration) -> (String, String) { use rustc::util::common::duration_to_secs_str; - (duration_to_secs_str(dur.clone()), - String::new() - ) + (duration_to_secs_str(dur.clone()), String::new()) } -fn html_of_fraction(frac: f64) -> (String, String) { +fn html_of_fraction(frac: f64) -> (String, &'static str) { let css = { - if frac > 0.50 { "frac-50".to_string() } - else if frac > 0.40 { "frac-40".to_string() } - else if frac > 0.30 { "frac-30".to_string() } - else if frac > 0.20 { "frac-20".to_string() } - else if frac > 0.10 { "frac-10".to_string() } - else if frac > 0.05 { "frac-05".to_string() } - else if frac > 0.02 { "frac-02".to_string() } - else if frac > 0.01 { "frac-01".to_string() } - else if frac > 0.001 { "frac-001".to_string() } - else { "frac-0".to_string() } + if frac > 0.50 { "frac-50" } + else if frac > 0.40 { "frac-40" } + else if frac > 0.30 { "frac-30" } + else if frac > 0.20 { "frac-20" } + else if frac > 0.10 { "frac-10" } + else if frac > 0.05 { "frac-05" } + else if frac > 0.02 { "frac-02" } + else if frac > 0.01 { "frac-01" } + else if frac > 0.001 { "frac-001" } + else { "frac-0" } }; let percent = frac * 100.0; - if percent > 0.1 { (format!("{:.1}%", percent), css) } - else { ("< 0.1%".to_string(), css) } + + if percent > 0.1 { + (format!("{:.1}%", percent), css) + } else { + ("< 0.1%".to_string(), css) + } } fn total_duration(traces: &[Rec]) -> Duration { - let mut sum : Duration = Duration::new(0,0); - for t in traces.iter() { - sum += t.dur_total; - } - return sum + Duration::new(0, 0) + traces.iter().map(|t| t.dur_total).sum() } fn duration_div(nom: Duration, den: Duration) -> f64 { @@ -130,64 +128,65 @@ fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usi let fraction = duration_div(t.dur_total, total); let percent = fraction * 100.0; let (frc_text, frc_css_classes) = html_of_fraction(fraction); - write!(file, "
\n", - depth, - t.extent.len(), - /* Heuristic for 'important' CSS class: */ - if t.extent.len() > 5 || percent >= 1.0 { - " important" } - else { "" }, - eff_css_classes, - dur_css_classes, - frc_css_classes, + writeln!(file, "
", + depth, + t.extent.len(), + /* Heuristic for 'important' CSS class: */ + if t.extent.len() > 5 || percent >= 1.0 { " important" } else { "" }, + eff_css_classes, + dur_css_classes, + frc_css_classes, ).unwrap(); - write!(file, "
{}
\n", eff_text).unwrap(); - write!(file, "
{}
\n", dur_text).unwrap(); - write!(file, "
{}
\n", frc_text).unwrap(); + writeln!(file, "
{}
", eff_text).unwrap(); + writeln!(file, "
{}
", dur_text).unwrap(); + writeln!(file, "
{}
", frc_text).unwrap(); write_traces_rec(file, &t.extent, total, depth + 1); - write!(file, "
\n").unwrap(); + writeln!(file, "
").unwrap(); } } fn compute_counts_rec(counts: &mut FxHashMap, traces: &[Rec]) { + counts.reserve(traces.len()); for t in traces.iter() { match t.effect { Effect::TimeBegin(ref msg) => { let qm = match counts.get(msg) { - Some(_qm) => { panic!("TimeBegin with non-unique, repeat message") } - None => QueryMetric{ + Some(_qm) => panic!("TimeBegin with non-unique, repeat message"), + None => QueryMetric { count: 1, dur_self: t.dur_self, dur_total: t.dur_total, - }}; + } + }; counts.insert(msg.clone(), qm); }, Effect::TaskBegin(ref key) => { let cons = cons_of_key(key); let qm = match counts.get(&cons) { Some(qm) => - QueryMetric{ + QueryMetric { count: qm.count + 1, dur_self: qm.dur_self + t.dur_self, dur_total: qm.dur_total + t.dur_total, }, - None => QueryMetric{ + None => QueryMetric { count: 1, dur_self: t.dur_self, dur_total: t.dur_total, - }}; + } + }; counts.insert(cons, qm); }, Effect::QueryBegin(ref qmsg, ref _cc) => { let qcons = cons_of_query_msg(qmsg); let qm = match counts.get(&qcons) { Some(qm) => - QueryMetric{ + QueryMetric { count: qm.count + 1, dur_total: qm.dur_total + t.dur_total, dur_self: qm.dur_self + t.dur_self }, - None => QueryMetric{ + None => QueryMetric { count: 1, dur_total: t.dur_total, dur_self: t.dur_self, @@ -200,19 +199,20 @@ fn compute_counts_rec(counts: &mut FxHashMap, traces: &[Rec] } } -pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap) { +pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap) { use rustc::util::common::duration_to_secs_str; use std::cmp::Reverse; let mut data = counts.iter().map(|(ref cons, ref qm)| (cons.clone(), qm.count.clone(), qm.dur_total.clone(), qm.dur_self.clone()) ).collect::>(); + data.sort_by_key(|k| Reverse(k.3)); for (cons, count, dur_total, dur_self) in data { - write!(count_file, "{}, {}, {}, {}\n", - cons, count, - duration_to_secs_str(dur_total), - duration_to_secs_str(dur_self) + writeln!(count_file, "{}, {}, {}, {}", + cons, count, + duration_to_secs_str(dur_total), + duration_to_secs_str(dur_self) ).unwrap(); } } @@ -223,12 +223,12 @@ pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &[Rec] compute_counts_rec(&mut counts, traces); write_counts(counts_file, &mut counts); - let total : Duration = total_duration(traces); + let total: Duration = total_duration(traces); write_traces_rec(html_file, traces, total, 0) } pub fn write_style(html_file: &mut File) { - write!(html_file,"{}", " + write!(html_file, "{}", " body { font-family: sans-serif; background: black;