diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 7d5d12e6300..5bdc427f739 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs @@ -156,7 +156,7 @@ impl ChangeFixture { let crate_root = default_crate_root.unwrap(); crate_graph.add_crate_root( crate_root, - Edition::Edition2018, + Edition::CURRENT, Some(CrateName::new("test").unwrap().into()), default_cfg.clone(), default_cfg, @@ -227,10 +227,7 @@ impl From for FileMeta { krate: f.krate, deps: f.deps, cfg, - edition: f - .edition - .as_ref() - .map_or(Edition::Edition2018, |v| Edition::from_str(v).unwrap()), + edition: f.edition.as_ref().map_or(Edition::CURRENT, |v| Edition::from_str(v).unwrap()), env: f.env.into_iter().collect(), introduce_new_source_root: f.introduce_new_source_root, } diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs index 0b80e9e47d7..5f746ec5a5e 100644 --- a/crates/base_db/src/input.rs +++ b/crates/base_db/src/input.rs @@ -195,6 +195,10 @@ pub enum Edition { Edition2021, } +impl Edition { + pub const CURRENT: Edition = Edition::Edition2018; +} + #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct Env { entries: FxHashMap, diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index f8c811c8ed6..525f052ede6 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -217,7 +217,7 @@ impl Analysis { cfg_options.insert_atom("test".into()); crate_graph.add_crate_root( file_id, - Edition::Edition2018, + Edition::CURRENT, None, cfg_options.clone(), cfg_options, diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index 5f65b7bbe6e..4ee720a53ab 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs @@ -228,11 +228,11 @@ struct PackageMetadata { } impl CargoWorkspace { - pub fn from_cargo_metadata( + pub fn fetch_metadata( cargo_toml: &AbsPath, config: &CargoConfig, progress: &dyn Fn(String), - ) -> Result { + ) -> Result { let mut meta = MetadataCommand::new(); meta.cargo_path(toolchain::cargo()); meta.manifest_path(cargo_toml.to_path_buf()); @@ -262,10 +262,12 @@ impl CargoWorkspace { meta.other_options(vec![String::from("--filter-platform"), target]); } - // FIXME: Currently MetadataCommand is not based on parse_stream, - // So we just report it as a whole + // FIXME: Fetching metadata is a slow process, as it might require + // calling crates.io. We should be reporting progress here, but it's + // unclear whether cargo itself supports it. progress("metadata".to_string()); - let mut meta = meta.exec().with_context(|| { + + let meta = meta.exec().with_context(|| { let cwd: Option = std::env::current_dir().ok().and_then(|p| p.try_into().ok()); @@ -283,6 +285,14 @@ impl CargoWorkspace { ) })?; + Ok(meta) + } + + pub fn new( + cargo_toml: &AbsPath, + config: &CargoConfig, + mut meta: cargo_metadata::Metadata, + ) -> CargoWorkspace { let mut pkg_by_id = FxHashMap::default(); let mut packages = Arena::default(); let mut targets = Arena::default(); @@ -296,9 +306,10 @@ impl CargoWorkspace { } = meta_pkg; let meta = from_value::(metadata.clone()).unwrap_or_default(); let is_member = ws_members.contains(id); - let edition = edition - .parse::() - .with_context(|| format!("Failed to parse edition {}", edition))?; + let edition = edition.parse::().unwrap_or_else(|err| { + log::error!("Failed to parse edition {}", err); + Edition::CURRENT + }); let pkg = packages.alloc(PackageData { id: id.repr.clone(), @@ -366,7 +377,16 @@ impl CargoWorkspace { let build_data_config = BuildDataConfig::new(cargo_toml.to_path_buf(), config.clone(), Arc::new(meta.packages)); - Ok(CargoWorkspace { packages, targets, workspace_root, build_data_config }) + CargoWorkspace { packages, targets, workspace_root, build_data_config } + } + + pub fn from_cargo_metadata3( + cargo_toml: &AbsPath, + config: &CargoConfig, + progress: &dyn Fn(String), + ) -> Result { + let meta = CargoWorkspace::fetch_metadata(cargo_toml, config, progress)?; + Ok(CargoWorkspace::new(cargo_toml, config, meta)) } pub fn packages<'a>(&'a self) -> impl Iterator + ExactSizeIterator + 'a { diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index c1750d43a5f..76c4388f193 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -126,7 +126,7 @@ impl ProjectWorkspace { cmd })?; - let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, config, progress) + let meta = CargoWorkspace::fetch_metadata(&cargo_toml, config, progress) .with_context(|| { format!( "Failed to read Cargo metadata from Cargo.toml file {}, {}", @@ -134,6 +134,7 @@ impl ProjectWorkspace { cargo_version ) })?; + let cargo = CargoWorkspace::new(&cargo_toml, config, meta); let sysroot = if config.no_sysroot { Sysroot::default() @@ -156,15 +157,15 @@ impl ProjectWorkspace { None }; - let rustc = if let Some(rustc_dir) = rustc_dir { - Some( - CargoWorkspace::from_cargo_metadata(&rustc_dir, config, progress) + let rustc = match rustc_dir { + Some(rustc_dir) => Some({ + let meta = CargoWorkspace::fetch_metadata(&rustc_dir, config, progress) .with_context(|| { format!("Failed to read Cargo metadata for Rust sources") - })?, - ) - } else { - None + })?; + CargoWorkspace::new(&rustc_dir, config, meta) + }), + None => None, }; let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref()); @@ -595,7 +596,7 @@ fn detached_files_to_crate_graph( .map(|file_stem| CrateDisplayName::from_canonical_name(file_stem.to_string())); let detached_file_crate = crate_graph.add_crate_root( file_id, - Edition::Edition2018, + Edition::CURRENT, display_name, cfg_options.clone(), cfg_options.clone(), @@ -777,7 +778,7 @@ fn sysroot_to_crate_graph( let display_name = CrateDisplayName::from_canonical_name(sysroot[krate].name.clone()); let crate_id = crate_graph.add_crate_root( file_id, - Edition::Edition2018, + Edition::CURRENT, Some(display_name), cfg_options.clone(), cfg_options.clone(),