mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Add support for loading rustc private crates
This commit is contained in:
parent
5c06e820fa
commit
8716087919
6 changed files with 3606 additions and 77 deletions
|
@ -64,6 +64,9 @@ pub struct CargoConfig {
|
||||||
|
|
||||||
/// rustc target
|
/// rustc target
|
||||||
pub target: Option<String>,
|
pub target: Option<String>,
|
||||||
|
|
||||||
|
/// rustc private crate source
|
||||||
|
pub rustc_source: Option<AbsPathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Package = Idx<PackageData>;
|
pub type Package = Idx<PackageData>;
|
||||||
|
|
|
@ -9,6 +9,7 @@ use std::{
|
||||||
fmt,
|
fmt,
|
||||||
fs::{self, read_dir, ReadDir},
|
fs::{self, read_dir, ReadDir},
|
||||||
io,
|
io,
|
||||||
|
path::Component,
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ pub use proc_macro_api::ProcMacroClient;
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
pub enum ProjectWorkspace {
|
pub enum ProjectWorkspace {
|
||||||
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
|
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
|
||||||
Cargo { cargo: CargoWorkspace, sysroot: Sysroot },
|
Cargo { cargo: CargoWorkspace, sysroot: Sysroot, rustc: Option<CargoWorkspace> },
|
||||||
/// Project workspace was manually specified using a `rust-project.json` file.
|
/// Project workspace was manually specified using a `rust-project.json` file.
|
||||||
Json { project: ProjectJson, sysroot: Option<Sysroot> },
|
Json { project: ProjectJson, sysroot: Option<Sysroot> },
|
||||||
}
|
}
|
||||||
|
@ -39,10 +40,14 @@ pub enum ProjectWorkspace {
|
||||||
impl fmt::Debug for ProjectWorkspace {
|
impl fmt::Debug for ProjectWorkspace {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => f
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc } => f
|
||||||
.debug_struct("Cargo")
|
.debug_struct("Cargo")
|
||||||
.field("n_packages", &cargo.packages().len())
|
.field("n_packages", &cargo.packages().len())
|
||||||
.field("n_sysroot_crates", &sysroot.crates().len())
|
.field("n_sysroot_crates", &sysroot.crates().len())
|
||||||
|
.field(
|
||||||
|
"n_rustc_compiler_crates",
|
||||||
|
&rustc.as_ref().map(|rc| rc.packages().len()).unwrap_or(0),
|
||||||
|
)
|
||||||
.finish(),
|
.finish(),
|
||||||
ProjectWorkspace::Json { project, sysroot } => {
|
ProjectWorkspace::Json { project, sysroot } => {
|
||||||
let mut debug_struct = f.debug_struct("Json");
|
let mut debug_struct = f.debug_struct("Json");
|
||||||
|
@ -200,7 +205,19 @@ impl ProjectWorkspace {
|
||||||
} else {
|
} else {
|
||||||
Sysroot::default()
|
Sysroot::default()
|
||||||
};
|
};
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot }
|
|
||||||
|
let rustc = if let Some(rustc_dir) = &cargo_config.rustc_source {
|
||||||
|
Some(
|
||||||
|
CargoWorkspace::from_cargo_metadata(&rustc_dir, cargo_config)
|
||||||
|
.with_context(|| {
|
||||||
|
format!("Failed to read Cargo metadata for Rust sources")
|
||||||
|
})?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,31 +255,43 @@ impl ProjectWorkspace {
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc } => {
|
||||||
.packages()
|
let roots = cargo
|
||||||
.map(|pkg| {
|
.packages()
|
||||||
let is_member = cargo[pkg].is_member;
|
.map(|pkg| {
|
||||||
let pkg_root = cargo[pkg].root().to_path_buf();
|
let is_member = cargo[pkg].is_member;
|
||||||
|
let pkg_root = cargo[pkg].root().to_path_buf();
|
||||||
|
|
||||||
let mut include = vec![pkg_root.clone()];
|
let mut include = vec![pkg_root.clone()];
|
||||||
include.extend(cargo[pkg].out_dir.clone());
|
include.extend(cargo[pkg].out_dir.clone());
|
||||||
|
|
||||||
let mut exclude = vec![pkg_root.join(".git")];
|
let mut exclude = vec![pkg_root.join(".git")];
|
||||||
if is_member {
|
if is_member {
|
||||||
exclude.push(pkg_root.join("target"));
|
exclude.push(pkg_root.join("target"));
|
||||||
} else {
|
} else {
|
||||||
exclude.push(pkg_root.join("tests"));
|
exclude.push(pkg_root.join("tests"));
|
||||||
exclude.push(pkg_root.join("examples"));
|
exclude.push(pkg_root.join("examples"));
|
||||||
exclude.push(pkg_root.join("benches"));
|
exclude.push(pkg_root.join("benches"));
|
||||||
}
|
}
|
||||||
PackageRoot { is_member, include, exclude }
|
PackageRoot { is_member, include, exclude }
|
||||||
})
|
})
|
||||||
.chain(sysroot.crates().map(|krate| PackageRoot {
|
.chain(sysroot.crates().map(|krate| PackageRoot {
|
||||||
is_member: false,
|
is_member: false,
|
||||||
include: vec![sysroot[krate].root_dir().to_path_buf()],
|
include: vec![sysroot[krate].root_dir().to_path_buf()],
|
||||||
exclude: Vec::new(),
|
exclude: Vec::new(),
|
||||||
}))
|
}));
|
||||||
.collect(),
|
if let Some(rustc_packages) = rustc {
|
||||||
|
roots
|
||||||
|
.chain(rustc_packages.packages().map(|krate| PackageRoot {
|
||||||
|
is_member: false,
|
||||||
|
include: vec![rustc_packages[krate].root().to_path_buf()],
|
||||||
|
exclude: Vec::new(),
|
||||||
|
}))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
roots.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +302,7 @@ impl ProjectWorkspace {
|
||||||
.filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref())
|
.filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref())
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo
|
ProjectWorkspace::Cargo { cargo, sysroot: _sysroot, rustc: _rustc_crates } => cargo
|
||||||
.packages()
|
.packages()
|
||||||
.filter_map(|pkg| cargo[pkg].proc_macro_dylib_path.as_ref())
|
.filter_map(|pkg| cargo[pkg].proc_macro_dylib_path.as_ref())
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -284,8 +313,10 @@ impl ProjectWorkspace {
|
||||||
pub fn n_packages(&self) -> usize {
|
pub fn n_packages(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Json { project, .. } => project.n_crates(),
|
ProjectWorkspace::Json { project, .. } => project.n_crates(),
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => {
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc } => {
|
||||||
cargo.packages().len() + sysroot.crates().len()
|
let rustc_package_len = rustc.as_ref().map(|rc| rc.packages().len()).unwrap_or(0);
|
||||||
|
dbg!(rustc_package_len);
|
||||||
|
cargo.packages().len() + sysroot.crates().len() + rustc_package_len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,7 +396,7 @@ impl ProjectWorkspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => {
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc } => {
|
||||||
let (public_deps, libproc_macro) =
|
let (public_deps, libproc_macro) =
|
||||||
sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load);
|
sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load);
|
||||||
|
|
||||||
|
@ -373,50 +404,88 @@ impl ProjectWorkspace {
|
||||||
cfg_options.extend(get_rustc_cfg_options(target));
|
cfg_options.extend(get_rustc_cfg_options(target));
|
||||||
|
|
||||||
let mut pkg_to_lib_crate = FxHashMap::default();
|
let mut pkg_to_lib_crate = FxHashMap::default();
|
||||||
let mut pkg_crates = FxHashMap::default();
|
|
||||||
|
|
||||||
// Add test cfg for non-sysroot crates
|
// Add test cfg for non-sysroot crates
|
||||||
cfg_options.insert_atom("test".into());
|
cfg_options.insert_atom("test".into());
|
||||||
cfg_options.insert_atom("debug_assertions".into());
|
cfg_options.insert_atom("debug_assertions".into());
|
||||||
|
|
||||||
|
let mut rustc_pkg_crates = FxHashMap::default();
|
||||||
|
|
||||||
|
// Add crate roots for rustc_private libs if a path to source is provided
|
||||||
|
if let Some(rustc_workspace) = rustc {
|
||||||
|
for pkg in rustc_workspace.packages() {
|
||||||
|
for &tgt in rustc_workspace[pkg].targets.iter() {
|
||||||
|
if rustc_workspace[tgt].kind != TargetKind::Lib {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Exclude alloc / core / std
|
||||||
|
if rustc_workspace[tgt]
|
||||||
|
.root
|
||||||
|
.components()
|
||||||
|
.any(|c| c == Component::Normal("library".as_ref()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(crate_id) = add_target_crate_root(
|
||||||
|
&mut crate_graph,
|
||||||
|
&rustc_workspace[pkg],
|
||||||
|
&rustc_workspace[tgt],
|
||||||
|
&cfg_options,
|
||||||
|
proc_macro_client,
|
||||||
|
load,
|
||||||
|
) {
|
||||||
|
pkg_to_lib_crate.insert(pkg, crate_id);
|
||||||
|
// Add dependencies on the core / std / alloc for rustc
|
||||||
|
for (name, krate) in public_deps.iter() {
|
||||||
|
if let Err(_) =
|
||||||
|
crate_graph.add_dep(crate_id, name.clone(), *krate)
|
||||||
|
{
|
||||||
|
log::error!(
|
||||||
|
"cyclic dependency on {} for {}",
|
||||||
|
name,
|
||||||
|
&cargo[pkg].name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now add a dep edge from all targets of upstream to the lib
|
||||||
|
// target of downstream.
|
||||||
|
for pkg in rustc_workspace.packages() {
|
||||||
|
for dep in rustc_workspace[pkg].dependencies.iter() {
|
||||||
|
let name = CrateName::new(&dep.name).unwrap();
|
||||||
|
if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
|
||||||
|
for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() {
|
||||||
|
if let Err(_) = crate_graph.add_dep(from, name.clone(), to) {
|
||||||
|
log::error!(
|
||||||
|
"cyclic dependency {} -> {}",
|
||||||
|
&rustc_workspace[pkg].name,
|
||||||
|
&rustc_workspace[dep.pkg].name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut pkg_crates = FxHashMap::default();
|
||||||
|
|
||||||
// Next, create crates for each package, target pair
|
// Next, create crates for each package, target pair
|
||||||
for pkg in cargo.packages() {
|
for pkg in cargo.packages() {
|
||||||
let mut lib_tgt = None;
|
let mut lib_tgt = None;
|
||||||
for &tgt in cargo[pkg].targets.iter() {
|
for &tgt in cargo[pkg].targets.iter() {
|
||||||
let root = cargo[tgt].root.as_path();
|
if let Some(crate_id) = add_target_crate_root(
|
||||||
if let Some(file_id) = load(root) {
|
&mut crate_graph,
|
||||||
let edition = cargo[pkg].edition;
|
&cargo[pkg],
|
||||||
let cfg_options = {
|
&cargo[tgt],
|
||||||
let mut opts = cfg_options.clone();
|
&cfg_options,
|
||||||
for feature in cargo[pkg].features.iter() {
|
proc_macro_client,
|
||||||
opts.insert_key_value("feature".into(), feature.into());
|
load,
|
||||||
}
|
) {
|
||||||
opts.extend(cargo[pkg].cfgs.iter().cloned());
|
|
||||||
opts
|
|
||||||
};
|
|
||||||
let mut env = Env::default();
|
|
||||||
if let Some(out_dir) = &cargo[pkg].out_dir {
|
|
||||||
// NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!()
|
|
||||||
if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) {
|
|
||||||
env.set("OUT_DIR", out_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let proc_macro = cargo[pkg]
|
|
||||||
.proc_macro_dylib_path
|
|
||||||
.as_ref()
|
|
||||||
.map(|it| proc_macro_client.by_dylib_path(&it))
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let display_name =
|
|
||||||
CrateDisplayName::from_canonical_name(cargo[pkg].name.clone());
|
|
||||||
let crate_id = crate_graph.add_crate_root(
|
|
||||||
file_id,
|
|
||||||
edition,
|
|
||||||
Some(display_name),
|
|
||||||
cfg_options,
|
|
||||||
env,
|
|
||||||
proc_macro.clone(),
|
|
||||||
);
|
|
||||||
if cargo[tgt].kind == TargetKind::Lib {
|
if cargo[tgt].kind == TargetKind::Lib {
|
||||||
lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
|
lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
|
||||||
pkg_to_lib_crate.insert(pkg, crate_id);
|
pkg_to_lib_crate.insert(pkg, crate_id);
|
||||||
|
@ -466,6 +535,30 @@ impl ProjectWorkspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have access to the rust sources, create dependencies onto rustc_private libraries from all targets
|
||||||
|
// that are members of the current workspace
|
||||||
|
if let Some(rustc_workspace) = rustc {
|
||||||
|
for dep in rustc_workspace.packages() {
|
||||||
|
let name = CrateName::normalize_dashes(&rustc_workspace[dep].name);
|
||||||
|
|
||||||
|
if let Some(&from) = pkg_to_lib_crate.get(&dep) {
|
||||||
|
for pkg in cargo.packages() {
|
||||||
|
if !cargo[pkg].is_member {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for &to in pkg_crates.get(&pkg).into_iter().flatten() {
|
||||||
|
if let Err(_) = crate_graph.add_dep(to, name.clone(), from) {
|
||||||
|
log::error!(
|
||||||
|
"cyclic dependency22 {} -> {}",
|
||||||
|
&cargo[pkg].name,
|
||||||
|
&rustc_workspace[dep].name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Now add a dep edge from all targets of upstream to the lib
|
// Now add a dep edge from all targets of upstream to the lib
|
||||||
// target of downstream.
|
// target of downstream.
|
||||||
for pkg in cargo.packages() {
|
for pkg in cargo.packages() {
|
||||||
|
@ -537,6 +630,52 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> {
|
||||||
Ok(stdout.trim().to_string())
|
Ok(stdout.trim().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_target_crate_root(
|
||||||
|
crate_graph: &mut CrateGraph,
|
||||||
|
pkg: &cargo_workspace::PackageData,
|
||||||
|
tgt: &cargo_workspace::TargetData,
|
||||||
|
cfg_options: &CfgOptions,
|
||||||
|
proc_macro_client: &ProcMacroClient,
|
||||||
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
|
) -> Option<CrateId> {
|
||||||
|
let root = tgt.root.as_path();
|
||||||
|
if let Some(file_id) = load(root) {
|
||||||
|
let edition = pkg.edition;
|
||||||
|
let cfg_options = {
|
||||||
|
let mut opts = cfg_options.clone();
|
||||||
|
for feature in pkg.features.iter() {
|
||||||
|
opts.insert_key_value("feature".into(), feature.into());
|
||||||
|
}
|
||||||
|
opts.extend(pkg.cfgs.iter().cloned());
|
||||||
|
opts
|
||||||
|
};
|
||||||
|
let mut env = Env::default();
|
||||||
|
if let Some(out_dir) = &pkg.out_dir {
|
||||||
|
// NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!()
|
||||||
|
if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) {
|
||||||
|
env.set("OUT_DIR", out_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let proc_macro = pkg
|
||||||
|
.proc_macro_dylib_path
|
||||||
|
.as_ref()
|
||||||
|
.map(|it| proc_macro_client.by_dylib_path(&it))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone());
|
||||||
|
let crate_id = crate_graph.add_crate_root(
|
||||||
|
file_id,
|
||||||
|
edition,
|
||||||
|
Some(display_name),
|
||||||
|
cfg_options,
|
||||||
|
env,
|
||||||
|
proc_macro.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Some(crate_id);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
fn sysroot_to_crate_graph(
|
fn sysroot_to_crate_graph(
|
||||||
crate_graph: &mut CrateGraph,
|
crate_graph: &mut CrateGraph,
|
||||||
sysroot: &Sysroot,
|
sysroot: &Sysroot,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//! configure the server itself, feature flags are passed into analysis, and
|
//! configure the server itself, feature flags are passed into analysis, and
|
||||||
//! tweak things like automatic insertion of `()` in completions.
|
//! tweak things like automatic insertion of `()` in completions.
|
||||||
|
|
||||||
use std::{ffi::OsString, path::PathBuf};
|
use std::{convert::TryFrom, ffi::OsString, path::PathBuf};
|
||||||
|
|
||||||
use flycheck::FlycheckConfig;
|
use flycheck::FlycheckConfig;
|
||||||
use hir::PrefixKind;
|
use hir::PrefixKind;
|
||||||
|
@ -227,12 +227,25 @@ impl Config {
|
||||||
self.notifications =
|
self.notifications =
|
||||||
NotificationsConfig { cargo_toml_not_found: data.notifications_cargoTomlNotFound };
|
NotificationsConfig { cargo_toml_not_found: data.notifications_cargoTomlNotFound };
|
||||||
self.cargo_autoreload = data.cargo_autoreload;
|
self.cargo_autoreload = data.cargo_autoreload;
|
||||||
|
|
||||||
|
let rustc_source = if let Some(rustc_source) = data.rustcSource {
|
||||||
|
let rustpath: PathBuf = rustc_source.into();
|
||||||
|
AbsPathBuf::try_from(rustpath)
|
||||||
|
.map_err(|_| {
|
||||||
|
log::error!("rustc source directory must be an absolute path");
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
self.cargo = CargoConfig {
|
self.cargo = CargoConfig {
|
||||||
no_default_features: data.cargo_noDefaultFeatures,
|
no_default_features: data.cargo_noDefaultFeatures,
|
||||||
all_features: data.cargo_allFeatures,
|
all_features: data.cargo_allFeatures,
|
||||||
features: data.cargo_features.clone(),
|
features: data.cargo_features.clone(),
|
||||||
load_out_dirs_from_check: data.cargo_loadOutDirsFromCheck,
|
load_out_dirs_from_check: data.cargo_loadOutDirsFromCheck,
|
||||||
target: data.cargo_target.clone(),
|
target: data.cargo_target.clone(),
|
||||||
|
rustc_source: rustc_source,
|
||||||
};
|
};
|
||||||
self.runnables = RunnablesConfig {
|
self.runnables = RunnablesConfig {
|
||||||
override_cargo: data.runnables_overrideCargo,
|
override_cargo: data.runnables_overrideCargo,
|
||||||
|
@ -532,5 +545,6 @@ config_data! {
|
||||||
rustfmt_overrideCommand: Option<Vec<String>> = None,
|
rustfmt_overrideCommand: Option<Vec<String>> = None,
|
||||||
|
|
||||||
withSysroot: bool = true,
|
withSysroot: bool = true,
|
||||||
|
rustcSource : Option<String> = None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,9 @@ impl GlobalState {
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(id, w)| match w {
|
.filter_map(|(id, w)| match w {
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot: _ } => Some((id, cargo.workspace_root())),
|
ProjectWorkspace::Cargo { cargo, sysroot: _, rustc: _ } => {
|
||||||
|
Some((id, cargo.workspace_root()))
|
||||||
|
}
|
||||||
ProjectWorkspace::Json { project, .. } => {
|
ProjectWorkspace::Json { project, .. } => {
|
||||||
// Enable flychecks for json projects if a custom flycheck command was supplied
|
// Enable flychecks for json projects if a custom flycheck command was supplied
|
||||||
// in the workspace configuration.
|
// in the workspace configuration.
|
||||||
|
|
3385
editors/code/package-lock.json
generated
3385
editors/code/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -687,6 +687,12 @@
|
||||||
},
|
},
|
||||||
"default": [],
|
"default": [],
|
||||||
"description": "Additional arguments to be passed to cargo for runnables such as tests or binaries.\nFor example, it may be '--release'"
|
"description": "Additional arguments to be passed to cargo for runnables such as tests or binaries.\nFor example, it may be '--release'"
|
||||||
|
},
|
||||||
|
"rust-analyzer.rustcSource" : {
|
||||||
|
"type": [ "null", "string" ],
|
||||||
|
"default": null,
|
||||||
|
"description": "Path to the rust compiler sources, for usage in rustc_private projects."
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue