Skip to content

Commit a4a6a43

Browse files
committed
Split out ProjectWorkspace::load_cargo
1 parent 8606441 commit a4a6a43

File tree

1 file changed

+139
-142
lines changed
  • src/tools/rust-analyzer/crates/project-model/src

1 file changed

+139
-142
lines changed

src/tools/rust-analyzer/crates/project-model/src/workspace.rs

Lines changed: 139 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -219,155 +219,152 @@ impl ProjectWorkspace {
219219
ProjectWorkspace::load_detached_file(rust_file, config)?
220220
}
221221
ProjectManifest::CargoToml(cargo_toml) => {
222-
// FIXME: Split sysroot discovery from sysroot loading, as to load the sysroot we
223-
// want to pass the analysis target, but to discover the target we need to know the
224-
// sysroot location so we know which cargo to use
225-
let sysroot = match (&config.sysroot, &config.sysroot_src) {
226-
(Some(RustLibSource::Discover), None) => Sysroot::discover(
227-
cargo_toml.parent(),
228-
&config.extra_env,
229-
&config.sysroot_query_metadata,
230-
),
231-
(Some(RustLibSource::Discover), Some(sysroot_src)) => {
232-
Sysroot::discover_with_src_override(
233-
cargo_toml.parent(),
234-
&config.extra_env,
235-
sysroot_src.clone(),
236-
&config.sysroot_query_metadata,
237-
)
238-
}
239-
(Some(RustLibSource::Path(path)), None) => Sysroot::discover_sysroot_src_dir(
240-
path.clone(),
241-
&config.sysroot_query_metadata,
242-
),
243-
(Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => Sysroot::load(
244-
Some(sysroot.clone()),
245-
Some(sysroot_src.clone()),
246-
&config.sysroot_query_metadata,
247-
),
248-
(None, _) => Sysroot::empty(),
249-
};
250-
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");
251-
252-
let rustc_dir = match &config.rustc_source {
253-
Some(RustLibSource::Path(path)) => ManifestPath::try_from(path.clone())
254-
.map_err(|p| Some(format!("rustc source path is not absolute: {p}"))),
255-
Some(RustLibSource::Discover) => {
256-
sysroot.discover_rustc_src().ok_or_else(|| {
257-
Some("Failed to discover rustc source for sysroot.".to_owned())
258-
})
259-
}
260-
None => Err(None),
261-
};
262-
let targets = target_triple::get(
263-
QueryConfig::Cargo(&sysroot, cargo_toml),
264-
config.target.as_deref(),
222+
ProjectWorkspace::load_cargo(cargo_toml, config, progress)?
223+
}
224+
};
225+
226+
Ok(res)
227+
}
228+
229+
fn load_cargo(
230+
cargo_toml: &ManifestPath,
231+
config: &CargoConfig,
232+
progress: &dyn Fn(String),
233+
) -> Result<ProjectWorkspace, anyhow::Error> {
234+
// FIXME: Split sysroot discovery from sysroot loading, as to load the sysroot we
235+
// want to pass the analysis target, but to discover the target we need to know the
236+
// sysroot location so we know which cargo to use
237+
let sysroot = match (&config.sysroot, &config.sysroot_src) {
238+
(Some(RustLibSource::Discover), None) => Sysroot::discover(
239+
cargo_toml.parent(),
240+
&config.extra_env,
241+
&config.sysroot_query_metadata,
242+
),
243+
(Some(RustLibSource::Discover), Some(sysroot_src)) => {
244+
Sysroot::discover_with_src_override(
245+
cargo_toml.parent(),
265246
&config.extra_env,
247+
sysroot_src.clone(),
248+
&config.sysroot_query_metadata,
266249
)
267-
.unwrap_or_default();
268-
let rustc = rustc_dir.and_then(|rustc_dir| {
269-
info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
270-
match CargoWorkspace::fetch_metadata(
271-
&rustc_dir,
250+
}
251+
(Some(RustLibSource::Path(path)), None) => {
252+
Sysroot::discover_sysroot_src_dir(path.clone(), &config.sysroot_query_metadata)
253+
}
254+
(Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => Sysroot::load(
255+
Some(sysroot.clone()),
256+
Some(sysroot_src.clone()),
257+
&config.sysroot_query_metadata,
258+
),
259+
(None, _) => Sysroot::empty(),
260+
};
261+
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");
262+
let rustc_dir = match &config.rustc_source {
263+
Some(RustLibSource::Path(path)) => ManifestPath::try_from(path.clone())
264+
.map_err(|p| Some(format!("rustc source path is not absolute: {p}"))),
265+
Some(RustLibSource::Discover) => sysroot
266+
.discover_rustc_src()
267+
.ok_or_else(|| Some("Failed to discover rustc source for sysroot.".to_owned())),
268+
None => Err(None),
269+
};
270+
let targets = target_triple::get(
271+
QueryConfig::Cargo(&sysroot, cargo_toml),
272+
config.target.as_deref(),
273+
&config.extra_env,
274+
)
275+
.unwrap_or_default();
276+
let rustc = rustc_dir.and_then(|rustc_dir| {
277+
info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
278+
match CargoWorkspace::fetch_metadata(
279+
&rustc_dir,
280+
cargo_toml.parent(),
281+
&CargoMetadataConfig {
282+
features: crate::CargoFeatures::default(),
283+
targets: targets.clone(),
284+
extra_args: config.extra_args.clone(),
285+
extra_env: config.extra_env.clone(),
286+
},
287+
&sysroot,
288+
false,
289+
progress,
290+
) {
291+
Ok((meta, _error)) => {
292+
let workspace = CargoWorkspace::new(meta, cargo_toml.clone());
293+
let buildscripts = WorkspaceBuildScripts::rustc_crates(
294+
&workspace,
272295
cargo_toml.parent(),
273-
&CargoMetadataConfig {
274-
features: crate::CargoFeatures::default(),
275-
targets: targets.clone(),
276-
extra_args: config.extra_args.clone(),
277-
extra_env: config.extra_env.clone(),
278-
},
296+
&config.extra_env,
279297
&sysroot,
280-
false,
281-
progress,
282-
) {
283-
Ok((meta, _error)) => {
284-
let workspace = CargoWorkspace::new(meta, cargo_toml.clone());
285-
let buildscripts = WorkspaceBuildScripts::rustc_crates(
286-
&workspace,
287-
cargo_toml.parent(),
288-
&config.extra_env,
289-
&sysroot
290-
);
291-
Ok(Box::new((workspace, buildscripts)))
292-
}
293-
Err(e) => {
294-
tracing::error!(
295-
%e,
296-
"Failed to read Cargo metadata from rustc source at {rustc_dir}",
297-
);
298-
Err(Some(format!(
299-
"Failed to read Cargo metadata from rustc source at {rustc_dir}: {e}"
300-
)))
301-
}
302-
}
303-
});
304-
305-
let toolchain = get_toolchain_version(
306-
cargo_toml.parent(),
307-
&sysroot,
308-
Tool::Cargo,
309-
&config.extra_env,
310-
"cargo ",
311-
)?;
312-
let rustc_cfg = rustc_cfg::get(
313-
QueryConfig::Cargo(&sysroot, cargo_toml),
314-
targets.first().map(Deref::deref),
315-
&config.extra_env,
316-
);
317-
318-
let cfg_overrides = config.cfg_overrides.clone();
319-
let data_layout = target_data_layout::get(
320-
QueryConfig::Cargo(&sysroot, cargo_toml),
321-
targets.first().map(Deref::deref),
322-
&config.extra_env,
323-
);
324-
if let Err(e) = &data_layout {
325-
tracing::error!(%e, "failed fetching data layout for {cargo_toml:?} workspace");
298+
);
299+
Ok(Box::new((workspace, buildscripts)))
326300
}
327-
328-
let (meta, error) = CargoWorkspace::fetch_metadata(
329-
cargo_toml,
330-
cargo_toml.parent(),
331-
&CargoMetadataConfig {
332-
features: config.features.clone(),
333-
targets,
334-
extra_args: config.extra_args.clone(),
335-
extra_env: config.extra_env.clone(),
336-
},
337-
&sysroot,
338-
false,
339-
progress,
340-
)
341-
.with_context(|| {
342-
format!(
343-
"Failed to read Cargo metadata from Cargo.toml file {cargo_toml}, {toolchain:?}",
344-
)
345-
})?;
346-
let cargo = CargoWorkspace::new(meta, cargo_toml.clone());
347-
348-
let cargo_config_extra_env =
349-
cargo_config_env(cargo_toml, &config.extra_env, &sysroot);
350-
ProjectWorkspace {
351-
kind: ProjectWorkspaceKind::Cargo {
352-
cargo,
353-
build_scripts: WorkspaceBuildScripts::default(),
354-
rustc,
355-
cargo_config_extra_env,
356-
error: error.map(Arc::new),
357-
set_test: config.set_test,
358-
},
359-
sysroot,
360-
rustc_cfg,
361-
cfg_overrides,
362-
toolchain,
363-
target_layout: data_layout
364-
.map(Arc::from)
365-
.map_err(|it| Arc::from(it.to_string())),
301+
Err(e) => {
302+
tracing::error!(
303+
%e,
304+
"Failed to read Cargo metadata from rustc source at {rustc_dir}",
305+
);
306+
Err(Some(format!(
307+
"Failed to read Cargo metadata from rustc source at {rustc_dir}: {e}"
308+
)))
366309
}
367310
}
368-
};
369-
370-
Ok(res)
311+
});
312+
let toolchain = get_toolchain_version(
313+
cargo_toml.parent(),
314+
&sysroot,
315+
Tool::Cargo,
316+
&config.extra_env,
317+
"cargo ",
318+
)?;
319+
let rustc_cfg = rustc_cfg::get(
320+
QueryConfig::Cargo(&sysroot, cargo_toml),
321+
targets.first().map(Deref::deref),
322+
&config.extra_env,
323+
);
324+
let cfg_overrides = config.cfg_overrides.clone();
325+
let data_layout = target_data_layout::get(
326+
QueryConfig::Cargo(&sysroot, cargo_toml),
327+
targets.first().map(Deref::deref),
328+
&config.extra_env,
329+
);
330+
if let Err(e) = &data_layout {
331+
tracing::error!(%e, "failed fetching data layout for {cargo_toml:?} workspace");
332+
}
333+
let (meta, error) = CargoWorkspace::fetch_metadata(
334+
cargo_toml,
335+
cargo_toml.parent(),
336+
&CargoMetadataConfig {
337+
features: config.features.clone(),
338+
targets,
339+
extra_args: config.extra_args.clone(),
340+
extra_env: config.extra_env.clone(),
341+
},
342+
&sysroot,
343+
false,
344+
progress,
345+
)
346+
.with_context(|| {
347+
format!(
348+
"Failed to read Cargo metadata from Cargo.toml file {cargo_toml}, {toolchain:?}",
349+
)
350+
})?;
351+
let cargo = CargoWorkspace::new(meta, cargo_toml.clone());
352+
let cargo_config_extra_env = cargo_config_env(cargo_toml, &config.extra_env, &sysroot);
353+
Ok(ProjectWorkspace {
354+
kind: ProjectWorkspaceKind::Cargo {
355+
cargo,
356+
build_scripts: WorkspaceBuildScripts::default(),
357+
rustc,
358+
cargo_config_extra_env,
359+
error: error.map(Arc::new),
360+
set_test: config.set_test,
361+
},
362+
sysroot,
363+
rustc_cfg,
364+
cfg_overrides,
365+
toolchain,
366+
target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())),
367+
})
371368
}
372369

373370
pub fn load_inline(project_json: ProjectJson, config: &CargoConfig) -> ProjectWorkspace {

0 commit comments

Comments
 (0)