From c01e4ce74e96737f99492a185e2d170964f11556 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 11 Sep 2018 16:39:07 +0200 Subject: [PATCH 1/7] Emit used rustc invocation in the save-analysis file --- src/Cargo.toml | 1 + src/librustc_save_analysis/dump_visitor.rs | 64 +++++++++++++++++++++- src/librustc_save_analysis/json_dumper.rs | 10 +++- src/librustc_save_analysis/lib.rs | 27 +++++++-- src/librustc_save_analysis/span_utils.rs | 13 +++-- 5 files changed, 101 insertions(+), 14 deletions(-) diff --git a/src/Cargo.toml b/src/Cargo.toml index e8c44ea57c2e9..b4ef8754b81b1 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -57,6 +57,7 @@ cargo = { path = "tools/cargo" } # that we're shipping as well (to ensure that the rustfmt in RLS and the # `rustfmt` executable are the same exact version). rustfmt-nightly = { path = "tools/rustfmt" } +rls-data = { git = "/~https://github.com/Xanewok/rls-data", branch = "compilation-options" } # See comments in `tools/rustc-workspace-hack/README.md` for what's going on # here diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index d719d257f352c..b044210c092e4 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -28,7 +28,8 @@ use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashSet; -use std::path::Path; +use std::path::{Path, PathBuf}; +use std::env; use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID}; use syntax::parse::token; @@ -49,8 +50,10 @@ use json_dumper::{Access, DumpOutput, JsonDumper}; use span_utils::SpanUtils; use sig; -use rls_data::{CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref, RefKind, - Relation, RelationKind, SpanData}; +use rls_data::{ + CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref, + RefKind, Relation, RelationKind, SpanData, +}; macro_rules! down_cast_data { ($id:ident, $kind:ident, $sp:expr) => { @@ -169,6 +172,61 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.dumper.crate_prelude(data); } + pub fn dump_compilation_options(&mut self) { + // Apply possible `remap-path-prefix` remapping to the raw invocation + let invocation = { + let remap_arg_indices = { + let mut indices = FxHashSet(); + for (i, e) in env::args().enumerate() { + if e.starts_with("--remap-path-prefix=") { + indices.insert(i); + } else if e == "--remap-path-prefix" { + indices.insert(i); + indices.insert(i + 1); + } + } + indices + }; + + let args_without_remap_args = env::args() + .enumerate() + .filter(|(i, _)| !remap_arg_indices.contains(i)) + .map(|(_, e)| e); + + let mapping = self.tcx.sess.source_map().path_mapping(); + let remap_arg = |x: &str| -> String { + mapping.map_prefix(PathBuf::from(x)).0.to_str().unwrap().to_owned() + }; + + // Naively attempt to remap every argument + let args = args_without_remap_args + .map(|elem| { + let mut arg = elem.splitn(2, '='); + match (arg.next(), arg.next()) { + // Apart from `--remap...`, in `a=b` args usually only + // `b` is a path (e.g. `--extern some_crate=/path/to..`) + (Some(a), Some(b)) => format!("{}={}", a, remap_arg(b)), + (Some(a), _) => remap_arg(a), + _ => unreachable!(), + } + }).collect::>(); + + args.as_slice().join(" ") + }; + + let opts = &self.tcx.sess.opts; + + let data = CompilationOptions { + invocation, + crate_name: opts.crate_name.clone(), + test: opts.test, + sysroot: opts.maybe_sysroot.clone(), + target_triple: opts.target_triple.to_string(), + }; + + self.dumper.compilation_opts(data); + } + // Return all non-empty prefixes of a path. // For each prefix, we return the span for the last segment in the prefix and // a str representation of the entire prefix. diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index d2e52f98238dd..bfd3a01ca4221 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -12,9 +12,11 @@ use std::io::Write; use rustc_serialize::json::as_json; -use rls_data::{self, Analysis, CratePreludeData, Def, DefKind, Import, MacroRef, Ref, RefKind, - Relation, Impl}; use rls_data::config::Config; +use rls_data::{ + self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import, MacroRef, + Ref, RefKind, Relation, +}; use rls_span::{Column, Row}; #[derive(Debug)] @@ -89,6 +91,10 @@ impl<'b, O: DumpOutput + 'b> JsonDumper { self.result.prelude = Some(data) } + pub fn compilation_opts(&mut self, data: CompilationOptions) { + self.result.compilation = Some(data); + } + pub fn macro_use(&mut self, data: MacroRef) { if self.config.pub_only || self.config.reachable_only { return; diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c9bae297031ff..06496db527452 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -70,10 +70,11 @@ use json_dumper::JsonDumper; use dump_visitor::DumpVisitor; use span_utils::SpanUtils; -use rls_data::{Def, DefKind, ExternalCrateData, GlobalCrateId, MacroRef, Ref, RefKind, Relation, - RelationKind, SpanData, Impl, ImplKind}; use rls_data::config::Config; - +use rls_data::{ + CrateSource, Def, DefKind, ExternalCrateData, GlobalCrateId, Impl, ImplKind, MacroRef, Ref, + RefKind, Relation, RelationKind, SpanData, +}; pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, @@ -122,16 +123,32 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { continue; } }; + let src = self.tcx.used_crate_source(n); let lo_loc = self.span_utils.sess.source_map().lookup_char_pos(span.lo()); + let map_prefix = |path: &PathBuf| -> PathBuf { + self.tcx.sess.source_map().path_mapping().map_prefix(path.to_owned()).0 + }; + result.push(ExternalCrateData { // FIXME: change file_name field to PathBuf in rls-data // /~https://github.com/nrc/rls-data/issues/7 - file_name: self.span_utils.make_path_string(&lo_loc.file.name), + file_name: self.span_utils.make_filename_string(&lo_loc.file), num: n.as_u32(), id: GlobalCrateId { name: self.tcx.crate_name(n).to_string(), disambiguator: self.tcx.crate_disambiguator(n).to_fingerprint().as_value(), }, + source: CrateSource { + dylib: src.dylib.as_ref().map(|(ref path, _)| + map_prefix(path).display().to_string() + ), + rlib: src.rlib.as_ref().map(|(ref path, _)| + map_prefix(path).display().to_string() + ), + rmeta: src.rmeta.as_ref().map(|(ref path, _)| + map_prefix(path).display().to_string() + ), + } }); } @@ -1086,6 +1103,7 @@ impl<'a> SaveHandler for DumpHandler<'a> { let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); + visitor.dump_compilation_options(); visit::walk_crate(&mut visitor, krate); } } @@ -1111,6 +1129,7 @@ impl<'b> SaveHandler for CallbackHandler<'b> { let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); + visitor.dump_compilation_options(); visit::walk_crate(&mut visitor, krate); } } diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index 2550a312c5d6d..56728aed76921 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -35,14 +35,17 @@ impl<'a> SpanUtils<'a> { } } - pub fn make_path_string(&self, path: &FileName) -> String { - match *path { - FileName::Real(ref path) if !path.is_absolute() => + pub fn make_filename_string(&self, file: &SourceFile) -> String { + match &file.name { + FileName::Real(path) if !path.is_absolute() && !file.name_was_remapped => { self.sess.working_dir.0 .join(&path) .display() - .to_string(), - _ => path.to_string(), + .to_string() + }, + // If the file name is already remapped, we assume the user + // configured it the way they wanted to, so use that directly + filename => filename.to_string() } } From cddd00a1e60924fd41e2b51cfd22b9756f6145e8 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sat, 22 Sep 2018 22:24:32 +0200 Subject: [PATCH 2/7] Move `filename_for_metadata` to codegen_utils This function isn't strictly tied to LLVM (it's more of a utility) and it's now near an analogous, almost identical `filename_for_input` (for rlibs and so forth). Also this means not depending on the backend when one wants to know the accurate .rmeta output filename. --- src/librustc_codegen_llvm/back/link.rs | 12 ++---------- src/librustc_codegen_utils/link.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 8248385c12764..ce52fe00b0eb2 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -47,7 +47,8 @@ use std::str; use syntax::attr; pub use rustc_codegen_utils::link::{find_crate_name, filename_for_input, default_output_for_target, - invalid_output_for_target, out_filename, check_file_is_writeable}; + invalid_output_for_target, out_filename, check_file_is_writeable, + filename_for_metadata}; // The third parameter is for env vars, used on windows to set up the // path for MSVC to find its DLLs, and gcc to find its bundled @@ -218,15 +219,6 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool { false } -fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilenames) -> PathBuf { - let out_filename = outputs.single_output_file.clone() - .unwrap_or(outputs - .out_directory - .join(&format!("lib{}{}.rmeta", crate_name, sess.opts.cg.extra_filename))); - check_file_is_writeable(&out_filename, sess); - out_filename -} - pub(crate) fn each_linked_rlib(sess: &Session, info: &CrateInfo, f: &mut dyn FnMut(CrateNum, &Path)) -> Result<(), String> { diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index 75f1d614ae72f..3d47f91a6239a 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -97,6 +97,19 @@ pub fn find_crate_name(sess: Option<&Session>, "rust_out".to_string() } +pub fn filename_for_metadata(sess: &Session, + crate_name: &str, + outputs: &OutputFilenames) -> PathBuf { + let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename); + + let out_filename = outputs.single_output_file.clone() + .unwrap_or(outputs.out_directory.join(&format!("lib{}.rmeta", libname))); + + check_file_is_writeable(&out_filename, sess); + + out_filename +} + pub fn filename_for_input(sess: &Session, crate_type: config::CrateType, crate_name: &str, From d45f87701ce9926ecd4f4e01c4a60443227de62d Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sat, 22 Sep 2018 23:19:39 +0200 Subject: [PATCH 3/7] Emit only necessary compilation options in save-analysis This is `command`, `directory` and `output` file. --- src/Cargo.lock | 1 + src/librustc_save_analysis/Cargo.toml | 1 + src/librustc_save_analysis/dump_visitor.rs | 41 ++++++++++------------ src/librustc_save_analysis/lib.rs | 38 +++++++++++++------- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 9a383a381d5fb..5a44b696a03e1 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2373,6 +2373,7 @@ dependencies = [ "rls-span 0.4.0 (registry+/~https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-serialize 0.3.24 (registry+/~https://github.com/rust-lang/crates.io-index)", + "rustc_codegen_utils 0.0.0", "rustc_data_structures 0.0.0", "rustc_target 0.0.0", "rustc_typeck 0.0.0", diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index b6dd9ec8d3fd9..e47f89c64ff07 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -12,6 +12,7 @@ crate-type = ["dylib"] log = "0.4" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_target = { path = "../librustc_target" } rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index b044210c092e4..c87f52f8bd158 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -28,8 +28,9 @@ use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashSet; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::env; +use std::fs; use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID}; use syntax::parse::token; @@ -172,11 +173,20 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.dumper.crate_prelude(data); } - pub fn dump_compilation_options(&mut self) { - // Apply possible `remap-path-prefix` remapping to the raw invocation - let invocation = { + pub fn dump_compilation_options(&mut self, crate_name: &str) { + // Apply possible `remap-path-prefix` remapping to the raw command + let command = { + let mapping = self.tcx.sess.source_map().path_mapping(); + let remap_arg = |x: &str| -> String { + match fs::canonicalize(x) { + Ok(path) => mapping.map_prefix(path).0.to_str().unwrap().to_owned(), + Err(_) => x.to_owned(), // Probably not a path, ignore + } + }; + let remap_arg_indices = { let mut indices = FxHashSet(); + // rustc args are guaranteed to be valid UTF-8 (checked early) for (i, e) in env::args().enumerate() { if e.starts_with("--remap-path-prefix=") { indices.insert(i); @@ -188,19 +198,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { indices }; - let args_without_remap_args = env::args() + let args = env::args() .enumerate() .filter(|(i, _)| !remap_arg_indices.contains(i)) - .map(|(_, e)| e); - - let mapping = self.tcx.sess.source_map().path_mapping(); - let remap_arg = |x: &str| -> String { - mapping.map_prefix(PathBuf::from(x)).0.to_str().unwrap().to_owned() - }; - - // Naively attempt to remap every argument - let args = args_without_remap_args - .map(|elem| { + .map(|(_, elem)| { let mut arg = elem.splitn(2, '='); match (arg.next(), arg.next()) { // Apart from `--remap...`, in `a=b` args usually only @@ -214,14 +215,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { args.as_slice().join(" ") }; - let opts = &self.tcx.sess.opts; - let data = CompilationOptions { - invocation, - crate_name: opts.crate_name.clone(), - test: opts.test, - sysroot: opts.maybe_sysroot.clone(), - target_triple: opts.target_triple.to_string(), + directory: self.tcx.sess.working_dir.0.clone(), + command, + output: self.save_ctxt.compilation_output(crate_name), }; self.dumper.compilation_opts(data); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 06496db527452..702edb7075713 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -23,6 +23,7 @@ extern crate rustc; #[macro_use] extern crate log; extern crate rustc_data_structures; +extern crate rustc_codegen_utils; extern crate rustc_serialize; extern crate rustc_target; extern crate rustc_typeck; @@ -45,9 +46,10 @@ use rustc::hir::def::Def as HirDef; use rustc::hir::Node; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::cstore::ExternCrate; -use rustc::session::config::CrateType; +use rustc::session::config::{CrateType, OutputType}; use rustc::ty::{self, TyCtxt}; use rustc_typeck::hir_ty_to_ty; +use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; use std::cell::Cell; use std::default::Default; @@ -111,6 +113,24 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } + // Returns path to the compilation output (e.g. libfoo-12345678.rmeta) + pub fn compilation_output(&self, crate_name: &str) -> PathBuf { + let sess = &self.tcx.sess; + // Save-analysis is emitted per whole session, not per each crate type + let crate_type = sess.crate_types.borrow()[0]; + let outputs = &*self.tcx.output_filenames(LOCAL_CRATE); + + if outputs.outputs.contains_key(&OutputType::Metadata) { + filename_for_metadata(sess, crate_name, outputs) + } else if outputs.outputs.should_codegen() { + out_filename(sess, crate_type, outputs, crate_name) + } else { + // Otherwise it's only a DepInfo, in which case we return early and + // not even reach the analysis stage. + unreachable!() + } + } + // List external crates used by the current crate. pub fn get_external_crates(&self) -> Vec { let mut result = Vec::with_capacity(self.tcx.crates().len()); @@ -139,15 +159,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { disambiguator: self.tcx.crate_disambiguator(n).to_fingerprint().as_value(), }, source: CrateSource { - dylib: src.dylib.as_ref().map(|(ref path, _)| - map_prefix(path).display().to_string() - ), - rlib: src.rlib.as_ref().map(|(ref path, _)| - map_prefix(path).display().to_string() - ), - rmeta: src.rmeta.as_ref().map(|(ref path, _)| - map_prefix(path).display().to_string() - ), + dylib: src.dylib.as_ref().map(|(path, _)| map_prefix(path)), + rlib: src.rlib.as_ref().map(|(path, _)| map_prefix(path)), + rmeta: src.rmeta.as_ref().map(|(path, _)| map_prefix(path)), } }); } @@ -1103,7 +1117,7 @@ impl<'a> SaveHandler for DumpHandler<'a> { let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); - visitor.dump_compilation_options(); + visitor.dump_compilation_options(cratename); visit::walk_crate(&mut visitor, krate); } } @@ -1129,7 +1143,7 @@ impl<'b> SaveHandler for CallbackHandler<'b> { let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); - visitor.dump_compilation_options(); + visitor.dump_compilation_options(cratename); visit::walk_crate(&mut visitor, krate); } } From 1e593be5936a3b42a2b2680b3d04082e89fa4158 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 24 Sep 2018 16:28:53 +0200 Subject: [PATCH 4/7] Remap only source files in the command line --- src/librustc_driver/lib.rs | 1 + src/librustc_save_analysis/dump_visitor.rs | 47 ++++++++++------------ src/librustc_save_analysis/lib.rs | 23 +++++------ 3 files changed, 32 insertions(+), 39 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f8ca154d168ba..27176a821b4af 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -980,6 +980,7 @@ pub fn enable_save_analysis(control: &mut CompileController) { state.expanded_crate.unwrap(), state.analysis.unwrap(), state.crate_name.unwrap(), + state.input, None, DumpHandler::new(state.out_dir, state.crate_name.unwrap())) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index c87f52f8bd158..278880b841d97 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -25,12 +25,12 @@ use rustc::hir::def::Def as HirDef; use rustc::hir::def_id::DefId; +use rustc::session::config::Input; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use std::path::Path; use std::env; -use std::fs; use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID}; use syntax::parse::token; @@ -173,20 +173,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.dumper.crate_prelude(data); } - pub fn dump_compilation_options(&mut self, crate_name: &str) { - // Apply possible `remap-path-prefix` remapping to the raw command - let command = { - let mapping = self.tcx.sess.source_map().path_mapping(); - let remap_arg = |x: &str| -> String { - match fs::canonicalize(x) { - Ok(path) => mapping.map_prefix(path).0.to_str().unwrap().to_owned(), - Err(_) => x.to_owned(), // Probably not a path, ignore - } - }; - + pub fn dump_compilation_options(&mut self, input: &Input, crate_name: &str) { + // Apply possible `remap-path-prefix` remapping to the input source file + // (and don't include remapping args anymore) + let (program, arguments) = { let remap_arg_indices = { let mut indices = FxHashSet(); - // rustc args are guaranteed to be valid UTF-8 (checked early) + // Args are guaranteed to be valid UTF-8 (checked early) for (i, e) in env::args().enumerate() { if e.starts_with("--remap-path-prefix=") { indices.insert(i); @@ -198,26 +191,30 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { indices }; - let args = env::args() + let mut args = env::args() .enumerate() .filter(|(i, _)| !remap_arg_indices.contains(i)) - .map(|(_, elem)| { - let mut arg = elem.splitn(2, '='); - match (arg.next(), arg.next()) { - // Apart from `--remap...`, in `a=b` args usually only - // `b` is a path (e.g. `--extern some_crate=/path/to..`) - (Some(a), Some(b)) => format!("{}={}", a, remap_arg(b)), - (Some(a), _) => remap_arg(a), - _ => unreachable!(), + .map(|(_, arg)| { + match input { + Input::File(ref path) if path == Path::new(&arg) => { + let mapped = &self.tcx.sess.local_crate_source_file; + mapped + .as_ref() + .unwrap() + .to_string_lossy() + .into() + }, + _ => arg, } - }).collect::>(); + }); - args.as_slice().join(" ") + (args.next().unwrap(), args.collect()) }; let data = CompilationOptions { directory: self.tcx.sess.working_dir.0.clone(), - command, + program, + arguments, output: self.save_ctxt.compilation_output(crate_name), }; diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 702edb7075713..e092fc786dde9 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -46,7 +46,7 @@ use rustc::hir::def::Def as HirDef; use rustc::hir::Node; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::cstore::ExternCrate; -use rustc::session::config::{CrateType, OutputType}; +use rustc::session::config::{CrateType, Input, OutputType}; use rustc::ty::{self, TyCtxt}; use rustc_typeck::hir_ty_to_ty; use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; @@ -74,7 +74,7 @@ use span_utils::SpanUtils; use rls_data::config::Config; use rls_data::{ - CrateSource, Def, DefKind, ExternalCrateData, GlobalCrateId, Impl, ImplKind, MacroRef, Ref, + Def, DefKind, ExternalCrateData, GlobalCrateId, Impl, ImplKind, MacroRef, Ref, RefKind, Relation, RelationKind, SpanData, }; @@ -143,11 +143,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { continue; } }; - let src = self.tcx.used_crate_source(n); let lo_loc = self.span_utils.sess.source_map().lookup_char_pos(span.lo()); - let map_prefix = |path: &PathBuf| -> PathBuf { - self.tcx.sess.source_map().path_mapping().map_prefix(path.to_owned()).0 - }; result.push(ExternalCrateData { // FIXME: change file_name field to PathBuf in rls-data @@ -158,11 +154,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: self.tcx.crate_name(n).to_string(), disambiguator: self.tcx.crate_disambiguator(n).to_fingerprint().as_value(), }, - source: CrateSource { - dylib: src.dylib.as_ref().map(|(path, _)| map_prefix(path)), - rlib: src.rlib.as_ref().map(|(path, _)| map_prefix(path)), - rmeta: src.rmeta.as_ref().map(|(path, _)| map_prefix(path)), - } }); } @@ -1046,6 +1037,7 @@ pub trait SaveHandler { save_ctxt: SaveContext<'l, 'tcx>, krate: &ast::Crate, cratename: &str, + input: &'l Input, ); } @@ -1111,13 +1103,14 @@ impl<'a> SaveHandler for DumpHandler<'a> { save_ctxt: SaveContext<'l, 'tcx>, krate: &ast::Crate, cratename: &str, + input: &'l Input, ) { let output = &mut self.output_file(&save_ctxt); let mut dumper = JsonDumper::new(output, save_ctxt.config.clone()); let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); - visitor.dump_compilation_options(cratename); + visitor.dump_compilation_options(input, cratename); visit::walk_crate(&mut visitor, krate); } } @@ -1133,6 +1126,7 @@ impl<'b> SaveHandler for CallbackHandler<'b> { save_ctxt: SaveContext<'l, 'tcx>, krate: &ast::Crate, cratename: &str, + input: &'l Input, ) { // We're using the JsonDumper here because it has the format of the // save-analysis results that we will pass to the callback. IOW, we are @@ -1143,7 +1137,7 @@ impl<'b> SaveHandler for CallbackHandler<'b> { let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); - visitor.dump_compilation_options(cratename); + visitor.dump_compilation_options(input, cratename); visit::walk_crate(&mut visitor, krate); } } @@ -1153,6 +1147,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( krate: &ast::Crate, analysis: &'l ty::CrateAnalysis, cratename: &str, + input: &'l Input, config: Option, mut handler: H, ) { @@ -1170,7 +1165,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( impl_counter: Cell::new(0), }; - handler.save(save_ctxt, krate, cratename) + handler.save(save_ctxt, krate, cratename, input) }) } From 24123ddea90411851fa69a33369f3e4130ccf831 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 24 Sep 2018 16:38:54 +0200 Subject: [PATCH 5/7] Minimize final diff --- src/librustc_save_analysis/dump_visitor.rs | 6 ++---- src/librustc_save_analysis/json_dumper.rs | 6 ++---- src/librustc_save_analysis/lib.rs | 8 +++----- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 278880b841d97..ab8f468672944 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -51,10 +51,8 @@ use json_dumper::{Access, DumpOutput, JsonDumper}; use span_utils::SpanUtils; use sig; -use rls_data::{ - CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref, - RefKind, Relation, RelationKind, SpanData, -}; +use rls_data::{CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import, + ImportKind, Ref, RefKind, Relation, RelationKind, SpanData}; macro_rules! down_cast_data { ($id:ident, $kind:ident, $sp:expr) => { diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index bfd3a01ca4221..e14ac73ee1020 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -13,10 +13,8 @@ use std::io::Write; use rustc_serialize::json::as_json; use rls_data::config::Config; -use rls_data::{ - self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import, MacroRef, - Ref, RefKind, Relation, -}; +use rls_data::{self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import, + MacroRef, Ref, RefKind, Relation}; use rls_span::{Column, Row}; #[derive(Debug)] diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index e092fc786dde9..f6045c7b2d2df 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -72,11 +72,10 @@ use json_dumper::JsonDumper; use dump_visitor::DumpVisitor; use span_utils::SpanUtils; +use rls_data::{Def, DefKind, ExternalCrateData, GlobalCrateId, MacroRef, Ref, RefKind, Relation, + RelationKind, SpanData, Impl, ImplKind}; use rls_data::config::Config; -use rls_data::{ - Def, DefKind, ExternalCrateData, GlobalCrateId, Impl, ImplKind, MacroRef, Ref, - RefKind, Relation, RelationKind, SpanData, -}; + pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, @@ -144,7 +143,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } }; let lo_loc = self.span_utils.sess.source_map().lookup_char_pos(span.lo()); - result.push(ExternalCrateData { // FIXME: change file_name field to PathBuf in rls-data // /~https://github.com/nrc/rls-data/issues/7 From 3ceae8db47ec82774df29c45b2d89d379bfd1676 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 24 Sep 2018 16:53:49 +0200 Subject: [PATCH 6/7] Also remap absolute source names in save-analysis --- src/librustc_save_analysis/span_utils.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index 56728aed76921..47677a751712e 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -37,11 +37,18 @@ impl<'a> SpanUtils<'a> { pub fn make_filename_string(&self, file: &SourceFile) -> String { match &file.name { - FileName::Real(path) if !path.is_absolute() && !file.name_was_remapped => { - self.sess.working_dir.0 - .join(&path) - .display() - .to_string() + FileName::Real(path) if !file.name_was_remapped => { + if path.is_absolute() { + self.sess.source_map().path_mapping() + .map_prefix(path.clone()).0 + .display() + .to_string() + } else { + self.sess.working_dir.0 + .join(&path) + .display() + .to_string() + } }, // If the file name is already remapped, we assume the user // configured it the way they wanted to, so use that directly From 58a86213abe70ffda0b2edba475d96b3aed95844 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 25 Sep 2018 08:32:49 +0200 Subject: [PATCH 7/7] Use rls-data 0.18.1 --- src/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Cargo.toml b/src/Cargo.toml index b4ef8754b81b1..e8c44ea57c2e9 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -57,7 +57,6 @@ cargo = { path = "tools/cargo" } # that we're shipping as well (to ensure that the rustfmt in RLS and the # `rustfmt` executable are the same exact version). rustfmt-nightly = { path = "tools/rustfmt" } -rls-data = { git = "/~https://github.com/Xanewok/rls-data", branch = "compilation-options" } # See comments in `tools/rustc-workspace-hack/README.md` for what's going on # here