From 44f27329c0095fe5d13fe07d8a7a6fb183f68877 Mon Sep 17 00:00:00 2001 From: duncan Date: Wed, 22 Jan 2025 14:27:27 +0000 Subject: [PATCH 001/260] fix testing for packages with multiple targets fix test running by invoking cargo per package remove hack_recover_crate_name make clippy happy fix testing for packages with multiple targets fix test running by invoking cargo per package remove hack_recover_crate_name make clippy happy fix testing for packages with multiple targets fix bad merge replace TargetKind::fmt with TargetKind::as_cargo_target to clarify intention dedupulicate requested test runs replace ParseFromLine with CargoParser formatting - remove trailing space formatting for rustfmt CI --- .../project-model/src/cargo_workspace.rs | 17 +++ .../crates/rust-analyzer/src/command.rs | 39 ++++-- .../crates/rust-analyzer/src/discover.rs | 12 +- .../crates/rust-analyzer/src/flycheck.rs | 12 +- .../src/hack_recover_crate_name.rs | 25 ---- .../rust-analyzer/src/handlers/request.rs | 121 ++++++++++-------- .../crates/rust-analyzer/src/lib.rs | 1 - .../crates/rust-analyzer/src/main_loop.rs | 22 ++-- .../crates/rust-analyzer/src/test_runner.rs | 80 ++++++++---- 9 files changed, 186 insertions(+), 143 deletions(-) delete mode 100644 src/tools/rust-analyzer/crates/rust-analyzer/src/hack_recover_crate_name.rs diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 40ab8c53faeb8..1a9501c0638bc 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -224,6 +224,7 @@ pub enum TargetKind { Example, Test, Bench, + /// Cargo calls this kind `custom-build` BuildScript, Other, } @@ -252,6 +253,22 @@ impl TargetKind { pub fn is_proc_macro(self) -> bool { matches!(self, TargetKind::Lib { is_proc_macro: true }) } + + /// If this is a valid cargo target, returns the name cargo uses in command line arguments + /// and output, otherwise None. + /// https://docs.rs/cargo_metadata/latest/cargo_metadata/enum.TargetKind.html + pub fn as_cargo_target(self) -> Option<&'static str> { + match self { + TargetKind::Bin => Some("bin"), + TargetKind::Lib { is_proc_macro: true } => Some("proc-macro"), + TargetKind::Lib { is_proc_macro: false } => Some("lib"), + TargetKind::Example => Some("example"), + TargetKind::Test => Some("test"), + TargetKind::Bench => Some("bench"), + TargetKind::BuildScript => Some("custom-build"), + TargetKind::Other => None, + } + } } #[derive(Default, Clone, Debug, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs index b19a1b8d16700..8e2d3d52b8770 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs @@ -13,24 +13,33 @@ use crossbeam_channel::Sender; use process_wrap::std::{StdChildWrapper, StdCommandWrap}; use stdx::process::streaming_output; -/// Cargo output is structured as a one JSON per line. This trait abstracts parsing one line of -/// cargo output into a Rust data type. -pub(crate) trait ParseFromLine: Sized + Send + 'static { - fn from_line(line: &str, error: &mut String) -> Option; - fn from_eof() -> Option; +/// Cargo output is structured as one JSON per line. This trait abstracts parsing one line of +/// cargo output into a Rust data type +pub(crate) trait CargoParser: Send + 'static { + fn from_line(&self, line: &str, error: &mut String) -> Option; + fn from_eof(&self) -> Option; } struct CargoActor { + parser: Box>, sender: Sender, stdout: ChildStdout, stderr: ChildStderr, } -impl CargoActor { - fn new(sender: Sender, stdout: ChildStdout, stderr: ChildStderr) -> Self { - CargoActor { sender, stdout, stderr } +impl CargoActor { + fn new( + parser: impl CargoParser, + sender: Sender, + stdout: ChildStdout, + stderr: ChildStderr, + ) -> Self { + let parser = Box::new(parser); + CargoActor { parser, sender, stdout, stderr } } +} +impl CargoActor { fn run(self) -> io::Result<(bool, String)> { // We manually read a line at a time, instead of using serde's // stream deserializers, because the deserializer cannot recover @@ -47,7 +56,7 @@ impl CargoActor { let mut read_at_least_one_stderr_message = false; let process_line = |line: &str, error: &mut String| { // Try to deserialize a message from Cargo or Rustc. - if let Some(t) = T::from_line(line, error) { + if let Some(t) = self.parser.from_line(line, error) { self.sender.send(t).unwrap(); true } else { @@ -68,7 +77,7 @@ impl CargoActor { } }, &mut || { - if let Some(t) = T::from_eof() { + if let Some(t) = self.parser.from_eof() { self.sender.send(t).unwrap(); } }, @@ -116,8 +125,12 @@ impl fmt::Debug for CommandHandle { } } -impl CommandHandle { - pub(crate) fn spawn(mut command: Command, sender: Sender) -> std::io::Result { +impl CommandHandle { + pub(crate) fn spawn( + mut command: Command, + parser: impl CargoParser, + sender: Sender, + ) -> std::io::Result { command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null()); let program = command.get_program().into(); @@ -134,7 +147,7 @@ impl CommandHandle { let stdout = child.0.stdout().take().unwrap(); let stderr = child.0.stderr().take().unwrap(); - let actor = CargoActor::::new(sender, stdout, stderr); + let actor = CargoActor::::new(parser, sender, stdout, stderr); let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) .name("CommandHandle".to_owned()) .spawn(move || actor.run()) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs index 0c111319bb41b..09de309ce9564 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use tracing::{info_span, span::EnteredSpan}; -use crate::command::{CommandHandle, ParseFromLine}; +use crate::command::{CargoParser, CommandHandle}; pub(crate) const ARG_PLACEHOLDER: &str = "{arg}"; @@ -66,7 +66,7 @@ impl DiscoverCommand { cmd.args(args); Ok(DiscoverHandle { - _handle: CommandHandle::spawn(cmd, self.sender.clone())?, + _handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone())?, span: info_span!("discover_command").entered(), }) } @@ -115,8 +115,10 @@ impl DiscoverProjectMessage { } } -impl ParseFromLine for DiscoverProjectMessage { - fn from_line(line: &str, _error: &mut String) -> Option { +struct DiscoverProjectParser; + +impl CargoParser for DiscoverProjectParser { + fn from_line(&self, line: &str, _error: &mut String) -> Option { // can the line even be deserialized as JSON? let Ok(data) = serde_json::from_str::(line) else { let err = DiscoverProjectData::Error { error: line.to_owned(), source: None }; @@ -131,7 +133,7 @@ impl ParseFromLine for DiscoverProjectMessage { Some(msg) } - fn from_eof() -> Option { + fn from_eof(&self) -> Option { None } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 2309f94a7429b..1e46d9ba56d5f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -17,7 +17,7 @@ pub(crate) use cargo_metadata::diagnostic::{ use toolchain::Tool; use triomphe::Arc; -use crate::command::{CommandHandle, ParseFromLine}; +use crate::command::{CargoParser, CommandHandle}; #[derive(Clone, Debug, Default, PartialEq, Eq)] pub(crate) enum InvocationStrategy { @@ -324,7 +324,7 @@ impl FlycheckActor { tracing::debug!(?command, "will restart flycheck"); let (sender, receiver) = unbounded(); - match CommandHandle::spawn(command, sender) { + match CommandHandle::spawn(command, CargoCheckParser, sender) { Ok(command_handle) => { tracing::debug!(command = formatted_command, "did restart flycheck"); self.command_handle = Some(command_handle); @@ -550,8 +550,10 @@ enum CargoCheckMessage { Diagnostic { diagnostic: Diagnostic, package_id: Option> }, } -impl ParseFromLine for CargoCheckMessage { - fn from_line(line: &str, error: &mut String) -> Option { +struct CargoCheckParser; + +impl CargoParser for CargoCheckParser { + fn from_line(&self, line: &str, error: &mut String) -> Option { let mut deserializer = serde_json::Deserializer::from_str(line); deserializer.disable_recursion_limit(); if let Ok(message) = JsonMessage::deserialize(&mut deserializer) { @@ -580,7 +582,7 @@ impl ParseFromLine for CargoCheckMessage { None } - fn from_eof() -> Option { + fn from_eof(&self) -> Option { None } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/hack_recover_crate_name.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/hack_recover_crate_name.rs deleted file mode 100644 index d7285653c5fa5..0000000000000 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/hack_recover_crate_name.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Currently cargo does not emit crate name in the `cargo test --format=json`, which needs to be changed. This -//! module contains a way to recover crate names in a very hacky and wrong way. - -// FIXME(hack_recover_crate_name): Remove this module. - -use std::sync::{Mutex, MutexGuard, OnceLock}; - -use ide_db::FxHashMap; - -static STORAGE: OnceLock>> = OnceLock::new(); - -fn get_storage() -> MutexGuard<'static, FxHashMap> { - STORAGE.get_or_init(|| Mutex::new(FxHashMap::default())).lock().unwrap() -} - -pub(crate) fn insert_name(name_with_crate: String) { - let Some((_, name_without_crate)) = name_with_crate.split_once("::") else { - return; - }; - get_storage().insert(name_without_crate.to_owned(), name_with_crate); -} - -pub(crate) fn lookup_name(name_without_crate: String) -> Option { - get_storage().get(&name_without_crate).cloned() -} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index b91a5dbd4166f..1410138da82ef 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -36,7 +36,6 @@ use crate::{ config::{Config, RustfmtConfig, WorkspaceSymbolConfig}, diagnostics::convert_diagnostic, global_state::{FetchWorkspaceRequest, GlobalState, GlobalStateSnapshot}, - hack_recover_crate_name, line_index::LineEndings, lsp::{ ext::{ @@ -196,20 +195,48 @@ pub(crate) fn handle_view_item_tree( Ok(res) } -// cargo test requires the real package name which might contain hyphens but -// the test identifier passed to this function is the namespace form where hyphens -// are replaced with underscores so we have to reverse this and find the real package name -fn find_package_name(namespace_root: &str, cargo: &CargoWorkspace) -> Option { +// cargo test requires: +// - the package name - the root of the test identifier supplied to this handler can be +// a package or a target inside a package. +// - the target name - if the test identifier is a target, it's needed in addition to the +// package name to run the right test +// - real names - the test identifier uses the namespace form where hyphens are replaced with +// underscores. cargo test requires the real name. +// - the target kind e.g. bin or lib +fn find_test_target(namespace_root: &str, cargo: &CargoWorkspace) -> Option { cargo.packages().find_map(|p| { let package_name = &cargo[p].name; - if package_name.replace('-', "_") == namespace_root { - Some(package_name.clone()) - } else { - None + for target in cargo[p].targets.iter() { + let target_name = &cargo[*target].name; + if target_name.replace('-', "_") == namespace_root { + return Some(TestTarget { + package: package_name.clone(), + target: target_name.clone(), + kind: cargo[*target].kind, + }); + } } + None }) } +fn get_all_targets(cargo: &CargoWorkspace) -> Vec { + cargo + .packages() + .flat_map(|p| { + let package_name = &cargo[p].name; + cargo[p].targets.iter().map(|target| { + let target_name = &cargo[*target].name; + TestTarget { + package: package_name.clone(), + target: target_name.clone(), + kind: cargo[*target].kind, + } + }) + }) + .collect() +} + pub(crate) fn handle_run_test( state: &mut GlobalState, params: lsp_ext::RunTestParams, @@ -217,53 +244,41 @@ pub(crate) fn handle_run_test( if let Some(_session) = state.test_run_session.take() { state.send_notification::(()); } - // We detect the lowest common ancestor of all included tests, and - // run it. We ignore excluded tests for now, the client will handle - // it for us. - let lca = match params.include { - Some(tests) => tests - .into_iter() - .reduce(|x, y| { - let mut common_prefix = "".to_owned(); - for (xc, yc) in x.chars().zip(y.chars()) { - if xc != yc { - break; - } - common_prefix.push(xc); - } - common_prefix - }) - .unwrap_or_default(), - None => "".to_owned(), - }; - let (namespace_root, test_path) = if lca.is_empty() { - (None, None) - } else if let Some((namespace_root, path)) = lca.split_once("::") { - (Some(namespace_root), Some(path)) - } else { - (Some(lca.as_str()), None) - }; + let mut handles = vec![]; for ws in &*state.workspaces { if let ProjectWorkspaceKind::Cargo { cargo, .. } = &ws.kind { - let test_target = if let Some(namespace_root) = namespace_root { - if let Some(package_name) = find_package_name(namespace_root, cargo) { - TestTarget::Package(package_name) - } else { - TestTarget::Workspace - } - } else { - TestTarget::Workspace + // need to deduplicate `include` to avoid redundant test runs + let tests = match params.include { + Some(ref include) => include + .iter() + .unique() + .filter_map(|test| { + let (root, remainder) = match test.split_once("::") { + Some((root, remainder)) => (root.to_owned(), Some(remainder)), + None => (test.clone(), None), + }; + if let Some(target) = find_test_target(&root, cargo) { + Some((target, remainder)) + } else { + tracing::error!("Test target not found for: {test}"); + None + } + }) + .collect_vec(), + None => get_all_targets(cargo).into_iter().map(|target| (target, None)).collect(), }; - let handle = CargoTestHandle::new( - test_path, - state.config.cargo_test_options(None), - cargo.workspace_root(), - test_target, - state.test_run_sender.clone(), - )?; - handles.push(handle); + for (target, path) in tests { + let handle = CargoTestHandle::new( + path, + state.config.cargo_test_options(None), + cargo.workspace_root(), + target, + state.test_run_sender.clone(), + )?; + handles.push(handle); + } } } // Each process send finished signal twice, once for stdout and once for stderr @@ -287,9 +302,7 @@ pub(crate) fn handle_discover_test( } None => (snap.analysis.discover_test_roots()?, None), }; - for t in &tests { - hack_recover_crate_name::insert_name(t.id.clone()); - } + Ok(lsp_ext::DiscoverTestResults { tests: tests .into_iter() diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 27d6225cdb7e2..daf75e86e6409 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -15,7 +15,6 @@ mod command; mod diagnostics; mod discover; mod flycheck; -mod hack_recover_crate_name; mod line_index; mod main_loop; mod mem_docs; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index f5d9469f2622f..e63572d81a5ae 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -26,7 +26,6 @@ use crate::{ file_id_to_url, url_to_file_id, FetchBuildDataResponse, FetchWorkspaceRequest, FetchWorkspaceResponse, GlobalState, }, - hack_recover_crate_name, handlers::{ dispatch::{NotificationDispatcher, RequestDispatcher}, request::empty_diagnostic_report, @@ -37,7 +36,7 @@ use crate::{ }, lsp_ext, reload::{BuildDataProgress, ProcMacroProgress, ProjectWorkspaceProgress}, - test_runner::{CargoTestMessage, TestState}, + test_runner::{CargoTestMessage, CargoTestOutput, TestState}, }; pub fn main_loop(config: Config, connection: Connection) -> anyhow::Result<()> { @@ -659,9 +658,7 @@ impl GlobalState { .filter_map(|f| snapshot.analysis.discover_tests_in_file(f).ok()) .flatten() .collect::>(); - for t in &tests { - hack_recover_crate_name::insert_name(t.id.clone()); - } + Task::DiscoverTest(lsp_ext::DiscoverTestResults { tests: tests .into_iter() @@ -958,30 +955,29 @@ impl GlobalState { } fn handle_cargo_test_msg(&mut self, message: CargoTestMessage) { - match message { - CargoTestMessage::Test { name, state } => { + match message.output { + CargoTestOutput::Test { name, state } => { let state = match state { TestState::Started => lsp_ext::TestState::Started, TestState::Ignored => lsp_ext::TestState::Skipped, TestState::Ok => lsp_ext::TestState::Passed, TestState::Failed { stdout } => lsp_ext::TestState::Failed { message: stdout }, }; - let Some(test_id) = hack_recover_crate_name::lookup_name(name) else { - return; - }; + let test_id = format!("{}::{name}", message.target.target); + self.send_notification::( lsp_ext::ChangeTestStateParams { test_id, state }, ); } - CargoTestMessage::Suite => (), - CargoTestMessage::Finished => { + CargoTestOutput::Suite => (), + CargoTestOutput::Finished => { self.test_run_remaining_jobs = self.test_run_remaining_jobs.saturating_sub(1); if self.test_run_remaining_jobs == 0 { self.send_notification::(()); self.test_run_session = None; } } - CargoTestMessage::Custom { text } => { + CargoTestOutput::Custom { text } => { self.send_notification::(text); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs index 3edfb812cf5cf..f245c6ac4bf69 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs @@ -3,12 +3,13 @@ use crossbeam_channel::Sender; use paths::AbsPath; +use project_model::TargetKind; use serde::Deserialize as _; use serde_derive::Deserialize; use toolchain::Tool; use crate::{ - command::{CommandHandle, ParseFromLine}, + command::{CargoParser, CommandHandle}, flycheck::CargoOptions, }; @@ -25,9 +26,15 @@ pub(crate) enum TestState { }, } +#[derive(Debug)] +pub(crate) struct CargoTestMessage { + pub target: TestTarget, + pub output: CargoTestOutput, +} + #[derive(Debug, Deserialize)] #[serde(tag = "type", rename_all = "camelCase")] -pub(crate) enum CargoTestMessage { +pub(crate) enum CargoTestOutput { Test { name: String, #[serde(flatten)] @@ -40,19 +47,33 @@ pub(crate) enum CargoTestMessage { }, } -impl ParseFromLine for CargoTestMessage { - fn from_line(line: &str, _: &mut String) -> Option { +pub(crate) struct CargoTestOutputParser { + pub target: TestTarget, +} + +impl CargoTestOutputParser { + pub(crate) fn new(test_target: &TestTarget) -> Self { + Self { target: test_target.clone() } + } +} + +impl CargoParser for CargoTestOutputParser { + fn from_line(&self, line: &str, _error: &mut String) -> Option { let mut deserializer = serde_json::Deserializer::from_str(line); deserializer.disable_recursion_limit(); - if let Ok(message) = CargoTestMessage::deserialize(&mut deserializer) { - return Some(message); - } - Some(CargoTestMessage::Custom { text: line.to_owned() }) + Some(CargoTestMessage { + target: self.target.clone(), + output: if let Ok(message) = CargoTestOutput::deserialize(&mut deserializer) { + message + } else { + CargoTestOutput::Custom { text: line.to_owned() } + }, + }) } - fn from_eof() -> Option { - Some(CargoTestMessage::Finished) + fn from_eof(&self) -> Option { + Some(CargoTestMessage { target: self.target.clone(), output: CargoTestOutput::Finished }) } } @@ -62,14 +83,14 @@ pub(crate) struct CargoTestHandle { } // Example of a cargo test command: -// cargo test --workspace --no-fail-fast -- -Z unstable-options --format=json -// or -// cargo test --package my-package --no-fail-fast -- module::func -Z unstable-options --format=json +// +// cargo test --package my-package --bin my_bin --no-fail-fast -- module::func -Z unstable-options --format=json -#[derive(Debug)] -pub(crate) enum TestTarget { - Workspace, - Package(String), +#[derive(Debug, Clone)] +pub(crate) struct TestTarget { + pub package: String, + pub target: String, + pub kind: TargetKind, } impl CargoTestHandle { @@ -84,15 +105,18 @@ impl CargoTestHandle { cmd.env("RUSTC_BOOTSTRAP", "1"); cmd.arg("test"); - match &test_target { - TestTarget::Package(package) => { - cmd.arg("--package"); - cmd.arg(package); - } - TestTarget::Workspace => { - cmd.arg("--workspace"); - } - }; + cmd.arg("--package"); + cmd.arg(&test_target.package); + + if let TargetKind::Lib { .. } = test_target.kind { + // no name required with lib because there can only be one lib target per package + cmd.arg("--lib"); + } else if let Some(cargo_target) = test_target.kind.as_cargo_target() { + cmd.arg(format!("--{cargo_target}")); + cmd.arg(&test_target.target); + } else { + tracing::warn!("Running test for unknown cargo target {:?}", test_target.kind); + } // --no-fail-fast is needed to ensure that all requested tests will run cmd.arg("--no-fail-fast"); @@ -110,6 +134,8 @@ impl CargoTestHandle { cmd.arg(extra_arg); } - Ok(Self { _handle: CommandHandle::spawn(cmd, sender)? }) + Ok(Self { + _handle: CommandHandle::spawn(cmd, CargoTestOutputParser::new(&test_target), sender)?, + }) } } From e0409677fd449a3b8024bfa81481116c2fb3c850 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Wed, 5 Mar 2025 22:03:54 +0100 Subject: [PATCH 002/260] Show when build scripts fail what the errors were --- src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 733a7c359b8e7..273be22d8d328 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -139,9 +139,10 @@ impl GlobalState { "Proc-macros and/or build scripts have changed and need to be rebuilt.\n\n", ); } - if self.fetch_build_data_error().is_err() { - status.health |= lsp_ext::Health::Warning; + if let Err(build_data_err) = self.fetch_build_data_error() { + status.health |= lsp_ext::Health::Error; message.push_str("Failed to run build scripts of some packages.\n\n"); + format_to!(message, "{build_data_err}\n"); } if let Some(err) = &self.config_errors { status.health |= lsp_ext::Health::Warning; From 00fb741ac188f292842fa6762d8bf487d6110952 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Fri, 7 Mar 2025 18:27:29 +0100 Subject: [PATCH 003/260] Remove explicit error message when build.rs fails --- src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 273be22d8d328..3aec2582d1523 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -139,10 +139,10 @@ impl GlobalState { "Proc-macros and/or build scripts have changed and need to be rebuilt.\n\n", ); } - if let Err(build_data_err) = self.fetch_build_data_error() { - status.health |= lsp_ext::Health::Error; + if self.fetch_build_data_error().is_err() { + status.health |= lsp_ext::Health::Warning; message.push_str("Failed to run build scripts of some packages.\n\n"); - format_to!(message, "{build_data_err}\n"); + message.push_str("Please refer to the logs for more details on the errors."); } if let Some(err) = &self.config_errors { status.health |= lsp_ext::Health::Warning; From 680e6f35bcd3f23b9f98e05a3c193405bb69c510 Mon Sep 17 00:00:00 2001 From: Alex Kirszenberg Date: Mon, 10 Mar 2025 10:43:28 +0100 Subject: [PATCH 004/260] Fix diagnostics being cleared right after being received --- src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 7529e7c188f8a..dd5103258069e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -401,7 +401,9 @@ impl FlycheckActor { package_id = package_id.as_ref().map(|it| &it.repr), "diagnostic received" ); - self.diagnostics_received = DiagnosticsReceived::Yes; + if self.diagnostics_received == DiagnosticsReceived::No { + self.diagnostics_received = DiagnosticsReceived::Yes; + } if let Some(package_id) = &package_id { if self.diagnostics_cleared_for.insert(package_id.clone()) { tracing::trace!( From 1ba439124dd8e695c1eeb4b689bb322a4ce5a473 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 10 Mar 2025 10:39:04 +0100 Subject: [PATCH 005/260] Make change annotations per text-edit --- .../crates/ide-assists/src/tests.rs | 25 +++-------- .../crates/ide-completion/src/render.rs | 3 +- .../rust-analyzer/crates/ide-db/src/rename.rs | 8 +--- .../crates/ide-db/src/text_edit.rs | 21 ++++----- .../rust-analyzer/crates/ide/src/rename.rs | 29 +----------- src/tools/rust-analyzer/crates/ide/src/ssr.rs | 6 +-- .../crates/rust-analyzer/src/lsp/to_proto.rs | 45 ++++++++++++------- 7 files changed, 53 insertions(+), 84 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 7d7012c462222..b4042abf5d649 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -710,24 +710,21 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "let", delete: 45..47, - annotation: None, }, Indel { insert: "var_name", delete: 48..60, - annotation: None, }, Indel { insert: "=", delete: 61..81, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = var_name {\n true\n } else {\n false\n }", delete: 82..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -845,24 +842,21 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "let", delete: 45..47, - annotation: None, }, Indel { insert: "var_name", delete: 48..60, - annotation: None, }, Indel { insert: "=", delete: 61..81, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = var_name {\n true\n } else {\n false\n }", delete: 82..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -914,29 +908,25 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "const", delete: 45..47, - annotation: None, }, Indel { insert: "VAR_NAME:", delete: 48..60, - annotation: None, }, Indel { insert: "i32", delete: 61..81, - annotation: None, }, Indel { insert: "=", delete: 82..86, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", delete: 87..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -988,29 +978,25 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "static", delete: 45..47, - annotation: None, }, Indel { insert: "VAR_NAME:", delete: 48..60, - annotation: None, }, Indel { insert: "i32", delete: 61..81, - annotation: None, }, Indel { insert: "=", delete: 82..86, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", delete: 87..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -1062,14 +1048,13 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "fun_name()", delete: 59..60, - annotation: None, }, Indel { insert: "\n\nfn fun_name() -> i32 {\n 5\n}", delete: 110..110, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 4d0a4a4782247..90abd4337f4ae 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -2770,14 +2770,13 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } Indel { insert: "(", delete: 107..107, - annotation: None, }, Indel { insert: "qux)()", delete: 109..110, - annotation: None, }, ], + annotation: None, }, kind: SymbolKind( Field, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index 1633065f65217..a7584f67f118c 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -367,14 +367,10 @@ fn rename_reference( ) })); - let mut insert_def_edit = |def| { - let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; - source_change.insert_source_edit(file_id, edit); - Ok(()) - }; // This needs to come after the references edits, because we change the annotation of existing edits // if a conflict is detected. - insert_def_edit(def)?; + let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; + source_change.insert_source_edit(file_id, edit); Ok(source_change) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs b/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs index b59010f2f8c83..6e9bd7bdcc21a 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs @@ -18,18 +18,19 @@ pub struct Indel { pub insert: String, /// Refers to offsets in the original text pub delete: TextRange, - pub annotation: Option, } #[derive(Default, Debug, Clone)] pub struct TextEdit { /// Invariant: disjoint and sorted by `delete`. indels: Vec, + annotation: Option, } #[derive(Debug, Default, Clone)] pub struct TextEditBuilder { indels: Vec, + annotation: Option, } impl Indel { @@ -40,7 +41,7 @@ impl Indel { Indel::replace(range, String::new()) } pub fn replace(range: TextRange, replace_with: String) -> Indel { - Indel { delete: range, insert: replace_with, annotation: None } + Indel { delete: range, insert: replace_with } } pub fn apply(&self, text: &mut String) { @@ -142,12 +143,12 @@ impl TextEdit { Some(res) } - pub fn set_annotation(&mut self, annotation: Option) { - if annotation.is_some() { - for indel in &mut self.indels { - indel.annotation = annotation; - } - } + pub(crate) fn set_annotation(&mut self, conflict_annotation: Option) { + self.annotation = conflict_annotation; + } + + pub fn change_annotation(&self) -> Option { + self.annotation } } @@ -183,10 +184,10 @@ impl TextEditBuilder { self.indel(Indel::insert(offset, text)); } pub fn finish(self) -> TextEdit { - let mut indels = self.indels; + let TextEditBuilder { mut indels, annotation } = self; assert_disjoint_or_equal(&mut indels); indels = coalesce_indels(indels); - TextEdit { indels } + TextEdit { indels, annotation } } pub fn invalidates_offset(&self, offset: TextSize) -> bool { self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset)) diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index d0e1c2097a7a9..08e25dde60631 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -509,10 +509,9 @@ mod tests { let found_conflicts = source_change .source_file_edits .iter() + .filter(|(_, (edit, _))| edit.change_annotation().is_some()) .flat_map(|(file_id, (edit, _))| { - edit.into_iter() - .filter(|edit| edit.annotation.is_some()) - .map(move |edit| (*file_id, edit.delete)) + edit.into_iter().map(move |edit| (*file_id, edit.delete)) }) .sorted_unstable_by_key(|(file_id, range)| (*file_id, range.start())) .collect_vec(); @@ -1081,7 +1080,6 @@ mod foo$0; Indel { insert: "foo2", delete: 4..7, - annotation: None, }, ], ), @@ -1129,7 +1127,6 @@ use crate::foo$0::FooContent; Indel { insert: "quux", delete: 8..11, - annotation: None, }, ], ), @@ -1141,7 +1138,6 @@ use crate::foo$0::FooContent; Indel { insert: "quux", delete: 11..14, - annotation: None, }, ], ), @@ -1183,7 +1179,6 @@ mod fo$0o; Indel { insert: "foo2", delete: 4..7, - annotation: None, }, ], ), @@ -1232,7 +1227,6 @@ mod outer { mod fo$0o; } Indel { insert: "bar", delete: 16..19, - annotation: None, }, ], ), @@ -1304,7 +1298,6 @@ pub mod foo$0; Indel { insert: "foo2", delete: 27..30, - annotation: None, }, ], ), @@ -1316,7 +1309,6 @@ pub mod foo$0; Indel { insert: "foo2", delete: 8..11, - annotation: None, }, ], ), @@ -1372,7 +1364,6 @@ mod quux; Indel { insert: "foo2", delete: 4..7, - annotation: None, }, ], ), @@ -1506,12 +1497,10 @@ pub fn baz() {} Indel { insert: "r#fn", delete: 4..7, - annotation: None, }, Indel { insert: "r#fn", delete: 22..25, - annotation: None, }, ], ), @@ -1576,12 +1565,10 @@ pub fn baz() {} Indel { insert: "foo", delete: 4..8, - annotation: None, }, Indel { insert: "foo", delete: 23..27, - annotation: None, }, ], ), @@ -1643,7 +1630,6 @@ fn bar() { Indel { insert: "dyn", delete: 7..10, - annotation: None, }, ], ), @@ -1655,7 +1641,6 @@ fn bar() { Indel { insert: "r#dyn", delete: 18..21, - annotation: None, }, ], ), @@ -1685,7 +1670,6 @@ fn bar() { Indel { insert: "r#dyn", delete: 7..10, - annotation: None, }, ], ), @@ -1697,7 +1681,6 @@ fn bar() { Indel { insert: "dyn", delete: 18..21, - annotation: None, }, ], ), @@ -1727,7 +1710,6 @@ fn bar() { Indel { insert: "r#dyn", delete: 7..10, - annotation: None, }, ], ), @@ -1739,7 +1721,6 @@ fn bar() { Indel { insert: "dyn", delete: 18..21, - annotation: None, }, ], ), @@ -1776,12 +1757,10 @@ fn bar() { Indel { insert: "abc", delete: 7..10, - annotation: None, }, Indel { insert: "abc", delete: 32..35, - annotation: None, }, ], ), @@ -1793,7 +1772,6 @@ fn bar() { Indel { insert: "abc", delete: 18..23, - annotation: None, }, ], ), @@ -1827,12 +1805,10 @@ fn bar() { Indel { insert: "abc", delete: 7..12, - annotation: None, }, Indel { insert: "abc", delete: 34..39, - annotation: None, }, ], ), @@ -1844,7 +1820,6 @@ fn bar() { Indel { insert: "abc", delete: 18..21, - annotation: None, }, ], ), diff --git a/src/tools/rust-analyzer/crates/ide/src/ssr.rs b/src/tools/rust-analyzer/crates/ide/src/ssr.rs index 90e350949b81f..5812a92b3893f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/ssr.rs +++ b/src/tools/rust-analyzer/crates/ide/src/ssr.rs @@ -139,9 +139,9 @@ mod tests { Indel { insert: "3", delete: 33..34, - annotation: None, }, ], + annotation: None, }, None, ), @@ -182,9 +182,9 @@ mod tests { Indel { insert: "3", delete: 33..34, - annotation: None, }, ], + annotation: None, }, None, ), @@ -196,9 +196,9 @@ mod tests { Indel { insert: "3", delete: 11..12, - annotation: None, }, ], + annotation: None, }, None, ), diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 6db7bcb11102c..70e567ec76920 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -16,7 +16,7 @@ use ide::{ SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize, UpdateTest, }; -use ide_db::{assists, rust_doc::format_docs, FxHasher}; +use ide_db::{assists, rust_doc::format_docs, source_change::ChangeAnnotationId, FxHasher}; use itertools::Itertools; use paths::{Utf8Component, Utf8Prefix}; use semver::VersionReq; @@ -200,10 +200,10 @@ pub(crate) fn snippet_text_edit( line_index: &LineIndex, is_snippet: bool, indel: Indel, + annotation: Option, client_supports_annotations: bool, ) -> lsp_ext::SnippetTextEdit { - let annotation_id = - indel.annotation.filter(|_| client_supports_annotations).map(|it| it.to_string()); + let annotation_id = annotation.filter(|_| client_supports_annotations).map(|it| it.to_string()); let text_edit = text_edit(line_index, indel); let insert_text_format = if is_snippet { Some(lsp_types::InsertTextFormat::SNIPPET) } else { None }; @@ -228,10 +228,17 @@ pub(crate) fn snippet_text_edit_vec( text_edit: TextEdit, clients_support_annotations: bool, ) -> Vec { + let annotation = text_edit.change_annotation(); text_edit .into_iter() .map(|indel| { - self::snippet_text_edit(line_index, is_snippet, indel, clients_support_annotations) + self::snippet_text_edit( + line_index, + is_snippet, + indel, + annotation, + clients_support_annotations, + ) }) .collect() } @@ -1082,6 +1089,7 @@ fn merge_text_and_snippet_edits( ) -> Vec { let mut edits: Vec = vec![]; let mut snippets = snippet_edit.into_edit_ranges().into_iter().peekable(); + let annotation = edit.change_annotation(); let text_edits = edit.into_iter(); // offset to go from the final source location to the original source location let mut source_text_offset = 0i32; @@ -1127,11 +1135,8 @@ fn merge_text_and_snippet_edits( edits.push(snippet_text_edit( line_index, true, - Indel { - insert: format!("${snippet_index}"), - delete: snippet_range, - annotation: None, - }, + Indel { insert: format!("${snippet_index}"), delete: snippet_range }, + annotation, client_supports_annotations, )) } @@ -1190,11 +1195,8 @@ fn merge_text_and_snippet_edits( edits.push(snippet_text_edit( line_index, true, - Indel { - insert: new_text, - delete: current_indel.delete, - annotation: current_indel.annotation, - }, + Indel { insert: new_text, delete: current_indel.delete }, + annotation, client_supports_annotations, )) } else { @@ -1204,6 +1206,7 @@ fn merge_text_and_snippet_edits( line_index, false, current_indel, + annotation, client_supports_annotations, )); } @@ -1230,7 +1233,8 @@ fn merge_text_and_snippet_edits( snippet_text_edit( line_index, true, - Indel { insert: format!("${snippet_index}"), delete: snippet_range, annotation: None }, + Indel { insert: format!("${snippet_index}"), delete: snippet_range }, + annotation, client_supports_annotations, ) })); @@ -1251,8 +1255,17 @@ pub(crate) fn snippet_text_document_edit( let mut edits = if let Some(snippet_edit) = snippet_edit { merge_text_and_snippet_edits(&line_index, edit, snippet_edit, client_supports_annotations) } else { + let annotation = edit.change_annotation(); edit.into_iter() - .map(|it| snippet_text_edit(&line_index, is_snippet, it, client_supports_annotations)) + .map(|it| { + snippet_text_edit( + &line_index, + is_snippet, + it, + annotation, + client_supports_annotations, + ) + }) .collect() }; From 1dd859f65865415a84837e487f54a1a69eb05b12 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 10 Mar 2025 06:47:02 +0100 Subject: [PATCH 006/260] Add missing name-ref parents to syntactic highlighting --- .../crates/ide/src/syntax_highlighting/highlight.rs | 3 +++ .../syntax_highlighting/test_data/highlight_doctest.html | 9 ++++----- .../crates/ide/src/syntax_highlighting/tests.rs | 9 ++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index 282fbb4433b22..2b7c871a386d2 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -824,6 +824,7 @@ fn highlight_name_ref_by_syntax( h.into() } } + RECORD_EXPR_FIELD | RECORD_PAT_FIELD => HlTag::Symbol(SymbolKind::Field).into(), PATH_SEGMENT => { let name_based_fallback = || { if name.text().chars().next().unwrap_or_default().is_uppercase() { @@ -862,6 +863,8 @@ fn highlight_name_ref_by_syntax( .into(), } } + ASSOC_TYPE_ARG => SymbolKind::TypeAlias.into(), + USE_BOUND_GENERIC_ARG => SymbolKind::TypeParam.into(), _ => default.into(), } } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index c8c8c5dba4c40..d00f279c82995 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -45,14 +45,13 @@ //! fn test() {} //! ``` +//! Syntactic name ref highlighting testing //! ```rust //! extern crate self; -//! extern crate std; +//! extern crate other as otter; //! extern crate core; -//! extern crate alloc; -//! extern crate proc_macro; -//! extern crate test; -//! extern crate Krate; +//! trait T { type Assoc; } +//! fn f<Arg>() -> use<Arg> where (): T<Assoc = ()> {} //! ``` mod outline_module; diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index 8f69bb8230000..9e8af4bac2277 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -739,14 +739,13 @@ fn test_highlight_doc_comment() { //! fn test() {} //! ``` +//! Syntactic name ref highlighting testing //! ```rust //! extern crate self; -//! extern crate std; +//! extern crate other as otter; //! extern crate core; -//! extern crate alloc; -//! extern crate proc_macro; -//! extern crate test; -//! extern crate Krate; +//! trait T { type Assoc; } +//! fn f() -> use where (): T {} //! ``` mod outline_module; From 99fe5167e55644b542d38150b9fd1c370ed2fe09 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 10 Mar 2025 13:57:26 +0100 Subject: [PATCH 007/260] Remove generated md book files --- src/tools/rust-analyzer/docs/book/README.md | 1 + .../docs/book/src/assists_generated.md | 3890 ----------------- .../docs/book/src/diagnostics_generated.md | 516 --- .../docs/book/src/features_generated.md | 940 ---- 4 files changed, 1 insertion(+), 5346 deletions(-) delete mode 100644 src/tools/rust-analyzer/docs/book/src/assists_generated.md delete mode 100644 src/tools/rust-analyzer/docs/book/src/diagnostics_generated.md delete mode 100644 src/tools/rust-analyzer/docs/book/src/features_generated.md diff --git a/src/tools/rust-analyzer/docs/book/README.md b/src/tools/rust-analyzer/docs/book/README.md index 043524b2341b7..464ea02512f74 100644 --- a/src/tools/rust-analyzer/docs/book/README.md +++ b/src/tools/rust-analyzer/docs/book/README.md @@ -8,6 +8,7 @@ To run the documentation site locally: ```shell cargo install mdbook +cargo xtask codegen cd docs/book mdbook serve # make changes to documentation files in doc/book/src diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md deleted file mode 100644 index 9a80185179279..0000000000000 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ /dev/null @@ -1,3890 +0,0 @@ -//! Generated by `cargo xtask codegen assists-doc-tests`, do not edit by hand. - -### `add_braces` -**Source:** [add_braces.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_braces.rs#L8) - -Adds braces to lambda and match arm expressions. - -#### Before -```rust -fn foo(n: i32) -> i32 { - match n { - 1 =>┃ n + 1, - _ => 0 - } -} -``` - -#### After -```rust -fn foo(n: i32) -> i32 { - match n { - 1 => { - n + 1 - }, - _ => 0 - } -} -``` - - -### `add_explicit_enum_discriminant` -**Source:** [add_explicit_enum_discriminant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs#L11) - -Adds explicit discriminant to all enum variants. - -#### Before -```rust -enum TheEnum┃ { - Foo, - Bar, - Baz = 42, - Quux, -} -``` - -#### After -```rust -enum TheEnum { - Foo = 0, - Bar = 1, - Baz = 42, - Quux = 43, -} -``` - - -### `add_explicit_type` -**Source:** [add_explicit_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_explicit_type.rs#L7) - -Specify type for a let binding. - -#### Before -```rust -fn main() { - let x┃ = 92; -} -``` - -#### After -```rust -fn main() { - let x: i32 = 92; -} -``` - - -### `add_hash` -**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L89) - -Adds a hash to a raw string literal. - -#### Before -```rust -fn main() { - r#"Hello,┃ World!"#; -} -``` - -#### After -```rust -fn main() { - r##"Hello, World!"##; -} -``` - - -### `add_impl_default_members` -**Source:** [add_missing_impl_members.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_missing_impl_members.rs#L58) - -Adds scaffold for overriding default impl members. - -#### Before -```rust -trait Trait { - type X; - fn foo(&self); - fn bar(&self) {} -} - -impl Trait for () { - type X = (); - fn foo(&self) {}┃ -} -``` - -#### After -```rust -trait Trait { - type X; - fn foo(&self); - fn bar(&self) {} -} - -impl Trait for () { - type X = (); - fn foo(&self) {} - - ┃fn bar(&self) {} -} -``` - - -### `add_impl_missing_members` -**Source:** [add_missing_impl_members.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_missing_impl_members.rs#L16) - -Adds scaffold for required impl members. - -#### Before -```rust -trait Trait { - type X; - fn foo(&self) -> T; - fn bar(&self) {} -} - -impl Trait for () {┃ - -} -``` - -#### After -```rust -trait Trait { - type X; - fn foo(&self) -> T; - fn bar(&self) {} -} - -impl Trait for () { - ┃type X; - - fn foo(&self) -> u32 { - todo!() - } -} -``` - - -### `add_label_to_loop` -**Source:** [add_label_to_loop.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_label_to_loop.rs#L9) - -Adds a label to a loop. - -#### Before -```rust -fn main() { - loop┃ { - break; - continue; - } -} -``` - -#### After -```rust -fn main() { - 'l: loop { - break 'l; - continue 'l; - } -} -``` - - -### `add_lifetime_to_type` -**Source:** [add_lifetime_to_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_lifetime_to_type.rs#L5) - -Adds a new lifetime to a struct, enum or union. - -#### Before -```rust -struct Point { - x: &┃u32, - y: u32, -} -``` - -#### After -```rust -struct Point<'a> { - x: &'a u32, - y: u32, -} -``` - - -### `add_missing_match_arms` -**Source:** [add_missing_match_arms.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_missing_match_arms.rs#L16) - -Adds missing clauses to a `match` expression. - -#### Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - ┃ - } -} -``` - -#### After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } => ${1:todo!()}, - Action::Stop => ${2:todo!()},┃ - } -} -``` - - -### `add_return_type` -**Source:** [add_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_return_type.rs#L6) - -Adds the return type to a function or closure inferred from its tail expression if it doesn't have a return -type specified. This assists is useable in a functions or closures tail expression or return type position. - -#### Before -```rust -fn foo() { 4┃2i32 } -``` - -#### After -```rust -fn foo() -> i32 { 42i32 } -``` - - -### `add_turbo_fish` -**Source:** [add_turbo_fish.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_turbo_fish.rs#L14) - -Adds `::<_>` to a call of a generic method or function. - -#### Before -```rust -fn make() -> T { todo!() } -fn main() { - let x = make┃(); -} -``` - -#### After -```rust -fn make() -> T { todo!() } -fn main() { - let x = make::<${0:_}>(); -} -``` - - -### `apply_demorgan` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L23) - -Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). -This transforms expressions of the form `!l || !r` into `!(l && r)`. -This also works with `&&`. This assist can only be applied with the cursor -on either `||` or `&&`. - -#### Before -```rust -fn main() { - if x != 4 ||┃ y < 3.14 {} -} -``` - -#### After -```rust -fn main() { - if !(x == 4 && y >= 3.14) {} -} -``` - - -### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L156) - -Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to -`Iterator::all` and `Iterator::any`. - -This transforms expressions of the form `!iter.any(|x| predicate(x))` into -`iter.all(|x| !predicate(x))` and vice versa. This also works the other way for -`Iterator::all` into `Iterator::any`. - -#### Before -```rust -fn main() { - let arr = [1, 2, 3]; - if !arr.into_iter().┃any(|num| num == 4) { - println!("foo"); - } -} -``` - -#### After -```rust -fn main() { - let arr = [1, 2, 3]; - if arr.into_iter().all(|num| num != 4) { - println!("foo"); - } -} -``` - - -### `auto_import` -**Source:** [auto_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/auto_import.rs#L73) - -If the name is unresolved, provides all possible imports for it. - -#### Before -```rust -fn main() { - let map = HashMap┃::new(); -} -``` - -#### After -```rust -use std::collections::HashMap; - -fn main() { - let map = HashMap::new(); -} -``` - - -### `bind_unused_param` -**Source:** [bind_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/bind_unused_param.rs#L12) - -Binds unused function parameter to an underscore. - -#### Before -```rust -fn some_function(x: i32┃) {} -``` - -#### After -```rust -fn some_function(x: i32) { - let _ = x; -} -``` - - -### `change_visibility` -**Source:** [change_visibility.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/change_visibility.rs#L13) - -Adds or changes existing visibility specifier. - -#### Before -```rust -┃fn frobnicate() {} -``` - -#### After -```rust -pub(crate) fn frobnicate() {} -``` - - -### `comment_to_doc` -**Source:** [convert_comment_from_or_to_doc.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs#L9) - -Converts comments to documentation. - -#### Before -```rust -// Wow what ┃a nice module -// I sure hope this shows up when I hover over it -``` - -#### After -```rust -//! Wow what a nice module -//! I sure hope this shows up when I hover over it -``` - - -### `convert_bool_then_to_if` -**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L143) - -Converts a `bool::then` method call to an equivalent if expression. - -#### Before -```rust -fn main() { - (0 == 0).then┃(|| val) -} -``` - -#### After -```rust -fn main() { - if 0 == 0 { - Some(val) - } else { - None - } -} -``` - - -### `convert_bool_to_enum` -**Source:** [convert_bool_to_enum.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_to_enum.rs#L29) - -This converts boolean local variables, fields, constants, and statics into a new -enum with two variants `Bool::True` and `Bool::False`, as well as replacing -all assignments with the variants and replacing all usages with `== Bool::True` or -`== Bool::False`. - -#### Before -```rust -fn main() { - let ┃bool = true; - - if bool { - println!("foo"); - } -} -``` - -#### After -```rust -#[derive(PartialEq, Eq)] -enum Bool { True, False } - -fn main() { - let bool = Bool::True; - - if bool == Bool::True { - println!("foo"); - } -} -``` - - -### `convert_closure_to_fn` -**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L25) - -This converts a closure to a freestanding function, changing all captures to parameters. - -#### Before -```rust -fn main() { - let mut s = String::new(); - let closure = |┃a| s.push_str(a); - closure("abc"); -} -``` - -#### After -```rust -fn main() { - let mut s = String::new(); - fn closure(a: &str, s: &mut String) { - s.push_str(a) - } - closure("abc", &mut s); -} -``` - - -### `convert_for_loop_with_for_each` -**Source:** [convert_iter_for_each_to_for.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#L76) - -Converts a for loop into a for_each loop on the Iterator. - -#### Before -```rust -fn main() { - let x = vec![1, 2, 3]; - for┃ v in x { - let y = v * 2; - } -} -``` - -#### After -```rust -fn main() { - let x = vec![1, 2, 3]; - x.into_iter().for_each(|v| { - let y = v * 2; - }); -} -``` - - -### `convert_from_to_tryfrom` -**Source:** [convert_from_to_tryfrom.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs#L10) - -Converts a From impl to a TryFrom impl, wrapping returns in `Ok`. - -#### Before -```rust -impl ┃From for Thing { - fn from(val: usize) -> Self { - Thing { - b: val.to_string(), - a: val - } - } -} -``` - -#### After -```rust -impl TryFrom for Thing { - type Error = ${0:()}; - - fn try_from(val: usize) -> Result { - Ok(Thing { - b: val.to_string(), - a: val - }) - } -} -``` - - -### `convert_if_to_bool_then` -**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L21) - -Converts an if expression into a corresponding `bool::then` call. - -#### Before -```rust -fn main() { - if┃ cond { - Some(val) - } else { - None - } -} -``` - -#### After -```rust -fn main() { - cond.then(|| val) -} -``` - - -### `convert_integer_literal` -**Source:** [convert_integer_literal.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_integer_literal.rs#L5) - -Converts the base of integer literals to other bases. - -#### Before -```rust -const _: i32 = 10┃; -``` - -#### After -```rust -const _: i32 = 0b1010; -``` - - -### `convert_into_to_from` -**Source:** [convert_into_to_from.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_into_to_from.rs#L8) - -Converts an Into impl to an equivalent From impl. - -#### Before -```rust -impl ┃Into for usize { - fn into(self) -> Thing { - Thing { - b: self.to_string(), - a: self - } - } -} -``` - -#### After -```rust -impl From for Thing { - fn from(val: usize) -> Self { - Thing { - b: val.to_string(), - a: val - } - } -} -``` - - -### `convert_iter_for_each_to_for` -**Source:** [convert_iter_for_each_to_for.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#L11) - -Converts an Iterator::for_each function into a for loop. - -#### Before -```rust -fn main() { - let iter = iter::repeat((9, 2)); - iter.for_each┃(|(x, y)| { - println!("x: {}, y: {}", x, y); - }); -} -``` - -#### After -```rust -fn main() { - let iter = iter::repeat((9, 2)); - for (x, y) in iter { - println!("x: {}, y: {}", x, y); - } -} -``` - - -### `convert_let_else_to_match` -**Source:** [convert_let_else_to_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_let_else_to_match.rs#L9) - -Converts let-else statement to let statement and match expression. - -#### Before -```rust -fn main() { - let Ok(mut x) = f() else┃ { return }; -} -``` - -#### After -```rust -fn main() { - let mut x = match f() { - Ok(x) => x, - _ => return, - }; -} -``` - - -### `convert_match_to_let_else` -**Source:** [convert_match_to_let_else.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_match_to_let_else.rs#L12) - -Converts let statement with match initializer to let-else statement. - -#### Before -```rust -fn foo(opt: Option<()>) { - let val┃ = match opt { - Some(it) => it, - None => return, - }; -} -``` - -#### After -```rust -fn foo(opt: Option<()>) { - let Some(val) = opt else { return }; -} -``` - - -### `convert_named_struct_to_tuple_struct` -**Source:** [convert_named_struct_to_tuple_struct.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs#L11) - -Converts struct with named fields to tuple struct, and analogously for enum variants with named -fields. - -#### Before -```rust -struct Point┃ { x: f32, y: f32 } - -impl Point { - pub fn new(x: f32, y: f32) -> Self { - Point { x, y } - } - - pub fn x(&self) -> f32 { - self.x - } - - pub fn y(&self) -> f32 { - self.y - } -} -``` - -#### After -```rust -struct Point(f32, f32); - -impl Point { - pub fn new(x: f32, y: f32) -> Self { - Point(x, y) - } - - pub fn x(&self) -> f32 { - self.0 - } - - pub fn y(&self) -> f32 { - self.1 - } -} -``` - - -### `convert_nested_function_to_closure` -**Source:** [convert_nested_function_to_closure.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_nested_function_to_closure.rs#L7) - -Converts a function that is defined within the body of another function into a closure. - -#### Before -```rust -fn main() { - fn fo┃o(label: &str, number: u64) { - println!("{}: {}", label, number); - } - - foo("Bar", 100); -} -``` - -#### After -```rust -fn main() { - let foo = |label: &str, number: u64| { - println!("{}: {}", label, number); - }; - - foo("Bar", 100); -} -``` - - -### `convert_to_guarded_return` -**Source:** [convert_to_guarded_return.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_to_guarded_return.rs#L24) - -Replace a large conditional with a guarded return. - -#### Before -```rust -fn main() { - ┃if cond { - foo(); - bar(); - } -} -``` - -#### After -```rust -fn main() { - if !cond { - return; - } - foo(); - bar(); -} -``` - - -### `convert_tuple_return_type_to_struct` -**Source:** [convert_tuple_return_type_to_struct.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs#L20) - -This converts the return type of a function from a tuple type -into a tuple struct and updates the body accordingly. - -#### Before -```rust -fn bar() { - let (a, b, c) = foo(); -} - -fn foo() -> (┃u32, u32, u32) { - (1, 2, 3) -} -``` - -#### After -```rust -fn bar() { - let FooResult(a, b, c) = foo(); -} - -struct FooResult(u32, u32, u32); - -fn foo() -> FooResult { - FooResult(1, 2, 3) -} -``` - - -### `convert_tuple_struct_to_named_struct` -**Source:** [convert_tuple_struct_to_named_struct.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs#L10) - -Converts tuple struct to struct with named fields, and analogously for tuple enum variants. - -#### Before -```rust -struct Point┃(f32, f32); - -impl Point { - pub fn new(x: f32, y: f32) -> Self { - Point(x, y) - } - - pub fn x(&self) -> f32 { - self.0 - } - - pub fn y(&self) -> f32 { - self.1 - } -} -``` - -#### After -```rust -struct Point { field1: f32, field2: f32 } - -impl Point { - pub fn new(x: f32, y: f32) -> Self { - Point { field1: x, field2: y } - } - - pub fn x(&self) -> f32 { - self.field1 - } - - pub fn y(&self) -> f32 { - self.field2 - } -} -``` - - -### `convert_two_arm_bool_match_to_matches_macro` -**Source:** [convert_two_arm_bool_match_to_matches_macro.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs#L8) - -Convert 2-arm match that evaluates to a boolean into the equivalent matches! invocation. - -#### Before -```rust -fn main() { - match scrutinee┃ { - Some(val) if val.cond() => true, - _ => false, - } -} -``` - -#### After -```rust -fn main() { - matches!(scrutinee, Some(val) if val.cond()) -} -``` - - -### `convert_while_to_loop` -**Source:** [convert_while_to_loop.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_while_to_loop.rs#L20) - -Replace a while with a loop. - -#### Before -```rust -fn main() { - ┃while cond { - foo(); - } -} -``` - -#### After -```rust -fn main() { - loop { - if !cond { - break; - } - foo(); - } -} -``` - - -### `destructure_struct_binding` -**Source:** [destructure_struct_binding.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/destructure_struct_binding.rs#L18) - -Destructures a struct binding in place. - -#### Before -```rust -struct Foo { - bar: i32, - baz: i32, -} -fn main() { - let ┃foo = Foo { bar: 1, baz: 2 }; - let bar2 = foo.bar; - let baz2 = &foo.baz; -} -``` - -#### After -```rust -struct Foo { - bar: i32, - baz: i32, -} -fn main() { - let Foo { bar, baz } = Foo { bar: 1, baz: 2 }; - let bar2 = bar; - let baz2 = &baz; -} -``` - - -### `destructure_tuple_binding` -**Source:** [destructure_tuple_binding.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/destructure_tuple_binding.rs#L19) - -Destructures a tuple binding in place. - -#### Before -```rust -fn main() { - let ┃t = (1,2); - let v = t.0; -} -``` - -#### After -```rust -fn main() { - let (┃_0, _1) = (1,2); - let v = _0; -} -``` - - -### `desugar_async_into_impl_future` -**Source:** [toggle_async_sugar.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_async_sugar.rs#L103) - -Rewrites asynchronous function from `async fn` into `-> impl Future`. -This action does not touch the function body and therefore `0` -block does not transform to `async { 0 }`. - -#### Before -```rust -pub as┃ync fn foo() -> usize { - 0 -} -``` - -#### After -```rust -pub fn foo() -> impl core::future::Future { - 0 -} -``` - - -### `desugar_doc_comment` -**Source:** [desugar_doc_comment.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/desugar_doc_comment.rs#L14) - -Desugars doc-comments to the attribute form. - -#### Before -```rust -/// Multi-line┃ -/// comment -``` - -#### After -```rust -#[doc = r"Multi-line -comment"] -``` - - -### `expand_glob_import` -**Source:** [expand_glob_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_glob_import.rs#L19) - -Expands glob imports. - -#### Before -```rust -mod foo { - pub struct Bar; - pub struct Baz; -} - -use foo::*┃; - -fn qux(bar: Bar, baz: Baz) {} -``` - -#### After -```rust -mod foo { - pub struct Bar; - pub struct Baz; -} - -use foo::{Bar, Baz}; - -fn qux(bar: Bar, baz: Baz) {} -``` - - -### `expand_glob_reexport` -**Source:** [expand_glob_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_glob_import.rs#L81) - -Expands non-private glob imports. - -#### Before -```rust -mod foo { - pub struct Bar; - pub struct Baz; -} - -pub use foo::*┃; -``` - -#### After -```rust -mod foo { - pub struct Bar; - pub struct Baz; -} - -pub use foo::{Bar, Baz}; -``` - - -### `expand_record_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L26) - -Fills fields by replacing rest pattern in record patterns. - -#### Before -```rust -struct Bar { y: Y, z: Z } - -fn foo(bar: Bar) { - let Bar { ..┃ } = bar; -} -``` - -#### After -```rust -struct Bar { y: Y, z: Z } - -fn foo(bar: Bar) { - let Bar { y, z } = bar; -} -``` - - -### `expand_tuple_struct_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L82) - -Fills fields by replacing rest pattern in tuple struct patterns. - -#### Before -```rust -struct Bar(Y, Z); - -fn foo(bar: Bar) { - let Bar(..┃) = bar; -} -``` - -#### After -```rust -struct Bar(Y, Z); - -fn foo(bar: Bar) { - let Bar(_0, _1) = bar; -} -``` - - -### `extract_constant` -**Source:** [extract_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_variable.rs#L35) - -Extracts subexpression into a constant. - -#### Before -```rust -fn main() { - ┃(1 + 2)┃ * 4; -} -``` - -#### After -```rust -fn main() { - const ┃VAR_NAME: i32 = 1 + 2; - VAR_NAME * 4; -} -``` - - -### `extract_expressions_from_format_string` -**Source:** [extract_expressions_from_format_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs#L14) - -Move an expression out of a format string. - -#### Before -```rust -fn main() { - print!("{var} {x + 1}┃"); -} -``` - -#### After -```rust -fn main() { - print!("{var} {}"┃, x + 1); -} -``` - - -### `extract_function` -**Source:** [extract_function.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_function.rs#L39) - -Extracts selected statements and comments into new function. - -#### Before -```rust -fn main() { - let n = 1; - ┃let m = n + 2; - // calculate - let k = m + n;┃ - let g = 3; -} -``` - -#### After -```rust -fn main() { - let n = 1; - fun_name(n); - let g = 3; -} - -fn ┃fun_name(n: i32) { - let m = n + 2; - // calculate - let k = m + n; -} -``` - - -### `extract_module` -**Source:** [extract_module.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_module.rs#L29) - -Extracts a selected region as separate module. All the references, visibility and imports are -resolved. - -#### Before -```rust -┃fn foo(name: i32) -> i32 { - name + 1 -}┃ - -fn bar(name: i32) -> i32 { - name + 2 -} -``` - -#### After -```rust -mod modname { - pub(crate) fn foo(name: i32) -> i32 { - name + 1 - } -} - -fn bar(name: i32) -> i32 { - name + 2 -} -``` - - -### `extract_static` -**Source:** [extract_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_variable.rs#L52) - -Extracts subexpression into a static. - -#### Before -```rust -fn main() { - ┃(1 + 2)┃ * 4; -} -``` - -#### After -```rust -fn main() { - static ┃VAR_NAME: i32 = 1 + 2; - VAR_NAME * 4; -} -``` - - -### `extract_struct_from_enum_variant` -**Source:** [extract_struct_from_enum_variant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs#L26) - -Extracts a struct from enum variant. - -#### Before -```rust -enum A { ┃One(u32, u32) } -``` - -#### After -```rust -struct One(u32, u32); - -enum A { One(One) } -``` - - -### `extract_type_alias` -**Source:** [extract_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_type_alias.rs#L10) - -Extracts the selected type as a type alias. - -#### Before -```rust -struct S { - field: ┃(u8, u8, u8)┃, -} -``` - -#### After -```rust -type ┃Type = (u8, u8, u8); - -struct S { - field: Type, -} -``` - - -### `extract_variable` -**Source:** [extract_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_variable.rs#L18) - -Extracts subexpression into a variable. - -#### Before -```rust -fn main() { - ┃(1 + 2)┃ * 4; -} -``` - -#### After -```rust -fn main() { - let ┃var_name = 1 + 2; - var_name * 4; -} -``` - - -### `fix_visibility` -**Source:** [fix_visibility.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/fix_visibility.rs#L14) - -Makes inaccessible item public. - -#### Before -```rust -mod m { - fn frobnicate() {} -} -fn main() { - m::frobnicate┃(); -} -``` - -#### After -```rust -mod m { - ┃pub(crate) fn frobnicate() {} -} -fn main() { - m::frobnicate(); -} -``` - - -### `flip_binexpr` -**Source:** [flip_binexpr.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_binexpr.rs#L8) - -Flips operands of a binary expression. - -#### Before -```rust -fn main() { - let _ = 90 +┃ 2; -} -``` - -#### After -```rust -fn main() { - let _ = 2 + 90; -} -``` - - -### `flip_comma` -**Source:** [flip_comma.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_comma.rs#L10) - -Flips two comma-separated items. - -#### Before -```rust -fn main() { - ((1, 2),┃ (3, 4)); -} -``` - -#### After -```rust -fn main() { - ((3, 4), (1, 2)); -} -``` - - -### `flip_or_pattern` -**Source:** [flip_or_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_or_pattern.rs#L9) - -Flips two patterns in an or-pattern. - -#### Before -```rust -fn foo() { - let (a |┃ b) = 1; -} -``` - -#### After -```rust -fn foo() { - let (b | a) = 1; -} -``` - - -### `flip_trait_bound` -**Source:** [flip_trait_bound.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_trait_bound.rs#L9) - -Flips two trait bounds. - -#### Before -```rust -fn foo() { } -``` - -#### After -```rust -fn foo() { } -``` - - -### `generate_constant` -**Source:** [generate_constant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_constant.rs#L14) - -Generate a named constant. - -#### Before -```rust -struct S { i: usize } -impl S { pub fn new(n: usize) {} } -fn main() { - let v = S::new(CAPA┃CITY); -} -``` - -#### After -```rust -struct S { i: usize } -impl S { pub fn new(n: usize) {} } -fn main() { - const CAPACITY: usize = ┃; - let v = S::new(CAPACITY); -} -``` - - -### `generate_default_from_enum_variant` -**Source:** [generate_default_from_enum_variant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs#L6) - -Adds a Default impl for an enum using a variant. - -#### Before -```rust -enum Version { - Undefined, - Minor┃, - Major, -} -``` - -#### After -```rust -enum Version { - Undefined, - Minor, - Major, -} - -impl Default for Version { - fn default() -> Self { - Self::Minor - } -} -``` - - -### `generate_default_from_new` -**Source:** [generate_default_from_new.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_default_from_new.rs#L13) - -Generates default implementation from new method. - -#### Before -```rust -struct Example { _inner: () } - -impl Example { - pub fn n┃ew() -> Self { - Self { _inner: () } - } -} -``` - -#### After -```rust -struct Example { _inner: () } - -impl Example { - pub fn new() -> Self { - Self { _inner: () } - } -} - -impl Default for Example { - fn default() -> Self { - Self::new() - } -} -``` - - -### `generate_delegate_methods` -**Source:** [generate_delegate_methods.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_delegate_methods.rs#L15) - -Generate delegate methods. - -#### Before -```rust -struct Age(u8); -impl Age { - fn age(&self) -> u8 { - self.0 - } -} - -struct Person { - ag┃e: Age, -} -``` - -#### After -```rust -struct Age(u8); -impl Age { - fn age(&self) -> u8 { - self.0 - } -} - -struct Person { - age: Age, -} - -impl Person { - ┃fn age(&self) -> u8 { - self.age.age() - } -} -``` - - -### `generate_delegate_trait` -**Source:** [generate_delegate_trait.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_delegate_trait.rs#L29) - -Generate delegate trait implementation for `StructField`s. - -#### Before -```rust -trait SomeTrait { - type T; - fn fn_(arg: u32) -> u32; - fn method_(&mut self) -> bool; -} -struct A; -impl SomeTrait for A { - type T = u32; - - fn fn_(arg: u32) -> u32 { - 42 - } - - fn method_(&mut self) -> bool { - false - } -} -struct B { - a┃: A, -} -``` - -#### After -```rust -trait SomeTrait { - type T; - fn fn_(arg: u32) -> u32; - fn method_(&mut self) -> bool; -} -struct A; -impl SomeTrait for A { - type T = u32; - - fn fn_(arg: u32) -> u32 { - 42 - } - - fn method_(&mut self) -> bool { - false - } -} -struct B { - a: A, -} - -impl SomeTrait for B { - type T = ::T; - - fn fn_(arg: u32) -> u32 { - ::fn_(arg) - } - - fn method_(&mut self) -> bool { - ::method_(&mut self.a) - } -} -``` - - -### `generate_deref` -**Source:** [generate_deref.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_deref.rs#L16) - -Generate `Deref` impl using the given struct field. - -#### Before -```rust -struct A; -struct B { - ┃a: A -} -``` - -#### After -```rust -struct A; -struct B { - a: A -} - -impl core::ops::Deref for B { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.a - } -} -``` - - -### `generate_derive` -**Source:** [generate_derive.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_derive.rs#L8) - -Adds a new `#[derive()]` clause to a struct or enum. - -#### Before -```rust -struct Point { - x: u32, - y: u32,┃ -} -``` - -#### After -```rust -#[derive(┃)] -struct Point { - x: u32, - y: u32, -} -``` - - -### `generate_doc_example` -**Source:** [generate_documentation_template.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_documentation_template.rs#L76) - -Generates a rustdoc example when editing an item's documentation. - -#### Before -```rust -/// Adds two numbers.┃ -pub fn add(a: i32, b: i32) -> i32 { a + b } -``` - -#### After -```rust -/// Adds two numbers. -/// -/// # Examples -/// -/// ``` -/// use ra_test_fixture::add; -/// -/// assert_eq!(add(a, b), ); -/// ``` -pub fn add(a: i32, b: i32) -> i32 { a + b } -``` - - -### `generate_documentation_template` -**Source:** [generate_documentation_template.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_documentation_template.rs#L13) - -Adds a documentation template above a function definition / declaration. - -#### Before -```rust -pub struct S; -impl S { - pub unsafe fn set_len┃(&mut self, len: usize) -> Result<(), std::io::Error> { - /* ... */ - } -} -``` - -#### After -```rust -pub struct S; -impl S { - /// Sets the length of this [`S`]. - /// - /// # Errors - /// - /// This function will return an error if . - /// - /// # Safety - /// - /// . - pub unsafe fn set_len(&mut self, len: usize) -> Result<(), std::io::Error> { - /* ... */ - } -} -``` - - -### `generate_enum_as_method` -**Source:** [generate_enum_projection_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_projection_method.rs#L59) - -Generate an `as_` method for this enum variant. - -#### Before -```rust -enum Value { - Number(i32), - Text(String)┃, -} -``` - -#### After -```rust -enum Value { - Number(i32), - Text(String), -} - -impl Value { - fn as_text(&self) -> Option<&String> { - if let Self::Text(v) = self { - Some(v) - } else { - None - } - } -} -``` - - -### `generate_enum_is_method` -**Source:** [generate_enum_is_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_is_method.rs#L11) - -Generate an `is_` method for this enum variant. - -#### Before -```rust -enum Version { - Undefined, - Minor┃, - Major, -} -``` - -#### After -```rust -enum Version { - Undefined, - Minor, - Major, -} - -impl Version { - /// Returns `true` if the version is [`Minor`]. - /// - /// [`Minor`]: Version::Minor - #[must_use] - fn is_minor(&self) -> bool { - matches!(self, Self::Minor) - } -} -``` - - -### `generate_enum_try_into_method` -**Source:** [generate_enum_projection_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_projection_method.rs#L12) - -Generate a `try_into_` method for this enum variant. - -#### Before -```rust -enum Value { - Number(i32), - Text(String)┃, -} -``` - -#### After -```rust -enum Value { - Number(i32), - Text(String), -} - -impl Value { - fn try_into_text(self) -> Result { - if let Self::Text(v) = self { - Ok(v) - } else { - Err(self) - } - } -} -``` - - -### `generate_enum_variant` -**Source:** [generate_enum_variant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_variant.rs#L10) - -Adds a variant to an enum. - -#### Before -```rust -enum Countries { - Ghana, -} - -fn main() { - let country = Countries::Lesotho┃; -} -``` - -#### After -```rust -enum Countries { - Ghana, - Lesotho, -} - -fn main() { - let country = Countries::Lesotho; -} -``` - - -### `generate_fn_type_alias_named` -**Source:** [generate_fn_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_fn_type_alias.rs#L10) - -Generate a type alias for the function with named parameters. - -#### Before -```rust -unsafe fn fo┃o(n: i32) -> i32 { 42i32 } -``` - -#### After -```rust -type ${0:FooFn} = unsafe fn(n: i32) -> i32; - -unsafe fn foo(n: i32) -> i32 { 42i32 } -``` - - -### `generate_fn_type_alias_unnamed` -**Source:** [generate_fn_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_fn_type_alias.rs#L24) - -Generate a type alias for the function with unnamed parameters. - -#### Before -```rust -unsafe fn fo┃o(n: i32) -> i32 { 42i32 } -``` - -#### After -```rust -type ${0:FooFn} = unsafe fn(i32) -> i32; - -unsafe fn foo(n: i32) -> i32 { 42i32 } -``` - - -### `generate_from_impl_for_enum` -**Source:** [generate_from_impl_for_enum.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs#L8) - -Adds a From impl for this enum variant with one tuple field. - -#### Before -```rust -enum A { ┃One(u32) } -``` - -#### After -```rust -enum A { One(u32) } - -impl From for A { - fn from(v: u32) -> Self { - Self::One(v) - } -} -``` - - -### `generate_function` -**Source:** [generate_function.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_function.rs#L28) - -Adds a stub function with a signature matching the function under the cursor. - -#### Before -```rust -struct Baz; -fn baz() -> Baz { Baz } -fn foo() { - bar┃("", baz()); -} - -``` - -#### After -```rust -struct Baz; -fn baz() -> Baz { Baz } -fn foo() { - bar("", baz()); -} - -fn bar(arg: &str, baz: Baz) ${0:-> _} { - todo!() -} - -``` - - -### `generate_getter` -**Source:** [generate_getter_or_setter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#L73) - -Generate a getter method. - -#### Before -```rust -struct Person { - nam┃e: String, -} -``` - -#### After -```rust -struct Person { - name: String, -} - -impl Person { - fn ┃name(&self) -> &str { - &self.name - } -} -``` - - -### `generate_getter_mut` -**Source:** [generate_getter_or_setter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#L127) - -Generate a mut getter method. - -#### Before -```rust -struct Person { - nam┃e: String, -} -``` - -#### After -```rust -struct Person { - name: String, -} - -impl Person { - fn ┃name_mut(&mut self) -> &mut String { - &mut self.name - } -} -``` - - -### `generate_impl` -**Source:** [generate_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_impl.rs#L20) - -Adds a new inherent impl for a type. - -#### Before -```rust -struct Ctx┃ { - data: T, -} -``` - -#### After -```rust -struct Ctx { - data: T, -} - -impl Ctx {┃} -``` - - -### `generate_is_empty_from_len` -**Source:** [generate_is_empty_from_len.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs#L12) - -Generates is_empty implementation from the len method. - -#### Before -```rust -struct MyStruct { data: Vec } - -impl MyStruct { - #[must_use] - p┃ub fn len(&self) -> usize { - self.data.len() - } -} -``` - -#### After -```rust -struct MyStruct { data: Vec } - -impl MyStruct { - #[must_use] - pub fn len(&self) -> usize { - self.data.len() - } - - #[must_use] - pub fn is_empty(&self) -> bool { - self.len() == 0 - } -} -``` - - -### `generate_mut_trait_impl` -**Source:** [generate_mut_trait_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs#L12) - -Adds a IndexMut impl from the `Index` trait. - -#### Before -```rust -pub enum Axis { X = 0, Y = 1, Z = 2 } - -impl core::ops::Index┃ for [T; 3] { - type Output = T; - - fn index(&self, index: Axis) -> &Self::Output { - &self[index as usize] - } -} -``` - -#### After -```rust -pub enum Axis { X = 0, Y = 1, Z = 2 } - -┃impl core::ops::IndexMut for [T; 3] { - fn index_mut(&mut self, index: Axis) -> &mut Self::Output { - &self[index as usize] - } -} - -impl core::ops::Index for [T; 3] { - type Output = T; - - fn index(&self, index: Axis) -> &Self::Output { - &self[index as usize] - } -} -``` - - -### `generate_new` -**Source:** [generate_new.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_new.rs#L14) - -Adds a `fn new` for a type. - -#### Before -```rust -struct Ctx { - data: T,┃ -} -``` - -#### After -```rust -struct Ctx { - data: T, -} - -impl Ctx { - fn ┃new(data: T) -> Self { - Self { data } - } -} -``` - - -### `generate_setter` -**Source:** [generate_getter_or_setter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#L13) - -Generate a setter method. - -#### Before -```rust -struct Person { - nam┃e: String, -} -``` - -#### After -```rust -struct Person { - name: String, -} - -impl Person { - fn ┃set_name(&mut self, name: String) { - self.name = name; - } -} -``` - - -### `generate_trait_from_impl` -**Source:** [generate_trait_from_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_trait_from_impl.rs#L18) - -Generate trait for an already defined inherent impl and convert impl to a trait impl. - -#### Before -```rust -struct Foo([i32; N]); - -macro_rules! const_maker { - ($t:ty, $v:tt) => { - const CONST: $t = $v; - }; -} - -impl Fo┃o { - // Used as an associated constant. - const CONST_ASSOC: usize = N * 4; - - fn create() -> Option<()> { - Some(()) - } - - const_maker! {i32, 7} -} -``` - -#### After -```rust -struct Foo([i32; N]); - -macro_rules! const_maker { - ($t:ty, $v:tt) => { - const CONST: $t = $v; - }; -} - -trait ${0:NewTrait} { - // Used as an associated constant. - const CONST_ASSOC: usize = N * 4; - - fn create() -> Option<()>; - - const_maker! {i32, 7} -} - -impl ${0:NewTrait} for Foo { - // Used as an associated constant. - const CONST_ASSOC: usize = N * 4; - - fn create() -> Option<()> { - Some(()) - } - - const_maker! {i32, 7} -} -``` - - -### `generate_trait_impl` -**Source:** [generate_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_impl.rs#L66) - -Adds a new trait impl for a type. - -#### Before -```rust -struct ┃Ctx { - data: T, -} -``` - -#### After -```rust -struct Ctx { - data: T, -} - -impl ${1:_} for Ctx {┃} -``` - - -### `inline_call` -**Source:** [inline_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_call.rs#L170) - -Inlines a function or method body creating a `let` statement per parameter unless the parameter -can be inlined. The parameter will be inlined either if it the supplied argument is a simple local -or if the parameter is only accessed inside the function body once. - -#### Before -```rust -fn foo(name: Option<&str>) { - let name = name.unwrap┃(); -} -``` - -#### After -```rust -fn foo(name: Option<&str>) { - let name = match name { - Some(val) => val, - None => panic!("called `Option::unwrap()` on a `None` value"), - }; -} -``` - - -### `inline_const_as_literal` -**Source:** [inline_const_as_literal.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_const_as_literal.rs#L6) - -Evaluate and inline const variable as literal. - -#### Before -```rust -const STRING: &str = "Hello, World!"; - -fn something() -> &'static str { - STRING┃ -} -``` - -#### After -```rust -const STRING: &str = "Hello, World!"; - -fn something() -> &'static str { - "Hello, World!" -} -``` - - -### `inline_into_callers` -**Source:** [inline_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_call.rs#L32) - -Inline a function or method body into all of its callers where possible, creating a `let` statement per parameter -unless the parameter can be inlined. The parameter will be inlined either if it the supplied argument is a simple local -or if the parameter is only accessed inside the function body once. -If all calls can be inlined the function will be removed. - -#### Before -```rust -fn print(_: &str) {} -fn foo┃(word: &str) { - if !word.is_empty() { - print(word); - } -} -fn bar() { - foo("안녕하세요"); - foo("여러분"); -} -``` - -#### After -```rust -fn print(_: &str) {} - -fn bar() { - { - let word: &str = "안녕하세요"; - if !word.is_empty() { - print(word); - } - }; - { - let word: &str = "여러분"; - if !word.is_empty() { - print(word); - } - }; -} -``` - - -### `inline_local_variable` -**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L17) - -Inlines a local variable. - -#### Before -```rust -fn main() { - let x┃ = 1 + 2; - x * 4; -} -``` - -#### After -```rust -fn main() { - (1 + 2) * 4; -} -``` - - -### `inline_macro` -**Source:** [inline_macro.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_macro.rs#L7) - -Takes a macro and inlines it one step. - -#### Before -```rust -macro_rules! num { - (+$($t:tt)+) => (1 + num!($($t )+)); - (-$($t:tt)+) => (-1 + num!($($t )+)); - (+) => (1); - (-) => (-1); -} - -fn main() { - let number = num┃!(+ + + - + +); - println!("{number}"); -} -``` - -#### After -```rust -macro_rules! num { - (+$($t:tt)+) => (1 + num!($($t )+)); - (-$($t:tt)+) => (-1 + num!($($t )+)); - (+) => (1); - (-) => (-1); -} - -fn main() { - let number = 1+num!(+ + - + +); - println!("{number}"); -} -``` - - -### `inline_type_alias` -**Source:** [inline_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_type_alias.rs#L106) - -Replace a type alias with its concrete type. - -#### Before -```rust -type A = Vec; - -fn main() { - let a: ┃A; -} -``` - -#### After -```rust -type A = Vec; - -fn main() { - let a: Vec; -} -``` - - -### `inline_type_alias_uses` -**Source:** [inline_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_type_alias.rs#L24) - -Inline a type alias into all of its uses where possible. - -#### Before -```rust -type ┃A = i32; -fn id(x: A) -> A { - x -}; -fn foo() { - let _: A = 3; -} -``` - -#### After -```rust - -fn id(x: i32) -> i32 { - x -}; -fn foo() { - let _: i32 = 3; -} -``` - - -### `into_to_qualified_from` -**Source:** [into_to_qualified_from.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/into_to_qualified_from.rs#L10) - -Convert an `into` method call to a fully qualified `from` call. - -#### Before -```rust -//- minicore: from -struct B; -impl From for B { - fn from(a: i32) -> Self { - B - } -} - -fn main() -> () { - let a = 3; - let b: B = a.in┃to(); -} -``` - -#### After -```rust -struct B; -impl From for B { - fn from(a: i32) -> Self { - B - } -} - -fn main() -> () { - let a = 3; - let b: B = B::from(a); -} -``` - - -### `introduce_named_lifetime` -**Source:** [introduce_named_lifetime.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/introduce_named_lifetime.rs#L13) - -Change an anonymous lifetime to a named lifetime. - -#### Before -```rust -impl Cursor<'_┃> { - fn node(self) -> &SyntaxNode { - match self { - Cursor::Replace(node) | Cursor::Before(node) => node, - } - } -} -``` - -#### After -```rust -impl<'a> Cursor<'a> { - fn node(self) -> &SyntaxNode { - match self { - Cursor::Replace(node) | Cursor::Before(node) => node, - } - } -} -``` - - -### `introduce_named_type_parameter` -**Source:** [introduce_named_type_parameter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs#L7) - -Replaces `impl Trait` function argument with the named generic. - -#### Before -```rust -fn foo(bar: ┃impl Bar) {} -``` - -#### After -```rust -fn foo<┃B: Bar>(bar: B) {} -``` - - -### `invert_if` -**Source:** [invert_if.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/invert_if.rs#L13) - -This transforms if expressions of the form `if !x {A} else {B}` into `if x {B} else {A}` -This also works with `!=`. This assist can only be applied with the cursor on `if`. - -#### Before -```rust -fn main() { - if┃ !y { A } else { B } -} -``` - -#### After -```rust -fn main() { - if y { B } else { A } -} -``` - - -### `line_to_block` -**Source:** [convert_comment_block.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_comment_block.rs#L9) - -Converts comments between block and single-line form. - -#### Before -```rust - // Multi-line┃ - // comment -``` - -#### After -```rust - /* - Multi-line - comment - */ -``` - - -### `make_raw_string` -**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L7) - -Adds `r#` to a plain string literal. - -#### Before -```rust -fn main() { - "Hello,┃ World!"; -} -``` - -#### After -```rust -fn main() { - r#"Hello, World!"#; -} -``` - - -### `make_usual_string` -**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L47) - -Turns a raw string into a plain string. - -#### Before -```rust -fn main() { - r#"Hello,┃ "World!""#; -} -``` - -#### After -```rust -fn main() { - "Hello, \"World!\""; -} -``` - - -### `merge_imports` -**Source:** [merge_imports.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/merge_imports.rs#L21) - -Merges neighbor imports with a common prefix. - -#### Before -```rust -use std::┃fmt::Formatter; -use std::io; -``` - -#### After -```rust -use std::{fmt::Formatter, io}; -``` - - -### `merge_match_arms` -**Source:** [merge_match_arms.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/merge_match_arms.rs#L12) - -Merges the current match arm with the following if their bodies are identical. - -#### Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - ┃Action::Move(..) => foo(), - Action::Stop => foo(), - } -} -``` - -#### After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move(..) | Action::Stop => foo(), - } -} -``` - - -### `merge_nested_if` -**Source:** [merge_nested_if.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/merge_nested_if.rs#L11) - -This transforms if expressions of the form `if x { if y {A} }` into `if x && y {A}` -This assist can only be applied with the cursor on `if`. - -#### Before -```rust -fn main() { - i┃f x == 3 { if y == 4 { 1 } } -} -``` - -#### After -```rust -fn main() { - if x == 3 && y == 4 { 1 } -} -``` - - -### `move_arm_cond_to_match_guard` -**Source:** [move_guard.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_guard.rs#L69) - -Moves if expression from match arm body into a guard. - -#### Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } => ┃if distance > 10 { foo() }, - _ => (), - } -} -``` - -#### After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } if distance > 10 => foo(), - _ => (), - } -} -``` - - -### `move_bounds_to_where_clause` -**Source:** [move_bounds.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_bounds.rs#L12) - -Moves inline type bounds to a where clause. - -#### Before -```rust -fn apply U>(f: F, x: T) -> U { - f(x) -} -``` - -#### After -```rust -fn apply(f: F, x: T) -> U where F: FnOnce(T) -> U { - f(x) -} -``` - - -### `move_const_to_impl` -**Source:** [move_const_to_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_const_to_impl.rs#L14) - -Move a local constant item in a method to impl's associated constant. All the references will be -qualified with `Self::`. - -#### Before -```rust -struct S; -impl S { - fn foo() -> usize { - /// The answer. - const C┃: usize = 42; - - C * C - } -} -``` - -#### After -```rust -struct S; -impl S { - /// The answer. - const C: usize = 42; - - fn foo() -> usize { - Self::C * Self::C - } -} -``` - - -### `move_from_mod_rs` -**Source:** [move_from_mod_rs.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_from_mod_rs.rs#L12) - -Moves xxx/mod.rs to xxx.rs. - -#### Before -```rust -//- /main.rs -mod a; -//- /a/mod.rs -┃fn t() {}┃ -``` - -#### After -```rust -fn t() {} -``` - - -### `move_guard_to_arm_body` -**Source:** [move_guard.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_guard.rs#L8) - -Moves match guard into match arm body. - -#### Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } ┃if distance > 10 => foo(), - _ => (), - } -} -``` - -#### After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } => if distance > 10 { - foo() - }, - _ => (), - } -} -``` - - -### `move_module_to_file` -**Source:** [move_module_to_file.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_module_to_file.rs#L15) - -Moves inline module's contents to a separate file. - -#### Before -```rust -mod ┃foo { - fn t() {} -} -``` - -#### After -```rust -mod foo; -``` - - -### `move_to_mod_rs` -**Source:** [move_to_mod_rs.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_to_mod_rs.rs#L12) - -Moves xxx.rs to xxx/mod.rs. - -#### Before -```rust -//- /main.rs -mod a; -//- /a.rs -┃fn t() {}┃ -``` - -#### After -```rust -fn t() {} -``` - - -### `normalize_import` -**Source:** [normalize_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/normalize_import.rs#L9) - -Normalizes an import. - -#### Before -```rust -use┃ std::{io, {fmt::Formatter}}; -``` - -#### After -```rust -use std::{fmt::Formatter, io}; -``` - - -### `promote_local_to_const` -**Source:** [promote_local_to_const.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/promote_local_to_const.rs#L17) - -Promotes a local variable to a const item changing its name to a `SCREAMING_SNAKE_CASE` variant -if the local uses no non-const expressions. - -#### Before -```rust -fn main() { - let foo┃ = true; - - if foo { - println!("It's true"); - } else { - println!("It's false"); - } -} -``` - -#### After -```rust -fn main() { - const ┃FOO: bool = true; - - if FOO { - println!("It's true"); - } else { - println!("It's false"); - } -} -``` - - -### `pull_assignment_up` -**Source:** [pull_assignment_up.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/pull_assignment_up.rs#L11) - -Extracts variable assignment to outside an if or match statement. - -#### Before -```rust -fn main() { - let mut foo = 6; - - if true { - ┃foo = 5; - } else { - foo = 4; - } -} -``` - -#### After -```rust -fn main() { - let mut foo = 6; - - foo = if true { - 5 - } else { - 4 - }; -} -``` - - -### `qualify_method_call` -**Source:** [qualify_method_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/qualify_method_call.rs#L10) - -Replaces the method call with a qualified function call. - -#### Before -```rust -struct Foo; -impl Foo { - fn foo(&self) {} -} -fn main() { - let foo = Foo; - foo.fo┃o(); -} -``` - -#### After -```rust -struct Foo; -impl Foo { - fn foo(&self) {} -} -fn main() { - let foo = Foo; - Foo::foo(&foo); -} -``` - - -### `qualify_path` -**Source:** [qualify_path.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/qualify_path.rs#L24) - -If the name is unresolved, provides all possible qualified paths for it. - -#### Before -```rust -fn main() { - let map = HashMap┃::new(); -} -``` - -#### After -```rust -fn main() { - let map = std::collections::HashMap::new(); -} -``` - - -### `reformat_number_literal` -**Source:** [number_representation.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/number_representation.rs#L7) - -Adds or removes separators from integer literal. - -#### Before -```rust -const _: i32 = 1012345┃; -``` - -#### After -```rust -const _: i32 = 1_012_345; -``` - - -### `remove_dbg` -**Source:** [remove_dbg.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_dbg.rs#L9) - -Removes `dbg!()` macro call. - -#### Before -```rust -fn main() { - let x = ┃dbg!(42 * dbg!(4 + 2));┃ -} -``` - -#### After -```rust -fn main() { - let x = 42 * (4 + 2); -} -``` - - -### `remove_hash` -**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L117) - -Removes a hash from a raw string literal. - -#### Before -```rust -fn main() { - r#"Hello,┃ World!"#; -} -``` - -#### After -```rust -fn main() { - r"Hello, World!"; -} -``` - - -### `remove_mut` -**Source:** [remove_mut.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_mut.rs#L5) - -Removes the `mut` keyword. - -#### Before -```rust -impl Walrus { - fn feed(&mut┃ self, amount: u32) {} -} -``` - -#### After -```rust -impl Walrus { - fn feed(&self, amount: u32) {} -} -``` - - -### `remove_parentheses` -**Source:** [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L9) - -Removes redundant parentheses. - -#### Before -```rust -fn main() { - _ = ┃(2) + 2; -} -``` - -#### After -```rust -fn main() { - _ = 2 + 2; -} -``` - - -### `remove_unused_imports` -**Source:** [remove_unused_imports.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_imports.rs#L17) - -Removes any use statements in the current selection that are unused. - -#### Before -```rust -struct X(); -mod foo { - use super::X┃; -} -``` - -#### After -```rust -struct X(); -mod foo { -} -``` - - -### `remove_unused_param` -**Source:** [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L16) - -Removes unused function parameter. - -#### Before -```rust -fn frobnicate(x: i32┃) {} - -fn main() { - frobnicate(92); -} -``` - -#### After -```rust -fn frobnicate() {} - -fn main() { - frobnicate(); -} -``` - - -### `reorder_fields` -**Source:** [reorder_fields.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/reorder_fields.rs#L8) - -Reorder the fields of record literals and record patterns in the same order as in -the definition. - -#### Before -```rust -struct Foo {foo: i32, bar: i32}; -const test: Foo = ┃Foo {bar: 0, foo: 1} -``` - -#### After -```rust -struct Foo {foo: i32, bar: i32}; -const test: Foo = Foo {foo: 1, bar: 0} -``` - - -### `reorder_impl_items` -**Source:** [reorder_impl_items.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/reorder_impl_items.rs#L11) - -Reorder the items of an `impl Trait`. The items will be ordered -in the same order as in the trait definition. - -#### Before -```rust -trait Foo { - type A; - const B: u8; - fn c(); -} - -struct Bar; -┃impl Foo for Bar┃ { - const B: u8 = 17; - fn c() {} - type A = String; -} -``` - -#### After -```rust -trait Foo { - type A; - const B: u8; - fn c(); -} - -struct Bar; -impl Foo for Bar { - type A = String; - const B: u8 = 17; - fn c() {} -} -``` - - -### `replace_arith_with_checked` -**Source:** [replace_arith_op.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_arith_op.rs#L9) - -Replaces arithmetic on integers with the `checked_*` equivalent. - -#### Before -```rust -fn main() { - let x = 1 ┃+ 2; -} -``` - -#### After -```rust -fn main() { - let x = 1.checked_add(2); -} -``` - - -### `replace_arith_with_saturating` -**Source:** [replace_arith_op.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_arith_op.rs#L28) - -Replaces arithmetic on integers with the `saturating_*` equivalent. - -#### Before -```rust -fn main() { - let x = 1 ┃+ 2; -} -``` - -#### After -```rust -fn main() { - let x = 1.saturating_add(2); -} -``` - - -### `replace_arith_with_wrapping` -**Source:** [replace_arith_op.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_arith_op.rs#L50) - -Replaces arithmetic on integers with the `wrapping_*` equivalent. - -#### Before -```rust -fn main() { - let x = 1 ┃+ 2; -} -``` - -#### After -```rust -fn main() { - let x = 1.wrapping_add(2); -} -``` - - -### `replace_char_with_string` -**Source:** [replace_string_with_char.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_string_with_char.rs#L51) - -Replace a char literal with a string literal. - -#### Before -```rust -fn main() { - find('{┃'); -} -``` - -#### After -```rust -fn main() { - find("{"); -} -``` - - -### `replace_derive_with_manual_impl` -**Source:** [replace_derive_with_manual_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs#L20) - -Converts a `derive` impl into a manual one. - -#### Before -```rust -#[derive(Deb┃ug, Display)] -struct S; -``` - -#### After -```rust -#[derive(Display)] -struct S; - -impl Debug for S { - ┃fn fmt(&self, f: &mut Formatter) -> Result<()> { - f.debug_struct("S").finish() - } -} -``` - - -### `replace_if_let_with_match` -**Source:** [replace_if_let_with_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_if_let_with_match.rs#L20) - -Replaces a `if let` expression with a `match` expression. - -#### Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - ┃if let Action::Move { distance } = action { - foo(distance) - } else { - bar() - } -} -``` - -#### After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } => foo(distance), - _ => bar(), - } -} -``` - - -### `replace_is_some_with_if_let_some` -**Source:** [replace_is_method_with_if_let_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs#L9) - -Replace `if x.is_some()` with `if let Some(_tmp) = x` or `if x.is_ok()` with `if let Ok(_tmp) = x`. - -#### Before -```rust -fn main() { - let x = Some(1); - if x.is_som┃e() {} -} -``` - -#### After -```rust -fn main() { - let x = Some(1); - if let Some(${0:x1}) = x {} -} -``` - - -### `replace_let_with_if_let` -**Source:** [replace_let_with_if_let.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_let_with_if_let.rs#L9) - -Replaces `let` with an `if let`. - -#### Before -```rust - -fn main(action: Action) { - ┃let x = compute(); -} - -fn compute() -> Option { None } -``` - -#### After -```rust - -fn main(action: Action) { - if let Some(x) = compute() { - } -} - -fn compute() -> Option { None } -``` - - -### `replace_match_with_if_let` -**Source:** [replace_if_let_with_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_if_let_with_match.rs#L188) - -Replaces a binary `match` with a wildcard pattern and no guards with an `if let` expression. - -#### Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - ┃match action { - Action::Move { distance } => foo(distance), - _ => bar(), - } -} -``` - -#### After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - if let Action::Move { distance } = action { - foo(distance) - } else { - bar() - } -} -``` - - -### `replace_named_generic_with_impl` -**Source:** [replace_named_generic_with_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs#L18) - -Replaces named generic with an `impl Trait` in function argument. - -#### Before -```rust -fn new>(location: P) -> Self {} -``` - -#### After -```rust -fn new(location: impl AsRef) -> Self {} -``` - - -### `replace_qualified_name_with_use` -**Source:** [replace_qualified_name_with_use.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs#L13) - -Adds a use statement for a given fully-qualified name. - -#### Before -```rust -fn process(map: std::collections::┃HashMap) {} -``` - -#### After -```rust -use std::collections::HashMap; - -fn process(map: HashMap) {} -``` - - -### `replace_string_with_char` -**Source:** [replace_string_with_char.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_string_with_char.rs#L11) - -Replace string literal with char literal. - -#### Before -```rust -fn main() { - find("{┃"); -} -``` - -#### After -```rust -fn main() { - find('{'); -} -``` - - -### `replace_try_expr_with_match` -**Source:** [replace_try_expr_with_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs#L18) - -Replaces a `try` expression with a `match` expression. - -#### Before -```rust -fn handle() { - let pat = Some(true)┃?; -} -``` - -#### After -```rust -fn handle() { - let pat = match Some(true) { - Some(it) => it, - None => return None, - }; -} -``` - - -### `replace_turbofish_with_explicit_type` -**Source:** [replace_turbofish_with_explicit_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs#L12) - -Converts `::<_>` to an explicit type assignment. - -#### Before -```rust -fn make() -> T { ) } -fn main() { - let a = make┃::(); -} -``` - -#### After -```rust -fn make() -> T { ) } -fn main() { - let a: i32 = make(); -} -``` - - -### `replace_with_eager_method` -**Source:** [replace_method_eager_lazy.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#L89) - -Replace `unwrap_or_else` with `unwrap_or` and `ok_or_else` with `ok_or`. - -#### Before -```rust -fn foo() { - let a = Some(1); - a.unwra┃p_or_else(|| 2); -} -``` - -#### After -```rust -fn foo() { - let a = Some(1); - a.unwrap_or(2); -} -``` - - -### `replace_with_lazy_method` -**Source:** [replace_method_eager_lazy.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#L9) - -Replace `unwrap_or` with `unwrap_or_else` and `ok_or` with `ok_or_else`. - -#### Before -```rust -fn foo() { - let a = Some(1); - a.unwra┃p_or(2); -} -``` - -#### After -```rust -fn foo() { - let a = Some(1); - a.unwrap_or_else(|| 2); -} -``` - - -### `sort_items` -**Source:** [sort_items.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/sort_items.rs#L12) - -Sorts item members alphabetically: fields, enum variants and methods. - -#### Before -```rust -struct ┃Foo┃ { second: u32, first: String } -``` - -#### After -```rust -struct Foo { first: String, second: u32 } -``` - ---- - -#### Before -```rust -trait ┃Bar┃ { - fn second(&self) -> u32; - fn first(&self) -> String; -} -``` - -#### After -```rust -trait Bar { - fn first(&self) -> String; - fn second(&self) -> u32; -} -``` - ---- - -#### Before -```rust -struct Baz; -impl ┃Baz┃ { - fn second(&self) -> u32; - fn first(&self) -> String; -} -``` - -#### After -```rust -struct Baz; -impl Baz { - fn first(&self) -> String; - fn second(&self) -> u32; -} -``` - ---- -There is a difference between sorting enum variants: - -#### Before -```rust -enum ┃Animal┃ { - Dog(String, f64), - Cat { weight: f64, name: String }, -} -``` - -#### After -```rust -enum Animal { - Cat { weight: f64, name: String }, - Dog(String, f64), -} -``` - -and sorting a single enum struct variant: - -#### Before -```rust -enum Animal { - Dog(String, f64), - Cat ┃{ weight: f64, name: String }┃, -} -``` - -#### After -```rust -enum Animal { - Dog(String, f64), - Cat { name: String, weight: f64 }, -} -``` - - -### `split_import` -**Source:** [split_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/split_import.rs#L5) - -Wraps the tail of import into braces. - -#### Before -```rust -use std::┃collections::HashMap; -``` - -#### After -```rust -use std::{collections::HashMap}; -``` - - -### `sugar_impl_future_into_async` -**Source:** [toggle_async_sugar.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_async_sugar.rs#L13) - -Rewrites asynchronous function from `-> impl Future` into `async fn`. -This action does not touch the function body and therefore `async { 0 }` -block does not transform to just `0`. - -#### Before -```rust -pub fn foo() -> impl core::future::F┃uture { - async { 0 } -} -``` - -#### After -```rust -pub async fn foo() -> usize { - async { 0 } -} -``` - - -### `toggle_ignore` -**Source:** [toggle_ignore.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_ignore.rs#L8) - -Adds `#[ignore]` attribute to the test. - -#### Before -```rust -┃#[test] -fn arithmetics { - assert_eq!(2 + 2, 5); -} -``` - -#### After -```rust -#[test] -#[ignore] -fn arithmetics { - assert_eq!(2 + 2, 5); -} -``` - - -### `toggle_macro_delimiter` -**Source:** [toggle_macro_delimiter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs#L9) - -Change macro delimiters in the order of `( -> { -> [ -> (`. - -#### Before -```rust -macro_rules! sth { - () => {}; -} - -sth!┃( ); -``` - -#### After -```rust -macro_rules! sth { - () => {}; -} - -sth!{ } -``` - - -### `unmerge_match_arm` -**Source:** [unmerge_match_arm.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unmerge_match_arm.rs#L10) - -Splits the current match with a `|` pattern into two arms with identical bodies. - -#### Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move(..) ┃| Action::Stop => foo(), - } -} -``` - -#### After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move(..) => foo(), - Action::Stop => foo(), - } -} -``` - - -### `unmerge_use` -**Source:** [unmerge_use.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unmerge_use.rs#L12) - -Extracts single use item from use list. - -#### Before -```rust -use std::fmt::{Debug, Display┃}; -``` - -#### After -```rust -use std::fmt::{Debug}; -use std::fmt::Display; -``` - - -### `unnecessary_async` -**Source:** [unnecessary_async.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unnecessary_async.rs#L17) - -Removes the `async` mark from functions which have no `.await` in their body. -Looks for calls to the functions and removes the `.await` on the call site. - -#### Before -```rust -pub asy┃nc fn foo() {} -pub async fn bar() { foo().await } -``` - -#### After -```rust -pub fn foo() {} -pub async fn bar() { foo() } -``` - - -### `unqualify_method_call` -**Source:** [unqualify_method_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unqualify_method_call.rs#L9) - -Transforms universal function call syntax into a method call. - -#### Before -```rust -fn main() { - std::ops::Add::add┃(1, 2); -} -``` - -#### After -```rust -use std::ops::Add; - -fn main() { - 1.add(2); -} -``` - - -### `unwrap_block` -**Source:** [unwrap_block.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_block.rs#L12) - -This assist removes if...else, for, while and loop control statements to just keep the body. - -#### Before -```rust -fn foo() { - if true {┃ - println!("foo"); - } -} -``` - -#### After -```rust -fn foo() { - println!("foo"); -} -``` - - -### `unwrap_option_return_type` -**Source:** [unwrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_return_type.rs#L13) - -Unwrap the function's return type. - -#### Before -```rust -fn foo() -> Option┃ { Some(42i32) } -``` - -#### After -```rust -fn foo() -> i32 { 42i32 } -``` - - -### `unwrap_result_return_type` -**Source:** [unwrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_return_type.rs#L26) - -Unwrap the function's return type. - -#### Before -```rust -fn foo() -> Result┃ { Ok(42i32) } -``` - -#### After -```rust -fn foo() -> i32 { 42i32 } -``` - - -### `unwrap_tuple` -**Source:** [unwrap_tuple.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_tuple.rs#L8) - -Unwrap the tuple to different variables. - -#### Before -```rust -fn main() { - ┃let (foo, bar) = ("Foo", "Bar"); -} -``` - -#### After -```rust -fn main() { - let foo = "Foo"; - let bar = "Bar"; -} -``` - - -### `wrap_return_type_in_option` -**Source:** [wrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/wrap_return_type.rs#L16) - -Wrap the function's return type into Option. - -#### Before -```rust -fn foo() -> i32┃ { 42i32 } -``` - -#### After -```rust -fn foo() -> Option { Some(42i32) } -``` - - -### `wrap_return_type_in_result` -**Source:** [wrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/wrap_return_type.rs#L29) - -Wrap the function's return type into Result. - -#### Before -```rust -fn foo() -> i32┃ { 42i32 } -``` - -#### After -```rust -fn foo() -> Result { Ok(42i32) } -``` - - -### `wrap_unwrap_cfg_attr` -**Source:** [wrap_unwrap_cfg_attr.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs#L12) - -Wraps an attribute to a cfg_attr attribute or unwraps a cfg_attr attribute to the inner attributes. - -#### Before -```rust -#[derive┃(Debug)] -struct S { - field: i32 -} -``` - -#### After -```rust -#[cfg_attr(┃, derive(Debug))] -struct S { - field: i32 -} -``` diff --git a/src/tools/rust-analyzer/docs/book/src/diagnostics_generated.md b/src/tools/rust-analyzer/docs/book/src/diagnostics_generated.md deleted file mode 100644 index d34c459ad0258..0000000000000 --- a/src/tools/rust-analyzer/docs/book/src/diagnostics_generated.md +++ /dev/null @@ -1,516 +0,0 @@ -//! Generated by `cargo xtask codegen diagnostics-docs`, do not edit by hand. - -#### attribute-expansion-disabled - -Source: [macro_error.rs](crates/ide-diagnostics/src/handlers/macro_error.rs#7) - - -This diagnostic is shown for attribute proc macros when attribute expansions have been disabled. - - - - -#### await-outside-of-async - -Source: [await_outside_of_async.rs](crates/ide-diagnostics/src/handlers/await_outside_of_async.rs#3) - - -This diagnostic is triggered if the `await` keyword is used outside of an async function or block - - - - -#### break-outside-of-loop - -Source: [break_outside_of_loop.rs](crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs#3) - - -This diagnostic is triggered if the `break` keyword is used outside of a loop. - - - - -#### cast-to-unsized - -Source: [invalid_cast.rs](crates/ide-diagnostics/src/handlers/invalid_cast.rs#106) - - -This diagnostic is triggered when casting to an unsized type - - - - -#### expected-function - -Source: [expected_function.rs](crates/ide-diagnostics/src/handlers/expected_function.rs#5) - - -This diagnostic is triggered if a call is made on something that is not callable. - - - - -#### generic-args-prohibited - -Source: [generic_args_prohibited.rs](crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs#10) - - -This diagnostic is shown when generic arguments are provided for a type that does not accept -generic arguments. - - - - -#### inactive-code - -Source: [inactive_code.rs](crates/ide-diagnostics/src/handlers/inactive_code.rs#6) - - -This diagnostic is shown for code with inactive `#[cfg]` attributes. - - - - -#### incoherent-impl - -Source: [incoherent_impl.rs](crates/ide-diagnostics/src/handlers/incoherent_impl.rs#6) - - -This diagnostic is triggered if the targe type of an impl is from a foreign crate. - - - - -#### incorrect-ident-case - -Source: [incorrect_case.rs](crates/ide-diagnostics/src/handlers/incorrect_case.rs#13) - - -This diagnostic is triggered if an item name doesn't follow [Rust naming convention](https://doc.rust-lang.org/1.0.0/style/style/naming/README.html). - - - - -#### invalid-cast - -Source: [invalid_cast.rs](crates/ide-diagnostics/src/handlers/invalid_cast.rs#18) - - -This diagnostic is triggered if the code contains an illegal cast - - - - -#### invalid-derive-target - -Source: [invalid_derive_target.rs](crates/ide-diagnostics/src/handlers/invalid_derive_target.rs#3) - - -This diagnostic is shown when the derive attribute is used on an item other than a `struct`, -`enum` or `union`. - - - - -#### macro-def-error - -Source: [macro_error.rs](crates/ide-diagnostics/src/handlers/macro_error.rs#24) - - -This diagnostic is shown for macro expansion errors. - - - - -#### macro-error - -Source: [macro_error.rs](crates/ide-diagnostics/src/handlers/macro_error.rs#3) - - -This diagnostic is shown for macro expansion errors. - - - - -#### malformed-derive - -Source: [malformed_derive.rs](crates/ide-diagnostics/src/handlers/malformed_derive.rs#3) - - -This diagnostic is shown when the derive attribute has invalid input. - - - - -#### mismatched-arg-count - -Source: [mismatched_arg_count.rs](crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs#31) - - -This diagnostic is triggered if a function is invoked with an incorrect amount of arguments. - - - - -#### mismatched-tuple-struct-pat-arg-count - -Source: [mismatched_arg_count.rs](crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs#11) - - -This diagnostic is triggered if a function is invoked with an incorrect amount of arguments. - - - - -#### missing-fields - -Source: [missing_fields.rs](crates/ide-diagnostics/src/handlers/missing_fields.rs#19) - - -This diagnostic is triggered if record lacks some fields that exist in the corresponding structure. - -Example: - -```rust -struct A { a: u8, b: u8 } - -let a = A { a: 10 }; -``` - - - - -#### missing-match-arm - -Source: [missing_match_arms.rs](crates/ide-diagnostics/src/handlers/missing_match_arms.rs#3) - - -This diagnostic is triggered if `match` block is missing one or more match arms. - - - - -#### missing-unsafe - -Source: [missing_unsafe.rs](crates/ide-diagnostics/src/handlers/missing_unsafe.rs#10) - - -This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block. - - - - -#### moved-out-of-ref - -Source: [moved_out_of_ref.rs](crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs#4) - - -This diagnostic is triggered on moving non copy things out of references. - - - - -#### need-mut - -Source: [mutability_errors.rs](crates/ide-diagnostics/src/handlers/mutability_errors.rs#8) - - -This diagnostic is triggered on mutating an immutable variable. - - - - -#### no-such-field - -Source: [no_such_field.rs](crates/ide-diagnostics/src/handlers/no_such_field.rs#12) - - -This diagnostic is triggered if created structure does not have field provided in record. - - - - -#### non-exhaustive-let - -Source: [non_exhaustive_let.rs](crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs#3) - - -This diagnostic is triggered if a `let` statement without an `else` branch has a non-exhaustive -pattern. - - - - -#### private-assoc-item - -Source: [private_assoc_item.rs](crates/ide-diagnostics/src/handlers/private_assoc_item.rs#3) - - -This diagnostic is triggered if the referenced associated item is not visible from the current -module. - - - - -#### private-field - -Source: [private_field.rs](crates/ide-diagnostics/src/handlers/private_field.rs#3) - - -This diagnostic is triggered if the accessed field is not visible from the current module. - - - - -#### proc-macro-disabled - -Source: [macro_error.rs](crates/ide-diagnostics/src/handlers/macro_error.rs#11) - - -This diagnostic is shown for proc macros that have been specifically disabled via `rust-analyzer.procMacro.ignored`. - - - - -#### remove-trailing-return - -Source: [remove_trailing_return.rs](crates/ide-diagnostics/src/handlers/remove_trailing_return.rs#8) - - -This diagnostic is triggered when there is a redundant `return` at the end of a function -or closure. - - - - -#### remove-unnecessary-else - -Source: [remove_unnecessary_else.rs](crates/ide-diagnostics/src/handlers/remove_unnecessary_else.rs#17) - - -This diagnostic is triggered when there is an `else` block for an `if` expression whose -then branch diverges (e.g. ends with a `return`, `continue`, `break` e.t.c). - - - - -#### replace-filter-map-next-with-find-map - -Source: [replace_filter_map_next_with_find_map.rs](crates/ide-diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs#11) - - -This diagnostic is triggered when `.filter_map(..).next()` is used, rather than the more concise `.find_map(..)`. - - - - -#### trait-impl-incorrect-safety - -Source: [trait_impl_incorrect_safety.rs](crates/ide-diagnostics/src/handlers/trait_impl_incorrect_safety.rs#6) - - -Diagnoses incorrect safety annotations of trait impls. - - - - -#### trait-impl-missing-assoc_item - -Source: [trait_impl_missing_assoc_item.rs](crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs#7) - - -Diagnoses missing trait items in a trait impl. - - - - -#### trait-impl-orphan - -Source: [trait_impl_orphan.rs](crates/ide-diagnostics/src/handlers/trait_impl_orphan.rs#5) - - -Only traits defined in the current crate can be implemented for arbitrary types - - - - -#### trait-impl-redundant-assoc_item - -Source: [trait_impl_redundant_assoc_item.rs](crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs#12) - - -Diagnoses redundant trait items in a trait impl. - - - - -#### type-mismatch - -Source: [type_mismatch.rs](crates/ide-diagnostics/src/handlers/type_mismatch.rs#20) - - -This diagnostic is triggered when the type of an expression or pattern does not match -the expected type. - - - - -#### typed-hole - -Source: [typed_hole.rs](crates/ide-diagnostics/src/handlers/typed_hole.rs#18) - - -This diagnostic is triggered when an underscore expression is used in an invalid position. - - - - -#### undeclared-label - -Source: [undeclared_label.rs](crates/ide-diagnostics/src/handlers/undeclared_label.rs#3) - - - - - - -#### unimplemented-builtin-macro - -Source: [unimplemented_builtin_macro.rs](crates/ide-diagnostics/src/handlers/unimplemented_builtin_macro.rs#3) - - -This diagnostic is shown for builtin macros which are not yet implemented by rust-analyzer - - - - -#### unlinked-file - -Source: [unlinked_file.rs](crates/ide-diagnostics/src/handlers/unlinked_file.rs#20) - - -This diagnostic is shown for files that are not included in any crate, or files that are part of -crates rust-analyzer failed to discover. The file will not have IDE features available. - - - - -#### unnecessary-braces - -Source: [useless_braces.rs](crates/ide-diagnostics/src/handlers/useless_braces.rs#9) - - -Diagnostic for unnecessary braces in `use` items. - - - - -#### unreachable-label - -Source: [unreachable_label.rs](crates/ide-diagnostics/src/handlers/unreachable_label.rs#3) - - - - - - -#### unresolved-assoc-item - -Source: [unresolved_assoc_item.rs](crates/ide-diagnostics/src/handlers/unresolved_assoc_item.rs#3) - - -This diagnostic is triggered if the referenced associated item does not exist. - - - - -#### unresolved-extern-crate - -Source: [unresolved_extern_crate.rs](crates/ide-diagnostics/src/handlers/unresolved_extern_crate.rs#3) - - -This diagnostic is triggered if rust-analyzer is unable to discover referred extern crate. - - - - -#### unresolved-field - -Source: [unresolved_field.rs](crates/ide-diagnostics/src/handlers/unresolved_field.rs#23) - - -This diagnostic is triggered if a field does not exist on a given type. - - - - -#### unresolved-ident - -Source: [unresolved_ident.rs](crates/ide-diagnostics/src/handlers/unresolved_ident.rs#3) - - -This diagnostic is triggered if an expr-position ident is invalid. - - - - -#### unresolved-import - -Source: [unresolved_import.rs](crates/ide-diagnostics/src/handlers/unresolved_import.rs#3) - - -This diagnostic is triggered if rust-analyzer is unable to resolve a path in -a `use` declaration. - - - - -#### unresolved-macro-call - -Source: [unresolved_macro_call.rs](crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs#3) - - -This diagnostic is triggered if rust-analyzer is unable to resolve the path -to a macro in a macro invocation. - - - - -#### unresolved-method - -Source: [unresolved_method.rs](crates/ide-diagnostics/src/handlers/unresolved_method.rs#15) - - -This diagnostic is triggered if a method does not exist on a given type. - - - - -#### unresolved-module - -Source: [unresolved_module.rs](crates/ide-diagnostics/src/handlers/unresolved_module.rs#8) - - -This diagnostic is triggered if rust-analyzer is unable to discover referred module. - - - - -#### unused-mut - -Source: [mutability_errors.rs](crates/ide-diagnostics/src/handlers/mutability_errors.rs#62) - - -This diagnostic is triggered when a mutable variable isn't actually mutated. - - - - -#### unused-variables - -Source: [unused_variables.rs](crates/ide-diagnostics/src/handlers/unused_variables.rs#13) - - -This diagnostic is triggered when a local variable is not used. - - diff --git a/src/tools/rust-analyzer/docs/book/src/features_generated.md b/src/tools/rust-analyzer/docs/book/src/features_generated.md deleted file mode 100644 index 2c5829b1f54c0..0000000000000 --- a/src/tools/rust-analyzer/docs/book/src/features_generated.md +++ /dev/null @@ -1,940 +0,0 @@ -//! Generated by `cargo xtask codegen feature-docs`, do not edit by hand. - -### Annotations -**Source:** [annotations.rs](crates/ide/src/annotations.rs#19) - -Provides user with annotations above items for looking up references or impl blocks -and running/debugging binaries. - -![Annotations](https://user-images.githubusercontent.com/48062697/113020672-b7c34f00-917a-11eb-8f6e-858735660a0e.png) - - -### Auto Import -**Source:** [auto_import.rs](crates/ide-assists/src/handlers/auto_import.rs#15) - -Using the `auto-import` assist it is possible to insert missing imports for unresolved items. -When inserting an import it will do so in a structured manner by keeping imports grouped, -separated by a newline in the following order: - -- `std` and `core` -- External Crates -- Current Crate, paths prefixed by `crate` -- Current Module, paths prefixed by `self` -- Super Module, paths prefixed by `super` - -Example: -```rust -use std::fs::File; - -use itertools::Itertools; -use syntax::ast; - -use crate::utils::insert_use; - -use self::auto_import; - -use super::AssistContext; -``` - -#### Import Granularity - -It is possible to configure how use-trees are merged with the `imports.granularity.group` setting. -It has the following configurations: - -- `crate`: Merge imports from the same crate into a single use statement. This kind of - nesting is only supported in Rust versions later than 1.24. -- `module`: Merge imports from the same module into a single use statement. -- `item`: Don't merge imports at all, creating one import per item. -- `preserve`: Do not change the granularity of any imports. For auto-import this has the same - effect as `item`. -- `one`: Merge all imports into a single use statement as long as they have the same visibility - and attributes. - -In `VS Code` the configuration for this is `rust-analyzer.imports.granularity.group`. - -#### Import Prefix - -The style of imports in the same crate is configurable through the `imports.prefix` setting. -It has the following configurations: - -- `crate`: This setting will force paths to be always absolute, starting with the `crate` - prefix, unless the item is defined outside of the current crate. -- `self`: This setting will force paths that are relative to the current module to always - start with `self`. This will result in paths that always start with either `crate`, `self`, - `super` or an extern crate identifier. -- `plain`: This setting does not impose any restrictions in imports. - -In `VS Code` the configuration for this is `rust-analyzer.imports.prefix`. - -![Auto Import](https://user-images.githubusercontent.com/48062697/113020673-b85be580-917a-11eb-9022-59585f35d4f8.gif) - - -### Completion With Autoimport -**Source:** [flyimport.rs](crates/ide-completion/src/completions/flyimport.rs#20) - -When completing names in the current scope, proposes additional imports from other modules or crates, -if they can be qualified in the scope, and their name contains all symbols from the completion input. - -To be considered applicable, the name must contain all input symbols in the given order, not necessarily adjacent. -If any input symbol is not lowercased, the name must contain all symbols in exact case; otherwise the containing is checked case-insensitively. - -``` -fn main() { - pda$0 -} -# pub mod std { pub mod marker { pub struct PhantomData { } } } -``` --> -``` -use std::marker::PhantomData; - -fn main() { - PhantomData -} -# pub mod std { pub mod marker { pub struct PhantomData { } } } -``` - -Also completes associated items, that require trait imports. -If any unresolved and/or partially-qualified path precedes the input, it will be taken into account. -Currently, only the imports with their import path ending with the whole qualifier will be proposed -(no fuzzy matching for qualifier). - -``` -mod foo { - pub mod bar { - pub struct Item; - - impl Item { - pub const TEST_ASSOC: usize = 3; - } - } -} - -fn main() { - bar::Item::TEST_A$0 -} -``` --> -``` -use foo::bar; - -mod foo { - pub mod bar { - pub struct Item; - - impl Item { - pub const TEST_ASSOC: usize = 3; - } - } -} - -fn main() { - bar::Item::TEST_ASSOC -} -``` - -NOTE: currently, if an assoc item comes from a trait that's not currently imported, and it also has an unresolved and/or partially-qualified path, -no imports will be proposed. - -#### Fuzzy search details - -To avoid an excessive amount of the results returned, completion input is checked for inclusion in the names only -(i.e. in `HashMap` in the `std::collections::HashMap` path). -For the same reasons, avoids searching for any path imports for inputs with their length less than 2 symbols -(but shows all associated items for any input length). - -#### Import configuration - -It is possible to configure how use-trees are merged with the `imports.granularity.group` setting. -Mimics the corresponding behavior of the `Auto Import` feature. - -#### LSP and performance implications - -The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits` -(case-sensitive) resolve client capability in its client capabilities. -This way the server is able to defer the costly computations, doing them for a selected completion item only. -For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones, -which might be slow ergo the feature is automatically disabled. - -#### Feature toggle - -The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.autoimport.enable` flag. -Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corresponding -capability enabled. - - -### Debug ItemTree -**Source:** [view_item_tree.rs](crates/ide/src/view_item_tree.rs#5) - -Displays the ItemTree of the currently open file, for debugging. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Debug ItemTree** | - - -### Expand Macro Recursively -**Source:** [expand_macro.rs](crates/ide/src/expand_macro.rs#18) - -Shows the full macro expansion of the macro at the current caret position. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Expand macro recursively at caret** | - -![Expand Macro Recursively](https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif) - - -### Expand and Shrink Selection -**Source:** [extend_selection.rs](crates/ide/src/extend_selection.rs#15) - -Extends or shrinks the current selection to the encompassing syntactic construct -(expression, statement, item, module, etc). It works with multiple cursors. - -| Editor | Shortcut | -|---------|----------| -| VS Code | Alt+Shift+→, Alt+Shift+← | - -![Expand and Shrink Selection](https://user-images.githubusercontent.com/48062697/113020651-b42fc800-917a-11eb-8a4f-cf1a07859fac.gif) - - -### File Structure -**Source:** [file_structure.rs](crates/ide/src/file_structure.rs#26) - -Provides a tree of the symbols defined in the file. Can be used to - -* fuzzy search symbol in a file (super useful) -* draw breadcrumbs to describe the context around the cursor -* draw outline of the file - -| Editor | Shortcut | -|---------|----------| -| VS Code | Ctrl+Shift+O | - -![File Structure](https://user-images.githubusercontent.com/48062697/113020654-b42fc800-917a-11eb-8388-e7dc4d92b02e.gif) - - -### Find All References -**Source:** [references.rs](crates/ide/src/references.rs#42) - -Shows all references of the item at the cursor location - -| Editor | Shortcut | -|---------|----------| -| VS Code | Shift+Alt+F12 | - -![Find All References](https://user-images.githubusercontent.com/48062697/113020670-b7c34f00-917a-11eb-8003-370ac5f2b3cb.gif) - - -### Folding -**Source:** [folding_ranges.rs](crates/ide/src/folding_ranges.rs#36) - -Defines folding regions for curly braced blocks, runs of consecutive use, mod, const or static -items, and `region` / `endregion` comment markers. - - -### Format String Completion -**Source:** [format_like.rs](crates/ide-completion/src/completions/postfix/format_like.rs#0) - -`"Result {result} is {2 + 2}"` is expanded to the `"Result {} is {}", result, 2 + 2`. - -The following postfix snippets are available: - -* `format` -> `format!(...)` -* `panic` -> `panic!(...)` -* `println` -> `println!(...)` -* `log`: -** `logd` -> `log::debug!(...)` -** `logt` -> `log::trace!(...)` -** `logi` -> `log::info!(...)` -** `logw` -> `log::warn!(...)` -** `loge` -> `log::error!(...)` - -![Format String Completion](https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif) - - -### Go to Declaration -**Source:** [goto_declaration.rs](crates/ide/src/goto_declaration.rs#13) - -Navigates to the declaration of an identifier. - -This is the same as `Go to Definition` with the following exceptions: -- outline modules will navigate to the `mod name;` item declaration -- trait assoc items will navigate to the assoc item of the trait declaration as opposed to the trait impl -- fields in patterns will navigate to the field declaration of the struct, union or variant - - -### Go to Definition -**Source:** [goto_definition.rs](crates/ide/src/goto_definition.rs#28) - -Navigates to the definition of an identifier. - -For outline modules, this will navigate to the source file of the module. - -| Editor | Shortcut | -|---------|----------| -| VS Code | F12 | - -![Go to Definition](https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif) - - -### Go to Implementation -**Source:** [goto_implementation.rs](crates/ide/src/goto_implementation.rs#11) - -Navigates to the impl items of types. - -| Editor | Shortcut | -|---------|----------| -| VS Code | Ctrl+F12 - -![Go to Implementation](https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif) - - -### Go to Type Definition -**Source:** [goto_type_definition.rs](crates/ide/src/goto_type_definition.rs#7) - -Navigates to the type of an identifier. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **Go to Type Definition** | - -![Go to Type Definition](https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif) - - -### Highlight Related -**Source:** [highlight_related.rs](crates/ide/src/highlight_related.rs#42) - -Highlights constructs related to the thing under the cursor: - -1. if on an identifier, highlights all references to that identifier in the current file - * additionally, if the identifier is a trait in a where clause, type parameter trait bound or use item, highlights all references to that trait's assoc items in the corresponding scope -1. if on an `async` or `await` token, highlights all yield points for that async context -1. if on a `return` or `fn` keyword, `?` character or `->` return type arrow, highlights all exit points for that context -1. if on a `break`, `loop`, `while` or `for` token, highlights all break points for that loop or block context -1. if on a `move` or `|` token that belongs to a closure, highlights all captures of the closure. - -Note: `?`, `|` and `->` do not currently trigger this behavior in the VSCode editor. - - -### Hover -**Source:** [hover.rs](crates/ide/src/hover.rs#116) - -Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code. -Focusing is usually hovering with a mouse, but can also be triggered with a shortcut. - -![Hover](https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif) - - -### Inlay Hints -**Source:** [inlay_hints.rs](crates/ide/src/inlay_hints.rs#41) - -rust-analyzer shows additional information inline with the source code. -Editors usually render this using read-only virtual text snippets interspersed with code. - -rust-analyzer by default shows hints for - -* types of local variables -* names of function arguments -* names of const generic parameters -* types of chained expressions - -Optionally, one can enable additional hints for - -* return types of closure expressions -* elided lifetimes -* compiler inserted reborrows -* names of generic type and lifetime parameters - -Note: inlay hints for function argument names are heuristically omitted to reduce noise and will not appear if -any of the -[following criteria](https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L92-L99) -are met: - -* the parameter name is a suffix of the function's name -* the argument is a qualified constructing or call expression where the qualifier is an ADT -* exact argument<->parameter match(ignoring leading underscore) or parameter is a prefix/suffix - of argument with _ splitting it off -* the parameter name starts with `ra_fixture` -* the parameter name is a -[well known name](https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L200) -in a unary function -* the parameter name is a -[single character](https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L201) -in a unary function - -![Inlay hints](https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png) - - -### Interpret A Function, Static Or Const. -**Source:** [interpret.rs](crates/ide/src/interpret.rs#8) - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Interpret** | - - -### Join Lines -**Source:** [join_lines.rs](crates/ide/src/join_lines.rs#20) - -Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces. - -See [this gif](https://user-images.githubusercontent.com/1711539/124515923-4504e800-dde9-11eb-8d58-d97945a1a785.gif) for the cases handled specially by joined lines. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Join lines** | - -![Join Lines](https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif) - - -### Magic Completions -**Source:** [lib.rs](crates/ide-completion/src/lib.rs#78) - -In addition to usual reference completion, rust-analyzer provides some ✨magic✨ -completions as well: - -Keywords like `if`, `else` `while`, `loop` are completed with braces, and cursor -is placed at the appropriate position. Even though `if` is easy to type, you -still want to complete it, to get ` { }` for free! `return` is inserted with a -space or `;` depending on the return type of the function. - -When completing a function call, `()` are automatically inserted. If a function -takes arguments, the cursor is positioned inside the parenthesis. - -There are postfix completions, which can be triggered by typing something like -`foo().if`. The word after `.` determines postfix completion. Possible variants are: - -- `expr.if` -> `if expr {}` or `if let ... {}` for `Option` or `Result` -- `expr.match` -> `match expr {}` -- `expr.while` -> `while expr {}` or `while let ... {}` for `Option` or `Result` -- `expr.ref` -> `&expr` -- `expr.refm` -> `&mut expr` -- `expr.let` -> `let $0 = expr;` -- `expr.lete` -> `let $1 = expr else { $0 };` -- `expr.letm` -> `let mut $0 = expr;` -- `expr.not` -> `!expr` -- `expr.dbg` -> `dbg!(expr)` -- `expr.dbgr` -> `dbg!(&expr)` -- `expr.call` -> `(expr)` - -There also snippet completions: - -#### Expressions - -- `pd` -> `eprintln!(" = {:?}", );` -- `ppd` -> `eprintln!(" = {:#?}", );` - -#### Items - -- `tfn` -> `#[test] fn feature(){}` -- `tmod` -> -```rust -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_name() {} -} -``` - -And the auto import completions, enabled with the `rust-analyzer.completion.autoimport.enable` setting and the corresponding LSP client capabilities. -Those are the additional completion options with automatic `use` import and options from all project importable items, -fuzzy matched against the completion input. - -![Magic Completions](https://user-images.githubusercontent.com/48062697/113020667-b72ab880-917a-11eb-8778-716cf26a0eb3.gif) - - -### Matching Brace -**Source:** [matching_brace.rs](crates/ide/src/matching_brace.rs#6) - -If the cursor is on any brace (`<>(){}[]||`) which is a part of a brace-pair, -moves cursor to the matching brace. It uses the actual parser to determine -braces, so it won't confuse generics with comparisons. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Find matching brace** | - -![Matching Brace](https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif) - - -### Memory Usage -**Source:** [apply_change.rs](crates/ide-db/src/apply_change.rs#43) - -Clears rust-analyzer's internal database and prints memory usage statistics. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Memory Usage (Clears Database)** - - -### Move Item -**Source:** [move_item.rs](crates/ide/src/move_item.rs#16) - -Move item under cursor or selection up and down. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Move item up** -| VS Code | **rust-analyzer: Move item down** - -![Move Item](https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif) - - -### On Enter -**Source:** [on_enter.rs](crates/ide/src/typing/on_enter.rs#17) - -rust-analyzer can override Enter key to make it smarter: - -- Enter inside triple-slash comments automatically inserts `///` -- Enter in the middle or after a trailing space in `//` inserts `//` -- Enter inside `//!` doc comments automatically inserts `//!` -- Enter after `{` indents contents and closing `}` of single-line block - -This action needs to be assigned to shortcut explicitly. - -Note that, depending on the other installed extensions, this feature can visibly slow down typing. -Similarly, if rust-analyzer crashes or stops responding, `Enter` might not work. -In that case, you can still press `Shift-Enter` to insert a newline. - -#### VS Code - -Add the following to `keybindings.json`: -```json -{ - "key": "Enter", - "command": "rust-analyzer.onEnter", - "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust" -} -```` - -When using the Vim plugin: -```json -{ - "key": "Enter", - "command": "rust-analyzer.onEnter", - "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust && vim.mode == 'Insert'" -} -```` - -![On Enter](https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif) - - -### On Typing Assists -**Source:** [typing.rs](crates/ide/src/typing.rs#42) - -Some features trigger on typing certain characters: - -- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression -- typing `=` between two expressions adds `;` when in statement position -- typing `=` to turn an assignment into an equality comparison removes `;` when in expression position -- typing `.` in a chain method call auto-indents -- typing `{` or `(` in front of an expression inserts a closing `}` or `)` after the expression -- typing `{` in a use item adds a closing `}` in the right place -- typing `>` to complete a return type `->` will insert a whitespace after it - -#### VS Code - -Add the following to `settings.json`: -```json -"editor.formatOnType": true, -``` - -![On Typing Assists](https://user-images.githubusercontent.com/48062697/113166163-69758500-923a-11eb-81ee-eb33ec380399.gif) -![On Typing Assists](https://user-images.githubusercontent.com/48062697/113171066-105c2000-923f-11eb-87ab-f4a263346567.gif) - - -### Open Docs -**Source:** [doc_links.rs](crates/ide/src/doc_links.rs#118) - -Retrieve a links to documentation for the given symbol. - -The simplest way to use this feature is via the context menu. Right-click on -the selected item. The context menu opens. Select **Open Docs**. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Open Docs** | - - -### Parent Module -**Source:** [parent_module.rs](crates/ide/src/parent_module.rs#14) - -Navigates to the parent module of the current module. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Locate parent module** | - -![Parent Module](https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif) - - -### Related Tests -**Source:** [runnables.rs](crates/ide/src/runnables.rs#202) - -Provides a sneak peek of all tests where the current item is used. - -The simplest way to use this feature is via the context menu. Right-click on -the selected item. The context menu opens. Select **Peek Related Tests**. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Peek Related Tests** | - - -### Rename -**Source:** [rename.rs](crates/ide/src/rename.rs#70) - -Renames the item below the cursor and all of its references - -| Editor | Shortcut | -|---------|----------| -| VS Code | F2 | - -![Rename](https://user-images.githubusercontent.com/48062697/113065582-055aae80-91b1-11eb-8ade-2b58e6d81883.gif) - - -### Run -**Source:** [runnables.rs](crates/ide/src/runnables.rs#116) - -Shows a popup suggesting to run a test/benchmark/binary **at the current cursor -location**. Super useful for repeatedly running just a single test. Do bind this -to a shortcut! - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Run** | - -![Run](https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif) - - -### Semantic Syntax Highlighting -**Source:** [syntax_highlighting.rs](crates/ide/src/syntax_highlighting.rs#68) - -rust-analyzer highlights the code semantically. -For example, `Bar` in `foo::Bar` might be colored differently depending on whether `Bar` is an enum or a trait. -rust-analyzer does not specify colors directly, instead it assigns a tag (like `struct`) and a set of modifiers (like `declaration`) to each token. -It's up to the client to map those to specific colors. - -The general rule is that a reference to an entity gets colored the same way as the entity itself. -We also give special modifier for `mut` and `&mut` local variables. - - -#### Token Tags - -Rust-analyzer currently emits the following token tags: - -- For items: - -| | | -|-----------|--------------------------------| -| attribute | Emitted for attribute macros. | -|enum| Emitted for enums. | -|function| Emitted for free-standing functions. | -|derive| Emitted for derive macros. | -|macro| Emitted for function-like macros. | -|method| Emitted for associated functions, also knowns as methods. | -|namespace| Emitted for modules. | -|struct| Emitted for structs.| -|trait| Emitted for traits.| -|typeAlias| Emitted for type aliases and `Self` in `impl`s.| -|union| Emitted for unions.| - -- For literals: - -| | | -|-----------|--------------------------------| -| boolean| Emitted for the boolean literals `true` and `false`.| -| character| Emitted for character literals.| -| number| Emitted for numeric literals.| -| string| Emitted for string literals.| -| escapeSequence| Emitted for escaped sequences inside strings like `\n`.| -| formatSpecifier| Emitted for format specifiers `{:?}` in `format!`-like macros.| - -- For operators: - -| | | -|-----------|--------------------------------| -|operator| Emitted for general operators.| -|arithmetic| Emitted for the arithmetic operators `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=`.| -|bitwise| Emitted for the bitwise operators `|`, `&`, `!`, `^`, `|=`, `&=`, `^=`.| -|comparison| Emitted for the comparison oerators `>`, `<`, `==`, `>=`, `<=`, `!=`.| -|logical| Emitted for the logical operatos `||`, `&&`, `!`.| - -- For punctuation: - -| | | -|-----------|--------------------------------| -|punctuation| Emitted for general punctuation.| -|attributeBracket| Emitted for attribute invocation brackets, that is the `#[` and `]` tokens.| -|angle| Emitted for `<>` angle brackets.| -|brace| Emitted for `{}` braces.| -|bracket| Emitted for `[]` brackets.| -|parenthesis| Emitted for `()` parentheses.| -|colon| Emitted for the `:` token.| -|comma| Emitted for the `,` token.| -|dot| Emitted for the `.` token.| -|semi| Emitted for the `;` token.| -|macroBang| Emitted for the `!` token in macro calls.| - -- - -| | | -|-----------|--------------------------------| -|builtinAttribute| Emitted for names to builtin attributes in attribute path, the `repr` in `#[repr(u8)]` for example.| -|builtinType| Emitted for builtin types like `u32`, `str` and `f32`.| -|comment| Emitted for comments.| -|constParameter| Emitted for const parameters.| -|deriveHelper| Emitted for derive helper attributes.| -|enumMember| Emitted for enum variants.| -|generic| Emitted for generic tokens that have no mapping.| -|keyword| Emitted for keywords.| -|label| Emitted for labels.| -|lifetime| Emitted for lifetimes.| -|parameter| Emitted for non-self function parameters.| -|property| Emitted for struct and union fields.| -|selfKeyword| Emitted for the self function parameter and self path-specifier.| -|selfTypeKeyword| Emitted for the Self type parameter.| -|toolModule| Emitted for tool modules.| -|typeParameter| Emitted for type parameters.| -|unresolvedReference| Emitted for unresolved references, names that rust-analyzer can't find the definition of.| -|variable| Emitted for locals, constants and statics.| - - -#### Token Modifiers - -Token modifiers allow to style some elements in the source code more precisely. - -Rust-analyzer currently emits the following token modifiers: - -| | | -|-----------|--------------------------------| -|async| Emitted for async functions and the `async` and `await` keywords.| -|attribute| Emitted for tokens inside attributes.| -|callable| Emitted for locals whose types implements one of the `Fn*` traits.| -|constant| Emitted for const.| -|consuming| Emitted for locals that are being consumed when use in a function call.| -|controlFlow| Emitted for control-flow related tokens, this includes th `?` operator.| -|crateRoot| Emitted for crate names, like `serde` and `crate.| -|declaration| Emitted for names of definitions, like `foo` in `fn foo(){}`.| -|defaultLibrary| Emitted for items from built-in crates (std, core, allc, test and proc_macro).| -|documentation| Emitted for documentation comment.| -|injected| Emitted for doc-string injected highlighting like rust source blocks in documentation.| -|intraDocLink| Emitted for intra doc links in doc-string.| -|library| Emitted for items that are defined outside of the current crae.| -|macro| Emitted for tokens inside macro call.| -|mutable| Emitted for mutable locals and statics as well as functions taking `&mut self`.| -|public| Emitted for items that are from the current crate and are `pub.| -|reference| Emitted for locals behind a reference and functions taking self` by reference.| -|static| Emitted for "static" functions, also known as functions that d not take a `self` param, as well as statics and consts.| -|trait| Emitted for associated trait item.| -|unsafe| Emitted for unsafe operations, like unsafe function calls, as ell as the `unsafe` token.| - -![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png) -![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png) - - -### Show Dependency Tree -**Source:** [fetch_crates.rs](crates/ide/src/fetch_crates.rs#13) - -Shows a view tree with all the dependencies of this project - -| Editor | Panel Name | -|---------|------------| -| VS Code | **Rust Dependencies** | - -![Show Dependency Tree](https://user-images.githubusercontent.com/5748995/229394139-2625beab-f4c9-484b-84ed-ad5dee0b1e1a.png) - - -### Show Syntax Tree -**Source:** [view_syntax_tree.rs](crates/ide/src/view_syntax_tree.rs#14) - -Shows a tree view with the syntax tree of the current file - -| Editor | Panel Name | -|---------|-------------| -| VS Code | **Rust Syntax Tree** | - - -### Status -**Source:** [status.rs](crates/ide/src/status.rs#28) - -Shows internal statistic about memory usage of rust-analyzer. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: Status** | - -![Status](https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif) - - -### Structural Search and Replace -**Source:** [lib.rs](crates/ide-ssr/src/lib.rs#6) - -Search and replace with named wildcards that will match any expression, type, path, pattern or item. -The syntax for a structural search replace command is ` ==>> `. -A `$` placeholder in the search pattern will match any AST node and `$` will reference it in the replacement. -Within a macro call, a placeholder will match up until whatever token follows the placeholder. - -All paths in both the search pattern and the replacement template must resolve in the context -in which this command is invoked. Paths in the search pattern will then match the code if they -resolve to the same item, even if they're written differently. For example if we invoke the -command in the module `foo` with a pattern of `Bar`, then code in the parent module that refers -to `foo::Bar` will match. - -Paths in the replacement template will be rendered appropriately for the context in which the -replacement occurs. For example if our replacement template is `foo::Bar` and we match some -code in the `foo` module, we'll insert just `Bar`. - -Inherent method calls should generally be written in UFCS form. e.g. `foo::Bar::baz($s, $a)` will -match `$s.baz($a)`, provided the method call `baz` resolves to the method `foo::Bar::baz`. When a -placeholder is the receiver of a method call in the search pattern (e.g. `$s.foo()`), but not in -the replacement template (e.g. `bar($s)`), then *, & and &mut will be added as needed to mirror -whatever autoderef and autoref was happening implicitly in the matched code. - -The scope of the search / replace will be restricted to the current selection if any, otherwise -it will apply to the whole workspace. - -Placeholders may be given constraints by writing them as `${::...}`. - -Supported constraints: - -| Constraint | Restricts placeholder | -|---------------|------------------------| -| kind(literal) | Is a literal (e.g. `42` or `"forty two"`) | -| not(a) | Negates the constraint `a` | - -Available via the command `rust-analyzer.ssr`. - -```rust -// Using structural search replace command [foo($a, $b) ==>> ($a).foo($b)] - -// BEFORE -String::from(foo(y + 5, z)) - -// AFTER -String::from((y + 5).foo(z)) -``` - -| Editor | Action Name | -|---------|--------------| -| VS Code | **rust-analyzer: Structural Search Replace** | - -Also available as an assist, by writing a comment containing the structural -search and replace rule. You will only see the assist if the comment can -be parsed as a valid structural search and replace rule. - -```rust -// Place the cursor on the line below to see the assist 💡. -// foo($a, $b) ==>> ($a).foo($b) -``` - - -### User Snippet Completions -**Source:** [snippet.rs](crates/ide-completion/src/snippet.rs#5) - -rust-analyzer allows the user to define custom (postfix)-snippets that may depend on items to be accessible for the current scope to be applicable. - -A custom snippet can be defined by adding it to the `rust-analyzer.completion.snippets.custom` object respectively. - -```json -{ - "rust-analyzer.completion.snippets.custom": { - "thread spawn": { - "prefix": ["spawn", "tspawn"], - "body": [ - "thread::spawn(move || {", - "\t$0", - "});", - ], - "description": "Insert a thread::spawn call", - "requires": "std::thread", - "scope": "expr", - } - } -} -``` - -In the example above: - -* `"thread spawn"` is the name of the snippet. - -* `prefix` defines one or more trigger words that will trigger the snippets completion. -Using `postfix` will instead create a postfix snippet. - -* `body` is one or more lines of content joined via newlines for the final output. - -* `description` is an optional description of the snippet, if unset the snippet name will be used. - -* `requires` is an optional list of item paths that have to be resolvable in the current crate where the completion is rendered. - - -### View Crate Graph -**Source:** [view_crate_graph.rs](crates/ide/src/view_crate_graph.rs#8) - -Renders the currently loaded crate graph as an SVG graphic. Requires the `dot` tool, which -is part of graphviz, to be installed. - -Only workspace crates are included, no crates.io dependencies or sysroot crates. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: View Crate Graph** | - - -### View Hir -**Source:** [view_hir.rs](crates/ide/src/view_hir.rs#5) - -| Editor | Action Name | -|---------|--------------| -| VS Code | **rust-analyzer: View Hir** - -![View Hir](https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif) - - -### View Memory Layout -**Source:** [view_memory_layout.rs](crates/ide/src/view_memory_layout.rs#74) - -Displays the recursive memory layout of a datatype. - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: View Memory Layout** | - - -### View Mir -**Source:** [view_mir.rs](crates/ide/src/view_mir.rs#5) - -| Editor | Action Name | -|---------|-------------| -| VS Code | **rust-analyzer: View Mir** - - -### Workspace Symbol -**Source:** [symbol_index.rs](crates/ide-db/src/symbol_index.rs#174) - -Uses fuzzy-search to find types, modules and functions by name across your -project and dependencies. This is **the** most useful feature, which improves code -navigation tremendously. It mostly works on top of the built-in LSP -functionality, however `#` and `*` symbols can be used to narrow down the -search. Specifically, - -- `Foo` searches for `Foo` type in the current workspace -- `foo#` searches for `foo` function in the current workspace -- `Foo*` searches for `Foo` type among dependencies, including `stdlib` -- `foo#*` searches for `foo` function among dependencies - -That is, `#` switches from "types" to all symbols, `*` switches from the current -workspace to dependencies. - -Note that filtering does not currently work in VSCode due to the editor never -sending the special symbols to the language server. Instead, you can configure -the filtering via the `rust-analyzer.workspace.symbol.search.scope` and -`rust-analyzer.workspace.symbol.search.kind` settings. Symbols prefixed -with `__` are hidden from the search results unless configured otherwise. - -| Editor | Shortcut | -|---------|-----------| -| VS Code | Ctrl+T From 3ae6a540d75b0378d0f9c2d9d01c1d64bd10ebb9 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 10 Mar 2025 12:31:55 +0530 Subject: [PATCH 008/260] doc: add doc to proc-macro-api --- .../src/legacy_protocol/json.rs | 2 + .../proc-macro-api/src/legacy_protocol/msg.rs | 44 ++++++++++++++++++- .../crates/proc-macro-api/src/lib.rs | 12 +++++ .../crates/proc-macro-api/src/process.rs | 14 ++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs index ec89f6a9e65d2..8e50ed5a8589d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs @@ -1,6 +1,7 @@ //! Protocol functions for json. use std::io::{self, BufRead, Write}; +/// Reads a JSON message from the input stream. pub fn read_json<'a>( inp: &mut impl BufRead, buf: &'a mut String, @@ -26,6 +27,7 @@ pub fn read_json<'a>( } } +/// Writes a JSON message to the output stream. pub fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> { tracing::debug!("> {}", msg); out.write_all(msg.as_bytes())?; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs index 4b831e4acebb9..968150c12b59a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs @@ -20,69 +20,103 @@ pub const VERSION_CHECK_VERSION: u32 = 1; pub const ENCODE_CLOSE_SPAN_VERSION: u32 = 2; pub const HAS_GLOBAL_SPANS: u32 = 3; pub const RUST_ANALYZER_SPAN_SUPPORT: u32 = 4; -/// Whether literals encode their kind as an additional u32 field and idents their rawness as a u32 field +/// Whether literals encode their kind as an additional u32 field and idents their rawness as a u32 field. pub const EXTENDED_LEAF_DATA: u32 = 5; +/// Current API version of the proc-macro protocol. pub const CURRENT_API_VERSION: u32 = EXTENDED_LEAF_DATA; +/// Represents requests sent from the client to the proc-macro-srv. #[derive(Debug, Serialize, Deserialize)] pub enum Request { + /// Retrieves a list of macros from a given dynamic library. /// Since [`NO_VERSION_CHECK_VERSION`] ListMacros { dylib_path: Utf8PathBuf }, + + /// Expands a procedural macro. /// Since [`NO_VERSION_CHECK_VERSION`] ExpandMacro(Box), + + /// Performs an API version check between the client and the server. /// Since [`VERSION_CHECK_VERSION`] ApiVersionCheck {}, + + /// Sets server-specific configurations. /// Since [`RUST_ANALYZER_SPAN_SUPPORT`] SetConfig(ServerConfig), } +/// Defines the mode used for handling span data. #[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub enum SpanMode { + /// Default mode, where spans are identified by an ID. #[default] Id, + + /// Rust Analyzer-specific span handling mode. RustAnalyzer, } +/// Represents responses sent from the proc-macro-srv to the client. #[derive(Debug, Serialize, Deserialize)] pub enum Response { + /// Returns a list of available macros in a dynamic library. /// Since [`NO_VERSION_CHECK_VERSION`] ListMacros(Result, String>), + + /// Returns result of a macro expansion. /// Since [`NO_VERSION_CHECK_VERSION`] ExpandMacro(Result), + + /// Returns the API version supported by the server. /// Since [`NO_VERSION_CHECK_VERSION`] ApiVersionCheck(u32), + + /// Confirms the application of a configuration update. /// Since [`RUST_ANALYZER_SPAN_SUPPORT`] SetConfig(ServerConfig), + + /// Returns the result of a macro expansion, including extended span data. /// Since [`RUST_ANALYZER_SPAN_SUPPORT`] ExpandMacroExtended(Result), } +/// Configuration settings for the proc-macro-srv. #[derive(Debug, Serialize, Deserialize, Default)] #[serde(default)] pub struct ServerConfig { + /// Defines how span data should be handled. pub span_mode: SpanMode, } +/// Represents an extended macro expansion response, including span data mappings. #[derive(Debug, Serialize, Deserialize)] pub struct ExpandMacroExtended { + /// The expanded syntax tree. pub tree: FlatTree, + /// Additional span data mappings. pub span_data_table: Vec, } +/// Represents an error message when a macro expansion results in a panic. #[derive(Debug, Serialize, Deserialize)] pub struct PanicMessage(pub String); +/// Represents a macro expansion request sent from the client. #[derive(Debug, Serialize, Deserialize)] pub struct ExpandMacro { + /// The path to the dynamic library containing the macro. pub lib: Utf8PathBuf, /// Environment variables to set during macro expansion. pub env: Vec<(String, String)>, + /// The current working directory for the macro expansion. pub current_dir: Option, + /// Macro expansion data, including the macro body, name and attributes. #[serde(flatten)] pub data: ExpandMacroData, } +/// Represents the input data required for expanding a macro. #[derive(Debug, Serialize, Deserialize)] pub struct ExpandMacroData { /// Argument of macro call. @@ -103,18 +137,24 @@ pub struct ExpandMacroData { #[serde(skip_serializing_if = "ExpnGlobals::skip_serializing_if")] #[serde(default)] pub has_global_spans: ExpnGlobals, + /// Table of additional span data. #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] pub span_data_table: Vec, } +/// Represents global expansion settings, including span resolution. #[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct ExpnGlobals { + /// Determines whether to serialize the expansion settings. #[serde(skip_serializing)] #[serde(default)] pub serialize: bool, + /// Defines the `def_site` span location. pub def_site: usize, + /// Defines the `call_site` span location. pub call_site: usize, + /// Defines the `mixed_site` span location. pub mixed_site: usize, } @@ -150,9 +190,11 @@ pub trait Message: serde::Serialize + DeserializeOwned { impl Message for Request {} impl Message for Response {} +/// Type alias for a function that reads protocol messages from a buffered input stream. #[allow(type_alias_bounds)] type ProtocolRead = for<'i, 'buf> fn(inp: &'i mut R, buf: &'buf mut String) -> io::Result>; +/// Type alias for a function that writes protocol messages to an output stream. #[allow(type_alias_bounds)] type ProtocolWrite = for<'o, 'msg> fn(out: &'o mut W, msg: &'msg str) -> io::Result<()>; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index dc3328ebcda48..7061f7ea474c7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -24,9 +24,12 @@ use crate::{ process::ProcMacroServerProcess, }; +/// Represents different kinds of procedural macros that can be expanded by the external server. #[derive(Copy, Clone, Eq, PartialEq, Debug, serde_derive::Serialize, serde_derive::Deserialize)] pub enum ProcMacroKind { + /// A macro that derives implementations for a struct or enum. CustomDerive, + /// An attribute-like procedural macro. Attr, // This used to be called FuncLike, so that's what the server expects currently. #[serde(alias = "Bang")] @@ -46,11 +49,13 @@ pub struct ProcMacroClient { path: AbsPathBuf, } +/// Represents a dynamically loaded library containing procedural macros. pub struct MacroDylib { path: AbsPathBuf, } impl MacroDylib { + /// Creates a new MacroDylib instance with the given path. pub fn new(path: AbsPathBuf) -> MacroDylib { MacroDylib { path } } @@ -78,6 +83,7 @@ impl PartialEq for ProcMacro { } } +/// Represents errors encountered when communicating with the proc-macro server. #[derive(Clone, Debug)] pub struct ServerError { pub message: String, @@ -106,6 +112,7 @@ impl ProcMacroClient { Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) } + /// Returns the absolute path to the proc-macro server. pub fn server_path(&self) -> &AbsPath { &self.path } @@ -130,20 +137,25 @@ impl ProcMacroClient { } } + /// Checks if the proc-macro server has exited. pub fn exited(&self) -> Option<&ServerError> { self.process.exited() } } impl ProcMacro { + /// Returns the name of the procedural macro. pub fn name(&self) -> &str { &self.name } + /// Returns the type of procedural macro. pub fn kind(&self) -> ProcMacroKind { self.kind } + /// Expands the procedural macro by sending an expansion request to the server. + /// This includes span information and environmental context. pub fn expand( &self, subtree: tt::SubtreeView<'_, Span>, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index d998b23d3bbef..d8ae2df7faa94 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -21,6 +21,7 @@ use crate::{ ProcMacroKind, ServerError, }; +/// Represents a process handling proc-macro communication. #[derive(Debug)] pub(crate) struct ProcMacroServerProcess { /// The state of the proc-macro server process, the protocol is currently strictly sequential @@ -32,6 +33,7 @@ pub(crate) struct ProcMacroServerProcess { exited: OnceLock>, } +/// Maintains the state of the proc-macro server process. #[derive(Debug)] struct ProcessSrvState { process: Process, @@ -40,6 +42,7 @@ struct ProcessSrvState { } impl ProcMacroServerProcess { + /// Starts the proc-macro server and performs a version check pub(crate) fn run( process_path: &AbsPath, env: impl IntoIterator, impl AsRef)> @@ -85,14 +88,17 @@ impl ProcMacroServerProcess { } } + /// Returns the server error if the process has exited. pub(crate) fn exited(&self) -> Option<&ServerError> { self.exited.get().map(|it| &it.0) } + /// Retrieves the API version of the proc-macro server. pub(crate) fn version(&self) -> u32 { self.version } + /// Checks the API version of the running proc-macro server. fn version_check(&self) -> Result { let request = Request::ApiVersionCheck {}; let response = self.send_task(request)?; @@ -103,6 +109,7 @@ impl ProcMacroServerProcess { } } + /// Enable support for rust-analyzer span mode if the server supports it. fn enable_rust_analyzer_spans(&self) -> Result { let request = Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer }); let response = self.send_task(request)?; @@ -113,6 +120,7 @@ impl ProcMacroServerProcess { } } + /// Finds proc-macros in a given dynamic library. pub(crate) fn find_proc_macros( &self, dylib_path: &AbsPath, @@ -127,6 +135,7 @@ impl ProcMacroServerProcess { } } + /// Sends a request to the proc-macro server and waits for a response. pub(crate) fn send_task(&self, req: Request) -> Result { if let Some(server_error) = self.exited.get() { return Err(server_error.0.clone()); @@ -177,12 +186,14 @@ impl ProcMacroServerProcess { } } +/// Manages the execution of the proc-macro server process. #[derive(Debug)] struct Process { child: JodChild, } impl Process { + /// Runs a new proc-macro server process with the specified environment variables. fn run( path: &AbsPath, env: impl IntoIterator, impl AsRef)>, @@ -191,6 +202,7 @@ impl Process { Ok(Process { child }) } + /// Retrieves stdin and stdout handles for the process. fn stdio(&mut self) -> Option<(ChildStdin, BufReader)> { let stdin = self.child.stdin.take()?; let stdout = self.child.stdout.take()?; @@ -200,6 +212,7 @@ impl Process { } } +/// Creates and configures a new child process for the proc-macro server. fn mk_child( path: &AbsPath, env: impl IntoIterator, impl AsRef)>, @@ -221,6 +234,7 @@ fn mk_child( cmd.spawn() } +/// Sends a request to the server and reads the response. fn send_request( mut writer: &mut impl Write, mut reader: &mut impl BufRead, From 02ac23a7d6e4a5d9832a720c3f7ffe211091ef17 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Thu, 6 Mar 2025 16:00:08 -0500 Subject: [PATCH 009/260] internal: vendor `query-group-macro` --- src/tools/rust-analyzer/Cargo.lock | 365 ++++++++++++++- .../crates/query-group-macro/Cargo.toml | 23 + .../crates/query-group-macro/src/lib.rs | 437 ++++++++++++++++++ .../crates/query-group-macro/src/queries.rs | 329 +++++++++++++ .../crates/query-group-macro/tests/arity.rs | 28 ++ .../crates/query-group-macro/tests/cycle.rs | 275 +++++++++++ .../query-group-macro/tests/hello_world.rs | 125 +++++ .../query-group-macro/tests/interned.rs | 52 +++ .../query-group-macro/tests/logger_db.rs | 60 +++ .../crates/query-group-macro/tests/lru.rs | 67 +++ .../query-group-macro/tests/multiple_dbs.rs | 23 + .../query-group-macro/tests/old_and_new.rs | 115 +++++ .../crates/query-group-macro/tests/result.rs | 50 ++ .../query-group-macro/tests/supertrait.rs | 19 + .../crates/query-group-macro/tests/tuples.rs | 38 ++ .../ra-salsa/ra-salsa-macros/Cargo.toml | 2 +- src/tools/rust-analyzer/xtask/src/tidy.rs | 1 + 17 files changed, 1988 insertions(+), 21 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/arity.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/cycle.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/hello_world.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/lru.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/multiple_dbs.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/result.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs create mode 100644 src/tools/rust-analyzer/crates/query-group-macro/tests/tuples.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index c57953ba65476..7b83a859792e7 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -17,6 +17,21 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "always-assert" version = "0.2.0" @@ -71,7 +86,7 @@ dependencies = [ "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lz4_flex", "rustc-hash 2.0.0", - "salsa", + "salsa 0.0.0", "semver", "span", "stdx", @@ -108,6 +123,15 @@ dependencies = [ "cfg_aliases 0.2.1", ] +[[package]] +name = "boxcar" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225450ee9328e1e828319b48a89726cffc1b0ad26fd9211ad435de9fa376acae" +dependencies = [ + "loom", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -289,6 +313,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -312,7 +345,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -449,6 +496,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -473,6 +526,19 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" +[[package]] +name = "generator" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.58.0", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -496,11 +562,31 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.2", +] + [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -545,12 +631,12 @@ dependencies = [ "bitflags 2.7.0", "cfg", "cov-mark", - "dashmap", + "dashmap 5.5.3", "drop_bomb", "either", "expect-test", "fst", - "hashbrown", + "hashbrown 0.14.5", "hir-expand", "indexmap", "intern", @@ -584,7 +670,7 @@ dependencies = [ "cov-mark", "either", "expect-test", - "hashbrown", + "hashbrown 0.14.5", "intern", "itertools", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -811,7 +897,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -838,8 +924,8 @@ dependencies = [ name = "intern" version = "0.0.0" dependencies = [ - "dashmap", - "hashbrown", + "dashmap 5.5.3", + "hashbrown 0.14.5", "rustc-hash 2.0.0", "triomphe", ] @@ -999,6 +1085,19 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + [[package]] name = "lsp-server" version = "0.7.7" @@ -1043,6 +1142,15 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "mbe" version = "0.0.0" @@ -1170,6 +1278,16 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.50.1" @@ -1240,6 +1358,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.3" @@ -1329,6 +1453,12 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + [[package]] name = "powerfmt" version = "0.2.0" @@ -1414,7 +1544,7 @@ dependencies = [ "indexmap", "nix", "tracing", - "windows", + "windows 0.56.0", ] [[package]] @@ -1493,6 +1623,18 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "query-group-macro" +version = "0.0.0" +dependencies = [ + "expect-test", + "heck", + "proc-macro2", + "quote", + "salsa 0.19.0", + "syn", +] + [[package]] name = "quote" version = "1.0.36" @@ -1648,6 +1790,50 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "rowan" version = "0.15.15" @@ -1655,7 +1841,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" dependencies = [ "countme", - "hashbrown", + "hashbrown 0.14.5", "memoffset", "rustc-hash 1.1.0", "text-size", @@ -1760,6 +1946,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "ryu" version = "1.0.18" @@ -1780,12 +1972,40 @@ dependencies = [ "parking_lot", "rand", "rustc-hash 2.0.0", - "salsa-macros", + "salsa-macros 0.0.0", "smallvec", "tracing", "triomphe", ] +[[package]] +name = "salsa" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd55c6549513b2a42884dae31e3d4f4ac8a6cc51062e68e24d162133889f327c" +dependencies = [ + "boxcar", + "crossbeam-queue", + "dashmap 6.1.0", + "hashbrown 0.15.2", + "hashlink", + "indexmap", + "parking_lot", + "portable-atomic", + "rayon", + "rustc-hash 2.0.0", + "salsa-macro-rules", + "salsa-macros 0.19.0", + "smallvec", + "tracing", +] + +[[package]] +name = "salsa-macro-rules" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2619b4b451beab0a7e4364ff1e6f31950e7e418888fd9bf2f28889671563166a" + [[package]] name = "salsa-macros" version = "0.0.0" @@ -1796,6 +2016,19 @@ dependencies = [ "syn", ] +[[package]] +name = "salsa-macros" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be57a99b3896e8d26850428a6874fb86849e2db874e1db3528e5cee4337d277" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "same-file" version = "1.0.6" @@ -1923,10 +2156,10 @@ dependencies = [ name = "span" version = "0.0.0" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.0.0", - "salsa", + "salsa 0.0.0", "stdx", "syntax", "text-size", @@ -2246,9 +2479,15 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ + "matchers", + "nu-ansi-term 0.46.0", + "once_cell", + "regex", "sharded-slab", + "smallvec", "thread_local", "time", + "tracing", "tracing-core", "tracing-log", ] @@ -2259,7 +2498,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b56c62d2c80033cb36fae448730a2f2ef99410fe3ecbffc916681a32f6807dbe" dependencies = [ - "nu-ansi-term", + "nu-ansi-term 0.50.1", "tracing-core", "tracing-log", "tracing-subscriber", @@ -2405,6 +2644,22 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -2414,13 +2669,29 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows" version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" dependencies = [ - "windows-core", + "windows-core 0.56.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", "windows-targets 0.52.6", ] @@ -2430,9 +2701,22 @@ version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", + "windows-implement 0.56.0", + "windows-interface 0.56.0", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings", "windows-targets 0.52.6", ] @@ -2447,6 +2731,17 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-interface" version = "0.56.0" @@ -2458,6 +2753,17 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -2467,6 +2773,25 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml new file mode 100644 index 0000000000000..24e059f40bee5 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "query-group-macro" +version = "0.0.0" +repository.workspace = true +description = "A macro mimicking the `#[salsa::query_group]` macro for migrating to new Salsa" + +authors.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true + +[lib] +proc-macro = true + +[dependencies] +heck = "0.5.0" +proc-macro2 = "1.0" +quote = "1.0" +syn = { version = "2.0", features = ["full", "extra-traits"] } +salsa = { version = "0.19.0" } + +[dev-dependencies] +expect-test = "1.5.0" diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs new file mode 100644 index 0000000000000..af49081db5bd6 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs @@ -0,0 +1,437 @@ +//! A macro that mimics the old Salsa-style `#[query_group]` macro. + +use core::fmt; +use std::vec; + +use proc_macro::TokenStream; +use proc_macro2::Span; +use queries::{ + GeneratedInputStruct, InputQuery, InputSetter, InputSetterWithDurability, Intern, Lookup, + Queries, SetterKind, TrackedQuery, Transparent, +}; +use quote::{format_ident, quote, ToTokens}; +use syn::spanned::Spanned; +use syn::visit_mut::VisitMut; +use syn::{parse_quote, Attribute, FnArg, ItemTrait, Path, TraitItem, TraitItemFn}; + +mod queries; + +#[proc_macro_attribute] +pub fn query_group(args: TokenStream, input: TokenStream) -> TokenStream { + match query_group_impl(args, input.clone()) { + Ok(tokens) => tokens, + Err(e) => token_stream_with_error(input, e), + } +} + +#[derive(Debug)] +struct InputStructField { + name: proc_macro2::TokenStream, + ty: proc_macro2::TokenStream, +} + +impl fmt::Display for InputStructField { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name) + } +} + +struct SalsaAttr { + name: String, + tts: TokenStream, + span: Span, +} + +impl std::fmt::Debug for SalsaAttr { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(fmt, "{:?}", self.name) + } +} + +impl TryFrom for SalsaAttr { + type Error = syn::Attribute; + + fn try_from(attr: syn::Attribute) -> Result { + if is_not_salsa_attr_path(attr.path()) { + return Err(attr); + } + + let span = attr.span(); + + let name = attr.path().segments[1].ident.to_string(); + let tts = match attr.meta { + syn::Meta::Path(path) => path.into_token_stream(), + syn::Meta::List(ref list) => { + let tts = list + .into_token_stream() + .into_iter() + .skip(attr.path().to_token_stream().into_iter().count()); + proc_macro2::TokenStream::from_iter(tts) + } + syn::Meta::NameValue(nv) => nv.into_token_stream(), + } + .into(); + + Ok(SalsaAttr { name, tts, span }) + } +} + +fn is_not_salsa_attr_path(path: &syn::Path) -> bool { + path.segments.first().map(|s| s.ident != "salsa").unwrap_or(true) || path.segments.len() != 2 +} + +fn filter_attrs(attrs: Vec) -> (Vec, Vec) { + let mut other = vec![]; + let mut salsa = vec![]; + // Leave non-salsa attributes untouched. These are + // attributes that don't start with `salsa::` or don't have + // exactly two segments in their path. + for attr in attrs { + match SalsaAttr::try_from(attr) { + Ok(it) => salsa.push(it), + Err(it) => other.push(it), + } + } + (other, salsa) +} + +#[derive(Debug, Clone, PartialEq, Eq)] +enum QueryKind { + Input, + Tracked, + TrackedWithSalsaStruct, + Transparent, + Interned, +} + +pub(crate) fn query_group_impl( + _args: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> Result { + let mut item_trait = syn::parse::(input)?; + + let supertraits = &item_trait.supertraits; + + let db_attr: Attribute = parse_quote! { + #[salsa::db] + }; + item_trait.attrs.push(db_attr); + + let trait_name_ident = &item_trait.ident.clone(); + let input_struct_name = format_ident!("{}Data", trait_name_ident); + let create_data_ident = format_ident!("create_data_{}", trait_name_ident); + + let mut input_struct_fields: Vec = vec![]; + let mut trait_methods = vec![]; + let mut setter_trait_methods = vec![]; + let mut lookup_signatures = vec![]; + let mut lookup_methods = vec![]; + + for item in item_trait.clone().items { + if let syn::TraitItem::Fn(method) = item { + let method_name = &method.sig.ident; + let signature = &method.sig.clone(); + + let (_attrs, salsa_attrs) = filter_attrs(method.attrs); + + let mut query_kind = QueryKind::Tracked; + let mut invoke = None; + let mut cycle = None; + let mut interned_struct_path = None; + let mut lru = None; + + let params: Vec = signature.inputs.clone().into_iter().collect(); + let pat_and_tys = params + .into_iter() + .filter(|fn_arg| matches!(fn_arg, FnArg::Typed(_))) + .map(|fn_arg| match fn_arg { + FnArg::Typed(pat_type) => pat_type.clone(), + FnArg::Receiver(_) => unreachable!("this should have been filtered out"), + }) + .collect::>(); + + for SalsaAttr { name, tts, span } in salsa_attrs { + match name.as_str() { + "cycle" => { + let path = syn::parse::>(tts)?; + cycle = Some(path.0.clone()) + } + "input" => { + if !pat_and_tys.is_empty() { + return Err(syn::Error::new( + span, + "input methods cannot have a parameter", + )); + } + query_kind = QueryKind::Input; + } + "interned" => { + let syn::ReturnType::Type(_, ty) = &signature.output else { + return Err(syn::Error::new( + span, + "interned queries must have return type", + )); + }; + let syn::Type::Path(path) = &**ty else { + return Err(syn::Error::new( + span, + "interned queries must have return type", + )); + }; + interned_struct_path = Some(path.path.clone()); + query_kind = QueryKind::Interned; + } + "invoke" => { + let path = syn::parse::>(tts)?; + invoke = Some(path.0.clone()); + } + "invoke_actual" => { + let path = syn::parse::>(tts)?; + invoke = Some(path.0.clone()); + query_kind = QueryKind::TrackedWithSalsaStruct; + } + "lru" => { + let lru_count = syn::parse::>(tts)?; + let lru_count = lru_count.0.base10_parse::()?; + + lru = Some(lru_count); + } + "transparent" => { + query_kind = QueryKind::Transparent; + } + _ => return Err(syn::Error::new(span, format!("unknown attribute `{name}`"))), + } + } + + let syn::ReturnType::Type(_, return_ty) = signature.output.clone() else { + return Err(syn::Error::new(signature.span(), "Queries must have a return type")); + }; + + if let syn::Type::Path(ref ty_path) = *return_ty { + if matches!(query_kind, QueryKind::Input) { + let field = InputStructField { + name: method_name.to_token_stream(), + ty: ty_path.path.to_token_stream(), + }; + + input_struct_fields.push(field); + } + } + + match (query_kind, invoke) { + // input + (QueryKind::Input, None) => { + let query = InputQuery { + signature: method.sig.clone(), + create_data_ident: create_data_ident.clone(), + }; + let value = Queries::InputQuery(query); + trait_methods.push(value); + + let setter = InputSetter { + signature: method.sig.clone(), + return_type: *return_ty.clone(), + create_data_ident: create_data_ident.clone(), + }; + setter_trait_methods.push(SetterKind::Plain(setter)); + + let setter = InputSetterWithDurability { + signature: method.sig.clone(), + return_type: *return_ty.clone(), + create_data_ident: create_data_ident.clone(), + }; + setter_trait_methods.push(SetterKind::WithDurability(setter)); + } + (QueryKind::Interned, None) => { + let interned_struct_path = interned_struct_path.unwrap(); + let method = Intern { + signature: signature.clone(), + pat_and_tys: pat_and_tys.clone(), + interned_struct_path: interned_struct_path.clone(), + }; + + trait_methods.push(Queries::Intern(method)); + + let mut method = Lookup { + signature: signature.clone(), + pat_and_tys: pat_and_tys.clone(), + return_ty: *return_ty, + interned_struct_path, + }; + method.prepare_signature(); + + lookup_signatures + .push(TraitItem::Fn(make_trait_method(method.signature.clone()))); + lookup_methods.push(method); + } + // tracked function. it might have an invoke, or might not. + (QueryKind::Tracked, invoke) => { + let method = TrackedQuery { + trait_name: trait_name_ident.clone(), + generated_struct: Some(GeneratedInputStruct { + input_struct_name: input_struct_name.clone(), + create_data_ident: create_data_ident.clone(), + }), + signature: signature.clone(), + pat_and_tys: pat_and_tys.clone(), + invoke, + cycle, + lru, + }; + + trait_methods.push(Queries::TrackedQuery(method)); + } + (QueryKind::TrackedWithSalsaStruct, Some(invoke)) => { + let method = TrackedQuery { + trait_name: trait_name_ident.clone(), + generated_struct: None, + signature: signature.clone(), + pat_and_tys: pat_and_tys.clone(), + invoke: Some(invoke), + cycle, + lru, + }; + + trait_methods.push(Queries::TrackedQuery(method)) + } + // while it is possible to make this reachable, it's not really worthwhile for a migration aid. + // doing this would require attaching an attribute to the salsa struct parameter in the query. + (QueryKind::TrackedWithSalsaStruct, None) => unreachable!(), + (QueryKind::Transparent, invoke) => { + let method = Transparent { + signature: method.sig.clone(), + pat_and_tys: pat_and_tys.clone(), + invoke, + }; + trait_methods.push(Queries::Transparent(method)); + } + // error/invalid constructions + (QueryKind::Interned, Some(path)) => { + return Err(syn::Error::new( + path.span(), + "Interned queries cannot be used with an `#[invoke]`".to_string(), + )) + } + (QueryKind::Input, Some(path)) => { + return Err(syn::Error::new( + path.span(), + "Inputs cannot be used with an `#[invoke]`".to_string(), + )) + } + } + } + } + + let fields = input_struct_fields + .into_iter() + .map(|input| { + let name = input.name; + let ret = input.ty; + quote! { #name: Option<#ret> } + }) + .collect::>(); + + let input_struct = quote! { + #[salsa::input] + pub(crate) struct #input_struct_name { + #(#fields),* + } + }; + + let field_params = std::iter::repeat_n(quote! { None }, fields.len()) + .collect::>(); + + let create_data_method = quote! { + #[allow(non_snake_case)] + #[salsa::tracked] + fn #create_data_ident(db: &dyn #trait_name_ident) -> #input_struct_name { + #input_struct_name::new(db, #(#field_params),*) + } + }; + + let mut setter_signatures = vec![]; + let mut setter_methods = vec![]; + for trait_item in setter_trait_methods + .iter() + .map(|method| method.to_token_stream()) + .map(|tokens| syn::parse2::(tokens).unwrap()) + { + let mut methods_sans_body = trait_item.clone(); + methods_sans_body.default = None; + methods_sans_body.semi_token = Some(syn::Token![;](trait_item.span())); + + setter_signatures.push(TraitItem::Fn(methods_sans_body)); + setter_methods.push(TraitItem::Fn(trait_item)); + } + + item_trait.items.append(&mut setter_signatures); + item_trait.items.append(&mut lookup_signatures); + + let trait_impl = quote! { + #[salsa::db] + impl #trait_name_ident for DB + where + DB: #supertraits, + { + #(#trait_methods)* + + #(#setter_methods)* + + #(#lookup_methods)* + } + }; + RemoveAttrsFromTraitMethods.visit_item_trait_mut(&mut item_trait); + + let out = quote! { + #item_trait + + #trait_impl + + #input_struct + + #create_data_method + } + .into(); + + Ok(out) +} + +/// Parenthesis helper +pub(crate) struct Parenthesized(pub(crate) T); + +impl syn::parse::Parse for Parenthesized +where + T: syn::parse::Parse, +{ + fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { + let content; + syn::parenthesized!(content in input); + content.parse::().map(Parenthesized) + } +} + +fn make_trait_method(sig: syn::Signature) -> TraitItemFn { + TraitItemFn { + attrs: vec![], + sig: sig.clone(), + semi_token: Some(syn::Token![;](sig.span())), + default: None, + } +} + +struct RemoveAttrsFromTraitMethods; + +impl VisitMut for RemoveAttrsFromTraitMethods { + fn visit_item_trait_mut(&mut self, i: &mut syn::ItemTrait) { + for item in &mut i.items { + if let TraitItem::Fn(trait_item_fn) = item { + trait_item_fn.attrs = vec![]; + } + } + } +} + +pub(crate) fn token_stream_with_error(mut tokens: TokenStream, error: syn::Error) -> TokenStream { + tokens.extend(TokenStream::from(error.into_compile_error())); + tokens +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs new file mode 100644 index 0000000000000..8c6bb8a0a729c --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs @@ -0,0 +1,329 @@ +//! The IR of the `#[query_group]` macro. + +use quote::{format_ident, quote, ToTokens}; +use syn::{parse_quote, FnArg, Ident, PatType, Path, Receiver, ReturnType, Type}; + +pub(crate) struct TrackedQuery { + pub(crate) trait_name: Ident, + pub(crate) signature: syn::Signature, + pub(crate) pat_and_tys: Vec, + pub(crate) invoke: Option, + pub(crate) cycle: Option, + pub(crate) lru: Option, + pub(crate) generated_struct: Option, +} + +pub(crate) struct GeneratedInputStruct { + pub(crate) input_struct_name: Ident, + pub(crate) create_data_ident: Ident, +} + +impl ToTokens for TrackedQuery { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let sig = &self.signature; + let trait_name = &self.trait_name; + + let ret = &sig.output; + + let invoke = match &self.invoke { + Some(path) => path.to_token_stream(), + None => sig.ident.to_token_stream(), + }; + + let fn_ident = &sig.ident; + let shim: Ident = format_ident!("{}_shim", fn_ident); + + let annotation = match (self.cycle.clone(), self.lru) { + (Some(cycle), Some(lru)) => quote!(#[salsa::tracked(lru = #lru, recovery_fn = #cycle)]), + (Some(cycle), None) => quote!(#[salsa::tracked(recovery_fn = #cycle)]), + (None, Some(lru)) => quote!(#[salsa::tracked(lru = #lru)]), + (None, None) => quote!(#[salsa::tracked]), + }; + + let pat_and_tys = &self.pat_and_tys; + let params = self + .pat_and_tys + .iter() + .map(|pat_type| pat_type.pat.clone()) + .collect::>>(); + + let method = match &self.generated_struct { + Some(generated_struct) => { + let input_struct_name = &generated_struct.input_struct_name; + let create_data_ident = &generated_struct.create_data_ident; + + quote! { + #sig { + #annotation + fn #shim( + db: &dyn #trait_name, + _input: #input_struct_name, + #(#pat_and_tys),* + ) #ret { + #invoke(db, #(#params),*) + } + #shim(self, #create_data_ident(self), #(#params),*) + } + } + } + None => { + quote! { + #sig { + #annotation + fn #shim( + db: &dyn #trait_name, + #(#pat_and_tys),* + ) #ret { + #invoke(db, #(#params),*) + } + #shim(self, #(#params),*) + } + } + } + }; + + method.to_tokens(tokens); + } +} + +pub(crate) struct InputQuery { + pub(crate) signature: syn::Signature, + pub(crate) create_data_ident: Ident, +} + +impl ToTokens for InputQuery { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let sig = &self.signature; + let fn_ident = &sig.ident; + let create_data_ident = &self.create_data_ident; + + let method = quote! { + #sig { + let data = #create_data_ident(self); + data.#fn_ident(self).unwrap() + } + }; + method.to_tokens(tokens); + } +} + +pub(crate) struct InputSetter { + pub(crate) signature: syn::Signature, + pub(crate) return_type: syn::Type, + pub(crate) create_data_ident: Ident, +} + +impl ToTokens for InputSetter { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let sig = &mut self.signature.clone(); + + let ty = &self.return_type; + let fn_ident = &sig.ident; + let create_data_ident = &self.create_data_ident; + + let setter_ident = format_ident!("set_{}", fn_ident); + sig.ident = setter_ident.clone(); + + let value_argument: PatType = parse_quote!(__value: #ty); + sig.inputs.push(FnArg::Typed(value_argument.clone())); + + // make `&self` `&mut self` instead. + let mut_receiver: Receiver = parse_quote!(&mut self); + if let Some(og) = sig.inputs.first_mut() { + *og = FnArg::Receiver(mut_receiver) + } + + // remove the return value. + sig.output = ReturnType::Default; + + let value = &value_argument.pat; + let method = quote! { + #sig { + use salsa::Setter; + let data = #create_data_ident(self); + data.#setter_ident(self).to(Some(#value)); + } + }; + method.to_tokens(tokens); + } +} + +pub(crate) struct InputSetterWithDurability { + pub(crate) signature: syn::Signature, + pub(crate) return_type: syn::Type, + pub(crate) create_data_ident: Ident, +} + +impl ToTokens for InputSetterWithDurability { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let sig = &mut self.signature.clone(); + + let ty = &self.return_type; + let fn_ident = &sig.ident; + let setter_ident = format_ident!("set_{}", fn_ident); + + let create_data_ident = &self.create_data_ident; + + sig.ident = format_ident!("set_{}_with_durability", fn_ident); + + let value_argument: PatType = parse_quote!(__value: #ty); + sig.inputs.push(FnArg::Typed(value_argument.clone())); + + let durability_argument: PatType = parse_quote!(durability: salsa::Durability); + sig.inputs.push(FnArg::Typed(durability_argument.clone())); + + // make `&self` `&mut self` instead. + let mut_receiver: Receiver = parse_quote!(&mut self); + if let Some(og) = sig.inputs.first_mut() { + *og = FnArg::Receiver(mut_receiver) + } + + // remove the return value. + sig.output = ReturnType::Default; + + let value = &value_argument.pat; + let durability = &durability_argument.pat; + let method = quote! { + #sig { + use salsa::Setter; + let data = #create_data_ident(self); + data.#setter_ident(self) + .with_durability(#durability) + .to(Some(#value)); + } + }; + method.to_tokens(tokens); + } +} + +pub(crate) enum SetterKind { + Plain(InputSetter), + WithDurability(InputSetterWithDurability), +} + +impl ToTokens for SetterKind { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + match self { + SetterKind::Plain(input_setter) => input_setter.to_tokens(tokens), + SetterKind::WithDurability(input_setter_with_durability) => { + input_setter_with_durability.to_tokens(tokens) + } + } + } +} + +pub(crate) struct Transparent { + pub(crate) signature: syn::Signature, + pub(crate) pat_and_tys: Vec, + pub(crate) invoke: Option, +} + +impl ToTokens for Transparent { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let sig = &self.signature; + + let ty = self + .pat_and_tys + .iter() + .map(|pat_type| pat_type.pat.clone()) + .collect::>>(); + + let invoke = match &self.invoke { + Some(path) => path.to_token_stream(), + None => sig.ident.to_token_stream(), + }; + + let method = quote! { + #sig { + #invoke(self, #(#ty),*) + } + }; + + method.to_tokens(tokens); + } +} +pub(crate) struct Intern { + pub(crate) signature: syn::Signature, + pub(crate) pat_and_tys: Vec, + pub(crate) interned_struct_path: Path, +} + +impl ToTokens for Intern { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let sig = &self.signature; + + let ty = self.pat_and_tys.to_vec(); + + let interned_pat = ty.first().expect("at least one pat; this is a bug"); + let interned_pat = &interned_pat.pat; + + let wrapper_struct = self.interned_struct_path.to_token_stream(); + + let method = quote! { + #sig { + #wrapper_struct::new(self, #interned_pat) + } + }; + + method.to_tokens(tokens); + } +} + +pub(crate) struct Lookup { + pub(crate) signature: syn::Signature, + pub(crate) pat_and_tys: Vec, + pub(crate) return_ty: Type, + pub(crate) interned_struct_path: Path, +} + +impl Lookup { + pub(crate) fn prepare_signature(&mut self) { + let sig = &self.signature; + + let ident = format_ident!("lookup_{}", sig.ident); + + let ty = self.pat_and_tys.to_vec(); + + let interned_key = &self.return_ty; + + let interned_pat = ty.first().expect("at least one pat; this is a bug"); + let interned_return_ty = &interned_pat.ty; + + self.signature = parse_quote!( + fn #ident(&self, id: #interned_key) -> #interned_return_ty + ); + } +} + +impl ToTokens for Lookup { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let sig = &self.signature; + + let wrapper_struct = self.interned_struct_path.to_token_stream(); + let method = quote! { + #sig { + #wrapper_struct::ingredient(self).data(self.as_dyn_database(), id.as_id()).0.clone() + } + }; + + method.to_tokens(tokens); + } +} + +pub(crate) enum Queries { + TrackedQuery(TrackedQuery), + InputQuery(InputQuery), + Intern(Intern), + Transparent(Transparent), +} + +impl ToTokens for Queries { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + match self { + Queries::TrackedQuery(tracked_query) => tracked_query.to_tokens(tokens), + Queries::InputQuery(input_query) => input_query.to_tokens(tokens), + Queries::Transparent(transparent) => transparent.to_tokens(tokens), + Queries::Intern(intern) => intern.to_tokens(tokens), + } + } +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/arity.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/arity.rs new file mode 100644 index 0000000000000..440db7b821371 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/arity.rs @@ -0,0 +1,28 @@ +use query_group_macro::query_group; + +#[query_group] +pub trait ArityDb: salsa::Database { + fn one(&self, a: ()) -> String; + + fn two(&self, a: (), b: ()) -> String; + + fn three(&self, a: (), b: (), c: ()) -> String; + + fn none(&self) -> String; +} + +fn one(_db: &dyn ArityDb, _a: ()) -> String { + String::new() +} + +fn two(_db: &dyn ArityDb, _a: (), _b: ()) -> String { + String::new() +} + +fn three(_db: &dyn ArityDb, _a: (), _b: (), _c: ()) -> String { + String::new() +} + +fn none(_db: &dyn ArityDb) -> String { + String::new() +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/cycle.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/cycle.rs new file mode 100644 index 0000000000000..12df4ae3eff33 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/cycle.rs @@ -0,0 +1,275 @@ +use std::panic::UnwindSafe; + +use expect_test::expect; +use query_group_macro::query_group; +use salsa::Setter; + +/// The queries A, B, and C in `Database` can be configured +/// to invoke one another in arbitrary ways using this +/// enum. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +enum CycleQuery { + None, + A, + B, + C, + AthenC, +} + +#[salsa::input] +struct ABC { + a: CycleQuery, + b: CycleQuery, + c: CycleQuery, +} + +impl CycleQuery { + fn invoke(self, db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> { + match self { + CycleQuery::A => db.cycle_a(abc), + CycleQuery::B => db.cycle_b(abc), + CycleQuery::C => db.cycle_c(abc), + CycleQuery::AthenC => { + let _ = db.cycle_a(abc); + db.cycle_c(abc) + } + CycleQuery::None => Ok(()), + } + } +} + +#[salsa::input] +struct MyInput {} + +#[salsa::tracked] +fn memoized_a(db: &dyn CycleDatabase, input: MyInput) { + memoized_b(db, input) +} + +#[salsa::tracked] +fn memoized_b(db: &dyn CycleDatabase, input: MyInput) { + memoized_a(db, input) +} + +#[salsa::tracked] +fn volatile_a(db: &dyn CycleDatabase, input: MyInput) { + db.report_untracked_read(); + volatile_b(db, input) +} + +#[salsa::tracked] +fn volatile_b(db: &dyn CycleDatabase, input: MyInput) { + db.report_untracked_read(); + volatile_a(db, input) +} + +#[track_caller] +fn extract_cycle(f: impl FnOnce() + UnwindSafe) -> salsa::Cycle { + let v = std::panic::catch_unwind(f); + if let Err(d) = &v { + if let Some(cycle) = d.downcast_ref::() { + return cycle.clone(); + } + } + panic!("unexpected value: {:?}", v) +} + +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +struct Error { + cycle: Vec, +} + +#[query_group] +trait CycleDatabase: salsa::Database { + #[salsa::cycle(recover_a)] + fn cycle_a(&self, abc: ABC) -> Result<(), Error>; + + #[salsa::cycle(recover_b)] + fn cycle_b(&self, abc: ABC) -> Result<(), Error>; + + fn cycle_c(&self, abc: ABC) -> Result<(), Error>; +} + +fn cycle_a(db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> { + abc.a(db).invoke(db, abc) +} + +fn recover_a( + _db: &dyn CycleDatabase, + cycle: &salsa::Cycle, + _: CycleDatabaseData, + _abc: ABC, +) -> Result<(), Error> { + Err(Error { cycle: cycle.participant_keys().map(|k| format!("{k:?}")).collect() }) +} + +fn cycle_b(db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> { + abc.b(db).invoke(db, abc) +} + +fn recover_b( + _db: &dyn CycleDatabase, + cycle: &salsa::Cycle, + _: CycleDatabaseData, + _abc: ABC, +) -> Result<(), Error> { + Err(Error { cycle: cycle.participant_keys().map(|k| format!("{k:?}")).collect() }) +} + +fn cycle_c(db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> { + abc.c(db).invoke(db, abc) +} + +#[test] +fn cycle_memoized() { + let db = salsa::DatabaseImpl::new(); + + let input = MyInput::new(&db); + let cycle = extract_cycle(|| memoized_a(&db, input)); + let expected = expect![[r#" + [ + DatabaseKeyIndex( + IngredientIndex( + 1, + ), + Id(0), + ), + DatabaseKeyIndex( + IngredientIndex( + 2, + ), + Id(0), + ), + ] + "#]]; + expected.assert_debug_eq(&cycle.all_participants(&db)); +} + +#[test] +fn inner_cycle() { + // A --> B <-- C + // ^ | + // +-----+ + let db = salsa::DatabaseImpl::new(); + + let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::B); + let err = db.cycle_c(abc); + assert!(err.is_err()); + let expected = expect![[r#" + [ + "cycle_a_shim(Id(1400))", + "cycle_b_shim(Id(1000))", + ] + "#]]; + expected.assert_debug_eq(&err.unwrap_err().cycle); +} + +#[test] +fn cycle_revalidate() { + // A --> B + // ^ | + // +-----+ + let mut db = salsa::DatabaseImpl::new(); + let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::None); + assert!(db.cycle_a(abc).is_err()); + abc.set_b(&mut db).to(CycleQuery::A); // same value as default + assert!(db.cycle_a(abc).is_err()); +} + +#[test] +fn cycle_recovery_unchanged_twice() { + // A --> B + // ^ | + // +-----+ + let mut db = salsa::DatabaseImpl::new(); + let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::None); + assert!(db.cycle_a(abc).is_err()); + + abc.set_c(&mut db).to(CycleQuery::A); // force new revision + assert!(db.cycle_a(abc).is_err()); +} + +#[test] +fn cycle_appears() { + let mut db = salsa::DatabaseImpl::new(); + // A --> B + let abc = ABC::new(&db, CycleQuery::B, CycleQuery::None, CycleQuery::None); + assert!(db.cycle_a(abc).is_ok()); + + // A --> B + // ^ | + // +-----+ + abc.set_b(&mut db).to(CycleQuery::A); + assert!(db.cycle_a(abc).is_err()); +} + +#[test] +fn cycle_disappears() { + let mut db = salsa::DatabaseImpl::new(); + + // A --> B + // ^ | + // +-----+ + let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::None); + assert!(db.cycle_a(abc).is_err()); + + // A --> B + abc.set_b(&mut db).to(CycleQuery::None); + assert!(db.cycle_a(abc).is_ok()); +} + +#[test] +fn cycle_multiple() { + // No matter whether we start from A or B, we get the same set of participants: + let db = salsa::DatabaseImpl::new(); + + // Configuration: + // + // A --> B <-- C + // ^ | ^ + // +-----+ | + // | | + // +-----+ + // + // Here, conceptually, B encounters a cycle with A and then + // recovers. + let abc = ABC::new(&db, CycleQuery::B, CycleQuery::AthenC, CycleQuery::A); + + let c = db.cycle_c(abc); + let b = db.cycle_b(abc); + let a = db.cycle_a(abc); + let expected = expect![[r#" + ( + [ + "cycle_a_shim(Id(1000))", + "cycle_b_shim(Id(1400))", + ], + [ + "cycle_a_shim(Id(1000))", + "cycle_b_shim(Id(1400))", + ], + [ + "cycle_a_shim(Id(1000))", + "cycle_b_shim(Id(1400))", + ], + ) + "#]]; + expected.assert_debug_eq(&(c.unwrap_err().cycle, b.unwrap_err().cycle, a.unwrap_err().cycle)); +} + +#[test] +fn cycle_mixed_1() { + let db = salsa::DatabaseImpl::new(); + // A --> B <-- C + // | ^ + // +-----+ + let abc = ABC::new(&db, CycleQuery::B, CycleQuery::C, CycleQuery::B); + + let expected = expect![[r#" + [ + "cycle_b_shim(Id(1000))", + "cycle_c_shim(Id(c00))", + ] + "#]]; + expected.assert_debug_eq(&db.cycle_c(abc).unwrap_err().cycle); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/hello_world.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/hello_world.rs new file mode 100644 index 0000000000000..86cf591f52126 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/hello_world.rs @@ -0,0 +1,125 @@ +use expect_test::expect; +use query_group_macro::query_group; + +mod logger_db; +use logger_db::LoggerDb; + +#[query_group] +pub trait HelloWorldDatabase: salsa::Database { + // input + // // input with no params + #[salsa::input] + fn input_string(&self) -> String; + + // unadorned query + fn length_query(&self, key: ()) -> usize; + + // unadorned query + fn length_query_with_no_params(&self) -> usize; + + // renamed/invoke query + #[salsa::invoke(invoke_length_query_actual)] + fn invoke_length_query(&self, key: ()) -> usize; + + // not a query. should not invoked + #[salsa::transparent] + fn transparent_length(&self, key: ()) -> usize; + + #[salsa::transparent] + #[salsa::invoke(transparent_and_invoke_length_actual)] + fn transparent_and_invoke_length(&self, key: ()) -> usize; +} + +fn length_query(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +fn length_query_with_no_params(db: &dyn HelloWorldDatabase) -> usize { + db.input_string().len() +} + +fn invoke_length_query_actual(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +fn transparent_length(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +fn transparent_and_invoke_length_actual(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +#[test] +fn unadorned_query() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} + +#[test] +fn invoke_query() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.invoke_length_query(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} + +#[test] +fn transparent() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.transparent_length(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + ]"#]]); +} + +#[test] +fn transparent_invoke() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.transparent_and_invoke_length(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs new file mode 100644 index 0000000000000..be4fc4f52b62b --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs @@ -0,0 +1,52 @@ +use query_group_macro::query_group; + +use expect_test::expect; +use salsa::plumbing::AsId; + +mod logger_db; +use logger_db::LoggerDb; + +#[salsa::interned(no_lifetime)] +pub struct InternedString { + data: String, +} + +#[query_group] +pub trait InternedDB: salsa::Database { + #[salsa::interned] + fn intern_string(&self, data: String) -> InternedString; + + fn interned_len(&self, id: InternedString) -> usize; +} + +fn interned_len(db: &dyn InternedDB, id: InternedString) -> usize { + db.lookup_intern_string(id).len() +} + +#[test] +fn intern_round_trip() { + let db = LoggerDb::default(); + + let id = db.intern_string(String::from("Hello, world!")); + let s = db.lookup_intern_string(id); + + assert_eq!(s.len(), 13); + db.assert_logs(expect![[r#"[]"#]]); +} + +#[test] +fn intern_with_query() { + let db = LoggerDb::default(); + + let id = db.intern_string(String::from("Hello, world!")); + let len = db.interned_len(id); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_InternedDB(Id(400)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: interned_len_shim(Id(c00)) })", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs new file mode 100644 index 0000000000000..b3457c1046e5e --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs @@ -0,0 +1,60 @@ +use std::sync::{Arc, Mutex}; + +#[salsa::db] +#[derive(Default, Clone)] +pub(crate) struct LoggerDb { + storage: salsa::Storage, + logger: Logger, +} + +#[derive(Default, Clone)] +struct Logger { + logs: Arc>>, +} + +#[salsa::db] +impl salsa::Database for LoggerDb { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); + match event.kind { + salsa::EventKind::WillExecute { .. } + | salsa::EventKind::WillCheckCancellation { .. } + | salsa::EventKind::DidValidateMemoizedValue { .. } + | salsa::EventKind::WillDiscardStaleOutput { .. } + | salsa::EventKind::DidDiscard { .. } => { + self.push_log(format!("salsa_event({:?})", event.kind)); + } + _ => {} + } + } +} + +impl LoggerDb { + /// Log an event from inside a tracked function. + pub(crate) fn push_log(&self, string: String) { + self.logger.logs.lock().unwrap().push(string); + } + + /// Asserts what the (formatted) logs should look like, + /// clearing the logged events. This takes `&mut self` because + /// it is meant to be run from outside any tracked functions. + pub(crate) fn assert_logs(&self, expected: expect_test::Expect) { + let logs = std::mem::take(&mut *self.logger.logs.lock().unwrap()); + expected.assert_eq(&format!("{:#?}", logs)); + } +} + +/// Test the logger database. +/// +/// This test isn't very interesting, but it *does* remove a dead code warning. +#[test] +fn test_logger_db() { + let db = LoggerDb::default(); + db.push_log("test".to_string()); + db.assert_logs(expect_test::expect![ + r#" + [ + "test", + ]"# + ]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/lru.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/lru.rs new file mode 100644 index 0000000000000..d2eee42ba8c6d --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/lru.rs @@ -0,0 +1,67 @@ +use expect_test::expect; + +mod logger_db; +use logger_db::LoggerDb; +use query_group_macro::query_group; + +#[query_group] +pub trait LruDB: salsa::Database { + // // input with no params + #[salsa::input] + fn input_string(&self) -> String; + + #[salsa::lru(16)] + fn length_query(&self, key: ()) -> usize; + + #[salsa::lru(16)] + #[salsa::invoke(invoked_query)] + fn length_query_invoke(&self, key: ()) -> usize; +} + +fn length_query(db: &dyn LruDB, _key: ()) -> usize { + db.input_string().len() +} + +fn invoked_query(db: &dyn LruDB, _key: ()) -> usize { + db.input_string().len() +} + +#[test] +fn plain_lru() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} + +#[test] +fn invoke_lru() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query_invoke(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_invoke_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/multiple_dbs.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/multiple_dbs.rs new file mode 100644 index 0000000000000..802077bfd3cb2 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/multiple_dbs.rs @@ -0,0 +1,23 @@ +use query_group_macro::query_group; + +#[query_group] +pub trait DatabaseOne: salsa::Database { + #[salsa::input] + fn input_string(&self) -> String; + + // unadorned query + fn length(&self, key: ()) -> usize; +} + +#[query_group] +pub trait DatabaseTwo: DatabaseOne { + fn second_length(&self, key: ()) -> usize; +} + +fn length(db: &dyn DatabaseOne, _key: ()) -> usize { + db.input_string().len() +} + +fn second_length(db: &dyn DatabaseTwo, _key: ()) -> usize { + db.input_string().len() +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs new file mode 100644 index 0000000000000..733b3793ae002 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs @@ -0,0 +1,115 @@ +use expect_test::expect; + +mod logger_db; +use logger_db::LoggerDb; +use query_group_macro::query_group; + +#[salsa::input] +struct Input { + str: String, +} + +#[query_group] +trait PartialMigrationDatabase: salsa::Database { + fn length_query(&self, input: Input) -> usize; + + // renamed/invoke query + #[salsa::invoke(invoke_length_query_actual)] + fn invoke_length_query(&self, input: Input) -> usize; + + // invoke tracked function + #[salsa::invoke(invoke_length_tracked_actual)] + fn invoke_length_tracked(&self, input: Input) -> usize; +} + +fn length_query(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() +} + +fn invoke_length_query_actual(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() +} + +#[salsa::tracked] +fn invoke_length_tracked_actual(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() +} + +#[test] +fn unadorned_query() { + let db = LoggerDb::default(); + + let input = Input::new(&db, String::from("Hello, world!")); + let len = db.length_query(input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_PartialMigrationDatabase(Id(400)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(c00)) })", + ]"#]]); +} + +#[test] +fn invoke_query() { + let db = LoggerDb::default(); + + let input = Input::new(&db, String::from("Hello, world!")); + let len = db.invoke_length_query(input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_PartialMigrationDatabase(Id(400)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_query_shim(Id(c00)) })", + ]"#]]); +} + +// todo: does this even make sense? +#[test] +fn invoke_tracked_query() { + let db = LoggerDb::default(); + + let input = Input::new(&db, String::from("Hello, world!")); + let len = db.invoke_length_tracked(input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_PartialMigrationDatabase(Id(400)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_tracked_shim(Id(c00)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_tracked_actual(Id(0)) })", + ]"#]]); +} + +#[test] +fn new_salsa_baseline() { + let db = LoggerDb::default(); + + #[salsa::input] + struct Input { + str: String, + } + + #[salsa::tracked] + fn new_salsa_length_query(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() + } + + let input = Input::new(&db, String::from("Hello, world!")); + let len = new_salsa_length_query(&db, input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: new_salsa_length_query(Id(0)) })", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/result.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/result.rs new file mode 100644 index 0000000000000..51adde2a7ec0b --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/result.rs @@ -0,0 +1,50 @@ +mod logger_db; +use expect_test::expect; +use logger_db::LoggerDb; + +use query_group_macro::query_group; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Error; + +#[query_group] +pub trait ResultDatabase: salsa::Database { + #[salsa::input] + fn input_string(&self) -> String; + + fn length(&self, key: ()) -> Result; + + fn length2(&self, key: ()) -> Result; +} + +fn length(db: &dyn ResultDatabase, _key: ()) -> Result { + Ok(db.input_string().len()) +} + +fn length2(db: &dyn ResultDatabase, _key: ()) -> Result { + Ok(db.input_string().len()) +} + +#[test] +fn test_queries_with_results() { + let mut db = LoggerDb::default(); + let input = "hello"; + db.set_input_string(input.to_owned()); + assert_eq!(db.length(()), Ok(input.len())); + assert_eq!(db.length2(()), Ok(input.len())); + + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_ResultDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_ResultDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length2_shim(Id(c00)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs new file mode 100644 index 0000000000000..f7361eaa90fc5 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs @@ -0,0 +1,19 @@ +use query_group_macro::query_group; + +#[salsa::db] +pub trait SourceDb: salsa::Database { + /// Text of the file. + fn file_text(&self, id: usize) -> String; +} + +#[query_group] +pub trait RootDb: SourceDb { + fn parse(&self, id: usize) -> String; +} + +fn parse(db: &dyn RootDb, id: usize) -> String { + // this is the test: does the following compile? + db.file_text(id); + + String::new() +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/tuples.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/tuples.rs new file mode 100644 index 0000000000000..01f225ee10104 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/tuples.rs @@ -0,0 +1,38 @@ +use query_group_macro::query_group; + +mod logger_db; +use expect_test::expect; +use logger_db::LoggerDb; + +#[query_group] +pub trait HelloWorldDatabase: salsa::Database { + #[salsa::input] + fn input_string(&self) -> String; + + fn length_query(&self, key: ()) -> (usize, usize); +} + +fn length_query(db: &dyn HelloWorldDatabase, _key: ()) -> (usize, usize) { + let len = db.input_string().len(); + (len, len) +} + +#[test] +fn query() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query(()); + + assert_eq!(len, (13, 13)); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml index 5613d75c75225..3c2daacaf9501 100644 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true name = "ra_salsa_macros" [dependencies] -heck = "0.4" +heck = "0.5.0" proc-macro2 = "1.0" quote = "1.0" syn = { version = "2.0", features = ["full", "extra-traits"] } diff --git a/src/tools/rust-analyzer/xtask/src/tidy.rs b/src/tools/rust-analyzer/xtask/src/tidy.rs index b500b251ed355..04952de731893 100644 --- a/src/tools/rust-analyzer/xtask/src/tidy.rs +++ b/src/tools/rust-analyzer/xtask/src/tidy.rs @@ -147,6 +147,7 @@ MIT/Apache-2.0 MPL-2.0 Unlicense OR MIT Unlicense/MIT +Zlib Zlib OR Apache-2.0 OR MIT " .lines() From 83c1c4c2bb7c5744fe7e39869c941f52d54d80b7 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Mon, 10 Mar 2025 12:16:59 -0400 Subject: [PATCH 010/260] internal(config): use `FxIndexMap` for default completion snippets --- src/tools/rust-analyzer/Cargo.lock | 2 + src/tools/rust-analyzer/Cargo.toml | 2 +- .../crates/rust-analyzer/Cargo.toml | 1 + .../crates/rust-analyzer/src/config.rs | 50 ++++++++++--------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 4e9b4f7e41b43..a50e1e8f49add 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -897,6 +897,7 @@ checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown 0.14.5", + "serde", ] [[package]] @@ -1866,6 +1867,7 @@ dependencies = [ "ide-completion", "ide-db", "ide-ssr", + "indexmap", "intern", "itertools", "load-cargo", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index ce2d66000e396..35afbdd1b5c2d 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -117,7 +117,7 @@ expect-test = "1.4.0" hashbrown = { version = "0.14", features = [ "inline-more", ], default-features = false } -indexmap = "2.1.0" +indexmap = { version = "2.1.0", features = ["serde"] } itertools = "0.12.0" libc = "0.2.150" libloading = "0.8.0" diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index 6c81c238fd3f2..9d30c5d38eb42 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -25,6 +25,7 @@ crossbeam-channel.workspace = true dirs = "5.0.1" dissimilar.workspace = true ide-completion.workspace = true +indexmap.workspace = true itertools.workspace = true scip = "0.5.1" lsp-types = { version = "=0.95.0", features = ["proposed"] } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 45ac68339b38c..8d5440b85843c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -41,6 +41,8 @@ use crate::{ lsp_ext::{WorkspaceSymbolSearchKind, WorkspaceSymbolSearchScope}, }; +type FxIndexMap = indexmap::IndexMap; + mod patch_old_style; // Conventions for configuration keys to preserve maximal extendability without breakage: @@ -81,7 +83,7 @@ config_data! { cachePriming_numThreads: NumThreads = NumThreads::Physical, /// Custom completion snippets. - completion_snippets_custom: FxHashMap = Config::completion_snippets_default(), + completion_snippets_custom: FxIndexMap = Config::completion_snippets_default(), /// These paths (file/directories) will be ignored by rust-analyzer. They are @@ -931,7 +933,7 @@ impl Config { patch_old_style::patch_json_for_outdated_configs(&mut json); let mut json_errors = vec![]; - let snips = get_field_json::>( + let snips = get_field_json::>( &mut json, &mut json_errors, "completion_snippets_custom", @@ -2032,21 +2034,13 @@ impl Config { *self.cfg_setTest(source_root) } - pub(crate) fn completion_snippets_default() -> FxHashMap { + pub(crate) fn completion_snippets_default() -> FxIndexMap { serde_json::from_str( r#"{ - "Arc::new": { - "postfix": "arc", - "body": "Arc::new(${receiver})", - "requires": "std::sync::Arc", - "description": "Put the expression into an `Arc`", - "scope": "expr" - }, - "Rc::new": { - "postfix": "rc", - "body": "Rc::new(${receiver})", - "requires": "std::rc::Rc", - "description": "Put the expression into an `Rc`", + "Ok": { + "postfix": "ok", + "body": "Ok(${receiver})", + "description": "Wrap the expression in a `Result::Ok`", "scope": "expr" }, "Box::pin": { @@ -2056,10 +2050,17 @@ impl Config { "description": "Put the expression into a pinned `Box`", "scope": "expr" }, - "Ok": { - "postfix": "ok", - "body": "Ok(${receiver})", - "description": "Wrap the expression in a `Result::Ok`", + "Arc::new": { + "postfix": "arc", + "body": "Arc::new(${receiver})", + "requires": "std::sync::Arc", + "description": "Put the expression into an `Arc`", + "scope": "expr" + }, + "Some": { + "postfix": "some", + "body": "Some(${receiver})", + "description": "Wrap the expression in an `Option::Some`", "scope": "expr" }, "Err": { @@ -2068,10 +2069,11 @@ impl Config { "description": "Wrap the expression in a `Result::Err`", "scope": "expr" }, - "Some": { - "postfix": "some", - "body": "Some(${receiver})", - "description": "Wrap the expression in an `Option::Some`", + "Rc::new": { + "postfix": "rc", + "body": "Rc::new(${receiver})", + "requires": "std::rc::Rc", + "description": "Put the expression into an `Rc`", "scope": "expr" } }"#, @@ -3210,7 +3212,7 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json "FxHashMap, Box<[Box]>>" => set! { "type": "object", }, - "FxHashMap" => set! { + "FxIndexMap" => set! { "type": "object", }, "FxHashMap" => set! { From a5c071633be35085edff186cef7fcfb2d17c22af Mon Sep 17 00:00:00 2001 From: David Barsky Date: Tue, 5 Nov 2024 12:24:41 -0500 Subject: [PATCH 011/260] internal: port rust-analyzer to new Salsa --- src/tools/rust-analyzer/Cargo.lock | 855 ++++++++++++------ src/tools/rust-analyzer/Cargo.toml | 3 +- .../rust-analyzer/crates/base-db/Cargo.toml | 4 +- .../crates/base-db/src/change.rs | 15 +- .../rust-analyzer/crates/base-db/src/lib.rs | 338 ++++--- .../rust-analyzer/crates/edition/src/lib.rs | 10 + .../rust-analyzer/crates/hir-def/Cargo.toml | 4 +- .../rust-analyzer/crates/hir-def/src/attr.rs | 7 +- .../crates/hir-def/src/data/adt.rs | 1 + .../rust-analyzer/crates/hir-def/src/db.rs | 184 ++-- .../crates/hir-def/src/expr_store.rs | 7 +- .../crates/hir-def/src/expr_store/lower.rs | 19 +- .../crates/hir-def/src/expr_store/scope.rs | 27 +- .../hir-def/src/expr_store/tests/block.rs | 4 +- .../crates/hir-def/src/generics.rs | 6 +- .../crates/hir-def/src/import_map.rs | 2 +- .../crates/hir-def/src/item_tree/pretty.rs | 2 +- .../crates/hir-def/src/item_tree/tests.rs | 2 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 100 +- .../hir-def/src/macro_expansion_tests/mbe.rs | 30 +- .../hir-def/src/macro_expansion_tests/mod.rs | 13 +- .../src/macro_expansion_tests/proc_macros.rs | 6 +- .../crates/hir-def/src/nameres.rs | 7 +- .../crates/hir-def/src/nameres/collector.rs | 6 +- .../hir-def/src/nameres/mod_resolution.rs | 5 +- .../crates/hir-def/src/nameres/tests.rs | 2 +- .../hir-def/src/nameres/tests/incremental.rs | 22 +- .../crates/hir-def/src/path/lower.rs | 2 +- .../crates/hir-def/src/resolver.rs | 25 +- .../crates/hir-def/src/test_db.rs | 134 ++- .../crates/hir-expand/Cargo.toml | 2 + .../crates/hir-expand/src/builtin/fn_macro.rs | 25 +- .../crates/hir-expand/src/builtin/quote.rs | 4 +- .../crates/hir-expand/src/change.rs | 8 +- .../rust-analyzer/crates/hir-expand/src/db.rs | 131 +-- .../crates/hir-expand/src/declarative.rs | 5 +- .../crates/hir-expand/src/eager.rs | 10 +- .../crates/hir-expand/src/files.rs | 20 +- .../crates/hir-expand/src/hygiene.rs | 137 ++- .../crates/hir-expand/src/lib.rs | 41 +- .../crates/hir-expand/src/mod_path.rs | 4 +- .../src/prettify_macro_expansion_.rs | 3 +- .../crates/hir-expand/src/span_map.rs | 12 +- .../rust-analyzer/crates/hir-ty/Cargo.toml | 3 + .../crates/hir-ty/src/chalk_db.rs | 4 +- .../crates/hir-ty/src/consteval.rs | 26 +- .../crates/hir-ty/src/consteval/tests.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/db.rs | 219 +++-- .../hir-ty/src/diagnostics/decl_check.rs | 4 +- .../crates/hir-ty/src/diagnostics/expr.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/drop.rs | 9 +- .../crates/hir-ty/src/infer/expr.rs | 2 +- .../crates/hir-ty/src/interner.rs | 5 +- .../rust-analyzer/crates/hir-ty/src/layout.rs | 17 +- .../crates/hir-ty/src/layout/adt.rs | 13 +- .../rust-analyzer/crates/hir-ty/src/lib.rs | 2 - .../rust-analyzer/crates/hir-ty/src/lower.rs | 37 +- .../crates/hir-ty/src/mapping.rs | 49 +- .../crates/hir-ty/src/method_resolution.rs | 1 + .../rust-analyzer/crates/hir-ty/src/mir.rs | 9 +- .../crates/hir-ty/src/mir/borrowck.rs | 8 +- .../crates/hir-ty/src/mir/eval.rs | 1 + .../crates/hir-ty/src/mir/lower.rs | 6 +- .../crates/hir-ty/src/mir/monomorphization.rs | 14 +- .../crates/hir-ty/src/test_db.rs | 121 ++- .../rust-analyzer/crates/hir-ty/src/tests.rs | 2 +- .../hir-ty/src/tests/closure_captures.rs | 6 +- .../crates/hir-ty/src/tests/incremental.rs | 10 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 2 +- .../crates/hir-ty/src/variance.rs | 6 +- src/tools/rust-analyzer/crates/hir/src/db.rs | 81 +- .../crates/hir/src/has_source.rs | 2 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 10 +- .../rust-analyzer/crates/hir/src/semantics.rs | 20 +- .../hir/src/semantics/child_by_source.rs | 2 +- .../crates/hir/src/semantics/source_to_def.rs | 16 +- .../crates/hir/src/source_analyzer.rs | 3 +- .../rust-analyzer/crates/hir/src/symbols.rs | 6 +- .../crates/ide-assists/src/assist_context.rs | 6 +- .../src/handlers/add_missing_match_arms.rs | 8 +- .../src/handlers/convert_bool_to_enum.rs | 2 +- .../src/handlers/convert_closure_to_fn.rs | 2 +- .../src/handlers/extract_module.rs | 12 +- .../src/handlers/generate_function.rs | 7 +- .../src/handlers/remove_unused_param.rs | 10 +- .../crates/ide-assists/src/tests.rs | 19 +- .../ide-completion/src/completions/mod_.rs | 7 +- .../ide-completion/src/completions/postfix.rs | 2 +- .../crates/ide-completion/src/context.rs | 17 +- .../crates/ide-completion/src/lib.rs | 7 +- .../crates/ide-completion/src/render.rs | 2 +- .../crates/ide-completion/src/tests.rs | 2 +- .../src/tests/raw_identifiers.rs | 2 +- .../rust-analyzer/crates/ide-db/Cargo.toml | 4 + .../crates/ide-db/src/apply_change.rs | 361 ++++---- .../crates/ide-db/src/famous_defs.rs | 2 +- .../crates/ide-db/src/helpers.rs | 6 +- .../ide-db/src/imports/insert_use/tests.rs | 7 + .../rust-analyzer/crates/ide-db/src/lib.rs | 181 ++-- .../crates/ide-db/src/prime_caches.rs | 18 +- .../rust-analyzer/crates/ide-db/src/search.rs | 43 +- .../crates/ide-db/src/symbol_index.rs | 39 +- .../ide-db/src/syntax_helpers/suggest_name.rs | 6 +- .../ide-db/src/test_data/test_doc_alias.txt | 14 +- .../test_symbol_index_collection.txt | 60 +- .../rust-analyzer/crates/ide-db/src/traits.rs | 13 +- .../src/handlers/type_mismatch.rs | 2 +- .../src/handlers/unlinked_file.rs | 16 +- .../crates/ide-diagnostics/src/lib.rs | 49 +- .../crates/ide-diagnostics/src/tests.rs | 10 +- .../crates/ide-ssr/src/from_comment.rs | 11 +- .../rust-analyzer/crates/ide-ssr/src/lib.rs | 24 +- .../crates/ide-ssr/src/matching.rs | 2 +- .../crates/ide-ssr/src/resolving.rs | 9 +- .../crates/ide-ssr/src/search.rs | 12 +- .../rust-analyzer/crates/ide-ssr/src/tests.rs | 4 +- .../rust-analyzer/crates/ide/src/doc_links.rs | 2 +- .../crates/ide/src/doc_links/tests.rs | 4 +- .../crates/ide/src/expand_macro.rs | 6 +- .../crates/ide/src/fetch_crates.rs | 2 +- .../crates/ide/src/goto_definition.rs | 7 +- .../crates/ide/src/highlight_related.rs | 6 +- .../crates/ide/src/hover/render.rs | 2 +- .../crates/ide/src/hover/tests.rs | 14 +- .../crates/ide/src/inlay_hints.rs | 10 +- .../crates/ide/src/inlay_hints/bind_pat.rs | 8 +- .../rust-analyzer/crates/ide/src/interpret.rs | 17 +- src/tools/rust-analyzer/crates/ide/src/lib.rs | 68 +- .../crates/ide/src/parent_module.rs | 6 +- .../rust-analyzer/crates/ide/src/rename.rs | 5 +- .../rust-analyzer/crates/ide/src/runnables.rs | 2 +- src/tools/rust-analyzer/crates/ide/src/ssr.rs | 2 +- .../crates/ide/src/static_index.rs | 8 +- .../rust-analyzer/crates/ide/src/status.rs | 237 +---- .../crates/ide/src/syntax_highlighting.rs | 8 +- .../ide/src/syntax_highlighting/html.rs | 5 +- .../test_data/highlight_rainbow.html | 12 +- .../crates/ide/src/test_explorer.rs | 2 +- .../rust-analyzer/crates/ide/src/typing.rs | 13 +- .../crates/ide/src/typing/on_enter.rs | 10 +- .../crates/ide/src/view_crate_graph.rs | 9 +- .../crates/load-cargo/src/lib.rs | 2 +- .../rust-analyzer/crates/mbe/src/tests.rs | 160 ++-- .../crates/query-group-macro/Cargo.toml | 2 +- .../rust-analyzer/src/cli/analysis_stats.rs | 92 +- .../rust-analyzer/src/cli/diagnostics.rs | 6 +- .../crates/rust-analyzer/src/cli/run_tests.rs | 10 +- .../rust-analyzer/src/cli/rustc_tests.rs | 4 +- .../crates/rust-analyzer/src/cli/ssr.rs | 6 +- .../src/cli/unresolved_references.rs | 12 +- .../crates/rust-analyzer/src/global_state.rs | 31 +- .../rust-analyzer/src/handlers/dispatch.rs | 5 +- .../src/handlers/notification.rs | 3 +- .../rust-analyzer/src/handlers/request.rs | 25 +- .../crates/rust-analyzer/src/main_loop.rs | 18 +- .../crates/rust-analyzer/src/reload.rs | 2 +- .../rust-analyzer/crates/span/Cargo.toml | 5 +- .../rust-analyzer/crates/span/src/hygiene.rs | 381 ++++++-- .../rust-analyzer/crates/span/src/lib.rs | 135 +-- .../crates/test-fixture/src/lib.rs | 9 +- src/tools/rust-analyzer/xtask/src/tidy.rs | 5 +- 161 files changed, 3042 insertions(+), 2298 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index a50e1e8f49add..efd7362594c21 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -40,41 +40,41 @@ checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.36.3", + "object 0.36.7", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -82,11 +82,13 @@ name = "base-db" version = "0.0.0" dependencies = [ "cfg", + "dashmap 5.5.3", "intern", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lz4_flex", - "rustc-hash 2.0.0", - "salsa 0.0.0", + "query-group-macro", + "rustc-hash 2.1.1", + "salsa 0.19.0", "semver", "span", "stdx", @@ -110,17 +112,17 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc" dependencies = [ - "cfg_aliases 0.2.1", + "cfg_aliases", ] [[package]] @@ -140,18 +142,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -172,9 +174,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.22" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "shlex", ] @@ -188,7 +190,7 @@ dependencies = [ "expect-test", "intern", "oorandom", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "syntax", "syntax-bridge", "tracing", @@ -201,12 +203,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "cfg_aliases" version = "0.2.1" @@ -231,7 +227,7 @@ version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f114996bda14c0213f014a4ef31a7867dcf5f539a3900477fc6b20138e7a17b" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "chalk-derive", ] @@ -287,18 +283,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -324,18 +320,18 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "ctrlc" -version = "3.4.4" +version = "3.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" dependencies = [ "nix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -376,9 +372,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", @@ -415,11 +411,22 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dissimilar" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" +checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" [[package]] name = "dot" @@ -439,9 +446,9 @@ version = "0.0.0" [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "ena" @@ -454,15 +461,15 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "expect-test" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e0be0a561335815e06dab7c62e50353134c796e7a6155402a64bcff66b6a5e0" +checksum = "63af43ff4431e848fb47472a920f14fa71c24de13255a5692e93d4e90302acb0" dependencies = [ "dissimilar", "once_cell", @@ -470,9 +477,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -488,9 +495,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.31" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", @@ -552,9 +559,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "hashbrown" @@ -609,7 +616,7 @@ dependencies = [ "indexmap", "intern", "itertools", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "smallvec", "span", "stdx", @@ -628,7 +635,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags 2.7.0", + "bitflags 2.9.0", "cfg", "cov-mark", "dashmap 5.5.3", @@ -643,11 +650,13 @@ dependencies = [ "itertools", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "mbe", + "query-group-macro", "ra-ap-rustc_abi", "ra-ap-rustc_hashes", "ra-ap-rustc_parse_format", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc_apfloat", + "salsa 0.19.0", "smallvec", "span", "stdx", @@ -676,7 +685,9 @@ dependencies = [ "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "mbe", "parser", - "rustc-hash 2.0.0", + "query-group-macro", + "rustc-hash 2.1.1", + "salsa 0.19.0", "smallvec", "span", "stdx", @@ -693,12 +704,13 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags 2.7.0", + "bitflags 2.9.0", "chalk-derive", "chalk-ir", "chalk-recursive", "chalk-solve", "cov-mark", + "dashmap 5.5.3", "either", "ena", "expect-test", @@ -711,11 +723,13 @@ dependencies = [ "nohash-hasher", "oorandom", "project-model", + "query-group-macro", "ra-ap-rustc_abi", "ra-ap-rustc_index", "ra-ap-rustc_pattern_analysis", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc_apfloat", + "salsa 0.19.0", "scoped-tls", "smallvec", "span", @@ -732,11 +746,129 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -816,9 +948,10 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags 2.7.0", + "bitflags 2.9.0", "cov-mark", "crossbeam-channel", + "dashmap 5.5.3", "either", "expect-test", "fst", @@ -830,8 +963,10 @@ dependencies = [ "nohash-hasher", "parser", "profile", + "query-group-macro", "rayon", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", + "salsa 0.19.0", "span", "stdx", "syntax", @@ -839,6 +974,7 @@ dependencies = [ "test-utils", "tracing", "triomphe", + "vfs", ] [[package]] @@ -881,22 +1017,33 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "indexmap" -version = "2.3.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "serde", ] @@ -906,7 +1053,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "inotify-sys", "libc", ] @@ -926,7 +1073,7 @@ version = "0.0.0" dependencies = [ "dashmap 5.5.3", "hashbrown 0.14.5", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "triomphe", ] @@ -941,9 +1088,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jod-thread" @@ -989,15 +1136,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -1019,7 +1166,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "libc", "redox_syscall", ] @@ -1049,6 +1196,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "litemap" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" + [[package]] name = "load-cargo" version = "0.0.0" @@ -1081,9 +1234,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "loom" @@ -1100,24 +1253,25 @@ dependencies = [ [[package]] name = "lsp-server" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9" +version = "0.7.8" dependencies = [ "crossbeam-channel", + "ctrlc", "log", + "lsp-types", "serde", + "serde_derive", "serde_json", ] [[package]] name = "lsp-server" version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9462c4dc73e17f971ec1f171d44bfffb72e65a130117233388a0ebc7ec5656f9" dependencies = [ "crossbeam-channel", - "ctrlc", "log", - "lsp-types", "serde", "serde_derive", "serde_json", @@ -1161,7 +1315,7 @@ dependencies = [ "intern", "parser", "ra-ap-rustc_lexer", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "smallvec", "span", "stdx", @@ -1207,11 +1361,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1237,13 +1391,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "cfg-if", - "cfg_aliases 0.1.1", + "cfg_aliases", "libc", ] @@ -1259,7 +1413,7 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "filetime", "fsevent-sys", "inotify", @@ -1333,24 +1487,24 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "option-ext" @@ -1449,9 +1603,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "portable-atomic" @@ -1467,9 +1621,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] @@ -1481,7 +1635,7 @@ dependencies = [ "indexmap", "intern", "paths", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "serde", "serde_derive", "serde_json", @@ -1528,23 +1682,23 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "process-wrap" -version = "8.0.2" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ee68ae331824036479c84060534b18254c864fa73366c58d86db3b7b811619" +checksum = "d35f4dc9988d1326b065b4def5e950c3ed727aa03e3151b86cc9e2aec6b03f54" dependencies = [ "indexmap", "nix", "tracing", - "windows 0.56.0", + "windows 0.59.0", ] [[package]] @@ -1571,7 +1725,7 @@ dependencies = [ "itertools", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "paths", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "semver", "serde", "serde_derive", @@ -1609,7 +1763,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "memchr", "unicase", ] @@ -1637,9 +1791,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" dependencies = [ "proc-macro2", ] @@ -1650,7 +1804,7 @@ version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1651b0f7e8c3eb7c27a88f39d277e69c32bfe58e3be174d286c1a24d6a7a4d8" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "ra-ap-rustc_hashes", "ra-ap-rustc_index", "tracing", @@ -1714,7 +1868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef3ff73fa4653252ffe1d1e9177a446f49ef46d97140e4816b7ff2dad59ed53" dependencies = [ "ra-ap-rustc_index", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc_apfloat", "smallvec", "tracing", @@ -1772,18 +1926,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -1871,7 +2025,7 @@ dependencies = [ "intern", "itertools", "load-cargo", - "lsp-server 0.7.7", + "lsp-server 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "lsp-types", "memchr", "mimalloc", @@ -1886,7 +2040,7 @@ dependencies = [ "profile", "project-model", "rayon", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "scip", "semver", "serde", @@ -1927,23 +2081,23 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-stable-hash" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2febf9acc5ee5e99d1ad0afcdbccc02d87aa3f857a1f01f825b80eacf8edfcd1" +checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" [[package]] name = "rustc_apfloat" -version = "0.2.1+llvm-462a31f5a5ab" +version = "0.2.2+llvm-462a31f5a5ab" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886d94c63c812a8037c4faca2607453a0fa4cf82f734665266876b022244543f" +checksum = "121e2195ff969977a4e2b5c9965ea867fce7e4cb5aee5b09dee698a7932d574f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.0", "smallvec", ] @@ -1955,9 +2109,9 @@ checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa" @@ -1972,7 +2126,7 @@ dependencies = [ "oorandom", "parking_lot", "rand", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "salsa-macros 0.0.0", "smallvec", "tracing", @@ -1994,7 +2148,7 @@ dependencies = [ "parking_lot", "portable-atomic", "rayon", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "salsa-macro-rules", "salsa-macros 0.19.0", "smallvec", @@ -2041,9 +2195,9 @@ dependencies = [ [[package]] name = "scip" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dfafd2fa14c6237fa1fc4310f739d02fa915d92977fa069426591f1de046f81" +checksum = "fb2b449a5e4660ce817676a0871cd1b4e2ff1023e33a1ac046670fa594b543a2" dependencies = [ "protobuf", ] @@ -2062,27 +2216,27 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -2091,9 +2245,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "indexmap", "itoa", @@ -2104,9 +2258,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", @@ -2115,9 +2269,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -2139,9 +2293,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "smol_str" @@ -2159,14 +2313,20 @@ version = "0.0.0" dependencies = [ "hashbrown 0.14.5", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hash 2.0.0", - "salsa 0.0.0", + "rustc-hash 2.1.1", + "salsa 0.19.0", "stdx", "syntax", "text-size", "vfs", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "stdx" version = "0.0.0" @@ -2183,9 +2343,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -2216,7 +2376,7 @@ dependencies = [ "ra-ap-rustc_lexer", "rayon", "rowan", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc_apfloat", "smol_str", "stdx", @@ -2231,7 +2391,7 @@ version = "0.0.0" dependencies = [ "intern", "parser", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "span", "stdx", "syntax", @@ -2254,7 +2414,7 @@ dependencies = [ "cfg", "hir-expand", "intern", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "span", "stdx", "test-utils", @@ -2268,7 +2428,7 @@ dependencies = [ "dissimilar", "paths", "profile", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "stdx", "text-size", "tracing", @@ -2282,18 +2442,18 @@ checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -2343,9 +2503,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" dependencies = [ "deranged", "itoa", @@ -2360,40 +2520,35 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" dependencies = [ "num-conv", "time-core", ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "toml" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", @@ -2412,9 +2567,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", @@ -2433,9 +2588,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -2444,9 +2599,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -2455,9 +2610,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -2476,9 +2631,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term 0.46.0", @@ -2536,51 +2691,33 @@ checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -2589,16 +2726,22 @@ dependencies = [ ] [[package]] -name = "valuable" -version = "0.1.0" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] -name = "version_check" -version = "0.9.5" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vfs" @@ -2609,7 +2752,7 @@ dependencies = [ "indexmap", "nohash-hasher", "paths", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "stdx", "tracing", ] @@ -2622,7 +2765,7 @@ dependencies = [ "notify", "paths", "rayon", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "stdx", "tracing", "vfs", @@ -2676,16 +2819,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" -dependencies = [ - "windows-core 0.56.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.58.0" @@ -2697,15 +2830,13 @@ dependencies = [ ] [[package]] -name = "windows-core" -version = "0.56.0" +name = "windows" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1" dependencies = [ - "windows-implement 0.56.0", - "windows-interface 0.56.0", - "windows-result 0.1.2", - "windows-targets 0.52.6", + "windows-core 0.59.0", + "windows-targets 0.53.0", ] [[package]] @@ -2717,19 +2848,21 @@ dependencies = [ "windows-implement 0.58.0", "windows-interface 0.58.0", "windows-result 0.2.0", - "windows-strings", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] [[package]] -name = "windows-implement" -version = "0.56.0" +name = "windows-core" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce" dependencies = [ - "proc-macro2", - "quote", - "syn", + "windows-implement 0.59.0", + "windows-interface 0.59.0", + "windows-result 0.3.1", + "windows-strings 0.3.1", + "windows-targets 0.53.0", ] [[package]] @@ -2744,10 +2877,10 @@ dependencies = [ ] [[package]] -name = "windows-interface" -version = "0.56.0" +name = "windows-implement" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" dependencies = [ "proc-macro2", "quote", @@ -2766,14 +2899,22 @@ dependencies = [ ] [[package]] -name = "windows-result" -version = "0.1.2" +name = "windows-interface" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01" dependencies = [ - "windows-targets 0.52.6", + "proc-macro2", + "quote", + "syn", ] +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + [[package]] name = "windows-result" version = "0.2.0" @@ -2783,6 +2924,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-strings" version = "0.1.0" @@ -2793,6 +2943,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -2844,13 +3003,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -2863,6 +3038,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -2875,6 +3056,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -2887,12 +3074,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -2905,6 +3104,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -2917,6 +3122,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -2929,6 +3140,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -2941,11 +3158,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.6.18" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] @@ -2956,6 +3179,18 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23f6174b2566cc4a74f95e1367ec343e7fa80c93cc8087f5c4a3d6a1088b2118" +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xflags" version = "0.3.2" @@ -3007,21 +3242,87 @@ dependencies = [ "zip", ] +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 35afbdd1b5c2d..7dd5f2bb1faa9 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -72,7 +72,7 @@ proc-macro-srv = { path = "./crates/proc-macro-srv", version = "0.0.0" } proc-macro-srv-cli = { path = "./crates/proc-macro-srv-cli", version = "0.0.0" } profile = { path = "./crates/profile", version = "0.0.0" } project-model = { path = "./crates/project-model", version = "0.0.0" } -ra-salsa = { path = "./crates/ra-salsa", package = "salsa", version = "0.0.0" } +query-group = { package = "query-group-macro", path = "./crates/query-group-macro", version = "0.0.0" } span = { path = "./crates/span", version = "0.0.0" } stdx = { path = "./crates/stdx", version = "0.0.0" } syntax = { path = "./crates/syntax", version = "0.0.0" } @@ -135,6 +135,7 @@ process-wrap = { version = "8.0.2", features = ["std"] } pulldown-cmark-to-cmark = "10.0.4" pulldown-cmark = { version = "0.9.0", default-features = false } rayon = "1.8.0" +salsa = "0.19" rustc-hash = "2.0.0" semver = "1.0.14" serde = { version = "1.0.192" } diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index 042dd36488aa9..4780d5191befb 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -15,7 +15,9 @@ rust-version.workspace = true lz4_flex = { version = "0.11", default-features = false } la-arena.workspace = true -ra-salsa.workspace = true +dashmap.workspace = true +salsa.workspace = true +query-group.workspace = true rustc-hash.workspace = true triomphe.workspace = true semver.workspace = true diff --git a/src/tools/rust-analyzer/crates/base-db/src/change.rs b/src/tools/rust-analyzer/crates/base-db/src/change.rs index 7e40f5408f144..90413a573aef3 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/change.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/change.rs @@ -3,15 +3,12 @@ use std::fmt; -use ra_salsa::Durability; use rustc_hash::FxHashMap; +use salsa::Durability; use triomphe::Arc; use vfs::FileId; -use crate::{ - CrateGraph, CrateId, CrateWorkspaceData, SourceDatabaseFileInputExt, SourceRoot, - SourceRootDatabase, SourceRootId, -}; +use crate::{CrateGraph, CrateId, CrateWorkspaceData, RootQueryDb, SourceRoot, SourceRootId}; /// Encapsulate a bunch of raw `.set` calls on the database. #[derive(Default)] @@ -59,7 +56,7 @@ impl FileChange { self.ws_data = Some(data); } - pub fn apply(self, db: &mut dyn SourceRootDatabase) { + pub fn apply(self, db: &mut dyn RootQueryDb) { let _p = tracing::info_span!("FileChange::apply").entered(); if let Some(roots) = self.roots { for (idx, root) in roots.into_iter().enumerate() { @@ -68,14 +65,16 @@ impl FileChange { for file_id in root.iter() { db.set_file_source_root_with_durability(file_id, root_id, durability); } + db.set_source_root_with_durability(root_id, Arc::new(root), durability); } } for (file_id, text) in self.files_changed { let source_root_id = db.file_source_root(file_id); - let source_root = db.source_root(source_root_id); - let durability = durability(&source_root); + let source_root = db.source_root(source_root_id.source_root_id(db)); + + let durability = durability(&source_root.source_root(db)); // XXX: can't actually remove the file, just reset the text let text = text.unwrap_or_default(); db.set_file_text_with_durability(file_id, &text, durability) diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index eed8c88683951..9ec9100968d22 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -3,14 +3,7 @@ mod change; mod input; -use std::panic; - -use ra_salsa::Durability; -use rustc_hash::FxHashMap; -use span::EditionedFileId; -use syntax::{ast, Parse, SourceFile, SyntaxError}; -use triomphe::Arc; -use vfs::FileId; +use std::hash::BuildHasherDefault; pub use crate::{ change::FileChange, @@ -20,20 +13,30 @@ pub use crate::{ TargetLayoutLoadResult, }, }; -pub use ra_salsa::{self, Cancelled}; -pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, VfsPath}; - +use dashmap::{mapref::entry::Entry, DashMap}; +pub use query_group::{self}; +use rustc_hash::{FxHashMap, FxHasher}; +pub use salsa::{self}; +use salsa::{Durability, Setter}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; +use syntax::{ast, Parse, SyntaxError}; +use triomphe::Arc; +pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath}; #[macro_export] macro_rules! impl_intern_key { - ($name:ident) => { - impl $crate::ra_salsa::InternKey for $name { - fn from_intern_id(v: $crate::ra_salsa::InternId) -> Self { - $name(v) - } - fn as_intern_id(&self) -> $crate::ra_salsa::InternId { - self.0 + ($id:ident, $loc:ident) => { + #[salsa::interned(no_debug, no_lifetime)] + pub struct $id { + pub loc: $loc, + } + + // If we derive this salsa prints the values recursively, and this causes us to blow. + impl ::std::fmt::Debug for $id { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.debug_tuple(stringify!($id)) + .field(&format_args!("{:04x}", self.0.as_u32())) + .finish() } } }; @@ -47,39 +50,213 @@ pub const DEFAULT_FILE_TEXT_LRU_CAP: u16 = 16; pub const DEFAULT_PARSE_LRU_CAP: u16 = 128; pub const DEFAULT_BORROWCK_LRU_CAP: u16 = 2024; -pub trait FileLoader { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option; - /// Crates whose root's source root is the same as the source root of `file_id` - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]>; +#[derive(Debug, Default)] +pub struct Files { + files: Arc>>, + source_roots: Arc>>, + file_source_roots: Arc>>, } -/// Database which stores all significant input facts: source code and project -/// model. Everything else in rust-analyzer is derived from these queries. -#[ra_salsa::query_group(SourceDatabaseStorage)] -pub trait SourceDatabase: FileLoader + std::fmt::Debug { - #[ra_salsa::input] - fn compressed_file_text(&self, file_id: FileId) -> Arc<[u8]>; +impl Files { + pub fn file_text(&self, file_id: vfs::FileId) -> FileText { + *self.files.get(&file_id).expect("Unable to fetch file; this is a bug") + } - /// Text of the file. - #[ra_salsa::lru] - fn file_text(&self, file_id: FileId) -> Arc; + pub fn set_file_text(&self, db: &mut dyn SourceDatabase, file_id: vfs::FileId, text: &str) { + let files = Arc::clone(&self.files); + match files.entry(file_id) { + Entry::Occupied(mut occupied) => { + occupied.get_mut().set_text(db).to(Arc::from(text)); + } + Entry::Vacant(vacant) => { + let text = FileText::new(db, Arc::from(text), file_id); + vacant.insert(text); + } + }; + } + pub fn set_file_text_with_durability( + &self, + db: &mut dyn SourceDatabase, + file_id: vfs::FileId, + text: &str, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + match files.entry(file_id) { + Entry::Occupied(mut occupied) => { + occupied.get_mut().set_text(db).to(Arc::from(text)); + } + Entry::Vacant(vacant) => { + let text = + FileText::builder(Arc::from(text), file_id).durability(durability).new(db); + vacant.insert(text); + } + }; + } + + /// Source root of the file. + pub fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput { + let source_root = self + .source_roots + .get(&source_root_id) + .expect("Unable to fetch source root id; this is a bug"); + + *source_root + } + + pub fn set_source_root_with_durability( + &self, + db: &mut dyn SourceDatabase, + source_root_id: SourceRootId, + source_root: Arc, + durability: Durability, + ) { + let source_roots = Arc::clone(&self.source_roots); + match source_roots.entry(source_root_id) { + Entry::Occupied(mut occupied) => { + occupied.get_mut().set_source_root(db).to(source_root); + } + Entry::Vacant(vacant) => { + let source_root = + SourceRootInput::builder(source_root).durability(durability).new(db); + vacant.insert(source_root); + } + }; + } + + pub fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput { + let file_source_root = self + .file_source_roots + .get(&id) + .expect("Unable to fetch FileSourceRootInput; this is a bug"); + *file_source_root + } + + pub fn set_file_source_root_with_durability( + &self, + db: &mut dyn SourceDatabase, + id: vfs::FileId, + source_root_id: SourceRootId, + durability: Durability, + ) { + let file_source_roots = Arc::clone(&self.file_source_roots); + // let db = self; + match file_source_roots.entry(id) { + Entry::Occupied(mut occupied) => { + occupied.get_mut().set_source_root_id(db).to(source_root_id); + } + Entry::Vacant(vacant) => { + let file_source_root = + FileSourceRootInput::builder(source_root_id).durability(durability).new(db); + vacant.insert(file_source_root); + } + }; + } +} + +#[salsa::interned(no_lifetime)] +pub struct EditionedFileId { + pub editioned_file_id: span::EditionedFileId, +} + +impl EditionedFileId { + pub fn file_id(&self, db: &dyn salsa::Database) -> vfs::FileId { + let id = self.editioned_file_id(db); + id.file_id() + } + + fn unpack(&self, db: &dyn salsa::Database) -> (vfs::FileId, span::Edition) { + let id = self.editioned_file_id(db); + (id.file_id(), id.edition()) + } +} + +#[salsa::input] +pub struct FileText { + pub text: Arc, + pub file_id: vfs::FileId, +} + +#[salsa::input] +pub struct FileSourceRootInput { + pub source_root_id: SourceRootId, +} + +#[salsa::input] +pub struct SourceRootInput { + pub source_root: Arc, +} + +/// Database which stores all significant input facts: source code and project +/// model. Everything else in rust-analyzer is derived from these queries. +#[query_group::query_group] +pub trait RootQueryDb: SourceDatabase + salsa::Database { /// Parses the file into the syntax tree. - #[ra_salsa::lru] + #[salsa::invoke_actual(parse)] + #[salsa::lru(128)] fn parse(&self, file_id: EditionedFileId) -> Parse; /// Returns the set of errors obtained from parsing the file including validation errors. fn parse_errors(&self, file_id: EditionedFileId) -> Option>; /// The crate graph. - #[ra_salsa::input] + #[salsa::input] fn crate_graph(&self) -> Arc; - #[ra_salsa::input] + #[salsa::input] fn crate_workspace_data(&self) -> Arc>>; - #[ra_salsa::transparent] + #[salsa::transparent] fn toolchain_channel(&self, krate: CrateId) -> Option; + + /// Crates whose root file is in `id`. + fn source_root_crates(&self, id: SourceRootId) -> Arc<[CrateId]>; + + #[salsa::transparent] + fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]>; +} + +#[salsa::db] +pub trait SourceDatabase: salsa::Database { + /// Text of the file. + fn file_text(&self, file_id: vfs::FileId) -> FileText; + + fn set_file_text(&mut self, file_id: vfs::FileId, text: &str); + + fn set_file_text_with_durability( + &mut self, + file_id: vfs::FileId, + text: &str, + durability: Durability, + ); + + /// Contents of the source root. + fn source_root(&self, id: SourceRootId) -> SourceRootInput; + + fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput; + + fn set_file_source_root_with_durability( + &mut self, + id: vfs::FileId, + source_root_id: SourceRootId, + durability: Durability, + ); + + /// Source root of the file. + fn set_source_root_with_durability( + &mut self, + source_root_id: SourceRootId, + source_root: Arc, + durability: Durability, + ); + + fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { + // FIXME: this *somehow* should be platform agnostic... + let source_root = self.file_source_root(path.anchor); + let source_root = self.source_root(source_root.source_root_id(self)); + source_root.source_root(self).resolve_path(path) + } } /// Crate related data shared by the whole workspace. @@ -91,7 +268,7 @@ pub struct CrateWorkspaceData { pub toolchain: Option, } -fn toolchain_channel(db: &dyn SourceDatabase, krate: CrateId) -> Option { +fn toolchain_channel(db: &dyn RootQueryDb, krate: CrateId) -> Option { db.crate_workspace_data() .get(&krate)? .toolchain @@ -99,14 +276,14 @@ fn toolchain_channel(db: &dyn SourceDatabase, krate: CrateId) -> Option Parse { +fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse { let _p = tracing::info_span!("parse", ?file_id).entered(); - let (file_id, edition) = file_id.unpack(); - let text = db.file_text(file_id); - SourceFile::parse(&text, edition) + let (file_id, edition) = file_id.unpack(db.as_dyn_database()); + let text = db.file_text(file_id).text(db); + ast::SourceFile::parse(&text, edition) } -fn parse_errors(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Option> { +fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option> { let errors = db.parse(file_id).errors(); match &*errors { [] => None, @@ -114,67 +291,13 @@ fn parse_errors(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Option Arc { - let bytes = db.compressed_file_text(file_id); - let bytes = - lz4_flex::decompress_size_prepended(&bytes).expect("lz4 decompression should not fail"); - let text = std::str::from_utf8(&bytes).expect("file contents should be valid UTF-8"); - Arc::from(text) -} - -/// We don't want to give HIR knowledge of source roots, hence we extract these -/// methods into a separate DB. -#[ra_salsa::query_group(SourceRootDatabaseStorage)] -pub trait SourceRootDatabase: SourceDatabase { - /// Path to a file, relative to the root of its source root. - /// Source root of the file. - #[ra_salsa::input] - fn file_source_root(&self, file_id: FileId) -> SourceRootId; - /// Contents of the source root. - #[ra_salsa::input] - fn source_root(&self, id: SourceRootId) -> Arc; - - /// Crates whose root file is in `id`. - fn source_root_crates(&self, id: SourceRootId) -> Arc<[CrateId]>; -} - -pub trait SourceDatabaseFileInputExt { - fn set_file_text(&mut self, file_id: FileId, text: &str) { - self.set_file_text_with_durability(file_id, text, Durability::LOW); - } - - fn set_file_text_with_durability( - &mut self, - file_id: FileId, - text: &str, - durability: Durability, - ); -} - -impl SourceDatabaseFileInputExt for Db { - fn set_file_text_with_durability( - &mut self, - file_id: FileId, - text: &str, - durability: Durability, - ) { - let bytes = text.as_bytes(); - let compressed = lz4_flex::compress_prepend_size(bytes); - self.set_compressed_file_text_with_durability( - file_id, - Arc::from(compressed.as_slice()), - durability, - ) - } -} - -fn source_root_crates(db: &dyn SourceRootDatabase, id: SourceRootId) -> Arc<[CrateId]> { +fn source_root_crates(db: &dyn RootQueryDb, id: SourceRootId) -> Arc<[CrateId]> { let graph = db.crate_graph(); let mut crates = graph .iter() .filter(|&krate| { let root_file = graph[krate].root_file_id; - db.file_source_root(root_file) == id + db.file_source_root(root_file).source_root_id(db) == id }) .collect::>(); crates.sort(); @@ -182,22 +305,9 @@ fn source_root_crates(db: &dyn SourceRootDatabase, id: SourceRootId) -> Arc<[Cra crates.into_iter().collect() } -// FIXME: Would be nice to get rid of this somehow -/// Silly workaround for cyclic deps due to the SourceRootDatabase and SourceDatabase split -/// regarding FileLoader -pub struct FileLoaderDelegate(pub T); +fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[CrateId]> { + let _p = tracing::info_span!("relevant_crates").entered(); -impl FileLoader for FileLoaderDelegate<&'_ T> { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { - // FIXME: this *somehow* should be platform agnostic... - let source_root = self.0.file_source_root(path.anchor); - let source_root = self.0.source_root(source_root); - source_root.resolve_path(path) - } - - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { - let _p = tracing::info_span!("relevant_crates").entered(); - let source_root = self.0.file_source_root(file_id); - self.0.source_root_crates(source_root) - } + let source_root = db.file_source_root(file_id); + db.source_root_crates(source_root.source_root_id(db)) } diff --git a/src/tools/rust-analyzer/crates/edition/src/lib.rs b/src/tools/rust-analyzer/crates/edition/src/lib.rs index 7e9c94af408c1..a2269bf54d435 100644 --- a/src/tools/rust-analyzer/crates/edition/src/lib.rs +++ b/src/tools/rust-analyzer/crates/edition/src/lib.rs @@ -19,6 +19,16 @@ impl Edition { /// The current latest stable edition, note this is usually not the right choice in code. pub const CURRENT_FIXME: Edition = Edition::Edition2021; + pub fn from_u32(u32: u32) -> Edition { + match u32 { + 0 => Edition::Edition2015, + 1 => Edition::Edition2018, + 2 => Edition::Edition2021, + 3 => Edition::Edition2024, + _ => panic!("invalid edition"), + } + } + pub fn at_least_2024(self) -> bool { self >= Edition::Edition2024 } diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml index a22961c26c84c..1b1d430ffdfd5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml @@ -29,6 +29,8 @@ hashbrown.workspace = true triomphe.workspace = true rustc_apfloat = "0.2.0" text-size.workspace = true +salsa.workspace = true +query-group.workspace = true ra-ap-rustc_hashes.workspace = true ra-ap-rustc_parse_format.workspace = true @@ -45,7 +47,6 @@ cfg.workspace = true tt.workspace = true span.workspace = true - [dev-dependencies] expect-test.workspace = true @@ -53,6 +54,7 @@ expect-test.workspace = true test-utils.workspace = true test-fixture.workspace = true syntax-bridge.workspace = true + [features] in-rust-tree = ["hir-expand/in-rust-tree"] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 710bffcefe900..52a72bce91dce 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -601,17 +601,14 @@ impl<'attr> AttrQuery<'attr> { fn any_has_attrs<'db>( db: &(dyn DefDatabase + 'db), - id: impl Lookup< - Database<'db> = dyn DefDatabase + 'db, - Data = impl HasSource, - >, + id: impl Lookup>, ) -> InFile { id.lookup(db).source(db).map(ast::AnyHasAttrs::new) } fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>( db: &(dyn DefDatabase + 'db), - lookup: impl Lookup = dyn DefDatabase + 'db, Data = impl ItemTreeLoc>, + lookup: impl Lookup>, ) -> RawAttrs { let id = lookup.lookup(db).item_tree_id(); let tree = id.item_tree(db); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index c94622016d355..28992ec600aeb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -228,6 +228,7 @@ impl StructData { None, ); let types_map = strukt.types_map.clone(); + ( Arc::new(StructData { name: strukt.name.clone(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 598a850898bb6..0772d00f03c8a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -1,5 +1,5 @@ //! Defines database & queries for name resolution. -use base_db::{ra_salsa, CrateId, SourceDatabase, Upcast}; +use base_db::{CrateId, RootQueryDb, SourceDatabase, Upcast}; use either::Either; use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; use intern::sym; @@ -33,178 +33,204 @@ use crate::{ UseId, UseLoc, VariantId, }; -#[ra_salsa::query_group(InternDatabaseStorage)] -pub trait InternDatabase: SourceDatabase { +use salsa::plumbing::AsId; + +#[query_group::query_group(InternDatabaseStorage)] +pub trait InternDatabase: RootQueryDb { // region: items - #[ra_salsa::interned] + #[salsa::interned] fn intern_use(&self, loc: UseLoc) -> UseId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_extern_crate(&self, loc: ExternCrateLoc) -> ExternCrateId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_function(&self, loc: FunctionLoc) -> FunctionId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_struct(&self, loc: StructLoc) -> StructId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_union(&self, loc: UnionLoc) -> UnionId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_enum(&self, loc: EnumLoc) -> EnumId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_enum_variant(&self, loc: EnumVariantLoc) -> EnumVariantId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_const(&self, loc: ConstLoc) -> ConstId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_static(&self, loc: StaticLoc) -> StaticId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_trait(&self, loc: TraitLoc) -> TraitId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_trait_alias(&self, loc: TraitAliasLoc) -> TraitAliasId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_impl(&self, loc: ImplLoc) -> ImplId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_macro2(&self, loc: Macro2Loc) -> Macro2Id; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_proc_macro(&self, loc: ProcMacroLoc) -> ProcMacroId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId; - // endregion: items + // // endregion: items - #[ra_salsa::interned] + #[salsa::interned] fn intern_block(&self, loc: BlockLoc) -> BlockId; - #[ra_salsa::interned] + #[salsa::interned] fn intern_anonymous_const(&self, id: ConstBlockLoc) -> ConstBlockId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_in_type_const(&self, id: InTypeConstLoc) -> InTypeConstId; } -#[ra_salsa::query_group(DefDatabaseStorage)] -pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast { +#[query_group::query_group] +pub trait DefDatabase: + InternDatabase + + ExpandDatabase + + SourceDatabase + + Upcast + + Upcast +{ /// Whether to expand procedural macros during name resolution. - #[ra_salsa::input] + #[salsa::input] fn expand_proc_attr_macros(&self) -> bool; /// Computes an [`ItemTree`] for the given file or macro expansion. - #[ra_salsa::invoke(ItemTree::file_item_tree_query)] + #[salsa::invoke(ItemTree::file_item_tree_query)] fn file_item_tree(&self, file_id: HirFileId) -> Arc; - #[ra_salsa::invoke(ItemTree::block_item_tree_query)] + #[salsa::invoke_actual(ItemTree::block_item_tree_query)] fn block_item_tree(&self, block_id: BlockId) -> Arc; - #[ra_salsa::invoke(ItemTree::file_item_tree_with_source_map_query)] + #[salsa::invoke(ItemTree::file_item_tree_with_source_map_query)] fn file_item_tree_with_source_map( &self, file_id: HirFileId, ) -> (Arc, Arc); - #[ra_salsa::invoke(ItemTree::block_item_tree_with_source_map_query)] + #[salsa::invoke_actual(ItemTree::block_item_tree_with_source_map_query)] fn block_item_tree_with_source_map( &self, block_id: BlockId, ) -> (Arc, Arc); - #[ra_salsa::invoke(DefMap::crate_def_map_query)] + #[salsa::invoke(DefMap::crate_def_map_query)] fn crate_def_map(&self, krate: CrateId) -> Arc; /// Computes the block-level `DefMap`. - #[ra_salsa::invoke(DefMap::block_def_map_query)] + #[salsa::invoke_actual(DefMap::block_def_map_query)] fn block_def_map(&self, block: BlockId) -> Arc; /// Turns a MacroId into a MacroDefId, describing the macro's definition post name resolution. + #[salsa::invoke_actual(macro_def)] fn macro_def(&self, m: MacroId) -> MacroDefId; // region:data - #[ra_salsa::transparent] - #[ra_salsa::invoke(StructData::struct_data_query)] + #[salsa::transparent] + #[salsa::invoke_actual(StructData::struct_data_query)] fn struct_data(&self, id: StructId) -> Arc; - #[ra_salsa::invoke(StructData::struct_data_with_diagnostics_query)] + #[salsa::invoke_actual(StructData::struct_data_with_diagnostics_query)] fn struct_data_with_diagnostics(&self, id: StructId) -> (Arc, DefDiagnostics); - #[ra_salsa::transparent] - #[ra_salsa::invoke(StructData::union_data_query)] + #[salsa::transparent] + #[salsa::invoke_actual(StructData::union_data_query)] fn union_data(&self, id: UnionId) -> Arc; - #[ra_salsa::invoke(StructData::union_data_with_diagnostics_query)] + #[salsa::invoke_actual(StructData::union_data_with_diagnostics_query)] fn union_data_with_diagnostics(&self, id: UnionId) -> (Arc, DefDiagnostics); - #[ra_salsa::invoke(EnumData::enum_data_query)] + #[salsa::invoke_actual(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; - #[ra_salsa::transparent] - #[ra_salsa::invoke(EnumVariantData::enum_variant_data_query)] + #[salsa::transparent] + #[salsa::invoke_actual(EnumVariantData::enum_variant_data_query)] fn enum_variant_data(&self, id: EnumVariantId) -> Arc; - #[ra_salsa::invoke(EnumVariantData::enum_variant_data_with_diagnostics_query)] + #[salsa::invoke_actual(EnumVariantData::enum_variant_data_with_diagnostics_query)] fn enum_variant_data_with_diagnostics( &self, id: EnumVariantId, ) -> (Arc, DefDiagnostics); - #[ra_salsa::transparent] - #[ra_salsa::invoke(VariantData::variant_data)] + #[salsa::transparent] + #[salsa::invoke_actual(VariantData::variant_data)] fn variant_data(&self, id: VariantId) -> Arc; - #[ra_salsa::transparent] - #[ra_salsa::invoke(ImplData::impl_data_query)] + #[salsa::transparent] + #[salsa::invoke_actual(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; - #[ra_salsa::invoke(ImplData::impl_data_with_diagnostics_query)] + #[salsa::invoke_actual(ImplData::impl_data_with_diagnostics_query)] fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); - #[ra_salsa::transparent] - #[ra_salsa::invoke(TraitData::trait_data_query)] + #[salsa::transparent] + #[salsa::invoke_actual(TraitData::trait_data_query)] fn trait_data(&self, e: TraitId) -> Arc; - #[ra_salsa::invoke(TraitData::trait_data_with_diagnostics_query)] + #[salsa::invoke_actual(TraitData::trait_data_with_diagnostics_query)] fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); - #[ra_salsa::invoke(TraitAliasData::trait_alias_query)] + #[salsa::invoke_actual(TraitAliasData::trait_alias_query)] fn trait_alias_data(&self, e: TraitAliasId) -> Arc; - #[ra_salsa::invoke(TypeAliasData::type_alias_data_query)] + #[salsa::invoke_actual(TypeAliasData::type_alias_data_query)] fn type_alias_data(&self, e: TypeAliasId) -> Arc; - #[ra_salsa::invoke(FunctionData::fn_data_query)] + #[salsa::invoke_actual(FunctionData::fn_data_query)] fn function_data(&self, func: FunctionId) -> Arc; - #[ra_salsa::invoke(ConstData::const_data_query)] + #[salsa::invoke_actual(ConstData::const_data_query)] fn const_data(&self, konst: ConstId) -> Arc; - #[ra_salsa::invoke(StaticData::static_data_query)] + #[salsa::invoke_actual(StaticData::static_data_query)] fn static_data(&self, statik: StaticId) -> Arc; - #[ra_salsa::invoke(Macro2Data::macro2_data_query)] + #[salsa::invoke_actual(Macro2Data::macro2_data_query)] fn macro2_data(&self, makro: Macro2Id) -> Arc; - #[ra_salsa::invoke(MacroRulesData::macro_rules_data_query)] + #[salsa::invoke_actual(MacroRulesData::macro_rules_data_query)] fn macro_rules_data(&self, makro: MacroRulesId) -> Arc; - #[ra_salsa::invoke(ProcMacroData::proc_macro_data_query)] + #[salsa::invoke_actual(ProcMacroData::proc_macro_data_query)] fn proc_macro_data(&self, makro: ProcMacroId) -> Arc; - #[ra_salsa::invoke(ExternCrateDeclData::extern_crate_decl_data_query)] + #[salsa::invoke_actual(ExternCrateDeclData::extern_crate_decl_data_query)] fn extern_crate_decl_data(&self, extern_crate: ExternCrateId) -> Arc; // endregion:data - #[ra_salsa::invoke(Body::body_with_source_map_query)] - #[ra_salsa::lru] + #[salsa::invoke(Body::body_with_source_map_query)] + #[salsa::lru(512)] fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc, Arc); - #[ra_salsa::invoke(Body::body_query)] + #[salsa::invoke(Body::body_query)] fn body(&self, def: DefWithBodyId) -> Arc; - #[ra_salsa::invoke(ExprScopes::expr_scopes_query)] + #[salsa::invoke_actual(ExprScopes::expr_scopes_query)] fn expr_scopes(&self, def: DefWithBodyId) -> Arc; - #[ra_salsa::invoke(GenericParams::generic_params_query)] + #[salsa::invoke_actual(GenericParams::generic_params_query)] fn generic_params(&self, def: GenericDefId) -> Arc; /// If this returns `None` for the source map, that means it is the same as with the item tree. - #[ra_salsa::invoke(GenericParams::generic_params_with_source_map_query)] + #[salsa::invoke_actual(GenericParams::generic_params_with_source_map_query)] fn generic_params_with_source_map( &self, def: GenericDefId, @@ -212,51 +238,51 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast Arc>; // should this really be a query? - #[ra_salsa::invoke(crate::attr::fields_attrs_source_map)] + #[salsa::invoke_actual(crate::attr::fields_attrs_source_map)] fn fields_attrs_source_map( &self, def: VariantId, ) -> Arc>>>; - #[ra_salsa::invoke(AttrsWithOwner::attrs_query)] + #[salsa::invoke(AttrsWithOwner::attrs_query)] fn attrs(&self, def: AttrDefId) -> Attrs; - #[ra_salsa::transparent] - #[ra_salsa::invoke(lang_item::lang_attr)] + #[salsa::transparent] + #[salsa::invoke(lang_item::lang_attr)] fn lang_attr(&self, def: AttrDefId) -> Option; // endregion:attrs - #[ra_salsa::invoke(LangItems::lang_item_query)] + #[salsa::invoke(LangItems::lang_item_query)] fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option; - #[ra_salsa::invoke(ImportMap::import_map_query)] + #[salsa::invoke(ImportMap::import_map_query)] fn import_map(&self, krate: CrateId) -> Arc; // region:visibilities - #[ra_salsa::invoke(visibility::field_visibilities_query)] + #[salsa::invoke(visibility::field_visibilities_query)] fn field_visibilities(&self, var: VariantId) -> Arc>; // FIXME: unify function_visibility and const_visibility? - #[ra_salsa::invoke(visibility::function_visibility_query)] + #[salsa::invoke_actual(visibility::function_visibility_query)] fn function_visibility(&self, def: FunctionId) -> Visibility; - #[ra_salsa::invoke(visibility::const_visibility_query)] + #[salsa::invoke_actual(visibility::const_visibility_query)] fn const_visibility(&self, def: ConstId) -> Visibility; // endregion:visibilities - #[ra_salsa::invoke(LangItems::crate_lang_items_query)] + #[salsa::invoke(LangItems::crate_lang_items_query)] fn crate_lang_items(&self, krate: CrateId) -> Option>; - #[ra_salsa::invoke(crate::lang_item::notable_traits_in_deps)] + #[salsa::invoke(crate::lang_item::notable_traits_in_deps)] fn notable_traits_in_deps(&self, krate: CrateId) -> Arc<[Arc<[TraitId]>]>; - #[ra_salsa::invoke(crate::lang_item::crate_notable_traits)] + #[salsa::invoke(crate::lang_item::crate_notable_traits)] fn crate_notable_traits(&self, krate: CrateId) -> Option>; fn crate_supports_no_std(&self, crate_id: CrateId) -> bool; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs index 5ff6a7ffe5669..616d2c9fd89a4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs @@ -16,7 +16,7 @@ use hir_expand::{name::Name, ExpandError, InFile}; use la_arena::{Arena, ArenaMap}; use rustc_hash::FxHashMap; use smallvec::SmallVec; -use span::{Edition, MacroFileId, SyntaxContextData}; +use span::{Edition, MacroFileId, SyntaxContext}; use syntax::{ast, AstPtr, SyntaxNodePtr}; use triomphe::Arc; use tt::TextRange; @@ -49,8 +49,9 @@ impl HygieneId { Self(ctx) } - pub(crate) fn lookup(self, db: &dyn DefDatabase) -> SyntaxContextData { - db.lookup_intern_syntax_context(self.0) + // FIXME: Inline this + pub(crate) fn lookup(self) -> SyntaxContext { + self.0 } pub(crate) fn is_root(self) -> bool { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 6e505a6b1126e..c3ca610faecbe 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -1931,11 +1931,11 @@ impl ExprCollector<'_> { None => (HygieneId::ROOT, None), Some(span_map) => { let span = span_map.span_at(lifetime.syntax().text_range().start()); - let ctx = self.db.lookup_intern_syntax_context(span.ctx); - let hygiene_id = HygieneId::new(ctx.opaque_and_semitransparent); - let hygiene_info = ctx.outer_expn.map(|expansion| { + let ctx = span.ctx; + let hygiene_id = HygieneId::new(ctx.opaque_and_semitransparent(self.db)); + let hygiene_info = ctx.outer_expn(self.db).map(|expansion| { let expansion = self.db.lookup_intern_macro_call(expansion); - (ctx.parent, expansion.def) + (ctx.parent(self.db), expansion.def) }); (hygiene_id, hygiene_info) } @@ -1962,11 +1962,12 @@ impl ExprCollector<'_> { // A macro is allowed to refer to labels from before its declaration. // Therefore, if we got to the rib of its declaration, give up its hygiene // and use its parent expansion. - let parent_ctx = self.db.lookup_intern_syntax_context(parent_ctx); - hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent); - hygiene_info = parent_ctx.outer_expn.map(|expansion| { + + hygiene_id = + HygieneId::new(parent_ctx.opaque_and_semitransparent(self.db)); + hygiene_info = parent_ctx.outer_expn(self.db).map(|expansion| { let expansion = self.db.lookup_intern_macro_call(expansion); - (parent_ctx.parent, expansion.def) + (parent_ctx.parent(self.db), expansion.def) }); } } @@ -2593,7 +2594,7 @@ impl ExprCollector<'_> { None => HygieneId::ROOT, Some(span_map) => { let ctx = span_map.span_at(span_start).ctx; - HygieneId::new(self.db.lookup_intern_syntax_context(ctx).opaque_and_semitransparent) + HygieneId::new(ctx.opaque_and_semitransparent(self.db)) } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs index 859a706177aab..42a8eae4064dc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs @@ -324,8 +324,9 @@ fn compute_expr_scopes( #[cfg(test)] mod tests { - use base_db::SourceDatabase; + use base_db::RootQueryDb; use hir_expand::{name::AsName, InFile}; + use salsa::AsDynDatabase; use span::FileId; use syntax::{algo::find_node_at_offset, ast, AstNode}; use test_fixture::WithFixture; @@ -357,18 +358,22 @@ mod tests { }; let (db, position) = TestDB::with_position(&code); - let file_id = position.file_id; + let editioned_file_id = position.file_id; let offset = position.offset; - let file_syntax = db.parse(file_id).syntax_node(); + let (file_id, _) = editioned_file_id.unpack(); + let editioned_file_id_wrapper = + base_db::EditionedFileId::new(db.as_dyn_database(), editioned_file_id); + + let file_syntax = db.parse(editioned_file_id_wrapper).syntax_node(); let marker: ast::PathExpr = find_node_at_offset(&file_syntax, offset).unwrap(); - let function = find_function(&db, file_id.file_id()); + let function = find_function(&db, file_id); let scopes = db.expr_scopes(function.into()); let (_body, source_map) = db.body_with_source_map(function.into()); let expr_id = source_map - .node_expr(InFile { file_id: file_id.into(), value: &marker.into() }) + .node_expr(InFile { file_id: editioned_file_id.into(), value: &marker.into() }) .unwrap() .as_expr() .unwrap(); @@ -511,15 +516,19 @@ fn foo() { fn do_check_local_name(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_offset: u32) { let (db, position) = TestDB::with_position(ra_fixture); - let file_id = position.file_id; + let editioned_file_id = position.file_id; let offset = position.offset; - let file = db.parse(file_id).ok().unwrap(); + let (file_id, _) = editioned_file_id.unpack(); + let file_id_wrapper = + base_db::EditionedFileId::new(db.as_dyn_database(), editioned_file_id); + + let file = db.parse(file_id_wrapper).ok().unwrap(); let expected_name = find_node_at_offset::(file.syntax(), expected_offset.into()) .expect("failed to find a name at the target offset"); let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), offset).unwrap(); - let function = find_function(&db, file_id.file_id()); + let function = find_function(&db, file_id); let scopes = db.expr_scopes(function.into()); let (_, source_map) = db.body_with_source_map(function.into()); @@ -527,7 +536,7 @@ fn foo() { let expr_scope = { let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); let expr_id = source_map - .node_expr(InFile { file_id: file_id.into(), value: &expr_ast }) + .node_expr(InFile { file_id: editioned_file_id.into(), value: &expr_ast }) .unwrap() .as_expr() .unwrap(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs index e136dd18a55e5..df0bbe5c3ef38 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs @@ -189,8 +189,8 @@ fn f() { } "#, expect![[r#" - BlockId(1) in BlockRelativeModuleId { block: Some(BlockId(0)), local_id: Idx::(1) } - BlockId(0) in BlockRelativeModuleId { block: None, local_id: Idx::(0) } + BlockId(4c01) in BlockRelativeModuleId { block: Some(BlockId(4c00)), local_id: Idx::(1) } + BlockId(4c00) in BlockRelativeModuleId { block: None, local_id: Idx::(0) } crate scope "#]], ); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs index e2b36da79b232..80820193796de 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs @@ -362,10 +362,7 @@ impl GenericParams { }; fn id_to_generics( db: &dyn DefDatabase, - id: impl for<'db> Lookup< - Database<'db> = dyn DefDatabase + 'db, - Data = impl ItemTreeLoc, - >, + id: impl Lookup>, enabled_params: impl Fn( &Arc, &ItemTree, @@ -378,6 +375,7 @@ impl GenericParams { let id = id.lookup(db).item_tree_id(); let tree = id.item_tree(db); let item = &tree[id.value]; + (enabled_params(item.generic_params(), &tree, id.value.into()), None) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index d43776b8a66ad..64c1d0d274f34 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -475,7 +475,7 @@ fn search_maps( #[cfg(test)] mod tests { - use base_db::{SourceDatabase, Upcast}; + use base_db::{RootQueryDb, Upcast}; use expect_test::{expect, Expect}; use test_fixture::WithFixture; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs index 70bf2f13c88a1..d113a500ef76f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs @@ -546,7 +546,7 @@ impl Printer<'_> { let MacroCall { path, ast_id, expand_to, ctxt } = &self.tree[it]; let _ = writeln!( self, - "// AstId: {:?}, SyntaxContext: {}, ExpandTo: {:?}", + "// AstId: {:?}, SyntaxContextId: {}, ExpandTo: {:?}", ast_id.erase().into_raw(), ctxt, expand_to diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs index 80b699649fba8..b442e877343fc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs @@ -270,7 +270,7 @@ m!(); // AstId: 2 pub macro m2 { ... } - // AstId: 3, SyntaxContext: 2, ExpandTo: Items + // AstId: 3, SyntaxContextId: 4294967037, ExpandTo: Items m!(...); "#]], ); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 9c947df35e990..15ef8364ed215 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -69,16 +69,9 @@ mod pretty; #[cfg(test)] mod test_db; -use std::{ - hash::{Hash, Hasher}, - panic::{RefUnwindSafe, UnwindSafe}, -}; +use std::hash::{Hash, Hasher}; -use base_db::{ - impl_intern_key, - ra_salsa::{self, InternValueTrivial}, - CrateId, -}; +use base_db::{impl_intern_key, CrateId}; use hir_expand::{ builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, @@ -192,8 +185,7 @@ pub trait ItemTreeLoc { macro_rules! impl_intern { ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => { - impl_intern_key!($id); - impl InternValueTrivial for $loc {} + impl_intern_key!($id, $loc); impl_intern_lookup!(DefDatabase, $id, $loc, $intern, $lookup); }; } @@ -213,87 +205,58 @@ macro_rules! impl_loc { }; } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct FunctionId(ra_salsa::InternId); type FunctionLoc = AssocItemLoc; impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); impl_loc!(FunctionLoc, id: Function, container: ItemContainerId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct StructId(ra_salsa::InternId); type StructLoc = ItemLoc; impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); impl_loc!(StructLoc, id: Struct, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct UnionId(ra_salsa::InternId); pub type UnionLoc = ItemLoc; impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); impl_loc!(UnionLoc, id: Union, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct EnumId(ra_salsa::InternId); pub type EnumLoc = ItemLoc; impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); impl_loc!(EnumLoc, id: Enum, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct ConstId(ra_salsa::InternId); type ConstLoc = AssocItemLoc; impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); impl_loc!(ConstLoc, id: Const, container: ItemContainerId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct StaticId(ra_salsa::InternId); pub type StaticLoc = AssocItemLoc; impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); impl_loc!(StaticLoc, id: Static, container: ItemContainerId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct TraitId(ra_salsa::InternId); pub type TraitLoc = ItemLoc; impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); impl_loc!(TraitLoc, id: Trait, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TraitAliasId(ra_salsa::InternId); pub type TraitAliasLoc = ItemLoc; impl_intern!(TraitAliasId, TraitAliasLoc, intern_trait_alias, lookup_intern_trait_alias); impl_loc!(TraitAliasLoc, id: TraitAlias, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TypeAliasId(ra_salsa::InternId); type TypeAliasLoc = AssocItemLoc; impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); impl_loc!(TypeAliasLoc, id: TypeAlias, container: ItemContainerId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ImplId(ra_salsa::InternId); type ImplLoc = ItemLoc; impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); impl_loc!(ImplLoc, id: Impl, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct UseId(ra_salsa::InternId); type UseLoc = ItemLoc; impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use); impl_loc!(UseLoc, id: Use, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ExternCrateId(ra_salsa::InternId); type ExternCrateLoc = ItemLoc; impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate); impl_loc!(ExternCrateLoc, id: ExternCrate, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ExternBlockId(ra_salsa::InternId); type ExternBlockLoc = ItemLoc; impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block); impl_loc!(ExternBlockLoc, id: ExternBlock, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct EnumVariantId(ra_salsa::InternId); - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EnumVariantLoc { pub id: ItemTreeId, @@ -302,9 +265,6 @@ pub struct EnumVariantLoc { } impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant); impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct Macro2Id(ra_salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Macro2Loc { pub container: ModuleId, @@ -316,8 +276,6 @@ pub struct Macro2Loc { impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2); impl_loc!(Macro2Loc, id: Macro2, container: ModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct MacroRulesId(ra_salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct MacroRulesLoc { pub container: ModuleId, @@ -345,8 +303,7 @@ pub enum MacroExpander { BuiltInDerive(BuiltinDeriveExpander), BuiltInEager(EagerExpander), } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ProcMacroId(ra_salsa::InternId); + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ProcMacroLoc { pub container: CrateRootModuleId, @@ -358,8 +315,6 @@ pub struct ProcMacroLoc { impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); impl_loc!(ProcMacroLoc, id: Function, container: CrateRootModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct BlockId(ra_salsa::InternId); #[derive(Debug, Hash, PartialEq, Eq, Clone)] pub struct BlockLoc { pub ast_id: AstId, @@ -368,10 +323,8 @@ pub struct BlockLoc { } impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); -/// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and -/// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -pub struct ConstBlockId(ra_salsa::InternId); +// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and +// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent. impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const); #[derive(Debug, Hash, PartialEq, Eq, Clone)] @@ -536,12 +489,11 @@ pub struct TupleFieldId { pub index: u32, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct TypeOrConstParamId { pub parent: GenericDefId, pub local_id: LocalTypeOrConstParamId, } -impl InternValueTrivial for TypeOrConstParamId {} /// A TypeOrConstParamId with an invariant that it actually belongs to a type #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -603,7 +555,6 @@ pub struct LifetimeParamId { pub local_id: LocalLifetimeParamId, } pub type LocalLifetimeParamId = Idx; -impl InternValueTrivial for LifetimeParamId {} #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ItemContainerId { @@ -615,7 +566,7 @@ pub enum ItemContainerId { impl_from!(ModuleId for ItemContainerId); /// A Data Type -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum AdtId { StructId(StructId), UnionId(UnionId), @@ -624,7 +575,7 @@ pub enum AdtId { impl_from!(StructId, UnionId, EnumId for AdtId); /// A macro -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum MacroId { Macro2Id(Macro2Id), MacroRulesId(MacroRulesId), @@ -760,9 +711,7 @@ impl From for TypeOwnerId { /// currently only used in `InTypeConstId` for storing the type (which has type `Ty` defined in /// the `hir-ty` crate) of the constant in its id, which is a temporary hack so we may want /// to remove this after removing that. -pub trait OpaqueInternableThing: - std::any::Any + std::fmt::Debug + Sync + Send + UnwindSafe + RefUnwindSafe -{ +pub trait OpaqueInternableThing: std::any::Any + std::fmt::Debug + Sync + Send { fn as_any(&self) -> &dyn std::any::Any; fn box_any(&self) -> Box; fn dyn_hash(&self, state: &mut dyn Hasher); @@ -809,11 +758,9 @@ impl Clone for Box { // and the name of the struct that contains this constant is resolved, so a query that only traverses the // type owner by its syntax tree might have a hard time here. -/// A constant in a type as a substitution for const generics (like `Foo<{ 2 + 2 }>`) or as an array -/// length (like `[u8; 2 + 2]`). These constants are body owner and are a variant of `DefWithBodyId`. These -/// are not called `AnonymousConstId` to prevent confusion with [`ConstBlockId`]. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -pub struct InTypeConstId(ra_salsa::InternId); +// A constant in a type as a substitution for const generics (like `Foo<{ 2 + 2 }>`) or as an array +// length (like `[u8; 2 + 2]`). These constants are body owner and are a variant of `DefWithBodyId`. These +// are not called `AnonymousConstId` to prevent confusion with [`ConstBlockId`]. impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const); // We would like to set `derive(PartialEq)` @@ -838,8 +785,8 @@ impl InTypeConstId { pub fn source(&self, db: &dyn DefDatabase) -> ast::ConstArg { let src = self.lookup(db).id; let file_id = src.file_id; - let root = &db.parse_or_expand(file_id); - db.ast_id_map(file_id).get(src.value).to_node(root) + let root = db.parse_or_expand(file_id); + db.ast_id_map(file_id).get(src.value).to_node(&root) } } @@ -884,7 +831,7 @@ impl GeneralConstId { } /// The defs which have a body. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum DefWithBodyId { FunctionId(FunctionId), StaticId(StaticId), @@ -892,7 +839,6 @@ pub enum DefWithBodyId { InTypeConstId(InTypeConstId), VariantId(EnumVariantId), } - impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId); impl From for DefWithBodyId { @@ -928,7 +874,7 @@ pub enum AssocItemId { // casting them, and somehow making the constructors private, which would be annoying. impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId); -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum GenericDefId { AdtId(AdtId), // consts can have type parameters from their parents (i.e. associated consts of traits) @@ -962,7 +908,7 @@ impl GenericDefId { ) -> (HirFileId, Option) { fn file_id_and_params_of_item_loc( db: &dyn DefDatabase, - def: impl for<'db> Lookup = dyn DefDatabase + 'db, Data = Loc>, + def: impl Lookup, ) -> (HirFileId, Option) where Loc: src::HasSource, @@ -1017,15 +963,13 @@ impl From for GenericDefId { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum CallableDefId { FunctionId(FunctionId), StructId(StructId), EnumVariantId(EnumVariantId), } -impl InternValueTrivial for CallableDefId {} - impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId); impl From for ModuleDefId { fn from(def: CallableDefId) -> ModuleDefId { @@ -1135,7 +1079,7 @@ impl From for AttrDefId { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum VariantId { EnumVariantId(EnumVariantId), StructId(StructId), @@ -1197,7 +1141,7 @@ pub trait HasModule { impl HasModule for ItemId where N: ItemTreeNode, - ItemId: for<'db> Lookup = dyn DefDatabase + 'db, Data = ItemLoc> + Copy, + ItemId: Lookup> + Copy, { #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { @@ -1222,7 +1166,7 @@ where #[inline] fn module_for_assoc_item_loc<'db>( db: &(dyn 'db + DefDatabase), - id: impl Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, + id: impl Lookup>, ) -> ModuleId { id.lookup(db).container.module(db) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs index 8c5bd3b6d3696..66e344d72452d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs @@ -35,9 +35,9 @@ macro_rules! f { }; } -struct#0:1@58..64#4# MyTraitMap2#0:2@31..42#2# {#0:1@72..73#4# - map#0:1@86..89#4#:#0:1@89..90#4# #0:1@89..90#4#::#0:1@91..93#4#std#0:1@93..96#4#::#0:1@96..98#4#collections#0:1@98..109#4#::#0:1@109..111#4#HashSet#0:1@111..118#4#<#0:1@118..119#4#(#0:1@119..120#4#)#0:1@120..121#4#>#0:1@121..122#4#,#0:1@122..123#4# -}#0:1@132..133#4# +struct#0:1@58..64#20480# MyTraitMap2#0:2@31..42#4294967037# {#0:1@72..73#20480# + map#0:1@86..89#20480#:#0:1@89..90#20480# #0:1@89..90#20480#::#0:1@91..93#20480#std#0:1@93..96#20480#::#0:1@96..98#20480#collections#0:1@98..109#20480#::#0:1@109..111#20480#HashSet#0:1@111..118#20480#<#0:1@118..119#20480#(#0:1@119..120#20480#)#0:1@120..121#20480#>#0:1@121..122#20480#,#0:1@122..123#20480# +}#0:1@132..133#20480# "#]], ); } @@ -75,12 +75,12 @@ macro_rules! f { }; } -fn#0:2@30..32#2# main#0:2@33..37#2#(#0:2@37..38#2#)#0:2@38..39#2# {#0:2@40..41#2# - 1#0:2@50..51#2#;#0:2@51..52#2# - 1.0#0:2@61..64#2#;#0:2@64..65#2# - (#0:2@74..75#2#(#0:2@75..76#2#1#0:2@76..77#2#,#0:2@77..78#2# )#0:2@78..79#2#,#0:2@79..80#2# )#0:2@80..81#2#.#0:2@81..82#2#0#0:2@82..85#2#.#0:2@82..85#2#0#0:2@82..85#2#;#0:2@85..86#2# - let#0:2@95..98#2# x#0:2@99..100#2# =#0:2@101..102#2# 1#0:2@103..104#2#;#0:2@104..105#2# -}#0:2@110..111#2# +fn#0:2@30..32#4294967037# main#0:2@33..37#4294967037#(#0:2@37..38#4294967037#)#0:2@38..39#4294967037# {#0:2@40..41#4294967037# + 1#0:2@50..51#4294967037#;#0:2@51..52#4294967037# + 1.0#0:2@61..64#4294967037#;#0:2@64..65#4294967037# + (#0:2@74..75#4294967037#(#0:2@75..76#4294967037#1#0:2@76..77#4294967037#,#0:2@77..78#4294967037# )#0:2@78..79#4294967037#,#0:2@79..80#4294967037# )#0:2@80..81#4294967037#.#0:2@81..82#4294967037#0#0:2@82..85#4294967037#.#0:2@82..85#4294967037#0#0:2@82..85#4294967037#;#0:2@85..86#4294967037# + let#0:2@95..98#4294967037# x#0:2@99..100#4294967037# =#0:2@101..102#4294967037# 1#0:2@103..104#4294967037#;#0:2@104..105#4294967037# +}#0:2@110..111#4294967037# "#]], @@ -171,7 +171,7 @@ fn main(foo: ()) { } fn main(foo: ()) { - /* error: unresolved macro unresolved */"helloworld!"#0:3@236..321#2#; + /* error: unresolved macro unresolved */"helloworld!"#0:3@236..321#4294967037#; } } @@ -197,7 +197,7 @@ macro_rules! mk_struct { #[macro_use] mod foo; -struct#1:1@59..65#4# Foo#0:2@32..35#2#(#1:1@70..71#4#u32#0:2@41..44#2#)#1:1@74..75#4#;#1:1@75..76#4# +struct#1:1@59..65#20480# Foo#0:2@32..35#4294967037#(#1:1@70..71#20480#u32#0:2@41..44#4294967037#)#1:1@74..75#20480#;#1:1@75..76#20480# "#]], ); } @@ -423,10 +423,10 @@ m! { foo, bar } macro_rules! m { ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } ); } -impl#\4# Bar#\4# {#\4# - fn#\4# foo#\2#(#\4#)#\4# {#\4#}#\4# - fn#\4# bar#\2#(#\4#)#\4# {#\4#}#\4# -}#\4# +impl#\20480# Bar#\20480# {#\20480# + fn#\20480# foo#\4294967037#(#\20480#)#\20480# {#\20480#}#\20480# + fn#\20480# bar#\4294967037#(#\20480#)#\20480# {#\20480#}#\20480# +}#\20480# "#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index a2d0ba3deb845..d0678a40652fd 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -16,7 +16,7 @@ mod proc_macros; use std::{iter, ops::Range, sync}; -use base_db::SourceDatabase; +use base_db::RootQueryDb; use expect_test::Expect; use hir_expand::{ db::ExpandDatabase, @@ -26,6 +26,7 @@ use hir_expand::{ }; use intern::Symbol; use itertools::Itertools; +use salsa::AsDynDatabase; use span::{Edition, Span}; use stdx::{format_to, format_to_acc}; use syntax::{ @@ -63,9 +64,13 @@ fn check_errors(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) MacroCallKind::Derive { ast_id, .. } => ast_id.map(|it| it.erase()), MacroCallKind::Attr { ast_id, .. } => ast_id.map(|it| it.erase()), }; - let ast = db - .parse(ast_id.file_id.file_id().expect("macros inside macros are not supported")) - .syntax_node(); + + let editioned_file_id = + ast_id.file_id.file_id().expect("macros inside macros are not supported"); + let editioned_file_id = + base_db::EditionedFileId::new(db.as_dyn_database(), editioned_file_id); + + let ast = db.parse(editioned_file_id).syntax_node(); let ast_id_map = db.ast_id_map(ast_id.file_id); let node = ast_id_map.get_erased(ast_id.value).to_node(&ast); Some((node.text_range(), errors)) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs index a43c0eb9d70bb..650807fb4acf1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs @@ -181,9 +181,9 @@ fn foo(&self) { self.0. 1; } -fn#0:1@45..47#2# foo#0:1@48..51#2#(#0:1@51..52#2#�:1@52..53#2#self#0:1@53..57#2# )#0:1@57..58#2# {#0:1@59..60#2# - self#0:1@65..69#2# .#0:1@69..70#2#0#0:1@70..71#2#.#0:1@71..72#2#1#0:1@73..74#2#;#0:1@74..75#2# -}#0:1@76..77#2#"#]], +fn#0:1@45..47#4294967037# foo#0:1@48..51#4294967037#(#0:1@51..52#4294967037#�:1@52..53#4294967037#self#0:1@53..57#4294967037# )#0:1@57..58#4294967037# {#0:1@59..60#4294967037# + self#0:1@65..69#4294967037# .#0:1@69..70#4294967037#0#0:1@70..71#4294967037#.#0:1@71..72#4294967037#1#0:1@73..74#4294967037#;#0:1@74..75#4294967037# +}#0:1@76..77#4294967037#"#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 3b6e3c5916e32..5b3d75c4ee669 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -295,9 +295,12 @@ impl ModuleOrigin { /// That is, a file or a `mod foo {}` with items. pub fn definition_source(&self, db: &dyn DefDatabase) -> InFile { match self { - &ModuleOrigin::File { definition, .. } | &ModuleOrigin::CrateRoot { definition } => { + &ModuleOrigin::File { definition: editioned_file_id, .. } + | &ModuleOrigin::CrateRoot { definition: editioned_file_id } => { + let definition = base_db::EditionedFileId::new(db, editioned_file_id); + let sf = db.parse(definition).tree(); - InFile::new(definition.into(), ModuleSource::SourceFile(sf)) + InFile::new(editioned_file_id.into(), ModuleSource::SourceFile(sf)) } &ModuleOrigin::Inline { definition, definition_tree_id } => InFile::new( definition_tree_id.file_id(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 16f3fd56eb9ed..bf013c25ef5e3 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -376,7 +376,7 @@ impl DefCollector<'_> { 'resolve_attr: loop { let _p = tracing::info_span!("resolve_macros loop").entered(); 'resolve_macros: loop { - self.db.unwind_if_cancelled(); + self.db.unwind_if_revision_cancelled(); { let _p = tracing::info_span!("resolve_imports loop").entered(); @@ -977,7 +977,7 @@ impl DefCollector<'_> { vis: Visibility, import: Option, ) { - self.db.unwind_if_cancelled(); + self.db.unwind_if_revision_cancelled(); self.update_recursive(module_id, resolutions, vis, import, 0) } @@ -2517,7 +2517,7 @@ impl ModCollector<'_, '_> { #[cfg(test)] mod tests { - use base_db::SourceDatabase; + use base_db::RootQueryDb; use test_fixture::WithFixture; use crate::{nameres::DefMapCrateData, test_db::TestDB}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs index 17d09bcbd0478..a012eb6ff7eb9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs @@ -1,6 +1,6 @@ //! This module resolves `mod foo;` declaration to file. use arrayvec::ArrayVec; -use base_db::AnchoredPath; +use base_db::{AnchoredPath, RootQueryDb}; use hir_expand::{name::Name, HirFileIdExt}; use span::EditionedFileId; @@ -80,7 +80,8 @@ impl ModDir { let orig_file_id = file_id.original_file_respecting_includes(db.upcast()); for candidate in candidate_files.iter() { let path = AnchoredPath { anchor: orig_file_id.file_id(), path: candidate.as_str() }; - if let Some(file_id) = db.resolve_path(path) { + if let Some(file_id) = base_db::Upcast::::upcast(db).resolve_path(path) + { let is_mod_rs = candidate.ends_with("/mod.rs"); let root_dir_owner = is_mod_rs || attr_path.is_some(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs index 73fc6787bfe81..7c9fad91865db 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs @@ -4,7 +4,7 @@ mod macros; mod mod_resolution; mod primitives; -use base_db::SourceDatabase; +use base_db::RootQueryDb; use expect_test::{expect, Expect}; use test_fixture::WithFixture; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs index c8b7ec463a0fd..cd590205766da 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs @@ -1,4 +1,4 @@ -use base_db::SourceDatabaseFileInputExt as _; +use base_db::SourceDatabase; use test_fixture::WithFixture; use crate::{db::DefDatabase, nameres::tests::TestDB, AdtId, ModuleDefId}; @@ -255,10 +255,10 @@ m!(Z); assert_eq!(module_data.scope.resolutions().count(), 4); }); let n_recalculated_item_trees = - events.iter().filter(|it| it.contains("item_tree(")).count(); + events.iter().filter(|it| it.contains("file_item_tree_shim")).count(); assert_eq!(n_recalculated_item_trees, 6); let n_reparsed_macros = - events.iter().filter(|it| it.contains("parse_macro_expansion(")).count(); + events.iter().filter(|it| it.contains("parse_macro_expansion_shim")).count(); assert_eq!(n_reparsed_macros, 3); } @@ -276,10 +276,11 @@ m!(Z); let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); assert_eq!(module_data.scope.resolutions().count(), 4); }); - let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count(); - assert_eq!(n_recalculated_item_trees, 1); + let n_recalculated_item_trees = + events.iter().filter(|it| it.contains("file_item_tree_shim")).count(); + assert_eq!(n_recalculated_item_trees, 0); let n_reparsed_macros = - events.iter().filter(|it| it.contains("parse_macro_expansion(")).count(); + events.iter().filter(|it| it.contains("parse_macro_expansion_shim")).count(); assert_eq!(n_reparsed_macros, 0); } } @@ -310,14 +311,15 @@ pub type Ty = (); let events = db.log_executed(|| { db.file_item_tree(pos.file_id.into()); }); - let n_calculated_item_trees = events.iter().filter(|it| it.contains("item_tree(")).count(); + let n_calculated_item_trees = + events.iter().filter(|it| it.contains("file_item_tree_shim")).count(); assert_eq!(n_calculated_item_trees, 1); - let n_parsed_files = events.iter().filter(|it| it.contains("parse(")).count(); + let n_parsed_files = events.iter().filter(|it| it.contains("parse")).count(); assert_eq!(n_parsed_files, 1); } - // Delete the parse tree. - base_db::ParseQuery.in_db(&db).purge(); + // FIXME(salsa-transition): bring this back + // base_db::ParseQuery.in_db(&db).purge(); { let events = db.log_executed(|| { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs index 3b7e7653fba55..7a6d6973298b7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs @@ -185,7 +185,7 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option< if segments.len() == 1 && kind == PathKind::Plain { if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { let syn_ctxt = ctx.span_map().span_for_range(path.segment()?.syntax().text_range()).ctx; - if let Some(macro_call_id) = ctx.db.lookup_intern_syntax_context(syn_ctxt).outer_expn { + if let Some(macro_call_id) = syn_ctxt.outer_expn(ctx.db) { if ctx.db.lookup_intern_macro_call(macro_call_id).def.local_inner { kind = match resolve_crate_root(ctx.db.upcast(), syn_ctxt) { Some(crate_root) => PathKind::DollarCrate(crate_root), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index a2e6e4cc04368..f4773de08555b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -207,7 +207,13 @@ impl Resolver { return self.module_scope.resolve_path_in_type_ns(db, path); } - let remaining_idx = || if path.segments().len() == 1 { None } else { Some(1) }; + let remaining_idx = || { + if path.segments().len() == 1 { + None + } else { + Some(1) + } + }; for scope in self.scopes() { match scope { @@ -314,7 +320,7 @@ impl Resolver { None, ), ResolvePathResultPrefixInfo::default(), - )) + )); } Path::LangItem(l, Some(_)) => { let type_ns = match *l { @@ -889,11 +895,10 @@ fn handle_macro_def_scope( // A macro is allowed to refer to variables from before its declaration. // Therefore, if we got to the rib of its declaration, give up its hygiene // and use its parent expansion. - let parent_ctx = db.lookup_intern_syntax_context(*parent_ctx); - *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent); - *hygiene_info = parent_ctx.outer_expn.map(|expansion| { + *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db)); + *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| { let expansion = db.lookup_intern_macro_call(expansion); - (parent_ctx.parent, expansion.def) + (parent_ctx.parent(db), expansion.def) }); } } @@ -905,10 +910,10 @@ fn hygiene_info( hygiene_id: HygieneId, ) -> Option<(SyntaxContextId, MacroDefId)> { if !hygiene_id.is_root() { - let ctx = hygiene_id.lookup(db); - ctx.outer_expn.map(|expansion| { + let ctx = hygiene_id.lookup(); + ctx.outer_expn(db).map(|expansion| { let expansion = db.lookup_intern_macro_call(expansion); - (ctx.parent, expansion.def) + (ctx.parent(db), expansion.def) }) } else { None @@ -1438,7 +1443,7 @@ impl HasResolver for MacroRulesId { fn lookup_resolver<'db>( db: &(dyn DefDatabase + 'db), lookup: impl Lookup< - Database<'db> = dyn DefDatabase + 'db, + Database = dyn DefDatabase, Data = impl ItemTreeLoc, >, ) -> Resolver { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs index 54e6c1fd206d8..b6f08c0cafdbb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs @@ -3,10 +3,11 @@ use std::{fmt, panic, sync::Mutex}; use base_db::{ - ra_salsa::{self, Durability}, - AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, + CrateId, FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, + SourceRootInput, Upcast, }; use hir_expand::{db::ExpandDatabase, files::FilePosition, InFile}; +use salsa::{AsDynDatabase, Durability}; use span::{EditionedFileId, FileId}; use syntax::{algo, ast, AstNode}; use triomphe::Arc; @@ -18,43 +19,58 @@ use crate::{ LocalModuleId, Lookup, ModuleDefId, ModuleId, }; -#[ra_salsa::database( - base_db::SourceRootDatabaseStorage, - base_db::SourceDatabaseStorage, - hir_expand::db::ExpandDatabaseStorage, - crate::db::InternDatabaseStorage, - crate::db::DefDatabaseStorage -)] +#[salsa::db] +#[derive(Clone)] pub(crate) struct TestDB { - storage: ra_salsa::Storage, - events: Mutex>>, + storage: salsa::Storage, + files: Arc, + events: Arc>>>, } impl Default for TestDB { fn default() -> Self { - let mut this = Self { storage: Default::default(), events: Default::default() }; - this.setup_syntax_context_root(); + let mut this = Self { + storage: Default::default(), + events: Default::default(), + files: Default::default(), + }; this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); this } } impl Upcast for TestDB { + #[inline] fn upcast(&self) -> &(dyn ExpandDatabase + 'static) { self } } impl Upcast for TestDB { + #[inline] fn upcast(&self) -> &(dyn DefDatabase + 'static) { self } } -impl ra_salsa::Database for TestDB { - fn salsa_event(&self, event: ra_salsa::Event) { +impl Upcast for TestDB { + fn upcast(&self) -> &(dyn RootQueryDb + 'static) { + self + } +} + +impl Upcast for TestDB { + fn upcast(&self) -> &(dyn SourceDatabase + 'static) { + self + } +} + +#[salsa::db] +impl salsa::Database for TestDB { + fn salsa_event(&self, event: &dyn std::ops::Fn() -> salsa::Event) { let mut events = self.events.lock().unwrap(); if let Some(events) = &mut *events { + let event = event(); events.push(event); } } @@ -68,12 +84,54 @@ impl fmt::Debug for TestDB { impl panic::RefUnwindSafe for TestDB {} -impl FileLoader for TestDB { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { - FileLoaderDelegate(self).resolve_path(path) +#[salsa::db] +impl SourceDatabase for TestDB { + fn file_text(&self, file_id: base_db::FileId) -> FileText { + self.files.file_text(file_id) } - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { - FileLoaderDelegate(self).relevant_crates(file_id) + + fn set_file_text(&mut self, file_id: base_db::FileId, text: &str) { + let files = Arc::clone(&self.files); + files.set_file_text(self, file_id, text); + } + + fn set_file_text_with_durability( + &mut self, + file_id: base_db::FileId, + text: &str, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_text_with_durability(self, file_id, text, durability); + } + + /// Source root of the file. + fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput { + self.files.source_root(source_root_id) + } + + fn set_source_root_with_durability( + &mut self, + source_root_id: SourceRootId, + source_root: Arc, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_source_root_with_durability(self, source_root_id, source_root, durability); + } + + fn file_source_root(&self, id: base_db::FileId) -> FileSourceRootInput { + self.files.file_source_root(id) + } + + fn set_file_source_root_with_durability( + &mut self, + id: base_db::FileId, + source_root_id: SourceRootId, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_source_root_with_durability(self, id, source_root_id, durability); } } @@ -92,8 +150,10 @@ impl TestDB { } pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { + let db = >::upcast(self); + for &krate in self.relevant_crates(file_id).iter() { - let crate_def_map = self.crate_def_map(krate); + let crate_def_map = db.crate_def_map(krate); for (local_id, data) in crate_def_map.modules() { if data.origin.file_id().map(EditionedFileId::file_id) == Some(file_id) { return crate_def_map.module_id(local_id); @@ -104,8 +164,10 @@ impl TestDB { } pub(crate) fn module_at_position(&self, position: FilePosition) -> ModuleId { + let db = >::upcast(self); + let file_module = self.module_for_file(position.file_id.file_id()); - let mut def_map = file_module.def_map(self); + let mut def_map = file_module.def_map(db); let module = self.mod_at_position(&def_map, position); def_map = match self.block_at_position(&def_map, position) { @@ -128,10 +190,11 @@ impl TestDB { /// Finds the smallest/innermost module in `def_map` containing `position`. fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId { + let db = >::upcast(self); let mut size = None; let mut res = DefMap::ROOT; for (module, data) in def_map.modules() { - let src = data.definition_source(self); + let src = data.definition_source(db); if src.file_id != position.file_id { continue; } @@ -167,17 +230,18 @@ impl TestDB { } fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option> { + let db = >::upcast(self); // Find the smallest (innermost) function in `def_map` containing the cursor. let mut size = None; let mut fn_def = None; for (_, module) in def_map.modules() { - let file_id = module.definition_source(self).file_id; + let file_id = module.definition_source(db).file_id; if file_id != position.file_id { continue; } for decl in module.scope.declarations() { if let ModuleDefId::FunctionId(it) = decl { - let range = it.lookup(self).source(self).value.syntax().text_range(); + let range = it.lookup(db).source(db).value.syntax().text_range(); if !range.contains(position.offset) { continue; @@ -203,10 +267,13 @@ impl TestDB { // Find the innermost block expression that has a `DefMap`. let def_with_body = fn_def?.into(); - let (_, source_map) = self.body_with_source_map(def_with_body); - let scopes = self.expr_scopes(def_with_body); - let root = self.parse(position.file_id); + let source_map = db.body_with_source_map(def_with_body).1; + let scopes = db.expr_scopes(def_with_body); + + let editioned_file_id_wrapper = + base_db::EditionedFileId::new(db.as_dyn_database(), position.file_id); + let root = db.parse(editioned_file_id_wrapper); let scope_iter = algo::ancestors_at_offset(&root.syntax_node(), position.offset) .filter_map(|node| { let block = ast::BlockExpr::cast(node)?; @@ -223,7 +290,7 @@ impl TestDB { let mut containing_blocks = scopes.scope_chain(Some(scope)).filter_map(|scope| scopes.block(scope)); - if let Some(block) = containing_blocks.next().map(|block| self.block_def_map(block)) { + if let Some(block) = containing_blocks.next().map(|block| db.block_def_map(block)) { return Some(block); } } @@ -231,7 +298,7 @@ impl TestDB { None } - pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { + pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { *self.events.lock().unwrap() = Some(Vec::new()); f(); self.events.lock().unwrap().take().unwrap() @@ -244,8 +311,11 @@ impl TestDB { .filter_map(|e| match e.kind { // This is pretty horrible, but `Debug` is the only way to inspect // QueryDescriptor at the moment. - ra_salsa::EventKind::WillExecute { database_key } => { - Some(format!("{:?}", database_key.debug(self))) + salsa::EventKind::WillExecute { database_key } => { + let ingredient = self + .as_dyn_database() + .ingredient_debug_name(database_key.ingredient_index()); + Some(ingredient.to_string()) } _ => None, }) diff --git a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml index 7d561e0527d91..607199a62443d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml @@ -21,6 +21,8 @@ itertools.workspace = true hashbrown.workspace = true smallvec.workspace = true triomphe.workspace = true +query-group.workspace = true +salsa.workspace = true # local deps stdx.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 55242ab3e57d1..d8b3f40e8f413 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -3,9 +3,12 @@ use base_db::AnchoredPath; use cfg::CfgExpr; use either::Either; -use intern::{sym, Symbol}; +use intern::{ + sym::{self}, + Symbol, +}; use mbe::{expect_fragment, DelimiterKind}; -use span::{Edition, EditionedFileId, Span}; +use span::{Edition, EditionedFileId, FileId, Span}; use stdx::format_to; use syntax::{ format_smolstr, @@ -401,7 +404,7 @@ fn use_panic_2021(db: &dyn ExpandDatabase, span: Span) -> bool { // stack that does not have #[allow_internal_unstable(edition_panic)]. // (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.) loop { - let Some(expn) = db.lookup_intern_syntax_context(span.ctx).outer_expn else { + let Some(expn) = span.ctx.outer_expn(db) else { break false; }; let expn = db.lookup_intern_macro_call(expn); @@ -656,10 +659,10 @@ fn relative_file( allow_recursion: bool, err_span: Span, ) -> Result { - let lookup = call_id.lookup(db); + let lookup = db.lookup_intern_macro_call(call_id); let call_site = lookup.kind.file_id().original_file_respecting_includes(db).file_id(); let path = AnchoredPath { anchor: call_site, path: path_str }; - let res = db + let res: FileId = db .resolve_path(path) .ok_or_else(|| ExpandError::other(err_span, format!("failed to load file `{path_str}`")))?; // Prevent include itself @@ -725,8 +728,10 @@ fn include_expand( tt: &tt::TopSubtree, span: Span, ) -> ExpandResult { - let file_id = match include_input_to_file_id(db, arg_id, tt) { - Ok(it) => it, + let (file_id_wrapper, editioned_file_id) = match include_input_to_file_id(db, arg_id, tt) { + Ok(editioned_file_id) => { + (base_db::EditionedFileId::new(db, editioned_file_id), editioned_file_id) + } Err(e) => { return ExpandResult::new( tt::TopSubtree::empty(DelimSpan { open: span, close: span }), @@ -734,10 +739,10 @@ fn include_expand( ) } }; - let span_map = db.real_span_map(file_id); + let span_map = db.real_span_map(editioned_file_id); // FIXME: Parse errors ExpandResult::ok(syntax_node_to_token_tree( - &db.parse(file_id).syntax_node(), + &db.parse(file_id_wrapper).syntax_node(), SpanMap::RealSpanMap(span_map), span, syntax_bridge::DocCommentDesugarMode::ProcMacro, @@ -800,7 +805,7 @@ fn include_str_expand( }; let text = db.file_text(file_id.file_id()); - let text = &*text; + let text = &*text.text(db); ExpandResult::ok(quote!(span =>#text)) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs index 9b637fc768446..a961df181db23 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs @@ -277,8 +277,8 @@ mod tests { assert_eq!(quoted.to_string(), "hello"); let t = format!("{quoted:#?}"); expect![[r#" - SUBTREE $$ 937550:0@0..0#2 937550:0@0..0#2 - IDENT hello 937550:0@0..0#2"#]] + SUBTREE $$ 937550:0@0..0#4294967037 937550:0@0..0#4294967037 + IDENT hello 937550:0@0..0#4294967037"#]] .assert_eq(&t); } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs index 1fdf251ba5210..7a42d6626010b 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs @@ -1,10 +1,8 @@ //! Defines a unit of change that can applied to the database to get the next //! state. Changes are transactional. -use base_db::{ - ra_salsa::Durability, CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot, - SourceRootDatabase, -}; +use base_db::{CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot}; use rustc_hash::FxHashMap; +use salsa::Durability; use span::FileId; use triomphe::Arc; @@ -21,7 +19,7 @@ impl ChangeWithProcMacros { Self::default() } - pub fn apply(self, db: &mut (impl ExpandDatabase + SourceRootDatabase)) { + pub fn apply(self, db: &mut impl ExpandDatabase) { self.source_change.apply(db); if let Some(proc_macros) = self.proc_macros { db.set_proc_macros_with_durability(Arc::new(proc_macros), Durability::HIGH); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 8ca8bf1ba4a6e..2f97cceab554a 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -1,10 +1,14 @@ //! Defines database & queries for macro expansion. -use base_db::{ra_salsa, CrateId, SourceDatabase}; +use base_db::{CrateId, RootQueryDb}; use either::Either; use mbe::MatchedArmIndex; use rustc_hash::FxHashSet; -use span::{AstIdMap, Edition, EditionedFileId, Span, SyntaxContextData, SyntaxContextId}; +use salsa::plumbing::AsId; +use span::{ + AstIdMap, Edition, EditionedFileId, HirFileId, HirFileIdRepr, MacroCallId, MacroFileId, Span, + SyntaxContextId, +}; use syntax::{ast, AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T}; use syntax_bridge::{syntax_node_to_token_tree, DocCommentDesugarMode}; use triomphe::Arc; @@ -19,12 +23,11 @@ use crate::{ span_with_call_site_ctxt, span_with_def_site_ctxt, span_with_mixed_site_ctxt, SyntaxContextExt as _, }, - proc_macro::ProcMacros, - span_map::{RealSpanMap, SpanMap, SpanMapRef}, - tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, - CustomProcMacroExpander, EagerCallInfo, EagerExpander, ExpandError, ExpandResult, ExpandTo, - ExpansionSpanMap, HirFileId, HirFileIdRepr, Lookup, MacroCallId, MacroCallKind, MacroCallLoc, - MacroDefId, MacroDefKind, MacroFileId, + proc_macro::{CustomProcMacroExpander, ProcMacros}, + span_map::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef}, + tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo, + EagerExpander, ExpandError, ExpandResult, ExpandTo, MacroCallKind, MacroCallLoc, MacroDefId, + MacroDefKind, }; /// This is just to ensure the types of smart_macro_arg and macro_arg are the same type MacroArgResult = (Arc, SyntaxFixupUndoInfo, Span); @@ -52,32 +55,32 @@ pub enum TokenExpander { ProcMacro(CustomProcMacroExpander), } -#[ra_salsa::query_group(ExpandDatabaseStorage)] -pub trait ExpandDatabase: SourceDatabase { +#[query_group::query_group] +pub trait ExpandDatabase: RootQueryDb { /// The proc macros. - #[ra_salsa::input] + #[salsa::input] fn proc_macros(&self) -> Arc; fn ast_id_map(&self, file_id: HirFileId) -> Arc; - /// Main public API -- parses a hir file, not caring whether it's a real - /// file or a macro expansion. - #[ra_salsa::transparent] + #[salsa::transparent] fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode; + /// Implementation for the macro case. - #[ra_salsa::lru] + #[salsa::lru(512)] fn parse_macro_expansion( &self, - macro_file: MacroFileId, + macro_file: span::MacroFileId, ) -> ExpandResult<(Parse, Arc)>; - #[ra_salsa::transparent] - #[ra_salsa::invoke(SpanMap::new)] + + #[salsa::transparent] + #[salsa::invoke(SpanMap::new)] fn span_map(&self, file_id: HirFileId) -> SpanMap; - #[ra_salsa::transparent] - #[ra_salsa::invoke(crate::span_map::expansion_span_map)] + #[salsa::transparent] + #[salsa::invoke(crate::span_map::expansion_span_map)] fn expansion_span_map(&self, file_id: MacroFileId) -> Arc; - #[ra_salsa::invoke(crate::span_map::real_span_map)] + #[salsa::invoke(crate::span_map::real_span_map)] fn real_span_map(&self, file_id: EditionedFileId) -> Arc; /// Macro ids. That's probably the tricksiest bit in rust-analyzer, and the @@ -85,43 +88,47 @@ pub trait ExpandDatabase: SourceDatabase { /// /// We encode macro definitions into ids of macro calls, this what allows us /// to be incremental. - #[ra_salsa::interned] + #[salsa::transparent] fn intern_macro_call(&self, macro_call: MacroCallLoc) -> MacroCallId; - #[ra_salsa::interned] - fn intern_syntax_context(&self, ctx: SyntaxContextData) -> SyntaxContextId; + #[salsa::transparent] + fn lookup_intern_macro_call(&self, macro_call: MacroCallId) -> MacroCallLoc; - #[ra_salsa::transparent] - fn setup_syntax_context_root(&self) -> (); - #[ra_salsa::transparent] - #[ra_salsa::invoke(crate::hygiene::dump_syntax_contexts)] + #[salsa::transparent] + #[salsa::invoke(crate::hygiene::dump_syntax_contexts)] fn dump_syntax_contexts(&self) -> String; /// Lowers syntactic macro call to a token tree representation. That's a firewall /// query, only typing in the macro call itself changes the returned /// subtree. #[deprecated = "calling this is incorrect, call `macro_arg_considering_derives` instead"] + #[salsa::invoke(macro_arg)] fn macro_arg(&self, id: MacroCallId) -> MacroArgResult; - #[ra_salsa::transparent] + + #[salsa::transparent] fn macro_arg_considering_derives( &self, id: MacroCallId, kind: &MacroCallKind, ) -> MacroArgResult; + /// Fetches the expander for this macro. - #[ra_salsa::transparent] - #[ra_salsa::invoke(TokenExpander::macro_expander)] + #[salsa::transparent] + #[salsa::invoke(TokenExpander::macro_expander)] fn macro_expander(&self, id: MacroDefId) -> TokenExpander; + /// Fetches (and compiles) the expander of this decl macro. - #[ra_salsa::invoke(DeclarativeMacroExpander::expander)] + #[salsa::invoke(DeclarativeMacroExpander::expander)] fn decl_macro_expander( &self, def_crate: CrateId, id: AstId, ) -> Arc; + /// Special case of the previous query for procedural macros. We can't LRU /// proc macros, since they are not deterministic in general, and /// non-determinism breaks salsa in a very, very, very bad way. /// @edwin0cheng heroically debugged this once! See #4315 for details + #[salsa::invoke(expand_proc_macro)] fn expand_proc_macro(&self, call: MacroCallId) -> ExpandResult>; /// Retrieves the span to be used for a proc-macro expansions spans. /// This is a firewall query as it requires parsing the file, which we don't want proc-macros to @@ -129,22 +136,42 @@ pub trait ExpandDatabase: SourceDatabase { /// parse queries being LRU cached. If they weren't the invalidations would only happen if the /// user wrote in the file that defines the proc-macro. fn proc_macro_span(&self, fun: AstId) -> Span; + /// Firewall query that returns the errors from the `parse_macro_expansion` query. + #[salsa::invoke(parse_macro_expansion_error)] fn parse_macro_expansion_error( &self, macro_call: MacroCallId, ) -> Option>>>; - #[ra_salsa::transparent] + + #[salsa::transparent] fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContextId; } +#[salsa::interned(no_lifetime, id = span::MacroCallId)] +pub struct MacroCallWrapper { + pub loc: MacroCallLoc, +} + +fn intern_macro_call(db: &dyn ExpandDatabase, macro_call: MacroCallLoc) -> MacroCallId { + MacroCallWrapper::new(db, macro_call).0 +} + +fn lookup_intern_macro_call(db: &dyn ExpandDatabase, macro_call: MacroCallId) -> MacroCallLoc { + MacroCallWrapper::ingredient(db).data(db.as_dyn_database(), macro_call.as_id()).0.clone() +} + +#[salsa::interned(no_lifetime, id = span::SyntaxContextId)] +pub struct SyntaxContextWrapper { + pub data: SyntaxContextId, +} + fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) -> SyntaxContextId { match file.repr() { HirFileIdRepr::FileId(_) => SyntaxContextId::root(edition), HirFileIdRepr::MacroFile(m) => { - db.macro_arg_considering_derives(m.macro_call_id, &m.macro_call_id.lookup(db).kind) - .2 - .ctx + let kind = db.lookup_intern_macro_call(m.macro_call_id).kind; + db.macro_arg_considering_derives(m.macro_call_id, &kind).2.ctx } } } @@ -322,9 +349,15 @@ fn ast_id_map(db: &dyn ExpandDatabase, file_id: span::HirFileId) -> triomphe::Ar triomphe::Arc::new(AstIdMap::from_source(&db.parse_or_expand(file_id))) } +/// Main public API -- parses a hir file, not caring whether it's a real +/// file or a macro expansion. fn parse_or_expand(db: &dyn ExpandDatabase, file_id: HirFileId) -> SyntaxNode { match file_id.repr() { - HirFileIdRepr::FileId(file_id) => db.parse(file_id).syntax_node(), + HirFileIdRepr::FileId(editioned_file_id) => { + let file_id = base_db::EditionedFileId::new(db, editioned_file_id); + db.parse(file_id).syntax_node() + } + HirFileIdRepr::MacroFile(macro_file) => { db.parse_macro_expansion(macro_file).value.0.syntax_node() } @@ -376,8 +409,13 @@ pub(crate) fn parse_with_map( file_id: HirFileId, ) -> (Parse, SpanMap) { match file_id.repr() { - HirFileIdRepr::FileId(file_id) => { - (db.parse(file_id).to_syntax(), SpanMap::RealSpanMap(db.real_span_map(file_id))) + HirFileIdRepr::FileId(editioned_file_id) => { + let file_id = base_db::EditionedFileId::new(db, editioned_file_id); + + ( + db.parse(file_id).to_syntax(), + SpanMap::RealSpanMap(db.real_span_map(editioned_file_id)), + ) } HirFileIdRepr::MacroFile(macro_file) => { let (parse, map) = db.parse_macro_expansion(macro_file).value; @@ -597,7 +635,7 @@ fn macro_expand( let (ExpandResult { value: (tt, matched_arm), err }, span) = match loc.def.kind { MacroDefKind::ProcMacro(..) => { - return db.expand_proc_macro(macro_call_id).map(CowArc::Arc).zip_val(None) + return db.expand_proc_macro(macro_call_id).map(CowArc::Arc).zip_val(None); } _ => { let (macro_arg, undo_info, span) = @@ -728,12 +766,7 @@ pub(crate) fn token_tree_to_syntax_node( ExpandTo::Type => syntax_bridge::TopEntryPoint::Type, ExpandTo::Expr => syntax_bridge::TopEntryPoint::Expr, }; - syntax_bridge::token_tree_to_syntax_node( - tt, - entry_point, - &mut |ctx| ctx.lookup(db).edition, - edition, - ) + syntax_bridge::token_tree_to_syntax_node(tt, entry_point, &mut |ctx| ctx.edition(db), edition) } fn check_tt_count(tt: &tt::TopSubtree) -> Result<(), ExpandResult<()>> { @@ -754,9 +787,3 @@ fn check_tt_count(tt: &tt::TopSubtree) -> Result<(), ExpandResult<()>> { }) } } - -fn setup_syntax_context_root(db: &dyn ExpandDatabase) { - for edition in Edition::iter() { - db.intern_syntax_context(SyntaxContextData::root(edition)); - } -} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index fef77acb7bbb7..91cbbc373649c 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -102,12 +102,13 @@ impl DeclarativeMacroExpander { }; let ctx_edition = |ctx: SyntaxContextId| { let crate_graph = db.crate_graph(); + if ctx.is_root() { crate_graph[def_crate].edition } else { - let data = db.lookup_intern_syntax_context(ctx); // UNWRAP-SAFETY: Only the root context has no outer expansion - crate_graph[data.outer_expn.unwrap().lookup(db).def.krate].edition + let krate = db.lookup_intern_macro_call(ctx.outer_expn(db).unwrap()).def.krate; + crate_graph[krate].edition } }; let (mac, transparency) = match id.to_ptr(db).to_node(&root) { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs index f476d1b564c4c..4a98b455cab83 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs @@ -28,7 +28,7 @@ use crate::{ ast::{self, AstNode}, db::ExpandDatabase, mod_path::ModPath, - AstId, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, InFile, Intern, + AstId, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, InFile, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, }; @@ -47,13 +47,13 @@ pub fn expand_eager_macro_input( // When `lazy_expand` is called, its *parent* file must already exist. // Here we store an eager macro id for the argument expanded subtree // for that purpose. - let arg_id = MacroCallLoc { + let loc = MacroCallLoc { def, krate, kind: MacroCallKind::FnLike { ast_id, expand_to: ExpandTo::Expr, eager: None }, ctxt: call_site, - } - .intern(db); + }; + let arg_id = db.intern_macro_call(loc); #[allow(deprecated)] // builtin eager macros are never derives let (_, _, span) = db.macro_arg(arg_id); let ExpandResult { value: (arg_exp, arg_exp_map), err: parse_err } = @@ -107,7 +107,7 @@ pub fn expand_eager_macro_input( ctxt: call_site, }; - ExpandResult { value: Some(loc.intern(db)), err } + ExpandResult { value: Some(db.intern_macro_call(loc)), err } } fn lazy_expand( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs index f3bcc77268224..5810d11338cb9 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs @@ -159,7 +159,9 @@ trait FileIdToSyntax: Copy { impl FileIdToSyntax for EditionedFileId { fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode { - db.parse(self).syntax_node() + let file_id = base_db::EditionedFileId::new(db, self); + + db.parse(file_id).syntax_node() } } impl FileIdToSyntax for MacroFileId { @@ -274,7 +276,7 @@ impl> InFile { // as we don't have node inputs otherwise and therefore can't find an `N` node in the input let file_id = match self.file_id.repr() { HirFileIdRepr::FileId(file_id) => { - return Some(InRealFile { file_id, value: self.value.borrow().clone() }) + return Some(InRealFile { file_id, value: self.value.borrow().clone() }); } HirFileIdRepr::MacroFile(m) if matches!(m.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) => @@ -284,12 +286,14 @@ impl> InFile { _ => return None, }; - let FileRange { file_id, range } = map_node_range_up_rooted( + let FileRange { file_id: editioned_file_id, range } = map_node_range_up_rooted( db, &db.expansion_span_map(file_id), self.value.borrow().text_range(), )?; + let file_id = base_db::EditionedFileId::new(db, editioned_file_id); + let kind = self.kind(); let value = db .parse(file_id) @@ -298,7 +302,7 @@ impl> InFile { .ancestors() .take_while(|it| it.text_range() == range) .find(|it| it.kind() == kind)?; - Some(InRealFile::new(file_id, value)) + Some(InRealFile::new(editioned_file_id, value)) } } @@ -453,7 +457,7 @@ impl InFile { // as we don't have node inputs otherwise and therefore can't find an `N` node in the input let file_id = match self.file_id.repr() { HirFileIdRepr::FileId(file_id) => { - return Some(InRealFile { file_id, value: self.value }) + return Some(InRealFile { file_id, value: self.value }); } HirFileIdRepr::MacroFile(m) => m, }; @@ -461,16 +465,18 @@ impl InFile { return None; } - let FileRange { file_id, range } = map_node_range_up_rooted( + let FileRange { file_id: editioned_file_id, range } = map_node_range_up_rooted( db, &db.expansion_span_map(file_id), self.value.syntax().text_range(), )?; + let file_id = base_db::EditionedFileId::new(db, editioned_file_id); + // FIXME: This heuristic is brittle and with the right macro may select completely unrelated nodes? let anc = db.parse(file_id).syntax_node().covering_element(range); let value = anc.ancestors().find_map(N::cast)?; - Some(InRealFile::new(file_id, value)) + Some(InRealFile::new(editioned_file_id, value)) } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs index fe05af0ac9d31..b53468ccacdca 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs @@ -22,11 +22,11 @@ // FIXME: Move this into the span crate? Not quite possible today as that depends on `MacroCallLoc` // which contains a bunch of unrelated things -use std::iter; +use std::{convert::identity, iter}; -use span::{Edition, MacroCallId, Span, SyntaxContextData, SyntaxContextId}; +use span::{Edition, MacroCallId, Span, SyntaxContextId}; -use crate::db::{ExpandDatabase, InternSyntaxContextQuery}; +use crate::db::{ExpandDatabase, MacroCallWrapper}; pub use span::Transparency; @@ -72,8 +72,8 @@ fn span_with_ctxt_from_mark( pub(super) fn apply_mark( db: &dyn ExpandDatabase, - ctxt: SyntaxContextId, - call_id: MacroCallId, + ctxt: span::SyntaxContextId, + call_id: span::MacroCallId, transparency: Transparency, edition: Edition, ) -> SyntaxContextId { @@ -114,92 +114,75 @@ fn apply_mark_internal( transparency: Transparency, edition: Edition, ) -> SyntaxContextId { - use base_db::ra_salsa; - let call_id = Some(call_id); - let syntax_context_data = db.lookup_intern_syntax_context(ctxt); - let mut opaque = syntax_context_data.opaque; - let mut opaque_and_semitransparent = syntax_context_data.opaque_and_semitransparent; + let mut opaque = ctxt.opaque(db); + let mut opaque_and_semitransparent = ctxt.opaque_and_semitransparent(db); if transparency >= Transparency::Opaque { let parent = opaque; - opaque = ra_salsa::plumbing::get_query_table::(db).get_or_insert( - (parent, call_id, transparency, edition), - |new_opaque| SyntaxContextData { - outer_expn: call_id, - outer_transparency: transparency, - parent, - opaque: new_opaque, - opaque_and_semitransparent: new_opaque, - edition, - }, - ); + opaque = + SyntaxContextId::new(db, call_id, transparency, edition, parent, identity, identity); } if transparency >= Transparency::SemiTransparent { let parent = opaque_and_semitransparent; opaque_and_semitransparent = - ra_salsa::plumbing::get_query_table::(db).get_or_insert( - (parent, call_id, transparency, edition), - |new_opaque_and_semitransparent| SyntaxContextData { - outer_expn: call_id, - outer_transparency: transparency, - parent, - opaque, - opaque_and_semitransparent: new_opaque_and_semitransparent, - edition, - }, - ); + SyntaxContextId::new(db, call_id, transparency, edition, parent, |_| opaque, identity); } let parent = ctxt; - db.intern_syntax_context(SyntaxContextData { - outer_expn: call_id, - outer_transparency: transparency, - parent, - opaque, - opaque_and_semitransparent, + SyntaxContextId::new( + db, + call_id, + transparency, edition, - }) + parent, + |_| opaque, + |_| opaque_and_semitransparent, + ) } pub trait SyntaxContextExt { - fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> Self; - fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> Self; - fn parent_ctxt(self, db: &dyn ExpandDatabase) -> Self; - fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option, Transparency); - fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency); - fn marks(self, db: &dyn ExpandDatabase) -> Vec<(MacroCallId, Transparency)>; + fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId; + fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId; + fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId; + fn remove_mark(&mut self, db: &dyn ExpandDatabase) + -> (Option, Transparency); + fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency); + fn marks(self, db: &dyn ExpandDatabase) -> Vec<(span::MacroCallId, Transparency)>; fn is_opaque(self, db: &dyn ExpandDatabase) -> bool; } impl SyntaxContextExt for SyntaxContextId { - fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> Self { - db.lookup_intern_syntax_context(self).opaque_and_semitransparent + fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId { + self.opaque_and_semitransparent(db) } - fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> Self { - db.lookup_intern_syntax_context(self).opaque + fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId { + self.opaque(db) } - fn parent_ctxt(self, db: &dyn ExpandDatabase) -> Self { - db.lookup_intern_syntax_context(self).parent + fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId { + self.parent(db) } - fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency) { - let data = db.lookup_intern_syntax_context(self); - (data.outer_expn, data.outer_transparency) + fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency) { + let data = self; + (data.outer_expn(db), data.outer_transparency(db)) } - fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option, Transparency) { - let data = db.lookup_intern_syntax_context(*self); - *self = data.parent; - (data.outer_expn, data.outer_transparency) + fn remove_mark( + &mut self, + db: &dyn ExpandDatabase, + ) -> (Option, Transparency) { + let data = *self; + *self = data.parent(db); + (data.outer_expn(db), data.outer_transparency(db)) } - fn marks(self, db: &dyn ExpandDatabase) -> Vec<(MacroCallId, Transparency)> { + fn marks(self, db: &dyn ExpandDatabase) -> Vec<(span::MacroCallId, Transparency)> { let mut marks = marks_rev(self, db).collect::>(); marks.reverse(); marks } fn is_opaque(self, db: &dyn ExpandDatabase) -> bool { - !self.is_root() && db.lookup_intern_syntax_context(self).outer_transparency.is_opaque() + !self.is_root() && self.outer_transparency(db).is_opaque() } } @@ -207,7 +190,7 @@ impl SyntaxContextExt for SyntaxContextId { pub fn marks_rev( ctxt: SyntaxContextId, db: &dyn ExpandDatabase, -) -> impl Iterator + '_ { +) -> impl Iterator + '_ { iter::successors(Some(ctxt), move |&mark| Some(mark.parent_ctxt(db))) .take_while(|&it| !it.is_root()) .map(|ctx| { @@ -219,18 +202,14 @@ pub fn marks_rev( } pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String { - use crate::db::{InternMacroCallLookupQuery, InternSyntaxContextLookupQuery}; - use base_db::ra_salsa::debug::DebugQueryTable; - let mut s = String::from("Expansions:"); - let mut entries = InternMacroCallLookupQuery.in_db(db).entries::>(); - entries.sort_by_key(|e| e.key); - for e in entries { - let id = e.key; - let expn_data = e.value.as_ref().unwrap(); + let entries = + MacroCallWrapper::ingredient(db).entries(db.as_dyn_database()).collect::>(); + for loc in entries { + let expn_data = &loc.fields().0; + s.push_str(&format!( - "\n{:?}: parent: {:?}, call_site_ctxt: {:?}, kind: {:?}", - id, + "parent: {:?}, call_site_ctxt: {:?}, kind: {:?}", expn_data.kind.file_id(), expn_data.ctxt, expn_data.kind.descr(), @@ -238,28 +217,25 @@ pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String { } s.push_str("\n\nSyntaxContexts:\n"); - let mut entries = InternSyntaxContextLookupQuery.in_db(db).entries::>(); - entries.sort_by_key(|e| e.key); + let entries = SyntaxContextId::ingredient(db).entries(db.as_dyn_database()).collect::>(); for e in entries { struct SyntaxContextDebug<'a>( &'a dyn ExpandDatabase, - SyntaxContextId, - &'a SyntaxContextData, + &'a span::SyntaxContextUnderlyingData, ); impl std::fmt::Debug for SyntaxContextDebug<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fancy_debug(self.2, self.1, self.0, f) + fancy_debug(self.1, self.0, f) } } fn fancy_debug( - this: &SyntaxContextData, - self_id: SyntaxContextId, + this: &span::SyntaxContextUnderlyingData, db: &dyn ExpandDatabase, f: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { - write!(f, "#{self_id} parent: #{}, outer_mark: (", this.parent)?; + write!(f, "parent: #{}, outer_mark: (", this.parent)?; match this.outer_expn { Some(id) => { write!(f, "{:?}::{{{{expn{:?}}}}}", db.lookup_intern_macro_call(id).krate, id)? @@ -269,7 +245,8 @@ pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String { write!(f, ", {:?})", this.outer_transparency) } - stdx::format_to!(s, "{:?}\n", SyntaxContextDebug(db, e.key, &e.value.unwrap())); + let dbg = SyntaxContextDebug(db, e.fields()); + stdx::format_to!(s, "{:?}\n", dbg); } s } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index c1d808cbf2c5a..f8c83dce55ac6 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -33,11 +33,11 @@ use triomphe::Arc; use core::fmt; use std::hash::Hash; -use base_db::{ra_salsa::InternValueTrivial, CrateId}; +use base_db::CrateId; use either::Either; use span::{ Edition, EditionedFileId, ErasedFileAstId, FileAstId, HirFileIdRepr, Span, SpanAnchor, - SyntaxContextData, SyntaxContextId, + SyntaxContextId, }; use syntax::{ ast::{self, AstNode}, @@ -89,17 +89,17 @@ pub mod tt { macro_rules! impl_intern_lookup { ($db:ident, $id:ident, $loc:ident, $intern:ident, $lookup:ident) => { impl $crate::Intern for $loc { - type Database<'db> = dyn $db + 'db; + type Database = dyn $db; type ID = $id; - fn intern(self, db: &Self::Database<'_>) -> $id { + fn intern(self, db: &Self::Database) -> Self::ID { db.$intern(self) } } impl $crate::Lookup for $id { - type Database<'db> = dyn $db + 'db; + type Database = dyn $db; type Data = $loc; - fn lookup(&self, db: &Self::Database<'_>) -> $loc { + fn lookup(&self, db: &Self::Database) -> Self::Data { db.$lookup(*self) } } @@ -108,15 +108,15 @@ macro_rules! impl_intern_lookup { // ideally these would be defined in base-db, but the orphan rule doesn't let us pub trait Intern { - type Database<'db>: ?Sized; + type Database: ?Sized; type ID; - fn intern(self, db: &Self::Database<'_>) -> Self::ID; + fn intern(self, db: &Self::Database) -> Self::ID; } pub trait Lookup { - type Database<'db>: ?Sized; + type Database: ?Sized; type Data; - fn lookup(&self, db: &Self::Database<'_>) -> Self::Data; + fn lookup(&self, db: &Self::Database) -> Self::Data; } impl_intern_lookup!( @@ -127,14 +127,6 @@ impl_intern_lookup!( lookup_intern_macro_call ); -impl_intern_lookup!( - ExpandDatabase, - SyntaxContextId, - SyntaxContextData, - intern_syntax_context, - lookup_intern_syntax_context -); - pub type ExpandResult = ValueResult; #[derive(Debug, PartialEq, Eq, Clone, Hash)] @@ -262,7 +254,6 @@ pub struct MacroCallLoc { pub kind: MacroCallKind, pub ctxt: SyntaxContextId, } -impl InternValueTrivial for MacroCallLoc {} #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct MacroDefId { @@ -357,7 +348,7 @@ impl HirFileIdExt for HirFileId { fn edition(self, db: &dyn ExpandDatabase) -> Edition { match self.repr() { HirFileIdRepr::FileId(file_id) => file_id.edition(), - HirFileIdRepr::MacroFile(m) => m.macro_call_id.lookup(db).def.edition, + HirFileIdRepr::MacroFile(m) => db.lookup_intern_macro_call(m.macro_call_id).def.edition, } } fn original_file(self, db: &dyn ExpandDatabase) -> EditionedFileId { @@ -366,7 +357,7 @@ impl HirFileIdExt for HirFileId { match file_id.repr() { HirFileIdRepr::FileId(id) => break id, HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => { - file_id = macro_call_id.lookup(db).kind.file_id(); + file_id = db.lookup_intern_macro_call(macro_call_id).kind.file_id() } } } @@ -409,7 +400,7 @@ impl HirFileIdExt for HirFileId { fn as_builtin_derive_attr_node(&self, db: &dyn ExpandDatabase) -> Option> { let macro_file = self.macro_file()?; - let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id); + let loc = db.lookup_intern_macro_call(macro_file.macro_call_id); let attr = match loc.def.kind { MacroDefKind::BuiltInDerive(..) => loc.to_node(db), _ => return None, @@ -467,7 +458,7 @@ impl MacroFileIdExt for MacroFileId { let mut level = 0; let mut macro_file = self; loop { - let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id); + let loc = db.lookup_intern_macro_call(macro_file.macro_call_id); level += 1; macro_file = match loc.kind.file_id().repr() { @@ -477,7 +468,7 @@ impl MacroFileIdExt for MacroFileId { } } fn parent(self, db: &dyn ExpandDatabase) -> HirFileId { - self.macro_call_id.lookup(db).kind.file_id() + db.lookup_intern_macro_call(self.macro_call_id).kind.file_id() } /// Return expansion information if it is a macro-expansion file @@ -538,7 +529,7 @@ impl MacroDefId { kind: MacroCallKind, ctxt: SyntaxContextId, ) -> MacroCallId { - MacroCallLoc { def: self, krate, kind, ctxt }.intern(db) + db.intern_macro_call(MacroCallLoc { def: self, krate, kind, ctxt }) } pub fn definition_range(&self, db: &dyn ExpandDatabase) -> InFile { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 75b5861454056..6f6f41f322abf 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -277,7 +277,7 @@ fn convert_path( if mod_path.segments.len() == 1 && mod_path.kind == PathKind::Plain { if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { let syn_ctx = span_for_range(segment.syntax().text_range()); - if let Some(macro_call_id) = db.lookup_intern_syntax_context(syn_ctx).outer_expn { + if let Some(macro_call_id) = syn_ctx.outer_expn(db) { if db.lookup_intern_macro_call(macro_call_id).def.local_inner { mod_path.kind = match resolve_crate_root(db, syn_ctx) { Some(crate_root) => PathKind::DollarCrate(crate_root), @@ -336,7 +336,7 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: tt::TokenTreesView<'_>) -> Optio pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) -> Option { // When resolving `$crate` from a `macro_rules!` invoked in a `macro`, // we don't want to pretend that the `macro_rules!` definition is in the `macro` - // as described in `SyntaxContext::apply_mark`, so we ignore prepended opaque marks. + // as described in `SyntaxContextId::apply_mark`, so we ignore prepended opaque marks. // FIXME: This is only a guess and it doesn't work correctly for `macro_rules!` // definitions actually produced by `macro` and `macro` definitions produced by // `macro_rules!`, but at least such configurations are not stable yet. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs index c744fbce77b7c..944341ec3f2cd 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs @@ -25,9 +25,8 @@ pub fn prettify_macro_expansion( let ctx = span_map.span_at(dollar_crate.text_range().start() + span_offset).ctx; let replacement = syntax_ctx_id_to_dollar_crate_replacement.entry(ctx).or_insert_with(|| { - let ctx_data = db.lookup_intern_syntax_context(ctx); let macro_call_id = - ctx_data.outer_expn.expect("`$crate` cannot come from `SyntaxContextId::ROOT`"); + ctx.outer_expn(db).expect("`$crate` cannot come from `SyntaxContextId::ROOT`"); let macro_call = db.lookup_intern_macro_call(macro_call_id); let macro_def_crate = macro_call.def.krate; // First, if this is the same crate as the macro, nothing will work but `crate`. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs index 740c27b89cea1..ab99cb14f9562 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs @@ -79,10 +79,16 @@ impl SpanMapRef<'_> { } } -pub(crate) fn real_span_map(db: &dyn ExpandDatabase, file_id: EditionedFileId) -> Arc { +pub(crate) fn real_span_map( + db: &dyn ExpandDatabase, + editioned_file_id: EditionedFileId, +) -> Arc { use syntax::ast::HasModuleItem; let mut pairs = vec![(syntax::TextSize::new(0), span::ROOT_ERASED_FILE_AST_ID)]; - let ast_id_map = db.ast_id_map(file_id.into()); + let ast_id_map = db.ast_id_map(editioned_file_id.into()); + + let file_id = base_db::EditionedFileId::new(db, editioned_file_id); + let tree = db.parse(file_id).tree(); // This is an incrementality layer. Basically we can't use absolute ranges for our spans as that // would mean we'd invalidate everything whenever we type. So instead we make the text ranges @@ -134,7 +140,7 @@ pub(crate) fn real_span_map(db: &dyn ExpandDatabase, file_id: EditionedFileId) - }); Arc::new(RealSpanMap::from_file( - file_id, + editioned_file_id, pairs.into_boxed_slice(), tree.syntax().text_range().end(), )) diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml index 1d12bee646c4f..30074105331c5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml @@ -31,8 +31,11 @@ la-arena.workspace = true triomphe.workspace = true nohash-hasher.workspace = true typed-arena = "2.0.1" +dashmap.workspace = true indexmap.workspace = true rustc_apfloat = "0.2.0" +query-group.workspace = true +salsa.workspace = true ra-ap-rustc_abi.workspace = true ra-ap-rustc_index.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 67fb73696f766..2be321733075b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -451,10 +451,10 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { self.db.type_alias_data(id).name.display(self.db.upcast(), self.edition()).to_string() } fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId) -> String { - format!("Opaque_{}", opaque_ty_id.0) + format!("Opaque_{:?}", opaque_ty_id.0) } fn fn_def_name(&self, fn_def_id: chalk_ir::FnDefId) -> String { - format!("fn_{}", fn_def_id.0) + format!("fn_{:?}", fn_def_id.0) } fn coroutine_datum( &self, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index fb604569f439d..b3c604015a0c1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -1,6 +1,6 @@ //! Constant evaluation details -use base_db::{ra_salsa::Cycle, CrateId}; +use base_db::CrateId; use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; use hir_def::{ expr_store::{Body, HygieneId}, @@ -11,14 +11,19 @@ use hir_def::{ ConstBlockLoc, EnumVariantId, GeneralConstId, HasModule as _, StaticId, }; use hir_expand::Lookup; +use salsa::Cycle; use stdx::never; use triomphe::Arc; use crate::{ - db::HirDatabase, display::DisplayTarget, generics::Generics, infer::InferenceContext, - lower::ParamLoweringMode, mir::monomorphize_mir_body_bad, to_placeholder_idx, Const, ConstData, - ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, TraitEnvironment, Ty, - TyBuilder, + db::{HirDatabase, HirDatabaseData}, + display::DisplayTarget, + generics::Generics, + infer::InferenceContext, + lower::ParamLoweringMode, + mir::monomorphize_mir_body_bad, + to_placeholder_idx, Const, ConstData, ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, + Substitution, TraitEnvironment, Ty, TyBuilder, }; use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError}; @@ -224,9 +229,10 @@ pub fn try_const_isize(db: &dyn HirDatabase, c: &Const) -> Option { pub(crate) fn const_eval_recover( _: &dyn HirDatabase, _: &Cycle, - _: &GeneralConstId, - _: &Substitution, - _: &Option>, + _: HirDatabaseData, + _: GeneralConstId, + _: Substitution, + _: Option>, ) -> Result { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) } @@ -234,7 +240,7 @@ pub(crate) fn const_eval_recover( pub(crate) fn const_eval_static_recover( _: &dyn HirDatabase, _: &Cycle, - _: &StaticId, + _: StaticId, ) -> Result { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) } @@ -242,7 +248,7 @@ pub(crate) fn const_eval_static_recover( pub(crate) fn const_eval_discriminant_recover( _: &dyn HirDatabase, _: &Cycle, - _: &EnumVariantId, + _: EnumVariantId, ) -> Result { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 26a3b7022976f..f2673dc58fa41 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -1,4 +1,4 @@ -use base_db::SourceDatabase; +use base_db::RootQueryDb; use chalk_ir::Substitution; use hir_def::db::DefDatabase; use rustc_apfloat::{ diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 76031491d9a07..5817ed2ef20cd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -3,11 +3,7 @@ use std::sync; -use base_db::{ - impl_intern_key, - ra_salsa::{self, InternValueTrivial}, - CrateId, Upcast, -}; +use base_db::{impl_intern_key, CrateId, Upcast}; use hir_def::{ db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, @@ -15,6 +11,7 @@ use hir_def::{ }; use hir_expand::name::Name; use la_arena::ArenaMap; +use salsa::plumbing::AsId; use smallvec::SmallVec; use triomphe::Arc; @@ -31,22 +28,22 @@ use crate::{ PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId, }; -#[ra_salsa::query_group(HirDatabaseStorage)] -pub trait HirDatabase: DefDatabase + Upcast { - #[ra_salsa::invoke(crate::infer::infer_query)] +#[query_group::query_group] +pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { + #[salsa::invoke_actual(crate::infer::infer_query)] fn infer(&self, def: DefWithBodyId) -> Arc; // region:mir - #[ra_salsa::invoke(crate::mir::mir_body_query)] - #[ra_salsa::cycle(crate::mir::mir_body_recover)] + #[salsa::invoke_actual(crate::mir::mir_body_query)] + #[salsa::cycle(crate::mir::mir_body_recover)] fn mir_body(&self, def: DefWithBodyId) -> Result, MirLowerError>; - #[ra_salsa::invoke(crate::mir::mir_body_for_closure_query)] + #[salsa::invoke(crate::mir::mir_body_for_closure_query)] fn mir_body_for_closure(&self, def: ClosureId) -> Result, MirLowerError>; - #[ra_salsa::invoke(crate::mir::monomorphized_mir_body_query)] - #[ra_salsa::cycle(crate::mir::monomorphized_mir_body_recover)] + #[salsa::invoke(crate::mir::monomorphized_mir_body_query)] + #[salsa::cycle(crate::mir::monomorphized_mir_body_recover)] fn monomorphized_mir_body( &self, def: DefWithBodyId, @@ -54,7 +51,7 @@ pub trait HirDatabase: DefDatabase + Upcast { env: Arc, ) -> Result, MirLowerError>; - #[ra_salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)] + #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)] fn monomorphized_mir_body_for_closure( &self, def: ClosureId, @@ -62,12 +59,12 @@ pub trait HirDatabase: DefDatabase + Upcast { env: Arc, ) -> Result, MirLowerError>; - #[ra_salsa::invoke(crate::mir::borrowck_query)] - #[ra_salsa::lru] + #[salsa::invoke(crate::mir::borrowck_query)] + #[salsa::lru(2024)] fn borrowck(&self, def: DefWithBodyId) -> Result, MirLowerError>; - #[ra_salsa::invoke(crate::consteval::const_eval_query)] - #[ra_salsa::cycle(crate::consteval::const_eval_recover)] + #[salsa::invoke(crate::consteval::const_eval_query)] + #[salsa::cycle(crate::consteval::const_eval_recover)] fn const_eval( &self, def: GeneralConstId, @@ -75,15 +72,15 @@ pub trait HirDatabase: DefDatabase + Upcast { trait_env: Option>, ) -> Result; - #[ra_salsa::invoke(crate::consteval::const_eval_static_query)] - #[ra_salsa::cycle(crate::consteval::const_eval_static_recover)] + #[salsa::invoke_actual(crate::consteval::const_eval_static_query)] + #[salsa::cycle(crate::consteval::const_eval_static_recover)] fn const_eval_static(&self, def: StaticId) -> Result; - #[ra_salsa::invoke(crate::consteval::const_eval_discriminant_variant)] - #[ra_salsa::cycle(crate::consteval::const_eval_discriminant_recover)] + #[salsa::invoke_actual(crate::consteval::const_eval_discriminant_variant)] + #[salsa::cycle(crate::consteval::const_eval_discriminant_recover)] fn const_eval_discriminant(&self, def: EnumVariantId) -> Result; - #[ra_salsa::invoke(crate::method_resolution::lookup_impl_method_query)] + #[salsa::invoke(crate::method_resolution::lookup_impl_method_query)] fn lookup_impl_method( &self, env: Arc, @@ -93,8 +90,8 @@ pub trait HirDatabase: DefDatabase + Upcast { // endregion:mir - #[ra_salsa::invoke(crate::layout::layout_of_adt_query)] - #[ra_salsa::cycle(crate::layout::layout_of_adt_recover)] + #[salsa::invoke(crate::layout::layout_of_adt_query)] + #[salsa::cycle(crate::layout::layout_of_adt_recover)] fn layout_of_adt( &self, def: AdtId, @@ -102,63 +99,67 @@ pub trait HirDatabase: DefDatabase + Upcast { env: Arc, ) -> Result, LayoutError>; - #[ra_salsa::invoke(crate::layout::layout_of_ty_query)] - #[ra_salsa::cycle(crate::layout::layout_of_ty_recover)] + #[salsa::invoke(crate::layout::layout_of_ty_query)] + #[salsa::cycle(crate::layout::layout_of_ty_recover)] fn layout_of_ty(&self, ty: Ty, env: Arc) -> Result, LayoutError>; - #[ra_salsa::invoke(crate::layout::target_data_layout_query)] + #[salsa::invoke(crate::layout::target_data_layout_query)] fn target_data_layout(&self, krate: CrateId) -> Result, Arc>; - #[ra_salsa::invoke(crate::dyn_compatibility::dyn_compatibility_of_trait_query)] + #[salsa::invoke_actual(crate::dyn_compatibility::dyn_compatibility_of_trait_query)] fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option; - #[ra_salsa::invoke(crate::lower::ty_query)] - #[ra_salsa::cycle(crate::lower::ty_recover)] + #[salsa::invoke(crate::lower::ty_query)] + #[salsa::cycle(crate::lower::ty_recover)] fn ty(&self, def: TyDefId) -> Binders; - #[ra_salsa::invoke(crate::lower::type_for_type_alias_with_diagnostics_query)] + #[salsa::invoke_actual(crate::lower::type_for_type_alias_with_diagnostics_query)] fn type_for_type_alias_with_diagnostics(&self, def: TypeAliasId) -> (Binders, Diagnostics); /// Returns the type of the value of the given constant, or `None` if the `ValueTyDefId` is /// a `StructId` or `EnumVariantId` with a record constructor. - #[ra_salsa::invoke(crate::lower::value_ty_query)] + #[salsa::invoke_actual(crate::lower::value_ty_query)] fn value_ty(&self, def: ValueTyDefId) -> Option>; - #[ra_salsa::invoke(crate::lower::impl_self_ty_with_diagnostics_query)] - #[ra_salsa::cycle(crate::lower::impl_self_ty_with_diagnostics_recover)] + #[salsa::invoke_actual(crate::lower::impl_self_ty_with_diagnostics_query)] + #[salsa::cycle(crate::lower::impl_self_ty_with_diagnostics_recover)] fn impl_self_ty_with_diagnostics(&self, def: ImplId) -> (Binders, Diagnostics); - #[ra_salsa::invoke(crate::lower::impl_self_ty_query)] + + #[salsa::invoke_actual(crate::lower::impl_self_ty_query)] fn impl_self_ty(&self, def: ImplId) -> Binders; - #[ra_salsa::invoke(crate::lower::const_param_ty_with_diagnostics_query)] + #[salsa::invoke(crate::lower::const_param_ty_with_diagnostics_query)] fn const_param_ty_with_diagnostics(&self, def: ConstParamId) -> (Ty, Diagnostics); - #[ra_salsa::invoke(crate::lower::const_param_ty_query)] + + #[salsa::invoke(crate::lower::const_param_ty_query)] fn const_param_ty(&self, def: ConstParamId) -> Ty; - #[ra_salsa::invoke(crate::lower::impl_trait_with_diagnostics_query)] + #[salsa::invoke_actual(crate::lower::impl_trait_with_diagnostics_query)] fn impl_trait_with_diagnostics(&self, def: ImplId) -> Option<(Binders, Diagnostics)>; - #[ra_salsa::invoke(crate::lower::impl_trait_query)] + + #[salsa::invoke_actual(crate::lower::impl_trait_query)] fn impl_trait(&self, def: ImplId) -> Option>; - #[ra_salsa::invoke(crate::lower::field_types_with_diagnostics_query)] + #[salsa::invoke_actual(crate::lower::field_types_with_diagnostics_query)] fn field_types_with_diagnostics( &self, var: VariantId, ) -> (Arc>>, Diagnostics); - #[ra_salsa::invoke(crate::lower::field_types_query)] + + #[salsa::invoke_actual(crate::lower::field_types_query)] fn field_types(&self, var: VariantId) -> Arc>>; - #[ra_salsa::invoke(crate::lower::callable_item_sig)] + #[salsa::invoke_actual(crate::lower::callable_item_sig)] fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig; - #[ra_salsa::invoke(crate::lower::return_type_impl_traits)] + #[salsa::invoke_actual(crate::lower::return_type_impl_traits)] fn return_type_impl_traits(&self, def: FunctionId) -> Option>>; - #[ra_salsa::invoke(crate::lower::type_alias_impl_traits)] + #[salsa::invoke_actual(crate::lower::type_alias_impl_traits)] fn type_alias_impl_traits(&self, def: TypeAliasId) -> Option>>; - #[ra_salsa::invoke(crate::lower::generic_predicates_for_param_query)] - #[ra_salsa::cycle(crate::lower::generic_predicates_for_param_recover)] + #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] + #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] fn generic_predicates_for_param( &self, def: GenericDefId, @@ -166,132 +167,139 @@ pub trait HirDatabase: DefDatabase + Upcast { assoc_name: Option, ) -> GenericPredicates; - #[ra_salsa::invoke(crate::lower::generic_predicates_query)] + #[salsa::invoke_actual(crate::lower::generic_predicates_query)] fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates; - #[ra_salsa::invoke(crate::lower::generic_predicates_without_parent_with_diagnostics_query)] + #[salsa::invoke_actual(crate::lower::generic_predicates_without_parent_with_diagnostics_query)] fn generic_predicates_without_parent_with_diagnostics( &self, def: GenericDefId, ) -> (GenericPredicates, Diagnostics); - #[ra_salsa::invoke(crate::lower::generic_predicates_without_parent_query)] + + #[salsa::invoke_actual(crate::lower::generic_predicates_without_parent_query)] fn generic_predicates_without_parent(&self, def: GenericDefId) -> GenericPredicates; - #[ra_salsa::invoke(crate::lower::trait_environment_for_body_query)] - #[ra_salsa::transparent] + #[salsa::invoke_actual(crate::lower::trait_environment_for_body_query)] + #[salsa::transparent] fn trait_environment_for_body(&self, def: DefWithBodyId) -> Arc; - #[ra_salsa::invoke(crate::lower::trait_environment_query)] + #[salsa::invoke_actual(crate::lower::trait_environment_query)] fn trait_environment(&self, def: GenericDefId) -> Arc; - #[ra_salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)] - #[ra_salsa::cycle(crate::lower::generic_defaults_with_diagnostics_recover)] + #[salsa::invoke_actual(crate::lower::generic_defaults_with_diagnostics_query)] + #[salsa::cycle(crate::lower::generic_defaults_with_diagnostics_recover)] fn generic_defaults_with_diagnostics( &self, def: GenericDefId, ) -> (GenericDefaults, Diagnostics); - #[ra_salsa::invoke(crate::lower::generic_defaults_query)] + + #[salsa::invoke_actual(crate::lower::generic_defaults_query)] fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults; - #[ra_salsa::invoke(InherentImpls::inherent_impls_in_crate_query)] + #[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)] fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc; - #[ra_salsa::invoke(InherentImpls::inherent_impls_in_block_query)] + #[salsa::invoke_actual(InherentImpls::inherent_impls_in_block_query)] fn inherent_impls_in_block(&self, block: BlockId) -> Option>; /// Collects all crates in the dependency graph that have impls for the /// given fingerprint. This is only used for primitive types and types /// annotated with `rustc_has_incoherent_inherent_impls`; for other types /// we just look at the crate where the type is defined. - #[ra_salsa::invoke(crate::method_resolution::incoherent_inherent_impl_crates)] + #[salsa::invoke(crate::method_resolution::incoherent_inherent_impl_crates)] fn incoherent_inherent_impl_crates( &self, krate: CrateId, fp: TyFingerprint, ) -> SmallVec<[CrateId; 2]>; - #[ra_salsa::invoke(TraitImpls::trait_impls_in_crate_query)] + #[salsa::invoke(TraitImpls::trait_impls_in_crate_query)] fn trait_impls_in_crate(&self, krate: CrateId) -> Arc; - #[ra_salsa::invoke(TraitImpls::trait_impls_in_block_query)] + #[salsa::invoke_actual(TraitImpls::trait_impls_in_block_query)] fn trait_impls_in_block(&self, block: BlockId) -> Option>; - #[ra_salsa::invoke(TraitImpls::trait_impls_in_deps_query)] + #[salsa::invoke(TraitImpls::trait_impls_in_deps_query)] fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<[Arc]>; // Interned IDs for Chalk integration - #[ra_salsa::interned] + #[salsa::interned] fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_type_or_const_param_id( &self, param_id: TypeOrConstParamId, ) -> InternedTypeOrConstParamId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_lifetime_param_id(&self, param_id: LifetimeParamId) -> InternedLifetimeParamId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_closure(&self, id: InternedClosure) -> InternedClosureId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_coroutine(&self, id: InternedCoroutine) -> InternedCoroutineId; - #[ra_salsa::invoke(chalk_db::associated_ty_data_query)] + #[salsa::invoke(chalk_db::associated_ty_data_query)] fn associated_ty_data( &self, id: chalk_db::AssocTypeId, ) -> sync::Arc; - #[ra_salsa::invoke(chalk_db::trait_datum_query)] + #[salsa::invoke(chalk_db::trait_datum_query)] fn trait_datum( &self, krate: CrateId, trait_id: chalk_db::TraitId, ) -> sync::Arc; - #[ra_salsa::invoke(chalk_db::adt_datum_query)] + #[salsa::invoke(chalk_db::adt_datum_query)] fn adt_datum( &self, krate: CrateId, struct_id: chalk_db::AdtId, ) -> sync::Arc; - #[ra_salsa::invoke(chalk_db::impl_datum_query)] + #[salsa::invoke(chalk_db::impl_datum_query)] fn impl_datum( &self, krate: CrateId, impl_id: chalk_db::ImplId, ) -> sync::Arc; - #[ra_salsa::invoke(chalk_db::fn_def_datum_query)] + #[salsa::invoke(chalk_db::fn_def_datum_query)] fn fn_def_datum(&self, fn_def_id: FnDefId) -> sync::Arc; - #[ra_salsa::invoke(chalk_db::fn_def_variance_query)] + #[salsa::invoke(chalk_db::fn_def_variance_query)] fn fn_def_variance(&self, fn_def_id: FnDefId) -> chalk_db::Variances; - #[ra_salsa::invoke(chalk_db::adt_variance_query)] + #[salsa::invoke(chalk_db::adt_variance_query)] fn adt_variance(&self, adt_id: chalk_db::AdtId) -> chalk_db::Variances; - #[ra_salsa::invoke(crate::variance::variances_of)] - #[ra_salsa::cycle(crate::variance::variances_of_cycle)] + #[salsa::invoke_actual(crate::variance::variances_of)] + #[salsa::cycle(crate::variance::variances_of_cycle)] fn variances_of(&self, def: GenericDefId) -> Option>; - #[ra_salsa::invoke(chalk_db::associated_ty_value_query)] + #[salsa::invoke(chalk_db::associated_ty_value_query)] fn associated_ty_value( &self, krate: CrateId, id: chalk_db::AssociatedTyValueId, ) -> sync::Arc; - #[ra_salsa::invoke(crate::traits::normalize_projection_query)] - #[ra_salsa::transparent] + #[salsa::invoke(crate::traits::normalize_projection_query)] + #[salsa::transparent] fn normalize_projection( &self, projection: crate::ProjectionTy, env: Arc, ) -> Ty; - #[ra_salsa::invoke(crate::traits::trait_solve_query)] + #[salsa::invoke(crate::traits::trait_solve_query)] fn trait_solve( &self, krate: CrateId, @@ -299,7 +307,7 @@ pub trait HirDatabase: DefDatabase + Upcast { goal: crate::Canonical>, ) -> Option; - #[ra_salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)] + #[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)] fn program_clauses_for_chalk_env( &self, krate: CrateId, @@ -307,9 +315,9 @@ pub trait HirDatabase: DefDatabase + Upcast { env: chalk_ir::Environment, ) -> chalk_ir::ProgramClauses; - #[ra_salsa::invoke(crate::drop::has_drop_glue)] - #[ra_salsa::cycle(crate::drop::has_drop_glue_recover)] - fn has_drop_glue(&self, ty: Ty, env: Arc) -> DropGlue {} + #[salsa::invoke(crate::drop::has_drop_glue)] + #[salsa::cycle(crate::drop::has_drop_glue_recover)] + fn has_drop_glue(&self, ty: Ty, env: Arc) -> DropGlue; } #[test] @@ -317,41 +325,22 @@ fn hir_database_is_dyn_compatible() { fn _assert_dyn_compatible(_: &dyn HirDatabase) {} } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedTypeOrConstParamId(ra_salsa::InternId); -impl_intern_key!(InternedTypeOrConstParamId); +impl_intern_key!(InternedTypeOrConstParamId, TypeOrConstParamId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedLifetimeParamId(ra_salsa::InternId); -impl_intern_key!(InternedLifetimeParamId); +impl_intern_key!(InternedLifetimeParamId, LifetimeParamId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedConstParamId(ra_salsa::InternId); -impl_intern_key!(InternedConstParamId); +impl_intern_key!(InternedConstParamId, ConstParamId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedOpaqueTyId(ra_salsa::InternId); -impl_intern_key!(InternedOpaqueTyId); +impl_intern_key!(InternedOpaqueTyId, ImplTraitId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedClosureId(ra_salsa::InternId); -impl_intern_key!(InternedClosureId); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct InternedClosure(pub DefWithBodyId, pub ExprId); +impl_intern_key!(InternedClosureId, InternedClosure); -impl InternValueTrivial for InternedClosure {} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedCoroutineId(ra_salsa::InternId); -impl_intern_key!(InternedCoroutineId); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct InternedCoroutine(pub DefWithBodyId, pub ExprId); -impl InternValueTrivial for InternedCoroutine {} +impl_intern_key!(InternedCoroutineId, InternedCoroutine); -/// This exists just for Chalk, because Chalk just has a single `FnDefId` where -/// we have different IDs for struct and enum variant constructors. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct InternedCallableDefId(ra_salsa::InternId); -impl_intern_key!(InternedCallableDefId); +// This exists just for Chalk, because Chalk just has a single `FnDefId` where +// we have different IDs for struct and enum variant constructors. +impl_intern_key!(InternedCallableDefId, CallableDefId); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 774991560e9ca..eed74e1eee358 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -251,7 +251,7 @@ impl<'a> DeclValidator<'a> { return; } - let (_, source_map) = self.db.body_with_source_map(func.into()); + let source_map = self.db.body_with_source_map(func.into()).1; for (id, replacement) in pats_replacements { let Ok(source_ptr) = source_map.pat_syntax(id) else { continue; @@ -597,7 +597,7 @@ impl<'a> DeclValidator<'a> { ) where N: AstNode + HasName + fmt::Debug, S: HasSource, - L: Lookup = dyn DefDatabase + 'a> + HasModule + Copy, + L: Lookup + HasModule + Copy, { let to_expected_case_type = match expected_case { CaseType::LowerSnakeCase => to_lower_snake_case, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index cc6f4d9e52eb8..975143b29f2f9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -434,7 +434,7 @@ impl ExprValidator { let last_then_expr_ty = &self.infer[last_then_expr]; if last_then_expr_ty.is_never() { // Only look at sources if the then branch diverges and we have an else branch. - let (_, source_map) = db.body_with_source_map(self.owner); + let source_map = db.body_with_source_map(self.owner).1; let Ok(source_ptr) = source_map.expr_syntax(id) else { return; }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index 351926c86c473..4ad16cf8bcf7e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -1,6 +1,5 @@ //! Utilities for computing drop info about types. -use base_db::ra_salsa; use chalk_ir::cast::Cast; use hir_def::data::adt::StructFlags; use hir_def::lang_item::LangItem; @@ -8,6 +7,7 @@ use hir_def::AdtId; use stdx::never; use triomphe::Arc; +use crate::db::HirDatabaseData; use crate::{ db::HirDatabase, method_resolution::TyFingerprint, AliasTy, Canonical, CanonicalVarKinds, InEnvironment, Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, @@ -201,9 +201,10 @@ fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc) -> bool { pub(crate) fn has_drop_glue_recover( _db: &dyn HirDatabase, - _cycle: &ra_salsa::Cycle, - _ty: &Ty, - _env: &Arc, + _cycle: &salsa::Cycle, + _: HirDatabaseData, + _ty: Ty, + _env: Arc, ) -> DropGlue { DropGlue::None } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 80e3ca1fa282e..131e98d729651 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -289,7 +289,7 @@ impl InferenceContext<'_> { expected: &Expectation, is_read: ExprIsRead, ) -> Ty { - self.db.unwind_if_cancelled(); + self.db.unwind_if_revision_cancelled(); let ty = match &self.body[tgt_expr] { Expr::Missing => self.err_ty(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs index 804c3aea3a5c9..832a00e1e5e7b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs @@ -8,7 +8,6 @@ use crate::{ ProgramClauseData, ProgramClauses, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, Substitution, Ty, TyData, TyKind, VariableKind, VariableKinds, }; -use base_db::ra_salsa::InternId; use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variance}; use hir_def::TypeAliasId; use intern::{impl_internable, Interned}; @@ -68,7 +67,7 @@ impl chalk_ir::interner::Interner for Interner { type InternedCanonicalVarKinds = Interned>>; type InternedConstraints = Vec>; type InternedVariances = SmallVec<[Variance; 16]>; - type DefId = InternId; + type DefId = salsa::Id; type InternedAdtId = hir_def::AdtId; type Identifier = TypeAliasId; type FnAbi = FnAbi; @@ -98,7 +97,7 @@ impl chalk_ir::interner::Interner for Interner { opaque_ty_id: OpaqueTyId, fmt: &mut fmt::Formatter<'_>, ) -> Option { - Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0)) + Some(write!(fmt, "OpaqueTy#{:?}", opaque_ty_id.0)) } fn debug_fn_def_id(fn_def_id: FnDefId, fmt: &mut fmt::Formatter<'_>) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index bbd419d9659bf..167dcec3bb3f8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -2,7 +2,6 @@ use std::fmt; -use base_db::ra_salsa::Cycle; use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; use hir_def::{ layout::{ @@ -14,21 +13,20 @@ use hir_def::{ use la_arena::{Idx, RawIdx}; use rustc_abi::AddressSpace; use rustc_index::IndexVec; +use salsa::Cycle; use triomphe::Arc; use crate::{ consteval::try_const_usize, - db::{HirDatabase, InternedClosure}, + db::{HirDatabase, HirDatabaseData, InternedClosure}, infer::normalize, utils::ClosureSubst, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, }; -pub use self::{ - adt::{layout_of_adt_query, layout_of_adt_recover}, - target::target_data_layout_query, -}; +pub(crate) use self::adt::layout_of_adt_recover; +pub use self::{adt::layout_of_adt_query, target::target_data_layout_query}; mod adt; mod target; @@ -367,11 +365,12 @@ pub fn layout_of_ty_query( Ok(Arc::new(result)) } -pub fn layout_of_ty_recover( +pub(crate) fn layout_of_ty_recover( _: &dyn HirDatabase, _: &Cycle, - _: &Ty, - _: &Arc, + _: HirDatabaseData, + _: Ty, + _: Arc, ) -> Result, LayoutError> { Err(LayoutError::RecursiveTypeWithoutIndirection) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index eb4729fab8426..ab9c07779c07a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -2,7 +2,6 @@ use std::{cmp, ops::Bound}; -use base_db::ra_salsa::Cycle; use hir_def::{ data::adt::VariantData, layout::{Integer, ReprOptions, TargetDataLayout}, @@ -10,6 +9,7 @@ use hir_def::{ }; use intern::sym; use rustc_index::IndexVec; +use salsa::Cycle; use smallvec::SmallVec; use triomphe::Arc; @@ -20,7 +20,7 @@ use crate::{ Substitution, TraitEnvironment, }; -use super::LayoutCx; +use super::{HirDatabaseData, LayoutCx}; pub fn layout_of_adt_query( db: &dyn HirDatabase, @@ -131,12 +131,13 @@ fn layout_scalar_valid_range(db: &dyn HirDatabase, def: AdtId) -> (Bound, ) } -pub fn layout_of_adt_recover( +pub(crate) fn layout_of_adt_recover( _: &dyn HirDatabase, _: &Cycle, - _: &AdtId, - _: &Substitution, - _: &Arc, + _: HirDatabaseData, + _: AdtId, + _: Substitution, + _: Arc, ) -> Result, LayoutError> { Err(LayoutError::RecursiveTypeWithoutIndirection) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 624767cedf822..f35298846a858 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -56,7 +56,6 @@ mod variance; use std::hash::Hash; -use base_db::ra_salsa::InternValueTrivial; use chalk_ir::{ fold::{Shift, TypeFoldable}, interner::HasInterner, @@ -610,7 +609,6 @@ pub enum ImplTraitId { TypeAliasImplTrait(hir_def::TypeAliasId, ImplTraitIdx), AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), } -impl InternValueTrivial for ImplTraitId {} #[derive(PartialEq, Eq, Debug, Hash)] pub struct ImplTraits { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index af73b5ed9a7b4..ff7f0349638cd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -14,7 +14,7 @@ use std::{ ops::{self, Not as _}, }; -use base_db::{ra_salsa::Cycle, CrateId}; +use base_db::CrateId; use chalk_ir::{ cast::Cast, fold::{Shift, TypeFoldable}, @@ -47,6 +47,7 @@ use hir_expand::{name::Name, ExpandResult}; use la_arena::{Arena, ArenaMap}; use rustc_hash::FxHashSet; use rustc_pattern_analysis::Captures; +use salsa::Cycle; use stdx::{impl_from, never}; use syntax::ast; use triomphe::{Arc, ThinArc}; @@ -57,7 +58,7 @@ use crate::{ intern_const_ref, intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic, }, - db::HirDatabase, + db::{HirDatabase, HirDatabaseData}, error_lifetime, generics::{generics, trait_self_param_idx, Generics}, lower::{ @@ -1111,10 +1112,11 @@ pub(crate) fn generic_predicates_for_param_query( pub(crate) fn generic_predicates_for_param_recover( _db: &dyn HirDatabase, - _cycle: &Cycle, - _def: &GenericDefId, - _param_id: &TypeOrConstParamId, - _assoc_name: &Option, + _cycle: &salsa::Cycle, + _: HirDatabaseData, + _def: GenericDefId, + _param_id: TypeOrConstParamId, + _assoc_name: Option, ) -> GenericPredicates { GenericPredicates(None) } @@ -1271,6 +1273,7 @@ where ); }; } + ( GenericPredicates(predicates.is_empty().not().then(|| predicates.into())), create_diagnostics(ctx.diagnostics), @@ -1414,9 +1417,9 @@ pub(crate) fn generic_defaults_with_diagnostics_query( pub(crate) fn generic_defaults_with_diagnostics_recover( db: &dyn HirDatabase, _cycle: &Cycle, - def: &GenericDefId, + def: GenericDefId, ) -> (GenericDefaults, Diagnostics) { - let generic_params = generics(db.upcast(), *def); + let generic_params = generics(db.upcast(), def); if generic_params.len() == 0 { return (GenericDefaults(None), None); } @@ -1591,6 +1594,7 @@ pub(crate) fn type_for_type_alias_with_diagnostics_query( .map(|type_ref| ctx.lower_ty(type_ref)) .unwrap_or_else(|| TyKind::Error.intern(Interner)) }; + (make_binders(db, &generics, inner), create_diagnostics(ctx.diagnostics)) } @@ -1602,7 +1606,7 @@ pub enum TyDefId { } impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum ValueTyDefId { FunctionId(FunctionId), StructId(StructId), @@ -1638,8 +1642,13 @@ pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders { } } -pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &Cycle, def: &TyDefId) -> Binders { - let generics = match *def { +pub(crate) fn ty_recover( + db: &dyn HirDatabase, + _cycle: &salsa::Cycle, + _: HirDatabaseData, + def: TyDefId, +) -> Binders { + let generics = match def { TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)), TyDefId::AdtId(it) => generics(db.upcast(), it.into()), TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()), @@ -1703,10 +1712,10 @@ pub(crate) fn const_param_ty_with_diagnostics_query( pub(crate) fn impl_self_ty_with_diagnostics_recover( db: &dyn HirDatabase, - _cycle: &Cycle, - impl_id: &ImplId, + _cycle: &salsa::Cycle, + impl_id: ImplId, ) -> (Binders, Diagnostics) { - let generics = generics(db.upcast(), (*impl_id).into()); + let generics = generics(db.upcast(), (impl_id).into()); (make_binders(db, &generics, TyKind::Error.intern(Interner)), None) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs index 2f38e8fa14c0b..cfa2a49b79c53 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs @@ -5,8 +5,11 @@ use chalk_solve::rust_ir; -use base_db::ra_salsa::{self, InternKey}; use hir_def::{LifetimeParamId, TraitId, TypeAliasId, TypeOrConstParamId}; +use salsa::{ + plumbing::{AsId, FromId}, + Id, +}; use crate::{ chalk_db, db::HirDatabase, AssocTypeId, CallableDefId, ChalkTraitId, FnDefId, ForeignDefId, @@ -30,11 +33,11 @@ impl ToChalk for hir_def::ImplId { type Chalk = chalk_db::ImplId; fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::ImplId { - chalk_ir::ImplId(self.as_intern_id()) + chalk_ir::ImplId(self.as_id()) } fn from_chalk(_db: &dyn HirDatabase, impl_id: chalk_db::ImplId) -> hir_def::ImplId { - InternKey::from_intern_id(impl_id.0) + FromId::from_id(impl_id.0.as_id()) } } @@ -56,84 +59,84 @@ impl ToChalk for TypeAliasAsValue { type Chalk = chalk_db::AssociatedTyValueId; fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::AssociatedTyValueId { - rust_ir::AssociatedTyValueId(self.0.as_intern_id()) + rust_ir::AssociatedTyValueId(self.0.as_id()) } fn from_chalk( _db: &dyn HirDatabase, assoc_ty_value_id: chalk_db::AssociatedTyValueId, ) -> TypeAliasAsValue { - TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) + TypeAliasAsValue(TypeAliasId::from_id(assoc_ty_value_id.0)) } } impl From for crate::db::InternedCallableDefId { fn from(fn_def_id: FnDefId) -> Self { - InternKey::from_intern_id(fn_def_id.0) + Self::from_id(fn_def_id.0) } } impl From for FnDefId { fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { - chalk_ir::FnDefId(callable_def_id.as_intern_id()) + chalk_ir::FnDefId(callable_def_id.as_id()) } } impl From for crate::db::InternedOpaqueTyId { fn from(id: OpaqueTyId) -> Self { - InternKey::from_intern_id(id.0) + FromId::from_id(id.0) } } impl From for OpaqueTyId { fn from(id: crate::db::InternedOpaqueTyId) -> Self { - chalk_ir::OpaqueTyId(id.as_intern_id()) + chalk_ir::OpaqueTyId(id.as_id()) } } impl From> for crate::db::InternedClosureId { fn from(id: chalk_ir::ClosureId) -> Self { - Self::from_intern_id(id.0) + FromId::from_id(id.0) } } impl From for chalk_ir::ClosureId { fn from(id: crate::db::InternedClosureId) -> Self { - chalk_ir::ClosureId(id.as_intern_id()) + chalk_ir::ClosureId(id.as_id()) } } impl From> for crate::db::InternedCoroutineId { fn from(id: chalk_ir::CoroutineId) -> Self { - Self::from_intern_id(id.0) + Self::from_id(id.0) } } impl From for chalk_ir::CoroutineId { fn from(id: crate::db::InternedCoroutineId) -> Self { - chalk_ir::CoroutineId(id.as_intern_id()) + chalk_ir::CoroutineId(id.as_id()) } } pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { - chalk_ir::ForeignDefId(ra_salsa::InternKey::as_intern_id(&id)) + chalk_ir::ForeignDefId(id.as_id()) } pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { - ra_salsa::InternKey::from_intern_id(id.0) + FromId::from_id(id.0) } pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { - chalk_ir::AssocTypeId(ra_salsa::InternKey::as_intern_id(&id)) + chalk_ir::AssocTypeId(id.as_id()) } pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { - ra_salsa::InternKey::from_intern_id(id.0) + FromId::from_id(id.0) } pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeOrConstParamId { assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); - let interned_id = ra_salsa::InternKey::from_intern_id(ra_salsa::InternId::from(idx.idx)); + let interned_id = FromId::from_id(Id::from_u32(idx.idx.try_into().unwrap())); db.lookup_intern_type_or_const_param_id(interned_id) } @@ -141,13 +144,13 @@ pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Place let interned_id = db.intern_type_or_const_param_id(id); PlaceholderIndex { ui: chalk_ir::UniverseIndex::ROOT, - idx: ra_salsa::InternKey::as_intern_id(&interned_id).as_usize(), + idx: interned_id.as_id().as_u32() as usize, } } pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId { assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); - let interned_id = ra_salsa::InternKey::from_intern_id(ra_salsa::InternId::from(idx.idx)); + let interned_id = FromId::from_id(Id::from_u32(idx.idx.try_into().unwrap())); db.lookup_intern_lifetime_param_id(interned_id) } @@ -155,14 +158,14 @@ pub fn lt_to_placeholder_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> Place let interned_id = db.intern_lifetime_param_id(id); PlaceholderIndex { ui: chalk_ir::UniverseIndex::ROOT, - idx: ra_salsa::InternKey::as_intern_id(&interned_id).as_usize(), + idx: interned_id.as_id().as_u32() as usize, } } pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { - chalk_ir::TraitId(ra_salsa::InternKey::as_intern_id(&id)) + chalk_ir::TraitId(id.as_id()) } pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { - ra_salsa::InternKey::from_intern_id(id.0) + FromId::from_id(id.0) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index db94351dcc995..c5ad808accdf4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -714,6 +714,7 @@ pub(crate) fn lookup_impl_method_query( else { return (func, fn_subst); }; + ( impl_fn, Substitution::from_iter( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index 56c431ef8dab6..ae454fbe528a5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -32,17 +32,18 @@ pub use borrowck::{borrowck_query, BorrowckResult, MutabilityReason}; pub use eval::{ interpret_mir, pad16, render_const_using_debug_impl, Evaluator, MirEvalError, VTableMap, }; -pub use lower::{ - lower_to_mir, mir_body_for_closure_query, mir_body_query, mir_body_recover, MirLowerError, -}; +pub use lower::{lower_to_mir, mir_body_for_closure_query, mir_body_query, MirLowerError}; pub use monomorphization::{ monomorphize_mir_body_bad, monomorphized_mir_body_for_closure_query, - monomorphized_mir_body_query, monomorphized_mir_body_recover, + monomorphized_mir_body_query, }; use rustc_hash::FxHashMap; use smallvec::{smallvec, SmallVec}; use stdx::{impl_from, never}; +pub(crate) use lower::mir_body_recover; +pub(crate) use monomorphization::monomorphized_mir_body_recover; + use super::consteval::{intern_const_scalar, try_const_usize}; pub type BasicBlockId = Idx; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index fbcca388e781d..fd1e724ee88ec 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -145,7 +145,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec Operand::Constant(_) | Operand::Static(_) => (), }; for (_, block) in body.basic_blocks.iter() { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); for statement in &block.statements { match &statement.kind { StatementKind::Assign(_, r) => match r { @@ -235,7 +235,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec Operand::Constant(_) | Operand::Static(_) => (), }; for (_, block) in body.basic_blocks.iter() { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); for statement in &block.statements { match &statement.kind { StatementKind::Assign(_, r) => match r { @@ -306,7 +306,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec fn borrow_regions(db: &dyn HirDatabase, body: &MirBody) -> Vec { let mut borrows = FxHashMap::default(); for (_, block) in body.basic_blocks.iter() { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); for statement in &block.statements { if let StatementKind::Assign(_, Rvalue::Ref(kind, p)) = &statement.kind { borrows @@ -477,7 +477,7 @@ fn ever_initialized_map( dfs(db, body, l, &mut stack, &mut result); } for l in body.locals.iter().map(|it| it.0) { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); if !result[body.start_block].contains_idx(l) { result[body.start_block].insert(l, false); stack.clear(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 74a34e2981710..c9d62f566c1a6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -2558,6 +2558,7 @@ impl Evaluator<'_> { } else { let (imp, generic_args) = self.db.lookup_impl_method(self.trait_env.clone(), def, generic_args.clone()); + let mir_body = self .db .monomorphized_mir_body(imp.into(), generic_args, self.trait_env.clone()) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 520717e799521..17f1da0c9f378 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -2,7 +2,7 @@ use std::{fmt::Write, iter, mem}; -use base_db::{ra_salsa::Cycle, CrateId}; +use base_db::{salsa::Cycle, CrateId}; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ data::adt::{StructKind, VariantData}, @@ -2149,10 +2149,10 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result Result> { Err(MirLowerError::Loop) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs index 92132fa047362..6d1e9a1ea1972 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs @@ -9,7 +9,6 @@ use std::mem; -use base_db::ra_salsa::Cycle; use chalk_ir::{ fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}, ConstData, DebruijnIndex, @@ -19,7 +18,7 @@ use triomphe::Arc; use crate::{ consteval::{intern_const_scalar, unknown_const}, - db::{HirDatabase, InternedClosure}, + db::{HirDatabase, HirDatabaseData, InternedClosure}, from_placeholder_idx, generics::{generics, Generics}, infer::normalize, @@ -314,12 +313,13 @@ pub fn monomorphized_mir_body_query( Ok(Arc::new(body)) } -pub fn monomorphized_mir_body_recover( +pub(crate) fn monomorphized_mir_body_recover( _: &dyn HirDatabase, - _: &Cycle, - _: &DefWithBodyId, - _: &Substitution, - _: &Arc, + _: &salsa::Cycle, + _: HirDatabaseData, + _: DefWithBodyId, + _: Substitution, + _: Arc, ) -> Result, MirLowerError> { Err(MirLowerError::Loop) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs index f37dd91d8e90f..b18a057ba0b9d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs @@ -3,34 +3,34 @@ use std::{fmt, panic, sync::Mutex}; use base_db::{ - ra_salsa::{self, Durability}, - AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, + FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, + SourceRootInput, Upcast, }; + use hir_def::{db::DefDatabase, ModuleId}; use hir_expand::db::ExpandDatabase; use rustc_hash::FxHashMap; +use salsa::{AsDynDatabase, Durability}; use span::{EditionedFileId, FileId}; use syntax::TextRange; use test_utils::extract_annotations; use triomphe::Arc; -#[ra_salsa::database( - base_db::SourceRootDatabaseStorage, - base_db::SourceDatabaseStorage, - hir_expand::db::ExpandDatabaseStorage, - hir_def::db::InternDatabaseStorage, - hir_def::db::DefDatabaseStorage, - crate::db::HirDatabaseStorage -)] +#[salsa::db] +#[derive(Clone)] pub(crate) struct TestDB { - storage: ra_salsa::Storage, - events: Mutex>>, + storage: salsa::Storage, + files: Arc, + events: Arc>>>, } impl Default for TestDB { fn default() -> Self { - let mut this = Self { storage: Default::default(), events: Default::default() }; - this.setup_syntax_context_root(); + let mut this = Self { + storage: Default::default(), + events: Default::default(), + files: Default::default(), + }; this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); this } @@ -54,35 +54,81 @@ impl Upcast for TestDB { } } -impl ra_salsa::Database for TestDB { - fn salsa_event(&self, event: ra_salsa::Event) { - let mut events = self.events.lock().unwrap(); - if let Some(events) = &mut *events { - events.push(event); - } +impl Upcast for TestDB { + fn upcast(&self) -> &(dyn RootQueryDb + 'static) { + self } } -impl ra_salsa::ParallelDatabase for TestDB { - fn snapshot(&self) -> ra_salsa::Snapshot { - ra_salsa::Snapshot::new(TestDB { - storage: self.storage.snapshot(), - events: Default::default(), - }) +impl Upcast for TestDB { + fn upcast(&self) -> &(dyn SourceDatabase + 'static) { + self } } -impl panic::RefUnwindSafe for TestDB {} +#[salsa::db] +impl SourceDatabase for TestDB { + fn file_text(&self, file_id: base_db::FileId) -> FileText { + self.files.file_text(file_id) + } -impl FileLoader for TestDB { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { - FileLoaderDelegate(self).resolve_path(path) + fn set_file_text(&mut self, file_id: base_db::FileId, text: &str) { + let files = Arc::clone(&self.files); + files.set_file_text(self, file_id, text); } - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { - FileLoaderDelegate(self).relevant_crates(file_id) + + fn set_file_text_with_durability( + &mut self, + file_id: base_db::FileId, + text: &str, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_text_with_durability(self, file_id, text, durability); + } + + /// Source root of the file. + fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput { + self.files.source_root(source_root_id) + } + + fn set_source_root_with_durability( + &mut self, + source_root_id: SourceRootId, + source_root: Arc, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_source_root_with_durability(self, source_root_id, source_root, durability); + } + + fn file_source_root(&self, id: base_db::FileId) -> FileSourceRootInput { + self.files.file_source_root(id) + } + + fn set_file_source_root_with_durability( + &mut self, + id: base_db::FileId, + source_root_id: SourceRootId, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_source_root_with_durability(self, id, source_root_id, durability); } } +#[salsa::db] +impl salsa::Database for TestDB { + fn salsa_event(&self, event: &dyn std::ops::Fn() -> salsa::Event) { + let mut events = self.events.lock().unwrap(); + if let Some(events) = &mut *events { + events.push(event()); + } + } +} + +impl panic::RefUnwindSafe for TestDB {} + impl TestDB { pub(crate) fn module_for_file_opt(&self, file_id: impl Into) -> Option { let file_id = file_id.into(); @@ -117,7 +163,7 @@ impl TestDB { .into_iter() .filter_map(|file_id| { let text = self.file_text(file_id.file_id()); - let annotations = extract_annotations(&text); + let annotations = extract_annotations(&text.text(self)); if annotations.is_empty() { return None; } @@ -128,7 +174,7 @@ impl TestDB { } impl TestDB { - pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { + pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { *self.events.lock().unwrap() = Some(Vec::new()); f(); self.events.lock().unwrap().take().unwrap() @@ -141,8 +187,11 @@ impl TestDB { .filter_map(|e| match e.kind { // This is pretty horrible, but `Debug` is the only way to inspect // QueryDescriptor at the moment. - ra_salsa::EventKind::WillExecute { database_key } => { - Some(format!("{:?}", database_key.debug(self))) + salsa::EventKind::WillExecute { database_key } => { + let ingredient = self + .as_dyn_database() + .ingredient_debug_name(database_key.ingredient_index()); + Some(ingredient.to_string()) } _ => None, }) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index 81e38be2285ab..26229040582b8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -15,7 +15,7 @@ mod type_alias_impl_traits; use std::env; use std::sync::LazyLock; -use base_db::{CrateId, SourceDatabaseFileInputExt as _}; +use base_db::{CrateId, SourceDatabase}; use expect_test::Expect; use hir_def::{ db::DefDatabase, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index 6f7bfc4ea7a00..efb1728d0561d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -1,8 +1,8 @@ -use base_db::ra_salsa::InternKey; use expect_test::{expect, Expect}; use hir_def::db::DefDatabase; use hir_expand::files::InFileWrapper; use itertools::Itertools; +use salsa::plumbing::FromId; use span::{HirFileId, TextRange}; use syntax::{AstNode, AstPtr}; use test_fixture::WithFixture; @@ -34,8 +34,8 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let infer = db.infer(def); let db = &db; captures_info.extend(infer.closure_info.iter().flat_map(|(closure_id, (captures, _))| { - let closure = db.lookup_intern_closure(InternedClosureId::from_intern_id(closure_id.0)); - let (_, source_map) = db.body_with_source_map(closure.0); + let closure = db.lookup_intern_closure(InternedClosureId::from_id(closure_id.0)); + let source_map = db.body_with_source_map(closure.0).1; let closure_text_range = source_map .expr_syntax(closure.1) .expect("failed to map closure to SyntaxNode") diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 3757d722ac83b..d54c6937bc393 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -1,4 +1,4 @@ -use base_db::SourceDatabaseFileInputExt as _; +use base_db::SourceDatabase; use hir_def::ModuleDefId; use test_fixture::WithFixture; @@ -25,7 +25,7 @@ fn foo() -> i32 { } }); }); - assert!(format!("{events:?}").contains("infer")) + assert!(format!("{events:?}").contains("infer_shim")) } let new_text = " @@ -47,7 +47,7 @@ fn foo() -> i32 { } }); }); - assert!(!format!("{events:?}").contains("infer"), "{events:#?}") + assert!(!format!("{events:?}").contains("infer_shim"), "{events:#?}") } } @@ -76,7 +76,7 @@ fn baz() -> i32 { } }); }); - assert!(format!("{events:?}").contains("infer")) + assert!(format!("{events:?}").contains("infer_shim")) } let new_text = " @@ -103,6 +103,6 @@ fn baz() -> i32 { } }); }); - assert!(format!("{events:?}").matches("infer").count() == 1, "{events:#?}") + assert!(format!("{events:?}").matches("infer_shim").count() == 1, "{events:#?}") } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 8cb7dbf60f37b..0135e0a409bbe 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -160,7 +160,7 @@ fn solve( let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL); let should_continue = || { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); let remaining = fuel.get(); fuel.set(remaining - 1); if remaining == 0 { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index 3a22158ce6f1d..425196d92f79a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -19,7 +19,7 @@ use crate::{ AliasTy, Const, ConstScalar, DynTyExt, GenericArg, GenericArgData, Interner, Lifetime, LifetimeData, Ty, TyKind, }; -use base_db::ra_salsa::Cycle; +use base_db::salsa::Cycle; use chalk_ir::Mutability; use hir_def::data::adt::StructFlags; use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId}; @@ -58,9 +58,9 @@ pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> Option Option> { - let generics = generics(db.upcast(), *def); + let generics = generics(db.upcast(), def); let count = generics.len(); if count == 0 { diff --git a/src/tools/rust-analyzer/crates/hir/src/db.rs b/src/tools/rust-analyzer/crates/hir/src/db.rs index 22760c41aaecf..9e8e87ecff001 100644 --- a/src/tools/rust-analyzer/crates/hir/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir/src/db.rs @@ -3,44 +3,43 @@ //! we didn't do that. //! //! But we need this for at least LRU caching at the query level. -pub use hir_def::db::{ - AttrsQuery, BlockDefMapQuery, BlockItemTreeQuery, BlockItemTreeWithSourceMapQuery, BodyQuery, - BodyWithSourceMapQuery, ConstDataQuery, ConstVisibilityQuery, CrateDefMapQuery, - CrateLangItemsQuery, CrateNotableTraitsQuery, CrateSupportsNoStdQuery, DefDatabase, - DefDatabaseStorage, EnumDataQuery, EnumVariantDataWithDiagnosticsQuery, - ExpandProcAttrMacrosQuery, ExprScopesQuery, ExternCrateDeclDataQuery, FieldVisibilitiesQuery, - FieldsAttrsQuery, FieldsAttrsSourceMapQuery, FileItemTreeQuery, FileItemTreeWithSourceMapQuery, - FunctionDataQuery, FunctionVisibilityQuery, GenericParamsQuery, - GenericParamsWithSourceMapQuery, ImplDataWithDiagnosticsQuery, ImportMapQuery, - IncludeMacroInvocQuery, InternAnonymousConstQuery, InternBlockQuery, InternConstQuery, - InternDatabase, InternDatabaseStorage, InternEnumQuery, InternExternBlockQuery, - InternExternCrateQuery, InternFunctionQuery, InternImplQuery, InternInTypeConstQuery, - InternMacro2Query, InternMacroRulesQuery, InternProcMacroQuery, InternStaticQuery, - InternStructQuery, InternTraitAliasQuery, InternTraitQuery, InternTypeAliasQuery, - InternUnionQuery, InternUseQuery, LangItemQuery, Macro2DataQuery, MacroDefQuery, - MacroRulesDataQuery, NotableTraitsInDepsQuery, ProcMacroDataQuery, StaticDataQuery, - StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitDataWithDiagnosticsQuery, - TypeAliasDataQuery, UnionDataWithDiagnosticsQuery, -}; -pub use hir_expand::db::{ - AstIdMapQuery, DeclMacroExpanderQuery, ExpandDatabase, ExpandDatabaseStorage, - ExpandProcMacroQuery, InternMacroCallQuery, InternSyntaxContextQuery, MacroArgQuery, - ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery, ProcMacroSpanQuery, ProcMacrosQuery, - RealSpanMapQuery, -}; -pub use hir_ty::db::{ - AdtDatumQuery, AdtVarianceQuery, AssociatedTyDataQuery, AssociatedTyValueQuery, BorrowckQuery, - CallableItemSignatureQuery, ConstEvalDiscriminantQuery, ConstEvalQuery, ConstEvalStaticQuery, - ConstParamTyQuery, DynCompatibilityOfTraitQuery, FieldTypesQuery, FnDefDatumQuery, - FnDefVarianceQuery, GenericDefaultsQuery, GenericPredicatesForParamQuery, - GenericPredicatesQuery, GenericPredicatesWithoutParentQuery, HirDatabase, HirDatabaseStorage, - ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, IncoherentInherentImplCratesQuery, InferQuery, - InherentImplsInBlockQuery, InherentImplsInCrateQuery, InternCallableDefQuery, - InternClosureQuery, InternCoroutineQuery, InternImplTraitIdQuery, InternLifetimeParamIdQuery, - InternTypeOrConstParamIdQuery, LayoutOfAdtQuery, LayoutOfTyQuery, LookupImplMethodQuery, - MirBodyForClosureQuery, MirBodyQuery, MonomorphizedMirBodyForClosureQuery, - MonomorphizedMirBodyQuery, ProgramClausesForChalkEnvQuery, ReturnTypeImplTraitsQuery, - TargetDataLayoutQuery, TraitDatumQuery, TraitEnvironmentQuery, TraitImplsInBlockQuery, - TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery, - TypeAliasImplTraitsQuery, ValueTyQuery, -}; +pub use hir_def::db::DefDatabase; +// AttrsQuery, BlockDefMapQuery, BlockItemTreeQuery, BlockItemTreeWithSourceMapQuery, BodyQuery, +// BodyWithSourceMapQuery, ConstDataQuery, ConstVisibilityQuery, CrateDefMapQuery, +// CrateLangItemsQuery, CrateNotableTraitsQuery, CrateSupportsNoStdQuery, DefDatabase, +// DefDatabaseStorage, EnumDataQuery, EnumVariantDataWithDiagnosticsQuery, +// ExpandProcAttrMacrosQuery, ExprScopesQuery, ExternCrateDeclDataQuery, FieldVisibilitiesQuery, +// FieldsAttrsQuery, FieldsAttrsSourceMapQuery, FileItemTreeQuery, FileItemTreeWithSourceMapQuery, +// FunctionDataQuery, FunctionVisibilityQuery, GenericParamsQuery, +// GenericParamsWithSourceMapQuery, ImplDataWithDiagnosticsQuery, ImportMapQuery, +// IncludeMacroInvocQuery, InternAnonymousConstQuery, InternBlockQuery, InternConstQuery, +// InternDatabase, InternDatabaseStorage, InternEnumQuery, InternExternBlockQuery, +// InternExternCrateQuery, InternFunctionQuery, InternImplQuery, InternInTypeConstQuery, +// InternMacro2Query, InternMacroRulesQuery, InternProcMacroQuery, InternStaticQuery, +// InternStructQuery, InternTraitAliasQuery, InternTraitQuery, InternTypeAliasQuery, +// InternUnionQuery, InternUseQuery, LangItemQuery, Macro2DataQuery, MacroDefQuery, +// MacroRulesDataQuery, NotableTraitsInDepsQuery, ProcMacroDataQuery, StaticDataQuery, +// StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitDataWithDiagnosticsQuery, +// TypeAliasDataQuery, UnionDataWithDiagnosticsQuery, +// }; +pub use hir_expand::db::ExpandDatabase; +// AstIdMapQuery, DeclMacroExpanderQuery, ExpandDatabase, ExpandDatabaseStorage, +// ExpandProcMacroQuery, InternMacroCallQuery, InternSyntaxContextQuery, MacroArgQuery, +// ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery, ProcMacroSpanQuery, ProcMacrosQuery, +// RealSpanMapQuery, +pub use hir_ty::db::HirDatabase; +// AdtDatumQuery, AdtVarianceQuery, AssociatedTyDataQuery, AssociatedTyValueQuery, BorrowckQuery, +// CallableItemSignatureQuery, ConstEvalDiscriminantQuery, ConstEvalQuery, ConstEvalStaticQuery, +// ConstParamTyQuery, DynCompatibilityOfTraitQuery, FieldTypesQuery, FnDefDatumQuery, +// FnDefVarianceQuery, GenericDefaultsQuery, GenericPredicatesForParamQuery, +// GenericPredicatesQuery, GenericPredicatesWithoutParentQuery, HirDatabase, HirDatabaseStorage, +// ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, IncoherentInherentImplCratesQuery, InferQuery, +// InherentImplsInBlockQuery, InherentImplsInCrateQuery, InternCallableDefQuery, +// InternClosureQuery, InternCoroutineQuery, InternImplTraitIdQuery, InternLifetimeParamIdQuery, +// InternTypeOrConstParamIdQuery, LayoutOfAdtQuery, LayoutOfTyQuery, LookupImplMethodQuery, +// MirBodyForClosureQuery, MirBodyQuery, MonomorphizedMirBodyForClosureQuery, +// MonomorphizedMirBodyQuery, ProgramClausesForChalkEnvQuery, ReturnTypeImplTraitsQuery, +// TargetDataLayoutQuery, TraitDatumQuery, TraitEnvironmentQuery, TraitImplsInBlockQuery, +// TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery, +// TypeAliasImplTraitsQuery, ValueTyQuery, +// }; diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index 372c725293441..b4468178fbede 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs @@ -306,7 +306,7 @@ impl HasSource for ExternCrateDecl { impl HasSource for InlineAsmOperand { type Ast = ast::AsmOperandNamed; fn source(self, db: &dyn HirDatabase) -> Option> { - let (_body, source_map) = db.body_with_source_map(self.owner); + let source_map = db.body_with_source_map(self.owner).1; if let Ok(src) = source_map.expr_syntax(self.expr) { let root = src.file_syntax(db.upcast()); return src diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index a8075509474ab..dbe743e7e2f85 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -662,6 +662,7 @@ impl Module { db.field_types_with_diagnostics(s.id.into()).1, tree_source_maps.strukt(tree_id.value).item(), ); + for diag in db.struct_data_with_diagnostics(s.id).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } @@ -675,6 +676,7 @@ impl Module { db.field_types_with_diagnostics(u.id.into()).1, tree_source_maps.union(tree_id.value).item(), ); + for diag in db.union_data_with_diagnostics(u.id).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } @@ -1906,6 +1908,7 @@ impl DefWithBody { let krate = self.module(db).id.krate(); let (body, source_map) = db.body_with_source_map(self.into()); + let item_tree_source_maps; let outer_types_source_map = match self { DefWithBody::Function(function) => { @@ -1955,7 +1958,7 @@ impl DefWithBody { None }; MacroError { - node: (*node).map(|it| it.into()), + node: (node).map(|it| it.into()), precise_location, message, error, @@ -3346,7 +3349,7 @@ fn as_assoc_item<'db, ID, DEF, LOC>( id: ID, ) -> Option where - ID: Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, + ID: Lookup>, DEF: From, LOC: ItemTreeNode, { @@ -3362,7 +3365,7 @@ fn as_extern_assoc_item<'db, ID, DEF, LOC>( id: ID, ) -> Option where - ID: Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, + ID: Lookup>, DEF: From, LOC: ItemTreeNode, { @@ -4656,6 +4659,7 @@ pub struct CaptureUsages { impl CaptureUsages { pub fn sources(&self, db: &dyn HirDatabase) -> Vec { let (body, source_map) = db.body_with_source_map(self.parent); + let mut result = Vec::with_capacity(self.spans.len()); for &span in self.spans.iter() { let is_ref = span.is_ref_span(&body); diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 5e2eebcd13c69..aeeb3f9790986 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -307,9 +307,10 @@ impl<'db> SemanticsImpl<'db> { SemanticsImpl { db, s2d_cache: Default::default(), macro_call_cache: Default::default() } } - pub fn parse(&self, file_id: EditionedFileId) -> ast::SourceFile { + pub fn parse(&self, file_id: base_db::EditionedFileId) -> ast::SourceFile { + let hir_file_id = file_id.editioned_file_id(self.db).into(); let tree = self.db.parse(file_id).tree(); - self.cache(tree.syntax().clone(), file_id.into()); + self.cache(tree.syntax().clone(), hir_file_id); tree } @@ -329,11 +330,14 @@ impl<'db> SemanticsImpl<'db> { } pub fn parse_guess_edition(&self, file_id: FileId) -> ast::SourceFile { - let file_id = self + let editioned_file_id = self .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); + + let file_id = base_db::EditionedFileId::new(self.db, editioned_file_id); + let tree = self.db.parse(file_id).tree(); - self.cache(tree.syntax().clone(), file_id.into()); + self.cache(tree.syntax().clone(), editioned_file_id.into()); tree } @@ -1903,7 +1907,9 @@ fn macro_call_to_macro_id( match loc.def.ast_id() { Either::Left(it) => { let node = match it.file_id.repr() { - HirFileIdRepr::FileId(file_id) => { + HirFileIdRepr::FileId(editioned_file_id) => { + let file_id = base_db::EditionedFileId::new(db, editioned_file_id); + it.to_ptr(db).to_node(&db.parse(file_id).syntax_node()) } HirFileIdRepr::MacroFile(macro_file) => { @@ -1915,7 +1921,9 @@ fn macro_call_to_macro_id( } Either::Right(it) => { let node = match it.file_id.repr() { - HirFileIdRepr::FileId(file_id) => { + HirFileIdRepr::FileId(editioned_file_id) => { + let file_id = base_db::EditionedFileId::new(db, editioned_file_id); + it.to_ptr(db).to_node(&db.parse(file_id).syntax_node()) } HirFileIdRepr::MacroFile(macro_file) => { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index d0fdf5cbdf7a3..da9bb8b15c8c0 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -254,7 +254,7 @@ fn insert_item_loc( id: ID, key: Key, ) where - ID: for<'db> Lookup = dyn DefDatabase + 'db, Data = Data> + 'static, + ID: Lookup + 'static, Data: ItemTreeLoc, N: ItemTreeNode, N::Source: 'static, diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 18cbaa15aeaed..4ec0739656076 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -85,6 +85,7 @@ //! active crate for a given position, and then provide an API to resolve all //! syntax nodes against this specific crate. +use base_db::{RootQueryDb, Upcast}; use either::Either; use hir_def::{ dyn_map::{ @@ -99,11 +100,11 @@ use hir_def::{ }; use hir_expand::{ attrs::AttrId, name::AsName, ExpansionInfo, HirFileId, HirFileIdExt, InMacroFile, MacroCallId, - MacroFileIdExt, + MacroFileId, MacroFileIdExt, }; use rustc_hash::FxHashMap; use smallvec::SmallVec; -use span::{EditionedFileId, FileId, MacroFileId}; +use span::{EditionedFileId, FileId}; use stdx::impl_from; use syntax::{ ast::{self, HasName}, @@ -142,7 +143,7 @@ impl SourceToDefCache { return m; } self.included_file_cache.insert(file, None); - for &crate_id in db.relevant_crates(file.into()).iter() { + for &crate_id in Upcast::::upcast(db).relevant_crates(file.into()).iter() { db.include_macro_invoc(crate_id).iter().for_each(|&(macro_call_id, file_id)| { self.included_file_cache.insert(file_id, Some(MacroFileId { macro_call_id })); }); @@ -176,7 +177,9 @@ impl SourceToDefCtx<'_, '_> { let _p = tracing::info_span!("SourceToDefCtx::file_to_def").entered(); self.cache.file_to_def_cache.entry(file).or_insert_with(|| { let mut mods = SmallVec::new(); - for &crate_id in self.db.relevant_crates(file).iter() { + + for &crate_id in Upcast::::upcast(self.db).relevant_crates(file).iter() + { // Note: `mod` declarations in block modules cannot be supported here let crate_def_map = self.db.crate_def_map(crate_id); let n_mods = mods.len(); @@ -344,7 +347,7 @@ impl SourceToDefCtx<'_, '_> { }) .position(|it| it == *src.value)?; let container = self.find_pat_or_label_container(src.syntax_ref())?; - let (_, source_map) = self.db.body_with_source_map(container); + let source_map = self.db.body_with_source_map(container).1; let expr = source_map.node_expr(src.with_value(&ast::Expr::AsmExpr(asm)))?.as_expr()?; Some(InlineAsmOperand { owner: container, expr, index }) } @@ -377,7 +380,8 @@ impl SourceToDefCtx<'_, '_> { src: InFile<&ast::Label>, ) -> Option<(DefWithBodyId, LabelId)> { let container = self.find_pat_or_label_container(src.syntax_ref())?; - let (_body, source_map) = self.db.body_with_source_map(container); + let source_map = self.db.body_with_source_map(container).1; + let label_id = source_map.node_label(src)?; Some((container, label_id)) } diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index d1245f5f7d681..aa0eac9478a22 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -1635,8 +1635,7 @@ pub(crate) fn name_hygiene(db: &dyn HirDatabase, name: InFile<&SyntaxNode>) -> H }; let span_map = db.expansion_span_map(macro_file); let ctx = span_map.span_at(name.value.text_range().start()).ctx; - let ctx = db.lookup_intern_syntax_context(ctx); - HygieneId::new(ctx.opaque_and_semitransparent) + HygieneId::new(ctx.opaque_and_semitransparent(db)) } fn type_of_expr_including_adjust(infer: &InferenceResult, id: ExprId) -> Option<&Ty> { diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 81eb6a70ad73e..fa8153ad2162d 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -111,7 +111,7 @@ impl<'a> SymbolCollector<'a> { fn do_work(&mut self, work: SymbolCollectorWork) { let _p = tracing::info_span!("SymbolCollector::do_work", ?work).entered(); tracing::info!(?work, "SymbolCollector::do_work"); - self.db.unwind_if_cancelled(); + self.db.unwind_if_revision_cancelled(); let parent_name = work.parent.map(|name| name.as_str().to_smolstr()); self.with_container_name(parent_name, |s| s.collect_from_module(work.module_id)); @@ -346,9 +346,9 @@ impl<'a> SymbolCollector<'a> { } } - fn push_decl<'db, L>(&mut self, id: L, name: &Name, is_assoc: bool) + fn push_decl(&mut self, id: L, name: &Name, is_assoc: bool) where - L: Lookup = dyn DefDatabase + 'db> + Into, + L: Lookup + Into, ::Data: HasSource, <::Data as HasSource>::Value: HasName, { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs index b1189f0d0b06e..c4e98c0742358 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs @@ -1,6 +1,7 @@ //! See [`AssistContext`]. use hir::{FileRange, Semantics}; +use ide_db::base_db::salsa::AsDynDatabase; use ide_db::EditionedFileId; use ide_db::{label::Label, FileId, RootDatabase}; use syntax::Edition; @@ -64,7 +65,10 @@ impl<'a> AssistContext<'a> { config: &'a AssistConfig, frange: FileRange, ) -> AssistContext<'a> { - let source_file = sema.parse(frange.file_id); + let editioned_file_id = + ide_db::base_db::EditionedFileId::new(sema.db.as_dyn_database(), frange.file_id); + + let source_file = sema.parse(editioned_file_id); let start = frange.range.start(); let end = frange.range.end(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 37f5f44dfa020..fee7662a78494 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -2,6 +2,7 @@ use std::iter::{self, Peekable}; use either::Either; use hir::{sym, Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics}; +use ide_db::base_db::salsa::AsDynDatabase; use ide_db::syntax_helpers::suggest_name; use ide_db::RootDatabase; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; @@ -256,7 +257,12 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) // Just replace the element that the original range came from let old_place = { // Find the original element - let file = ctx.sema.parse(arm_list_range.file_id); + let editioned_file_id = ide_db::base_db::EditionedFileId::new( + ctx.sema.db.as_dyn_database(), + arm_list_range.file_id, + ); + + let file = ctx.sema.parse(editioned_file_id); let old_place = file.syntax().covering_element(arm_list_range.range); match old_place { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs index 7716e99e604b3..9cb14e8d9a007 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs @@ -1136,7 +1136,7 @@ fn foo() { } //- /main.rs -use foo::Foo; +use foo::{Bool, Foo}; mod foo; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs index d34cf895cd90a..54826f03884f3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs @@ -590,7 +590,7 @@ fn handle_call( let indent = if insert_newlines { first_arg_indent.unwrap().to_string() } else { String::new() }; // FIXME: This text manipulation seems risky. - let text = ctx.db().file_text(file_id.file_id()); + let text = ctx.db().file_text(file_id.file_id()).text(ctx.db()); let mut text = text[..u32::from(range.end()).try_into().unwrap()].trim_end(); if !text.ends_with(')') { return None; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs index 6e3be0ce69279..b94422b13c1bc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs @@ -2,6 +2,7 @@ use std::iter; use either::Either; use hir::{HasSource, HirFileIdExt, ModuleSource}; +use ide_db::base_db::salsa::AsDynDatabase; use ide_db::{ assists::{AssistId, AssistKind}, defs::{Definition, NameClass, NameRefClass}, @@ -331,7 +332,10 @@ impl Module { let mut use_stmts_set = FxHashSet::default(); for (file_id, refs) in node_def.usages(&ctx.sema).all() { - let source_file = ctx.sema.parse(file_id); + let editioned_file_id = + ide_db::base_db::EditionedFileId::new(ctx.sema.db.as_dyn_database(), file_id); + + let source_file = ctx.sema.parse(editioned_file_id); let usages = refs.into_iter().filter_map(|FileReference { range, .. }| { // handle normal usages let name_ref = find_node_at_range::(source_file.syntax(), range)?; @@ -457,7 +461,11 @@ impl Module { let selection_range = ctx.selection_trimmed(); let file_id = ctx.file_id(); let usage_res = def.usages(&ctx.sema).in_scope(&SearchScope::single_file(file_id)).all(); - let file = ctx.sema.parse(file_id); + + let editioned_file_id = + ide_db::base_db::EditionedFileId::new(ctx.sema.db.as_dyn_database(), file_id); + + let file = ctx.sema.parse(editioned_file_id); // track uses which does not exists in `Use` let mut uses_exist_in_sel = false; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 7af2a2e1e6a33..29bd8cf0d1a65 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -2,6 +2,7 @@ use hir::{ Adt, AsAssocItem, HasSource, HirDisplay, HirFileIdExt, Module, PathResolution, Semantics, StructKind, Type, TypeInfo, }; +use ide_db::base_db::salsa::AsDynDatabase; use ide_db::{ defs::{Definition, NameRefClass}, famous_defs::FamousDefs, @@ -205,7 +206,11 @@ fn get_adt_source( fn_name: &str, ) -> Option<(Option, FileId)> { let range = adt.source(ctx.sema.db)?.syntax().original_file_range_rooted(ctx.sema.db); - let file = ctx.sema.parse(range.file_id); + + let editioned_file_id = + ide_db::base_db::EditionedFileId::new(ctx.sema.db.as_dyn_database(), range.file_id); + + let file = ctx.sema.parse(editioned_file_id); let adt_source = ctx.sema.find_node_at_offset_with_macros(file.syntax(), range.range.start())?; find_struct_impl(ctx, &adt_source, &[fn_name.to_owned()]) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs index 5ddb17b20729a..2d7722a654e8e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs @@ -1,4 +1,6 @@ -use ide_db::{defs::Definition, search::FileReference, EditionedFileId}; +use ide_db::{ + base_db::salsa::AsDynDatabase, defs::Definition, search::FileReference, EditionedFileId, +}; use syntax::{ algo::{find_node_at_range, least_common_ancestor_element}, ast::{self, HasArgList}, @@ -102,7 +104,11 @@ fn process_usages( arg_to_remove: usize, is_self_present: bool, ) { - let source_file = ctx.sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(ctx.sema.db.as_dyn_database(), file_id); + + let source_file = ctx.sema.parse(editioned_file_id_wrapper); + builder.edit_file(file_id); let possible_ranges = references .into_iter() .filter_map(|usage| process_usage(&source_file, usage, arg_to_remove, is_self_present)); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index b4042abf5d649..4f751b68e7f0b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -3,7 +3,7 @@ mod generated; use expect_test::expect; use hir::{FileRange, Semantics}; use ide_db::{ - base_db::{SourceDatabase, SourceRootDatabase}, + base_db::SourceDatabase, imports::insert_use::{ImportGranularity, InsertUseConfig}, source_change::FileSystemEdit, EditionedFileId, RootDatabase, SnippetCap, @@ -222,7 +222,7 @@ pub(crate) fn check_assist_unresolved( fn check_doc_test(assist_id: &str, before: &str, after: &str) { let after = trim_indent(after); let (db, file_id, selection) = RootDatabase::with_range_or_offset(before); - let before = db.file_text(file_id.file_id()).to_string(); + let before = db.file_text(file_id.file_id()).text(&db).to_string(); let frange = FileRange { file_id, range: selection.into() }; let assist = assists(&db, &TEST_CONFIG, AssistResolveStrategy::All, frange.into()) @@ -281,7 +281,7 @@ fn check_with_config( ) { let (mut db, file_with_caret_id, range_or_offset) = RootDatabase::with_range_or_offset(before); db.enable_proc_attr_macros(); - let text_without_caret = db.file_text(file_with_caret_id.into()).to_string(); + let text_without_caret = db.file_text(file_with_caret_id.into()).text(&db).to_string(); let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; @@ -311,14 +311,14 @@ fn check_with_config( let mut buf = String::new(); for (file_id, (edit, snippet_edit)) in source_change.source_file_edits { - let mut text = db.file_text(file_id).as_ref().to_owned(); + let mut text = db.file_text(file_id).text(&db).as_ref().to_owned(); edit.apply(&mut text); if let Some(snippet_edit) = snippet_edit { snippet_edit.apply(&mut text); } if !skip_header { - let sr = db.file_source_root(file_id); - let sr = db.source_root(sr); + let source_root_id = db.file_source_root(file_id).source_root_id(&db); + let sr = db.source_root(source_root_id).source_root(&db); let path = sr.path_for_file(&file_id).unwrap(); format_to!(buf, "//- {}\n", path) } @@ -329,15 +329,16 @@ fn check_with_config( let (dst, contents) = match file_system_edit { FileSystemEdit::CreateFile { dst, initial_contents } => (dst, initial_contents), FileSystemEdit::MoveFile { src, dst } => { - (dst, db.file_text(src).as_ref().to_owned()) + (dst, db.file_text(src).text(&db).as_ref().to_owned()) } FileSystemEdit::MoveDir { src, src_id, dst } => { // temporary placeholder for MoveDir since we are not using MoveDir in ide assists yet. (dst, format!("{src_id:?}\n{src:?}")) } }; - let sr = db.file_source_root(dst.anchor); - let sr = db.source_root(sr); + + let source_root_id = db.file_source_root(dst.anchor).source_root_id(&db); + let sr = db.source_root(source_root_id).source_root(&db); let mut base = sr.path_for_file(&dst.anchor).unwrap().clone(); base.pop(); let created_file_path = base.join(&dst.path).unwrap(); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs index cca6a22f290d2..fad7c92d8aecb 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs @@ -4,7 +4,7 @@ use std::iter; use hir::{HirFileIdExt, Module}; use ide_db::{ - base_db::{SourceRootDatabase, VfsPath}, + base_db::{SourceDatabase, VfsPath}, FxHashSet, RootDatabase, SymbolKind, }; use syntax::{ast, AstNode, SyntaxKind}; @@ -43,7 +43,10 @@ pub(crate) fn complete_mod( let module_definition_file = current_module.definition_source_file_id(ctx.db).original_file(ctx.db); - let source_root = ctx.db.source_root(ctx.db.file_source_root(module_definition_file.file_id())); + let source_root_id = + ctx.db.file_source_root(module_definition_file.file_id()).source_root_id(ctx.db); + let source_root = ctx.db.source_root(source_root_id).source_root(ctx.db); + let directory_to_look_for_submodules = directory_to_look_for_submodules( current_module, ctx.db, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs index 28e2853096e0e..611f8a2873d7b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs @@ -277,7 +277,7 @@ fn get_receiver_text( range.range = TextRange::at(range.range.start(), range.range.len() - TextSize::of('.')) } let file_text = sema.db.file_text(range.file_id.file_id()); - let mut text = file_text[range.range].to_owned(); + let mut text = file_text.text(sema.db)[range.range].to_owned(); // The receiver texts should be interpreted as-is, as they are expected to be // normal Rust expressions. diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index e686a29309461..54620bbad1bce 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -6,13 +6,14 @@ mod tests; use std::{iter, ops::ControlFlow}; +use base_db::{salsa::AsDynDatabase, RootQueryDb as _}; use hir::{ DisplayTarget, HasAttrs, Local, ModPath, ModuleDef, ModuleSource, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Symbol, Type, TypeInfo, }; use ide_db::{ - base_db::SourceDatabase, famous_defs::FamousDefs, helpers::is_editable_crate, FilePosition, - FxHashMap, FxHashSet, RootDatabase, + famous_defs::FamousDefs, helpers::is_editable_crate, FilePosition, FxHashMap, FxHashSet, + RootDatabase, }; use syntax::{ ast::{self, AttrKind, NameOrNameRef}, @@ -706,15 +707,19 @@ impl<'a> CompletionContext<'a> { let _p = tracing::info_span!("CompletionContext::new").entered(); let sema = Semantics::new(db); - let file_id = sema.attach_first_edition(file_id)?; - let original_file = sema.parse(file_id); + let editioned_file_id = sema.attach_first_edition(file_id)?; + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(sema.db.as_dyn_database(), editioned_file_id); + + let original_file = sema.parse(editioned_file_id_wrapper); // Insert a fake ident to get a valid parse tree. We will use this file // to determine context, though the original_file will be used for // actual completion. let file_with_fake_ident = { - let parse = db.parse(file_id); - parse.reparse(TextRange::empty(offset), COMPLETION_MARKER, file_id.edition()).tree() + let (_, edition) = editioned_file_id.unpack(); + let parse = db.parse(editioned_file_id_wrapper); + parse.reparse(TextRange::empty(offset), COMPLETION_MARKER, edition).tree() }; // always pick the token to the immediate left of the cursor, as that is what we are actually diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index a990b39481a19..c9fc5ae152400 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -11,6 +11,7 @@ mod snippet; mod tests; use ide_db::{ + base_db::salsa::AsDynDatabase, imports::insert_use::{self, ImportScope}, syntax_helpers::tree_diff::diff, text_edit::TextEdit, @@ -275,7 +276,11 @@ pub fn resolve_completion_edits( let _p = tracing::info_span!("resolve_completion_edits").entered(); let sema = hir::Semantics::new(db); - let original_file = sema.parse(sema.attach_first_edition(file_id)?); + let editioned_file_id = sema.attach_first_edition(file_id)?; + let editioned_file_id = + ide_db::base_db::EditionedFileId::new(db.as_dyn_database(), editioned_file_id); + + let original_file = sema.parse(editioned_file_id); let original_token = syntax::AstNode::syntax(&original_file).token_at_offset(offset).left_biased()?; let position_for_import = &original_token.parent()?; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 0735be38cd9c8..0f0fa115af0b3 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -2042,8 +2042,8 @@ fn f() { A { bar: b$0 }; } expect![[r#" fn bar() fn() -> u8 [type+name] fn baz() fn() -> u8 [type] - ex bar() [type] ex baz() [type] + ex bar() [type] st A A [] fn f() fn() [] "#]], diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs index 9d91f95eb65b8..2984348a3278d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs @@ -246,7 +246,7 @@ pub(crate) fn check_edit_with_config( .filter(|it| it.lookup() == what) .collect_tuple() .unwrap_or_else(|| panic!("can't find {what:?} completion in {completions:#?}")); - let mut actual = db.file_text(position.file_id).to_string(); + let mut actual = db.file_text(position.file_id).text(&db).to_string(); let mut combined_edit = completion.text_edit.clone(); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs index 9ab66243b5c8c..823cc8c3d8c55 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs @@ -7,7 +7,7 @@ use crate::tests::{completion_list_with_config_raw, position, TEST_CONFIG}; fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let completions = completion_list_with_config_raw(TEST_CONFIG, ra_fixture, true, None); let (db, position) = position(ra_fixture); - let mut actual = db.file_text(position.file_id).to_string(); + let mut actual = db.file_text(position.file_id).text(&db).to_string(); completions .into_iter() .exactly_one() diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml index 641998c3dacaf..848556523387e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml @@ -15,6 +15,7 @@ rust-version.workspace = true cov-mark = "2.0.0-pre.1" crossbeam-channel.workspace = true tracing.workspace = true +dashmap.workspace = true rayon.workspace = true fst = { version = "0.4.7", default-features = false } rustc-hash.workspace = true @@ -23,6 +24,8 @@ itertools.workspace = true arrayvec.workspace = true indexmap.workspace = true memchr = "2.6.4" +salsa.workspace = true +query-group.workspace = true triomphe.workspace = true nohash-hasher.workspace = true bitflags.workspace = true @@ -34,6 +37,7 @@ profile.workspace = true stdx.workspace = true syntax.workspace = true span.workspace = true +vfs.workspace = true # ide should depend only on the top-level `hir` package. if you need # something from some `hir-xxx` subpackage, reexport the API via `hir`. hir.workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs index 46ff4fbf9e904..d8b265678278b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs @@ -1,14 +1,9 @@ //! Applies changes to the IDE state transactionally. -use base_db::{ - ra_salsa::{ - debug::{DebugQueryTable, TableEntry}, - Database, Durability, Query, QueryTable, - }, - SourceRootId, -}; -use profile::{memory_usage, Bytes}; +use base_db::SourceRootId; +use profile::Bytes; use rustc_hash::FxHashSet; +use salsa::{Database as _, Durability}; use triomphe::Arc; use crate::{symbol_index::SymbolsDatabase, ChangeWithProcMacros, RootDatabase}; @@ -52,23 +47,23 @@ impl RootDatabase { pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes, usize)> { let mut acc: Vec<(String, Bytes, usize)> = vec![]; - fn collect_query_count<'q, Q>(table: &QueryTable<'q, Q>) -> usize - where - QueryTable<'q, Q>: DebugQueryTable, - Q: Query, - ::Storage: 'q, - { - struct EntryCounter(usize); - impl FromIterator> for EntryCounter { - fn from_iter(iter: T) -> EntryCounter - where - T: IntoIterator>, - { - EntryCounter(iter.into_iter().count()) - } - } - table.entries::().0 - } + // fn collect_query_count<'q, Q>(table: &QueryTable<'q, Q>) -> usize + // where + // QueryTable<'q, Q>: DebugQueryTable, + // Q: Query, + // ::Storage: 'q, + // { + // struct EntryCounter(usize); + // impl FromIterator> for EntryCounter { + // fn from_iter(iter: T) -> EntryCounter + // where + // T: IntoIterator>, + // { + // EntryCounter(iter.into_iter().count()) + // } + // } + // table.entries::().0 + // } macro_rules! purge_each_query { ($($q:path)*) => {$( @@ -83,170 +78,170 @@ impl RootDatabase { )*} } purge_each_query![ - // SymbolsDatabase - crate::symbol_index::ModuleSymbolsQuery - crate::symbol_index::LibrarySymbolsQuery - crate::symbol_index::LocalRootsQuery - crate::symbol_index::LibraryRootsQuery - // HirDatabase - hir::db::AdtDatumQuery - hir::db::AdtVarianceQuery - hir::db::AssociatedTyDataQuery - hir::db::AssociatedTyValueQuery - hir::db::BorrowckQuery - hir::db::CallableItemSignatureQuery - hir::db::ConstEvalDiscriminantQuery - hir::db::ConstEvalQuery - hir::db::ConstEvalStaticQuery - hir::db::ConstParamTyQuery - hir::db::DynCompatibilityOfTraitQuery - hir::db::FieldTypesQuery - hir::db::FnDefDatumQuery - hir::db::FnDefVarianceQuery - hir::db::GenericDefaultsQuery - hir::db::GenericPredicatesForParamQuery - hir::db::GenericPredicatesQuery - hir::db::GenericPredicatesWithoutParentQuery - hir::db::ImplDatumQuery - hir::db::ImplSelfTyQuery - hir::db::ImplTraitQuery - hir::db::IncoherentInherentImplCratesQuery - hir::db::InferQuery - hir::db::InherentImplsInBlockQuery - hir::db::InherentImplsInCrateQuery - hir::db::InternCallableDefQuery - hir::db::InternClosureQuery - hir::db::InternCoroutineQuery - hir::db::InternImplTraitIdQuery - hir::db::InternLifetimeParamIdQuery - hir::db::InternTypeOrConstParamIdQuery - hir::db::LayoutOfAdtQuery - hir::db::LayoutOfTyQuery - hir::db::LookupImplMethodQuery - hir::db::MirBodyForClosureQuery - hir::db::MirBodyQuery - hir::db::MonomorphizedMirBodyForClosureQuery - hir::db::MonomorphizedMirBodyQuery - hir::db::ProgramClausesForChalkEnvQuery - hir::db::ReturnTypeImplTraitsQuery - hir::db::TargetDataLayoutQuery - hir::db::TraitDatumQuery - hir::db::TraitEnvironmentQuery - hir::db::TraitImplsInBlockQuery - hir::db::TraitImplsInCrateQuery - hir::db::TraitImplsInDepsQuery - hir::db::TraitSolveQuery - hir::db::TyQuery - hir::db::TypeAliasImplTraitsQuery - hir::db::ValueTyQuery + // // SymbolsDatabase + // crate::symbol_index::ModuleSymbolsQuery + // crate::symbol_index::LibrarySymbolsQuery + // crate::symbol_index::LocalRootsQuery + // crate::symbol_index::LibraryRootsQuery + // // HirDatabase + // hir::db::AdtDatumQuery + // hir::db::AdtVarianceQuery + // hir::db::AssociatedTyDataQuery + // hir::db::AssociatedTyValueQuery + // hir::db::BorrowckQuery + // hir::db::CallableItemSignatureQuery + // hir::db::ConstEvalDiscriminantQuery + // hir::db::ConstEvalQuery + // hir::db::ConstEvalStaticQuery + // hir::db::ConstParamTyQuery + // hir::db::DynCompatibilityOfTraitQuery + // hir::db::FieldTypesQuery + // hir::db::FnDefDatumQuery + // hir::db::FnDefVarianceQuery + // hir::db::GenericDefaultsQuery + // hir::db::GenericPredicatesForParamQuery + // hir::db::GenericPredicatesQuery + // hir::db::GenericPredicatesWithoutParentQuery + // hir::db::ImplDatumQuery + // hir::db::ImplSelfTyQuery + // hir::db::ImplTraitQuery + // hir::db::IncoherentInherentImplCratesQuery + // hir::db::InferQuery + // hir::db::InherentImplsInBlockQuery + // hir::db::InherentImplsInCrateQuery + // hir::db::InternCallableDefQuery + // hir::db::InternClosureQuery + // hir::db::InternCoroutineQuery + // hir::db::InternImplTraitIdQuery + // hir::db::InternLifetimeParamIdQuery + // hir::db::InternTypeOrConstParamIdQuery + // hir::db::LayoutOfAdtQuery + // hir::db::LayoutOfTyQuery + // hir::db::LookupImplMethodQuery + // hir::db::MirBodyForClosureQuery + // hir::db::MirBodyQuery + // hir::db::MonomorphizedMirBodyForClosureQuery + // hir::db::MonomorphizedMirBodyQuery + // hir::db::ProgramClausesForChalkEnvQuery + // hir::db::ReturnTypeImplTraitsQuery + // hir::db::TargetDataLayoutQuery + // hir::db::TraitDatumQuery + // hir::db::TraitEnvironmentQuery + // hir::db::TraitImplsInBlockQuery + // hir::db::TraitImplsInCrateQuery + // hir::db::TraitImplsInDepsQuery + // hir::db::TraitSolveQuery + // hir::db::TyQuery + // hir::db::TypeAliasImplTraitsQuery + // hir::db::ValueTyQuery - // DefDatabase - hir::db::AttrsQuery - hir::db::BlockDefMapQuery - hir::db::BlockItemTreeQuery - hir::db::BlockItemTreeWithSourceMapQuery - hir::db::BodyQuery - hir::db::BodyWithSourceMapQuery - hir::db::ConstDataQuery - hir::db::ConstVisibilityQuery - hir::db::CrateDefMapQuery - hir::db::CrateLangItemsQuery - hir::db::CrateNotableTraitsQuery - hir::db::CrateSupportsNoStdQuery - hir::db::EnumDataQuery - hir::db::EnumVariantDataWithDiagnosticsQuery - hir::db::ExpandProcAttrMacrosQuery - hir::db::ExprScopesQuery - hir::db::ExternCrateDeclDataQuery - hir::db::FieldVisibilitiesQuery - hir::db::FieldsAttrsQuery - hir::db::FieldsAttrsSourceMapQuery - hir::db::FileItemTreeQuery - hir::db::FileItemTreeWithSourceMapQuery - hir::db::FunctionDataQuery - hir::db::FunctionVisibilityQuery - hir::db::GenericParamsQuery - hir::db::GenericParamsWithSourceMapQuery - hir::db::ImplDataWithDiagnosticsQuery - hir::db::ImportMapQuery - hir::db::IncludeMacroInvocQuery - hir::db::InternAnonymousConstQuery - hir::db::InternBlockQuery - hir::db::InternConstQuery - hir::db::InternEnumQuery - hir::db::InternExternBlockQuery - hir::db::InternExternCrateQuery - hir::db::InternFunctionQuery - hir::db::InternImplQuery - hir::db::InternInTypeConstQuery - hir::db::InternMacro2Query - hir::db::InternMacroRulesQuery - hir::db::InternProcMacroQuery - hir::db::InternStaticQuery - hir::db::InternStructQuery - hir::db::InternTraitAliasQuery - hir::db::InternTraitQuery - hir::db::InternTypeAliasQuery - hir::db::InternUnionQuery - hir::db::InternUseQuery - hir::db::LangItemQuery - hir::db::Macro2DataQuery - hir::db::MacroDefQuery - hir::db::MacroRulesDataQuery - hir::db::NotableTraitsInDepsQuery - hir::db::ProcMacroDataQuery - hir::db::StaticDataQuery - hir::db::StructDataWithDiagnosticsQuery - hir::db::TraitAliasDataQuery - hir::db::TraitDataWithDiagnosticsQuery - hir::db::TypeAliasDataQuery - hir::db::UnionDataWithDiagnosticsQuery + // // DefDatabase + // hir::db::AttrsQuery + // hir::db::BlockDefMapQuery + // hir::db::BlockItemTreeQuery + // hir::db::BlockItemTreeWithSourceMapQuery + // hir::db::BodyQuery + // hir::db::BodyWithSourceMapQuery + // hir::db::ConstDataQuery + // hir::db::ConstVisibilityQuery + // hir::db::CrateDefMapQuery + // hir::db::CrateLangItemsQuery + // hir::db::CrateNotableTraitsQuery + // hir::db::CrateSupportsNoStdQuery + // hir::db::EnumDataQuery + // hir::db::EnumVariantDataWithDiagnosticsQuery + // hir::db::ExpandProcAttrMacrosQuery + // hir::db::ExprScopesQuery + // hir::db::ExternCrateDeclDataQuery + // hir::db::FieldVisibilitiesQuery + // hir::db::FieldsAttrsQuery + // hir::db::FieldsAttrsSourceMapQuery + // hir::db::FileItemTreeQuery + // hir::db::FileItemTreeWithSourceMapQuery + // hir::db::FunctionDataQuery + // hir::db::FunctionVisibilityQuery + // hir::db::GenericParamsQuery + // hir::db::GenericParamsWithSourceMapQuery + // hir::db::ImplDataWithDiagnosticsQuery + // hir::db::ImportMapQuery + // hir::db::IncludeMacroInvocQuery + // hir::db::InternAnonymousConstQuery + // hir::db::InternBlockQuery + // hir::db::InternConstQuery + // hir::db::InternEnumQuery + // hir::db::InternExternBlockQuery + // hir::db::InternExternCrateQuery + // hir::db::InternFunctionQuery + // hir::db::InternImplQuery + // hir::db::InternInTypeConstQuery + // hir::db::InternMacro2Query + // hir::db::InternMacroRulesQuery + // hir::db::InternProcMacroQuery + // hir::db::InternStaticQuery + // hir::db::InternStructQuery + // hir::db::InternTraitAliasQuery + // hir::db::InternTraitQuery + // hir::db::InternTypeAliasQuery + // hir::db::InternUnionQuery + // hir::db::InternUseQuery + // hir::db::LangItemQuery + // hir::db::Macro2DataQuery + // hir::db::MacroDefQuery + // hir::db::MacroRulesDataQuery + // hir::db::NotableTraitsInDepsQuery + // hir::db::ProcMacroDataQuery + // hir::db::StaticDataQuery + // hir::db::StructDataWithDiagnosticsQuery + // hir::db::TraitAliasDataQuery + // hir::db::TraitDataWithDiagnosticsQuery + // hir::db::TypeAliasDataQuery + // hir::db::UnionDataWithDiagnosticsQuery - // InternDatabase - hir::db::InternFunctionQuery - hir::db::InternStructQuery - hir::db::InternUnionQuery - hir::db::InternEnumQuery - hir::db::InternConstQuery - hir::db::InternStaticQuery - hir::db::InternTraitQuery - hir::db::InternTraitAliasQuery - hir::db::InternTypeAliasQuery - hir::db::InternImplQuery - hir::db::InternExternBlockQuery - hir::db::InternBlockQuery - hir::db::InternMacro2Query - hir::db::InternProcMacroQuery - hir::db::InternMacroRulesQuery + // // InternDatabase + // hir::db::InternFunctionQuery + // hir::db::InternStructQuery + // hir::db::InternUnionQuery + // hir::db::InternEnumQuery + // hir::db::InternConstQuery + // hir::db::InternStaticQuery + // hir::db::InternTraitQuery + // hir::db::InternTraitAliasQuery + // hir::db::InternTypeAliasQuery + // hir::db::InternImplQuery + // hir::db::InternExternBlockQuery + // hir::db::InternBlockQuery + // hir::db::InternMacro2Query + // hir::db::InternProcMacroQuery + // hir::db::InternMacroRulesQuery - // ExpandDatabase - hir::db::AstIdMapQuery - hir::db::DeclMacroExpanderQuery - hir::db::ExpandProcMacroQuery - hir::db::InternMacroCallQuery - hir::db::InternSyntaxContextQuery - hir::db::MacroArgQuery - hir::db::ParseMacroExpansionErrorQuery - hir::db::ParseMacroExpansionQuery - hir::db::ProcMacroSpanQuery - hir::db::ProcMacrosQuery - hir::db::RealSpanMapQuery + // // ExpandDatabase + // hir::db::AstIdMapQuery + // hir::db::DeclMacroExpanderQuery + // hir::db::ExpandProcMacroQuery + // hir::db::InternMacroCallQuery + // hir::db::InternSyntaxContextQuery + // hir::db::MacroArgQuery + // hir::db::ParseMacroExpansionErrorQuery + // hir::db::ParseMacroExpansionQuery + // hir::db::ProcMacroSpanQuery + // hir::db::ProcMacrosQuery + // hir::db::RealSpanMapQuery - // LineIndexDatabase - crate::LineIndexQuery + // // LineIndexDatabase + // crate::LineIndexQuery - // SourceDatabase - base_db::ParseQuery - base_db::ParseErrorsQuery - base_db::CrateGraphQuery - base_db::CrateWorkspaceDataQuery + // // SourceDatabase + // base_db::ParseQuery + // base_db::ParseErrorsQuery + // base_db::CrateGraphQuery + // base_db::CrateWorkspaceDataQuery - // SourceDatabaseExt - base_db::FileTextQuery - base_db::CompressedFileTextQuery - base_db::FileSourceRootQuery - base_db::SourceRootQuery - base_db::SourceRootCratesQuery + // // SourceDatabaseExt + // base_db::FileTextQuery + // base_db::CompressedFileTextQuery + // base_db::FileSourceRootQuery + // base_db::SourceRootQuery + // base_db::SourceRootCratesQuery ]; acc.sort_by_key(|it| std::cmp::Reverse(it.1)); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs index 2f4d07446f2c1..af4c10f8ea6b5 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs @@ -1,6 +1,6 @@ //! See [`FamousDefs`]. -use base_db::{CrateOrigin, LangCrateOrigin, SourceDatabase}; +use base_db::{CrateOrigin, LangCrateOrigin, RootQueryDb as _}; use hir::{Crate, Enum, Function, Macro, Module, ScopeDef, Semantics, Trait}; use crate::RootDatabase; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs index 84fa58d743bbc..ebafc8876f249 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs @@ -2,7 +2,7 @@ use std::collections::VecDeque; -use base_db::SourceRootDatabase; +use base_db::SourceDatabase; use hir::{Crate, ItemInNs, ModuleDef, Name, Semantics}; use span::{Edition, FileId}; use syntax::{ @@ -108,8 +108,8 @@ pub fn lint_eq_or_in_group(lint: &str, lint_is: &str) -> bool { pub fn is_editable_crate(krate: Crate, db: &RootDatabase) -> bool { let root_file = krate.root_file(db); - let source_root_id = db.file_source_root(root_file); - !db.source_root(source_root_id).is_library + let source_root_id = db.file_source_root(root_file).source_root_id(db); + !db.source_root(source_root_id).source_root(db).is_library } // FIXME: This is a weird function diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs index decb0ea9d8a8a..39810c615bb77 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs @@ -1,3 +1,4 @@ +use salsa::AsDynDatabase; use stdx::trim_indent; use test_fixture::WithFixture; use test_utils::{assert_eq_text, CURSOR_MARKER}; @@ -1250,9 +1251,15 @@ fn check_with_config( ) { let (db, file_id, pos) = if ra_fixture_before.contains(CURSOR_MARKER) { let (db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture_before); + + let file_id = crate::base_db::EditionedFileId::new(db.as_dyn_database(), file_id); + (db, file_id, Some(range_or_offset)) } else { let (db, file_id) = RootDatabase::with_single_file(ra_fixture_before); + + let file_id = crate::base_db::EditionedFileId::new(db.as_dyn_database(), file_id); + (db, file_id, None) }; let sema = &Semantics::new(&db); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 96115eee6dc2a..2516a9d0aa388 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -46,13 +46,14 @@ pub mod syntax_helpers { } pub use hir::ChangeWithProcMacros; +use salsa::Durability; use std::{fmt, mem::ManuallyDrop}; use base_db::{ - ra_salsa::{self, Durability}, - AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, - DEFAULT_FILE_TEXT_LRU_CAP, + query_group::{self}, + FileSourceRootInput, FileText, Files, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, + SourceRootInput, Upcast, }; use hir::{ db::{DefDatabase, ExpandDatabase, HirDatabase}, @@ -76,22 +77,21 @@ pub type FxIndexMap = pub type FilePosition = FilePositionWrapper; pub type FileRange = FileRangeWrapper; -#[ra_salsa::database( - base_db::SourceRootDatabaseStorage, - base_db::SourceDatabaseStorage, - hir::db::ExpandDatabaseStorage, - hir::db::DefDatabaseStorage, - hir::db::HirDatabaseStorage, - hir::db::InternDatabaseStorage, - LineIndexDatabaseStorage, - symbol_index::SymbolsDatabaseStorage -)] +#[salsa::db] pub struct RootDatabase { // We use `ManuallyDrop` here because every codegen unit that contains a // `&RootDatabase -> &dyn OtherDatabase` cast will instantiate its drop glue in the vtable, // which duplicates `Weak::drop` and `Arc::drop` tens of thousands of times, which makes // compile times of all `ide_*` and downstream crates suffer greatly. - storage: ManuallyDrop>, + storage: ManuallyDrop>, + files: Arc, +} + +impl std::panic::RefUnwindSafe for RootDatabase {} + +#[salsa::db] +impl salsa::Database for RootDatabase { + fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {} } impl Drop for RootDatabase { @@ -100,6 +100,12 @@ impl Drop for RootDatabase { } } +impl Clone for RootDatabase { + fn clone(&self) -> Self { + Self { storage: self.storage.clone(), files: self.files.clone() } + } +} + impl fmt::Debug for RootDatabase { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RootDatabase").finish() @@ -127,16 +133,68 @@ impl Upcast for RootDatabase { } } -impl FileLoader for RootDatabase { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { - FileLoaderDelegate(self).resolve_path(path) +impl Upcast for RootDatabase { + fn upcast(&self) -> &(dyn RootQueryDb + 'static) { + self } - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { - FileLoaderDelegate(self).relevant_crates(file_id) +} + +impl Upcast for RootDatabase { + fn upcast(&self) -> &(dyn SourceDatabase + 'static) { + self } } -impl ra_salsa::Database for RootDatabase {} +#[salsa::db] +impl SourceDatabase for RootDatabase { + fn file_text(&self, file_id: vfs::FileId) -> FileText { + self.files.file_text(file_id) + } + + fn set_file_text(&mut self, file_id: vfs::FileId, text: &str) { + let files = Arc::clone(&self.files); + files.set_file_text(self, file_id, text); + } + + fn set_file_text_with_durability( + &mut self, + file_id: vfs::FileId, + text: &str, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_text_with_durability(self, file_id, text, durability); + } + + /// Source root of the file. + fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput { + self.files.source_root(source_root_id) + } + + fn set_source_root_with_durability( + &mut self, + source_root_id: SourceRootId, + source_root: Arc, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_source_root_with_durability(self, source_root_id, source_root, durability); + } + + fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput { + self.files.file_source_root(id) + } + + fn set_file_source_root_with_durability( + &mut self, + id: vfs::FileId, + source_root_id: SourceRootId, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_source_root_with_durability(self, id, source_root_id, durability); + } +} impl Default for RootDatabase { fn default() -> RootDatabase { @@ -146,14 +204,16 @@ impl Default for RootDatabase { impl RootDatabase { pub fn new(lru_capacity: Option) -> RootDatabase { - let mut db = RootDatabase { storage: ManuallyDrop::new(ra_salsa::Storage::default()) }; + let mut db = RootDatabase { + storage: ManuallyDrop::new(salsa::Storage::default()), + files: Default::default(), + }; db.set_crate_graph_with_durability(Default::default(), Durability::HIGH); db.set_proc_macros_with_durability(Default::default(), Durability::HIGH); db.set_local_roots_with_durability(Default::default(), Durability::HIGH); db.set_library_roots_with_durability(Default::default(), Durability::HIGH); db.set_expand_proc_attr_macros_with_durability(false, Durability::HIGH); db.update_base_query_lru_capacities(lru_capacity); - db.setup_syntax_context_root(); db } @@ -161,57 +221,54 @@ impl RootDatabase { self.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); } - pub fn update_base_query_lru_capacities(&mut self, lru_capacity: Option) { - let lru_capacity = lru_capacity.unwrap_or(base_db::DEFAULT_PARSE_LRU_CAP); - base_db::FileTextQuery.in_db_mut(self).set_lru_capacity(DEFAULT_FILE_TEXT_LRU_CAP); - base_db::ParseQuery.in_db_mut(self).set_lru_capacity(lru_capacity); - // macro expansions are usually rather small, so we can afford to keep more of them alive - hir::db::ParseMacroExpansionQuery.in_db_mut(self).set_lru_capacity(4 * lru_capacity); - hir::db::BorrowckQuery.in_db_mut(self).set_lru_capacity(base_db::DEFAULT_BORROWCK_LRU_CAP); - hir::db::BodyWithSourceMapQuery.in_db_mut(self).set_lru_capacity(2048); + pub fn update_base_query_lru_capacities(&mut self, _lru_capacity: Option) { + // let lru_capacity = lru_capacity.unwrap_or(base_db::DEFAULT_PARSE_LRU_CAP); + // base_db::FileTextQuery.in_db_mut(self).set_lru_capacity(DEFAULT_FILE_TEXT_LRU_CAP); + // base_db::ParseQuery.in_db_mut(self).set_lru_capacity(lru_capacity); + // // macro expansions are usually rather small, so we can afford to keep more of them alive + // hir::db::ParseMacroExpansionQuery.in_db_mut(self).set_lru_capacity(4 * lru_capacity); + // hir::db::BorrowckQuery.in_db_mut(self).set_lru_capacity(base_db::DEFAULT_BORROWCK_LRU_CAP); + // hir::db::BodyWithSourceMapQuery.in_db_mut(self).set_lru_capacity(2048); } - pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap, u16>) { - use hir::db as hir_db; - - base_db::FileTextQuery.in_db_mut(self).set_lru_capacity(DEFAULT_FILE_TEXT_LRU_CAP); - base_db::ParseQuery.in_db_mut(self).set_lru_capacity( - lru_capacities - .get(stringify!(ParseQuery)) - .copied() - .unwrap_or(base_db::DEFAULT_PARSE_LRU_CAP), - ); - hir_db::ParseMacroExpansionQuery.in_db_mut(self).set_lru_capacity( - lru_capacities - .get(stringify!(ParseMacroExpansionQuery)) - .copied() - .unwrap_or(4 * base_db::DEFAULT_PARSE_LRU_CAP), - ); - hir_db::BorrowckQuery.in_db_mut(self).set_lru_capacity( - lru_capacities - .get(stringify!(BorrowckQuery)) - .copied() - .unwrap_or(base_db::DEFAULT_BORROWCK_LRU_CAP), - ); - hir::db::BodyWithSourceMapQuery.in_db_mut(self).set_lru_capacity(2048); + pub fn update_lru_capacities(&mut self, _lru_capacities: &FxHashMap, u16>) { + // FIXME(salsa-transition): bring this back; allow changing LRU settings at runtime. + // use hir::db as hir_db; + + // base_db::FileTextQuery.in_db_mut(self).set_lru_capacity(DEFAULT_FILE_TEXT_LRU_CAP); + // base_db::ParseQuery.in_db_mut(self).set_lru_capacity( + // lru_capacities + // .get(stringify!(ParseQuery)) + // .copied() + // .unwrap_or(base_db::DEFAULT_PARSE_LRU_CAP), + // ); + // hir_db::ParseMacroExpansionQuery.in_db_mut(self).set_lru_capacity( + // lru_capacities + // .get(stringify!(ParseMacroExpansionQuery)) + // .copied() + // .unwrap_or(4 * base_db::DEFAULT_PARSE_LRU_CAP), + // ); + // hir_db::BorrowckQuery.in_db_mut(self).set_lru_capacity( + // lru_capacities + // .get(stringify!(BorrowckQuery)) + // .copied() + // .unwrap_or(base_db::DEFAULT_BORROWCK_LRU_CAP), + // ); + // hir::db::BodyWithSourceMapQuery.in_db_mut(self).set_lru_capacity(2048); } -} -impl ra_salsa::ParallelDatabase for RootDatabase { - fn snapshot(&self) -> ra_salsa::Snapshot { - ra_salsa::Snapshot::new(RootDatabase { - storage: ManuallyDrop::new(self.storage.snapshot()), - }) + pub fn snapshot(&self) -> Self { + Self { storage: self.storage.clone(), files: self.files.clone() } } } -#[ra_salsa::query_group(LineIndexDatabaseStorage)] -pub trait LineIndexDatabase: base_db::SourceDatabase { +#[query_group::query_group] +pub trait LineIndexDatabase: base_db::RootQueryDb { fn line_index(&self, file_id: FileId) -> Arc; } fn line_index(db: &dyn LineIndexDatabase, file_id: FileId) -> Arc { - let text = db.file_text(file_id); + let text = db.file_text(file_id).text(db); Arc::new(LineIndex::new(&text)) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs index 22dc3d9e29d65..74d79cd69557f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs @@ -8,12 +8,10 @@ use std::time::Duration; use hir::{db::DefDatabase, Symbol}; use itertools::Itertools; +use salsa::{Cancelled, Database}; use crate::{ - base_db::{ - ra_salsa::{Database, ParallelDatabase, Snapshot}, - Cancelled, CrateId, SourceDatabase, - }, + base_db::{CrateId, RootQueryDb}, symbol_index::SymbolsDatabase, FxIndexMap, RootDatabase, }; @@ -66,7 +64,7 @@ pub fn parallel_prime_caches( let (work_sender, progress_receiver) = { let (progress_sender, progress_receiver) = crossbeam_channel::unbounded(); let (work_sender, work_receiver) = crossbeam_channel::unbounded(); - let prime_caches_worker = move |db: Snapshot| { + let prime_caches_worker = move |db: RootDatabase| { while let Ok((crate_id, crate_name, kind)) = work_receiver.recv() { progress_sender .send(ParallelPrimeCacheWorkerProgress::BeginCrate { crate_id, crate_name })?; @@ -90,7 +88,7 @@ pub fn parallel_prime_caches( stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) .allow_leak(true) .name(format!("PrimeCaches#{id}")) - .spawn(move || Cancelled::catch(|| worker(db))) + .spawn(move || Cancelled::catch(|| worker(db.snapshot()))) .expect("failed to spawn thread"); } @@ -108,7 +106,7 @@ pub fn parallel_prime_caches( let mut additional_phases = vec![]; while crates_done < crates_total { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); for crate_id in &mut crates_to_prime { let krate = &graph[crate_id]; @@ -145,7 +143,7 @@ pub fn parallel_prime_caches( } Err(crossbeam_channel::RecvTimeoutError::Disconnected) => { // our workers may have died from a cancelled task, so we'll check and re-raise here. - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); break; } }; @@ -177,7 +175,7 @@ pub fn parallel_prime_caches( } while crates_done < crates_total { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); // recv_timeout is somewhat a hack, we need a way to from this thread check to see if the current salsa revision // is cancelled on a regular basis. workers will only exit if they are processing a task that is cancelled, or @@ -189,7 +187,7 @@ pub fn parallel_prime_caches( } Err(crossbeam_channel::RecvTimeoutError::Disconnected) => { // our workers may have died from a cancelled task, so we'll check and re-raise here. - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); break; } }; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 02cd8b8bdf510..81df0c0f0f88b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -7,7 +7,7 @@ use std::mem; use std::{cell::LazyCell, cmp::Reverse}; -use base_db::{ra_salsa::Database, SourceDatabase, SourceRootDatabase}; +use base_db::{RootQueryDb, SourceDatabase}; use either::Either; use hir::{ sym, Adt, AsAssocItem, DefWithBody, FileRange, FileRangeWrapper, HasAttrs, HasContainer, @@ -17,6 +17,7 @@ use hir::{ use memchr::memmem::Finder; use parser::SyntaxKind; use rustc_hash::{FxHashMap, FxHashSet}; +use salsa::Database; use span::EditionedFileId; use syntax::{ ast::{self, HasName, Rename}, @@ -164,8 +165,8 @@ impl SearchScope { let graph = db.crate_graph(); for krate in graph.iter() { let root_file = graph[krate].root_file_id; - let source_root_id = db.file_source_root(root_file); - let source_root = db.source_root(source_root_id); + let source_root = db.file_source_root(root_file).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); entries.extend( source_root.iter().map(|id| (EditionedFileId::new(id, graph[krate].edition), None)), ); @@ -178,8 +179,9 @@ impl SearchScope { let mut entries = FxHashMap::default(); for rev_dep in of.transitive_reverse_dependencies(db) { let root_file = rev_dep.root_file(db); - let source_root_id = db.file_source_root(root_file); - let source_root = db.source_root(source_root_id); + + let source_root = db.file_source_root(root_file).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); entries.extend( source_root.iter().map(|id| (EditionedFileId::new(id, rev_dep.edition(db)), None)), ); @@ -190,8 +192,9 @@ impl SearchScope { /// Build a search scope spanning the given crate. fn krate(db: &RootDatabase, of: hir::Crate) -> SearchScope { let root_file = of.root_file(db); - let source_root_id = db.file_source_root(root_file); - let source_root = db.source_root(source_root_id); + + let source_root_id = db.file_source_root(root_file).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); SearchScope { entries: source_root .iter() @@ -483,7 +486,7 @@ impl<'a> FindUsages<'a> { scope: &'b SearchScope, ) -> impl Iterator, EditionedFileId, TextRange)> + 'b { scope.entries.iter().map(|(&file_id, &search_range)| { - let text = db.file_text(file_id.file_id()); + let text = db.file_text(file_id.file_id()).text(db); let search_range = search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text))); @@ -649,6 +652,8 @@ impl<'a> FindUsages<'a> { for (file_text, file_id, search_range) in FindUsages::scope_files(db, ¤t_to_process_search_scope) { + let file_id = crate::base_db::EditionedFileId::new(db, file_id); + let tree = LazyCell::new(move || sema.parse(file_id).syntax().clone()); for offset in FindUsages::match_indices(&file_text, &finder, search_range) { @@ -808,7 +813,9 @@ impl<'a> FindUsages<'a> { sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) { for (file_text, file_id, search_range) in files { - let tree = LazyCell::new(move || this.sema.parse(file_id).syntax().clone()); + let file_id_wrapper = crate::base_db::EditionedFileId::new(this.sema.db, file_id); + + let tree = LazyCell::new(move || this.sema.parse(file_id_wrapper).syntax().clone()); for offset in FindUsages::match_indices(&file_text, finder, search_range) { let usages = FindUsages::find_nodes(this.sema, name, &tree, offset) @@ -853,7 +860,7 @@ impl<'a> FindUsages<'a> { name, is_possibly_self.into_iter().map(|position| { ( - self.sema.db.file_text(position.file_id.file_id()), + self.sema.db.file_text(position.file_id.file_id()).text(self.sema.db), position.file_id, position.range, ) @@ -947,8 +954,9 @@ impl<'a> FindUsages<'a> { let include_self_kw_refs = self.include_self_kw_refs.as_ref().map(|ty| (ty, Finder::new("Self"))); for (text, file_id, search_range) in Self::scope_files(sema.db, &search_scope) { - self.sema.db.unwind_if_cancelled(); - let tree = LazyCell::new(move || sema.parse(file_id).syntax().clone()); + let file_id_wrapper = crate::base_db::EditionedFileId::new(sema.db, file_id); + + let tree = LazyCell::new(move || sema.parse(file_id_wrapper).syntax().clone()); // Search for occurrences of the items name for offset in Self::match_indices(&text, finder, search_range) { @@ -1001,8 +1009,10 @@ impl<'a> FindUsages<'a> { let finder = &Finder::new("super"); for (text, file_id, search_range) in Self::scope_files(sema.db, &scope) { - self.sema.db.unwind_if_cancelled(); - let tree = LazyCell::new(move || sema.parse(file_id).syntax().clone()); + self.sema.db.unwind_if_revision_cancelled(); + + let file_id_wrapper = crate::base_db::EditionedFileId::new(sema.db, file_id); + let tree = LazyCell::new(move || sema.parse(file_id_wrapper).syntax().clone()); for offset in Self::match_indices(&text, finder, search_range) { for name_ref in Self::find_nodes(sema, "super", &tree, offset) @@ -1050,10 +1060,13 @@ impl<'a> FindUsages<'a> { return; }; - let text = sema.db.file_text(file_id.file_id()); + let file_text = sema.db.file_text(file_id.file_id()); + let text = file_text.text(sema.db); let search_range = search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text))); + let file_id = crate::base_db::EditionedFileId::new(sema.db, file_id); + let tree = LazyCell::new(|| sema.parse(file_id).syntax().clone()); let finder = &Finder::new("self"); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index 2737436993deb..5fea97b32dbde 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -27,10 +27,7 @@ use std::{ ops::ControlFlow, }; -use base_db::{ - ra_salsa::{self, ParallelDatabase}, - SourceRootDatabase, SourceRootId, Upcast, -}; +use base_db::{RootQueryDb, SourceDatabase, SourceRootId, Upcast}; use fst::{raw::IndexedValue, Automaton, Streamer}; use hir::{ db::HirDatabase, @@ -99,8 +96,8 @@ impl Query { } } -#[ra_salsa::query_group(SymbolsDatabaseStorage)] -pub trait SymbolsDatabase: HirDatabase + SourceRootDatabase + Upcast { +#[query_group::query_group] +pub trait SymbolsDatabase: HirDatabase + SourceDatabase + Upcast { /// The symbol index for a given module. These modules should only be in source roots that /// are inside local_roots. fn module_symbols(&self, module: Module) -> Arc; @@ -108,18 +105,18 @@ pub trait SymbolsDatabase: HirDatabase + SourceRootDatabase + Upcast Arc; - #[ra_salsa::transparent] + #[salsa::transparent] /// The symbol indices of modules that make up a given crate. fn crate_symbols(&self, krate: Crate) -> Box<[Arc]>; /// The set of "local" (that is, from the current workspace) roots. /// Files in local roots are assumed to change frequently. - #[ra_salsa::input] + #[salsa::input] fn local_roots(&self) -> Arc>; /// The set of roots for crates.io libraries. /// Files in libraries are assumed to never change. - #[ra_salsa::input] + #[salsa::input] fn library_roots(&self) -> Arc>; } @@ -150,26 +147,6 @@ pub fn crate_symbols(db: &dyn SymbolsDatabase, krate: Crate) -> Box<[Arc(DB); -impl Snap> { - fn new(db: &DB) -> Self { - Self(db.snapshot()) - } -} -impl Clone for Snap> { - fn clone(&self) -> Snap> { - Snap(self.0.snapshot()) - } -} -impl std::ops::Deref for Snap { - type Target = DB; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - // Feature: Workspace Symbol // // Uses fuzzy-search to find types, modules and functions by name across your @@ -201,7 +178,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { let indices: Vec<_> = if query.libs { db.library_roots() .par_iter() - .map_with(Snap::new(db), |snap, &root| snap.library_symbols(root)) + .map_with(db.clone(), |snap, &root| snap.library_symbols(root)) .collect() } else { let mut crates = Vec::new(); @@ -211,7 +188,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { } let indices: Vec<_> = crates .into_par_iter() - .map_with(Snap::new(db), |snap, krate| snap.crate_symbols(krate.into())) + .map_with(db.clone(), |snap, krate| snap.crate_symbols(krate.into())) .collect(); indices.iter().flat_map(|indices| indices.iter().cloned()).collect() }; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs index e085bf15cb92d..21dd098781a85 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs @@ -457,9 +457,11 @@ mod tests { fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: &str) { let (db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture); let frange = FileRange { file_id, range: range_or_offset.into() }; - let sema = Semantics::new(&db); - let source_file = sema.parse(frange.file_id); + + let file_id = crate::base_db::EditionedFileId::new(sema.db, frange.file_id); + let source_file = sema.parse(file_id); + let element = source_file.syntax().covering_element(frange.range); let expr = element.ancestors().find_map(ast::Expr::cast).expect("selection is not an expression"); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt index efcf53ded64f0..0cae7f367c205 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt @@ -14,7 +14,7 @@ Struct( Struct { id: StructId( - 1, + 4401, ), }, ), @@ -47,7 +47,7 @@ Struct( Struct { id: StructId( - 0, + 4400, ), }, ), @@ -80,7 +80,7 @@ Struct( Struct { id: StructId( - 0, + 4400, ), }, ), @@ -113,7 +113,7 @@ Struct( Struct { id: StructId( - 0, + 4400, ), }, ), @@ -146,7 +146,7 @@ Struct( Struct { id: StructId( - 0, + 4400, ), }, ), @@ -179,7 +179,7 @@ Struct( Struct { id: StructId( - 1, + 4401, ), }, ), @@ -212,7 +212,7 @@ Struct( Struct { id: StructId( - 0, + 4400, ), }, ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 7dce95592b819..48de1fb837a20 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -13,7 +13,7 @@ def: TypeAlias( TypeAlias { id: TypeAliasId( - 0, + 8400, ), }, ), @@ -44,7 +44,7 @@ def: Const( Const { id: ConstId( - 0, + 7c00, ), }, ), @@ -75,7 +75,7 @@ def: Const( Const { id: ConstId( - 2, + 7c02, ), }, ), @@ -107,7 +107,7 @@ Enum( Enum { id: EnumId( - 0, + 6400, ), }, ), @@ -140,7 +140,7 @@ Macro { id: Macro2Id( Macro2Id( - 0, + 6000, ), ), }, @@ -173,7 +173,7 @@ Macro { id: Macro2Id( Macro2Id( - 0, + 6000, ), ), }, @@ -205,7 +205,7 @@ def: Static( Static { id: StaticId( - 0, + 8000, ), }, ), @@ -237,7 +237,7 @@ Struct( Struct { id: StructId( - 1, + 5c01, ), }, ), @@ -270,14 +270,14 @@ Struct( Struct { id: StructId( - 0, + 5c00, ), }, ), ), loc: DeclarationLocation { hir_file_id: MacroFile( - 0, + Id(4800), ), ptr: SyntaxNodePtr { kind: STRUCT, @@ -300,7 +300,7 @@ Struct( Struct { id: StructId( - 5, + 5c05, ), }, ), @@ -335,7 +335,7 @@ Struct( Struct { id: StructId( - 6, + 5c06, ), }, ), @@ -370,7 +370,7 @@ Struct( Struct { id: StructId( - 7, + 5c07, ), }, ), @@ -403,7 +403,7 @@ Struct( Struct { id: StructId( - 2, + 5c02, ), }, ), @@ -435,7 +435,7 @@ def: Trait( Trait { id: TraitId( - 0, + 7400, ), }, ), @@ -467,7 +467,7 @@ Macro { id: Macro2Id( Macro2Id( - 0, + 6000, ), ), }, @@ -500,7 +500,7 @@ Union( Union { id: UnionId( - 0, + 6c00, ), }, ), @@ -599,7 +599,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 1, + 4401, ), ), }, @@ -631,7 +631,7 @@ def: Function( Function { id: FunctionId( - 2, + 7802, ), }, ), @@ -664,7 +664,7 @@ def: Function( Function { id: FunctionId( - 1, + 7801, ), }, ), @@ -698,7 +698,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 0, + 4400, ), ), }, @@ -730,7 +730,7 @@ def: Function( Function { id: FunctionId( - 0, + 7800, ), }, ), @@ -762,7 +762,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 1, + 4401, ), ), }, @@ -794,7 +794,7 @@ def: Function( Function { id: FunctionId( - 3, + 7803, ), }, ), @@ -839,7 +839,7 @@ Struct( Struct { id: StructId( - 3, + 5c03, ), }, ), @@ -882,7 +882,7 @@ def: Trait( Trait { id: TraitId( - 0, + 7400, ), }, ), @@ -914,7 +914,7 @@ Macro { id: Macro2Id( Macro2Id( - 0, + 6000, ), ), }, @@ -947,7 +947,7 @@ Struct( Struct { id: StructId( - 4, + 5c04, ), }, ), @@ -980,7 +980,7 @@ Macro { id: Macro2Id( Macro2Id( - 0, + 6000, ), ), }, @@ -1013,7 +1013,7 @@ Struct( Struct { id: StructId( - 4, + 5c04, ), }, ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs index 0f67496d0989e..fb231393a473d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs @@ -116,6 +116,7 @@ mod tests { use expect_test::{expect, Expect}; use hir::FilePosition; use hir::Semantics; + use salsa::AsDynDatabase; use span::Edition; use syntax::ast::{self, AstNode}; use test_fixture::ChangeFixture; @@ -138,7 +139,11 @@ mod tests { fn check_trait(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let (db, position) = position(ra_fixture); let sema = Semantics::new(&db); - let file = sema.parse(position.file_id); + + let editioned_file_id = + crate::base_db::EditionedFileId::new(sema.db.as_dyn_database(), position.file_id); + + let file = sema.parse(editioned_file_id); let impl_block: ast::Impl = sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap(); let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block); @@ -152,7 +157,11 @@ mod tests { fn check_missing_assoc(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let (db, position) = position(ra_fixture); let sema = Semantics::new(&db); - let file = sema.parse(position.file_id); + + let editioned_file_id = + crate::base_db::EditionedFileId::new(sema.db.as_dyn_database(), position.file_id); + + let file = sema.parse(editioned_file_id); let impl_block: ast::Impl = sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap(); let items = crate::traits::get_missing_assoc_items(&sema, &impl_block); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs index c726a3bcd3cad..f17e9e64ab74e 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -1053,7 +1053,7 @@ fn test() -> String { fn f() { let mut x = (|| 1, 2); x = (|| 3, 4); - //^^^^ error: expected {closure#0}, found {closure#1} + //^^^^ error: expected {closure#23552}, found {closure#23553} } "#, ); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs index f3109b9bb73a2..550751b6c01c4 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -3,9 +3,10 @@ use std::iter; use hir::{db::DefDatabase, DefMap, InFile, ModuleSource}; +use ide_db::base_db::RootQueryDb; use ide_db::text_edit::TextEdit; use ide_db::{ - base_db::{FileLoader, SourceDatabase, SourceRootDatabase}, + base_db::{SourceDatabase, Upcast}, source_change::SourceChange, FileId, FileRange, LineIndexDatabase, }; @@ -48,6 +49,7 @@ pub(crate) fn unlinked_file( // Only show this diagnostic on the first three characters of // the file, to avoid overwhelming the user during startup. range = SourceDatabase::file_text(ctx.sema.db, file_id) + .text(ctx.sema.db) .char_indices() .take(3) .last() @@ -78,7 +80,11 @@ fn fixes( // If there's an existing module that could add `mod` or `pub mod` items to include the unlinked file, // suggest that as a fix. - let source_root = ctx.sema.db.source_root(ctx.sema.db.file_source_root(file_id)); + let db = ctx.sema.db; + + let source_root = ctx.sema.db.file_source_root(file_id).source_root_id(db); + let source_root = ctx.sema.db.source_root(source_root).source_root(db); + let our_path = source_root.path_for_file(&file_id)?; let parent = our_path.parent()?; let (module_name, _) = our_path.name_and_extension()?; @@ -93,7 +99,8 @@ fn fixes( }; // check crate roots, i.e. main.rs, lib.rs, ... - 'crates: for &krate in &*ctx.sema.db.relevant_crates(file_id) { + let relevant_crates = Upcast::::upcast(db).relevant_crates(file_id); + 'crates: for &krate in &*relevant_crates { let crate_def_map = ctx.sema.db.crate_def_map(krate); let root_module = &crate_def_map[DefMap::ROOT]; @@ -141,7 +148,8 @@ fn fixes( paths.into_iter().find_map(|path| source_root.file_for_path(&path)) })?; stack.pop(); - 'crates: for &krate in ctx.sema.db.relevant_crates(parent_id).iter() { + let relevant_crates = Upcast::::upcast(db).relevant_crates(parent_id); + 'crates: for &krate in relevant_crates.iter() { let crate_def_map = ctx.sema.db.crate_def_map(krate); let Some((_, module)) = crate_def_map.modules().find(|(_, module)| { module.origin.file_id().map(Into::into) == Some(parent_id) && !module.origin.is_inline() diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index e15d349578914..5ce3336eb41f6 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -85,9 +85,10 @@ use hir::{ db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, DisplayTarget, HirFileId, InFile, Semantics, }; +use ide_db::base_db::salsa::AsDynDatabase; use ide_db::{ assists::{Assist, AssistId, AssistKind, AssistResolveStrategy}, - base_db::{ReleaseChannel, SourceDatabase}, + base_db::{ReleaseChannel, RootQueryDb as _}, generated::lints::{Lint, LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, DEFAULT_LINT_GROUPS}, imports::insert_use::InsertUseConfig, label::Label, @@ -319,12 +320,17 @@ pub fn syntax_diagnostics( } let sema = Semantics::new(db); - let file_id = sema + let editioned_file_id = sema .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); + let (file_id, _) = editioned_file_id.unpack(); + + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(db.as_dyn_database(), editioned_file_id); + // [#3434] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily. - db.parse_errors(file_id) + db.parse_errors(editioned_file_id_wrapper) .as_deref() .into_iter() .flatten() @@ -333,7 +339,7 @@ pub fn syntax_diagnostics( Diagnostic::new( DiagnosticCode::SyntaxError, format!("Syntax Error: {err}"), - FileRange { file_id: file_id.into(), range: err.range() }, + FileRange { file_id, range: err.range() }, ) }) .collect() @@ -349,26 +355,31 @@ pub fn semantic_diagnostics( ) -> Vec { let _p = tracing::info_span!("semantic_diagnostics").entered(); let sema = Semantics::new(db); - let file_id = sema + let editioned_file_id = sema .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); + + let (file_id, edition) = editioned_file_id.unpack(); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(db.as_dyn_database(), editioned_file_id); + let mut res = Vec::new(); - let parse = sema.parse(file_id); + let parse = sema.parse(editioned_file_id_wrapper); // FIXME: This iterates the entire file which is a rather expensive operation. // We should implement these differently in some form? // Salsa caching + incremental re-parse would be better here for node in parse.syntax().descendants() { - handlers::useless_braces::useless_braces(&mut res, file_id, &node); - handlers::field_shorthand::field_shorthand(&mut res, file_id, &node); + handlers::useless_braces::useless_braces(&mut res, editioned_file_id, &node); + handlers::field_shorthand::field_shorthand(&mut res, editioned_file_id, &node); handlers::json_is_not_rust::json_in_items( &sema, &mut res, - file_id, + editioned_file_id, &node, config, - file_id.edition(), + edition, ); } @@ -382,25 +393,19 @@ pub fn semantic_diagnostics( (*db.crate_graph().crates_in_topological_order().last().unwrap()).into() }); let display_target = krate.to_display_target(db); - let ctx = DiagnosticsContext { - config, - sema, - resolve, - edition: file_id.edition(), - is_nightly, - display_target, - }; + let ctx = DiagnosticsContext { config, sema, resolve, edition, is_nightly, display_target }; let mut diags = Vec::new(); match module { // A bunch of parse errors in a file indicate some bigger structural parse changes in the // file, so we skip semantic diagnostics so we can show these faster. Some(m) => { - if db.parse_errors(file_id).as_deref().is_none_or(|es| es.len() < 16) { + if db.parse_errors(editioned_file_id_wrapper).as_deref().is_none_or(|es| es.len() < 16) + { m.diagnostics(db, &mut diags, config.style_lints); } } - None => handlers::unlinked_file::unlinked_file(&ctx, &mut res, file_id.file_id()), + None => handlers::unlinked_file::unlinked_file(&ctx, &mut res, editioned_file_id.file_id()), } for diag in diags { @@ -517,7 +522,7 @@ pub fn semantic_diagnostics( &mut FxHashMap::default(), &mut lints, &mut Vec::new(), - file_id.edition(), + editioned_file_id.edition(), ); res.retain(|d| d.severity != Severity::Allow); @@ -559,7 +564,7 @@ fn handle_diag_from_macros( let span_map = sema.db.expansion_span_map(macro_file); let mut spans = span_map.spans_for_range(node.text_range()); if spans.any(|span| { - sema.db.lookup_intern_syntax_context(span.ctx).outer_expn.is_some_and(|expansion| { + span.ctx.outer_expn(sema.db).is_some_and(|expansion| { let macro_call = sema.db.lookup_intern_macro_call(expansion.as_macro_file().macro_call_id); // We don't want to show diagnostics for non-local macros at all, but proc macros authors diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs index fc2a7db7174e9..7b33bbdaa22c4 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs @@ -85,7 +85,7 @@ fn check_nth_fix_with_config( let actual = { let source_change = fix.source_change.as_ref().unwrap(); let file_id = *source_change.source_file_edits.keys().next().unwrap(); - let mut actual = db.file_text(file_id).to_string(); + let mut actual = db.file_text(file_id).text(&db).to_string(); for (edit, snippet_edit) in source_change.source_file_edits.values() { edit.apply(&mut actual); @@ -142,7 +142,7 @@ pub(crate) fn check_has_fix( let actual = { let source_change = fix.source_change.as_ref().unwrap(); let file_id = *source_change.source_file_edits.keys().next().unwrap(); - let mut actual = db.file_text(file_id).to_string(); + let mut actual = db.file_text(file_id).text(&db).to_string(); for (edit, snippet_edit) in source_change.source_file_edits.values() { edit.apply(&mut actual); @@ -190,7 +190,7 @@ pub(crate) fn check_has_single_fix( let actual = { let source_change = fix.source_change.as_ref().unwrap(); let file_id = *source_change.source_file_edits.keys().next().unwrap(); - let mut actual = db.file_text(file_id).to_string(); + let mut actual = db.file_text(file_id).text(&db).to_string(); for (edit, snippet_edit) in source_change.source_file_edits.values() { edit.apply(&mut actual); @@ -276,7 +276,7 @@ pub(crate) fn check_diagnostics_with_config( let line_index = db.line_index(file_id); let mut actual = annotations.remove(&file_id).unwrap_or_default(); - let expected = extract_annotations(&db.file_text(file_id)); + let expected = extract_annotations(&db.file_text(file_id).text(&db)); actual.sort_by_key(|(range, _)| range.start()); // FIXME: We should panic on duplicates instead, but includes currently cause us to report // diagnostics twice for the calling module when both files are queried. @@ -289,7 +289,7 @@ pub(crate) fn check_diagnostics_with_config( for (e, _) in &actual { eprintln!( "Code in range {e:?} = {}", - &db.file_text(file_id)[usize::from(e.start())..usize::from(e.end())] + &db.file_text(file_id).text(&db)[usize::from(e.start())..usize::from(e.end())] ) } } diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs index a14e69030e325..f6fe705a98741 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs @@ -1,7 +1,10 @@ //! This module allows building an SSR MatchFinder by parsing the SSR rule //! from a comment. -use ide_db::{base_db::SourceDatabase, EditionedFileId, FilePosition, FileRange, RootDatabase}; +use ide_db::{ + base_db::{salsa::AsDynDatabase, RootQueryDb}, + EditionedFileId, FilePosition, FileRange, RootDatabase, +}; use syntax::{ ast::{self, AstNode, AstToken}, TextRange, @@ -17,7 +20,11 @@ pub fn ssr_from_comment( frange: FileRange, ) -> Option<(MatchFinder<'_>, TextRange)> { let comment = { - let file = db.parse(EditionedFileId::current_edition(frange.file_id)); + let editioned_file_id = EditionedFileId::current_edition(frange.file_id); + let file_id = + ide_db::base_db::EditionedFileId::new(db.as_dyn_database(), editioned_file_id); + + let file = db.parse(file_id); file.tree().syntax().token_at_offset(frange.range.start()).find_map(ast::Comment::cast) }?; let comment_text_without_prefix = comment.text().strip_prefix(comment.prefix()).unwrap(); diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs index 889258c94c535..971547ca1f8e6 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs @@ -80,8 +80,12 @@ pub use crate::{errors::SsrError, from_comment::ssr_from_comment, matching::Matc use crate::{errors::bail, matching::MatchFailureReason}; use hir::{FileRange, Semantics}; +use ide_db::symbol_index::SymbolsDatabase; use ide_db::text_edit::TextEdit; -use ide_db::{base_db::SourceDatabase, EditionedFileId, FileId, FxHashMap, RootDatabase}; +use ide_db::{ + base_db::{salsa::AsDynDatabase, SourceDatabase}, + EditionedFileId, FileId, FxHashMap, RootDatabase, +}; use resolving::ResolvedRule; use syntax::{ast, AstNode, SyntaxNode, TextRange}; @@ -137,10 +141,11 @@ impl<'db> MatchFinder<'db> { /// Constructs an instance using the start of the first file in `db` as the lookup context. pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result, SsrError> { - use ide_db::base_db::SourceRootDatabase; - use ide_db::symbol_index::SymbolsDatabase; - if let Some(first_file_id) = - db.local_roots().iter().next().and_then(|root| db.source_root(*root).iter().next()) + if let Some(first_file_id) = db + .local_roots() + .iter() + .next() + .and_then(|root| db.source_root(*root).source_root(db).iter().next()) { MatchFinder::in_context( db, @@ -184,7 +189,7 @@ impl<'db> MatchFinder<'db> { replacing::matches_to_edit( self.sema.db, &matches, - &self.sema.db.file_text(file_id), + &self.sema.db.file_text(file_id).text(self.sema.db), &self.rules, ), ) @@ -223,9 +228,12 @@ impl<'db> MatchFinder<'db> { file_id: EditionedFileId, snippet: &str, ) -> Vec { - let file = self.sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(self.sema.db.as_dyn_database(), file_id); + + let file = self.sema.parse(editioned_file_id_wrapper); let mut res = Vec::new(); - let file_text = self.sema.db.file_text(file_id.into()); + let file_text = self.sema.db.file_text(file_id.into()).text(self.sema.db); let mut remaining_text = &*file_text; let mut base = 0; let len = snippet.len() as u32; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index e219ba4bf6398..d32ba06f1eb4f 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -7,7 +7,7 @@ use crate::{ SsrMatches, }; use hir::{FileRange, ImportPathConfig, Semantics}; -use ide_db::{base_db::SourceDatabase, FxHashMap}; +use ide_db::{base_db::RootQueryDb, FxHashMap}; use std::{cell::Cell, iter::Peekable}; use syntax::{ ast::{self, AstNode, AstToken, HasGenericArgs}, diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs index 270ee0b3ec967..8c98d8de9183e 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs @@ -1,7 +1,7 @@ //! This module is responsible for resolving paths within rules. use hir::AsAssocItem; -use ide_db::FxHashMap; +use ide_db::{base_db::salsa::AsDynDatabase, FxHashMap}; use parsing::Placeholder; use syntax::{ ast::{self, HasGenericArgs}, @@ -198,7 +198,12 @@ impl<'db> ResolutionScope<'db> { resolve_context: hir::FilePosition, ) -> Option> { use syntax::ast::AstNode; - let file = sema.parse(resolve_context.file_id); + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + sema.db.as_dyn_database(), + resolve_context.file_id, + ); + + let file = sema.parse(editioned_file_id_wrapper); // Find a node at the requested position, falling back to the whole file. let node = file .syntax() diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs index b1cade39266a0..b094712e1bd56 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs @@ -7,6 +7,7 @@ use crate::{ }; use hir::FileRange; use ide_db::{ + base_db::salsa::AsDynDatabase, defs::Definition, search::{SearchScope, UsageSearchResult}, EditionedFileId, FileId, FxHashSet, @@ -74,7 +75,12 @@ impl MatchFinder<'_> { resolved_path: &ResolvedPath, file_range: FileRange, ) -> Vec { - let file = self.sema.parse(file_range.file_id); + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + self.sema.db.as_dyn_database(), + file_range.file_id, + ); + + let file = self.sema.parse(editioned_file_id_wrapper); let depth = resolved_path.depth as usize; let offset = file_range.range.start(); @@ -156,10 +162,10 @@ impl MatchFinder<'_> { fn search_files_do(&self, mut callback: impl FnMut(FileId)) { if self.restrict_ranges.is_empty() { // Unrestricted search. - use ide_db::base_db::SourceRootDatabase; + use ide_db::base_db::SourceDatabase; use ide_db::symbol_index::SymbolsDatabase; for &root in self.sema.db.local_roots().iter() { - let sr = self.sema.db.source_root(root); + let sr = self.sema.db.source_root(root).source_root(self.sema.db); for file_id in sr.iter() { callback(file_id); } diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs index d783e1952526c..0b510c9c6b244 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs @@ -1,7 +1,7 @@ use expect_test::{expect, Expect}; use hir::{FilePosition, FileRange}; use ide_db::{ - base_db::{ra_salsa::Durability, SourceDatabase}, + base_db::{salsa::Durability, SourceDatabase}, EditionedFileId, FxHashSet, }; use test_utils::RangeOrOffset; @@ -114,7 +114,7 @@ fn assert_ssr_transforms(rules: &[&str], input: &str, expected: Expect) { } // Note, db.file_text is not necessarily the same as `input`, since fixture parsing alters // stuff. - let mut actual = db.file_text(position.file_id.into()).to_string(); + let mut actual = db.file_text(position.file_id.into()).text(&db).to_string(); edits[&position.file_id.into()].apply(&mut actual); expected.assert_eq(&actual); } diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 8d2ca33bf254d..0acb129e93986 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -12,7 +12,7 @@ use url::Url; use hir::{db::HirDatabase, sym, Adt, AsAssocItem, AssocItem, AssocItemContainer, HasAttrs}; use ide_db::{ - base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, SourceDatabase}, + base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, RootQueryDb}, defs::{Definition, NameClass, NameRefClass}, documentation::{docs_with_rangemap, Documentation, HasDocs}, helpers::pick_best_token, diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs index b09e3a3c8047c..d70a3f9706cfd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs @@ -43,7 +43,7 @@ fn check_external_docs( fn check_rewrite(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let (analysis, position) = fixture::position(ra_fixture); - let sema = &Semantics::new(&*analysis.db); + let sema = &Semantics::new(&analysis.db); let (cursor_def, docs) = def_under_cursor(sema, &position); let res = rewrite_links(sema.db, docs.as_str(), cursor_def); expect.assert_eq(&res) @@ -54,7 +54,7 @@ fn check_doc_links(#[rust_analyzer::rust_fixture] ra_fixture: &str) { let (analysis, position, mut expected) = fixture::annotations(ra_fixture); expected.sort_by_key(key_fn); - let sema = &Semantics::new(&*analysis.db); + let sema = &Semantics::new(&analysis.db); let (cursor_def, docs) = def_under_cursor(sema, &position); let defs = extract_definitions_from_docs(&docs); let actual: Vec<_> = defs diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index ad4308e06a14b..2347e2e8a36d8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -234,7 +234,6 @@ fn _format( file_id: FileId, expansion: &str, ) -> Option { - use ide_db::base_db::{FileLoader, SourceDatabase}; // hack until we get hygiene working (same character amount to preserve formatting as much as possible) const DOLLAR_CRATE_REPLACE: &str = "__r_a_"; const BUILTIN_REPLACE: &str = "builtin__POUND"; @@ -248,8 +247,9 @@ fn _format( }; let expansion = format!("{prefix}{expansion}{suffix}"); - let &crate_id = db.relevant_crates(file_id).iter().next()?; - let edition = db.crate_graph()[crate_id].edition; + let upcast_db = ide_db::base_db::Upcast::::upcast(db); + let &crate_id = upcast_db.relevant_crates(file_id).iter().next()?; + let edition = upcast_db.crate_graph()[crate_id].edition; #[allow(clippy::disallowed_methods)] let mut cmd = std::process::Command::new(toolchain::Tool::Rustfmt.path()); diff --git a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs index 5ed2144430741..0e5bb89b6b717 100644 --- a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs +++ b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs @@ -1,5 +1,5 @@ use ide_db::{ - base_db::{CrateOrigin, SourceDatabase}, + base_db::{CrateOrigin, RootQueryDb}, FileId, FxIndexSet, RootDatabase, }; diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs index 60a904233a9a5..84138986f66ba 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs @@ -10,7 +10,7 @@ use hir::{ ModuleDef, Semantics, }; use ide_db::{ - base_db::{AnchoredPath, FileLoader, SourceDatabase}, + base_db::{AnchoredPath, RootQueryDb, SourceDatabase, Upcast}, defs::{Definition, IdentClass}, famous_defs::FamousDefs, helpers::pick_best_token, @@ -216,8 +216,9 @@ fn try_lookup_include_path( } let path = token.value().ok()?; - let file_id = sema.db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?; - let size = sema.db.file_text(file_id).len().try_into().ok()?; + let file_id = Upcast::::upcast(sema.db) + .resolve_path(AnchoredPath { anchor: file_id, path: &path })?; + let size = sema.db.file_text(file_id).text(sema.db).len().try_into().ok()?; Some(NavigationTarget { file_id, full_range: TextRange::new(0.into(), size), diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs index 6463206596af5..0ef7eb503f64a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs +++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs @@ -2,6 +2,7 @@ use std::iter; use hir::{db, FilePosition, FileRange, HirFileId, InFile, Semantics}; use ide_db::{ + base_db::salsa::AsDynDatabase, defs::{Definition, IdentClass}, helpers::pick_best_token, search::{FileReference, ReferenceCategory, SearchScope}, @@ -60,7 +61,10 @@ pub(crate) fn highlight_related( let file_id = sema .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); - let syntax = sema.parse(file_id).syntax().clone(); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(sema.db.as_dyn_database(), file_id); + + let syntax = sema.parse(editioned_file_id_wrapper).syntax().clone(); let token = pick_best_token(syntax.token_at_offset(offset), |kind| match kind { T![?] => 4, // prefer `?` when the cursor is sandwiched like in `await$0?` diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index 31ef89a07cde1..5d888ceb5edb9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -8,7 +8,7 @@ use hir::{ MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, }; use ide_db::{ - base_db::SourceDatabase, + base_db::RootQueryDb, defs::Definition, documentation::HasDocs, famous_defs::FamousDefs, diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 6b470d921f7a7..736d355ef2276 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -47,7 +47,7 @@ fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { .unwrap(); let content = analysis.db.file_text(position.file_id); - let hovered_element = &content[hover.range]; + let hovered_element = &content.text(&analysis.db)[hover.range]; let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); expect.assert_eq(&actual) @@ -72,7 +72,7 @@ fn check_hover_fields_limit( .unwrap() .unwrap(); - let content = analysis.db.file_text(position.file_id); + let content = analysis.db.file_text(position.file_id).text(&analysis.db); let hovered_element = &content[hover.range]; let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); @@ -98,7 +98,7 @@ fn check_hover_enum_variants_limit( .unwrap() .unwrap(); - let content = analysis.db.file_text(position.file_id); + let content = analysis.db.file_text(position.file_id).text(&analysis.db); let hovered_element = &content[hover.range]; let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); @@ -124,7 +124,7 @@ fn check_assoc_count( .unwrap() .unwrap(); - let content = analysis.db.file_text(position.file_id); + let content = analysis.db.file_text(position.file_id).text(&analysis.db); let hovered_element = &content[hover.range]; let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); @@ -141,7 +141,7 @@ fn check_hover_no_links(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: .unwrap() .unwrap(); - let content = analysis.db.file_text(position.file_id); + let content = analysis.db.file_text(position.file_id).text(&analysis.db); let hovered_element = &content[hover.range]; let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); @@ -158,7 +158,7 @@ fn check_hover_no_memory_layout(#[rust_analyzer::rust_fixture] ra_fixture: &str, .unwrap() .unwrap(); - let content = analysis.db.file_text(position.file_id); + let content = analysis.db.file_text(position.file_id).text(&analysis.db); let hovered_element = &content[hover.range]; let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); @@ -179,7 +179,7 @@ fn check_hover_no_markdown(#[rust_analyzer::rust_fixture] ra_fixture: &str, expe .unwrap() .unwrap(); - let content = analysis.db.file_text(position.file_id); + let content = analysis.db.file_text(position.file_id).text(&analysis.db); let hovered_element = &content[hover.range]; let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 6babdff52a2be..3a709e71fbe70 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -8,7 +8,7 @@ use hir::{ sym, ClosureStyle, DisplayTarget, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef, ModuleDefId, Semantics, }; -use ide_db::{famous_defs::FamousDefs, FileRange, RootDatabase}; +use ide_db::{base_db::salsa::AsDynDatabase, famous_defs::FamousDefs, FileRange, RootDatabase}; use ide_db::{text_edit::TextEdit, FxHashSet}; use itertools::Itertools; use smallvec::{smallvec, SmallVec}; @@ -86,7 +86,9 @@ pub(crate) fn inlay_hints( let file_id = sema .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); - let file = sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(sema.db.as_dyn_database(), file_id); + let file = sema.parse(editioned_file_id_wrapper); let file = file.syntax(); let mut acc = Vec::new(); @@ -137,7 +139,9 @@ pub(crate) fn inlay_hints_resolve( let file_id = sema .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); - let file = sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(sema.db.as_dyn_database(), file_id); + let file = sema.parse(editioned_file_id_wrapper); let file = file.syntax(); let scope = sema.scope(file)?; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 4379153acaa17..592c8603964da 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -868,15 +868,15 @@ fn main() { //- minicore: fn fn main() { let x = || 2; - //^ {closure#0} + //^ {closure#26624} let y = |t: i32| x() + t; - //^ {closure#1} + //^ {closure#26625} let mut t = 5; //^ i32 let z = |k: i32| { t += k; }; - //^ {closure#2} + //^ {closure#26626} let p = (y, z); - //^ ({closure#1}, {closure#2}) + //^ ({closure#26625}, {closure#26626}) } "#, ); diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs index 74dad488b4d30..0499d8a447fbf 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -1,5 +1,5 @@ use hir::{ConstEvalError, DefWithBody, DisplayTarget, Semantics}; -use ide_db::{base_db::SourceRootDatabase, FilePosition, LineIndexDatabase, RootDatabase}; +use ide_db::{base_db::SourceDatabase, FilePosition, LineIndexDatabase, RootDatabase}; use std::time::{Duration, Instant}; use stdx::format_to; use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; @@ -35,10 +35,10 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura _ => return None, }; let span_formatter = |file_id, text_range: TextRange| { - let path = &db - .source_root(db.file_source_root(file_id)) - .path_for_file(&file_id) - .map(|x| x.to_string()); + let source_root = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); + + let path = source_root.path_for_file(&file_id).map(|x| x.to_string()); let path = path.as_deref().unwrap_or(""); match db.line_index(file_id).try_line_col(text_range.start()) { Some(line_col) => format!("file://{path}:{}:{}", line_col.line + 1, line_col.col), @@ -64,10 +64,9 @@ pub(crate) fn render_const_eval_error( display_target: DisplayTarget, ) -> String { let span_formatter = |file_id, text_range: TextRange| { - let path = &db - .source_root(db.file_source_root(file_id)) - .path_for_file(&file_id) - .map(|x| x.to_string()); + let source_root = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); + let path = source_root.path_for_file(&file_id).map(|x| x.to_string()); let path = path.as_deref().unwrap_or(""); match db.line_index(file_id).try_line_col(text_range.start()) { Some(line_col) => format!("file://{path}:{}:{}", line_col.line + 1, line_col.col), diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index 8ac1a96cc6524..dcb170f3f7b63 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -64,9 +64,9 @@ use fetch_crates::CrateInfo; use hir::{sym, ChangeWithProcMacros}; use ide_db::{ base_db::{ - ra_salsa::{self, ParallelDatabase}, - CrateOrigin, CrateWorkspaceData, Env, FileLoader, FileSet, SourceDatabase, - SourceRootDatabase, VfsPath, + salsa::{AsDynDatabase, Cancelled}, + CrateOrigin, CrateWorkspaceData, Env, FileSet, RootQueryDb, SourceDatabase, Upcast, + VfsPath, }, prime_caches, symbol_index, FxHashMap, FxIndexSet, LineIndexDatabase, }; @@ -125,7 +125,7 @@ pub use ide_completion::{ }; pub use ide_db::text_edit::{Indel, TextEdit}; pub use ide_db::{ - base_db::{Cancelled, CrateGraph, CrateId, FileChange, SourceRoot, SourceRootId}, + base_db::{CrateGraph, CrateId, FileChange, SourceRoot, SourceRootId}, documentation::Documentation, label::Label, line_index::{LineCol, LineIndex}, @@ -217,7 +217,7 @@ impl Default for AnalysisHost { /// `Analysis` are canceled (most method return `Err(Canceled)`). #[derive(Debug)] pub struct Analysis { - db: ra_salsa::Snapshot, + db: RootDatabase, } // As a general design guideline, `Analysis` API are intended to be independent @@ -276,12 +276,12 @@ impl Analysis { } pub fn source_root_id(&self, file_id: FileId) -> Cancellable { - self.with_db(|db| db.file_source_root(file_id)) + self.with_db(|db| db.file_source_root(file_id).source_root_id(db)) } pub fn is_local_source_root(&self, source_root_id: SourceRootId) -> Cancellable { self.with_db(|db| { - let sr = db.source_root(source_root_id); + let sr = db.source_root(source_root_id).source_root(db); !sr.is_library }) } @@ -295,18 +295,28 @@ impl Analysis { /// Gets the text of the source file. pub fn file_text(&self, file_id: FileId) -> Cancellable> { - self.with_db(|db| SourceDatabase::file_text(db, file_id)) + self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db)) } /// Gets the syntax tree of the file. pub fn parse(&self, file_id: FileId) -> Cancellable { // FIXME edition - self.with_db(|db| db.parse(EditionedFileId::current_edition(file_id)).tree()) + self.with_db(|db| { + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + self.db.as_dyn_database(), + EditionedFileId::current_edition(file_id), + ); + + db.parse(editioned_file_id_wrapper).tree() + }) } /// Returns true if this file belongs to an immutable library. pub fn is_library_file(&self, file_id: FileId) -> Cancellable { - self.with_db(|db| db.source_root(db.file_source_root(file_id)).is_library) + self.with_db(|db| { + let source_root = db.file_source_root(file_id).source_root_id(db); + db.source_root(source_root).source_root(db).is_library + }) } /// Gets the file's `LineIndex`: data structure to convert between absolute @@ -324,7 +334,11 @@ impl Analysis { /// supported). pub fn matching_brace(&self, position: FilePosition) -> Cancellable> { self.with_db(|db| { - let parse = db.parse(EditionedFileId::current_edition(position.file_id)); + let file_id = ide_db::base_db::EditionedFileId::new( + self.db.as_dyn_database(), + EditionedFileId::current_edition(position.file_id), + ); + let parse = db.parse(file_id); let file = parse.tree(); matching_brace::matching_brace(&file, position.offset) }) @@ -383,7 +397,11 @@ impl Analysis { /// stuff like trailing commas. pub fn join_lines(&self, config: &JoinLinesConfig, frange: FileRange) -> Cancellable { self.with_db(|db| { - let parse = db.parse(EditionedFileId::current_edition(frange.file_id)); + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + self.db.as_dyn_database(), + EditionedFileId::current_edition(frange.file_id), + ); + let parse = db.parse(editioned_file_id_wrapper); join_lines::join_lines(config, &parse.tree(), frange.range) }) } @@ -419,9 +437,12 @@ impl Analysis { pub fn file_structure(&self, file_id: FileId) -> Cancellable> { // FIXME: Edition self.with_db(|db| { - file_structure::file_structure( - &db.parse(EditionedFileId::current_edition(file_id)).tree(), - ) + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + self.db.as_dyn_database(), + EditionedFileId::current_edition(file_id), + ); + + file_structure::file_structure(&db.parse(editioned_file_id_wrapper).tree()) }) } @@ -450,9 +471,12 @@ impl Analysis { /// Returns the set of folding ranges. pub fn folding_ranges(&self, file_id: FileId) -> Cancellable> { self.with_db(|db| { - folding_ranges::folding_ranges( - &db.parse(EditionedFileId::current_edition(file_id)).tree(), - ) + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + self.db.as_dyn_database(), + EditionedFileId::current_edition(file_id), + ); + + folding_ranges::folding_ranges(&db.parse(editioned_file_id_wrapper).tree()) }) } @@ -589,7 +613,10 @@ impl Analysis { /// Returns crates that this file *might* belong to. pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable> { - self.with_db(|db| db.relevant_crates(file_id).iter().copied().collect()) + self.with_db(|db| { + let db = Upcast::::upcast(db); + db.relevant_crates(file_id).iter().copied().collect() + }) } /// Returns the edition of the given crate. @@ -828,7 +855,8 @@ impl Analysis { where F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe, { - Cancelled::catch(|| f(&self.db)) + let snap = self.db.snapshot(); + Cancelled::catch(|| f(&snap)) } } diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs index 6d82f9b0634b4..90cccca5e80f4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs +++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs @@ -1,6 +1,6 @@ use hir::{db::DefDatabase, Semantics}; use ide_db::{ - base_db::{CrateId, FileLoader}, + base_db::{CrateId, RootQueryDb, Upcast}, FileId, FilePosition, RootDatabase, }; use itertools::Itertools; @@ -54,7 +54,9 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec Vec { - db.relevant_crates(file_id) + let root_db = Upcast::::upcast(db); + root_db + .relevant_crates(file_id) .iter() .copied() .filter(|&crate_id| db.crate_def_map(crate_id).modules_for_file(file_id).next().is_some()) diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index 08e25dde60631..57d297700ad37 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -6,6 +6,7 @@ use hir::{AsAssocItem, HirFileIdExt, InFile, Semantics}; use ide_db::{ + base_db::salsa::AsDynDatabase, defs::{Definition, NameClass, NameRefClass}, rename::{bail, format_err, source_edit_from_references, IdentifierKind}, source_change::SourceChangeBuilder, @@ -85,7 +86,9 @@ pub(crate) fn rename( let file_id = sema .attach_first_edition(position.file_id) .ok_or_else(|| format_err!("No references found at position"))?; - let source_file = sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(db.as_dyn_database(), file_id); + let source_file = sema.parse(editioned_file_id_wrapper); let syntax = source_file.syntax(); let defs = find_definitions(&sema, syntax, position)?; diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index b8deed01fb7f2..33eef6d75c21a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -9,7 +9,7 @@ use hir::{ }; use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn}; use ide_db::{ - base_db::SourceDatabase, + base_db::RootQueryDb, defs::Definition, documentation::docs_from_attrs, helpers::visit_file_defs, diff --git a/src/tools/rust-analyzer/crates/ide/src/ssr.rs b/src/tools/rust-analyzer/crates/ide/src/ssr.rs index 5812a92b3893f..81b5988126519 100644 --- a/src/tools/rust-analyzer/crates/ide/src/ssr.rs +++ b/src/tools/rust-analyzer/crates/ide/src/ssr.rs @@ -59,7 +59,7 @@ mod tests { use expect_test::expect; use ide_assists::{Assist, AssistResolveStrategy}; use ide_db::{ - base_db::ra_salsa::Durability, symbol_index::SymbolsDatabase, FileRange, FxHashSet, + base_db::salsa::Durability, symbol_index::SymbolsDatabase, FileRange, FxHashSet, RootDatabase, }; use test_fixture::WithFixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 332aecf1e3cc5..ceea34b721373 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -3,7 +3,7 @@ use hir::{db::HirDatabase, Crate, HirFileIdExt, Module, Semantics}; use ide_db::{ - base_db::{SourceDatabase, SourceRootDatabase, VfsPath}, + base_db::{RootQueryDb, SourceDatabase, VfsPath}, defs::Definition, documentation::Documentation, famous_defs::FamousDefs, @@ -267,11 +267,11 @@ impl StaticIndex<'_> { analysis: &'a Analysis, vendored_libs_config: VendoredLibrariesConfig<'_>, ) -> StaticIndex<'a> { - let db = &*analysis.db; + let db = &analysis.db; let work = all_modules(db).into_iter().filter(|module| { let file_id = module.definition_source_file_id(db).original_file(db); - let source_root = db.file_source_root(file_id.into()); - let source_root = db.source_root(source_root); + let source_root = db.file_source_root(file_id.into()).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); let is_vendored = match vendored_libs_config { VendoredLibrariesConfig::Included { workspace_root } => source_root .path_for_file(&file_id.into()) diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index a44be67668ce3..47ac4ebf20e3b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -1,29 +1,8 @@ -use std::{fmt, marker::PhantomData}; - -use hir::{ - db::{AstIdMapQuery, AttrsQuery, BlockDefMapQuery, ParseMacroExpansionQuery}, - Attr, Attrs, ExpandResult, MacroFileId, Module, -}; -use ide_db::{ - base_db::{ - ra_salsa::{ - debug::{DebugQueryTable, TableEntry}, - Query, QueryTable, - }, - CompressedFileTextQuery, CrateData, ParseQuery, SourceDatabase, SourceRootId, - }, - symbol_index::ModuleSymbolsQuery, -}; -use ide_db::{ - symbol_index::{LibrarySymbolsQuery, SymbolIndex}, - RootDatabase, -}; +use ide_db::base_db::{CrateData, RootQueryDb, Upcast}; +use ide_db::RootDatabase; use itertools::Itertools; -use profile::{memory_usage, Bytes}; -use span::{EditionedFileId, FileId}; +use span::FileId; use stdx::format_to; -use syntax::{ast, Parse, SyntaxNode}; -use triomphe::Arc; // Feature: Status // @@ -37,17 +16,17 @@ use triomphe::Arc; pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { let mut buf = String::new(); - format_to!(buf, "{}\n", collect_query(CompressedFileTextQuery.in_db(db))); - format_to!(buf, "{}\n", collect_query(ParseQuery.in_db(db))); - format_to!(buf, "{}\n", collect_query(ParseMacroExpansionQuery.in_db(db))); - format_to!(buf, "{}\n", collect_query(LibrarySymbolsQuery.in_db(db))); - format_to!(buf, "{}\n", collect_query(ModuleSymbolsQuery.in_db(db))); - format_to!(buf, "{} in total\n", memory_usage()); + // format_to!(buf, "{}\n", collect_query(CompressedFileTextQuery.in_db(db))); + // format_to!(buf, "{}\n", collect_query(ParseQuery.in_db(db))); + // format_to!(buf, "{}\n", collect_query(ParseMacroExpansionQuery.in_db(db))); + // format_to!(buf, "{}\n", collect_query(LibrarySymbolsQuery.in_db(db))); + // format_to!(buf, "{}\n", collect_query(ModuleSymbolsQuery.in_db(db))); + // format_to!(buf, "{} in total\n", memory_usage()); - format_to!(buf, "\nDebug info:\n"); - format_to!(buf, "{}\n", collect_query(AttrsQuery.in_db(db))); - format_to!(buf, "{} ast id maps\n", collect_query_count(AstIdMapQuery.in_db(db))); - format_to!(buf, "{} block def maps\n", collect_query_count(BlockDefMapQuery.in_db(db))); + // format_to!(buf, "\nDebug info:\n"); + // format_to!(buf, "{}\n", collect_query(AttrsQuery.in_db(db))); + // format_to!(buf, "{} ast id maps\n", collect_query_count(AstIdMapQuery.in_db(db))); + // format_to!(buf, "{} block def maps\n", collect_query_count(BlockDefMapQuery.in_db(db))); if let Some(file_id) = file_id { format_to!(buf, "\nCrates for file {}:\n", file_id.index()); @@ -55,7 +34,8 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { if crates.is_empty() { format_to!(buf, "Does not belong to any crate"); } - let crate_graph = db.crate_graph(); + + let crate_graph = Upcast::::upcast(db).crate_graph(); for crate_id in crates { let CrateData { root_file_id, @@ -97,190 +77,3 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { buf.trim().to_owned() } - -fn collect_query<'q, Q>(table: QueryTable<'q, Q>) -> ::Collector -where - QueryTable<'q, Q>: DebugQueryTable, - Q: QueryCollect, - ::Storage: 'q, - ::Collector: StatCollect< - as DebugQueryTable>::Key, - as DebugQueryTable>::Value, - >, -{ - struct StatCollectorWrapper(C); - impl, K, V> FromIterator> for StatCollectorWrapper { - fn from_iter(iter: T) -> StatCollectorWrapper - where - T: IntoIterator>, - { - let mut res = C::default(); - for entry in iter { - res.collect_entry(entry.key, entry.value); - } - StatCollectorWrapper(res) - } - } - table.entries::::Collector>>().0 -} - -fn collect_query_count<'q, Q>(table: QueryTable<'q, Q>) -> usize -where - QueryTable<'q, Q>: DebugQueryTable, - Q: Query, - ::Storage: 'q, -{ - struct EntryCounter(usize); - impl FromIterator> for EntryCounter { - fn from_iter(iter: T) -> EntryCounter - where - T: IntoIterator>, - { - EntryCounter(iter.into_iter().count()) - } - } - table.entries::().0 -} - -trait QueryCollect: Query { - type Collector; -} - -impl QueryCollect for LibrarySymbolsQuery { - type Collector = SymbolsStats; -} - -impl QueryCollect for ParseQuery { - type Collector = SyntaxTreeStats; -} - -impl QueryCollect for ParseMacroExpansionQuery { - type Collector = SyntaxTreeStats; -} - -impl QueryCollect for CompressedFileTextQuery { - type Collector = FilesStats; -} - -impl QueryCollect for ModuleSymbolsQuery { - type Collector = SymbolsStats; -} - -impl QueryCollect for AttrsQuery { - type Collector = AttrsStats; -} - -trait StatCollect: Default { - fn collect_entry(&mut self, key: K, value: Option); -} - -#[derive(Default)] -struct FilesStats { - total: usize, - size: Bytes, -} - -impl fmt::Display for FilesStats { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(fmt, "{} of files", self.size) - } -} - -impl StatCollect> for FilesStats { - fn collect_entry(&mut self, _: FileId, value: Option>) { - self.total += 1; - self.size += value.unwrap().len(); - } -} - -#[derive(Default)] -pub(crate) struct SyntaxTreeStats { - total: usize, - pub(crate) retained: usize, -} - -impl fmt::Display for SyntaxTreeStats { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - fmt, - "{} trees, {} preserved{}", - self.total, - self.retained, - if MACROS { " (macros)" } else { "" } - ) - } -} - -impl StatCollect> for SyntaxTreeStats { - fn collect_entry(&mut self, _: EditionedFileId, value: Option>) { - self.total += 1; - self.retained += value.is_some() as usize; - } -} - -impl StatCollect, M)>> for SyntaxTreeStats { - fn collect_entry( - &mut self, - _: MacroFileId, - value: Option, M)>>, - ) { - self.total += 1; - self.retained += value.is_some() as usize; - } -} - -struct SymbolsStats { - total: usize, - size: Bytes, - phantom: PhantomData, -} - -impl Default for SymbolsStats { - fn default() -> Self { - Self { total: Default::default(), size: Default::default(), phantom: PhantomData } - } -} - -impl fmt::Display for SymbolsStats { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(fmt, "{} of module index symbols ({})", self.size, self.total) - } -} -impl fmt::Display for SymbolsStats { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(fmt, "{} of library index symbols ({})", self.size, self.total) - } -} -impl StatCollect> for SymbolsStats { - fn collect_entry(&mut self, _: Key, value: Option>) { - if let Some(symbols) = value { - self.total += symbols.len(); - self.size += symbols.memory_size(); - } - } -} - -#[derive(Default)] -struct AttrsStats { - entries: usize, - total: usize, -} - -impl fmt::Display for AttrsStats { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let size = self.entries * size_of::() + self.total * size_of::(); - let size = Bytes::new(size as _); - write!( - fmt, - "{} attribute query entries, {} total attributes ({} for storing entries)", - self.entries, self.total, size - ) - } -} - -impl StatCollect for AttrsStats { - fn collect_entry(&mut self, _: Key, value: Option) { - self.entries += 1; - self.total += value.map_or(0, |it| it.len()); - } -} diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index 83082496d5b64..ef5d480b49c70 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -18,7 +18,9 @@ use either::Either; use hir::{ DefWithBody, HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics, }; -use ide_db::{FxHashMap, FxHashSet, Ranker, RootDatabase, SymbolKind}; +use ide_db::{ + base_db::salsa::AsDynDatabase, FxHashMap, FxHashSet, Ranker, RootDatabase, SymbolKind, +}; use span::EditionedFileId; use syntax::{ ast::{self, IsString}, @@ -203,7 +205,9 @@ pub(crate) fn highlight( // Determine the root based on the given range. let (root, range_to_highlight) = { - let file = sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(db.as_dyn_database(), file_id); + let file = sema.parse(editioned_file_id_wrapper); let source_file = file.syntax(); match range_to_highlight { Some(range) => { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs index 07d40bafeba17..6a03da6a6eaa5 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs @@ -1,6 +1,7 @@ //! Renders a bit of code as HTML. use hir::Semantics; +use ide_db::base_db::salsa::AsDynDatabase; use oorandom::Rand32; use span::EditionedFileId; use stdx::format_to; @@ -16,7 +17,9 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo let file_id = sema .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); - let file = sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(db.as_dyn_database(), file_id); + let file = sema.parse(editioned_file_id_wrapper); let file = file.syntax(); fn rainbowify(seed: u64) -> String { let mut rng = Rand32::new(seed); diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html index 7f6b4c2c880e1..e1a8d876c417b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html @@ -41,14 +41,14 @@ .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
fn main() {
-    let hello = "hello";
-    let x = hello.to_string();
-    let y = hello.to_string();
+    let hello = "hello";
+    let x = hello.to_string();
+    let y = hello.to_string();
 
-    let x = "other color please!";
-    let y = x.to_string();
+    let x = "other color please!";
+    let y = x.to_string();
 }
 
 fn bar() {
-    let mut hello = "hello";
+    let mut hello = "hello";
 }
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs index 30b1d4c39b301..68f5c72d20531 100644 --- a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs +++ b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs @@ -2,7 +2,7 @@ use hir::{Crate, Module, ModuleDef, Semantics}; use ide_db::{ - base_db::{CrateGraph, CrateId, SourceDatabase}, + base_db::{CrateGraph, CrateId, RootQueryDb}, FileId, RootDatabase, }; use syntax::TextRange; diff --git a/src/tools/rust-analyzer/crates/ide/src/typing.rs b/src/tools/rust-analyzer/crates/ide/src/typing.rs index 8c9dd05145272..f583aa801eaac 100644 --- a/src/tools/rust-analyzer/crates/ide/src/typing.rs +++ b/src/tools/rust-analyzer/crates/ide/src/typing.rs @@ -15,10 +15,13 @@ mod on_enter; +use ide_db::{ + base_db::{salsa::AsDynDatabase, RootQueryDb}, + FilePosition, RootDatabase, +}; +use span::{Edition, EditionedFileId}; use std::iter; -use ide_db::{base_db::SourceDatabase, FilePosition, RootDatabase}; -use span::{Edition, EditionedFileId}; use syntax::{ algo::{ancestors_at_offset, find_node_at_offset}, ast::{self, edit::IndentLevel, AstToken}, @@ -73,7 +76,11 @@ pub(crate) fn on_char_typed( // FIXME: We are hitting the database here, if we are unlucky this call might block momentarily // causing the editor to feel sluggish! let edition = Edition::CURRENT_FIXME; - let file = &db.parse(EditionedFileId::new(position.file_id, edition)); + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + db.as_dyn_database(), + EditionedFileId::new(position.file_id, edition), + ); + let file = &db.parse(editioned_file_id_wrapper); let char_matches_position = file.tree().syntax().text().char_at(position.offset) == Some(char_typed); if !stdx::always!(char_matches_position) { diff --git a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs index c6d1c283f4eca..8cadb61040390 100644 --- a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs +++ b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs @@ -1,8 +1,8 @@ //! Handles the `Enter` key press. At the momently, this only continues //! comments, but should handle indent some time in the future as well. -use ide_db::RootDatabase; -use ide_db::{base_db::SourceDatabase, FilePosition}; +use ide_db::base_db::RootQueryDb; +use ide_db::{base_db::salsa::AsDynDatabase, FilePosition, RootDatabase}; use span::EditionedFileId; use syntax::{ algo::find_node_at_offset, @@ -51,7 +51,11 @@ use ide_db::text_edit::TextEdit; // // ![On Enter](https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif) pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option { - let parse = db.parse(EditionedFileId::current_edition(position.file_id)); + let editioned_file_id_wrapper = ide_db::base_db::EditionedFileId::new( + db.as_dyn_database(), + EditionedFileId::current_edition(position.file_id), + ); + let parse = db.parse(editioned_file_id_wrapper); let file = parse.tree(); let token = file.syntax().token_at_offset(position.offset).left_biased()?; diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs index eb6eb7da1e90a..eeb65ac038932 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs @@ -1,6 +1,6 @@ use dot::{Id, LabelText}; use ide_db::{ - base_db::{CrateGraph, CrateId, Dependency, SourceDatabase, SourceRootDatabase}, + base_db::{CrateGraph, CrateId, Dependency, RootQueryDb, SourceDatabase, Upcast}, FxHashSet, RootDatabase, }; use triomphe::Arc; @@ -16,7 +16,7 @@ use triomphe::Arc; // |---------|-------------| // | VS Code | **rust-analyzer: View Crate Graph** | pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result { - let crate_graph = db.crate_graph(); + let crate_graph = Upcast::::upcast(db).crate_graph(); let crates_to_render = crate_graph .iter() .filter(|krate| { @@ -24,8 +24,9 @@ pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result [joint] 0:0@93..94#2 - PUNCH , [alone] 0:0@94..95#2 + SUBTREE $$ 1:0@0..20#4294967037 1:0@0..20#4294967037 + IDENT struct 0:0@34..40#4294967037 + IDENT MyTraitMap2 1:0@8..19#4294967037 + SUBTREE {} 0:0@48..49#4294967037 0:0@100..101#4294967037 + IDENT map 0:0@58..61#4294967037 + PUNCH : [alone] 0:0@61..62#4294967037 + PUNCH : [joint] 0:0@63..64#4294967037 + PUNCH : [alone] 0:0@64..65#4294967037 + IDENT std 0:0@65..68#4294967037 + PUNCH : [joint] 0:0@68..69#4294967037 + PUNCH : [alone] 0:0@69..70#4294967037 + IDENT collections 0:0@70..81#4294967037 + PUNCH : [joint] 0:0@81..82#4294967037 + PUNCH : [alone] 0:0@82..83#4294967037 + IDENT HashSet 0:0@83..90#4294967037 + PUNCH < [alone] 0:0@90..91#4294967037 + SUBTREE () 0:0@91..92#4294967037 0:0@92..93#4294967037 + PUNCH > [joint] 0:0@93..94#4294967037 + PUNCH , [alone] 0:0@94..95#4294967037 struct MyTraitMap2 { map: ::std::collections::HashSet<()>, @@ -179,28 +179,28 @@ fn main() { } "#, expect![[r#" - SUBTREE $$ 1:0@0..63#2 1:0@0..63#2 - IDENT fn 1:0@1..3#2 - IDENT main 1:0@4..8#2 - SUBTREE () 1:0@8..9#2 1:0@9..10#2 - SUBTREE {} 1:0@11..12#2 1:0@61..62#2 - LITERAL Integer 1 1:0@17..18#2 - PUNCH ; [alone] 1:0@18..19#2 - LITERAL Float 1.0 1:0@24..27#2 - PUNCH ; [alone] 1:0@27..28#2 - SUBTREE () 1:0@33..34#2 1:0@39..40#2 - SUBTREE () 1:0@34..35#2 1:0@37..38#2 - LITERAL Integer 1 1:0@35..36#2 - PUNCH , [alone] 1:0@36..37#2 - PUNCH , [alone] 1:0@38..39#2 - PUNCH . [alone] 1:0@40..41#2 - LITERAL Float 0.0 1:0@41..44#2 - PUNCH ; [alone] 1:0@44..45#2 - IDENT let 1:0@50..53#2 - IDENT x 1:0@54..55#2 - PUNCH = [alone] 1:0@56..57#2 - LITERAL Integer 1 1:0@58..59#2 - PUNCH ; [alone] 1:0@59..60#2 + SUBTREE $$ 1:0@0..63#4294967037 1:0@0..63#4294967037 + IDENT fn 1:0@1..3#4294967037 + IDENT main 1:0@4..8#4294967037 + SUBTREE () 1:0@8..9#4294967037 1:0@9..10#4294967037 + SUBTREE {} 1:0@11..12#4294967037 1:0@61..62#4294967037 + LITERAL Integer 1 1:0@17..18#4294967037 + PUNCH ; [alone] 1:0@18..19#4294967037 + LITERAL Float 1.0 1:0@24..27#4294967037 + PUNCH ; [alone] 1:0@27..28#4294967037 + SUBTREE () 1:0@33..34#4294967037 1:0@39..40#4294967037 + SUBTREE () 1:0@34..35#4294967037 1:0@37..38#4294967037 + LITERAL Integer 1 1:0@35..36#4294967037 + PUNCH , [alone] 1:0@36..37#4294967037 + PUNCH , [alone] 1:0@38..39#4294967037 + PUNCH . [alone] 1:0@40..41#4294967037 + LITERAL Float 0.0 1:0@41..44#4294967037 + PUNCH ; [alone] 1:0@44..45#4294967037 + IDENT let 1:0@50..53#4294967037 + IDENT x 1:0@54..55#4294967037 + PUNCH = [alone] 1:0@56..57#4294967037 + LITERAL Integer 1 1:0@58..59#4294967037 + PUNCH ; [alone] 1:0@59..60#4294967037 fn main(){ 1; @@ -226,14 +226,14 @@ fn expr_2021() { const { 1 }, "#, expect![[r#" - SUBTREE $$ 1:0@0..25#2 1:0@0..25#2 - IDENT _ 1:0@5..6#2 - PUNCH ; [joint] 0:0@36..37#2 - SUBTREE () 0:0@34..35#2 0:0@34..35#2 - IDENT const 1:0@12..17#2 - SUBTREE {} 1:0@18..19#2 1:0@22..23#2 - LITERAL Integer 1 1:0@20..21#2 - PUNCH ; [alone] 0:0@39..40#2 + SUBTREE $$ 1:0@0..25#4294967037 1:0@0..25#4294967037 + IDENT _ 1:0@5..6#4294967037 + PUNCH ; [joint] 0:0@36..37#4294967037 + SUBTREE () 0:0@34..35#4294967037 0:0@34..35#4294967037 + IDENT const 1:0@12..17#4294967037 + SUBTREE {} 1:0@18..19#4294967037 1:0@22..23#4294967037 + LITERAL Integer 1 1:0@20..21#4294967037 + PUNCH ; [alone] 0:0@39..40#4294967037 _; (const { @@ -254,13 +254,13 @@ fn expr_2021() { expect![[r#" ExpandError { inner: ( - 1:0@5..6#2, + 1:0@5..6#4294967037, NoMatchingRule, ), } - SUBTREE $$ 1:0@0..8#2 1:0@0..8#2 - PUNCH ; [alone] 0:0@39..40#2 + SUBTREE $$ 1:0@0..8#4294967037 1:0@0..8#4294967037 + PUNCH ; [alone] 0:0@39..40#4294967037 ;"#]], ); @@ -278,13 +278,13 @@ fn expr_2021() { expect![[r#" ExpandError { inner: ( - 1:0@5..10#2, + 1:0@5..10#4294967037, NoMatchingRule, ), } - SUBTREE $$ 1:0@0..18#2 1:0@0..18#2 - PUNCH ; [alone] 0:0@39..40#2 + SUBTREE $$ 1:0@0..18#4294967037 1:0@0..18#4294967037 + PUNCH ; [alone] 0:0@39..40#4294967037 ;"#]], ); @@ -304,26 +304,26 @@ fn expr_2021() { break 'foo bar, "#, expect![[r#" - SUBTREE $$ 1:0@0..76#2 1:0@0..76#2 - LITERAL Integer 4 1:0@5..6#2 - PUNCH ; [joint] 0:0@41..42#2 - LITERAL Str literal 1:0@12..21#2 - PUNCH ; [joint] 0:0@41..42#2 - SUBTREE () 0:0@39..40#2 0:0@39..40#2 - IDENT funcall 1:0@27..34#2 - SUBTREE () 1:0@34..35#2 1:0@35..36#2 - PUNCH ; [joint] 0:0@41..42#2 - SUBTREE () 0:0@39..40#2 0:0@39..40#2 - IDENT future 1:0@42..48#2 - PUNCH . [alone] 1:0@48..49#2 - IDENT await 1:0@49..54#2 - PUNCH ; [joint] 0:0@41..42#2 - SUBTREE () 0:0@39..40#2 0:0@39..40#2 - IDENT break 1:0@60..65#2 - PUNCH ' [joint] 1:0@66..67#2 - IDENT foo 1:0@67..70#2 - IDENT bar 1:0@71..74#2 - PUNCH ; [alone] 0:0@44..45#2 + SUBTREE $$ 1:0@0..76#4294967037 1:0@0..76#4294967037 + LITERAL Integer 4 1:0@5..6#4294967037 + PUNCH ; [joint] 0:0@41..42#4294967037 + LITERAL Str literal 1:0@12..21#4294967037 + PUNCH ; [joint] 0:0@41..42#4294967037 + SUBTREE () 0:0@39..40#4294967037 0:0@39..40#4294967037 + IDENT funcall 1:0@27..34#4294967037 + SUBTREE () 1:0@34..35#4294967037 1:0@35..36#4294967037 + PUNCH ; [joint] 0:0@41..42#4294967037 + SUBTREE () 0:0@39..40#4294967037 0:0@39..40#4294967037 + IDENT future 1:0@42..48#4294967037 + PUNCH . [alone] 1:0@48..49#4294967037 + IDENT await 1:0@49..54#4294967037 + PUNCH ; [joint] 0:0@41..42#4294967037 + SUBTREE () 0:0@39..40#4294967037 0:0@39..40#4294967037 + IDENT break 1:0@60..65#4294967037 + PUNCH ' [joint] 1:0@66..67#4294967037 + IDENT foo 1:0@67..70#4294967037 + IDENT bar 1:0@71..74#4294967037 + PUNCH ; [alone] 0:0@44..45#4294967037 4; "literal"; @@ -345,13 +345,13 @@ fn expr_2021() { expect![[r#" ExpandError { inner: ( - 1:0@5..6#2, + 1:0@5..6#4294967037, NoMatchingRule, ), } - SUBTREE $$ 1:0@0..8#2 1:0@0..8#2 - PUNCH ; [alone] 0:0@44..45#2 + SUBTREE $$ 1:0@0..8#4294967037 1:0@0..8#4294967037 + PUNCH ; [alone] 0:0@44..45#4294967037 ;"#]], ); diff --git a/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml index 24e059f40bee5..99d1bf7e2c7ce 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml +++ b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml @@ -17,7 +17,7 @@ heck = "0.5.0" proc-macro2 = "1.0" quote = "1.0" syn = { version = "2.0", features = ["full", "extra-traits"] } -salsa = { version = "0.19.0" } +salsa.workspace = true [dev-dependencies] expect-test = "1.5.0" diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index dee76ee15c3df..a391a01fae74e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -22,21 +22,15 @@ use ide::{ Analysis, AnalysisHost, AnnotationConfig, DiagnosticsConfig, Edition, InlayFieldsToResolve, InlayHintsConfig, LineCol, RootDatabase, }; -use ide_db::{ - base_db::{ - ra_salsa::{self, debug::DebugQueryTable, ParallelDatabase}, - SourceDatabase, SourceRootDatabase, - }, - EditionedFileId, LineIndexDatabase, SnippetCap, -}; +use ide_db::{base_db::SourceDatabase, EditionedFileId, LineIndexDatabase, SnippetCap}; use itertools::Itertools; use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice}; use oorandom::Rand32; -use profile::{Bytes, StopWatch}; +use profile::StopWatch; use project_model::{CargoConfig, CfgOverrides, ProjectManifest, ProjectWorkspace, RustLibSource}; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; -use syntax::{AstNode, SyntaxNode}; +use syntax::AstNode; use vfs::{AbsPathBuf, Vfs, VfsPath}; use crate::cli::{ @@ -46,14 +40,6 @@ use crate::cli::{ report_metric, Verbosity, }; -/// Need to wrap Snapshot to provide `Clone` impl for `map_with` -struct Snap(DB); -impl Clone for Snap> { - fn clone(&self) -> Snap> { - Snap(self.0.snapshot()) - } -} - impl flags::AnalysisStats { pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { let mut rng = { @@ -129,10 +115,13 @@ impl flags::AnalysisStats { let mut item_tree_sw = self.stop_watch(); let mut num_item_trees = 0; - let source_roots = - krates.iter().cloned().map(|krate| db.file_source_root(krate.root_file(db))).unique(); + let source_roots = krates + .iter() + .cloned() + .map(|krate| db.file_source_root(krate.root_file(db)).source_root_id(db)) + .unique(); for source_root_id in source_roots { - let source_root = db.source_root(source_root_id); + let source_root = db.source_root(source_root_id).source_root(db); if !source_root.is_library || self.with_deps { for file_id in source_root.iter() { if let Some(p) = source_root.path_for_file(&file_id) { @@ -157,8 +146,9 @@ impl flags::AnalysisStats { let module = krate.root_module(); let file_id = module.definition_source_file_id(db); let file_id = file_id.original_file(db); - let source_root = db.file_source_root(file_id.into()); - let source_root = db.source_root(source_root); + + let source_root = db.file_source_root(file_id.into()).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); if !source_root.is_library || self.with_deps { num_crates += 1; visit_queue.push(module); @@ -268,17 +258,21 @@ impl flags::AnalysisStats { report_metric("total memory", total_span.memory.allocated.megabytes() as u64, "MB"); if self.source_stats { - let mut total_file_size = Bytes::default(); - for e in ide_db::base_db::ParseQuery.in_db(db).entries::>() { - total_file_size += syntax_len(db.parse(e.key).syntax_node()) - } - - let mut total_macro_file_size = Bytes::default(); - for e in hir::db::ParseMacroExpansionQuery.in_db(db).entries::>() { - let val = db.parse_macro_expansion(e.key).value.0; - total_macro_file_size += syntax_len(val.syntax_node()) - } - eprintln!("source files: {total_file_size}, macro files: {total_macro_file_size}"); + // FIXME(salsa-transition): bring back stats for ParseQuery (file size) + // and ParseMacroExpansionQuery (mcaro expansion "file") size whenever we implement + // Salsa's memory usage tracking works with tracked functions. + + // let mut total_file_size = Bytes::default(); + // for e in ide_db::base_db::ParseQuery.in_db(db).entries::>() { + // total_file_size += syntax_len(db.parse(e.key).syntax_node()) + // } + + // let mut total_macro_file_size = Bytes::default(); + // for e in hir::db::ParseMacroExpansionQuery.in_db(db).entries::>() { + // let val = db.parse_macro_expansion(e.key).value.0; + // total_macro_file_size += syntax_len(val.syntax_node()) + // } + // eprintln!("source files: {total_file_size}, macro files: {total_macro_file_size}"); } if verbosity.is_verbose() { @@ -423,6 +417,7 @@ impl flags::AnalysisStats { let range = sema.original_range(expected_tail.syntax()).range; let original_text: String = db .file_text(file_id.into()) + .text(db) .chars() .skip(usize::from(range.start())) .take(usize::from(range.end()) - usize::from(range.start())) @@ -475,7 +470,7 @@ impl flags::AnalysisStats { syntax_hit_found |= trim(&original_text) == trim(&generated); // Validate if type-checks - let mut txt = file_txt.to_string(); + let mut txt = file_txt.text(db).to_string(); let edit = ide::TextEdit::replace(range, generated.clone()); edit.apply(&mut txt); @@ -530,7 +525,7 @@ impl flags::AnalysisStats { } // Revert file back to original state if self.validate_term_search { - std::fs::write(path, file_txt.to_string()).unwrap(); + std::fs::write(path, file_txt.text(db).to_string()).unwrap(); } bar.inc(1); @@ -572,6 +567,11 @@ impl flags::AnalysisStats { } fn run_mir_lowering(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: Verbosity) { + let mut bar = match verbosity { + Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(), + _ if self.parallel || self.output.is_some() => ProgressReport::hidden(), + _ => ProgressReport::new(bodies.len() as u64), + }; let mut sw = self.stop_watch(); let mut all = 0; let mut fail = 0; @@ -593,11 +593,13 @@ impl flags::AnalysisStats { .chain(Some(body.name(db).unwrap_or_else(Name::missing))) .map(|it| it.display(db, Edition::LATEST).to_string()) .join("::"); - println!("Mir body for {full_name} failed due {e:?}"); + bar.println(format!("Mir body for {full_name} failed due {e:?}")); } fail += 1; + bar.tick(); } let mir_lowering_time = sw.elapsed(); + bar.finish_and_clear(); eprintln!("{:<20} {}", "MIR lowering:", mir_lowering_time); eprintln!("Mir failed bodies: {fail} ({}%)", percentage(fail, all)); report_metric("mir failed bodies", fail, "#"); @@ -619,12 +621,12 @@ impl flags::AnalysisStats { if self.parallel { let mut inference_sw = self.stop_watch(); - let snap = Snap(db.snapshot()); + let snap = db.snapshot(); bodies .par_iter() .map_with(snap, |snap, &body| { - snap.0.body(body.into()); - snap.0.infer(body.into()); + snap.body(body.into()); + snap.infer(body.into()); }) .count(); eprintln!("{:<20} {}", "Parallel Inference:", inference_sw.elapsed()); @@ -1206,8 +1208,10 @@ fn percentage(n: u64, total: u64) -> u64 { (n * 100).checked_div(total).unwrap_or(100) } -fn syntax_len(node: SyntaxNode) -> usize { - // Macro expanded code doesn't contain whitespace, so erase *all* whitespace - // to make macro and non-macro code comparable. - node.to_string().replace(|it: char| it.is_ascii_whitespace(), "").len() -} +// FIXME(salsa-transition): bring this back whenever we implement +// Salsa's memory usage tracking to work with tracked functions. +// fn syntax_len(node: SyntaxNode) -> usize { +// // Macro expanded code doesn't contain whitespace, so erase *all* whitespace +// // to make macro and non-macro code comparable. +// node.to_string().replace(|it: char| it.is_ascii_whitespace(), "").len() +// } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs index 6a3ceb640b91a..ae1054a804980 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs @@ -6,7 +6,7 @@ use rustc_hash::FxHashSet; use hir::{db::HirDatabase, sym, Crate, HirFileIdExt, Module}; use ide::{AnalysisHost, AssistResolveStrategy, Diagnostic, DiagnosticsConfig, Severity}; -use ide_db::{base_db::SourceRootDatabase, LineIndexDatabase}; +use ide_db::{base_db::SourceDatabase, LineIndexDatabase}; use load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice}; use crate::cli::flags; @@ -51,8 +51,8 @@ impl flags::Diagnostics { let work = all_modules(db).into_iter().filter(|module| { let file_id = module.definition_source_file_id(db).original_file(db); - let source_root = db.file_source_root(file_id.into()); - let source_root = db.source_root(source_root); + let source_root = db.file_source_root(file_id.into()).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); !source_root.is_library }); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs index 7398b9a9ef0b0..20da40f384b17 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs @@ -2,7 +2,7 @@ use hir::{Crate, Module}; use hir_ty::db::HirDatabase; -use ide_db::{base_db::SourceRootDatabase, LineIndexDatabase}; +use ide_db::{base_db::SourceDatabase, LineIndexDatabase}; use profile::StopWatch; use project_model::{CargoConfig, RustLibSource}; use syntax::TextRange; @@ -40,10 +40,10 @@ impl flags::RunTests { None => " (unknown line col)".to_owned(), Some(x) => format!("#{}:{}", x.line + 1, x.col), }; - let path = &db - .source_root(db.file_source_root(file_id)) - .path_for_file(&file_id) - .map(|x| x.to_string()); + let source_root = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); + + let path = source_root.path_for_file(&file_id).map(|x| x.to_string()); let path = path.as_deref().unwrap_or(""); format!("file://{path}{line_col}") }; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index e9ca12deaf6e6..7c7ed911293f5 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -164,13 +164,13 @@ impl Tester { let analysis = self.host.analysis(); let root_file = self.root_file; move || { - let res = std::panic::catch_unwind(move || { + let res = std::panic::catch_unwind(AssertUnwindSafe(move || { analysis.full_diagnostics( diagnostic_config, ide::AssistResolveStrategy::None, root_file, ) - }); + })); main.unpark(); res } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs index c03688e8009cb..a3bb70421512a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs @@ -34,7 +34,7 @@ impl flags::Ssr { let edits = match_finder.edits(); for (file_id, edit) in edits { if let Some(path) = vfs.file_path(file_id).as_path() { - let mut contents = db.file_text(file_id).to_string(); + let mut contents = db.file_text(file_id).text(db).to_string(); edit.apply(&mut contents); std::fs::write(path, contents) .with_context(|| format!("failed to write {path}"))?; @@ -49,7 +49,7 @@ impl flags::Search { /// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful /// for much else. pub fn run(self) -> anyhow::Result<()> { - use ide_db::base_db::SourceRootDatabase; + use ide_db::base_db::SourceDatabase; use ide_db::symbol_index::SymbolsDatabase; let cargo_config = CargoConfig { all_targets: true, set_test: true, ..CargoConfig::default() }; @@ -70,7 +70,7 @@ impl flags::Search { } if let Some(debug_snippet) = &self.debug { for &root in db.local_roots().iter() { - let sr = db.source_root(root); + let sr = db.source_root(root).source_root(db); for file_id in sr.iter() { for debug_info in match_finder.debug_where_text_equal( EditionedFileId::current_edition(file_id), diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs index 021b1bff39301..9acf4b85334cb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs @@ -2,7 +2,7 @@ use hir::{db::HirDatabase, sym, AnyDiagnostic, Crate, HirFileIdExt as _, Module, Semantics}; use ide::{AnalysisHost, RootDatabase, TextRange}; use ide_db::{ - base_db::{SourceDatabase, SourceRootDatabase}, + base_db::{salsa::AsDynDatabase, SourceDatabase}, defs::NameRefClass, EditionedFileId, FxHashSet, LineIndexDatabase as _, }; @@ -57,8 +57,8 @@ impl flags::UnresolvedReferences { let work = all_modules(db).into_iter().filter(|module| { let file_id = module.definition_source_file_id(db).original_file(db); - let source_root = db.file_source_root(file_id.into()); - let source_root = db.source_root(source_root); + let source_root = db.file_source_root(file_id.into()).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); !source_root.is_library }); @@ -77,7 +77,7 @@ impl flags::UnresolvedReferences { let line_col = line_index.line_col(range.start()); let line = line_col.line + 1; let col = line_col.col + 1; - let text = &file_text[range]; + let text = &file_text.text(db)[range]; println!("{file_path}:{line}:{col}: {text}"); } @@ -141,7 +141,9 @@ fn all_unresolved_references( let file_id = sema .attach_first_edition(file_id) .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); - let file = sema.parse(file_id); + let editioned_file_id_wrapper = + ide_db::base_db::EditionedFileId::new(sema.db.as_dyn_database(), file_id); + let file = sema.parse(editioned_file_id_wrapper); let root = file.syntax(); let mut unresolved_references = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 54670b675984d..f114a4454e002 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -8,7 +8,7 @@ use std::{ops::Not as _, time::Instant}; use crossbeam_channel::{unbounded, Receiver, Sender}; use hir::ChangeWithProcMacros; use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId}; -use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabase, SourceRootDatabase}; +use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabase}; use itertools::Itertools; use load_cargo::SourceRootConfig; use lsp_types::{SemanticTokens, Url}; @@ -426,29 +426,28 @@ impl GlobalState { tracing::info!(%vfs_path, ?change_kind, "Processing rust-analyzer.toml changes"); if vfs_path.as_path() == user_config_abs_path { tracing::info!(%vfs_path, ?change_kind, "Use config rust-analyzer.toml changes"); - change.change_user_config(Some(db.file_text(file_id))); - continue; + change.change_user_config(Some(db.file_text(file_id).text(db))); } // If change has been made to a ratoml file that // belongs to a non-local source root, we will ignore it. - let sr_id = db.file_source_root(file_id); - let sr = db.source_root(sr_id); + let source_root_id = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); - if !sr.is_library { + if !source_root.is_library { let entry = if workspace_ratoml_paths.contains(&vfs_path) { - tracing::info!(%vfs_path, ?sr_id, "workspace rust-analyzer.toml changes"); + tracing::info!(%vfs_path, ?source_root_id, "workspace rust-analyzer.toml changes"); change.change_workspace_ratoml( - sr_id, + source_root_id, vfs_path.clone(), - Some(db.file_text(file_id)), + Some(db.file_text(file_id).text(db)), ) } else { - tracing::info!(%vfs_path, ?sr_id, "crate rust-analyzer.toml changes"); + tracing::info!(%vfs_path, ?source_root_id, "crate rust-analyzer.toml changes"); change.change_ratoml( - sr_id, + source_root_id, vfs_path.clone(), - Some(db.file_text(file_id)), + Some(db.file_text(file_id).text(db)), ) }; @@ -459,10 +458,14 @@ impl GlobalState { // Put the old one back in. match kind { RatomlFileKind::Crate => { - change.change_ratoml(sr_id, old_path, old_text); + change.change_ratoml(source_root_id, old_path, old_text); } RatomlFileKind::Workspace => { - change.change_workspace_ratoml(sr_id, old_path, old_text); + change.change_workspace_ratoml( + source_root_id, + old_path, + old_text, + ); } } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs index 4683877db69b0..680ff00608378 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs @@ -4,8 +4,7 @@ use std::{ panic, thread, }; -use ide::Cancelled; -use ide_db::base_db::ra_salsa::Cycle; +use ide_db::base_db::salsa::{self, Cancelled, Cycle}; use lsp_server::{ExtractError, Response, ResponseError}; use serde::{de::DeserializeOwned, Serialize}; use stdx::thread::ThreadIntent; @@ -311,7 +310,7 @@ impl RequestDispatcher<'_> { #[derive(Debug)] enum HandlerCancelledError { PropagatedPanic, - Inner(ide::Cancelled), + Inner(salsa::Cancelled), } impl std::error::Error for HandlerCancelledError { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index 55344a4d6ac60..a30e5d8ce268e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -3,6 +3,7 @@ use std::ops::{Deref, Not as _}; +use ide_db::base_db::salsa::Cancelled; use itertools::Itertools; use lsp_types::{ CancelParams, DidChangeConfigurationParams, DidChangeTextDocumentParams, @@ -305,7 +306,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { let invocation_strategy_once = state.config.flycheck(None).invocation_strategy_once(); let may_flycheck_workspace = state.config.flycheck_workspace(None); let mut updated = false; - let task = move || -> std::result::Result<(), ide::Cancelled> { + let task = move || -> std::result::Result<(), Cancelled> { if invocation_strategy_once { let saved_file = vfs_path.as_path().map(|p| p.to_owned()); world.flycheck[0].restart_workspace(saved_file.clone()); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 68b2d6b696289..170481ea70164 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -502,6 +502,7 @@ pub(crate) fn handle_document_diagnostics( if !snap.analysis.is_local_source_root(source_root)? { return Ok(empty_diagnostic_report()); } + let source_root = snap.analysis.source_root_id(file_id)?; let config = snap.config.diagnostics(Some(source_root)); if !config.enabled { return Ok(empty_diagnostic_report()); @@ -1068,7 +1069,11 @@ pub(crate) fn handle_related_tests( pub(crate) fn handle_completion( snap: GlobalStateSnapshot, - lsp_types::CompletionParams { text_document_position, context,.. }: lsp_types::CompletionParams, + lsp_types::CompletionParams { + text_document_position, + context, + .. + }: lsp_types::CompletionParams, ) -> anyhow::Result> { let _p = tracing::info_span!("handle_completion").entered(); let mut position = @@ -1117,7 +1122,9 @@ pub(crate) fn handle_completion_resolve( .into()); } - let Some(data) = original_completion.data.take() else { return Ok(original_completion) }; + let Some(data) = original_completion.data.take() else { + return Ok(original_completion); + }; let resolve_data: lsp_ext::CompletionResolveData = serde_json::from_value(data)?; @@ -1500,7 +1507,7 @@ pub(crate) fn handle_code_action_resolve( "Failed to parse action id string '{}': {e}", params.id )) - .into()) + .into()); } }; @@ -1608,7 +1615,9 @@ pub(crate) fn handle_code_lens_resolve( snap: GlobalStateSnapshot, mut code_lens: CodeLens, ) -> anyhow::Result { - let Some(data) = code_lens.data.take() else { return Ok(code_lens) }; + let Some(data) = code_lens.data.take() else { + return Ok(code_lens); + }; let resolve = serde_json::from_value::(data)?; let Some(annotation) = from_proto::annotation(&snap, code_lens.range, resolve)? else { return Ok(code_lens); @@ -1718,14 +1727,18 @@ pub(crate) fn handle_inlay_hints_resolve( ) -> anyhow::Result { let _p = tracing::info_span!("handle_inlay_hints_resolve").entered(); - let Some(data) = original_hint.data.take() else { return Ok(original_hint) }; + let Some(data) = original_hint.data.take() else { + return Ok(original_hint); + }; let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?; let file_id = FileId::from_raw(resolve_data.file_id); if resolve_data.version != snap.file_version(file_id) { tracing::warn!("Inlay hint resolve data is outdated"); return Ok(original_hint); } - let Some(hash) = resolve_data.hash.parse().ok() else { return Ok(original_hint) }; + let Some(hash) = resolve_data.hash.parse().ok() else { + return Ok(original_hint); + }; anyhow::ensure!(snap.file_exists(file_id), "Invalid LSP resolve data"); let line_index = snap.file_line_index(file_id)?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index f5d9469f2622f..b47a126424aa0 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -10,7 +10,7 @@ use std::{ use always_assert::always; use crossbeam_channel::{select, Receiver}; -use ide_db::base_db::{SourceDatabase, SourceRootDatabase, VfsPath}; +use ide_db::base_db::{RootQueryDb, SourceDatabase, VfsPath}; use lsp_server::{Connection, Notification, Request}; use lsp_types::{notification::Notification as _, TextDocumentIdentifier}; use stdx::thread::ThreadIntent; @@ -529,7 +529,7 @@ impl GlobalState { let num_worker_threads = self.config.prime_caches_num_threads(); self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, { - let analysis = self.snapshot().analysis; + let analysis = AssertUnwindSafe(self.snapshot().analysis); move |sender| { sender.send(Task::PrimeCaches(PrimeCachesProgress::Begin)).unwrap(); let res = analysis.parallel_prime_caches(num_worker_threads, |progress| { @@ -555,13 +555,14 @@ impl GlobalState { (excluded == vfs::FileExcluded::No).then_some(file_id) }) .filter(|&file_id| { - let source_root = db.file_source_root(file_id); + let source_root_id = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); // Only publish diagnostics for files in the workspace, not from crates.io deps // or the sysroot. // While theoretically these should never have errors, we have quite a few false // positives particularly in the stdlib, and those diagnostics would stay around // forever if we emitted them here. - !db.source_root(source_root).is_library + !source_root.is_library }) .collect::>() }; @@ -642,8 +643,9 @@ impl GlobalState { (excluded == vfs::FileExcluded::No).then_some(file_id) }) .filter(|&file_id| { - let source_root = db.file_source_root(file_id); - !db.source_root(source_root).is_library + let source_root_id = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); + !source_root.is_library }) .collect::>(); tracing::trace!("updating tests for {:?}", subscriptions); @@ -908,12 +910,12 @@ impl GlobalState { } QueuedTask::CheckProcMacroSources(modified_rust_files) => { let crate_graph = self.analysis_host.raw_database().crate_graph(); - let snap = self.snapshot(); + let analysis = AssertUnwindSafe(self.snapshot().analysis); self.task_pool.handle.spawn_with_sender(stdx::thread::ThreadIntent::Worker, { move |sender| { if modified_rust_files.into_iter().any(|file_id| { // FIXME: Check whether these files could be build script related - match snap.analysis.crates_for(file_id) { + match analysis.crates_for(file_id) { Ok(crates) => { crates.iter().any(|&krate| crate_graph[krate].is_proc_macro) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 09b0adfeb8ae6..1a60fa06c9eb8 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -18,7 +18,7 @@ use std::{iter, mem}; use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder}; use ide::CrateId; use ide_db::{ - base_db::{ra_salsa::Durability, CrateGraph, CrateWorkspaceData, ProcMacroPaths}, + base_db::{salsa::Durability, CrateGraph, CrateWorkspaceData, ProcMacroPaths}, FxHashMap, }; use itertools::Itertools; diff --git a/src/tools/rust-analyzer/crates/span/Cargo.toml b/src/tools/rust-analyzer/crates/span/Cargo.toml index 097a056c99a45..3381dac0b4255 100644 --- a/src/tools/rust-analyzer/crates/span/Cargo.toml +++ b/src/tools/rust-analyzer/crates/span/Cargo.toml @@ -12,7 +12,7 @@ authors.workspace = true [dependencies] la-arena.workspace = true -ra-salsa = { workspace = true, optional = true } +salsa.workspace = true rustc-hash.workspace = true hashbrown.workspace = true text-size.workspace = true @@ -22,8 +22,5 @@ vfs.workspace = true syntax.workspace = true stdx.workspace = true -[features] -default = ["ra-salsa"] - [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index 6becc8e41ed00..a6402e870150e 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -21,44 +21,287 @@ //! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer. use std::fmt; -#[cfg(not(feature = "ra-salsa"))] -use crate::InternId; -#[cfg(feature = "ra-salsa")] -use ra_salsa::{InternId, InternValue}; - use crate::{Edition, MacroCallId}; -/// Interned [`SyntaxContextData`]. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SyntaxContextId(InternId); +// Recursive expansion of interned macro +// ====================================== -impl fmt::Debug for SyntaxContextId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.alternate() { - write!(f, "{}", self.0.as_u32()) - } else { - f.debug_tuple("SyntaxContextId").field(&self.0).finish() +/// A syntax context describes a hierarchy tracking order of macro definitions. +#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +pub struct SyntaxContext( + salsa::Id, + std::marker::PhantomData<&'static salsa::plumbing::interned::Value>, +); + +/// The underlying data interned by Salsa. +#[derive(Clone, Eq, Debug)] +pub struct SyntaxContextUnderlyingData { + pub outer_expn: Option, + pub outer_transparency: Transparency, + pub edition: Edition, + pub parent: SyntaxContext, + pub opaque: SyntaxContext, + pub opaque_and_semitransparent: SyntaxContext, +} + +const _: () = { + use salsa::plumbing as zalsa_; + use salsa::plumbing::interned as zalsa_struct_; + + impl PartialEq for SyntaxContextUnderlyingData { + fn eq(&self, other: &Self) -> bool { + self.outer_expn == other.outer_expn + && self.outer_transparency == other.outer_transparency + && self.edition == other.edition + && self.parent == other.parent } } -} -#[cfg(feature = "ra-salsa")] -impl ra_salsa::InternKey for SyntaxContextId { - fn from_intern_id(v: ra_salsa::InternId) -> Self { - SyntaxContextId(v) + impl std::hash::Hash for SyntaxContextUnderlyingData { + fn hash(&self, state: &mut H) { + self.outer_expn.hash(state); + self.outer_transparency.hash(state); + self.edition.hash(state); + self.parent.hash(state); + } + } + /// Key to use during hash lookups. Each field is some type that implements `Lookup` + /// for the owned type. This permits interning with an `&str` when a `String` is required and so forth. + #[derive(Hash)] + struct StructKey<'db, T0, T1, T2, T3>(T0, T1, T2, T3, std::marker::PhantomData<&'db ()>); + + impl<'db, T0, T1, T2, T3> zalsa_::interned::HashEqLike> + for SyntaxContextUnderlyingData + where + Option: zalsa_::interned::HashEqLike, + Transparency: zalsa_::interned::HashEqLike, + Edition: zalsa_::interned::HashEqLike, + SyntaxContext: zalsa_::interned::HashEqLike, + { + fn hash(&self, h: &mut H) { + zalsa_::interned::HashEqLike::::hash(&self.outer_expn, &mut *h); + zalsa_::interned::HashEqLike::::hash(&self.outer_transparency, &mut *h); + zalsa_::interned::HashEqLike::::hash(&self.edition, &mut *h); + zalsa_::interned::HashEqLike::::hash(&self.parent, &mut *h); + } + fn eq(&self, data: &StructKey<'db, T0, T1, T2, T3>) -> bool { + zalsa_::interned::HashEqLike::::eq(&self.outer_expn, &data.0) + && zalsa_::interned::HashEqLike::::eq(&self.outer_transparency, &data.1) + && zalsa_::interned::HashEqLike::::eq(&self.edition, &data.2) + && zalsa_::interned::HashEqLike::::eq(&self.parent, &data.3) + } + } + impl zalsa_struct_::Configuration for SyntaxContext { + const DEBUG_NAME: &'static str = "SyntaxContextData"; + type Fields<'a> = SyntaxContextUnderlyingData; + type Struct<'a> = SyntaxContext; + fn struct_from_id<'db>(id: salsa::Id) -> Self::Struct<'db> { + SyntaxContext(id, std::marker::PhantomData) + } + fn deref_struct(s: Self::Struct<'_>) -> salsa::Id { + s.0 + } } - fn as_intern_id(&self) -> ra_salsa::InternId { - self.0 + impl SyntaxContext { + pub fn ingredient(db: &Db) -> &zalsa_struct_::IngredientImpl + where + Db: ?Sized + zalsa_::Database, + { + static CACHE: zalsa_::IngredientCache> = + zalsa_::IngredientCache::new(); + CACHE.get_or_create(db.as_dyn_database(), || { + db.zalsa().add_or_lookup_jar_by_type::>() + }) + } } -} + impl zalsa_::AsId for SyntaxContext { + fn as_id(&self) -> salsa::Id { + self.0 + } + } + impl zalsa_::FromId for SyntaxContext { + fn from_id(id: salsa::Id) -> Self { + Self(id, std::marker::PhantomData) + } + } + unsafe impl Send for SyntaxContext {} -impl fmt::Display for SyntaxContextId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0.as_u32()) + unsafe impl Sync for SyntaxContext {} + + impl zalsa_::SalsaStructInDb for SyntaxContext { + type MemoIngredientMap = salsa::plumbing::MemoIngredientSingletonIndex; + + fn lookup_or_create_ingredient_index( + aux: &salsa::plumbing::Zalsa, + ) -> salsa::plumbing::IngredientIndices { + aux.add_or_lookup_jar_by_type::>().into() + } + + #[inline] + fn cast(id: salsa::Id, type_id: std::any::TypeId) -> Option { + if type_id == std::any::TypeId::of::() { + Some(::from_id(id)) + } else { + None + } + } + } + + unsafe impl salsa::plumbing::Update for SyntaxContext { + unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool { + if unsafe { *old_pointer } != new_value { + unsafe { *old_pointer = new_value }; + true + } else { + false + } + } + } + impl<'db> SyntaxContext { + pub fn new< + Db, + T0: zalsa_::interned::Lookup> + std::hash::Hash, + T1: zalsa_::interned::Lookup + std::hash::Hash, + T2: zalsa_::interned::Lookup + std::hash::Hash, + T3: zalsa_::interned::Lookup + std::hash::Hash, + >( + db: &'db Db, + outer_expn: T0, + outer_transparency: T1, + edition: T2, + parent: T3, + opaque: impl FnOnce(SyntaxContext) -> SyntaxContext, + opaque_and_semitransparent: impl FnOnce(SyntaxContext) -> SyntaxContext, + ) -> Self + where + Db: ?Sized + salsa::Database, + Option: zalsa_::interned::HashEqLike, + Transparency: zalsa_::interned::HashEqLike, + Edition: zalsa_::interned::HashEqLike, + SyntaxContext: zalsa_::interned::HashEqLike, + { + SyntaxContext::ingredient(db).intern( + db.as_dyn_database(), + StructKey::<'db>( + outer_expn, + outer_transparency, + edition, + parent, + std::marker::PhantomData, + ), + |id, data| SyntaxContextUnderlyingData { + outer_expn: zalsa_::interned::Lookup::into_owned(data.0), + outer_transparency: zalsa_::interned::Lookup::into_owned(data.1), + edition: zalsa_::interned::Lookup::into_owned(data.2), + parent: zalsa_::interned::Lookup::into_owned(data.3), + opaque: opaque(zalsa_::FromId::from_id(id)), + opaque_and_semitransparent: opaque_and_semitransparent( + zalsa_::FromId::from_id(id), + ), + }, + ) + } + + /// Invariant: Only [`SyntaxContext::ROOT`] has a [`None`] outer expansion. + // FIXME: The None case needs to encode the context crate id. We can encode that as the MSB of + // MacroCallId is reserved anyways so we can do bit tagging here just fine. + // The bigger issue is that this will cause interning to now create completely separate chains + // per crate. Though that is likely not a problem as `MacroCallId`s are already crate calling dependent. + pub fn outer_expn(self, db: &'db Db) -> Option + where + Db: ?Sized + zalsa_::Database, + { + if self.is_root() { + return None; + } + let fields = SyntaxContext::ingredient(db).fields(db.as_dyn_database(), self); + std::clone::Clone::clone(&fields.outer_expn) + } + + pub fn outer_transparency(self, db: &'db Db) -> Transparency + where + Db: ?Sized + zalsa_::Database, + { + if self.is_root() { + return Transparency::Opaque; + } + let fields = SyntaxContext::ingredient(db).fields(db.as_dyn_database(), self); + std::clone::Clone::clone(&fields.outer_transparency) + } + + pub fn edition(self, db: &'db Db) -> Edition + where + Db: ?Sized + zalsa_::Database, + { + if self.is_root() { + return Edition::from_u32(SyntaxContext::MAX_ID - self.0.as_u32()); + } + let fields = SyntaxContext::ingredient(db).fields(db.as_dyn_database(), self); + std::clone::Clone::clone(&fields.edition) + } + + pub fn parent(self, db: &'db Db) -> SyntaxContext + where + Db: ?Sized + zalsa_::Database, + { + if self.is_root() { + return self; + } + let fields = SyntaxContext::ingredient(db).fields(db.as_dyn_database(), self); + std::clone::Clone::clone(&fields.parent) + } + + /// This context, but with all transparent and semi-transparent expansions filtered away. + pub fn opaque(self, db: &'db Db) -> SyntaxContext + where + Db: ?Sized + zalsa_::Database, + { + if self.is_root() { + return self; + } + let fields = SyntaxContext::ingredient(db).fields(db.as_dyn_database(), self); + std::clone::Clone::clone(&fields.opaque) + } + + /// This context, but with all transparent expansions filtered away. + pub fn opaque_and_semitransparent(self, db: &'db Db) -> SyntaxContext + where + Db: ?Sized + zalsa_::Database, + { + if self.is_root() { + return self; + } + let fields = SyntaxContext::ingredient(db).fields(db.as_dyn_database(), self); + std::clone::Clone::clone(&fields.opaque_and_semitransparent) + } + + pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + salsa::with_attached_database(|db| { + let fields = SyntaxContext::ingredient(db).fields(db.as_dyn_database(), this); + let mut f = f.debug_struct("SyntaxContextData"); + let f = f.field("outer_expn", &fields.outer_expn); + let f = f.field("outer_transparency", &fields.outer_expn); + let f = f.field("edition", &fields.edition); + let f = f.field("parent", &fields.parent); + let f = f.field("opaque", &fields.opaque); + let f = f.field("opaque_and_semitransparent", &fields.opaque_and_semitransparent); + f.finish() + }) + .unwrap_or_else(|| { + f.debug_tuple("SyntaxContextData").field(&zalsa_::AsId::as_id(&this)).finish() + }) + } + } +}; + +impl SyntaxContext { + const MAX_ID: u32 = salsa::Id::MAX_U32 - 1; + + pub fn is_root(self) -> bool { + (SyntaxContext::MAX_ID - Edition::LATEST as u32) <= self.into_u32() + && self.into_u32() <= (SyntaxContext::MAX_ID - Edition::Edition2015 as u32) } -} -impl SyntaxContextId { #[inline] pub fn remove_root_edition(&mut self) { if self.is_root() { @@ -68,75 +311,19 @@ impl SyntaxContextId { /// The root context, which is the parent of all other contexts. All [`FileId`]s have this context. pub const fn root(edition: Edition) -> Self { - SyntaxContextId(unsafe { InternId::new_unchecked(edition as u32) }) + let edition = edition as u32; + SyntaxContext( + salsa::Id::from_u32(SyntaxContext::MAX_ID - edition), + std::marker::PhantomData, + ) } - pub fn is_root(self) -> bool { - self.into_u32() <= Edition::LATEST as u32 - } - - /// Deconstruct a `SyntaxContextId` into a raw `u32`. - /// This should only be used for deserialization purposes for the proc-macro server. pub fn into_u32(self) -> u32 { self.0.as_u32() } - /// Constructs a `SyntaxContextId` from a raw `u32`. - /// This should only be used for serialization purposes for the proc-macro server. pub fn from_u32(u32: u32) -> Self { - Self(InternId::from(u32)) - } -} - -/// A syntax context describes a hierarchy tracking order of macro definitions. -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub struct SyntaxContextData { - /// Invariant: Only [`SyntaxContextId::ROOT`] has a [`None`] outer expansion. - // FIXME: The None case needs to encode the context crate id. We can encode that as the MSB of - // MacroCallId is reserved anyways so we can do bit tagging here just fine. - // The bigger issue is that this will cause interning to now create completely separate chains - // per crate. Though that is likely not a problem as `MacroCallId`s are already crate calling dependent. - pub outer_expn: Option, - pub outer_transparency: Transparency, - pub edition: Edition, - pub parent: SyntaxContextId, - /// This context, but with all transparent and semi-transparent expansions filtered away. - pub opaque: SyntaxContextId, - /// This context, but with all transparent expansions filtered away. - pub opaque_and_semitransparent: SyntaxContextId, -} - -#[cfg(feature = "ra-salsa")] -impl InternValue for SyntaxContextData { - type Key = (SyntaxContextId, Option, Transparency, Edition); - - fn into_key(&self) -> Self::Key { - (self.parent, self.outer_expn, self.outer_transparency, self.edition) - } -} - -impl std::fmt::Debug for SyntaxContextData { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("SyntaxContextData") - .field("outer_expn", &self.outer_expn) - .field("outer_transparency", &self.outer_transparency) - .field("parent", &self.parent) - .field("opaque", &self.opaque) - .field("opaque_and_semitransparent", &self.opaque_and_semitransparent) - .finish() - } -} - -impl SyntaxContextData { - pub fn root(edition: Edition) -> Self { - SyntaxContextData { - outer_expn: None, - outer_transparency: Transparency::Opaque, - parent: SyntaxContextId::root(edition), - opaque: SyntaxContextId::root(edition), - opaque_and_semitransparent: SyntaxContextId::root(edition), - edition, - } + Self(salsa::Id::from_u32(u32), std::marker::PhantomData) } } @@ -167,3 +354,19 @@ impl Transparency { matches!(self, Self::Opaque) } } + +impl fmt::Display for SyntaxContext { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0.as_u32()) + } +} + +impl std::fmt::Debug for SyntaxContext { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if f.alternate() { + write!(f, "{}", self.0.as_u32()) + } else { + f.debug_tuple("SyntaxContext").field(&self.0).finish() + } + } +} diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index 8dc957350381c..7abdacee2b970 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -1,19 +1,19 @@ //! File and span related types. use std::fmt::{self, Write}; -#[cfg(feature = "ra-salsa")] -use ra_salsa::InternId; - mod ast_id; mod hygiene; mod map; pub use self::{ ast_id::{AstIdMap, AstIdNode, ErasedFileAstId, FileAstId}, - hygiene::{SyntaxContextData, SyntaxContextId, Transparency}, + hygiene::{SyntaxContext, Transparency}, map::{RealSpanMap, SpanMap}, }; +// Remove this +pub use self::hygiene::{SyntaxContext as SyntaxContextId, SyntaxContextUnderlyingData}; + pub use syntax::Edition; pub use text_size::{TextRange, TextSize}; pub use vfs::FileId; @@ -202,11 +202,23 @@ impl EditionedFileId { /// `MacroCallId`. // FIXME: Give this a better fitting name #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct HirFileId(u32); +pub struct HirFileId(salsa::Id); + +impl salsa::plumbing::AsId for HirFileId { + fn as_id(&self) -> salsa::Id { + self.0 + } +} + +impl salsa::plumbing::FromId for HirFileId { + fn from_id(id: salsa::Id) -> Self { + HirFileId(id) + } +} impl From for u32 { fn from(value: HirFileId) -> Self { - value.0 + value.0.as_u32() } } @@ -262,18 +274,20 @@ pub struct MacroFileId { /// `MacroCallId` identifies a particular macro invocation, like /// `println!("Hello, {}", world)`. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct MacroCallId(InternId); +pub struct MacroCallId(salsa::Id); -#[cfg(feature = "ra-salsa")] -impl ra_salsa::InternKey for MacroCallId { - fn from_intern_id(v: ra_salsa::InternId) -> Self { - MacroCallId(v) - } - fn as_intern_id(&self) -> ra_salsa::InternId { +impl salsa::plumbing::AsId for MacroCallId { + fn as_id(&self) -> salsa::Id { self.0 } } +impl salsa::plumbing::FromId for MacroCallId { + fn from_id(id: salsa::Id) -> Self { + MacroCallId(id) + } +} + impl MacroCallId { pub const MAX_ID: u32 = 0x7fff_ffff; @@ -307,16 +321,16 @@ impl From for HirFileId { #[allow(clippy::let_unit_value)] fn from(id: EditionedFileId) -> Self { assert!(id.as_u32() <= Self::MAX_HIR_FILE_ID, "FileId index {} is too large", id.as_u32()); - HirFileId(id.as_u32()) + HirFileId(salsa::Id::from_u32(id.0)) } } impl From for HirFileId { #[allow(clippy::let_unit_value)] fn from(MacroFileId { macro_call_id: MacroCallId(id) }: MacroFileId) -> Self { - let id = id.as_u32(); + let id: u32 = id.as_u32(); assert!(id <= Self::MAX_HIR_FILE_ID, "MacroCallId index {id} is too large"); - HirFileId(id | Self::MACRO_FILE_TAG_MASK) + HirFileId(salsa::Id::from_u32(id | Self::MACRO_FILE_TAG_MASK)) } } @@ -326,33 +340,37 @@ impl HirFileId { #[inline] pub fn is_macro(self) -> bool { - self.0 & Self::MACRO_FILE_TAG_MASK != 0 + self.0.as_u32() & Self::MACRO_FILE_TAG_MASK != 0 } #[inline] pub fn macro_file(self) -> Option { - match self.0 & Self::MACRO_FILE_TAG_MASK { + match self.0.as_u32() & Self::MACRO_FILE_TAG_MASK { 0 => None, _ => Some(MacroFileId { - macro_call_id: MacroCallId(InternId::from(self.0 ^ Self::MACRO_FILE_TAG_MASK)), + macro_call_id: MacroCallId(salsa::Id::from_u32( + self.0.as_u32() ^ Self::MACRO_FILE_TAG_MASK, + )), }), } } #[inline] pub fn file_id(self) -> Option { - match self.0 & Self::MACRO_FILE_TAG_MASK { - 0 => Some(EditionedFileId(self.0)), + match self.0.as_u32() & Self::MACRO_FILE_TAG_MASK { + 0 => Some(EditionedFileId(self.0.as_u32())), _ => None, } } #[inline] pub fn repr(self) -> HirFileIdRepr { - match self.0 & Self::MACRO_FILE_TAG_MASK { - 0 => HirFileIdRepr::FileId(EditionedFileId(self.0)), + match self.0.as_u32() & Self::MACRO_FILE_TAG_MASK { + 0 => HirFileIdRepr::FileId(EditionedFileId(self.0.as_u32())), _ => HirFileIdRepr::MacroFile(MacroFileId { - macro_call_id: MacroCallId(InternId::from(self.0 ^ Self::MACRO_FILE_TAG_MASK)), + macro_call_id: MacroCallId(salsa::Id::from_u32( + self.0.as_u32() ^ Self::MACRO_FILE_TAG_MASK, + )), }), } } @@ -369,72 +387,3 @@ impl std::fmt::Debug for TokenId { self.0.fmt(f) } } - -#[cfg(not(feature = "ra-salsa"))] -mod intern_id_proxy { - use std::fmt; - use std::num::NonZeroU32; - - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] - pub(super) struct InternId { - value: NonZeroU32, - } - - impl InternId { - pub(super) const MAX: u32 = 0xFFFF_FF00; - - pub(super) const unsafe fn new_unchecked(value: u32) -> Self { - debug_assert!(value < InternId::MAX); - let value = unsafe { NonZeroU32::new_unchecked(value + 1) }; - InternId { value } - } - - pub(super) fn as_u32(self) -> u32 { - self.value.get() - 1 - } - - pub(super) fn as_usize(self) -> usize { - self.as_u32() as usize - } - } - - impl From for u32 { - fn from(raw: InternId) -> u32 { - raw.as_u32() - } - } - - impl From for usize { - fn from(raw: InternId) -> usize { - raw.as_usize() - } - } - - impl From for InternId { - fn from(id: u32) -> InternId { - assert!(id < InternId::MAX); - unsafe { InternId::new_unchecked(id) } - } - } - - impl From for InternId { - fn from(id: usize) -> InternId { - assert!(id < (InternId::MAX as usize)); - unsafe { InternId::new_unchecked(id as u32) } - } - } - - impl fmt::Debug for InternId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_usize().fmt(f) - } - } - - impl fmt::Display for InternId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_usize().fmt(f) - } - } -} -#[cfg(not(feature = "ra-salsa"))] -use intern_id_proxy::InternId; diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 37dfb87721c83..4b5c2ff4cf7d2 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -3,7 +3,8 @@ use std::{iter, mem, str::FromStr, sync}; use base_db::{ CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, CrateWorkspaceData, Dependency, - Env, FileChange, FileSet, LangCrateOrigin, SourceRoot, SourceRootDatabase, Version, VfsPath, + Env, FileChange, FileSet, LangCrateOrigin, RootQueryDb, SourceDatabase, SourceRoot, Version, + VfsPath, }; use cfg::CfgOptions; use hir_expand::{ @@ -28,7 +29,7 @@ use test_utils::{ pub const WORKSPACE: base_db::SourceRootId = base_db::SourceRootId(0); -pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { +pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { #[track_caller] fn with_single_file( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -101,7 +102,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { } fn test_crate(&self) -> CrateId { - let crate_graph = self.crate_graph(); + let crate_graph = RootQueryDb::crate_graph(self); let mut it = crate_graph.iter(); let mut res = it.next().unwrap(); while crate_graph[res].origin.is_lang() { @@ -111,7 +112,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { } } -impl WithFixture for DB {} +impl WithFixture for DB {} pub struct ChangeFixture { pub file_position: Option<(EditionedFileId, RangeOrOffset)>, diff --git a/src/tools/rust-analyzer/xtask/src/tidy.rs b/src/tools/rust-analyzer/xtask/src/tidy.rs index 04952de731893..0e4208e096738 100644 --- a/src/tools/rust-analyzer/xtask/src/tidy.rs +++ b/src/tools/rust-analyzer/xtask/src/tidy.rs @@ -127,7 +127,7 @@ fn check_cargo_toml(path: &Path, text: String) { fn check_licenses(sh: &Shell) { let expected = " -(MIT OR Apache-2.0) AND Unicode-DFS-2016 +(MIT OR Apache-2.0) AND Unicode-3.0 0BSD OR MIT OR Apache-2.0 Apache-2.0 Apache-2.0 OR BSL-1.0 @@ -141,14 +141,13 @@ ISC MIT MIT / Apache-2.0 MIT OR Apache-2.0 -MIT OR Apache-2.0 OR Zlib MIT OR Zlib OR Apache-2.0 MIT/Apache-2.0 MPL-2.0 +Unicode-3.0 Unlicense OR MIT Unlicense/MIT Zlib -Zlib OR Apache-2.0 OR MIT " .lines() .filter(|it| !it.is_empty()) From 521fa18d5d6fd01e6cfb37d61471c26d0f6d3998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A8Florian?= <¨flodiebold@gmail.com¨> Date: Sun, 23 Feb 2025 18:40:31 +0100 Subject: [PATCH 012/260] Make GenericParamsCollector::type_or_consts not unnecessarily pub(crate) --- .../rust-analyzer/crates/hir-def/src/generics.rs | 14 +++++++++++++- .../crates/hir-def/src/item_tree/lower.rs | 11 ++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs index 80820193796de..ed5038c5aebd3 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs @@ -10,6 +10,7 @@ use hir_expand::{ name::{AsName, Name}, ExpandResult, }; +use intern::sym; use la_arena::{Arena, RawIdx}; use stdx::{ impl_from, @@ -446,12 +447,23 @@ impl GenericParams { #[derive(Clone, Default)] pub(crate) struct GenericParamsCollector { - pub(crate) type_or_consts: Arena, + type_or_consts: Arena, lifetimes: Arena, where_predicates: Vec, } impl GenericParamsCollector { + pub(crate) fn fill_self_param(&mut self) { + self.type_or_consts.alloc( + TypeParamData { + name: Some(Name::new_symbol_root(sym::Self_.clone())), + default: None, + provenance: TypeParamProvenance::TraitSelf, + } + .into(), + ); + } + pub(crate) fn fill( &mut self, lower_ctx: &mut LowerCtx<'_>, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 71848845a84df..b0546d4f33fde 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -21,7 +21,7 @@ use triomphe::Arc; use crate::{ db::DefDatabase, - generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance}, + generics::{GenericParams, GenericParamsCollector}, item_tree::{ AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldParent, FieldsShape, FileItemTreeId, FnFlags, Function, GenericArgs, GenericItemSourceMapBuilder, @@ -881,14 +881,7 @@ impl<'a> Ctx<'a> { if let HasImplicitSelf::Yes(bounds) = has_implicit_self { // Traits and trait aliases get the Self type as an implicit first type parameter. - generics.type_or_consts.alloc( - TypeParamData { - name: Some(Name::new_symbol_root(sym::Self_.clone())), - default: None, - provenance: TypeParamProvenance::TraitSelf, - } - .into(), - ); + generics.fill_self_param(); // add super traits as bounds on Self // i.e., `trait Foo: Bar` is equivalent to `trait Foo where Self: Bar` let bound_target = Either::Left(body_ctx.alloc_type_ref_desugared(TypeRef::Path( From 5c7292336873999ae979cc17c9f251bee14d6cf8 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 2 Jan 2025 01:45:32 +0200 Subject: [PATCH 013/260] Salsify the crate graph I.e. make it not one giant input but multiple, for incrementality and decreased memory usage for Salsa 3 reasons. --- src/tools/rust-analyzer/Cargo.lock | 1 + .../crates/base-db/src/change.rs | 21 +- .../rust-analyzer/crates/base-db/src/input.rs | 510 +++++++--- .../rust-analyzer/crates/base-db/src/lib.rs | 86 +- src/tools/rust-analyzer/crates/cfg/src/lib.rs | 12 + .../rust-analyzer/crates/hir-def/src/attr.rs | 7 +- .../rust-analyzer/crates/hir-def/src/data.rs | 18 +- .../crates/hir-def/src/data/adt.rs | 12 +- .../rust-analyzer/crates/hir-def/src/db.rs | 41 +- .../crates/hir-def/src/expander.rs | 6 +- .../crates/hir-def/src/expr_store/body.rs | 3 +- .../crates/hir-def/src/expr_store/lower.rs | 19 +- .../crates/hir-def/src/expr_store/tests.rs | 4 +- .../crates/hir-def/src/find_path.rs | 20 +- .../crates/hir-def/src/generics.rs | 21 +- .../crates/hir-def/src/import_map.rs | 29 +- .../crates/hir-def/src/item_scope.rs | 4 +- .../crates/hir-def/src/item_tree.rs | 6 +- .../crates/hir-def/src/lang_item.rs | 31 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 47 +- .../hir-def/src/macro_expansion_tests/mod.rs | 4 + .../crates/hir-def/src/nameres.rs | 110 +- .../hir-def/src/nameres/attr_resolution.rs | 10 +- .../crates/hir-def/src/nameres/collector.rs | 162 ++- .../hir-def/src/nameres/path_resolution.rs | 60 +- .../hir-def/src/nameres/tests/incremental.rs | 75 +- .../hir-def/src/nameres/tests/macros.rs | 4 +- .../crates/hir-def/src/pretty.rs | 11 +- .../crates/hir-def/src/resolver.rs | 102 +- .../rust-analyzer/crates/hir-def/src/src.rs | 4 +- .../crates/hir-def/src/test_db.rs | 28 +- .../crates/hir-expand/src/attrs.rs | 7 +- .../crates/hir-expand/src/builtin/fn_macro.rs | 8 +- .../crates/hir-expand/src/cfg_process.rs | 16 +- .../crates/hir-expand/src/change.rs | 23 +- .../rust-analyzer/crates/hir-expand/src/db.rs | 11 +- .../crates/hir-expand/src/declarative.rs | 10 +- .../crates/hir-expand/src/eager.rs | 10 +- .../crates/hir-expand/src/lib.rs | 12 +- .../crates/hir-expand/src/mod_path.rs | 6 +- .../crates/hir-expand/src/name.rs | 2 +- .../src/prettify_macro_expansion_.rs | 9 +- .../crates/hir-expand/src/proc_macro.rs | 159 ++- .../crates/hir-ty/src/chalk_db.rs | 22 +- .../crates/hir-ty/src/consteval.rs | 6 +- .../crates/hir-ty/src/consteval/tests.rs | 5 +- .../rust-analyzer/crates/hir-ty/src/db.rs | 43 +- .../hir-ty/src/diagnostics/decl_check.rs | 2 +- .../crates/hir-ty/src/diagnostics/expr.rs | 4 +- .../hir-ty/src/diagnostics/unsafe_check.rs | 2 +- .../crates/hir-ty/src/display.rs | 16 +- .../crates/hir-ty/src/infer/closure.rs | 6 +- .../crates/hir-ty/src/layout/target.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 11 +- .../crates/hir-ty/src/method_resolution.rs | 29 +- .../rust-analyzer/crates/hir-ty/src/mir.rs | 4 +- .../crates/hir-ty/src/mir/eval.rs | 6 +- .../crates/hir-ty/src/mir/eval/shim.rs | 2 +- .../crates/hir-ty/src/mir/lower.rs | 8 +- .../crates/hir-ty/src/test_db.rs | 16 +- .../rust-analyzer/crates/hir-ty/src/tests.rs | 8 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 16 +- .../rust-analyzer/crates/hir-ty/src/utils.rs | 7 +- .../rust-analyzer/crates/hir/src/from_id.rs | 2 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 70 +- .../rust-analyzer/crates/hir/src/semantics.rs | 2 +- .../rust-analyzer/crates/hir/src/symbols.rs | 5 +- .../ide-assists/src/handlers/inline_call.rs | 6 +- .../crates/ide-db/src/apply_change.rs | 8 +- .../crates/ide-db/src/famous_defs.rs | 5 +- .../rust-analyzer/crates/ide-db/src/lib.rs | 27 +- .../crates/ide-db/src/prime_caches.rs | 36 +- .../rust-analyzer/crates/ide-db/src/search.rs | 10 +- .../ide-db/src/test_data/test_doc_alias.txt | 4 +- .../test_symbol_index_collection.txt | 20 +- .../crates/ide-diagnostics/src/lib.rs | 6 +- .../crates/ide-ssr/src/matching.rs | 10 +- .../rust-analyzer/crates/ide/src/doc_links.rs | 4 +- .../crates/ide/src/expand_macro.rs | 8 +- .../crates/ide/src/fetch_crates.rs | 21 +- .../crates/ide/src/hover/render.rs | 4 +- .../crates/ide/src/hover/tests.rs | 2 +- .../crates/ide/src/inlay_hints/bind_pat.rs | 8 +- src/tools/rust-analyzer/crates/ide/src/lib.rs | 44 +- .../crates/ide/src/parent_module.rs | 4 +- .../rust-analyzer/crates/ide/src/runnables.rs | 5 +- .../crates/ide/src/static_index.rs | 4 +- .../rust-analyzer/crates/ide/src/status.rs | 23 +- .../crates/ide/src/test_explorer.rs | 37 +- .../crates/ide/src/view_crate_graph.rs | 60 +- .../rust-analyzer/crates/intern/src/symbol.rs | 14 +- .../crates/load-cargo/src/lib.rs | 31 +- .../crates/proc-macro-api/src/lib.rs | 10 +- .../crates/proc-macro-srv/src/tests/mod.rs | 130 +-- .../crates/project-model/src/project_json.rs | 2 +- .../crates/project-model/src/tests.rs | 12 +- .../crates/project-model/src/workspace.rs | 184 ++-- .../cargo_hello_world_project_model.txt | 448 ++++---- ...project_model_with_selective_overrides.txt | 448 ++++---- ..._project_model_with_wildcard_overrides.txt | 448 ++++---- .../output/rust_project_cfg_groups.txt | 962 ++++++++++-------- ...rust_project_hello_world_project_model.txt | 832 ++++++++------- .../crates/rust-analyzer/src/global_state.rs | 6 +- .../crates/rust-analyzer/src/main_loop.rs | 20 +- .../crates/rust-analyzer/src/reload.rs | 95 +- .../crates/rust-analyzer/src/target_spec.rs | 4 +- .../crates/test-fixture/Cargo.toml | 1 + .../crates/test-fixture/src/lib.rs | 98 +- 108 files changed, 3629 insertions(+), 2511 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index efd7362594c21..00da1c973dc0f 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2418,6 +2418,7 @@ dependencies = [ "span", "stdx", "test-utils", + "triomphe", "tt", ] diff --git a/src/tools/rust-analyzer/crates/base-db/src/change.rs b/src/tools/rust-analyzer/crates/base-db/src/change.rs index 90413a573aef3..1f19556a766c2 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/change.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/change.rs @@ -3,20 +3,18 @@ use std::fmt; -use rustc_hash::FxHashMap; use salsa::Durability; use triomphe::Arc; use vfs::FileId; -use crate::{CrateGraph, CrateId, CrateWorkspaceData, RootQueryDb, SourceRoot, SourceRootId}; +use crate::{CrateGraphBuilder, CratesIdMap, RootQueryDb, SourceRoot, SourceRootId}; /// Encapsulate a bunch of raw `.set` calls on the database. #[derive(Default)] pub struct FileChange { pub roots: Option>, pub files_changed: Vec<(FileId, Option)>, - pub crate_graph: Option, - pub ws_data: Option>>, + pub crate_graph: Option, } impl fmt::Debug for FileChange { @@ -48,15 +46,11 @@ impl FileChange { self.files_changed.push((file_id, new_text)) } - pub fn set_crate_graph(&mut self, graph: CrateGraph) { + pub fn set_crate_graph(&mut self, graph: CrateGraphBuilder) { self.crate_graph = Some(graph); } - pub fn set_ws_data(&mut self, data: FxHashMap>) { - self.ws_data = Some(data); - } - - pub fn apply(self, db: &mut dyn RootQueryDb) { + pub fn apply(self, db: &mut dyn RootQueryDb) -> Option { let _p = tracing::info_span!("FileChange::apply").entered(); if let Some(roots) = self.roots { for (idx, root) in roots.into_iter().enumerate() { @@ -79,12 +73,11 @@ impl FileChange { let text = text.unwrap_or_default(); db.set_file_text_with_durability(file_id, &text, durability) } + if let Some(crate_graph) = self.crate_graph { - db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH); - } - if let Some(data) = self.ws_data { - db.set_crate_workspace_data_with_durability(Arc::new(data), Durability::HIGH); + return Some(crate_graph.set_in_db(db)); } + None } } diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index bd08387b58219..c4e64b372f36a 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -6,17 +6,23 @@ //! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how //! actual IO is done and lowered to input. +use std::hash::BuildHasherDefault; use std::{fmt, mem, ops}; -use cfg::CfgOptions; +use cfg::{CfgOptions, HashableCfgOptions}; +use dashmap::mapref::entry::Entry; +use dashmap::DashMap; use intern::Symbol; use la_arena::{Arena, Idx, RawIdx}; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +use salsa::{Durability, Setter}; use span::{Edition, EditionedFileId}; use triomphe::Arc; use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath}; -pub type ProcMacroPaths = FxHashMap>; +use crate::{CrateWorkspaceData, RootQueryDb}; + +pub type ProcMacroPaths = FxHashMap>; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct SourceRootId(pub u32); @@ -64,30 +70,31 @@ impl SourceRoot { } } -/// `CrateGraph` is a bit of information which turns a set of text files into a -/// number of Rust crates. -/// -/// Each crate is defined by the `FileId` of its root module, the set of enabled -/// `cfg` flags and the set of dependencies. -/// -/// Note that, due to cfg's, there might be several crates for a single `FileId`! -/// -/// For the purposes of analysis, a crate does not have a name. Instead, names -/// are specified on dependency edges. That is, a crate might be known under -/// different names in different dependent crates. -/// -/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust -/// language proper, not a concept of the build system. In practice, we get -/// `CrateGraph` by lowering `cargo metadata` output. -/// -/// `CrateGraph` is `!Serialize` by design, see -/// -#[derive(Clone, Default)] -pub struct CrateGraph { - arena: Arena, +#[derive(Default, Clone)] +pub struct CrateGraphBuilder { + arena: Arena, } -impl fmt::Debug for CrateGraph { +pub type CrateBuilderId = Idx; + +impl ops::Index for CrateGraphBuilder { + type Output = CrateBuilder; + + fn index(&self, index: CrateBuilderId) -> &Self::Output { + &self.arena[index] + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CrateBuilder { + pub basic: CrateDataBuilder, + pub extra: ExtraCrateData, + pub cfg_options: Arc, + pub env: Env, + ws_data: Arc, +} + +impl fmt::Debug for CrateGraphBuilder { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map() .entries(self.arena.iter().map(|(id, data)| (u32::from(id.into_raw()), data))) @@ -95,8 +102,6 @@ impl fmt::Debug for CrateGraph { } } -pub type CrateId = Idx; - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateName(Symbol); @@ -272,28 +277,34 @@ impl ReleaseChannel { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CrateData { +/// The crate data from which we derive the `Crate`. +/// +/// We want this to contain as little data as possible, because if it contains dependencies and +/// something changes, this crate and all of its dependencies ids are invalidated, which causes +/// pretty much everything to be recomputed. If the crate id is not invalidated, only this crate's +/// information needs to be recomputed. +/// +/// *Most* different crates have different root files (actually, pretty much all of them). +/// Still, it is possible to have crates distinguished by other factors (e.g. dependencies). +/// So we store only the root file - unless we find that this crate has the same root file as +/// another crate, in which case we store all data for one of them (if one is a dependency of +/// the other, we store for it, because it has more dependencies to be invalidated). +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct UniqueCrateData { + root_file_id: FileId, + disambiguator: Option>, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct CrateData { pub root_file_id: FileId, pub edition: Edition, - pub version: Option, - /// A name used in the package's project declaration: for Cargo projects, - /// its `[package].name` can be different for other project types or even - /// absent (a dummy crate for the code snippet, for example). - /// - /// For purposes of analysis, crates are anonymous (only names in - /// `Dependency` matters), this name should only be used for UI. - pub display_name: Option, - pub cfg_options: Arc, - /// The cfg options that could be used by the crate - pub potential_cfg_options: Option>, - pub env: Env, /// The dependencies of this crate. /// /// Note that this may contain more dependencies than the crate actually uses. /// A common example is the test crate which is included but only actually is active when /// declared in source via `extern crate test`. - pub dependencies: Vec, + pub dependencies: Vec>, pub origin: CrateOrigin, pub is_proc_macro: bool, /// The working directory to run proc-macros in. This is the workspace root of the cargo workspace @@ -301,6 +312,23 @@ pub struct CrateData { pub proc_macro_cwd: Option, } +pub type CrateDataBuilder = CrateData; +pub type BuiltCrateData = CrateData; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ExtraCrateData { + pub version: Option, + /// A name used in the package's project declaration: for Cargo projects, + /// its `[package].name` can be different for other project types or even + /// absent (a dummy crate for the code snippet, for example). + /// + /// For purposes of analysis, crates are anonymous (only names in + /// `Dependency` matters), this name should only be used for UI. + pub display_name: Option, + /// The cfg options that could be used by the crate + pub potential_cfg_options: Option, +} + #[derive(Default, Clone, PartialEq, Eq)] pub struct Env { entries: FxHashMap, @@ -326,22 +354,32 @@ impl fmt::Debug for Env { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Dependency { - pub crate_id: CrateId, +pub struct Dependency { + pub crate_id: Id, pub name: CrateName, prelude: bool, sysroot: bool, } -impl Dependency { - pub fn new(name: CrateName, crate_id: CrateId) -> Self { +pub type DependencyBuilder = Dependency; +pub type BuiltDependency = Dependency; + +impl DependencyBuilder { + pub fn new(name: CrateName, crate_id: CrateBuilderId) -> Self { Self { name, crate_id, prelude: true, sysroot: false } } - pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool, sysroot: bool) -> Self { + pub fn with_prelude( + name: CrateName, + crate_id: CrateBuilderId, + prelude: bool, + sysroot: bool, + ) -> Self { Self { name, crate_id, prelude, sysroot } } +} +impl BuiltDependency { /// Whether this dependency is to be added to the depending crate's extern prelude. pub fn is_prelude(&self) -> bool { self.prelude @@ -353,7 +391,32 @@ impl Dependency { } } -impl CrateGraph { +pub type CratesIdMap = FxHashMap; + +#[salsa::input] +pub struct Crate { + #[return_ref] + pub data: BuiltCrateData, + /// Crate data that is not needed for analysis. + /// + /// This is split into a separate field to increase incrementality. + #[return_ref] + pub extra_data: ExtraCrateData, + // This is in `Arc` because it is shared for all crates in a workspace. + #[return_ref] + pub workspace_data: Arc, + // FIXME: Remove this `Arc`. + #[return_ref] + pub cfg_options: Arc, + #[return_ref] + pub env: Env, +} + +/// The mapping from [`UniqueCrateData`] to their [`Crate`] input. +#[derive(Debug, Default)] +pub struct CratesMap(DashMap>); + +impl CrateGraphBuilder { pub fn add_crate_root( &mut self, root_file_id: FileId, @@ -361,33 +424,34 @@ impl CrateGraph { display_name: Option, version: Option, cfg_options: Arc, - potential_cfg_options: Option>, + potential_cfg_options: Option, mut env: Env, origin: CrateOrigin, is_proc_macro: bool, proc_macro_cwd: Option, - ) -> CrateId { + ws_data: Arc, + ) -> CrateBuilderId { env.entries.shrink_to_fit(); - let data = CrateData { - root_file_id, - edition, - version, - display_name, + self.arena.alloc(CrateBuilder { + basic: CrateData { + root_file_id, + edition, + dependencies: Vec::new(), + origin, + is_proc_macro, + proc_macro_cwd, + }, + extra: ExtraCrateData { version, display_name, potential_cfg_options }, cfg_options, - potential_cfg_options, env, - dependencies: Vec::new(), - origin, - is_proc_macro, - proc_macro_cwd, - }; - self.arena.alloc(data) + ws_data, + }) } pub fn add_dep( &mut self, - from: CrateId, - dep: Dependency, + from: CrateBuilderId, + dep: DependencyBuilder, ) -> Result<(), CyclicDependenciesError> { let _p = tracing::info_span!("add_dep").entered(); @@ -395,37 +459,160 @@ impl CrateGraph { // that out, look for a path in the *opposite* direction, from `to` to // `from`. if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) { - let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect(); + let path = + path.into_iter().map(|it| (it, self[it].extra.display_name.clone())).collect(); let err = CyclicDependenciesError { path }; assert!(err.from().0 == from && err.to().0 == dep.crate_id); return Err(err); } - self.arena[from].add_dep(dep); + self.arena[from].basic.dependencies.push(dep); Ok(()) } - pub fn is_empty(&self) -> bool { - self.arena.is_empty() - } + pub fn set_in_db(self, db: &mut dyn RootQueryDb) -> CratesIdMap { + let mut all_crates = Vec::with_capacity(self.arena.len()); + let mut visited = FxHashMap::default(); + let mut visited_root_files = FxHashSet::default(); - pub fn len(&self) -> usize { - self.arena.len() + let old_all_crates = db.all_crates(); + + let crates_map = db.crates_map(); + // salsa doesn't compare new input to old input to see if they are the same, so here we are doing all the work ourselves. + for krate in self.iter() { + go( + &self, + db, + &crates_map, + &mut visited, + &mut visited_root_files, + &mut all_crates, + krate, + ); + } + + if **old_all_crates != *all_crates { + db.set_all_crates_with_durability( + Arc::new(all_crates.into_boxed_slice()), + Durability::HIGH, + ); + } + + return visited; + + fn go( + graph: &CrateGraphBuilder, + db: &mut dyn RootQueryDb, + crates_map: &CratesMap, + visited: &mut FxHashMap, + visited_root_files: &mut FxHashSet, + all_crates: &mut Vec, + source: CrateBuilderId, + ) -> Crate { + if let Some(&crate_id) = visited.get(&source) { + return crate_id; + } + let krate = &graph[source]; + let dependencies = krate + .basic + .dependencies + .iter() + .map(|dep| BuiltDependency { + crate_id: go( + graph, + db, + crates_map, + visited, + visited_root_files, + all_crates, + dep.crate_id, + ), + name: dep.name.clone(), + prelude: dep.prelude, + sysroot: dep.sysroot, + }) + .collect::>(); + let crate_data = BuiltCrateData { + dependencies, + edition: krate.basic.edition, + is_proc_macro: krate.basic.is_proc_macro, + origin: krate.basic.origin.clone(), + root_file_id: krate.basic.root_file_id, + proc_macro_cwd: krate.basic.proc_macro_cwd.clone(), + }; + let disambiguator = if visited_root_files.insert(krate.basic.root_file_id) { + None + } else { + Some(Box::new((crate_data.clone(), krate.cfg_options.to_hashable()))) + }; + + let unique_crate_data = + UniqueCrateData { root_file_id: krate.basic.root_file_id, disambiguator }; + let crate_input = match crates_map.0.entry(unique_crate_data) { + Entry::Occupied(entry) => { + let old_crate = *entry.get(); + if crate_data != *old_crate.data(db) { + old_crate.set_data(db).with_durability(Durability::HIGH).to(crate_data); + } + if krate.extra != *old_crate.extra_data(db) { + old_crate + .set_extra_data(db) + .with_durability(Durability::HIGH) + .to(krate.extra.clone()); + } + if krate.cfg_options != *old_crate.cfg_options(db) { + old_crate + .set_cfg_options(db) + .with_durability(Durability::HIGH) + .to(krate.cfg_options.clone()); + } + if krate.env != *old_crate.env(db) { + old_crate + .set_env(db) + .with_durability(Durability::HIGH) + .to(krate.env.clone()); + } + if krate.ws_data != *old_crate.workspace_data(db) { + old_crate + .set_workspace_data(db) + .with_durability(Durability::HIGH) + .to(krate.ws_data.clone()); + } + old_crate + } + Entry::Vacant(entry) => { + let input = Crate::builder( + crate_data, + krate.extra.clone(), + krate.ws_data.clone(), + krate.cfg_options.clone(), + krate.env.clone(), + ) + .durability(Durability::HIGH) + .new(db); + entry.insert(input); + input + } + }; + all_crates.push(crate_input); + visited.insert(source, crate_input); + crate_input + } } - pub fn iter(&self) -> impl Iterator + '_ { + pub fn iter(&self) -> impl Iterator + '_ { self.arena.iter().map(|(idx, _)| idx) } // FIXME: used for fixing up the toolchain sysroot, should be removed and done differently #[doc(hidden)] - pub fn iter_mut(&mut self) -> impl Iterator + '_ { + pub fn iter_mut(&mut self) -> impl Iterator + '_ { self.arena.iter_mut() } /// Returns an iterator over all transitive dependencies of the given crate, /// including the crate itself. - pub fn transitive_deps(&self, of: CrateId) -> impl Iterator { + pub fn transitive_deps(&self, of: CrateBuilderId) -> impl Iterator { let mut worklist = vec![of]; let mut deps = FxHashSet::default(); @@ -434,42 +621,15 @@ impl CrateGraph { continue; } - worklist.extend(self[krate].dependencies.iter().map(|dep| dep.crate_id)); + worklist.extend(self[krate].basic.dependencies.iter().map(|dep| dep.crate_id)); } deps.into_iter() } - /// Returns all transitive reverse dependencies of the given crate, - /// including the crate itself. - pub fn transitive_rev_deps(&self, of: CrateId) -> impl Iterator { - let mut worklist = vec![of]; - let mut rev_deps = FxHashSet::default(); - rev_deps.insert(of); - - let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); - self.arena.iter().for_each(|(krate, data)| { - data.dependencies - .iter() - .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate)) - }); - - while let Some(krate) = worklist.pop() { - if let Some(krate_rev_deps) = inverted_graph.get(&krate) { - krate_rev_deps - .iter() - .copied() - .filter(|&rev_dep| rev_deps.insert(rev_dep)) - .for_each(|rev_dep| worklist.push(rev_dep)); - } - } - - rev_deps.into_iter() - } - /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate /// come before the crate itself). - pub fn crates_in_topological_order(&self) -> Vec { + fn crates_in_topological_order(&self) -> Vec { let mut res = Vec::new(); let mut visited = FxHashSet::default(); @@ -480,15 +640,15 @@ impl CrateGraph { return res; fn go( - graph: &CrateGraph, - visited: &mut FxHashSet, - res: &mut Vec, - source: CrateId, + graph: &CrateGraphBuilder, + visited: &mut FxHashSet, + res: &mut Vec, + source: CrateBuilderId, ) { if !visited.insert(source) { return; } - for dep in graph[source].dependencies.iter() { + for dep in graph[source].basic.dependencies.iter() { go(graph, visited, res, dep.crate_id) } res.push(source) @@ -504,23 +664,27 @@ impl CrateGraph { /// Returns a map mapping `other`'s IDs to the new IDs in `self`. pub fn extend( &mut self, - mut other: CrateGraph, + mut other: CrateGraphBuilder, proc_macros: &mut ProcMacroPaths, - ) -> FxHashMap { + ) -> FxHashMap { // Sorting here is a bit pointless because the input is likely already sorted. // However, the overhead is small and it makes the `extend` method harder to misuse. self.arena .iter_mut() - .for_each(|(_, data)| data.dependencies.sort_by_key(|dep| dep.crate_id)); + .for_each(|(_, data)| data.basic.dependencies.sort_by_key(|dep| dep.crate_id)); - let m = self.len(); + let m = self.arena.len(); let topo = other.crates_in_topological_order(); - let mut id_map: FxHashMap = FxHashMap::default(); + let mut id_map: FxHashMap = FxHashMap::default(); for topo in topo { let crate_data = &mut other.arena[topo]; - crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]); - crate_data.dependencies.sort_by_key(|dep| dep.crate_id); + crate_data + .basic + .dependencies + .iter_mut() + .for_each(|dep| dep.crate_id = id_map[&dep.crate_id]); + crate_data.basic.dependencies.sort_by_key(|dep| dep.crate_id); let find = self.arena.iter().take(m).find_map(|(k, v)| (v == crate_data).then_some(k)); let new_id = find.unwrap_or_else(|| self.arena.alloc(crate_data.clone())); @@ -534,10 +698,10 @@ impl CrateGraph { fn find_path( &self, - visited: &mut FxHashSet, - from: CrateId, - to: CrateId, - ) -> Option> { + visited: &mut FxHashSet, + from: CrateBuilderId, + to: CrateBuilderId, + ) -> Option> { if !visited.insert(from) { return None; } @@ -546,7 +710,7 @@ impl CrateGraph { return Some(vec![to]); } - for dep in &self[from].dependencies { + for dep in &self[from].basic.dependencies { let crate_id = dep.crate_id; if let Some(mut path) = self.find_path(visited, crate_id, to) { path.push(from); @@ -559,7 +723,10 @@ impl CrateGraph { /// Removes all crates from this crate graph except for the ones in `to_keep` and fixes up the dependencies. /// Returns a mapping from old crate ids to new crate ids. - pub fn remove_crates_except(&mut self, to_keep: &[CrateId]) -> Vec> { + pub fn remove_crates_except( + &mut self, + to_keep: &[CrateBuilderId], + ) -> Vec> { let mut id_map = vec![None; self.arena.len()]; self.arena = std::mem::take(&mut self.arena) .into_iter() @@ -567,12 +734,12 @@ impl CrateGraph { .enumerate() .map(|(new_id, (id, data))| { id_map[id.into_raw().into_u32() as usize] = - Some(CrateId::from_raw(RawIdx::from_u32(new_id as u32))); + Some(CrateBuilderId::from_raw(RawIdx::from_u32(new_id as u32))); data }) .collect(); for (_, data) in self.arena.iter_mut() { - data.dependencies.iter_mut().for_each(|dep| { + data.basic.dependencies.iter_mut().for_each(|dep| { dep.crate_id = id_map[dep.crate_id.into_raw().into_u32() as usize].expect("crate was filtered") }); @@ -585,20 +752,34 @@ impl CrateGraph { } } -impl ops::Index for CrateGraph { - type Output = CrateData; - fn index(&self, crate_id: CrateId) -> &CrateData { - &self.arena[crate_id] +pub(crate) fn transitive_rev_deps(db: &dyn RootQueryDb, of: Crate) -> FxHashSet { + let mut worklist = vec![of]; + let mut rev_deps = FxHashSet::default(); + rev_deps.insert(of); + + let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); + db.all_crates().iter().for_each(|&krate| { + krate + .data(db) + .dependencies + .iter() + .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate)) + }); + + while let Some(krate) = worklist.pop() { + if let Some(crate_rev_deps) = inverted_graph.get(&krate) { + crate_rev_deps + .iter() + .copied() + .filter(|&rev_dep| rev_deps.insert(rev_dep)) + .for_each(|rev_dep| worklist.push(rev_dep)); + } } -} -impl CrateData { - /// Add a dependency to `self` without checking if the dependency - // is existent among `self.dependencies`. - fn add_dep(&mut self, dep: Dependency) { - self.dependencies.push(dep) - } + rev_deps +} +impl BuiltCrateData { pub fn root_file_id(&self) -> EditionedFileId { EditionedFileId::new(self.root_file_id, self.edition) } @@ -657,21 +838,21 @@ impl<'a> IntoIterator for &'a Env { #[derive(Debug)] pub struct CyclicDependenciesError { - path: Vec<(CrateId, Option)>, + path: Vec<(CrateBuilderId, Option)>, } impl CyclicDependenciesError { - fn from(&self) -> &(CrateId, Option) { + fn from(&self) -> &(CrateBuilderId, Option) { self.path.first().unwrap() } - fn to(&self) -> &(CrateId, Option) { + fn to(&self) -> &(CrateBuilderId, Option) { self.path.last().unwrap() } } impl fmt::Display for CyclicDependenciesError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let render = |(id, name): &(CrateId, Option)| match name { + let render = |(id, name): &(CrateBuilderId, Option)| match name { Some(it) => format!("{it}({id:?})"), None => format!("{id:?}"), }; @@ -688,13 +869,19 @@ impl fmt::Display for CyclicDependenciesError { #[cfg(test)] mod tests { - use crate::CrateOrigin; + use triomphe::Arc; + + use crate::{CrateWorkspaceData, DependencyBuilder}; - use super::{CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId}; + use super::{CrateGraphBuilder, CrateName, CrateOrigin, Edition::Edition2018, Env, FileId}; + + fn empty_ws_data() -> Arc { + Arc::new(CrateWorkspaceData { data_layout: Err("".into()), toolchain: None }) + } #[test] fn detect_cyclic_dependency_indirect() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -706,6 +893,7 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -718,6 +906,7 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); let crate3 = graph.add_crate_root( FileId::from_raw(3u32), @@ -730,21 +919,22 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); assert!(graph - .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) .is_ok()); assert!(graph - .add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3,)) + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) .is_ok()); assert!(graph - .add_dep(crate3, Dependency::new(CrateName::new("crate1").unwrap(), crate1,)) + .add_dep(crate3, DependencyBuilder::new(CrateName::new("crate1").unwrap(), crate1,)) .is_err()); } #[test] fn detect_cyclic_dependency_direct() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -756,6 +946,7 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -768,18 +959,19 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); assert!(graph - .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) .is_ok()); assert!(graph - .add_dep(crate2, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) .is_err()); } #[test] fn it_works() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -791,6 +983,7 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -803,6 +996,7 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); let crate3 = graph.add_crate_root( FileId::from_raw(3u32), @@ -815,18 +1009,19 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); assert!(graph - .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) .is_ok()); assert!(graph - .add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3,)) + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) .is_ok()); } #[test] fn dashes_are_normalized() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -838,6 +1033,7 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -850,16 +1046,22 @@ mod tests { CrateOrigin::Local { repo: None, name: None }, false, None, + empty_ws_data(), ); assert!(graph .add_dep( crate1, - Dependency::new(CrateName::normalize_dashes("crate-name-with-dashes"), crate2,) + DependencyBuilder::new( + CrateName::normalize_dashes("crate-name-with-dashes"), + crate2, + ) ) .is_ok()); assert_eq!( - graph[crate1].dependencies, - vec![Dependency::new(CrateName::new("crate_name_with_dashes").unwrap(), crate2,)] + graph.arena[crate1].basic.dependencies, + vec![ + DependencyBuilder::new(CrateName::new("crate_name_with_dashes").unwrap(), crate2,) + ] ); } } diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 9ec9100968d22..324979b2e463b 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -8,14 +8,15 @@ use std::hash::BuildHasherDefault; pub use crate::{ change::FileChange, input::{ - CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env, - LangCrateOrigin, ProcMacroPaths, ReleaseChannel, SourceRoot, SourceRootId, - TargetLayoutLoadResult, + BuiltCrateData, BuiltDependency, Crate, CrateBuilder, CrateBuilderId, CrateDataBuilder, + CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CratesIdMap, CratesMap, + DependencyBuilder, Env, ExtraCrateData, LangCrateOrigin, ProcMacroPaths, ReleaseChannel, + SourceRoot, SourceRootId, TargetLayoutLoadResult, UniqueCrateData, }, }; use dashmap::{mapref::entry::Entry, DashMap}; pub use query_group::{self}; -use rustc_hash::{FxHashMap, FxHasher}; +use rustc_hash::{FxHashSet, FxHasher}; pub use salsa::{self}; use salsa::{Durability, Setter}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; @@ -200,21 +201,53 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database { /// Returns the set of errors obtained from parsing the file including validation errors. fn parse_errors(&self, file_id: EditionedFileId) -> Option>; - /// The crate graph. - #[salsa::input] - fn crate_graph(&self) -> Arc; + #[salsa::transparent] + fn toolchain_channel(&self, krate: Crate) -> Option; - #[salsa::input] - fn crate_workspace_data(&self) -> Arc>>; + /// Crates whose root file is in `id`. + fn source_root_crates(&self, id: SourceRootId) -> Arc<[Crate]>; #[salsa::transparent] - fn toolchain_channel(&self, krate: CrateId) -> Option; + fn relevant_crates(&self, file_id: FileId) -> Arc<[Crate]>; - /// Crates whose root file is in `id`. - fn source_root_crates(&self, id: SourceRootId) -> Arc<[CrateId]>; + /// Returns the crates in topological order. + /// + /// **Warning**: do not use this query in analysis! It kills incrementality across crate metadata modifications. + #[salsa::input] + fn all_crates(&self) -> Arc>; + + /// Returns an iterator over all transitive dependencies of the given crate, + /// including the crate itself. + /// + /// **Warning**: do not use this query in analysis! It kills incrementality across crate metadata modifications. + /// + #[salsa::transparent] + fn transitive_deps(&self, crate_id: Crate) -> FxHashSet; + /// Returns all transitive reverse dependencies of the given crate, + /// including the crate itself. + /// + /// **Warning**: Do not use this query in analysis! It kills incrementality across crate metadata modifications. + #[salsa::invoke(input::transitive_rev_deps)] #[salsa::transparent] - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]>; + fn transitive_rev_deps(&self, of: Crate) -> FxHashSet; +} + +pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet { + // There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible + // and removing that is a bit difficult. + let mut worklist = vec![crate_id]; + let mut deps = FxHashSet::default(); + + while let Some(krate) = worklist.pop() { + if !deps.insert(krate) { + continue; + } + + worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id)); + } + + deps } #[salsa::db] @@ -257,6 +290,9 @@ pub trait SourceDatabase: salsa::Database { let source_root = self.source_root(source_root.source_root_id(self)); source_root.source_root(self).resolve_path(path) } + + #[doc(hidden)] + fn crates_map(&self) -> Arc; } /// Crate related data shared by the whole workspace. @@ -268,12 +304,8 @@ pub struct CrateWorkspaceData { pub toolchain: Option, } -fn toolchain_channel(db: &dyn RootQueryDb, krate: CrateId) -> Option { - db.crate_workspace_data() - .get(&krate)? - .toolchain - .as_ref() - .and_then(|v| ReleaseChannel::from_str(&v.pre)) +fn toolchain_channel(db: &dyn RootQueryDb, krate: Crate) -> Option { + krate.workspace_data(db).toolchain.as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre)) } fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse { @@ -291,21 +323,19 @@ fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option Arc<[CrateId]> { - let graph = db.crate_graph(); - let mut crates = graph +fn source_root_crates(db: &dyn RootQueryDb, id: SourceRootId) -> Arc<[Crate]> { + let crates = db.all_crates(); + crates .iter() + .copied() .filter(|&krate| { - let root_file = graph[krate].root_file_id; + let root_file = krate.data(db).root_file_id; db.file_source_root(root_file).source_root_id(db) == id }) - .collect::>(); - crates.sort(); - crates.dedup(); - crates.into_iter().collect() + .collect() } -fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[CrateId]> { +fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> { let _p = tracing::info_span!("relevant_crates").entered(); let source_root = db.file_source_root(file_id); diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index 08545b685119d..26860fb932077 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -104,6 +104,12 @@ impl CfgOptions { _ => None, }) } + + pub fn to_hashable(&self) -> HashableCfgOptions { + let mut enabled = self.enabled.iter().cloned().collect::>(); + enabled.sort_unstable(); + HashableCfgOptions { _enabled: enabled } + } } impl Extend for CfgOptions { @@ -256,3 +262,9 @@ impl fmt::Display for InactiveReason { Ok(()) } } + +/// A `CfgOptions` that implements `Hash`, for the sake of hashing only. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct HashableCfgOptions { + _enabled: Box<[CfgAtom]>, +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 52a72bce91dce..579ea12e6ae03 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, hash::Hash, ops}; -use base_db::CrateId; +use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ @@ -44,7 +44,7 @@ impl Attrs { (**self).iter().find(|attr| attr.id == id) } - pub(crate) fn filter(db: &dyn DefDatabase, krate: CrateId, raw_attrs: RawAttrs) -> Attrs { + pub(crate) fn filter(db: &dyn DefDatabase, krate: Crate, raw_attrs: RawAttrs) -> Attrs { Attrs(raw_attrs.filter(db.upcast(), krate)) } } @@ -76,7 +76,6 @@ impl Attrs { // FIXME: There should be some proper form of mapping between item tree field ids and hir field ids let mut res = ArenaMap::default(); - let crate_graph = db.crate_graph(); let item_tree; let (parent, fields, krate) = match v { VariantId::EnumVariantId(it) => { @@ -102,7 +101,7 @@ impl Attrs { } }; - let cfg_options = &crate_graph[krate].cfg_options; + let cfg_options = krate.cfg_options(db); let mut idx = 0; for (id, _field) in fields.iter().enumerate() { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index bec662787728c..9c87dc31dba95 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -2,7 +2,7 @@ pub mod adt; -use base_db::CrateId; +use base_db::Crate; use hir_expand::{ name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind, }; @@ -22,7 +22,7 @@ use crate::{ attr_resolution::ResolvedAttr, diagnostics::{DefDiagnostic, DefDiagnostics}, proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, - DefMap, MacroSubNs, + DefMap, LocalDefMap, MacroSubNs, }, path::ImportAlias, type_ref::{TraitRef, TypeBound, TypeRefId, TypesMap}, @@ -57,8 +57,7 @@ impl FunctionData { item_tree[func.visibility].clone() }; - let crate_graph = db.crate_graph(); - let cfg_options = &crate_graph[krate].cfg_options; + let cfg_options = krate.cfg_options(db); let attr_owner = |idx| { item_tree::AttrOwner::Param(loc.id.value, Idx::from_raw(RawIdx::from(idx as u32))) }; @@ -525,7 +524,7 @@ pub struct ExternCrateDeclData { pub name: Name, pub alias: Option, pub visibility: RawVisibility, - pub crate_id: Option, + pub crate_id: Option, } impl ExternCrateDeclData { @@ -542,7 +541,7 @@ impl ExternCrateDeclData { let crate_id = if name == sym::self_.clone() { Some(krate) } else { - db.crate_graph()[krate].dependencies.iter().find_map(|dep| { + krate.data(db).dependencies.iter().find_map(|dep| { if dep.name.symbol() == name.symbol() { Some(dep.crate_id) } else { @@ -633,6 +632,7 @@ struct AssocItemCollector<'a> { db: &'a dyn DefDatabase, module_id: ModuleId, def_map: Arc, + local_def_map: Arc, diagnostics: Vec, container: ItemContainerId, expander: Expander, @@ -648,10 +648,12 @@ impl<'a> AssocItemCollector<'a> { file_id: HirFileId, container: ItemContainerId, ) -> Self { + let (def_map, local_def_map) = module_id.local_def_map(db); Self { db, module_id, - def_map: module_id.def_map(db), + def_map, + local_def_map, container, expander: Expander::new(db, file_id, module_id), items: Vec::new(), @@ -697,6 +699,7 @@ impl<'a> AssocItemCollector<'a> { let ast_id_with_path = AstIdWithPath { path: attr.path.clone(), ast_id }; match self.def_map.resolve_attr_macro( + &self.local_def_map, self.db, self.module_id.local_id, ast_id_with_path, @@ -780,6 +783,7 @@ impl<'a> AssocItemCollector<'a> { let resolver = |path: &_| { self.def_map .resolve_path( + &self.local_def_map, self.db, module, path, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index 28992ec600aeb..bf8f5024c2d6a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -1,6 +1,6 @@ //! Defines hir-level representation of structs, enums and unions -use base_db::CrateId; +use base_db::Crate; use bitflags::bitflags; use cfg::CfgOptions; use either::Either; @@ -90,7 +90,7 @@ pub struct FieldData { fn repr_from_value( db: &dyn DefDatabase, - krate: CrateId, + krate: Crate, item_tree: &ItemTree, of: AttrOwner, ) -> Option { @@ -222,7 +222,7 @@ impl StructData { loc.container.local_id, loc.id.tree_id(), &item_tree, - &db.crate_graph()[krate].cfg_options, + krate.cfg_options(db), FieldParent::Struct(loc.id.value), &strukt.fields, None, @@ -274,7 +274,7 @@ impl StructData { loc.container.local_id, loc.id.tree_id(), &item_tree, - &db.crate_graph()[krate].cfg_options, + krate.cfg_options(db), FieldParent::Union(loc.id.value), &union.fields, None, @@ -377,7 +377,7 @@ impl EnumVariantData { container.local_id, loc.id.tree_id(), &item_tree, - &db.crate_graph()[krate].cfg_options, + krate.cfg_options(db), FieldParent::Variant(loc.id.value), &variant.fields, Some(item_tree[loc.parent.lookup(db).id.value].visibility), @@ -448,7 +448,7 @@ pub enum StructKind { fn lower_fields( db: &dyn DefDatabase, - krate: CrateId, + krate: Crate, container: LocalModuleId, tree_id: TreeId, item_tree: &ItemTree, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 0772d00f03c8a..b6707af618115 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -1,5 +1,5 @@ //! Defines database & queries for name resolution. -use base_db::{CrateId, RootQueryDb, SourceDatabase, Upcast}; +use base_db::{Crate, RootQueryDb, SourceDatabase, Upcast}; use either::Either; use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; use intern::sym; @@ -20,7 +20,7 @@ use crate::{ import_map::ImportMap, item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps}, lang_item::{self, LangItem, LangItemTarget, LangItems}, - nameres::{diagnostics::DefDiagnostics, DefMap}, + nameres::{diagnostics::DefDiagnostics, DefMap, LocalDefMap}, tt, type_ref::TypesSourceMap, visibility::{self, Visibility}, @@ -130,8 +130,11 @@ pub trait DefDatabase: block_id: BlockId, ) -> (Arc, Arc); - #[salsa::invoke(DefMap::crate_def_map_query)] - fn crate_def_map(&self, krate: CrateId) -> Arc; + #[salsa::invoke_actual(DefMap::crate_local_def_map_query)] + fn crate_local_def_map(&self, krate: Crate) -> (Arc, Arc); + + #[salsa::invoke_actual(DefMap::crate_def_map_query)] + fn crate_def_map(&self, krate: Crate) -> Arc; /// Computes the block-level `DefMap`. #[salsa::invoke_actual(DefMap::block_def_map_query)] @@ -258,10 +261,10 @@ pub trait DefDatabase: // endregion:attrs #[salsa::invoke(LangItems::lang_item_query)] - fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option; + fn lang_item(&self, start_crate: Crate, item: LangItem) -> Option; - #[salsa::invoke(ImportMap::import_map_query)] - fn import_map(&self, krate: CrateId) -> Arc; + #[salsa::invoke_actual(ImportMap::import_map_query)] + fn import_map(&self, krate: Crate) -> Arc; // region:visibilities @@ -277,23 +280,25 @@ pub trait DefDatabase: // endregion:visibilities - #[salsa::invoke(LangItems::crate_lang_items_query)] - fn crate_lang_items(&self, krate: CrateId) -> Option>; + #[salsa::invoke_actual(LangItems::crate_lang_items_query)] + fn crate_lang_items(&self, krate: Crate) -> Option>; - #[salsa::invoke(crate::lang_item::notable_traits_in_deps)] - fn notable_traits_in_deps(&self, krate: CrateId) -> Arc<[Arc<[TraitId]>]>; - #[salsa::invoke(crate::lang_item::crate_notable_traits)] - fn crate_notable_traits(&self, krate: CrateId) -> Option>; + #[salsa::invoke_actual(crate::lang_item::notable_traits_in_deps)] + fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>; + #[salsa::invoke_actual(crate::lang_item::crate_notable_traits)] + fn crate_notable_traits(&self, krate: Crate) -> Option>; - fn crate_supports_no_std(&self, crate_id: CrateId) -> bool; + #[salsa::invoke_actual(crate_supports_no_std)] + fn crate_supports_no_std(&self, crate_id: Crate) -> bool; - fn include_macro_invoc(&self, crate_id: CrateId) -> Arc<[(MacroCallId, EditionedFileId)]>; + #[salsa::invoke_actual(include_macro_invoc)] + fn include_macro_invoc(&self, crate_id: Crate) -> Arc<[(MacroCallId, EditionedFileId)]>; } // return: macro call id and include file id fn include_macro_invoc( db: &dyn DefDatabase, - krate: CrateId, + krate: Crate, ) -> Arc<[(MacroCallId, EditionedFileId)]> { db.crate_def_map(krate) .modules @@ -307,8 +312,8 @@ fn include_macro_invoc( .collect() } -fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool { - let file = db.crate_graph()[crate_id].root_file_id(); +fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool { + let file = crate_id.data(db).root_file_id(); let item_tree = db.file_item_tree(file.into()); let attrs = item_tree.raw_attrs(AttrOwner::TopLevel); for attr in &**attrs { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs index a1b3123c9914e..c5ce8c454ce35 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs @@ -2,7 +2,7 @@ use std::cell::OnceCell; -use base_db::CrateId; +use base_db::Crate; use cfg::CfgOptions; use drop_bomb::DropBomb; use hir_expand::{ @@ -44,7 +44,7 @@ impl Expander { module, recursion_depth: 0, recursion_limit, - cfg_options: db.crate_graph()[module.krate].cfg_options.clone(), + cfg_options: Arc::clone(module.krate.cfg_options(db)), span_map: OnceCell::new(), } } @@ -53,7 +53,7 @@ impl Expander { self.span_map.get_or_init(|| db.span_map(self.current_file_id)) } - pub fn krate(&self) -> CrateId { + pub fn krate(&self) -> Crate { self.module.krate } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs index a55fec4f8b1e1..8aca4eb9bc1ef 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs @@ -86,7 +86,6 @@ impl Body { let item_tree = f.id.item_tree(db); let func = &item_tree[f.id.value]; let krate = f.container.module(db).krate; - let crate_graph = db.crate_graph(); ( param_list, (0..func.params.len()).map(move |idx| { @@ -99,7 +98,7 @@ impl Body { Idx::from_raw(RawIdx::from(idx as u32)), ), ) - .is_cfg_enabled(&crate_graph[krate].cfg_options) + .is_cfg_enabled(krate.cfg_options(db)) }), ) }); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index c3ca610faecbe..c346cec242eb6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -5,7 +5,7 @@ mod asm; use std::mem; -use base_db::CrateId; +use base_db::Crate; use either::Either; use hir_expand::{ mod_path::tool_path, @@ -50,7 +50,7 @@ use crate::{ item_scope::BuiltinShadowMode, lang_item::LangItem, lower::LowerCtx, - nameres::{DefMap, MacroSubNs}, + nameres::{DefMap, LocalDefMap, MacroSubNs}, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness, TypeRef}, AdtId, BlockId, BlockLoc, ConstBlockLoc, DefWithBodyId, MacroId, ModuleDefId, UnresolvedMacro, @@ -64,7 +64,7 @@ pub(super) fn lower_body( expander: Expander, parameters: Option<(ast::ParamList, impl Iterator)>, body: Option, - krate: CrateId, + krate: Crate, is_async_fn: bool, ) -> (Body, BodySourceMap) { // We cannot leave the root span map empty and let any identifier from it be treated as root, @@ -189,7 +189,7 @@ pub(super) fn lower( owner: ExprStoreOwnerId, expander: Expander, body: Option, - krate: CrateId, + krate: Crate, ) -> (ExpressionStore, ExpressionStoreSourceMap) { // We cannot leave the root span map empty and let any identifier from it be treated as root, // because when inside nested macros `SyntaxContextId`s from the outer macro will be interleaved @@ -214,8 +214,9 @@ struct ExprCollector<'a> { expander: Expander, owner: ExprStoreOwnerId, def_map: Arc, + local_def_map: Arc, ast_id_map: Arc, - krate: CrateId, + krate: Crate, store: ExpressionStoreBuilder, source_map: ExpressionStoreSourceMap, @@ -327,14 +328,16 @@ impl ExprCollector<'_> { db: &dyn DefDatabase, owner: ExprStoreOwnerId, expander: Expander, - krate: CrateId, + krate: Crate, span_map: Option>, ) -> ExprCollector<'_> { + let (def_map, local_def_map) = expander.module.local_def_map(db); ExprCollector { db, owner, krate, - def_map: expander.module.def_map(db), + def_map, + local_def_map, source_map: ExpressionStoreSourceMap::default(), ast_id_map: db.ast_id_map(expander.current_file_id()), store: ExpressionStoreBuilder::default(), @@ -1306,6 +1309,7 @@ impl ExprCollector<'_> { None => self.expander.enter_expand(self.db, mcall, |path| { self.def_map .resolve_path( + &self.local_def_map, self.db, module, path, @@ -1608,6 +1612,7 @@ impl ExprCollector<'_> { // This could also be a single-segment path pattern. To // decide that, we need to try resolving the name. let (resolved, _) = self.def_map.resolve_path( + &self.local_def_map, self.db, self.expander.module.local_id, &name.clone().into(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs index 16bf46d3e3f95..7bf27747c464a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs @@ -293,7 +293,7 @@ impl SsrError { assert_eq!(db.body_with_source_map(def).1.diagnostics(), &[]); expect![[r#" fn main() -> () { - _ = $crate::error::SsrError::new( + _ = ra_test_fixture::error::SsrError::new( builtin#lang(Arguments::new_v1_formatted)( &[ "Failed to resolve path `", "`", @@ -353,7 +353,7 @@ fn f(a: i32, b: u32) -> String { expect![[r#" fn f(a: i32, b: u32) -> String { { - $crate::panicking::panic_fmt( + core::panicking::panic_fmt( builtin#lang(Arguments::new_v1_formatted)( &[ "cc", diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index c30ad0163b9db..48f31698ddf8e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -2,7 +2,7 @@ use std::{cell::Cell, cmp::Ordering, iter}; -use base_db::{CrateId, CrateOrigin, LangCrateOrigin}; +use base_db::{Crate, CrateOrigin, LangCrateOrigin}; use hir_expand::{ name::{AsName, Name}, Lookup, @@ -50,7 +50,7 @@ pub fn find_path( prefix: prefix_kind, cfg, ignore_local_imports, - is_std_item: db.crate_graph()[item_module.krate()].origin.is_lang(), + is_std_item: item_module.krate().data(db).origin.is_lang(), from, from_def_map: &from.def_map(db), fuel: Cell::new(FIND_PATH_FUEL), @@ -174,9 +174,9 @@ fn find_path_for_module( } // - otherwise if the item is the crate root of a dependency crate, return the name from the extern prelude - let root_def_map = ctx.from.derive_crate_root().def_map(ctx.db); + let root_local_def_map = ctx.from.derive_crate_root().local_def_map(ctx.db).1; // rev here so we prefer looking at renamed extern decls first - for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude().rev() { + for (name, (def_id, _extern_crate)) in root_local_def_map.extern_prelude().rev() { if crate_root != def_id { continue; } @@ -360,7 +360,7 @@ fn calculate_best_path( // too (unless we can't name it at all). It could *also* be (re)exported by the same crate // that wants to import it here, but we always prefer to use the external path here. - ctx.db.crate_graph()[ctx.from.krate].dependencies.iter().for_each(|dep| { + ctx.from.krate.data(ctx.db).dependencies.iter().for_each(|dep| { find_in_dep(ctx, visited_modules, item, max_len, best_choice, dep.crate_id) }); } @@ -373,11 +373,10 @@ fn find_in_sysroot( max_len: usize, best_choice: &mut Option, ) { - let crate_graph = ctx.db.crate_graph(); - let dependencies = &crate_graph[ctx.from.krate].dependencies; + let dependencies = &ctx.from.krate.data(ctx.db).dependencies; let mut search = |lang, best_choice: &mut _| { if let Some(dep) = dependencies.iter().filter(|it| it.is_sysroot()).find(|dep| { - match crate_graph[dep.crate_id].origin { + match dep.crate_id.data(ctx.db).origin { CrateOrigin::Lang(l) => l == lang, _ => false, } @@ -419,7 +418,7 @@ fn find_in_dep( item: ItemInNs, max_len: usize, best_choice: &mut Option, - dep: CrateId, + dep: Crate, ) { let import_map = ctx.db.import_map(dep); let Some(import_info_for) = import_map.import_info_for(item) else { @@ -688,9 +687,10 @@ mod tests { }) .unwrap(); - let def_map = module.def_map(&db); + let (def_map, local_def_map) = module.local_def_map(&db); let resolved = def_map .resolve_path( + &local_def_map, &db, module.local_id, &mod_path, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs index 80820193796de..09b4591a21a6f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs @@ -23,7 +23,7 @@ use crate::{ expander::Expander, item_tree::{AttrOwner, FileItemTreeId, GenericModItem, GenericsItemTreeNode, ItemTree}, lower::LowerCtx, - nameres::{DefMap, MacroSubNs}, + nameres::{DefMap, LocalDefMap, MacroSubNs}, path::{AssociatedTypeBinding, GenericArg, GenericArgs, NormalPath, Path}, type_ref::{ ArrayType, ConstRef, FnType, LifetimeRef, PathId, RefType, TypeBound, TypeRef, TypeRefId, @@ -313,8 +313,7 @@ impl GenericParams { let _p = tracing::info_span!("generic_params_query").entered(); let krate = def.krate(db); - let cfg_options = db.crate_graph(); - let cfg_options = &cfg_options[krate].cfg_options; + let cfg_options = &krate.cfg_options(db); // Returns the generic parameters that are enabled under the current `#[cfg]` options let enabled_params = @@ -413,7 +412,12 @@ impl GenericParams { &mut types_source_maps, &mut expander, &mut || { - (module.def_map(db), Expander::new(db, loc.id.file_id(), module)) + let (def_map, local_def_map) = module.local_def_map(db); + ( + def_map, + local_def_map, + Expander::new(db, loc.id.file_id(), module), + ) }, param, &item.types_map, @@ -626,8 +630,8 @@ impl GenericParamsCollector { generics_types_map: &mut TypesMap, generics_types_source_map: &mut TypesSourceMap, // FIXME: Change this back to `LazyCell` if https://github.com/rust-lang/libs-team/issues/429 is accepted. - exp: &mut Option<(Arc, Expander)>, - exp_fill: &mut dyn FnMut() -> (Arc, Expander), + exp: &mut Option<(Arc, Arc, Expander)>, + exp_fill: &mut dyn FnMut() -> (Arc, Arc, Expander), type_ref: TypeRefId, types_map: &TypesMap, types_source_map: &TypesSourceMap, @@ -657,12 +661,13 @@ impl GenericParamsCollector { if let TypeRef::Macro(mc) = type_ref { let macro_call = mc.to_node(db.upcast()); - let (def_map, expander) = exp.get_or_insert_with(&mut *exp_fill); + let (def_map, local_def_map, expander) = exp.get_or_insert_with(&mut *exp_fill); let module = expander.module.local_id; let resolver = |path: &_| { def_map .resolve_path( + local_def_map, db, module, path, @@ -690,7 +695,7 @@ impl GenericParamsCollector { ¯o_types_map, ¯o_types_source_map, ); - exp.get_or_insert_with(&mut *exp_fill).1.exit(mark); + exp.get_or_insert_with(&mut *exp_fill).2.exit(mark); } } }); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 64c1d0d274f34..1cdc4c025975c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -2,7 +2,7 @@ use std::fmt; -use base_db::CrateId; +use base_db::Crate; use fst::{raw::IndexedValue, Automaton, Streamer}; use hir_expand::name::Name; use itertools::Itertools; @@ -78,7 +78,7 @@ impl ImportMap { out } - pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc { + pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: Crate) -> Arc { let _p = tracing::info_span!("import_map_query").entered(); let map = Self::collect_import_map(db, krate); @@ -129,7 +129,7 @@ impl ImportMap { self.item_to_info_map.get(&item).map(|(info, _)| &**info) } - fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMapIndex { + fn collect_import_map(db: &dyn DefDatabase, krate: Crate) -> ImportMapIndex { let _p = tracing::info_span!("collect_import_map").entered(); let def_map = db.crate_def_map(krate); @@ -400,15 +400,13 @@ impl Query { /// This returns a list of items that could be imported from dependencies of `krate`. pub fn search_dependencies( db: &dyn DefDatabase, - krate: CrateId, + krate: Crate, query: &Query, ) -> FxHashSet { let _p = tracing::info_span!("search_dependencies", ?query).entered(); - let graph = db.crate_graph(); - let import_maps: Vec<_> = - graph[krate].dependencies.iter().map(|dep| db.import_map(dep.crate_id)).collect(); + krate.data(db).dependencies.iter().map(|dep| db.import_map(dep.crate_id)).collect(); let mut op = fst::map::OpBuilder::new(); @@ -512,11 +510,13 @@ mod tests { expect: Expect, ) { let db = TestDB::with_files(ra_fixture); - let crate_graph = db.crate_graph(); - let krate = crate_graph + let all_crates = db.all_crates(); + let krate = all_crates .iter() + .copied() .find(|&krate| { - crate_graph[krate] + krate + .extra_data(&db) .display_name .as_ref() .is_some_and(|it| it.crate_name().as_str() == crate_name) @@ -545,7 +545,7 @@ mod tests { Some(format!( "{}::{} ({})\n", - crate_graph[dependency_krate].display_name.as_ref()?, + dependency_krate.extra_data(&db).display_name.as_ref()?, path, mark )) @@ -590,12 +590,13 @@ mod tests { fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let db = TestDB::with_files(ra_fixture); - let crate_graph = db.crate_graph(); + let all_crates = db.all_crates(); - let actual = crate_graph + let actual = all_crates .iter() + .copied() .filter_map(|krate| { - let cdata = &crate_graph[krate]; + let cdata = &krate.extra_data(&db); let name = cdata.display_name.as_ref()?; let map = db.import_map(krate); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 0ca1eb9bcfe37..0c683f3531c95 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -3,7 +3,7 @@ use std::sync::LazyLock; -use base_db::CrateId; +use base_db::Crate; use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId}; use indexmap::map::Entry; use itertools::Itertools; @@ -916,7 +916,7 @@ impl ItemInNs { } /// Returns the crate defining this item (or `None` if `self` is built-in). - pub fn krate(&self, db: &dyn DefDatabase) -> Option { + pub fn krate(&self, db: &dyn DefDatabase) -> Option { match self { ItemInNs::Types(id) | ItemInNs::Values(id) => id.module(db).map(|m| m.krate), ItemInNs::Macros(id) => Some(id.module(db).krate), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 382afbcb1dd4f..9acf98e62cd5c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -44,7 +44,7 @@ use std::{ }; use ast::{AstNode, StructKind}; -use base_db::CrateId; +use base_db::Crate; use either::Either; use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile}; use intern::{Interned, Symbol}; @@ -202,7 +202,7 @@ impl ItemTree { } /// Returns the inner attributes of the source file. - pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { + pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs { Attrs::filter( db, krate, @@ -214,7 +214,7 @@ impl ItemTree { self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY) } - pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs { + pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: Crate, of: AttrOwner) -> Attrs { Attrs::filter(db, krate, self.raw_attrs(of).clone()) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 59f51db9f7401..70c28009f4b99 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use triomphe::Arc; use crate::{ - db::DefDatabase, path::Path, AdtId, AssocItemId, AttrDefId, CrateId, EnumId, EnumVariantId, + db::DefDatabase, path::Path, AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId, }; @@ -96,7 +96,7 @@ impl LangItems { /// Salsa query. This will look for lang items in a specific crate. pub(crate) fn crate_lang_items_query( db: &dyn DefDatabase, - krate: CrateId, + krate: Crate, ) -> Option> { let _p = tracing::info_span!("crate_lang_items_query").entered(); @@ -175,7 +175,7 @@ impl LangItems { /// traversing its dependencies. pub(crate) fn lang_item_query( db: &dyn DefDatabase, - start_crate: CrateId, + start_crate: Crate, item: LangItem, ) -> Option { let _p = tracing::info_span!("lang_item_query").entered(); @@ -184,10 +184,7 @@ impl LangItems { { return Some(target); } - db.crate_graph()[start_crate] - .dependencies - .iter() - .find_map(|dep| db.lang_item(dep.crate_id, item)) + start_crate.data(db).dependencies.iter().find_map(|dep| db.lang_item(dep.crate_id, item)) } fn collect_lang_item( @@ -209,19 +206,14 @@ pub(crate) fn lang_attr(db: &dyn DefDatabase, item: AttrDefId) -> Option Arc<[Arc<[TraitId]>]> { +pub(crate) fn notable_traits_in_deps(db: &dyn DefDatabase, krate: Crate) -> Arc<[Arc<[TraitId]>]> { let _p = tracing::info_span!("notable_traits_in_deps", ?krate).entered(); - let crate_graph = db.crate_graph(); - Arc::from_iter( - crate_graph.transitive_deps(krate).filter_map(|krate| db.crate_notable_traits(krate)), + db.transitive_deps(krate).into_iter().filter_map(|krate| db.crate_notable_traits(krate)), ) } -pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: CrateId) -> Option> { +pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option> { let _p = tracing::info_span!("crate_notable_traits", ?krate).entered(); let mut traits = Vec::new(); @@ -290,17 +282,12 @@ impl LangItem { Self::from_symbol(name.symbol()) } - pub fn path(&self, db: &dyn DefDatabase, start_crate: CrateId) -> Option { + pub fn path(&self, db: &dyn DefDatabase, start_crate: Crate) -> Option { let t = db.lang_item(start_crate, *self)?; Some(Path::LangItem(t, None)) } - pub fn ty_rel_path( - &self, - db: &dyn DefDatabase, - start_crate: CrateId, - seg: Name, - ) -> Option { + pub fn ty_rel_path(&self, db: &dyn DefDatabase, start_crate: Crate, seg: Name) -> Option { let t = db.lang_item(start_crate, *self)?; Some(Path::LangItem(t, Some(seg))) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 15ef8364ed215..fbbeb4beb99b9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -71,7 +71,7 @@ mod test_db; use std::hash::{Hash, Hasher}; -use base_db::{impl_intern_key, CrateId}; +use base_db::{impl_intern_key, Crate}; use hir_expand::{ builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, @@ -99,10 +99,10 @@ use crate::{ Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant, }, + nameres::LocalDefMap, }; -type FxIndexMap = - indexmap::IndexMap>; +type FxIndexMap = indexmap::IndexMap; /// A wrapper around three booleans #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] pub struct ImportPathConfig { @@ -338,7 +338,7 @@ pub struct ConstBlockLoc { /// A `ModuleId` that is always a crate's root module. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct CrateRootModuleId { - krate: CrateId, + krate: Crate, } impl CrateRootModuleId { @@ -346,7 +346,11 @@ impl CrateRootModuleId { db.crate_def_map(self.krate) } - pub fn krate(self) -> CrateId { + pub(crate) fn local_def_map(&self, db: &dyn DefDatabase) -> (Arc, Arc) { + db.crate_local_def_map(self.krate) + } + + pub fn krate(self) -> Crate { self.krate } } @@ -374,8 +378,8 @@ impl From for ModuleDefId { } } -impl From for CrateRootModuleId { - fn from(krate: CrateId) -> Self { +impl From for CrateRootModuleId { + fn from(krate: Crate) -> Self { CrateRootModuleId { krate } } } @@ -394,7 +398,7 @@ impl TryFrom for CrateRootModuleId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct ModuleId { - krate: CrateId, + krate: Crate, /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the /// `BlockId` of that block expression. If `None`, this module is part of the crate-level /// `DefMap` of `krate`. @@ -411,11 +415,22 @@ impl ModuleId { } } + pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (Arc, Arc) { + match self.block { + Some(block) => (db.block_def_map(block), self.only_local_def_map(db)), + None => db.crate_local_def_map(self.krate), + } + } + + pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> Arc { + db.crate_local_def_map(self.krate).1 + } + pub fn crate_def_map(self, db: &dyn DefDatabase) -> Arc { db.crate_def_map(self.krate) } - pub fn krate(self) -> CrateId { + pub fn krate(self) -> Crate { self.krate } @@ -982,7 +997,7 @@ impl From for ModuleDefId { } impl CallableDefId { - pub fn krate(self, db: &dyn DefDatabase) -> CrateId { + pub fn krate(self, db: &dyn DefDatabase) -> Crate { match self { CallableDefId::FunctionId(f) => f.krate(db), CallableDefId::StructId(s) => s.krate(db), @@ -1119,7 +1134,7 @@ pub trait HasModule { /// Returns the crate this thing is defined within. #[inline] #[doc(alias = "crate")] - fn krate(&self, db: &dyn DefDatabase) -> CrateId { + fn krate(&self, db: &dyn DefDatabase) -> Crate { self.module(db).krate } } @@ -1367,7 +1382,7 @@ pub trait AsMacroCall { fn as_call_id( &self, db: &dyn ExpandDatabase, - krate: CrateId, + krate: Crate, resolver: impl Fn(&path::ModPath) -> Option + Copy, ) -> Option { self.as_call_id_with_errors(db, krate, resolver).ok()?.value @@ -1376,7 +1391,7 @@ pub trait AsMacroCall { fn as_call_id_with_errors( &self, db: &dyn ExpandDatabase, - krate: CrateId, + krate: Crate, resolver: impl Fn(&path::ModPath) -> Option + Copy, ) -> Result>, UnresolvedMacro>; } @@ -1385,7 +1400,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> { fn as_call_id_with_errors( &self, db: &dyn ExpandDatabase, - krate: CrateId, + krate: Crate, resolver: impl Fn(&path::ModPath) -> Option + Copy, ) -> Result>, UnresolvedMacro> { let expands_to = hir_expand::ExpandTo::from_call_site(self.value); @@ -1442,7 +1457,7 @@ fn macro_call_as_call_id( call: &AstIdWithPath, call_site: SyntaxContextId, expand_to: ExpandTo, - krate: CrateId, + krate: Crate, resolver: impl Fn(&path::ModPath) -> Option + Copy, ) -> Result, UnresolvedMacro> { macro_call_as_call_id_with_eager( @@ -1464,7 +1479,7 @@ fn macro_call_as_call_id_with_eager( path: &path::ModPath, call_site: SyntaxContextId, expand_to: ExpandTo, - krate: CrateId, + krate: Crate, resolver: impl FnOnce(&path::ModPath) -> Option, eager_resolver: impl Fn(&path::ModPath) -> Option, ) -> Result>, UnresolvedMacro> { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index d0678a40652fd..70b512c014b94 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -376,4 +376,8 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander { panic!("got invalid macro input: {:?}", parse.errors()); } } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 5b3d75c4ee669..054c285fa2567 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -59,7 +59,7 @@ mod tests; use std::ops::Deref; -use base_db::CrateId; +use base_db::Crate; use hir_expand::{ name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId, }; @@ -69,7 +69,7 @@ use la_arena::Arena; use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, EditionedFileId, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; -use syntax::{ast, AstNode, SmolStr, SyntaxNode}; +use syntax::{ast, AstNode, SmolStr, SyntaxNode, ToSmolStr}; use triomphe::Arc; use tt::TextRange; @@ -95,6 +95,39 @@ const PREDEFINED_TOOLS: &[SmolStr] = &[ SmolStr::new_static("rust_analyzer"), ]; +/// Parts of the def map that are only needed when analyzing code in the same crate. +/// +/// There are some data in the def map (e.g. extern prelude) that is only needed when analyzing +/// things in the same crate (and maybe in the IDE layer), e.g. the extern prelude. If we put +/// it in the DefMap dependant DefMaps will be invalidated when they change (e.g. when we add +/// a dependency to the crate). Instead we split them out of the DefMap into a LocalDefMap struct. +/// `crate_local_def_map()` returns both, and `crate_def_map()` returns only the external-relevant +/// DefMap. +#[derive(Debug, PartialEq, Eq, Default)] +pub struct LocalDefMap { + // FIXME: There are probably some other things that could be here, but this is less severe and you + // need to be careful with things that block def maps also have. + /// The extern prelude which contains all root modules of external crates that are in scope. + extern_prelude: FxIndexMap)>, +} + +impl LocalDefMap { + pub(crate) const EMPTY: &Self = + &Self { extern_prelude: FxIndexMap::with_hasher(rustc_hash::FxBuildHasher) }; + + fn shrink_to_fit(&mut self) { + let Self { extern_prelude } = self; + extern_prelude.shrink_to_fit(); + } + + pub(crate) fn extern_prelude( + &self, + ) -> impl DoubleEndedIterator))> + '_ + { + self.extern_prelude.iter().map(|(name, &def)| (name, def)) + } +} + /// Contains the results of (early) name resolution. /// /// A `DefMap` stores the module tree and the definitions that are in scope in every module after @@ -107,7 +140,7 @@ const PREDEFINED_TOOLS: &[SmolStr] = &[ #[derive(Debug, PartialEq, Eq)] pub struct DefMap { /// The crate this `DefMap` belongs to. - krate: CrateId, + krate: Crate, /// When this is a block def map, this will hold the block id of the block and module that /// contains this block. block: Option, @@ -141,9 +174,6 @@ pub struct DefMap { /// Data that belongs to a crate which is shared between a crate's def map and all its block def maps. #[derive(Clone, Debug, PartialEq, Eq)] struct DefMapCrateData { - /// The extern prelude which contains all root modules of external crates that are in scope. - extern_prelude: FxIndexMap)>, - /// Side table for resolving derive helpers. exported_derives: FxHashMap>, fn_proc_macro_mapping: FxHashMap, @@ -166,7 +196,6 @@ struct DefMapCrateData { impl DefMapCrateData { fn new(edition: Edition) -> Self { Self { - extern_prelude: FxIndexMap::default(), exported_derives: FxHashMap::default(), fn_proc_macro_mapping: FxHashMap::default(), registered_attrs: Vec::new(), @@ -182,7 +211,6 @@ impl DefMapCrateData { fn shrink_to_fit(&mut self) { let Self { - extern_prelude, exported_derives, fn_proc_macro_mapping, registered_attrs, @@ -194,7 +222,6 @@ impl DefMapCrateData { edition: _, recursion_limit: _, } = self; - extern_prelude.shrink_to_fit(); exported_derives.shrink_to_fit(); fn_proc_macro_mapping.shrink_to_fit(); registered_attrs.shrink_to_fit(); @@ -219,11 +246,11 @@ struct BlockRelativeModuleId { } impl BlockRelativeModuleId { - fn def_map(self, db: &dyn DefDatabase, krate: CrateId) -> Arc { + fn def_map(self, db: &dyn DefDatabase, krate: Crate) -> Arc { self.into_module(krate).def_map(db) } - fn into_module(self, krate: CrateId) -> ModuleId { + fn into_module(self, krate: Crate) -> ModuleId { ModuleId { krate, block: self.block, local_id: self.local_id } } @@ -337,11 +364,25 @@ impl DefMap { self.data.edition } - pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: CrateId) -> Arc { - let crate_graph = db.crate_graph(); - let krate = &crate_graph[crate_id]; - let name = krate.display_name.as_deref().map(Symbol::as_str).unwrap_or_default(); - let _p = tracing::info_span!("crate_def_map_query", ?name).entered(); + pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: Crate) -> Arc { + db.crate_local_def_map(crate_id).0 + } + + pub(crate) fn crate_local_def_map_query( + db: &dyn DefDatabase, + crate_id: Crate, + ) -> (Arc, Arc) { + let krate = crate_id.data(db); + let _p = tracing::info_span!( + "crate_def_map_query", + name=?crate_id + .extra_data(db) + .display_name + .as_ref() + .map(|it| it.crate_name().to_smolstr()) + .unwrap_or_default() + ) + .entered(); let module_data = ModuleData::new( ModuleOrigin::CrateRoot { definition: krate.root_file_id() }, @@ -354,10 +395,14 @@ impl DefMap { module_data, None, ); - let def_map = - collector::collect_defs(db, def_map, TreeId::new(krate.root_file_id().into(), None)); + let (def_map, local_def_map) = collector::collect_defs( + db, + def_map, + TreeId::new(krate.root_file_id().into(), None), + None, + ); - Arc::new(def_map) + (Arc::new(def_map), Arc::new(local_def_map)) } pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc { @@ -370,10 +415,10 @@ impl DefMap { let module_data = ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility); - let parent_map = module.def_map(db); + let (crate_map, crate_local_map) = db.crate_local_def_map(module.krate); let def_map = DefMap::empty( module.krate, - parent_map.data.clone(), + crate_map.data.clone(), module_data, Some(BlockInfo { block: block_id, @@ -381,13 +426,17 @@ impl DefMap { }), ); - let def_map = - collector::collect_defs(db, def_map, TreeId::new(ast_id.file_id, Some(block_id))); + let (def_map, _) = collector::collect_defs( + db, + def_map, + TreeId::new(ast_id.file_id, Some(block_id)), + Some(crate_local_map), + ); Arc::new(def_map) } fn empty( - krate: CrateId, + krate: Crate, crate_data: Arc, module_data: ModuleData, block: Option, @@ -479,7 +528,7 @@ impl DefMap { self.data.fn_proc_macro_mapping.get(&id).copied() } - pub fn krate(&self) -> CrateId { + pub fn krate(&self) -> Crate { self.krate } @@ -590,19 +639,13 @@ impl DefMap { self.prelude } - pub(crate) fn extern_prelude( - &self, - ) -> impl DoubleEndedIterator))> + '_ - { - self.data.extern_prelude.iter().map(|(name, &def)| (name, def)) - } - pub(crate) fn macro_use_prelude(&self) -> &FxHashMap)> { &self.macro_use_prelude } pub(crate) fn resolve_path( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, original_module: LocalModuleId, path: &ModPath, @@ -610,6 +653,7 @@ impl DefMap { expected_macro_subns: Option, ) -> (PerNs, Option) { let res = self.resolve_path_fp_with_macro( + local_def_map, db, ResolveMode::Other, original_module, @@ -624,12 +668,14 @@ impl DefMap { /// points at the unresolved segments. pub(crate) fn resolve_path_locally( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, original_module: LocalModuleId, path: &ModPath, shadow: BuiltinShadowMode, ) -> (PerNs, Option, ResolvePathResultPrefixInfo) { let res = self.resolve_path_fp_with_macro_single( + local_def_map, db, ResolveMode::Other, original_module, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index d1f6ed023c2fa..289b9e2fb7e9f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -1,6 +1,6 @@ //! Post-nameres attribute resolution. -use base_db::CrateId; +use base_db::Crate; use hir_expand::{ attrs::{Attr, AttrId, AttrInput}, inert_attr_macro::find_builtin_attr_idx, @@ -13,7 +13,7 @@ use triomphe::Arc; use crate::{ db::DefDatabase, item_scope::BuiltinShadowMode, - nameres::path_resolution::ResolveMode, + nameres::{path_resolution::ResolveMode, LocalDefMap}, path::{self, ModPath, PathKind}, AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro, }; @@ -30,6 +30,7 @@ pub enum ResolvedAttr { impl DefMap { pub(crate) fn resolve_attr_macro( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, original_module: LocalModuleId, ast_id: AstIdWithPath, @@ -42,6 +43,7 @@ impl DefMap { } let resolved_res = self.resolve_path_fp_with_macro( + local_def_map, db, ResolveMode::Other, original_module, @@ -105,7 +107,7 @@ pub(super) fn attr_macro_as_call_id( db: &dyn DefDatabase, item_attr: &AstIdWithPath, macro_attr: &Attr, - krate: CrateId, + krate: Crate, def: MacroDefId, ) -> MacroCallId { let arg = match macro_attr.input.as_deref() { @@ -136,7 +138,7 @@ pub(super) fn derive_macro_as_call_id( derive_attr_index: AttrId, derive_pos: u32, call_site: SyntaxContextId, - krate: CrateId, + krate: Crate, resolver: impl Fn(&path::ModPath) -> Option<(MacroId, MacroDefId)>, derive_macro_id: MacroCallId, ) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index bf013c25ef5e3..371e99433469f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -5,7 +5,7 @@ use std::{cmp::Ordering, iter, mem, ops::Not}; -use base_db::{CrateId, CrateOrigin, Dependency, LangCrateOrigin}; +use base_db::{BuiltDependency, Crate, CrateOrigin, LangCrateOrigin}; use cfg::{CfgAtom, CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ @@ -39,8 +39,8 @@ use crate::{ mod_resolution::ModDir, path_resolution::ReachedFixedPoint, proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroDef, ProcMacroKind}, - sub_namespace_match, BuiltinShadowMode, DefMap, MacroSubNs, ModuleData, ModuleOrigin, - ResolveMode, + sub_namespace_match, BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, ModuleData, + ModuleOrigin, ResolveMode, }, path::{ImportAlias, ModPath, PathKind}, per_ns::{Item, PerNs}, @@ -57,10 +57,14 @@ use crate::{ const GLOB_RECURSION_LIMIT: usize = 100; const FIXED_POINT_LIMIT: usize = 8192; -pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeId) -> DefMap { - let crate_graph = db.crate_graph(); - - let krate = &crate_graph[def_map.krate]; +pub(super) fn collect_defs( + db: &dyn DefDatabase, + def_map: DefMap, + tree_id: TreeId, + crate_local_def_map: Option>, +) -> (DefMap, LocalDefMap) { + let krate = &def_map.krate.data(db); + let cfg_options = def_map.krate.cfg_options(db); // populate external prelude and dependency list let mut deps = @@ -72,8 +76,10 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI } let proc_macros = if krate.is_proc_macro { - db.proc_macros() - .for_crate(def_map.krate, db.syntax_context(tree_id.file_id(), krate.edition)) + db.proc_macros_for_crate(def_map.krate) + .and_then(|proc_macros| { + proc_macros.list(db.syntax_context(tree_id.file_id(), krate.edition)) + }) .unwrap_or_default() } else { Default::default() @@ -82,13 +88,15 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI let mut collector = DefCollector { db, def_map, + local_def_map: LocalDefMap::default(), + crate_local_def_map, deps, glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), indeterminate_imports: Vec::new(), unresolved_macros: Vec::new(), mod_dirs: FxHashMap::default(), - cfg_options: &krate.cfg_options, + cfg_options, proc_macros, from_glob_import: Default::default(), skip_attrs: Default::default(), @@ -101,9 +109,10 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI collector.seed_with_top_level(); } collector.collect(); - let mut def_map = collector.finish(); + let (mut def_map, mut local_def_map) = collector.finish(); def_map.shrink_to_fit(); - def_map + local_def_map.shrink_to_fit(); + (def_map, local_def_map) } #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -205,8 +214,11 @@ enum MacroDirectiveKind { struct DefCollector<'a> { db: &'a dyn DefDatabase, def_map: DefMap, + local_def_map: LocalDefMap, + /// Set only in case of blocks. + crate_local_def_map: Option>, // The dependencies of the current crate, including optional deps like `test`. - deps: FxHashMap, + deps: FxHashMap, glob_imports: FxHashMap>, unresolved_imports: Vec, indeterminate_imports: Vec<(ImportDirective, PerNs)>, @@ -238,8 +250,7 @@ impl DefCollector<'_> { fn seed_with_top_level(&mut self) { let _p = tracing::info_span!("seed_with_top_level").entered(); - let crate_graph = self.db.crate_graph(); - let file_id = crate_graph[self.def_map.krate].root_file_id(); + let file_id = self.def_map.krate.data(self.db).root_file_id(); let item_tree = self.db.file_item_tree(file_id.into()); let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate); let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); @@ -310,20 +321,24 @@ impl DefCollector<'_> { // don't do pre-configured attribute resolution yet. // So here check if we are no_core / no_std and we are trying to add the // corresponding dep from the sysroot - let skip = match crate_graph[dep.crate_id].origin { - CrateOrigin::Lang(LangCrateOrigin::Core) => { - crate_data.no_core && dep.is_sysroot() - } - CrateOrigin::Lang(LangCrateOrigin::Std) => { - crate_data.no_std && dep.is_sysroot() - } - _ => false, - }; + + // Depending on the crate data of a dependency seems bad for incrementality, but + // we only do that for sysroot crates (this is why the order of the `&&` is important) + // - which are normally standard library crate, which realistically aren't going + // to have their crate ID invalidated, because they stay on the same root file and + // they're dependencies of everything else, so if some collision miraculously occurs + // we will resolve it by disambiguating the other crate. + let skip = dep.is_sysroot() + && match dep.crate_id.data(self.db).origin { + CrateOrigin::Lang(LangCrateOrigin::Core) => crate_data.no_core, + CrateOrigin::Lang(LangCrateOrigin::Std) => crate_data.no_std, + _ => false, + }; if skip { continue; } - crate_data + self.local_def_map .extern_prelude .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None)); } @@ -494,7 +509,7 @@ impl DefCollector<'_> { let krate = if self.def_map.data.no_std { Name::new_symbol_root(sym::core.clone()) - } else if self.def_map.extern_prelude().any(|(name, _)| *name == sym::std.clone()) { + } else if self.local_def_map().extern_prelude().any(|(name, _)| *name == sym::std.clone()) { Name::new_symbol_root(sym::std.clone()) } else { // If `std` does not exist for some reason, fall back to core. This mostly helps @@ -518,8 +533,14 @@ impl DefCollector<'_> { [krate, Name::new_symbol_root(sym::prelude.clone()), edition], ); - let (per_ns, _) = - self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None); + let (per_ns, _) = self.def_map.resolve_path( + self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map), + self.db, + DefMap::ROOT, + &path, + BuiltinShadowMode::Other, + None, + ); match per_ns.types { Some(Item { def: ModuleDefId::ModuleId(m), import, .. }) => { @@ -535,6 +556,10 @@ impl DefCollector<'_> { } } + fn local_def_map(&mut self) -> &LocalDefMap { + self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map) + } + /// Adds a definition of procedural macro `name` to the root module. /// /// # Notes on procedural macro resolution @@ -660,7 +685,13 @@ impl DefCollector<'_> { ) { let vis = self .def_map - .resolve_visibility(self.db, module_id, vis, false) + .resolve_visibility( + self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map), + self.db, + module_id, + vis, + false, + ) .unwrap_or(Visibility::Public); self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( @@ -694,7 +725,7 @@ impl DefCollector<'_> { /// created by `use` in the root module, ignoring the visibility of `use`. fn import_macros_from_extern_crate( &mut self, - krate: CrateId, + krate: Crate, names: Option>, extern_crate: Option, ) { @@ -779,6 +810,7 @@ impl DefCollector<'_> { .entered(); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition); let res = self.def_map.resolve_path_fp_with_macro( + self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map), self.db, ResolveMode::Import, module_id, @@ -814,7 +846,13 @@ impl DefCollector<'_> { let mut def = directive.status.namespaces(); let vis = self .def_map - .resolve_visibility(self.db, module_id, &directive.import.visibility, false) + .resolve_visibility( + self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map), + self.db, + module_id, + &directive.import.visibility, + false, + ) .unwrap_or(Visibility::Public); match import.source { @@ -1210,6 +1248,7 @@ impl DefCollector<'_> { }; let resolver = |path: &_| { let resolved_res = self.def_map.resolve_path_fp_with_macro( + self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map), self.db, ResolveMode::Other, directive.module_id, @@ -1495,7 +1534,7 @@ impl DefCollector<'_> { .collect(item_tree.top_level_items(), container); } - fn finish(mut self) -> DefMap { + fn finish(mut self) -> (DefMap, LocalDefMap) { // Emit diagnostics for all remaining unexpanded macros. let _p = tracing::info_span!("DefCollector::finish").entered(); @@ -1511,6 +1550,7 @@ impl DefCollector<'_> { self.def_map.krate, |path| { let resolved_res = self.def_map.resolve_path_fp_with_macro( + self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map), self.db, ResolveMode::Other, directive.module_id, @@ -1582,7 +1622,7 @@ impl DefCollector<'_> { )); } - self.def_map + (self.def_map, self.local_def_map) } } @@ -1635,9 +1675,9 @@ impl ModCollector<'_, '_> { None, ) }; - let resolve_vis = |def_map: &DefMap, visibility| { + let resolve_vis = |def_map: &DefMap, local_def_map: &LocalDefMap, visibility| { def_map - .resolve_visibility(db, module_id, visibility, false) + .resolve_visibility(local_def_map, db, module_id, visibility, false) .unwrap_or(Visibility::Public) }; @@ -1658,6 +1698,11 @@ impl ModCollector<'_, '_> { let module = self.def_collector.def_map.module_id(module_id); let def_map = &mut self.def_collector.def_map; + let local_def_map = self + .def_collector + .crate_local_def_map + .as_deref() + .unwrap_or(&self.def_collector.local_def_map); match item { ModItem::Mod(m) => self.collect_module(m, &attrs), @@ -1711,13 +1756,13 @@ impl ModCollector<'_, '_> { }; if let Some(resolved) = resolved { - let vis = resolve_vis(def_map, &self.item_tree[*visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[*visibility]); if is_crate_root { // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 if let Some(name) = name { - Arc::get_mut(&mut def_map.data) - .unwrap() + self.def_collector + .local_def_map .extern_prelude .insert(name.clone(), (resolved, Some(id))); } @@ -1784,7 +1829,7 @@ impl ModCollector<'_, '_> { let fn_id = FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db); - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); if self.def_collector.def_map.block.is_none() && self.def_collector.is_proc_macro @@ -1804,7 +1849,7 @@ impl ModCollector<'_, '_> { ModItem::Struct(id) => { let it = &self.item_tree[id]; - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, StructLoc { container: module, id: ItemTreeId::new(self.tree_id, id) } @@ -1818,7 +1863,7 @@ impl ModCollector<'_, '_> { ModItem::Union(id) => { let it = &self.item_tree[id]; - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, UnionLoc { container: module, id: ItemTreeId::new(self.tree_id, id) } @@ -1835,7 +1880,7 @@ impl ModCollector<'_, '_> { EnumLoc { container: module, id: ItemTreeId::new(self.tree_id, id) } .intern(db); - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def(self.def_collector, enum_.into(), &it.name, vis, false); let mut index = 0; @@ -1878,7 +1923,8 @@ impl ModCollector<'_, '_> { match &it.name { Some(name) => { - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = + resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def(self.def_collector, const_id.into(), name, vis, false); } None => { @@ -1892,7 +1938,7 @@ impl ModCollector<'_, '_> { ModItem::Static(id) => { let it = &self.item_tree[id]; - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, StaticLoc { container, id: ItemTreeId::new(self.tree_id, id) } @@ -1906,7 +1952,7 @@ impl ModCollector<'_, '_> { ModItem::Trait(id) => { let it = &self.item_tree[id]; - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, TraitLoc { container: module, id: ItemTreeId::new(self.tree_id, id) } @@ -1920,7 +1966,7 @@ impl ModCollector<'_, '_> { ModItem::TraitAlias(id) => { let it = &self.item_tree[id]; - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, TraitAliasLoc { container: module, id: ItemTreeId::new(self.tree_id, id) } @@ -1934,7 +1980,7 @@ impl ModCollector<'_, '_> { ModItem::TypeAlias(id) => { let it = &self.item_tree[id]; - let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); + let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, TypeAliasLoc { container, id: ItemTreeId::new(self.tree_id, id) } @@ -1971,7 +2017,7 @@ impl ModCollector<'_, '_> { &mut self, extern_crate_id: ExternCrateId, macro_use_attrs: impl Iterator, - target_crate: CrateId, + target_crate: Crate, ) { cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); let mut single_imports = Vec::new(); @@ -2115,7 +2161,16 @@ impl ModCollector<'_, '_> { ) -> LocalModuleId { let def_map = &mut self.def_collector.def_map; let vis = def_map - .resolve_visibility(self.def_collector.db, self.module_id, visibility, false) + .resolve_visibility( + self.def_collector + .crate_local_def_map + .as_deref() + .unwrap_or(&self.def_collector.local_def_map), + self.def_collector.db, + self.module_id, + visibility, + false, + ) .unwrap_or(Visibility::Public); let origin = match definition { None => ModuleOrigin::Inline { @@ -2417,6 +2472,10 @@ impl ModCollector<'_, '_> { }, |path| { let resolved_res = self.def_collector.def_map.resolve_path_fp_with_macro( + self.def_collector + .crate_local_def_map + .as_deref() + .unwrap_or(&self.def_collector.local_def_map), db, ResolveMode::Other, self.module_id, @@ -2517,7 +2576,6 @@ impl ModCollector<'_, '_> { #[cfg(test)] mod tests { - use base_db::RootQueryDb; use test_fixture::WithFixture; use crate::{nameres::DefMapCrateData, test_db::TestDB}; @@ -2528,6 +2586,8 @@ mod tests { let mut collector = DefCollector { db, def_map, + local_def_map: LocalDefMap::default(), + crate_local_def_map: None, deps: FxHashMap::default(), glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), @@ -2550,7 +2610,7 @@ mod tests { let (db, file_id) = TestDB::with_single_file(not_ra_fixture); let krate = db.test_crate(); - let edition = db.crate_graph()[krate].edition; + let edition = krate.data(&db).edition; let module_origin = ModuleOrigin::CrateRoot { definition: file_id }; let def_map = DefMap::empty( krate, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index 47c08d3d1dc67..977bc16adf7ee 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -19,7 +19,7 @@ use crate::{ db::DefDatabase, item_scope::{ImportOrExternCrate, BUILTIN_SCOPE}, item_tree::FieldsShape, - nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs}, + nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs}, path::{ModPath, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, @@ -91,6 +91,7 @@ impl PerNs { impl DefMap { pub(crate) fn resolve_visibility( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, // module to import to original_module: LocalModuleId, @@ -101,8 +102,14 @@ impl DefMap { ) -> Option { let mut vis = match visibility { RawVisibility::Module(path, explicitness) => { - let (result, remaining) = - self.resolve_path(db, original_module, path, BuiltinShadowMode::Module, None); + let (result, remaining) = self.resolve_path( + local_def_map, + db, + original_module, + path, + BuiltinShadowMode::Module, + None, + ); if remaining.is_some() { return None; } @@ -137,6 +144,7 @@ impl DefMap { // the result. pub(super) fn resolve_path_fp_with_macro( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, mode: ResolveMode, // module to import to @@ -148,6 +156,7 @@ impl DefMap { expected_macro_subns: Option, ) -> ResolvePathResult { let mut result = self.resolve_path_fp_with_macro_single( + local_def_map, db, mode, original_module, @@ -196,6 +205,7 @@ impl DefMap { current_map = &arc; let new = current_map.resolve_path_fp_in_all_preludes( + local_def_map, db, mode, original_module, @@ -210,6 +220,7 @@ impl DefMap { } let new = current_map.resolve_path_fp_with_macro_single( + local_def_map, db, mode, original_module, @@ -224,6 +235,7 @@ impl DefMap { pub(super) fn resolve_path_fp_with_macro_single( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, mode: ResolveMode, original_module: LocalModuleId, @@ -258,7 +270,12 @@ impl DefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; tracing::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude(db, original_module, segment) + self.resolve_name_in_crate_root_or_extern_prelude( + local_def_map, + db, + original_module, + segment, + ) } PathKind::Plain => { let (_, segment) = match segments.next() { @@ -276,6 +293,7 @@ impl DefMap { tracing::debug!("resolving {:?} in module", segment); self.resolve_name_in_module( + local_def_map, db, original_module, segment, @@ -321,7 +339,9 @@ impl DefMap { // with), resolve the remaining path segments in that `DefMap`. let path = ModPath::from_segments(PathKind::SELF, path.segments().iter().cloned()); + // This is the same crate, so the local def map is the same. return def_map.resolve_path_fp_with_macro( + local_def_map, db, mode, local_id, @@ -333,7 +353,7 @@ impl DefMap { PerNs::types(module.into(), Visibility::Public, None) } - PathKind::Abs => match self.resolve_path_abs(&mut segments, path) { + PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) { Either::Left(it) => it, Either::Right(reached_fixed_point) => { return ResolvePathResult::empty(reached_fixed_point) @@ -347,6 +367,7 @@ impl DefMap { /// Resolves a path only in the preludes, without accounting for item scopes. pub(super) fn resolve_path_fp_in_all_preludes( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, mode: ResolveMode, original_module: LocalModuleId, @@ -368,7 +389,7 @@ impl DefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; tracing::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_extern_prelude(segment) + self.resolve_name_in_extern_prelude(local_def_map, segment) } PathKind::Plain => { let (_, segment) = match segments.next() { @@ -376,9 +397,9 @@ impl DefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; tracing::debug!("resolving {:?} in module", segment); - self.resolve_name_in_all_preludes(db, segment) + self.resolve_name_in_all_preludes(local_def_map, db, segment) } - PathKind::Abs => match self.resolve_path_abs(&mut segments, path) { + PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) { Either::Left(it) => it, Either::Right(reached_fixed_point) => { return ResolvePathResult::empty(reached_fixed_point) @@ -395,6 +416,7 @@ impl DefMap { /// 2018-style absolute path -- only extern prelude fn resolve_path_abs<'a>( &self, + local_def_map: &LocalDefMap, segments: &mut impl Iterator, path: &ModPath, ) -> Either { @@ -402,7 +424,7 @@ impl DefMap { Some((_, segment)) => segment, None => return Either::Right(ReachedFixedPoint::Yes), }; - if let Some(&(def, extern_crate)) = self.data.extern_prelude.get(segment) { + if let Some(&(def, extern_crate)) = local_def_map.extern_prelude.get(segment) { tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def); Either::Left(PerNs::types( def.into(), @@ -451,6 +473,7 @@ impl DefMap { // this point, we know we're resolving a multi-segment path so macro kind // expectation is discarded. let resolution = defp_map.resolve_path_fp_with_macro( + LocalDefMap::EMPTY, db, ResolveMode::Other, module.local_id, @@ -568,6 +591,7 @@ impl DefMap { fn resolve_name_in_module( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, module: LocalModuleId, name: &Name, @@ -611,7 +635,7 @@ impl DefMap { // they might been shadowed by local names. return PerNs::none(); } - self.resolve_name_in_extern_prelude(name) + self.resolve_name_in_extern_prelude(local_def_map, name) }; let macro_use_prelude = || self.resolve_in_macro_use_prelude(name); let prelude = || { @@ -628,19 +652,24 @@ impl DefMap { .or_else(prelude) } - fn resolve_name_in_all_preludes(&self, db: &dyn DefDatabase, name: &Name) -> PerNs { + fn resolve_name_in_all_preludes( + &self, + local_def_map: &LocalDefMap, + db: &dyn DefDatabase, + name: &Name, + ) -> PerNs { // Resolve in: // - extern prelude / macro_use prelude // - std prelude - let extern_prelude = self.resolve_name_in_extern_prelude(name); + let extern_prelude = self.resolve_name_in_extern_prelude(local_def_map, name); let macro_use_prelude = || self.resolve_in_macro_use_prelude(name); let prelude = || self.resolve_in_prelude(db, name); extern_prelude.or_else(macro_use_prelude).or_else(prelude) } - fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { - self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| { + fn resolve_name_in_extern_prelude(&self, local_def_map: &LocalDefMap, name: &Name) -> PerNs { + local_def_map.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| { PerNs::types( it.into(), Visibility::Public, @@ -662,6 +691,7 @@ impl DefMap { fn resolve_name_in_crate_root_or_extern_prelude( &self, + local_def_map: &LocalDefMap, db: &dyn DefDatabase, module: LocalModuleId, name: &Name, @@ -678,7 +708,7 @@ impl DefMap { // Don't resolve extern prelude in pseudo-module of a block. return PerNs::none(); } - self.resolve_name_in_extern_prelude(name) + self.resolve_name_in_extern_prelude(local_def_map, name) }; from_crate_root.or_else(from_extern_prelude) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs index cd590205766da..9a601e0f01384 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs @@ -1,5 +1,11 @@ -use base_db::SourceDatabase; +use base_db::{ + CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData, + DependencyBuilder, Env, RootQueryDb, SourceDatabase, +}; +use intern::Symbol; +use span::Edition; use test_fixture::WithFixture; +use triomphe::Arc; use crate::{db::DefDatabase, nameres::tests::TestDB, AdtId, ModuleDefId}; @@ -22,6 +28,73 @@ fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change: } } +#[test] +fn crate_metadata_changes_should_not_invalidate_unrelated_def_maps() { + let (mut db, files) = TestDB::with_many_files( + r#" +//- /a.rs crate:a +pub fn foo() {} + +//- /b.rs crate:b +pub struct Bar; + +//- /c.rs crate:c deps:b +pub const BAZ: u32 = 0; + "#, + ); + + for &krate in db.all_crates().iter() { + db.crate_def_map(krate); + } + + let all_crates_before = db.all_crates(); + + { + // Add a dependency a -> b. + let mut new_crate_graph = CrateGraphBuilder::default(); + let mut add_crate = |crate_name, root_file_idx: usize| { + new_crate_graph.add_crate_root( + files[root_file_idx].file_id(), + Edition::CURRENT, + Some(CrateDisplayName::from_canonical_name(crate_name)), + None, + Arc::default(), + None, + Env::default(), + CrateOrigin::Local { repo: None, name: Some(Symbol::intern(crate_name)) }, + false, + None, + Arc::new(CrateWorkspaceData { data_layout: Err("".into()), toolchain: None }), + ) + }; + let a = add_crate("a", 0); + let b = add_crate("b", 1); + let c = add_crate("c", 2); + new_crate_graph + .add_dep(c, DependencyBuilder::new(CrateName::new("b").unwrap(), b)) + .unwrap(); + new_crate_graph + .add_dep(b, DependencyBuilder::new(CrateName::new("a").unwrap(), a)) + .unwrap(); + new_crate_graph.set_in_db(&mut db); + } + + let all_crates_after = db.all_crates(); + assert!( + Arc::ptr_eq(&all_crates_before, &all_crates_after), + "the all_crates list should not have been invalidated" + ); + + let events = db.log_executed(|| { + for &krate in db.all_crates().iter() { + db.crate_def_map(krate); + } + }); + let invalidated_def_maps = + events.iter().filter(|event| event.contains("crate_def_map")).count(); + assert_eq!(invalidated_def_maps, 1, "{events:#?}") +} + #[test] fn typing_inside_a_function_should_not_invalidate_def_map() { check_def_map_is_not_recomputed( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs index 610886d55f40f..0348a7076a8d0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs @@ -1095,7 +1095,7 @@ pub fn derive_macro_2(_item: TokenStream) -> TokenStream { } "#, ); - let krate = db.crate_graph().iter().next().unwrap(); + let krate = *db.all_crates().last().unwrap(); let def_map = db.crate_def_map(krate); assert_eq!(def_map.data.exported_derives.len(), 1); @@ -1445,7 +1445,7 @@ struct TokenStream; fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } "#, ); - let krate = db.crate_graph().iter().next().unwrap(); + let krate = *db.all_crates().last().unwrap(); let def_map = db.crate_def_map(krate); let root_module = &def_map[DefMap::ROOT].scope; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs index eb9488feaa914..c431b45dc79cd 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs @@ -80,7 +80,16 @@ pub(crate) fn print_path( } PathKind::Crate => write!(buf, "crate")?, PathKind::Abs => {} - PathKind::DollarCrate(_) => write!(buf, "$crate")?, + PathKind::DollarCrate(krate) => write!( + buf, + "{}", + krate + .extra_data(db) + .display_name + .as_ref() + .map(|it| it.crate_name().symbol().as_str()) + .unwrap_or("$crate") + )?, }, } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index f4773de08555b..72723499fc973 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -1,7 +1,7 @@ //! Name resolution façade. use std::{fmt, iter, mem}; -use base_db::CrateId; +use base_db::Crate; use hir_expand::{name::Name, MacroDefId}; use intern::{sym, Symbol}; use itertools::Itertools as _; @@ -22,7 +22,7 @@ use crate::{ hir::{BindingId, ExprId, LabelId}, item_scope::{BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, BUILTIN_SCOPE}, lang_item::LangItemTarget, - nameres::{DefMap, MacroSubNs, ResolvePathResultPrefixInfo}, + nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo}, path::{ModPath, Path, PathKind}, per_ns::PerNs, type_ref::{LifetimeRef, TypesMap}, @@ -47,6 +47,7 @@ pub struct Resolver { #[derive(Clone)] struct ModuleItemMap { def_map: Arc, + local_def_map: Arc, module_id: LocalModuleId, } @@ -278,8 +279,8 @@ impl Resolver { let within_impl = self.scopes().any(|scope| matches!(scope, Scope::ImplDefScope(_))); match visibility { RawVisibility::Module(_, _) => { - let (item_map, module) = self.item_scope(); - item_map.resolve_visibility(db, module, visibility, within_impl) + let (item_map, item_local_map, module) = self.item_scope(); + item_map.resolve_visibility(item_local_map, db, module, visibility, within_impl) } RawVisibility::Public => Some(Visibility::Public), } @@ -474,9 +475,16 @@ impl Resolver { path: &ModPath, expected_macro_kind: Option, ) -> Option<(MacroId, Option)> { - let (item_map, module) = self.item_scope(); + let (item_map, item_local_map, module) = self.item_scope(); item_map - .resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind) + .resolve_path( + item_local_map, + db, + module, + path, + BuiltinShadowMode::Other, + expected_macro_kind, + ) .0 .take_macros_import() } @@ -550,7 +558,7 @@ impl Resolver { for scope in self.scopes() { scope.process_names(&mut res, db); } - let ModuleItemMap { ref def_map, module_id } = self.module_scope; + let ModuleItemMap { ref def_map, module_id, ref local_def_map } = self.module_scope; // FIXME: should we provide `self` here? // f( // Name::self_param(), @@ -572,7 +580,7 @@ impl Resolver { res.add(name, ScopeDef::ModuleDef(def.into())); }, ); - def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| { + local_def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| { res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into()))); }); BUILTIN_SCOPE.iter().for_each(|(name, &def)| { @@ -599,7 +607,7 @@ impl Resolver { pub fn extern_crates_in_scope(&self) -> impl Iterator + '_ { self.module_scope - .def_map + .local_def_map .extern_prelude() .map(|(name, module_id)| (name.clone(), module_id.0.into())) } @@ -647,11 +655,11 @@ impl Resolver { } pub fn module(&self) -> ModuleId { - let (def_map, local_id) = self.item_scope(); + let (def_map, _, local_id) = self.item_scope(); def_map.module_id(local_id) } - pub fn krate(&self) -> CrateId { + pub fn krate(&self) -> Crate { self.module_scope.def_map.krate() } @@ -844,9 +852,12 @@ impl Resolver { })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = db.block_def_map(block); - resolver - .scopes - .push(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT })); + let local_def_map = block.lookup(db).module.only_local_def_map(db); + resolver.scopes.push(Scope::BlockScope(ModuleItemMap { + def_map, + local_def_map, + module_id: DefMap::ROOT, + })); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the // innermost module scope instead? @@ -933,9 +944,10 @@ impl Resolver { path: &ModPath, shadow: BuiltinShadowMode, ) -> PerNs { - let (item_map, module) = self.item_scope(); + let (item_map, item_local_map, module) = self.item_scope(); // This method resolves `path` just like import paths, so no expected macro subns is given. - let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow, None); + let (module_res, segment_index) = + item_map.resolve_path(item_local_map, db, module, path, shadow, None); if segment_index.is_some() { return PerNs::none(); } @@ -943,13 +955,17 @@ impl Resolver { } /// The innermost block scope that contains items or the module scope that contains this resolver. - fn item_scope(&self) -> (&DefMap, LocalModuleId) { + fn item_scope(&self) -> (&DefMap, &LocalDefMap, LocalModuleId) { self.scopes() .find_map(|scope| match scope { - Scope::BlockScope(m) => Some((&*m.def_map, m.module_id)), + Scope::BlockScope(m) => Some((&*m.def_map, &*m.local_def_map, m.module_id)), _ => None, }) - .unwrap_or((&self.module_scope.def_map, self.module_scope.module_id)) + .unwrap_or(( + &self.module_scope.def_map, + &self.module_scope.local_def_map, + self.module_scope.module_id, + )) } } @@ -1050,7 +1066,8 @@ fn resolver_for_scope_( for scope in scope_chain.into_iter().rev() { if let Some(block) = scopes.block(scope) { let def_map = db.block_def_map(block); - r = r.push_block_scope(def_map); + let local_def_map = block.lookup(db).module.only_local_def_map(db); + r = r.push_block_scope(def_map, local_def_map); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the // innermost module scope instead? @@ -1079,9 +1096,12 @@ impl Resolver { self.push_scope(Scope::ImplDefScope(impl_def)) } - fn push_block_scope(self, def_map: Arc) -> Resolver { - debug_assert!(def_map.block_id().is_some()); - self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT })) + fn push_block_scope(self, def_map: Arc, local_def_map: Arc) -> Resolver { + self.push_scope(Scope::BlockScope(ModuleItemMap { + def_map, + local_def_map, + module_id: DefMap::ROOT, + })) } fn push_expr_scope( @@ -1100,8 +1120,13 @@ impl ModuleItemMap { db: &dyn DefDatabase, path: &ModPath, ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> { - let (module_def, unresolved_idx, prefix_info) = - self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other); + let (module_def, unresolved_idx, prefix_info) = self.def_map.resolve_path_locally( + &self.local_def_map, + db, + self.module_id, + path, + BuiltinShadowMode::Other, + ); match unresolved_idx { None => { let (value, import) = to_value_ns(module_def)?; @@ -1134,8 +1159,13 @@ impl ModuleItemMap { path: &ModPath, ) -> Option<(TypeNs, Option, Option, ResolvePathResultPrefixInfo)> { - let (module_def, idx, prefix_info) = - self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other); + let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally( + &self.local_def_map, + db, + self.module_id, + path, + BuiltinShadowMode::Other, + ); let (res, import) = to_type_ns(module_def)?; Some((res, idx, import, prefix_info)) } @@ -1230,11 +1260,14 @@ pub trait HasResolver: Copy { impl HasResolver for ModuleId { fn resolver(self, db: &dyn DefDatabase) -> Resolver { - let mut def_map = self.def_map(db); + let (mut def_map, local_def_map) = self.local_def_map(db); let mut module_id = self.local_id; if !self.is_block_module() { - return Resolver { scopes: vec![], module_scope: ModuleItemMap { def_map, module_id } }; + return Resolver { + scopes: vec![], + module_scope: ModuleItemMap { def_map, local_def_map, module_id }, + }; } let mut modules: SmallVec<[_; 1]> = smallvec![]; @@ -1248,10 +1281,14 @@ impl HasResolver for ModuleId { } let mut resolver = Resolver { scopes: Vec::with_capacity(modules.len()), - module_scope: ModuleItemMap { def_map, module_id }, + module_scope: ModuleItemMap { + def_map, + local_def_map: local_def_map.clone(), + module_id, + }, }; for def_map in modules.into_iter().rev() { - resolver = resolver.push_block_scope(def_map); + resolver = resolver.push_block_scope(def_map, local_def_map.clone()); } resolver } @@ -1259,9 +1296,10 @@ impl HasResolver for ModuleId { impl HasResolver for CrateRootModuleId { fn resolver(self, db: &dyn DefDatabase) -> Resolver { + let (def_map, local_def_map) = self.local_def_map(db); Resolver { scopes: vec![], - module_scope: ModuleItemMap { def_map: self.def_map(db), module_id: DefMap::ROOT }, + module_scope: ModuleItemMap { def_map, local_def_map, module_id: DefMap::ROOT }, } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs index c7ebfeecf5141..43d31aa503ce0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs @@ -158,7 +158,7 @@ impl HasChildSource for VariantId { let mut map = ArenaMap::new(); match &src.value { ast::StructKind::Tuple(fl) => { - let cfg_options = &db.crate_graph()[container.krate].cfg_options; + let cfg_options = container.krate.cfg_options(db); let mut idx = 0; for (i, fd) in fl.fields().enumerate() { let attrs = item_tree.attrs( @@ -177,7 +177,7 @@ impl HasChildSource for VariantId { } } ast::StructKind::Record(fl) => { - let cfg_options = &db.crate_graph()[container.krate].cfg_options; + let cfg_options = container.krate.cfg_options(db); let mut idx = 0; for (i, fd) in fl.fields().enumerate() { let attrs = item_tree.attrs( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs index b6f08c0cafdbb..0b97e6c9ce5b9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs @@ -3,8 +3,8 @@ use std::{fmt, panic, sync::Mutex}; use base_db::{ - CrateId, FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, - SourceRootInput, Upcast, + Crate, CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, RootQueryDb, + SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, Upcast, }; use hir_expand::{db::ExpandDatabase, files::FilePosition, InFile}; use salsa::{AsDynDatabase, Durability}; @@ -24,6 +24,7 @@ use crate::{ pub(crate) struct TestDB { storage: salsa::Storage, files: Arc, + crates_map: Arc, events: Arc>>>, } @@ -33,8 +34,12 @@ impl Default for TestDB { storage: Default::default(), events: Default::default(), files: Default::default(), + crates_map: Default::default(), }; this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); + // This needs to be here otherwise `CrateGraphBuilder` panics. + this.set_all_crates(Arc::new(Box::new([]))); + CrateGraphBuilder::default().set_in_db(&mut this); this } } @@ -133,20 +138,23 @@ impl SourceDatabase for TestDB { let files = Arc::clone(&self.files); files.set_file_source_root_with_durability(self, id, source_root_id, durability); } + + fn crates_map(&self) -> Arc { + self.crates_map.clone() + } } impl TestDB { - pub(crate) fn fetch_test_crate(&self) -> CrateId { - let crate_graph = self.crate_graph(); - let it = crate_graph + pub(crate) fn fetch_test_crate(&self) -> Crate { + let all_crates = self.all_crates(); + all_crates .iter() - .find(|&idx| { - crate_graph[idx].display_name.as_ref().map(|it| it.canonical_name().as_str()) + .copied() + .find(|&krate| { + krate.extra_data(self).display_name.as_ref().map(|it| it.canonical_name().as_str()) == Some("ra_test_fixture") }) - .or_else(|| crate_graph.iter().next()) - .unwrap(); - it + .unwrap_or(*all_crates.last().unwrap()) } pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index c9c793d54f26c..64b9b49b3e472 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -1,7 +1,7 @@ //! A higher level attributes based on TokenTree, with also some shortcuts. use std::{borrow::Cow, fmt, ops}; -use base_db::CrateId; +use base_db::Crate; use cfg::CfgExpr; use either::Either; use intern::{sym, Interned, Symbol}; @@ -119,7 +119,7 @@ impl RawAttrs { /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. // FIXME: This should return a different type, signaling it was filtered? - pub fn filter(self, db: &dyn ExpandDatabase, krate: CrateId) -> RawAttrs { + pub fn filter(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs { let has_cfg_attrs = self .iter() .any(|attr| attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr.clone())); @@ -127,7 +127,7 @@ impl RawAttrs { return self; } - let crate_graph = db.crate_graph(); + let cfg_options = krate.cfg_options(db); let new_attrs = self.iter() .flat_map(|attr| -> SmallVec<[_; 1]> { @@ -151,7 +151,6 @@ impl RawAttrs { |(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)), ); - let cfg_options = &crate_graph[krate].cfg_options; let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg); let cfg = CfgExpr::parse(&cfg); if cfg_options.check(&cfg) == Some(false) { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index d8b3f40e8f413..b56ec3d04c07e 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -231,7 +231,7 @@ fn assert_expand( let cond = expect_fragment( &mut iter, parser::PrefixEntryPoint::Expr, - db.crate_graph()[id.lookup(db).krate].edition, + id.lookup(db).krate.data(db).edition, tt.top_subtree().delimiter.delim_span(), ); _ = iter.expect_char(','); @@ -333,7 +333,7 @@ fn cfg_expand( ) -> ExpandResult { let loc = db.lookup_intern_macro_call(id); let expr = CfgExpr::parse(tt); - let enabled = db.crate_graph()[loc.krate].cfg_options.check(&expr) != Some(false); + let enabled = loc.krate.cfg_options(db).check(&expr) != Some(false); let expanded = if enabled { quote!(span=>true) } else { quote!(span=>false) }; ExpandResult::ok(expanded) } @@ -669,7 +669,7 @@ fn relative_file( if res == call_site && !allow_recursion { Err(ExpandError::other(err_span, format!("recursive inclusion of `{path_str}`"))) } else { - Ok(EditionedFileId::new(res, db.crate_graph()[lookup.krate].edition)) + Ok(EditionedFileId::new(res, lookup.krate.data(db).edition)) } } @@ -812,7 +812,7 @@ fn include_str_expand( fn get_env_inner(db: &dyn ExpandDatabase, arg_id: MacroCallId, key: &Symbol) -> Option { let krate = db.lookup_intern_macro_call(arg_id).krate; - db.crate_graph()[krate].env.get(key.as_str()) + krate.env(db).get(key.as_str()) } fn env_expand( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs index 626a82ae08eab..0ceab3c890217 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs @@ -1,7 +1,7 @@ //! Processes out #[cfg] and #[cfg_attr] attributes from the input for the derive macro use std::iter::Peekable; -use base_db::CrateId; +use base_db::Crate; use cfg::{CfgAtom, CfgExpr}; use intern::{sym, Symbol}; use rustc_hash::FxHashSet; @@ -13,16 +13,16 @@ use tracing::{debug, warn}; use crate::{db::ExpandDatabase, proc_macro::ProcMacroKind, MacroCallLoc, MacroDefKind}; -fn check_cfg(db: &dyn ExpandDatabase, attr: &Attr, krate: CrateId) -> Option { +fn check_cfg(db: &dyn ExpandDatabase, attr: &Attr, krate: Crate) -> Option { if !attr.simple_name().as_deref().map(|v| v == "cfg")? { return None; } let cfg = parse_from_attr_token_tree(&attr.meta()?.token_tree()?)?; - let enabled = db.crate_graph()[krate].cfg_options.check(&cfg) != Some(false); + let enabled = krate.cfg_options(db).check(&cfg) != Some(false); Some(enabled) } -fn check_cfg_attr(db: &dyn ExpandDatabase, attr: &Attr, krate: CrateId) -> Option { +fn check_cfg_attr(db: &dyn ExpandDatabase, attr: &Attr, krate: Crate) -> Option { if !attr.simple_name().as_deref().map(|v| v == "cfg_attr")? { return None; } @@ -32,17 +32,17 @@ fn check_cfg_attr(db: &dyn ExpandDatabase, attr: &Attr, krate: CrateId) -> Optio pub fn check_cfg_attr_value( db: &dyn ExpandDatabase, attr: &TokenTree, - krate: CrateId, + krate: Crate, ) -> Option { let cfg_expr = parse_from_attr_token_tree(attr)?; - let enabled = db.crate_graph()[krate].cfg_options.check(&cfg_expr) != Some(false); + let enabled = krate.cfg_options(db).check(&cfg_expr) != Some(false); Some(enabled) } fn process_has_attrs_with_possible_comma( db: &dyn ExpandDatabase, items: impl Iterator, - krate: CrateId, + krate: Crate, remove: &mut FxHashSet, ) -> Option<()> { for item in items { @@ -144,7 +144,7 @@ fn remove_possible_comma(item: &impl AstNode, res: &mut FxHashSet fn process_enum( db: &dyn ExpandDatabase, variants: VariantList, - krate: CrateId, + krate: Crate, remove: &mut FxHashSet, ) -> Option<()> { 'variant: for variant in variants.variants() { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs index 7a42d6626010b..3f5b8fdc9bd5e 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs @@ -1,17 +1,16 @@ //! Defines a unit of change that can applied to the database to get the next //! state. Changes are transactional. -use base_db::{CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot}; -use rustc_hash::FxHashMap; +use base_db::{CrateGraphBuilder, FileChange, SourceRoot}; use salsa::Durability; use span::FileId; use triomphe::Arc; -use crate::{db::ExpandDatabase, proc_macro::ProcMacros}; +use crate::{db::ExpandDatabase, proc_macro::ProcMacrosBuilder}; #[derive(Debug, Default)] pub struct ChangeWithProcMacros { pub source_change: FileChange, - pub proc_macros: Option, + pub proc_macros: Option, } impl ChangeWithProcMacros { @@ -20,8 +19,13 @@ impl ChangeWithProcMacros { } pub fn apply(self, db: &mut impl ExpandDatabase) { - self.source_change.apply(db); + let crates_id_map = self.source_change.apply(db); if let Some(proc_macros) = self.proc_macros { + let proc_macros = proc_macros.build( + crates_id_map + .as_ref() + .expect("cannot set proc macros without setting the crate graph too"), + ); db.set_proc_macros_with_durability(Arc::new(proc_macros), Durability::HIGH); } } @@ -30,16 +34,11 @@ impl ChangeWithProcMacros { self.source_change.change_file(file_id, new_text) } - pub fn set_crate_graph( - &mut self, - graph: CrateGraph, - ws_data: FxHashMap>, - ) { + pub fn set_crate_graph(&mut self, graph: CrateGraphBuilder) { self.source_change.set_crate_graph(graph); - self.source_change.set_ws_data(ws_data); } - pub fn set_proc_macros(&mut self, proc_macros: ProcMacros) { + pub fn set_proc_macros(&mut self, proc_macros: ProcMacrosBuilder) { self.proc_macros = Some(proc_macros); } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 2f97cceab554a..112327f11e1a8 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -1,6 +1,6 @@ //! Defines database & queries for macro expansion. -use base_db::{CrateId, RootQueryDb}; +use base_db::{Crate, RootQueryDb}; use either::Either; use mbe::MatchedArmIndex; use rustc_hash::FxHashSet; @@ -23,7 +23,7 @@ use crate::{ span_with_call_site_ctxt, span_with_def_site_ctxt, span_with_mixed_site_ctxt, SyntaxContextExt as _, }, - proc_macro::{CustomProcMacroExpander, ProcMacros}, + proc_macro::{CrateProcMacros, CustomProcMacroExpander, ProcMacros}, span_map::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef}, tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo, EagerExpander, ExpandError, ExpandResult, ExpandTo, MacroCallKind, MacroCallLoc, MacroDefId, @@ -57,10 +57,13 @@ pub enum TokenExpander { #[query_group::query_group] pub trait ExpandDatabase: RootQueryDb { - /// The proc macros. + /// The proc macros. Do not use this! Use `proc_macros_for_crate()` instead. #[salsa::input] fn proc_macros(&self) -> Arc; + #[salsa::invoke_actual(crate::proc_macro::proc_macros_for_crate)] + fn proc_macros_for_crate(&self, krate: Crate) -> Option>; + fn ast_id_map(&self, file_id: HirFileId) -> Arc; #[salsa::transparent] @@ -120,7 +123,7 @@ pub trait ExpandDatabase: RootQueryDb { #[salsa::invoke(DeclarativeMacroExpander::expander)] fn decl_macro_expander( &self, - def_crate: CrateId, + def_crate: Crate, id: AstId, ) -> Arc; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index 91cbbc373649c..fbce320756645 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -1,6 +1,6 @@ //! Compiled declarative macro expanders (`macro_rules!` and `macro`) -use base_db::CrateId; +use base_db::Crate; use intern::sym; use span::{Edition, HirFileIdRepr, MacroCallId, Span, SyntaxContextId}; use stdx::TupleExt; @@ -70,7 +70,7 @@ impl DeclarativeMacroExpander { pub(crate) fn expander( db: &dyn ExpandDatabase, - def_crate: CrateId, + def_crate: Crate, id: AstId, ) -> Arc { let (root, map) = crate::db::parse_with_map(db, id.file_id); @@ -101,14 +101,12 @@ impl DeclarativeMacroExpander { } }; let ctx_edition = |ctx: SyntaxContextId| { - let crate_graph = db.crate_graph(); - if ctx.is_root() { - crate_graph[def_crate].edition + def_crate.data(db).edition } else { // UNWRAP-SAFETY: Only the root context has no outer expansion let krate = db.lookup_intern_macro_call(ctx.outer_expn(db).unwrap()).def.krate; - crate_graph[krate].edition + krate.data(db).edition } }; let (mac, transparency) = match id.to_ptr(db).to_node(&root) { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs index 4a98b455cab83..02dc75a4a6d87 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs @@ -18,7 +18,7 @@ //! //! //! See the full discussion : -use base_db::CrateId; +use base_db::Crate; use span::SyntaxContextId; use syntax::{ted, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent}; use syntax_bridge::DocCommentDesugarMode; @@ -34,7 +34,7 @@ use crate::{ pub fn expand_eager_macro_input( db: &dyn ExpandDatabase, - krate: CrateId, + krate: Crate, macro_call: &ast::MacroCall, ast_id: AstId, def: MacroDefId, @@ -115,7 +115,7 @@ fn lazy_expand( def: &MacroDefId, macro_call: &ast::MacroCall, ast_id: AstId, - krate: CrateId, + krate: Crate, call_site: SyntaxContextId, ) -> ExpandResult<(InFile>, Arc)> { let expand_to = ExpandTo::from_call_site(macro_call); @@ -137,7 +137,7 @@ fn eager_macro_recur( expanded_map: &mut ExpansionSpanMap, mut offset: TextSize, curr: InFile, - krate: CrateId, + krate: Crate, call_site: SyntaxContextId, macro_resolver: &dyn Fn(&ModPath) -> Option, ) -> ExpandResult> { @@ -176,7 +176,7 @@ fn eager_macro_recur( Some(path) => match macro_resolver(&path) { Some(def) => def, None => { - let edition = db.crate_graph()[krate].edition; + let edition = krate.data(db).edition; error = Some(ExpandError::other( span_map.span_at(call.syntax().text_range().start()), format!("unresolved macro {}", path.display(db, edition)), diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index f8c83dce55ac6..a1e484c08bcbf 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -33,7 +33,7 @@ use triomphe::Arc; use core::fmt; use std::hash::Hash; -use base_db::CrateId; +use base_db::Crate; use either::Either; use span::{ Edition, EditionedFileId, ErasedFileAstId, FileAstId, HirFileIdRepr, Span, SpanAnchor, @@ -157,7 +157,7 @@ impl ExpandError { pub enum ExpandErrorKind { /// Attribute macro expansion is disabled. ProcMacroAttrExpansionDisabled, - MissingProcMacroExpander(CrateId), + MissingProcMacroExpander(Crate), /// The macro for this call is disabled. MacroDisabled, /// The macro definition has errors. @@ -200,7 +200,7 @@ impl ExpandErrorKind { kind: RenderedExpandError::DISABLED, }, &ExpandErrorKind::MissingProcMacroExpander(def_crate) => { - match db.proc_macros().get_error_for_crate(def_crate) { + match db.proc_macros_for_crate(def_crate).as_ref().and_then(|it| it.get_error()) { Some((e, hard_err)) => RenderedExpandError { message: e.to_owned(), error: hard_err, @@ -250,14 +250,14 @@ impl From for ExpandError { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct MacroCallLoc { pub def: MacroDefId, - pub krate: CrateId, + pub krate: Crate, pub kind: MacroCallKind, pub ctxt: SyntaxContextId, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct MacroDefId { - pub krate: CrateId, + pub krate: Crate, pub edition: Edition, pub kind: MacroDefKind, pub local_inner: bool, @@ -525,7 +525,7 @@ impl MacroDefId { pub fn make_call( self, db: &dyn ExpandDatabase, - krate: CrateId, + krate: Crate, kind: MacroCallKind, ctxt: SyntaxContextId, ) -> MacroCallId { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 6f6f41f322abf..40b10cb4380af 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -11,7 +11,7 @@ use crate::{ name::{AsName, Name}, tt, }; -use base_db::CrateId; +use base_db::Crate; use intern::sym; use smallvec::SmallVec; use span::{Edition, SyntaxContextId}; @@ -33,7 +33,7 @@ pub enum PathKind { Abs, // FIXME: Can we remove this somehow? /// `$crate` from macro expansion - DollarCrate(CrateId), + DollarCrate(Crate), } impl PathKind { @@ -333,7 +333,7 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: tt::TokenTreesView<'_>) -> Optio Some(ModPath { kind, segments }) } -pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) -> Option { +pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) -> Option { // When resolving `$crate` from a `macro_rules!` invoked in a `macro`, // we don't want to pretend that the `macro_rules!` definition is in the `macro` // as described in `SyntaxContextId::apply_mark`, so we ignore prepended opaque marks. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 0758bd4515ef2..51721effa355d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -260,7 +260,7 @@ impl AsName for ast::FieldKind { } } -impl AsName for base_db::Dependency { +impl AsName for base_db::BuiltDependency { fn as_name(&self) -> Name { Name::new_symbol_root((*self.name).clone()) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs index 944341ec3f2cd..f398b070f791b 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs @@ -1,6 +1,6 @@ //! Pretty printing of macros output. -use base_db::CrateId; +use base_db::Crate; use rustc_hash::FxHashMap; use syntax::NodeOrToken; use syntax::{ast::make, SyntaxNode}; @@ -13,13 +13,12 @@ pub fn prettify_macro_expansion( db: &dyn ExpandDatabase, syn: SyntaxNode, span_map: &ExpansionSpanMap, - target_crate_id: CrateId, + target_crate_id: Crate, ) -> SyntaxNode { // Because `syntax_bridge::prettify_macro_expansion::prettify_macro_expansion()` clones subtree for `syn`, // that means it will be offsetted to the beginning. let span_offset = syn.text_range().start(); - let crate_graph = db.crate_graph(); - let target_crate = &crate_graph[target_crate_id]; + let target_crate = target_crate_id.data(db); let mut syntax_ctx_id_to_dollar_crate_replacement = FxHashMap::default(); syntax_bridge::prettify_macro_expansion::prettify_macro_expansion(syn, &mut |dollar_crate| { let ctx = span_map.span_at(dollar_crate.text_range().start() + span_offset).ctx; @@ -41,7 +40,7 @@ pub fn prettify_macro_expansion( target_crate.dependencies.iter().find(|dep| dep.crate_id == macro_def_crate) { make::tokens::ident(dep.name.as_str()) - } else if let Some(crate_name) = &crate_graph[macro_def_crate].display_name { + } else if let Some(crate_name) = ¯o_def_crate.extra_data(db).display_name { make::tokens::ident(crate_name.crate_name().as_str()) } else { return dollar_crate.clone(); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs index 3dc3dcd760cd3..cdf63e92a89b5 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs @@ -1,24 +1,36 @@ //! Proc Macro Expander stuff use core::fmt; +use std::any::Any; use std::{panic::RefUnwindSafe, sync}; -use base_db::{CrateId, Env}; +use base_db::{Crate, CrateBuilderId, CratesIdMap, Env}; use intern::Symbol; use rustc_hash::FxHashMap; use span::Span; +use triomphe::Arc; use crate::{db::ExpandDatabase, tt, ExpandError, ExpandErrorKind, ExpandResult}; -#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug, Hash)] pub enum ProcMacroKind { CustomDerive, Bang, Attr, } +pub trait AsAny: Any { + fn as_any(&self) -> &dyn Any; +} + +impl AsAny for T { + fn as_any(&self) -> &dyn Any { + self + } +} + /// A proc-macro expander implementation. -pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe { +pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe + AsAny { /// Run the expander with the given input subtree, optional attribute input subtree (for /// [`ProcMacroKind::Attr`]), environment variables, and span information. fn expand( @@ -31,8 +43,18 @@ pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe { mixed_site: Span, current_dir: Option, ) -> Result; + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool; } +impl PartialEq for dyn ProcMacroExpander { + fn eq(&self, other: &Self) -> bool { + self.eq_dyn(other) + } +} + +impl Eq for dyn ProcMacroExpander {} + #[derive(Debug)] pub enum ProcMacroExpansionError { /// The proc-macro panicked. @@ -45,41 +67,68 @@ pub type ProcMacroLoadResult = Result, (String, bool)>; type StoredProcMacroLoadResult = Result, (Box, bool)>; #[derive(Default, Debug)] -pub struct ProcMacrosBuilder(FxHashMap); +pub struct ProcMacrosBuilder(FxHashMap>); + impl ProcMacrosBuilder { - pub fn insert(&mut self, proc_macros_crate: CrateId, proc_macro: ProcMacroLoadResult) { + pub fn insert( + &mut self, + proc_macros_crate: CrateBuilderId, + mut proc_macro: ProcMacroLoadResult, + ) { + if let Ok(proc_macros) = &mut proc_macro { + // Sort proc macros to improve incrementality when only their order has changed (ideally the build system + // will not change their order, but just to be sure). + proc_macros + .sort_unstable_by_key(|proc_macro| (proc_macro.name.clone(), proc_macro.kind)); + } self.0.insert( proc_macros_crate, match proc_macro { - Ok(it) => Ok(it.into_boxed_slice()), - Err((e, hard_err)) => Err((e.into_boxed_str(), hard_err)), + Ok(it) => Arc::new(CrateProcMacros(Ok(it.into_boxed_slice()))), + Err((e, hard_err)) => { + Arc::new(CrateProcMacros(Err((e.into_boxed_str(), hard_err)))) + } }, ); } - pub fn build(mut self) -> ProcMacros { - self.0.shrink_to_fit(); - ProcMacros(self.0) + + pub(crate) fn build(self, crates_id_map: &CratesIdMap) -> ProcMacros { + let mut map = self + .0 + .into_iter() + .map(|(krate, proc_macro)| (crates_id_map[&krate], proc_macro)) + .collect::>(); + map.shrink_to_fit(); + ProcMacros(map) } } -#[derive(Default, Debug)] -pub struct ProcMacros(FxHashMap); - -impl FromIterator<(CrateId, ProcMacroLoadResult)> for ProcMacros { - fn from_iter>(iter: T) -> Self { +impl FromIterator<(CrateBuilderId, ProcMacroLoadResult)> for ProcMacrosBuilder { + fn from_iter>(iter: T) -> Self { let mut builder = ProcMacrosBuilder::default(); for (k, v) in iter { builder.insert(k, v); } - builder.build() + builder } } +#[derive(Debug, PartialEq, Eq)] +pub struct CrateProcMacros(StoredProcMacroLoadResult); + +#[derive(Default, Debug)] +pub struct ProcMacros(FxHashMap>); impl ProcMacros { - fn get(&self, krate: CrateId, idx: u32, err_span: Span) -> Result<&ProcMacro, ExpandError> { - let proc_macros = match self.0.get(&krate) { - Some(Ok(proc_macros)) => proc_macros, - Some(Err(_)) | None => { + fn get(&self, krate: Crate) -> Option> { + self.0.get(&krate).cloned() + } +} + +impl CrateProcMacros { + fn get(&self, idx: u32, err_span: Span) -> Result<&ProcMacro, ExpandError> { + let proc_macros = match &self.0 { + Ok(proc_macros) => proc_macros, + Err(_) => { return Err(ExpandError::other( err_span, "internal error: no proc macros for crate", @@ -98,18 +147,17 @@ impl ProcMacros { ) } - pub fn get_error_for_crate(&self, krate: CrateId) -> Option<(&str, bool)> { - self.0.get(&krate).and_then(|it| it.as_ref().err()).map(|(e, hard_err)| (&**e, *hard_err)) + pub fn get_error(&self) -> Option<(&str, bool)> { + self.0.as_ref().err().map(|(e, hard_err)| (&**e, *hard_err)) } /// Fetch the [`CustomProcMacroExpander`]s and their corresponding names for the given crate. - pub fn for_crate( + pub fn list( &self, - krate: CrateId, def_site_ctx: span::SyntaxContextId, ) -> Option> { - match self.0.get(&krate) { - Some(Ok(proc_macros)) => Some({ + match &self.0 { + Ok(proc_macros) => Some( proc_macros .iter() .enumerate() @@ -117,15 +165,15 @@ impl ProcMacros { let name = crate::name::Name::new_symbol(it.name.clone(), def_site_ctx); (name, CustomProcMacroExpander::new(idx as u32), it.disabled) }) - .collect() - }), + .collect(), + ), _ => None, } } } /// A loaded proc-macro. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Eq)] pub struct ProcMacro { /// The name of the proc macro. pub name: Symbol, @@ -137,6 +185,23 @@ pub struct ProcMacro { pub disabled: bool, } +// `#[derive(PartialEq)]` generates a strange "cannot move" error. +impl PartialEq for ProcMacro { + fn eq(&self, other: &Self) -> bool { + let Self { name, kind, expander, disabled } = self; + let Self { + name: other_name, + kind: other_kind, + expander: other_expander, + disabled: other_disabled, + } = other; + name == other_name + && kind == other_kind + && expander == other_expander + && disabled == other_disabled + } +} + /// A custom proc-macro expander handle. This handle together with its crate resolves to a [`ProcMacro`] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct CustomProcMacroExpander { @@ -187,7 +252,7 @@ impl CustomProcMacroExpander { } /// The macro is explicitly disabled due to proc-macro attribute expansion being disabled. - pub fn as_expand_error(&self, def_crate: CrateId) -> Option { + pub fn as_expand_error(&self, def_crate: Crate) -> Option { match self.proc_macro_id { Self::PROC_MACRO_ATTR_DISABLED => Some(ExpandErrorKind::ProcMacroAttrExpansionDisabled), Self::DISABLED_ID => Some(ExpandErrorKind::MacroDisabled), @@ -199,8 +264,8 @@ impl CustomProcMacroExpander { pub fn expand( self, db: &dyn ExpandDatabase, - def_crate: CrateId, - calling_crate: CrateId, + def_crate: Crate, + calling_crate: Crate, tt: &tt::TopSubtree, attr_arg: Option<&tt::TopSubtree>, def_site: Span, @@ -221,8 +286,22 @@ impl CustomProcMacroExpander { ExpandError::new(call_site, ExpandErrorKind::MacroDisabled), ), id => { - let proc_macros = db.proc_macros(); - let proc_macro = match proc_macros.get(def_crate, id, call_site) { + let proc_macros = match db.proc_macros_for_crate(def_crate) { + Some(it) => it, + None => { + return ExpandResult::new( + tt::TopSubtree::empty(tt::DelimSpan { + open: call_site, + close: call_site, + }), + ExpandError::other( + call_site, + "internal error: no proc macros for crate", + ), + ) + } + }; + let proc_macro = match proc_macros.get(id, call_site) { Ok(proc_macro) => proc_macro, Err(e) => { return ExpandResult::new( @@ -235,11 +314,10 @@ impl CustomProcMacroExpander { } }; - let krate_graph = db.crate_graph(); // Proc macros have access to the environment variables of the invoking crate. - let env = &krate_graph[calling_crate].env; + let env = calling_crate.env(db); let current_dir = - krate_graph[calling_crate].proc_macro_cwd.as_deref().map(ToString::to_string); + calling_crate.data(db).proc_macro_cwd.as_deref().map(ToString::to_string); match proc_macro.expander.expand( tt, @@ -278,3 +356,10 @@ impl CustomProcMacroExpander { } } } + +pub(crate) fn proc_macros_for_crate( + db: &dyn ExpandDatabase, + krate: Crate, +) -> Option> { + db.proc_macros().get(krate) +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 2be321733075b..84eb964d564bd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -11,7 +11,7 @@ use tracing::debug; use chalk_ir::{cast::Caster, fold::shift::Shift, CanonicalVarKinds}; use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; -use base_db::CrateId; +use base_db::Crate; use hir_def::{ data::{adt::StructFlags, TraitFlags}, hir::Movability, @@ -523,7 +523,7 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { impl ChalkContext<'_> { fn edition(&self) -> Edition { - self.db.crate_graph()[self.krate].edition + self.krate.data(self.db).edition } fn for_trait_impls( @@ -593,7 +593,7 @@ impl chalk_ir::UnificationDatabase for &dyn HirDatabase { pub(crate) fn program_clauses_for_chalk_env_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, block: Option, environment: chalk_ir::Environment, ) -> chalk_ir::ProgramClauses { @@ -665,7 +665,7 @@ pub(crate) fn associated_ty_data_query( pub(crate) fn trait_datum_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, trait_id: TraitId, ) -> Arc { debug!("trait_datum {:?}", trait_id); @@ -750,7 +750,7 @@ fn lang_item_from_well_known_trait(trait_: WellKnownTrait) -> LangItem { pub(crate) fn adt_datum_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, chalk_ir::AdtId(adt_id): AdtId, ) -> Arc { debug!("adt_datum {:?}", adt_id); @@ -824,7 +824,7 @@ pub(crate) fn adt_datum_query( pub(crate) fn impl_datum_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, impl_id: ImplId, ) -> Arc { let _p = tracing::info_span!("impl_datum_query").entered(); @@ -833,11 +833,7 @@ pub(crate) fn impl_datum_query( impl_def_datum(db, krate, impl_) } -fn impl_def_datum( - db: &dyn HirDatabase, - krate: CrateId, - impl_id: hir_def::ImplId, -) -> Arc { +fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId) -> Arc { let trait_ref = db .impl_trait(impl_id) // ImplIds for impls where the trait ref can't be resolved should never reach Chalk @@ -887,7 +883,7 @@ fn impl_def_datum( pub(crate) fn associated_ty_value_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, id: AssociatedTyValueId, ) -> Arc { let type_alias: TypeAliasAsValue = from_chalk(db, id); @@ -896,7 +892,7 @@ pub(crate) fn associated_ty_value_query( fn type_alias_associated_ty_value( db: &dyn HirDatabase, - _krate: CrateId, + _krate: Crate, type_alias: TypeAliasId, ) -> Arc { let type_alias_data = db.type_alias_data(type_alias); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index b3c604015a0c1..525672bc39951 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -1,6 +1,6 @@ //! Constant evaluation details -use base_db::CrateId; +use base_db::Crate; use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; use hir_def::{ expr_store::{Body, HygieneId}, @@ -162,7 +162,7 @@ pub fn intern_const_ref( db: &dyn HirDatabase, value: &LiteralConstRef, ty: Ty, - krate: CrateId, + krate: Crate, ) -> Const { let layout = db.layout_of_ty(ty.clone(), TraitEnvironment::empty(krate)); let bytes = match value { @@ -185,7 +185,7 @@ pub fn intern_const_ref( } /// Interns a possibly-unknown target usize -pub fn usize_const(db: &dyn HirDatabase, value: Option, krate: CrateId) -> Const { +pub fn usize_const(db: &dyn HirDatabase, value: Option, krate: Crate) -> Const { intern_const_ref( db, &value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index f2673dc58fa41..37e7df6f4b46e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -101,10 +101,7 @@ fn check_answer( fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String { let mut err = String::new(); let span_formatter = |file, range| format!("{file:?} {range:?}"); - let display_target = DisplayTarget::from_crate( - &db, - *db.crate_graph().crates_in_topological_order().last().unwrap(), - ); + let display_target = DisplayTarget::from_crate(&db, *db.all_crates().last().unwrap()); match e { ConstEvalError::MirLowerError(e) => { e.pretty_print(&mut err, &db, span_formatter, display_target) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 5817ed2ef20cd..8f48cfc4327ff 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -3,7 +3,7 @@ use std::sync; -use base_db::{impl_intern_key, CrateId, Upcast}; +use base_db::{impl_intern_key, Crate, Upcast}; use hir_def::{ db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, @@ -103,8 +103,8 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::cycle(crate::layout::layout_of_ty_recover)] fn layout_of_ty(&self, ty: Ty, env: Arc) -> Result, LayoutError>; - #[salsa::invoke(crate::layout::target_data_layout_query)] - fn target_data_layout(&self, krate: CrateId) -> Result, Arc>; + #[salsa::invoke_actual(crate::layout::target_data_layout_query)] + fn target_data_layout(&self, krate: Crate) -> Result, Arc>; #[salsa::invoke_actual(crate::dyn_compatibility::dyn_compatibility_of_trait_query)] fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option; @@ -196,8 +196,8 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::invoke_actual(crate::lower::generic_defaults_query)] fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults; - #[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)] - fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc; + #[salsa::invoke_actual(InherentImpls::inherent_impls_in_crate_query)] + fn inherent_impls_in_crate(&self, krate: Crate) -> Arc; #[salsa::invoke_actual(InherentImpls::inherent_impls_in_block_query)] fn inherent_impls_in_block(&self, block: BlockId) -> Option>; @@ -209,18 +209,18 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::invoke(crate::method_resolution::incoherent_inherent_impl_crates)] fn incoherent_inherent_impl_crates( &self, - krate: CrateId, + krate: Crate, fp: TyFingerprint, - ) -> SmallVec<[CrateId; 2]>; + ) -> SmallVec<[Crate; 2]>; - #[salsa::invoke(TraitImpls::trait_impls_in_crate_query)] - fn trait_impls_in_crate(&self, krate: CrateId) -> Arc; + #[salsa::invoke_actual(TraitImpls::trait_impls_in_crate_query)] + fn trait_impls_in_crate(&self, krate: Crate) -> Arc; #[salsa::invoke_actual(TraitImpls::trait_impls_in_block_query)] fn trait_impls_in_block(&self, block: BlockId) -> Option>; - #[salsa::invoke(TraitImpls::trait_impls_in_deps_query)] - fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<[Arc]>; + #[salsa::invoke_actual(TraitImpls::trait_impls_in_deps_query)] + fn trait_impls_in_deps(&self, krate: Crate) -> Arc<[Arc]>; // Interned IDs for Chalk integration #[salsa::interned] @@ -253,23 +253,16 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::invoke(chalk_db::trait_datum_query)] fn trait_datum( &self, - krate: CrateId, + krate: Crate, trait_id: chalk_db::TraitId, ) -> sync::Arc; #[salsa::invoke(chalk_db::adt_datum_query)] - fn adt_datum( - &self, - krate: CrateId, - struct_id: chalk_db::AdtId, - ) -> sync::Arc; + fn adt_datum(&self, krate: Crate, struct_id: chalk_db::AdtId) -> sync::Arc; #[salsa::invoke(chalk_db::impl_datum_query)] - fn impl_datum( - &self, - krate: CrateId, - impl_id: chalk_db::ImplId, - ) -> sync::Arc; + fn impl_datum(&self, krate: Crate, impl_id: chalk_db::ImplId) + -> sync::Arc; #[salsa::invoke(chalk_db::fn_def_datum_query)] fn fn_def_datum(&self, fn_def_id: FnDefId) -> sync::Arc; @@ -287,7 +280,7 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::invoke(chalk_db::associated_ty_value_query)] fn associated_ty_value( &self, - krate: CrateId, + krate: Crate, id: chalk_db::AssociatedTyValueId, ) -> sync::Arc; @@ -302,7 +295,7 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::invoke(crate::traits::trait_solve_query)] fn trait_solve( &self, - krate: CrateId, + krate: Crate, block: Option, goal: crate::Canonical>, ) -> Option; @@ -310,7 +303,7 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)] fn program_clauses_for_chalk_env( &self, - krate: CrateId, + krate: Crate, block: Option, env: chalk_ir::Environment, ) -> chalk_ir::ProgramClauses; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index eed74e1eee358..a0b1fe32ce52d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -288,7 +288,7 @@ impl<'a> DeclValidator<'a> { fn edition(&self, id: impl HasModule) -> span::Edition { let krate = id.krate(self.db.upcast()); - self.db.crate_graph()[krate].edition + krate.data(self.db).edition } fn validate_struct(&mut self, struct_id: StructId) { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 975143b29f2f9..053d1cd41e9f1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -4,7 +4,7 @@ use std::fmt; -use base_db::CrateId; +use base_db::Crate; use chalk_solve::rust_ir::AdtKind; use either::Either; use hir_def::{ @@ -630,7 +630,7 @@ fn missing_match_arms<'p>( scrut_ty: &Ty, witnesses: Vec>, arms_is_empty: bool, - krate: CrateId, + krate: Crate, ) -> String { struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>, DisplayTarget); impl fmt::Display for DisplayWitness<'_, '_> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs index d2b908839c42e..84dd4be67fe8d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -160,7 +160,7 @@ impl<'a> UnsafeVisitor<'a> { DefWithBodyId::FunctionId(func) => TargetFeatures::from_attrs(&db.attrs(func.into())), _ => TargetFeatures::default(), }; - let edition = db.crate_graph()[resolver.module().krate()].edition; + let edition = resolver.module().krate().data(db).edition; Self { db, infer, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 95ce36390d33d..2ae7e746ba203 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -7,7 +7,7 @@ use std::{ mem, }; -use base_db::CrateId; +use base_db::Crate; use chalk_ir::{BoundVar, Safety, TyKind}; use either::Either; use hir_def::{ @@ -339,7 +339,7 @@ pub trait HirDisplay { } impl HirFormatter<'_> { - pub fn krate(&self) -> CrateId { + pub fn krate(&self) -> Crate { self.display_target.krate } @@ -408,13 +408,13 @@ impl HirFormatter<'_> { #[derive(Debug, Clone, Copy)] pub struct DisplayTarget { - krate: CrateId, + krate: Crate, pub edition: Edition, } impl DisplayTarget { - pub fn from_crate(db: &dyn HirDatabase, krate: CrateId) -> Self { - let edition = db.crate_graph()[krate].edition; + pub fn from_crate(db: &dyn HirDatabase, krate: Crate) -> Self { + let edition = krate.data(db).edition; Self { krate, edition } } } @@ -1711,7 +1711,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator String { let body = db.body(owner); let krate = owner.krate(db.upcast()); - let edition = db.crate_graph()[krate].edition; + let edition = krate.data(db).edition; let mut result = body[self.place.local].name.display(db.upcast(), edition).to_string(); for proj in &self.place.projections { match proj { @@ -368,7 +368,7 @@ impl CapturedItem { pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { let body = db.body(owner); let krate = owner.krate(db.upcast()); - let edition = db.crate_graph()[krate].edition; + let edition = krate.data(db).edition; let mut result = body[self.place.local].name.display(db.upcast(), edition).to_string(); let mut field_need_paren = false; for proj in &self.place.projections { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/target.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/target.rs index 7d77f6d0731a3..e1e1c44996cde 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/target.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/target.rs @@ -1,6 +1,6 @@ //! Target dependent parameters needed for layouts -use base_db::CrateId; +use base_db::Crate; use hir_def::layout::TargetDataLayout; use rustc_abi::{AlignFromBytesError, TargetDataLayoutErrors}; use triomphe::Arc; @@ -9,9 +9,9 @@ use crate::db::HirDatabase; pub fn target_data_layout_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, ) -> Result, Arc> { - match &db.crate_workspace_data()[&krate].data_layout { + match &krate.workspace_data(db).data_layout { Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it) { Ok(it) => Ok(Arc::new(it)), Err(e) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index ff7f0349638cd..29ab0251f8360 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -14,7 +14,7 @@ use std::{ ops::{self, Not as _}, }; -use base_db::CrateId; +use base_db::Crate; use chalk_ir::{ cast::Cast, fold::{Shift, TypeFoldable}, @@ -801,7 +801,7 @@ impl<'a> TyLoweringContext<'a> { } } - fn lower_impl_trait(&mut self, bounds: &[TypeBound], krate: CrateId) -> ImplTrait { + fn lower_impl_trait(&mut self, bounds: &[TypeBound], krate: Crate) -> ImplTrait { cov_mark::hit!(lower_rpit); let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner); let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { @@ -1863,8 +1863,11 @@ pub(crate) fn const_or_path_to_chalk<'g>( .unwrap_or_else(|| unknown_const(expected_ty)) } &ConstRef::Complex(it) => { - let crate_data = &db.crate_graph()[resolver.krate()]; - if crate_data.env.get("__ra_is_test_fixture").is_none() && crate_data.origin.is_local() + let krate = resolver.krate(); + // Keep the `&&` this way, because it's better to access the crate data, as we access it for + // a bunch of other things nevertheless. + if krate.data(db).origin.is_local() + && krate.env(db).get("__ra_is_test_fixture").is_none() { // FIXME: current `InTypeConstId` is very unstable, so we only use it in non local crate // that are unlikely to be edited. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index c5ad808accdf4..50b0fce62f76e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -5,7 +5,7 @@ use std::ops::ControlFlow; use arrayvec::ArrayVec; -use base_db::CrateId; +use base_db::Crate; use chalk_ir::{cast::Cast, UniverseIndex, WithKind}; use hir_def::{ data::{adt::StructFlags, ImplData, TraitFlags}, @@ -148,7 +148,7 @@ pub struct TraitImpls { } impl TraitImpls { - pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc { + pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: Crate) -> Arc { let _p = tracing::info_span!("trait_impls_in_crate_query", ?krate).entered(); let mut impls = FxHashMap::default(); @@ -175,13 +175,11 @@ impl TraitImpls { pub(crate) fn trait_impls_in_deps_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, ) -> Arc<[Arc]> { let _p = tracing::info_span!("trait_impls_in_deps_query", ?krate).entered(); - let crate_graph = db.crate_graph(); - Arc::from_iter( - crate_graph.transitive_deps(krate).map(|krate| db.trait_impls_in_crate(krate)), + db.transitive_deps(krate).into_iter().map(|krate| db.trait_impls_in_crate(krate)), ) } @@ -282,7 +280,7 @@ pub struct InherentImpls { } impl InherentImpls { - pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc { + pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: Crate) -> Arc { let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered(); let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() }; @@ -367,16 +365,15 @@ impl InherentImpls { pub(crate) fn incoherent_inherent_impl_crates( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, fp: TyFingerprint, -) -> SmallVec<[CrateId; 2]> { +) -> SmallVec<[Crate; 2]> { let _p = tracing::info_span!("incoherent_inherent_impl_crates").entered(); let mut res = SmallVec::new(); - let crate_graph = db.crate_graph(); // should pass crate for finger print and do reverse deps - for krate in crate_graph.transitive_deps(krate) { + for krate in db.transitive_deps(krate) { let impls = db.inherent_impls_in_crate(krate); if impls.map.get(&fp).is_some_and(|v| !v.is_empty()) { res.push(krate); @@ -386,11 +383,7 @@ pub(crate) fn incoherent_inherent_impl_crates( res } -pub fn def_crates( - db: &dyn HirDatabase, - ty: &Ty, - cur_crate: CrateId, -) -> Option> { +pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option> { match ty.kind(Interner) { &TyKind::Adt(AdtId(def_id), _) => { let rustc_has_incoherent_inherent_impls = match def_id { @@ -1226,7 +1219,7 @@ fn iterate_trait_method_candidates( { // FIXME: this should really be using the edition of the method name's span, in case it // comes from a macro - if !db.crate_graph()[krate].edition.at_least_2021() { + if !krate.data(db).edition.at_least_2021() { continue; } } @@ -1239,7 +1232,7 @@ fn iterate_trait_method_candidates( { // FIXME: this should really be using the edition of the method name's span, in case it // comes from a macro - if !db.crate_graph()[krate].edition.at_least_2024() { + if !krate.data(db).edition.at_least_2024() { continue; } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index ae454fbe528a5..7faa23f818b8f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -12,7 +12,7 @@ use crate::{ CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap, Substitution, TraitEnvironment, Ty, TyExt, TyKind, }; -use base_db::CrateId; +use base_db::Crate; use chalk_ir::Mutability; use either::Either; use hir_def::{ @@ -143,7 +143,7 @@ impl ProjectionElem { mut base: Ty, db: &dyn HirDatabase, closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty, - krate: CrateId, + krate: Crate, ) -> Ty { // we only bail on mir building when there are type mismatches // but error types may pop up resulting in us still attempting to build the mir diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index c9d62f566c1a6..597e6a3ef0bf1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, cell::RefCell, fmt::Write, iter, mem, ops::Range}; -use base_db::CrateId; +use base_db::Crate; use chalk_ir::{cast::Cast, Mutability}; use either::Either; use hir_def::{ @@ -186,7 +186,7 @@ pub struct Evaluator<'a> { cached_fn_trait_func: Option, cached_fn_mut_trait_func: Option, cached_fn_once_trait_func: Option, - crate_id: CrateId, + crate_id: Crate, // FIXME: This is a workaround, see the comment on `interpret_mir` assert_placeholder_ty_is_unused: bool, /// A general limit on execution, to prevent non terminating programs from breaking r-a main process @@ -2785,7 +2785,7 @@ impl Evaluator<'_> { let db = self.db.upcast(); let loc = variant.lookup(db); let enum_loc = loc.parent.lookup(db); - let edition = self.db.crate_graph()[self.crate_id].edition; + let edition = self.crate_id.data(self.db).edition; let name = format!( "{}::{}", enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast(), edition), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index f61ecabb7e41d..346dea82526fb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -569,7 +569,7 @@ impl Evaluator<'_> { } String::from_utf8_lossy(&name_buf) }; - let value = self.db.crate_graph()[self.crate_id].env.get(&name); + let value = self.crate_id.env(self.db).get(&name); match value { None => { // Write null as fail diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 17f1da0c9f378..57d4baa137cee 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -2,7 +2,7 @@ use std::{fmt::Write, iter, mem}; -use base_db::{salsa::Cycle, CrateId}; +use base_db::{salsa::Cycle, Crate}; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ data::adt::{StructKind, VariantData}, @@ -1920,10 +1920,10 @@ impl<'ctx> MirLowerCtx<'ctx> { } fn edition(&self) -> Edition { - self.db.crate_graph()[self.krate()].edition + self.krate().data(self.db).edition } - fn krate(&self) -> CrateId { + fn krate(&self) -> Crate { self.owner.krate(self.db.upcast()) } @@ -2121,7 +2121,7 @@ pub fn mir_body_for_closure_query( pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result> { let krate = def.krate(db.upcast()); - let edition = db.crate_graph()[krate].edition; + let edition = krate.data(db).edition; let detail = match def { DefWithBodyId::FunctionId(it) => { db.function_data(it).name.display(db.upcast(), edition).to_string() diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs index b18a057ba0b9d..68d0c8cd5a312 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs @@ -3,8 +3,8 @@ use std::{fmt, panic, sync::Mutex}; use base_db::{ - FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, - SourceRootInput, Upcast, + CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, + SourceRoot, SourceRootId, SourceRootInput, Upcast, }; use hir_def::{db::DefDatabase, ModuleId}; @@ -21,6 +21,7 @@ use triomphe::Arc; pub(crate) struct TestDB { storage: salsa::Storage, files: Arc, + crates_map: Arc, events: Arc>>>, } @@ -30,8 +31,12 @@ impl Default for TestDB { storage: Default::default(), events: Default::default(), files: Default::default(), + crates_map: Default::default(), }; this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); + // This needs to be here otherwise `CrateGraphBuilder` panics. + this.set_all_crates(Arc::new(Box::new([]))); + CrateGraphBuilder::default().set_in_db(&mut this); this } } @@ -115,6 +120,10 @@ impl SourceDatabase for TestDB { let files = Arc::clone(&self.files); files.set_file_source_root_with_durability(self, id, source_root_id, durability); } + + fn crates_map(&self) -> Arc { + self.crates_map.clone() + } } #[salsa::db] @@ -151,8 +160,7 @@ impl TestDB { &self, ) -> FxHashMap> { let mut files = Vec::new(); - let crate_graph = self.crate_graph(); - for krate in crate_graph.iter() { + for &krate in self.all_crates().iter() { let crate_def_map = self.crate_def_map(krate); for (module_id, _) in crate_def_map.modules() { let file_id = crate_def_map[module_id].origin.file_id(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index 26229040582b8..cdb9e9edf8831 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -15,7 +15,7 @@ mod type_alias_impl_traits; use std::env; use std::sync::LazyLock; -use base_db::{CrateId, SourceDatabase}; +use base_db::{Crate, SourceDatabase}; use expect_test::Expect; use hir_def::{ db::DefDatabase, @@ -124,7 +124,7 @@ fn check_impl( } assert!(had_annotations || allow_none, "no `//^` annotations found"); - let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new(); + let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new(); for file_id in files { let module = db.module_for_file_opt(file_id); let module = match module { @@ -302,7 +302,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let mut infer_def = |inference_result: Arc, body: Arc, body_source_map: Arc, - krate: CrateId| { + krate: Crate| { let display_target = DisplayTarget::from_crate(&db, krate); let mut types: Vec<(InFile, &Ty)> = Vec::new(); let mut mismatches: Vec<(InFile, &TypeMismatch)> = Vec::new(); @@ -391,7 +391,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let module = db.module_for_file(file_id); let def_map = module.def_map(&db); - let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new(); + let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new(); visit_module(&db, &def_map, module.local_id, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 0135e0a409bbe..f8db6a8298f6b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -7,7 +7,7 @@ use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData}; use chalk_recursive::Cache; use chalk_solve::{logging_db::LoggingRustIrDatabase, rust_ir, Solver}; -use base_db::CrateId; +use base_db::Crate; use hir_def::{ lang_item::{LangItem, LangItemTarget}, BlockId, TraitId, @@ -30,7 +30,7 @@ const CHALK_SOLVER_FUEL: i32 = 1000; #[derive(Debug, Copy, Clone)] pub(crate) struct ChalkContext<'a> { pub(crate) db: &'a dyn HirDatabase, - pub(crate) krate: CrateId, + pub(crate) krate: Crate, pub(crate) block: Option, } @@ -48,7 +48,7 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver { /// we assume that `T: Default`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TraitEnvironment { - pub krate: CrateId, + pub krate: Crate, pub block: Option, // FIXME make this a BTreeMap traits_from_clauses: Box<[(Ty, TraitId)]>, @@ -56,7 +56,7 @@ pub struct TraitEnvironment { } impl TraitEnvironment { - pub fn empty(krate: CrateId) -> Arc { + pub fn empty(krate: Crate) -> Arc { Arc::new(TraitEnvironment { krate, block: None, @@ -66,7 +66,7 @@ impl TraitEnvironment { } pub fn new( - krate: CrateId, + krate: Crate, block: Option, traits_from_clauses: Box<[(Ty, TraitId)]>, env: chalk_ir::Environment, @@ -109,7 +109,7 @@ pub(crate) fn normalize_projection_query( /// Solve a trait goal using Chalk. pub(crate) fn trait_solve_query( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, block: Option, goal: Canonical>, ) -> Option { @@ -148,7 +148,7 @@ pub(crate) fn trait_solve_query( fn solve( db: &dyn HirDatabase, - krate: CrateId, + krate: Crate, block: Option, goal: &chalk_ir::UCanonical>>, ) -> Option> { @@ -294,7 +294,7 @@ impl FnTrait { } } - pub fn get_id(self, db: &dyn HirDatabase, krate: CrateId) -> Option { + pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option { let target = db.lang_item(krate, self.lang_item())?; match target { LangItemTarget::Trait(t) => Some(t), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index 89d89fe2230af..b90f4e4d7faaa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -3,7 +3,7 @@ use std::{hash::Hash, iter}; -use base_db::CrateId; +use base_db::Crate; use chalk_ir::{ fold::{FallibleTypeFolder, Shift}, DebruijnIndex, @@ -34,10 +34,7 @@ use crate::{ TraitRefExt, Ty, WhereClause, }; -pub(crate) fn fn_traits( - db: &dyn DefDatabase, - krate: CrateId, -) -> impl Iterator + '_ { +pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator + '_ { [LangItem::Fn, LangItem::FnMut, LangItem::FnOnce] .into_iter() .filter_map(move |lang| db.lang_item(krate, lang)) diff --git a/src/tools/rust-analyzer/crates/hir/src/from_id.rs b/src/tools/rust-analyzer/crates/hir/src/from_id.rs index 72df07ef8c0cc..891d2fd2ba5dc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/from_id.rs +++ b/src/tools/rust-analyzer/crates/hir/src/from_id.rs @@ -30,7 +30,7 @@ macro_rules! from_id { } from_id![ - (base_db::CrateId, crate::Crate), + (base_db::Crate, crate::Crate), (hir_def::ModuleId, crate::Module), (hir_def::StructId, crate::Struct), (hir_def::UnionId, crate::Union), diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index dbe743e7e2f85..5da2b5ed09361 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -39,7 +39,7 @@ use std::{ }; use arrayvec::ArrayVec; -use base_db::{CrateDisplayName, CrateId, CrateOrigin, LangCrateOrigin}; +use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ data::{adt::VariantData, TraitFlags}, @@ -176,7 +176,7 @@ use { /// root module. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Crate { - pub(crate) id: CrateId, + pub(crate) id: base_db::Crate, } #[derive(Debug)] @@ -187,7 +187,7 @@ pub struct CrateDependency { impl Crate { pub fn origin(self, db: &dyn HirDatabase) -> CrateOrigin { - db.crate_graph()[self.id].origin.clone() + self.id.data(db).origin.clone() } pub fn is_builtin(self, db: &dyn HirDatabase) -> bool { @@ -195,7 +195,8 @@ impl Crate { } pub fn dependencies(self, db: &dyn HirDatabase) -> Vec { - db.crate_graph()[self.id] + self.id + .data(db) .dependencies .iter() .map(|dep| { @@ -207,12 +208,11 @@ impl Crate { } pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec { - let crate_graph = db.crate_graph(); - crate_graph + let all_crates = db.all_crates(); + all_crates .iter() - .filter(|&krate| { - crate_graph[krate].dependencies.iter().any(|it| it.crate_id == self.id) - }) + .copied() + .filter(|&krate| krate.data(db).dependencies.iter().any(|it| it.crate_id == self.id)) .map(|id| Crate { id }) .collect() } @@ -221,7 +221,7 @@ impl Crate { self, db: &dyn HirDatabase, ) -> impl Iterator { - db.crate_graph().transitive_rev_deps(self.id).map(|id| Crate { id }) + db.transitive_rev_deps(self.id).into_iter().map(|id| Crate { id }) } pub fn root_module(self) -> Module { @@ -234,19 +234,19 @@ impl Crate { } pub fn root_file(self, db: &dyn HirDatabase) -> FileId { - db.crate_graph()[self.id].root_file_id + self.id.data(db).root_file_id } pub fn edition(self, db: &dyn HirDatabase) -> Edition { - db.crate_graph()[self.id].edition + self.id.data(db).edition } pub fn version(self, db: &dyn HirDatabase) -> Option { - db.crate_graph()[self.id].version.clone() + self.id.extra_data(db).version.clone() } pub fn display_name(self, db: &dyn HirDatabase) -> Option { - db.crate_graph()[self.id].display_name.clone() + self.id.extra_data(db).display_name.clone() } pub fn query_external_importables( @@ -264,7 +264,7 @@ impl Crate { } pub fn all(db: &dyn HirDatabase) -> Vec { - db.crate_graph().iter().map(|id| Crate { id }).collect() + db.all_crates().iter().map(|&id| Crate { id }).collect() } /// Try to get the root URL of the documentation of a crate. @@ -276,12 +276,12 @@ impl Crate { } pub fn cfg(&self, db: &dyn HirDatabase) -> Arc { - db.crate_graph()[self.id].cfg_options.clone() + Arc::clone(self.id.cfg_options(db)) } - pub fn potential_cfg(&self, db: &dyn HirDatabase) -> Arc { - let data = &db.crate_graph()[self.id]; - data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone()) + pub fn potential_cfg<'db>(&self, db: &'db dyn HirDatabase) -> &'db CfgOptions { + let data = self.id.extra_data(db); + data.potential_cfg_options.as_ref().unwrap_or_else(|| self.id.cfg_options(db)) } pub fn to_display_target(self, db: &dyn HirDatabase) -> DisplayTarget { @@ -289,11 +289,12 @@ impl Crate { } fn core(db: &dyn HirDatabase) -> Option { - let crate_graph = db.crate_graph(); - let result = crate_graph + let result = db + .all_crates() .iter() + .copied() .find(|&krate| { - matches!(crate_graph[krate].origin, CrateOrigin::Lang(LangCrateOrigin::Core)) + matches!(krate.data(db).origin, CrateOrigin::Lang(LangCrateOrigin::Core)) }) .map(Crate::from); result @@ -490,9 +491,7 @@ impl HasCrate for ModuleDef { fn krate(&self, db: &dyn HirDatabase) -> Crate { match self.module(db) { Some(module) => module.krate(), - None => Crate::core(db).unwrap_or_else(|| { - (*db.crate_graph().crates_in_topological_order().last().unwrap()).into() - }), + None => Crate::core(db).unwrap_or_else(|| db.all_crates()[0].into()), } } } @@ -611,7 +610,7 @@ impl Module { style_lints: bool, ) { let _p = tracing::info_span!("diagnostics", name = ?self.name(db)).entered(); - let edition = db.crate_graph()[self.id.krate()].edition; + let edition = self.id.krate().data(db).edition; let def_map = self.id.def_map(db.upcast()); for diag in def_map.diagnostics() { if diag.in_module != self.id.local_id { @@ -970,7 +969,7 @@ fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec return; }; let krate = HasModule::krate(&m.id, db.upcast()); - let edition = db.crate_graph()[krate].edition; + let edition = krate.data(db).edition; emit_def_diagnostic_( db, acc, @@ -3027,7 +3026,8 @@ impl BuiltinType { } pub fn ty(self, db: &dyn HirDatabase) -> Type { - Type::new_for_crate(db.crate_graph().iter().next().unwrap(), TyBuilder::builtin(self.inner)) + let core = Crate::core(db).map(|core| core.id).unwrap_or_else(|| db.all_crates()[0]); + Type::new_for_crate(core, TyBuilder::builtin(self.inner)) } pub fn name(self) -> Name { @@ -3968,7 +3968,7 @@ impl DeriveHelper { // FIXME: Wrong name? This is could also be a registered attribute #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct BuiltinAttr { - krate: Option, + krate: Option, idx: u32, } @@ -4014,7 +4014,7 @@ impl BuiltinAttr { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct ToolModule { - krate: CrateId, + krate: base_db::Crate, idx: u32, } @@ -4732,7 +4732,7 @@ impl Type { Type { env: environment, ty } } - pub(crate) fn new_for_crate(krate: CrateId, ty: Ty) -> Type { + pub(crate) fn new_for_crate(krate: base_db::Crate, ty: Ty) -> Type { Type { env: TraitEnvironment::empty(krate), ty } } @@ -4794,7 +4794,7 @@ impl Type { Type { env: ty.env, ty: TyBuilder::slice(ty.ty) } } - pub fn new_tuple(krate: CrateId, tys: &[Type]) -> Type { + pub fn new_tuple(krate: base_db::Crate, tys: &[Type]) -> Type { let tys = tys.iter().map(|it| it.ty.clone()); Type { env: TraitEnvironment::empty(krate), ty: TyBuilder::tuple_with(tys) } } @@ -4826,7 +4826,7 @@ impl Type { pub fn contains_reference(&self, db: &dyn HirDatabase) -> bool { return go(db, self.env.krate, &self.ty); - fn go(db: &dyn HirDatabase, krate: CrateId, ty: &Ty) -> bool { + fn go(db: &dyn HirDatabase, krate: base_db::Crate, ty: &Ty) -> bool { match ty.kind(Interner) { // Reference itself TyKind::Ref(_, _, _) => true, @@ -6209,7 +6209,7 @@ impl HasContainer for Module { let def_map = self.id.def_map(db.upcast()); match def_map[self.id.local_id].parent { Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }), - None => ItemContainer::Crate(def_map.krate()), + None => ItemContainer::Crate(def_map.krate().into()), } } } @@ -6289,7 +6289,7 @@ pub enum ItemContainer { Impl(Impl), Module(Module), ExternBlock(ExternBlock), - Crate(CrateId), + Crate(Crate), } /// Subset of `ide_db::Definition` that doc links can resolve to. diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index aeeb3f9790986..6378eebd24fa0 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -318,7 +318,7 @@ impl<'db> SemanticsImpl<'db> { pub fn first_crate_or_default(&self, file: FileId) -> Crate { match self.file_to_module_defs(file).next() { Some(module) => module.krate(), - None => (*self.db.crate_graph().crates_in_topological_order().last().unwrap()).into(), + None => (*self.db.all_crates().last().unwrap()).into(), } } diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index fa8153ad2162d..cc8aa1f1a18ed 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -77,10 +77,7 @@ impl<'a> SymbolCollector<'a> { symbols: Default::default(), work: Default::default(), current_container_name: None, - display_target: DisplayTarget::from_crate( - db, - *db.crate_graph().crates_in_topological_order().last().unwrap(), - ), + display_target: DisplayTarget::from_crate(db, *db.all_crates().last().unwrap()), } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs index 9e09f198feb4a..5a791c58bfd52 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs @@ -7,7 +7,7 @@ use hir::{ sym, FileRange, PathResolution, Semantics, TypeInfo, }; use ide_db::{ - base_db::CrateId, + base_db::Crate, defs::Definition, imports::insert_use::remove_path_if_in_use_stmt, path_transform::PathTransform, @@ -251,11 +251,11 @@ struct CallInfo { node: ast::CallableExpr, arguments: Vec, generic_arg_list: Option, - krate: CrateId, + krate: Crate, } impl CallInfo { - fn from_name_ref(name_ref: ast::NameRef, krate: CrateId) -> Option { + fn from_name_ref(name_ref: ast::NameRef, krate: Crate) -> Option { let parent = name_ref.syntax().parent()?; if let Some(call) = ast::MethodCallExpr::cast(parent.clone()) { let receiver = call.receiver()?; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs index d8b265678278b..4c8940db95cc7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs @@ -233,7 +233,13 @@ impl RootDatabase { // // SourceDatabase // base_db::ParseQuery // base_db::ParseErrorsQuery - // base_db::CrateGraphQuery + // base_db::AllCratesQuery + // base_db::InternUniqueCrateDataQuery + // base_db::InternUniqueCrateDataLookupQuery + // base_db::CrateDataQuery + // base_db::ExtraCrateDataQuery + // base_db::CrateCfgQuery + // base_db::CrateEnvQuery // base_db::CrateWorkspaceDataQuery // // SourceDatabaseExt diff --git a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs index af4c10f8ea6b5..fe4662785af11 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs @@ -1,6 +1,6 @@ //! See [`FamousDefs`]. -use base_db::{CrateOrigin, LangCrateOrigin, RootQueryDb as _}; +use base_db::{CrateOrigin, LangCrateOrigin}; use hir::{Crate, Enum, Function, Macro, Module, ScopeDef, Semantics, Trait}; use crate::RootDatabase; @@ -198,11 +198,10 @@ impl FamousDefs<'_, '_> { fn find_lang_crate(&self, origin: LangCrateOrigin) -> Option { let krate = self.1; let db = self.0.db; - let crate_graph = self.0.db.crate_graph(); let res = krate .dependencies(db) .into_iter() - .find(|dep| crate_graph[dep.krate.into()].origin == CrateOrigin::Lang(origin))? + .find(|dep| dep.krate.origin(db) == CrateOrigin::Lang(origin))? .krate; Some(res) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 2516a9d0aa388..414cc6cd18fa9 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -51,9 +51,8 @@ use salsa::Durability; use std::{fmt, mem::ManuallyDrop}; use base_db::{ - query_group::{self}, - FileSourceRootInput, FileText, Files, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, - SourceRootInput, Upcast, + query_group, CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, Files, RootQueryDb, + SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, Upcast, }; use hir::{ db::{DefDatabase, ExpandDatabase, HirDatabase}, @@ -85,6 +84,7 @@ pub struct RootDatabase { // compile times of all `ide_*` and downstream crates suffer greatly. storage: ManuallyDrop>, files: Arc, + crates_map: Arc, } impl std::panic::RefUnwindSafe for RootDatabase {} @@ -102,7 +102,11 @@ impl Drop for RootDatabase { impl Clone for RootDatabase { fn clone(&self) -> Self { - Self { storage: self.storage.clone(), files: self.files.clone() } + Self { + storage: self.storage.clone(), + files: self.files.clone(), + crates_map: self.crates_map.clone(), + } } } @@ -194,6 +198,10 @@ impl SourceDatabase for RootDatabase { let files = Arc::clone(&self.files); files.set_file_source_root_with_durability(self, id, source_root_id, durability); } + + fn crates_map(&self) -> Arc { + self.crates_map.clone() + } } impl Default for RootDatabase { @@ -207,8 +215,11 @@ impl RootDatabase { let mut db = RootDatabase { storage: ManuallyDrop::new(salsa::Storage::default()), files: Default::default(), + crates_map: Default::default(), }; - db.set_crate_graph_with_durability(Default::default(), Durability::HIGH); + // This needs to be here otherwise `CrateGraphBuilder` will panic. + db.set_all_crates(Arc::new(Box::new([]))); + CrateGraphBuilder::default().set_in_db(&mut db); db.set_proc_macros_with_durability(Default::default(), Durability::HIGH); db.set_local_roots_with_durability(Default::default(), Durability::HIGH); db.set_library_roots_with_durability(Default::default(), Durability::HIGH); @@ -258,7 +269,11 @@ impl RootDatabase { } pub fn snapshot(&self) -> Self { - Self { storage: self.storage.clone(), files: self.files.clone() } + Self { + storage: self.storage.clone(), + files: self.files.clone(), + crates_map: self.crates_map.clone(), + } } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs index 74d79cd69557f..cd3099fe93819 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs @@ -11,7 +11,7 @@ use itertools::Itertools; use salsa::{Cancelled, Database}; use crate::{ - base_db::{CrateId, RootQueryDb}, + base_db::{Crate, RootQueryDb}, symbol_index::SymbolsDatabase, FxIndexMap, RootDatabase, }; @@ -35,20 +35,22 @@ pub fn parallel_prime_caches( ) { let _p = tracing::info_span!("parallel_prime_caches").entered(); - let graph = db.crate_graph(); let mut crates_to_prime = { + // FIXME: We already have the crate list topologically sorted (but without the things + // `TopologicalSortIter` gives us). Maybe there is a way to avoid using it and rip it out + // of the codebase? let mut builder = topologic_sort::TopologicalSortIter::builder(); - for crate_id in graph.iter() { - builder.add(crate_id, graph[crate_id].dependencies.iter().map(|d| d.crate_id)); + for &crate_id in db.all_crates().iter() { + builder.add(crate_id, crate_id.data(db).dependencies.iter().map(|d| d.crate_id)); } builder.build() }; enum ParallelPrimeCacheWorkerProgress { - BeginCrate { crate_id: CrateId, crate_name: Symbol }, - EndCrate { crate_id: CrateId }, + BeginCrate { crate_id: Crate, crate_name: Symbol }, + EndCrate { crate_id: Crate }, } // We split off def map computation from other work, @@ -108,16 +110,14 @@ pub fn parallel_prime_caches( while crates_done < crates_total { db.unwind_if_revision_cancelled(); - for crate_id in &mut crates_to_prime { - let krate = &graph[crate_id]; - let name = krate - .display_name - .as_deref() - .cloned() - .unwrap_or_else(|| Symbol::integer(crate_id.into_raw().into_u32() as usize)); - if krate.origin.is_lang() { - additional_phases.push((crate_id, name.clone(), PrimingPhase::ImportMap)); - } else if krate.origin.is_local() { + for krate in &mut crates_to_prime { + let name = krate.extra_data(db).display_name.as_deref().cloned().unwrap_or_else(|| { + Symbol::integer(salsa::plumbing::AsId::as_id(&krate).as_u32() as usize) + }); + let origin = &krate.data(db).origin; + if origin.is_lang() { + additional_phases.push((krate, name.clone(), PrimingPhase::ImportMap)); + } else if origin.is_local() { // Compute the symbol search index. // This primes the cache for `ide_db::symbol_index::world_symbols()`. // @@ -127,10 +127,10 @@ pub fn parallel_prime_caches( // FIXME: We should do it unconditionally if the configuration is set to default to // searching dependencies (rust-analyzer.workspace.symbol.search.scope), but we // would need to pipe that configuration information down here. - additional_phases.push((crate_id, name.clone(), PrimingPhase::CrateSymbols)); + additional_phases.push((krate, name.clone(), PrimingPhase::CrateSymbols)); } - work_sender.send((crate_id, name, PrimingPhase::DefMap)).ok(); + work_sender.send((krate, name, PrimingPhase::DefMap)).ok(); } // recv_timeout is somewhat a hack, we need a way to from this thread check to see if the current salsa revision diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 81df0c0f0f88b..4f9ef05b20e79 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -162,13 +162,13 @@ impl SearchScope { fn crate_graph(db: &RootDatabase) -> SearchScope { let mut entries = FxHashMap::default(); - let graph = db.crate_graph(); - for krate in graph.iter() { - let root_file = graph[krate].root_file_id; - let source_root = db.file_source_root(root_file).source_root_id(db); + let all_crates = db.all_crates(); + for &krate in all_crates.iter() { + let crate_data = krate.data(db); + let source_root = db.file_source_root(crate_data.root_file_id).source_root_id(db); let source_root = db.source_root(source_root).source_root(db); entries.extend( - source_root.iter().map(|id| (EditionedFileId::new(id, graph[krate].edition), None)), + source_root.iter().map(|id| (EditionedFileId::new(id, crate_data.edition), None)), ); } SearchScope { entries } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt index 0cae7f367c205..1e2d4f1ab94fc 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt @@ -2,7 +2,9 @@ ( Module { id: ModuleId { - krate: Idx::(0), + krate: Crate { + [salsa id]: Id(2c00), + }, block: None, local_id: Idx::(0), }, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 48de1fb837a20..1a77052b18d46 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -2,7 +2,9 @@ ( Module { id: ModuleId { - krate: Idx::(0), + krate: Crate { + [salsa id]: Id(2c00), + }, block: None, local_id: Idx::(0), }, @@ -532,7 +534,9 @@ def: Module( Module { id: ModuleId { - krate: Idx::(0), + krate: Crate { + [salsa id]: Id(2c00), + }, block: None, local_id: Idx::(1), }, @@ -565,7 +569,9 @@ def: Module( Module { id: ModuleId { - krate: Idx::(0), + krate: Crate { + [salsa id]: Id(2c00), + }, block: None, local_id: Idx::(2), }, @@ -827,7 +833,9 @@ ( Module { id: ModuleId { - krate: Idx::(0), + krate: Crate { + [salsa id]: Id(2c00), + }, block: None, local_id: Idx::(1), }, @@ -871,7 +879,9 @@ ( Module { id: ModuleId { - krate: Idx::(0), + krate: Crate { + [salsa id]: Id(2c00), + }, block: None, local_id: Idx::(2), }, diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 5ce3336eb41f6..f4ced736b3df8 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -389,9 +389,9 @@ pub fn semantic_diagnostics( module.and_then(|m| db.toolchain_channel(m.krate().into())), Some(ReleaseChannel::Nightly) | None ); - let krate = module.map(|module| module.krate()).unwrap_or_else(|| { - (*db.crate_graph().crates_in_topological_order().last().unwrap()).into() - }); + let krate = module + .map(|module| module.krate()) + .unwrap_or_else(|| (*db.all_crates().last().unwrap()).into()); let display_target = krate.to_display_target(db); let ctx = DiagnosticsContext { config, sema, resolve, edition, is_nightly, display_target }; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index d32ba06f1eb4f..48d2431a11fbf 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -626,11 +626,11 @@ impl<'db, 'sema> Matcher<'db, 'sema> { match_error!("Failed to get receiver type for `{}`", expr.syntax().text()) })? .original; - let krate = self.sema.scope(expr.syntax()).map(|it| it.krate()).unwrap_or_else(|| { - hir::Crate::from( - *self.sema.db.crate_graph().crates_in_topological_order().last().unwrap(), - ) - }); + let krate = self + .sema + .scope(expr.syntax()) + .map(|it| it.krate()) + .unwrap_or_else(|| hir::Crate::from(*self.sema.db.all_crates().last().unwrap())); let res = code_type .autoderef(self.sema.db) .enumerate() diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 0acb129e93986..9bdc2e7d13337 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -504,9 +504,7 @@ fn get_doc_base_urls( let Some(krate) = krate else { return Default::default() }; let Some(display_name) = krate.display_name(db) else { return Default::default() }; - let crate_data = &db.crate_graph()[krate.into()]; - - let (web_base, local_base) = match &crate_data.origin { + let (web_base, local_base) = match krate.origin(db) { // std and co do not specify `html_root_url` any longer so we gotta handwrite this ourself. // FIXME: Use the toolchains channel instead of nightly CrateOrigin::Lang( diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 2347e2e8a36d8..3771efc17b69d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -1,8 +1,8 @@ use hir::db::ExpandDatabase; use hir::{ExpandResult, InFile, MacroFileIdExt, Semantics}; -use ide_db::base_db::CrateId; use ide_db::{ - helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase, + base_db::Crate, helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, + RootDatabase, }; use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize}; use stdx::format_to; @@ -208,7 +208,7 @@ fn format( file_id: FileId, expanded: SyntaxNode, span_map: &SpanMap, - krate: CrateId, + krate: Crate, ) -> String { let expansion = prettify_macro_expansion(db, expanded, span_map, krate).to_string(); @@ -249,7 +249,7 @@ fn _format( let upcast_db = ide_db::base_db::Upcast::::upcast(db); let &crate_id = upcast_db.relevant_crates(file_id).iter().next()?; - let edition = upcast_db.crate_graph()[crate_id].edition; + let edition = crate_id.data(upcast_db).edition; #[allow(clippy::disallowed_methods)] let mut cmd = std::process::Command::new(toolchain::Tool::Rustfmt.path()); diff --git a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs index 0e5bb89b6b717..b682c4bc0f791 100644 --- a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs +++ b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs @@ -20,21 +20,24 @@ pub struct CrateInfo { // // ![Show Dependency Tree](https://user-images.githubusercontent.com/5748995/229394139-2625beab-f4c9-484b-84ed-ad5dee0b1e1a.png) pub(crate) fn fetch_crates(db: &RootDatabase) -> FxIndexSet { - let crate_graph = db.crate_graph(); - crate_graph + db.all_crates() .iter() - .map(|crate_id| &crate_graph[crate_id]) - .filter(|&data| !matches!(data.origin, CrateOrigin::Local { .. })) - .map(crate_info) + .copied() + .map(|crate_id| (crate_id.data(db), crate_id.extra_data(db))) + .filter(|(data, _)| !matches!(data.origin, CrateOrigin::Local { .. })) + .map(|(data, extra_data)| crate_info(data, extra_data)) .collect() } -fn crate_info(data: &ide_db::base_db::CrateData) -> CrateInfo { - let crate_name = crate_name(data); - let version = data.version.clone(); +fn crate_info( + data: &ide_db::base_db::BuiltCrateData, + extra_data: &ide_db::base_db::ExtraCrateData, +) -> CrateInfo { + let crate_name = crate_name(extra_data); + let version = extra_data.version.clone(); CrateInfo { name: crate_name, version, root_file_id: data.root_file_id } } -fn crate_name(data: &ide_db::base_db::CrateData) -> Option { +fn crate_name(data: &ide_db::base_db::ExtraCrateData) -> Option { data.display_name.as_ref().map(|it| it.canonical_name().as_str().to_owned()) } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index 5d888ceb5edb9..1d807fb14c7bf 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -8,7 +8,6 @@ use hir::{ MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, }; use ide_db::{ - base_db::RootQueryDb, defs::Definition, documentation::HasDocs, famous_defs::FamousDefs, @@ -466,8 +465,7 @@ pub(super) fn path( item_name: Option, edition: Edition, ) -> String { - let crate_name = - db.crate_graph()[module.krate().into()].display_name.as_ref().map(|it| it.to_string()); + let crate_name = module.krate().display_name(db).as_ref().map(|it| it.to_string()); let module_path = module .path_to_root(db) .into_iter() diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 736d355ef2276..afddeb6deaa62 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -9252,7 +9252,7 @@ fn main() { S ``` ___ - Implements notable traits: Notable, Future, Iterator"#]], + Implements notable traits: Future, Iterator, Notable"#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 592c8603964da..aab8a3f873994 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -868,15 +868,15 @@ fn main() { //- minicore: fn fn main() { let x = || 2; - //^ {closure#26624} + //^ {closure#25600} let y = |t: i32| x() + t; - //^ {closure#26625} + //^ {closure#25601} let mut t = 5; //^ i32 let z = |k: i32| { t += k; }; - //^ {closure#26626} + //^ {closure#25602} let p = (y, z); - //^ ({closure#26625}, {closure#26626}) + //^ ({closure#25601}, {closure#25602}) } "#, ); diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index dcb170f3f7b63..79863f4680d80 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -57,7 +57,7 @@ mod view_memory_layout; mod view_mir; mod view_syntax_tree; -use std::{iter, panic::UnwindSafe}; +use std::panic::UnwindSafe; use cfg::CfgOptions; use fetch_crates::CrateInfo; @@ -125,7 +125,7 @@ pub use ide_completion::{ }; pub use ide_db::text_edit::{Indel, TextEdit}; pub use ide_db::{ - base_db::{CrateGraph, CrateId, FileChange, SourceRoot, SourceRootId}, + base_db::{Crate, CrateGraphBuilder, FileChange, SourceRoot, SourceRootId}, documentation::Documentation, label::Label, line_index::{LineCol, LineIndex}, @@ -239,7 +239,7 @@ impl Analysis { let mut change = ChangeWithProcMacros::new(); change.set_roots(vec![source_root]); - let mut crate_graph = CrateGraph::default(); + let mut crate_graph = CrateGraphBuilder::default(); // FIXME: cfg options // Default to enable test for single file. let mut cfg_options = CfgOptions::default(); @@ -255,16 +255,13 @@ impl Analysis { CrateOrigin::Local { repo: None, name: None }, false, None, - ); - change.change_file(file_id, Some(text)); - let ws_data = crate_graph - .iter() - .zip(iter::repeat(Arc::new(CrateWorkspaceData { + Arc::new(CrateWorkspaceData { data_layout: Err("fixture has no layout".into()), toolchain: None, - }))) - .collect(); - change.set_crate_graph(crate_graph, ws_data); + }), + ); + change.change_file(file_id, Some(text)); + change.set_crate_graph(crate_graph); host.apply_change(change); (host.analysis(), file_id) @@ -372,7 +369,7 @@ impl Analysis { self.with_db(|db| test_explorer::discover_tests_in_crate_by_test_id(db, crate_id)) } - pub fn discover_tests_in_crate(&self, crate_id: CrateId) -> Cancellable> { + pub fn discover_tests_in_crate(&self, crate_id: Crate) -> Cancellable> { self.with_db(|db| test_explorer::discover_tests_in_crate(db, crate_id)) } @@ -602,17 +599,17 @@ impl Analysis { } /// Returns crates that this file belongs to. - pub fn crates_for(&self, file_id: FileId) -> Cancellable> { + pub fn crates_for(&self, file_id: FileId) -> Cancellable> { self.with_db(|db| parent_module::crates_for(db, file_id)) } /// Returns crates that this file belongs to. - pub fn transitive_rev_deps(&self, crate_id: CrateId) -> Cancellable> { - self.with_db(|db| db.crate_graph().transitive_rev_deps(crate_id).collect()) + pub fn transitive_rev_deps(&self, crate_id: Crate) -> Cancellable> { + self.with_db(|db| Vec::from_iter(db.transitive_rev_deps(crate_id))) } /// Returns crates that this file *might* belong to. - pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable> { + pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable> { self.with_db(|db| { let db = Upcast::::upcast(db); db.relevant_crates(file_id).iter().copied().collect() @@ -620,18 +617,23 @@ impl Analysis { } /// Returns the edition of the given crate. - pub fn crate_edition(&self, crate_id: CrateId) -> Cancellable { - self.with_db(|db| db.crate_graph()[crate_id].edition) + pub fn crate_edition(&self, crate_id: Crate) -> Cancellable { + self.with_db(|db| crate_id.data(db).edition) + } + + /// Returns whether the given crate is a proc macro. + pub fn is_proc_macro_crate(&self, crate_id: Crate) -> Cancellable { + self.with_db(|db| crate_id.data(db).is_proc_macro) } /// Returns true if this crate has `no_std` or `no_core` specified. - pub fn is_crate_no_std(&self, crate_id: CrateId) -> Cancellable { + pub fn is_crate_no_std(&self, crate_id: Crate) -> Cancellable { self.with_db(|db| hir::db::DefDatabase::crate_def_map(db, crate_id).is_no_std()) } /// Returns the root file of the given crate. - pub fn crate_root(&self, crate_id: CrateId) -> Cancellable { - self.with_db(|db| db.crate_graph()[crate_id].root_file_id) + pub fn crate_root(&self, crate_id: Crate) -> Cancellable { + self.with_db(|db| crate_id.data(db).root_file_id) } /// Returns the set of possible targets to run for the current file. diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs index 90cccca5e80f4..06ab4750ac5b9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs +++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs @@ -1,6 +1,6 @@ use hir::{db::DefDatabase, Semantics}; use ide_db::{ - base_db::{CrateId, RootQueryDb, Upcast}, + base_db::{Crate, RootQueryDb, Upcast}, FileId, FilePosition, RootDatabase, }; use itertools::Itertools; @@ -53,7 +53,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec Vec { +pub(crate) fn crates_for(db: &RootDatabase, file_id: FileId) -> Vec { let root_db = Upcast::::upcast(db); root_db .relevant_crates(file_id) diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 33eef6d75c21a..baa7ee6897352 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -498,9 +498,8 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option { }; let krate = def.krate(db); let edition = krate.map(|it| it.edition(db)).unwrap_or(Edition::CURRENT); - let display_target = krate - .unwrap_or_else(|| (*db.crate_graph().crates_in_topological_order().last().unwrap()).into()) - .to_display_target(db); + let display_target = + krate.unwrap_or_else(|| (*db.all_crates().last().unwrap()).into()).to_display_target(db); if !has_runnable_doc_test(&attrs) { return None; } diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index ceea34b721373..5a2b09b513774 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -119,9 +119,7 @@ fn documentation_for_definition( sema.db, famous_defs.as_ref(), def.krate(sema.db) - .unwrap_or_else(|| { - (*sema.db.crate_graph().crates_in_topological_order().last().unwrap()).into() - }) + .unwrap_or_else(|| (*sema.db.all_crates().last().unwrap()).into()) .to_display_target(sema.db), ) } diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index 47ac4ebf20e3b..52d38041ec125 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -1,4 +1,4 @@ -use ide_db::base_db::{CrateData, RootQueryDb, Upcast}; +use ide_db::base_db::{BuiltCrateData, ExtraCrateData}; use ide_db::RootDatabase; use itertools::Itertools; use span::FileId; @@ -34,28 +34,25 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { if crates.is_empty() { format_to!(buf, "Does not belong to any crate"); } - - let crate_graph = Upcast::::upcast(db).crate_graph(); for crate_id in crates { - let CrateData { + let BuiltCrateData { root_file_id, edition, - version, - display_name, - cfg_options, - potential_cfg_options, - env, dependencies, origin, is_proc_macro, proc_macro_cwd, - } = &crate_graph[crate_id]; + } = crate_id.data(db); + let ExtraCrateData { version, display_name, potential_cfg_options } = + crate_id.extra_data(db); + let cfg_options = crate_id.cfg_options(db); + let env = crate_id.env(db); format_to!( buf, "Crate: {}\n", match display_name { - Some(it) => format!("{it}({})", crate_id.into_raw()), - None => format!("{}", crate_id.into_raw()), + Some(it) => format!("{it}({:?})", crate_id), + None => format!("{:?}", crate_id), } ); format_to!(buf, " Root module file id: {}\n", root_file_id.index()); @@ -69,7 +66,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { format_to!(buf, " Proc macro cwd: {:?}\n", proc_macro_cwd); let deps = dependencies .iter() - .map(|dep| format!("{}={}", dep.name, dep.crate_id.into_raw())) + .map(|dep| format!("{}={:?}", dep.name, dep.crate_id)) .format(", "); format_to!(buf, " Dependencies: {}\n", deps); } diff --git a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs index 68f5c72d20531..d22133c856587 100644 --- a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs +++ b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs @@ -1,17 +1,15 @@ //! Discovers tests use hir::{Crate, Module, ModuleDef, Semantics}; -use ide_db::{ - base_db::{CrateGraph, CrateId, RootQueryDb}, - FileId, RootDatabase, -}; +use ide_db::base_db; +use ide_db::{base_db::RootQueryDb, FileId, RootDatabase}; use syntax::TextRange; use crate::{runnables::runnable_fn, NavigationTarget, Runnable, TryToNav}; #[derive(Debug)] pub enum TestItemKind { - Crate(CrateId), + Crate(base_db::Crate), Module, Function, } @@ -28,12 +26,12 @@ pub struct TestItem { } pub(crate) fn discover_test_roots(db: &RootDatabase) -> Vec { - let crate_graph = db.crate_graph(); - crate_graph + db.all_crates() .iter() - .filter(|&id| crate_graph[id].origin.is_local()) + .copied() + .filter(|&id| id.data(db).origin.is_local()) .filter_map(|id| { - let test_id = crate_graph[id].display_name.as_ref()?.to_string(); + let test_id = id.extra_data(db).display_name.as_ref()?.to_string(); Some(TestItem { kind: TestItemKind::Crate(id), label: test_id.clone(), @@ -47,12 +45,12 @@ pub(crate) fn discover_test_roots(db: &RootDatabase) -> Vec { .collect() } -fn find_crate_by_id(crate_graph: &CrateGraph, crate_id: &str) -> Option { +fn find_crate_by_id(db: &RootDatabase, crate_id: &str) -> Option { // here, we use display_name as the crate id. This is not super ideal, but it works since we // only show tests for the local crates. - crate_graph.iter().find(|&id| { - crate_graph[id].origin.is_local() - && crate_graph[id].display_name.as_ref().is_some_and(|x| x.to_string() == crate_id) + db.all_crates().iter().copied().find(|&id| { + id.data(db).origin.is_local() + && id.extra_data(db).display_name.as_ref().is_some_and(|x| x.to_string() == crate_id) }) } @@ -115,8 +113,7 @@ pub(crate) fn discover_tests_in_crate_by_test_id( db: &RootDatabase, crate_test_id: &str, ) -> Vec { - let crate_graph = db.crate_graph(); - let Some(crate_id) = find_crate_by_id(&crate_graph, crate_test_id) else { + let Some(crate_id) = find_crate_by_id(db, crate_test_id) else { return vec![]; }; discover_tests_in_crate(db, crate_id) @@ -171,12 +168,14 @@ fn find_module_id_and_test_parents( Some((r, id)) } -pub(crate) fn discover_tests_in_crate(db: &RootDatabase, crate_id: CrateId) -> Vec { - let crate_graph = db.crate_graph(); - if !crate_graph[crate_id].origin.is_local() { +pub(crate) fn discover_tests_in_crate( + db: &RootDatabase, + crate_id: base_db::Crate, +) -> Vec { + if !crate_id.data(db).origin.is_local() { return vec![]; } - let Some(crate_test_id) = &crate_graph[crate_id].display_name else { + let Some(crate_test_id) = &crate_id.extra_data(db).display_name else { return vec![]; }; let kind = TestItemKind::Crate(crate_id); diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs index eeb65ac038932..09f21ecfe41cc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs @@ -1,9 +1,10 @@ use dot::{Id, LabelText}; use ide_db::{ - base_db::{CrateGraph, CrateId, Dependency, RootQueryDb, SourceDatabase, Upcast}, - FxHashSet, RootDatabase, + base_db::{ + BuiltCrateData, BuiltDependency, Crate, ExtraCrateData, RootQueryDb, SourceDatabase, + }, + FxHashMap, RootDatabase, }; -use triomphe::Arc; // Feature: View Crate Graph // @@ -16,77 +17,80 @@ use triomphe::Arc; // |---------|-------------| // | VS Code | **rust-analyzer: View Crate Graph** | pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result { - let crate_graph = Upcast::::upcast(db).crate_graph(); - let crates_to_render = crate_graph + let all_crates = db.all_crates(); + let crates_to_render = all_crates .iter() - .filter(|krate| { + .copied() + .map(|krate| (krate, (krate.data(db), krate.extra_data(db)))) + .filter(|(_, (crate_data, _))| { if full { true } else { // Only render workspace crates - let root_id = - db.file_source_root(crate_graph[*krate].root_file_id).source_root_id(db); + let root_id = db.file_source_root(crate_data.root_file_id).source_root_id(db); !db.source_root(root_id).source_root(db).is_library } }) .collect(); - let graph = DotCrateGraph { graph: crate_graph, crates_to_render }; + let graph = DotCrateGraph { crates_to_render }; let mut dot = Vec::new(); dot::render(&graph, &mut dot).unwrap(); Ok(String::from_utf8(dot).unwrap()) } -struct DotCrateGraph { - graph: Arc, - crates_to_render: FxHashSet, +struct DotCrateGraph<'db> { + crates_to_render: FxHashMap, } -type Edge<'a> = (CrateId, &'a Dependency); +type Edge<'a> = (Crate, &'a BuiltDependency); -impl<'a> dot::GraphWalk<'a, CrateId, Edge<'a>> for DotCrateGraph { - fn nodes(&'a self) -> dot::Nodes<'a, CrateId> { - self.crates_to_render.iter().copied().collect() +impl<'a> dot::GraphWalk<'a, Crate, Edge<'a>> for DotCrateGraph<'_> { + fn nodes(&'a self) -> dot::Nodes<'a, Crate> { + self.crates_to_render.keys().copied().collect() } fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.crates_to_render .iter() - .flat_map(|krate| { - self.graph[*krate] + .flat_map(|(krate, (crate_data, _))| { + crate_data .dependencies .iter() - .filter(|dep| self.crates_to_render.contains(&dep.crate_id)) + .filter(|dep| self.crates_to_render.contains_key(&dep.crate_id)) .map(move |dep| (*krate, dep)) }) .collect() } - fn source(&'a self, edge: &Edge<'a>) -> CrateId { + fn source(&'a self, edge: &Edge<'a>) -> Crate { edge.0 } - fn target(&'a self, edge: &Edge<'a>) -> CrateId { + fn target(&'a self, edge: &Edge<'a>) -> Crate { edge.1.crate_id } } -impl<'a> dot::Labeller<'a, CrateId, Edge<'a>> for DotCrateGraph { +impl<'a> dot::Labeller<'a, Crate, Edge<'a>> for DotCrateGraph<'_> { fn graph_id(&'a self) -> Id<'a> { Id::new("rust_analyzer_crate_graph").unwrap() } - fn node_id(&'a self, n: &CrateId) -> Id<'a> { - Id::new(format!("_{}", u32::from(n.into_raw()))).unwrap() + fn node_id(&'a self, n: &Crate) -> Id<'a> { + Id::new(format!("_{:?}", n)).unwrap() } - fn node_shape(&'a self, _node: &CrateId) -> Option> { + fn node_shape(&'a self, _node: &Crate) -> Option> { Some(LabelText::LabelStr("box".into())) } - fn node_label(&'a self, n: &CrateId) -> LabelText<'a> { - let name = - self.graph[*n].display_name.as_ref().map_or("(unnamed crate)", |name| name.as_str()); + fn node_label(&'a self, n: &Crate) -> LabelText<'a> { + let name = self.crates_to_render[n] + .1 + .display_name + .as_ref() + .map_or("(unnamed crate)", |name| name.as_str()); LabelText::LabelStr(name.into()) } } diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index 0fa6701ca3fa3..f6a74d97416ef 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -42,6 +42,18 @@ struct TaggedArcPtr { unsafe impl Send for TaggedArcPtr {} unsafe impl Sync for TaggedArcPtr {} +impl Ord for TaggedArcPtr { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.as_str().cmp(other.as_str()) + } +} + +impl PartialOrd for TaggedArcPtr { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + impl TaggedArcPtr { const BOOL_BITS: usize = true as usize; @@ -113,7 +125,7 @@ impl TaggedArcPtr { } } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Symbol { repr: TaggedArcPtr, } diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index fbb0043ad2d21..01d29d88df4a2 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -2,15 +2,15 @@ //! for incorporating changes. // Note, don't remove any public api from this. This API is consumed by external tools // to run rust-analyzer as a library. -use std::{collections::hash_map::Entry, iter, mem, path::Path, sync}; +use std::{collections::hash_map::Entry, mem, path::Path, sync}; use crossbeam_channel::{unbounded, Receiver}; use hir_expand::proc_macro::{ ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacroLoadResult, - ProcMacros, + ProcMacrosBuilder, }; use ide_db::{ - base_db::{CrateGraph, CrateWorkspaceData, Env, SourceRoot, SourceRootId}, + base_db::{CrateGraphBuilder, Env, SourceRoot, SourceRootId}, prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase, }; use itertools::Itertools; @@ -139,7 +139,6 @@ pub fn load_workspace( }); let db = load_crate_graph( - &ws, crate_graph, proc_macros, project_folders.source_root_config, @@ -418,15 +417,12 @@ pub fn load_proc_macro( } fn load_crate_graph( - ws: &ProjectWorkspace, - crate_graph: CrateGraph, - proc_macros: ProcMacros, + crate_graph: CrateGraphBuilder, + proc_macros: ProcMacrosBuilder, source_root_config: SourceRootConfig, vfs: &mut vfs::Vfs, receiver: &Receiver, ) -> RootDatabase { - let ProjectWorkspace { toolchain, target_layout, .. } = ws; - let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::().ok()); let mut db = RootDatabase::new(lru_cap); let mut analysis_change = ChangeWithProcMacros::new(); @@ -461,14 +457,7 @@ fn load_crate_graph( let source_roots = source_root_config.partition(vfs); analysis_change.set_roots(source_roots); - let ws_data = crate_graph - .iter() - .zip(iter::repeat(From::from(CrateWorkspaceData { - data_layout: target_layout.clone(), - toolchain: toolchain.clone(), - }))) - .collect(); - analysis_change.set_crate_graph(crate_graph, ws_data); + analysis_change.set_crate_graph(crate_graph); analysis_change.set_proc_macros(proc_macros); db.apply_change(analysis_change); @@ -494,7 +483,7 @@ fn expander_to_proc_macro( } } -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] struct Expander(proc_macro_api::ProcMacro); impl ProcMacroExpander for Expander { @@ -522,6 +511,10 @@ impl ProcMacroExpander for Expander { Err(err) => Err(ProcMacroExpansionError::System(err.to_string())), } } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().downcast_ref::().is_some_and(|other| self == other) + } } #[cfg(test)] @@ -543,7 +536,7 @@ mod tests { let (db, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {}).unwrap(); - let n_crates = db.crate_graph().iter().count(); + let n_crates = db.all_crates().len(); // RA has quite a few crates, but the exact count doesn't matter assert!(n_crates > 20); } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index dc3328ebcda48..571ceaabe62cd 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -13,7 +13,7 @@ mod process; use paths::{AbsPath, AbsPathBuf}; use span::Span; -use std::{fmt, io, sync::Arc}; +use std::{fmt, io, sync::Arc, time::SystemTime}; use crate::{ legacy_protocol::msg::{ @@ -66,6 +66,7 @@ pub struct ProcMacro { dylib_path: Arc, name: Box, kind: ProcMacroKind, + dylib_last_modified: Option, } impl Eq for ProcMacro {} @@ -73,7 +74,8 @@ impl PartialEq for ProcMacro { fn eq(&self, other: &Self) -> bool { self.name == other.name && self.kind == other.kind - && Arc::ptr_eq(&self.dylib_path, &other.dylib_path) + && self.dylib_path == other.dylib_path + && self.dylib_last_modified == other.dylib_last_modified && Arc::ptr_eq(&self.process, &other.process) } } @@ -116,6 +118,9 @@ impl ProcMacroClient { let macros = self.process.find_proc_macros(&dylib.path)?; let dylib_path = Arc::new(dylib.path); + let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) + .ok() + .and_then(|metadata| metadata.modified().ok()); match macros { Ok(macros) => Ok(macros .into_iter() @@ -124,6 +129,7 @@ impl ProcMacroClient { name: name.into(), kind, dylib_path: dylib_path.clone(), + dylib_last_modified, }) .collect()), Err(message) => Err(ServerError { message, io: None }), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs index 15de88ea656d0..716d351271efa 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs @@ -12,7 +12,7 @@ fn test_derive_empty() { "DeriveEmpty", r#"struct S;"#, expect!["SUBTREE $$ 1 1"], - expect!["SUBTREE $$ 42:2@0..100#2 42:2@0..100#2"], + expect!["SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037"], ); } @@ -29,12 +29,12 @@ fn test_derive_error() { LITERAL Str #[derive(DeriveError)] struct S ; 1 PUNCH ; [alone] 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT compile_error 42:2@0..100#2 - PUNCH ! [alone] 42:2@0..100#2 - SUBTREE () 42:2@0..100#2 42:2@0..100#2 - LITERAL Str #[derive(DeriveError)] struct S ; 42:2@0..100#2 - PUNCH ; [alone] 42:2@0..100#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT compile_error 42:2@0..100#4294967037 + PUNCH ! [alone] 42:2@0..100#4294967037 + SUBTREE () 42:2@0..100#4294967037 42:2@0..100#4294967037 + LITERAL Str #[derive(DeriveError)] struct S ; 42:2@0..100#4294967037 + PUNCH ; [alone] 42:2@0..100#4294967037"#]], ); } @@ -53,14 +53,14 @@ fn test_fn_like_macro_noop() { PUNCH , [alone] 1 SUBTREE [] 1 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT ident 42:2@0..5#2 - PUNCH , [alone] 42:2@5..6#2 - LITERAL Integer 0 42:2@7..8#2 - PUNCH , [alone] 42:2@8..9#2 - LITERAL Integer 1 42:2@10..11#2 - PUNCH , [alone] 42:2@11..12#2 - SUBTREE [] 42:2@13..14#2 42:2@14..15#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT ident 42:2@0..5#4294967037 + PUNCH , [alone] 42:2@5..6#4294967037 + LITERAL Integer 0 42:2@7..8#4294967037 + PUNCH , [alone] 42:2@8..9#4294967037 + LITERAL Integer 1 42:2@10..11#4294967037 + PUNCH , [alone] 42:2@11..12#4294967037 + SUBTREE [] 42:2@13..14#4294967037 42:2@14..15#4294967037"#]], ); } @@ -75,10 +75,10 @@ fn test_fn_like_macro_clone_ident_subtree() { PUNCH , [alone] 1 SUBTREE [] 1 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT ident 42:2@0..5#2 - PUNCH , [alone] 42:2@5..6#2 - SUBTREE [] 42:2@7..8#2 42:2@7..8#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT ident 42:2@0..5#4294967037 + PUNCH , [alone] 42:2@5..6#4294967037 + SUBTREE [] 42:2@7..8#4294967037 42:2@7..8#4294967037"#]], ); } @@ -91,8 +91,8 @@ fn test_fn_like_macro_clone_raw_ident() { SUBTREE $$ 1 1 IDENT r#async 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT r#async 42:2@0..7#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT r#async 42:2@0..7#4294967037"#]], ); } @@ -105,8 +105,8 @@ fn test_fn_like_fn_like_span_join() { SUBTREE $$ 1 1 IDENT r#joined 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT r#joined 42:2@0..11#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT r#joined 42:2@0..11#4294967037"#]], ); } @@ -121,10 +121,10 @@ fn test_fn_like_fn_like_span_ops() { IDENT resolved_at_def_site 1 IDENT start_span 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT set_def_site 41:1@0..150#2 - IDENT resolved_at_def_site 42:2@13..33#2 - IDENT start_span 42:2@34..34#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT set_def_site 41:1@0..150#4294967037 + IDENT resolved_at_def_site 42:2@13..33#4294967037 + IDENT start_span 42:2@34..34#4294967037"#]], ); } @@ -143,14 +143,14 @@ fn test_fn_like_mk_literals() { LITERAL Integer 123i64 1 LITERAL Integer 123 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - LITERAL ByteStr byte_string 42:2@0..100#2 - LITERAL Char c 42:2@0..100#2 - LITERAL Str string 42:2@0..100#2 - LITERAL Float 3.14f64 42:2@0..100#2 - LITERAL Float 3.14 42:2@0..100#2 - LITERAL Integer 123i64 42:2@0..100#2 - LITERAL Integer 123 42:2@0..100#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + LITERAL ByteStr byte_string 42:2@0..100#4294967037 + LITERAL Char c 42:2@0..100#4294967037 + LITERAL Str string 42:2@0..100#4294967037 + LITERAL Float 3.14f64 42:2@0..100#4294967037 + LITERAL Float 3.14 42:2@0..100#4294967037 + LITERAL Integer 123i64 42:2@0..100#4294967037 + LITERAL Integer 123 42:2@0..100#4294967037"#]], ); } @@ -164,9 +164,9 @@ fn test_fn_like_mk_idents() { IDENT standard 1 IDENT r#raw 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT standard 42:2@0..100#2 - IDENT r#raw 42:2@0..100#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT standard 42:2@0..100#4294967037 + IDENT r#raw 42:2@0..100#4294967037"#]], ); } @@ -198,27 +198,27 @@ fn test_fn_like_macro_clone_literals() { PUNCH , [alone] 1 LITERAL CStr null 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - LITERAL Integer 1u16 42:2@0..4#2 - PUNCH , [alone] 42:2@4..5#2 - LITERAL Integer 2_u32 42:2@6..11#2 - PUNCH , [alone] 42:2@11..12#2 - PUNCH - [alone] 42:2@13..14#2 - LITERAL Integer 4i64 42:2@14..18#2 - PUNCH , [alone] 42:2@18..19#2 - LITERAL Float 3.14f32 42:2@20..27#2 - PUNCH , [alone] 42:2@27..28#2 - LITERAL Str hello bridge 42:2@29..43#2 - PUNCH , [alone] 42:2@43..44#2 - LITERAL Str suffixedsuffix 42:2@45..61#2 - PUNCH , [alone] 42:2@61..62#2 - LITERAL StrRaw(2) raw 42:2@63..73#2 - PUNCH , [alone] 42:2@73..74#2 - LITERAL Char a 42:2@75..78#2 - PUNCH , [alone] 42:2@78..79#2 - LITERAL Byte b 42:2@80..84#2 - PUNCH , [alone] 42:2@84..85#2 - LITERAL CStr null 42:2@86..93#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + LITERAL Integer 1u16 42:2@0..4#4294967037 + PUNCH , [alone] 42:2@4..5#4294967037 + LITERAL Integer 2_u32 42:2@6..11#4294967037 + PUNCH , [alone] 42:2@11..12#4294967037 + PUNCH - [alone] 42:2@13..14#4294967037 + LITERAL Integer 4i64 42:2@14..18#4294967037 + PUNCH , [alone] 42:2@18..19#4294967037 + LITERAL Float 3.14f32 42:2@20..27#4294967037 + PUNCH , [alone] 42:2@27..28#4294967037 + LITERAL Str hello bridge 42:2@29..43#4294967037 + PUNCH , [alone] 42:2@43..44#4294967037 + LITERAL Str suffixedsuffix 42:2@45..61#4294967037 + PUNCH , [alone] 42:2@61..62#4294967037 + LITERAL StrRaw(2) raw 42:2@63..73#4294967037 + PUNCH , [alone] 42:2@73..74#4294967037 + LITERAL Char a 42:2@75..78#4294967037 + PUNCH , [alone] 42:2@78..79#4294967037 + LITERAL Byte b 42:2@80..84#4294967037 + PUNCH , [alone] 42:2@84..85#4294967037 + LITERAL CStr null 42:2@86..93#4294967037"#]], ); } @@ -239,12 +239,12 @@ fn test_attr_macro() { LITERAL Str #[attr_error(some arguments)] mod m {} 1 PUNCH ; [alone] 1"#]], expect![[r#" - SUBTREE $$ 42:2@0..100#2 42:2@0..100#2 - IDENT compile_error 42:2@0..100#2 - PUNCH ! [alone] 42:2@0..100#2 - SUBTREE () 42:2@0..100#2 42:2@0..100#2 - LITERAL Str #[attr_error(some arguments)] mod m {} 42:2@0..100#2 - PUNCH ; [alone] 42:2@0..100#2"#]], + SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037 + IDENT compile_error 42:2@0..100#4294967037 + PUNCH ! [alone] 42:2@0..100#4294967037 + SUBTREE () 42:2@0..100#4294967037 42:2@0..100#4294967037 + LITERAL Str #[attr_error(some arguments)] mod m {} 42:2@0..100#4294967037 + PUNCH ; [alone] 42:2@0..100#4294967037"#]], ); } diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index b2df8e4703ab3..3c14e6e627771 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -452,7 +452,7 @@ pub enum TargetKindData { } /// Identifies a crate by position in the crates array. /// -/// This will differ from `CrateId` when multiple `ProjectJson` +/// This will differ from `Crate` when multiple `ProjectJson` /// workspaces are loaded. #[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)] #[serde(transparent)] diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 837406227323e..d4c93b0e9bc9a 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -1,4 +1,4 @@ -use base_db::{CrateGraph, ProcMacroPaths}; +use base_db::{CrateGraphBuilder, ProcMacroPaths}; use cargo_metadata::Metadata; use cfg::{CfgAtom, CfgDiff}; use expect_test::{expect_file, ExpectFile}; @@ -15,7 +15,7 @@ use crate::{ Sysroot, WorkspaceBuildScripts, }; -fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) { +fn load_cargo(file: &str) -> (CrateGraphBuilder, ProcMacroPaths) { let project_workspace = load_workspace_from_metadata(file); to_crate_graph(project_workspace, &mut Default::default()) } @@ -23,7 +23,7 @@ fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) { fn load_cargo_with_overrides( file: &str, cfg_overrides: CfgOverrides, -) -> (CrateGraph, ProcMacroPaths) { +) -> (CrateGraphBuilder, ProcMacroPaths) { let project_workspace = ProjectWorkspace { cfg_overrides, ..load_workspace_from_metadata(file) }; to_crate_graph(project_workspace, &mut Default::default()) @@ -51,7 +51,7 @@ fn load_workspace_from_metadata(file: &str) -> ProjectWorkspace { } } -fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) { +fn load_rust_project(file: &str) -> (CrateGraphBuilder, ProcMacroPaths) { let data = get_test_json_file(file); let project = rooted_project_json(data); let sysroot = get_fake_sysroot(); @@ -142,7 +142,7 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson { fn to_crate_graph( project_workspace: ProjectWorkspace, file_map: &mut FxHashMap, -) -> (CrateGraph, ProcMacroPaths) { +) -> (CrateGraphBuilder, ProcMacroPaths) { project_workspace.to_crate_graph( &mut { |path| { @@ -154,7 +154,7 @@ fn to_crate_graph( ) } -fn check_crate_graph(crate_graph: CrateGraph, expect: ExpectFile) { +fn check_crate_graph(crate_graph: CrateGraphBuilder, expect: ExpectFile) { let mut crate_graph = format!("{crate_graph:#?}"); replace_root(&mut crate_graph, false); diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 62c13c7d9ec8d..114c2551e1c13 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -6,8 +6,9 @@ use std::{collections::VecDeque, fmt, fs, iter, ops::Deref, sync, thread}; use anyhow::Context; use base_db::{ - CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env, - LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult, + CrateBuilderId, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, + CrateWorkspaceData, DependencyBuilder, Env, LangCrateOrigin, ProcMacroPaths, + TargetLayoutLoadResult, }; use cfg::{CfgAtom, CfgDiff, CfgOptions}; use intern::{sym, Symbol}; @@ -848,10 +849,14 @@ impl ProjectWorkspace { &self, load: FileLoader<'_>, extra_env: &FxHashMap, - ) -> (CrateGraph, ProcMacroPaths) { + ) -> (CrateGraphBuilder, ProcMacroPaths) { let _p = tracing::info_span!("ProjectWorkspace::to_crate_graph").entered(); let Self { kind, sysroot, cfg_overrides, rustc_cfg, .. } = self; + let crate_ws_data = Arc::new(CrateWorkspaceData { + toolchain: self.toolchain.clone(), + data_layout: self.target_layout.clone(), + }); let (crate_graph, proc_macros) = match kind { ProjectWorkspaceKind::Json(project) => project_json_to_crate_graph( rustc_cfg.clone(), @@ -861,6 +866,7 @@ impl ProjectWorkspace { extra_env, cfg_overrides, self.set_test, + crate_ws_data, ), ProjectWorkspaceKind::Cargo { cargo, rustc, build_scripts, error: _ } => { cargo_to_crate_graph( @@ -872,6 +878,7 @@ impl ProjectWorkspace { cfg_overrides, build_scripts, self.set_test, + crate_ws_data, ) } ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => { @@ -885,6 +892,7 @@ impl ProjectWorkspace { cfg_overrides, build_scripts, self.set_test, + crate_ws_data, ) } else { detached_file_to_crate_graph( @@ -894,6 +902,7 @@ impl ProjectWorkspace { sysroot, cfg_overrides, self.set_test, + crate_ws_data, ) } } @@ -959,15 +968,22 @@ fn project_json_to_crate_graph( extra_env: &FxHashMap, override_cfg: &CfgOverrides, set_test: bool, -) -> (CrateGraph, ProcMacroPaths) { - let mut res = (CrateGraph::default(), ProcMacroPaths::default()); + crate_ws_data: Arc, +) -> (CrateGraphBuilder, ProcMacroPaths) { + let mut res = (CrateGraphBuilder::default(), ProcMacroPaths::default()); let (crate_graph, proc_macros) = &mut res; - let (public_deps, libproc_macro) = - sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); + let (public_deps, libproc_macro) = sysroot_to_crate_graph( + crate_graph, + sysroot, + rustc_cfg.clone(), + load, + // FIXME: This looks incorrect but I don't think this matters. + crate_ws_data.clone(), + ); let mut cfg_cache: FxHashMap<&str, Vec> = FxHashMap::default(); - let idx_to_crate_id: FxHashMap = project + let idx_to_crate_id: FxHashMap = project .crates() .filter_map(|(idx, krate)| Some((idx, krate, load(&krate.root_module)?))) .map( @@ -1042,6 +1058,7 @@ fn project_json_to_crate_graph( }, *is_proc_macro, proc_macro_cwd.clone(), + crate_ws_data.clone(), ); debug!( ?crate_graph_crate_id, @@ -1092,12 +1109,19 @@ fn cargo_to_crate_graph( override_cfg: &CfgOverrides, build_scripts: &WorkspaceBuildScripts, set_test: bool, -) -> (CrateGraph, ProcMacroPaths) { + crate_ws_data: Arc, +) -> (CrateGraphBuilder, ProcMacroPaths) { let _p = tracing::info_span!("cargo_to_crate_graph").entered(); - let mut res = (CrateGraph::default(), ProcMacroPaths::default()); + let mut res = (CrateGraphBuilder::default(), ProcMacroPaths::default()); let (crate_graph, proc_macros) = &mut res; - let (public_deps, libproc_macro) = - sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); + let (public_deps, libproc_macro) = sysroot_to_crate_graph( + crate_graph, + sysroot, + rustc_cfg.clone(), + load, + // FIXME: This looks incorrect but I don't think this causes problems. + crate_ws_data.clone(), + ); let cfg_options = CfgOptions::from_iter(rustc_cfg); @@ -1163,6 +1187,7 @@ fn cargo_to_crate_graph( name: Symbol::intern(&pkg_data.name), } }, + crate_ws_data.clone(), ); if let TargetKind::Lib { .. } = kind { lib_tgt = Some((crate_id, name.clone())); @@ -1267,6 +1292,8 @@ fn cargo_to_crate_graph( } else { rustc_build_scripts }, + // FIXME: This looks incorrect but I don't think this causes problems. + crate_ws_data, ); } } @@ -1280,11 +1307,18 @@ fn detached_file_to_crate_graph( sysroot: &Sysroot, override_cfg: &CfgOverrides, set_test: bool, -) -> (CrateGraph, ProcMacroPaths) { + crate_ws_data: Arc, +) -> (CrateGraphBuilder, ProcMacroPaths) { let _p = tracing::info_span!("detached_file_to_crate_graph").entered(); - let mut crate_graph = CrateGraph::default(); - let (public_deps, _libproc_macro) = - sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); + let mut crate_graph = CrateGraphBuilder::default(); + let (public_deps, _libproc_macro) = sysroot_to_crate_graph( + &mut crate_graph, + sysroot, + rustc_cfg.clone(), + load, + // FIXME: This looks incorrect but I don't think this causes problems. + crate_ws_data.clone(), + ); let mut cfg_options = CfgOptions::from_iter(rustc_cfg); if set_test { @@ -1316,6 +1350,7 @@ fn detached_file_to_crate_graph( }, false, None, + crate_ws_data, ); public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate); @@ -1323,18 +1358,19 @@ fn detached_file_to_crate_graph( } fn handle_rustc_crates( - crate_graph: &mut CrateGraph, + crate_graph: &mut CrateGraphBuilder, proc_macros: &mut ProcMacroPaths, - pkg_to_lib_crate: &mut FxHashMap, + pkg_to_lib_crate: &mut FxHashMap, load: FileLoader<'_>, rustc_workspace: &CargoWorkspace, cargo: &CargoWorkspace, public_deps: &SysrootPublicDeps, - libproc_macro: Option, - pkg_crates: &FxHashMap>, + libproc_macro: Option, + pkg_crates: &FxHashMap>, cfg_options: &CfgOptions, override_cfg: &CfgOverrides, build_scripts: &WorkspaceBuildScripts, + crate_ws_data: Arc, ) { let mut rustc_pkg_crates = FxHashMap::default(); // The root package of the rustc-dev component is rustc_driver, so we match that @@ -1377,6 +1413,7 @@ fn handle_rustc_crates( &rustc_workspace[tgt].name, kind, CrateOrigin::Rustc { name: Symbol::intern(&rustc_workspace[pkg].name) }, + crate_ws_data.clone(), ); pkg_to_lib_crate.insert(pkg, crate_id); // Add dependencies on core / std / alloc for this crate @@ -1417,7 +1454,7 @@ fn handle_rustc_crates( // This avoids the situation where `from` depends on e.g. `arrayvec`, but // `rust_analyzer` thinks that it should use the one from the `rustc_source` // instead of the one from `crates.io` - if !crate_graph[*from].dependencies.iter().any(|d| d.name == name) { + if !crate_graph[*from].basic.dependencies.iter().any(|d| d.name == name) { add_dep(crate_graph, *from, name.clone(), to); } } @@ -1427,7 +1464,7 @@ fn handle_rustc_crates( } fn add_target_crate_root( - crate_graph: &mut CrateGraph, + crate_graph: &mut CrateGraphBuilder, proc_macros: &mut ProcMacroPaths, cargo: &CargoWorkspace, pkg: &PackageData, @@ -1437,7 +1474,8 @@ fn add_target_crate_root( cargo_name: &str, kind: TargetKind, origin: CrateOrigin, -) -> CrateId { + crate_ws_data: Arc, +) -> CrateBuilderId { let edition = pkg.edition; let potential_cfg_options = if pkg.features.is_empty() { None @@ -1474,7 +1512,7 @@ fn add_target_crate_root( Some(CrateDisplayName::from_canonical_name(cargo_name)), Some(pkg.version.to_string()), Arc::new(cfg_options), - potential_cfg_options.map(Arc::new), + potential_cfg_options, env, origin, matches!(kind, TargetKind::Lib { is_proc_macro: true }), @@ -1483,6 +1521,7 @@ fn add_target_crate_root( } else { pkg.manifest.parent().to_path_buf() }), + crate_ws_data, ); if let TargetKind::Lib { is_proc_macro: true } = kind { let proc_macro = match build_data { @@ -1503,12 +1542,12 @@ fn add_target_crate_root( #[derive(Default, Debug)] struct SysrootPublicDeps { - deps: Vec<(CrateName, CrateId, bool)>, + deps: Vec<(CrateName, CrateBuilderId, bool)>, } impl SysrootPublicDeps { /// Makes `from` depend on the public sysroot crates. - fn add_to_crate_graph(&self, crate_graph: &mut CrateGraph, from: CrateId) { + fn add_to_crate_graph(&self, crate_graph: &mut CrateGraphBuilder, from: CrateBuilderId) { for (name, krate, prelude) in &self.deps { add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude, true); } @@ -1516,10 +1555,10 @@ impl SysrootPublicDeps { } fn extend_crate_graph_with_sysroot( - crate_graph: &mut CrateGraph, - mut sysroot_crate_graph: CrateGraph, + crate_graph: &mut CrateGraphBuilder, + mut sysroot_crate_graph: CrateGraphBuilder, mut sysroot_proc_macros: ProcMacroPaths, -) -> (SysrootPublicDeps, Option) { +) -> (SysrootPublicDeps, Option) { let mut pub_deps = vec![]; let mut libproc_macro = None; let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]); @@ -1527,11 +1566,11 @@ fn extend_crate_graph_with_sysroot( // uninject `test` flag so `core` keeps working. Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone()); // patch the origin - if c.origin.is_local() { + if c.basic.origin.is_local() { let lang_crate = LangCrateOrigin::from( - c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), + c.extra.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), ); - c.origin = CrateOrigin::Lang(lang_crate); + c.basic.origin = CrateOrigin::Lang(lang_crate); match lang_crate { LangCrateOrigin::Test | LangCrateOrigin::Alloc @@ -1579,11 +1618,12 @@ fn extend_crate_graph_with_sysroot( } fn sysroot_to_crate_graph( - crate_graph: &mut CrateGraph, + crate_graph: &mut CrateGraphBuilder, sysroot: &Sysroot, rustc_cfg: Vec, load: FileLoader<'_>, -) -> (SysrootPublicDeps, Option) { + crate_ws_data: Arc, +) -> (SysrootPublicDeps, Option) { let _p = tracing::info_span!("sysroot_to_crate_graph").entered(); match sysroot.workspace() { RustLibSrcWorkspace::Workspace(cargo) => { @@ -1605,6 +1645,7 @@ fn sysroot_to_crate_graph( }, &WorkspaceBuildScripts::default(), false, + crate_ws_data, ); extend_crate_graph_with_sysroot(crate_graph, cg, pm) @@ -1627,6 +1668,7 @@ fn sysroot_to_crate_graph( ..Default::default() }, false, + crate_ws_data, ); extend_crate_graph_with_sysroot(crate_graph, cg, pm) @@ -1639,29 +1681,31 @@ fn sysroot_to_crate_graph( cfg_options.insert_atom(sym::miri.clone()); cfg_options }); - let sysroot_crates: FxHashMap = - stitched - .crates() - .filter_map(|krate| { - let file_id = load(&stitched[krate].root)?; - - let display_name = - CrateDisplayName::from_canonical_name(&stitched[krate].name); - let crate_id = crate_graph.add_crate_root( - file_id, - Edition::CURRENT_FIXME, - Some(display_name), - None, - cfg_options.clone(), - None, - Env::default(), - CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)), - false, - None, - ); - Some((krate, crate_id)) - }) - .collect(); + let sysroot_crates: FxHashMap< + crate::sysroot::stitched::RustLibSrcCrate, + CrateBuilderId, + > = stitched + .crates() + .filter_map(|krate| { + let file_id = load(&stitched[krate].root)?; + + let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name); + let crate_id = crate_graph.add_crate_root( + file_id, + Edition::CURRENT_FIXME, + Some(display_name), + None, + cfg_options.clone(), + None, + Env::default(), + CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)), + false, + None, + crate_ws_data.clone(), + ); + Some((krate, crate_id)) + }) + .collect(); for from in stitched.crates() { for &to in stitched[from].deps.iter() { @@ -1691,22 +1735,32 @@ fn sysroot_to_crate_graph( } } -fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) { - add_dep_inner(graph, from, Dependency::new(name, to)) +fn add_dep( + graph: &mut CrateGraphBuilder, + from: CrateBuilderId, + name: CrateName, + to: CrateBuilderId, +) { + add_dep_inner(graph, from, DependencyBuilder::new(name, to)) } fn add_dep_with_prelude( - graph: &mut CrateGraph, - from: CrateId, + graph: &mut CrateGraphBuilder, + from: CrateBuilderId, name: CrateName, - to: CrateId, + to: CrateBuilderId, prelude: bool, sysroot: bool, ) { - add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude, sysroot)) + add_dep_inner(graph, from, DependencyBuilder::with_prelude(name, to, prelude, sysroot)) } -fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId, prelude: bool) { +fn add_proc_macro_dep( + crate_graph: &mut CrateGraphBuilder, + from: CrateBuilderId, + to: CrateBuilderId, + prelude: bool, +) { add_dep_with_prelude( crate_graph, from, @@ -1717,7 +1771,7 @@ fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId, ); } -fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) { +fn add_dep_inner(graph: &mut CrateGraphBuilder, from: CrateBuilderId, dep: DependencyBuilder) { if let Err(err) = graph.add_dep(from, dep) { tracing::warn!("{}", err) } diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt index fae0b6fcca4dd..ae842bf704d30 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt @@ -1,20 +1,47 @@ { - 0: CrateData { - root_file_id: FileId( - 1, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "hello_world", + 0: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - canonical_name: "hello-world", }, - ), + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", + ), + ), + }, + extra: ExtraCrateData { + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -22,7 +49,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -44,45 +70,64 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", ), + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", - ), - ), }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "hello_world", + 1: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - canonical_name: "hello-world", }, - ), + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", + ), + ), + }, + extra: ExtraCrateData { + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -90,7 +135,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -112,53 +156,64 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 2: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - prelude: true, - sysroot: false, }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.1.0", ), - ), - }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "an_example", - ), - canonical_name: "an-example", - }, - ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "an_example", + ), + canonical_name: "an-example", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -166,7 +221,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -188,53 +242,64 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 3: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - prelude: true, - sysroot: false, }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.1.0", ), - ), - }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "it", - ), - canonical_name: "it", - }, - ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "it", + ), + canonical_name: "it", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -242,7 +307,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -264,53 +328,60 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 4: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2015, + dependencies: [], + origin: Library { + repo: Some( + "https://github.com/rust-lang/libc", ), - prelude: true, - sysroot: false, + name: "libc", }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.2.98", ), - ), - }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2015, - version: Some( - "0.2.98", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "libc", + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "libc", + ), + canonical_name: "libc", + }, + ), + potential_cfg_options: Some( + CfgOptions( + [ + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + "true", + ], ), - canonical_name: "libc", - }, - ), + ), + }, cfg_options: CfgOptions( [ "feature=default", @@ -318,20 +389,6 @@ "true", ], ), - potential_cfg_options: Some( - CfgOptions( - [ - "feature=align", - "feature=const-extern-fn", - "feature=default", - "feature=extra_traits", - "feature=rustc-dep-of-std", - "feature=std", - "feature=use_std", - "true", - ], - ), - ), env: Env { entries: { "CARGO": "$CARGO$", @@ -353,18 +410,11 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [], - origin: Library { - repo: Some( - "https://github.com/rust-lang/libc", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", ), - name: "libc", + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", - ), - ), }, } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt index fae0b6fcca4dd..ae842bf704d30 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt @@ -1,20 +1,47 @@ { - 0: CrateData { - root_file_id: FileId( - 1, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "hello_world", + 0: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - canonical_name: "hello-world", }, - ), + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", + ), + ), + }, + extra: ExtraCrateData { + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -22,7 +49,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -44,45 +70,64 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", ), + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", - ), - ), }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "hello_world", + 1: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - canonical_name: "hello-world", }, - ), + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", + ), + ), + }, + extra: ExtraCrateData { + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -90,7 +135,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -112,53 +156,64 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 2: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - prelude: true, - sysroot: false, }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.1.0", ), - ), - }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "an_example", - ), - canonical_name: "an-example", - }, - ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "an_example", + ), + canonical_name: "an-example", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -166,7 +221,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -188,53 +242,64 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 3: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - prelude: true, - sysroot: false, }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.1.0", ), - ), - }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "it", - ), - canonical_name: "it", - }, - ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "it", + ), + canonical_name: "it", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -242,7 +307,6 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -264,53 +328,60 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 4: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2015, + dependencies: [], + origin: Library { + repo: Some( + "https://github.com/rust-lang/libc", ), - prelude: true, - sysroot: false, + name: "libc", }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.2.98", ), - ), - }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2015, - version: Some( - "0.2.98", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "libc", + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "libc", + ), + canonical_name: "libc", + }, + ), + potential_cfg_options: Some( + CfgOptions( + [ + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + "true", + ], ), - canonical_name: "libc", - }, - ), + ), + }, cfg_options: CfgOptions( [ "feature=default", @@ -318,20 +389,6 @@ "true", ], ), - potential_cfg_options: Some( - CfgOptions( - [ - "feature=align", - "feature=const-extern-fn", - "feature=default", - "feature=extra_traits", - "feature=rustc-dep-of-std", - "feature=std", - "feature=use_std", - "true", - ], - ), - ), env: Env { entries: { "CARGO": "$CARGO$", @@ -353,18 +410,11 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [], - origin: Library { - repo: Some( - "https://github.com/rust-lang/libc", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", ), - name: "libc", + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", - ), - ), }, } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt index 566174882ddac..272cd69cb140b 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt @@ -1,27 +1,53 @@ { - 0: CrateData { - root_file_id: FileId( - 1, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "hello_world", + 0: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - canonical_name: "hello-world", }, - ), + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", + ), + ), + }, + extra: ExtraCrateData { + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -43,52 +69,70 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", ), + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", - ), - ), }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "hello_world", + 1: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - canonical_name: "hello-world", }, - ), + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", + ), + ), + }, + extra: ExtraCrateData { + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -110,60 +154,70 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 2: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - prelude: true, - sysroot: false, }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.1.0", ), - ), - }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "an_example", - ), - canonical_name: "an-example", - }, - ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "an_example", + ), + canonical_name: "an-example", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -185,60 +239,70 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 3: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "hello_world", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "libc", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Local { + repo: None, + name: Some( + "hello-world", ), - prelude: true, - sysroot: false, }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$hello-world", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.1.0", ), - ), - }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "it", - ), - canonical_name: "it", - }, - ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "it", + ), + canonical_name: "it", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", "true", ], ), - potential_cfg_options: None, env: Env { entries: { "CARGO": "$CARGO$", @@ -260,53 +324,60 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", + ), + toolchain: None, + }, + }, + 4: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2015, + dependencies: [], + origin: Library { + repo: Some( + "https://github.com/rust-lang/libc", ), - prelude: true, - sysroot: false, + name: "libc", }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "libc", + is_proc_macro: false, + proc_macro_cwd: Some( + AbsPathBuf( + "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", ), - prelude: true, - sysroot: false, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello-world", ), }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$hello-world", + extra: ExtraCrateData { + version: Some( + "0.2.98", ), - ), - }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2015, - version: Some( - "0.2.98", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "libc", + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "libc", + ), + canonical_name: "libc", + }, + ), + potential_cfg_options: Some( + CfgOptions( + [ + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + "true", + ], ), - canonical_name: "libc", - }, - ), + ), + }, cfg_options: CfgOptions( [ "feature=default", @@ -314,20 +385,6 @@ "true", ], ), - potential_cfg_options: Some( - CfgOptions( - [ - "feature=align", - "feature=const-extern-fn", - "feature=default", - "feature=extra_traits", - "feature=rustc-dep-of-std", - "feature=std", - "feature=use_std", - "true", - ], - ), - ), env: Env { entries: { "CARGO": "$CARGO$", @@ -349,18 +406,11 @@ "CARGO_PKG_VERSION_PRE": "", }, }, - dependencies: [], - origin: Library { - repo: Some( - "https://github.com/rust-lang/libc", + ws_data: CrateWorkspaceData { + data_layout: Err( + "target_data_layout not loaded", ), - name: "libc", + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: Some( - AbsPathBuf( - "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", - ), - ), }, } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 9b4be19c41c83..2b8e521f3442d 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -1,18 +1,38 @@ { - 0: CrateData { - root_file_id: FileId( - 1, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "alloc", - ), - canonical_name: "alloc", - }, - ), + 0: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2021, + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Alloc, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "alloc", + ), + canonical_name: "alloc", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -20,40 +40,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Alloc, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "core", - ), - canonical_name: "core", - }, - ), + 1: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Core, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "core", + ), + canonical_name: "core", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -61,31 +82,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Core, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_abort", - ), - canonical_name: "panic_abort", - }, - ), + 2: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_abort", + ), + canonical_name: "panic_abort", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -93,31 +124,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_unwind", - ), - canonical_name: "panic_unwind", - }, - ), + 3: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_unwind", + ), + canonical_name: "panic_unwind", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -125,31 +166,58 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "proc_macro", - ), - canonical_name: "proc_macro", - }, - ), + 4: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2021, + dependencies: [ + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + ProcMacro, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "proc_macro", + ), + canonical_name: "proc_macro", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -157,48 +225,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - ProcMacro, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 5: CrateData { - root_file_id: FileId( - 6, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "profiler_builtins", - ), - canonical_name: "profiler_builtins", - }, - ), + 5: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 6, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "profiler_builtins", + ), + canonical_name: "profiler_builtins", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -206,31 +267,106 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 6: CrateData { - root_file_id: FileId( - 7, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std", - ), - canonical_name: "std", - }, - ), + 6: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 7, + ), + edition: Edition2021, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(3), + name: CrateName( + "panic_unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(2), + name: CrateName( + "panic_abort", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(5), + name: CrateName( + "profiler_builtins", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(9), + name: CrateName( + "unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(7), + name: CrateName( + "std_detect", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Std, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std", + ), + canonical_name: "std", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -238,96 +374,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(3), - name: CrateName( - "panic_unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(2), - name: CrateName( - "panic_abort", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(5), - name: CrateName( - "profiler_builtins", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(9), - name: CrateName( - "unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(7), - name: CrateName( - "std_detect", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Std, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 7: CrateData { - root_file_id: FileId( - 8, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std_detect", - ), - canonical_name: "std_detect", - }, - ), + 7: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 8, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std_detect", + ), + canonical_name: "std_detect", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -335,31 +416,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 8: CrateData { - root_file_id: FileId( - 9, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "test", - ), - canonical_name: "test", - }, - ), + 8: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 9, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Test, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "test", + ), + canonical_name: "test", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -367,31 +458,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Test, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 9: CrateData { - root_file_id: FileId( - 10, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "unwind", - ), - canonical_name: "unwind", - }, - ), + 9: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 10, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "unwind", + ), + canonical_name: "unwind", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -399,31 +500,85 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 10: CrateData { - root_file_id: FileId( - 11, - ), - edition: Edition2018, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( + 10: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 11, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "proc_macro", + ), + prelude: false, + sysroot: true, + }, + ], + origin: Local { + repo: None, + name: Some( "hello_world", ), - canonical_name: "hello_world", }, - ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello_world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "group1_cfg=some_config", @@ -434,75 +589,85 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", ), + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: None, }, - 11: CrateData { - root_file_id: FileId( - 11, - ), - edition: Edition2018, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( + 11: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 11, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "proc_macro", + ), + prelude: false, + sysroot: true, + }, + ], + origin: Local { + repo: None, + name: Some( "other_crate", ), - canonical_name: "other_crate", }, - ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "other_crate", + ), + canonical_name: "other_crate", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "group2_cfg=fourth_config", @@ -513,59 +678,14 @@ "unrelated_cfg", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], - origin: Local { - repo: None, - name: Some( - "other_crate", + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", ), + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: None, }, } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index 4c8e66e8e968b..053e9473cf20b 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -1,18 +1,38 @@ { - 0: CrateData { - root_file_id: FileId( - 1, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "alloc", - ), - canonical_name: "alloc", - }, - ), + 0: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2021, + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Alloc, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "alloc", + ), + canonical_name: "alloc", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -20,40 +40,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Alloc, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "core", - ), - canonical_name: "core", - }, - ), + 1: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Core, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "core", + ), + canonical_name: "core", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -61,31 +82,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Core, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_abort", - ), - canonical_name: "panic_abort", - }, - ), + 2: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_abort", + ), + canonical_name: "panic_abort", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -93,31 +124,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_unwind", - ), - canonical_name: "panic_unwind", - }, - ), + 3: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_unwind", + ), + canonical_name: "panic_unwind", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -125,31 +166,58 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "proc_macro", - ), - canonical_name: "proc_macro", - }, - ), + 4: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2021, + dependencies: [ + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + ProcMacro, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "proc_macro", + ), + canonical_name: "proc_macro", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -157,48 +225,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - ProcMacro, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 5: CrateData { - root_file_id: FileId( - 6, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "profiler_builtins", - ), - canonical_name: "profiler_builtins", - }, - ), + 5: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 6, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "profiler_builtins", + ), + canonical_name: "profiler_builtins", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -206,31 +267,106 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 6: CrateData { - root_file_id: FileId( - 7, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std", - ), - canonical_name: "std", - }, - ), + 6: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 7, + ), + edition: Edition2021, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(3), + name: CrateName( + "panic_unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(2), + name: CrateName( + "panic_abort", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(5), + name: CrateName( + "profiler_builtins", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(9), + name: CrateName( + "unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(7), + name: CrateName( + "std_detect", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Std, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std", + ), + canonical_name: "std", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -238,96 +374,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(3), - name: CrateName( - "panic_unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(2), - name: CrateName( - "panic_abort", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(5), - name: CrateName( - "profiler_builtins", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(9), - name: CrateName( - "unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(7), - name: CrateName( - "std_detect", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Std, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 7: CrateData { - root_file_id: FileId( - 8, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std_detect", - ), - canonical_name: "std_detect", - }, - ), + 7: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 8, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std_detect", + ), + canonical_name: "std_detect", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -335,31 +416,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 8: CrateData { - root_file_id: FileId( - 9, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "test", - ), - canonical_name: "test", - }, - ), + 8: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 9, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Test, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "test", + ), + canonical_name: "test", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -367,31 +458,41 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Test, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 9: CrateData { - root_file_id: FileId( - 10, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "unwind", - ), - canonical_name: "unwind", - }, - ), + 9: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 10, + ), + edition: Edition2021, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "unwind", + ), + canonical_name: "unwind", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "debug_assertions", @@ -399,31 +500,85 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", + ), + toolchain: None, + }, }, - 10: CrateData { - root_file_id: FileId( - 11, - ), - edition: Edition2018, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( + 10: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 11, + ), + edition: Edition2018, + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "proc_macro", + ), + prelude: false, + sysroot: true, + }, + ], + origin: Local { + repo: None, + name: Some( "hello_world", ), - canonical_name: "hello_world", }, - ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello_world", + }, + ), + potential_cfg_options: None, + }, cfg_options: CfgOptions( [ "rust_analyzer", @@ -431,59 +586,14 @@ "true", ], ), - potential_cfg_options: None, env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], - origin: Local { - repo: None, - name: Some( - "hello_world", + ws_data: CrateWorkspaceData { + data_layout: Err( + "test has no data layout", ), + toolchain: None, }, - is_proc_macro: false, - proc_macro_cwd: None, }, } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index f114a4454e002..a6aa0376b0c81 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -8,7 +8,7 @@ use std::{ops::Not as _, time::Instant}; use crossbeam_channel::{unbounded, Receiver, Sender}; use hir::ChangeWithProcMacros; use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId}; -use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabase}; +use ide_db::base_db::{Crate, ProcMacroPaths, SourceDatabase}; use itertools::Itertools; use load_cargo::SourceRootConfig; use lsp_types::{SemanticTokens, Url}; @@ -158,7 +158,7 @@ pub(crate) struct GlobalState { // op queues pub(crate) fetch_workspaces_queue: OpQueue, pub(crate) fetch_build_data_queue: OpQueue<(), FetchBuildDataResponse>, - pub(crate) fetch_proc_macros_queue: OpQueue, bool>, + pub(crate) fetch_proc_macros_queue: OpQueue<(ChangeWithProcMacros, Vec), bool>, pub(crate) prime_caches_queue: OpQueue, pub(crate) discover_workspace_queue: OpQueue, @@ -714,7 +714,7 @@ impl GlobalStateSnapshot { self.vfs_read().file_path(file_id).clone() } - pub(crate) fn target_spec_for_crate(&self, crate_id: CrateId) -> Option { + pub(crate) fn target_spec_for_crate(&self, crate_id: Crate) -> Option { let file_id = self.analysis.crate_root(crate_id).ok()?; let path = self.vfs_read().file_path(file_id).clone(); let path = path.as_path()?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index b47a126424aa0..7244fbc4aaac9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -10,7 +10,7 @@ use std::{ use always_assert::always; use crossbeam_channel::{select, Receiver}; -use ide_db::base_db::{RootQueryDb, SourceDatabase, VfsPath}; +use ide_db::base_db::{SourceDatabase, VfsPath}; use lsp_server::{Connection, Notification, Request}; use lsp_types::{notification::Notification as _, TextDocumentIdentifier}; use stdx::thread::ThreadIntent; @@ -504,8 +504,10 @@ impl GlobalState { if !self.fetch_workspaces_queue.op_in_progress() { if let Some((cause, ())) = self.fetch_build_data_queue.should_start_op() { self.fetch_build_data(cause); - } else if let Some((cause, paths)) = self.fetch_proc_macros_queue.should_start_op() { - self.fetch_proc_macros(cause, paths); + } else if let Some((cause, (change, paths))) = + self.fetch_proc_macros_queue.should_start_op() + { + self.fetch_proc_macros(cause, change, paths); } } @@ -804,9 +806,10 @@ impl GlobalState { let (state, msg) = match progress { ProcMacroProgress::Begin => (Some(Progress::Begin), None), ProcMacroProgress::Report(msg) => (Some(Progress::Report), Some(msg)), - ProcMacroProgress::End(proc_macro_load_result) => { + ProcMacroProgress::End(change) => { self.fetch_proc_macros_queue.op_completed(true); - self.set_proc_macros(proc_macro_load_result); + self.analysis_host.apply_change(change); + self.finish_loading_crate_graph(); (Some(Progress::End), None) } }; @@ -909,16 +912,15 @@ impl GlobalState { }); } QueuedTask::CheckProcMacroSources(modified_rust_files) => { - let crate_graph = self.analysis_host.raw_database().crate_graph(); let analysis = AssertUnwindSafe(self.snapshot().analysis); self.task_pool.handle.spawn_with_sender(stdx::thread::ThreadIntent::Worker, { move |sender| { if modified_rust_files.into_iter().any(|file_id| { // FIXME: Check whether these files could be build script related match analysis.crates_for(file_id) { - Ok(crates) => { - crates.iter().any(|&krate| crate_graph[krate].is_proc_macro) - } + Ok(crates) => crates.iter().any(|&krate| { + analysis.is_proc_macro_crate(krate).is_ok_and(|it| it) + }), _ => false, } }) { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 1a60fa06c9eb8..d6a99fbe55a55 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -15,10 +15,9 @@ // FIXME: This is a mess that needs some untangling work use std::{iter, mem}; -use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder}; -use ide::CrateId; +use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacrosBuilder}; use ide_db::{ - base_db::{salsa::Durability, CrateGraph, CrateWorkspaceData, ProcMacroPaths}, + base_db::{salsa::Durability, CrateGraphBuilder, ProcMacroPaths, RootQueryDb}, FxHashMap, }; use itertools::Itertools; @@ -60,7 +59,7 @@ pub(crate) enum BuildDataProgress { pub(crate) enum ProcMacroProgress { Begin, Report(String), - End(ProcMacros), + End(ChangeWithProcMacros), } impl GlobalState { @@ -387,7 +386,12 @@ impl GlobalState { }); } - pub(crate) fn fetch_proc_macros(&mut self, cause: Cause, paths: Vec) { + pub(crate) fn fetch_proc_macros( + &mut self, + cause: Cause, + mut change: ChangeWithProcMacros, + paths: Vec, + ) { info!(%cause, "will load proc macros"); let ignored_proc_macros = self.config.ignored_proc_macros(None).clone(); let proc_macro_clients = self.proc_macro_clients.clone(); @@ -440,16 +444,11 @@ impl GlobalState { .for_each(|(krate, res)| builder.insert(krate, res)); } - sender.send(Task::LoadProcMacros(ProcMacroProgress::End(builder.build()))).unwrap(); + change.set_proc_macros(builder); + sender.send(Task::LoadProcMacros(ProcMacroProgress::End(change))).unwrap(); }); } - pub(crate) fn set_proc_macros(&mut self, proc_macros: ProcMacros) { - let mut change = ChangeWithProcMacros::new(); - change.set_proc_macros(proc_macros); - self.analysis_host.apply_change(change); - } - pub(crate) fn switch_workspaces(&mut self, cause: Cause) { let _p = tracing::info_span!("GlobalState::switch_workspaces").entered(); tracing::info!(%cause, "will switch workspaces"); @@ -528,6 +527,14 @@ impl GlobalState { if self.config.run_build_scripts(None) { self.build_deps_changed = false; self.fetch_build_data_queue.request_op("workspace updated".to_owned(), ()); + + let initial_build = self.analysis_host.raw_database().all_crates().is_empty(); + if !initial_build { + // `switch_workspaces()` will be called again when build scripts already run, which should + // take a short time. If we update the workspace now we will invalidate proc macros and cfgs, + // and then when build scripts complete we will invalidate them again. + return; + } } } @@ -711,7 +718,7 @@ impl GlobalState { }) .collect(); - let (crate_graph, proc_macro_paths, ws_data) = { + let (crate_graph, proc_macro_paths) = { // Create crate graph from all the workspaces let vfs = &self.vfs.read().0; let load = |path: &AbsPath| { @@ -725,24 +732,35 @@ impl GlobalState { ws_to_crate_graph(&self.workspaces, self.config.extra_env(None), load) }; let mut change = ChangeWithProcMacros::new(); - if self.config.expand_proc_macros() { - change.set_proc_macros( - crate_graph - .iter() - .map(|id| (id, Err(("proc-macro has not been built yet".to_owned(), true)))) - .collect(), - ); - self.fetch_proc_macros_queue.request_op(cause, proc_macro_paths); - } else { - change.set_proc_macros( - crate_graph - .iter() - .map(|id| (id, Err(("proc-macro expansion is disabled".to_owned(), false)))) - .collect(), - ); + let initial_build = self.analysis_host.raw_database().all_crates().is_empty(); + if initial_build || !self.config.expand_proc_macros() { + if self.config.expand_proc_macros() { + change.set_proc_macros( + crate_graph + .iter() + .map(|id| (id, Err(("proc-macro has not been built yet".to_owned(), true)))) + .collect(), + ); + } else { + change.set_proc_macros( + crate_graph + .iter() + .map(|id| (id, Err(("proc-macro expansion is disabled".to_owned(), false)))) + .collect(), + ); + } + + change.set_crate_graph(crate_graph); + self.analysis_host.apply_change(change); + + self.finish_loading_crate_graph(); + return; } - change.set_crate_graph(crate_graph, ws_data); - self.analysis_host.apply_change(change); + change.set_crate_graph(crate_graph); + self.fetch_proc_macros_queue.request_op(cause, (change, proc_macro_paths)); + } + + pub(crate) fn finish_loading_crate_graph(&mut self) { self.report_progress( "Building CrateGraph", crate::lsp::utils::Progress::End, @@ -883,26 +901,19 @@ pub fn ws_to_crate_graph( workspaces: &[ProjectWorkspace], extra_env: &FxHashMap, mut load: impl FnMut(&AbsPath) -> Option, -) -> (CrateGraph, Vec, FxHashMap>) { - let mut crate_graph = CrateGraph::default(); +) -> (CrateGraphBuilder, Vec) { + let mut crate_graph = CrateGraphBuilder::default(); let mut proc_macro_paths = Vec::default(); - let mut ws_data = FxHashMap::default(); for ws in workspaces { let (other, mut crate_proc_macros) = ws.to_crate_graph(&mut load, extra_env); - let ProjectWorkspace { toolchain, target_layout, .. } = ws; - - let mapping = crate_graph.extend(other, &mut crate_proc_macros); - // Populate the side tables for the newly merged crates - ws_data.extend(mapping.values().copied().zip(iter::repeat(Arc::new(CrateWorkspaceData { - toolchain: toolchain.clone(), - data_layout: target_layout.clone(), - })))); + + crate_graph.extend(other, &mut crate_proc_macros); proc_macro_paths.push(crate_proc_macros); } crate_graph.shrink_to_fit(); proc_macro_paths.shrink_to_fit(); - (crate_graph, proc_macro_paths, ws_data) + (crate_graph, proc_macro_paths) } pub(crate) fn should_refresh_for_change( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index b28567fe09b58..abb70ebe36f48 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -4,7 +4,7 @@ use std::mem; use cfg::{CfgAtom, CfgExpr}; use hir::sym; -use ide::{Cancellable, CrateId, FileId, RunnableKind, TestId}; +use ide::{Cancellable, Crate, FileId, RunnableKind, TestId}; use project_model::project_json::Runnable; use project_model::{CargoFeatures, ManifestPath, TargetKind}; use rustc_hash::FxHashSet; @@ -54,7 +54,7 @@ pub(crate) struct CargoTargetSpec { pub(crate) package: String, pub(crate) target: String, pub(crate) target_kind: TargetKind, - pub(crate) crate_id: CrateId, + pub(crate) crate_id: Crate, pub(crate) required_features: Vec, pub(crate) features: FxHashSet, pub(crate) sysroot_root: Option, diff --git a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml index 95f4cb9d67e25..2547a02a2916c 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml +++ b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml @@ -18,6 +18,7 @@ rustc-hash.workspace = true span.workspace = true stdx.workspace = true intern.workspace = true +triomphe.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 4b5c2ff4cf7d2..51d6179a62bad 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -1,10 +1,10 @@ //! A set of high-level utility fixture methods to use in tests. -use std::{iter, mem, str::FromStr, sync}; +use std::{mem, str::FromStr, sync}; use base_db::{ - CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, CrateWorkspaceData, Dependency, - Env, FileChange, FileSet, LangCrateOrigin, RootQueryDb, SourceDatabase, SourceRoot, Version, - VfsPath, + Crate, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData, + DependencyBuilder, Env, FileChange, FileSet, LangCrateOrigin, SourceDatabase, SourceRoot, + Version, VfsPath, }; use cfg::CfgOptions; use hir_expand::{ @@ -26,6 +26,7 @@ use test_utils::{ extract_range_or_offset, Fixture, FixtureWithProjectMeta, RangeOrOffset, CURSOR_MARKER, ESCAPED_CURSOR_MARKER, }; +use triomphe::Arc; pub const WORKSPACE: base_db::SourceRootId = base_db::SourceRootId(0); @@ -101,14 +102,8 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, file_id, range_or_offset) } - fn test_crate(&self) -> CrateId { - let crate_graph = RootQueryDb::crate_graph(self); - let mut it = crate_graph.iter(); - let mut res = it.next().unwrap(); - while crate_graph[res].origin.is_lang() { - res = it.next().unwrap(); - } - res + fn test_crate(&self) -> Crate { + self.all_crates().iter().copied().find(|&krate| !krate.data(self).origin.is_lang()).unwrap() } } @@ -146,7 +141,7 @@ impl ChangeFixture { let mut source_change = FileChange::new(); let mut files = Vec::new(); - let mut crate_graph = CrateGraph::default(); + let mut crate_graph = CrateGraphBuilder::default(); let mut crates = FxHashMap::default(); let mut crate_deps = Vec::new(); let mut default_crate_root: Option = None; @@ -163,6 +158,9 @@ impl ChangeFixture { let mut file_position = None; + let crate_ws_data = + Arc::new(CrateWorkspaceData { data_layout: target_data_layout, toolchain }); + for entry in fixture { let mut range_or_offset = None; let text = if entry.text.contains(CURSOR_MARKER) { @@ -210,11 +208,12 @@ impl ChangeFixture { Some(crate_name.clone().into()), version, From::from(meta.cfg.clone()), - Some(From::from(meta.cfg)), + Some(meta.cfg), meta.env, origin, false, None, + crate_ws_data.clone(), ); let prev = crates.insert(crate_name.clone(), crate_id); assert!(prev.is_none(), "multiple crates with same name: {crate_name}"); @@ -249,19 +248,23 @@ impl ChangeFixture { Some(CrateName::new("ra_test_fixture").unwrap().into()), None, From::from(default_cfg.clone()), - Some(From::from(default_cfg)), + Some(default_cfg), default_env, CrateOrigin::Local { repo: None, name: None }, false, None, + crate_ws_data.clone(), ); } else { for (from, to, prelude) in crate_deps { let from_id = crates[&from]; let to_id = crates[&to]; - let sysroot = crate_graph[to_id].origin.is_lang(); + let sysroot = crate_graph[to_id].basic.origin.is_lang(); crate_graph - .add_dep(from_id, Dependency::with_prelude(to.clone(), to_id, prelude, sysroot)) + .add_dep( + from_id, + DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot), + ) .unwrap(); } } @@ -276,7 +279,7 @@ impl ChangeFixture { source_change.change_file(core_file, Some(mini_core.source_code())); - let all_crates = crate_graph.crates_in_topological_order(); + let all_crates = crate_graph.iter().collect::>(); let core_crate = crate_graph.add_crate_root( core_file, @@ -292,13 +295,14 @@ impl ChangeFixture { CrateOrigin::Lang(LangCrateOrigin::Core), false, None, + crate_ws_data.clone(), ); for krate in all_crates { crate_graph .add_dep( krate, - Dependency::with_prelude( + DependencyBuilder::with_prelude( CrateName::new("core").unwrap(), core_crate, true, @@ -324,7 +328,7 @@ impl ChangeFixture { source_change.change_file(proc_lib_file, Some(source)); - let all_crates = crate_graph.crates_in_topological_order(); + let all_crates = crate_graph.iter().collect::>(); let proc_macros_crate = crate_graph.add_crate_root( proc_lib_file, @@ -340,6 +344,7 @@ impl ChangeFixture { CrateOrigin::Local { repo: None, name: None }, true, None, + crate_ws_data, ); proc_macros.insert(proc_macros_crate, Ok(proc_macro)); @@ -347,7 +352,10 @@ impl ChangeFixture { crate_graph .add_dep( krate, - Dependency::new(CrateName::new("proc_macros").unwrap(), proc_macros_crate), + DependencyBuilder::new( + CrateName::new("proc_macros").unwrap(), + proc_macros_crate, + ), ) .unwrap(); } @@ -359,19 +367,9 @@ impl ChangeFixture { }; roots.push(root); - let mut change = - ChangeWithProcMacros { source_change, proc_macros: Some(proc_macros.build()) }; + let mut change = ChangeWithProcMacros { source_change, proc_macros: Some(proc_macros) }; change.source_change.set_roots(roots); - change.source_change.set_ws_data( - crate_graph - .iter() - .zip(iter::repeat(From::from(CrateWorkspaceData { - data_layout: target_data_layout, - toolchain, - }))) - .collect(), - ); change.source_change.set_crate_graph(crate_graph); ChangeFixture { file_position, files, change } @@ -654,6 +652,10 @@ impl ProcMacroExpander for IdentityProcMacroExpander { ) -> Result { Ok(subtree.clone()) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } // Expands to a macro_rules! macro, for issue #18089. @@ -685,6 +687,10 @@ impl ProcMacroExpander for Issue18089ProcMacroExpander { #subtree }) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } // Pastes the attribute input as its output @@ -705,6 +711,10 @@ impl ProcMacroExpander for AttributeInputReplaceProcMacroExpander { .cloned() .ok_or_else(|| ProcMacroExpansionError::Panic("Expected attribute input".into())) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } #[derive(Debug)] @@ -736,6 +746,10 @@ impl ProcMacroExpander for Issue18840ProcMacroExpander { top_subtree_delimiter_mut.close = def_site; Ok(result) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } #[derive(Debug)] @@ -767,6 +781,10 @@ impl ProcMacroExpander for MirrorProcMacroExpander { traverse(&mut builder, input.iter()); Ok(builder.build()) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } // Replaces every literal with an empty string literal and every identifier with its first letter, @@ -807,6 +825,10 @@ impl ProcMacroExpander for ShortenProcMacroExpander { } } } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } // Reads ident type within string quotes, for issue #17479. @@ -832,6 +854,10 @@ impl ProcMacroExpander for Issue17479ProcMacroExpander { #symbol() }) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } // Reads ident type within string quotes, for issue #17479. @@ -883,6 +909,10 @@ impl ProcMacroExpander for Issue18898ProcMacroExpander { } }) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } // Reads ident type within string quotes, for issue #17479. @@ -910,4 +940,8 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander { } Ok(subtree.clone()) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::() + } } From f335d00263fd429d12fd844134df54657357de56 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 8 Mar 2025 20:38:47 +0200 Subject: [PATCH 014/260] Lower Return Type Notation (`Type::method(..): Send`) We do it the way rustc does it, by only marking segments with it, and not the whole path. This will allow extending where it is allowed in the future. --- .../crates/hir-def/src/generics.rs | 2 +- .../rust-analyzer/crates/hir-def/src/path.rs | 29 +++- .../crates/hir-def/src/path/lower.rs | 26 +++- .../crates/hir-ty/src/display.rs | 131 +++++++++--------- .../crates/hir-ty/src/lower/path.rs | 17 ++- 5 files changed, 125 insertions(+), 80 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs index 6f1650adeb6fe..682f21ab3b4c0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs @@ -872,7 +872,7 @@ fn copy_generic_args( args, has_self_type: generic_args.has_self_type, bindings, - desugared_from_fn: generic_args.desugared_from_fn, + parenthesized: generic_args.parenthesized, } }) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path.rs b/src/tools/rust-analyzer/crates/hir-def/src/path.rs index 713e7389736a0..8f170fb983acc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path.rs @@ -79,6 +79,19 @@ thin_vec_with_header_struct! { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum GenericArgsParentheses { + No, + /// Bounds of the form `Type::method(..): Send` or `impl Trait`, + /// aka. Return Type Notation or RTN. + ReturnTypeNotation, + /// `Fn`-family parenthesized traits, e.g. `impl Fn(u32) -> String`. + /// + /// This is desugared into one generic argument containing a tuple of all arguments, + /// and an associated type binding for `Output` for the return type. + ParenSugar, +} + /// Generic arguments to a path segment (e.g. the `i32` in `Option`). This /// also includes bindings of associated types, like in `Iterator`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -92,9 +105,8 @@ pub struct GenericArgs { pub has_self_type: bool, /// Associated type bindings like in `Iterator`. pub bindings: Box<[AssociatedTypeBinding]>, - /// Whether these generic args were desugared from `Trait(Arg) -> Output` - /// parenthesis notation typically used for the `Fn` traits. - pub desugared_from_fn: bool, + /// Whether these generic args were written with parentheses and how. + pub parenthesized: GenericArgsParentheses, } /// An associated type binding like in `Iterator`. @@ -326,7 +338,16 @@ impl GenericArgs { args: Box::default(), has_self_type: false, bindings: Box::default(), - desugared_from_fn: false, + parenthesized: GenericArgsParentheses::No, + } + } + + pub(crate) fn return_type_notation() -> GenericArgs { + GenericArgs { + args: Box::default(), + has_self_type: false, + bindings: Box::default(), + parenthesized: GenericArgsParentheses::ReturnTypeNotation, } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs index 7a6d6973298b7..c6ea3c4d71054 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs @@ -13,7 +13,10 @@ use stdx::thin_vec::EmptyOptimizedThinVec; use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds}; use crate::{ - path::{AssociatedTypeBinding, GenericArg, GenericArgs, ModPath, Path, PathKind}, + path::{ + AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, ModPath, Path, + PathKind, + }, type_ref::{LifetimeRef, TypeBound, TypeRef}, }; @@ -73,6 +76,9 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option< segment.parenthesized_arg_list(), segment.ret_type(), ) + }) + .or_else(|| { + segment.return_type_syntax().map(|_| GenericArgs::return_type_notation()) }); if args.is_some() { generic_args.resize(segments.len(), None); @@ -126,7 +132,7 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option< has_self_type: true, bindings: it.bindings.clone(), - desugared_from_fn: it.desugared_from_fn, + parenthesized: it.parenthesized, }, None => GenericArgs { args: Box::new([self_type]), @@ -281,7 +287,12 @@ pub(super) fn lower_generic_args( let name = name_ref.as_name(); let args = assoc_type_arg .generic_arg_list() - .and_then(|args| lower_generic_args(lower_ctx, args)); + .and_then(|args| lower_generic_args(lower_ctx, args)) + .or_else(|| { + assoc_type_arg + .return_type_syntax() + .map(|_| GenericArgs::return_type_notation()) + }); let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it)); let type_ref = type_ref @@ -315,7 +326,7 @@ pub(super) fn lower_generic_args( args: args.into_boxed_slice(), has_self_type: false, bindings: bindings.into_boxed_slice(), - desugared_from_fn: false, + parenthesized: GenericArgsParentheses::No, }) } @@ -353,5 +364,10 @@ fn lower_generic_args_from_fn_path( bounds: Box::default(), }]) }; - Some(GenericArgs { args, has_self_type: false, bindings, desugared_from_fn: true }) + Some(GenericArgs { + args, + has_self_type: false, + bindings, + parenthesized: GenericArgsParentheses::ParenSugar, + }) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 2ae7e746ba203..db305e98da434 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -2303,77 +2303,82 @@ impl HirDisplayWithTypesMap for Path { if let Some(generic_args) = segment.args_and_bindings { // We should be in type context, so format as `Foo` instead of `Foo::`. // Do we actually format expressions? - if generic_args.desugared_from_fn { - // First argument will be a tuple, which already includes the parentheses. - // If the tuple only contains 1 item, write it manually to avoid the trailing `,`. - let tuple = match generic_args.args[0] { - hir_def::path::GenericArg::Type(ty) => match &types_map[ty] { - TypeRef::Tuple(it) => Some(it), + match generic_args.parenthesized { + hir_def::path::GenericArgsParentheses::ReturnTypeNotation => { + write!(f, "(..)")?; + } + hir_def::path::GenericArgsParentheses::ParenSugar => { + // First argument will be a tuple, which already includes the parentheses. + // If the tuple only contains 1 item, write it manually to avoid the trailing `,`. + let tuple = match generic_args.args[0] { + hir_def::path::GenericArg::Type(ty) => match &types_map[ty] { + TypeRef::Tuple(it) => Some(it), + _ => None, + }, _ => None, - }, - _ => None, - }; - if let Some(v) = tuple { - if v.len() == 1 { - write!(f, "(")?; - v[0].hir_fmt(f, types_map)?; - write!(f, ")")?; - } else { - generic_args.args[0].hir_fmt(f, types_map)?; + }; + if let Some(v) = tuple { + if v.len() == 1 { + write!(f, "(")?; + v[0].hir_fmt(f, types_map)?; + write!(f, ")")?; + } else { + generic_args.args[0].hir_fmt(f, types_map)?; + } } - } - if let Some(ret) = generic_args.bindings[0].type_ref { - if !matches!(&types_map[ret], TypeRef::Tuple(v) if v.is_empty()) { - write!(f, " -> ")?; - ret.hir_fmt(f, types_map)?; + if let Some(ret) = generic_args.bindings[0].type_ref { + if !matches!(&types_map[ret], TypeRef::Tuple(v) if v.is_empty()) { + write!(f, " -> ")?; + ret.hir_fmt(f, types_map)?; + } } } - return Ok(()); - } - - let mut first = true; - // Skip the `Self` bound if exists. It's handled outside the loop. - for arg in &generic_args.args[generic_args.has_self_type as usize..] { - if first { - first = false; - write!(f, "<")?; - } else { - write!(f, ", ")?; - } - arg.hir_fmt(f, types_map)?; - } - for binding in generic_args.bindings.iter() { - if first { - first = false; - write!(f, "<")?; - } else { - write!(f, ", ")?; - } - write!(f, "{}", binding.name.display(f.db.upcast(), f.edition()))?; - match &binding.type_ref { - Some(ty) => { - write!(f, " = ")?; - ty.hir_fmt(f, types_map)? + hir_def::path::GenericArgsParentheses::No => { + let mut first = true; + // Skip the `Self` bound if exists. It's handled outside the loop. + for arg in &generic_args.args[generic_args.has_self_type as usize..] { + if first { + first = false; + write!(f, "<")?; + } else { + write!(f, ", ")?; + } + arg.hir_fmt(f, types_map)?; } - None => { - write!(f, ": ")?; - f.write_joined( - binding.bounds.iter().map(TypesMapAdapter::wrap(types_map)), - " + ", - )?; + for binding in generic_args.bindings.iter() { + if first { + first = false; + write!(f, "<")?; + } else { + write!(f, ", ")?; + } + write!(f, "{}", binding.name.display(f.db.upcast(), f.edition()))?; + match &binding.type_ref { + Some(ty) => { + write!(f, " = ")?; + ty.hir_fmt(f, types_map)? + } + None => { + write!(f, ": ")?; + f.write_joined( + binding.bounds.iter().map(TypesMapAdapter::wrap(types_map)), + " + ", + )?; + } + } } - } - } - // There may be no generic arguments to print, in case of a trait having only a - // single `Self` bound which is converted to `::Assoc`. - if !first { - write!(f, ">")?; - } + // There may be no generic arguments to print, in case of a trait having only a + // single `Self` bound which is converted to `::Assoc`. + if !first { + write!(f, ">")?; + } - // Current position: `|` - if generic_args.has_self_type { - write!(f, ">")?; + // Current position: `|` + if generic_args.has_self_type { + write!(f, ">")?; + } + } } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index a165932ddcc8c..58b143e84e0cf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -8,7 +8,7 @@ use hir_def::{ data::TraitFlags, expr_store::HygieneId, generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, - path::{GenericArg, GenericArgs, Path, PathSegment, PathSegments}, + path::{GenericArg, GenericArgs, GenericArgsParentheses, Path, PathSegment, PathSegments}, resolver::{ResolveValueResult, TypeNs, ValueNs}, type_ref::{TypeBound, TypeRef, TypesMap}, GenericDefId, GenericParamId, ItemContainerId, Lookup, TraitId, @@ -138,12 +138,15 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { fn prohibit_parenthesized_generic_args(&mut self) -> bool { if let Some(generic_args) = self.current_or_prev_segment.args_and_bindings { - if generic_args.desugared_from_fn { - let segment = self.current_segment_u32(); - self.on_diagnostic( - PathLoweringDiagnostic::ParenthesizedGenericArgsWithoutFnTrait { segment }, - ); - return true; + match generic_args.parenthesized { + GenericArgsParentheses::No => {} + GenericArgsParentheses::ReturnTypeNotation | GenericArgsParentheses::ParenSugar => { + let segment = self.current_segment_u32(); + self.on_diagnostic( + PathLoweringDiagnostic::ParenthesizedGenericArgsWithoutFnTrait { segment }, + ); + return true; + } } } false From f31ddcf52406c28dad8c35c7d5bbbe496e9cf2fb Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 8 Mar 2025 20:56:54 +0200 Subject: [PATCH 015/260] Emit an error when RTN is used in an incorrect place We miss one place: associated type bindings aka. `impl Trait`, but we also miss it for Fn-style parenthesizes error so I left it out for now. --- .../crates/hir-ty/src/lower/path.rs | 10 +++- .../crates/hir/src/diagnostics.rs | 18 +++++++ .../ide-diagnostics/src/handlers/bad_rtn.rs | 52 +++++++++++++++++++ .../crates/ide-diagnostics/src/lib.rs | 2 + 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/bad_rtn.rs diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index 58b143e84e0cf..e237009ebaf65 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -607,8 +607,14 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { ) -> Substitution { let prohibit_parens = match def { GenericDefId::TraitId(trait_) => { - let trait_data = self.ctx.db.trait_data(trait_); - !trait_data.flags.contains(TraitFlags::RUSTC_PAREN_SUGAR) + // RTN is prohibited anyways if we got here. + let is_rtn = + self.current_or_prev_segment.args_and_bindings.is_some_and(|generics| { + generics.parenthesized == GenericArgsParentheses::ReturnTypeNotation + }); + let is_fn_trait = + !self.ctx.db.trait_data(trait_).flags.contains(TraitFlags::RUSTC_PAREN_SUGAR); + is_rtn || is_fn_trait } _ => true, }; diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs index 1ed0daa375630..b383fa625e3bc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs @@ -113,6 +113,7 @@ diagnostics![ UnusedVariable, GenericArgsProhibited, ParenthesizedGenericArgsWithoutFnTrait, + BadRtn, ]; #[derive(Debug)] @@ -420,6 +421,11 @@ pub struct ParenthesizedGenericArgsWithoutFnTrait { pub args: InFile>, } +#[derive(Debug)] +pub struct BadRtn { + pub rtn: InFile>, +} + impl AnyDiagnostic { pub(crate) fn body_validation_diagnostic( db: &dyn HirDatabase, @@ -712,6 +718,12 @@ impl AnyDiagnostic { Some(match *diag { PathLoweringDiagnostic::GenericArgsProhibited { segment, reason } => { let segment = hir_segment_to_ast_segment(&path.value, segment)?; + + if let Some(rtn) = segment.return_type_syntax() { + // RTN errors are emitted as `GenericArgsProhibited` or `ParenthesizedGenericArgsWithoutFnTrait`. + return Some(BadRtn { rtn: path.with_value(AstPtr::new(&rtn)) }.into()); + } + let args = if let Some(generics) = segment.generic_arg_list() { AstPtr::new(&generics).wrap_left() } else { @@ -722,6 +734,12 @@ impl AnyDiagnostic { } PathLoweringDiagnostic::ParenthesizedGenericArgsWithoutFnTrait { segment } => { let segment = hir_segment_to_ast_segment(&path.value, segment)?; + + if let Some(rtn) = segment.return_type_syntax() { + // RTN errors are emitted as `GenericArgsProhibited` or `ParenthesizedGenericArgsWithoutFnTrait`. + return Some(BadRtn { rtn: path.with_value(AstPtr::new(&rtn)) }.into()); + } + let args = AstPtr::new(&segment.parenthesized_arg_list()?); let args = path.with_value(args); ParenthesizedGenericArgsWithoutFnTrait { args }.into() diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/bad_rtn.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/bad_rtn.rs new file mode 100644 index 0000000000000..9ed85f9f208e8 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/bad_rtn.rs @@ -0,0 +1,52 @@ +use ide_db::Severity; + +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; + +// Diagnostic: bad-rtn +// +// This diagnostic is shown when a RTN (Return Type Notation, `Type::method(..): Send`) is written in an improper place. +pub(crate) fn bad_rtn(ctx: &DiagnosticsContext<'_>, d: &hir::BadRtn) -> Diagnostic { + Diagnostic::new_with_syntax_node_ptr( + ctx, + DiagnosticCode::Ra("bad-rtn", Severity::Error), + "return type notation not allowed in this position yet", + d.rtn.map(Into::into), + ) +} + +#[cfg(test)] +mod tests { + use crate::tests::check_diagnostics; + + #[test] + fn fn_traits_also_emit() { + check_diagnostics( + r#" +//- minicore: fn +fn foo< + A: Fn(..), + // ^^^^ error: return type notation not allowed in this position yet +>() {} + "#, + ); + } + + #[test] + fn bad_rtn() { + check_diagnostics( + r#" +mod module { + pub struct Type; +} +trait Trait {} + +fn foo() +where + module(..)::Type: Trait + // ^^^^ error: return type notation not allowed in this position yet +{ +} + "#, + ); + } +} diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index f4ced736b3df8..d1d852faf00e7 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -25,6 +25,7 @@ mod handlers { pub(crate) mod await_outside_of_async; + pub(crate) mod bad_rtn; pub(crate) mod break_outside_of_loop; pub(crate) mod expected_function; pub(crate) mod generic_args_prohibited; @@ -493,6 +494,7 @@ pub fn semantic_diagnostics( AnyDiagnostic::ParenthesizedGenericArgsWithoutFnTrait(d) => { handlers::parenthesized_generic_args_without_fn_trait::parenthesized_generic_args_without_fn_trait(&ctx, &d) } + AnyDiagnostic::BadRtn(d) => handlers::bad_rtn::bad_rtn(&ctx, &d), }; res.push(d) } From 7bcf2506f7d5560d81cc3998953b1cd0f8019efd Mon Sep 17 00:00:00 2001 From: jnyfah Date: Thu, 13 Mar 2025 09:04:47 +0100 Subject: [PATCH 016/260] insert braces for closure --- .../crates/ide/src/inlay_hints/bind_pat.rs | 10 +++++-- .../crates/ide/src/inlay_hints/closure_ret.rs | 27 ++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index aab8a3f873994..60abb7a44e0ce 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -1140,12 +1140,11 @@ fn test() { #[test] fn no_edit_for_closure_return_without_body_block() { - // We can lift this limitation; see FIXME in closure_ret module. let config = InlayHintsConfig { closure_return_type_hints: ClosureReturnTypeHints::Always, ..TEST_CONFIG }; - check_no_edit( + check_edit( config, r#" struct S(T); @@ -1154,6 +1153,13 @@ fn test() { let f = |a: S| S(a); } "#, + expect![[r#" + struct S(T); + fn test() { + let f = || -> i32 { 3 }; + let f = |a: S| -> S> { S(a) }; + } + "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs index 61c9c25fe7396..b9bbff333f594 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs @@ -1,8 +1,8 @@ //! Implementation of "closure return type" inlay hints. //! //! Tests live in [`bind_pat`][super::bind_pat] module. -use hir::DisplayTarget; -use ide_db::famous_defs::FamousDefs; +use hir::{DisplayTarget, HirDisplay}; +use ide_db::{famous_defs::FamousDefs, text_edit::TextEdit}; use syntax::ast::{self, AstNode}; use crate::{ @@ -62,7 +62,28 @@ pub(super) fn hints( if arrow.is_none() { " -> " } else { "" }, ) } else { - None + let body = closure.body()?; + let body_range = body.syntax().text_range(); + + Some(config.lazy_text_edit(|| { + let mut builder = TextEdit::builder(); + let insert_pos = param_list.syntax().text_range().end(); + + let rendered = match sema.scope(closure.syntax()).and_then(|scope| { + ty.display_source_code(scope.db, scope.module().into(), false).ok() + }) { + Some(rendered) => rendered, + None => return TextEdit::builder().finish(), + }; + + let arrow_text = if arrow.is_none() { " -> ".to_owned() } else { "".to_owned() }; + builder.insert(insert_pos, arrow_text); + builder.insert(insert_pos, rendered); + builder.insert(body_range.start(), "{ ".to_owned()); + builder.insert(body_range.end(), " }".to_owned()); + + builder.finish() + })) }; acc.push(InlayHint { From 21ee875b4c619141af7347cff9853c7a71131bcf Mon Sep 17 00:00:00 2001 From: jnyfah Date: Thu, 13 Mar 2025 10:53:34 +0100 Subject: [PATCH 017/260] remove fixme --- .../rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs index b9bbff333f594..03835ec1f4cf1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs @@ -48,7 +48,6 @@ pub(super) fn hints( if arrow.is_none() { label.prepend_str(" -> "); } - // FIXME?: We could provide text edit to insert braces for closures with non-block body. let text_edit = if has_block_body { ty_to_text_edit( sema, From a508206f4e39e28274f77e6f1eb6eac1bbb27191 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Thu, 13 Mar 2025 13:38:29 -0400 Subject: [PATCH 018/260] internal: don't panic when the crate graph isn't ready #19351 --- src/tools/rust-analyzer/crates/base-db/src/lib.rs | 7 +++---- .../crates/hir-def/src/nameres/tests/macros.rs | 4 ++-- .../crates/hir-ty/src/consteval/tests.rs | 3 ++- .../rust-analyzer/crates/hir/src/semantics.rs | 8 ++++---- src/tools/rust-analyzer/crates/hir/src/symbols.rs | 5 ++++- .../crates/ide-diagnostics/src/lib.rs | 14 +++++++++++--- .../rust-analyzer/crates/ide-ssr/src/matching.rs | 8 +++----- src/tools/rust-analyzer/crates/ide/src/hover.rs | 2 +- .../rust-analyzer/crates/ide/src/inlay_hints.rs | 5 ++++- .../rust-analyzer/crates/ide/src/runnables.rs | 5 +++-- .../rust-analyzer/crates/ide/src/signature_help.rs | 2 +- .../rust-analyzer/crates/ide/src/static_index.rs | 9 +++++++-- .../crates/ide/src/view_memory_layout.rs | 2 +- .../crates/rust-analyzer/src/cli/analysis_stats.rs | 6 ++++-- 14 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 324979b2e463b..0f29abbb54f14 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -212,22 +212,21 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database { /// Returns the crates in topological order. /// - /// **Warning**: do not use this query in analysis! It kills incrementality across crate metadata modifications. + /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. #[salsa::input] fn all_crates(&self) -> Arc>; /// Returns an iterator over all transitive dependencies of the given crate, /// including the crate itself. /// - /// **Warning**: do not use this query in analysis! It kills incrementality across crate metadata modifications. - /// + /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. #[salsa::transparent] fn transitive_deps(&self, crate_id: Crate) -> FxHashSet; /// Returns all transitive reverse dependencies of the given crate, /// including the crate itself. /// - /// **Warning**: Do not use this query in analysis! It kills incrementality across crate metadata modifications. + /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. #[salsa::invoke(input::transitive_rev_deps)] #[salsa::transparent] fn transitive_rev_deps(&self, of: Crate) -> FxHashSet; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs index 0348a7076a8d0..5f8a01523d820 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs @@ -1095,7 +1095,7 @@ pub fn derive_macro_2(_item: TokenStream) -> TokenStream { } "#, ); - let krate = *db.all_crates().last().unwrap(); + let krate = *db.all_crates().last().expect("no crate graph present"); let def_map = db.crate_def_map(krate); assert_eq!(def_map.data.exported_derives.len(), 1); @@ -1445,7 +1445,7 @@ struct TokenStream; fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } "#, ); - let krate = *db.all_crates().last().unwrap(); + let krate = *db.all_crates().last().expect("no crate graph present"); let def_map = db.crate_def_map(krate); let root_module = &def_map[DefMap::ROOT].scope; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 37e7df6f4b46e..d679f9dd7ca42 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -101,7 +101,8 @@ fn check_answer( fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String { let mut err = String::new(); let span_formatter = |file, range| format!("{file:?} {range:?}"); - let display_target = DisplayTarget::from_crate(&db, *db.all_crates().last().unwrap()); + let display_target = + DisplayTarget::from_crate(&db, *db.all_crates().last().expect("no crate graph present")); match e { ConstEvalError::MirLowerError(e) => { e.pretty_print(&mut err, &db, span_formatter, display_target) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 6378eebd24fa0..15cd69f320d33 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -314,11 +314,11 @@ impl<'db> SemanticsImpl<'db> { tree } - /// If not crate is found for the file, returns the last crate in topological order. - pub fn first_crate_or_default(&self, file: FileId) -> Crate { + /// If not crate is found for the file, try to return the last crate in topological order. + pub fn first_crate(&self, file: FileId) -> Option { match self.file_to_module_defs(file).next() { - Some(module) => module.krate(), - None => (*self.db.all_crates().last().unwrap()).into(), + Some(module) => Some(module.krate()), + None => self.db.all_crates().last().copied().map(Into::into), } } diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index cc8aa1f1a18ed..2a6c15207a337 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -77,7 +77,10 @@ impl<'a> SymbolCollector<'a> { symbols: Default::default(), work: Default::default(), current_container_name: None, - display_target: DisplayTarget::from_crate(db, *db.all_crates().last().unwrap()), + display_target: DisplayTarget::from_crate( + db, + *db.all_crates().last().expect("no crate graph present"), + ), } } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index f4ced736b3df8..dc6fd1f5eaeb7 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -389,9 +389,17 @@ pub fn semantic_diagnostics( module.and_then(|m| db.toolchain_channel(m.krate().into())), Some(ReleaseChannel::Nightly) | None ); - let krate = module - .map(|module| module.krate()) - .unwrap_or_else(|| (*db.all_crates().last().unwrap()).into()); + + let krate = match module { + Some(module) => module.krate(), + None => { + match db.all_crates().last() { + Some(last) => (*last).into(), + // short-circuit, return an empty vec of diagnostics + None => return vec![], + } + } + }; let display_target = krate.to_display_target(db); let ctx = DiagnosticsContext { config, sema, resolve, edition, is_nightly, display_target }; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index 48d2431a11fbf..a76516f44f03b 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -626,11 +626,9 @@ impl<'db, 'sema> Matcher<'db, 'sema> { match_error!("Failed to get receiver type for `{}`", expr.syntax().text()) })? .original; - let krate = self - .sema - .scope(expr.syntax()) - .map(|it| it.krate()) - .unwrap_or_else(|| hir::Crate::from(*self.sema.db.all_crates().last().unwrap())); + let krate = self.sema.scope(expr.syntax()).map(|it| it.krate()).unwrap_or_else(|| { + hir::Crate::from(*self.sema.db.all_crates().last().expect("no crate graph present")) + }); let res = code_type .autoderef(self.sema.db) .enumerate() diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index b00de6ba40833..04189ed52aa79 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -130,7 +130,7 @@ pub(crate) fn hover( let file = sema.parse_guess_edition(file_id).syntax().clone(); let edition = sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT); - let display_target = sema.first_crate_or_default(file_id).to_display_target(db); + let display_target = sema.first_crate(file_id)?.to_display_target(db); let mut res = if range.is_empty() { hover_offset( sema, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 3a709e71fbe70..57adf3e2a4721 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -211,7 +211,10 @@ fn hints( file_id: EditionedFileId, node: SyntaxNode, ) { - let display_target = sema.first_crate_or_default(file_id.file_id()).to_display_target(sema.db); + let Some(krate) = sema.first_crate(file_id.file_id()) else { + return; + }; + let display_target = krate.to_display_target(sema.db); closing_brace::hints(hints, sema, config, file_id, display_target, node.clone()); if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) { generic_param::hints(hints, famous_defs, config, any_has_generic_args); diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index baa7ee6897352..f2cb3c1f991a7 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -498,8 +498,9 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option { }; let krate = def.krate(db); let edition = krate.map(|it| it.edition(db)).unwrap_or(Edition::CURRENT); - let display_target = - krate.unwrap_or_else(|| (*db.all_crates().last().unwrap()).into()).to_display_target(db); + let display_target = krate + .unwrap_or_else(|| (*db.all_crates().last().expect("no crate graph present")).into()) + .to_display_target(db); if !has_runnable_doc_test(&attrs) { return None; } diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index b5468a5aee9ff..84912f6be65af 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -84,7 +84,7 @@ pub(crate) fn signature_help( let token = sema.descend_into_macros_single_exact(token); let edition = sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT); - let display_target = sema.first_crate_or_default(file_id).to_display_target(db); + let display_target = sema.first_crate(file_id)?.to_display_target(db); for node in token.parent_ancestors() { match_ast! { diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 5a2b09b513774..c1562769309ed 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -119,7 +119,9 @@ fn documentation_for_definition( sema.db, famous_defs.as_ref(), def.krate(sema.db) - .unwrap_or_else(|| (*sema.db.all_crates().last().unwrap()).into()) + .unwrap_or_else(|| { + (*sema.db.all_crates().last().expect("no crate graph present")).into() + }) .to_display_target(sema.db), ) } @@ -175,7 +177,10 @@ impl StaticIndex<'_> { let root = sema.parse_guess_edition(file_id).syntax().clone(); let edition = sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT); - let display_target = sema.first_crate_or_default(file_id).to_display_target(self.db); + let display_target = match sema.first_crate(file_id) { + Some(krate) => krate.to_display_target(sema.db), + None => return, + }; let tokens = root.descendants_with_tokens().filter_map(|it| match it { syntax::NodeOrToken::Node(_) => None, syntax::NodeOrToken::Token(it) => Some(it), diff --git a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs index 34bca7bce12cf..02e3b1d500f26 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs @@ -83,7 +83,7 @@ pub(crate) fn view_memory_layout( ) -> Option { let sema = Semantics::new(db); let file = sema.parse_guess_edition(position.file_id); - let display_target = sema.first_crate_or_default(position.file_id).to_display_target(db); + let display_target = sema.first_crate(position.file_id)?.to_display_target(db); let token = pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind { SyntaxKind::IDENT => 3, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index a391a01fae74e..1efc242bfb6d0 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -384,8 +384,10 @@ impl flags::AnalysisStats { for &file_id in &file_ids { let sema = hir::Semantics::new(db); - let display_target = - sema.first_crate_or_default(file_id.file_id()).to_display_target(db); + let display_target = match sema.first_crate(file_id.file_id()) { + Some(krate) => krate.to_display_target(sema.db), + None => continue, + }; let parse = sema.parse_guess_edition(file_id.into()); let file_txt = db.file_text(file_id.into()); From 9ccee20d423f567220ce8f29ee215f5d1a17736b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 26 Feb 2025 07:40:42 +0100 Subject: [PATCH 019/260] Split assoc items out of `trait_data`/`impl_data` queries --- .../rust-analyzer/crates/hir-def/src/data.rs | 321 +---------------- .../rust-analyzer/crates/hir-def/src/db.rs | 25 +- .../crates/hir-def/src/expr_store/pretty.rs | 2 +- .../crates/hir-def/src/import_map.rs | 6 +- .../crates/hir-def/src/lang_item.rs | 4 +- .../crates/hir-def/src/nameres.rs | 1 + .../crates/hir-def/src/nameres/assoc.rs | 325 ++++++++++++++++++ .../crates/hir-ty/src/autoderef.rs | 2 +- .../crates/hir-ty/src/chalk_db.rs | 12 +- .../crates/hir-ty/src/diagnostics/expr.rs | 2 +- .../crates/hir-ty/src/display.rs | 2 +- .../crates/hir-ty/src/dyn_compatibility.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 2 +- .../crates/hir-ty/src/infer/closure.rs | 2 +- .../crates/hir-ty/src/infer/expr.rs | 8 +- .../crates/hir-ty/src/infer/mutability.rs | 4 +- .../crates/hir-ty/src/infer/path.rs | 2 +- .../crates/hir-ty/src/infer/unify.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/lib.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 4 +- .../crates/hir-ty/src/lower/path.rs | 2 +- .../crates/hir-ty/src/method_resolution.rs | 24 +- .../crates/hir-ty/src/mir/eval.rs | 12 +- .../crates/hir-ty/src/mir/eval/shim.rs | 2 +- .../crates/hir-ty/src/mir/lower/as_place.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/tests.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/utils.rs | 2 +- .../rust-analyzer/crates/hir/src/attrs.rs | 2 +- src/tools/rust-analyzer/crates/hir/src/db.rs | 4 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 37 +- .../hir/src/semantics/child_by_source.rs | 4 +- .../crates/hir/src/source_analyzer.rs | 6 +- .../rust-analyzer/crates/hir/src/symbols.rs | 4 +- .../crates/ide-db/src/apply_change.rs | 4 +- 34 files changed, 446 insertions(+), 397 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index 9c87dc31dba95..8a1f07c92efff 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -3,33 +3,21 @@ pub mod adt; use base_db::Crate; -use hir_expand::{ - name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind, -}; +use hir_expand::name::Name; use intern::{sym, Symbol}; use la_arena::{Idx, RawIdx}; -use smallvec::SmallVec; -use syntax::{ast, Parse}; use triomphe::Arc; use tt::iter::TtElement; use crate::{ db::DefDatabase, - expander::{Expander, Mark}, - item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId}, - macro_call_as_call_id, - nameres::{ - attr_resolution::ResolvedAttr, - diagnostics::{DefDiagnostic, DefDiagnostics}, - proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, - DefMap, LocalDefMap, MacroSubNs, - }, + item_tree::{self, FnFlags, ModItem}, + nameres::proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, path::ImportAlias, type_ref::{TraitRef, TypeBound, TypeRefId, TypesMap}, visibility::RawVisibility, - AssocItemId, AstIdWithPath, ConstId, ConstLoc, ExternCrateId, FunctionId, FunctionLoc, - HasModule, ImplId, Intern, ItemContainerId, ItemLoc, Lookup, Macro2Id, MacroRulesId, ModuleId, - ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, TypeAliasLoc, + ConstId, ExternCrateId, FunctionId, HasModule, ImplId, ItemContainerId, ItemLoc, Lookup, + Macro2Id, MacroRulesId, ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -256,23 +244,13 @@ bitflags::bitflags! { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraitData { pub name: Name, - pub items: Box<[(Name, AssocItemId)]>, pub flags: TraitFlags, pub visibility: RawVisibility, - // box it as the vec is usually empty anyways - pub macro_calls: Option, MacroCallId)>>>, } impl TraitData { #[inline] pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc { - db.trait_data_with_diagnostics(tr).0 - } - - pub(crate) fn trait_data_with_diagnostics_query( - db: &dyn DefDatabase, - tr: TraitId, - ) -> (Arc, DefDiagnostics) { let ItemLoc { container: module_id, id: tree_id } = tr.lookup(db); let item_tree = tree_id.item_tree(db); let tr_def = &item_tree[tree_id.value]; @@ -317,40 +295,7 @@ impl TraitData { flags |= TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH; } - let mut collector = - AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr)); - collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items); - let (items, macro_calls, diagnostics) = collector.finish(); - - ( - Arc::new(TraitData { name, macro_calls, items, visibility, flags }), - DefDiagnostics::new(diagnostics), - ) - } - - pub fn associated_types(&self) -> impl Iterator + '_ { - self.items.iter().filter_map(|(_name, item)| match item { - AssocItemId::TypeAliasId(t) => Some(*t), - _ => None, - }) - } - - pub fn associated_type_by_name(&self, name: &Name) -> Option { - self.items.iter().find_map(|(item_name, item)| match item { - AssocItemId::TypeAliasId(t) if item_name == name => Some(*t), - _ => None, - }) - } - - pub fn method_by_name(&self, name: &Name) -> Option { - self.items.iter().find_map(|(item_name, item)| match item { - AssocItemId::FunctionId(t) if item_name == name => Some(*t), - _ => None, - }) - } - - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { - self.macro_calls.iter().flat_map(|it| it.iter()).copied() + Arc::new(TraitData { name, visibility, flags }) } } @@ -375,26 +320,16 @@ impl TraitAliasData { pub struct ImplData { pub target_trait: Option, pub self_ty: TypeRefId, - pub items: Box<[(Name, AssocItemId)]>, pub is_negative: bool, pub is_unsafe: bool, - // box it as the vec is usually empty anyways - pub macro_calls: Option, MacroCallId)>>>, pub types_map: Arc, } impl ImplData { #[inline] pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc { - db.impl_data_with_diagnostics(id).0 - } - - pub(crate) fn impl_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: ImplId, - ) -> (Arc, DefDiagnostics) { - let _p = tracing::info_span!("impl_data_with_diagnostics_query").entered(); - let ItemLoc { container: module_id, id: tree_id } = id.lookup(db); + let _p = tracing::info_span!("impl_data_query").entered(); + let ItemLoc { id: tree_id, .. } = id.lookup(db); let item_tree = tree_id.item_tree(db); let impl_def = &item_tree[tree_id.value]; @@ -403,28 +338,13 @@ impl ImplData { let is_negative = impl_def.is_negative; let is_unsafe = impl_def.is_unsafe; - let mut collector = - AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::ImplId(id)); - collector.collect(&item_tree, tree_id.tree_id(), &impl_def.items); - - let (items, macro_calls, diagnostics) = collector.finish(); - - ( - Arc::new(ImplData { - target_trait, - self_ty, - items, - is_negative, - is_unsafe, - macro_calls, - types_map: impl_def.types_map.clone(), - }), - DefDiagnostics::new(diagnostics), - ) - } - - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { - self.macro_calls.iter().flat_map(|it| it.iter()).copied() + Arc::new(ImplData { + target_trait, + self_ty, + is_negative, + is_unsafe, + types_map: impl_def.types_map.clone(), + }) } } @@ -628,217 +548,6 @@ impl StaticData { } } -struct AssocItemCollector<'a> { - db: &'a dyn DefDatabase, - module_id: ModuleId, - def_map: Arc, - local_def_map: Arc, - diagnostics: Vec, - container: ItemContainerId, - expander: Expander, - - items: Vec<(Name, AssocItemId)>, - macro_calls: Vec<(AstId, MacroCallId)>, -} - -impl<'a> AssocItemCollector<'a> { - fn new( - db: &'a dyn DefDatabase, - module_id: ModuleId, - file_id: HirFileId, - container: ItemContainerId, - ) -> Self { - let (def_map, local_def_map) = module_id.local_def_map(db); - Self { - db, - module_id, - def_map, - local_def_map, - container, - expander: Expander::new(db, file_id, module_id), - items: Vec::new(), - macro_calls: Vec::new(), - diagnostics: Vec::new(), - } - } - - fn finish( - self, - ) -> ( - Box<[(Name, AssocItemId)]>, - Option, MacroCallId)>>>, - Vec, - ) { - ( - self.items.into_boxed_slice(), - if self.macro_calls.is_empty() { None } else { Some(Box::new(self.macro_calls)) }, - self.diagnostics, - ) - } - - fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[AssocItem]) { - let container = self.container; - self.items.reserve(assoc_items.len()); - - 'items: for &item in assoc_items { - let attrs = item_tree.attrs(self.db, self.module_id.krate, ModItem::from(item).into()); - if !attrs.is_cfg_enabled(self.expander.cfg_options()) { - self.diagnostics.push(DefDiagnostic::unconfigured_code( - self.module_id.local_id, - tree_id, - ModItem::from(item).into(), - attrs.cfg().unwrap(), - self.expander.cfg_options().clone(), - )); - continue; - } - - 'attrs: for attr in &*attrs { - let ast_id = - AstId::new(self.expander.current_file_id(), item.ast_id(item_tree).upcast()); - let ast_id_with_path = AstIdWithPath { path: attr.path.clone(), ast_id }; - - match self.def_map.resolve_attr_macro( - &self.local_def_map, - self.db, - self.module_id.local_id, - ast_id_with_path, - attr, - ) { - Ok(ResolvedAttr::Macro(call_id)) => { - let loc = self.db.lookup_intern_macro_call(call_id); - if let MacroDefKind::ProcMacro(_, exp, _) = loc.def.kind { - // If there's no expander for the proc macro (e.g. the - // proc macro is ignored, or building the proc macro - // crate failed), skip expansion like we would if it was - // disabled. This is analogous to the handling in - // `DefCollector::collect_macros`. - if let Some(err) = exp.as_expand_error(self.module_id.krate) { - self.diagnostics.push(DefDiagnostic::macro_error( - self.module_id.local_id, - ast_id, - (*attr.path).clone(), - err, - )); - continue 'attrs; - } - } - - self.macro_calls.push((ast_id, call_id)); - let res = - self.expander.enter_expand_id::(self.db, call_id); - self.collect_macro_items(res); - continue 'items; - } - Ok(_) => (), - Err(_) => { - self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, - MacroCallKind::Attr { - ast_id, - attr_args: None, - invoc_attr_index: attr.id, - }, - attr.path().clone(), - )); - } - } - } - - self.collect_item(item_tree, tree_id, container, item); - } - } - - fn collect_item( - &mut self, - item_tree: &ItemTree, - tree_id: TreeId, - container: ItemContainerId, - item: AssocItem, - ) { - match item { - AssocItem::Function(id) => { - let item = &item_tree[id]; - let def = - FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((item.name.clone(), def.into())); - } - AssocItem::TypeAlias(id) => { - let item = &item_tree[id]; - let def = - TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((item.name.clone(), def.into())); - } - AssocItem::Const(id) => { - let item = &item_tree[id]; - let Some(name) = item.name.clone() else { return }; - let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((name, def.into())); - } - AssocItem::MacroCall(call) => { - let file_id = self.expander.current_file_id(); - let MacroCall { ast_id, expand_to, ctxt, ref path } = item_tree[call]; - let module = self.expander.module.local_id; - - let resolver = |path: &_| { - self.def_map - .resolve_path( - &self.local_def_map, - self.db, - module, - path, - crate::item_scope::BuiltinShadowMode::Other, - Some(MacroSubNs::Bang), - ) - .0 - .take_macros() - .map(|it| self.db.macro_def(it)) - }; - match macro_call_as_call_id( - self.db.upcast(), - &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)), - ctxt, - expand_to, - self.expander.krate(), - resolver, - ) { - Ok(Some(call_id)) => { - let res = - self.expander.enter_expand_id::(self.db, call_id); - self.macro_calls.push((InFile::new(file_id, ast_id.upcast()), call_id)); - self.collect_macro_items(res); - } - Ok(None) => (), - Err(_) => { - self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, - MacroCallKind::FnLike { - ast_id: InFile::new(file_id, ast_id), - expand_to, - eager: None, - }, - Clone::clone(path), - )); - } - } - } - } - } - - fn collect_macro_items(&mut self, res: ExpandResult)>>) { - let Some((mark, _parse)) = res.value else { return }; - - let tree_id = item_tree::TreeId::new(self.expander.current_file_id(), None); - let item_tree = tree_id.item_tree(self.db); - let iter: SmallVec<[_; 2]> = - item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item).collect(); - - self.collect(&item_tree, tree_id, &iter); - - self.expander.exit(mark); - } -} - fn trait_vis(db: &dyn DefDatabase, trait_id: TraitId) -> RawVisibility { let ItemLoc { id: tree_id, .. } = trait_id.lookup(db); let item_tree = tree_id.item_tree(db); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index b6707af618115..ff33056538071 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -20,7 +20,11 @@ use crate::{ import_map::ImportMap, item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps}, lang_item::{self, LangItem, LangItemTarget, LangItems}, - nameres::{diagnostics::DefDiagnostics, DefMap, LocalDefMap}, + nameres::{ + assoc::{ImplItems, TraitItems}, + diagnostics::DefDiagnostics, + DefMap, LocalDefMap, + }, tt, type_ref::TypesSourceMap, visibility::{self, Visibility}, @@ -176,19 +180,26 @@ pub trait DefDatabase: #[salsa::transparent] #[salsa::invoke_actual(VariantData::variant_data)] fn variant_data(&self, id: VariantId) -> Arc; - #[salsa::transparent] + #[salsa::invoke_actual(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; - #[salsa::invoke_actual(ImplData::impl_data_with_diagnostics_query)] - fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); - #[salsa::transparent] + #[salsa::invoke_actual(ImplItems::impl_items_query)] + fn impl_items(&self, e: ImplId) -> Arc; + + #[salsa::invoke_actual(ImplItems::impl_items_with_diagnostics_query)] + fn impl_items_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); + #[salsa::invoke_actual(TraitData::trait_data_query)] fn trait_data(&self, e: TraitId) -> Arc; - #[salsa::invoke_actual(TraitData::trait_data_with_diagnostics_query)] - fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); + #[salsa::transparent] + #[salsa::invoke_actual(TraitItems::trait_items_query)] + fn trait_items(&self, e: TraitId) -> Arc; + + #[salsa::invoke_actual(TraitItems::trait_items_with_diagnostics_query)] + fn trait_items_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); #[salsa::invoke_actual(TraitAliasData::trait_alias_query)] fn trait_alias_data(&self, e: TraitAliasId) -> Arc; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs index 82ad756dc2c6a..cc6d200051c3f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs @@ -82,7 +82,7 @@ pub(super) fn print_body_hir( p.buf.push_str(", "); }); // remove the last ", " in param list - if body.params.len() > 0 { + if !body.params.is_empty() { p.buf.truncate(p.buf.len() - 2); } p.buf.push(')'); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 1cdc4c025975c..9e4479f05b427 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -222,7 +222,7 @@ impl ImportMap { trait_import_info: &ImportInfo, ) { let _p = tracing::info_span!("collect_trait_assoc_items").entered(); - for &(ref assoc_item_name, item) in &db.trait_data(tr).items { + for &(ref assoc_item_name, item) in &db.trait_items(tr).items { let module_def_id = match item { AssocItemId::FunctionId(f) => ModuleDefId::from(f), AssocItemId::ConstId(c) => ModuleDefId::from(c), @@ -575,8 +575,8 @@ mod tests { let trait_info = dependency_imports.import_info_for(ItemInNs::Types(trait_id.into()))?; - let trait_data = db.trait_data(trait_id); - let (assoc_item_name, _) = trait_data + let trait_items = db.trait_items(trait_id); + let (assoc_item_name, _) = trait_items .items .iter() .find(|(_, assoc_item_id)| &dependency_assoc_item_id == assoc_item_id)?; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 70c28009f4b99..67788576c13bc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -107,7 +107,7 @@ impl LangItems { for (_, module_data) in crate_def_map.modules() { for impl_def in module_data.scope.impls() { lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef); - for &(_, assoc) in db.impl_data(impl_def).items.iter() { + for &(_, assoc) in db.impl_items(impl_def).items.iter() { match assoc { AssocItemId::FunctionId(f) => { lang_items.collect_lang_item(db, f, LangItemTarget::Function) @@ -124,7 +124,7 @@ impl LangItems { match def { ModuleDefId::TraitId(trait_) => { lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait); - db.trait_data(trait_).items.iter().for_each( + db.trait_items(trait_).items.iter().for_each( |&(_, assoc_id)| match assoc_id { AssocItemId::FunctionId(f) => { lang_items.collect_lang_item(db, f, LangItemTarget::Function); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 054c285fa2567..a34766ebc1dca 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -47,6 +47,7 @@ //! path and, upon success, we run macro expansion and "collect module" phase on //! the result +pub mod assoc; pub mod attr_resolution; mod collector; pub mod diagnostics; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs new file mode 100644 index 0000000000000..dea6d334f8aa6 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs @@ -0,0 +1,325 @@ +//! Expansion of associated items + +use hir_expand::{ + name::Name, AstId, ExpandResult, InFile, Intern, Lookup, MacroCallKind, MacroDefKind, +}; +use smallvec::SmallVec; +use span::{HirFileId, MacroCallId}; +use syntax::{ast, Parse}; +use triomphe::Arc; + +use crate::{ + db::DefDatabase, + expander::{Expander, Mark}, + item_tree::{self, AssocItem, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId}, + macro_call_as_call_id, + nameres::{ + attr_resolution::ResolvedAttr, + diagnostics::{DefDiagnostic, DefDiagnostics}, + DefMap, LocalDefMap, MacroSubNs, + }, + AssocItemId, AstIdWithPath, ConstLoc, FunctionId, FunctionLoc, ImplId, ItemContainerId, + ItemLoc, ModuleId, TraitId, TypeAliasId, TypeAliasLoc, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TraitItems { + pub items: Box<[(Name, AssocItemId)]>, + // box it as the vec is usually empty anyways + pub macro_calls: Option, MacroCallId)>>>, +} + +impl TraitItems { + #[inline] + pub(crate) fn trait_items_query(db: &dyn DefDatabase, tr: TraitId) -> Arc { + db.trait_items_with_diagnostics(tr).0 + } + + pub(crate) fn trait_items_with_diagnostics_query( + db: &dyn DefDatabase, + tr: TraitId, + ) -> (Arc, DefDiagnostics) { + let ItemLoc { container: module_id, id: tree_id } = tr.lookup(db); + let item_tree = tree_id.item_tree(db); + let tr_def = &item_tree[tree_id.value]; + + let mut collector = + AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr)); + collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items); + let (items, macro_calls, diagnostics) = collector.finish(); + + (Arc::new(TraitItems { macro_calls, items }), DefDiagnostics::new(diagnostics)) + } + + pub fn associated_types(&self) -> impl Iterator + '_ { + self.items.iter().filter_map(|(_name, item)| match item { + AssocItemId::TypeAliasId(t) => Some(*t), + _ => None, + }) + } + + pub fn associated_type_by_name(&self, name: &Name) -> Option { + self.items.iter().find_map(|(item_name, item)| match item { + AssocItemId::TypeAliasId(t) if item_name == name => Some(*t), + _ => None, + }) + } + + pub fn method_by_name(&self, name: &Name) -> Option { + self.items.iter().find_map(|(item_name, item)| match item { + AssocItemId::FunctionId(t) if item_name == name => Some(*t), + _ => None, + }) + } + + pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { + self.macro_calls.iter().flat_map(|it| it.iter()).copied() + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct ImplItems { + pub items: Box<[(Name, AssocItemId)]>, + // box it as the vec is usually empty anyways + pub macro_calls: Option, MacroCallId)>>>, +} + +impl ImplItems { + #[inline] + pub(crate) fn impl_items_query(db: &dyn DefDatabase, id: ImplId) -> Arc { + db.impl_items_with_diagnostics(id).0 + } + + pub(crate) fn impl_items_with_diagnostics_query( + db: &dyn DefDatabase, + id: ImplId, + ) -> (Arc, DefDiagnostics) { + let _p = tracing::info_span!("impl_items_with_diagnostics_query").entered(); + let ItemLoc { container: module_id, id: tree_id } = id.lookup(db); + + let item_tree = tree_id.item_tree(db); + let impl_def = &item_tree[tree_id.value]; + let mut collector = + AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::ImplId(id)); + collector.collect(&item_tree, tree_id.tree_id(), &impl_def.items); + + let (items, macro_calls, diagnostics) = collector.finish(); + + (Arc::new(ImplItems { items, macro_calls }), DefDiagnostics::new(diagnostics)) + } + + pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { + self.macro_calls.iter().flat_map(|it| it.iter()).copied() + } +} + +struct AssocItemCollector<'a> { + db: &'a dyn DefDatabase, + module_id: ModuleId, + def_map: Arc, + local_def_map: Arc, + diagnostics: Vec, + container: ItemContainerId, + expander: Expander, + + items: Vec<(Name, AssocItemId)>, + macro_calls: Vec<(AstId, MacroCallId)>, +} + +impl<'a> AssocItemCollector<'a> { + fn new( + db: &'a dyn DefDatabase, + module_id: ModuleId, + file_id: HirFileId, + container: ItemContainerId, + ) -> Self { + let (def_map, local_def_map) = module_id.local_def_map(db); + Self { + db, + module_id, + def_map, + local_def_map, + container, + expander: Expander::new(db, file_id, module_id), + items: Vec::new(), + macro_calls: Vec::new(), + diagnostics: Vec::new(), + } + } + + fn finish( + self, + ) -> ( + Box<[(Name, AssocItemId)]>, + Option, MacroCallId)>>>, + Vec, + ) { + ( + self.items.into_boxed_slice(), + if self.macro_calls.is_empty() { None } else { Some(Box::new(self.macro_calls)) }, + self.diagnostics, + ) + } + + fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[AssocItem]) { + let container = self.container; + self.items.reserve(assoc_items.len()); + + 'items: for &item in assoc_items { + let attrs = item_tree.attrs(self.db, self.module_id.krate, ModItem::from(item).into()); + if !attrs.is_cfg_enabled(self.expander.cfg_options()) { + self.diagnostics.push(DefDiagnostic::unconfigured_code( + self.module_id.local_id, + tree_id, + ModItem::from(item).into(), + attrs.cfg().unwrap(), + self.expander.cfg_options().clone(), + )); + continue; + } + + 'attrs: for attr in &*attrs { + let ast_id = + AstId::new(self.expander.current_file_id(), item.ast_id(item_tree).upcast()); + let ast_id_with_path = AstIdWithPath { path: attr.path.clone(), ast_id }; + + match self.def_map.resolve_attr_macro( + &self.local_def_map, + self.db, + self.module_id.local_id, + ast_id_with_path, + attr, + ) { + Ok(ResolvedAttr::Macro(call_id)) => { + let loc = self.db.lookup_intern_macro_call(call_id); + if let MacroDefKind::ProcMacro(_, exp, _) = loc.def.kind { + // If there's no expander for the proc macro (e.g. the + // proc macro is ignored, or building the proc macro + // crate failed), skip expansion like we would if it was + // disabled. This is analogous to the handling in + // `DefCollector::collect_macros`. + if let Some(err) = exp.as_expand_error(self.module_id.krate) { + self.diagnostics.push(DefDiagnostic::macro_error( + self.module_id.local_id, + ast_id, + (*attr.path).clone(), + err, + )); + continue 'attrs; + } + } + + self.macro_calls.push((ast_id, call_id)); + let res = + self.expander.enter_expand_id::(self.db, call_id); + self.collect_macro_items(res); + continue 'items; + } + Ok(_) => (), + Err(_) => { + self.diagnostics.push(DefDiagnostic::unresolved_macro_call( + self.module_id.local_id, + MacroCallKind::Attr { + ast_id, + attr_args: None, + invoc_attr_index: attr.id, + }, + attr.path().clone(), + )); + } + } + } + + self.collect_item(item_tree, tree_id, container, item); + } + } + + fn collect_item( + &mut self, + item_tree: &ItemTree, + tree_id: TreeId, + container: ItemContainerId, + item: AssocItem, + ) { + match item { + AssocItem::Function(id) => { + let item = &item_tree[id]; + let def = + FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); + self.items.push((item.name.clone(), def.into())); + } + AssocItem::TypeAlias(id) => { + let item = &item_tree[id]; + let def = + TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); + self.items.push((item.name.clone(), def.into())); + } + AssocItem::Const(id) => { + let item = &item_tree[id]; + let Some(name) = item.name.clone() else { return }; + let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); + self.items.push((name, def.into())); + } + AssocItem::MacroCall(call) => { + let file_id = self.expander.current_file_id(); + let MacroCall { ast_id, expand_to, ctxt, ref path } = item_tree[call]; + let module = self.expander.module.local_id; + + let resolver = |path: &_| { + self.def_map + .resolve_path( + &self.local_def_map, + self.db, + module, + path, + crate::item_scope::BuiltinShadowMode::Other, + Some(MacroSubNs::Bang), + ) + .0 + .take_macros() + .map(|it| self.db.macro_def(it)) + }; + match macro_call_as_call_id( + self.db.upcast(), + &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)), + ctxt, + expand_to, + self.expander.krate(), + resolver, + ) { + Ok(Some(call_id)) => { + let res = + self.expander.enter_expand_id::(self.db, call_id); + self.macro_calls.push((InFile::new(file_id, ast_id.upcast()), call_id)); + self.collect_macro_items(res); + } + Ok(None) => (), + Err(_) => { + self.diagnostics.push(DefDiagnostic::unresolved_macro_call( + self.module_id.local_id, + MacroCallKind::FnLike { + ast_id: InFile::new(file_id, ast_id), + expand_to, + eager: None, + }, + Clone::clone(path), + )); + } + } + } + } + } + + fn collect_macro_items(&mut self, res: ExpandResult)>>) { + let Some((mark, _parse)) = res.value else { return }; + + let tree_id = item_tree::TreeId::new(self.expander.current_file_id(), None); + let item_tree = tree_id.item_tree(self.db); + let iter: SmallVec<[_; 2]> = + item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item).collect(); + + self.collect(&item_tree, tree_id, &iter); + + self.expander.exit(mark); + } +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs index 171ba001c4a79..2c27f5e3bbf18 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs @@ -210,7 +210,7 @@ pub(crate) fn deref_by_trait( }; let trait_id = trait_id()?; let target = db - .trait_data(trait_id) + .trait_items(trait_id) .associated_type_by_name(&Name::new_symbol_root(sym::Target.clone()))?; let projection = { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 84eb964d564bd..e5751a394dae5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -294,7 +294,7 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { .lang_item(self.krate, LangItem::Future) .and_then(|item| item.as_trait()) .and_then(|trait_| { - let alias = self.db.trait_data(trait_).associated_type_by_name( + let alias = self.db.trait_items(trait_).associated_type_by_name( &Name::new_symbol_root(sym::Output.clone()), )?; Some((trait_, alias)) @@ -684,7 +684,8 @@ pub(crate) fn trait_datum_query( fundamental: trait_data.flags.contains(TraitFlags::IS_FUNDAMENTAL), }; let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); - let associated_ty_ids = trait_data.associated_types().map(to_assoc_type_id).collect(); + let associated_ty_ids = + db.trait_items(trait_).associated_types().map(to_assoc_type_id).collect(); let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; let well_known = db.lang_attr(trait_.into()).and_then(well_known_trait_from_lang_item); let trait_datum = TraitDatum { @@ -856,8 +857,9 @@ fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId) let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive }; let impl_datum_bound = rust_ir::ImplDatumBound { trait_ref, where_clauses }; - let trait_data = db.trait_data(trait_); - let associated_ty_value_ids = impl_data + let trait_data = db.trait_items(trait_); + let associated_ty_value_ids = db + .impl_items(impl_id) .items .iter() .filter_map(|(_, item)| match item { @@ -908,7 +910,7 @@ fn type_alias_associated_ty_value( .0; // we don't return any assoc ty values if the impl'd trait can't be resolved let assoc_ty = db - .trait_data(trait_ref.hir_trait_id()) + .trait_items(trait_ref.hir_trait_id()) .associated_type_by_name(&type_alias_data.name) .expect("assoc ty value should not exist"); // validated when building the impl data as well let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 053d1cd41e9f1..1035651692ec8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -492,7 +492,7 @@ impl FilterMapNextChecker { Some(next_function_id), match next_function_id.lookup(db.upcast()).container { ItemContainerId::TraitId(iterator_trait_id) => { - let iterator_trait_items = &db.trait_data(iterator_trait_id).items; + let iterator_trait_items = &db.trait_items(iterator_trait_id).items; iterator_trait_items.iter().find_map(|(name, it)| match it { &AssocItemId::FunctionId(id) if *name == sym::filter_map.clone() => { Some(id) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 2ae7e746ba203..be590b6101d6a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1342,7 +1342,7 @@ impl HirDisplay for Ty { .lang_item(body.module(db.upcast()).krate(), LangItem::Future) .and_then(LangItemTarget::as_trait); let output = future_trait.and_then(|t| { - db.trait_data(t).associated_type_by_name(&Name::new_symbol_root( + db.trait_items(t).associated_type_by_name(&Name::new_symbol_root( sym::Output.clone(), )) }); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 6a01579bccc9d..af16a2499ba08 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -103,7 +103,7 @@ where // rustc checks for non-lifetime binders here, but we don't support HRTB yet - let trait_data = db.trait_data(trait_); + let trait_data = db.trait_items(trait_); for (_, assoc_item) in &trait_data.items { dyn_compatibility_violation_for_assoc_item(db, trait_, *assoc_item, cb)?; } @@ -166,7 +166,7 @@ fn predicates_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool { // Same as the above, `predicates_reference_self` fn bounds_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool { - let trait_data = db.trait_data(trait_); + let trait_data = db.trait_items(trait_); trait_data .items .iter() diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 556091c404614..9a4b7af85d8f9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -1723,7 +1723,7 @@ impl<'a> InferenceContext<'a> { fn resolve_output_on(&self, trait_: TraitId) -> Option { self.db - .trait_data(trait_) + .trait_items(trait_) .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone())) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index 50cac034e493f..ef02762c80a53 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -815,7 +815,7 @@ impl InferenceContext<'_> { { if let Some(deref_fn) = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&Name::new_symbol_root(sym::deref_mut.clone())) { break 'b deref_fn == f; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 131e98d729651..d0936185957f1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -772,7 +772,7 @@ impl InferenceContext<'_> { if let Some(deref_trait) = self.resolve_lang_trait(LangItem::Deref) { if let Some(deref_fn) = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&Name::new_symbol_root(sym::deref.clone())) { // FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that @@ -930,7 +930,7 @@ impl InferenceContext<'_> { self.write_expr_adj(*base, adj); if let Some(func) = self .db - .trait_data(index_trait) + .trait_items(index_trait) .method_by_name(&Name::new_symbol_root(sym::index.clone())) { let subst = TyBuilder::subst_for_def(self.db, index_trait, None); @@ -1258,7 +1258,7 @@ impl InferenceContext<'_> { let Some(trait_) = fn_x.get_id(self.db, self.table.trait_env.krate) else { return; }; - let trait_data = self.db.trait_data(trait_); + let trait_data = self.db.trait_items(trait_); if let Some(func) = trait_data.method_by_name(&fn_x.method_name()) { let subst = TyBuilder::subst_for_def(self.db, trait_, None) .push(callee_ty.clone()) @@ -1426,7 +1426,7 @@ impl InferenceContext<'_> { let trait_func = lang_items_for_bin_op(op).and_then(|(name, lang_item)| { let trait_id = self.resolve_lang_item(lang_item)?.as_trait()?; - let func = self.db.trait_data(trait_id).method_by_name(&name)?; + let func = self.db.trait_items(trait_id).method_by_name(&name)?; Some((trait_id, func)) }); let (trait_, func) = match trait_func { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs index d74a383f44ef4..96d84cad9394c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs @@ -134,7 +134,7 @@ impl InferenceContext<'_> { { if let Some(index_fn) = self .db - .trait_data(index_trait) + .trait_items(index_trait) .method_by_name(&Name::new_symbol_root(sym::index_mut.clone())) { *f = index_fn; @@ -201,7 +201,7 @@ impl InferenceContext<'_> { mutability = Mutability::Not; } else if let Some(deref_fn) = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&Name::new_symbol_root(sym::deref_mut.clone())) { *f = deref_fn; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 6254bc12392b0..29f455a61b941 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -277,7 +277,7 @@ impl InferenceContext<'_> { ) -> Option<(ValueNs, Substitution)> { let trait_ = trait_ref.hir_trait_id(); let item = - self.db.trait_data(trait_).items.iter().map(|(_name, id)| *id).find_map(|item| { + self.db.trait_items(trait_).items.iter().map(|(_name, id)| *id).find_map(|item| { match item { AssocItemId::FunctionId(func) => { if segment.name == &self.db.function_data(func).name { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index 8a8992cf372da..a9332a5a96374 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -801,7 +801,7 @@ impl<'a> InferenceTable<'a> { ] { let krate = self.trait_env.krate; let fn_trait = fn_trait_name.get_id(self.db, krate)?; - let trait_data = self.db.trait_data(fn_trait); + let trait_data = self.db.trait_items(fn_trait); let output_assoc_type = trait_data.associated_type_by_name(&Name::new_symbol_root(output_assoc_name))?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index f35298846a858..836319431dfb4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -906,7 +906,7 @@ pub fn callable_sig_from_fn_trait( let krate = trait_env.krate; let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?; let output_assoc_type = db - .trait_data(fn_once_trait) + .trait_items(fn_once_trait) .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone()))?; let mut table = InferenceTable::new(db, trait_env.clone()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 29ab0251f8360..33e852aaee46c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -898,7 +898,7 @@ fn named_associated_type_shorthand_candidates( ) -> Option { let mut search = |t| { all_super_trait_refs(db, t, |t| { - let data = db.trait_data(t.hir_trait_id()); + let data = db.trait_items(t.hir_trait_id()); for (name, assoc_id) in &data.items { if let AssocItemId::TypeAliasId(alias) = assoc_id { @@ -1068,7 +1068,7 @@ pub(crate) fn generic_predicates_for_param_query( }; all_super_traits(db.upcast(), tr).iter().any(|tr| { - db.trait_data(*tr).items.iter().any(|(name, item)| { + db.trait_items(*tr).items.iter().any(|(name, item)| { matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name }) }) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index a165932ddcc8c..a9e9e83e871ff 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -169,7 +169,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { self.skip_resolved_segment(); let segment = self.current_or_prev_segment; let found = - self.ctx.db.trait_data(trait_).associated_type_by_name(segment.name); + self.ctx.db.trait_items(trait_).associated_type_by_name(segment.name); match found { Some(associated_ty) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 50b0fce62f76e..bb3aaef20b76c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -8,8 +8,8 @@ use arrayvec::ArrayVec; use base_db::Crate; use chalk_ir::{cast::Cast, UniverseIndex, WithKind}; use hir_def::{ - data::{adt::StructFlags, ImplData, TraitFlags}, - nameres::DefMap, + data::{adt::StructFlags, TraitFlags}, + nameres::{assoc::ImplItems, DefMap}, AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, ModuleId, TraitId, }; @@ -325,7 +325,7 @@ impl InherentImpls { let self_ty = db.impl_self_ty(impl_id); let self_ty = self_ty.skip_binders(); - match is_inherent_impl_coherent(db, def_map, &data, self_ty) { + match is_inherent_impl_coherent(db, def_map, impl_id, self_ty) { true => { // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution) if let Some(fp) = TyFingerprint::for_inherent_impl(self_ty) { @@ -765,11 +765,10 @@ fn find_matching_impl( mut impls: impl Iterator, mut table: InferenceTable<'_>, actual_trait_ref: TraitRef, -) -> Option<(Arc, Substitution)> { +) -> Option<(Arc, Substitution)> { let db = table.db; impls.find_map(|impl_| { table.run_in_snapshot(|table| { - let impl_data = db.impl_data(impl_); let impl_substs = TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build(); let trait_ref = db @@ -787,7 +786,7 @@ fn find_matching_impl( let goal = crate::Goal::all(Interner, wcs); table.try_obligation(goal.clone())?; table.register_obligation(goal); - Some((impl_data, table.resolve_completely(impl_substs))) + Some((db.impl_items(impl_), table.resolve_completely(impl_substs))) }) }) } @@ -795,7 +794,7 @@ fn find_matching_impl( fn is_inherent_impl_coherent( db: &dyn HirDatabase, def_map: &DefMap, - impl_data: &ImplData, + impl_id: ImplId, self_ty: &Ty, ) -> bool { let self_ty = self_ty.kind(Interner); @@ -848,9 +847,10 @@ fn is_inherent_impl_coherent( _ => false, }; + let items = db.impl_items(impl_id); rustc_has_incoherent_inherent_impls - && !impl_data.items.is_empty() - && impl_data.items.iter().all(|&(_, assoc)| match assoc { + && !items.items.is_empty() + && items.items.iter().all(|&(_, assoc)| match assoc { AssocItemId::FunctionId(it) => db.function_data(it).rustc_allow_incoherent_impl, AssocItemId::ConstId(it) => db.const_data(it).rustc_allow_incoherent_impl, AssocItemId::TypeAliasId(it) => db.type_alias_data(it).rustc_allow_incoherent_impl, @@ -1241,7 +1241,7 @@ fn iterate_trait_method_candidates( // trait, but if we find out it doesn't, we'll skip the rest of the // iteration let mut known_implemented = false; - for &(_, item) in data.items.iter() { + for &(_, item) in db.trait_items(t).items.iter() { // Don't pass a `visible_from_module` down to `is_valid_candidate`, // since only inherent methods should be included into visibility checking. let visible = @@ -1368,7 +1368,7 @@ fn iterate_inherent_methods( ) -> ControlFlow<()> { let db = table.db; for t in traits { - let data = db.trait_data(t); + let data = db.trait_items(t); for &(_, item) in data.items.iter() { // We don't pass `visible_from_module` as all trait items should be visible. let visible = match is_valid_trait_method_candidate( @@ -1401,7 +1401,7 @@ fn iterate_inherent_methods( callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()> { for &impl_id in impls.for_self_ty(self_ty) { - for &(ref item_name, item) in table.db.impl_data(impl_id).items.iter() { + for &(ref item_name, item) in table.db.impl_items(impl_id).items.iter() { let visible = match is_valid_impl_method_candidate( table, self_ty, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 597e6a3ef0bf1..97710aab06c76 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -661,19 +661,19 @@ impl Evaluator<'_> { .lang_item(crate_id, LangItem::Fn) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call.clone())) + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call.clone())) }), cached_fn_mut_trait_func: db .lang_item(crate_id, LangItem::FnMut) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_mut.clone())) + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut.clone())) }), cached_fn_once_trait_func: db .lang_item(crate_id, LangItem::FnOnce) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_once.clone())) + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once.clone())) }), }) } @@ -2818,7 +2818,9 @@ impl Evaluator<'_> { ) -> Result<()> { let Some(drop_fn) = (|| { let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?; - self.db.trait_data(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop.clone())) + self.db + .trait_items(drop_trait) + .method_by_name(&Name::new_symbol_root(sym::drop.clone())) })() else { // in some tests we don't have drop trait in minicore, and // we can ignore drop in them. @@ -2928,7 +2930,7 @@ pub fn render_const_using_debug_impl( not_supported!("core::fmt::Debug not found"); }; let Some(debug_fmt_fn) = - db.trait_data(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt.clone())) + db.trait_items(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt.clone())) else { not_supported!("core::fmt::Debug::fmt not found"); }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 346dea82526fb..edd028cdeb26c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -1261,7 +1261,7 @@ impl Evaluator<'_> { if let Some(target) = self.db.lang_item(self.crate_id, LangItem::FnOnce) { if let Some(def) = target.as_trait().and_then(|it| { self.db - .trait_data(it) + .trait_items(it) .method_by_name(&Name::new_symbol_root(sym::call_once.clone())) }) { self.exec_fn_trait( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs index 420f2aaff46d6..7b0ee22d51fcf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs @@ -195,7 +195,7 @@ impl MirLowerCtx<'_> { self.resolve_lang_item(LangItem::DerefMut)?.as_trait() { if let Some(deref_fn) = - self.db.trait_data(deref_trait).method_by_name( + self.db.trait_items(deref_trait).method_by_name( &Name::new_symbol_root(sym::deref_mut.clone()), ) { @@ -353,7 +353,7 @@ impl MirLowerCtx<'_> { .ok_or(MirLowerError::LangItemNotFound(trait_lang_item))?; let deref_fn = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&trait_method_name) .ok_or(MirLowerError::LangItemNotFound(trait_lang_item))?; let deref_fn_op = Operand::const_zst( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index cdb9e9edf8831..9ad07922fac71 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -439,7 +439,7 @@ pub(crate) fn visit_module( ) { visit_scope(db, crate_def_map, &crate_def_map[module_id].scope, cb); for impl_id in crate_def_map[module_id].scope.impls() { - let impl_data = db.impl_data(impl_id); + let impl_data = db.impl_items(impl_id); for &(_, item) in impl_data.items.iter() { match item { AssocItemId::FunctionId(it) => { @@ -488,7 +488,7 @@ pub(crate) fn visit_module( }); } ModuleDefId::TraitId(it) => { - let trait_data = db.trait_data(it); + let trait_data = db.trait_items(it); for &(_, item) in trait_data.items.iter() { match item { AssocItemId::FunctionId(it) => cb(it.into()), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index b90f4e4d7faaa..cbb78ef40d84e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -226,7 +226,7 @@ pub(super) fn associated_type_by_name_including_super_traits( name: &Name, ) -> Option<(TraitRef, TypeAliasId)> { all_super_trait_refs(db, trait_ref, |t| { - let assoc_type = db.trait_data(t.hir_trait_id()).associated_type_by_name(name)?; + let assoc_type = db.trait_items(t.hir_trait_id()).associated_type_by_name(name)?; Some((t, assoc_type)) }) } diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index 4351a34e82282..1c88e79933fba 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -194,7 +194,7 @@ fn resolve_assoc_or_field( // Doc paths in this context may only resolve to an item of this trait // (i.e. no items of its supertraits), so we need to handle them here // independently of others. - return db.trait_data(id).items.iter().find(|it| it.0 == name).map(|(_, assoc_id)| { + return db.trait_items(id).items.iter().find(|it| it.0 == name).map(|(_, assoc_id)| { let def = match *assoc_id { AssocItemId::FunctionId(it) => ModuleDef::Function(it.into()), AssocItemId::ConstId(it) => ModuleDef::Const(it.into()), diff --git a/src/tools/rust-analyzer/crates/hir/src/db.rs b/src/tools/rust-analyzer/crates/hir/src/db.rs index 9e8e87ecff001..64d97b3f2a238 100644 --- a/src/tools/rust-analyzer/crates/hir/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir/src/db.rs @@ -11,7 +11,7 @@ pub use hir_def::db::DefDatabase; // ExpandProcAttrMacrosQuery, ExprScopesQuery, ExternCrateDeclDataQuery, FieldVisibilitiesQuery, // FieldsAttrsQuery, FieldsAttrsSourceMapQuery, FileItemTreeQuery, FileItemTreeWithSourceMapQuery, // FunctionDataQuery, FunctionVisibilityQuery, GenericParamsQuery, -// GenericParamsWithSourceMapQuery, ImplDataWithDiagnosticsQuery, ImportMapQuery, +// GenericParamsWithSourceMapQuery, ImplItemsWithDiagnosticsQuery, ImportMapQuery, // IncludeMacroInvocQuery, InternAnonymousConstQuery, InternBlockQuery, InternConstQuery, // InternDatabase, InternDatabaseStorage, InternEnumQuery, InternExternBlockQuery, // InternExternCrateQuery, InternFunctionQuery, InternImplQuery, InternInTypeConstQuery, @@ -19,7 +19,7 @@ pub use hir_def::db::DefDatabase; // InternStructQuery, InternTraitAliasQuery, InternTraitQuery, InternTypeAliasQuery, // InternUnionQuery, InternUseQuery, LangItemQuery, Macro2DataQuery, MacroDefQuery, // MacroRulesDataQuery, NotableTraitsInDepsQuery, ProcMacroDataQuery, StaticDataQuery, -// StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitDataWithDiagnosticsQuery, +// StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitItemsWithDiagnosticsQuery, // TypeAliasDataQuery, UnionDataWithDiagnosticsQuery, // }; pub use hir_expand::db::ExpandDatabase; diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 5da2b5ed09361..5cc330fb38f3b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -636,7 +636,7 @@ impl Module { acc.extend(def.diagnostics(db, style_lints)) } ModuleDef::Trait(t) => { - for diag in db.trait_data_with_diagnostics(t.id).1.iter() { + for diag in db.trait_items_with_diagnostics(t.id).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } @@ -743,7 +743,7 @@ impl Module { let ast_id_map = db.ast_id_map(file_id); - for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() { + for diag in db.impl_items_with_diagnostics(impl_def.id).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } @@ -801,13 +801,13 @@ impl Module { // Negative impls can't have items, don't emit missing items diagnostic for them if let (false, Some(trait_)) = (impl_is_negative, trait_) { - let items = &db.trait_data(trait_.into()).items; + let items = &db.trait_items(trait_.into()).items; let required_items = items.iter().filter(|&(_, assoc)| match *assoc { AssocItemId::FunctionId(it) => !db.function_data(it).has_body(), AssocItemId::ConstId(id) => !db.const_data(id).has_body, AssocItemId::TypeAliasId(it) => db.type_alias_data(it).type_ref.is_none(), }); - impl_assoc_items_scratch.extend(db.impl_data(impl_def.id).items.iter().cloned()); + impl_assoc_items_scratch.extend(db.impl_items(impl_def.id).items.iter().cloned()); let redundant = impl_assoc_items_scratch .iter() @@ -863,7 +863,7 @@ impl Module { source_map, ); - for &(_, item) in db.impl_data(impl_def.id).items.iter() { + for &(_, item) in db.impl_items(impl_def.id).items.iter() { AssocItem::from(item).diagnostics(db, acc, style_lints); } } @@ -2868,16 +2868,15 @@ impl Trait { } pub fn function(self, db: &dyn HirDatabase, name: impl PartialEq) -> Option { - db.trait_data(self.id).items.iter().find(|(n, _)| name == *n).and_then( - |&(_, it)| match it { - AssocItemId::FunctionId(id) => Some(Function { id }), - _ => None, - }, - ) + db.trait_items(self.id).items.iter().find(|(n, _)| name == *n).and_then(|&(_, it)| match it + { + AssocItemId::FunctionId(id) => Some(Function { id }), + _ => None, + }) } pub fn items(self, db: &dyn HirDatabase) -> Vec { - db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() + db.trait_items(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() } pub fn items_with_supertraits(self, db: &dyn HirDatabase) -> Vec { @@ -2921,7 +2920,7 @@ impl Trait { } fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId, MacroCallId)]> { - db.trait_data(self.id) + db.trait_items(self.id) .macro_calls .as_ref() .map(|it| it.as_ref().clone().into_boxed_slice()) @@ -4428,7 +4427,7 @@ impl Impl { } pub fn items(self, db: &dyn HirDatabase) -> Vec { - db.impl_data(self.id).items.iter().map(|&(_, it)| it.into()).collect() + db.impl_items(self.id).items.iter().map(|&(_, it)| it.into()).collect() } pub fn is_negative(self, db: &dyn HirDatabase) -> bool { @@ -4478,7 +4477,7 @@ impl Impl { } fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId, MacroCallId)]> { - db.impl_data(self.id) + db.impl_items(self.id) .macro_calls .as_ref() .map(|it| it.as_ref().clone().into_boxed_slice()) @@ -4959,7 +4958,7 @@ impl Type { } let output_assoc_type = db - .trait_data(trait_) + .trait_items(trait_) .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone()))?; self.normalize_trait_assoc_type(db, &[], output_assoc_type.into()) } @@ -4975,7 +4974,7 @@ impl Type { pub fn iterator_item(self, db: &dyn HirDatabase) -> Option { let iterator_trait = db.lang_item(self.env.krate, LangItem::Iterator)?.as_trait()?; let iterator_item = db - .trait_data(iterator_trait) + .trait_items(iterator_trait) .associated_type_by_name(&Name::new_symbol_root(sym::Item.clone()))?; self.normalize_trait_assoc_type(db, &[], iterator_item.into()) } @@ -5007,7 +5006,7 @@ impl Type { } let into_iter_assoc_type = db - .trait_data(trait_) + .trait_items(trait_) .associated_type_by_name(&Name::new_symbol_root(sym::IntoIter.clone()))?; self.normalize_trait_assoc_type(db, &[], into_iter_assoc_type.into()) } @@ -5301,7 +5300,7 @@ impl Type { let impls = db.inherent_impls_in_crate(krate); for impl_def in impls.for_self_ty(&self.ty) { - for &(_, item) in db.impl_data(*impl_def).items.iter() { + for &(_, item) in db.impl_items(*impl_def).items.iter() { if callback(item) { return; } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index da9bb8b15c8c0..556b21124dd5c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -34,7 +34,7 @@ pub(crate) trait ChildBySource { impl ChildBySource for TraitId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { - let data = db.trait_data(*self); + let data = db.trait_items(*self); data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( |(ast_id, call_id)| { @@ -49,7 +49,7 @@ impl ChildBySource for TraitId { impl ChildBySource for ImplId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { - let data = db.impl_data(*self); + let data = db.impl_items(*self); // FIXME: Macro calls data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( |(ast_id, call_id)| { diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index aa0eac9478a22..e390fb0b935ff 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -1291,7 +1291,7 @@ impl SourceAnalyzer { method_name: &Name, ) -> Option<(TraitId, FunctionId)> { let trait_id = db.lang_item(self.resolver.krate(), lang_trait)?.as_trait()?; - let fn_id = db.trait_data(trait_id).method_by_name(method_name)?; + let fn_id = db.trait_items(trait_id).method_by_name(method_name)?; Some((trait_id, fn_id)) } @@ -1453,7 +1453,7 @@ fn resolve_hir_path_( // within the trait's associated types. if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) { if let Some(type_alias_id) = - db.trait_data(trait_id).associated_type_by_name(unresolved.name) + db.trait_items(trait_id).associated_type_by_name(unresolved.name) { return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into())); } @@ -1586,7 +1586,7 @@ fn resolve_hir_path_qualifier( // within the trait's associated types. if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) { if let Some(type_alias_id) = - db.trait_data(trait_id).associated_type_by_name(unresolved.name) + db.trait_items(trait_id).associated_type_by_name(unresolved.name) { return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into())); } diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 2a6c15207a337..853df7ee2d88a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -313,7 +313,7 @@ impl<'a> SymbolCollector<'a> { .to_smolstr(), ); self.with_container_name(impl_name, |s| { - for &(ref name, assoc_item_id) in &impl_data.items { + for &(ref name, assoc_item_id) in &self.db.impl_items(impl_id).items { s.push_assoc_item(assoc_item_id, name) } }) @@ -322,7 +322,7 @@ impl<'a> SymbolCollector<'a> { fn collect_from_trait(&mut self, trait_id: TraitId) { let trait_data = self.db.trait_data(trait_id); self.with_container_name(Some(trait_data.name.as_str().into()), |s| { - for &(ref name, assoc_item_id) in &trait_data.items { + for &(ref name, assoc_item_id) in &self.db.trait_items(trait_id).items { s.push_assoc_item(assoc_item_id, name); } }); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs index 4c8940db95cc7..6b08ada34b609 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs @@ -162,7 +162,7 @@ impl RootDatabase { // hir::db::FunctionVisibilityQuery // hir::db::GenericParamsQuery // hir::db::GenericParamsWithSourceMapQuery - // hir::db::ImplDataWithDiagnosticsQuery + // hir::db::ImplItemsWithDiagnosticsQuery // hir::db::ImportMapQuery // hir::db::IncludeMacroInvocQuery // hir::db::InternAnonymousConstQuery @@ -193,7 +193,7 @@ impl RootDatabase { // hir::db::StaticDataQuery // hir::db::StructDataWithDiagnosticsQuery // hir::db::TraitAliasDataQuery - // hir::db::TraitDataWithDiagnosticsQuery + // hir::db::TraitItemsWithDiagnosticsQuery // hir::db::TypeAliasDataQuery // hir::db::UnionDataWithDiagnosticsQuery From 1835bc2a874b6f55af759dbf7361370a65294b62 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 26 Feb 2025 07:55:00 +0100 Subject: [PATCH 020/260] Move attribute parsing out of data module --- .../rust-analyzer/crates/hir-def/src/attr.rs | 125 ++++++++++++++++++ .../rust-analyzer/crates/hir-def/src/data.rs | 33 +---- .../crates/hir-def/src/data/adt.rs | 94 +------------ 3 files changed, 128 insertions(+), 124 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 579ea12e6ae03..030d064584cd6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -12,6 +12,7 @@ use hir_expand::{ use intern::{sym, Symbol}; use la_arena::{ArenaMap, Idx, RawIdx}; use mbe::DelimiterKind; +use rustc_abi::ReprOptions; use syntax::{ ast::{self, HasAttrs}, AstPtr, @@ -221,6 +222,130 @@ impl Attrs { pub fn is_unstable(&self) -> bool { self.by_key(&sym::unstable).exists() } + + pub fn rustc_legacy_const_generics(&self) -> Option>> { + self.by_key(&sym::rustc_legacy_const_generics) + .tt_values() + .next() + .map(parse_rustc_legacy_const_generics) + .filter(|it| !it.is_empty()) + .map(Box::new) + } + + pub fn repr(&self) -> Option { + self.by_key(&sym::repr).tt_values().find_map(parse_repr_tt) + } +} + +fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> { + let mut indices = Vec::new(); + let mut iter = tt.iter(); + while let (Some(first), second) = (iter.next(), iter.next()) { + match first { + TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() { + Ok(index) => indices.push(index), + Err(_) => break, + }, + _ => break, + } + + if let Some(comma) = second { + match comma { + TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {} + _ => break, + } + } + } + + indices.into_boxed_slice() +} + +fn parse_repr_tt(tt: &crate::tt::TopSubtree) -> Option { + use crate::builtin_type::{BuiltinInt, BuiltinUint}; + use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions}; + + match tt.top_subtree().delimiter { + tt::Delimiter { kind: DelimiterKind::Parenthesis, .. } => {} + _ => return None, + } + + let mut flags = ReprFlags::empty(); + let mut int = None; + let mut max_align: Option = None; + let mut min_pack: Option = None; + + let mut tts = tt.iter(); + while let Some(tt) = tts.next() { + if let TtElement::Leaf(tt::Leaf::Ident(ident)) = tt { + flags.insert(match &ident.sym { + s if *s == sym::packed => { + let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { + tts.next(); + if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() { + lit.symbol.as_str().parse().unwrap_or_default() + } else { + 0 + } + } else { + 0 + }; + let pack = Align::from_bytes(pack).unwrap_or(Align::ONE); + min_pack = + Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack }); + ReprFlags::empty() + } + s if *s == sym::align => { + if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { + tts.next(); + if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() { + if let Ok(align) = lit.symbol.as_str().parse() { + let align = Align::from_bytes(align).ok(); + max_align = max_align.max(align); + } + } + } + ReprFlags::empty() + } + s if *s == sym::C => ReprFlags::IS_C, + s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT, + s if *s == sym::simd => ReprFlags::IS_SIMD, + repr => { + if let Some(builtin) = BuiltinInt::from_suffix_sym(repr) + .map(Either::Left) + .or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right)) + { + int = Some(match builtin { + Either::Left(bi) => match bi { + BuiltinInt::Isize => IntegerType::Pointer(true), + BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true), + BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true), + BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true), + BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true), + BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true), + }, + Either::Right(bu) => match bu { + BuiltinUint::Usize => IntegerType::Pointer(false), + BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false), + BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false), + BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false), + BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false), + BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false), + }, + }); + } + ReprFlags::empty() + } + }) + } + } + + Some(ReprOptions { + int, + align: max_align, + pack: min_pack, + flags, + field_shuffle_seed: rustc_hashes::Hash64::ZERO, + }) } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index 8a1f07c92efff..1a6bed6cabbdd 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -7,7 +7,6 @@ use hir_expand::name::Name; use intern::{sym, Symbol}; use la_arena::{Idx, RawIdx}; use triomphe::Arc; -use tt::iter::TtElement; use crate::{ db::DefDatabase, @@ -73,13 +72,6 @@ impl FunctionData { } let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); - let legacy_const_generics_indices = attrs - .by_key(&sym::rustc_legacy_const_generics) - .tt_values() - .next() - .map(parse_rustc_legacy_const_generics) - .filter(|it| !it.is_empty()) - .map(Box::new); let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists(); if flags.contains(FnFlags::HAS_UNSAFE_KW) && attrs.by_key(&sym::rustc_deprecated_safe_2024).exists() @@ -106,7 +98,7 @@ impl FunctionData { ret_type: func.ret_type, visibility, abi: func.abi.clone(), - legacy_const_generics_indices, + legacy_const_generics_indices: attrs.rustc_legacy_const_generics(), types_map: func.types_map.clone(), flags, rustc_allow_incoherent_impl, @@ -156,29 +148,6 @@ impl FunctionData { } } -fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> { - let mut indices = Vec::new(); - let mut iter = tt.iter(); - while let (Some(first), second) = (iter.next(), iter.next()) { - match first { - TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() { - Ok(index) => indices.push(index), - Err(_) => break, - }, - _ => break, - } - - if let Some(comma) = second { - match comma { - TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {} - _ => break, - } - } - } - - indices.into_boxed_slice() -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct TypeAliasData { pub name: Name, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index bf8f5024c2d6a..161b205c80941 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -3,18 +3,14 @@ use base_db::Crate; use bitflags::bitflags; use cfg::CfgOptions; -use either::Either; use hir_expand::name::Name; use intern::sym; use la_arena::Arena; -use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions}; -use rustc_hashes::Hash64; +use rustc_abi::{IntegerType, ReprOptions}; use triomphe::Arc; -use tt::iter::TtElement; use crate::{ - builtin_type::{BuiltinInt, BuiltinUint}, db::DefDatabase, hir::Expr, item_tree::{ @@ -22,7 +18,6 @@ use crate::{ }, lang_item::LangItem, nameres::diagnostics::{DefDiagnostic, DefDiagnostics}, - tt::{Delimiter, DelimiterKind, Leaf, TopSubtree}, type_ref::{TypeRefId, TypesMap}, visibility::RawVisibility, EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId, @@ -94,92 +89,7 @@ fn repr_from_value( item_tree: &ItemTree, of: AttrOwner, ) -> Option { - item_tree.attrs(db, krate, of).by_key(&sym::repr).tt_values().find_map(parse_repr_tt) -} - -fn parse_repr_tt(tt: &TopSubtree) -> Option { - match tt.top_subtree().delimiter { - Delimiter { kind: DelimiterKind::Parenthesis, .. } => {} - _ => return None, - } - - let mut flags = ReprFlags::empty(); - let mut int = None; - let mut max_align: Option = None; - let mut min_pack: Option = None; - - let mut tts = tt.iter(); - while let Some(tt) = tts.next() { - if let TtElement::Leaf(Leaf::Ident(ident)) = tt { - flags.insert(match &ident.sym { - s if *s == sym::packed => { - let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { - tts.next(); - if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() { - lit.symbol.as_str().parse().unwrap_or_default() - } else { - 0 - } - } else { - 0 - }; - let pack = Align::from_bytes(pack).unwrap_or(Align::ONE); - min_pack = - Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack }); - ReprFlags::empty() - } - s if *s == sym::align => { - if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { - tts.next(); - if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() { - if let Ok(align) = lit.symbol.as_str().parse() { - let align = Align::from_bytes(align).ok(); - max_align = max_align.max(align); - } - } - } - ReprFlags::empty() - } - s if *s == sym::C => ReprFlags::IS_C, - s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT, - s if *s == sym::simd => ReprFlags::IS_SIMD, - repr => { - if let Some(builtin) = BuiltinInt::from_suffix_sym(repr) - .map(Either::Left) - .or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right)) - { - int = Some(match builtin { - Either::Left(bi) => match bi { - BuiltinInt::Isize => IntegerType::Pointer(true), - BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true), - BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true), - BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true), - BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true), - BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true), - }, - Either::Right(bu) => match bu { - BuiltinUint::Usize => IntegerType::Pointer(false), - BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false), - BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false), - BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false), - BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false), - BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false), - }, - }); - } - ReprFlags::empty() - } - }) - } - } - - Some(ReprOptions { - int, - align: max_align, - pack: min_pack, - flags, - field_shuffle_seed: Hash64::ZERO, - }) + item_tree.attrs(db, krate, of).repr() } impl StructData { From 176981ef495ebd9117f15a1520c470661c4d10da Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 26 Feb 2025 08:02:53 +0100 Subject: [PATCH 021/260] Split enum variants out of `enum_data` query --- .../crates/hir-def/src/data/adt.rs | 60 ++++++++++++------- .../rust-analyzer/crates/hir-def/src/db.rs | 5 +- .../crates/hir-ty/src/chalk_db.rs | 2 +- .../crates/hir-ty/src/consteval.rs | 2 +- .../hir-ty/src/diagnostics/decl_check.rs | 2 +- .../crates/hir-ty/src/diagnostics/expr.rs | 2 +- .../diagnostics/match_check/pat_analysis.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/drop.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 4 +- .../crates/hir-ty/src/infer/cast.rs | 2 +- .../crates/hir-ty/src/infer/closure.rs | 2 +- .../crates/hir-ty/src/infer/path.rs | 2 +- .../crates/hir-ty/src/inhabitedness.rs | 2 +- .../crates/hir-ty/src/layout/adt.rs | 8 +-- .../crates/hir-ty/src/mir/eval.rs | 5 +- .../rust-analyzer/crates/hir-ty/src/tests.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/utils.rs | 6 +- .../crates/hir-ty/src/variance.rs | 2 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 6 +- .../hir/src/semantics/child_by_source.rs | 2 +- .../ide-completion/src/completions/pattern.rs | 4 +- 21 files changed, 74 insertions(+), 52 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index 161b205c80941..c8429d8b6897f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -56,12 +56,16 @@ bitflags! { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumData { pub name: Name, - pub variants: Box<[(EnumVariantId, Name)]>, pub repr: Option, pub visibility: RawVisibility, pub rustc_has_incoherent_inherent_impls: bool, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EnumVariants { + pub variants: Box<[(EnumVariantId, Name)]>, +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumVariantData { pub name: Name, @@ -203,28 +207,16 @@ impl StructData { } } -impl EnumData { - pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc { +impl EnumVariants { + pub(crate) fn enum_variants_query(db: &dyn DefDatabase, e: EnumId) -> Arc { let loc = e.lookup(db); - let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); - let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); - let rustc_has_incoherent_inherent_impls = item_tree - .attrs(db, loc.container.krate, ModItem::from(loc.id.value).into()) - .by_key(&sym::rustc_has_incoherent_inherent_impls) - .exists(); - - let enum_ = &item_tree[loc.id.value]; - Arc::new(EnumData { - name: enum_.name.clone(), + Arc::new(EnumVariants { variants: loc.container.def_map(db).enum_definitions[&e] .iter() .map(|&id| (id, item_tree[id.lookup(db).id.value].name.clone())) .collect(), - repr, - visibility: item_tree[enum_.visibility].clone(), - rustc_has_incoherent_inherent_impls, }) } @@ -233,13 +225,6 @@ impl EnumData { Some(id) } - pub fn variant_body_type(&self) -> IntegerType { - match self.repr { - Some(ReprOptions { int: Some(builtin), .. }) => builtin, - _ => IntegerType::Pointer(true), - } - } - // [Adopted from rustc](https://github.com/rust-lang/rust/blob/bd53aa3bf7a24a70d763182303bd75e5fc51a9af/compiler/rustc_middle/src/ty/adt.rs#L446-L448) pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool { self.variants.iter().all(|(v, _)| { @@ -262,6 +247,35 @@ impl EnumData { } } +impl EnumData { + pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc { + let loc = e.lookup(db); + let krate = loc.container.krate; + let item_tree = loc.id.item_tree(db); + let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); + let rustc_has_incoherent_inherent_impls = item_tree + .attrs(db, loc.container.krate, ModItem::from(loc.id.value).into()) + .by_key(&sym::rustc_has_incoherent_inherent_impls) + .exists(); + + let enum_ = &item_tree[loc.id.value]; + + Arc::new(EnumData { + name: enum_.name.clone(), + repr, + visibility: item_tree[enum_.visibility].clone(), + rustc_has_incoherent_inherent_impls, + }) + } + + pub fn variant_body_type(&self) -> IntegerType { + match self.repr { + Some(ReprOptions { int: Some(builtin), .. }) => builtin, + _ => IntegerType::Pointer(true), + } + } +} + impl EnumVariantData { #[inline] pub(crate) fn enum_variant_data_query( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index ff33056538071..bc9fc8e079306 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -11,7 +11,7 @@ use triomphe::Arc; use crate::{ attr::{Attrs, AttrsWithOwner}, data::{ - adt::{EnumData, EnumVariantData, StructData, VariantData}, + adt::{EnumData, EnumVariantData, EnumVariants, StructData, VariantData}, ConstData, ExternCrateDeclData, FunctionData, ImplData, Macro2Data, MacroRulesData, ProcMacroData, StaticData, TraitAliasData, TraitData, TypeAliasData, }, @@ -167,6 +167,9 @@ pub trait DefDatabase: #[salsa::invoke_actual(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; + #[salsa::invoke_actual(EnumVariants::enum_variants_query)] + fn enum_variants(&self, e: EnumId) -> Arc; + #[salsa::transparent] #[salsa::invoke_actual(EnumVariantData::enum_variant_data_query)] fn enum_variant_data(&self, id: EnumVariantId) -> Arc; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index e5751a394dae5..ac4d1babd62b4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -801,7 +801,7 @@ pub(crate) fn adt_datum_query( } hir_def::AdtId::EnumId(id) => { let variants = db - .enum_data(id) + .enum_variants(id) .variants .iter() .map(|&(variant_id, _)| variant_id_to_fields(variant_id.into())) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 525672bc39951..ec8f9b7c31186 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -309,7 +309,7 @@ pub(crate) fn const_eval_discriminant_variant( let value = match prev_idx { Some(prev_idx) => { 1 + db.const_eval_discriminant( - db.enum_data(loc.parent).variants[prev_idx as usize].0, + db.enum_variants(loc.parent).variants[prev_idx as usize].0, )? } _ => 0, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index a0b1fe32ce52d..0b21ae7ade377 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -394,7 +394,7 @@ impl<'a> DeclValidator<'a> { /// Check incorrect names for enum variants. fn validate_enum_variants(&mut self, enum_id: EnumId) { - let data = self.db.enum_data(enum_id); + let data = self.db.enum_variants(enum_id); for (variant_id, _) in data.variants.iter() { self.validate_enum_variant_fields(*variant_id); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 1035651692ec8..6096439565cba 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -642,7 +642,7 @@ fn missing_match_arms<'p>( } let non_empty_enum = match scrut_ty.as_adt() { - Some((AdtId::EnumId(e), _)) => !cx.db.enum_data(e).variants.is_empty(), + Some((AdtId::EnumId(e), _)) => !cx.db.enum_variants(e).variants.is_empty(), _ => false, }; let display_target = DisplayTarget::from_crate(cx.db, krate); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 91eb59fb3140f..b7f8a0c610c54 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -49,7 +49,7 @@ impl EnumVariantContiguousIndex { } fn to_enum_variant_id(self, db: &dyn HirDatabase, eid: EnumId) -> EnumVariantId { - db.enum_data(eid).variants[self.0].0 + db.enum_variants(eid).variants[self.0].0 } } @@ -449,7 +449,7 @@ impl PatCx for MatchCheckCtx<'_> { TyKind::Scalar(Scalar::Int(..) | Scalar::Uint(..)) => unhandled(), TyKind::Array(..) | TyKind::Slice(..) => unhandled(), &TyKind::Adt(AdtId(adt @ hir_def::AdtId::EnumId(enum_id)), ref subst) => { - let enum_data = cx.db.enum_data(enum_id); + let enum_data = cx.db.enum_variants(enum_id); let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive(adt); if enum_data.variants.is_empty() && !is_declared_nonexhaustive { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index 4ad16cf8bcf7e..ab17f86b5b2cb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -72,7 +72,7 @@ pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc DropGlue::None, AdtId::EnumId(id) => db - .enum_data(id) + .enum_variants(id) .variants .iter() .map(|&(variant, _)| { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 9a4b7af85d8f9..ecadfccf00299 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -1587,7 +1587,7 @@ impl<'a> InferenceContext<'a> { // If we can resolve to an enum variant, it takes priority over associated type // of the same name. if let Some((AdtId::EnumId(id), _)) = ty.as_adt() { - let enum_data = self.db.enum_data(id); + let enum_data = self.db.enum_variants(id); if let Some(variant) = enum_data.variant(current_segment.name) { return if remaining_segments.len() == 1 { (ty, Some(variant.into())) @@ -1701,7 +1701,7 @@ impl<'a> InferenceContext<'a> { let segment = path.segments().last().unwrap(); // this could be an enum variant or associated type if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() { - let enum_data = self.db.enum_data(enum_id); + let enum_data = self.db.enum_variants(enum_id); if let Some(variant) = enum_data.variant(segment) { return (ty, Some(variant.into())); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index eb193686e967f..6c0e0b0273761 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs @@ -43,7 +43,7 @@ impl CastTy { let (AdtId::EnumId(id), _) = t.as_adt()? else { return None; }; - let enum_data = table.db.enum_data(id); + let enum_data = table.db.enum_variants(id); if enum_data.is_payload_free(table.db.upcast()) { Some(Self::Int(Int::CEnum)) } else { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index ef02762c80a53..6c50f056c18af 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -963,7 +963,7 @@ impl InferenceContext<'_> { if let Some(variant) = self.result.variant_resolution_for_pat(p) { let adt = variant.adt_id(self.db.upcast()); let is_multivariant = match adt { - hir_def::AdtId::EnumId(e) => self.db.enum_data(e).variants.len() != 1, + hir_def::AdtId::EnumId(e) => self.db.enum_variants(e).variants.len() != 1, _ => false, }; if is_multivariant { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 29f455a61b941..8ff0cf308224c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -398,7 +398,7 @@ impl InferenceContext<'_> { Some((AdtId::EnumId(e), subst)) => (e, subst), _ => return None, }; - let enum_data = self.db.enum_data(enum_id); + let enum_data = self.db.enum_variants(enum_id); let variant = enum_data.variant(name)?; self.write_variant_resolution(id, variant.into()); Some((ValueNs::EnumVariantId(variant), subst.clone())) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs index d6039c548b6f5..800ba0d454490 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs @@ -98,7 +98,7 @@ impl UninhabitedFrom<'_> { AdtId::UnionId(_) => CONTINUE_OPAQUELY_INHABITED, AdtId::StructId(s) => self.visit_variant(s.into(), subst), AdtId::EnumId(e) => { - let enum_data = self.db.enum_data(e); + let enum_data = self.db.enum_variants(e); for &(variant, _) in enum_data.variants.iter() { let variant_inhabitedness = self.visit_variant(variant.into(), subst); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index ab9c07779c07a..40a1d4e6707ab 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -54,13 +54,13 @@ pub fn layout_of_adt_query( (r, data.repr.unwrap_or_default()) } AdtId::EnumId(e) => { - let data = db.enum_data(e); - let r = data + let variants = db.enum_variants(e); + let r = variants .variants .iter() .map(|&(v, _)| handle_variant(v.into(), &db.enum_variant_data(v).variant_data)) .collect::, _>>()?; - (r, data.repr.unwrap_or_default()) + (r, db.enum_data(e).repr.unwrap_or_default()) } }; let variants = variants @@ -80,7 +80,7 @@ pub fn layout_of_adt_query( |min, max| repr_discr(dl, &repr, min, max).unwrap_or((Integer::I8, false)), variants.iter_enumerated().filter_map(|(id, _)| { let AdtId::EnumId(e) = def else { return None }; - let d = db.const_eval_discriminant(db.enum_data(e).variants[id.0].0).ok()?; + let d = db.const_eval_discriminant(db.enum_variants(e).variants[id.0].0).ok()?; Some((id, d)) }), // FIXME: The current code for niche-filling relies on variant indices diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 97710aab06c76..25aa2606558c1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -1641,7 +1641,8 @@ impl Evaluator<'_> { match &layout.variants { Variants::Empty => unreachable!(), Variants::Single { index } => { - let r = self.const_eval_discriminant(self.db.enum_data(e).variants[index.0].0)?; + let r = + self.const_eval_discriminant(self.db.enum_variants(e).variants[index.0].0)?; Ok(r) } Variants::Multiple { tag, tag_encoding, variants, .. } => { @@ -1666,7 +1667,7 @@ impl Evaluator<'_> { .unwrap_or(*untagged_variant) .0; let result = - self.const_eval_discriminant(self.db.enum_data(e).variants[idx].0)?; + self.const_eval_discriminant(self.db.enum_variants(e).variants[idx].0)?; Ok(result) } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index 9ad07922fac71..13d74264c560d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -481,7 +481,7 @@ pub(crate) fn visit_module( visit_body(db, &body, cb); } ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => { - db.enum_data(it).variants.iter().for_each(|&(it, _)| { + db.enum_variants(it).variants.iter().for_each(|&(it, _)| { let body = db.body(it.into()); cb(it.into()); visit_body(db, &body, cb); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index cbb78ef40d84e..3bd04b21b285d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -369,7 +369,7 @@ pub(crate) fn detect_variant_from_bytes<'a>( let (var_id, var_layout) = match &layout.variants { hir_def::layout::Variants::Empty => unreachable!(), hir_def::layout::Variants::Single { index } => { - (db.enum_data(e).variants[index.0].0, layout) + (db.enum_variants(e).variants[index.0].0, layout) } hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => { let size = tag.size(target_data_layout).bytes_usize(); @@ -379,7 +379,7 @@ pub(crate) fn detect_variant_from_bytes<'a>( TagEncoding::Direct => { let (var_idx, layout) = variants.iter_enumerated().find_map(|(var_idx, v)| { - let def = db.enum_data(e).variants[var_idx.0].0; + let def = db.enum_variants(e).variants[var_idx.0].0; (db.const_eval_discriminant(def) == Ok(tag)).then_some((def, v)) })?; (var_idx, layout) @@ -392,7 +392,7 @@ pub(crate) fn detect_variant_from_bytes<'a>( .filter(|x| x != untagged_variant) .nth(candidate_tag) .unwrap_or(*untagged_variant); - (db.enum_data(e).variants[variant.0].0, &variants[variant]) + (db.enum_variants(e).variants[variant.0].0, &variants[variant]) } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index 425196d92f79a..ab3d098908893 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -206,7 +206,7 @@ impl Context<'_> { AdtId::StructId(s) => add_constraints_from_variant(VariantId::StructId(s)), AdtId::UnionId(u) => add_constraints_from_variant(VariantId::UnionId(u)), AdtId::EnumId(e) => { - db.enum_data(e).variants.iter().for_each(|&(variant, _)| { + db.enum_variants(e).variants.iter().for_each(|&(variant, _)| { add_constraints_from_variant(VariantId::EnumVariantId(variant)) }); } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 5cc330fb38f3b..f78b7a5c435cb 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -1519,7 +1519,11 @@ impl Enum { } pub fn variants(self, db: &dyn HirDatabase) -> Vec { - db.enum_data(self.id).variants.iter().map(|&(id, _)| Variant { id }).collect() + db.enum_variants(self.id).variants.iter().map(|&(id, _)| Variant { id }).collect() + } + + pub fn num_variants(self, db: &dyn HirDatabase) -> usize { + db.enum_variants(self.id).variants.len() } pub fn repr(self, db: &dyn HirDatabase) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index 556b21124dd5c..b89d332238b65 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -182,7 +182,7 @@ impl ChildBySource for EnumId { let tree = loc.id.item_tree(db); let ast_id_map = db.ast_id_map(loc.id.file_id()); - db.enum_data(*self).variants.iter().for_each(|&(variant, _)| { + db.enum_variants(*self).variants.iter().for_each(|&(variant, _)| { res[keys::ENUM_VARIANT] .insert(ast_id_map.get(tree[variant.lookup(db).id.value].ast_id), variant); }); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs index 8f38e02ed7685..9df13c5a4ef53 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs @@ -1,6 +1,6 @@ //! Completes constants and paths in unqualified patterns. -use hir::{db::DefDatabase, AssocItem, ScopeDef}; +use hir::{AssocItem, ScopeDef}; use ide_db::syntax_helpers::suggest_name; use syntax::ast::Pat; @@ -60,7 +60,7 @@ pub(crate) fn complete_pattern( } let refutable = pattern_ctx.refutability == PatternRefutability::Refutable; - let single_variant_enum = |enum_: hir::Enum| ctx.db.enum_data(enum_.into()).variants.len() == 1; + let single_variant_enum = |enum_: hir::Enum| enum_.num_variants(ctx.db) == 1; if let Some(hir::Adt::Enum(e)) = ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt()) From 2e83e8a84d614292e126728eab28d1492f35382e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 27 Feb 2025 11:22:29 +0100 Subject: [PATCH 022/260] Split `variant_data` into its own query --- .../rust-analyzer/crates/hir-def/src/attr.rs | 2 +- .../crates/hir-def/src/data/adt.rs | 215 +++++++++--------- .../rust-analyzer/crates/hir-def/src/db.rs | 24 +- .../crates/hir-def/src/expr_store/lower.rs | 2 +- .../crates/hir-def/src/item_tree.rs | 2 +- .../crates/hir-def/src/item_tree/lower.rs | 2 +- .../crates/hir-def/src/item_tree/pretty.rs | 7 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 6 +- .../crates/hir-def/src/resolver.rs | 9 +- .../rust-analyzer/crates/hir-def/src/src.rs | 2 +- .../crates/hir-ty/src/chalk_db.rs | 2 +- .../hir-ty/src/diagnostics/decl_check.rs | 8 +- .../crates/hir-ty/src/display.rs | 4 +- .../crates/hir-ty/src/infer/cast.rs | 4 +- .../crates/hir-ty/src/infer/closure.rs | 4 +- .../crates/hir-ty/src/infer/expr.rs | 12 +- .../crates/hir-ty/src/infer/unify.rs | 5 +- .../rust-analyzer/crates/hir-ty/src/layout.rs | 8 +- .../crates/hir-ty/src/layout/adt.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 26 +-- .../crates/hir-ty/src/mir/eval.rs | 10 +- .../crates/hir-ty/src/mir/eval/shim/simd.rs | 4 +- .../crates/hir-ty/src/mir/lower.rs | 5 +- .../hir-ty/src/mir/lower/pattern_matching.rs | 4 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 23 +- .../crates/ide-db/src/apply_change.rs | 4 +- 26 files changed, 189 insertions(+), 211 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 030d064584cd6..2775e1398c28d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -84,7 +84,7 @@ impl Attrs { let krate = loc.parent.lookup(db).container.krate; item_tree = loc.id.item_tree(db); let variant = &item_tree[loc.id.value]; - (FieldParent::Variant(loc.id.value), &variant.fields, krate) + (FieldParent::EnumVariant(loc.id.value), &variant.fields, krate) } VariantId::StructId(it) => { let loc = it.lookup(db); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index c8429d8b6897f..9db66d6e91c99 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -27,7 +27,6 @@ use crate::{ #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructData { pub name: Name, - pub variant_data: Arc, pub repr: Option, pub visibility: RawVisibility, pub flags: StructFlags, @@ -69,7 +68,6 @@ pub struct EnumVariants { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumVariantData { pub name: Name, - pub variant_data: Arc, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -79,6 +77,94 @@ pub enum VariantData { Unit, } +impl VariantData { + #[inline] + pub(crate) fn variant_data_query(db: &dyn DefDatabase, id: VariantId) -> Arc { + db.variant_data_with_diagnostics(id).0 + } + + pub(crate) fn variant_data_with_diagnostics_query( + db: &dyn DefDatabase, + id: VariantId, + ) -> (Arc, DefDiagnostics) { + let (shape, types_map, (fields, diagnostics)) = match id { + VariantId::EnumVariantId(id) => { + let loc = id.lookup(db); + let item_tree = loc.id.item_tree(db); + let parent = loc.parent.lookup(db); + let krate = parent.container.krate; + let variant = &item_tree[loc.id.value]; + ( + variant.shape, + variant.types_map.clone(), + lower_fields( + db, + krate, + parent.container.local_id, + loc.id.tree_id(), + &item_tree, + krate.cfg_options(db), + FieldParent::EnumVariant(loc.id.value), + &variant.fields, + Some(item_tree[parent.id.value].visibility), + ), + ) + } + VariantId::StructId(id) => { + let loc = id.lookup(db); + let item_tree = loc.id.item_tree(db); + let krate = loc.container.krate; + let strukt = &item_tree[loc.id.value]; + ( + strukt.shape, + strukt.types_map.clone(), + lower_fields( + db, + krate, + loc.container.local_id, + loc.id.tree_id(), + &item_tree, + krate.cfg_options(db), + FieldParent::Struct(loc.id.value), + &strukt.fields, + None, + ), + ) + } + VariantId::UnionId(id) => { + let loc = id.lookup(db); + let item_tree = loc.id.item_tree(db); + let krate = loc.container.krate; + let union = &item_tree[loc.id.value]; + ( + FieldsShape::Record, + union.types_map.clone(), + lower_fields( + db, + krate, + loc.container.local_id, + loc.id.tree_id(), + &item_tree, + krate.cfg_options(db), + FieldParent::Union(loc.id.value), + &union.fields, + None, + ), + ) + } + }; + + ( + Arc::new(match shape { + FieldsShape::Record => VariantData::Record { fields, types_map }, + FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, + FieldsShape::Unit => VariantData::Unit, + }), + DefDiagnostics::new(diagnostics), + ) + } +} + /// A single field of an enum variant or struct #[derive(Debug, Clone, PartialEq, Eq)] pub struct FieldData { @@ -99,13 +185,6 @@ fn repr_from_value( impl StructData { #[inline] pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc { - db.struct_data_with_diagnostics(id).0 - } - - pub(crate) fn struct_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: StructId, - ) -> (Arc, DefDiagnostics) { let loc = id.lookup(db); let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); @@ -130,44 +209,16 @@ impl StructData { } let strukt = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - loc.container.local_id, - loc.id.tree_id(), - &item_tree, - krate.cfg_options(db), - FieldParent::Struct(loc.id.value), - &strukt.fields, - None, - ); - let types_map = strukt.types_map.clone(); - - ( - Arc::new(StructData { - name: strukt.name.clone(), - variant_data: Arc::new(match strukt.shape { - FieldsShape::Record => VariantData::Record { fields, types_map }, - FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, - FieldsShape::Unit => VariantData::Unit, - }), - repr, - visibility: item_tree[strukt.visibility].clone(), - flags, - }), - DefDiagnostics::new(diagnostics), - ) + Arc::new(StructData { + name: strukt.name.clone(), + repr, + visibility: item_tree[strukt.visibility].clone(), + flags, + }) } #[inline] pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc { - db.union_data_with_diagnostics(id).0 - } - - pub(crate) fn union_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: UnionId, - ) -> (Arc, DefDiagnostics) { let loc = id.lookup(db); let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); @@ -182,28 +233,13 @@ impl StructData { } let union = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - loc.container.local_id, - loc.id.tree_id(), - &item_tree, - krate.cfg_options(db), - FieldParent::Union(loc.id.value), - &union.fields, - None, - ); - let types_map = union.types_map.clone(); - ( - Arc::new(StructData { - name: union.name.clone(), - variant_data: Arc::new(VariantData::Record { fields, types_map }), - repr, - visibility: item_tree[union.visibility].clone(), - flags, - }), - DefDiagnostics::new(diagnostics), - ) + + Arc::new(StructData { + name: union.name.clone(), + repr, + visibility: item_tree[union.visibility].clone(), + flags, + }) } } @@ -227,16 +263,16 @@ impl EnumVariants { // [Adopted from rustc](https://github.com/rust-lang/rust/blob/bd53aa3bf7a24a70d763182303bd75e5fc51a9af/compiler/rustc_middle/src/ty/adt.rs#L446-L448) pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool { - self.variants.iter().all(|(v, _)| { + self.variants.iter().all(|&(v, _)| { // The condition check order is slightly modified from rustc // to improve performance by early returning with relatively fast checks - let variant = &db.enum_variant_data(*v).variant_data; + let variant = &db.variant_data(v.into()); if !variant.fields().is_empty() { return false; } // The outer if condition is whether this variant has const ctor or not if !matches!(variant.kind(), StructKind::Unit) { - let body = db.body((*v).into()); + let body = db.body(v.into()); // A variant with explicit discriminant if body.exprs[body.body_expr] != Expr::Missing { return false; @@ -282,43 +318,11 @@ impl EnumVariantData { db: &dyn DefDatabase, e: EnumVariantId, ) -> Arc { - db.enum_variant_data_with_diagnostics(e).0 - } - - pub(crate) fn enum_variant_data_with_diagnostics_query( - db: &dyn DefDatabase, - e: EnumVariantId, - ) -> (Arc, DefDiagnostics) { let loc = e.lookup(db); - let container = loc.parent.lookup(db).container; - let krate = container.krate; let item_tree = loc.id.item_tree(db); let variant = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - container.local_id, - loc.id.tree_id(), - &item_tree, - krate.cfg_options(db), - FieldParent::Variant(loc.id.value), - &variant.fields, - Some(item_tree[loc.parent.lookup(db).id.value].visibility), - ); - let types_map = variant.types_map.clone(); - - ( - Arc::new(EnumVariantData { - name: variant.name.clone(), - variant_data: Arc::new(match variant.shape { - FieldsShape::Record => VariantData::Record { fields, types_map }, - FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, - FieldsShape::Unit => VariantData::Unit, - }), - }), - DefDiagnostics::new(diagnostics), - ) + Arc::new(EnumVariantData { name: variant.name.clone() }) } } @@ -352,15 +356,6 @@ impl VariantData { VariantData::Unit => StructKind::Unit, } } - - #[allow(clippy::self_named_constructors)] - pub(crate) fn variant_data(db: &dyn DefDatabase, id: VariantId) -> Arc { - match id { - VariantId::StructId(it) => db.struct_data(it).variant_data.clone(), - VariantId::EnumVariantId(it) => db.enum_variant_data(it).variant_data.clone(), - VariantId::UnionId(it) => db.union_data(it).variant_data.clone(), - } - } } #[derive(Debug, Copy, Clone, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index bc9fc8e079306..108968fe52e2a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -151,39 +151,27 @@ pub trait DefDatabase: // region:data #[salsa::transparent] + #[salsa::invoke_actual(VariantData::variant_data_query)] + fn variant_data(&self, id: VariantId) -> Arc; + + #[salsa::invoke_actual(VariantData::variant_data_with_diagnostics_query)] + fn variant_data_with_diagnostics(&self, id: VariantId) -> (Arc, DefDiagnostics); + #[salsa::invoke_actual(StructData::struct_data_query)] fn struct_data(&self, id: StructId) -> Arc; - #[salsa::invoke_actual(StructData::struct_data_with_diagnostics_query)] - fn struct_data_with_diagnostics(&self, id: StructId) -> (Arc, DefDiagnostics); - - #[salsa::transparent] #[salsa::invoke_actual(StructData::union_data_query)] fn union_data(&self, id: UnionId) -> Arc; - #[salsa::invoke_actual(StructData::union_data_with_diagnostics_query)] - fn union_data_with_diagnostics(&self, id: UnionId) -> (Arc, DefDiagnostics); - #[salsa::invoke_actual(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; #[salsa::invoke_actual(EnumVariants::enum_variants_query)] fn enum_variants(&self, e: EnumId) -> Arc; - #[salsa::transparent] #[salsa::invoke_actual(EnumVariantData::enum_variant_data_query)] fn enum_variant_data(&self, id: EnumVariantId) -> Arc; - #[salsa::invoke_actual(EnumVariantData::enum_variant_data_with_diagnostics_query)] - fn enum_variant_data_with_diagnostics( - &self, - id: EnumVariantId, - ) -> (Arc, DefDiagnostics); - - #[salsa::transparent] - #[salsa::invoke_actual(VariantData::variant_data)] - fn variant_data(&self, id: VariantId) -> Arc; - #[salsa::invoke_actual(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index c346cec242eb6..b9b00108dcd24 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -1631,7 +1631,7 @@ impl ExprCollector<'_> { (None, Pat::Path(name.into())) } Some(ModuleDefId::AdtId(AdtId::StructId(s))) - if self.db.struct_data(s).variant_data.kind() != StructKind::Record => + if self.db.variant_data(s.into()).kind() != StructKind::Record => { (None, Pat::Path(name.into())) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 9acf98e62cd5c..d42104faa2e04 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -506,7 +506,7 @@ impl AttrOwner { pub enum FieldParent { Struct(FileItemTreeId), Union(FileItemTreeId), - Variant(FileItemTreeId), + EnumVariant(FileItemTreeId), } pub type ItemTreeParamId = Idx; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index b0546d4f33fde..05b99ae31f423 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -428,7 +428,7 @@ impl<'a> Ctx<'a> { for (idx, attr) in attrs { self.add_attrs( AttrOwner::Field( - FieldParent::Variant(FileItemTreeId(id)), + FieldParent::EnumVariant(FileItemTreeId(id)), Idx::from_raw(RawIdx::from_u32(idx as u32)), ), attr, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs index d113a500ef76f..e666b1ea6bc29 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs @@ -382,7 +382,12 @@ impl Printer<'_> { this.print_ast_id(ast_id.erase()); this.print_attrs_of(variant, "\n"); w!(this, "{}", name.display(self.db.upcast(), edition)); - this.print_fields(FieldParent::Variant(variant), *kind, fields, types_map); + this.print_fields( + FieldParent::EnumVariant(variant), + *kind, + fields, + types_map, + ); wln!(this, ","); } }); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index fbbeb4beb99b9..5f8cd0fde04ab 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -1104,11 +1104,7 @@ impl_from!(EnumVariantId, StructId, UnionId for VariantId); impl VariantId { pub fn variant_data(self, db: &dyn DefDatabase) -> Arc { - match self { - VariantId::StructId(it) => db.struct_data(it).variant_data.clone(), - VariantId::UnionId(it) => db.union_data(it).variant_data.clone(), - VariantId::EnumVariantId(it) => db.enum_variant_data(it).variant_data.clone(), - } + db.variant_data(self) } pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 72723499fc973..0ed26ca853e80 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -276,11 +276,16 @@ impl Resolver { db: &dyn DefDatabase, visibility: &RawVisibility, ) -> Option { - let within_impl = self.scopes().any(|scope| matches!(scope, Scope::ImplDefScope(_))); match visibility { RawVisibility::Module(_, _) => { let (item_map, item_local_map, module) = self.item_scope(); - item_map.resolve_visibility(item_local_map, db, module, visibility, within_impl) + item_map.resolve_visibility( + item_local_map, + db, + module, + visibility, + self.scopes().any(|scope| matches!(scope, Scope::ImplDefScope(_))), + ) } RawVisibility::Public => Some(Visibility::Public), } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs index 43d31aa503ce0..347c4803be1cc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs @@ -131,7 +131,7 @@ impl HasChildSource for VariantId { item_tree = lookup.id.item_tree(db); ( lookup.source(db).map(|it| it.kind()), - FieldParent::Variant(lookup.id.value), + FieldParent::EnumVariant(lookup.id.value), lookup.parent.lookup(db).container, ) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index ac4d1babd62b4..acaca24f54f9b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -137,7 +137,7 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS, Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS, - _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), + _ => self_ty_fp.as_slice(), }; let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 0b21ae7ade377..5106056d40971 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -307,8 +307,8 @@ impl<'a> DeclValidator<'a> { /// Check incorrect names for struct fields. fn validate_struct_fields(&mut self, struct_id: StructId) { - let data = self.db.struct_data(struct_id); - let VariantData::Record { fields, .. } = data.variant_data.as_ref() else { + let data = self.db.variant_data(struct_id.into()); + let VariantData::Record { fields, .. } = data.as_ref() else { return; }; let edition = self.edition(struct_id); @@ -467,8 +467,8 @@ impl<'a> DeclValidator<'a> { /// Check incorrect names for fields of enum variant. fn validate_enum_variant_fields(&mut self, variant_id: EnumVariantId) { - let variant_data = self.db.enum_variant_data(variant_id); - let VariantData::Record { fields, .. } = variant_data.variant_data.as_ref() else { + let variant_data = self.db.variant_data(variant_id.into()); + let VariantData::Record { fields, .. } = variant_data.as_ref() else { return; }; let edition = self.edition(variant_id); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index be590b6101d6a..7bce23f398a60 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -846,7 +846,7 @@ fn render_const_scalar( write!(f, "{}", data.name.display(f.db.upcast(), f.edition()))?; let field_types = f.db.field_types(s.into()); render_variant_after_name( - &data.variant_data, + &f.db.variant_data(s.into()), f, &field_types, f.db.trait_environment(adt.0.into()), @@ -872,7 +872,7 @@ fn render_const_scalar( write!(f, "{}", data.name.display(f.db.upcast(), f.edition()))?; let field_types = f.db.field_types(var_id.into()); render_variant_after_name( - &data.variant_data, + &f.db.variant_data(var_id.into()), f, &field_types, f.db.trait_environment(adt.0.into()), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index 6c0e0b0273761..8b43d0188a9de 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs @@ -389,8 +389,8 @@ fn pointer_kind(ty: &Ty, table: &mut InferenceTable<'_>) -> Result { self.consume_place(place) } VariantId::StructId(s) => { - let vd = &*self.db.struct_data(s).variant_data; + let vd = &*self.db.variant_data(s.into()); for field_pat in args.iter() { let arg = field_pat.pat; let Some(local_id) = vd.field(&field_pat.name) else { @@ -1211,7 +1211,7 @@ impl InferenceContext<'_> { self.consume_place(place) } VariantId::StructId(s) => { - let vd = &*self.db.struct_data(s).variant_data; + let vd = &*self.db.variant_data(s.into()); let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize)); let fields = vd.fields().iter(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index d0936185957f1..d0cbce70a2f14 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -1681,14 +1681,14 @@ impl InferenceContext<'_> { }) }); } - TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { - let local_id = self.db.struct_data(*s).variant_data.field(name)?; - let field = FieldId { parent: (*s).into(), local_id }; + &TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref parameters) => { + let local_id = self.db.variant_data(s.into()).field(name)?; + let field = FieldId { parent: s.into(), local_id }; (field, parameters.clone()) } - TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { - let local_id = self.db.union_data(*u).variant_data.field(name)?; - let field = FieldId { parent: (*u).into(), local_id }; + &TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), ref parameters) => { + let local_id = self.db.variant_data(u.into()).field(name)?; + let field = FieldId { parent: u.into(), local_id }; (field, parameters.clone()) } _ => return None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index a9332a5a96374..e55fc0a9b83d9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -928,9 +928,8 @@ impl<'a> InferenceTable<'a> { // Must use a loop here and not recursion because otherwise users will conduct completely // artificial examples of structs that have themselves as the tail field and complain r-a crashes. while let Some((AdtId::StructId(id), subst)) = ty.as_adt() { - let struct_data = self.db.struct_data(id); - if let Some((last_field, _)) = struct_data.variant_data.fields().iter().next_back() - { + let struct_data = self.db.variant_data(id.into()); + if let Some((last_field, _)) = struct_data.fields().iter().next_back() { let last_field_ty = self.db.field_types(id.into())[last_field] .clone() .substitute(Interner, subst); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 167dcec3bb3f8..2f7ad2b99d25b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -377,12 +377,12 @@ pub(crate) fn layout_of_ty_recover( fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty { match pointee.kind(Interner) { - TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), subst) => { - let data = db.struct_data(*i); - let mut it = data.variant_data.fields().iter().rev(); + &TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), ref subst) => { + let data = db.variant_data(i.into()); + let mut it = data.fields().iter().rev(); match it.next() { Some((f, _)) => { - let last_field_ty = field_ty(db, (*i).into(), f, subst); + let last_field_ty = field_ty(db, i.into(), f, subst); struct_tail_erasing_lifetimes(db, last_field_ty) } None => pointee, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index 40a1d4e6707ab..9f453162e30c5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -44,13 +44,13 @@ pub fn layout_of_adt_query( AdtId::StructId(s) => { let data = db.struct_data(s); let mut r = SmallVec::<[_; 1]>::new(); - r.push(handle_variant(s.into(), &data.variant_data)?); + r.push(handle_variant(s.into(), &db.variant_data(s.into()))?); (r, data.repr.unwrap_or_default()) } AdtId::UnionId(id) => { let data = db.union_data(id); let mut r = SmallVec::new(); - r.push(handle_variant(id.into(), &data.variant_data)?); + r.push(handle_variant(id.into(), &db.variant_data(id.into()))?); (r, data.repr.unwrap_or_default()) } AdtId::EnumId(e) => { @@ -58,7 +58,7 @@ pub fn layout_of_adt_query( let r = variants .variants .iter() - .map(|&(v, _)| handle_variant(v.into(), &db.enum_variant_data(v).variant_data)) + .map(|&(v, _)| handle_variant(v.into(), &db.variant_data(v.into()))) .collect::, _>>()?; (r, db.enum_data(e).repr.unwrap_or_default()) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 33e852aaee46c..12f3a1138fcc0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1491,16 +1491,12 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders { } fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { - let struct_data = db.struct_data(def); - let fields = struct_data.variant_data.fields(); + let struct_data = db.variant_data(def.into()); + let fields = struct_data.fields(); let resolver = def.resolver(db.upcast()); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - struct_data.variant_data.types_map(), - AdtId::from(def).into(), - ) - .with_type_param_mode(ParamLoweringMode::Variable); + let mut ctx = + TyLoweringContext::new(db, &resolver, struct_data.types_map(), AdtId::from(def).into()) + .with_type_param_mode(ParamLoweringMode::Variable); let params = fields.iter().map(|(_, field)| ctx.lower_ty(field.type_ref)); let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders(); Binders::new( @@ -1511,8 +1507,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS /// Build the type of a tuple struct constructor. fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option> { - let struct_data = db.struct_data(def); - match struct_data.variant_data.kind() { + let struct_data = db.variant_data(def.into()); + match struct_data.kind() { StructKind::Record => None, StructKind::Unit => Some(type_for_adt(db, def.into())), StructKind::Tuple => { @@ -1528,13 +1524,13 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option PolyFnSig { - let var_data = db.enum_variant_data(def); - let fields = var_data.variant_data.fields(); + let var_data = db.variant_data(def.into()); + let fields = var_data.fields(); let resolver = def.resolver(db.upcast()); let mut ctx = TyLoweringContext::new( db, &resolver, - var_data.variant_data.types_map(), + var_data.types_map(), DefWithBodyId::VariantId(def).into(), ) .with_type_param_mode(ParamLoweringMode::Variable); @@ -1553,7 +1549,7 @@ fn type_for_enum_variant_constructor( def: EnumVariantId, ) -> Option> { let e = def.lookup(db.upcast()).parent; - match db.enum_variant_data(def).variant_data.kind() { + match db.variant_data(def.into()).kind() { StructKind::Record => None, StructKind::Unit => Some(type_for_adt(db, e.into())), StructKind::Tuple => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 25aa2606558c1..45b4385568196 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -1761,7 +1761,7 @@ impl Evaluator<'_> { AdtId::EnumId(_) => not_supported!("unsizing enums"), }; let Some((last_field, _)) = - self.db.struct_data(id).variant_data.fields().iter().next_back() + self.db.variant_data(id.into()).fields().iter().next_back() else { not_supported!("unsizing struct without field"); }; @@ -2243,10 +2243,10 @@ impl Evaluator<'_> { } chalk_ir::TyKind::Adt(adt, subst) => match adt.0 { AdtId::StructId(s) => { - let data = this.db.struct_data(s); + let data = this.db.variant_data(s.into()); let layout = this.layout(ty)?; let field_types = this.db.field_types(s.into()); - for (f, _) in data.variant_data.fields().iter() { + for (f, _) in data.fields().iter() { let offset = layout .fields .offset(u32::from(f.into_raw()) as usize) @@ -2272,7 +2272,7 @@ impl Evaluator<'_> { bytes, e, ) { - let data = &this.db.enum_variant_data(v).variant_data; + let data = &this.db.variant_data(v.into()); let field_types = this.db.field_types(v.into()); for (f, _) in data.fields().iter() { let offset = @@ -2851,7 +2851,7 @@ impl Evaluator<'_> { return Ok(()); } let layout = self.layout_adt(id.0, subst.clone())?; - match data.variant_data.as_ref() { + match self.db.variant_data(s.into()).as_ref() { VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => { let field_types = self.db.field_types(s.into()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs index e229a4ab31727..829ed9efa2bc1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs @@ -31,8 +31,8 @@ impl Evaluator<'_> { Some(len) => len, _ => { if let AdtId::StructId(id) = id.0 { - let struct_data = self.db.struct_data(id); - let fields = struct_data.variant_data.fields(); + let struct_data = self.db.variant_data(id.into()); + let fields = struct_data.fields(); let Some((first_field, _)) = fields.iter().next() else { not_supported!("simd type with no field"); }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 57d4baa137cee..102048b3f4dca 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -499,7 +499,7 @@ impl<'ctx> MirLowerCtx<'ctx> { Ok(Some(current)) } ValueNs::EnumVariantId(variant_id) => { - let variant_data = &self.db.enum_variant_data(variant_id).variant_data; + let variant_data = &self.db.variant_data(variant_id.into()); if variant_data.kind() == StructKind::Unit { let ty = self.infer.type_of_expr[expr_id].clone(); current = self.lower_enum_variant( @@ -1165,8 +1165,7 @@ impl<'ctx> MirLowerCtx<'ctx> { Rvalue::Aggregate( AggregateKind::Adt(st.into(), subst.clone()), self.db - .struct_data(st) - .variant_data + .variant_data(st.into()) .fields() .iter() .map(|it| { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs index 783f92b2043f6..1c6dc4fecd81e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -597,7 +597,7 @@ impl MirLowerCtx<'_> { } self.pattern_matching_variant_fields( shape, - &self.db.enum_variant_data(v).variant_data, + &self.db.variant_data(v.into()), variant, current, current_else, @@ -607,7 +607,7 @@ impl MirLowerCtx<'_> { } VariantId::StructId(s) => self.pattern_matching_variant_fields( shape, - &self.db.struct_data(s).variant_data, + &self.db.variant_data(s.into()), variant, current, current_else, diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index f78b7a5c435cb..9f91f155ea77b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -661,8 +661,7 @@ impl Module { db.field_types_with_diagnostics(s.id.into()).1, tree_source_maps.strukt(tree_id.value).item(), ); - - for diag in db.struct_data_with_diagnostics(s.id).1.iter() { + for diag in db.variant_data_with_diagnostics(s.id.into()).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } } @@ -675,8 +674,7 @@ impl Module { db.field_types_with_diagnostics(u.id.into()).1, tree_source_maps.union(tree_id.value).item(), ); - - for diag in db.union_data_with_diagnostics(u.id).1.iter() { + for diag in db.variant_data_with_diagnostics(u.id.into()).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } } @@ -692,7 +690,7 @@ impl Module { tree_source_maps.variant(tree_id.value), ); acc.extend(ModuleDef::Variant(v).diagnostics(db, style_lints)); - for diag in db.enum_variant_data_with_diagnostics(v.id).1.iter() { + for diag in db.variant_data_with_diagnostics(v.id.into()).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } } @@ -1059,7 +1057,7 @@ fn emit_def_diagnostic_( AttrOwner::Variant(it) => { ast_id_map.get(item_tree[it].ast_id).syntax_node_ptr() } - AttrOwner::Field(FieldParent::Variant(parent), idx) => process_field_list( + AttrOwner::Field(FieldParent::EnumVariant(parent), idx) => process_field_list( ast_id_map .get(item_tree[parent].ast_id) .to_node(&db.parse_or_expand(tree.file_id())) @@ -1392,6 +1390,7 @@ impl HasVisibility for Field { let variant_data = self.parent.variant_data(db); let visibility = &variant_data.fields()[self.id].visibility; let parent_id: hir_def::VariantId = self.parent.into(); + // FIXME: RawVisibility::Public doesn't need to construct a resolver visibility.resolve(db.upcast(), &parent_id.resolver(db.upcast())) } } @@ -1411,8 +1410,7 @@ impl Struct { } pub fn fields(self, db: &dyn HirDatabase) -> Vec { - db.struct_data(self.id) - .variant_data + db.variant_data(self.id.into()) .fields() .iter() .map(|(id, _)| Field { parent: self.into(), id }) @@ -1440,7 +1438,7 @@ impl Struct { } fn variant_data(self, db: &dyn HirDatabase) -> Arc { - db.struct_data(self.id).variant_data.clone() + db.variant_data(self.id.into()).clone() } pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { @@ -1481,8 +1479,7 @@ impl Union { } pub fn fields(self, db: &dyn HirDatabase) -> Vec { - db.union_data(self.id) - .variant_data + db.variant_data(self.id.into()) .fields() .iter() .map(|(id, _)| Field { parent: self.into(), id }) @@ -1490,7 +1487,7 @@ impl Union { } fn variant_data(self, db: &dyn HirDatabase) -> Arc { - db.union_data(self.id).variant_data.clone() + db.variant_data(self.id.into()).clone() } pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { @@ -1633,7 +1630,7 @@ impl Variant { } pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc { - db.enum_variant_data(self.id).variant_data.clone() + db.variant_data(self.id.into()).clone() } pub fn value(self, db: &dyn HirDatabase) -> Option { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs index 6b08ada34b609..4e058bb0106a2 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs @@ -149,7 +149,6 @@ impl RootDatabase { // hir::db::CrateNotableTraitsQuery // hir::db::CrateSupportsNoStdQuery // hir::db::EnumDataQuery - // hir::db::EnumVariantDataWithDiagnosticsQuery // hir::db::ExpandProcAttrMacrosQuery // hir::db::ExprScopesQuery // hir::db::ExternCrateDeclDataQuery @@ -191,11 +190,10 @@ impl RootDatabase { // hir::db::NotableTraitsInDepsQuery // hir::db::ProcMacroDataQuery // hir::db::StaticDataQuery - // hir::db::StructDataWithDiagnosticsQuery // hir::db::TraitAliasDataQuery // hir::db::TraitItemsWithDiagnosticsQuery // hir::db::TypeAliasDataQuery - // hir::db::UnionDataWithDiagnosticsQuery + // hir::db::VariantDataWithDiagnosticsQuery // // InternDatabase // hir::db::InternFunctionQuery From aed21ed588677c4d556650e7ca0fa575956e12f3 Mon Sep 17 00:00:00 2001 From: Vishruth-Thimmaiah Date: Mon, 3 Mar 2025 18:31:13 +0530 Subject: [PATCH 023/260] feat: for loop to while let assist --- .../src/handlers/convert_for_to_while_let.rs | 422 ++++++++++++++++++ .../crates/ide-assists/src/lib.rs | 2 + .../crates/ide-assists/src/tests/generated.rs | 24 + .../crates/syntax/src/ast/make.rs | 4 + .../src/ast/syntax_factory/constructors.rs | 17 +- 5 files changed, 467 insertions(+), 2 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs new file mode 100644 index 0000000000000..2d2751de99d87 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs @@ -0,0 +1,422 @@ +use hir::{ + sym::{self}, + Name, +}; +use ide_db::{famous_defs::FamousDefs, syntax_helpers::suggest_name}; +use syntax::{ + ast::{self, edit::IndentLevel, make, syntax_factory::SyntaxFactory, HasLoopBody}, + syntax_editor::Position, + AstNode, +}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: convert_for_loop_to_while_let +// +// Converts a for loop into a while let on the Iterator. +// +// ``` +// fn main() { +// let x = vec![1, 2, 3]; +// for$0 v in x { +// let y = v * 2; +// }; +// } +// ``` +// -> +// ``` +// fn main() { +// let x = vec![1, 2, 3]; +// let mut tmp = x.into_iter(); +// while let Some(v) = tmp.next() { +// let y = v * 2; +// }; +// } +// ``` +pub(crate) fn convert_for_loop_to_while_let( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { + let for_loop = ctx.find_node_at_offset::()?; + let iterable = for_loop.iterable()?; + let pat = for_loop.pat()?; + let body = for_loop.loop_body()?; + if body.syntax().text_range().start() < ctx.offset() { + cov_mark::hit!(not_available_in_body); + return None; + } + + acc.add( + AssistId("convert_for_loop_to_while_let", AssistKind::RefactorRewrite), + "Replace this for loop with `while let`", + for_loop.syntax().text_range(), + |builder| { + let make = SyntaxFactory::new(); + let mut editor = builder.make_editor(for_loop.syntax()); + + let (iterable, method) = if impls_core_iter(&ctx.sema, &iterable) { + (iterable, None) + } else if let Some((expr, method)) = is_ref_and_impls_iter_method(&ctx.sema, &iterable) + { + (expr, Some(make.name_ref(method.as_str()))) + } else if let ast::Expr::RefExpr(_) = iterable { + (make::expr_paren(iterable), Some(make.name_ref("into_iter"))) + } else { + (iterable, Some(make.name_ref("into_iter"))) + }; + + let iterable = if let Some(method) = method { + make::expr_method_call(iterable, method, make::arg_list([])) + } else { + iterable + }; + + let mut new_name = suggest_name::NameGenerator::new_from_scope_locals( + ctx.sema.scope(for_loop.syntax()), + ); + let tmp_var = new_name.suggest_name("tmp"); + + let mut_expr = make.let_stmt( + make.ident_pat(false, true, make.name(&tmp_var)).into(), + None, + Some(iterable), + ); + let indent = IndentLevel::from_node(for_loop.syntax()); + editor.insert( + Position::before(for_loop.syntax()), + make::tokens::whitespace(format!("\n{indent}").as_str()), + ); + editor.insert(Position::before(for_loop.syntax()), mut_expr.syntax()); + + let opt_pat = make.tuple_struct_pat(make::ext::ident_path("Some"), [pat]); + let iter_next_expr = make.expr_method_call( + make.expr_path(make::ext::ident_path(&tmp_var)), + make.name_ref("next"), + make.arg_list([]), + ); + let cond = make.expr_let(opt_pat.into(), iter_next_expr.into()); + + let while_loop = make.expr_while_loop(cond.into(), body); + + editor.replace(for_loop.syntax(), while_loop.syntax()); + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); + }, + ) +} + +/// If iterable is a reference where the expression behind the reference implements a method +/// returning an Iterator called iter or iter_mut (depending on the type of reference) then return +/// the expression behind the reference and the method name +fn is_ref_and_impls_iter_method( + sema: &hir::Semantics<'_, ide_db::RootDatabase>, + iterable: &ast::Expr, +) -> Option<(ast::Expr, hir::Name)> { + let ref_expr = match iterable { + ast::Expr::RefExpr(r) => r, + _ => return None, + }; + let wanted_method = Name::new_symbol_root(if ref_expr.mut_token().is_some() { + sym::iter_mut.clone() + } else { + sym::iter.clone() + }); + let expr_behind_ref = ref_expr.expr()?; + let ty = sema.type_of_expr(&expr_behind_ref)?.adjusted(); + let scope = sema.scope(iterable.syntax())?; + let krate = scope.krate(); + let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; + + let has_wanted_method = ty + .iterate_method_candidates(sema.db, &scope, None, Some(&wanted_method), |func| { + if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) { + return Some(()); + } + None + }) + .is_some(); + if !has_wanted_method { + return None; + } + + Some((expr_behind_ref, wanted_method)) +} + +/// Whether iterable implements core::Iterator +fn impls_core_iter(sema: &hir::Semantics<'_, ide_db::RootDatabase>, iterable: &ast::Expr) -> bool { + (|| { + let it_typ = sema.type_of_expr(iterable)?.adjusted(); + + let module = sema.scope(iterable.syntax())?.module(); + + let krate = module.krate(); + let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; + cov_mark::hit!(test_already_impls_iterator); + Some(it_typ.impls_trait(sema.db, iter_trait, &[])) + })() + .unwrap_or(false) +} + +#[cfg(test)] +mod tests { + use crate::tests::{check_assist, check_assist_not_applicable}; + + use super::*; + + #[test] + fn each_to_for_simple_for() { + check_assist( + convert_for_loop_to_while_let, + r" +fn main() { + let mut x = vec![1, 2, 3]; + for $0v in x { + v *= 2; + }; +}", + r" +fn main() { + let mut x = vec![1, 2, 3]; + let mut tmp = x.into_iter(); + while let Some(v) = tmp.next() { + v *= 2; + }; +}", + ) + } + + #[test] + fn each_to_for_for_in_range() { + check_assist( + convert_for_loop_to_while_let, + r#" +//- minicore: range, iterators +impl core::iter::Iterator for core::ops::Range { + type Item = T; + + fn next(&mut self) -> Option { + None + } +} + +fn main() { + for $0x in 0..92 { + print!("{}", x); + } +}"#, + r#" +impl core::iter::Iterator for core::ops::Range { + type Item = T; + + fn next(&mut self) -> Option { + None + } +} + +fn main() { + let mut tmp = 0..92; + while let Some(x) = tmp.next() { + print!("{}", x); + } +}"#, + ) + } + + #[test] + fn each_to_for_not_available_in_body() { + cov_mark::check!(not_available_in_body); + check_assist_not_applicable( + convert_for_loop_to_while_let, + r" +fn main() { + let mut x = vec![1, 2, 3]; + for v in x { + $0v *= 2; + } +}", + ) + } + + #[test] + fn each_to_for_for_borrowed() { + check_assist( + convert_for_loop_to_while_let, + r#" +//- minicore: iterators +use core::iter::{Repeat, repeat}; + +struct S; +impl S { + fn iter(&self) -> Repeat { repeat(92) } + fn iter_mut(&mut self) -> Repeat { repeat(92) } +} + +fn main() { + let x = S; + for $0v in &x { + let a = v * 2; + } +} +"#, + r#" +use core::iter::{Repeat, repeat}; + +struct S; +impl S { + fn iter(&self) -> Repeat { repeat(92) } + fn iter_mut(&mut self) -> Repeat { repeat(92) } +} + +fn main() { + let x = S; + let mut tmp = x.iter(); + while let Some(v) = tmp.next() { + let a = v * 2; + } +} +"#, + ) + } + + #[test] + fn each_to_for_for_borrowed_no_iter_method() { + check_assist( + convert_for_loop_to_while_let, + r" +struct NoIterMethod; +fn main() { + let x = NoIterMethod; + for $0v in &x { + let a = v * 2; + } +} +", + r" +struct NoIterMethod; +fn main() { + let x = NoIterMethod; + let mut tmp = (&x).into_iter(); + while let Some(v) = tmp.next() { + let a = v * 2; + } +} +", + ) + } + + #[test] + fn each_to_for_for_borrowed_no_iter_method_mut() { + check_assist( + convert_for_loop_to_while_let, + r" +struct NoIterMethod; +fn main() { + let x = NoIterMethod; + for $0v in &mut x { + let a = v * 2; + } +} +", + r" +struct NoIterMethod; +fn main() { + let x = NoIterMethod; + let mut tmp = (&mut x).into_iter(); + while let Some(v) = tmp.next() { + let a = v * 2; + } +} +", + ) + } + + #[test] + fn each_to_for_for_borrowed_mut() { + check_assist( + convert_for_loop_to_while_let, + r#" +//- minicore: iterators +use core::iter::{Repeat, repeat}; + +struct S; +impl S { + fn iter(&self) -> Repeat { repeat(92) } + fn iter_mut(&mut self) -> Repeat { repeat(92) } +} + +fn main() { + let x = S; + for $0v in &mut x { + let a = v * 2; + } +} +"#, + r#" +use core::iter::{Repeat, repeat}; + +struct S; +impl S { + fn iter(&self) -> Repeat { repeat(92) } + fn iter_mut(&mut self) -> Repeat { repeat(92) } +} + +fn main() { + let x = S; + let mut tmp = x.iter_mut(); + while let Some(v) = tmp.next() { + let a = v * 2; + } +} +"#, + ) + } + + #[test] + fn each_to_for_for_borrowed_mut_behind_var() { + check_assist( + convert_for_loop_to_while_let, + r" +fn main() { + let mut x = vec![1, 2, 3]; + let y = &mut x; + for $0v in y { + *v *= 2; + } +}", + r" +fn main() { + let mut x = vec![1, 2, 3]; + let y = &mut x; + let mut tmp = y.into_iter(); + while let Some(v) = tmp.next() { + *v *= 2; + } +}", + ) + } + + #[test] + fn each_to_for_already_impls_iterator() { + cov_mark::check!(test_already_impls_iterator); + check_assist( + convert_for_loop_to_while_let, + r#" +//- minicore: iterators +fn main() { + for$0 a in core::iter::repeat(92).take(1) { + println!("{}", a); + } +} +"#, + r#" +fn main() { + let mut tmp = core::iter::repeat(92).take(1); + while let Some(a) = tmp.next() { + println!("{}", a); + } +} +"#, + ); + } +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index e8480b0de1906..7e9d59661481e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -122,6 +122,7 @@ mod handlers { mod convert_closure_to_fn; mod convert_comment_block; mod convert_comment_from_or_to_doc; + mod convert_for_to_while_let; mod convert_from_to_tryfrom; mod convert_integer_literal; mod convert_into_to_from; @@ -252,6 +253,7 @@ mod handlers { convert_closure_to_fn::convert_closure_to_fn, convert_comment_block::convert_comment_block, convert_comment_from_or_to_doc::convert_comment_from_or_to_doc, + convert_for_to_while_let::convert_for_loop_to_while_let, convert_from_to_tryfrom::convert_from_to_tryfrom, convert_integer_literal::convert_integer_literal, convert_into_to_from::convert_into_to_from, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 4234124d670ff..359de438ed6d2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -439,6 +439,30 @@ fn main() { ) } +#[test] +fn doctest_convert_for_loop_to_while_let() { + check_doc_test( + "convert_for_loop_to_while_let", + r#####" +fn main() { + let x = vec![1, 2, 3]; + for$0 v in x { + let y = v * 2; + }; +} +"#####, + r#####" +fn main() { + let x = vec![1, 2, 3]; + let mut tmp = x.into_iter(); + while let Some(v) = tmp.next() { + let y = v * 2; + }; +} +"#####, + ) +} + #[test] fn doctest_convert_for_loop_with_for_each() { check_doc_test( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 231c21c38f85f..234e3d1efe1fb 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -623,6 +623,10 @@ pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> a expr_from_text(&format!("for {pat} in {expr} {block}")) } +pub fn expr_while_loop(condition: ast::Expr, block: ast::BlockExpr) -> ast::WhileExpr { + expr_from_text(&format!("while {condition} {block}")) +} + pub fn expr_loop(block: ast::BlockExpr) -> ast::Expr { expr_from_text(&format!("loop {block}")) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 44f13041c244f..bec5d2a39a330 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -1,8 +1,8 @@ //! Wrappers over [`make`] constructors use crate::{ ast::{ - self, make, HasArgList, HasGenericArgs, HasGenericParams, HasName, HasTypeBounds, - HasVisibility, + self, make, HasArgList, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, + HasTypeBounds, HasVisibility, }, syntax_editor::SyntaxMappingBuilder, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken, @@ -543,6 +543,19 @@ impl SyntaxFactory { ast } + pub fn expr_while_loop(&self, condition: ast::Expr, body: ast::BlockExpr) -> ast::WhileExpr { + let ast = make::expr_while_loop(condition.clone(), body.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(condition.syntax().clone(), ast.condition().unwrap().syntax().clone()); + builder.map_node(body.syntax().clone(), ast.loop_body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_let(&self, pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr { let ast = make::expr_let(pattern.clone(), expr.clone()).clone_for_update(); From 2c2bc99a634689840e1c2c465ca7382c2bf0e1b9 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 14 Mar 2025 14:52:03 +0100 Subject: [PATCH 024/260] Avoid recursively debug printing crates --- .../rust-analyzer/crates/base-db/src/input.rs | 3 +- .../ide-db/src/test_data/test_doc_alias.txt | 6 ++-- .../test_symbol_index_collection.txt | 30 +++++++++---------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index c4e64b372f36a..913dfe6efb770 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -393,7 +393,8 @@ impl BuiltDependency { pub type CratesIdMap = FxHashMap; -#[salsa::input] +#[salsa::input(no_debug)] +#[derive(Debug)] pub struct Crate { #[return_ref] pub data: BuiltCrateData, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt index 1e2d4f1ab94fc..a527ce19d2051 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt @@ -2,9 +2,9 @@ ( Module { id: ModuleId { - krate: Crate { - [salsa id]: Id(2c00), - }, + krate: Crate( + Id(2c00), + ), block: None, local_id: Idx::(0), }, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 1a77052b18d46..82440d7c1ee09 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -2,9 +2,9 @@ ( Module { id: ModuleId { - krate: Crate { - [salsa id]: Id(2c00), - }, + krate: Crate( + Id(2c00), + ), block: None, local_id: Idx::(0), }, @@ -534,9 +534,9 @@ def: Module( Module { id: ModuleId { - krate: Crate { - [salsa id]: Id(2c00), - }, + krate: Crate( + Id(2c00), + ), block: None, local_id: Idx::(1), }, @@ -569,9 +569,9 @@ def: Module( Module { id: ModuleId { - krate: Crate { - [salsa id]: Id(2c00), - }, + krate: Crate( + Id(2c00), + ), block: None, local_id: Idx::(2), }, @@ -833,9 +833,9 @@ ( Module { id: ModuleId { - krate: Crate { - [salsa id]: Id(2c00), - }, + krate: Crate( + Id(2c00), + ), block: None, local_id: Idx::(1), }, @@ -879,9 +879,9 @@ ( Module { id: ModuleId { - krate: Crate { - [salsa id]: Id(2c00), - }, + krate: Crate( + Id(2c00), + ), block: None, local_id: Idx::(2), }, From 7060bfe553f67d5d8370e9f53a7ce2d74a8026f8 Mon Sep 17 00:00:00 2001 From: David Richey Date: Fri, 14 Mar 2025 16:55:24 -0500 Subject: [PATCH 025/260] Require Rust 1.85 --- src/tools/rust-analyzer/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 7dd5f2bb1faa9..e9d70bea346dc 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -4,7 +4,7 @@ exclude = ["crates/proc-macro-srv/proc-macro-test/imp"] resolver = "2" [workspace.package] -rust-version = "1.84" +rust-version = "1.85" edition = "2021" license = "MIT OR Apache-2.0" authors = ["rust-analyzer team"] From 246415809cb151cbe6411e075c815940d61f55b4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 15 Mar 2025 15:53:23 +0100 Subject: [PATCH 026/260] fix: Fix missing `with_durability` calls --- src/tools/rust-analyzer/crates/base-db/src/lib.rs | 10 +++++++--- src/tools/rust-analyzer/crates/hir-expand/src/db.rs | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 0f29abbb54f14..b733c4d24147e 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -86,7 +86,7 @@ impl Files { let files = Arc::clone(&self.files); match files.entry(file_id) { Entry::Occupied(mut occupied) => { - occupied.get_mut().set_text(db).to(Arc::from(text)); + occupied.get_mut().set_text(db).with_durability(durability).to(Arc::from(text)); } Entry::Vacant(vacant) => { let text = @@ -116,7 +116,7 @@ impl Files { let source_roots = Arc::clone(&self.source_roots); match source_roots.entry(source_root_id) { Entry::Occupied(mut occupied) => { - occupied.get_mut().set_source_root(db).to(source_root); + occupied.get_mut().set_source_root(db).with_durability(durability).to(source_root); } Entry::Vacant(vacant) => { let source_root = @@ -145,7 +145,11 @@ impl Files { // let db = self; match file_source_roots.entry(id) { Entry::Occupied(mut occupied) => { - occupied.get_mut().set_source_root_id(db).to(source_root_id); + occupied + .get_mut() + .set_source_root_id(db) + .with_durability(durability) + .to(source_root_id); } Entry::Vacant(vacant) => { let file_source_root = diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 112327f11e1a8..7e7858d15b4cf 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -61,6 +61,7 @@ pub trait ExpandDatabase: RootQueryDb { #[salsa::input] fn proc_macros(&self) -> Arc; + /// Incrementality query to prevent queries from directly depending on `ExpandDatabase::proc_macros`. #[salsa::invoke_actual(crate::proc_macro::proc_macros_for_crate)] fn proc_macros_for_crate(&self, krate: Crate) -> Option>; From 94e0b32258b024192f860709a3b64100eb05ba69 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 15 Mar 2025 16:10:02 +0100 Subject: [PATCH 027/260] chore: Drop legacy salsa --- src/tools/rust-analyzer/Cargo.lock | 111 +-- .../rust-analyzer/crates/ra-salsa/Cargo.toml | 35 - .../rust-analyzer/crates/ra-salsa/FAQ.md | 34 - .../crates/ra-salsa/LICENSE-APACHE | 176 ---- .../rust-analyzer/crates/ra-salsa/LICENSE-MIT | 23 - .../rust-analyzer/crates/ra-salsa/README.md | 42 - .../ra-salsa/ra-salsa-macros/Cargo.toml | 23 - .../ra-salsa/ra-salsa-macros/LICENSE-APACHE | 1 - .../ra-salsa/ra-salsa-macros/LICENSE-MIT | 1 - .../crates/ra-salsa/ra-salsa-macros/README.md | 1 - .../ra-salsa-macros/src/database_storage.rs | 243 ----- .../ra-salsa/ra-salsa-macros/src/lib.rs | 125 --- .../ra-salsa-macros/src/parenthesized.rs | 13 - .../ra-salsa-macros/src/query_group.rs | 753 --------------- .../crates/ra-salsa/src/debug.rs | 65 -- .../crates/ra-salsa/src/derived.rs | 163 ---- .../crates/ra-salsa/src/derived/slot.rs | 782 ---------------- .../crates/ra-salsa/src/derived_lru.rs | 233 ----- .../crates/ra-salsa/src/derived_lru/slot.rs | 856 ------------------ .../crates/ra-salsa/src/durability.rs | 49 - .../rust-analyzer/crates/ra-salsa/src/hash.rs | 3 - .../crates/ra-salsa/src/input.rs | 371 -------- .../crates/ra-salsa/src/intern_id.rs | 131 --- .../crates/ra-salsa/src/interned.rs | 510 ----------- .../rust-analyzer/crates/ra-salsa/src/lib.rs | 750 --------------- .../rust-analyzer/crates/ra-salsa/src/lru.rs | 325 ------- .../crates/ra-salsa/src/plumbing.rs | 245 ----- .../crates/ra-salsa/src/revision.rs | 66 -- .../crates/ra-salsa/src/runtime.rs | 668 -------------- .../ra-salsa/src/runtime/dependency_graph.rs | 250 ----- .../ra-salsa/src/runtime/local_state.rs | 204 ----- .../crates/ra-salsa/src/storage.rs | 53 -- .../crates/ra-salsa/tests/cycles.rs | 492 ---------- .../crates/ra-salsa/tests/dyn_trait.rs | 28 - .../ra-salsa/tests/incremental/constants.rs | 145 --- .../ra-salsa/tests/incremental/counter.rs | 14 - .../tests/incremental/implementation.rs | 59 -- .../crates/ra-salsa/tests/incremental/log.rs | 16 - .../crates/ra-salsa/tests/incremental/main.rs | 9 - .../tests/incremental/memoized_dep_inputs.rs | 60 -- .../tests/incremental/memoized_inputs.rs | 76 -- .../tests/incremental/memoized_volatile.rs | 77 -- .../crates/ra-salsa/tests/interned.rs | 90 -- .../crates/ra-salsa/tests/lru.rs | 104 --- .../crates/ra-salsa/tests/macros.rs | 12 - .../crates/ra-salsa/tests/no_send_sync.rs | 31 - .../crates/ra-salsa/tests/on_demand_inputs.rs | 147 --- .../crates/ra-salsa/tests/panic_safely.rs | 93 -- .../ra-salsa/tests/parallel/cancellation.rs | 132 --- .../crates/ra-salsa/tests/parallel/frozen.rs | 57 -- .../ra-salsa/tests/parallel/independent.rs | 29 - .../crates/ra-salsa/tests/parallel/main.rs | 13 - .../parallel/parallel_cycle_all_recover.rs | 109 --- .../parallel/parallel_cycle_mid_recover.rs | 109 --- .../parallel/parallel_cycle_none_recover.rs | 68 -- .../parallel/parallel_cycle_one_recovers.rs | 94 -- .../crates/ra-salsa/tests/parallel/race.rs | 37 - .../crates/ra-salsa/tests/parallel/setup.rs | 197 ---- .../crates/ra-salsa/tests/parallel/signal.rs | 40 - .../crates/ra-salsa/tests/parallel/stress.rs | 168 ---- .../ra-salsa/tests/parallel/true_parallel.rs | 125 --- .../tests/storage_varieties/implementation.rs | 19 - .../ra-salsa/tests/storage_varieties/main.rs | 5 - .../tests/storage_varieties/queries.rs | 22 - .../ra-salsa/tests/storage_varieties/tests.rs | 49 - .../crates/ra-salsa/tests/transparent.rs | 39 - .../crates/ra-salsa/tests/variadic.rs | 51 -- src/tools/rust-analyzer/xtask/src/tidy.rs | 3 +- 68 files changed, 9 insertions(+), 10115 deletions(-) delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/FAQ.md delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/LICENSE-APACHE delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/LICENSE-MIT delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/README.md delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-APACHE delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-MIT delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/README.md delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/database_storage.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/lib.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/parenthesized.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/query_group.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/debug.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/derived.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/derived/slot.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru/slot.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/hash.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/input.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/intern_id.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/interned.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/lru.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/plumbing.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/revision.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/runtime.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/runtime/dependency_graph.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/runtime/local_state.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/src/storage.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/dyn_trait.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/constants.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/counter.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/implementation.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/log.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/main.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_dep_inputs.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_inputs.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_volatile.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/interned.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/lru.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/macros.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/no_send_sync.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/on_demand_inputs.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/panic_safely.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/cancellation.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/frozen.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/independent.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/main.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_all_recover.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_mid_recover.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_none_recover.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_one_recovers.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/race.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/setup.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/signal.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/stress.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/true_parallel.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/implementation.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/main.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/queries.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/tests.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/transparent.rs delete mode 100644 src/tools/rust-analyzer/crates/ra-salsa/tests/variadic.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 00da1c973dc0f..54cc9d1c68025 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -88,7 +88,7 @@ dependencies = [ "lz4_flex", "query-group-macro", "rustc-hash 2.1.1", - "salsa 0.19.0", + "salsa", "semver", "span", "stdx", @@ -656,7 +656,7 @@ dependencies = [ "ra-ap-rustc_parse_format", "rustc-hash 2.1.1", "rustc_apfloat", - "salsa 0.19.0", + "salsa", "smallvec", "span", "stdx", @@ -687,7 +687,7 @@ dependencies = [ "parser", "query-group-macro", "rustc-hash 2.1.1", - "salsa 0.19.0", + "salsa", "smallvec", "span", "stdx", @@ -729,7 +729,7 @@ dependencies = [ "ra-ap-rustc_pattern_analysis", "rustc-hash 2.1.1", "rustc_apfloat", - "salsa 0.19.0", + "salsa", "scoped-tls", "smallvec", "span", @@ -966,7 +966,7 @@ dependencies = [ "query-group-macro", "rayon", "rustc-hash 2.1.1", - "salsa 0.19.0", + "salsa", "span", "stdx", "syntax", @@ -1190,12 +1190,6 @@ dependencies = [ "text-size", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "litemap" version = "0.7.5" @@ -1619,15 +1613,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro-api" version = "0.0.0" @@ -1785,7 +1770,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "salsa 0.19.0", + "salsa", "syn", ] @@ -1874,36 +1859,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "rayon" version = "1.10.0" @@ -2113,26 +2068,6 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" -[[package]] -name = "salsa" -version = "0.0.0" -dependencies = [ - "dissimilar", - "expect-test", - "indexmap", - "itertools", - "linked-hash-map", - "lock_api", - "oorandom", - "parking_lot", - "rand", - "rustc-hash 2.1.1", - "salsa-macros 0.0.0", - "smallvec", - "tracing", - "triomphe", -] - [[package]] name = "salsa" version = "0.19.0" @@ -2150,7 +2085,7 @@ dependencies = [ "rayon", "rustc-hash 2.1.1", "salsa-macro-rules", - "salsa-macros 0.19.0", + "salsa-macros", "smallvec", "tracing", ] @@ -2161,16 +2096,6 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2619b4b451beab0a7e4364ff1e6f31950e7e418888fd9bf2f28889671563166a" -[[package]] -name = "salsa-macros" -version = "0.0.0" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "salsa-macros" version = "0.19.0" @@ -2314,7 +2239,7 @@ dependencies = [ "hashbrown 0.14.5", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.1.1", - "salsa 0.19.0", + "salsa", "stdx", "syntax", "text-size", @@ -3267,26 +3192,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "zerofrom" version = "0.1.6" diff --git a/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml b/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml deleted file mode 100644 index 57a20be0cadd7..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "salsa" -version = "0.0.0" -authors = ["Salsa developers"] -edition = "2021" -license = "Apache-2.0 OR MIT" -repository = "https://github.com/salsa-rs/salsa" -description = "A generic framework for on-demand, incrementalized computation (experimental)" - -rust-version.workspace = true - -[lib] -name = "ra_salsa" - -[dependencies] -indexmap = "2.1.0" -lock_api = "0.4" -tracing = "0.1" -parking_lot = "0.12.1" -rustc-hash = "2.0.0" -smallvec = "1.0.0" -oorandom = "11" -triomphe.workspace = true -itertools.workspace = true - -ra-salsa-macros = { version = "0.0.0", path = "ra-salsa-macros", package = "salsa-macros" } - -[dev-dependencies] -linked-hash-map = "0.5.6" -rand = "0.8.5" -expect-test = "1.4.0" -dissimilar = "1.0.7" - -[lints] -workspace = true diff --git a/src/tools/rust-analyzer/crates/ra-salsa/FAQ.md b/src/tools/rust-analyzer/crates/ra-salsa/FAQ.md deleted file mode 100644 index 9c9f6f92da990..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/FAQ.md +++ /dev/null @@ -1,34 +0,0 @@ -# Frequently asked questions - -## Why is it called salsa? - -I like salsa! Don't you?! Well, ok, there's a bit more to it. The -underlying algorithm for figuring out which bits of code need to be -re-executed after any given change is based on the algorithm used in -rustc. Michael Woerister and I first described the rustc algorithm in -terms of two colors, red and green, and hence we called it the -"red-green algorithm". This made me think of the New Mexico State -Question --- ["Red or green?"][nm] --- which refers to chile -(salsa). Although this version no longer uses colors (we borrowed -revision counters from Glimmer, instead), I still like the name. - -[nm]: https://www.sos.state.nm.us/about-new-mexico/state-question/ - -## What is the relationship between salsa and an Entity-Component System (ECS)? - -You may have noticed that Salsa "feels" a lot like an ECS in some -ways. That's true -- Salsa's queries are a bit like *components* (and -the keys to the queries are a bit like *entities*). But there is one -big difference: **ECS is -- at its heart -- a mutable system**. You -can get or set a component of some entity whenever you like. In -contrast, salsa's queries **define "derived values" via pure -computations**. - -Partly as a consequence, ECS doesn't handle incremental updates for -you. When you update some component of some entity, you have to ensure -that other entities' components are updated appropriately. - -Finally, ECS offers interesting metadata and "aspect-like" facilities, -such as iterating over all entities that share certain components. -Salsa has no analogue to that. - diff --git a/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-APACHE b/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-APACHE deleted file mode 100644 index 1b5ec8b78e237..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-APACHE +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS diff --git a/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-MIT b/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-MIT deleted file mode 100644 index 31aa79387f27e..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/src/tools/rust-analyzer/crates/ra-salsa/README.md b/src/tools/rust-analyzer/crates/ra-salsa/README.md deleted file mode 100644 index 4a8d9f8c7317a..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# salsa - -*A generic framework for on-demand, incrementalized computation.* - -## Obligatory warning - -This is a fork of https://github.com/salsa-rs/salsa/ adjusted to rust-analyzer's needs. - -## Credits - -This system is heavily inspired by [adapton](http://adapton.org/), [glimmer](https://github.com/glimmerjs/glimmer-vm), and rustc's query -system. So credit goes to Eduard-Mihai Burtescu, Matthew Hammer, -Yehuda Katz, and Michael Woerister. - -## Key idea - -The key idea of `salsa` is that you define your program as a set of -**queries**. Every query is used like function `K -> V` that maps from -some key of type `K` to a value of type `V`. Queries come in two basic -varieties: - -- **Inputs**: the base inputs to your system. You can change these - whenever you like. -- **Functions**: pure functions (no side effects) that transform your - inputs into other values. The results of queries is memoized to - avoid recomputing them a lot. When you make changes to the inputs, - we'll figure out (fairly intelligently) when we can re-use these - memoized values and when we have to recompute them. - -## Want to learn more? - -To learn more about Salsa, try one of the following: - -- read the [heavily commented `hello_world` example](https://github.com/salsa-rs/salsa/blob/master/examples/hello_world/main.rs); -- check out the [Salsa book](https://salsa-rs.github.io/salsa); -- watch one of our [videos](https://salsa-rs.github.io/salsa/videos.html). - -## Getting in touch - -The bulk of the discussion happens in the [issues](https://github.com/salsa-rs/salsa/issues) -and [pull requests](https://github.com/salsa-rs/salsa/pulls), -but we have a [zulip chat](https://salsa.zulipchat.com/) as well. diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml deleted file mode 100644 index 3c2daacaf9501..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "salsa-macros" -version = "0.0.0" -authors = ["Salsa developers"] -edition = "2021" -license = "Apache-2.0 OR MIT" -repository = "https://github.com/salsa-rs/salsa" -description = "Procedural macros for the salsa crate" - -rust-version.workspace = true - -[lib] -proc-macro = true -name = "ra_salsa_macros" - -[dependencies] -heck = "0.5.0" -proc-macro2 = "1.0" -quote = "1.0" -syn = { version = "2.0", features = ["full", "extra-traits"] } - -[lints] -workspace = true diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-APACHE b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-APACHE deleted file mode 100644 index 0bf2cad6488f5..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-APACHE diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-MIT b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-MIT deleted file mode 100644 index d99cce5f72063..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-MIT diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/README.md b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/README.md deleted file mode 100644 index 94389aee61a0e..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/README.md +++ /dev/null @@ -1 +0,0 @@ -../README.md diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/database_storage.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/database_storage.rs deleted file mode 100644 index 63ab84a621e7e..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/database_storage.rs +++ /dev/null @@ -1,243 +0,0 @@ -//! Implementation for `[ra_salsa::database]` decorator. - -use heck::ToSnakeCase; -use proc_macro::TokenStream; -use syn::parse::{Parse, ParseStream}; -use syn::punctuated::Punctuated; -use syn::{Ident, ItemStruct, Path, Token}; - -type PunctuatedQueryGroups = Punctuated; - -pub(crate) fn database(args: TokenStream, input: TokenStream) -> TokenStream { - let args = syn::parse_macro_input!(args as QueryGroupList); - let input = syn::parse_macro_input!(input as ItemStruct); - - let query_groups = &args.query_groups; - let database_name = &input.ident; - let visibility = &input.vis; - let db_storage_field = quote! { storage }; - - let mut output = proc_macro2::TokenStream::new(); - output.extend(quote! { #input }); - - let query_group_names_snake: Vec<_> = query_groups - .iter() - .map(|query_group| { - let group_name = query_group.name(); - Ident::new(&group_name.to_string().to_snake_case(), group_name.span()) - }) - .collect(); - - let query_group_storage_names: Vec<_> = query_groups - .iter() - .map(|QueryGroup { group_path }| { - quote! { - <#group_path as ra_salsa::plumbing::QueryGroup>::GroupStorage - } - }) - .collect(); - - // For each query group `foo::MyGroup` create a link to its - // `foo::MyGroupGroupStorage` - let mut storage_fields = proc_macro2::TokenStream::new(); - let mut storage_initializers = proc_macro2::TokenStream::new(); - let mut has_group_impls = proc_macro2::TokenStream::new(); - for (((query_group, group_name_snake), group_storage), group_index) in query_groups - .iter() - .zip(&query_group_names_snake) - .zip(&query_group_storage_names) - .zip(0_u16..) - { - let group_path = &query_group.group_path; - - // rewrite the last identifier (`MyGroup`, above) to - // (e.g.) `MyGroupGroupStorage`. - storage_fields.extend(quote! { - #group_name_snake: #group_storage, - }); - - // rewrite the last identifier (`MyGroup`, above) to - // (e.g.) `MyGroupGroupStorage`. - storage_initializers.extend(quote! { - #group_name_snake: #group_storage::new(#group_index), - }); - - // ANCHOR:HasQueryGroup - has_group_impls.extend(quote! { - impl ra_salsa::plumbing::HasQueryGroup<#group_path> for #database_name { - fn group_storage(&self) -> &#group_storage { - &self.#db_storage_field.query_store().#group_name_snake - } - - fn group_storage_mut(&mut self) -> (&#group_storage, &mut ra_salsa::Runtime) { - let (query_store_mut, runtime) = self.#db_storage_field.query_store_mut(); - (&query_store_mut.#group_name_snake, runtime) - } - } - }); - // ANCHOR_END:HasQueryGroup - } - - // create group storage wrapper struct - output.extend(quote! { - #[doc(hidden)] - #visibility struct __SalsaDatabaseStorage { - #storage_fields - } - - impl Default for __SalsaDatabaseStorage { - fn default() -> Self { - Self { - #storage_initializers - } - } - } - }); - - // Create a tuple (D1, D2, ...) where Di is the data for a given query group. - let mut database_data = vec![]; - for QueryGroup { group_path } in query_groups { - database_data.push(quote! { - <#group_path as ra_salsa::plumbing::QueryGroup>::GroupData - }); - } - - // ANCHOR:DatabaseStorageTypes - output.extend(quote! { - impl ra_salsa::plumbing::DatabaseStorageTypes for #database_name { - type DatabaseStorage = __SalsaDatabaseStorage; - } - }); - // ANCHOR_END:DatabaseStorageTypes - - // ANCHOR:DatabaseOps - let mut fmt_ops = proc_macro2::TokenStream::new(); - let mut maybe_changed_ops = proc_macro2::TokenStream::new(); - let mut cycle_recovery_strategy_ops = proc_macro2::TokenStream::new(); - let mut for_each_ops = proc_macro2::TokenStream::new(); - for ((QueryGroup { group_path }, group_storage), group_index) in - query_groups.iter().zip(&query_group_storage_names).zip(0_u16..) - { - fmt_ops.extend(quote! { - #group_index => { - let storage: &#group_storage = - >::group_storage(self); - storage.fmt_index(self, input, fmt) - } - }); - maybe_changed_ops.extend(quote! { - #group_index => { - let storage: &#group_storage = - >::group_storage(self); - storage.maybe_changed_after(self, input, revision) - } - }); - cycle_recovery_strategy_ops.extend(quote! { - #group_index => { - let storage: &#group_storage = - >::group_storage(self); - storage.cycle_recovery_strategy(self, input) - } - }); - for_each_ops.extend(quote! { - let storage: &#group_storage = - >::group_storage(self); - storage.for_each_query(runtime, &mut op); - }); - } - output.extend(quote! { - impl ra_salsa::plumbing::DatabaseOps for #database_name { - fn ops_database(&self) -> &dyn ra_salsa::Database { - self - } - - fn ops_salsa_runtime(&self) -> &ra_salsa::Runtime { - self.#db_storage_field.salsa_runtime() - } - - fn synthetic_write(&mut self, durability: ra_salsa::Durability) { - self.#db_storage_field.salsa_runtime_mut().synthetic_write(durability) - } - - fn fmt_index( - &self, - input: ra_salsa::DatabaseKeyIndex, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - match input.group_index() { - #fmt_ops - i => panic!("ra_salsa: invalid group index {}", i) - } - } - - fn maybe_changed_after( - &self, - input: ra_salsa::DatabaseKeyIndex, - revision: ra_salsa::Revision - ) -> bool { - match input.group_index() { - #maybe_changed_ops - i => panic!("ra_salsa: invalid group index {}", i) - } - } - - fn cycle_recovery_strategy( - &self, - input: ra_salsa::DatabaseKeyIndex, - ) -> ra_salsa::plumbing::CycleRecoveryStrategy { - match input.group_index() { - #cycle_recovery_strategy_ops - i => panic!("ra_salsa: invalid group index {}", i) - } - } - - fn for_each_query( - &self, - mut op: &mut dyn FnMut(&dyn ra_salsa::plumbing::QueryStorageMassOps), - ) { - let runtime = ra_salsa::Database::salsa_runtime(self); - #for_each_ops - } - } - }); - // ANCHOR_END:DatabaseOps - - output.extend(has_group_impls); - - output.into() -} - -#[derive(Clone, Debug)] -struct QueryGroupList { - query_groups: PunctuatedQueryGroups, -} - -impl Parse for QueryGroupList { - fn parse(input: ParseStream<'_>) -> syn::Result { - let query_groups: PunctuatedQueryGroups = - input.parse_terminated(QueryGroup::parse, Token![,])?; - Ok(QueryGroupList { query_groups }) - } -} - -#[derive(Clone, Debug)] -struct QueryGroup { - group_path: Path, -} - -impl QueryGroup { - /// The name of the query group trait. - fn name(&self) -> Ident { - self.group_path.segments.last().unwrap().ident.clone() - } -} - -impl Parse for QueryGroup { - /// ```ignore - /// impl HelloWorldDatabase; - /// ``` - fn parse(input: ParseStream<'_>) -> syn::Result { - let group_path: Path = input.parse()?; - Ok(QueryGroup { group_path }) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/lib.rs deleted file mode 100644 index d3e17c5ebf1d4..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/lib.rs +++ /dev/null @@ -1,125 +0,0 @@ -//! This crate provides salsa's macros and attributes. - -#![recursion_limit = "256"] - -#[macro_use] -extern crate quote; - -use proc_macro::TokenStream; - -mod database_storage; -mod parenthesized; -mod query_group; - -/// The decorator that defines a salsa "query group" trait. This is a -/// trait that defines everything that a block of queries need to -/// execute, as well as defining the queries themselves that are -/// exported for others to use. -/// -/// This macro declares the "prototype" for a group of queries. It will -/// expand into a trait and a set of structs, one per query. -/// -/// For each query, you give the name of the accessor method to invoke -/// the query (e.g., `my_query`, below), as well as its parameter -/// types and the output type. You also give the name for a query type -/// (e.g., `MyQuery`, below) that represents the query, and optionally -/// other details, such as its storage. -/// -/// # Examples -/// -/// The simplest example is something like this: -/// -/// ```ignore -/// #[salsa::query_group] -/// trait TypeckDatabase { -/// #[salsa::input] // see below for other legal attributes -/// fn my_query(&self, input: u32) -> u64; -/// -/// /// Queries can have any number of inputs (including zero); if there -/// /// is not exactly one input, then the key type will be -/// /// a tuple of the input types, so in this case `(u32, f32)`. -/// fn other_query(&self, input1: u32, input2: f32) -> u64; -/// } -/// ``` -/// -/// Here is a list of legal `salsa::XXX` attributes: -/// -/// - Storage attributes: control how the query data is stored and set. These -/// are described in detail in the section below. -/// - `#[salsa::input]` -/// - `#[salsa::memoized]` -/// - `#[salsa::dependencies]` -/// - Query execution: -/// - `#[salsa::invoke(path::to::my_fn)]` -- for a non-input, this -/// indicates the function to call when a query must be -/// recomputed. The default is to call a function in the same -/// module with the same name as the query. -/// - `#[query_type(MyQueryTypeName)]` specifies the name of the -/// dummy struct created for the query. Default is the name of the -/// query, in camel case, plus the word "Query" (e.g., -/// `MyQueryQuery` and `OtherQueryQuery` in the examples above). -/// -/// # Storage attributes -/// -/// Here are the possible storage values for each query. The default -/// is `storage memoized`. -/// -/// ## Input queries -/// -/// Specifying `storage input` will give you an **input -/// query**. Unlike derived queries, whose value is given by a -/// function, input queries are explicitly set by doing -/// `db.query(QueryType).set(key, value)` (where `QueryType` is the -/// `type` specified for the query). Accessing a value that has not -/// yet been set will panic. Each time you invoke `set`, we assume the -/// value has changed, and so we will potentially re-execute derived -/// queries that read (transitively) from this input. -/// -/// ## Derived queries -/// -/// Derived queries are specified by a function. -/// -/// - `#[salsa::memoized]` (the default) -- The result is memoized -/// between calls. If the inputs have changed, we will recompute -/// the value, but then compare against the old memoized value, -/// which can significantly reduce the amount of recomputation -/// required in new revisions. This does require that the value -/// implements `Eq`. -/// - `#[salsa::dependencies]` -- does not cache the value, so it will -/// be recomputed every time it is needed. We do track the inputs, however, -/// so if they have not changed, then things that rely on this query -/// may be known not to have changed. -/// -/// ## Attribute combinations -/// -/// Some attributes are mutually exclusive. For example, it is an error to add -/// multiple storage specifiers or to annotate a function to `invoke` on an -/// `input` query. -#[proc_macro_attribute] -pub fn query_group(args: TokenStream, input: TokenStream) -> TokenStream { - query_group::query_group(args, input) -} - -/// This attribute is placed on your database struct. It takes a list of the -/// query groups that your database supports. The format looks like so: -/// -/// ```rust,ignore -/// #[salsa::database(MyQueryGroup1, MyQueryGroup2)] -/// struct MyDatabase { -/// runtime: salsa::Runtime, // <-- your database will need this field, too -/// } -/// ``` -/// -/// Here, the struct `MyDatabase` would support the two query groups -/// `MyQueryGroup1` and `MyQueryGroup2`. In addition to the `database` -/// attribute, the struct needs to have a `runtime` field (of type -/// [`salsa::Runtime`]) and to implement the `salsa::Database` trait. -/// -/// See [the `hello_world` example][hw] for more details. -/// -/// [`salsa::Runtime`]: struct.Runtime.html -/// [hw]: https://github.com/salsa-rs/salsa/tree/master/examples/hello_world -#[proc_macro_attribute] -pub fn database(args: TokenStream, input: TokenStream) -> TokenStream { - database_storage::database(args, input) -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/parenthesized.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/parenthesized.rs deleted file mode 100644 index 5ecd1b8a05838..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/parenthesized.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Parenthesis helper -pub(crate) struct Parenthesized(pub(crate) T); - -impl syn::parse::Parse for Parenthesized -where - T: syn::parse::Parse, -{ - fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { - let content; - syn::parenthesized!(content in input); - content.parse::().map(Parenthesized) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/query_group.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/query_group.rs deleted file mode 100644 index d761a5e798e89..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/query_group.rs +++ /dev/null @@ -1,753 +0,0 @@ -//! Implementation for `[ra_salsa::query_group]` decorator. - -use crate::parenthesized::Parenthesized; -use heck::ToUpperCamelCase; -use proc_macro::TokenStream; -use proc_macro2::Span; -use quote::ToTokens; -use syn::{ - parse_macro_input, parse_quote, spanned::Spanned, Attribute, Error, FnArg, Ident, ItemTrait, - ReturnType, TraitItem, Type, -}; - -/// Implementation for `[ra_salsa::query_group]` decorator. -pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream { - let group_struct = parse_macro_input!(args as Ident); - let input: ItemTrait = parse_macro_input!(input as ItemTrait); - // println!("args: {:#?}", args); - // println!("input: {:#?}", input); - - let input_span = input.span(); - let (trait_attrs, salsa_attrs) = filter_attrs(input.attrs); - if !salsa_attrs.is_empty() { - return Error::new(input_span, format!("unsupported attributes: {salsa_attrs:?}")) - .to_compile_error() - .into(); - } - - let trait_vis = input.vis; - let trait_name = input.ident; - let _generics = input.generics.clone(); - let dyn_db = quote! { dyn #trait_name }; - - // Decompose the trait into the corresponding queries. - let mut queries = vec![]; - for item in input.items { - if let TraitItem::Fn(method) = item { - let query_name = method.sig.ident.to_string(); - - let mut storage = QueryStorage::Memoized; - let mut cycle = None; - let mut invoke = None; - - let mut query_type = - format_ident!("{}Query", query_name.to_string().to_upper_camel_case()); - let mut num_storages = 0; - - // Extract attributes. - let (attrs, salsa_attrs) = filter_attrs(method.attrs); - for SalsaAttr { name, tts, span } in salsa_attrs { - match name.as_str() { - "memoized" => { - storage = QueryStorage::Memoized; - num_storages += 1; - } - "dependencies" => { - storage = QueryStorage::LruDependencies; - num_storages += 1; - } - "lru" => { - storage = QueryStorage::LruMemoized; - num_storages += 1; - } - "input" => { - storage = QueryStorage::Input; - num_storages += 1; - } - "interned" => { - storage = QueryStorage::Interned; - num_storages += 1; - } - "cycle" => { - cycle = Some(parse_macro_input!(tts as Parenthesized).0); - } - "invoke" => { - invoke = Some(parse_macro_input!(tts as Parenthesized).0); - } - "query_type" => { - query_type = parse_macro_input!(tts as Parenthesized).0; - } - "transparent" => { - storage = QueryStorage::Transparent; - num_storages += 1; - } - _ => { - return Error::new(span, format!("unknown ra_salsa attribute `{name}`")) - .to_compile_error() - .into(); - } - } - } - - let sig_span = method.sig.span(); - // Check attribute combinations. - if num_storages > 1 { - return Error::new(sig_span, "multiple storage attributes specified") - .to_compile_error() - .into(); - } - match &invoke { - Some(invoke) if storage == QueryStorage::Input => { - return Error::new( - invoke.span(), - "#[ra_salsa::invoke] cannot be set on #[ra_salsa::input] queries", - ) - .to_compile_error() - .into(); - } - _ => {} - } - - // Extract keys. - let mut iter = method.sig.inputs.iter(); - let self_receiver = match iter.next() { - Some(FnArg::Receiver(sr)) if sr.mutability.is_none() => sr, - _ => { - return Error::new( - sig_span, - format!("first argument of query `{query_name}` must be `&self`"), - ) - .to_compile_error() - .into(); - } - }; - let mut keys: Vec<(Ident, Type)> = vec![]; - for (idx, arg) in iter.enumerate() { - match arg { - FnArg::Typed(syn::PatType { pat, ty, .. }) => keys.push(( - match pat.as_ref() { - syn::Pat::Ident(ident_pat) => ident_pat.ident.clone(), - _ => format_ident!("key{}", idx), - }, - Type::clone(ty), - )), - arg => { - return Error::new( - arg.span(), - format!("unsupported argument `{arg:?}` of `{query_name}`",), - ) - .to_compile_error() - .into(); - } - } - } - - // Extract value. - let value = match method.sig.output { - ReturnType::Type(_, ref ty) => ty.as_ref().clone(), - ref ret => { - return Error::new( - ret.span(), - format!("unsupported return type `{ret:?}` of `{query_name}`"), - ) - .to_compile_error() - .into(); - } - }; - - // For `#[ra_salsa::interned]` keys, we create a "lookup key" automatically. - // - // For a query like: - // - // fn foo(&self, x: Key1, y: Key2) -> u32 - // - // we would create - // - // fn lookup_foo(&self, x: u32) -> (Key1, Key2) - let lookup_query = if let QueryStorage::Interned = storage { - let lookup_query_type = - format_ident!("{}LookupQuery", query_name.to_string().to_upper_camel_case()); - let lookup_fn_name = format_ident!("lookup_{}", query_name); - let keys = keys.iter().map(|(_, ty)| ty); - let lookup_value: Type = parse_quote!((#(#keys),*)); - let lookup_keys = vec![(parse_quote! { key }, value.clone())]; - Some(Query { - query_type: lookup_query_type, - query_name: format!("{lookup_fn_name}"), - fn_name: lookup_fn_name, - receiver: self_receiver.clone(), - attrs: vec![], // FIXME -- some automatically generated docs on this method? - storage: QueryStorage::InternedLookup { intern_query_type: query_type.clone() }, - keys: lookup_keys, - value: lookup_value, - invoke: None, - cycle: cycle.clone(), - }) - } else { - None - }; - - queries.push(Query { - query_type, - query_name, - fn_name: method.sig.ident, - receiver: self_receiver.clone(), - attrs, - storage, - keys, - value, - invoke, - cycle, - }); - - queries.extend(lookup_query); - } - } - - let group_storage = format_ident!("{}GroupStorage__", trait_name, span = Span::call_site()); - - let mut query_fn_declarations = proc_macro2::TokenStream::new(); - let mut query_fn_definitions = proc_macro2::TokenStream::new(); - let mut storage_fields = proc_macro2::TokenStream::new(); - let mut queries_with_storage = vec![]; - for query in &queries { - #[allow(clippy::map_identity)] - // clippy is incorrect here, this is not the identity function due to match ergonomics - let (key_names, keys): (Vec<_>, Vec<_>) = query.keys.iter().map(|(a, b)| (a, b)).unzip(); - let value = &query.value; - let fn_name = &query.fn_name; - let qt = &query.query_type; - let attrs = &query.attrs; - let self_receiver = &query.receiver; - - query_fn_declarations.extend(quote! { - #(#attrs)* - fn #fn_name(#self_receiver, #(#key_names: #keys),*) -> #value; - }); - - // Special case: transparent queries don't create actual storage, - // just inline the definition - if let QueryStorage::Transparent = query.storage { - let invoke = query.invoke_tt(); - query_fn_definitions.extend(quote! { - fn #fn_name(&self, #(#key_names: #keys),*) -> #value { - #invoke(self, #(#key_names),*) - } - }); - continue; - } - - queries_with_storage.push(fn_name); - - let tracing = if let QueryStorage::Memoized | QueryStorage::LruMemoized = query.storage { - let s = format!("{trait_name}::{fn_name}"); - Some(quote! { - let _p = tracing::trace_span!(#s, #(#key_names = tracing::field::debug(&#key_names)),*).entered(); - }) - } else { - None - } - .into_iter(); - - query_fn_definitions.extend(quote! { - fn #fn_name(&self, #(#key_names: #keys),*) -> #value { - #(#tracing),* - // Create a shim to force the code to be monomorphized in the - // query crate. Our experiments revealed that this makes a big - // difference in total compilation time in rust-analyzer, though - // it's not totally obvious why that should be. - fn __shim(db: &(dyn #trait_name + '_), #(#key_names: #keys),*) -> #value { - ra_salsa::plumbing::get_query_table::<#qt>(db).get((#(#key_names),*)) - } - __shim(self, #(#key_names),*) - - } - }); - - // For input queries, we need `set_foo` etc - if let QueryStorage::Input = query.storage { - let set_fn_name = format_ident!("set_{}", fn_name); - let set_with_durability_fn_name = format_ident!("set_{}_with_durability", fn_name); - - let set_fn_docs = format!( - " - Set the value of the `{fn_name}` input. - - See `{fn_name}` for details. - - *Note:* Setting values will trigger cancellation - of any ongoing queries; this method blocks until - those queries have been cancelled. - " - ); - - let set_constant_fn_docs = format!( - " - Set the value of the `{fn_name}` input with a - specific durability instead of the default of - `Durability::LOW`. You can use `Durability::MAX` - to promise that its value will never change again. - - See `{fn_name}` for details. - - *Note:* Setting values will trigger cancellation - of any ongoing queries; this method blocks until - those queries have been cancelled. - " - ); - - query_fn_declarations.extend(quote! { - # [doc = #set_fn_docs] - fn #set_fn_name(&mut self, #(#key_names: #keys,)* value__: #value); - - - # [doc = #set_constant_fn_docs] - fn #set_with_durability_fn_name(&mut self, #(#key_names: #keys,)* value__: #value, durability__: ra_salsa::Durability); - }); - - query_fn_definitions.extend(quote! { - fn #set_fn_name(&mut self, #(#key_names: #keys,)* value__: #value) { - fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value) { - ra_salsa::plumbing::get_query_table_mut::<#qt>(db).set((#(#key_names),*), value__) - } - __shim(self, #(#key_names,)* value__) - } - - fn #set_with_durability_fn_name(&mut self, #(#key_names: #keys,)* value__: #value, durability__: ra_salsa::Durability) { - fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value, durability__: ra_salsa::Durability) { - ra_salsa::plumbing::get_query_table_mut::<#qt>(db).set_with_durability((#(#key_names),*), value__, durability__) - } - __shim(self, #(#key_names,)* value__ ,durability__) - } - }); - } - - // A field for the storage struct - storage_fields.extend(quote! { - #fn_name: std::sync::Arc<<#qt as ra_salsa::Query>::Storage>, - }); - } - - // Emit the trait itself. - let mut output = { - let bounds = &input.supertraits; - quote! { - #(#trait_attrs)* - #trait_vis trait #trait_name : - ra_salsa::Database + - ra_salsa::plumbing::HasQueryGroup<#group_struct> + - #bounds - { - #query_fn_declarations - } - } - }; - - // Emit the query group struct and impl of `QueryGroup`. - output.extend(quote! { - /// Representative struct for the query group. - #trait_vis struct #group_struct { } - - impl ra_salsa::plumbing::QueryGroup for #group_struct - { - type DynDb = #dyn_db; - type GroupStorage = #group_storage; - } - }); - - // Emit an impl of the trait - output.extend({ - let bounds = input.supertraits; - quote! { - impl #trait_name for DB - where - DB: #bounds, - DB: ra_salsa::Database, - DB: ra_salsa::plumbing::HasQueryGroup<#group_struct>, - { - #query_fn_definitions - } - } - }); - - let non_transparent_queries = - || queries.iter().filter(|q| !matches!(q.storage, QueryStorage::Transparent)); - - // Emit the query types. - for (query, query_index) in non_transparent_queries().zip(0_u16..) { - let fn_name = &query.fn_name; - let qt = &query.query_type; - - let storage = match &query.storage { - QueryStorage::Memoized => quote!(ra_salsa::plumbing::MemoizedStorage), - QueryStorage::LruMemoized => quote!(ra_salsa::plumbing::LruMemoizedStorage), - QueryStorage::LruDependencies => { - quote!(ra_salsa::plumbing::LruDependencyStorage) - } - QueryStorage::Input if query.keys.is_empty() => { - quote!(ra_salsa::plumbing::UnitInputStorage) - } - QueryStorage::Input => quote!(ra_salsa::plumbing::InputStorage), - QueryStorage::Interned => quote!(ra_salsa::plumbing::InternedStorage), - QueryStorage::InternedLookup { intern_query_type } => { - quote!(ra_salsa::plumbing::LookupInternedStorage) - } - QueryStorage::Transparent => panic!("should have been filtered"), - }; - let keys = query.keys.iter().map(|(_, ty)| ty); - let value = &query.value; - let query_name = &query.query_name; - - // Emit the query struct and implement the Query trait on it. - output.extend(quote! { - #[derive(Default, Debug)] - #trait_vis struct #qt; - }); - - output.extend(quote! { - impl #qt { - /// Get access to extra methods pertaining to this query. - /// You can also use it to invoke this query. - #trait_vis fn in_db(self, db: &#dyn_db) -> ra_salsa::QueryTable<'_, Self> - { - ra_salsa::plumbing::get_query_table::<#qt>(db) - } - } - }); - - output.extend(quote! { - impl #qt { - /// Like `in_db`, but gives access to methods for setting the - /// value of an input. Not applicable to derived queries. - /// - /// # Threads, cancellation, and blocking - /// - /// Mutating the value of a query cannot be done while there are - /// still other queries executing. If you are using your database - /// within a single thread, this is not a problem: you only have - /// `&self` access to the database, but this method requires `&mut - /// self`. - /// - /// However, if you have used `snapshot` to create other threads, - /// then attempts to `set` will **block the current thread** until - /// those snapshots are dropped (usually when those threads - /// complete). This also implies that if you create a snapshot but - /// do not send it to another thread, then invoking `set` will - /// deadlock. - /// - /// Before blocking, the thread that is attempting to `set` will - /// also set a cancellation flag. This will cause any query - /// invocations in other threads to unwind with a `Cancelled` - /// sentinel value and eventually let the `set` succeed once all - /// threads have unwound past the ra_salsa invocation. - /// - /// If your query implementations are performing expensive - /// operations without invoking another query, you can also use - /// the `Runtime::unwind_if_cancelled` method to check for an - /// ongoing cancellation and bring those operations to a close, - /// thus allowing the `set` to succeed. Otherwise, long-running - /// computations may lead to "starvation", meaning that the - /// thread attempting to `set` has to wait a long, long time. =) - #trait_vis fn in_db_mut(self, db: &mut #dyn_db) -> ra_salsa::QueryTableMut<'_, Self> - { - ra_salsa::plumbing::get_query_table_mut::<#qt>(db) - } - } - - impl<'d> ra_salsa::QueryDb<'d> for #qt - { - type DynDb = #dyn_db + 'd; - type Group = #group_struct; - type GroupStorage = #group_storage; - } - - // ANCHOR:Query_impl - impl ra_salsa::Query for #qt - { - type Key = (#(#keys),*); - type Value = #value; - type Storage = #storage; - - const QUERY_INDEX: u16 = #query_index; - - const QUERY_NAME: &'static str = #query_name; - - fn query_storage<'a>( - group_storage: &'a >::GroupStorage, - ) -> &'a std::sync::Arc { - &group_storage.#fn_name - } - - fn query_storage_mut<'a>( - group_storage: &'a >::GroupStorage, - ) -> &'a std::sync::Arc { - &group_storage.#fn_name - } - } - // ANCHOR_END:Query_impl - }); - - // Implement the QueryFunction trait for queries which need it. - if query.storage.needs_query_function() { - let span = query.fn_name.span(); - - let key_names: Vec<_> = query.keys.iter().map(|(pat, _)| pat).collect(); - let key_pattern = if query.keys.len() == 1 { - quote! { #(#key_names),* } - } else { - quote! { (#(#key_names),*) } - }; - let invoke = query.invoke_tt(); - - let recover = if let Some(cycle_recovery_fn) = &query.cycle { - quote! { - const CYCLE_STRATEGY: ra_salsa::plumbing::CycleRecoveryStrategy = - ra_salsa::plumbing::CycleRecoveryStrategy::Fallback; - fn cycle_fallback(db: &>::DynDb, cycle: &ra_salsa::Cycle, #key_pattern: &::Key) - -> ::Value { - #cycle_recovery_fn( - db, - cycle, - #(#key_names),* - ) - } - } - } else { - quote! { - const CYCLE_STRATEGY: ra_salsa::plumbing::CycleRecoveryStrategy = - ra_salsa::plumbing::CycleRecoveryStrategy::Panic; - } - }; - - output.extend(quote_spanned! {span=> - // ANCHOR:QueryFunction_impl - impl ra_salsa::plumbing::QueryFunction for #qt - { - fn execute(db: &>::DynDb, #key_pattern: ::Key) - -> ::Value { - #invoke(db, #(#key_names),*) - } - - #recover - } - // ANCHOR_END:QueryFunction_impl - }); - } - } - - let mut fmt_ops = proc_macro2::TokenStream::new(); - for (Query { fn_name, .. }, query_index) in non_transparent_queries().zip(0_u16..) { - fmt_ops.extend(quote! { - #query_index => { - ra_salsa::plumbing::QueryStorageOps::fmt_index( - &*self.#fn_name, db, input.key_index(), fmt, - ) - } - }); - } - - let mut maybe_changed_ops = proc_macro2::TokenStream::new(); - for (Query { fn_name, .. }, query_index) in non_transparent_queries().zip(0_u16..) { - maybe_changed_ops.extend(quote! { - #query_index => { - ra_salsa::plumbing::QueryStorageOps::maybe_changed_after( - &*self.#fn_name, db, input.key_index(), revision - ) - } - }); - } - - let mut cycle_recovery_strategy_ops = proc_macro2::TokenStream::new(); - for (Query { fn_name, .. }, query_index) in non_transparent_queries().zip(0_u16..) { - cycle_recovery_strategy_ops.extend(quote! { - #query_index => { - ra_salsa::plumbing::QueryStorageOps::cycle_recovery_strategy( - &*self.#fn_name - ) - } - }); - } - - let mut for_each_ops = proc_macro2::TokenStream::new(); - for Query { fn_name, .. } in non_transparent_queries() { - for_each_ops.extend(quote! { - op(&*self.#fn_name); - }); - } - - // Emit query group storage struct - output.extend(quote! { - #trait_vis struct #group_storage { - #storage_fields - } - - // ANCHOR:group_storage_new - impl #group_storage { - #trait_vis fn new(group_index: u16) -> Self { - #group_storage { - #( - #queries_with_storage: - std::sync::Arc::new(ra_salsa::plumbing::QueryStorageOps::new(group_index)), - )* - } - } - } - // ANCHOR_END:group_storage_new - - // ANCHOR:group_storage_methods - impl #group_storage { - #trait_vis fn fmt_index( - &self, - db: &(#dyn_db + '_), - input: ra_salsa::DatabaseKeyIndex, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - match input.query_index() { - #fmt_ops - i => panic!("ra_salsa: impossible query index {}", i), - } - } - - #trait_vis fn maybe_changed_after( - &self, - db: &(#dyn_db + '_), - input: ra_salsa::DatabaseKeyIndex, - revision: ra_salsa::Revision, - ) -> bool { - match input.query_index() { - #maybe_changed_ops - i => panic!("ra_salsa: impossible query index {}", i), - } - } - - #trait_vis fn cycle_recovery_strategy( - &self, - db: &(#dyn_db + '_), - input: ra_salsa::DatabaseKeyIndex, - ) -> ra_salsa::plumbing::CycleRecoveryStrategy { - match input.query_index() { - #cycle_recovery_strategy_ops - i => panic!("ra_salsa: impossible query index {}", i), - } - } - - #trait_vis fn for_each_query( - &self, - _runtime: &ra_salsa::Runtime, - mut op: &mut dyn FnMut(&dyn ra_salsa::plumbing::QueryStorageMassOps), - ) { - #for_each_ops - } - } - // ANCHOR_END:group_storage_methods - }); - output.into() -} - -struct SalsaAttr { - name: String, - tts: TokenStream, - span: Span, -} - -impl std::fmt::Debug for SalsaAttr { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(fmt, "{:?}", self.name) - } -} - -impl TryFrom for SalsaAttr { - type Error = syn::Attribute; - - fn try_from(attr: syn::Attribute) -> Result { - if is_not_salsa_attr_path(attr.path()) { - return Err(attr); - } - - let span = attr.span(); - let name = attr.path().segments[1].ident.to_string(); - let tts = match attr.meta { - syn::Meta::Path(path) => path.into_token_stream(), - syn::Meta::List(ref list) => { - let tts = list - .into_token_stream() - .into_iter() - .skip(attr.path().to_token_stream().into_iter().count()); - proc_macro2::TokenStream::from_iter(tts) - } - syn::Meta::NameValue(nv) => nv.into_token_stream(), - } - .into(); - - Ok(SalsaAttr { name, tts, span }) - } -} - -fn is_not_salsa_attr_path(path: &syn::Path) -> bool { - path.segments.first().map(|s| s.ident != "ra_salsa").unwrap_or(true) || path.segments.len() != 2 -} - -fn filter_attrs(attrs: Vec) -> (Vec, Vec) { - let mut other = vec![]; - let mut ra_salsa = vec![]; - // Leave non-ra_salsa attributes untouched. These are - // attributes that don't start with `ra_salsa::` or don't have - // exactly two segments in their path. - // Keep the ra_salsa attributes around. - for attr in attrs { - match SalsaAttr::try_from(attr) { - Ok(it) => ra_salsa.push(it), - Err(it) => other.push(it), - } - } - (other, ra_salsa) -} - -#[derive(Debug)] -struct Query { - fn_name: Ident, - receiver: syn::Receiver, - query_name: String, - attrs: Vec, - query_type: Ident, - storage: QueryStorage, - keys: Vec<(Ident, syn::Type)>, - value: syn::Type, - invoke: Option, - cycle: Option, -} - -impl Query { - fn invoke_tt(&self) -> proc_macro2::TokenStream { - match &self.invoke { - Some(i) => i.into_token_stream(), - None => self.fn_name.clone().into_token_stream(), - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -enum QueryStorage { - Memoized, - LruDependencies, - LruMemoized, - Input, - Interned, - InternedLookup { intern_query_type: Ident }, - Transparent, -} - -impl QueryStorage { - /// Do we need a `QueryFunction` impl for this type of query? - fn needs_query_function(&self) -> bool { - match self { - QueryStorage::Input - | QueryStorage::Interned - | QueryStorage::InternedLookup { .. } - | QueryStorage::Transparent => false, - QueryStorage::Memoized | QueryStorage::LruMemoized | QueryStorage::LruDependencies => { - true - } - } - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/debug.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/debug.rs deleted file mode 100644 index 5f113541f04cf..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/debug.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! Debugging APIs: these are meant for use when unit-testing or -//! debugging your application but aren't ordinarily needed. - -use crate::durability::Durability; -use crate::plumbing::QueryStorageOps; -use crate::Query; -use crate::QueryTable; - -/// Additional methods on queries that can be used to "peek into" -/// their current state. These methods are meant for debugging and -/// observing the effects of garbage collection etc. -pub trait DebugQueryTable { - /// Key of this query. - type Key; - - /// Value of this query. - type Value; - - /// Returns a lower bound on the durability for the given key. - /// This is typically the minimum durability of all values that - /// the query accessed, but we may return a lower durability in - /// some cases. - fn durability(&self, key: Self::Key) -> Durability; - - /// Get the (current) set of the entries in the query table. - fn entries(&self) -> C - where - C: FromIterator>; -} - -/// An entry from a query table, for debugging and inspecting the table state. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -#[non_exhaustive] -pub struct TableEntry { - /// key of the query - pub key: K, - /// value of the query, if it is stored - pub value: Option, -} - -impl TableEntry { - pub(crate) fn new(key: K, value: Option) -> TableEntry { - TableEntry { key, value } - } -} - -impl DebugQueryTable for QueryTable<'_, Q> -where - Q: Query, - Q::Storage: QueryStorageOps, -{ - type Key = Q::Key; - type Value = Q::Value; - - fn durability(&self, key: Q::Key) -> Durability { - self.storage.durability(self.db, &key) - } - - fn entries(&self) -> C - where - C: FromIterator>, - { - self.storage.entries(self.db) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/derived.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived.rs deleted file mode 100644 index 8b2fdd6b19cc8..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/derived.rs +++ /dev/null @@ -1,163 +0,0 @@ -use crate::debug::TableEntry; -use crate::durability::Durability; -use crate::hash::FxIndexMap; -use crate::plumbing::DerivedQueryStorageOps; -use crate::plumbing::QueryFunction; -use crate::plumbing::QueryStorageMassOps; -use crate::plumbing::QueryStorageOps; -use crate::runtime::StampedValue; -use crate::Runtime; -use crate::{Database, DatabaseKeyIndex, QueryDb, Revision}; -use parking_lot::RwLock; -use std::borrow::Borrow; -use std::hash::Hash; -use triomphe::Arc; - -mod slot; -use slot::Slot; - -/// Memoized queries store the result plus a list of the other queries -/// that they invoked. This means we can avoid recomputing them when -/// none of those inputs have changed. -pub type MemoizedStorage = DerivedStorage; - -/// Handles storage where the value is 'derived' by executing a -/// function (in contrast to "inputs"). -pub struct DerivedStorage -where - Q: QueryFunction, -{ - group_index: u16, - slot_map: RwLock>>>, -} - -impl std::panic::RefUnwindSafe for DerivedStorage -where - Q: QueryFunction, - - Q::Key: std::panic::RefUnwindSafe, - Q::Value: std::panic::RefUnwindSafe, -{ -} - -impl DerivedStorage -where - Q: QueryFunction, - Q::Value: Eq, -{ - fn slot(&self, key: &Q::Key) -> Arc> { - if let Some(v) = self.slot_map.read().get(key) { - return v.clone(); - } - - let mut write = self.slot_map.write(); - let entry = write.entry(key.clone()); - let key_index = entry.index() as u32; - let database_key_index = DatabaseKeyIndex { - group_index: self.group_index, - query_index: Q::QUERY_INDEX, - key_index, - }; - entry.or_insert_with(|| Arc::new(Slot::new(database_key_index))).clone() - } -} - -impl QueryStorageOps for DerivedStorage -where - Q: QueryFunction, - Q::Value: Eq, -{ - const CYCLE_STRATEGY: crate::plumbing::CycleRecoveryStrategy = Q::CYCLE_STRATEGY; - - fn new(group_index: u16) -> Self { - DerivedStorage { group_index, slot_map: RwLock::new(FxIndexMap::default()) } - } - - fn fmt_index( - &self, - _db: &>::DynDb, - index: u32, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - let slot_map = self.slot_map.read(); - let key = slot_map.get_index(index as usize).unwrap().0; - write!(fmt, "{}::{}({:?})", std::any::type_name::(), Q::QUERY_NAME, key) - } - - fn maybe_changed_after( - &self, - db: &>::DynDb, - index: u32, - revision: Revision, - ) -> bool { - debug_assert!(revision < db.salsa_runtime().current_revision()); - let (key, slot) = { - let read = self.slot_map.read(); - let Some((key, slot)) = read.get_index(index as usize) else { - return false; - }; - (key.clone(), slot.clone()) - }; - slot.maybe_changed_after(db, revision, &key) - } - - fn fetch(&self, db: &>::DynDb, key: &Q::Key) -> Q::Value { - db.unwind_if_cancelled(); - - let slot = self.slot(key); - let StampedValue { value, durability, changed_at } = slot.read(db, key); - - db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted( - slot.database_key_index(), - durability, - changed_at, - ); - - value - } - - fn durability(&self, db: &>::DynDb, key: &Q::Key) -> Durability { - self.slot_map.read().get(key).map_or(Durability::LOW, |slot| slot.durability(db)) - } - - fn entries(&self, _db: &>::DynDb) -> C - where - C: std::iter::FromIterator>, - { - let slot_map = self.slot_map.read(); - slot_map.iter().filter_map(|(key, slot)| slot.as_table_entry(key)).collect() - } -} - -impl QueryStorageMassOps for DerivedStorage -where - Q: QueryFunction, -{ - fn purge(&self) { - *self.slot_map.write() = Default::default(); - } -} - -impl DerivedQueryStorageOps for DerivedStorage -where - Q: QueryFunction, - Q::Value: Eq, -{ - fn invalidate(&self, runtime: &mut Runtime, key: &S) - where - S: Eq + Hash, - Q::Key: Borrow, - { - runtime.with_incremented_revision(|new_revision| { - let map_read = self.slot_map.read(); - - if let Some(slot) = map_read.get(key) { - if let Some(durability) = slot.invalidate(new_revision) { - return Some(durability); - } - } - - None - }) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/derived/slot.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived/slot.rs deleted file mode 100644 index cfe2c48f411f1..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/derived/slot.rs +++ /dev/null @@ -1,782 +0,0 @@ -use crate::debug::TableEntry; -use crate::durability::Durability; -use crate::plumbing::{DatabaseOps, QueryFunction}; -use crate::revision::Revision; -use crate::runtime::local_state::ActiveQueryGuard; -use crate::runtime::local_state::QueryRevisions; -use crate::runtime::Runtime; -use crate::runtime::RuntimeId; -use crate::runtime::StampedValue; -use crate::runtime::WaitResult; -use crate::Cycle; -use crate::{Database, DatabaseKeyIndex, Event, EventKind, QueryDb}; -use parking_lot::{RawRwLock, RwLock}; -use std::ops::Deref; -use std::sync::atomic::{AtomicBool, Ordering}; -use tracing::trace; - -pub(super) struct Slot -where - Q: QueryFunction, -{ - key_index: u32, - // FIXME: Yeet this - group_index: u16, - state: RwLock>, -} - -/// Defines the "current state" of query's memoized results. -enum QueryState -where - Q: QueryFunction, -{ - NotComputed, - - /// The runtime with the given id is currently computing the - /// result of this query. - InProgress { - id: RuntimeId, - - /// Set to true if any other queries are blocked, - /// waiting for this query to complete. - anyone_waiting: AtomicBool, - }, - - /// We have computed the query already, and here is the result. - Memoized(Memo), -} - -struct Memo { - /// The result of the query, if we decide to memoize it. - value: V, - - /// Last revision when this memo was verified; this begins - /// as the current revision. - pub(crate) verified_at: Revision, - - /// Revision information - revisions: QueryRevisions, -} - -/// Return value of `probe` helper. -enum ProbeState { - /// Another thread was active but has completed. - /// Try again! - Retry, - - /// No entry for this key at all. - NotComputed(G), - - /// There is an entry, but its contents have not been - /// verified in this revision. - Stale(G), - - /// There is an entry which has been verified, - /// and it has the following value-- or, we blocked - /// on another thread, and that resulted in a cycle. - UpToDate(V), -} - -/// Return value of `maybe_changed_after_probe` helper. -enum MaybeChangedSinceProbeState { - /// Another thread was active but has completed. - /// Try again! - Retry, - - /// Value may have changed in the given revision. - ChangedAt(Revision), - - /// There is a stale cache entry that has not been - /// verified in this revision, so we can't say. - Stale(G), -} - -impl Slot -where - Q: QueryFunction, - Q::Value: Eq, -{ - pub(super) fn new(database_key_index: DatabaseKeyIndex) -> Self { - Self { - key_index: database_key_index.key_index, - group_index: database_key_index.group_index, - state: RwLock::new(QueryState::NotComputed), - } - } - - pub(super) fn database_key_index(&self) -> DatabaseKeyIndex { - DatabaseKeyIndex { - group_index: self.group_index, - query_index: Q::QUERY_INDEX, - key_index: self.key_index, - } - } - - pub(super) fn read( - &self, - db: &>::DynDb, - key: &Q::Key, - ) -> StampedValue { - let runtime = db.salsa_runtime(); - - // NB: We don't need to worry about people modifying the - // revision out from under our feet. Either `db` is a frozen - // database, in which case there is a lock, or the mutator - // thread is the current thread, and it will be prevented from - // doing any `set` invocations while the query function runs. - let revision_now = runtime.current_revision(); - - trace!("{:?}: invoked at {:?}", self, revision_now,); - - // First, do a check with a read-lock. - loop { - match self.probe(db, self.state.read(), runtime, revision_now) { - ProbeState::UpToDate(v) => return v, - ProbeState::Stale(..) | ProbeState::NotComputed(..) => break, - ProbeState::Retry => continue, - } - } - - self.read_upgrade(db, key, revision_now) - } - - /// Second phase of a read operation: acquires an upgradable-read - /// and -- if needed -- validates whether inputs have changed, - /// recomputes value, etc. This is invoked after our initial probe - /// shows a potentially out of date value. - fn read_upgrade( - &self, - db: &>::DynDb, - key: &Q::Key, - revision_now: Revision, - ) -> StampedValue { - let runtime = db.salsa_runtime(); - - trace!("{:?}: read_upgrade(revision_now={:?})", self, revision_now,); - - // Check with an upgradable read to see if there is a value - // already. (This permits other readers but prevents anyone - // else from running `read_upgrade` at the same time.) - let mut old_memo = loop { - match self.probe(db, self.state.upgradable_read(), runtime, revision_now) { - ProbeState::UpToDate(v) => return v, - ProbeState::Stale(state) | ProbeState::NotComputed(state) => { - type RwLockUpgradableReadGuard<'a, T> = - lock_api::RwLockUpgradableReadGuard<'a, RawRwLock, T>; - - let mut state = RwLockUpgradableReadGuard::upgrade(state); - match std::mem::replace(&mut *state, QueryState::in_progress(runtime.id())) { - QueryState::Memoized(old_memo) => break Some(old_memo), - QueryState::InProgress { .. } => unreachable!(), - QueryState::NotComputed => break None, - } - } - ProbeState::Retry => continue, - } - }; - - let panic_guard = PanicGuard::new(self, runtime); - let active_query = runtime.push_query(self.database_key_index()); - - // If we have an old-value, it *may* now be stale, since there - // has been a new revision since the last time we checked. So, - // first things first, let's walk over each of our previous - // inputs and check whether they are out of date. - if let Some(memo) = &mut old_memo { - if let Some(value) = memo.verify_value(db.ops_database(), revision_now, &active_query) { - trace!("{:?}: validated old memoized value", self,); - - db.salsa_event(Event { - runtime_id: runtime.id(), - kind: EventKind::DidValidateMemoizedValue { - database_key: self.database_key_index(), - }, - }); - - panic_guard.proceed(old_memo); - - return value; - } - } - - self.execute(db, runtime, revision_now, active_query, panic_guard, old_memo, key) - } - - fn execute( - &self, - db: &>::DynDb, - runtime: &Runtime, - revision_now: Revision, - active_query: ActiveQueryGuard<'_>, - panic_guard: PanicGuard<'_, Q>, - old_memo: Option>, - key: &Q::Key, - ) -> StampedValue { - tracing::trace!("{:?}: executing query", self.database_key_index().debug(db)); - - db.salsa_event(Event { - runtime_id: db.salsa_runtime().id(), - kind: EventKind::WillExecute { database_key: self.database_key_index() }, - }); - - // Query was not previously executed, or value is potentially - // stale, or value is absent. Let's execute! - let value = match Cycle::catch(|| Q::execute(db, key.clone())) { - Ok(v) => v, - Err(cycle) => { - tracing::trace!( - "{:?}: caught cycle {:?}, have strategy {:?}", - self.database_key_index().debug(db), - cycle, - Q::CYCLE_STRATEGY, - ); - match Q::CYCLE_STRATEGY { - crate::plumbing::CycleRecoveryStrategy::Panic => { - panic_guard.proceed(None); - cycle.throw() - } - crate::plumbing::CycleRecoveryStrategy::Fallback => { - if let Some(c) = active_query.take_cycle() { - assert!(c.is(&cycle)); - Q::cycle_fallback(db, &cycle, key) - } else { - // we are not a participant in this cycle - debug_assert!(!cycle - .participant_keys() - .any(|k| k == self.database_key_index())); - cycle.throw() - } - } - } - } - }; - - let mut revisions = active_query.pop(); - - // We assume that query is side-effect free -- that is, does - // not mutate the "inputs" to the query system. Sanity check - // that assumption here, at least to the best of our ability. - assert_eq!( - runtime.current_revision(), - revision_now, - "revision altered during query execution", - ); - - // If the new value is equal to the old one, then it didn't - // really change, even if some of its inputs have. So we can - // "backdate" its `changed_at` revision to be the same as the - // old value. - if let Some(old_memo) = &old_memo { - // Careful: if the value became less durable than it - // used to be, that is a "breaking change" that our - // consumers must be aware of. Becoming *more* durable - // is not. See the test `constant_to_non_constant`. - if revisions.durability >= old_memo.revisions.durability && old_memo.value == value { - trace!( - "read_upgrade({:?}): value is equal, back-dating to {:?}", - self, - old_memo.revisions.changed_at, - ); - - assert!(old_memo.revisions.changed_at <= revisions.changed_at); - revisions.changed_at = old_memo.revisions.changed_at; - } - } - - let new_value = StampedValue { - value, - durability: revisions.durability, - changed_at: revisions.changed_at, - }; - - let memo_value = new_value.value.clone(); - - trace!("read_upgrade({:?}): result.revisions = {:#?}", self, revisions,); - - panic_guard.proceed(Some(Memo { value: memo_value, verified_at: revision_now, revisions })); - - new_value - } - - /// Helper for `read` that does a shallow check (not recursive) if we have an up-to-date value. - /// - /// Invoked with the guard `state` corresponding to the `QueryState` of some `Slot` (the guard - /// can be either read or write). Returns a suitable `ProbeState`: - /// - /// - `ProbeState::UpToDate(r)` if the table has an up-to-date value (or we blocked on another - /// thread that produced such a value). - /// - `ProbeState::StaleOrAbsent(g)` if either (a) there is no memo for this key, (b) the memo - /// has no value; or (c) the memo has not been verified at the current revision. - /// - /// Note that in case `ProbeState::UpToDate`, the lock will have been released. - fn probe( - &self, - db: &>::DynDb, - state: StateGuard, - runtime: &Runtime, - revision_now: Revision, - ) -> ProbeState, StateGuard> - where - StateGuard: Deref>, - { - match &*state { - QueryState::NotComputed => ProbeState::NotComputed(state), - - QueryState::InProgress { id, anyone_waiting } => { - let other_id = *id; - - // NB: `Ordering::Relaxed` is sufficient here, - // as there are no loads that are "gated" on this - // value. Everything that is written is also protected - // by a lock that must be acquired. The role of this - // boolean is to decide *whether* to acquire the lock, - // not to gate future atomic reads. - anyone_waiting.store(true, Ordering::Relaxed); - - self.block_on_or_unwind(db, runtime, other_id, state); - - // Other thread completely normally, so our value may be available now. - ProbeState::Retry - } - - QueryState::Memoized(memo) => { - trace!( - "{:?}: found memoized value, verified_at={:?}, changed_at={:?}", - self, - memo.verified_at, - memo.revisions.changed_at, - ); - - if memo.verified_at < revision_now { - return ProbeState::Stale(state); - } - - let value = &memo.value; - let value = StampedValue { - durability: memo.revisions.durability, - changed_at: memo.revisions.changed_at, - value: value.clone(), - }; - - trace!("{:?}: returning memoized value changed at {:?}", self, value.changed_at); - - ProbeState::UpToDate(value) - } - } - } - - pub(super) fn durability(&self, db: &>::DynDb) -> Durability { - match &*self.state.read() { - QueryState::NotComputed => Durability::LOW, - QueryState::InProgress { .. } => panic!("query in progress"), - QueryState::Memoized(memo) => { - if memo.check_durability(db.salsa_runtime()) { - memo.revisions.durability - } else { - Durability::LOW - } - } - } - } - - pub(super) fn as_table_entry(&self, key: &Q::Key) -> Option> { - match &*self.state.read() { - QueryState::NotComputed => None, - QueryState::InProgress { .. } => Some(TableEntry::new(key.clone(), None)), - QueryState::Memoized(memo) => { - Some(TableEntry::new(key.clone(), Some(memo.value.clone()))) - } - } - } - - pub(super) fn invalidate(&self, new_revision: Revision) -> Option { - tracing::trace!("Slot::invalidate(new_revision = {:?})", new_revision); - match &mut *self.state.write() { - QueryState::Memoized(memo) => { - memo.revisions.untracked = true; - memo.revisions.inputs = None; - memo.revisions.changed_at = new_revision; - Some(memo.revisions.durability) - } - QueryState::NotComputed => None, - QueryState::InProgress { .. } => unreachable!(), - } - } - - pub(super) fn maybe_changed_after( - &self, - db: &>::DynDb, - revision: Revision, - key: &Q::Key, - ) -> bool { - let runtime = db.salsa_runtime(); - let revision_now = runtime.current_revision(); - - db.unwind_if_cancelled(); - - trace!( - "maybe_changed_after({:?}) called with revision={:?}, revision_now={:?}", - self, - revision, - revision_now, - ); - - // Do an initial probe with just the read-lock. - // - // If we find that a cache entry for the value is present - // but hasn't been verified in this revision, we'll have to - // do more. - loop { - match self.maybe_changed_after_probe(db, self.state.read(), runtime, revision_now) { - MaybeChangedSinceProbeState::Retry => continue, - MaybeChangedSinceProbeState::ChangedAt(changed_at) => return changed_at > revision, - MaybeChangedSinceProbeState::Stale(state) => { - drop(state); - return self.maybe_changed_after_upgrade(db, revision, key); - } - } - } - } - - fn maybe_changed_after_probe( - &self, - db: &>::DynDb, - state: StateGuard, - runtime: &Runtime, - revision_now: Revision, - ) -> MaybeChangedSinceProbeState - where - StateGuard: Deref>, - { - match self.probe(db, state, runtime, revision_now) { - ProbeState::Retry => MaybeChangedSinceProbeState::Retry, - - ProbeState::Stale(state) => MaybeChangedSinceProbeState::Stale(state), - - // If we know when value last changed, we can return right away. - // Note that we don't need the actual value to be available. - ProbeState::UpToDate(StampedValue { value: _, durability: _, changed_at }) => { - MaybeChangedSinceProbeState::ChangedAt(changed_at) - } - - // If we have nothing cached, then value may have changed. - ProbeState::NotComputed(_) => MaybeChangedSinceProbeState::ChangedAt(revision_now), - } - } - - fn maybe_changed_after_upgrade( - &self, - db: &>::DynDb, - revision: Revision, - key: &Q::Key, - ) -> bool { - let runtime = db.salsa_runtime(); - let revision_now = runtime.current_revision(); - - // Get an upgradable read lock, which permits other reads but no writers. - // Probe again. If the value is stale (needs to be verified), then upgrade - // to a write lock and swap it with InProgress while we work. - let mut old_memo = match self.maybe_changed_after_probe( - db, - self.state.upgradable_read(), - runtime, - revision_now, - ) { - MaybeChangedSinceProbeState::ChangedAt(changed_at) => return changed_at > revision, - - // If another thread was active, then the cache line is going to be - // either verified or cleared out. Just recurse to figure out which. - // Note that we don't need an upgradable read. - MaybeChangedSinceProbeState::Retry => { - return self.maybe_changed_after(db, revision, key) - } - - MaybeChangedSinceProbeState::Stale(state) => { - type RwLockUpgradableReadGuard<'a, T> = - lock_api::RwLockUpgradableReadGuard<'a, RawRwLock, T>; - - let mut state = RwLockUpgradableReadGuard::upgrade(state); - match std::mem::replace(&mut *state, QueryState::in_progress(runtime.id())) { - QueryState::Memoized(old_memo) => old_memo, - QueryState::NotComputed | QueryState::InProgress { .. } => unreachable!(), - } - } - }; - - let panic_guard = PanicGuard::new(self, runtime); - let active_query = runtime.push_query(self.database_key_index()); - - if old_memo.verify_revisions(db.ops_database(), revision_now, &active_query) { - let maybe_changed = old_memo.revisions.changed_at > revision; - panic_guard.proceed(Some(old_memo)); - maybe_changed - } else { - // We found that this memoized value may have changed - // but we have an old value. We can re-run the code and - // actually *check* if it has changed. - let StampedValue { changed_at, .. } = self.execute( - db, - runtime, - revision_now, - active_query, - panic_guard, - Some(old_memo), - key, - ); - changed_at > revision - } - } - - /// Helper: see [`Runtime::try_block_on_or_unwind`]. - fn block_on_or_unwind( - &self, - db: &>::DynDb, - runtime: &Runtime, - other_id: RuntimeId, - mutex_guard: MutexGuard, - ) { - runtime.block_on_or_unwind( - db.ops_database(), - self.database_key_index(), - other_id, - mutex_guard, - ) - } -} - -impl QueryState -where - Q: QueryFunction, -{ - fn in_progress(id: RuntimeId) -> Self { - QueryState::InProgress { id, anyone_waiting: Default::default() } - } -} - -struct PanicGuard<'me, Q> -where - Q: QueryFunction, - Q::Value: Eq, -{ - slot: &'me Slot, - runtime: &'me Runtime, -} - -impl<'me, Q> PanicGuard<'me, Q> -where - Q: QueryFunction, - Q::Value: Eq, -{ - fn new(slot: &'me Slot, runtime: &'me Runtime) -> Self { - Self { slot, runtime } - } - - /// Indicates that we have concluded normally (without panicking). - /// If `opt_memo` is some, then this memo is installed as the new - /// memoized value. If `opt_memo` is `None`, then the slot is cleared - /// and has no value. - fn proceed(mut self, opt_memo: Option>) { - self.overwrite_placeholder(WaitResult::Completed, opt_memo); - std::mem::forget(self) - } - - /// Overwrites the `InProgress` placeholder for `key` that we - /// inserted; if others were blocked, waiting for us to finish, - /// then notify them. - fn overwrite_placeholder(&mut self, wait_result: WaitResult, opt_memo: Option>) { - let old_value = { - let mut write = self.slot.state.write(); - match opt_memo { - // Replace the `InProgress` marker that we installed with the new - // memo, thus releasing our unique access to this key. - Some(memo) => std::mem::replace(&mut *write, QueryState::Memoized(memo)), - - // We had installed an `InProgress` marker, but we panicked before - // it could be removed. At this point, we therefore "own" unique - // access to our slot, so we can just remove the key. - None => std::mem::replace(&mut *write, QueryState::NotComputed), - } - }; - - match old_value { - QueryState::InProgress { id, anyone_waiting } => { - assert_eq!(id, self.runtime.id()); - - // NB: As noted on the `store`, `Ordering::Relaxed` is - // sufficient here. This boolean signals us on whether to - // acquire a mutex; the mutex will guarantee that all writes - // we are interested in are visible. - if anyone_waiting.load(Ordering::Relaxed) { - self.runtime - .unblock_queries_blocked_on(self.slot.database_key_index(), wait_result); - } - } - _ => panic!( - "\ -Unexpected panic during query evaluation, aborting the process. - -Please report this bug to https://github.com/salsa-rs/salsa/issues." - ), - } - } -} - -impl Drop for PanicGuard<'_, Q> -where - Q: QueryFunction, - Q::Value: Eq, -{ - fn drop(&mut self) { - if std::thread::panicking() { - // We panicked before we could proceed and need to remove `key`. - self.overwrite_placeholder(WaitResult::Panicked, None) - } else { - // If no panic occurred, then panic guard ought to be - // "forgotten" and so this Drop code should never run. - panic!(".forget() was not called") - } - } -} - -impl Memo -where - V: Clone, -{ - /// Determines whether the value stored in this memo (if any) is still - /// valid in the current revision. If so, returns a stamped value. - /// - /// If needed, this will walk each dependency and - /// recursively invoke `maybe_changed_after`, which may in turn - /// re-execute the dependency. This can cause cycles to occur, - /// so the current query must be pushed onto the - /// stack to permit cycle detection and recovery: therefore, - /// takes the `active_query` argument as evidence. - fn verify_value( - &mut self, - db: &dyn Database, - revision_now: Revision, - active_query: &ActiveQueryGuard<'_>, - ) -> Option> { - if self.verify_revisions(db, revision_now, active_query) { - Some(StampedValue { - durability: self.revisions.durability, - changed_at: self.revisions.changed_at, - value: self.value.clone(), - }) - } else { - None - } - } - - /// Determines whether the value represented by this memo is still - /// valid in the current revision; note that the value itself is - /// not needed for this check. If needed, this will walk each - /// dependency and recursively invoke `maybe_changed_after`, which - /// may in turn re-execute the dependency. This can cause cycles to occur, - /// so the current query must be pushed onto the - /// stack to permit cycle detection and recovery: therefore, - /// takes the `active_query` argument as evidence. - fn verify_revisions( - &mut self, - db: &dyn Database, - revision_now: Revision, - _active_query: &ActiveQueryGuard<'_>, - ) -> bool { - assert!(self.verified_at != revision_now); - let verified_at = self.verified_at; - - trace!( - "verify_revisions: verified_at={:?}, revision_now={:?}, inputs={:#?}", - verified_at, - revision_now, - self.revisions.inputs - ); - - if self.check_durability(db.salsa_runtime()) { - return self.mark_value_as_verified(revision_now); - } - - match &self.revisions.inputs { - // We can't validate values that had untracked inputs; just have to - // re-execute. - None if self.revisions.untracked => return false, - None => {} - - // Check whether any of our inputs changed since the - // **last point where we were verified** (not since we - // last changed). This is important: if we have - // memoized values, then an input may have changed in - // revision R2, but we found that *our* value was the - // same regardless, so our change date is still - // R1. But our *verification* date will be R2, and we - // are only interested in finding out whether the - // input changed *again*. - Some(inputs) => { - let changed_input = - inputs.slice.iter().find(|&&input| db.maybe_changed_after(input, verified_at)); - if let Some(input) = changed_input { - trace!("validate_memoized_value: `{:?}` may have changed", input); - - return false; - } - } - }; - - self.mark_value_as_verified(revision_now) - } - - /// True if this memo is known not to have changed based on its durability. - fn check_durability(&self, runtime: &Runtime) -> bool { - let last_changed = runtime.last_changed_revision(self.revisions.durability); - trace!( - "check_durability(last_changed={:?} <= verified_at={:?}) = {:?}", - last_changed, - self.verified_at, - last_changed <= self.verified_at, - ); - last_changed <= self.verified_at - } - - fn mark_value_as_verified(&mut self, revision_now: Revision) -> bool { - self.verified_at = revision_now; - true - } -} - -impl std::fmt::Debug for Slot -where - Q: QueryFunction, -{ - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(fmt, "{:?}", Q::default()) - } -} - -/// Check that `Slot: Send + Sync` as long as -/// `DB::DatabaseData: Send + Sync`, which in turn implies that -/// `Q::Key: Send + Sync`, `Q::Value: Send + Sync`. -#[allow(dead_code)] -fn check_send_sync() -where - Q: QueryFunction, - - Q::Key: Send + Sync, - Q::Value: Send + Sync, -{ - fn is_send_sync() {} - is_send_sync::>(); -} - -/// Check that `Slot: 'static` as long as -/// `DB::DatabaseData: 'static`, which in turn implies that -/// `Q::Key: 'static`, `Q::Value: 'static`. -#[allow(dead_code)] -fn check_static() -where - Q: QueryFunction + 'static, - Q::Key: 'static, - Q::Value: 'static, -{ - fn is_static() {} - is_static::>(); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru.rs deleted file mode 100644 index bdb448e2412ee..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru.rs +++ /dev/null @@ -1,233 +0,0 @@ -use crate::debug::TableEntry; -use crate::durability::Durability; -use crate::hash::FxIndexMap; -use crate::lru::Lru; -use crate::plumbing::DerivedQueryStorageOps; -use crate::plumbing::LruQueryStorageOps; -use crate::plumbing::QueryFunction; -use crate::plumbing::QueryStorageMassOps; -use crate::plumbing::QueryStorageOps; -use crate::runtime::StampedValue; -use crate::Runtime; -use crate::{Database, DatabaseKeyIndex, QueryDb, Revision}; -use parking_lot::RwLock; -use std::borrow::Borrow; -use std::hash::Hash; -use std::marker::PhantomData; -use triomphe::Arc; - -mod slot; -use slot::Slot; - -/// Memoized queries store the result plus a list of the other queries -/// that they invoked. This means we can avoid recomputing them when -/// none of those inputs have changed. -pub type MemoizedStorage = DerivedStorage; - -/// "Dependency" queries just track their dependencies and not the -/// actual value (which they produce on demand). This lessens the -/// storage requirements. -pub type DependencyStorage = DerivedStorage; - -/// Handles storage where the value is 'derived' by executing a -/// function (in contrast to "inputs"). -pub struct DerivedStorage -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - group_index: u16, - lru_list: Lru>, - slot_map: RwLock>>>, - policy: PhantomData, -} - -impl std::panic::RefUnwindSafe for DerivedStorage -where - Q: QueryFunction, - MP: MemoizationPolicy, - Q::Key: std::panic::RefUnwindSafe, - Q::Value: std::panic::RefUnwindSafe, -{ -} - -pub trait MemoizationPolicy: Send + Sync -where - Q: QueryFunction, -{ - fn should_memoize_value(key: &Q::Key) -> bool; - - fn memoized_value_eq(old_value: &Q::Value, new_value: &Q::Value) -> bool; -} - -pub enum AlwaysMemoizeValue {} -impl MemoizationPolicy for AlwaysMemoizeValue -where - Q: QueryFunction, - Q::Value: Eq, -{ - fn should_memoize_value(_key: &Q::Key) -> bool { - true - } - - fn memoized_value_eq(old_value: &Q::Value, new_value: &Q::Value) -> bool { - old_value == new_value - } -} - -pub enum NeverMemoizeValue {} -impl MemoizationPolicy for NeverMemoizeValue -where - Q: QueryFunction, -{ - fn should_memoize_value(_key: &Q::Key) -> bool { - false - } - - fn memoized_value_eq(_old_value: &Q::Value, _new_value: &Q::Value) -> bool { - panic!("cannot reach since we never memoize") - } -} - -impl DerivedStorage -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn slot(&self, key: &Q::Key) -> Arc> { - if let Some(v) = self.slot_map.read().get(key) { - return v.clone(); - } - - let mut write = self.slot_map.write(); - let entry = write.entry(key.clone()); - let key_index = entry.index() as u32; - let database_key_index = DatabaseKeyIndex { - group_index: self.group_index, - query_index: Q::QUERY_INDEX, - key_index, - }; - entry.or_insert_with(|| Arc::new(Slot::new(database_key_index))).clone() - } -} - -impl QueryStorageOps for DerivedStorage -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - const CYCLE_STRATEGY: crate::plumbing::CycleRecoveryStrategy = Q::CYCLE_STRATEGY; - - fn new(group_index: u16) -> Self { - DerivedStorage { - group_index, - slot_map: RwLock::new(FxIndexMap::default()), - lru_list: Default::default(), - policy: PhantomData, - } - } - - fn fmt_index( - &self, - _db: &>::DynDb, - index: u32, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - let slot_map = self.slot_map.read(); - let key = slot_map.get_index(index as usize).unwrap().0; - write!(fmt, "{}::{}({:?})", std::any::type_name::(), Q::QUERY_NAME, key) - } - - fn maybe_changed_after( - &self, - db: &>::DynDb, - index: u32, - revision: Revision, - ) -> bool { - debug_assert!(revision < db.salsa_runtime().current_revision()); - let (key, slot) = { - let read = self.slot_map.read(); - let Some((key, slot)) = read.get_index(index as usize) else { - return false; - }; - (key.clone(), slot.clone()) - }; - slot.maybe_changed_after(db, revision, &key) - } - - fn fetch(&self, db: &>::DynDb, key: &Q::Key) -> Q::Value { - db.unwind_if_cancelled(); - - let slot = self.slot(key); - let StampedValue { value, durability, changed_at } = slot.read(db, key); - - if let Some(evicted) = self.lru_list.record_use(&slot) { - evicted.evict(); - } - - db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted( - slot.database_key_index(), - durability, - changed_at, - ); - - value - } - - fn durability(&self, db: &>::DynDb, key: &Q::Key) -> Durability { - self.slot(key).durability(db) - } - - fn entries(&self, _db: &>::DynDb) -> C - where - C: std::iter::FromIterator>, - { - let slot_map = self.slot_map.read(); - slot_map.iter().filter_map(|(key, slot)| slot.as_table_entry(key)).collect() - } -} - -impl QueryStorageMassOps for DerivedStorage -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn purge(&self) { - self.lru_list.purge(); - *self.slot_map.write() = Default::default(); - } -} - -impl LruQueryStorageOps for DerivedStorage -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn set_lru_capacity(&self, new_capacity: u16) { - self.lru_list.set_lru_capacity(new_capacity); - } -} - -impl DerivedQueryStorageOps for DerivedStorage -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn invalidate(&self, runtime: &mut Runtime, key: &S) - where - S: Eq + Hash, - Q::Key: Borrow, - { - runtime.with_incremented_revision(|new_revision| { - let map_read = self.slot_map.read(); - - if let Some(slot) = map_read.get(key) { - if let Some(durability) = slot.invalidate(new_revision) { - return Some(durability); - } - } - - None - }) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru/slot.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru/slot.rs deleted file mode 100644 index 73a5e07aa05ab..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru/slot.rs +++ /dev/null @@ -1,856 +0,0 @@ -use crate::debug::TableEntry; -use crate::derived_lru::MemoizationPolicy; -use crate::durability::Durability; -use crate::lru::LruIndex; -use crate::lru::LruNode; -use crate::plumbing::{DatabaseOps, QueryFunction}; -use crate::revision::Revision; -use crate::runtime::local_state::ActiveQueryGuard; -use crate::runtime::local_state::QueryRevisions; -use crate::runtime::Runtime; -use crate::runtime::RuntimeId; -use crate::runtime::StampedValue; -use crate::runtime::WaitResult; -use crate::Cycle; -use crate::{Database, DatabaseKeyIndex, Event, EventKind, QueryDb}; -use parking_lot::{RawRwLock, RwLock}; -use std::marker::PhantomData; -use std::ops::Deref; -use std::sync::atomic::{AtomicBool, Ordering}; -use tracing::trace; - -pub(super) struct Slot -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - key_index: u32, - group_index: u16, - state: RwLock>, - lru_index: LruIndex, - policy: PhantomData, -} - -/// Defines the "current state" of query's memoized results. -enum QueryState -where - Q: QueryFunction, -{ - NotComputed, - - /// The runtime with the given id is currently computing the - /// result of this query. - InProgress { - id: RuntimeId, - - /// Set to true if any other queries are blocked, - /// waiting for this query to complete. - anyone_waiting: AtomicBool, - }, - - /// We have computed the query already, and here is the result. - Memoized(Memo), -} - -struct Memo { - /// The result of the query, if we decide to memoize it. - value: Option, - - /// Last revision when this memo was verified; this begins - /// as the current revision. - pub(crate) verified_at: Revision, - - /// Revision information - revisions: QueryRevisions, -} - -/// Return value of `probe` helper. -enum ProbeState { - /// Another thread was active but has completed. - /// Try again! - Retry, - - /// No entry for this key at all. - NotComputed(G), - - /// There is an entry, but its contents have not been - /// verified in this revision. - Stale(G), - - /// There is an entry, and it has been verified - /// in this revision, but it has no cached - /// value. The `Revision` is the revision where the - /// value last changed (if we were to recompute it). - NoValue(G, Revision), - - /// There is an entry which has been verified, - /// and it has the following value-- or, we blocked - /// on another thread, and that resulted in a cycle. - UpToDate(V), -} - -/// Return value of `maybe_changed_after_probe` helper. -enum MaybeChangedSinceProbeState { - /// Another thread was active but has completed. - /// Try again! - Retry, - - /// Value may have changed in the given revision. - ChangedAt(Revision), - - /// There is a stale cache entry that has not been - /// verified in this revision, so we can't say. - Stale(G), -} - -impl Slot -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - pub(super) fn new(database_key_index: DatabaseKeyIndex) -> Self { - Self { - key_index: database_key_index.key_index, - group_index: database_key_index.group_index, - state: RwLock::new(QueryState::NotComputed), - lru_index: LruIndex::default(), - policy: PhantomData, - } - } - - pub(super) fn database_key_index(&self) -> DatabaseKeyIndex { - DatabaseKeyIndex { - group_index: self.group_index, - query_index: Q::QUERY_INDEX, - key_index: self.key_index, - } - } - - pub(super) fn read( - &self, - db: &>::DynDb, - key: &Q::Key, - ) -> StampedValue { - let runtime = db.salsa_runtime(); - - // NB: We don't need to worry about people modifying the - // revision out from under our feet. Either `db` is a frozen - // database, in which case there is a lock, or the mutator - // thread is the current thread, and it will be prevented from - // doing any `set` invocations while the query function runs. - let revision_now = runtime.current_revision(); - - trace!("{:?}: invoked at {:?}", self, revision_now,); - - // First, do a check with a read-lock. - loop { - match self.probe(db, self.state.read(), runtime, revision_now) { - ProbeState::UpToDate(v) => return v, - ProbeState::Stale(..) | ProbeState::NoValue(..) | ProbeState::NotComputed(..) => { - break - } - ProbeState::Retry => continue, - } - } - - self.read_upgrade(db, key, revision_now) - } - - /// Second phase of a read operation: acquires an upgradable-read - /// and -- if needed -- validates whether inputs have changed, - /// recomputes value, etc. This is invoked after our initial probe - /// shows a potentially out of date value. - fn read_upgrade( - &self, - db: &>::DynDb, - key: &Q::Key, - revision_now: Revision, - ) -> StampedValue { - let runtime = db.salsa_runtime(); - - trace!("{:?}: read_upgrade(revision_now={:?})", self, revision_now,); - - // Check with an upgradable read to see if there is a value - // already. (This permits other readers but prevents anyone - // else from running `read_upgrade` at the same time.) - let mut old_memo = loop { - match self.probe(db, self.state.upgradable_read(), runtime, revision_now) { - ProbeState::UpToDate(v) => return v, - ProbeState::Stale(state) - | ProbeState::NotComputed(state) - | ProbeState::NoValue(state, _) => { - type RwLockUpgradableReadGuard<'a, T> = - lock_api::RwLockUpgradableReadGuard<'a, RawRwLock, T>; - - let mut state = RwLockUpgradableReadGuard::upgrade(state); - match std::mem::replace(&mut *state, QueryState::in_progress(runtime.id())) { - QueryState::Memoized(old_memo) => break Some(old_memo), - QueryState::InProgress { .. } => unreachable!(), - QueryState::NotComputed => break None, - } - } - ProbeState::Retry => continue, - } - }; - - let panic_guard = PanicGuard::new(self, runtime); - let active_query = runtime.push_query(self.database_key_index()); - - // If we have an old-value, it *may* now be stale, since there - // has been a new revision since the last time we checked. So, - // first things first, let's walk over each of our previous - // inputs and check whether they are out of date. - if let Some(memo) = &mut old_memo { - if let Some(value) = memo.verify_value(db.ops_database(), revision_now, &active_query) { - trace!("{:?}: validated old memoized value", self,); - - db.salsa_event(Event { - runtime_id: runtime.id(), - kind: EventKind::DidValidateMemoizedValue { - database_key: self.database_key_index(), - }, - }); - - panic_guard.proceed(old_memo); - - return value; - } - } - - self.execute(db, runtime, revision_now, active_query, panic_guard, old_memo, key) - } - - fn execute( - &self, - db: &>::DynDb, - runtime: &Runtime, - revision_now: Revision, - active_query: ActiveQueryGuard<'_>, - panic_guard: PanicGuard<'_, Q, MP>, - old_memo: Option>, - key: &Q::Key, - ) -> StampedValue { - tracing::trace!("{:?}: executing query", self.database_key_index().debug(db)); - - db.salsa_event(Event { - runtime_id: db.salsa_runtime().id(), - kind: EventKind::WillExecute { database_key: self.database_key_index() }, - }); - - // Query was not previously executed, or value is potentially - // stale, or value is absent. Let's execute! - let value = match Cycle::catch(|| Q::execute(db, key.clone())) { - Ok(v) => v, - Err(cycle) => { - tracing::trace!( - "{:?}: caught cycle {:?}, have strategy {:?}", - self.database_key_index().debug(db), - cycle, - Q::CYCLE_STRATEGY, - ); - match Q::CYCLE_STRATEGY { - crate::plumbing::CycleRecoveryStrategy::Panic => { - panic_guard.proceed(None); - cycle.throw() - } - crate::plumbing::CycleRecoveryStrategy::Fallback => { - if let Some(c) = active_query.take_cycle() { - assert!(c.is(&cycle)); - Q::cycle_fallback(db, &cycle, key) - } else { - // we are not a participant in this cycle - debug_assert!(!cycle - .participant_keys() - .any(|k| k == self.database_key_index())); - cycle.throw() - } - } - } - } - }; - - let mut revisions = active_query.pop(); - - // We assume that query is side-effect free -- that is, does - // not mutate the "inputs" to the query system. Sanity check - // that assumption here, at least to the best of our ability. - assert_eq!( - runtime.current_revision(), - revision_now, - "revision altered during query execution", - ); - - // If the new value is equal to the old one, then it didn't - // really change, even if some of its inputs have. So we can - // "backdate" its `changed_at` revision to be the same as the - // old value. - if let Some(old_memo) = &old_memo { - if let Some(old_value) = &old_memo.value { - // Careful: if the value became less durable than it - // used to be, that is a "breaking change" that our - // consumers must be aware of. Becoming *more* durable - // is not. See the test `constant_to_non_constant`. - if revisions.durability >= old_memo.revisions.durability - && MP::memoized_value_eq(old_value, &value) - { - trace!( - "read_upgrade({:?}): value is equal, back-dating to {:?}", - self, - old_memo.revisions.changed_at, - ); - - assert!(old_memo.revisions.changed_at <= revisions.changed_at); - revisions.changed_at = old_memo.revisions.changed_at; - } - } - } - - let new_value = StampedValue { - value, - durability: revisions.durability, - changed_at: revisions.changed_at, - }; - - let memo_value = - if self.should_memoize_value(key) { Some(new_value.value.clone()) } else { None }; - - trace!("read_upgrade({:?}): result.revisions = {:#?}", self, revisions,); - - panic_guard.proceed(Some(Memo { value: memo_value, verified_at: revision_now, revisions })); - - new_value - } - - /// Helper for `read` that does a shallow check (not recursive) if we have an up-to-date value. - /// - /// Invoked with the guard `state` corresponding to the `QueryState` of some `Slot` (the guard - /// can be either read or write). Returns a suitable `ProbeState`: - /// - /// - `ProbeState::UpToDate(r)` if the table has an up-to-date value (or we blocked on another - /// thread that produced such a value). - /// - `ProbeState::StaleOrAbsent(g)` if either (a) there is no memo for this key, (b) the memo - /// has no value; or (c) the memo has not been verified at the current revision. - /// - /// Note that in case `ProbeState::UpToDate`, the lock will have been released. - fn probe( - &self, - db: &>::DynDb, - state: StateGuard, - runtime: &Runtime, - revision_now: Revision, - ) -> ProbeState, StateGuard> - where - StateGuard: Deref>, - { - match &*state { - QueryState::NotComputed => ProbeState::NotComputed(state), - - QueryState::InProgress { id, anyone_waiting } => { - let other_id = *id; - - // NB: `Ordering::Relaxed` is sufficient here, - // as there are no loads that are "gated" on this - // value. Everything that is written is also protected - // by a lock that must be acquired. The role of this - // boolean is to decide *whether* to acquire the lock, - // not to gate future atomic reads. - anyone_waiting.store(true, Ordering::Relaxed); - - self.block_on_or_unwind(db, runtime, other_id, state); - - // Other thread completely normally, so our value may be available now. - ProbeState::Retry - } - - QueryState::Memoized(memo) => { - trace!( - "{:?}: found memoized value, verified_at={:?}, changed_at={:?}", - self, - memo.verified_at, - memo.revisions.changed_at, - ); - - if memo.verified_at < revision_now { - return ProbeState::Stale(state); - } - - if let Some(value) = &memo.value { - let value = StampedValue { - durability: memo.revisions.durability, - changed_at: memo.revisions.changed_at, - value: value.clone(), - }; - - trace!( - "{:?}: returning memoized value changed at {:?}", - self, - value.changed_at - ); - - ProbeState::UpToDate(value) - } else { - let changed_at = memo.revisions.changed_at; - ProbeState::NoValue(state, changed_at) - } - } - } - } - - pub(super) fn durability(&self, db: &>::DynDb) -> Durability { - match &*self.state.read() { - QueryState::NotComputed => Durability::LOW, - QueryState::InProgress { .. } => panic!("query in progress"), - QueryState::Memoized(memo) => { - if memo.check_durability(db.salsa_runtime()) { - memo.revisions.durability - } else { - Durability::LOW - } - } - } - } - - pub(super) fn as_table_entry(&self, key: &Q::Key) -> Option> { - match &*self.state.read() { - QueryState::NotComputed => None, - QueryState::InProgress { .. } => Some(TableEntry::new(key.clone(), None)), - QueryState::Memoized(memo) => Some(TableEntry::new(key.clone(), memo.value.clone())), - } - } - - pub(super) fn evict(&self) { - let mut state = self.state.write(); - if let QueryState::Memoized(memo) = &mut *state { - // Evicting a value with an untracked input could - // lead to inconsistencies. Note that we can't check - // `has_untracked_input` when we add the value to the cache, - // because inputs can become untracked in the next revision. - if memo.has_untracked_input() { - return; - } - memo.value = None; - } - } - - pub(super) fn invalidate(&self, new_revision: Revision) -> Option { - tracing::trace!("Slot::invalidate(new_revision = {:?})", new_revision); - match &mut *self.state.write() { - QueryState::Memoized(memo) => { - memo.revisions.untracked = true; - memo.revisions.inputs = None; - memo.revisions.changed_at = new_revision; - Some(memo.revisions.durability) - } - QueryState::NotComputed => None, - QueryState::InProgress { .. } => unreachable!(), - } - } - - pub(super) fn maybe_changed_after( - &self, - db: &>::DynDb, - revision: Revision, - key: &Q::Key, - ) -> bool { - let runtime = db.salsa_runtime(); - let revision_now = runtime.current_revision(); - - db.unwind_if_cancelled(); - - trace!( - "maybe_changed_after({:?}) called with revision={:?}, revision_now={:?}", - self, - revision, - revision_now, - ); - - // Do an initial probe with just the read-lock. - // - // If we find that a cache entry for the value is present - // but hasn't been verified in this revision, we'll have to - // do more. - loop { - match self.maybe_changed_after_probe(db, self.state.read(), runtime, revision_now) { - MaybeChangedSinceProbeState::Retry => continue, - MaybeChangedSinceProbeState::ChangedAt(changed_at) => return changed_at > revision, - MaybeChangedSinceProbeState::Stale(state) => { - drop(state); - return self.maybe_changed_after_upgrade(db, revision, key); - } - } - } - } - - fn maybe_changed_after_probe( - &self, - db: &>::DynDb, - state: StateGuard, - runtime: &Runtime, - revision_now: Revision, - ) -> MaybeChangedSinceProbeState - where - StateGuard: Deref>, - { - match self.probe(db, state, runtime, revision_now) { - ProbeState::Retry => MaybeChangedSinceProbeState::Retry, - - ProbeState::Stale(state) => MaybeChangedSinceProbeState::Stale(state), - - // If we know when value last changed, we can return right away. - // Note that we don't need the actual value to be available. - ProbeState::NoValue(_, changed_at) - | ProbeState::UpToDate(StampedValue { value: _, durability: _, changed_at }) => { - MaybeChangedSinceProbeState::ChangedAt(changed_at) - } - - // If we have nothing cached, then value may have changed. - ProbeState::NotComputed(_) => MaybeChangedSinceProbeState::ChangedAt(revision_now), - } - } - - fn maybe_changed_after_upgrade( - &self, - db: &>::DynDb, - revision: Revision, - key: &Q::Key, - ) -> bool { - let runtime = db.salsa_runtime(); - let revision_now = runtime.current_revision(); - - // Get an upgradable read lock, which permits other reads but no writers. - // Probe again. If the value is stale (needs to be verified), then upgrade - // to a write lock and swap it with InProgress while we work. - let mut old_memo = match self.maybe_changed_after_probe( - db, - self.state.upgradable_read(), - runtime, - revision_now, - ) { - MaybeChangedSinceProbeState::ChangedAt(changed_at) => return changed_at > revision, - - // If another thread was active, then the cache line is going to be - // either verified or cleared out. Just recurse to figure out which. - // Note that we don't need an upgradable read. - MaybeChangedSinceProbeState::Retry => { - return self.maybe_changed_after(db, revision, key) - } - - MaybeChangedSinceProbeState::Stale(state) => { - type RwLockUpgradableReadGuard<'a, T> = - lock_api::RwLockUpgradableReadGuard<'a, RawRwLock, T>; - - let mut state = RwLockUpgradableReadGuard::upgrade(state); - match std::mem::replace(&mut *state, QueryState::in_progress(runtime.id())) { - QueryState::Memoized(old_memo) => old_memo, - QueryState::NotComputed | QueryState::InProgress { .. } => unreachable!(), - } - } - }; - - let panic_guard = PanicGuard::new(self, runtime); - let active_query = runtime.push_query(self.database_key_index()); - - if old_memo.verify_revisions(db.ops_database(), revision_now, &active_query) { - let maybe_changed = old_memo.revisions.changed_at > revision; - panic_guard.proceed(Some(old_memo)); - maybe_changed - } else if old_memo.value.is_some() { - // We found that this memoized value may have changed - // but we have an old value. We can re-run the code and - // actually *check* if it has changed. - let StampedValue { changed_at, .. } = self.execute( - db, - runtime, - revision_now, - active_query, - panic_guard, - Some(old_memo), - key, - ); - changed_at > revision - } else { - // We found that inputs to this memoized value may have chanced - // but we don't have an old value to compare against or re-use. - // No choice but to drop the memo and say that its value may have changed. - panic_guard.proceed(None); - true - } - } - - /// Helper: see [`Runtime::try_block_on_or_unwind`]. - fn block_on_or_unwind( - &self, - db: &>::DynDb, - runtime: &Runtime, - other_id: RuntimeId, - mutex_guard: MutexGuard, - ) { - runtime.block_on_or_unwind( - db.ops_database(), - self.database_key_index(), - other_id, - mutex_guard, - ) - } - - fn should_memoize_value(&self, key: &Q::Key) -> bool { - MP::should_memoize_value(key) - } -} - -impl QueryState -where - Q: QueryFunction, -{ - fn in_progress(id: RuntimeId) -> Self { - QueryState::InProgress { id, anyone_waiting: Default::default() } - } -} - -struct PanicGuard<'me, Q, MP> -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - slot: &'me Slot, - runtime: &'me Runtime, -} - -impl<'me, Q, MP> PanicGuard<'me, Q, MP> -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn new(slot: &'me Slot, runtime: &'me Runtime) -> Self { - Self { slot, runtime } - } - - /// Indicates that we have concluded normally (without panicking). - /// If `opt_memo` is some, then this memo is installed as the new - /// memoized value. If `opt_memo` is `None`, then the slot is cleared - /// and has no value. - fn proceed(mut self, opt_memo: Option>) { - self.overwrite_placeholder(WaitResult::Completed, opt_memo); - std::mem::forget(self) - } - - /// Overwrites the `InProgress` placeholder for `key` that we - /// inserted; if others were blocked, waiting for us to finish, - /// then notify them. - fn overwrite_placeholder(&mut self, wait_result: WaitResult, opt_memo: Option>) { - let old_value = { - let mut write = self.slot.state.write(); - match opt_memo { - // Replace the `InProgress` marker that we installed with the new - // memo, thus releasing our unique access to this key. - Some(memo) => std::mem::replace(&mut *write, QueryState::Memoized(memo)), - - // We had installed an `InProgress` marker, but we panicked before - // it could be removed. At this point, we therefore "own" unique - // access to our slot, so we can just remove the key. - None => std::mem::replace(&mut *write, QueryState::NotComputed), - } - }; - - match old_value { - QueryState::InProgress { id, anyone_waiting } => { - assert_eq!(id, self.runtime.id()); - - // NB: As noted on the `store`, `Ordering::Relaxed` is - // sufficient here. This boolean signals us on whether to - // acquire a mutex; the mutex will guarantee that all writes - // we are interested in are visible. - if anyone_waiting.load(Ordering::Relaxed) { - self.runtime - .unblock_queries_blocked_on(self.slot.database_key_index(), wait_result); - } - } - _ => panic!( - "\ -Unexpected panic during query evaluation, aborting the process. - -Please report this bug to https://github.com/salsa-rs/salsa/issues." - ), - } - } -} - -impl Drop for PanicGuard<'_, Q, MP> -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn drop(&mut self) { - if std::thread::panicking() { - // We panicked before we could proceed and need to remove `key`. - self.overwrite_placeholder(WaitResult::Panicked, None) - } else { - // If no panic occurred, then panic guard ought to be - // "forgotten" and so this Drop code should never run. - panic!(".forget() was not called") - } - } -} - -impl Memo -where - V: Clone, -{ - /// Determines whether the value stored in this memo (if any) is still - /// valid in the current revision. If so, returns a stamped value. - /// - /// If needed, this will walk each dependency and - /// recursively invoke `maybe_changed_after`, which may in turn - /// re-execute the dependency. This can cause cycles to occur, - /// so the current query must be pushed onto the - /// stack to permit cycle detection and recovery: therefore, - /// takes the `active_query` argument as evidence. - fn verify_value( - &mut self, - db: &dyn Database, - revision_now: Revision, - active_query: &ActiveQueryGuard<'_>, - ) -> Option> { - // If we don't have a memoized value, nothing to validate. - if self.value.is_none() { - return None; - } - if self.verify_revisions(db, revision_now, active_query) { - self.value.clone().map(|value| StampedValue { - durability: self.revisions.durability, - changed_at: self.revisions.changed_at, - value, - }) - } else { - None - } - } - - /// Determines whether the value represented by this memo is still - /// valid in the current revision; note that the value itself is - /// not needed for this check. If needed, this will walk each - /// dependency and recursively invoke `maybe_changed_after`, which - /// may in turn re-execute the dependency. This can cause cycles to occur, - /// so the current query must be pushed onto the - /// stack to permit cycle detection and recovery: therefore, - /// takes the `active_query` argument as evidence. - fn verify_revisions( - &mut self, - db: &dyn Database, - revision_now: Revision, - _active_query: &ActiveQueryGuard<'_>, - ) -> bool { - assert!(self.verified_at != revision_now); - let verified_at = self.verified_at; - - trace!( - "verify_revisions: verified_at={:?}, revision_now={:?}, inputs={:#?}", - verified_at, - revision_now, - self.revisions.inputs - ); - - if self.check_durability(db.salsa_runtime()) { - return self.mark_value_as_verified(revision_now); - } - - match &self.revisions.inputs { - // We can't validate values that had untracked inputs; just have to - // re-execute. - None if self.revisions.untracked => return false, - None => {} - - // Check whether any of our inputs changed since the - // **last point where we were verified** (not since we - // last changed). This is important: if we have - // memoized values, then an input may have changed in - // revision R2, but we found that *our* value was the - // same regardless, so our change date is still - // R1. But our *verification* date will be R2, and we - // are only interested in finding out whether the - // input changed *again*. - Some(inputs) => { - let changed_input = - inputs.slice.iter().find(|&&input| db.maybe_changed_after(input, verified_at)); - if let Some(input) = changed_input { - trace!("validate_memoized_value: `{:?}` may have changed", input); - - return false; - } - } - }; - - self.mark_value_as_verified(revision_now) - } - - /// True if this memo is known not to have changed based on its durability. - fn check_durability(&self, runtime: &Runtime) -> bool { - let last_changed = runtime.last_changed_revision(self.revisions.durability); - trace!( - "check_durability(last_changed={:?} <= verified_at={:?}) = {:?}", - last_changed, - self.verified_at, - last_changed <= self.verified_at, - ); - last_changed <= self.verified_at - } - - fn mark_value_as_verified(&mut self, revision_now: Revision) -> bool { - self.verified_at = revision_now; - true - } - - fn has_untracked_input(&self) -> bool { - self.revisions.untracked - } -} - -impl std::fmt::Debug for Slot -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(fmt, "{:?}", Q::default()) - } -} - -impl LruNode for Slot -where - Q: QueryFunction, - MP: MemoizationPolicy, -{ - fn lru_index(&self) -> &LruIndex { - &self.lru_index - } -} - -/// Check that `Slot: Send + Sync` as long as -/// `DB::DatabaseData: Send + Sync`, which in turn implies that -/// `Q::Key: Send + Sync`, `Q::Value: Send + Sync`. -#[allow(dead_code)] -fn check_send_sync() -where - Q: QueryFunction, - MP: MemoizationPolicy, - Q::Key: Send + Sync, - Q::Value: Send + Sync, -{ - fn is_send_sync() {} - is_send_sync::>(); -} - -/// Check that `Slot: 'static` as long as -/// `DB::DatabaseData: 'static`, which in turn implies that -/// `Q::Key: 'static`, `Q::Value: 'static`. -#[allow(dead_code)] -fn check_static() -where - Q: QueryFunction + 'static, - MP: MemoizationPolicy + 'static, - Q::Key: 'static, - Q::Value: 'static, -{ - fn is_static() {} - is_static::>(); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs deleted file mode 100644 index 9116f1606faf1..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs +++ /dev/null @@ -1,49 +0,0 @@ -/// Describes how likely a value is to change -- how "durable" it is. -/// By default, inputs have `Durability::LOW` and interned values have -/// `Durability::HIGH`. But inputs can be explicitly set with other -/// durabilities. -/// -/// We use durabilities to optimize the work of "revalidating" a query -/// after some input has changed. Ordinarily, in a new revision, -/// queries have to trace all their inputs back to the base inputs to -/// determine if any of those inputs have changed. But if we know that -/// the only changes were to inputs of low durability (the common -/// case), and we know that the query only used inputs of medium -/// durability or higher, then we can skip that enumeration. -/// -/// Typically, one assigns low durabilities to inputs that the user is -/// frequently editing. Medium or high durabilities are used for -/// configuration, the source from library crates, or other things -/// that are unlikely to be edited. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct Durability(u8); - -impl Durability { - /// Low durability: things that change frequently. - /// - /// Example: part of the crate being edited - pub const LOW: Durability = Durability(0); - - /// Medium durability: things that change sometimes, but rarely. - /// - /// Example: a Cargo.toml file - pub const MEDIUM: Durability = Durability(1); - - /// High durability: things that are not expected to change under - /// common usage. - /// - /// Example: the standard library or something from crates.io - pub const HIGH: Durability = Durability(2); - - /// The maximum possible durability; equivalent to HIGH but - /// "conceptually" distinct (i.e., if we add more durability - /// levels, this could change). - pub(crate) const MAX: Durability = Self::HIGH; - - /// Number of durability levels. - pub(crate) const LEN: usize = Self::MAX.index() + 1; - - pub(crate) const fn index(self) -> usize { - self.0 as usize - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/hash.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/hash.rs deleted file mode 100644 index 3b2d7df3fbeaa..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/hash.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub(crate) type FxHasher = std::hash::BuildHasherDefault; -pub(crate) type FxIndexSet = indexmap::IndexSet; -pub(crate) type FxIndexMap = indexmap::IndexMap; diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/input.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/input.rs deleted file mode 100644 index 4992a0c7271cc..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/input.rs +++ /dev/null @@ -1,371 +0,0 @@ -use crate::debug::TableEntry; -use crate::durability::Durability; -use crate::hash::FxIndexMap; -use crate::plumbing::CycleRecoveryStrategy; -use crate::plumbing::InputQueryStorageOps; -use crate::plumbing::QueryStorageMassOps; -use crate::plumbing::QueryStorageOps; -use crate::revision::Revision; -use crate::runtime::StampedValue; -use crate::Database; -use crate::Query; -use crate::Runtime; -use crate::{DatabaseKeyIndex, QueryDb}; -use indexmap::map::Entry; -use parking_lot::RwLock; -use std::iter; -use tracing::trace; - -/// Input queries store the result plus a list of the other queries -/// that they invoked. This means we can avoid recomputing them when -/// none of those inputs have changed. -pub struct InputStorage -where - Q: Query, -{ - group_index: u16, - slots: RwLock>>, -} - -struct Slot { - key_index: u32, - stamped_value: RwLock>, -} - -impl std::panic::RefUnwindSafe for InputStorage -where - Q: Query, - Q::Key: std::panic::RefUnwindSafe, - Q::Value: std::panic::RefUnwindSafe, -{ -} - -impl QueryStorageOps for InputStorage -where - Q: Query, -{ - const CYCLE_STRATEGY: crate::plumbing::CycleRecoveryStrategy = CycleRecoveryStrategy::Panic; - - fn new(group_index: u16) -> Self { - InputStorage { group_index, slots: Default::default() } - } - - fn fmt_index( - &self, - _db: &>::DynDb, - index: u32, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - let slot_map = self.slots.read(); - let key = slot_map.get_index(index as usize).unwrap().0; - write!(fmt, "{}({:?})", Q::QUERY_NAME, key) - } - - fn maybe_changed_after( - &self, - db: &>::DynDb, - index: u32, - revision: Revision, - ) -> bool { - debug_assert!(revision < db.salsa_runtime().current_revision()); - let slots = &self.slots.read(); - let Some((_, slot)) = slots.get_index(index as usize) else { - return true; - }; - - trace!("maybe_changed_after(slot={:?}, revision={:?})", Q::default(), revision,); - - let changed_at = slot.stamped_value.read().changed_at; - - trace!("maybe_changed_after: changed_at = {:?}", changed_at); - - changed_at > revision - } - - fn fetch(&self, db: &>::DynDb, key: &Q::Key) -> Q::Value { - db.unwind_if_cancelled(); - - let slots = &self.slots.read(); - let slot = slots - .get(key) - .unwrap_or_else(|| panic!("no value set for {:?}({:?})", Q::default(), key)); - - let StampedValue { value, durability, changed_at } = slot.stamped_value.read().clone(); - - db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted( - DatabaseKeyIndex { - group_index: self.group_index, - query_index: Q::QUERY_INDEX, - key_index: slot.key_index, - }, - durability, - changed_at, - ); - - value - } - - fn durability(&self, _db: &>::DynDb, key: &Q::Key) -> Durability { - match self.slots.read().get(key) { - Some(slot) => slot.stamped_value.read().durability, - None => panic!("no value set for {:?}({:?})", Q::default(), key), - } - } - - fn entries(&self, _db: &>::DynDb) -> C - where - C: std::iter::FromIterator>, - { - let slots = self.slots.read(); - slots - .iter() - .map(|(key, slot)| { - TableEntry::new(key.clone(), Some(slot.stamped_value.read().value.clone())) - }) - .collect() - } -} - -impl QueryStorageMassOps for InputStorage -where - Q: Query, -{ - fn purge(&self) { - *self.slots.write() = Default::default(); - } -} - -impl InputQueryStorageOps for InputStorage -where - Q: Query, -{ - fn set(&self, runtime: &mut Runtime, key: &Q::Key, value: Q::Value, durability: Durability) { - tracing::trace!("{:?}({:?}) = {:?} ({:?})", Q::default(), key, value, durability); - - // The value is changing, so we need a new revision (*). We also - // need to update the 'last changed' revision by invoking - // `guard.mark_durability_as_changed`. - // - // CAREFUL: This will block until the global revision lock can - // be acquired. If there are still queries executing, they may - // need to read from this input. Therefore, we wait to acquire - // the lock on `map` until we also hold the global query write - // lock. - // - // (*) Technically, since you can't presently access an input - // for a non-existent key, and you can't enumerate the set of - // keys, we only need a new revision if the key used to - // exist. But we may add such methods in the future and this - // case doesn't generally seem worth optimizing for. - runtime.with_incremented_revision(|next_revision| { - let mut slots = self.slots.write(); - - // Do this *after* we acquire the lock, so that we are not - // racing with somebody else to modify this same cell. - // (Otherwise, someone else might write a *newer* revision - // into the same cell while we block on the lock.) - let stamped_value = StampedValue { value, durability, changed_at: next_revision }; - - match slots.entry(key.clone()) { - Entry::Occupied(entry) => { - let mut slot_stamped_value = entry.get().stamped_value.write(); - let old_durability = slot_stamped_value.durability; - *slot_stamped_value = stamped_value; - Some(old_durability) - } - - Entry::Vacant(entry) => { - let key_index = entry.index() as u32; - entry.insert(Slot { key_index, stamped_value: RwLock::new(stamped_value) }); - None - } - } - }); - } -} - -/// Same as `InputStorage`, but optimized for queries that take no inputs. -pub struct UnitInputStorage -where - Q: Query, -{ - slot: UnitSlot, -} - -struct UnitSlot { - database_key_index: DatabaseKeyIndex, - stamped_value: RwLock>>, -} - -impl std::panic::RefUnwindSafe for UnitInputStorage -where - Q: Query, - Q::Key: std::panic::RefUnwindSafe, - Q::Value: std::panic::RefUnwindSafe, -{ -} - -impl QueryStorageOps for UnitInputStorage -where - Q: Query, -{ - const CYCLE_STRATEGY: crate::plumbing::CycleRecoveryStrategy = CycleRecoveryStrategy::Panic; - - fn new(group_index: u16) -> Self { - let database_key_index = - DatabaseKeyIndex { group_index, query_index: Q::QUERY_INDEX, key_index: 0 }; - UnitInputStorage { slot: UnitSlot { database_key_index, stamped_value: RwLock::new(None) } } - } - - fn fmt_index( - &self, - _db: &>::DynDb, - _index: u32, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - write!(fmt, "{}", Q::QUERY_NAME) - } - - fn maybe_changed_after( - &self, - db: &>::DynDb, - _index: u32, - revision: Revision, - ) -> bool { - debug_assert!(revision < db.salsa_runtime().current_revision()); - - trace!("maybe_changed_after(slot={:?}, revision={:?})", Q::default(), revision,); - - let Some(value) = &*self.slot.stamped_value.read() else { - return true; - }; - let changed_at = value.changed_at; - - trace!("maybe_changed_after: changed_at = {:?}", changed_at); - - changed_at > revision - } - - fn fetch(&self, db: &>::DynDb, &(): &Q::Key) -> Q::Value { - db.unwind_if_cancelled(); - - let StampedValue { value, durability, changed_at } = self - .slot - .stamped_value - .read() - .clone() - .unwrap_or_else(|| panic!("no value set for {:?}", Q::default())); - - db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted( - self.slot.database_key_index, - durability, - changed_at, - ); - - value - } - - fn durability(&self, _db: &>::DynDb, &(): &Q::Key) -> Durability { - match &*self.slot.stamped_value.read() { - Some(stamped_value) => stamped_value.durability, - None => panic!("no value set for {:?}", Q::default(),), - } - } - - fn entries(&self, _db: &>::DynDb) -> C - where - C: std::iter::FromIterator>, - { - iter::once(TableEntry::new( - (), - self.slot.stamped_value.read().as_ref().map(|it| it.value.clone()), - )) - .collect() - } -} - -impl QueryStorageMassOps for UnitInputStorage -where - Q: Query, -{ - fn purge(&self) { - *self.slot.stamped_value.write() = Default::default(); - } -} - -impl InputQueryStorageOps for UnitInputStorage -where - Q: Query, -{ - fn set(&self, runtime: &mut Runtime, (): &Q::Key, value: Q::Value, durability: Durability) { - tracing::trace!("{:?} = {:?} ({:?})", Q::default(), value, durability); - - // The value is changing, so we need a new revision (*). We also - // need to update the 'last changed' revision by invoking - // `guard.mark_durability_as_changed`. - // - // CAREFUL: This will block until the global revision lock can - // be acquired. If there are still queries executing, they may - // need to read from this input. Therefore, we wait to acquire - // the lock on `map` until we also hold the global query write - // lock. - // - // (*) Technically, since you can't presently access an input - // for a non-existent key, and you can't enumerate the set of - // keys, we only need a new revision if the key used to - // exist. But we may add such methods in the future and this - // case doesn't generally seem worth optimizing for. - runtime.with_incremented_revision(|next_revision| { - let mut stamped_value_slot = self.slot.stamped_value.write(); - - // Do this *after* we acquire the lock, so that we are not - // racing with somebody else to modify this same cell. - // (Otherwise, someone else might write a *newer* revision - // into the same cell while we block on the lock.) - let stamped_value = StampedValue { value, durability, changed_at: next_revision }; - - match &mut *stamped_value_slot { - Some(slot_stamped_value) => { - let old_durability = slot_stamped_value.durability; - *slot_stamped_value = stamped_value; - Some(old_durability) - } - - stamped_value_slot @ None => { - *stamped_value_slot = Some(stamped_value); - None - } - } - }); - } -} - -/// Check that `Slot: Send + Sync` as long as -/// `DB::DatabaseData: Send + Sync`, which in turn implies that -/// `Q::Key: Send + Sync`, `Q::Value: Send + Sync`. -#[allow(dead_code)] -fn check_send_sync() -where - Q: Query, - Q::Key: Send + Sync, - Q::Value: Send + Sync, -{ - fn is_send_sync() {} - is_send_sync::>(); - is_send_sync::>(); -} - -/// Check that `Slot: 'static` as long as -/// `DB::DatabaseData: 'static`, which in turn implies that -/// `Q::Key: 'static`, `Q::Value: 'static`. -#[allow(dead_code)] -fn check_static() -where - Q: Query + 'static, - Q::Key: 'static, - Q::Value: 'static, -{ - fn is_static() {} - is_static::>(); - is_static::>(); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/intern_id.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/intern_id.rs deleted file mode 100644 index 35b495998e16a..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/intern_id.rs +++ /dev/null @@ -1,131 +0,0 @@ -use std::fmt; -use std::num::NonZeroU32; - -/// The "raw-id" is used for interned keys in salsa -- it is basically -/// a newtype'd u32. Typically, it is wrapped in a type of your own -/// devising. For more information about interned keys, see [the -/// interned key RFC][rfc]. -/// -/// # Creating a `InternId` -// -/// InternId values can be constructed using the `From` impls, -/// which are implemented for `u32` and `usize`: -/// -/// ``` -/// # use ra_salsa::InternId; -/// let intern_id1 = InternId::from(22_u32); -/// let intern_id2 = InternId::from(22_usize); -/// assert_eq!(intern_id1, intern_id2); -/// ``` -/// -/// # Converting to a u32 or usize -/// -/// Normally, there should be no need to access the underlying integer -/// in a `InternId`. But if you do need to do so, you can convert to a -/// `usize` using the `as_u32` or `as_usize` methods or the `From` impls. -/// -/// ``` -/// # use ra_salsa::InternId;; -/// let intern_id = InternId::from(22_u32); -/// let value = u32::from(intern_id); -/// assert_eq!(value, 22); -/// ``` -/// -/// ## Illegal values -/// -/// Be warned, however, that `InternId` values cannot be created from -/// *arbitrary* values -- in particular large values greater than -/// `InternId::MAX` will panic. Those large values are reserved so that -/// the Rust compiler can use them as sentinel values, which means -/// that (for example) `Option` is represented in a single -/// word. -/// -/// ```should_panic -/// # use ra_salsa::InternId;; -/// InternId::from(InternId::MAX); -/// ``` -/// -/// [rfc]: https://github.com/salsa-rs/salsa-rfcs/pull/2 -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct InternId { - value: NonZeroU32, -} - -impl InternId { - /// The maximum allowed `InternId`. This value can grow between - /// releases without affecting semver. - pub const MAX: u32 = 0xFFFF_FF00; - - /// Creates a new InternId. - /// - /// # Safety - /// - /// `value` must be less than `MAX` - pub const unsafe fn new_unchecked(value: u32) -> Self { - debug_assert!(value < InternId::MAX); - let value = unsafe { NonZeroU32::new_unchecked(value + 1) }; - InternId { value } - } - - /// Convert this raw-id into a u32 value. - /// - /// ``` - /// # use ra_salsa::InternId; - /// let intern_id = InternId::from(22_u32); - /// let value = intern_id.as_usize(); - /// assert_eq!(value, 22); - /// ``` - pub fn as_u32(self) -> u32 { - self.value.get() - 1 - } - - /// Convert this raw-id into a usize value. - /// - /// ``` - /// # use ra_salsa::InternId; - /// let intern_id = InternId::from(22_u32); - /// let value = intern_id.as_usize(); - /// assert_eq!(value, 22); - /// ``` - pub fn as_usize(self) -> usize { - self.as_u32() as usize - } -} - -impl From for u32 { - fn from(raw: InternId) -> u32 { - raw.as_u32() - } -} - -impl From for usize { - fn from(raw: InternId) -> usize { - raw.as_usize() - } -} - -impl From for InternId { - fn from(id: u32) -> InternId { - assert!(id < InternId::MAX); - unsafe { InternId::new_unchecked(id) } - } -} - -impl From for InternId { - fn from(id: usize) -> InternId { - assert!(id < (InternId::MAX as usize)); - unsafe { InternId::new_unchecked(id as u32) } - } -} - -impl fmt::Debug for InternId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_usize().fmt(f) - } -} - -impl fmt::Display for InternId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_usize().fmt(f) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/interned.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/interned.rs deleted file mode 100644 index 42c398d697de6..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/interned.rs +++ /dev/null @@ -1,510 +0,0 @@ -use crate::debug::TableEntry; -use crate::durability::Durability; -use crate::intern_id::InternId; -use crate::plumbing::CycleRecoveryStrategy; -use crate::plumbing::HasQueryGroup; -use crate::plumbing::QueryStorageMassOps; -use crate::plumbing::QueryStorageOps; -use crate::revision::Revision; -use crate::Query; -use crate::QueryTable; -use crate::{Database, DatabaseKeyIndex, QueryDb}; -use parking_lot::RwLock; -use rustc_hash::FxHashMap; -use std::collections::hash_map::Entry; -use std::fmt::Debug; -use std::hash::Hash; -use triomphe::Arc; - -const INTERN_DURABILITY: Durability = Durability::HIGH; - -/// Handles storage where the value is 'derived' by executing a -/// function (in contrast to "inputs"). -pub struct InternedStorage -where - Q: Query, - Q::Key: InternValue, - Q::Value: InternKey, -{ - group_index: u16, - tables: RwLock, Q::Key>>, -} - -/// Storage for the looking up interned things. -pub struct LookupInternedStorage -where - Q: Query, - Q::Key: InternKey, - Q::Value: InternValue, -{ - phantom: std::marker::PhantomData<(Q::Key, IQ)>, -} - -struct InternTables { - /// Map from the key to the corresponding intern-index. - map: FxHashMap, - - /// For each valid intern-index, stores the interned value. - values: Vec>>, -} - -/// Trait implemented for the "key" that results from a -/// `#[salsa::intern]` query. This is basically meant to be a -/// "newtype"'d `u32`. -pub trait InternKey { - /// Create an instance of the intern-key from a `u32` value. - fn from_intern_id(v: InternId) -> Self; - - /// Extract the `u32` with which the intern-key was created. - fn as_intern_id(&self) -> InternId; -} - -impl InternKey for InternId { - fn from_intern_id(v: InternId) -> InternId { - v - } - - fn as_intern_id(&self) -> InternId { - *self - } -} - -/// Trait implemented for the "value" that is being interned. -pub trait InternValue { - /// They key used to intern this value by. - type Key: Eq + Hash + Debug + Clone; - /// Maps the value to a key that will be used to intern it. - fn into_key(&self) -> Self::Key; - /// Calls the given function with the key that was used to intern this value. - /// - /// This is mainly used to prevent frequent cloning of the key when doing a lookup. - #[inline] - fn with_key T, T>(&self, f: F) -> T { - f(&self.into_key()) - } -} - -impl - InternValue for (A, B) -{ - type Key = Self; - #[inline] - fn into_key(&self) -> Self::Key { - self.clone() - } - #[inline] - fn with_key T, T>(&self, f: F) -> T { - f(self) - } -} - -pub trait InternValueTrivial -where - Self: Eq + Hash + Debug + Clone, -{ -} - -/// Implement [`InternValue`] trivially, that is without actually mapping at all. -impl InternValue for V { - type Key = Self; - #[inline] - fn into_key(&self) -> Self::Key { - self.clone() - } - #[inline] - fn with_key T, T>(&self, f: F) -> T { - f(self) - } -} - -impl InternValueTrivial for String {} - -#[derive(Debug)] -struct Slot { - /// key index for this slot. - key_index: u32, - - /// Value that was interned. - value: V, - - /// When was this intern'd? - /// - /// (This informs the "changed-at" result) - interned_at: Revision, -} - -impl std::panic::RefUnwindSafe for InternedStorage -where - Q: Query, - Q::Key: InternValue, - Q::Key: std::panic::RefUnwindSafe, - Q::Value: InternKey, - Q::Value: std::panic::RefUnwindSafe, -{ -} - -impl InternTables { - /// Returns the slot for the given key. - fn slot_for_key(&self, key: &K) -> Option<(Arc>, InternId)> { - let &index = self.map.get(key)?; - Some((self.slot_for_index(index), index)) - } - - /// Returns the slot at the given index. - fn slot_for_index(&self, index: InternId) -> Arc> { - let slot = &self.values[index.as_usize()]; - slot.clone() - } -} - -impl Default for InternTables -where - K: Eq + Hash, -{ - fn default() -> Self { - Self { map: Default::default(), values: Default::default() } - } -} - -type MappedKey = <::Key as InternValue>::Key; - -impl InternedStorage -where - Q: Query, - Q::Key: InternValue, - Q::Value: InternKey, -{ - /// Creates a new slot. - fn intern_index( - &self, - db: &>::DynDb, - mapped_key: MappedKey, - insert: impl FnOnce(Q::Value) -> Q::Key, - ) -> (Arc>, InternId) { - let revision_now = db.salsa_runtime().current_revision(); - - let mut tables = self.tables.write(); - let tables = &mut *tables; - let entry = match tables.map.entry(mapped_key) { - Entry::Vacant(entry) => entry, - Entry::Occupied(entry) => { - // Somebody inserted this key while we were waiting - // for the write lock. In this case, we don't need to - // update the `accessed_at` field because they should - // have already done so! - let index = *entry.get(); - let slot = &tables.values[index.as_usize()]; - return (slot.clone(), index); - } - }; - - let create_slot = |index: InternId| { - Arc::new(Slot { - key_index: index.as_u32(), - value: insert(Q::Value::from_intern_id(index)), - interned_at: revision_now, - }) - }; - - let index = InternId::from(tables.values.len()); - let slot = create_slot(index); - tables.values.push(slot.clone()); - entry.insert(index); - - (slot, index) - } - - fn intern_check(&self, key: &MappedKey) -> Option<(Arc>, InternId)> { - self.tables.read().slot_for_key(key) - } - - /// Given an index, lookup and clone its value, updating the - /// `accessed_at` time if necessary. - fn lookup_value(&self, index: InternId) -> Arc> { - self.tables.read().slot_for_index(index) - } - - fn fetch_or_insert( - &self, - db: &>::DynDb, - key: MappedKey, - insert: impl FnOnce(Q::Value) -> Q::Key, - ) -> Q::Value { - db.unwind_if_cancelled(); - let (slot, index) = match self.intern_check(&key) { - Some(i) => i, - None => self.intern_index(db, key, insert), - }; - let changed_at = slot.interned_at; - db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted( - DatabaseKeyIndex { - group_index: self.group_index, - query_index: Q::QUERY_INDEX, - key_index: slot.key_index, - }, - INTERN_DURABILITY, - changed_at, - ); - ::from_intern_id(index) - } -} - -impl QueryStorageOps for InternedStorage -where - Q: Query, - Q::Key: InternValue, - Q::Value: InternKey, -{ - const CYCLE_STRATEGY: crate::plumbing::CycleRecoveryStrategy = CycleRecoveryStrategy::Panic; - - fn new(group_index: u16) -> Self { - InternedStorage { group_index, tables: RwLock::new(InternTables::default()) } - } - - fn fmt_index( - &self, - _db: &>::DynDb, - index: u32, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - let intern_id = InternId::from(index); - let slot = self.lookup_value(intern_id); - write!(fmt, "{}({:?})", Q::QUERY_NAME, slot.value) - } - - fn maybe_changed_after( - &self, - db: &>::DynDb, - input: u32, - revision: Revision, - ) -> bool { - debug_assert!(revision < db.salsa_runtime().current_revision()); - let intern_id = InternId::from(input); - let slot = self.lookup_value(intern_id); - slot.maybe_changed_after(revision) - } - - fn fetch(&self, db: &>::DynDb, key: &Q::Key) -> Q::Value { - db.unwind_if_cancelled(); - - let (slot, index) = match key.with_key(|key| self.intern_check(key)) { - Some(i) => i, - None => self.intern_index(db, key.into_key(), |_| key.clone()), - }; - let changed_at = slot.interned_at; - db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted( - DatabaseKeyIndex { - group_index: self.group_index, - query_index: Q::QUERY_INDEX, - key_index: slot.key_index, - }, - INTERN_DURABILITY, - changed_at, - ); - ::from_intern_id(index) - } - - fn durability(&self, _db: &>::DynDb, _key: &Q::Key) -> Durability { - INTERN_DURABILITY - } - - fn entries(&self, _db: &>::DynDb) -> C - where - C: std::iter::FromIterator>, - { - let tables = self.tables.read(); - tables - .map - .values() - .map(|index| { - TableEntry::new( - tables.values[index.as_usize()].value.clone(), - Some(::from_intern_id(*index)), - ) - }) - .collect() - } -} - -impl QueryStorageMassOps for InternedStorage -where - Q: Query, - Q::Key: InternValue, - Q::Value: InternKey, -{ - fn purge(&self) { - *self.tables.write() = Default::default(); - } -} - -// Workaround for -// ``` -// IQ: for<'d> QueryDb< -// 'd, -// DynDb = >::DynDb, -// Group = >::Group, -// GroupStorage = >::GroupStorage, -// >, -// ``` -// not working to make rustc know DynDb, Group and GroupStorage being the same in `Q` and `IQ` -#[doc(hidden)] -pub trait EqualDynDb<'d, IQ>: QueryDb<'d> -where - IQ: QueryDb<'d>, -{ - fn convert_db(d: &Self::DynDb) -> &IQ::DynDb; - fn convert_group_storage(d: &Self::GroupStorage) -> &IQ::GroupStorage; -} - -impl<'d, IQ, Q> EqualDynDb<'d, IQ> for Q -where - Q: QueryDb<'d, DynDb = IQ::DynDb, Group = IQ::Group, GroupStorage = IQ::GroupStorage>, - Q::DynDb: HasQueryGroup, - IQ: QueryDb<'d>, -{ - fn convert_db(d: &Self::DynDb) -> &IQ::DynDb { - d - } - fn convert_group_storage(d: &Self::GroupStorage) -> &IQ::GroupStorage { - d - } -} - -impl QueryStorageOps for LookupInternedStorage -where - Q: Query, - Q::Key: InternKey, - Q::Value: InternValue, - IQ: Query>, - for<'d> Q: EqualDynDb<'d, IQ>, -{ - const CYCLE_STRATEGY: CycleRecoveryStrategy = CycleRecoveryStrategy::Panic; - - fn new(_group_index: u16) -> Self { - LookupInternedStorage { phantom: std::marker::PhantomData } - } - - fn fmt_index( - &self, - db: &>::DynDb, - index: u32, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - let group_storage = - <>::DynDb as HasQueryGroup>::group_storage(db); - let interned_storage = IQ::query_storage(Q::convert_group_storage(group_storage)); - interned_storage.fmt_index(Q::convert_db(db), index, fmt) - } - - fn maybe_changed_after( - &self, - db: &>::DynDb, - input: u32, - revision: Revision, - ) -> bool { - let group_storage = - <>::DynDb as HasQueryGroup>::group_storage(db); - let interned_storage = IQ::query_storage(Q::convert_group_storage(group_storage)); - interned_storage.maybe_changed_after(Q::convert_db(db), input, revision) - } - - fn fetch(&self, db: &>::DynDb, key: &Q::Key) -> Q::Value { - let index = key.as_intern_id(); - let group_storage = - <>::DynDb as HasQueryGroup>::group_storage(db); - let interned_storage = IQ::query_storage(Q::convert_group_storage(group_storage)); - let slot = interned_storage.lookup_value(index); - let value = slot.value.clone(); - let interned_at = slot.interned_at; - db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted( - DatabaseKeyIndex { - group_index: interned_storage.group_index, - query_index: Q::QUERY_INDEX, - key_index: slot.key_index, - }, - INTERN_DURABILITY, - interned_at, - ); - value - } - - fn durability(&self, _db: &>::DynDb, _key: &Q::Key) -> Durability { - INTERN_DURABILITY - } - - fn entries(&self, db: &>::DynDb) -> C - where - C: std::iter::FromIterator>, - { - let group_storage = - <>::DynDb as HasQueryGroup>::group_storage(db); - let interned_storage = IQ::query_storage(Q::convert_group_storage(group_storage)); - let tables = interned_storage.tables.read(); - tables - .map - .values() - .map(|index| { - TableEntry::new( - ::from_intern_id(*index), - Some(tables.values[index.as_usize()].value.clone()), - ) - }) - .collect() - } -} - -impl QueryStorageMassOps for LookupInternedStorage -where - Q: Query, - Q::Key: InternKey, - Q::Value: InternValue, - IQ: Query, -{ - fn purge(&self) {} -} - -impl Slot { - fn maybe_changed_after(&self, revision: Revision) -> bool { - self.interned_at > revision - } -} - -/// Check that `Slot: Send + Sync` as long as -/// `DB::DatabaseData: Send + Sync`, which in turn implies that -/// `Q::Key: Send + Sync`, `Q::Value: Send + Sync`. -#[allow(dead_code)] -fn check_send_sync() -where - K: Send + Sync, -{ - fn is_send_sync() {} - is_send_sync::>(); -} - -/// Check that `Slot: 'static` as long as -/// `DB::DatabaseData: 'static`, which in turn implies that -/// `Q::Key: 'static`, `Q::Value: 'static`. -#[allow(dead_code)] -fn check_static() -where - K: 'static, -{ - fn is_static() {} - is_static::>(); -} - -impl QueryTable<'_, Q> -where - Q: Query>, - Q::Key: InternValue, - Q::Value: InternKey, -{ - /// Fetches the intern id for the given key or inserts it if it does not exist. - pub fn get_or_insert( - &self, - key: MappedKey, - insert: impl FnOnce(Q::Value) -> Q::Key, - ) -> Q::Value { - self.storage.fetch_or_insert(self.db, key, insert) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs deleted file mode 100644 index 843b6d31f0c33..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs +++ /dev/null @@ -1,750 +0,0 @@ -#![allow(clippy::type_complexity)] -#![allow(clippy::question_mark)] -#![allow(missing_docs)] -#![warn(rust_2018_idioms)] - -//! The salsa crate is a crate for incremental recomputation. It -//! permits you to define a "database" of queries with both inputs and -//! values derived from those inputs; as you set the inputs, you can -//! re-execute the derived queries and it will try to re-use results -//! from previous invocations as appropriate. - -mod derived; -mod derived_lru; -mod durability; -mod hash; -mod input; -mod intern_id; -mod interned; -mod lru; -mod revision; -mod runtime; -mod storage; - -pub mod debug; -/// Items in this module are public for implementation reasons, -/// and are exempt from the SemVer guarantees. -#[doc(hidden)] -pub mod plumbing; - -use crate::plumbing::CycleRecoveryStrategy; -use crate::plumbing::DerivedQueryStorageOps; -use crate::plumbing::InputQueryStorageOps; -use crate::plumbing::LruQueryStorageOps; -use crate::plumbing::QueryStorageMassOps; -use crate::plumbing::QueryStorageOps; -pub use crate::revision::Revision; -use std::fmt::{self, Debug}; -use std::hash::Hash; -use std::panic::AssertUnwindSafe; -use std::panic::{self, UnwindSafe}; - -pub use crate::durability::Durability; -pub use crate::intern_id::InternId; -pub use crate::interned::{InternKey, InternValue, InternValueTrivial}; -pub use crate::runtime::Runtime; -pub use crate::runtime::RuntimeId; -pub use crate::storage::Storage; - -/// The base trait which your "query context" must implement. Gives -/// access to the salsa runtime, which you must embed into your query -/// context (along with whatever other state you may require). -pub trait Database: plumbing::DatabaseOps { - /// This function is invoked at key points in the salsa - /// runtime. It permits the database to be customized and to - /// inject logging or other custom behavior. - fn salsa_event(&self, event_fn: Event) { - _ = event_fn; - } - - /// Starts unwinding the stack if the current revision is cancelled. - /// - /// This method can be called by query implementations that perform - /// potentially expensive computations, in order to speed up propagation of - /// cancellation. - /// - /// Cancellation will automatically be triggered by salsa on any query - /// invocation. - /// - /// This method should not be overridden by `Database` implementors. A - /// `salsa_event` is emitted when this method is called, so that should be - /// used instead. - #[inline] - fn unwind_if_cancelled(&self) { - let runtime = self.salsa_runtime(); - self.salsa_event(Event { - runtime_id: runtime.id(), - kind: EventKind::WillCheckCancellation, - }); - - let current_revision = runtime.current_revision(); - let pending_revision = runtime.pending_revision(); - tracing::trace!( - "unwind_if_cancelled: current_revision={:?}, pending_revision={:?}", - current_revision, - pending_revision - ); - if pending_revision > current_revision { - runtime.unwind_cancelled(); - } - } - - /// Gives access to the underlying salsa runtime. - /// - /// This method should not be overridden by `Database` implementors. - fn salsa_runtime(&self) -> &Runtime { - self.ops_salsa_runtime() - } - - /// A "synthetic write" causes the system to act *as though* some - /// input of durability `durability` has changed. This is mostly - /// useful for profiling scenarios. - /// - /// **WARNING:** Just like an ordinary write, this method triggers - /// cancellation. If you invoke it while a snapshot exists, it - /// will block until that snapshot is dropped -- if that snapshot - /// is owned by the current thread, this could trigger deadlock. - fn synthetic_write(&mut self, durability: Durability) { - plumbing::DatabaseOps::synthetic_write(self, durability) - } -} - -/// The `Event` struct identifies various notable things that can -/// occur during salsa execution. Instances of this struct are given -/// to `salsa_event`. -pub struct Event { - /// The id of the snapshot that triggered the event. Usually - /// 1-to-1 with a thread, as well. - pub runtime_id: RuntimeId, - - /// What sort of event was it. - pub kind: EventKind, -} - -impl Event { - /// Returns a type that gives a user-readable debug output. - /// Use like `println!("{:?}", index.debug(db))`. - pub fn debug<'me, D>(&'me self, db: &'me D) -> impl std::fmt::Debug + 'me - where - D: ?Sized + plumbing::DatabaseOps, - { - EventDebug { event: self, db } - } -} - -impl fmt::Debug for Event { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Event") - .field("runtime_id", &self.runtime_id) - .field("kind", &self.kind) - .finish() - } -} - -struct EventDebug<'me, D: ?Sized> -where - D: plumbing::DatabaseOps, -{ - event: &'me Event, - db: &'me D, -} - -impl fmt::Debug for EventDebug<'_, D> -where - D: plumbing::DatabaseOps, -{ - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Event") - .field("runtime_id", &self.event.runtime_id) - .field("kind", &self.event.kind.debug(self.db)) - .finish() - } -} - -/// An enum identifying the various kinds of events that can occur. -pub enum EventKind { - /// Occurs when we found that all inputs to a memoized value are - /// up-to-date and hence the value can be re-used without - /// executing the closure. - /// - /// Executes before the "re-used" value is returned. - DidValidateMemoizedValue { - /// The database-key for the affected value. Implements `Debug`. - database_key: DatabaseKeyIndex, - }, - - /// Indicates that another thread (with id `other_runtime_id`) is processing the - /// given query (`database_key`), so we will block until they - /// finish. - /// - /// Executes after we have registered with the other thread but - /// before they have answered us. - /// - /// (NB: you can find the `id` of the current thread via the - /// `salsa_runtime`) - WillBlockOn { - /// The id of the runtime we will block on. - other_runtime_id: RuntimeId, - - /// The database-key for the affected value. Implements `Debug`. - database_key: DatabaseKeyIndex, - }, - - /// Indicates that the function for this query will be executed. - /// This is either because it has never executed before or because - /// its inputs may be out of date. - WillExecute { - /// The database-key for the affected value. Implements `Debug`. - database_key: DatabaseKeyIndex, - }, - - /// Indicates that `unwind_if_cancelled` was called and salsa will check if - /// the current revision has been cancelled. - WillCheckCancellation, -} - -impl EventKind { - /// Returns a type that gives a user-readable debug output. - /// Use like `println!("{:?}", index.debug(db))`. - pub fn debug<'me, D>(&'me self, db: &'me D) -> impl std::fmt::Debug + 'me - where - D: ?Sized + plumbing::DatabaseOps, - { - EventKindDebug { kind: self, db } - } -} - -impl fmt::Debug for EventKind { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - EventKind::DidValidateMemoizedValue { database_key } => fmt - .debug_struct("DidValidateMemoizedValue") - .field("database_key", database_key) - .finish(), - EventKind::WillBlockOn { other_runtime_id, database_key } => fmt - .debug_struct("WillBlockOn") - .field("other_runtime_id", other_runtime_id) - .field("database_key", database_key) - .finish(), - EventKind::WillExecute { database_key } => { - fmt.debug_struct("WillExecute").field("database_key", database_key).finish() - } - EventKind::WillCheckCancellation => fmt.debug_struct("WillCheckCancellation").finish(), - } - } -} - -struct EventKindDebug<'me, D: ?Sized> -where - D: plumbing::DatabaseOps, -{ - kind: &'me EventKind, - db: &'me D, -} - -impl fmt::Debug for EventKindDebug<'_, D> -where - D: plumbing::DatabaseOps, -{ - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - EventKind::DidValidateMemoizedValue { database_key } => fmt - .debug_struct("DidValidateMemoizedValue") - .field("database_key", &database_key.debug(self.db)) - .finish(), - EventKind::WillBlockOn { other_runtime_id, database_key } => fmt - .debug_struct("WillBlockOn") - .field("other_runtime_id", &other_runtime_id) - .field("database_key", &database_key.debug(self.db)) - .finish(), - EventKind::WillExecute { database_key } => fmt - .debug_struct("WillExecute") - .field("database_key", &database_key.debug(self.db)) - .finish(), - EventKind::WillCheckCancellation => fmt.debug_struct("WillCheckCancellation").finish(), - } - } -} - -/// Indicates a database that also supports parallel query -/// evaluation. All of Salsa's base query support is capable of -/// parallel execution, but for it to work, your query key/value types -/// must also be `Send`, as must any additional data in your database. -pub trait ParallelDatabase: Database + Send { - /// Creates a second handle to the database that holds the - /// database fixed at a particular revision. So long as this - /// "frozen" handle exists, any attempt to [`set`] an input will - /// block. - /// - /// [`set`]: struct.QueryTable.html#method.set - /// - /// This is the method you are meant to use most of the time in a - /// parallel setting where modifications may arise asynchronously - /// (e.g., a language server). In this context, it is common to - /// wish to "fork off" a snapshot of the database performing some - /// series of queries in parallel and arranging the results. Using - /// this method for that purpose ensures that those queries will - /// see a consistent view of the database (it is also advisable - /// for those queries to use the [`Database::unwind_if_cancelled`] - /// method to check for cancellation). - /// - /// # Panics - /// - /// It is not permitted to create a snapshot from inside of a - /// query. Attempting to do so will panic. - /// - /// # Deadlock warning - /// - /// The intended pattern for snapshots is that, once created, they - /// are sent to another thread and used from there. As such, the - /// `snapshot` acquires a "read lock" on the database -- - /// therefore, so long as the `snapshot` is not dropped, any - /// attempt to `set` a value in the database will block. If the - /// `snapshot` is owned by the same thread that is attempting to - /// `set`, this will cause a problem. - /// - /// # How to implement this - /// - /// Typically, this method will create a second copy of your - /// database type (`MyDatabaseType`, in the example below), - /// cloning over each of the fields from `self` into this new - /// copy. For the field that stores the salsa runtime, you should - /// use [the `Runtime::snapshot` method][rfm] to create a snapshot of the - /// runtime. Finally, package up the result using `Snapshot::new`, - /// which is a simple wrapper type that only gives `&self` access - /// to the database within (thus preventing the use of methods - /// that may mutate the inputs): - /// - /// [rfm]: struct.Runtime.html#method.snapshot - /// - /// ```rust,ignore - /// impl ParallelDatabase for MyDatabaseType { - /// fn snapshot(&self) -> Snapshot { - /// Snapshot::new( - /// MyDatabaseType { - /// runtime: self.runtime.snapshot(self), - /// other_field: self.other_field.clone(), - /// } - /// ) - /// } - /// } - /// ``` - fn snapshot(&self) -> Snapshot; -} - -/// Simple wrapper struct that takes ownership of a database `DB` and -/// only gives `&self` access to it. See [the `snapshot` method][fm] -/// for more details. -/// -/// [fm]: trait.ParallelDatabase.html#method.snapshot -#[derive(Debug)] -pub struct Snapshot -where - DB: ParallelDatabase, -{ - db: DB, -} - -impl Snapshot -where - DB: ParallelDatabase, -{ - /// Creates a `Snapshot` that wraps the given database handle - /// `db`. From this point forward, only shared references to `db` - /// will be possible. - pub fn new(db: DB) -> Self { - Snapshot { db } - } -} - -impl std::ops::Deref for Snapshot -where - DB: ParallelDatabase, -{ - type Target = DB; - - fn deref(&self) -> &DB { - &self.db - } -} - -/// An integer that uniquely identifies a particular query instance within the -/// database. Used to track dependencies between queries. Fully ordered and -/// equatable but those orderings are arbitrary, and meant to be used only for -/// inserting into maps and the like. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct DatabaseKeyIndex { - group_index: u16, - query_index: u16, - key_index: u32, -} - -impl DatabaseKeyIndex { - /// Returns the index of the query group containing this key. - #[inline] - pub fn group_index(self) -> u16 { - self.group_index - } - - /// Returns the index of the query within its query group. - #[inline] - pub fn query_index(self) -> u16 { - self.query_index - } - - /// Returns the index of this particular query key within the query. - #[inline] - pub fn key_index(self) -> u32 { - self.key_index - } - - /// Returns a type that gives a user-readable debug output. - /// Use like `println!("{:?}", index.debug(db))`. - pub fn debug(self, db: &D) -> impl std::fmt::Debug + '_ - where - D: ?Sized + plumbing::DatabaseOps, - { - DatabaseKeyIndexDebug { index: self, db } - } -} - -/// Helper type for `DatabaseKeyIndex::debug` -struct DatabaseKeyIndexDebug<'me, D: ?Sized> -where - D: plumbing::DatabaseOps, -{ - index: DatabaseKeyIndex, - db: &'me D, -} - -impl std::fmt::Debug for DatabaseKeyIndexDebug<'_, D> -where - D: plumbing::DatabaseOps, -{ - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.db.fmt_index(self.index, fmt) - } -} - -/// Trait implements by all of the "special types" associated with -/// each of your queries. -/// -/// Base trait of `Query` that has a lifetime parameter to allow the `DynDb` to be non-'static. -pub trait QueryDb<'d>: Sized { - /// Dyn version of the associated trait for this query group. - type DynDb: ?Sized + Database + HasQueryGroup + 'd; - - /// Associate query group struct. - type Group: plumbing::QueryGroup; - - /// Generated struct that contains storage for all queries in a group. - type GroupStorage; -} - -/// Trait implements by all of the "special types" associated with -/// each of your queries. -pub trait Query: Debug + Default + Sized + for<'d> QueryDb<'d> { - /// Type that you give as a parameter -- for queries with zero - /// or more than one input, this will be a tuple. - type Key: Clone + Debug + Hash + Eq; - - /// What value does the query return? - type Value: Clone + Debug; - - /// Internal struct storing the values for the query. - // type Storage: plumbing::QueryStorageOps; - type Storage; - - /// A unique index identifying this query within the group. - const QUERY_INDEX: u16; - - /// Name of the query method (e.g., `foo`) - const QUERY_NAME: &'static str; - - /// Extract storage for this query from the storage for its group. - fn query_storage<'a>( - group_storage: &'a >::GroupStorage, - ) -> &'a std::sync::Arc; - - /// Extract storage for this query from the storage for its group. - fn query_storage_mut<'a>( - group_storage: &'a >::GroupStorage, - ) -> &'a std::sync::Arc; -} - -/// Return value from [the `query` method] on `Database`. -/// Gives access to various less common operations on queries. -/// -/// [the `query` method]: trait.Database.html#method.query -pub struct QueryTable<'me, Q> -where - Q: Query, -{ - db: &'me >::DynDb, - storage: &'me Q::Storage, -} - -impl<'me, Q> QueryTable<'me, Q> -where - Q: Query, - Q::Storage: QueryStorageOps, -{ - /// Constructs a new `QueryTable`. - pub fn new(db: &'me >::DynDb, storage: &'me Q::Storage) -> Self { - Self { db, storage } - } - - /// Execute the query on a given input. Usually it's easier to - /// invoke the trait method directly. Note that for variadic - /// queries (those with no inputs, or those with more than one - /// input) the key will be a tuple. - pub fn get(&self, key: Q::Key) -> Q::Value { - self.storage.fetch(self.db, &key) - } - - /// Completely clears the storage for this query. - /// - /// This method breaks internal invariants of salsa, so any further queries - /// might return nonsense results. It is useful only in very specific - /// circumstances -- for example, when one wants to observe which values - /// dropped together with the table - pub fn purge(&self) - where - Q::Storage: plumbing::QueryStorageMassOps, - { - self.storage.purge(); - } - - pub fn storage(&self) -> &::Storage { - self.storage - } -} - -/// Return value from [the `query_mut` method] on `Database`. -/// Gives access to the `set` method, notably, that is used to -/// set the value of an input query. -/// -/// [the `query_mut` method]: trait.Database.html#method.query_mut -pub struct QueryTableMut<'me, Q> -where - Q: Query + 'me, -{ - runtime: &'me mut Runtime, - storage: &'me Q::Storage, -} - -impl<'me, Q> QueryTableMut<'me, Q> -where - Q: Query, -{ - /// Constructs a new `QueryTableMut`. - pub fn new(runtime: &'me mut Runtime, storage: &'me Q::Storage) -> Self { - Self { runtime, storage } - } - - /// Assign a value to an "input query". Must be used outside of - /// an active query computation. - /// - /// If you are using `snapshot`, see the notes on blocking - /// and cancellation on [the `query_mut` method]. - /// - /// [the `query_mut` method]: trait.Database.html#method.query_mut - pub fn set(&mut self, key: Q::Key, value: Q::Value) - where - Q::Storage: plumbing::InputQueryStorageOps, - { - self.set_with_durability(key, value, Durability::LOW); - } - - /// Assign a value to an "input query", with the additional - /// promise that this value will **never change**. Must be used - /// outside of an active query computation. - /// - /// If you are using `snapshot`, see the notes on blocking - /// and cancellation on [the `query_mut` method]. - /// - /// [the `query_mut` method]: trait.Database.html#method.query_mut - pub fn set_with_durability(&mut self, key: Q::Key, value: Q::Value, durability: Durability) - where - Q::Storage: plumbing::InputQueryStorageOps, - { - self.storage.set(self.runtime, &key, value, durability); - } - - /// Sets the size of LRU cache of values for this query table. - /// - /// That is, at most `cap` values will be preset in the table at the same - /// time. This helps with keeping maximum memory usage under control, at the - /// cost of potential extra recalculations of evicted values. - /// - /// If `cap` is zero, all values are preserved, this is the default. - pub fn set_lru_capacity(&self, cap: u16) - where - Q::Storage: plumbing::LruQueryStorageOps, - { - self.storage.set_lru_capacity(cap); - } - - /// Marks the computed value as outdated. - /// - /// This causes salsa to re-execute the query function on the next access to - /// the query, even if all dependencies are up to date. - /// - /// This is most commonly used as part of the [on-demand input - /// pattern](https://salsa-rs.github.io/salsa/common_patterns/on_demand_inputs.html). - pub fn invalidate(&mut self, key: &Q::Key) - where - Q::Storage: plumbing::DerivedQueryStorageOps, - { - self.storage.invalidate(self.runtime, key) - } -} - -/// A panic payload indicating that execution of a salsa query was cancelled. -/// -/// This can occur for a few reasons: -/// * -/// * -/// * -#[derive(Debug)] -#[non_exhaustive] -pub enum Cancelled { - /// The query was operating on revision R, but there is a pending write to move to revision R+1. - #[non_exhaustive] - PendingWrite, - - /// The query was blocked on another thread, and that thread panicked. - #[non_exhaustive] - PropagatedPanic, -} - -impl Cancelled { - fn throw(self) -> ! { - // We use resume and not panic here to avoid running the panic - // hook (that is, to avoid collecting and printing backtrace). - std::panic::resume_unwind(Box::new(self)); - } - - /// Runs `f`, and catches any salsa cancellation. - pub fn catch(f: F) -> Result - where - F: FnOnce() -> T + UnwindSafe, - { - match panic::catch_unwind(f) { - Ok(t) => Ok(t), - Err(payload) => match payload.downcast() { - Ok(cancelled) => Err(*cancelled), - Err(payload) => panic::resume_unwind(payload), - }, - } - } -} - -impl std::fmt::Display for Cancelled { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let why = match self { - Cancelled::PendingWrite => "pending write", - Cancelled::PropagatedPanic => "propagated panic", - }; - f.write_str("cancelled because of ")?; - f.write_str(why) - } -} - -impl std::error::Error for Cancelled {} - -/// Captures the participants of a cycle that occurred when executing a query. -/// -/// This type is meant to be used to help give meaningful error messages to the -/// user or to help salsa developers figure out why their program is resulting -/// in a computation cycle. -/// -/// It is used in a few ways: -/// -/// * During [cycle recovery](https://https://salsa-rs.github.io/salsa/cycles/fallback.html), -/// where it is given to the fallback function. -/// * As the panic value when an unexpected cycle (i.e., a cycle where one or more participants -/// lacks cycle recovery information) occurs. -/// -/// You can read more about cycle handling in -/// the [salsa book](https://https://salsa-rs.github.io/salsa/cycles.html). -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Cycle { - participants: plumbing::CycleParticipants, -} - -impl Cycle { - pub(crate) fn new(participants: plumbing::CycleParticipants) -> Self { - Self { participants } - } - - /// True if two `Cycle` values represent the same cycle. - pub(crate) fn is(&self, cycle: &Cycle) -> bool { - triomphe::Arc::ptr_eq(&self.participants, &cycle.participants) - } - - pub(crate) fn throw(self) -> ! { - tracing::trace!("throwing cycle {:?}", self); - std::panic::resume_unwind(Box::new(self)) - } - - pub(crate) fn catch(execute: impl FnOnce() -> T) -> Result { - match std::panic::catch_unwind(AssertUnwindSafe(execute)) { - Ok(v) => Ok(v), - Err(err) => match err.downcast::() { - Ok(cycle) => Err(*cycle), - Err(other) => std::panic::resume_unwind(other), - }, - } - } - - /// Iterate over the [`DatabaseKeyIndex`] for each query participating - /// in the cycle. The start point of this iteration within the cycle - /// is arbitrary but deterministic, but the ordering is otherwise determined - /// by the execution. - pub fn participant_keys(&self) -> impl Iterator + '_ { - self.participants.iter().copied() - } - - /// Returns a vector with the debug information for - /// all the participants in the cycle. - pub fn all_participants(&self, db: &DB) -> Vec { - self.participant_keys().map(|d| format!("{:?}", d.debug(db))).collect() - } - - /// Returns a vector with the debug information for - /// those participants in the cycle that lacked recovery - /// information. - pub fn unexpected_participants(&self, db: &DB) -> Vec { - self.participant_keys() - .filter(|&d| db.cycle_recovery_strategy(d) == CycleRecoveryStrategy::Panic) - .map(|d| format!("{:?}", d.debug(db))) - .collect() - } - - /// Returns a "debug" view onto this strict that can be used to print out information. - pub fn debug<'me, DB: ?Sized + Database>(&'me self, db: &'me DB) -> impl std::fmt::Debug + 'me { - struct UnexpectedCycleDebug<'me> { - c: &'me Cycle, - db: &'me dyn Database, - } - - impl std::fmt::Debug for UnexpectedCycleDebug<'_> { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fmt.debug_struct("UnexpectedCycle") - .field("all_participants", &self.c.all_participants(self.db)) - .field("unexpected_participants", &self.c.unexpected_participants(self.db)) - .finish() - } - } - - UnexpectedCycleDebug { c: self, db: db.ops_database() } - } -} - -// Re-export the procedural macros. -#[allow(unused_imports)] -#[macro_use] -extern crate ra_salsa_macros; -use plumbing::HasQueryGroup; -pub use ra_salsa_macros::*; diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/lru.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lru.rs deleted file mode 100644 index 7fbd42f92627a..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/lru.rs +++ /dev/null @@ -1,325 +0,0 @@ -use oorandom::Rand64; -use parking_lot::Mutex; -use std::fmt::Debug; -use std::sync::atomic::AtomicU16; -use std::sync::atomic::Ordering; -use triomphe::Arc; - -/// A simple and approximate concurrent lru list. -/// -/// We assume but do not verify that each node is only used with one -/// list. If this is not the case, it is not *unsafe*, but panics and -/// weird results will ensue. -/// -/// Each "node" in the list is of type `Node` and must implement -/// `LruNode`, which is a trait that gives access to a field that -/// stores the index in the list. This index gives us a rough idea of -/// how recently the node has been used. -#[derive(Debug)] -pub(crate) struct Lru -where - Node: LruNode, -{ - green_zone: AtomicU16, - data: Mutex>, -} - -#[derive(Debug)] -struct LruData { - end_red_zone: u16, - end_yellow_zone: u16, - end_green_zone: u16, - rng: Rand64, - entries: Vec>, -} - -pub(crate) trait LruNode: Sized + Debug { - fn lru_index(&self) -> &LruIndex; -} - -#[derive(Debug)] -pub(crate) struct LruIndex { - /// Index in the appropriate LRU list, or std::u16::MAX if not a - /// member. - index: AtomicU16, -} - -impl Default for Lru -where - Node: LruNode, -{ - fn default() -> Self { - Lru::new() - } -} - -// We always use a fixed seed for our randomness so that we have -// predictable results. -const LRU_SEED: &str = "Hello, Rustaceans"; - -impl Lru -where - Node: LruNode, -{ - /// Creates a new LRU list where LRU caching is disabled. - pub(crate) fn new() -> Self { - Self::with_seed(LRU_SEED) - } - - #[cfg_attr(not(test), allow(dead_code))] - fn with_seed(seed: &str) -> Self { - Lru { green_zone: AtomicU16::new(0), data: Mutex::new(LruData::with_seed(seed)) } - } - - /// Adjust the total number of nodes permitted to have a value at - /// once. If `len` is zero, this disables LRU caching completely. - pub(crate) fn set_lru_capacity(&self, len: u16) { - let mut data = self.data.lock(); - - // We require each zone to have at least 1 slot. Therefore, - // the length cannot be just 1 or 2. - if len == 0 { - self.green_zone.store(0, Ordering::Release); - data.resize(0, 0, 0); - } else { - let len = std::cmp::max(len, 3); - - // Top 10% is the green zone. This must be at least length 1. - let green_zone = std::cmp::max(len / 10, 1); - - // Next 20% is the yellow zone. - let yellow_zone = std::cmp::max(len / 5, 1); - - // Remaining 70% is the red zone. - let red_zone = len - yellow_zone - green_zone; - - // We need quick access to the green zone. - self.green_zone.store(green_zone, Ordering::Release); - - // Resize existing array. - data.resize(green_zone, yellow_zone, red_zone); - } - } - - /// Records that `node` was used. This may displace an old node (if the LRU limits are - pub(crate) fn record_use(&self, node: &Arc) -> Option> { - tracing::trace!("record_use(node={:?})", node); - - // Load green zone length and check if the LRU cache is even enabled. - let green_zone = self.green_zone.load(Ordering::Acquire); - tracing::trace!("record_use: green_zone={}", green_zone); - if green_zone == 0 { - return None; - } - - // Find current index of list (if any) and the current length - // of our green zone. - let index = node.lru_index().load(); - tracing::trace!("record_use: index={}", index); - - // Already a member of the list, and in the green zone -- nothing to do! - if index < green_zone { - return None; - } - - self.data.lock().record_use(node) - } - - pub(crate) fn purge(&self) { - self.green_zone.store(0, Ordering::SeqCst); - *self.data.lock() = LruData::with_seed(LRU_SEED); - } -} - -impl LruData -where - Node: LruNode, -{ - fn with_seed(seed_str: &str) -> Self { - Self::with_rng(rng_with_seed(seed_str)) - } - - fn with_rng(rng: Rand64) -> Self { - LruData { end_yellow_zone: 0, end_green_zone: 0, end_red_zone: 0, entries: Vec::new(), rng } - } - - fn green_zone(&self) -> std::ops::Range { - 0..self.end_green_zone - } - - fn yellow_zone(&self) -> std::ops::Range { - self.end_green_zone..self.end_yellow_zone - } - - fn red_zone(&self) -> std::ops::Range { - self.end_yellow_zone..self.end_red_zone - } - - fn resize(&mut self, len_green_zone: u16, len_yellow_zone: u16, len_red_zone: u16) { - self.end_green_zone = len_green_zone; - self.end_yellow_zone = self.end_green_zone + len_yellow_zone; - self.end_red_zone = self.end_yellow_zone + len_red_zone; - let entries = - std::mem::replace(&mut self.entries, Vec::with_capacity(self.end_red_zone as usize)); - - tracing::trace!("green_zone = {:?}", self.green_zone()); - tracing::trace!("yellow_zone = {:?}", self.yellow_zone()); - tracing::trace!("red_zone = {:?}", self.red_zone()); - - // We expect to resize when the LRU cache is basically empty. - // So just forget all the old LRU indices to start. - for entry in entries { - entry.lru_index().clear(); - } - } - - /// Records that a node was used. If it is already a member of the - /// LRU list, it is promoted to the green zone (unless it's - /// already there). Otherwise, it is added to the list first and - /// *then* promoted to the green zone. Adding a new node to the - /// list may displace an old member of the red zone, in which case - /// that is returned. - fn record_use(&mut self, node: &Arc) -> Option> { - tracing::trace!("record_use(node={:?})", node); - - // NB: When this is invoked, we have typically already loaded - // the LRU index (to check if it is in green zone). But that - // check was done outside the lock and -- for all we know -- - // the index may have changed since. So we always reload. - let index = node.lru_index().load(); - - if index < self.end_green_zone { - None - } else if index < self.end_yellow_zone { - self.promote_yellow_to_green(node, index); - None - } else if index < self.end_red_zone { - self.promote_red_to_green(node, index); - None - } else { - self.insert_new(node) - } - } - - /// Inserts a node that is not yet a member of the LRU list. If - /// the list is at capacity, this can displace an existing member. - fn insert_new(&mut self, node: &Arc) -> Option> { - debug_assert!(!node.lru_index().is_in_lru()); - - // Easy case: we still have capacity. Push it, and then promote - // it up to the appropriate zone. - let len = self.entries.len() as u16; - if len < self.end_red_zone { - self.entries.push(node.clone()); - node.lru_index().store(len); - tracing::trace!("inserted node {:?} at {}", node, len); - return self.record_use(node); - } - - // Harder case: no capacity. Create some by evicting somebody from red - // zone and then promoting. - let victim_index = self.pick_index(self.red_zone()); - let victim_node = std::mem::replace(&mut self.entries[victim_index as usize], node.clone()); - tracing::trace!("evicting red node {:?} from {}", victim_node, victim_index); - victim_node.lru_index().clear(); - self.promote_red_to_green(node, victim_index); - Some(victim_node) - } - - /// Promotes the node `node`, stored at `red_index` (in the red - /// zone), into a green index, demoting yellow/green nodes at - /// random. - /// - /// NB: It is not required that `node.lru_index()` is up-to-date - /// when entering this method. - fn promote_red_to_green(&mut self, node: &Arc, red_index: u16) { - debug_assert!(self.red_zone().contains(&red_index)); - - // Pick a yellow at random and switch places with it. - // - // Subtle: we do not update `node.lru_index` *yet* -- we're - // going to invoke `self.promote_yellow` next, and it will get - // updated then. - let yellow_index = self.pick_index(self.yellow_zone()); - tracing::trace!( - "demoting yellow node {:?} from {} to red at {}", - self.entries[yellow_index as usize], - yellow_index, - red_index, - ); - self.entries.swap(yellow_index as usize, red_index as usize); - self.entries[red_index as usize].lru_index().store(red_index); - - // Now move ourselves up into the green zone. - self.promote_yellow_to_green(node, yellow_index); - } - - /// Promotes the node `node`, stored at `yellow_index` (in the - /// yellow zone), into a green index, demoting a green node at - /// random to replace it. - /// - /// NB: It is not required that `node.lru_index()` is up-to-date - /// when entering this method. - fn promote_yellow_to_green(&mut self, node: &Arc, yellow_index: u16) { - debug_assert!(self.yellow_zone().contains(&yellow_index)); - - // Pick a yellow at random and switch places with it. - let green_index = self.pick_index(self.green_zone()); - tracing::trace!( - "demoting green node {:?} from {} to yellow at {}", - self.entries[green_index as usize], - green_index, - yellow_index - ); - self.entries.swap(green_index as usize, yellow_index as usize); - self.entries[yellow_index as usize].lru_index().store(yellow_index); - node.lru_index().store(green_index); - - tracing::trace!("promoted {:?} to green index {}", node, green_index); - } - - fn pick_index(&mut self, zone: std::ops::Range) -> u16 { - let end_index = std::cmp::min(zone.end, self.entries.len() as u16); - self.rng.rand_range(zone.start as u64..end_index as u64) as u16 - } -} - -impl Default for LruIndex { - fn default() -> Self { - Self { index: AtomicU16::new(u16::MAX) } - } -} - -impl LruIndex { - fn load(&self) -> u16 { - self.index.load(Ordering::Acquire) // see note on ordering below - } - - fn store(&self, value: u16) { - self.index.store(value, Ordering::Release) // see note on ordering below - } - - fn clear(&self) { - self.store(u16::MAX); - } - - fn is_in_lru(&self) -> bool { - self.load() != u16::MAX - } -} - -fn rng_with_seed(seed_str: &str) -> Rand64 { - let mut seed: [u8; 16] = [0; 16]; - for (i, &b) in seed_str.as_bytes().iter().take(16).enumerate() { - seed[i] = b; - } - Rand64::new(u128::from_le_bytes(seed)) -} - -// A note on ordering: -// -// I chose to use AcqRel for the ordering but I don't think it's -// strictly needed. All writes occur under a lock, so they should be -// ordered w/r/t one another. As for the reads, they can occur -// outside the lock, but they don't themselves enable dependent reads -// -- if the reads are out of bounds, we would acquire a lock. diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/plumbing.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/plumbing.rs deleted file mode 100644 index e96b9daa979fc..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/plumbing.rs +++ /dev/null @@ -1,245 +0,0 @@ -#![allow(missing_docs)] - -use crate::debug::TableEntry; -use crate::durability::Durability; -use crate::Cycle; -use crate::Database; -use crate::Query; -use crate::QueryTable; -use crate::QueryTableMut; -use std::borrow::Borrow; -use std::fmt::Debug; -use std::hash::Hash; -use triomphe::Arc; - -pub use crate::derived::MemoizedStorage; -pub use crate::derived_lru::DependencyStorage as LruDependencyStorage; -pub use crate::derived_lru::MemoizedStorage as LruMemoizedStorage; -pub use crate::input::{InputStorage, UnitInputStorage}; -pub use crate::interned::InternedStorage; -pub use crate::interned::LookupInternedStorage; -pub use crate::{revision::Revision, DatabaseKeyIndex, QueryDb, Runtime}; - -/// Defines various associated types. An impl of this -/// should be generated for your query-context type automatically by -/// the `database_storage` macro, so you shouldn't need to mess -/// with this trait directly. -pub trait DatabaseStorageTypes: Database { - /// Defines the "storage type", where all the query data is kept. - /// This type is defined by the `database_storage` macro. - type DatabaseStorage: Default; -} - -/// Internal operations that the runtime uses to operate on the database. -pub trait DatabaseOps { - /// Upcast this type to a `dyn Database`. - fn ops_database(&self) -> &dyn Database; - - /// Gives access to the underlying salsa runtime. - fn ops_salsa_runtime(&self) -> &Runtime; - - /// A "synthetic write" causes the system to act *as though* some - /// input of durability `durability` has changed. This is mostly - /// useful for profiling scenarios. - /// - /// **WARNING:** Just like an ordinary write, this method triggers - /// cancellation. If you invoke it while a snapshot exists, it - /// will block until that snapshot is dropped -- if that snapshot - /// is owned by the current thread, this could trigger deadlock. - fn synthetic_write(&mut self, durability: Durability); - - /// Formats a database key index in a human readable fashion. - fn fmt_index( - &self, - index: DatabaseKeyIndex, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result; - - /// True if the computed value for `input` may have changed since `revision`. - fn maybe_changed_after(&self, input: DatabaseKeyIndex, revision: Revision) -> bool; - - /// Find the `CycleRecoveryStrategy` for a given input. - fn cycle_recovery_strategy(&self, input: DatabaseKeyIndex) -> CycleRecoveryStrategy; - - /// Executes the callback for each kind of query. - fn for_each_query(&self, op: &mut dyn FnMut(&dyn QueryStorageMassOps)); -} - -/// Internal operations performed on the query storage as a whole -/// (note that these ops do not need to know the identity of the -/// query, unlike `QueryStorageOps`). -pub trait QueryStorageMassOps { - fn purge(&self); -} - -pub trait DatabaseKey: Clone + Debug + Eq + Hash {} - -pub trait QueryFunction: Query { - /// See `CycleRecoveryStrategy` - const CYCLE_STRATEGY: CycleRecoveryStrategy; - - fn execute(db: &>::DynDb, key: Self::Key) -> Self::Value; - - fn cycle_fallback( - db: &>::DynDb, - cycle: &Cycle, - key: &Self::Key, - ) -> Self::Value { - let _ = (db, cycle, key); - panic!("query `{:?}` doesn't support cycle fallback", Self::default()) - } -} - -/// Cycle recovery strategy: Is this query capable of recovering from -/// a cycle that results from executing the function? If so, how? -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum CycleRecoveryStrategy { - /// Cannot recover from cycles: panic. - /// - /// This is the default. It is also what happens if a cycle - /// occurs and the queries involved have different recovery - /// strategies. - /// - /// In the case of a failure due to a cycle, the panic - /// value will be XXX (FIXME). - Panic, - - /// Recovers from cycles by storing a sentinel value. - /// - /// This value is computed by the `QueryFunction::cycle_fallback` - /// function. - Fallback, -} - -/// Create a query table, which has access to the storage for the query -/// and offers methods like `get`. -pub fn get_query_table<'me, Q>(db: &'me >::DynDb) -> QueryTable<'me, Q> -where - Q: Query + 'me, - Q::Storage: QueryStorageOps, -{ - let group_storage: &Q::GroupStorage = HasQueryGroup::group_storage(db); - let query_storage: &Q::Storage = Q::query_storage(group_storage); - QueryTable::new(db, query_storage) -} - -/// Create a mutable query table, which has access to the storage -/// for the query and offers methods like `set`. -pub fn get_query_table_mut<'me, Q>(db: &'me mut >::DynDb) -> QueryTableMut<'me, Q> -where - Q: Query, -{ - let (group_storage, runtime) = HasQueryGroup::group_storage_mut(db); - let query_storage = Q::query_storage_mut(group_storage); - QueryTableMut::new(runtime, &**query_storage) -} - -pub trait QueryGroup: Sized { - type GroupStorage; - - /// Dyn version of the associated database trait. - type DynDb: ?Sized + Database + HasQueryGroup; -} - -/// Trait implemented by a database for each group that it supports. -/// `S` and `K` are the types for *group storage* and *group key*, respectively. -pub trait HasQueryGroup: Database -where - G: QueryGroup, -{ - /// Access the group storage struct from the database. - fn group_storage(&self) -> &G::GroupStorage; - - /// Access the group storage struct from the database. - /// Also returns a ref to the `Runtime`, since otherwise - /// the database is borrowed and one cannot get access to it. - fn group_storage_mut(&mut self) -> (&G::GroupStorage, &mut Runtime); -} - -// ANCHOR:QueryStorageOps -pub trait QueryStorageOps -where - Self: QueryStorageMassOps, - Q: Query, -{ - // ANCHOR_END:QueryStorageOps - - /// See CycleRecoveryStrategy - const CYCLE_STRATEGY: CycleRecoveryStrategy; - - fn new(group_index: u16) -> Self; - - /// Format a database key index in a suitable way. - fn fmt_index( - &self, - db: &>::DynDb, - index: u32, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result; - - // ANCHOR:maybe_changed_after - /// True if the value of `input`, which must be from this query, may have - /// changed after the given revision ended. - /// - /// This function should only be invoked with a revision less than the current - /// revision. - fn maybe_changed_after( - &self, - db: &>::DynDb, - index: u32, - revision: Revision, - ) -> bool; - // ANCHOR_END:maybe_changed_after - - fn cycle_recovery_strategy(&self) -> CycleRecoveryStrategy { - Self::CYCLE_STRATEGY - } - - // ANCHOR:fetch - /// Execute the query, returning the result (often, the result - /// will be memoized). This is the "main method" for - /// queries. - /// - /// Returns `Err` in the event of a cycle, meaning that computing - /// the value for this `key` is recursively attempting to fetch - /// itself. - fn fetch(&self, db: &>::DynDb, key: &Q::Key) -> Q::Value; - // ANCHOR_END:fetch - - /// Returns the durability associated with a given key. - fn durability(&self, db: &>::DynDb, key: &Q::Key) -> Durability; - - /// Get the (current) set of the entries in the query storage - fn entries(&self, db: &>::DynDb) -> C - where - C: std::iter::FromIterator>; -} - -/// An optional trait that is implemented for "user mutable" storage: -/// that is, storage whose value is not derived from other storage but -/// is set independently. -pub trait InputQueryStorageOps -where - Q: Query, -{ - fn set(&self, runtime: &mut Runtime, key: &Q::Key, new_value: Q::Value, durability: Durability); -} - -/// An optional trait that is implemented for "user mutable" storage: -/// that is, storage whose value is not derived from other storage but -/// is set independently. -pub trait LruQueryStorageOps { - fn set_lru_capacity(&self, new_capacity: u16); -} - -pub trait DerivedQueryStorageOps -where - Q: Query, -{ - fn invalidate(&self, runtime: &mut Runtime, key: &S) - where - S: Eq + Hash, - Q::Key: Borrow; -} - -pub type CycleParticipants = Arc>; diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/revision.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/revision.rs deleted file mode 100644 index 7f4c333fb1995..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/revision.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std::num::NonZeroU32; -use std::sync::atomic::{AtomicU32, Ordering}; - -/// Value of the initial revision, as a u32. We don't use 0 -/// because we want to use a `NonZeroU32`. -const START: u32 = 1; - -/// A unique identifier for the current version of the database; each -/// time an input is changed, the revision number is incremented. -/// `Revision` is used internally to track which values may need to be -/// recomputed, but is not something you should have to interact with -/// directly as a user of salsa. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct Revision { - generation: NonZeroU32, -} - -impl Revision { - pub(crate) fn start() -> Self { - Self::from(START) - } - - pub(crate) fn from(g: u32) -> Self { - Self { generation: NonZeroU32::new(g).unwrap() } - } - - pub(crate) fn next(self) -> Revision { - Self::from(self.generation.get() + 1) - } - - fn as_u32(self) -> u32 { - self.generation.get() - } -} - -impl std::fmt::Debug for Revision { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(fmt, "R{}", self.generation) - } -} - -#[derive(Debug)] -pub(crate) struct AtomicRevision { - data: AtomicU32, -} - -impl AtomicRevision { - pub(crate) const fn start() -> Self { - Self { data: AtomicU32::new(START) } - } - - pub(crate) fn load(&self) -> Revision { - Revision::from(self.data.load(Ordering::SeqCst)) - } - - pub(crate) fn store(&self, r: Revision) { - self.data.store(r.as_u32(), Ordering::SeqCst); - } - - /// Increment by 1, returning previous value. - pub(crate) fn fetch_then_increment(&self) -> Revision { - let v = self.data.fetch_add(1, Ordering::SeqCst); - assert!(v != u32::MAX, "revision overflow"); - Revision::from(v) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/runtime.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/runtime.rs deleted file mode 100644 index cb16ba0044dfd..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/runtime.rs +++ /dev/null @@ -1,668 +0,0 @@ -use crate::durability::Durability; -use crate::hash::FxIndexSet; -use crate::plumbing::CycleRecoveryStrategy; -use crate::revision::{AtomicRevision, Revision}; -use crate::{Cancelled, Cycle, Database, DatabaseKeyIndex, Event, EventKind}; -use itertools::Itertools; -use parking_lot::lock_api::{RawRwLock, RawRwLockRecursive}; -use parking_lot::{Mutex, RwLock}; -use std::hash::Hash; -use std::panic::panic_any; -use std::sync::atomic::{AtomicU32, Ordering}; -use tracing::trace; -use triomphe::{Arc, ThinArc}; - -mod dependency_graph; -use dependency_graph::DependencyGraph; - -pub(crate) mod local_state; -use local_state::LocalState; - -use self::local_state::{ActiveQueryGuard, QueryRevisions}; - -/// The salsa runtime stores the storage for all queries as well as -/// tracking the query stack and dependencies between cycles. -/// -/// Each new runtime you create (e.g., via `Runtime::new` or -/// `Runtime::default`) will have an independent set of query storage -/// associated with it. Normally, therefore, you only do this once, at -/// the start of your application. -pub struct Runtime { - /// Our unique runtime id. - id: RuntimeId, - - /// If this is a "forked" runtime, then the `revision_guard` will - /// be `Some`; this guard holds a read-lock on the global query - /// lock. - revision_guard: Option, - - /// Local state that is specific to this runtime (thread). - local_state: LocalState, - - /// Shared state that is accessible via all runtimes. - shared_state: Arc, -} - -#[derive(Clone, Debug)] -pub(crate) enum WaitResult { - Completed, - Panicked, - Cycle(Cycle), -} - -impl Default for Runtime { - fn default() -> Self { - Runtime { - id: RuntimeId { counter: 0 }, - revision_guard: None, - shared_state: Default::default(), - local_state: Default::default(), - } - } -} - -impl std::fmt::Debug for Runtime { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fmt.debug_struct("Runtime") - .field("id", &self.id()) - .field("forked", &self.revision_guard.is_some()) - .field("shared_state", &self.shared_state) - .finish() - } -} - -impl Runtime { - /// Create a new runtime; equivalent to `Self::default`. This is - /// used when creating a new database. - pub fn new() -> Self { - Self::default() - } - - /// See [`crate::storage::Storage::snapshot`]. - pub(crate) fn snapshot(&self) -> Self { - if self.local_state.query_in_progress() { - panic!("it is not legal to `snapshot` during a query (see salsa-rs/salsa#80)"); - } - - let revision_guard = RevisionGuard::new(&self.shared_state); - - let id = RuntimeId { counter: self.shared_state.next_id.fetch_add(1, Ordering::SeqCst) }; - - Runtime { - id, - revision_guard: Some(revision_guard), - shared_state: self.shared_state.clone(), - local_state: Default::default(), - } - } - - /// A "synthetic write" causes the system to act *as though* some - /// input of durability `durability` has changed. This is mostly - /// useful for profiling scenarios. - /// - /// **WARNING:** Just like an ordinary write, this method triggers - /// cancellation. If you invoke it while a snapshot exists, it - /// will block until that snapshot is dropped -- if that snapshot - /// is owned by the current thread, this could trigger deadlock. - pub fn synthetic_write(&mut self, durability: Durability) { - self.with_incremented_revision(|_next_revision| Some(durability)); - } - - /// The unique identifier attached to this `SalsaRuntime`. Each - /// snapshotted runtime has a distinct identifier. - #[inline] - pub fn id(&self) -> RuntimeId { - self.id - } - - /// Returns the database-key for the query that this thread is - /// actively executing (if any). - pub fn active_query(&self) -> Option { - self.local_state.active_query() - } - - /// Read current value of the revision counter. - #[inline] - pub(crate) fn current_revision(&self) -> Revision { - self.shared_state.revisions[0].load() - } - - /// The revision in which values with durability `d` may have last - /// changed. For D0, this is just the current revision. But for - /// higher levels of durability, this value may lag behind the - /// current revision. If we encounter a value of durability Di, - /// then, we can check this function to get a "bound" on when the - /// value may have changed, which allows us to skip walking its - /// dependencies. - #[inline] - pub(crate) fn last_changed_revision(&self, d: Durability) -> Revision { - self.shared_state.revisions[d.index()].load() - } - - /// Read current value of the revision counter. - #[inline] - pub(crate) fn pending_revision(&self) -> Revision { - self.shared_state.pending_revision.load() - } - - #[cold] - pub(crate) fn unwind_cancelled(&self) { - self.report_untracked_read(); - Cancelled::PendingWrite.throw(); - } - - /// Acquires the **global query write lock** (ensuring that no queries are - /// executing) and then increments the current revision counter; invokes - /// `op` with the global query write lock still held. - /// - /// While we wait to acquire the global query write lock, this method will - /// also increment `pending_revision_increments`, thus signalling to queries - /// that their results are "cancelled" and they should abort as expeditiously - /// as possible. - /// - /// The `op` closure should actually perform the writes needed. It is given - /// the new revision as an argument, and its return value indicates whether - /// any pre-existing value was modified: - /// - /// - returning `None` means that no pre-existing value was modified (this - /// could occur e.g. when setting some key on an input that was never set - /// before) - /// - returning `Some(d)` indicates that a pre-existing value was modified - /// and it had the durability `d`. This will update the records for when - /// values with each durability were modified. - /// - /// Note that, given our writer model, we can assume that only one thread is - /// attempting to increment the global revision at a time. - pub(crate) fn with_incremented_revision(&mut self, op: F) - where - F: FnOnce(Revision) -> Option, - { - tracing::trace!("increment_revision()"); - - if !self.permits_increment() { - panic!("increment_revision invoked during a query computation"); - } - - // Set the `pending_revision` field so that people - // know current revision is cancelled. - let current_revision = self.shared_state.pending_revision.fetch_then_increment(); - - // To modify the revision, we need the lock. - let shared_state = self.shared_state.clone(); - let _lock = shared_state.query_lock.write(); - - let old_revision = self.shared_state.revisions[0].fetch_then_increment(); - assert_eq!(current_revision, old_revision); - - let new_revision = current_revision.next(); - - trace!("increment_revision: incremented to {:?}", new_revision); - - if let Some(d) = op(new_revision) { - for rev in &self.shared_state.revisions[1..=d.index()] { - rev.store(new_revision); - } - } - } - - pub(crate) fn permits_increment(&self) -> bool { - self.revision_guard.is_none() && !self.local_state.query_in_progress() - } - - #[inline] - pub(crate) fn push_query(&self, database_key_index: DatabaseKeyIndex) -> ActiveQueryGuard<'_> { - self.local_state.push_query(database_key_index) - } - - /// Reports that the currently active query read the result from - /// another query. - /// - /// Also checks whether the "cycle participant" flag is set on - /// the current stack frame -- if so, panics with `CycleParticipant` - /// value, which should be caught by the code executing the query. - /// - /// # Parameters - /// - /// - `database_key`: the query whose result was read - /// - `changed_revision`: the last revision in which the result of that - /// query had changed - pub(crate) fn report_query_read_and_unwind_if_cycle_resulted( - &self, - input: DatabaseKeyIndex, - durability: Durability, - changed_at: Revision, - ) { - self.local_state - .report_query_read_and_unwind_if_cycle_resulted(input, durability, changed_at); - } - - /// Reports that the query depends on some state unknown to salsa. - /// - /// Queries which report untracked reads will be re-executed in the next - /// revision. - pub fn report_untracked_read(&self) { - self.local_state.report_untracked_read(self.current_revision()); - } - - /// Acts as though the current query had read an input with the given durability; this will force the current query's durability to be at most `durability`. - /// - /// This is mostly useful to control the durability level for [on-demand inputs](https://salsa-rs.github.io/salsa/common_patterns/on_demand_inputs.html). - pub fn report_synthetic_read(&self, durability: Durability) { - let changed_at = self.last_changed_revision(durability); - self.local_state.report_synthetic_read(durability, changed_at); - } - - /// Handles a cycle in the dependency graph that was detected when the - /// current thread tried to block on `database_key_index` which is being - /// executed by `to_id`. If this function returns, then `to_id` no longer - /// depends on the current thread, and so we should continue executing - /// as normal. Otherwise, the function will throw a `Cycle` which is expected - /// to be caught by some frame on our stack. This occurs either if there is - /// a frame on our stack with cycle recovery (possibly the top one!) or if there - /// is no cycle recovery at all. - fn unblock_cycle_and_maybe_throw( - &self, - db: &dyn Database, - dg: &mut DependencyGraph, - database_key_index: DatabaseKeyIndex, - to_id: RuntimeId, - ) { - trace!("unblock_cycle_and_maybe_throw(database_key={:?})", database_key_index); - - let mut from_stack = self.local_state.take_query_stack(); - let from_id = self.id(); - - // Make a "dummy stack frame". As we iterate through the cycle, we will collect the - // inputs from each participant. Then, if we are participating in cycle recovery, we - // will propagate those results to all participants. - let mut cycle_query = ActiveQuery::new(database_key_index); - - // Identify the cycle participants: - let cycle = { - let mut v = vec![]; - dg.for_each_cycle_participant( - from_id, - &mut from_stack, - database_key_index, - to_id, - |aqs| { - aqs.iter_mut().for_each(|aq| { - cycle_query.add_from(aq); - v.push(aq.database_key_index); - }); - }, - ); - - // We want to give the participants in a deterministic order - // (at least for this execution, not necessarily across executions), - // no matter where it started on the stack. Find the minimum - // key and rotate it to the front. - let index = v.iter().position_min().unwrap_or_default(); - v.rotate_left(index); - - // No need to store extra memory. - v.shrink_to_fit(); - - Cycle::new(Arc::new(v)) - }; - trace!("cycle {:?}, cycle_query {:#?}", cycle.debug(db), cycle_query,); - - // We can remove the cycle participants from the list of dependencies; - // they are a strongly connected component (SCC) and we only care about - // dependencies to things outside the SCC that control whether it will - // form again. - cycle_query.remove_cycle_participants(&cycle); - - // Mark each cycle participant that has recovery set, along with - // any frames that come after them on the same thread. Those frames - // are going to be unwound so that fallback can occur. - dg.for_each_cycle_participant(from_id, &mut from_stack, database_key_index, to_id, |aqs| { - aqs.iter_mut() - .skip_while(|aq| match db.cycle_recovery_strategy(aq.database_key_index) { - CycleRecoveryStrategy::Panic => true, - CycleRecoveryStrategy::Fallback => false, - }) - .for_each(|aq| { - trace!("marking {:?} for fallback", aq.database_key_index.debug(db)); - aq.take_inputs_from(&cycle_query); - assert!(aq.cycle.is_none()); - aq.cycle = Some(cycle.clone()); - }); - }); - - // Unblock every thread that has cycle recovery with a `WaitResult::Cycle`. - // They will throw the cycle, which will be caught by the frame that has - // cycle recovery so that it can execute that recovery. - let (me_recovered, others_recovered) = - dg.maybe_unblock_runtimes_in_cycle(from_id, &from_stack, database_key_index, to_id); - - self.local_state.restore_query_stack(from_stack); - - if me_recovered { - // If the current thread has recovery, we want to throw - // so that it can begin. - cycle.throw() - } else if others_recovered { - // If other threads have recovery but we didn't: return and we will block on them. - } else { - // if nobody has recover, then we panic - panic_any(cycle); - } - } - - /// Block until `other_id` completes executing `database_key`; - /// panic or unwind in the case of a cycle. - /// - /// `query_mutex_guard` is the guard for the current query's state; - /// it will be dropped after we have successfully registered the - /// dependency. - /// - /// # Propagating panics - /// - /// If the thread `other_id` panics, then our thread is considered - /// cancelled, so this function will panic with a `Cancelled` value. - /// - /// # Cycle handling - /// - /// If the thread `other_id` already depends on the current thread, - /// and hence there is a cycle in the query graph, then this function - /// will unwind instead of returning normally. The method of unwinding - /// depends on the [`Self::mutual_cycle_recovery_strategy`] - /// of the cycle participants: - /// - /// * [`CycleRecoveryStrategy::Panic`]: panic with the [`Cycle`] as the value. - /// * [`CycleRecoveryStrategy::Fallback`]: initiate unwinding with [`CycleParticipant::unwind`]. - pub(crate) fn block_on_or_unwind( - &self, - db: &dyn Database, - database_key: DatabaseKeyIndex, - other_id: RuntimeId, - query_mutex_guard: QueryMutexGuard, - ) { - let mut dg = self.shared_state.dependency_graph.lock(); - - if dg.depends_on(other_id, self.id()) { - self.unblock_cycle_and_maybe_throw(db, &mut dg, database_key, other_id); - - // If the above fn returns, then (via cycle recovery) it has unblocked the - // cycle, so we can continue. - assert!(!dg.depends_on(other_id, self.id())); - } - - db.salsa_event(Event { - runtime_id: self.id(), - kind: EventKind::WillBlockOn { other_runtime_id: other_id, database_key }, - }); - - let stack = self.local_state.take_query_stack(); - - let (stack, result) = DependencyGraph::block_on( - dg, - self.id(), - database_key, - other_id, - stack, - query_mutex_guard, - ); - - self.local_state.restore_query_stack(stack); - - match result { - WaitResult::Completed => (), - - // If the other thread panicked, then we consider this thread - // cancelled. The assumption is that the panic will be detected - // by the other thread and responded to appropriately. - WaitResult::Panicked => Cancelled::PropagatedPanic.throw(), - - WaitResult::Cycle(c) => c.throw(), - } - } - - /// Invoked when this runtime completed computing `database_key` with - /// the given result `wait_result` (`wait_result` should be `None` if - /// computing `database_key` panicked and could not complete). - /// This function unblocks any dependent queries and allows them - /// to continue executing. - pub(crate) fn unblock_queries_blocked_on( - &self, - database_key: DatabaseKeyIndex, - wait_result: WaitResult, - ) { - self.shared_state - .dependency_graph - .lock() - .unblock_runtimes_blocked_on(database_key, wait_result); - } -} - -/// State that will be common to all threads (when we support multiple threads) -struct SharedState { - /// Stores the next id to use for a snapshotted runtime (starts at 1). - next_id: AtomicU32, - - /// Whenever derived queries are executing, they acquire this lock - /// in read mode. Mutating inputs (and thus creating a new - /// revision) requires a write lock (thus guaranteeing that no - /// derived queries are in progress). Note that this is not needed - /// to prevent **race conditions** -- the revision counter itself - /// is stored in an `AtomicUsize` so it can be cheaply read - /// without acquiring the lock. Rather, the `query_lock` is used - /// to ensure a higher-level consistency property. - query_lock: RwLock<()>, - - /// This is typically equal to `revision` -- set to `revision+1` - /// when a new revision is pending (which implies that the current - /// revision is cancelled). - pending_revision: AtomicRevision, - - /// Stores the "last change" revision for values of each Durability. - /// This vector is always of length at least 1 (for Durability 0) - /// but its total length depends on the number of Durabilities. The - /// element at index 0 is special as it represents the "current - /// revision". In general, we have the invariant that revisions - /// in here are *declining* -- that is, `revisions[i] >= - /// revisions[i + 1]`, for all `i`. This is because when you - /// modify a value with durability D, that implies that values - /// with durability less than D may have changed too. - revisions: [AtomicRevision; Durability::LEN], - - /// The dependency graph tracks which runtimes are blocked on one - /// another, waiting for queries to terminate. - dependency_graph: Mutex, -} - -impl std::panic::RefUnwindSafe for SharedState {} - -impl Default for SharedState { - fn default() -> Self { - #[allow(clippy::declare_interior_mutable_const)] - const START: AtomicRevision = AtomicRevision::start(); - SharedState { - next_id: AtomicU32::new(1), - query_lock: Default::default(), - revisions: [START; Durability::LEN], - pending_revision: START, - dependency_graph: Default::default(), - } - } -} - -impl std::fmt::Debug for SharedState { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let query_lock = if self.query_lock.is_locked_exclusive() { - "" - } else if self.query_lock.is_locked() { - "" - } else { - "" - }; - fmt.debug_struct("SharedState") - .field("query_lock", &query_lock) - .field("revisions", &self.revisions) - .field("pending_revision", &self.pending_revision) - .finish() - } -} - -#[derive(Debug)] -struct ActiveQuery { - /// What query is executing - database_key_index: DatabaseKeyIndex, - - /// Minimum durability of inputs observed so far. - durability: Durability, - - /// Maximum revision of all inputs observed. If we observe an - /// untracked read, this will be set to the most recent revision. - changed_at: Revision, - - /// Set of subqueries that were accessed thus far, or `None` if - /// there was an untracked the read. - dependencies: Option>, - - /// Stores the entire cycle, if one is found and this query is part of it. - cycle: Option, -} - -impl ActiveQuery { - fn new(database_key_index: DatabaseKeyIndex) -> Self { - ActiveQuery { - database_key_index, - durability: Durability::MAX, - changed_at: Revision::start(), - dependencies: Some(FxIndexSet::default()), - cycle: None, - } - } - - fn add_read(&mut self, input: DatabaseKeyIndex, durability: Durability, revision: Revision) { - if let Some(set) = &mut self.dependencies { - set.insert(input); - } - - self.durability = self.durability.min(durability); - self.changed_at = self.changed_at.max(revision); - } - - fn add_untracked_read(&mut self, changed_at: Revision) { - self.dependencies = None; - self.durability = Durability::LOW; - self.changed_at = changed_at; - } - - fn add_synthetic_read(&mut self, durability: Durability, revision: Revision) { - self.dependencies = None; - self.durability = self.durability.min(durability); - self.changed_at = self.changed_at.max(revision); - } - - pub(crate) fn revisions(&self) -> QueryRevisions { - let (inputs, untracked) = match &self.dependencies { - None => (None, true), - - Some(dependencies) => ( - if dependencies.is_empty() { - None - } else { - Some(ThinArc::from_header_and_iter((), dependencies.iter().copied())) - }, - false, - ), - }; - - QueryRevisions { - changed_at: self.changed_at, - inputs, - untracked, - durability: self.durability, - } - } - - /// Adds any dependencies from `other` into `self`. - /// Used during cycle recovery, see [`Runtime::create_cycle_error`]. - fn add_from(&mut self, other: &ActiveQuery) { - self.changed_at = self.changed_at.max(other.changed_at); - self.durability = self.durability.min(other.durability); - if let Some(other_dependencies) = &other.dependencies { - if let Some(my_dependencies) = &mut self.dependencies { - my_dependencies.extend(other_dependencies.iter().copied()); - } - } else { - self.dependencies = None; - } - } - - /// Removes the participants in `cycle` from my dependencies. - /// Used during cycle recovery, see [`Runtime::create_cycle_error`]. - fn remove_cycle_participants(&mut self, cycle: &Cycle) { - if let Some(my_dependencies) = &mut self.dependencies { - for p in cycle.participant_keys() { - my_dependencies.swap_remove(&p); - } - } - } - - /// Copy the changed-at, durability, and dependencies from `cycle_query`. - /// Used during cycle recovery, see [`Runtime::create_cycle_error`]. - pub(crate) fn take_inputs_from(&mut self, cycle_query: &ActiveQuery) { - self.changed_at = cycle_query.changed_at; - self.durability = cycle_query.durability; - self.dependencies.clone_from(&cycle_query.dependencies); - } -} - -/// A unique identifier for a particular runtime. Each time you create -/// a snapshot, a fresh `RuntimeId` is generated. Once a snapshot is -/// complete, its `RuntimeId` may potentially be re-used. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct RuntimeId { - counter: u32, -} - -#[derive(Clone, Debug)] -pub(crate) struct StampedValue { - pub(crate) value: V, - pub(crate) durability: Durability, - pub(crate) changed_at: Revision, -} - -struct RevisionGuard { - shared_state: Arc, -} - -impl RevisionGuard { - fn new(shared_state: &Arc) -> Self { - // Subtle: we use a "recursive" lock here so that it is not an - // error to acquire a read-lock when one is already held (this - // happens when a query uses `snapshot` to spawn off parallel - // workers, for example). - // - // This has the side-effect that we are responsible to ensure - // that people contending for the write lock do not starve, - // but this is what we achieve via the cancellation mechanism. - // - // (In particular, since we only ever have one "mutating - // handle" to the database, the only contention for the global - // query lock occurs when there are "futures" evaluating - // queries in parallel, and those futures hold a read-lock - // already, so the starvation problem is more about them bring - // themselves to a close, versus preventing other people from - // *starting* work). - unsafe { - shared_state.query_lock.raw().lock_shared_recursive(); - } - - Self { shared_state: shared_state.clone() } - } -} - -impl Drop for RevisionGuard { - fn drop(&mut self) { - // Release our read-lock without using RAII. As documented in - // `Snapshot::new` above, this requires the unsafe keyword. - unsafe { - self.shared_state.query_lock.raw().unlock_shared(); - } - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/dependency_graph.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/dependency_graph.rs deleted file mode 100644 index ed1d499f63735..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/dependency_graph.rs +++ /dev/null @@ -1,250 +0,0 @@ -use triomphe::Arc; - -use crate::{DatabaseKeyIndex, RuntimeId}; -use parking_lot::{Condvar, MutexGuard}; -use rustc_hash::FxHashMap; -use smallvec::SmallVec; - -use super::{ActiveQuery, WaitResult}; - -type QueryStack = Vec; - -#[derive(Debug, Default)] -pub(super) struct DependencyGraph { - /// A `(K -> V)` pair in this map indicates that the runtime - /// `K` is blocked on some query executing in the runtime `V`. - /// This encodes a graph that must be acyclic (or else deadlock - /// will result). - edges: FxHashMap, - - /// Encodes the `RuntimeId` that are blocked waiting for the result - /// of a given query. - query_dependents: FxHashMap>, - - /// When a key K completes which had dependent queries Qs blocked on it, - /// it stores its `WaitResult` here. As they wake up, each query Q in Qs will - /// come here to fetch their results. - wait_results: FxHashMap, -} - -#[derive(Debug)] -struct Edge { - blocked_on_id: RuntimeId, - blocked_on_key: DatabaseKeyIndex, - stack: QueryStack, - - /// Signalled whenever a query with dependents completes. - /// Allows those dependents to check if they are ready to unblock. - condvar: Arc, -} - -impl DependencyGraph { - /// True if `from_id` depends on `to_id`. - /// - /// (i.e., there is a path from `from_id` to `to_id` in the graph.) - pub(super) fn depends_on(&mut self, from_id: RuntimeId, to_id: RuntimeId) -> bool { - let mut p = from_id; - while let Some(q) = self.edges.get(&p).map(|edge| edge.blocked_on_id) { - if q == to_id { - return true; - } - - p = q; - } - p == to_id - } - - /// Invokes `closure` with a `&mut ActiveQuery` for each query that participates in the cycle. - /// The cycle runs as follows: - /// - /// 1. The runtime `from_id`, which has the stack `from_stack`, would like to invoke `database_key`... - /// 2. ...but `database_key` is already being executed by `to_id`... - /// 3. ...and `to_id` is transitively dependent on something which is present on `from_stack`. - pub(super) fn for_each_cycle_participant( - &mut self, - from_id: RuntimeId, - from_stack: &mut QueryStack, - database_key: DatabaseKeyIndex, - to_id: RuntimeId, - mut closure: impl FnMut(&mut [ActiveQuery]), - ) { - debug_assert!(self.depends_on(to_id, from_id)); - - // To understand this algorithm, consider this [drawing](https://is.gd/TGLI9v): - // - // database_key = QB2 - // from_id = A - // to_id = B - // from_stack = [QA1, QA2, QA3] - // - // self.edges[B] = { C, QC2, [QB1..QB3] } - // self.edges[C] = { A, QA2, [QC1..QC3] } - // - // The cyclic - // edge we have - // failed to add. - // : - // A : B C - // : - // QA1 v QB1 QC1 - // ┌► QA2 ┌──► QB2 ┌─► QC2 - // │ QA3 ───┘ QB3 ──┘ QC3 ───┐ - // │ │ - // └───────────────────────────────┘ - // - // Final output: [QB2, QB3, QC2, QC3, QA2, QA3] - - let mut id = to_id; - let mut key = database_key; - while id != from_id { - // Looking at the diagram above, the idea is to - // take the edge from `to_id` starting at `key` - // (inclusive) and down to the end. We can then - // load up the next thread (i.e., we start at B/QB2, - // and then load up the dependency on C/QC2). - let edge = self.edges.get_mut(&id).unwrap(); - let prefix = edge.stack.iter_mut().take_while(|p| p.database_key_index != key).count(); - closure(&mut edge.stack[prefix..]); - id = edge.blocked_on_id; - key = edge.blocked_on_key; - } - - // Finally, we copy in the results from `from_stack`. - let prefix = from_stack.iter_mut().take_while(|p| p.database_key_index != key).count(); - closure(&mut from_stack[prefix..]); - } - - /// Unblock each blocked runtime (excluding the current one) if some - /// query executing in that runtime is participating in cycle fallback. - /// - /// Returns a boolean (Current, Others) where: - /// * Current is true if the current runtime has cycle participants - /// with fallback; - /// * Others is true if other runtimes were unblocked. - pub(super) fn maybe_unblock_runtimes_in_cycle( - &mut self, - from_id: RuntimeId, - from_stack: &QueryStack, - database_key: DatabaseKeyIndex, - to_id: RuntimeId, - ) -> (bool, bool) { - // See diagram in `for_each_cycle_participant`. - let mut id = to_id; - let mut key = database_key; - let mut others_unblocked = false; - while id != from_id { - let edge = self.edges.get(&id).unwrap(); - let prefix = edge.stack.iter().take_while(|p| p.database_key_index != key).count(); - let next_id = edge.blocked_on_id; - let next_key = edge.blocked_on_key; - - if let Some(cycle) = edge.stack[prefix..].iter().rev().find_map(|aq| aq.cycle.clone()) { - // Remove `id` from the list of runtimes blocked on `next_key`: - self.query_dependents.get_mut(&next_key).unwrap().retain(|r| *r != id); - - // Unblock runtime so that it can resume execution once lock is released: - self.unblock_runtime(id, WaitResult::Cycle(cycle)); - - others_unblocked = true; - } - - id = next_id; - key = next_key; - } - - let prefix = from_stack.iter().take_while(|p| p.database_key_index != key).count(); - let this_unblocked = from_stack[prefix..].iter().any(|aq| aq.cycle.is_some()); - - (this_unblocked, others_unblocked) - } - - /// Modifies the graph so that `from_id` is blocked - /// on `database_key`, which is being computed by - /// `to_id`. - /// - /// For this to be reasonable, the lock on the - /// results table for `database_key` must be held. - /// This ensures that computing `database_key` doesn't - /// complete before `block_on` executes. - /// - /// Preconditions: - /// * No path from `to_id` to `from_id` - /// (i.e., `me.depends_on(to_id, from_id)` is false) - /// * `held_mutex` is a read lock (or stronger) on `database_key` - pub(super) fn block_on( - mut me: MutexGuard<'_, Self>, - from_id: RuntimeId, - database_key: DatabaseKeyIndex, - to_id: RuntimeId, - from_stack: QueryStack, - query_mutex_guard: QueryMutexGuard, - ) -> (QueryStack, WaitResult) { - let condvar = me.add_edge(from_id, database_key, to_id, from_stack); - - // Release the mutex that prevents `database_key` - // from completing, now that the edge has been added. - drop(query_mutex_guard); - - loop { - if let Some(stack_and_result) = me.wait_results.remove(&from_id) { - debug_assert!(!me.edges.contains_key(&from_id)); - return stack_and_result; - } - condvar.wait(&mut me); - } - } - - /// Helper for `block_on`: performs actual graph modification - /// to add a dependency edge from `from_id` to `to_id`, which is - /// computing `database_key`. - fn add_edge( - &mut self, - from_id: RuntimeId, - database_key: DatabaseKeyIndex, - to_id: RuntimeId, - from_stack: QueryStack, - ) -> Arc { - assert_ne!(from_id, to_id); - debug_assert!(!self.edges.contains_key(&from_id)); - debug_assert!(!self.depends_on(to_id, from_id)); - - let condvar = Arc::new(Condvar::new()); - self.edges.insert( - from_id, - Edge { - blocked_on_id: to_id, - blocked_on_key: database_key, - stack: from_stack, - condvar: condvar.clone(), - }, - ); - self.query_dependents.entry(database_key).or_default().push(from_id); - condvar - } - - /// Invoked when runtime `to_id` completes executing - /// `database_key`. - pub(super) fn unblock_runtimes_blocked_on( - &mut self, - database_key: DatabaseKeyIndex, - wait_result: WaitResult, - ) { - let dependents = self.query_dependents.remove(&database_key).unwrap_or_default(); - - for from_id in dependents { - self.unblock_runtime(from_id, wait_result.clone()); - } - } - - /// Unblock the runtime with the given id with the given wait-result. - /// This will cause it resume execution (though it will have to grab - /// the lock on this data structure first, to recover the wait result). - fn unblock_runtime(&mut self, id: RuntimeId, wait_result: WaitResult) { - let edge = self.edges.remove(&id).expect("not blocked"); - self.wait_results.insert(id, (edge.stack, wait_result)); - - // Now that we have inserted the `wait_results`, - // notify the thread. - edge.condvar.notify_one(); - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/local_state.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/local_state.rs deleted file mode 100644 index 4ab4bad0cc508..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/local_state.rs +++ /dev/null @@ -1,204 +0,0 @@ -use tracing::trace; -use triomphe::ThinArc; - -use crate::durability::Durability; -use crate::runtime::ActiveQuery; -use crate::runtime::Revision; -use crate::Cycle; -use crate::DatabaseKeyIndex; -use std::cell::RefCell; - -/// State that is specific to a single execution thread. -/// -/// Internally, this type uses ref-cells. -/// -/// **Note also that all mutations to the database handle (and hence -/// to the local-state) must be undone during unwinding.** -pub(super) struct LocalState { - /// Vector of active queries. - /// - /// This is normally `Some`, but it is set to `None` - /// while the query is blocked waiting for a result. - /// - /// Unwinding note: pushes onto this vector must be popped -- even - /// during unwinding. - query_stack: RefCell>>, -} - -/// Summarizes "all the inputs that a query used" -#[derive(Debug, Clone)] -pub(crate) struct QueryRevisions { - /// The most revision in which some input changed. - pub(crate) changed_at: Revision, - - /// Minimum durability of the inputs to this query. - pub(crate) durability: Durability, - - /// Whether the input is untracked. - /// Invariant: if `untracked`, `inputs` is `None`. - /// Why is this encoded like this and not a proper enum? Struct size, this saves us 8 bytes. - pub(crate) untracked: bool, - - /// The inputs that went into our query, if we are tracking them. - pub(crate) inputs: Option>, -} - -impl Default for LocalState { - fn default() -> Self { - LocalState { query_stack: RefCell::new(Some(Vec::new())) } - } -} - -impl LocalState { - #[inline] - pub(super) fn push_query(&self, database_key_index: DatabaseKeyIndex) -> ActiveQueryGuard<'_> { - let mut query_stack = self.query_stack.borrow_mut(); - let query_stack = query_stack.as_mut().expect("local stack taken"); - query_stack.push(ActiveQuery::new(database_key_index)); - ActiveQueryGuard { local_state: self, database_key_index, push_len: query_stack.len() } - } - - fn with_query_stack(&self, c: impl FnOnce(&mut Vec) -> R) -> R { - c(self.query_stack.borrow_mut().as_mut().expect("query stack taken")) - } - - pub(super) fn query_in_progress(&self) -> bool { - self.with_query_stack(|stack| !stack.is_empty()) - } - - pub(super) fn active_query(&self) -> Option { - self.with_query_stack(|stack| { - stack.last().map(|active_query| active_query.database_key_index) - }) - } - - pub(super) fn report_query_read_and_unwind_if_cycle_resulted( - &self, - input: DatabaseKeyIndex, - durability: Durability, - changed_at: Revision, - ) { - trace!( - "report_query_read_and_unwind_if_cycle_resulted(input={:?}, durability={:?}, changed_at={:?})", - input, durability, changed_at - ); - self.with_query_stack(|stack| { - if let Some(top_query) = stack.last_mut() { - top_query.add_read(input, durability, changed_at); - - // We are a cycle participant: - // - // C0 --> ... --> Ci --> Ci+1 -> ... -> Cn --> C0 - // ^ ^ - // : | - // This edge -----+ | - // | - // | - // N0 - // - // In this case, the value we have just read from `Ci+1` - // is actually the cycle fallback value and not especially - // interesting. We unwind now with `CycleParticipant` to avoid - // executing the rest of our query function. This unwinding - // will be caught and our own fallback value will be used. - // - // Note that `Ci+1` may` have *other* callers who are not - // participants in the cycle (e.g., N0 in the graph above). - // They will not have the `cycle` marker set in their - // stack frames, so they will just read the fallback value - // from `Ci+1` and continue on their merry way. - if let Some(cycle) = &top_query.cycle { - cycle.clone().throw() - } - } - }) - } - - pub(super) fn report_untracked_read(&self, current_revision: Revision) { - self.with_query_stack(|stack| { - if let Some(top_query) = stack.last_mut() { - top_query.add_untracked_read(current_revision); - } - }) - } - - /// Update the top query on the stack to act as though it read a value - /// of durability `durability` which changed in `revision`. - pub(super) fn report_synthetic_read(&self, durability: Durability, revision: Revision) { - self.with_query_stack(|stack| { - if let Some(top_query) = stack.last_mut() { - top_query.add_synthetic_read(durability, revision); - } - }) - } - - /// Takes the query stack and returns it. This is used when - /// the current thread is blocking. The stack must be restored - /// with [`Self::restore_query_stack`] when the thread unblocks. - pub(super) fn take_query_stack(&self) -> Vec { - self.query_stack.take().expect("query stack already taken") - } - - /// Restores a query stack taken with [`Self::take_query_stack`] once - /// the thread unblocks. - pub(super) fn restore_query_stack(&self, stack: Vec) { - assert!(self.query_stack.borrow().is_none(), "query stack not taken"); - self.query_stack.replace(Some(stack)); - } -} - -impl std::panic::RefUnwindSafe for LocalState {} - -/// When a query is pushed onto the `active_query` stack, this guard -/// is returned to represent its slot. The guard can be used to pop -/// the query from the stack -- in the case of unwinding, the guard's -/// destructor will also remove the query. -pub(crate) struct ActiveQueryGuard<'me> { - local_state: &'me LocalState, - push_len: usize, - database_key_index: DatabaseKeyIndex, -} - -impl ActiveQueryGuard<'_> { - fn pop_helper(&self) -> ActiveQuery { - self.local_state.with_query_stack(|stack| { - // Sanity check: pushes and pops should be balanced. - assert_eq!(stack.len(), self.push_len); - debug_assert_eq!(stack.last().unwrap().database_key_index, self.database_key_index); - stack.pop().unwrap() - }) - } - - /// Invoked when the query has successfully completed execution. - pub(super) fn complete(self) -> ActiveQuery { - let query = self.pop_helper(); - std::mem::forget(self); - query - } - - /// Pops an active query from the stack. Returns the [`QueryRevisions`] - /// which summarizes the other queries that were accessed during this - /// query's execution. - #[inline] - pub(crate) fn pop(self) -> QueryRevisions { - // Extract accumulated inputs. - let popped_query = self.complete(); - - // If this frame were a cycle participant, it would have unwound. - assert!(popped_query.cycle.is_none()); - - popped_query.revisions() - } - - /// If the active query is registered as a cycle participant, remove and - /// return that cycle. - pub(crate) fn take_cycle(&self) -> Option { - self.local_state.with_query_stack(|stack| stack.last_mut()?.cycle.take()) - } -} - -impl Drop for ActiveQueryGuard<'_> { - fn drop(&mut self) { - self.pop_helper(); - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/storage.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/storage.rs deleted file mode 100644 index e0acf44041b49..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/storage.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::{plumbing::DatabaseStorageTypes, Runtime}; -use triomphe::Arc; - -/// Stores the cached results and dependency information for all the queries -/// defined on your salsa database. Also embeds a [`Runtime`] which is used to -/// manage query execution. Every database must include a `storage: -/// Storage` field. -pub struct Storage { - query_store: Arc, - runtime: Runtime, -} - -impl Default for Storage { - fn default() -> Self { - Self { query_store: Default::default(), runtime: Default::default() } - } -} - -impl Storage { - /// Gives access to the underlying salsa runtime. - pub fn salsa_runtime(&self) -> &Runtime { - &self.runtime - } - - /// Gives access to the underlying salsa runtime. - pub fn salsa_runtime_mut(&mut self) -> &mut Runtime { - &mut self.runtime - } - - /// Access the query storage tables. Not meant to be used directly by end - /// users. - pub fn query_store(&self) -> &DB::DatabaseStorage { - &self.query_store - } - - /// Access the query storage tables. Not meant to be used directly by end - /// users. - pub fn query_store_mut(&mut self) -> (&DB::DatabaseStorage, &mut Runtime) { - (&self.query_store, &mut self.runtime) - } - - /// Returns a "snapshotted" storage, suitable for use in a forked database. - /// This snapshot hold a read-lock on the global state, which means that any - /// attempt to `set` an input will block until the forked runtime is - /// dropped. See `ParallelDatabase::snapshot` for more information. - /// - /// **Warning.** This second handle is intended to be used from a separate - /// thread. Using two database handles from the **same thread** can lead to - /// deadlock. - pub fn snapshot(&self) -> Self { - Storage { query_store: self.query_store.clone(), runtime: self.runtime.snapshot() } - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs deleted file mode 100644 index 3c3931e658538..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs +++ /dev/null @@ -1,492 +0,0 @@ -use std::panic::UnwindSafe; - -use expect_test::expect; -use ra_salsa::{Durability, ParallelDatabase, Snapshot}; - -// Axes: -// -// Threading -// * Intra-thread -// * Cross-thread -- part of cycle is on one thread, part on another -// -// Recovery strategies: -// * Panic -// * Fallback -// * Mixed -- multiple strategies within cycle participants -// -// Across revisions: -// * N/A -- only one revision -// * Present in new revision, not old -// * Present in old revision, not new -// * Present in both revisions -// -// Dependencies -// * Tracked -// * Untracked -- cycle participant(s) contain untracked reads -// -// Layers -// * Direct -- cycle participant is directly invoked from test -// * Indirect -- invoked a query that invokes the cycle -// -// -// | Thread | Recovery | Old, New | Dep style | Layers | Test Name | -// | ------ | -------- | -------- | --------- | ------ | --------- | -// | Intra | Panic | N/A | Tracked | direct | cycle_memoized | -// | Intra | Panic | N/A | Untracked | direct | cycle_volatile | -// | Intra | Fallback | N/A | Tracked | direct | cycle_cycle | -// | Intra | Fallback | N/A | Tracked | indirect | inner_cycle | -// | Intra | Fallback | Both | Tracked | direct | cycle_revalidate | -// | Intra | Fallback | New | Tracked | direct | cycle_appears | -// | Intra | Fallback | Old | Tracked | direct | cycle_disappears | -// | Intra | Fallback | Old | Tracked | direct | cycle_disappears_durability | -// | Intra | Mixed | N/A | Tracked | direct | cycle_mixed_1 | -// | Intra | Mixed | N/A | Tracked | direct | cycle_mixed_2 | -// | Cross | Fallback | N/A | Tracked | both | parallel/cycles.rs: recover_parallel_cycle | -// | Cross | Panic | N/A | Tracked | both | parallel/cycles.rs: panic_parallel_cycle | - -#[derive(PartialEq, Eq, Hash, Clone, Debug)] -struct Error { - cycle: Vec, -} - -#[ra_salsa::database(GroupStruct)] -#[derive(Default)] -struct DatabaseImpl { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for DatabaseImpl {} - -impl ParallelDatabase for DatabaseImpl { - fn snapshot(&self) -> Snapshot { - Snapshot::new(DatabaseImpl { storage: self.storage.snapshot() }) - } -} - -/// The queries A, B, and C in `Database` can be configured -/// to invoke one another in arbitrary ways using this -/// enum. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -enum CycleQuery { - None, - A, - B, - C, - AthenC, -} - -#[ra_salsa::query_group(GroupStruct)] -trait Database: ra_salsa::Database { - // `a` and `b` depend on each other and form a cycle - fn memoized_a(&self) -> (); - fn memoized_b(&self) -> (); - fn volatile_a(&self) -> (); - fn volatile_b(&self) -> (); - - #[ra_salsa::input] - fn a_invokes(&self) -> CycleQuery; - - #[ra_salsa::input] - fn b_invokes(&self) -> CycleQuery; - - #[ra_salsa::input] - fn c_invokes(&self) -> CycleQuery; - - #[ra_salsa::cycle(recover_a)] - fn cycle_a(&self) -> Result<(), Error>; - - #[ra_salsa::cycle(recover_b)] - fn cycle_b(&self) -> Result<(), Error>; - - fn cycle_c(&self) -> Result<(), Error>; -} - -fn recover_a(db: &dyn Database, cycle: &ra_salsa::Cycle) -> Result<(), Error> { - Err(Error { cycle: cycle.all_participants(db) }) -} - -fn recover_b(db: &dyn Database, cycle: &ra_salsa::Cycle) -> Result<(), Error> { - Err(Error { cycle: cycle.all_participants(db) }) -} - -fn memoized_a(db: &dyn Database) { - db.memoized_b() -} - -fn memoized_b(db: &dyn Database) { - db.memoized_a() -} - -fn volatile_a(db: &dyn Database) { - db.salsa_runtime().report_untracked_read(); - db.volatile_b() -} - -fn volatile_b(db: &dyn Database) { - db.salsa_runtime().report_untracked_read(); - db.volatile_a() -} - -impl CycleQuery { - fn invoke(self, db: &dyn Database) -> Result<(), Error> { - match self { - CycleQuery::A => db.cycle_a(), - CycleQuery::B => db.cycle_b(), - CycleQuery::C => db.cycle_c(), - CycleQuery::AthenC => { - let _ = db.cycle_a(); - db.cycle_c() - } - CycleQuery::None => Ok(()), - } - } -} - -fn cycle_a(db: &dyn Database) -> Result<(), Error> { - db.a_invokes().invoke(db) -} - -fn cycle_b(db: &dyn Database) -> Result<(), Error> { - db.b_invokes().invoke(db) -} - -fn cycle_c(db: &dyn Database) -> Result<(), Error> { - db.c_invokes().invoke(db) -} - -#[track_caller] -fn extract_cycle(f: impl FnOnce() + UnwindSafe) -> ra_salsa::Cycle { - let v = std::panic::catch_unwind(f); - if let Err(d) = &v { - if let Some(cycle) = d.downcast_ref::() { - return cycle.clone(); - } - } - panic!("unexpected value: {v:?}") -} - -#[test] -fn cycle_memoized() { - let db = DatabaseImpl::default(); - let cycle = extract_cycle(|| db.memoized_a()); - expect![[r#" - [ - "cycles::MemoizedAQuery::memoized_a(())", - "cycles::MemoizedBQuery::memoized_b(())", - ] - "#]] - .assert_debug_eq(&cycle.unexpected_participants(&db)); -} - -#[test] -fn cycle_volatile() { - let db = DatabaseImpl::default(); - let cycle = extract_cycle(|| db.volatile_a()); - expect![[r#" - [ - "cycles::VolatileAQuery::volatile_a(())", - "cycles::VolatileBQuery::volatile_b(())", - ] - "#]] - .assert_debug_eq(&cycle.unexpected_participants(&db)); -} - -#[test] -fn cycle_cycle() { - let mut query = DatabaseImpl::default(); - - // A --> B - // ^ | - // +-----+ - - query.set_a_invokes(CycleQuery::B); - query.set_b_invokes(CycleQuery::A); - - assert!(query.cycle_a().is_err()); -} - -#[test] -fn inner_cycle() { - let mut query = DatabaseImpl::default(); - - // A --> B <-- C - // ^ | - // +-----+ - - query.set_a_invokes(CycleQuery::B); - query.set_b_invokes(CycleQuery::A); - query.set_c_invokes(CycleQuery::B); - - let err = query.cycle_c(); - assert!(err.is_err()); - let cycle = err.unwrap_err().cycle; - expect![[r#" - [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - ] - "#]] - .assert_debug_eq(&cycle); -} - -#[test] -fn cycle_revalidate() { - let mut db = DatabaseImpl::default(); - - // A --> B - // ^ | - // +-----+ - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::A); - - assert!(db.cycle_a().is_err()); - db.set_b_invokes(CycleQuery::A); // same value as default - assert!(db.cycle_a().is_err()); -} - -#[test] -fn cycle_revalidate_unchanged_twice() { - let mut db = DatabaseImpl::default(); - - // A --> B - // ^ | - // +-----+ - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::A); - - assert!(db.cycle_a().is_err()); - db.set_c_invokes(CycleQuery::A); // force new revision - - // on this run - expect![[r#" - Err( - Error { - cycle: [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - ], - }, - ) - "#]] - .assert_debug_eq(&db.cycle_a()); -} - -#[test] -fn cycle_appears() { - let mut db = DatabaseImpl::default(); - - // A --> B - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::None); - assert!(db.cycle_a().is_ok()); - - // A --> B - // ^ | - // +-----+ - db.set_b_invokes(CycleQuery::A); - tracing::debug!("Set Cycle Leaf"); - assert!(db.cycle_a().is_err()); -} - -#[test] -fn cycle_disappears() { - let mut db = DatabaseImpl::default(); - - // A --> B - // ^ | - // +-----+ - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::A); - assert!(db.cycle_a().is_err()); - - // A --> B - db.set_b_invokes(CycleQuery::None); - assert!(db.cycle_a().is_ok()); -} - -/// A variant on `cycle_disappears` in which the values of -/// `a_invokes` and `b_invokes` are set with durability values. -/// If we are not careful, this could cause us to overlook -/// the fact that the cycle will no longer occur. -#[test] -fn cycle_disappears_durability() { - let mut db = DatabaseImpl::default(); - db.set_a_invokes_with_durability(CycleQuery::B, Durability::LOW); - db.set_b_invokes_with_durability(CycleQuery::A, Durability::HIGH); - - let res = db.cycle_a(); - assert!(res.is_err()); - - // At this point, `a` read `LOW` input, and `b` read `HIGH` input. However, - // because `b` participates in the same cycle as `a`, its final durability - // should be `LOW`. - // - // Check that setting a `LOW` input causes us to re-execute `b` query, and - // observe that the cycle goes away. - db.set_a_invokes_with_durability(CycleQuery::None, Durability::LOW); - - let res = db.cycle_b(); - assert!(res.is_ok()); -} - -#[test] -fn cycle_mixed_1() { - let mut db = DatabaseImpl::default(); - // A --> B <-- C - // | ^ - // +-----+ - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::C); - db.set_c_invokes(CycleQuery::B); - - let u = db.cycle_c(); - expect![[r#" - Err( - Error { - cycle: [ - "cycles::CycleBQuery::cycle_b(())", - "cycles::CycleCQuery::cycle_c(())", - ], - }, - ) - "#]] - .assert_debug_eq(&u); -} - -#[test] -fn cycle_mixed_2() { - let mut db = DatabaseImpl::default(); - - // Configuration: - // - // A --> B --> C - // ^ | - // +-----------+ - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::C); - db.set_c_invokes(CycleQuery::A); - - let u = db.cycle_a(); - expect![[r#" - Err( - Error { - cycle: [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - "cycles::CycleCQuery::cycle_c(())", - ], - }, - ) - "#]] - .assert_debug_eq(&u); -} - -#[test] -fn cycle_deterministic_order() { - // No matter whether we start from A or B, we get the same set of participants: - let db = || { - let mut db = DatabaseImpl::default(); - // A --> B - // ^ | - // +-----+ - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::A); - db - }; - let a = db().cycle_a(); - let b = db().cycle_b(); - expect![[r#" - ( - Err( - Error { - cycle: [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - ], - }, - ), - Err( - Error { - cycle: [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - ], - }, - ), - ) - "#]] - .assert_debug_eq(&(a, b)); -} - -#[test] -fn cycle_multiple() { - // No matter whether we start from A or B, we get the same set of participants: - let mut db = DatabaseImpl::default(); - - // Configuration: - // - // A --> B <-- C - // ^ | ^ - // +-----+ | - // | | - // +-----+ - // - // Here, conceptually, B encounters a cycle with A and then - // recovers. - db.set_a_invokes(CycleQuery::B); - db.set_b_invokes(CycleQuery::AthenC); - db.set_c_invokes(CycleQuery::B); - - let c = db.cycle_c(); - let b = db.cycle_b(); - let a = db.cycle_a(); - expect![[r#" - ( - Err( - Error { - cycle: [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - ], - }, - ), - Err( - Error { - cycle: [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - ], - }, - ), - Err( - Error { - cycle: [ - "cycles::CycleAQuery::cycle_a(())", - "cycles::CycleBQuery::cycle_b(())", - ], - }, - ), - ) - "#]] - .assert_debug_eq(&(a, b, c)); -} - -#[test] -fn cycle_recovery_set_but_not_participating() { - let mut db = DatabaseImpl::default(); - - // A --> C -+ - // ^ | - // +--+ - db.set_a_invokes(CycleQuery::C); - db.set_c_invokes(CycleQuery::C); - - // Here we expect C to panic and A not to recover: - let r = extract_cycle(|| drop(db.cycle_a())); - expect![[r#" - [ - "cycles::CycleCQuery::cycle_c(())", - ] - "#]] - .assert_debug_eq(&r.all_participants(&db)); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/dyn_trait.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/dyn_trait.rs deleted file mode 100644 index 6075ae5c11e32..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/dyn_trait.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! Test that you can implement a query using a `dyn Trait` setup. - -#[ra_salsa::database(DynTraitStorage)] -#[derive(Default)] -struct DynTraitDatabase { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for DynTraitDatabase {} - -#[ra_salsa::query_group(DynTraitStorage)] -trait DynTrait { - #[ra_salsa::input] - fn input(&self, x: u32) -> u32; - - fn output(&self, x: u32) -> u32; -} - -fn output(db: &dyn DynTrait, x: u32) -> u32 { - db.input(x) * 2 -} - -#[test] -fn dyn_trait() { - let mut query = DynTraitDatabase::default(); - query.set_input(22, 23); - assert_eq!(query.output(22), 46); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/constants.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/constants.rs deleted file mode 100644 index 6e51545b60a15..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/constants.rs +++ /dev/null @@ -1,145 +0,0 @@ -use crate::implementation::{TestContext, TestContextImpl}; -use ra_salsa::debug::DebugQueryTable; -use ra_salsa::Durability; - -#[ra_salsa::query_group(Constants)] -pub(crate) trait ConstantsDatabase: TestContext { - #[ra_salsa::input] - fn input(&self, key: char) -> usize; - - fn add(&self, key1: char, key2: char) -> usize; - - fn add3(&self, key1: char, key2: char, key3: char) -> usize; -} - -fn add(db: &dyn ConstantsDatabase, key1: char, key2: char) -> usize { - db.log().add(format!("add({key1}, {key2})")); - db.input(key1) + db.input(key2) -} - -fn add3(db: &dyn ConstantsDatabase, key1: char, key2: char, key3: char) -> usize { - db.log().add(format!("add3({key1}, {key2}, {key3})")); - db.add(key1, key2) + db.input(key3) -} - -// Test we can assign a constant and things will be correctly -// recomputed afterwards. -#[test] -fn invalidate_constant() { - let db = &mut TestContextImpl::default(); - db.set_input_with_durability('a', 44, Durability::HIGH); - db.set_input_with_durability('b', 22, Durability::HIGH); - assert_eq!(db.add('a', 'b'), 66); - - db.set_input_with_durability('a', 66, Durability::HIGH); - assert_eq!(db.add('a', 'b'), 88); -} - -#[test] -fn invalidate_constant_1() { - let db = &mut TestContextImpl::default(); - - // Not constant: - db.set_input('a', 44); - assert_eq!(db.add('a', 'a'), 88); - - // Becomes constant: - db.set_input_with_durability('a', 44, Durability::HIGH); - assert_eq!(db.add('a', 'a'), 88); - - // Invalidates: - db.set_input_with_durability('a', 33, Durability::HIGH); - assert_eq!(db.add('a', 'a'), 66); -} - -// Test cases where we assign same value to 'a' after declaring it a -// constant. -#[test] -fn set_after_constant_same_value() { - let db = &mut TestContextImpl::default(); - db.set_input_with_durability('a', 44, Durability::HIGH); - db.set_input_with_durability('a', 44, Durability::HIGH); - db.set_input('a', 44); -} - -#[test] -fn not_constant() { - let mut db = TestContextImpl::default(); - - db.set_input('a', 22); - db.set_input('b', 44); - assert_eq!(db.add('a', 'b'), 66); - assert_eq!(Durability::LOW, AddQuery.in_db(&db).durability(('a', 'b'))); -} - -#[test] -fn durability() { - let mut db = TestContextImpl::default(); - - db.set_input_with_durability('a', 22, Durability::HIGH); - db.set_input_with_durability('b', 44, Durability::HIGH); - assert_eq!(db.add('a', 'b'), 66); - assert_eq!(Durability::HIGH, AddQuery.in_db(&db).durability(('a', 'b'))); -} - -#[test] -fn mixed_constant() { - let mut db = TestContextImpl::default(); - - db.set_input_with_durability('a', 22, Durability::HIGH); - db.set_input('b', 44); - assert_eq!(db.add('a', 'b'), 66); - assert_eq!(Durability::LOW, AddQuery.in_db(&db).durability(('a', 'b'))); -} - -#[test] -fn becomes_constant_with_change() { - let mut db = TestContextImpl::default(); - - db.set_input('a', 22); - db.set_input('b', 44); - assert_eq!(db.add('a', 'b'), 66); - assert_eq!(Durability::LOW, AddQuery.in_db(&db).durability(('a', 'b'))); - - db.set_input_with_durability('a', 23, Durability::HIGH); - assert_eq!(db.add('a', 'b'), 67); - assert_eq!(Durability::LOW, AddQuery.in_db(&db).durability(('a', 'b'))); - - db.set_input_with_durability('b', 45, Durability::HIGH); - assert_eq!(db.add('a', 'b'), 68); - assert_eq!(Durability::HIGH, AddQuery.in_db(&db).durability(('a', 'b'))); - - db.set_input_with_durability('b', 45, Durability::MEDIUM); - assert_eq!(db.add('a', 'b'), 68); - assert_eq!(Durability::MEDIUM, AddQuery.in_db(&db).durability(('a', 'b'))); -} - -// Test a subtle case in which an input changes from constant to -// non-constant, but its value doesn't change. If we're not careful, -// this can cause us to incorrectly consider derived values as still -// being constant. -#[test] -fn constant_to_non_constant() { - let mut db = TestContextImpl::default(); - - db.set_input_with_durability('a', 11, Durability::HIGH); - db.set_input_with_durability('b', 22, Durability::HIGH); - db.set_input_with_durability('c', 33, Durability::HIGH); - - // Here, `add3` invokes `add`, which yields 33. Both calls are - // constant. - assert_eq!(db.add3('a', 'b', 'c'), 66); - - db.set_input('a', 11); - - // Here, `add3` invokes `add`, which *still* yields 33, but which - // is no longer constant. Since value didn't change, we might - // preserve `add3` unchanged, not noticing that it is no longer - // constant. - assert_eq!(db.add3('a', 'b', 'c'), 66); - - // In that case, we would not get the correct result here, when - // 'a' changes *again*. - db.set_input('a', 22); - assert_eq!(db.add3('a', 'b', 'c'), 77); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/counter.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/counter.rs deleted file mode 100644 index c04857e24c9e8..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/counter.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::cell::Cell; - -#[derive(Default)] -pub(crate) struct Counter { - value: Cell, -} - -impl Counter { - pub(crate) fn increment(&self) -> usize { - let v = self.value.get(); - self.value.set(v + 1); - v - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/implementation.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/implementation.rs deleted file mode 100644 index e9a59c4630451..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/implementation.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::constants; -use crate::counter::Counter; -use crate::log::Log; -use crate::memoized_dep_inputs; -use crate::memoized_inputs; -use crate::memoized_volatile; - -pub(crate) trait TestContext: ra_salsa::Database { - fn clock(&self) -> &Counter; - fn log(&self) -> &Log; -} - -#[ra_salsa::database( - constants::Constants, - memoized_dep_inputs::MemoizedDepInputs, - memoized_inputs::MemoizedInputs, - memoized_volatile::MemoizedVolatile -)] -#[derive(Default)] -pub(crate) struct TestContextImpl { - storage: ra_salsa::Storage, - clock: Counter, - log: Log, -} - -impl TestContextImpl { - #[track_caller] - pub(crate) fn assert_log(&self, expected_log: &[&str]) { - let expected_text = &format!("{expected_log:#?}"); - let actual_text = &format!("{:#?}", self.log().take()); - - if expected_text == actual_text { - return; - } - - #[allow(clippy::print_stdout)] - for diff in dissimilar::diff(expected_text, actual_text) { - match diff { - dissimilar::Chunk::Delete(l) => println!("-{l}"), - dissimilar::Chunk::Equal(l) => println!(" {l}"), - dissimilar::Chunk::Insert(r) => println!("+{r}"), - } - } - - panic!("incorrect log results"); - } -} - -impl TestContext for TestContextImpl { - fn clock(&self) -> &Counter { - &self.clock - } - - fn log(&self) -> &Log { - &self.log - } -} - -impl ra_salsa::Database for TestContextImpl {} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/log.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/log.rs deleted file mode 100644 index 1ee57fe667d5f..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/log.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::cell::RefCell; - -#[derive(Default)] -pub(crate) struct Log { - data: RefCell>, -} - -impl Log { - pub(crate) fn add(&self, text: impl Into) { - self.data.borrow_mut().push(text.into()); - } - - pub(crate) fn take(&self) -> Vec { - self.data.take() - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/main.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/main.rs deleted file mode 100644 index bcd13c75f7157..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod constants; -mod counter; -mod implementation; -mod log; -mod memoized_dep_inputs; -mod memoized_inputs; -mod memoized_volatile; - -fn main() {} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_dep_inputs.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_dep_inputs.rs deleted file mode 100644 index 0043bb45745d8..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_dep_inputs.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::implementation::{TestContext, TestContextImpl}; - -#[ra_salsa::query_group(MemoizedDepInputs)] -pub(crate) trait MemoizedDepInputsContext: TestContext { - fn dep_memoized2(&self) -> usize; - fn dep_memoized1(&self) -> usize; - #[ra_salsa::dependencies] - fn dep_derived1(&self) -> usize; - #[ra_salsa::input] - fn dep_input1(&self) -> usize; - #[ra_salsa::input] - fn dep_input2(&self) -> usize; -} - -fn dep_memoized2(db: &dyn MemoizedDepInputsContext) -> usize { - db.log().add("Memoized2 invoked"); - db.dep_memoized1() -} - -fn dep_memoized1(db: &dyn MemoizedDepInputsContext) -> usize { - db.log().add("Memoized1 invoked"); - db.dep_derived1() * 2 -} - -fn dep_derived1(db: &dyn MemoizedDepInputsContext) -> usize { - db.log().add("Derived1 invoked"); - db.dep_input1() / 2 -} - -#[test] -fn revalidate() { - let db = &mut TestContextImpl::default(); - - db.set_dep_input1(0); - - // Initial run starts from Memoized2: - let v = db.dep_memoized2(); - assert_eq!(v, 0); - db.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Derived1 invoked"]); - - // After that, we first try to validate Memoized1 but wind up - // running Memoized2. Note that we don't try to validate - // Derived1, so it is invoked by Memoized1. - db.set_dep_input1(44); - let v = db.dep_memoized2(); - assert_eq!(v, 44); - db.assert_log(&["Memoized1 invoked", "Derived1 invoked", "Memoized2 invoked"]); - - // Here validation of Memoized1 succeeds so Memoized2 never runs. - db.set_dep_input1(45); - let v = db.dep_memoized2(); - assert_eq!(v, 44); - db.assert_log(&["Memoized1 invoked", "Derived1 invoked"]); - - // Here, a change to input2 doesn't affect us, so nothing runs. - db.set_dep_input2(45); - let v = db.dep_memoized2(); - assert_eq!(v, 44); - db.assert_log(&[]); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_inputs.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_inputs.rs deleted file mode 100644 index 007dc3db95a34..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_inputs.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::implementation::{TestContext, TestContextImpl}; - -#[ra_salsa::query_group(MemoizedInputs)] -pub(crate) trait MemoizedInputsContext: TestContext { - fn max(&self) -> usize; - #[ra_salsa::input] - fn input1(&self) -> usize; - #[ra_salsa::input] - fn input2(&self) -> usize; -} - -fn max(db: &dyn MemoizedInputsContext) -> usize { - db.log().add("Max invoked"); - std::cmp::max(db.input1(), db.input2()) -} - -#[test] -fn revalidate() { - let db = &mut TestContextImpl::default(); - - db.set_input1(0); - db.set_input2(0); - - let v = db.max(); - assert_eq!(v, 0); - db.assert_log(&["Max invoked"]); - - let v = db.max(); - assert_eq!(v, 0); - db.assert_log(&[]); - - db.set_input1(44); - db.assert_log(&[]); - - let v = db.max(); - assert_eq!(v, 44); - db.assert_log(&["Max invoked"]); - - let v = db.max(); - assert_eq!(v, 44); - db.assert_log(&[]); - - db.set_input1(44); - db.assert_log(&[]); - db.set_input2(66); - db.assert_log(&[]); - db.set_input1(64); - db.assert_log(&[]); - - let v = db.max(); - assert_eq!(v, 66); - db.assert_log(&["Max invoked"]); - - let v = db.max(); - assert_eq!(v, 66); - db.assert_log(&[]); -} - -/// Test that invoking `set` on an input with the same value still -/// triggers a new revision. -#[test] -fn set_after_no_change() { - let db = &mut TestContextImpl::default(); - - db.set_input2(0); - - db.set_input1(44); - let v = db.max(); - assert_eq!(v, 44); - db.assert_log(&["Max invoked"]); - - db.set_input1(44); - let v = db.max(); - assert_eq!(v, 44); - db.assert_log(&["Max invoked"]); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_volatile.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_volatile.rs deleted file mode 100644 index cd00cc2e6ccb6..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_volatile.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::implementation::{TestContext, TestContextImpl}; -use ra_salsa::{Database, Durability}; - -#[ra_salsa::query_group(MemoizedVolatile)] -pub(crate) trait MemoizedVolatileContext: TestContext { - // Queries for testing a "volatile" value wrapped by - // memoization. - fn memoized2(&self) -> usize; - fn memoized1(&self) -> usize; - fn volatile(&self) -> usize; -} - -fn memoized2(db: &dyn MemoizedVolatileContext) -> usize { - db.log().add("Memoized2 invoked"); - db.memoized1() -} - -fn memoized1(db: &dyn MemoizedVolatileContext) -> usize { - db.log().add("Memoized1 invoked"); - let v = db.volatile(); - v / 2 -} - -fn volatile(db: &dyn MemoizedVolatileContext) -> usize { - db.log().add("Volatile invoked"); - db.salsa_runtime().report_untracked_read(); - db.clock().increment() -} - -#[test] -fn volatile_x2() { - let query = TestContextImpl::default(); - - // Invoking volatile twice doesn't execute twice, because volatile - // queries are memoized by default. - query.volatile(); - query.volatile(); - query.assert_log(&["Volatile invoked"]); -} - -/// Test that: -/// -/// - On the first run of R0, we recompute everything. -/// - On the second run of R1, we recompute nothing. -/// - On the first run of R1, we recompute Memoized1 but not Memoized2 (since Memoized1 result -/// did not change). -/// - On the second run of R1, we recompute nothing. -/// - On the first run of R2, we recompute everything (since Memoized1 result *did* change). -#[test] -fn revalidate() { - let mut query = TestContextImpl::default(); - - query.memoized2(); - query.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Volatile invoked"]); - - query.memoized2(); - query.assert_log(&[]); - - // Second generation: volatile will change (to 1) but memoized1 - // will not (still 0, as 1/2 = 0) - query.synthetic_write(Durability::LOW); - query.memoized2(); - query.assert_log(&["Volatile invoked", "Memoized1 invoked"]); - query.memoized2(); - query.assert_log(&[]); - - // Third generation: volatile will change (to 2) and memoized1 - // will too (to 1). Therefore, after validating that Memoized1 - // changed, we now invoke Memoized2. - query.synthetic_write(Durability::LOW); - - query.memoized2(); - query.assert_log(&["Volatile invoked", "Memoized1 invoked", "Memoized2 invoked"]); - - query.memoized2(); - query.assert_log(&[]); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/interned.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/interned.rs deleted file mode 100644 index 108b129fa3f76..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/interned.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! Test that you can implement a query using a `dyn Trait` setup. - -use ra_salsa::InternId; - -#[ra_salsa::database(InternStorage)] -#[derive(Default)] -struct Database { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for Database {} - -impl ra_salsa::ParallelDatabase for Database { - fn snapshot(&self) -> ra_salsa::Snapshot { - ra_salsa::Snapshot::new(Database { storage: self.storage.snapshot() }) - } -} - -#[ra_salsa::query_group(InternStorage)] -trait Intern { - #[ra_salsa::interned] - fn intern1(&self, x: String) -> InternId; - - #[ra_salsa::interned] - fn intern2(&self, x: String, y: String) -> InternId; - - #[ra_salsa::interned] - fn intern_key(&self, x: String) -> InternKey; -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct InternKey(InternId); - -impl ra_salsa::InternKey for InternKey { - fn from_intern_id(v: InternId) -> Self { - InternKey(v) - } - - fn as_intern_id(&self) -> InternId { - self.0 - } -} - -#[test] -fn test_intern1() { - let db = Database::default(); - let foo0 = db.intern1("foo".to_owned()); - let bar0 = db.intern1("bar".to_owned()); - let foo1 = db.intern1("foo".to_owned()); - let bar1 = db.intern1("bar".to_owned()); - - assert_eq!(foo0, foo1); - assert_eq!(bar0, bar1); - assert_ne!(foo0, bar0); - - assert_eq!("foo".to_owned(), db.lookup_intern1(foo0)); - assert_eq!("bar".to_owned(), db.lookup_intern1(bar0)); -} - -#[test] -fn test_intern2() { - let db = Database::default(); - let foo0 = db.intern2("x".to_owned(), "foo".to_owned()); - let bar0 = db.intern2("x".to_owned(), "bar".to_owned()); - let foo1 = db.intern2("x".to_owned(), "foo".to_owned()); - let bar1 = db.intern2("x".to_owned(), "bar".to_owned()); - - assert_eq!(foo0, foo1); - assert_eq!(bar0, bar1); - assert_ne!(foo0, bar0); - - assert_eq!(("x".to_owned(), "foo".to_owned()), db.lookup_intern2(foo0)); - assert_eq!(("x".to_owned(), "bar".to_owned()), db.lookup_intern2(bar0)); -} - -#[test] -fn test_intern_key() { - let db = Database::default(); - let foo0 = db.intern_key("foo".to_owned()); - let bar0 = db.intern_key("bar".to_owned()); - let foo1 = db.intern_key("foo".to_owned()); - let bar1 = db.intern_key("bar".to_owned()); - - assert_eq!(foo0, foo1); - assert_eq!(bar0, bar1); - assert_ne!(foo0, bar0); - - assert_eq!("foo".to_owned(), db.lookup_intern_key(foo0)); - assert_eq!("bar".to_owned(), db.lookup_intern_key(bar0)); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/lru.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/lru.rs deleted file mode 100644 index f351f24246868..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/lru.rs +++ /dev/null @@ -1,104 +0,0 @@ -//! Test setting LRU actually limits the number of things in the database; -use std::sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, -}; - -#[derive(Debug, PartialEq, Eq)] -struct HotPotato(u32); - -static N_POTATOES: AtomicUsize = AtomicUsize::new(0); - -impl HotPotato { - fn new(id: u32) -> HotPotato { - N_POTATOES.fetch_add(1, Ordering::SeqCst); - HotPotato(id) - } -} - -impl Drop for HotPotato { - fn drop(&mut self) { - N_POTATOES.fetch_sub(1, Ordering::SeqCst); - } -} - -#[ra_salsa::query_group(QueryGroupStorage)] -trait QueryGroup: ra_salsa::Database { - #[ra_salsa::lru] - fn get(&self, x: u32) -> Arc; - #[ra_salsa::lru] - fn get_volatile(&self, x: u32) -> usize; -} - -fn get(_db: &dyn QueryGroup, x: u32) -> Arc { - Arc::new(HotPotato::new(x)) -} - -fn get_volatile(db: &dyn QueryGroup, _x: u32) -> usize { - static COUNTER: AtomicUsize = AtomicUsize::new(0); - db.salsa_runtime().report_untracked_read(); - COUNTER.fetch_add(1, Ordering::SeqCst) -} - -#[ra_salsa::database(QueryGroupStorage)] -#[derive(Default)] -struct Database { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for Database {} - -#[test] -fn lru_works() { - let mut db = Database::default(); - GetQuery.in_db_mut(&mut db).set_lru_capacity(32); - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 0); - - for i in 0..128u32 { - let p = db.get(i); - assert_eq!(p.0, i) - } - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 32); - - for i in 0..128u32 { - let p = db.get(i); - assert_eq!(p.0, i) - } - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 32); - - GetQuery.in_db_mut(&mut db).set_lru_capacity(32); - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 32); - - GetQuery.in_db_mut(&mut db).set_lru_capacity(64); - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 32); - for i in 0..128u32 { - let p = db.get(i); - assert_eq!(p.0, i) - } - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 64); - - // Special case: setting capacity to zero disables LRU - GetQuery.in_db_mut(&mut db).set_lru_capacity(0); - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 64); - for i in 0..128u32 { - let p = db.get(i); - assert_eq!(p.0, i) - } - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 128); - - drop(db); - assert_eq!(N_POTATOES.load(Ordering::SeqCst), 0); -} - -#[test] -fn lru_doesnt_break_volatile_queries() { - let mut db = Database::default(); - GetVolatileQuery.in_db_mut(&mut db).set_lru_capacity(32); - // Here, we check that we execute each volatile query at most once, despite - // LRU. That does mean that we have more values in DB than the LRU capacity, - // but it's much better than inconsistent results from volatile queries! - for i in (0..3).flat_map(|_| 0..128usize) { - let x = db.get_volatile(i as u32); - assert_eq!(x, i) - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/macros.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/macros.rs deleted file mode 100644 index 7bb6369b500c1..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/macros.rs +++ /dev/null @@ -1,12 +0,0 @@ -#[ra_salsa::query_group(MyStruct)] -trait MyDatabase: ra_salsa::Database { - #[ra_salsa::invoke(another_module::another_name)] - fn my_query(&self, key: ()) -> (); -} - -mod another_module { - #[allow(dead_code)] - pub(crate) fn another_name(_: &dyn crate::MyDatabase, (): ()) {} -} - -fn main() {} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/no_send_sync.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/no_send_sync.rs deleted file mode 100644 index 56bd3f4a7ed18..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/no_send_sync.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::rc::Rc; - -#[ra_salsa::query_group(NoSendSyncStorage)] -trait NoSendSyncDatabase: ra_salsa::Database { - fn no_send_sync_value(&self, key: bool) -> Rc; - fn no_send_sync_key(&self, key: Rc) -> bool; -} - -fn no_send_sync_value(_db: &dyn NoSendSyncDatabase, key: bool) -> Rc { - Rc::new(key) -} - -fn no_send_sync_key(_db: &dyn NoSendSyncDatabase, key: Rc) -> bool { - *key -} - -#[ra_salsa::database(NoSendSyncStorage)] -#[derive(Default)] -struct DatabaseImpl { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for DatabaseImpl {} - -#[test] -fn no_send_sync() { - let db = DatabaseImpl::default(); - - assert_eq!(db.no_send_sync_value(true), Rc::new(true)); - assert!(!db.no_send_sync_key(Rc::new(false))); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/on_demand_inputs.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/on_demand_inputs.rs deleted file mode 100644 index 4d7832f9ba05b..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/on_demand_inputs.rs +++ /dev/null @@ -1,147 +0,0 @@ -//! Test that "on-demand" input pattern works. -//! -//! On-demand inputs are inputs computed lazily on the fly. They are simulated -//! via a b query with zero inputs, which uses `add_synthetic_read` to -//! tweak durability and `invalidate` to clear the input. - -#![allow(clippy::disallowed_types, clippy::type_complexity)] - -use std::{cell::RefCell, collections::HashMap, rc::Rc}; - -use ra_salsa::{Database as _, Durability, EventKind}; - -#[ra_salsa::query_group(QueryGroupStorage)] -trait QueryGroup: ra_salsa::Database + AsRef> { - fn a(&self, x: u32) -> u32; - fn b(&self, x: u32) -> u32; - fn c(&self, x: u32) -> u32; -} - -fn a(db: &dyn QueryGroup, x: u32) -> u32 { - let durability = if x % 2 == 0 { Durability::LOW } else { Durability::HIGH }; - db.salsa_runtime().report_synthetic_read(durability); - let external_state: &HashMap = db.as_ref(); - external_state[&x] -} - -fn b(db: &dyn QueryGroup, x: u32) -> u32 { - db.a(x) -} - -fn c(db: &dyn QueryGroup, x: u32) -> u32 { - db.b(x) -} - -#[ra_salsa::database(QueryGroupStorage)] -#[derive(Default)] -struct Database { - storage: ra_salsa::Storage, - external_state: HashMap, - on_event: Option>, -} - -impl ra_salsa::Database for Database { - fn salsa_event(&self, event: ra_salsa::Event) { - if let Some(cb) = &self.on_event { - cb(self, event) - } - } -} - -impl AsRef> for Database { - fn as_ref(&self) -> &HashMap { - &self.external_state - } -} - -#[test] -fn on_demand_input_works() { - let mut db = Database::default(); - - db.external_state.insert(1, 10); - assert_eq!(db.b(1), 10); - assert_eq!(db.a(1), 10); - - // We changed external state, but haven't signaled about this yet, - // so we expect to see the old answer - db.external_state.insert(1, 92); - assert_eq!(db.b(1), 10); - assert_eq!(db.a(1), 10); - - AQuery.in_db_mut(&mut db).invalidate(&1); - assert_eq!(db.b(1), 92); - assert_eq!(db.a(1), 92); - - // Downstream queries should also be rerun if we call `a` first. - db.external_state.insert(1, 50); - AQuery.in_db_mut(&mut db).invalidate(&1); - assert_eq!(db.a(1), 50); - assert_eq!(db.b(1), 50); -} - -#[test] -fn on_demand_input_durability() { - let mut db = Database::default(); - - let events = Rc::new(RefCell::new(vec![])); - db.on_event = Some(Box::new({ - let events = events.clone(); - move |db, event| { - if let EventKind::WillCheckCancellation = event.kind { - // these events are not interesting - } else { - events.borrow_mut().push(format!("{:?}", event.debug(db))) - } - } - })); - - events.replace(vec![]); - db.external_state.insert(1, 10); - db.external_state.insert(2, 20); - assert_eq!(db.b(1), 10); - assert_eq!(db.b(2), 20); - expect_test::expect![[r#" - RefCell { - value: [ - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::BQuery::b(1) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::AQuery::a(1) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::BQuery::b(2) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::AQuery::a(2) } }", - ], - } - "#]].assert_debug_eq(&events); - - db.synthetic_write(Durability::LOW); - events.replace(vec![]); - assert_eq!(db.c(1), 10); - assert_eq!(db.c(2), 20); - // Re-execute `a(2)` because that has low durability, but not `a(1)` - expect_test::expect![[r#" - RefCell { - value: [ - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::CQuery::c(1) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: DidValidateMemoizedValue { database_key: on_demand_inputs::BQuery::b(1) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::CQuery::c(2) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::AQuery::a(2) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: DidValidateMemoizedValue { database_key: on_demand_inputs::BQuery::b(2) } }", - ], - } - "#]].assert_debug_eq(&events); - - db.synthetic_write(Durability::HIGH); - events.replace(vec![]); - assert_eq!(db.c(1), 10); - assert_eq!(db.c(2), 20); - // Re-execute both `a(1)` and `a(2)`, but we don't re-execute any `b` queries as the - // result didn't actually change. - expect_test::expect![[r#" - RefCell { - value: [ - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::AQuery::a(1) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: DidValidateMemoizedValue { database_key: on_demand_inputs::CQuery::c(1) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: on_demand_inputs::AQuery::a(2) } }", - "Event { runtime_id: RuntimeId { counter: 0 }, kind: DidValidateMemoizedValue { database_key: on_demand_inputs::CQuery::c(2) } }", - ], - } - "#]].assert_debug_eq(&events); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/panic_safely.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/panic_safely.rs deleted file mode 100644 index 047a50eb4b2b4..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/panic_safely.rs +++ /dev/null @@ -1,93 +0,0 @@ -use ra_salsa::{Database, ParallelDatabase, Snapshot}; -use std::panic::{self, AssertUnwindSafe}; -use std::sync::atomic::{AtomicU32, Ordering::SeqCst}; - -#[ra_salsa::query_group(PanicSafelyStruct)] -trait PanicSafelyDatabase: ra_salsa::Database { - #[ra_salsa::input] - fn one(&self) -> usize; - - fn panic_safely(&self) -> (); - - fn outer(&self) -> (); -} - -fn panic_safely(db: &dyn PanicSafelyDatabase) { - assert_eq!(db.one(), 1); -} - -static OUTER_CALLS: AtomicU32 = AtomicU32::new(0); - -fn outer(db: &dyn PanicSafelyDatabase) { - OUTER_CALLS.fetch_add(1, SeqCst); - db.panic_safely(); -} - -#[ra_salsa::database(PanicSafelyStruct)] -#[derive(Default)] -struct DatabaseStruct { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for DatabaseStruct {} - -impl ra_salsa::ParallelDatabase for DatabaseStruct { - fn snapshot(&self) -> Snapshot { - Snapshot::new(DatabaseStruct { storage: self.storage.snapshot() }) - } -} - -#[test] -fn should_panic_safely() { - let mut db = DatabaseStruct::default(); - db.set_one(0); - - // Invoke `db.panic_safely() without having set `db.one`. `db.one` will - // return 0 and we should catch the panic. - let result = panic::catch_unwind(AssertUnwindSafe({ - let db = db.snapshot(); - move || db.panic_safely() - })); - assert!(result.is_err()); - - // Set `db.one` to 1 and assert ok - db.set_one(1); - let result = panic::catch_unwind(AssertUnwindSafe(|| db.panic_safely())); - assert!(result.is_ok()); - - // Check, that memoized outer is not invalidated by a panic - { - assert_eq!(OUTER_CALLS.load(SeqCst), 0); - db.outer(); - assert_eq!(OUTER_CALLS.load(SeqCst), 1); - - db.set_one(0); - let result = panic::catch_unwind(AssertUnwindSafe(|| db.outer())); - assert!(result.is_err()); - assert_eq!(OUTER_CALLS.load(SeqCst), 1); - - db.set_one(1); - db.outer(); - assert_eq!(OUTER_CALLS.load(SeqCst), 2); - } -} - -#[test] -fn storages_are_unwind_safe() { - fn check_unwind_safe() {} - check_unwind_safe::<&DatabaseStruct>(); -} - -#[test] -fn panics_clear_query_stack() { - let db = DatabaseStruct::default(); - - // Invoke `db.panic_if_not_one() without having set `db.input`. `db.input` - // will default to 0 and we should catch the panic. - let result = panic::catch_unwind(AssertUnwindSafe(|| db.panic_safely())); - assert!(result.is_err()); - - // The database has been poisoned and any attempt to increment the - // revision should panic. - assert_eq!(db.salsa_runtime().active_query(), None); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/cancellation.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/cancellation.rs deleted file mode 100644 index e47a8ef9aa813..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/cancellation.rs +++ /dev/null @@ -1,132 +0,0 @@ -use crate::setup::{CancellationFlag, Knobs, ParDatabase, ParDatabaseImpl, WithValue}; -use ra_salsa::{Cancelled, ParallelDatabase}; - -macro_rules! assert_cancelled { - ($thread:expr) => { - match $thread.join() { - Ok(value) => panic!("expected cancellation, got {:?}", value), - Err(payload) => match payload.downcast::() { - Ok(_) => {} - Err(payload) => ::std::panic::resume_unwind(payload), - }, - } - }; -} - -/// Add test where a call to `sum` is cancelled by a simultaneous -/// write. Check that we recompute the result in next revision, even -/// though none of the inputs have changed. -#[test] -fn in_par_get_set_cancellation_immediate() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 100); - db.set_input('b', 10); - db.set_input('c', 1); - db.set_input('d', 0); - - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || { - // This will not return until it sees cancellation is - // signaled. - db.knobs().sum_signal_on_entry.with_value(1, || { - db.knobs() - .sum_wait_for_cancellation - .with_value(CancellationFlag::Panic, || db.sum("abc")) - }) - } - }); - - // Wait until we have entered `sum` in the other thread. - db.wait_for(1); - - // Try to set the input. This will signal cancellation. - db.set_input('d', 1000); - - // This should re-compute the value (even though no input has changed). - let thread2 = std::thread::spawn({ - let db = db.snapshot(); - move || db.sum("abc") - }); - - assert_eq!(db.sum("d"), 1000); - assert_cancelled!(thread1); - assert_eq!(thread2.join().unwrap(), 111); -} - -/// Here, we check that `sum`'s cancellation is propagated -/// to `sum2` properly. -#[test] -fn in_par_get_set_cancellation_transitive() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 100); - db.set_input('b', 10); - db.set_input('c', 1); - db.set_input('d', 0); - - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || { - // This will not return until it sees cancellation is - // signaled. - db.knobs().sum_signal_on_entry.with_value(1, || { - db.knobs() - .sum_wait_for_cancellation - .with_value(CancellationFlag::Panic, || db.sum2("abc")) - }) - } - }); - - // Wait until we have entered `sum` in the other thread. - db.wait_for(1); - - // Try to set the input. This will signal cancellation. - db.set_input('d', 1000); - - // This should re-compute the value (even though no input has changed). - let thread2 = std::thread::spawn({ - let db = db.snapshot(); - move || db.sum2("abc") - }); - - assert_eq!(db.sum2("d"), 1000); - assert_cancelled!(thread1); - assert_eq!(thread2.join().unwrap(), 111); -} - -/// https://github.com/ra_salsa-rs/ra_salsa/issues/66 -#[test] -fn no_back_dating_in_cancellation() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 1); - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || { - // Here we compute a long-chain of queries, - // but the last one gets cancelled. - db.knobs().sum_signal_on_entry.with_value(1, || { - db.knobs() - .sum_wait_for_cancellation - .with_value(CancellationFlag::Panic, || db.sum3("a")) - }) - } - }); - - db.wait_for(1); - - // Set unrelated input to bump revision - db.set_input('b', 2); - - // Here we should recompuet the whole chain again, clearing the cancellation - // state. If we get `usize::max()` here, it is a bug! - assert_eq!(db.sum3("a"), 1); - - assert_cancelled!(thread1); - - db.set_input('a', 3); - db.set_input('a', 4); - assert_eq!(db.sum3("ab"), 6); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/frozen.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/frozen.rs deleted file mode 100644 index 9e42e26151750..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/frozen.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::setup::{ParDatabase, ParDatabaseImpl}; -use crate::signal::Signal; -use ra_salsa::{Database, ParallelDatabase}; -use std::{ - panic::{catch_unwind, AssertUnwindSafe}, - sync::Arc, -}; - -/// Add test where a call to `sum` is cancelled by a simultaneous -/// write. Check that we recompute the result in next revision, even -/// though none of the inputs have changed. -#[test] -fn in_par_get_set_cancellation() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 1); - - let signal = Arc::new(Signal::default()); - - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - let signal = signal.clone(); - move || { - // Check that cancellation flag is not yet set, because - // `set` cannot have been called yet. - catch_unwind(AssertUnwindSafe(|| db.unwind_if_cancelled())).unwrap(); - - // Signal other thread to proceed. - signal.signal(1); - - // Wait for other thread to signal cancellation - catch_unwind(AssertUnwindSafe(|| loop { - db.unwind_if_cancelled(); - std::thread::yield_now(); - })) - .unwrap_err(); - } - }); - - let thread2 = std::thread::spawn({ - move || { - // Wait until thread 1 has asserted that they are not cancelled - // before we invoke `set.` - signal.wait_for(1); - - // This will block until thread1 drops the revision lock. - db.set_input('a', 2); - - db.input('a') - } - }); - - thread1.join().unwrap(); - - let c = thread2.join().unwrap(); - assert_eq!(c, 2); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/independent.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/independent.rs deleted file mode 100644 index cbbac0608d194..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/independent.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::setup::{ParDatabase, ParDatabaseImpl}; -use ra_salsa::ParallelDatabase; - -/// Test two `sum` queries (on distinct keys) executing in different -/// threads. Really just a test that `snapshot` etc compiles. -#[test] -fn in_par_two_independent_queries() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 100); - db.set_input('b', 10); - db.set_input('c', 1); - db.set_input('d', 200); - db.set_input('e', 20); - db.set_input('f', 2); - - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || db.sum("abc") - }); - - let thread2 = std::thread::spawn({ - let db = db.snapshot(); - move || db.sum("def") - }); - - assert_eq!(thread1.join().unwrap(), 111); - assert_eq!(thread2.join().unwrap(), 222); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/main.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/main.rs deleted file mode 100644 index 31c0da1837570..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -mod setup; - -mod cancellation; -mod frozen; -mod independent; -mod parallel_cycle_all_recover; -mod parallel_cycle_mid_recover; -mod parallel_cycle_none_recover; -mod parallel_cycle_one_recovers; -mod race; -mod signal; -mod stress; -mod true_parallel; diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_all_recover.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_all_recover.rs deleted file mode 100644 index dabdb3babc00b..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_all_recover.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! Test for cycle recover spread across two threads. -//! See `../cycles.rs` for a complete listing of cycle tests, -//! both intra and cross thread. - -use crate::setup::{Knobs, ParDatabaseImpl}; -use ra_salsa::ParallelDatabase; - -// Recover cycle test: -// -// The pattern is as follows. -// -// Thread A Thread B -// -------- -------- -// a1 b1 -// | wait for stage 1 (blocks) -// signal stage 1 | -// wait for stage 2 (blocks) (unblocked) -// | signal stage 2 -// (unblocked) wait for stage 3 (blocks) -// a2 | -// b1 (blocks -> stage 3) | -// | (unblocked) -// | b2 -// | a1 (cycle detected, recovers) -// | b2 completes, recovers -// | b1 completes, recovers -// a2 sees cycle, recovers -// a1 completes, recovers - -#[test] -fn parallel_cycle_all_recover() { - let db = ParDatabaseImpl::default(); - db.knobs().signal_on_will_block.set(3); - - let thread_a = std::thread::spawn({ - let db = db.snapshot(); - move || db.a1(1) - }); - - let thread_b = std::thread::spawn({ - let db = db.snapshot(); - move || db.b1(1) - }); - - assert_eq!(thread_a.join().unwrap(), 11); - assert_eq!(thread_b.join().unwrap(), 21); -} - -#[ra_salsa::query_group(ParallelCycleAllRecover)] -pub(crate) trait TestDatabase: Knobs { - #[ra_salsa::cycle(recover_a1)] - fn a1(&self, key: i32) -> i32; - - #[ra_salsa::cycle(recover_a2)] - fn a2(&self, key: i32) -> i32; - - #[ra_salsa::cycle(recover_b1)] - fn b1(&self, key: i32) -> i32; - - #[ra_salsa::cycle(recover_b2)] - fn b2(&self, key: i32) -> i32; -} - -fn recover_a1(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { - tracing::debug!("recover_a1"); - key * 10 + 1 -} - -fn recover_a2(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { - tracing::debug!("recover_a2"); - key * 10 + 2 -} - -fn recover_b1(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { - tracing::debug!("recover_b1"); - key * 20 + 1 -} - -fn recover_b2(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { - tracing::debug!("recover_b2"); - key * 20 + 2 -} - -fn a1(db: &dyn TestDatabase, key: i32) -> i32 { - // Wait to create the cycle until both threads have entered - db.signal(1); - db.wait_for(2); - - db.a2(key) -} - -fn a2(db: &dyn TestDatabase, key: i32) -> i32 { - db.b1(key) -} - -fn b1(db: &dyn TestDatabase, key: i32) -> i32 { - // Wait to create the cycle until both threads have entered - db.wait_for(1); - db.signal(2); - - // Wait for thread A to block on this thread - db.wait_for(3); - - db.b2(key) -} - -fn b2(db: &dyn TestDatabase, key: i32) -> i32 { - db.a1(key) -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_mid_recover.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_mid_recover.rs deleted file mode 100644 index 20c508e0b8bf9..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_mid_recover.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! Test for cycle recover spread across two threads. -//! See `../cycles.rs` for a complete listing of cycle tests, -//! both intra and cross thread. - -use crate::setup::{Knobs, ParDatabaseImpl}; -use ra_salsa::ParallelDatabase; - -// Recover cycle test: -// -// The pattern is as follows. -// -// Thread A Thread B -// -------- -------- -// a1 b1 -// | wait for stage 1 (blocks) -// signal stage 1 | -// wait for stage 2 (blocks) (unblocked) -// | | -// | b2 -// | b3 -// | a1 (blocks -> stage 2) -// (unblocked) | -// a2 (cycle detected) | -// b3 recovers -// b2 resumes -// b1 panics because bug - -#[test] -fn parallel_cycle_mid_recovers() { - let db = ParDatabaseImpl::default(); - db.knobs().signal_on_will_block.set(2); - - let thread_a = std::thread::spawn({ - let db = db.snapshot(); - move || db.a1(1) - }); - - let thread_b = std::thread::spawn({ - let db = db.snapshot(); - move || db.b1(1) - }); - - // We expect that the recovery function yields - // `1 * 20 + 2`, which is returned (and forwarded) - // to b1, and from there to a2 and a1. - assert_eq!(thread_a.join().unwrap(), 22); - assert_eq!(thread_b.join().unwrap(), 22); -} - -#[ra_salsa::query_group(ParallelCycleMidRecovers)] -pub(crate) trait TestDatabase: Knobs { - fn a1(&self, key: i32) -> i32; - - fn a2(&self, key: i32) -> i32; - - #[ra_salsa::cycle(recover_b1)] - fn b1(&self, key: i32) -> i32; - - fn b2(&self, key: i32) -> i32; - - #[ra_salsa::cycle(recover_b3)] - fn b3(&self, key: i32) -> i32; -} - -fn recover_b1(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { - tracing::debug!("recover_b1"); - key * 20 + 2 -} - -fn recover_b3(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { - tracing::debug!("recover_b1"); - key * 200 + 2 -} - -fn a1(db: &dyn TestDatabase, key: i32) -> i32 { - // tell thread b we have started - db.signal(1); - - // wait for thread b to block on a1 - db.wait_for(2); - - db.a2(key) -} - -fn a2(db: &dyn TestDatabase, key: i32) -> i32 { - // create the cycle - db.b1(key) -} - -fn b1(db: &dyn TestDatabase, key: i32) -> i32 { - // wait for thread a to have started - db.wait_for(1); - - db.b2(key); - - 0 -} - -fn b2(db: &dyn TestDatabase, key: i32) -> i32 { - // will encounter a cycle but recover - db.b3(key); - db.b1(key); // hasn't recovered yet - 0 -} - -fn b3(db: &dyn TestDatabase, key: i32) -> i32 { - // will block on thread a, signaling stage 2 - db.a1(key) -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_none_recover.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_none_recover.rs deleted file mode 100644 index 88d5fee0a22a4..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_none_recover.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Test a cycle where no queries recover that occurs across threads. -//! See the `../cycles.rs` for a complete listing of cycle tests, -//! both intra and cross thread. - -use crate::setup::{Knobs, ParDatabaseImpl}; -use expect_test::expect; -use ra_salsa::ParallelDatabase; - -#[test] -fn parallel_cycle_none_recover() { - let db = ParDatabaseImpl::default(); - db.knobs().signal_on_will_block.set(3); - - let thread_a = std::thread::spawn({ - let db = db.snapshot(); - move || db.a(-1) - }); - - let thread_b = std::thread::spawn({ - let db = db.snapshot(); - move || db.b(-1) - }); - - // We expect B to panic because it detects a cycle (it is the one that calls A, ultimately). - // Right now, it panics with a string. - let err_b = thread_b.join().unwrap_err(); - if let Some(c) = err_b.downcast_ref::() { - expect![[r#" - [ - "parallel::parallel_cycle_none_recover::AQuery::a(-1)", - "parallel::parallel_cycle_none_recover::BQuery::b(-1)", - ] - "#]] - .assert_debug_eq(&c.unexpected_participants(&db)); - } else { - panic!("b failed in an unexpected way: {err_b:?}"); - } - - // We expect A to propagate a panic, which causes us to use the sentinel - // type `Canceled`. - assert!(thread_a.join().unwrap_err().downcast_ref::().is_some()); -} - -#[ra_salsa::query_group(ParallelCycleNoneRecover)] -pub(crate) trait TestDatabase: Knobs { - fn a(&self, key: i32) -> i32; - fn b(&self, key: i32) -> i32; -} - -fn a(db: &dyn TestDatabase, key: i32) -> i32 { - // Wait to create the cycle until both threads have entered - db.signal(1); - db.wait_for(2); - - db.b(key) -} - -fn b(db: &dyn TestDatabase, key: i32) -> i32 { - // Wait to create the cycle until both threads have entered - db.wait_for(1); - db.signal(2); - - // Wait for thread A to block on this thread - db.wait_for(3); - - // Now try to execute A - db.a(key) -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_one_recovers.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_one_recovers.rs deleted file mode 100644 index 074ed1bd349de..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_one_recovers.rs +++ /dev/null @@ -1,94 +0,0 @@ -//! Test for cycle recover spread across two threads. -//! See `../cycles.rs` for a complete listing of cycle tests, -//! both intra and cross thread. - -use crate::setup::{Knobs, ParDatabaseImpl}; -use ra_salsa::ParallelDatabase; - -// Recover cycle test: -// -// The pattern is as follows. -// -// Thread A Thread B -// -------- -------- -// a1 b1 -// | wait for stage 1 (blocks) -// signal stage 1 | -// wait for stage 2 (blocks) (unblocked) -// | signal stage 2 -// (unblocked) wait for stage 3 (blocks) -// a2 | -// b1 (blocks -> stage 3) | -// | (unblocked) -// | b2 -// | a1 (cycle detected) -// a2 recovery fn executes | -// a1 completes normally | -// b2 completes, recovers -// b1 completes, recovers - -#[test] -fn parallel_cycle_one_recovers() { - let db = ParDatabaseImpl::default(); - db.knobs().signal_on_will_block.set(3); - - let thread_a = std::thread::spawn({ - let db = db.snapshot(); - move || db.a1(1) - }); - - let thread_b = std::thread::spawn({ - let db = db.snapshot(); - move || db.b1(1) - }); - - // We expect that the recovery function yields - // `1 * 20 + 2`, which is returned (and forwarded) - // to b1, and from there to a2 and a1. - assert_eq!(thread_a.join().unwrap(), 22); - assert_eq!(thread_b.join().unwrap(), 22); -} - -#[ra_salsa::query_group(ParallelCycleOneRecovers)] -pub(crate) trait TestDatabase: Knobs { - fn a1(&self, key: i32) -> i32; - - #[ra_salsa::cycle(recover)] - fn a2(&self, key: i32) -> i32; - - fn b1(&self, key: i32) -> i32; - - fn b2(&self, key: i32) -> i32; -} - -fn recover(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { - tracing::debug!("recover"); - key * 20 + 2 -} - -fn a1(db: &dyn TestDatabase, key: i32) -> i32 { - // Wait to create the cycle until both threads have entered - db.signal(1); - db.wait_for(2); - - db.a2(key) -} - -fn a2(db: &dyn TestDatabase, key: i32) -> i32 { - db.b1(key) -} - -fn b1(db: &dyn TestDatabase, key: i32) -> i32 { - // Wait to create the cycle until both threads have entered - db.wait_for(1); - db.signal(2); - - // Wait for thread A to block on this thread - db.wait_for(3); - - db.b2(key) -} - -fn b2(db: &dyn TestDatabase, key: i32) -> i32 { - db.a1(key) -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/race.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/race.rs deleted file mode 100644 index 7aa6d4530b4a7..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/race.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::panic::AssertUnwindSafe; - -use crate::setup::{ParDatabase, ParDatabaseImpl}; -use ra_salsa::{Cancelled, ParallelDatabase}; - -/// Test where a read and a set are racing with one another. -/// Should be atomic. -#[test] -fn in_par_get_set_race() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 100); - db.set_input('b', 10); - db.set_input('c', 1); - - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || Cancelled::catch(AssertUnwindSafe(|| db.sum("abc"))) - }); - - let thread2 = std::thread::spawn(move || { - db.set_input('a', 1000); - db.sum("a") - }); - - // If the 1st thread runs first, you get 111, otherwise you get - // 1011; if they run concurrently and the 1st thread observes the - // cancellation, it'll unwind. - let result1 = thread1.join().unwrap(); - if let Ok(value1) = result1 { - assert!(value1 == 111 || value1 == 1011, "illegal result {value1}"); - } - - // thread2 can not observe a cancellation because it performs a - // database write before running any other queries. - assert_eq!(thread2.join().unwrap(), 1000); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/setup.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/setup.rs deleted file mode 100644 index fd1f51326e320..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/setup.rs +++ /dev/null @@ -1,197 +0,0 @@ -use crate::signal::Signal; -use ra_salsa::Database; -use ra_salsa::ParallelDatabase; -use ra_salsa::Snapshot; -use std::sync::Arc; -use std::{ - cell::Cell, - panic::{catch_unwind, resume_unwind, AssertUnwindSafe}, -}; - -#[ra_salsa::query_group(Par)] -pub(crate) trait ParDatabase: Knobs { - #[ra_salsa::input] - fn input(&self, key: char) -> usize; - - fn sum(&self, key: &'static str) -> usize; - - /// Invokes `sum` - fn sum2(&self, key: &'static str) -> usize; - - /// Invokes `sum` but doesn't really care about the result. - fn sum2_drop_sum(&self, key: &'static str) -> usize; - - /// Invokes `sum2` - fn sum3(&self, key: &'static str) -> usize; - - /// Invokes `sum2_drop_sum` - fn sum3_drop_sum(&self, key: &'static str) -> usize; -} - -/// Various "knobs" and utilities used by tests to force -/// a certain behavior. -pub(crate) trait Knobs { - fn knobs(&self) -> &KnobsStruct; - - fn signal(&self, stage: usize); - - fn wait_for(&self, stage: usize); -} - -pub(crate) trait WithValue { - fn with_value(&self, value: T, closure: impl FnOnce() -> R) -> R; -} - -impl WithValue for Cell { - fn with_value(&self, value: T, closure: impl FnOnce() -> R) -> R { - let old_value = self.replace(value); - - let result = catch_unwind(AssertUnwindSafe(closure)); - - self.set(old_value); - - match result { - Ok(r) => r, - Err(payload) => resume_unwind(payload), - } - } -} - -#[derive(Default, Clone, Copy, PartialEq, Eq)] -pub(crate) enum CancellationFlag { - #[default] - Down, - Panic, -} - -/// Various "knobs" that can be used to customize how the queries -/// behave on one specific thread. Note that this state is -/// intentionally thread-local (apart from `signal`). -#[derive(Clone, Default)] -pub(crate) struct KnobsStruct { - /// A kind of flexible barrier used to coordinate execution across - /// threads to ensure we reach various weird states. - pub(crate) signal: Arc, - - /// When this database is about to block, send a signal. - pub(crate) signal_on_will_block: Cell, - - /// Invocations of `sum` will signal this stage on entry. - pub(crate) sum_signal_on_entry: Cell, - - /// Invocations of `sum` will wait for this stage on entry. - pub(crate) sum_wait_for_on_entry: Cell, - - /// If true, invocations of `sum` will panic before they exit. - pub(crate) sum_should_panic: Cell, - - /// If true, invocations of `sum` will wait for cancellation before - /// they exit. - pub(crate) sum_wait_for_cancellation: Cell, - - /// Invocations of `sum` will wait for this stage prior to exiting. - pub(crate) sum_wait_for_on_exit: Cell, - - /// Invocations of `sum` will signal this stage prior to exiting. - pub(crate) sum_signal_on_exit: Cell, - - /// Invocations of `sum3_drop_sum` will panic unconditionally - pub(crate) sum3_drop_sum_should_panic: Cell, -} - -fn sum(db: &dyn ParDatabase, key: &'static str) -> usize { - let mut sum = 0; - - db.signal(db.knobs().sum_signal_on_entry.get()); - - db.wait_for(db.knobs().sum_wait_for_on_entry.get()); - - if db.knobs().sum_should_panic.get() { - panic!("query set to panic before exit") - } - - for ch in key.chars() { - sum += db.input(ch); - } - - match db.knobs().sum_wait_for_cancellation.get() { - CancellationFlag::Down => (), - CancellationFlag::Panic => { - tracing::debug!("waiting for cancellation"); - loop { - db.unwind_if_cancelled(); - std::thread::yield_now(); - } - } - } - - db.wait_for(db.knobs().sum_wait_for_on_exit.get()); - - db.signal(db.knobs().sum_signal_on_exit.get()); - - sum -} - -fn sum2(db: &dyn ParDatabase, key: &'static str) -> usize { - db.sum(key) -} - -fn sum2_drop_sum(db: &dyn ParDatabase, key: &'static str) -> usize { - let _ = db.sum(key); - 22 -} - -fn sum3(db: &dyn ParDatabase, key: &'static str) -> usize { - db.sum2(key) -} - -fn sum3_drop_sum(db: &dyn ParDatabase, key: &'static str) -> usize { - if db.knobs().sum3_drop_sum_should_panic.get() { - panic!("sum3_drop_sum executed") - } - db.sum2_drop_sum(key) -} - -#[ra_salsa::database( - Par, - crate::parallel_cycle_all_recover::ParallelCycleAllRecover, - crate::parallel_cycle_none_recover::ParallelCycleNoneRecover, - crate::parallel_cycle_mid_recover::ParallelCycleMidRecovers, - crate::parallel_cycle_one_recovers::ParallelCycleOneRecovers -)] -#[derive(Default)] -pub(crate) struct ParDatabaseImpl { - storage: ra_salsa::Storage, - knobs: KnobsStruct, -} - -impl Database for ParDatabaseImpl { - fn salsa_event(&self, event: ra_salsa::Event) { - if let ra_salsa::EventKind::WillBlockOn { .. } = event.kind { - self.signal(self.knobs().signal_on_will_block.get()); - } - } -} - -impl ParallelDatabase for ParDatabaseImpl { - fn snapshot(&self) -> Snapshot { - Snapshot::new(ParDatabaseImpl { - storage: self.storage.snapshot(), - knobs: self.knobs.clone(), - }) - } -} - -impl Knobs for ParDatabaseImpl { - fn knobs(&self) -> &KnobsStruct { - &self.knobs - } - - fn signal(&self, stage: usize) { - self.knobs.signal.signal(stage); - } - - fn wait_for(&self, stage: usize) { - self.knobs.signal.wait_for(stage); - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/signal.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/signal.rs deleted file mode 100644 index 0af7b66e4826d..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/signal.rs +++ /dev/null @@ -1,40 +0,0 @@ -use parking_lot::{Condvar, Mutex}; - -#[derive(Default)] -pub(crate) struct Signal { - value: Mutex, - cond_var: Condvar, -} - -impl Signal { - pub(crate) fn signal(&self, stage: usize) { - tracing::debug!("signal({})", stage); - - // This check avoids acquiring the lock for things that will - // clearly be a no-op. Not *necessary* but helps to ensure we - // are more likely to encounter weird race conditions; - // otherwise calls to `sum` will tend to be unnecessarily - // synchronous. - if stage > 0 { - let mut v = self.value.lock(); - if stage > *v { - *v = stage; - self.cond_var.notify_all(); - } - } - } - - /// Waits until the given condition is true; the fn is invoked - /// with the current stage. - pub(crate) fn wait_for(&self, stage: usize) { - tracing::debug!("wait_for({})", stage); - - // As above, avoid lock if clearly a no-op. - if stage > 0 { - let mut v = self.value.lock(); - while *v < stage { - self.cond_var.wait(&mut v); - } - } - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/stress.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/stress.rs deleted file mode 100644 index f3a435b47f147..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/stress.rs +++ /dev/null @@ -1,168 +0,0 @@ -use rand::seq::SliceRandom; -use rand::Rng; - -use ra_salsa::ParallelDatabase; -use ra_salsa::Snapshot; -use ra_salsa::{Cancelled, Database}; - -// Number of operations a reader performs -const N_MUTATOR_OPS: usize = 100; -const N_READER_OPS: usize = 100; - -#[ra_salsa::query_group(Stress)] -trait StressDatabase: ra_salsa::Database { - #[ra_salsa::input] - fn a(&self, key: usize) -> usize; - - fn b(&self, key: usize) -> usize; - - fn c(&self, key: usize) -> usize; -} - -fn b(db: &dyn StressDatabase, key: usize) -> usize { - db.unwind_if_cancelled(); - db.a(key) -} - -fn c(db: &dyn StressDatabase, key: usize) -> usize { - db.b(key) -} - -#[ra_salsa::database(Stress)] -#[derive(Default)] -struct StressDatabaseImpl { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for StressDatabaseImpl {} - -impl ra_salsa::ParallelDatabase for StressDatabaseImpl { - fn snapshot(&self) -> Snapshot { - Snapshot::new(StressDatabaseImpl { storage: self.storage.snapshot() }) - } -} - -#[derive(Clone, Copy, Debug)] -enum Query { - A, - B, - C, -} - -enum MutatorOp { - WriteOp(WriteOp), - LaunchReader { ops: Vec, check_cancellation: bool }, -} - -#[derive(Debug)] -enum WriteOp { - SetA(usize, usize), -} - -#[derive(Debug)] -enum ReadOp { - Get(Query, usize), -} - -impl rand::distributions::Distribution for rand::distributions::Standard { - fn sample(&self, rng: &mut R) -> Query { - *[Query::A, Query::B, Query::C].choose(rng).unwrap() - } -} - -impl rand::distributions::Distribution for rand::distributions::Standard { - fn sample(&self, rng: &mut R) -> MutatorOp { - if rng.gen_bool(0.5) { - MutatorOp::WriteOp(rng.gen()) - } else { - MutatorOp::LaunchReader { - ops: (0..N_READER_OPS).map(|_| rng.gen()).collect(), - check_cancellation: rng.gen(), - } - } - } -} - -impl rand::distributions::Distribution for rand::distributions::Standard { - fn sample(&self, rng: &mut R) -> WriteOp { - let key = rng.gen::() % 10; - let value = rng.gen::() % 10; - WriteOp::SetA(key, value) - } -} - -impl rand::distributions::Distribution for rand::distributions::Standard { - fn sample(&self, rng: &mut R) -> ReadOp { - let query = rng.gen::(); - let key = rng.gen::() % 10; - ReadOp::Get(query, key) - } -} - -fn db_reader_thread(db: &StressDatabaseImpl, ops: Vec, check_cancellation: bool) { - for op in ops { - if check_cancellation { - db.unwind_if_cancelled(); - } - op.execute(db); - } -} - -impl WriteOp { - fn execute(self, db: &mut StressDatabaseImpl) { - match self { - WriteOp::SetA(key, value) => { - db.set_a(key, value); - } - } - } -} - -impl ReadOp { - fn execute(self, db: &StressDatabaseImpl) { - match self { - ReadOp::Get(query, key) => match query { - Query::A => { - db.a(key); - } - Query::B => { - let _ = db.b(key); - } - Query::C => { - let _ = db.c(key); - } - }, - } - } -} - -#[test] -fn stress_test() { - let mut db = StressDatabaseImpl::default(); - for i in 0..10 { - db.set_a(i, i); - } - - let mut rng = rand::thread_rng(); - - // generate the ops that the mutator thread will perform - let write_ops: Vec = (0..N_MUTATOR_OPS).map(|_| rng.gen()).collect(); - - // execute the "main thread", which sometimes snapshots off other threads - let mut all_threads = vec![]; - for op in write_ops { - match op { - MutatorOp::WriteOp(w) => w.execute(&mut db), - MutatorOp::LaunchReader { ops, check_cancellation } => { - all_threads.push(std::thread::spawn({ - let db = db.snapshot(); - move || Cancelled::catch(|| db_reader_thread(&db, ops, check_cancellation)) - })) - } - } - } - - for thread in all_threads { - thread.join().unwrap().ok(); - } -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/true_parallel.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/true_parallel.rs deleted file mode 100644 index 44db17bd85253..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/true_parallel.rs +++ /dev/null @@ -1,125 +0,0 @@ -use crate::setup::{Knobs, ParDatabase, ParDatabaseImpl, WithValue}; -use ra_salsa::ParallelDatabase; -use std::panic::{self, AssertUnwindSafe}; - -/// Test where two threads are executing sum. We show that they can -/// both be executing sum in parallel by having thread1 wait for -/// thread2 to send a signal before it leaves (similarly, thread2 -/// waits for thread1 to send a signal before it enters). -#[test] -fn true_parallel_different_keys() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 100); - db.set_input('b', 10); - db.set_input('c', 1); - - // Thread 1 will signal stage 1 when it enters and wait for stage 2. - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || { - let v = db - .knobs() - .sum_signal_on_entry - .with_value(1, || db.knobs().sum_wait_for_on_exit.with_value(2, || db.sum("a"))); - v - } - }); - - // Thread 2 will wait_for stage 1 when it enters and signal stage 2 - // when it leaves. - let thread2 = std::thread::spawn({ - let db = db.snapshot(); - move || { - let v = db - .knobs() - .sum_wait_for_on_entry - .with_value(1, || db.knobs().sum_signal_on_exit.with_value(2, || db.sum("b"))); - v - } - }); - - assert_eq!(thread1.join().unwrap(), 100); - assert_eq!(thread2.join().unwrap(), 10); -} - -/// Add a test that tries to trigger a conflict, where we fetch -/// `sum("abc")` from two threads simultaneously, and of them -/// therefore has to block. -#[test] -fn true_parallel_same_keys() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 100); - db.set_input('b', 10); - db.set_input('c', 1); - - // Thread 1 will wait_for a barrier in the start of `sum` - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || { - let v = db - .knobs() - .sum_signal_on_entry - .with_value(1, || db.knobs().sum_wait_for_on_entry.with_value(2, || db.sum("abc"))); - v - } - }); - - // Thread 2 will wait until Thread 1 has entered sum and then -- - // once it has set itself to block -- signal Thread 1 to - // continue. This way, we test out the mechanism of one thread - // blocking on another. - let thread2 = std::thread::spawn({ - let db = db.snapshot(); - move || { - db.knobs().signal.wait_for(1); - db.knobs().signal_on_will_block.set(2); - db.sum("abc") - } - }); - - assert_eq!(thread1.join().unwrap(), 111); - assert_eq!(thread2.join().unwrap(), 111); -} - -/// Add a test that tries to trigger a conflict, where we fetch `sum("a")` -/// from two threads simultaneously. After `thread2` begins blocking, -/// we force `thread1` to panic and should see that propagate to `thread2`. -#[test] -fn true_parallel_propagate_panic() { - let mut db = ParDatabaseImpl::default(); - - db.set_input('a', 1); - - // `thread1` will wait_for a barrier in the start of `sum`. Once it can - // continue, it will panic. - let thread1 = std::thread::spawn({ - let db = db.snapshot(); - move || { - let v = db.knobs().sum_signal_on_entry.with_value(1, || { - db.knobs() - .sum_wait_for_on_entry - .with_value(2, || db.knobs().sum_should_panic.with_value(true, || db.sum("a"))) - }); - v - } - }); - - // `thread2` will wait until `thread1` has entered sum and then -- once it - // has set itself to block -- signal `thread1` to continue. - let thread2 = std::thread::spawn({ - let db = db.snapshot(); - move || { - db.knobs().signal.wait_for(1); - db.knobs().signal_on_will_block.set(2); - db.sum("a") - } - }); - - let result1 = panic::catch_unwind(AssertUnwindSafe(|| thread1.join().unwrap())); - let result2 = panic::catch_unwind(AssertUnwindSafe(|| thread2.join().unwrap())); - - assert!(result1.is_err()); - assert!(result2.is_err()); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/implementation.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/implementation.rs deleted file mode 100644 index 39b2befd15b71..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/implementation.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::queries; -use std::cell::Cell; - -#[ra_salsa::database(queries::GroupStruct)] -#[derive(Default)] -pub(crate) struct DatabaseImpl { - storage: ra_salsa::Storage, - counter: Cell, -} - -impl queries::Counter for DatabaseImpl { - fn increment(&self) -> usize { - let v = self.counter.get(); - self.counter.set(v + 1); - v - } -} - -impl ra_salsa::Database for DatabaseImpl {} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/main.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/main.rs deleted file mode 100644 index e92c61740e0c8..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod implementation; -mod queries; -mod tests; - -fn main() {} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/queries.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/queries.rs deleted file mode 100644 index bc9b10ae7bb24..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/queries.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub(crate) trait Counter: ra_salsa::Database { - fn increment(&self) -> usize; -} - -#[ra_salsa::query_group(GroupStruct)] -pub(crate) trait Database: Counter { - fn memoized(&self) -> usize; - fn volatile(&self) -> usize; -} - -/// Because this query is memoized, we only increment the counter -/// the first time it is invoked. -fn memoized(db: &dyn Database) -> usize { - db.volatile() -} - -/// Because this query is volatile, each time it is invoked, -/// we will increment the counter. -fn volatile(db: &dyn Database) -> usize { - db.salsa_runtime().report_untracked_read(); - db.increment() -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/tests.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/tests.rs deleted file mode 100644 index 7c33bbfc7475b..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/tests.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![cfg(test)] - -use crate::implementation::DatabaseImpl; -use crate::queries::Database; -use ra_salsa::Database as _Database; -use ra_salsa::Durability; - -#[test] -fn memoized_twice() { - let db = DatabaseImpl::default(); - let v1 = db.memoized(); - let v2 = db.memoized(); - assert_eq!(v1, v2); -} - -#[test] -fn volatile_twice() { - let mut db = DatabaseImpl::default(); - let v1 = db.volatile(); - let v2 = db.volatile(); // volatiles are cached, so 2nd read returns the same - assert_eq!(v1, v2); - - db.synthetic_write(Durability::LOW); // clears volatile caches - - let v3 = db.volatile(); // will re-increment the counter - let v4 = db.volatile(); // second call will be cached - assert_eq!(v1 + 1, v3); - assert_eq!(v3, v4); -} - -#[test] -fn intermingled() { - let mut db = DatabaseImpl::default(); - let v1 = db.volatile(); - let v2 = db.memoized(); - let v3 = db.volatile(); // cached - let v4 = db.memoized(); // cached - - assert_eq!(v1, v2); - assert_eq!(v1, v3); - assert_eq!(v2, v4); - - db.synthetic_write(Durability::LOW); // clears volatile caches - - let v5 = db.memoized(); // re-executes volatile, caches new result - let v6 = db.memoized(); // re-use cached result - assert_eq!(v4 + 1, v5); - assert_eq!(v5, v6); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/transparent.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/transparent.rs deleted file mode 100644 index 886f46410658b..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/transparent.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Test that transparent (uncached) queries work - -#[ra_salsa::query_group(QueryGroupStorage)] -trait QueryGroup { - #[ra_salsa::input] - fn input(&self, x: u32) -> u32; - #[ra_salsa::transparent] - fn wrap(&self, x: u32) -> u32; - fn get(&self, x: u32) -> u32; -} - -fn wrap(db: &dyn QueryGroup, x: u32) -> u32 { - db.input(x) -} - -fn get(db: &dyn QueryGroup, x: u32) -> u32 { - db.wrap(x) -} - -#[ra_salsa::database(QueryGroupStorage)] -#[derive(Default)] -struct Database { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for Database {} - -#[test] -fn transparent_queries_work() { - let mut db = Database::default(); - - db.set_input(1, 10); - assert_eq!(db.get(1), 10); - assert_eq!(db.get(1), 10); - - db.set_input(1, 92); - assert_eq!(db.get(1), 92); - assert_eq!(db.get(1), 92); -} diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/variadic.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/variadic.rs deleted file mode 100644 index 11a6d13ebe214..0000000000000 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/variadic.rs +++ /dev/null @@ -1,51 +0,0 @@ -#[ra_salsa::query_group(HelloWorld)] -trait HelloWorldDatabase: ra_salsa::Database { - #[ra_salsa::input] - fn input(&self, a: u32, b: u32) -> u32; - - fn none(&self) -> u32; - - fn one(&self, k: u32) -> u32; - - fn two(&self, a: u32, b: u32) -> u32; - - fn trailing(&self, a: u32, b: u32) -> u32; -} - -fn none(_db: &dyn HelloWorldDatabase) -> u32 { - 22 -} - -fn one(_db: &dyn HelloWorldDatabase, k: u32) -> u32 { - k * 2 -} - -fn two(_db: &dyn HelloWorldDatabase, a: u32, b: u32) -> u32 { - a * b -} - -fn trailing(_db: &dyn HelloWorldDatabase, a: u32, b: u32) -> u32 { - a - b -} - -#[ra_salsa::database(HelloWorld)] -#[derive(Default)] -struct DatabaseStruct { - storage: ra_salsa::Storage, -} - -impl ra_salsa::Database for DatabaseStruct {} - -#[test] -fn execute() { - let mut db = DatabaseStruct::default(); - - // test what happens with inputs: - db.set_input(1, 2, 3); - assert_eq!(db.input(1, 2), 3); - - assert_eq!(db.none(), 22); - assert_eq!(db.one(11), 22); - assert_eq!(db.two(11, 2), 22); - assert_eq!(db.trailing(24, 2), 22); -} diff --git a/src/tools/rust-analyzer/xtask/src/tidy.rs b/src/tools/rust-analyzer/xtask/src/tidy.rs index 0e4208e096738..59427d29992b4 100644 --- a/src/tools/rust-analyzer/xtask/src/tidy.rs +++ b/src/tools/rust-analyzer/xtask/src/tidy.rs @@ -135,7 +135,6 @@ Apache-2.0 OR MIT Apache-2.0 WITH LLVM-exception Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT Apache-2.0/MIT -BSD-2-Clause OR Apache-2.0 OR MIT CC0-1.0 ISC MIT @@ -223,7 +222,7 @@ struct TidyDocs { impl TidyDocs { fn visit(&mut self, path: &Path, text: &str) { // Tests and diagnostic fixes don't need module level comments. - if is_exclude_dir(path, &["tests", "test_data", "fixes", "grammar", "ra-salsa", "stdx"]) { + if is_exclude_dir(path, &["tests", "test_data", "fixes", "grammar", "stdx"]) { return; } From f2d36158bc54f3828d1a7bf1bac99ec2472310c1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 15 Mar 2025 16:07:52 +0100 Subject: [PATCH 028/260] chore: Remove legacy `SyntaxContextId` re-export --- .../crates/hir-def/src/expander.rs | 6 +- .../crates/hir-def/src/expr_store.rs | 6 +- .../crates/hir-def/src/hir/format_args.rs | 4 +- .../crates/hir-def/src/item_tree.rs | 4 +- .../crates/hir-def/src/item_tree/lower.rs | 6 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 6 +- .../hir-def/src/nameres/attr_resolution.rs | 4 +- .../crates/hir-def/src/nameres/collector.rs | 6 +- .../crates/hir-def/src/resolver.rs | 6 +- .../crates/hir-def/src/visibility.rs | 6 +- .../crates/hir-expand/src/attrs.rs | 4 +- .../hir-expand/src/builtin/derive_macro.rs | 6 +- .../crates/hir-expand/src/builtin/quote.rs | 4 +- .../rust-analyzer/crates/hir-expand/src/db.rs | 16 ++-- .../crates/hir-expand/src/declarative.rs | 6 +- .../crates/hir-expand/src/eager.rs | 8 +- .../crates/hir-expand/src/files.rs | 16 ++-- .../crates/hir-expand/src/fixup.rs | 4 +- .../crates/hir-expand/src/hygiene.rs | 87 ++++--------------- .../crates/hir-expand/src/lib.rs | 22 ++--- .../crates/hir-expand/src/mod_path.rs | 8 +- .../crates/hir-expand/src/name.rs | 10 +-- .../crates/hir-expand/src/proc_macro.rs | 2 +- .../crates/hir-expand/src/span_map.rs | 4 +- .../rust-analyzer/crates/hir/src/semantics.rs | 10 +-- .../rust-analyzer/crates/ide-db/src/rename.rs | 6 +- .../crates/ide/src/expand_macro.rs | 8 +- src/tools/rust-analyzer/crates/mbe/src/lib.rs | 8 +- .../rust-analyzer/crates/mbe/src/parser.rs | 12 +-- .../rust-analyzer/crates/mbe/src/tests.rs | 8 +- .../proc-macro-api/src/legacy_protocol/msg.rs | 20 ++--- .../src/legacy_protocol/msg/flat.rs | 6 +- .../src/server_impl/rust_analyzer_span.rs | 6 +- .../crates/proc-macro-srv/src/tests/utils.rs | 8 +- .../rust-analyzer/crates/span/src/hygiene.rs | 34 ++++---- .../rust-analyzer/crates/span/src/lib.rs | 5 +- .../rust-analyzer/crates/span/src/map.rs | 4 +- .../crates/syntax-bridge/src/lib.rs | 6 +- 38 files changed, 164 insertions(+), 228 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs index c5ce8c454ce35..343d8aa1c9f10 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs @@ -9,7 +9,7 @@ use hir_expand::{ attrs::RawAttrs, mod_path::ModPath, span_map::SpanMap, ExpandError, ExpandErrorKind, ExpandResult, HirFileId, InFile, Lookup, MacroCallId, }; -use span::{Edition, SyntaxContextId}; +use span::{Edition, SyntaxContext}; use syntax::{ast, Parse}; use triomphe::Arc; @@ -57,9 +57,9 @@ impl Expander { self.module.krate } - pub fn syntax_context(&self) -> SyntaxContextId { + pub fn syntax_context(&self) -> SyntaxContext { // FIXME: - SyntaxContextId::root(Edition::CURRENT) + SyntaxContext::root(Edition::CURRENT) } pub fn enter_expand( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs index 616d2c9fd89a4..7e7ccbfa91a74 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs @@ -37,13 +37,13 @@ pub use self::body::{Body, BodySourceMap}; /// A wrapper around [`span::SyntaxContextId`] that is intended only for comparisons. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct HygieneId(span::SyntaxContextId); +pub struct HygieneId(span::SyntaxContext); impl HygieneId { // The edition doesn't matter here, we only use this for comparisons and to lookup the macro. - pub const ROOT: Self = Self(span::SyntaxContextId::root(Edition::Edition2015)); + pub const ROOT: Self = Self(span::SyntaxContext::root(Edition::Edition2015)); - pub fn new(mut ctx: span::SyntaxContextId) -> Self { + pub fn new(mut ctx: span::SyntaxContext) -> Self { // See `Name` for why we're doing that. ctx.remove_root_edition(); Self(ctx) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index 28c824fd31d73..6331861a992e8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -4,7 +4,7 @@ use either::Either; use hir_expand::name::Name; use intern::Symbol; use rustc_parse_format as parse; -use span::SyntaxContextId; +use span::SyntaxContext; use stdx::TupleExt; use syntax::{ ast::{self, IsString}, @@ -176,7 +176,7 @@ pub(crate) fn parse( is_direct_literal: bool, mut synth: impl FnMut(Name, Option) -> ExprId, mut record_usage: impl FnMut(Name, Option), - call_ctx: SyntaxContextId, + call_ctx: SyntaxContext, ) -> FormatArgs { let Ok(text) = s.value() else { return FormatArgs { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index d42104faa2e04..b9fc9c9489bad 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -51,7 +51,7 @@ use intern::{Interned, Symbol}; use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::FxHashMap; use smallvec::SmallVec; -use span::{AstIdNode, Edition, FileAstId, SyntaxContextId}; +use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::never; use syntax::{ast, match_ast, SyntaxKind}; use triomphe::Arc; @@ -1098,7 +1098,7 @@ pub struct MacroCall { pub path: Interned, pub ast_id: FileAstId, pub expand_to: ExpandTo, - pub ctxt: SyntaxContextId, + pub ctxt: SyntaxContext, } #[derive(Debug, Clone, Eq, PartialEq)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 05b99ae31f423..b0cc7ead8c0dd 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -11,7 +11,7 @@ use hir_expand::{ use intern::{sym, Symbol}; use la_arena::Arena; use rustc_hash::FxHashMap; -use span::{AstIdMap, SyntaxContextId}; +use span::{AstIdMap, SyntaxContext}; use stdx::thin_vec::ThinVec; use syntax::{ ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString}, @@ -968,7 +968,7 @@ impl UseTreeLowering<'_> { fn lower_use_tree( &mut self, tree: ast::UseTree, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> Option { if let Some(use_tree_list) = tree.use_tree_list() { let prefix = match tree.path() { @@ -1035,7 +1035,7 @@ impl UseTreeLowering<'_> { pub(crate) fn lower_use_tree( db: &dyn DefDatabase, tree: ast::UseTree, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> Option<(UseTree, Arena)> { let mut lowering = UseTreeLowering { db, mapping: Arena::new() }; let tree = lowering.lower_use_tree(tree, span_for_range)?; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 5f8cd0fde04ab..209ed46b7a85f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -85,7 +85,7 @@ use hir_expand::{ use item_tree::ExternBlock; use la_arena::Idx; use nameres::DefMap; -use span::{AstIdNode, Edition, FileAstId, SyntaxContextId}; +use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::impl_from; use syntax::{ast, AstNode}; @@ -1451,7 +1451,7 @@ impl AstIdWithPath { fn macro_call_as_call_id( db: &dyn ExpandDatabase, call: &AstIdWithPath, - call_site: SyntaxContextId, + call_site: SyntaxContext, expand_to: ExpandTo, krate: Crate, resolver: impl Fn(&path::ModPath) -> Option + Copy, @@ -1473,7 +1473,7 @@ fn macro_call_as_call_id_with_eager( db: &dyn ExpandDatabase, ast_id: AstId, path: &path::ModPath, - call_site: SyntaxContextId, + call_site: SyntaxContext, expand_to: ExpandTo, krate: Crate, resolver: impl FnOnce(&path::ModPath) -> Option, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index 289b9e2fb7e9f..c35a7fdc96d2a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -6,7 +6,7 @@ use hir_expand::{ inert_attr_macro::find_builtin_attr_idx, MacroCallId, MacroCallKind, MacroDefId, }; -use span::SyntaxContextId; +use span::SyntaxContext; use syntax::ast; use triomphe::Arc; @@ -137,7 +137,7 @@ pub(super) fn derive_macro_as_call_id( item_attr: &AstIdWithPath, derive_attr_index: AttrId, derive_pos: u32, - call_site: SyntaxContextId, + call_site: SyntaxContext, krate: Crate, resolver: impl Fn(&path::ModPath) -> Option<(MacroId, MacroDefId)>, derive_macro_id: MacroCallId, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 371e99433469f..43b011e57f46a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -20,7 +20,7 @@ use intern::{sym, Interned}; use itertools::{izip, Itertools}; use la_arena::Idx; use rustc_hash::{FxHashMap, FxHashSet}; -use span::{Edition, EditionedFileId, FileAstId, SyntaxContextId}; +use span::{Edition, EditionedFileId, FileAstId, SyntaxContext}; use syntax::ast; use triomphe::Arc; @@ -192,13 +192,13 @@ enum MacroDirectiveKind { FnLike { ast_id: AstIdWithPath, expand_to: ExpandTo, - ctxt: SyntaxContextId, + ctxt: SyntaxContext, }, Derive { ast_id: AstIdWithPath, derive_attr: AttrId, derive_pos: usize, - ctxt: SyntaxContextId, + ctxt: SyntaxContext, /// The "parent" macro it is resolved to. derive_macro_id: MacroCallId, }, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 0ed26ca853e80..997a12a328e10 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -7,7 +7,7 @@ use intern::{sym, Symbol}; use itertools::Itertools as _; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; -use span::SyntaxContextId; +use span::SyntaxContext; use triomphe::Arc; use crate::{ @@ -903,7 +903,7 @@ impl Resolver { fn handle_macro_def_scope( db: &dyn DefDatabase, hygiene_id: &mut HygieneId, - hygiene_info: &mut Option<(SyntaxContextId, MacroDefId)>, + hygiene_info: &mut Option<(SyntaxContext, MacroDefId)>, macro_id: &MacroDefId, ) { if let Some((parent_ctx, label_macro_id)) = hygiene_info { @@ -924,7 +924,7 @@ fn handle_macro_def_scope( fn hygiene_info( db: &dyn DefDatabase, hygiene_id: HygieneId, -) -> Option<(SyntaxContextId, MacroDefId)> { +) -> Option<(SyntaxContext, MacroDefId)> { if !hygiene_id.is_root() { let ctx = hygiene_id.lookup(); ctx.outer_expn(db).map(|expansion| { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index c4473e454a1bc..86a2d02a9f46e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -4,7 +4,7 @@ use std::iter; use intern::Interned; use la_arena::ArenaMap; -use span::SyntaxContextId; +use span::SyntaxContext; use syntax::ast; use triomphe::Arc; @@ -37,7 +37,7 @@ impl RawVisibility { pub(crate) fn from_ast( db: &dyn DefDatabase, node: Option, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> RawVisibility { let node = match node { None => return RawVisibility::private(), @@ -49,7 +49,7 @@ impl RawVisibility { fn from_ast_with_span_map( db: &dyn DefDatabase, node: ast::Visibility, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> RawVisibility { let path = match node.kind() { ast::VisibilityKind::In(path) => { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 64b9b49b3e472..6bfef1d28b720 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -8,7 +8,7 @@ use intern::{sym, Interned, Symbol}; use mbe::{DelimiterKind, Punct}; use smallvec::{smallvec, SmallVec}; -use span::{Span, SyntaxContextId}; +use span::{Span, SyntaxContext}; use syntax::unescape; use syntax::{ast, match_ast, AstNode, AstToken, SyntaxNode}; use syntax_bridge::{desugar_doc_comment_text, syntax_node_to_token_tree, DocCommentDesugarMode}; @@ -210,7 +210,7 @@ pub struct Attr { pub id: AttrId, pub path: Interned, pub input: Option>, - pub ctxt: SyntaxContextId, + pub ctxt: SyntaxContext, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs index 28b6812139446..ff50ccef0f48e 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs @@ -4,7 +4,7 @@ use intern::sym; use itertools::{izip, Itertools}; use parser::SyntaxKind; use rustc_hash::FxHashSet; -use span::{Edition, MacroCallId, Span, SyntaxContextId}; +use span::{Edition, MacroCallId, Span, SyntaxContext}; use stdx::never; use syntax_bridge::DocCommentDesugarMode; use tracing::debug; @@ -237,7 +237,7 @@ fn parse_adt( fn parse_adt_from_syntax( adt: &ast::Adt, - tm: &span::SpanMap, + tm: &span::SpanMap, call_site: Span, ) -> Result { let (name, generic_param_list, where_clause, shape) = match &adt { @@ -389,7 +389,7 @@ fn to_adt_syntax( db: &dyn ExpandDatabase, tt: &tt::TopSubtree, call_site: Span, -) -> Result<(ast::Adt, span::SpanMap), ExpandError> { +) -> Result<(ast::Adt, span::SpanMap), ExpandError> { let (parsed, tm) = crate::db::token_tree_to_syntax_node( db, tt, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs index a961df181db23..4c8eb74486bbf 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs @@ -226,7 +226,7 @@ mod tests { use ::tt::IdentIsRaw; use expect_test::expect; use intern::Symbol; - use span::{Edition, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; + use span::{Edition, SpanAnchor, SyntaxContext, ROOT_ERASED_FILE_AST_ID}; use syntax::{TextRange, TextSize}; use super::quote; @@ -240,7 +240,7 @@ mod tests { ), ast_id: ROOT_ERASED_FILE_AST_ID, }, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }; #[test] diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 112327f11e1a8..884d2a0b0b116 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -7,7 +7,7 @@ use rustc_hash::FxHashSet; use salsa::plumbing::AsId; use span::{ AstIdMap, Edition, EditionedFileId, HirFileId, HirFileIdRepr, MacroCallId, MacroFileId, Span, - SyntaxContextId, + SyntaxContext, }; use syntax::{ast, AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T}; use syntax_bridge::{syntax_node_to_token_tree, DocCommentDesugarMode}; @@ -96,10 +96,6 @@ pub trait ExpandDatabase: RootQueryDb { #[salsa::transparent] fn lookup_intern_macro_call(&self, macro_call: MacroCallId) -> MacroCallLoc; - #[salsa::transparent] - #[salsa::invoke(crate::hygiene::dump_syntax_contexts)] - fn dump_syntax_contexts(&self) -> String; - /// Lowers syntactic macro call to a token tree representation. That's a firewall /// query, only typing in the macro call itself changes the returned /// subtree. @@ -148,7 +144,7 @@ pub trait ExpandDatabase: RootQueryDb { ) -> Option>>>; #[salsa::transparent] - fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContextId; + fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContext; } #[salsa::interned(no_lifetime, id = span::MacroCallId)] @@ -164,14 +160,14 @@ fn lookup_intern_macro_call(db: &dyn ExpandDatabase, macro_call: MacroCallId) -> MacroCallWrapper::ingredient(db).data(db.as_dyn_database(), macro_call.as_id()).0.clone() } -#[salsa::interned(no_lifetime, id = span::SyntaxContextId)] +#[salsa::interned(no_lifetime, id = span::SyntaxContext)] pub struct SyntaxContextWrapper { - pub data: SyntaxContextId, + pub data: SyntaxContext, } -fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) -> SyntaxContextId { +fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) -> SyntaxContext { match file.repr() { - HirFileIdRepr::FileId(_) => SyntaxContextId::root(edition), + HirFileIdRepr::FileId(_) => SyntaxContext::root(edition), HirFileIdRepr::MacroFile(m) => { let kind = db.lookup_intern_macro_call(m.macro_call_id).kind; db.macro_arg_considering_derives(m.macro_call_id, &kind).2.ctx diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index fbce320756645..a0b614add4974 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -2,7 +2,7 @@ use base_db::Crate; use intern::sym; -use span::{Edition, HirFileIdRepr, MacroCallId, Span, SyntaxContextId}; +use span::{Edition, HirFileIdRepr, MacroCallId, Span, SyntaxContext}; use stdx::TupleExt; use syntax::{ast, AstNode}; use syntax_bridge::DocCommentDesugarMode; @@ -100,7 +100,7 @@ impl DeclarativeMacroExpander { _ => None, } }; - let ctx_edition = |ctx: SyntaxContextId| { + let ctx_edition = |ctx: SyntaxContext| { if ctx.is_root() { def_crate.data(db).edition } else { @@ -161,7 +161,7 @@ impl DeclarativeMacroExpander { }; let edition = ctx_edition(match id.file_id.repr() { HirFileIdRepr::MacroFile(macro_file) => macro_file.macro_call_id.lookup(db).ctxt, - HirFileIdRepr::FileId(file) => SyntaxContextId::root(file.edition()), + HirFileIdRepr::FileId(file) => SyntaxContext::root(file.edition()), }); Arc::new(DeclarativeMacroExpander { mac, transparency, edition }) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs index 02dc75a4a6d87..fcf3929eaab06 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs @@ -19,7 +19,7 @@ //! //! See the full discussion : use base_db::Crate; -use span::SyntaxContextId; +use span::SyntaxContext; use syntax::{ted, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent}; use syntax_bridge::DocCommentDesugarMode; use triomphe::Arc; @@ -38,7 +38,7 @@ pub fn expand_eager_macro_input( macro_call: &ast::MacroCall, ast_id: AstId, def: MacroDefId, - call_site: SyntaxContextId, + call_site: SyntaxContext, resolver: &dyn Fn(&ModPath) -> Option, ) -> ExpandResult> { let expand_to = ExpandTo::from_call_site(macro_call); @@ -116,7 +116,7 @@ fn lazy_expand( macro_call: &ast::MacroCall, ast_id: AstId, krate: Crate, - call_site: SyntaxContextId, + call_site: SyntaxContext, ) -> ExpandResult<(InFile>, Arc)> { let expand_to = ExpandTo::from_call_site(macro_call); let id = def.make_call( @@ -138,7 +138,7 @@ fn eager_macro_recur( mut offset: TextSize, curr: InFile, krate: Crate, - call_site: SyntaxContextId, + call_site: SyntaxContext, macro_resolver: &dyn Fn(&ModPath) -> Option, ) -> ExpandResult> { let original = curr.value.clone_for_update(); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs index 5810d11338cb9..3a26c62e1f200 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs @@ -4,7 +4,7 @@ use std::borrow::Borrow; use either::Either; use span::{ AstIdNode, EditionedFileId, ErasedFileAstId, FileAstId, HirFileId, HirFileIdRepr, MacroFileId, - SyntaxContextId, + SyntaxContext, }; use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize}; @@ -311,7 +311,7 @@ impl InFile<&SyntaxNode> { pub fn original_file_range_opt( self, db: &dyn db::ExpandDatabase, - ) -> Option<(FileRange, SyntaxContextId)> { + ) -> Option<(FileRange, SyntaxContext)> { self.borrow().map(SyntaxNode::text_range).original_node_file_range_opt(db) } } @@ -376,7 +376,7 @@ impl InFile { } impl InMacroFile { - pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> (FileRange, SyntaxContextId) { + pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> (FileRange, SyntaxContext) { span_for_offset(db, &db.expansion_span_map(self.file_id), self.value) } } @@ -385,17 +385,17 @@ impl InFile { pub fn original_node_file_range( self, db: &dyn db::ExpandDatabase, - ) -> (FileRange, SyntaxContextId) { + ) -> (FileRange, SyntaxContext) { match self.file_id.repr() { HirFileIdRepr::FileId(file_id) => { - (FileRange { file_id, range: self.value }, SyntaxContextId::root(file_id.edition())) + (FileRange { file_id, range: self.value }, SyntaxContext::root(file_id.edition())) } HirFileIdRepr::MacroFile(mac_file) => { match map_node_range_up(db, &db.expansion_span_map(mac_file), self.value) { Some(it) => it, None => { let loc = db.lookup_intern_macro_call(mac_file.macro_call_id); - (loc.kind.original_call_range(db), SyntaxContextId::root(loc.def.edition)) + (loc.kind.original_call_range(db), SyntaxContext::root(loc.def.edition)) } } } @@ -438,11 +438,11 @@ impl InFile { pub fn original_node_file_range_opt( self, db: &dyn db::ExpandDatabase, - ) -> Option<(FileRange, SyntaxContextId)> { + ) -> Option<(FileRange, SyntaxContext)> { match self.file_id.repr() { HirFileIdRepr::FileId(file_id) => Some(( FileRange { file_id, range: self.value }, - SyntaxContextId::root(file_id.edition()), + SyntaxContext::root(file_id.edition()), )), HirFileIdRepr::MacroFile(mac_file) => { map_node_range_up(db, &db.expansion_span_map(mac_file), self.value) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index 28894537d48f7..076dd75cde35f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -4,7 +4,7 @@ use intern::sym; use rustc_hash::{FxHashMap, FxHashSet}; use span::{ - ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, FIXUP_ERASED_FILE_AST_ID_MARKER, + ErasedFileAstId, Span, SpanAnchor, SyntaxContext, FIXUP_ERASED_FILE_AST_ID_MARKER, ROOT_ERASED_FILE_AST_ID, }; use stdx::never; @@ -353,7 +353,7 @@ pub(crate) fn reverse_fixups(tt: &mut TopSubtree, undo_info: &SyntaxFixupUndoInf let span = |file_id| Span { range: TextRange::empty(TextSize::new(0)), anchor: SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID }, - ctx: SyntaxContextId::root(span::Edition::Edition2015), + ctx: SyntaxContext::root(span::Edition::Edition2015), }; delimiter.open = span(delimiter.open.anchor.file_id); delimiter.close = span(delimiter.close.anchor.file_id); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs index b53468ccacdca..20694e7d6b80b 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs @@ -24,9 +24,9 @@ use std::{convert::identity, iter}; -use span::{Edition, MacroCallId, Span, SyntaxContextId}; +use span::{Edition, MacroCallId, Span, SyntaxContext}; -use crate::db::{ExpandDatabase, MacroCallWrapper}; +use crate::db::ExpandDatabase; pub use span::Transparency; @@ -65,18 +65,18 @@ fn span_with_ctxt_from_mark( edition: Edition, ) -> Span { Span { - ctx: apply_mark(db, SyntaxContextId::root(edition), expn_id, transparency, edition), + ctx: apply_mark(db, SyntaxContext::root(edition), expn_id, transparency, edition), ..span } } pub(super) fn apply_mark( db: &dyn ExpandDatabase, - ctxt: span::SyntaxContextId, + ctxt: span::SyntaxContext, call_id: span::MacroCallId, transparency: Transparency, edition: Edition, -) -> SyntaxContextId { +) -> SyntaxContext { if transparency == Transparency::Opaque { return apply_mark_internal(db, ctxt, call_id, transparency, edition); } @@ -109,11 +109,11 @@ pub(super) fn apply_mark( fn apply_mark_internal( db: &dyn ExpandDatabase, - ctxt: SyntaxContextId, + ctxt: SyntaxContext, call_id: MacroCallId, transparency: Transparency, edition: Edition, -) -> SyntaxContextId { +) -> SyntaxContext { let call_id = Some(call_id); let mut opaque = ctxt.opaque(db); @@ -121,18 +121,17 @@ fn apply_mark_internal( if transparency >= Transparency::Opaque { let parent = opaque; - opaque = - SyntaxContextId::new(db, call_id, transparency, edition, parent, identity, identity); + opaque = SyntaxContext::new(db, call_id, transparency, edition, parent, identity, identity); } if transparency >= Transparency::SemiTransparent { let parent = opaque_and_semitransparent; opaque_and_semitransparent = - SyntaxContextId::new(db, call_id, transparency, edition, parent, |_| opaque, identity); + SyntaxContext::new(db, call_id, transparency, edition, parent, |_| opaque, identity); } let parent = ctxt; - SyntaxContextId::new( + SyntaxContext::new( db, call_id, transparency, @@ -144,9 +143,9 @@ fn apply_mark_internal( } pub trait SyntaxContextExt { - fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId; - fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId; - fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId; + fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; + fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; + fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option, Transparency); fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency); @@ -154,14 +153,14 @@ pub trait SyntaxContextExt { fn is_opaque(self, db: &dyn ExpandDatabase) -> bool; } -impl SyntaxContextExt for SyntaxContextId { - fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId { +impl SyntaxContextExt for SyntaxContext { + fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContext { self.opaque_and_semitransparent(db) } - fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId { + fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContext { self.opaque(db) } - fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContextId { + fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContext { self.parent(db) } fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency) { @@ -188,7 +187,7 @@ impl SyntaxContextExt for SyntaxContextId { // FIXME: Make this a SyntaxContextExt method once we have RPIT pub fn marks_rev( - ctxt: SyntaxContextId, + ctxt: SyntaxContext, db: &dyn ExpandDatabase, ) -> impl Iterator + '_ { iter::successors(Some(ctxt), move |&mark| Some(mark.parent_ctxt(db))) @@ -200,53 +199,3 @@ pub fn marks_rev( (mark.0.unwrap(), mark.1) }) } - -pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String { - let mut s = String::from("Expansions:"); - let entries = - MacroCallWrapper::ingredient(db).entries(db.as_dyn_database()).collect::>(); - for loc in entries { - let expn_data = &loc.fields().0; - - s.push_str(&format!( - "parent: {:?}, call_site_ctxt: {:?}, kind: {:?}", - expn_data.kind.file_id(), - expn_data.ctxt, - expn_data.kind.descr(), - )); - } - - s.push_str("\n\nSyntaxContexts:\n"); - let entries = SyntaxContextId::ingredient(db).entries(db.as_dyn_database()).collect::>(); - for e in entries { - struct SyntaxContextDebug<'a>( - &'a dyn ExpandDatabase, - &'a span::SyntaxContextUnderlyingData, - ); - - impl std::fmt::Debug for SyntaxContextDebug<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fancy_debug(self.1, self.0, f) - } - } - - fn fancy_debug( - this: &span::SyntaxContextUnderlyingData, - db: &dyn ExpandDatabase, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - write!(f, "parent: #{}, outer_mark: (", this.parent)?; - match this.outer_expn { - Some(id) => { - write!(f, "{:?}::{{{{expn{:?}}}}}", db.lookup_intern_macro_call(id).krate, id)? - } - None => write!(f, "root")?, - } - write!(f, ", {:?})", this.outer_transparency) - } - - let dbg = SyntaxContextDebug(db, e.fields()); - stdx::format_to!(s, "{:?}\n", dbg); - } - s -} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index a1e484c08bcbf..ca5c40c9fac34 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -37,7 +37,7 @@ use base_db::Crate; use either::Either; use span::{ Edition, EditionedFileId, ErasedFileAstId, FileAstId, HirFileIdRepr, Span, SpanAnchor, - SyntaxContextId, + SyntaxContext, }; use syntax::{ ast::{self, AstNode}, @@ -252,7 +252,7 @@ pub struct MacroCallLoc { pub def: MacroDefId, pub krate: Crate, pub kind: MacroCallKind, - pub ctxt: SyntaxContextId, + pub ctxt: SyntaxContext, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -527,7 +527,7 @@ impl MacroDefId { db: &dyn ExpandDatabase, krate: Crate, kind: MacroCallKind, - ctxt: SyntaxContextId, + ctxt: SyntaxContext, ) -> MacroCallId { db.intern_macro_call(MacroCallLoc { def: self, krate, kind, ctxt }) } @@ -683,7 +683,7 @@ impl MacroCallLoc { } impl MacroCallKind { - fn descr(&self) -> &'static str { + pub fn descr(&self) -> &'static str { match self { MacroCallKind::FnLike { .. } => "macro call", MacroCallKind::Derive { .. } => "derive macro", @@ -831,7 +831,7 @@ impl ExpansionInfo { pub fn map_range_down_exact( &self, span: Span, - ) -> Option + '_>> { + ) -> Option + '_>> { let tokens = self.exp_map.ranges_with_span_exact(span).flat_map(move |(range, ctx)| { self.expanded.value.covering_element(range).into_token().zip(Some(ctx)) }); @@ -846,7 +846,7 @@ impl ExpansionInfo { pub fn map_range_down( &self, span: Span, - ) -> Option + '_>> { + ) -> Option + '_>> { let tokens = self.exp_map.ranges_with_span(span).flat_map(move |(range, ctx)| { self.expanded.value.covering_element(range).into_token().zip(Some(ctx)) }); @@ -859,7 +859,7 @@ impl ExpansionInfo { &self, db: &dyn ExpandDatabase, offset: TextSize, - ) -> (FileRange, SyntaxContextId) { + ) -> (FileRange, SyntaxContext) { debug_assert!(self.expanded.value.text_range().contains(offset)); span_for_offset(db, &self.exp_map, offset) } @@ -869,7 +869,7 @@ impl ExpansionInfo { &self, db: &dyn ExpandDatabase, range: TextRange, - ) -> Option<(FileRange, SyntaxContextId)> { + ) -> Option<(FileRange, SyntaxContext)> { debug_assert!(self.expanded.value.text_range().contains_range(range)); map_node_range_up(db, &self.exp_map, range) } @@ -953,7 +953,7 @@ pub fn map_node_range_up( db: &dyn ExpandDatabase, exp_map: &ExpansionSpanMap, range: TextRange, -) -> Option<(FileRange, SyntaxContextId)> { +) -> Option<(FileRange, SyntaxContext)> { let mut spans = exp_map.spans_for_range(range); let Span { range, anchor, ctx } = spans.next()?; let mut start = range.start(); @@ -980,7 +980,7 @@ pub fn map_node_range_up_aggregated( db: &dyn ExpandDatabase, exp_map: &ExpansionSpanMap, range: TextRange, -) -> FxHashMap<(SpanAnchor, SyntaxContextId), TextRange> { +) -> FxHashMap<(SpanAnchor, SyntaxContext), TextRange> { let mut map = FxHashMap::default(); for span in exp_map.spans_for_range(range) { let range = map.entry((span.anchor, span.ctx)).or_insert_with(|| span.range); @@ -1002,7 +1002,7 @@ pub fn span_for_offset( db: &dyn ExpandDatabase, exp_map: &ExpansionSpanMap, offset: TextSize, -) -> (FileRange, SyntaxContextId) { +) -> (FileRange, SyntaxContext) { let span = exp_map.span_at(offset); let anchor_offset = db .ast_id_map(span.anchor.file_id.into()) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 40b10cb4380af..5c160240a2ba2 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -14,7 +14,7 @@ use crate::{ use base_db::Crate; use intern::sym; use smallvec::SmallVec; -use span::{Edition, SyntaxContextId}; +use span::{Edition, SyntaxContext}; use syntax::{ast, AstNode}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -44,7 +44,7 @@ impl ModPath { pub fn from_src( db: &dyn ExpandDatabase, path: ast::Path, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> Option { convert_path(db, path, span_for_range) } @@ -209,7 +209,7 @@ fn display_fmt_path( fn convert_path( db: &dyn ExpandDatabase, path: ast::Path, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> Option { let mut segments = path.segments(); @@ -333,7 +333,7 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: tt::TokenTreesView<'_>) -> Optio Some(ModPath { kind, segments }) } -pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) -> Option { +pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContext) -> Option { // When resolving `$crate` from a `macro_rules!` invoked in a `macro`, // we don't want to pretend that the `macro_rules!` definition is in the `macro` // as described in `SyntaxContextId::apply_mark`, so we ignore prepended opaque marks. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 51721effa355d..79860a002afe7 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -3,7 +3,7 @@ use std::fmt; use intern::{sym, Symbol}; -use span::{Edition, SyntaxContextId}; +use span::{Edition, SyntaxContext}; use syntax::utils::is_raw_identifier; use syntax::{ast, format_smolstr}; @@ -74,7 +74,7 @@ impl Name { Name { symbol: Symbol::intern(text), ctx: () } } - pub fn new(text: &str, mut ctx: SyntaxContextId) -> Name { + pub fn new(text: &str, mut ctx: SyntaxContext) -> Name { // For comparisons etc. we remove the edition, because sometimes we search for some `Name` // and we don't know which edition it came from. // Can't do that for all `SyntaxContextId`s because it breaks Salsa. @@ -88,7 +88,7 @@ impl Name { pub fn new_root(text: &str) -> Name { // The edition doesn't matter for hygiene. - Self::new(text, SyntaxContextId::root(Edition::Edition2015)) + Self::new(text, SyntaxContext::root(Edition::Edition2015)) } pub fn new_tuple_field(idx: usize) -> Name { @@ -122,7 +122,7 @@ impl Name { } } - pub fn new_symbol(symbol: Symbol, ctx: SyntaxContextId) -> Self { + pub fn new_symbol(symbol: Symbol, ctx: SyntaxContext) -> Self { debug_assert!(!symbol.as_str().starts_with("r#")); _ = ctx; Self { symbol, ctx: () } @@ -130,7 +130,7 @@ impl Name { // FIXME: This needs to go once we have hygiene pub fn new_symbol_root(sym: Symbol) -> Self { - Self::new_symbol(sym, SyntaxContextId::root(Edition::Edition2015)) + Self::new_symbol(sym, SyntaxContext::root(Edition::Edition2015)) } /// A fake name for things missing in the source code. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs index cdf63e92a89b5..1330f6af9fd37 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs @@ -154,7 +154,7 @@ impl CrateProcMacros { /// Fetch the [`CustomProcMacroExpander`]s and their corresponding names for the given crate. pub fn list( &self, - def_site_ctx: span::SyntaxContextId, + def_site_ctx: span::SyntaxContext, ) -> Option> { match &self.0 { Ok(proc_macros) => Some( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs index ab99cb14f9562..55fe42e271f4d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs @@ -1,6 +1,6 @@ //! Span maps for real files and macro expansions. -use span::{EditionedFileId, HirFileId, HirFileIdRepr, MacroFileId, Span, SyntaxContextId}; +use span::{EditionedFileId, HirFileId, HirFileIdRepr, MacroFileId, Span, SyntaxContext}; use stdx::TupleExt; use syntax::{ast, AstNode, TextRange}; use triomphe::Arc; @@ -9,7 +9,7 @@ pub use span::RealSpanMap; use crate::{attrs::collect_attrs, db::ExpandDatabase}; -pub type ExpansionSpanMap = span::SpanMap; +pub type ExpansionSpanMap = span::SpanMap; /// Spanmap for a macro file or a real file #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 15cd69f320d33..b971b2e9f1a38 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -36,7 +36,7 @@ use intern::{sym, Symbol}; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::{smallvec, SmallVec}; -use span::{AstIdMap, EditionedFileId, FileId, HirFileIdRepr, SyntaxContextId}; +use span::{AstIdMap, EditionedFileId, FileId, HirFileIdRepr, SyntaxContext}; use stdx::TupleExt; use syntax::{ algo::skip_trivia_token, @@ -877,7 +877,7 @@ impl<'db> SemanticsImpl<'db> { pub fn descend_into_macros_cb( &self, token: SyntaxToken, - mut cb: impl FnMut(InFile, SyntaxContextId), + mut cb: impl FnMut(InFile, SyntaxContext), ) { if let Ok(token) = self.wrap_token_infile(token).into_real_file() { self.descend_into_macros_impl(token, &mut |t, ctx| { @@ -921,7 +921,7 @@ impl<'db> SemanticsImpl<'db> { pub fn descend_into_macros_breakable( &self, token: InRealFile, - mut cb: impl FnMut(InFile, SyntaxContextId) -> ControlFlow, + mut cb: impl FnMut(InFile, SyntaxContext) -> ControlFlow, ) -> Option { self.descend_into_macros_impl(token.clone(), &mut cb) } @@ -979,7 +979,7 @@ impl<'db> SemanticsImpl<'db> { fn descend_into_macros_impl( &self, InRealFile { value: token, file_id }: InRealFile, - f: &mut dyn FnMut(InFile, SyntaxContextId) -> ControlFlow, + f: &mut dyn FnMut(InFile, SyntaxContext) -> ControlFlow, ) -> Option { let _p = tracing::info_span!("descend_into_macros_impl").entered(); @@ -1016,7 +1016,7 @@ impl<'db> SemanticsImpl<'db> { None => { stack.push(( file_id.into(), - smallvec![(token, SyntaxContextId::root(file_id.edition()))], + smallvec![(token, SyntaxContext::root(file_id.edition()))], )); } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index a7584f67f118c..902ead977e582 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -29,7 +29,7 @@ use crate::{ use base_db::AnchoredPathBuf; use either::Either; use hir::{FieldSource, FileRange, HirFileIdExt, InFile, ModuleSource, Semantics}; -use span::{Edition, EditionedFileId, FileId, SyntaxContextId}; +use span::{Edition, EditionedFileId, FileId, SyntaxContext}; use stdx::{never, TupleExt}; use syntax::{ ast::{self, HasName}, @@ -113,7 +113,7 @@ impl Definition { /// renamed and extern crate names will report its range, though a rename will introduce /// an alias instead. pub fn range_for_rename(self, sema: &Semantics<'_, RootDatabase>) -> Option { - let syn_ctx_is_root = |(range, ctx): (_, SyntaxContextId)| ctx.is_root().then_some(range); + let syn_ctx_is_root = |(range, ctx): (_, SyntaxContext)| ctx.is_root().then_some(range); let res = match self { Definition::Macro(mac) => { let src = sema.source(mac)?; @@ -220,7 +220,7 @@ impl Definition { fn name_range( def: D, sema: &Semantics<'_, RootDatabase>, - ) -> Option<(FileRange, SyntaxContextId)> + ) -> Option<(FileRange, SyntaxContext)> where D: hir::HasSource, D::Ast: ast::HasName, diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 3771efc17b69d..a18eb9049ff67 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -4,7 +4,7 @@ use ide_db::{ base_db::Crate, helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase, }; -use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize}; +use span::{Edition, SpanMap, SyntaxContext, TextRange, TextSize}; use stdx::format_to; use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T}; @@ -142,7 +142,7 @@ fn expand_macro_recur( sema: &Semantics<'_, RootDatabase>, macro_call: &ast::Item, error: &mut String, - result_span_map: &mut SpanMap, + result_span_map: &mut SpanMap, offset_in_original_node: TextSize, ) -> Option { let ExpandResult { value: expanded, err } = match macro_call { @@ -170,7 +170,7 @@ fn expand( sema: &Semantics<'_, RootDatabase>, expanded: SyntaxNode, error: &mut String, - result_span_map: &mut SpanMap, + result_span_map: &mut SpanMap, mut offset_in_original_node: i32, ) -> SyntaxNode { let children = expanded.descendants().filter_map(ast::Item::cast); @@ -207,7 +207,7 @@ fn format( kind: SyntaxKind, file_id: FileId, expanded: SyntaxNode, - span_map: &SpanMap, + span_map: &SpanMap, krate: Crate, ) -> String { let expansion = prettify_macro_expansion(db, expanded, span_map, krate).to_string(); diff --git a/src/tools/rust-analyzer/crates/mbe/src/lib.rs b/src/tools/rust-analyzer/crates/mbe/src/lib.rs index bebd29ef74700..6bc019bf333e9 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/lib.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/lib.rs @@ -21,7 +21,7 @@ mod benchmark; #[cfg(test)] mod tests; -use span::{Edition, Span, SyntaxContextId}; +use span::{Edition, Span, SyntaxContext}; use syntax_bridge::to_parser_input; use tt::iter::TtIter; use tt::DelimSpan; @@ -149,7 +149,7 @@ impl DeclarativeMacro { /// The old, `macro_rules! m {}` flavor. pub fn parse_macro_rules( tt: &tt::TopSubtree, - ctx_edition: impl Copy + Fn(SyntaxContextId) -> Edition, + ctx_edition: impl Copy + Fn(SyntaxContext) -> Edition, ) -> DeclarativeMacro { // Note: this parsing can be implemented using mbe machinery itself, by // matching against `$($lhs:tt => $rhs:tt);*` pattern, but implementing @@ -189,7 +189,7 @@ impl DeclarativeMacro { pub fn parse_macro2( args: Option<&tt::TopSubtree>, body: &tt::TopSubtree, - ctx_edition: impl Copy + Fn(SyntaxContextId) -> Edition, + ctx_edition: impl Copy + Fn(SyntaxContext) -> Edition, ) -> DeclarativeMacro { let mut rules = Vec::new(); let mut err = None; @@ -262,7 +262,7 @@ impl DeclarativeMacro { impl Rule { fn parse( - edition: impl Copy + Fn(SyntaxContextId) -> Edition, + edition: impl Copy + Fn(SyntaxContext) -> Edition, src: &mut TtIter<'_, Span>, ) -> Result { let (_, lhs) = diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index 0a670053c9882..9d91387a07417 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use arrayvec::ArrayVec; use intern::{sym, Symbol}; -use span::{Edition, Span, SyntaxContextId}; +use span::{Edition, Span, SyntaxContext}; use tt::iter::{TtElement, TtIter}; use crate::ParseError; @@ -28,14 +28,14 @@ pub(crate) struct MetaTemplate(pub(crate) Box<[Op]>); impl MetaTemplate { pub(crate) fn parse_pattern( - edition: impl Copy + Fn(SyntaxContextId) -> Edition, + edition: impl Copy + Fn(SyntaxContext) -> Edition, pattern: TtIter<'_, Span>, ) -> Result { MetaTemplate::parse(edition, pattern, Mode::Pattern) } pub(crate) fn parse_template( - edition: impl Copy + Fn(SyntaxContextId) -> Edition, + edition: impl Copy + Fn(SyntaxContext) -> Edition, template: TtIter<'_, Span>, ) -> Result { MetaTemplate::parse(edition, template, Mode::Template) @@ -46,7 +46,7 @@ impl MetaTemplate { } fn parse( - edition: impl Copy + Fn(SyntaxContextId) -> Edition, + edition: impl Copy + Fn(SyntaxContext) -> Edition, mut src: TtIter<'_, Span>, mode: Mode, ) -> Result { @@ -179,7 +179,7 @@ enum Mode { } fn next_op( - edition: impl Copy + Fn(SyntaxContextId) -> Edition, + edition: impl Copy + Fn(SyntaxContext) -> Edition, first_peeked: TtElement<'_, Span>, src: &mut TtIter<'_, Span>, mode: Mode, @@ -287,7 +287,7 @@ fn next_op( } fn eat_fragment_kind( - edition: impl Copy + Fn(SyntaxContextId) -> Edition, + edition: impl Copy + Fn(SyntaxContext) -> Edition, src: &mut TtIter<'_, Span>, mode: Mode, ) -> Result, ParseError> { diff --git a/src/tools/rust-analyzer/crates/mbe/src/tests.rs b/src/tools/rust-analyzer/crates/mbe/src/tests.rs index 462c206bebfa7..7d9538a4b4dd6 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/tests.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/tests.rs @@ -3,7 +3,7 @@ // FIXME: Move more of the nameres independent tests from // crates\hir-def\src\macro_expansion_tests\mod.rs to this use expect_test::expect; -use span::{Edition, EditionedFileId, ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContextId}; +use span::{Edition, EditionedFileId, ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContext}; use stdx::format_to; use tt::{TextRange, TextSize}; @@ -26,7 +26,7 @@ fn check_( file_id: EditionedFileId::new(FileId::from_raw(0), def_edition), ast_id: ErasedFileAstId::from_raw(0), }, - SyntaxContextId::root(Edition::CURRENT), + SyntaxContext::root(Edition::CURRENT), decl, ) .unwrap(); @@ -42,7 +42,7 @@ fn check_( let arg_tt = syntax_bridge::parse_to_token_tree( call_edition, call_anchor, - SyntaxContextId::root(Edition::CURRENT), + SyntaxContext::root(Edition::CURRENT), arg, ) .unwrap(); @@ -52,7 +52,7 @@ fn check_( Span { range: TextRange::up_to(TextSize::of(arg)), anchor: call_anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, def_edition, ); diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs index 4b831e4acebb9..4178b04767a99 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs @@ -159,7 +159,7 @@ type ProtocolWrite = for<'o, 'msg> fn(out: &'o mut W, msg: &'msg str) #[cfg(test)] mod tests { use intern::{sym, Symbol}; - use span::{Edition, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange, TextSize}; + use span::{Edition, ErasedFileAstId, Span, SpanAnchor, SyntaxContext, TextRange, TextSize}; use tt::{ Delimiter, DelimiterKind, Ident, Leaf, Literal, Punct, Spacing, TopSubtree, TopSubtreeBuilder, @@ -180,12 +180,12 @@ mod tests { open: Span { range: TextRange::empty(TextSize::new(0)), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, close: Span { range: TextRange::empty(TextSize::new(19)), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, kind: DelimiterKind::Invisible, }); @@ -196,7 +196,7 @@ mod tests { span: Span { range: TextRange::at(TextSize::new(0), TextSize::of("struct")), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, is_raw: tt::IdentIsRaw::No, } @@ -208,7 +208,7 @@ mod tests { span: Span { range: TextRange::at(TextSize::new(5), TextSize::of("r#Foo")), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, is_raw: tt::IdentIsRaw::Yes, } @@ -219,7 +219,7 @@ mod tests { span: Span { range: TextRange::at(TextSize::new(10), TextSize::of("\"Foo\"")), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, kind: tt::LitKind::Str, suffix: None, @@ -229,7 +229,7 @@ mod tests { span: Span { range: TextRange::at(TextSize::new(13), TextSize::of('@')), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, spacing: Spacing::Joint, })); @@ -238,7 +238,7 @@ mod tests { Span { range: TextRange::at(TextSize::new(14), TextSize::of('{')), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, ); builder.push(Leaf::Literal(Literal { @@ -246,7 +246,7 @@ mod tests { span: Span { range: TextRange::at(TextSize::new(15), TextSize::of("0u32")), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }, kind: tt::LitKind::Integer, suffix: Some(sym::u32.clone()), @@ -254,7 +254,7 @@ mod tests { builder.close(Span { range: TextRange::at(TextSize::new(19), TextSize::of('}')), anchor, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }); builder.build() diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs index c194f301714fc..101c4b3105ad0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs @@ -40,9 +40,7 @@ use std::collections::VecDeque; use intern::Symbol; use rustc_hash::FxHashMap; use serde_derive::{Deserialize, Serialize}; -use span::{ - EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange, TokenId, -}; +use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContext, TextRange, TokenId}; use crate::legacy_protocol::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA}; @@ -74,7 +72,7 @@ pub fn deserialize_span_data_index_map(map: &[u32]) -> SpanDataIndexMap { ast_id: ErasedFileAstId::from_raw(ast_id), }, range: TextRange::new(start.into(), end.into()), - ctx: SyntaxContextId::from_u32(e), + ctx: SyntaxContext::from_u32(e), } }) .collect() diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 59293ee3f9659..f7cb0ab4655fa 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -428,7 +428,7 @@ impl server::Server for RaSpanServer { #[cfg(test)] mod tests { - use span::{EditionedFileId, FileId, SyntaxContextId}; + use span::{EditionedFileId, FileId, SyntaxContext}; use super::*; @@ -440,7 +440,7 @@ mod tests { file_id: EditionedFileId::current_edition(FileId::from_raw(0)), ast_id: span::ErasedFileAstId::from_raw(0), }, - ctx: SyntaxContextId::root(span::Edition::CURRENT), + ctx: SyntaxContext::root(span::Edition::CURRENT), }; let s = TokenStream { token_trees: vec![ @@ -482,7 +482,7 @@ mod tests { file_id: EditionedFileId::current_edition(FileId::from_raw(0)), ast_id: span::ErasedFileAstId::from_raw(0), }, - ctx: SyntaxContextId::root(span::Edition::CURRENT), + ctx: SyntaxContext::root(span::Edition::CURRENT), }; let subtree_paren_a = vec![ tt::TokenTree::Subtree(tt::Subtree { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 1b085520d5656..584a27468f847 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -1,7 +1,7 @@ //! utils used in proc-macro tests use expect_test::Expect; -use span::{EditionedFileId, ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContextId, TokenId}; +use span::{EditionedFileId, ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContext, TokenId}; use tt::TextRange; use crate::{dylib, proc_macro_test_dylib_path, EnvSnapshot, ProcMacroSrv}; @@ -17,7 +17,7 @@ fn parse_string(call_site: TokenId, src: &str) -> crate::server_impl::TokenStrea fn parse_string_spanned( anchor: SpanAnchor, - call_site: SyntaxContextId, + call_site: SyntaxContext, src: &str, ) -> crate::server_impl::TokenStream { crate::server_impl::TokenStream::with_subtree(crate::server_impl::TopSubtree( @@ -81,7 +81,7 @@ fn assert_expand_impl( file_id: EditionedFileId::current_edition(FileId::from_raw(41)), ast_id: ErasedFileAstId::from_raw(1), }, - ctx: SyntaxContextId::root(span::Edition::CURRENT), + ctx: SyntaxContext::root(span::Edition::CURRENT), }; let call_site = Span { range: TextRange::new(0.into(), 100.into()), @@ -89,7 +89,7 @@ fn assert_expand_impl( file_id: EditionedFileId::current_edition(FileId::from_raw(42)), ast_id: ErasedFileAstId::from_raw(2), }, - ctx: SyntaxContextId::root(span::Edition::CURRENT), + ctx: SyntaxContext::root(span::Edition::CURRENT), }; let mixed_site = call_site; diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index a6402e870150e..7cb1676a29de8 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -23,9 +23,6 @@ use std::fmt; use crate::{Edition, MacroCallId}; -// Recursive expansion of interned macro -// ====================================== - /// A syntax context describes a hierarchy tracking order of macro definitions. #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub struct SyntaxContext( @@ -33,22 +30,21 @@ pub struct SyntaxContext( std::marker::PhantomData<&'static salsa::plumbing::interned::Value>, ); -/// The underlying data interned by Salsa. -#[derive(Clone, Eq, Debug)] -pub struct SyntaxContextUnderlyingData { - pub outer_expn: Option, - pub outer_transparency: Transparency, - pub edition: Edition, - pub parent: SyntaxContext, - pub opaque: SyntaxContext, - pub opaque_and_semitransparent: SyntaxContext, -} - const _: () = { use salsa::plumbing as zalsa_; use salsa::plumbing::interned as zalsa_struct_; - impl PartialEq for SyntaxContextUnderlyingData { + #[derive(Clone, Eq, Debug)] + pub struct SyntaxContextData { + outer_expn: Option, + outer_transparency: Transparency, + edition: Edition, + parent: SyntaxContext, + opaque: SyntaxContext, + opaque_and_semitransparent: SyntaxContext, + } + + impl PartialEq for SyntaxContextData { fn eq(&self, other: &Self) -> bool { self.outer_expn == other.outer_expn && self.outer_transparency == other.outer_transparency @@ -57,7 +53,7 @@ const _: () = { } } - impl std::hash::Hash for SyntaxContextUnderlyingData { + impl std::hash::Hash for SyntaxContextData { fn hash(&self, state: &mut H) { self.outer_expn.hash(state); self.outer_transparency.hash(state); @@ -71,7 +67,7 @@ const _: () = { struct StructKey<'db, T0, T1, T2, T3>(T0, T1, T2, T3, std::marker::PhantomData<&'db ()>); impl<'db, T0, T1, T2, T3> zalsa_::interned::HashEqLike> - for SyntaxContextUnderlyingData + for SyntaxContextData where Option: zalsa_::interned::HashEqLike, Transparency: zalsa_::interned::HashEqLike, @@ -93,7 +89,7 @@ const _: () = { } impl zalsa_struct_::Configuration for SyntaxContext { const DEBUG_NAME: &'static str = "SyntaxContextData"; - type Fields<'a> = SyntaxContextUnderlyingData; + type Fields<'a> = SyntaxContextData; type Struct<'a> = SyntaxContext; fn struct_from_id<'db>(id: salsa::Id) -> Self::Struct<'db> { SyntaxContext(id, std::marker::PhantomData) @@ -189,7 +185,7 @@ const _: () = { parent, std::marker::PhantomData, ), - |id, data| SyntaxContextUnderlyingData { + |id, data| SyntaxContextData { outer_expn: zalsa_::interned::Lookup::into_owned(data.0), outer_transparency: zalsa_::interned::Lookup::into_owned(data.1), edition: zalsa_::interned::Lookup::into_owned(data.2), diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index 7abdacee2b970..fbd1b25cffcaf 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -11,9 +11,6 @@ pub use self::{ map::{RealSpanMap, SpanMap}, }; -// Remove this -pub use self::hygiene::{SyntaxContext as SyntaxContextId, SyntaxContextUnderlyingData}; - pub use syntax::Edition; pub use text_size::{TextRange, TextSize}; pub use vfs::FileId; @@ -31,7 +28,7 @@ pub const FIXUP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId = // is required to be stable for the proc-macro-server ErasedFileAstId::from_raw(!0 - 1); -pub type Span = SpanData; +pub type Span = SpanData; impl Span { pub fn cover(self, other: Span) -> Span { diff --git a/src/tools/rust-analyzer/crates/span/src/map.rs b/src/tools/rust-analyzer/crates/span/src/map.rs index dc35de67fd8db..9eb22d6e0b931 100644 --- a/src/tools/rust-analyzer/crates/span/src/map.rs +++ b/src/tools/rust-analyzer/crates/span/src/map.rs @@ -6,7 +6,7 @@ use std::{fmt, hash::Hash}; use stdx::{always, itertools::Itertools}; use crate::{ - EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SpanData, SyntaxContextId, TextRange, + EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SpanData, SyntaxContext, TextRange, TextSize, ROOT_ERASED_FILE_AST_ID, }; @@ -208,7 +208,7 @@ impl RealSpanMap { Span { range: range - offset, anchor: SpanAnchor { file_id: self.file_id, ast_id }, - ctx: SyntaxContextId::root(self.file_id.edition()), + ctx: SyntaxContext::root(self.file_id.edition()), } } } diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index a59a3270c9d9d..2dde236f0d279 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -45,7 +45,7 @@ impl> SpanMapper for &SM { /// Dummy things for testing where spans don't matter. pub mod dummy_test_span_utils { - use span::{Span, SyntaxContextId}; + use span::{Span, SyntaxContext}; use super::*; @@ -58,7 +58,7 @@ pub mod dummy_test_span_utils { ), ast_id: span::ROOT_ERASED_FILE_AST_ID, }, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), }; pub struct DummyTestSpanMap; @@ -74,7 +74,7 @@ pub mod dummy_test_span_utils { ), ast_id: span::ROOT_ERASED_FILE_AST_ID, }, - ctx: SyntaxContextId::root(Edition::CURRENT), + ctx: SyntaxContext::root(Edition::CURRENT), } } } From 3bec5066bc1575a4ca0964439bb3874a037e65bc Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 15 Mar 2025 21:27:18 +0200 Subject: [PATCH 029/260] Do not error for actions with no data to resolve Same as the other resolve code handlers in the same file. https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#version_3_17_0 does not forbid resolving with no data, so instead of erroring, just consider such items resolved already. --- .../rust-analyzer/crates/rust-analyzer/src/handlers/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 170481ea70164..5f27567c31ed7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -1480,7 +1480,7 @@ pub(crate) fn handle_code_action_resolve( ) -> anyhow::Result { let _p = tracing::info_span!("handle_code_action_resolve").entered(); let Some(params) = code_action.data.take() else { - return Err(invalid_params_error("code action without data".to_owned()).into()); + return Ok(code_action); }; let file_id = from_proto::file_id(&snap, ¶ms.code_action_params.text_document.uri)? From c6033c831dfac958d2365501d164a390b511de8c Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 15 Mar 2025 12:31:56 -0700 Subject: [PATCH 030/260] refactor: Simplify by removing ? operator `out.flush()` already returns a `io::Result<()>`, so there is no need for `?` operator and `Ok(())` --- .../crates/proc-macro-api/src/legacy_protocol/json.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs index ec89f6a9e65d2..30e35f8f14343 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs @@ -30,6 +30,5 @@ pub fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> { tracing::debug!("> {}", msg); out.write_all(msg.as_bytes())?; out.write_all(b"\n")?; - out.flush()?; - Ok(()) + out.flush() } From b12d934cede0092b26d642f8fdcca80a44d6c563 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Mon, 10 Mar 2025 12:37:43 +0100 Subject: [PATCH 031/260] Fix 2024 syntax errors --- .../hir-expand/src/builtin/derive_macro.rs | 26 +++++++++---------- .../crates/hir-expand/src/builtin/fn_macro.rs | 4 +-- .../crates/hir-expand/src/builtin/quote.rs | 2 +- .../crates/hir-ty/src/mir/lower.rs | 4 +-- src/tools/rust-analyzer/crates/hir/src/lib.rs | 7 +++-- .../rust-analyzer/crates/hir/src/semantics.rs | 2 +- .../crates/ide-diagnostics/src/lib.rs | 3 ++- .../crates/ide/src/inlay_hints/lifetime.rs | 4 +-- .../crates/rust-analyzer/src/bin/main.rs | 6 +++-- .../rust-analyzer/tests/slow-tests/support.rs | 3 ++- .../crates/syntax/src/ast/node_ext.rs | 2 +- 11 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs index ff50ccef0f48e..149ab73ec5477 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs @@ -117,7 +117,7 @@ impl VariantShape { quote! {span => #it : #mapped , } }); quote! {span => - #path { ##fields } + #path { # #fields } } } &VariantShape::Tuple(n) => { @@ -128,7 +128,7 @@ impl VariantShape { } }); quote! {span => - #path ( ##fields ) + #path ( # #fields ) } } VariantShape::Unit => path, @@ -523,7 +523,7 @@ fn expand_simple_derive_with_parsed( let name = info.name; quote! {invoc_span => - impl < ##params #extra_impl_params > #trait_path for #name < ##args > where ##where_block { #trait_body } + impl < # #params #extra_impl_params > #trait_path for #name < # #args > where # #where_block { #trait_body } } } @@ -572,7 +572,7 @@ fn clone_expand( quote! {span => fn clone(&self) -> Self { match self { - ##arms + # #arms } } } @@ -650,7 +650,7 @@ fn debug_expand( } }); quote! {span => - f.debug_struct(#name) ##for_fields .finish() + f.debug_struct(#name) # #for_fields .finish() } } VariantShape::Tuple(n) => { @@ -660,7 +660,7 @@ fn debug_expand( } }); quote! {span => - f.debug_tuple(#name) ##for_fields .finish() + f.debug_tuple(#name) # #for_fields .finish() } } VariantShape::Unit => quote! {span => @@ -703,7 +703,7 @@ fn debug_expand( quote! {span => fn fmt(&self, f: &mut #krate::fmt::Formatter) -> #krate::fmt::Result { match self { - ##arms + # #arms } } } @@ -736,7 +736,7 @@ fn hash_expand( let it = names.iter().map(|it| quote! {span => #it . hash(ra_expand_state); }); quote! {span => { - ##it + # #it } } }; let fat_arrow = fat_arrow(span); @@ -754,7 +754,7 @@ fn hash_expand( fn hash(&self, ra_expand_state: &mut H) { #check_discriminant match self { - ##arms + # #arms } } } @@ -803,7 +803,7 @@ fn partial_eq_expand( let t2 = tt::Ident::new(&format!("{}_other", first.sym), first.span); quote!(span =>#t1 .eq( #t2 )) }; - quote!(span =>#first ##rest) + quote!(span =>#first # #rest) } }; quote! {span => ( #pat1 , #pat2 ) #fat_arrow #body , } @@ -814,7 +814,7 @@ fn partial_eq_expand( quote! {span => fn eq(&self, other: &Self) -> bool { match (self, other) { - ##arms + # #arms _unused #fat_arrow false } } @@ -891,7 +891,7 @@ fn ord_expand( let fat_arrow = fat_arrow(span); let mut body = quote! {span => match (self, other) { - ##arms + # #arms _unused #fat_arrow #krate::cmp::Ordering::Equal } }; @@ -961,7 +961,7 @@ fn partial_ord_expand( right, quote! {span => match (self, other) { - ##arms + # #arms _unused #fat_arrow #krate::option::Option::Some(#krate::cmp::Ordering::Equal) } }, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index b56ec3d04c07e..2fb1f96350cd5 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -240,9 +240,9 @@ fn assert_expand( let dollar_crate = dollar_crate(span); let panic_args = rest.iter(); let mac = if use_panic_2021(db, span) { - quote! {call_site_span => #dollar_crate::panic::panic_2021!(##panic_args) } + quote! {call_site_span => #dollar_crate::panic::panic_2021!(# #panic_args) } } else { - quote! {call_site_span => #dollar_crate::panic!(##panic_args) } + quote! {call_site_span => #dollar_crate::panic!(# #panic_args) } }; let value = cond.value; let expanded = quote! {call_site_span =>{ diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs index 4c8eb74486bbf..9dd2b77b525c4 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs @@ -61,7 +61,7 @@ macro_rules! quote_impl__ { $crate::builtin::quote::__quote!($span $builder $($tail)*); }; - ($span:ident $builder:ident ## $first:ident $($tail:tt)* ) => {{ + ($span:ident $builder:ident # # $first:ident $($tail:tt)* ) => {{ ::std::iter::IntoIterator::into_iter($first).for_each(|it| $crate::builtin::quote::ToTokenTree::to_tokens(it, $span, $builder)); $crate::builtin::quote::__quote!($span $builder $($tail)*); }}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 102048b3f4dca..38924d7c95495 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -518,7 +518,7 @@ impl<'ctx> MirLowerCtx<'ctx> { let Some(def) = self.owner.as_generic_def_id(self.db.upcast()) else { not_supported!("owner without generic def id"); }; - let gen = generics(self.db.upcast(), def); + let generics = generics(self.db.upcast(), def); let ty = self.expr_ty_without_adjust(expr_id); self.push_assignment( current, @@ -528,7 +528,7 @@ impl<'ctx> MirLowerCtx<'ctx> { ty, value: chalk_ir::ConstValue::BoundVar(BoundVar::new( DebruijnIndex::INNERMOST, - gen.type_or_const_param_idx(p.into()).ok_or( + generics.type_or_const_param_idx(p.into()).ok_or( MirLowerError::TypeError( "fail to lower const generic param", ), diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 9f91f155ea77b..caf00665a1e6b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -5261,7 +5261,7 @@ impl Type { /// Returns types that this type dereferences to (including this type itself). The returned /// iterator won't yield the same type more than once even if the deref chain contains a cycle. - pub fn autoderef(&self, db: &dyn HirDatabase) -> impl Iterator + '_ { + pub fn autoderef<'db>(&self, db: &'db dyn HirDatabase) -> impl Iterator + use<'_, 'db> { self.autoderef_(db).map(move |ty| self.derived(ty)) } @@ -5637,7 +5637,10 @@ impl Type { .map(Trait::from) } - pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option> { + pub fn as_impl_traits( + &self, + db: &dyn HirDatabase, + ) -> Option + use<>> { self.ty.impl_trait_bounds(db).map(|it| { it.into_iter().filter_map(|pred| match pred.skip_binders() { hir_ty::WhereClause::Implemented(trait_ref) => { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index b971b2e9f1a38..a1c0521a5eb57 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -2087,7 +2087,7 @@ impl SemanticsScope<'_> { ) } - pub fn resolve_mod_path(&self, path: &ModPath) -> impl Iterator { + pub fn resolve_mod_path(&self, path: &ModPath) -> impl Iterator + use<> { let items = self.resolver.resolve_module_path_in_items(self.db.upcast(), path); items.iter_items().map(|(item, _)| item.into()) } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index dc6fd1f5eaeb7..c6f60a9a9654e 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -780,7 +780,8 @@ fn fill_lint_attrs( } }); - let all_matching_groups = lint_groups(&diag.code, edition) + let lints = lint_groups(&diag.code, edition); + let all_matching_groups = lints .iter() .filter_map(|lint_group| cached.get(lint_group)); let cached_severity = diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs index 1fdd698991710..7b0b3e19f2f08 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs @@ -268,13 +268,13 @@ fn hints_( ctx.lifetime_stacks.iter().flat_map(|it| it.iter()).cloned().zip(iter::repeat(0)).collect(); // allocate names let mut gen_idx_name = { - let mut gen = (0u8..).map(|idx| match idx { + let mut generic = (0u8..).map(|idx| match idx { idx if idx < 10 => SmolStr::from_iter(['\'', (idx + 48) as char]), idx => format_smolstr!("'{idx}"), }); let ctx = &*ctx; move || { - gen.by_ref() + generic.by_ref() .find(|s| ctx.lifetime_stacks.iter().flat_map(|it| it.iter()).all(|n| n != s)) .unwrap_or_default() } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs index 1a9cdef256d28..f2e96197ecd9e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs @@ -123,13 +123,15 @@ fn setup_logging(log_file_flag: Option) -> anyhow::Result<()> { // https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-syminitialize if let Ok(path) = env::current_exe() { if let Some(path) = path.parent() { - env::set_var("_NT_SYMBOL_PATH", path); + // SAFETY: This is safe because this is single-threaded. + unsafe { env::set_var("_NT_SYMBOL_PATH", path); } } } } if env::var("RUST_BACKTRACE").is_err() { - env::set_var("RUST_BACKTRACE", "short"); + // SAFETY: This is safe because this is single-threaded. + unsafe { env::set_var("RUST_BACKTRACE", "short"); } } let log_file = env::var("RA_LOG_FILE").ok().map(PathBuf::from).or(log_file_flag); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index 1f52f366c5469..8496068d67665 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -148,7 +148,8 @@ impl Project<'_> { let guard = CONFIG_DIR_LOCK.lock(); let test_dir = TestDir::new(); let value = test_dir.path().to_owned(); - env::set_var("__TEST_RA_USER_CONFIG_DIR", &value); + // SAFETY: This is safe because this is single-threaded. + unsafe { env::set_var("__TEST_RA_USER_CONFIG_DIR", &value); } (guard, test_dir) }) } else { diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 56f94b965e320..2b330f085866a 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -1066,7 +1066,7 @@ impl ast::GenericParamList { ast::GenericParam::TypeParam(_) | ast::GenericParam::ConstParam(_) => None, }) } - pub fn type_or_const_params(&self) -> impl Iterator { + pub fn type_or_const_params(&self) -> impl Iterator + use<> { self.generic_params().filter_map(|param| match param { ast::GenericParam::TypeParam(it) => Some(ast::TypeOrConstParam::Type(it)), ast::GenericParam::LifetimeParam(_) => None, From ebb85886abb8ea49c922601d6166b30e9e9cc8b3 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Mon, 10 Mar 2025 12:41:24 +0100 Subject: [PATCH 032/260] rust-version = "1.85" --- src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml | 2 +- src/tools/rust-analyzer/lib/la-arena/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml index c2c6dac72de1e..4d639777c3292 100644 --- a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml @@ -3,7 +3,7 @@ name = "syntax-fuzz" version = "0.0.1" publish = false edition = "2021" -rust-version = "1.78" +rust-version = "1.85" [package.metadata] cargo-fuzz = true diff --git a/src/tools/rust-analyzer/lib/la-arena/Cargo.toml b/src/tools/rust-analyzer/lib/la-arena/Cargo.toml index 589d026142bb7..5fb53a7a557ed 100644 --- a/src/tools/rust-analyzer/lib/la-arena/Cargo.toml +++ b/src/tools/rust-analyzer/lib/la-arena/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/la-aren documentation = "https://docs.rs/la-arena" categories = ["data-structures", "memory-management", "rust-patterns"] edition = "2021" -rust-version = "1.56" +rust-version = "1.85" [lints] workspace = true From 87228245cf4e4ada84709b98e12f36db22b40a9e Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Mon, 10 Mar 2025 12:41:35 +0100 Subject: [PATCH 033/260] edition = "2024" --- src/tools/rust-analyzer/Cargo.toml | 2 +- .../crates/proc-macro-srv/proc-macro-test/Cargo.toml | 2 +- .../crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml | 2 +- src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml | 2 +- src/tools/rust-analyzer/docs/book/book.toml | 2 +- src/tools/rust-analyzer/lib/la-arena/Cargo.toml | 2 +- src/tools/rust-analyzer/lib/line-index/Cargo.toml | 2 +- src/tools/rust-analyzer/lib/lsp-server/Cargo.toml | 2 +- src/tools/rust-analyzer/xtask/Cargo.toml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index e9d70bea346dc..03ecc8f2741e3 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" [workspace.package] rust-version = "1.85" -edition = "2021" +edition = "2024" license = "MIT OR Apache-2.0" authors = ["rust-analyzer team"] repository = "https://github.com/rust-lang/rust-analyzer" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml index 16fcc92962072..2a5bfdd2572f4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml @@ -3,7 +3,7 @@ name = "proc-macro-test" version = "0.0.0" publish = false -edition = "2021" +edition = "2024" license = "MIT OR Apache-2.0" [lib] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml index fb98d758a8b7b..33b7c2bb0ad66 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml @@ -2,7 +2,7 @@ name = "proc-macro-test-impl" version = "0.0.0" license = "MIT OR Apache-2.0" -edition = "2021" +edition = "2024" publish = false [lib] diff --git a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml index 4d639777c3292..8910911ff0259 100644 --- a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml @@ -2,7 +2,7 @@ name = "syntax-fuzz" version = "0.0.1" publish = false -edition = "2021" +edition = "2024" rust-version = "1.85" [package.metadata] diff --git a/src/tools/rust-analyzer/docs/book/book.toml b/src/tools/rust-analyzer/docs/book/book.toml index a6f6a6ed784db..edf11fadf0831 100644 --- a/src/tools/rust-analyzer/docs/book/book.toml +++ b/src/tools/rust-analyzer/docs/book/book.toml @@ -6,7 +6,7 @@ src = "src" title = "rust-analyzer" [rust] -edition = "2021" +edition = "2024" [output.html] edit-url-template = "https://github.com/rust-lang/rust-analyzer/edit/master/docs/book/{path}" diff --git a/src/tools/rust-analyzer/lib/la-arena/Cargo.toml b/src/tools/rust-analyzer/lib/la-arena/Cargo.toml index 5fb53a7a557ed..1c330e0e37e17 100644 --- a/src/tools/rust-analyzer/lib/la-arena/Cargo.toml +++ b/src/tools/rust-analyzer/lib/la-arena/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/la-arena" documentation = "https://docs.rs/la-arena" categories = ["data-structures", "memory-management", "rust-patterns"] -edition = "2021" +edition = "2024" rust-version = "1.85" [lints] diff --git a/src/tools/rust-analyzer/lib/line-index/Cargo.toml b/src/tools/rust-analyzer/lib/line-index/Cargo.toml index 14196ba3d0973..f15c2e39372da 100644 --- a/src/tools/rust-analyzer/lib/line-index/Cargo.toml +++ b/src/tools/rust-analyzer/lib/line-index/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.2" description = "Maps flat `TextSize` offsets to/from `(line, column)` representation." license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/line-index" -edition = "2021" +edition = "2024" [dependencies] text-size = "1.1.1" diff --git a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml index 2fa3272e6593f..39b931561bda8 100644 --- a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml +++ b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml @@ -4,7 +4,7 @@ version = "0.7.8" description = "Generic LSP server scaffold." license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server" -edition = "2021" +edition = "2024" [dependencies] log = "0.4.17" diff --git a/src/tools/rust-analyzer/xtask/Cargo.toml b/src/tools/rust-analyzer/xtask/Cargo.toml index ebd8903ad8ac3..01a561dcb9f38 100644 --- a/src/tools/rust-analyzer/xtask/Cargo.toml +++ b/src/tools/rust-analyzer/xtask/Cargo.toml @@ -3,7 +3,7 @@ name = "xtask" version = "0.1.0" publish = false license = "MIT OR Apache-2.0" -edition = "2021" +edition = "2024" rust-version.workspace = true [dependencies] From b5b7a54e95f6a9220008f6e2cb95e2d03fe97e1c Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Mon, 10 Mar 2025 12:41:51 +0100 Subject: [PATCH 034/260] cargo clippy --fix --- .../rust-analyzer/crates/hir-def/src/item_tree/lower.rs | 2 +- src/tools/rust-analyzer/crates/hir-ty/src/builder.rs | 6 +++--- src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs | 4 ++-- src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs | 4 ++-- .../rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs | 2 +- src/tools/rust-analyzer/crates/ide/src/signature_help.rs | 6 +++--- .../rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index b0cc7ead8c0dd..3c85d5bacb459 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -932,7 +932,7 @@ impl<'a> Ctx<'a> { fn desugar_future_path(ctx: &mut LowerCtx<'_>, orig: TypeRefId) -> PathId { let path = path![core::future::Future]; let mut generic_args: Vec<_> = - std::iter::repeat(None).take(path.segments().len() - 1).collect(); + std::iter::repeat_n(None, path.segments().len() - 1).collect(); let binding = AssociatedTypeBinding { name: Name::new_symbol_root(sym::Output.clone()), args: None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs index 76d9c60f6f903..4c35db0c9b98c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs @@ -263,7 +263,7 @@ impl TyBuilder<()> { .as_generic_def_id(db.upcast()) .map(|p| generics(db.upcast(), p).placeholder_subst(db)); // These represent resume type, yield type, and return type of coroutine. - let params = std::iter::repeat(ParamKind::Type).take(3).collect(); + let params = std::iter::repeat_n(ParamKind::Type, 3).collect(); TyBuilder::new((), params, parent_subst) } @@ -340,7 +340,7 @@ impl TyBuilder { pub struct Tuple(usize); impl TyBuilder { pub fn tuple(size: usize) -> TyBuilder { - TyBuilder::new(Tuple(size), iter::repeat(ParamKind::Type).take(size).collect(), None) + TyBuilder::new(Tuple(size), std::iter::repeat_n(ParamKind::Type, size).collect(), None) } pub fn build(self) -> Ty { @@ -356,7 +356,7 @@ impl TyBuilder { let elements = elements.into_iter(); let len = elements.len(); let mut b = - TyBuilder::new(Tuple(len), iter::repeat(ParamKind::Type).take(len).collect(), None); + TyBuilder::new(Tuple(len), std::iter::repeat_n(ParamKind::Type, len).collect(), None); for e in elements { b = b.push(e); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index e55fc0a9b83d9..6d80bfc38e5b7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -1,6 +1,6 @@ //! Unification and canonicalization logic. -use std::{fmt, iter, mem}; +use std::{fmt, mem}; use chalk_ir::{ cast::Cast, fold::TypeFoldable, interner::HasInterner, zip::Zip, CanonicalVarKind, FloatTy, @@ -386,7 +386,7 @@ impl<'a> InferenceTable<'a> { } fn extend_type_variable_table(&mut self, to_index: usize) { let count = to_index - self.type_variable_table.len() + 1; - self.type_variable_table.extend(iter::repeat(TypeVariableFlags::default()).take(count)); + self.type_variable_table.extend(std::iter::repeat_n(TypeVariableFlags::default(), count)); } fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 45b4385568196..be0a79f1dd394 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -1119,7 +1119,7 @@ impl Evaluator<'_> { "Stack overflow. Tried to grow stack to {stack_size} bytes" ))); } - self.stack.extend(iter::repeat(0).take(stack_size)); + self.stack.extend(std::iter::repeat_n(0, stack_size)); Ok((locals, prev_stack_pointer)) } @@ -2122,7 +2122,7 @@ impl Evaluator<'_> { return Err(MirEvalError::Panic(format!("Memory allocation of {size} bytes failed"))); } let pos = self.heap.len(); - self.heap.extend(iter::repeat(0).take(size)); + self.heap.extend(std::iter::repeat_n(0, size)); Ok(Address::Heap(pos)) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs index 829ed9efa2bc1..54754045c98aa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs @@ -127,7 +127,7 @@ impl Evaluator<'_> { Ordering::Greater => ["ge", "gt", "ne"].contains(&name), }; let result = if result { 255 } else { 0 }; - destination_bytes.extend(std::iter::repeat(result).take(dest_size)); + destination_bytes.extend(std::iter::repeat_n(result, dest_size)); } destination.write_from_bytes(self, &destination_bytes) diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index 84912f6be65af..ce3c4238b5b18 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -695,7 +695,7 @@ fn signature_help_for_tuple_pat_ish( } #[cfg(test)] mod tests { - use std::iter; + use expect_test::{expect, Expect}; use ide_db::FilePosition; @@ -742,11 +742,11 @@ mod tests { let gap = start.checked_sub(offset).unwrap_or_else(|| { panic!("parameter ranges out of order: {:?}", sig_help.parameter_ranges()) }); - rendered.extend(iter::repeat(' ').take(gap as usize)); + rendered.extend(std::iter::repeat_n(' ', gap as usize)); let param_text = &sig_help.signature[*range]; let width = param_text.chars().count(); // … let marker = if is_active { '^' } else { '-' }; - rendered.extend(iter::repeat(marker).take(width)); + rendered.extend(std::iter::repeat_n(marker, width)); offset += gap + u32::from(range.len()); } if !sig_help.parameter_ranges().is_empty() { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 70e567ec76920..d9fab85df1cc8 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1549,7 +1549,7 @@ pub(crate) fn runnable( ); let cwd = match runnable.kind { - ide::RunnableKind::Bin { .. } => workspace_root.clone(), + ide::RunnableKind::Bin => workspace_root.clone(), _ => spec.cargo_toml.parent().to_owned(), }; From edb25788a075011142eec177354e887717c20d79 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Mon, 10 Mar 2025 12:41:59 +0100 Subject: [PATCH 035/260] fix clippy::doc_overindented_list_items --- .../crates/project-model/src/project_json.rs | 3 +-- .../rust-analyzer/crates/toolchain/src/lib.rs | 24 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 3c14e6e627771..d78fa12d812e4 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -85,8 +85,7 @@ impl ProjectJson { /// /// * `manifest` - The path to the `rust-project.json`. /// * `base` - The path to the workspace root (i.e. the folder containing `rust-project.json`) - /// * `data` - The parsed contents of `rust-project.json`, or project json that's passed via - /// configuration. + /// * `data` - The parsed contents of `rust-project.json`, or project json that's passed via configuration. pub fn new( manifest: Option, base: &AbsPath, diff --git a/src/tools/rust-analyzer/crates/toolchain/src/lib.rs b/src/tools/rust-analyzer/crates/toolchain/src/lib.rs index 325b94cc33bae..e3b30ff9cdecd 100644 --- a/src/tools/rust-analyzer/crates/toolchain/src/lib.rs +++ b/src/tools/rust-analyzer/crates/toolchain/src/lib.rs @@ -27,14 +27,14 @@ impl Tool { /// /// The current implementation checks three places for an executable to use: /// 1) `$CARGO_HOME/bin/` - /// where $CARGO_HOME defaults to ~/.cargo (see ) - /// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset. - /// It seems that this is a reasonable place to try for cargo, rustc, and rustup + /// where $CARGO_HOME defaults to ~/.cargo (see ) + /// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset. + /// It seems that this is a reasonable place to try for cargo, rustc, and rustup /// 2) Appropriate environment variable (erroring if this is set but not a usable executable) - /// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc + /// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc /// 3) $PATH/`` - /// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the - /// first that exists + /// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the + /// first that exists /// 4) If all else fails, we just try to use the executable name directly pub fn prefer_proxy(self) -> Utf8PathBuf { invoke(&[cargo_proxy, lookup_as_env_var, lookup_in_path], self.name()) @@ -44,14 +44,14 @@ impl Tool { /// /// The current implementation checks three places for an executable to use: /// 1) Appropriate environment variable (erroring if this is set but not a usable executable) - /// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc + /// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc /// 2) $PATH/`` - /// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the - /// first that exists + /// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the + /// first that exists /// 3) `$CARGO_HOME/bin/` - /// where $CARGO_HOME defaults to ~/.cargo (see ) - /// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset. - /// It seems that this is a reasonable place to try for cargo, rustc, and rustup + /// where $CARGO_HOME defaults to ~/.cargo (see ) + /// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset. + /// It seems that this is a reasonable place to try for cargo, rustc, and rustup /// 4) If all else fails, we just try to use the executable name directly pub fn path(self) -> Utf8PathBuf { invoke(&[lookup_as_env_var, lookup_in_path, cargo_proxy], self.name()) From 4041c67e90fb6c6f621e3ada853f99874eb637cd Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Mon, 10 Mar 2025 12:42:27 +0100 Subject: [PATCH 036/260] cargo fmt --- .../crates/base-db/src/change.rs | 6 +- .../rust-analyzer/crates/base-db/src/input.rs | 84 +++++++++++-------- .../rust-analyzer/crates/base-db/src/lib.rs | 6 +- src/tools/rust-analyzer/crates/cfg/src/lib.rs | 2 +- .../rust-analyzer/crates/cfg/src/tests.rs | 9 +- .../rust-analyzer/crates/hir-def/src/attr.rs | 14 ++-- .../crates/hir-def/src/builtin_type.rs | 2 +- .../rust-analyzer/crates/hir-def/src/data.rs | 14 ++-- .../crates/hir-def/src/data/adt.rs | 2 +- .../rust-analyzer/crates/hir-def/src/db.rs | 26 +++--- .../crates/hir-def/src/dyn_map.rs | 6 +- .../crates/hir-def/src/expander.rs | 16 ++-- .../crates/hir-def/src/expr_store.rs | 6 +- .../crates/hir-def/src/expr_store/body.rs | 4 +- .../crates/hir-def/src/expr_store/lower.rs | 22 ++--- .../hir-def/src/expr_store/lower/asm.rs | 2 +- .../crates/hir-def/src/expr_store/scope.rs | 10 +-- .../crates/hir-def/src/expr_store/tests.rs | 4 +- .../crates/hir-def/src/find_path.rs | 6 +- .../crates/hir-def/src/generics.rs | 12 +-- .../rust-analyzer/crates/hir-def/src/hir.rs | 10 +-- .../crates/hir-def/src/hir/format_args.rs | 2 +- .../crates/hir-def/src/hir/type_ref.rs | 22 ++--- .../crates/hir-def/src/import_map.rs | 16 ++-- .../crates/hir-def/src/item_scope.rs | 8 +- .../crates/hir-def/src/item_tree.rs | 6 +- .../crates/hir-def/src/item_tree/lower.rs | 11 ++- .../crates/hir-def/src/item_tree/tests.rs | 2 +- .../crates/hir-def/src/lang_item.rs | 18 ++-- .../rust-analyzer/crates/hir-def/src/lib.rs | 16 ++-- .../rust-analyzer/crates/hir-def/src/lower.rs | 2 +- .../hir-def/src/macro_expansion_tests/mod.rs | 6 +- .../crates/hir-def/src/nameres.rs | 8 +- .../crates/hir-def/src/nameres/assoc.rs | 10 +-- .../hir-def/src/nameres/attr_resolution.rs | 6 +- .../crates/hir-def/src/nameres/collector.rs | 26 +++--- .../crates/hir-def/src/nameres/diagnostics.rs | 4 +- .../hir-def/src/nameres/mod_resolution.rs | 4 +- .../hir-def/src/nameres/path_resolution.rs | 14 ++-- .../crates/hir-def/src/nameres/tests.rs | 2 +- .../hir-def/src/nameres/tests/incremental.rs | 2 +- .../rust-analyzer/crates/hir-def/src/path.rs | 2 +- .../crates/hir-def/src/path/lower.rs | 2 +- .../crates/hir-def/src/path/tests.rs | 4 +- .../crates/hir-def/src/per_ns.rs | 8 +- .../crates/hir-def/src/resolver.rs | 26 +++--- .../rust-analyzer/crates/hir-def/src/src.rs | 6 +- .../crates/hir-def/src/test_db.rs | 6 +- .../crates/hir-def/src/visibility.rs | 2 +- .../crates/hir-expand/src/attrs.rs | 12 +-- .../crates/hir-expand/src/builtin.rs | 6 +- .../hir-expand/src/builtin/attr_macro.rs | 4 +- .../hir-expand/src/builtin/derive_macro.rs | 21 +++-- .../crates/hir-expand/src/builtin/fn_macro.rs | 33 ++++---- .../crates/hir-expand/src/builtin/quote.rs | 9 +- .../crates/hir-expand/src/cfg_process.rs | 10 +-- .../rust-analyzer/crates/hir-expand/src/db.rs | 23 +++-- .../crates/hir-expand/src/declarative.rs | 7 +- .../crates/hir-expand/src/eager.rs | 6 +- .../crates/hir-expand/src/files.rs | 9 +- .../crates/hir-expand/src/fixup.rs | 9 +- .../crates/hir-expand/src/hygiene.rs | 2 +- .../crates/hir-expand/src/lib.rs | 14 ++-- .../crates/hir-expand/src/mod_path.rs | 4 +- .../crates/hir-expand/src/name.rs | 2 +- .../src/prettify_macro_expansion_.rs | 2 +- .../crates/hir-expand/src/proc_macro.rs | 6 +- .../crates/hir-expand/src/span_map.rs | 2 +- .../crates/hir-ty/src/autoderef.rs | 4 +- .../crates/hir-ty/src/builder.rs | 12 +-- .../crates/hir-ty/src/chalk_db.rs | 19 +++-- .../crates/hir-ty/src/chalk_ext.rs | 12 +-- .../crates/hir-ty/src/consteval.rs | 11 +-- .../crates/hir-ty/src/consteval/tests.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/db.rs | 16 ++-- .../crates/hir-ty/src/diagnostics.rs | 8 +- .../hir-ty/src/diagnostics/decl_check.rs | 10 +-- .../src/diagnostics/decl_check/case_conv.rs | 2 +- .../crates/hir-ty/src/diagnostics/expr.rs | 8 +- .../hir-ty/src/diagnostics/match_check.rs | 6 +- .../diagnostics/match_check/pat_analysis.rs | 10 +-- .../hir-ty/src/diagnostics/unsafe_check.rs | 6 +- .../crates/hir-ty/src/display.rs | 26 +++--- .../rust-analyzer/crates/hir-ty/src/drop.rs | 12 +-- .../crates/hir-ty/src/dyn_compatibility.rs | 17 ++-- .../crates/hir-ty/src/generics.rs | 8 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 28 +++---- .../crates/hir-ty/src/infer/cast.rs | 6 +- .../crates/hir-ty/src/infer/closure.rs | 12 +-- .../crates/hir-ty/src/infer/coerce.rs | 6 +- .../crates/hir-ty/src/infer/diagnostics.rs | 4 +- .../crates/hir-ty/src/infer/expr.rs | 36 ++++---- .../crates/hir-ty/src/infer/mutability.rs | 6 +- .../crates/hir-ty/src/infer/pat.rs | 11 +-- .../crates/hir-ty/src/infer/path.rs | 11 +-- .../crates/hir-ty/src/infer/unify.rs | 22 ++--- .../crates/hir-ty/src/inhabitedness.rs | 6 +- .../crates/hir-ty/src/interner.rs | 12 +-- .../crates/hir-ty/src/lang_items.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/layout.rs | 8 +- .../crates/hir-ty/src/layout/adt.rs | 6 +- .../crates/hir-ty/src/layout/tests.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/lib.rs | 56 +++++-------- .../rust-analyzer/crates/hir-ty/src/lower.rs | 35 ++++---- .../crates/hir-ty/src/lower/path.rs | 12 +-- .../crates/hir-ty/src/mapping.rs | 6 +- .../crates/hir-ty/src/method_resolution.rs | 30 +++---- .../rust-analyzer/crates/hir-ty/src/mir.rs | 16 ++-- .../crates/hir-ty/src/mir/borrowck.rs | 8 +- .../crates/hir-ty/src/mir/eval.rs | 43 +++++----- .../crates/hir-ty/src/mir/eval/shim.rs | 10 +-- .../crates/hir-ty/src/mir/eval/shim/simd.rs | 6 +- .../crates/hir-ty/src/mir/eval/tests.rs | 4 +- .../crates/hir-ty/src/mir/lower.rs | 36 ++++---- .../hir-ty/src/mir/lower/pattern_matching.rs | 10 +-- .../crates/hir-ty/src/mir/monomorphization.rs | 6 +- .../crates/hir-ty/src/mir/pretty.rs | 4 +- .../crates/hir-ty/src/target_feature.rs | 22 ++--- .../crates/hir-ty/src/test_db.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/tests.rs | 10 +-- .../hir-ty/src/tests/closure_captures.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/tls.rs | 10 +-- .../rust-analyzer/crates/hir-ty/src/traits.rs | 18 ++-- .../rust-analyzer/crates/hir-ty/src/utils.rs | 18 ++-- .../crates/hir-ty/src/variance.rs | 8 +- .../rust-analyzer/crates/hir/src/attrs.rs | 8 +- .../crates/hir/src/diagnostics.rs | 15 ++-- .../rust-analyzer/crates/hir/src/display.rs | 10 +-- .../rust-analyzer/crates/hir/src/from_id.rs | 2 +- .../crates/hir/src/has_source.rs | 5 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 76 +++++++---------- .../rust-analyzer/crates/hir/src/semantics.rs | 26 +++--- .../hir/src/semantics/child_by_source.rs | 12 +-- .../crates/hir/src/semantics/source_to_def.rs | 18 ++-- .../crates/hir/src/source_analyzer.rs | 45 ++++------ .../rust-analyzer/crates/hir/src/symbols.rs | 10 +-- .../crates/hir/src/term_search/tactics.rs | 2 +- .../crates/ide-assists/src/assist_config.rs | 2 +- .../crates/ide-assists/src/assist_context.rs | 8 +- .../ide-assists/src/handlers/add_braces.rs | 2 +- .../add_explicit_enum_discriminant.rs | 4 +- .../src/handlers/add_label_to_loop.rs | 2 +- .../src/handlers/add_lifetime_to_type.rs | 12 +-- .../src/handlers/add_missing_impl_members.rs | 8 +- .../src/handlers/add_missing_match_arms.rs | 8 +- .../src/handlers/add_return_type.rs | 2 +- .../src/handlers/add_turbo_fish.rs | 8 +- .../src/handlers/apply_demorgan.rs | 11 ++- .../ide-assists/src/handlers/auto_import.rs | 12 +-- .../src/handlers/bind_unused_param.rs | 4 +- .../src/handlers/change_visibility.rs | 4 +- .../src/handlers/convert_bool_then.rs | 10 +-- .../src/handlers/convert_bool_to_enum.rs | 10 +-- .../src/handlers/convert_closure_to_fn.rs | 9 +- .../src/handlers/convert_comment_block.rs | 8 +- .../convert_comment_from_or_to_doc.rs | 2 +- .../src/handlers/convert_for_to_while_let.rs | 6 +- .../src/handlers/convert_from_to_tryfrom.rs | 2 +- .../src/handlers/convert_integer_literal.rs | 2 +- .../handlers/convert_iter_for_each_to_for.rs | 4 +- .../src/handlers/convert_let_else_to_match.rs | 10 +-- .../src/handlers/convert_match_to_let_else.rs | 5 +- .../convert_named_struct_to_tuple_struct.rs | 5 +- .../src/handlers/convert_to_guarded_return.rs | 9 +- .../convert_tuple_return_type_to_struct.rs | 9 +- .../convert_tuple_struct_to_named_struct.rs | 5 +- .../src/handlers/convert_while_to_loop.rs | 8 +- .../handlers/destructure_struct_binding.rs | 6 +- .../src/handlers/destructure_tuple_binding.rs | 2 +- .../src/handlers/desugar_doc_comment.rs | 4 +- .../src/handlers/expand_glob_import.rs | 7 +- .../src/handlers/expand_rest_pattern.rs | 3 +- .../extract_expressions_from_format_string.rs | 48 ++++++----- .../src/handlers/extract_function.rs | 23 +++-- .../src/handlers/extract_module.rs | 17 ++-- .../extract_struct_from_enum_variant.rs | 17 ++-- .../src/handlers/extract_type_alias.rs | 2 +- .../src/handlers/extract_variable.rs | 10 +-- .../src/handlers/fix_visibility.rs | 4 +- .../ide-assists/src/handlers/flip_binexpr.rs | 2 +- .../ide-assists/src/handlers/flip_comma.rs | 2 +- .../src/handlers/flip_or_pattern.rs | 2 +- .../src/handlers/flip_trait_bound.rs | 2 +- .../src/handlers/generate_constant.rs | 4 +- .../generate_default_from_enum_variant.rs | 8 +- .../src/handlers/generate_default_from_new.rs | 4 +- .../src/handlers/generate_delegate_methods.rs | 6 +- .../src/handlers/generate_delegate_trait.rs | 14 ++-- .../src/handlers/generate_deref.rs | 6 +- .../src/handlers/generate_derive.rs | 2 +- .../generate_documentation_template.rs | 5 +- .../src/handlers/generate_enum_is_method.rs | 2 +- .../generate_enum_projection_method.rs | 2 +- .../src/handlers/generate_enum_variant.rs | 5 +- .../src/handlers/generate_fn_type_alias.rs | 5 +- .../handlers/generate_from_impl_for_enum.rs | 10 +-- .../src/handlers/generate_function.rs | 16 ++-- .../src/handlers/generate_getter_or_setter.rs | 7 +- .../ide-assists/src/handlers/generate_impl.rs | 4 +- .../handlers/generate_is_empty_from_len.rs | 6 +- .../src/handlers/generate_mut_trait_impl.rs | 3 +- .../ide-assists/src/handlers/generate_new.rs | 4 +- .../src/handlers/generate_trait_from_impl.rs | 6 +- .../ide-assists/src/handlers/inline_call.rs | 14 ++-- .../src/handlers/inline_const_as_literal.rs | 2 +- .../src/handlers/inline_local_variable.rs | 6 +- .../src/handlers/inline_type_alias.rs | 7 +- .../src/handlers/into_to_qualified_from.rs | 2 +- .../src/handlers/introduce_named_lifetime.rs | 6 +- .../introduce_named_type_parameter.rs | 2 +- .../ide-assists/src/handlers/invert_if.rs | 4 +- .../ide-assists/src/handlers/merge_imports.rs | 7 +- .../src/handlers/merge_match_arms.rs | 2 +- .../src/handlers/merge_nested_if.rs | 4 +- .../ide-assists/src/handlers/move_bounds.rs | 4 +- .../src/handlers/move_const_to_impl.rs | 2 +- .../src/handlers/move_from_mod_rs.rs | 2 +- .../ide-assists/src/handlers/move_guard.rs | 2 +- .../src/handlers/move_module_to_file.rs | 4 +- .../src/handlers/move_to_mod_rs.rs | 2 +- .../src/handlers/normalize_import.rs | 4 +- .../src/handlers/number_representation.rs | 2 +- .../src/handlers/promote_local_to_const.rs | 5 +- .../src/handlers/pull_assignment_up.rs | 5 +- .../src/handlers/qualify_method_call.rs | 4 +- .../ide-assists/src/handlers/qualify_path.rs | 9 +- .../ide-assists/src/handlers/raw_string.rs | 4 +- .../ide-assists/src/handlers/remove_dbg.rs | 5 +- .../src/handlers/remove_parentheses.rs | 2 +- .../src/handlers/remove_unused_imports.rs | 4 +- .../src/handlers/remove_unused_param.rs | 8 +- .../src/handlers/reorder_fields.rs | 2 +- .../src/handlers/reorder_impl_items.rs | 2 +- .../src/handlers/replace_arith_op.rs | 2 +- .../replace_derive_with_manual_impl.rs | 10 +-- .../src/handlers/replace_if_let_with_match.rs | 8 +- .../replace_is_method_with_if_let_method.rs | 2 +- .../src/handlers/replace_let_with_if_let.rs | 2 +- .../src/handlers/replace_method_eager_lazy.rs | 14 +--- .../replace_named_generic_with_impl.rs | 9 +- .../replace_qualified_name_with_use.rs | 7 +- .../src/handlers/replace_string_with_char.rs | 5 +- .../handlers/replace_try_expr_with_match.rs | 2 +- .../replace_turbofish_with_explicit_type.rs | 4 +- .../ide-assists/src/handlers/sort_items.rs | 4 +- .../ide-assists/src/handlers/split_import.rs | 2 +- .../ide-assists/src/handlers/term_search.rs | 2 +- .../src/handlers/toggle_async_sugar.rs | 2 +- .../ide-assists/src/handlers/toggle_ignore.rs | 4 +- .../src/handlers/toggle_macro_delimiter.rs | 3 +- .../src/handlers/unmerge_match_arm.rs | 4 +- .../ide-assists/src/handlers/unmerge_use.rs | 6 +- .../src/handlers/unnecessary_async.rs | 4 +- .../src/handlers/unqualify_method_call.rs | 2 +- .../ide-assists/src/handlers/unwrap_block.rs | 2 +- .../src/handlers/unwrap_return_type.rs | 5 +- .../ide-assists/src/handlers/unwrap_tuple.rs | 2 +- .../src/handlers/wrap_return_type.rs | 5 +- .../src/handlers/wrap_unwrap_cfg_attr.rs | 11 +-- .../crates/ide-assists/src/tests.rs | 6 +- .../crates/ide-assists/src/utils.rs | 26 ++---- .../src/utils/gen_trait_fn_body.rs | 2 +- .../ide-assists/src/utils/ref_field_expr.rs | 2 +- .../crates/ide-completion/src/completions.rs | 10 +-- .../src/completions/attribute.rs | 8 +- .../src/completions/attribute/cfg.rs | 4 +- .../src/completions/attribute/derive.rs | 4 +- .../src/completions/attribute/lint.rs | 4 +- .../src/completions/attribute/macro_use.rs | 2 +- .../src/completions/attribute/repr.rs | 2 +- .../ide-completion/src/completions/dot.rs | 2 +- .../src/completions/env_vars.rs | 54 +++++++----- .../ide-completion/src/completions/expr.rs | 10 +-- .../src/completions/extern_abi.rs | 4 +- .../src/completions/extern_crate.rs | 4 +- .../ide-completion/src/completions/field.rs | 2 +- .../src/completions/flyimport.rs | 12 +-- .../src/completions/fn_param.rs | 6 +- .../src/completions/format_string.rs | 6 +- .../src/completions/item_list.rs | 2 +- .../src/completions/item_list/trait_impl.rs | 15 ++-- .../src/completions/lifetime.rs | 2 +- .../ide-completion/src/completions/mod_.rs | 6 +- .../ide-completion/src/completions/pattern.rs | 2 +- .../ide-completion/src/completions/postfix.rs | 28 ++++--- .../src/completions/postfix/format_like.rs | 6 +- .../ide-completion/src/completions/record.rs | 6 +- .../ide-completion/src/completions/snippet.rs | 26 +++--- .../ide-completion/src/completions/type.rs | 4 +- .../ide-completion/src/completions/use_.rs | 4 +- .../ide-completion/src/completions/vis.rs | 2 +- .../crates/ide-completion/src/config.rs | 4 +- .../crates/ide-completion/src/context.rs | 23 +++-- .../ide-completion/src/context/analysis.rs | 17 ++-- .../ide-completion/src/context/tests.rs | 4 +- .../crates/ide-completion/src/item.rs | 8 +- .../crates/ide-completion/src/lib.rs | 2 +- .../crates/ide-completion/src/render.rs | 16 ++-- .../ide-completion/src/render/function.rs | 16 ++-- .../ide-completion/src/render/literal.rs | 19 ++--- .../ide-completion/src/render/macro_.rs | 4 +- .../ide-completion/src/render/pattern.rs | 8 +- .../src/render/union_literal.rs | 4 +- .../ide-completion/src/render/variant.rs | 2 +- .../crates/ide-completion/src/tests.rs | 6 +- .../ide-completion/src/tests/expression.rs | 8 +- .../ide-completion/src/tests/flyimport.rs | 6 +- .../src/tests/raw_identifiers.rs | 4 +- .../ide-completion/src/tests/special.rs | 8 +- .../crates/ide-db/src/active_parameter.rs | 3 +- .../crates/ide-db/src/apply_change.rs | 2 +- .../rust-analyzer/crates/ide-db/src/defs.rs | 5 +- .../crates/ide-db/src/documentation.rs | 11 +-- .../crates/ide-db/src/famous_defs.rs | 6 +- .../crates/ide-db/src/helpers.rs | 5 +- .../ide-db/src/imports/import_assets.rs | 12 +-- .../crates/ide-db/src/imports/insert_use.rs | 14 ++-- .../ide-db/src/imports/insert_use/tests.rs | 2 +- .../ide-db/src/imports/merge_imports.rs | 9 +- .../crates/ide-db/src/items_locator.rs | 4 +- .../rust-analyzer/crates/ide-db/src/lib.rs | 12 +-- .../crates/ide-db/src/path_transform.rs | 5 +- .../crates/ide-db/src/prime_caches.rs | 4 +- .../rust-analyzer/crates/ide-db/src/rename.rs | 6 +- .../rust-analyzer/crates/ide-db/src/search.rs | 14 ++-- .../crates/ide-db/src/source_change.rs | 19 +++-- .../crates/ide-db/src/symbol_index.rs | 4 +- .../src/syntax_helpers/format_string.rs | 2 +- .../src/syntax_helpers/format_string_exprs.rs | 2 +- .../ide-db/src/syntax_helpers/node_ext.rs | 2 +- .../ide-db/src/syntax_helpers/suggest_name.rs | 3 +- .../ide-db/src/syntax_helpers/tree_diff.rs | 4 +- .../rust-analyzer/crates/ide-db/src/traits.rs | 8 +- .../crates/ide-db/src/ty_filter.rs | 2 +- .../ide-db/src/use_trivial_constructor.rs | 2 +- .../src/handlers/await_outside_of_async.rs | 2 +- .../src/handlers/field_shorthand.rs | 6 +- .../src/handlers/generic_args_prohibited.rs | 4 +- .../src/handlers/inactive_code.rs | 2 +- .../src/handlers/incoherent_impl.rs | 2 +- .../src/handlers/incorrect_case.rs | 6 +- .../src/handlers/json_is_not_rust.rs | 10 +-- .../src/handlers/macro_error.rs | 2 +- .../src/handlers/mismatched_arg_count.rs | 4 +- .../src/handlers/missing_fields.rs | 20 ++--- .../src/handlers/missing_match_arms.rs | 2 +- .../src/handlers/missing_unsafe.rs | 6 +- .../src/handlers/mutability_errors.rs | 4 +- .../src/handlers/no_such_field.rs | 8 +- .../src/handlers/remove_trailing_return.rs | 6 +- .../src/handlers/remove_unnecessary_else.rs | 6 +- .../replace_filter_map_next_with_find_map.rs | 8 +- .../handlers/trait_impl_incorrect_safety.rs | 2 +- .../handlers/trait_impl_missing_assoc_item.rs | 4 +- .../trait_impl_redundant_assoc_item.rs | 2 +- .../src/handlers/type_mismatch.rs | 15 ++-- .../src/handlers/typed_hole.rs | 10 +-- .../src/handlers/unlinked_file.rs | 12 +-- .../src/handlers/unresolved_field.rs | 19 ++--- .../src/handlers/unresolved_method.rs | 15 ++-- .../src/handlers/unresolved_module.rs | 4 +- .../src/handlers/unused_variables.rs | 2 +- .../src/handlers/useless_braces.rs | 8 +- .../crates/ide-diagnostics/src/lib.rs | 15 ++-- .../crates/ide-diagnostics/src/tests.rs | 4 +- .../crates/ide-ssr/src/fragments.rs | 2 +- .../crates/ide-ssr/src/from_comment.rs | 4 +- .../rust-analyzer/crates/ide-ssr/src/lib.rs | 4 +- .../crates/ide-ssr/src/matching.rs | 6 +- .../crates/ide-ssr/src/parsing.rs | 2 +- .../crates/ide-ssr/src/replacing.rs | 4 +- .../crates/ide-ssr/src/resolving.rs | 6 +- .../crates/ide-ssr/src/search.rs | 7 +- .../rust-analyzer/crates/ide-ssr/src/tests.rs | 6 +- .../crates/ide/src/annotations.rs | 14 ++-- .../ide/src/annotations/fn_references.rs | 4 +- .../crates/ide/src/call_hierarchy.rs | 8 +- .../rust-analyzer/crates/ide/src/doc_links.rs | 17 ++-- .../ide/src/doc_links/intra_doc_links.rs | 2 +- .../crates/ide/src/doc_links/tests.rs | 13 +-- .../crates/ide/src/expand_macro.rs | 8 +- .../crates/ide/src/extend_selection.rs | 18 ++-- .../crates/ide/src/fetch_crates.rs | 2 +- .../crates/ide/src/file_structure.rs | 6 +- .../rust-analyzer/crates/ide/src/fixture.rs | 2 +- .../crates/ide/src/folding_ranges.rs | 7 +- .../crates/ide/src/goto_declaration.rs | 16 ++-- .../crates/ide/src/goto_definition.rs | 15 ++-- .../crates/ide/src/goto_implementation.rs | 4 +- .../crates/ide/src/goto_type_definition.rs | 4 +- .../crates/ide/src/highlight_related.rs | 21 ++--- .../rust-analyzer/crates/ide/src/hover.rs | 14 ++-- .../crates/ide/src/hover/render.rs | 25 +++--- .../crates/ide/src/hover/tests.rs | 6 +- .../crates/ide/src/inlay_hints.rs | 19 +++-- .../crates/ide/src/inlay_hints/adjustment.rs | 6 +- .../crates/ide/src/inlay_hints/bind_pat.rs | 8 +- .../ide/src/inlay_hints/binding_mode.rs | 2 +- .../crates/ide/src/inlay_hints/bounds.rs | 4 +- .../crates/ide/src/inlay_hints/chaining.rs | 9 +- .../ide/src/inlay_hints/closing_brace.rs | 9 +- .../ide/src/inlay_hints/closure_captures.rs | 4 +- .../crates/ide/src/inlay_hints/closure_ret.rs | 4 +- .../ide/src/inlay_hints/discriminant.rs | 4 +- .../ide/src/inlay_hints/extern_block.rs | 4 +- .../ide/src/inlay_hints/generic_param.rs | 8 +- .../ide/src/inlay_hints/implicit_drop.rs | 9 +- .../ide/src/inlay_hints/implicit_static.rs | 4 +- .../crates/ide/src/inlay_hints/lifetime.rs | 15 ++-- .../crates/ide/src/inlay_hints/param_name.rs | 6 +- .../ide/src/inlay_hints/range_exclusive.rs | 4 +- .../rust-analyzer/crates/ide/src/interpret.rs | 4 +- .../crates/ide/src/join_lines.rs | 4 +- src/tools/rust-analyzer/crates/ide/src/lib.rs | 13 +-- .../crates/ide/src/matching_brace.rs | 2 +- .../rust-analyzer/crates/ide/src/moniker.rs | 12 +-- .../rust-analyzer/crates/ide/src/move_item.rs | 6 +- .../crates/ide/src/navigation_target.rs | 11 +-- .../crates/ide/src/parent_module.rs | 4 +- .../crates/ide/src/references.rs | 15 ++-- .../rust-analyzer/crates/ide/src/rename.rs | 8 +- .../rust-analyzer/crates/ide/src/runnables.rs | 13 +-- .../crates/ide/src/signature_help.rs | 13 ++- src/tools/rust-analyzer/crates/ide/src/ssr.rs | 6 +- .../crates/ide/src/static_index.rs | 16 ++-- .../rust-analyzer/crates/ide/src/status.rs | 2 +- .../crates/ide/src/syntax_highlighting.rs | 8 +- .../ide/src/syntax_highlighting/format.rs | 8 +- .../ide/src/syntax_highlighting/highlight.rs | 28 ++----- .../ide/src/syntax_highlighting/html.rs | 2 +- .../ide/src/syntax_highlighting/inject.rs | 12 +-- .../ide/src/syntax_highlighting/injector.rs | 6 +- .../ide/src/syntax_highlighting/tests.rs | 6 +- .../crates/ide/src/test_explorer.rs | 4 +- .../rust-analyzer/crates/ide/src/typing.rs | 6 +- .../crates/ide/src/typing/on_enter.rs | 6 +- .../crates/ide/src/view_crate_graph.rs | 2 +- .../rust-analyzer/crates/ide/src/view_hir.rs | 2 +- .../crates/ide/src/view_item_tree.rs | 2 +- .../crates/ide/src/view_memory_layout.rs | 2 +- .../rust-analyzer/crates/ide/src/view_mir.rs | 2 +- .../crates/ide/src/view_syntax_tree.rs | 4 +- .../rust-analyzer/crates/intern/src/lib.rs | 4 +- .../rust-analyzer/crates/intern/src/symbol.rs | 6 +- .../crates/intern/src/symbol/symbols.rs | 2 +- .../crates/load-cargo/src/lib.rs | 17 ++-- .../rust-analyzer/crates/mbe/src/benchmark.rs | 11 +-- .../rust-analyzer/crates/mbe/src/expander.rs | 2 +- .../crates/mbe/src/expander/matcher.rs | 8 +- .../crates/mbe/src/expander/transcriber.rs | 11 ++- src/tools/rust-analyzer/crates/mbe/src/lib.rs | 2 +- .../rust-analyzer/crates/mbe/src/parser.rs | 14 ++-- .../rust-analyzer/crates/parser/src/event.rs | 2 +- .../crates/parser/src/grammar.rs | 4 +- .../crates/parser/src/grammar/expressions.rs | 2 +- .../rust-analyzer/crates/parser/src/parser.rs | 6 +- .../rust-analyzer/crates/paths/src/lib.rs | 4 +- .../proc-macro-api/src/legacy_protocol/msg.rs | 4 +- .../crates/proc-macro-api/src/lib.rs | 8 +- .../crates/proc-macro-api/src/process.rs | 8 +- .../crates/proc-macro-srv-cli/src/main.rs | 4 +- .../proc-macro-srv-cli/src/main_loop.rs | 4 +- .../crates/proc-macro-srv/src/dylib.rs | 2 +- .../crates/proc-macro-srv/src/lib.rs | 2 +- .../crates/proc-macro-srv/src/proc_macros.rs | 2 +- .../src/server_impl/rust_analyzer_span.rs | 4 +- .../src/server_impl/token_id.rs | 2 +- .../src/server_impl/token_stream.rs | 2 +- .../crates/proc-macro-srv/src/tests/utils.rs | 2 +- .../project-model/src/build_dependencies.rs | 6 +- .../project-model/src/cargo_workspace.rs | 2 +- .../crates/project-model/src/env.rs | 2 +- .../crates/project-model/src/lib.rs | 8 +- .../crates/project-model/src/manifest_path.rs | 6 +- .../crates/project-model/src/project_json.rs | 2 +- .../crates/project-model/src/sysroot.rs | 20 ++--- .../crates/project-model/src/tests.rs | 8 +- .../src/toolchain_info/target_data_layout.rs | 2 +- .../src/toolchain_info/target_tuple.rs | 2 +- .../crates/project-model/src/workspace.rs | 10 +-- .../crates/query-group-macro/src/lib.rs | 8 +- .../crates/query-group-macro/src/queries.rs | 4 +- .../crates/rust-analyzer/src/bin/main.rs | 10 ++- .../rust-analyzer/src/cli/analysis_stats.rs | 11 +-- .../rust-analyzer/src/cli/diagnostics.rs | 6 +- .../crates/rust-analyzer/src/cli/lsif.rs | 4 +- .../crates/rust-analyzer/src/cli/run_tests.rs | 6 +- .../rust-analyzer/src/cli/rustc_tests.rs | 6 +- .../crates/rust-analyzer/src/cli/scip.rs | 2 +- .../crates/rust-analyzer/src/cli/ssr.rs | 4 +- .../src/cli/unresolved_references.rs | 10 +-- .../crates/rust-analyzer/src/command.rs | 9 +- .../crates/rust-analyzer/src/config.rs | 10 +-- .../src/config/patch_old_style.rs | 2 +- .../rust-analyzer/src/diagnostics/to_proto.rs | 8 +- .../crates/rust-analyzer/src/flycheck.rs | 2 +- .../crates/rust-analyzer/src/global_state.rs | 8 +- .../rust-analyzer/src/handlers/dispatch.rs | 2 +- .../rust-analyzer/src/handlers/request.rs | 23 +++-- .../src/integrated_benchmarks.rs | 4 +- .../rust-analyzer/src/lsp/capabilities.rs | 2 +- .../crates/rust-analyzer/src/lsp/ext.rs | 6 +- .../rust-analyzer/src/lsp/from_proto.rs | 2 +- .../crates/rust-analyzer/src/lsp/to_proto.rs | 23 ++--- .../crates/rust-analyzer/src/lsp/utils.rs | 2 +- .../crates/rust-analyzer/src/main_loop.rs | 20 +++-- .../crates/rust-analyzer/src/reload.rs | 12 +-- .../crates/rust-analyzer/src/target_spec.rs | 7 +- .../rust-analyzer/src/tracing/config.rs | 6 +- .../crates/rust-analyzer/src/tracing/hprof.rs | 5 +- .../crates/rust-analyzer/src/tracing/json.rs | 4 +- .../rust-analyzer/tests/slow-tests/main.rs | 12 +-- .../rust-analyzer/tests/slow-tests/ratoml.rs | 2 +- .../rust-analyzer/tests/slow-tests/support.rs | 22 ++--- .../rust-analyzer/crates/span/src/ast_id.rs | 2 +- .../rust-analyzer/crates/span/src/map.rs | 4 +- .../rust-analyzer/crates/stdx/src/lib.rs | 6 +- .../rust-analyzer/crates/stdx/src/process.rs | 2 +- .../rust-analyzer/crates/stdx/src/thin_vec.rs | 10 +-- .../crates/stdx/src/thread/pool.rs | 2 +- .../crates/syntax-bridge/src/lib.rs | 9 +- .../src/prettify_macro_expansion.rs | 6 +- .../crates/syntax-bridge/src/tests.rs | 9 +- .../rust-analyzer/crates/syntax/src/algo.rs | 4 +- .../rust-analyzer/crates/syntax/src/ast.rs | 2 +- .../crates/syntax/src/ast/edit.rs | 5 +- .../crates/syntax/src/ast/edit_in_place.rs | 6 +- .../crates/syntax/src/ast/expr_ext.rs | 12 +-- .../crates/syntax/src/ast/make.rs | 19 ++--- .../crates/syntax/src/ast/node_ext.rs | 25 ++---- .../crates/syntax/src/ast/prec.rs | 7 +- .../src/ast/syntax_factory/constructors.rs | 6 +- .../crates/syntax/src/ast/token_ext.rs | 18 ++-- .../crates/syntax/src/ast/traits.rs | 10 +-- .../rust-analyzer/crates/syntax/src/fuzz.rs | 2 +- .../rust-analyzer/crates/syntax/src/hacks.rs | 2 +- .../rust-analyzer/crates/syntax/src/lib.rs | 6 +- .../crates/syntax/src/parsing.rs | 2 +- .../crates/syntax/src/parsing/reparsing.rs | 6 +- .../rust-analyzer/crates/syntax/src/ptr.rs | 4 +- .../crates/syntax/src/syntax_editor.rs | 13 +-- .../syntax/src/syntax_editor/edit_algo.rs | 30 ++++--- .../crates/syntax/src/syntax_editor/edits.rs | 6 +- .../rust-analyzer/crates/syntax/src/ted.rs | 2 +- .../rust-analyzer/crates/syntax/src/tests.rs | 2 +- .../crates/syntax/src/validation.rs | 10 +-- .../crates/syntax/src/validation/block.rs | 2 +- .../crates/test-fixture/src/lib.rs | 8 +- .../crates/vfs-notify/src/lib.rs | 2 +- .../rust-analyzer/crates/vfs/src/file_set.rs | 6 +- src/tools/rust-analyzer/crates/vfs/src/lib.rs | 4 +- .../rust-analyzer/crates/vfs/src/vfs_path.rs | 6 +- .../lib/lsp-server/examples/goto_def.rs | 2 +- .../rust-analyzer/lib/lsp-server/src/lib.rs | 6 +- .../lib/lsp-server/src/socket.rs | 4 +- .../rust-analyzer/lib/lsp-server/src/stdio.rs | 2 +- src/tools/rust-analyzer/xtask/src/codegen.rs | 2 +- .../xtask/src/codegen/assists_doc_tests.rs | 2 +- .../xtask/src/codegen/diagnostics_docs.rs | 2 +- .../xtask/src/codegen/feature_docs.rs | 2 +- .../xtask/src/codegen/grammar.rs | 6 +- .../rust-analyzer/xtask/src/codegen/lints.rs | 4 +- .../xtask/src/codegen/parser_inline_tests.rs | 2 +- src/tools/rust-analyzer/xtask/src/dist.rs | 6 +- src/tools/rust-analyzer/xtask/src/install.rs | 14 +++- src/tools/rust-analyzer/xtask/src/main.rs | 2 +- src/tools/rust-analyzer/xtask/src/metrics.rs | 2 +- src/tools/rust-analyzer/xtask/src/publish.rs | 6 +- src/tools/rust-analyzer/xtask/src/release.rs | 11 +-- .../xtask/src/release/changelog.rs | 12 ++- src/tools/rust-analyzer/xtask/src/tidy.rs | 3 +- 571 files changed, 2182 insertions(+), 2430 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/change.rs b/src/tools/rust-analyzer/crates/base-db/src/change.rs index 1f19556a766c2..b5964ff5b4abe 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/change.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/change.rs @@ -82,9 +82,5 @@ impl FileChange { } fn durability(source_root: &SourceRoot) -> Durability { - if source_root.is_library { - Durability::HIGH - } else { - Durability::LOW - } + if source_root.is_library { Durability::HIGH } else { Durability::LOW } } diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 913dfe6efb770..564697facf6e5 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -10,15 +10,15 @@ use std::hash::BuildHasherDefault; use std::{fmt, mem, ops}; use cfg::{CfgOptions, HashableCfgOptions}; -use dashmap::mapref::entry::Entry; use dashmap::DashMap; +use dashmap::mapref::entry::Entry; use intern::Symbol; use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; use salsa::{Durability, Setter}; use span::{Edition, EditionedFileId}; use triomphe::Arc; -use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath}; +use vfs::{AbsPathBuf, AnchoredPath, FileId, VfsPath, file_set::FileSet}; use crate::{CrateWorkspaceData, RootQueryDb}; @@ -110,11 +110,7 @@ impl CrateName { /// Dashes are not allowed in the crate names, /// hence the input string is returned as `Err` for those cases. pub fn new(name: &str) -> Result { - if name.contains('-') { - Err(name) - } else { - Ok(Self(Symbol::intern(name))) - } + if name.contains('-') { Err(name) } else { Ok(Self(Symbol::intern(name))) } } /// Creates a crate name, unconditionally replacing the dashes with underscores. @@ -922,15 +918,21 @@ mod tests { None, empty_ws_data(), ); - assert!(graph - .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_ok()); - assert!(graph - .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) - .is_ok()); - assert!(graph - .add_dep(crate3, DependencyBuilder::new(CrateName::new("crate1").unwrap(), crate1,)) - .is_err()); + assert!( + graph + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate3, DependencyBuilder::new(CrateName::new("crate1").unwrap(), crate1,)) + .is_err() + ); } #[test] @@ -962,12 +964,16 @@ mod tests { None, empty_ws_data(), ); - assert!(graph - .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_ok()); - assert!(graph - .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_err()); + assert!( + graph + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_err() + ); } #[test] @@ -1012,12 +1018,16 @@ mod tests { None, empty_ws_data(), ); - assert!(graph - .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_ok()); - assert!(graph - .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) - .is_ok()); + assert!( + graph + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) + .is_ok() + ); } #[test] @@ -1049,15 +1059,17 @@ mod tests { None, empty_ws_data(), ); - assert!(graph - .add_dep( - crate1, - DependencyBuilder::new( - CrateName::normalize_dashes("crate-name-with-dashes"), - crate2, + assert!( + graph + .add_dep( + crate1, + DependencyBuilder::new( + CrateName::normalize_dashes("crate-name-with-dashes"), + crate2, + ) ) - ) - .is_ok()); + .is_ok() + ); assert_eq!( graph.arena[crate1].basic.dependencies, vec![ diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index b733c4d24147e..e6059e9e79058 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -14,15 +14,15 @@ pub use crate::{ SourceRoot, SourceRootId, TargetLayoutLoadResult, UniqueCrateData, }, }; -use dashmap::{mapref::entry::Entry, DashMap}; +use dashmap::{DashMap, mapref::entry::Entry}; pub use query_group::{self}; use rustc_hash::{FxHashSet, FxHasher}; pub use salsa::{self}; use salsa::{Durability, Setter}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; -use syntax::{ast, Parse, SyntaxError}; +use syntax::{Parse, SyntaxError, ast}; use triomphe::Arc; -pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath}; +pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet}; #[macro_export] macro_rules! impl_intern_key { diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index 26860fb932077..8218a81556018 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -9,7 +9,7 @@ use std::fmt; use rustc_hash::FxHashSet; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; pub use cfg_expr::{CfgAtom, CfgExpr}; pub use dnf::DnfExpr; diff --git a/src/tools/rust-analyzer/crates/cfg/src/tests.rs b/src/tools/rust-analyzer/crates/cfg/src/tests.rs index 6d87d83ad9300..6766748097f00 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/tests.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/tests.rs @@ -1,10 +1,11 @@ use arbitrary::{Arbitrary, Unstructured}; -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use intern::Symbol; -use syntax::{ast, AstNode, Edition}; +use syntax::{AstNode, Edition, ast}; use syntax_bridge::{ - dummy_test_span_utils::{DummyTestSpanMap, DUMMY}, - syntax_node_to_token_tree, DocCommentDesugarMode, + DocCommentDesugarMode, + dummy_test_span_utils::{DUMMY, DummyTestSpanMap}, + syntax_node_to_token_tree, }; use crate::{CfgAtom, CfgExpr, CfgOptions, DnfExpr}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 2775e1398c28d..78f26d6756907 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -6,28 +6,28 @@ use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ - attrs::{collect_attrs, Attr, AttrId, RawAttrs}, HirFileId, InFile, + attrs::{Attr, AttrId, RawAttrs, collect_attrs}, }; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use la_arena::{ArenaMap, Idx, RawIdx}; use mbe::DelimiterKind; use rustc_abi::ReprOptions; use syntax::{ - ast::{self, HasAttrs}, AstPtr, + ast::{self, HasAttrs}, }; use triomphe::Arc; use tt::iter::{TtElement, TtIter}; use crate::{ + AdtId, AttrDefId, GenericParamId, HasModule, ItemTreeLoc, LocalFieldId, Lookup, MacroId, + VariantId, db::DefDatabase, item_tree::{AttrOwner, FieldParent, ItemTreeNode}, lang_item::LangItem, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource}, - AdtId, AttrDefId, GenericParamId, HasModule, ItemTreeLoc, LocalFieldId, Lookup, MacroId, - VariantId, }; /// Desugared attributes of an item post `cfg_attr` expansion. @@ -770,8 +770,8 @@ mod tests { use hir_expand::span_map::{RealSpanMap, SpanMap}; use span::FileId; - use syntax::{ast, AstNode, TextRange}; - use syntax_bridge::{syntax_node_to_token_tree, DocCommentDesugarMode}; + use syntax::{AstNode, TextRange, ast}; + use syntax_bridge::{DocCommentDesugarMode, syntax_node_to_token_tree}; use crate::attr::{DocAtom, DocExpr}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs index 14b9af84e6ffb..6ea21356aa41e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs @@ -6,7 +6,7 @@ use std::fmt; use hir_expand::name::{AsName, Name}; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; /// Different signed int types. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum BuiltinInt { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index 1a6bed6cabbdd..b251564016c7e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -4,19 +4,19 @@ pub mod adt; use base_db::Crate; use hir_expand::name::Name; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use la_arena::{Idx, RawIdx}; use triomphe::Arc; use crate::{ + ConstId, ExternCrateId, FunctionId, HasModule, ImplId, ItemContainerId, ItemLoc, Lookup, + Macro2Id, MacroRulesId, ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, db::DefDatabase, item_tree::{self, FnFlags, ModItem}, - nameres::proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, + nameres::proc_macro::{ProcMacroKind, parse_macro_name_and_helper_attrs}, path::ImportAlias, type_ref::{TraitRef, TypeBound, TypeRefId, TypesMap}, visibility::RawVisibility, - ConstId, ExternCrateId, FunctionId, HasModule, ImplId, ItemContainerId, ItemLoc, Lookup, - Macro2Id, MacroRulesId, ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -431,11 +431,7 @@ impl ExternCrateDeclData { Some(krate) } else { krate.data(db).dependencies.iter().find_map(|dep| { - if dep.name.symbol() == name.symbol() { - Some(dep.crate_id) - } else { - None - } + if dep.name.symbol() == name.symbol() { Some(dep.crate_id) } else { None } }) }; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index 9db66d6e91c99..8ea79406531de 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -11,6 +11,7 @@ use rustc_abi::{IntegerType, ReprOptions}; use triomphe::Arc; use crate::{ + EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId, db::DefDatabase, hir::Expr, item_tree::{ @@ -20,7 +21,6 @@ use crate::{ nameres::diagnostics::{DefDiagnostic, DefDiagnostics}, type_ref::{TypeRefId, TypesMap}, visibility::RawVisibility, - EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId, }; /// Note that we use `StructData` for unions as well! diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 108968fe52e2a..58688d5f41280 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -1,40 +1,40 @@ //! Defines database & queries for name resolution. use base_db::{Crate, RootQueryDb, SourceDatabase, Upcast}; use either::Either; -use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; +use hir_expand::{HirFileId, MacroDefId, db::ExpandDatabase}; use intern::sym; use la_arena::ArenaMap; use span::{EditionedFileId, MacroCallId}; -use syntax::{ast, AstPtr}; +use syntax::{AstPtr, ast}; use triomphe::Arc; use crate::{ + AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId, + EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, + ExternCrateLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, InTypeConstId, + InTypeConstLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, + MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, + TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, + UseId, UseLoc, VariantId, attr::{Attrs, AttrsWithOwner}, data::{ - adt::{EnumData, EnumVariantData, EnumVariants, StructData, VariantData}, ConstData, ExternCrateDeclData, FunctionData, ImplData, Macro2Data, MacroRulesData, ProcMacroData, StaticData, TraitAliasData, TraitData, TypeAliasData, + adt::{EnumData, EnumVariantData, EnumVariants, StructData, VariantData}, }, - expr_store::{scope::ExprScopes, Body, BodySourceMap}, + expr_store::{Body, BodySourceMap, scope::ExprScopes}, generics::GenericParams, import_map::ImportMap, item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps}, lang_item::{self, LangItem, LangItemTarget, LangItems}, nameres::{ + DefMap, LocalDefMap, assoc::{ImplItems, TraitItems}, diagnostics::DefDiagnostics, - DefMap, LocalDefMap, }, tt, type_ref::TypesSourceMap, visibility::{self, Visibility}, - AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId, - EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, - ExternCrateLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, InTypeConstId, - InTypeConstLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, - MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, - TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, - UseId, UseLoc, VariantId, }; use salsa::plumbing::AsId; @@ -337,7 +337,7 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool { for output in segments.skip(1) { match output.flat_tokens() { [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::no_std => { - return true + return true; } _ => {} } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs index 8868bc0cd95bd..b17a2b0a2e2df 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs @@ -27,15 +27,15 @@ pub mod keys { use std::marker::PhantomData; - use hir_expand::{attrs::AttrId, MacroCallId}; + use hir_expand::{MacroCallId, attrs::AttrId}; use rustc_hash::FxHashMap; - use syntax::{ast, AstNode, AstPtr}; + use syntax::{AstNode, AstPtr, ast}; use crate::{ - dyn_map::{DynMap, Policy}, BlockId, ConstId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, ImplId, LifetimeParamId, Macro2Id, MacroRulesId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, UnionId, UseId, + dyn_map::{DynMap, Policy}, }; pub type Key = crate::dyn_map::Key, V, AstPtrPolicy>; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs index 343d8aa1c9f10..895b82796794f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs @@ -6,17 +6,17 @@ use base_db::Crate; use cfg::CfgOptions; use drop_bomb::DropBomb; use hir_expand::{ - attrs::RawAttrs, mod_path::ModPath, span_map::SpanMap, ExpandError, ExpandErrorKind, - ExpandResult, HirFileId, InFile, Lookup, MacroCallId, + ExpandError, ExpandErrorKind, ExpandResult, HirFileId, InFile, Lookup, MacroCallId, + attrs::RawAttrs, mod_path::ModPath, span_map::SpanMap, }; use span::{Edition, SyntaxContext}; -use syntax::{ast, Parse}; +use syntax::{Parse, ast}; use triomphe::Arc; use crate::type_ref::{TypesMap, TypesSourceMap}; use crate::{ - attr::Attrs, db::DefDatabase, lower::LowerCtx, path::Path, AsMacroCall, MacroId, ModuleId, - UnresolvedMacro, + AsMacroCall, MacroId, ModuleId, UnresolvedMacro, attr::Attrs, db::DefDatabase, lower::LowerCtx, + path::Path, }; #[derive(Debug)] @@ -84,11 +84,7 @@ impl Expander { } }); - if let Some(err) = unresolved_macro_err { - Err(err) - } else { - Ok(result) - } + if let Some(err) = unresolved_macro_err { Err(err) } else { Ok(result) } } pub fn enter_expand_id( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs index 7e7ccbfa91a74..c9a7566c8dab5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs @@ -12,16 +12,17 @@ use std::ops::{Deref, Index}; use cfg::{CfgExpr, CfgOptions}; use either::Either; -use hir_expand::{name::Name, ExpandError, InFile}; +use hir_expand::{ExpandError, InFile, name::Name}; use la_arena::{Arena, ArenaMap}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::{Edition, MacroFileId, SyntaxContext}; -use syntax::{ast, AstPtr, SyntaxNodePtr}; +use syntax::{AstPtr, SyntaxNodePtr, ast}; use triomphe::Arc; use tt::TextRange; use crate::{ + BlockId, DefWithBodyId, Lookup, SyntheticSyntax, db::DefDatabase, hir::{ Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat, @@ -30,7 +31,6 @@ use crate::{ nameres::DefMap, path::{ModPath, Path}, type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap}, - BlockId, DefWithBodyId, Lookup, SyntheticSyntax, }; pub use self::body::{Body, BodySourceMap}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs index 8aca4eb9bc1ef..0295874bd7759 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs @@ -9,13 +9,13 @@ use syntax::ast; use triomphe::Arc; use crate::{ + DefWithBodyId, HasModule, db::DefDatabase, expander::Expander, - expr_store::{lower, pretty, ExpressionStore, ExpressionStoreSourceMap, SelfParamPtr}, + expr_store::{ExpressionStore, ExpressionStoreSourceMap, SelfParamPtr, lower, pretty}, hir::{BindingId, ExprId, PatId}, item_tree::AttrOwner, src::HasSource, - DefWithBodyId, HasModule, }; /// The body of an item (function, const etc.). diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index b9b00108dcd24..fe1a5e8f29d10 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -8,26 +8,27 @@ use std::mem; use base_db::Crate; use either::Either; use hir_expand::{ + InFile, MacroDefId, mod_path::tool_path, name::{AsName, Name}, span_map::{ExpansionSpanMap, SpanMap}, - InFile, MacroDefId, }; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use rustc_hash::FxHashMap; use span::AstIdMap; use stdx::never; use syntax::{ + AstNode, AstPtr, AstToken as _, SyntaxNodePtr, ast::{ self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasGenericArgs, HasLoopBody, HasName, RangeItem, SlicePatComponents, }, - AstNode, AstPtr, AstToken as _, SyntaxNodePtr, }; use text_size::TextSize; use triomphe::Arc; use crate::{ + AdtId, BlockId, BlockLoc, ConstBlockLoc, DefWithBodyId, MacroId, ModuleDefId, UnresolvedMacro, attr::Attrs, builtin_type::BuiltinUint, data::adt::StructKind, @@ -38,14 +39,14 @@ use crate::{ ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, PatPtr, }, hir::{ + Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind, + Expr, ExprId, Item, Label, LabelId, Literal, MatchArm, Movability, OffsetOf, Pat, PatId, + RecordFieldPat, RecordLitField, Statement, format_args::{ self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind, FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, }, - Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind, - Expr, ExprId, Item, Label, LabelId, Literal, MatchArm, Movability, OffsetOf, Pat, PatId, - RecordFieldPat, RecordLitField, Statement, }, item_scope::BuiltinShadowMode, lang_item::LangItem, @@ -53,7 +54,6 @@ use crate::{ nameres::{DefMap, LocalDefMap, MacroSubNs}, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness, TypeRef}, - AdtId, BlockId, BlockLoc, ConstBlockLoc, DefWithBodyId, MacroId, ModuleDefId, UnresolvedMacro, }; type FxIndexSet = indexmap::IndexSet>; @@ -641,11 +641,7 @@ impl ExprCollector<'_> { let expr = self.collect_expr_opt(e.expr()); let raw_tok = e.raw_token().is_some(); let mutability = if raw_tok { - if e.mut_token().is_some() { - Mutability::Mut - } else { - Mutability::Shared - } + if e.mut_token().is_some() { Mutability::Mut } else { Mutability::Shared } } else { Mutability::from_mutable(e.mut_token().is_some()) }; @@ -2041,7 +2037,7 @@ impl ExprCollector<'_> { return match l.kind() { ast::LiteralKind::String(s) => Some((s, true)), _ => None, - } + }; } _ => return None, }; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs index 032c18688ea71..633f976a85ddb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs @@ -3,8 +3,8 @@ use hir_expand::name::Name; use intern::Symbol; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ - ast::{self, HasName, IsString}, AstNode, AstPtr, AstToken, T, + ast::{self, HasName, IsString}, }; use tt::TextRange; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs index 42a8eae4064dc..43e11508d8c8b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs @@ -1,13 +1,13 @@ //! Name resolution for expressions. -use hir_expand::{name::Name, MacroDefId}; +use hir_expand::{MacroDefId, name::Name}; use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx}; use triomphe::Arc; use crate::{ + BlockId, ConstBlockId, DefWithBodyId, db::DefDatabase, expr_store::{Body, ExpressionStore, HygieneId}, hir::{Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement}, - BlockId, ConstBlockId, DefWithBodyId, }; pub type ScopeId = Idx; @@ -325,14 +325,14 @@ fn compute_expr_scopes( #[cfg(test)] mod tests { use base_db::RootQueryDb; - use hir_expand::{name::AsName, InFile}; + use hir_expand::{InFile, name::AsName}; use salsa::AsDynDatabase; use span::FileId; - use syntax::{algo::find_node_at_offset, ast, AstNode}; + use syntax::{AstNode, algo::find_node_at_offset, ast}; use test_fixture::WithFixture; use test_utils::{assert_eq_text, extract_offset}; - use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId}; + use crate::{FunctionId, ModuleDefId, db::DefDatabase, test_db::TestDB}; fn find_function(db: &TestDB, file_id: FileId) -> FunctionId { let krate = db.test_crate(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs index 7bf27747c464a..a6fcfaa445e3e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs @@ -1,7 +1,7 @@ mod block; -use crate::{hir::MatchArm, test_db::TestDB, ModuleDefId}; -use expect_test::{expect, Expect}; +use crate::{ModuleDefId, hir::MatchArm, test_db::TestDB}; +use expect_test::{Expect, expect}; use la_arena::RawIdx; use test_fixture::WithFixture; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 48f31698ddf8e..69c7794327540 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -4,19 +4,19 @@ use std::{cell::Cell, cmp::Ordering, iter}; use base_db::{Crate, CrateOrigin, LangCrateOrigin}; use hir_expand::{ - name::{AsName, Name}, Lookup, + name::{AsName, Name}, }; use intern::sym; use rustc_hash::FxHashSet; use crate::{ + ImportPathConfig, ModuleDefId, ModuleId, db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, path::{ModPath, PathKind}, visibility::{Visibility, VisibilityExplicitness}, - ImportPathConfig, ModuleDefId, ModuleId, }; /// Find a path that can be used to refer to a certain item. This can depend on @@ -651,7 +651,7 @@ fn find_local_import_locations( #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use hir_expand::db::ExpandDatabase; use itertools::Itertools; use span::Edition; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs index 6f1650adeb6fe..ad4a8ba2ed16d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs @@ -7,8 +7,8 @@ use std::{ops, sync::LazyLock}; use either::Either; use hir_expand::{ - name::{AsName, Name}, ExpandResult, + name::{AsName, Name}, }; use intern::sym; use la_arena::{Arena, RawIdx}; @@ -20,6 +20,8 @@ use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds}; use triomphe::Arc; use crate::{ + AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId, + LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, db::DefDatabase, expander::Expander, item_tree::{AttrOwner, FileItemTreeId, GenericModItem, GenericsItemTreeNode, ItemTree}, @@ -30,8 +32,6 @@ use crate::{ ArrayType, ConstRef, FnType, LifetimeRef, PathId, RefType, TypeBound, TypeRef, TypeRefId, TypesMap, TypesSourceMap, }, - AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId, - LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, }; /// The index of the self param in the generic of the non-parent definition. @@ -292,11 +292,7 @@ impl GenericParams { parent: GenericDefId, ) -> Option { self.lifetimes.iter().find_map(|(id, p)| { - if &p.name == name { - Some(LifetimeParamId { local_id: id, parent }) - } else { - None - } + if &p.name == name { Some(LifetimeParamId { local_id: id, parent }) } else { None } }) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs index 494644d8eff9d..cd22ae6638ece 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs @@ -17,7 +17,7 @@ pub mod type_ref; use std::fmt; -use hir_expand::{name::Name, MacroDefId}; +use hir_expand::{MacroDefId, name::Name}; use intern::Symbol; use la_arena::Idx; use rustc_apfloat::ieee::{Half as f16, Quad as f128}; @@ -25,10 +25,10 @@ use syntax::ast; use type_ref::TypeRefId; use crate::{ + BlockId, ConstBlockId, builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness}, - BlockId, ConstBlockId, }; pub use syntax::ast::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp}; @@ -137,11 +137,7 @@ pub enum LiteralOrConst { impl Literal { pub fn negate(self) -> Option { - if let Literal::Int(i, k) = self { - Some(Literal::Int(-i, k)) - } else { - None - } + if let Literal::Int(i, k) = self { Some(Literal::Int(-i, k)) } else { None } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index 6331861a992e8..821ec565cff7b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -7,8 +7,8 @@ use rustc_parse_format as parse; use span::SyntaxContext; use stdx::TupleExt; use syntax::{ - ast::{self, IsString}, TextRange, + ast::{self, IsString}, }; use crate::hir::ExprId; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs index 6de4026dff75b..7bb558d34563e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs @@ -5,25 +5,25 @@ use core::fmt; use std::{fmt::Write, ops::Index}; use hir_expand::{ + AstId, InFile, db::ExpandDatabase, name::{AsName, Name}, - AstId, InFile, }; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use la_arena::{Arena, ArenaMap, Idx}; use span::Edition; -use stdx::thin_vec::{thin_vec_with_header_struct, EmptyOptimizedThinVec, ThinVec}; +use stdx::thin_vec::{EmptyOptimizedThinVec, ThinVec, thin_vec_with_header_struct}; use syntax::{ - ast::{self, HasGenericArgs, HasName, IsString}, AstPtr, + ast::{self, HasGenericArgs, HasName, IsString}, }; use crate::{ + SyntheticSyntax, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, hir::Literal, lower::LowerCtx, path::{GenericArg, Path}, - SyntheticSyntax, }; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -34,11 +34,7 @@ pub enum Mutability { impl Mutability { pub fn from_mutable(mutable: bool) -> Mutability { - if mutable { - Mutability::Mut - } else { - Mutability::Shared - } + if mutable { Mutability::Mut } else { Mutability::Shared } } pub fn as_keyword_for_ref(self) -> &'static str { @@ -80,11 +76,7 @@ pub enum Rawness { impl Rawness { pub fn from_raw(is_raw: bool) -> Rawness { - if is_raw { - Rawness::RawPtr - } else { - Rawness::Ref - } + if is_raw { Rawness::RawPtr } else { Rawness::Ref } } pub fn is_raw(&self) -> bool { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 9e4479f05b427..717566f9d7960 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -3,21 +3,21 @@ use std::fmt; use base_db::Crate; -use fst::{raw::IndexedValue, Automaton, Streamer}; +use fst::{Automaton, Streamer, raw::IndexedValue}; use hir_expand::name::Name; use itertools::Itertools; use rustc_hash::FxHashSet; use smallvec::SmallVec; use span::Edition; -use stdx::{format_to, TupleExt}; +use stdx::{TupleExt, format_to}; use triomphe::Arc; use crate::{ + AssocItemId, FxIndexMap, ModuleDefId, ModuleId, TraitId, db::DefDatabase, item_scope::{ImportOrExternCrate, ItemInNs}, nameres::DefMap, visibility::Visibility, - AssocItemId, FxIndexMap, ModuleDefId, ModuleId, TraitId, }; /// Item import details stored in the `ImportMap`. @@ -155,11 +155,7 @@ impl ImportMap { let visible_items = mod_data.scope.entries().filter_map(|(name, per_ns)| { let per_ns = per_ns.filter_visibility(|vis| vis == Visibility::Public); - if per_ns.is_none() { - None - } else { - Some((name, per_ns)) - } + if per_ns.is_none() { None } else { Some((name, per_ns)) } }); for (name, per_ns) in visible_items { @@ -474,10 +470,10 @@ fn search_maps( #[cfg(test)] mod tests { use base_db::{RootQueryDb, Upcast}; - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use test_fixture::WithFixture; - use crate::{test_db::TestDB, ItemContainerId, Lookup}; + use crate::{ItemContainerId, Lookup, test_db::TestDB}; use super::*; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 0c683f3531c95..47ad020043ce0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -4,22 +4,22 @@ use std::sync::LazyLock; use base_db::Crate; -use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId}; +use hir_expand::{AstId, MacroCallId, attrs::AttrId, db::ExpandDatabase, name::Name}; use indexmap::map::Entry; use itertools::Itertools; use la_arena::Idx; use rustc_hash::{FxHashMap, FxHashSet}; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use span::Edition; use stdx::format_to; use syntax::ast; use crate::{ + AdtId, BuiltinType, ConstId, ExternBlockId, ExternCrateId, FxIndexMap, HasModule, ImplId, + LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId, db::DefDatabase, per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem}, visibility::{Visibility, VisibilityExplicitness}, - AdtId, BuiltinType, ConstId, ExternBlockId, ExternCrateId, FxIndexMap, HasModule, ImplId, - LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId, }; #[derive(Debug, Default)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index b9fc9c9489bad..ea87b0f70006c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -46,24 +46,24 @@ use std::{ use ast::{AstNode, StructKind}; use base_db::Crate; use either::Either; -use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile}; +use hir_expand::{ExpandTo, HirFileId, InFile, attrs::RawAttrs, name::Name}; use intern::{Interned, Symbol}; use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::never; -use syntax::{ast, match_ast, SyntaxKind}; +use syntax::{SyntaxKind, ast, match_ast}; use triomphe::Arc; use crate::{ + BlockId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, attr::Attrs, db::DefDatabase, generics::GenericParams, path::{GenericArgs, ImportAlias, ModPath, Path, PathKind}, type_ref::{Mutability, TraitRef, TypeBound, TypeRefId, TypesMap, TypesSourceMap}, visibility::{RawVisibility, VisibilityExplicitness}, - BlockId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, }; #[derive(Copy, Clone, Eq, PartialEq)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 3c85d5bacb459..776ee98f3bce2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -3,23 +3,24 @@ use std::{cell::OnceCell, collections::hash_map::Entry}; use hir_expand::{ + HirFileId, mod_path::path, name::AsName, span_map::{SpanMap, SpanMapRef}, - HirFileId, }; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use la_arena::Arena; use rustc_hash::FxHashMap; use span::{AstIdMap, SyntaxContext}; use stdx::thin_vec::ThinVec; use syntax::{ - ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString}, AstNode, + ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString}, }; use triomphe::Arc; use crate::{ + LocalLifetimeParamId, LocalTypeOrConstParamId, db::DefDatabase, generics::{GenericParams, GenericParamsCollector}, item_tree::{ @@ -38,7 +39,6 @@ use crate::{ TypesMap, TypesSourceMap, }, visibility::RawVisibility, - LocalLifetimeParamId, LocalTypeOrConstParamId, }; fn id(index: Idx) -> FileItemTreeId { @@ -931,8 +931,7 @@ impl<'a> Ctx<'a> { fn desugar_future_path(ctx: &mut LowerCtx<'_>, orig: TypeRefId) -> PathId { let path = path![core::future::Future]; - let mut generic_args: Vec<_> = - std::iter::repeat_n(None, path.segments().len() - 1).collect(); + let mut generic_args: Vec<_> = std::iter::repeat_n(None, path.segments().len() - 1).collect(); let binding = AssociatedTypeBinding { name: Name::new_symbol_root(sym::Output.clone()), args: None, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs index b442e877343fc..47d374a2beeee 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs @@ -1,4 +1,4 @@ -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use span::Edition; use test_fixture::WithFixture; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 67788576c13bc..342c3fedb9608 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -3,13 +3,13 @@ //! This attribute to tell the compiler about semi built-in std library //! features, such as Fn family of traits. use hir_expand::name::Name; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use rustc_hash::FxHashMap; use triomphe::Arc; use crate::{ - db::DefDatabase, path::Path, AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, - FunctionId, ImplId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId, + AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId, + StaticId, StructId, TraitId, TypeAliasId, UnionId, db::DefDatabase, path::Path, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -164,11 +164,7 @@ impl LangItems { } } - if lang_items.items.is_empty() { - None - } else { - Some(Arc::new(lang_items)) - } + if lang_items.items.is_empty() { None } else { Some(Arc::new(lang_items)) } } /// Salsa query. Look for a lang item, starting from the specified crate and recursively @@ -230,11 +226,7 @@ pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option } } - if traits.is_empty() { - None - } else { - Some(traits.into_iter().collect()) - } + if traits.is_empty() { None } else { Some(traits.into_iter().collect()) } } pub enum GenericRequirement { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 209ed46b7a85f..615bd33feb6fa 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -71,25 +71,25 @@ mod test_db; use std::hash::{Hash, Hasher}; -use base_db::{impl_intern_key, Crate}; +use base_db::{Crate, impl_intern_key}; use hir_expand::{ + AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, + MacroDefId, MacroDefKind, builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, eager::expand_eager_macro_input, impl_intern_lookup, name::Name, proc_macro::{CustomProcMacroExpander, ProcMacroKind}, - AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, - MacroDefId, MacroDefKind, }; use item_tree::ExternBlock; use la_arena::Idx; use nameres::DefMap; use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::impl_from; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; -pub use hir_expand::{tt, Intern, Lookup}; +pub use hir_expand::{Intern, Lookup, tt}; use crate::{ builtin_type::BuiltinType, @@ -438,11 +438,7 @@ impl ModuleId { let def_map = self.def_map(db); let parent = def_map[self.local_id].parent?; def_map[parent].children.iter().find_map(|(name, module_id)| { - if *module_id == self.local_id { - Some(name.clone()) - } else { - None - } + if *module_id == self.local_id { Some(name.clone()) } else { None } }) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/lower.rs index 7cddd48eb174c..c0f6e1a6867ce 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lower.rs @@ -1,7 +1,7 @@ //! Context for lowering paths. use std::{cell::OnceCell, mem}; -use hir_expand::{span_map::SpanMap, AstId, HirFileId, InFile}; +use hir_expand::{AstId, HirFileId, InFile, span_map::SpanMap}; use span::{AstIdMap, AstIdNode, Edition, EditionedFileId, FileId, RealSpanMap}; use stdx::thin_vec::ThinVec; use syntax::ast; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 70b512c014b94..d9fbf4b17c5d8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -19,10 +19,10 @@ use std::{iter, ops::Range, sync}; use base_db::RootQueryDb; use expect_test::Expect; use hir_expand::{ + InFile, MacroCallKind, MacroFileId, MacroFileIdExt, MacroKind, db::ExpandDatabase, proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind}, span_map::SpanMapRef, - InFile, MacroCallKind, MacroFileId, MacroFileIdExt, MacroKind, }; use intern::Symbol; use itertools::Itertools; @@ -30,21 +30,21 @@ use salsa::AsDynDatabase; use span::{Edition, Span}; use stdx::{format_to, format_to_acc}; use syntax::{ - ast::{self, edit::IndentLevel}, AstNode, SyntaxKind::{COMMENT, EOF, IDENT, LIFETIME_IDENT}, SyntaxNode, T, + ast::{self, edit::IndentLevel}, }; use test_fixture::WithFixture; use crate::{ + AdtId, AsMacroCall, Lookup, ModuleDefId, db::DefDatabase, nameres::{DefMap, MacroSubNs, ModuleSource}, resolver::HasResolver, src::HasSource, test_db::TestDB, tt::TopSubtree, - AdtId, AsMacroCall, Lookup, ModuleDefId, }; #[track_caller] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index a34766ebc1dca..12293f3a6171e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -62,7 +62,7 @@ use std::ops::Deref; use base_db::Crate; use hir_expand::{ - name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId, + ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId, name::Name, proc_macro::ProcMacroKind, }; use intern::Symbol; use itertools::Itertools; @@ -70,11 +70,13 @@ use la_arena::Arena; use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, EditionedFileId, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; -use syntax::{ast, AstNode, SmolStr, SyntaxNode, ToSmolStr}; +use syntax::{AstNode, SmolStr, SyntaxNode, ToSmolStr, ast}; use triomphe::Arc; use tt::TextRange; use crate::{ + AstId, BlockId, BlockLoc, CrateRootModuleId, EnumId, EnumVariantId, ExternCrateId, FunctionId, + FxIndexMap, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, db::DefDatabase, item_scope::{BuiltinShadowMode, ItemScope}, item_tree::{ItemTreeId, Mod, TreeId}, @@ -82,8 +84,6 @@ use crate::{ path::ModPath, per_ns::PerNs, visibility::{Visibility, VisibilityExplicitness}, - AstId, BlockId, BlockLoc, CrateRootModuleId, EnumId, EnumVariantId, ExternCrateId, FunctionId, - FxIndexMap, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, }; pub use self::path_resolution::ResolvePathResultPrefixInfo; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs index dea6d334f8aa6..1b3d10f098b4a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs @@ -1,25 +1,25 @@ //! Expansion of associated items use hir_expand::{ - name::Name, AstId, ExpandResult, InFile, Intern, Lookup, MacroCallKind, MacroDefKind, + AstId, ExpandResult, InFile, Intern, Lookup, MacroCallKind, MacroDefKind, name::Name, }; use smallvec::SmallVec; use span::{HirFileId, MacroCallId}; -use syntax::{ast, Parse}; +use syntax::{Parse, ast}; use triomphe::Arc; use crate::{ + AssocItemId, AstIdWithPath, ConstLoc, FunctionId, FunctionLoc, ImplId, ItemContainerId, + ItemLoc, ModuleId, TraitId, TypeAliasId, TypeAliasLoc, db::DefDatabase, expander::{Expander, Mark}, item_tree::{self, AssocItem, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId}, macro_call_as_call_id, nameres::{ + DefMap, LocalDefMap, MacroSubNs, attr_resolution::ResolvedAttr, diagnostics::{DefDiagnostic, DefDiagnostics}, - DefMap, LocalDefMap, MacroSubNs, }, - AssocItemId, AstIdWithPath, ConstLoc, FunctionId, FunctionLoc, ImplId, ItemContainerId, - ItemLoc, ModuleId, TraitId, TypeAliasId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index c35a7fdc96d2a..7820c6fcbe311 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -2,20 +2,20 @@ use base_db::Crate; use hir_expand::{ + MacroCallId, MacroCallKind, MacroDefId, attrs::{Attr, AttrId, AttrInput}, inert_attr_macro::find_builtin_attr_idx, - MacroCallId, MacroCallKind, MacroDefId, }; use span::SyntaxContext; use syntax::ast; use triomphe::Arc; use crate::{ + AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro, db::DefDatabase, item_scope::BuiltinShadowMode, - nameres::{path_resolution::ResolveMode, LocalDefMap}, + nameres::{LocalDefMap, path_resolution::ResolveMode}, path::{self, ModPath, PathKind}, - AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro, }; use super::{DefMap, MacroSubNs}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 43b011e57f46a..045a8695407b7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -9,15 +9,15 @@ use base_db::{BuiltDependency, Crate, CrateOrigin, LangCrateOrigin}; use cfg::{CfgAtom, CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ + ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, + MacroFileIdExt, attrs::{Attr, AttrId}, builtin::{find_builtin_attr, find_builtin_derive, find_builtin_macro}, name::{AsName, Name}, proc_macro::CustomProcMacroExpander, - ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, - MacroFileIdExt, }; -use intern::{sym, Interned}; -use itertools::{izip, Itertools}; +use intern::{Interned, sym}; +use itertools::{Itertools, izip}; use la_arena::Idx; use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, EditionedFileId, FileAstId, SyntaxContext}; @@ -25,6 +25,12 @@ use syntax::ast; use triomphe::Arc; use crate::{ + AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantLoc, + ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, + ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, + MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, + ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, + UnresolvedMacro, UseId, UseLoc, attr::Attrs, db::DefDatabase, item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports}, @@ -34,24 +40,18 @@ use crate::{ }, macro_call_as_call_id, macro_call_as_call_id_with_eager, nameres::{ + BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, ModuleData, ModuleOrigin, ResolveMode, attr_resolution::{attr_macro_as_call_id, derive_macro_as_call_id}, diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, - proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroDef, ProcMacroKind}, - sub_namespace_match, BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, ModuleData, - ModuleOrigin, ResolveMode, + proc_macro::{ProcMacroDef, ProcMacroKind, parse_macro_name_and_helper_attrs}, + sub_namespace_match, }, path::{ImportAlias, ModPath, PathKind}, per_ns::{Item, PerNs}, tt, visibility::{RawVisibility, Visibility}, - AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantLoc, - ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, - ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, - MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, - ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, - UnresolvedMacro, UseId, UseLoc, }; const GLOB_RECURSION_LIMIT: usize = 100; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs index bc1617c55b029..1744d3465b272 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs @@ -3,15 +3,15 @@ use std::ops::Not; use cfg::{CfgExpr, CfgOptions}; -use hir_expand::{attrs::AttrId, ExpandErrorKind, MacroCallKind}; +use hir_expand::{ExpandErrorKind, MacroCallKind, attrs::AttrId}; use la_arena::Idx; use syntax::ast; use crate::{ + AstId, item_tree::{self, AttrOwner, ItemTreeId, TreeId}, nameres::LocalModuleId, path::ModPath, - AstId, }; #[derive(Debug, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs index a012eb6ff7eb9..97db89d1e7661 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs @@ -1,10 +1,10 @@ //! This module resolves `mod foo;` declaration to file. use arrayvec::ArrayVec; use base_db::{AnchoredPath, RootQueryDb}; -use hir_expand::{name::Name, HirFileIdExt}; +use hir_expand::{HirFileIdExt, name::Name}; use span::EditionedFileId; -use crate::{db::DefDatabase, HirFileId}; +use crate::{HirFileId, db::DefDatabase}; const MOD_DEPTH_LIMIT: usize = 32; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index 977bc16adf7ee..e7cb91300b58d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -11,19 +11,19 @@ //! `ReachedFixedPoint` signals about this. use either::Either; -use hir_expand::{name::Name, Lookup}; +use hir_expand::{Lookup, name::Name}; use span::Edition; use triomphe::Arc; use crate::{ + AdtId, LocalModuleId, ModuleDefId, db::DefDatabase, - item_scope::{ImportOrExternCrate, BUILTIN_SCOPE}, + item_scope::{BUILTIN_SCOPE, ImportOrExternCrate}, item_tree::FieldsShape, - nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs}, + nameres::{BlockInfo, BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, sub_namespace_match}, path::{ModPath, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, - AdtId, LocalModuleId, ModuleDefId, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -356,7 +356,7 @@ impl DefMap { PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) { Either::Left(it) => it, Either::Right(reached_fixed_point) => { - return ResolvePathResult::empty(reached_fixed_point) + return ResolvePathResult::empty(reached_fixed_point); } }, }; @@ -402,11 +402,11 @@ impl DefMap { PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) { Either::Left(it) => it, Either::Right(reached_fixed_point) => { - return ResolvePathResult::empty(reached_fixed_point) + return ResolvePathResult::empty(reached_fixed_point); } }, PathKind::DollarCrate(_) | PathKind::Crate | PathKind::Super(_) => { - return ResolvePathResult::empty(ReachedFixedPoint::Yes) + return ResolvePathResult::empty(ReachedFixedPoint::Yes); } }; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs index 7c9fad91865db..3fd095a9a98a8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs @@ -5,7 +5,7 @@ mod mod_resolution; mod primitives; use base_db::RootQueryDb; -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use test_fixture::WithFixture; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs index 9a601e0f01384..bd25d0bd58588 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs @@ -7,7 +7,7 @@ use span::Edition; use test_fixture::WithFixture; use triomphe::Arc; -use crate::{db::DefDatabase, nameres::tests::TestDB, AdtId, ModuleDefId}; +use crate::{AdtId, ModuleDefId, db::DefDatabase, nameres::tests::TestDB}; fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change: &str) { let (mut db, pos) = TestDB::with_position(ra_fixture_initial); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path.rs b/src/tools/rust-analyzer/crates/hir-def/src/path.rs index 713e7389736a0..ec2c8d12aad64 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path.rs @@ -19,7 +19,7 @@ use span::Edition; use stdx::thin_vec::thin_vec_with_header_struct; use syntax::ast; -pub use hir_expand::mod_path::{path, ModPath, PathKind}; +pub use hir_expand::mod_path::{ModPath, PathKind, path}; pub use lower::hir_segment_to_ast_segment; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs index 7a6d6973298b7..ef0ef0e82363b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs @@ -8,7 +8,7 @@ use hir_expand::{ mod_path::resolve_crate_root, name::{AsName, Name}, }; -use intern::{sym, Interned}; +use intern::{Interned, sym}; use stdx::thin_vec::EmptyOptimizedThinVec; use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/tests.rs index 67a27bf85e89c..c0bfb0c872178 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path/tests.rs @@ -1,4 +1,4 @@ -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use span::Edition; use syntax::ast::{self, make}; use test_fixture::WithFixture; @@ -6,8 +6,8 @@ use test_fixture::WithFixture; use crate::{ lower::LowerCtx, path::{ - lower::{hir_segment_to_ast_segment, SEGMENT_LOWERING_MAP}, Path, + lower::{SEGMENT_LOWERING_MAP, hir_segment_to_ast_segment}, }, pretty, test_db::TestDB, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs index c2d3f67f17e77..1f7dd6f0c4075 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs @@ -6,9 +6,9 @@ use bitflags::bitflags; use crate::{ + MacroId, ModuleDefId, item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob, ItemInNs}, visibility::Visibility, - MacroId, ModuleDefId, }; #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] @@ -146,11 +146,7 @@ impl PerNs { } pub fn or_else(self, f: impl FnOnce() -> PerNs) -> PerNs { - if self.is_full() { - self - } else { - self.or(f()) - } + if self.is_full() { self } else { self.or(f()) } } pub fn iter_items(self) -> impl Iterator)> { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 997a12a328e10..28ebaadf4d79e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -2,36 +2,36 @@ use std::{fmt, iter, mem}; use base_db::Crate; -use hir_expand::{name::Name, MacroDefId}; -use intern::{sym, Symbol}; +use hir_expand::{MacroDefId, name::Name}; +use intern::{Symbol, sym}; use itertools::Itertools as _; use rustc_hash::FxHashSet; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use span::SyntaxContext; use triomphe::Arc; use crate::{ + AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, + ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, + ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, + MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, + TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId, builtin_type::BuiltinType, data::ExternCrateDeclData, db::DefDatabase, expr_store::{ - scope::{ExprScopes, ScopeId}, HygieneId, + scope::{ExprScopes, ScopeId}, }, generics::{GenericParams, TypeOrConstParamData}, hir::{BindingId, ExprId, LabelId}, - item_scope::{BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, BUILTIN_SCOPE}, + item_scope::{BUILTIN_SCOPE, BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob}, lang_item::LangItemTarget, nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo}, path::{ModPath, Path, PathKind}, per_ns::PerNs, type_ref::{LifetimeRef, TypesMap}, visibility::{RawVisibility, Visibility}, - AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, - ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, - ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, - MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, - TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId, }; #[derive(Debug, Clone)] @@ -209,11 +209,7 @@ impl Resolver { } let remaining_idx = || { - if path.segments().len() == 1 { - None - } else { - Some(1) - } + if path.segments().len() == 1 { None } else { Some(1) } }; for scope in self.scopes() { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs index 347c4803be1cc..3867f39b8b173 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs @@ -3,13 +3,13 @@ use either::Either; use hir_expand::InFile; use la_arena::ArenaMap; -use syntax::{ast, AstNode, AstPtr}; +use syntax::{AstNode, AstPtr, ast}; use crate::{ - db::DefDatabase, - item_tree::{AttrOwner, FieldParent, ItemTreeNode}, GenericDefId, ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, UseId, VariantId, + db::DefDatabase, + item_tree::{AttrOwner, FieldParent, ItemTreeNode}, }; pub trait HasSource { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs index 0b97e6c9ce5b9..91cadb0e81046 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs @@ -6,17 +6,17 @@ use base_db::{ Crate, CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, Upcast, }; -use hir_expand::{db::ExpandDatabase, files::FilePosition, InFile}; +use hir_expand::{InFile, db::ExpandDatabase, files::FilePosition}; use salsa::{AsDynDatabase, Durability}; use span::{EditionedFileId, FileId}; -use syntax::{algo, ast, AstNode}; +use syntax::{AstNode, algo, ast}; use triomphe::Arc; use crate::{ + LocalModuleId, Lookup, ModuleDefId, ModuleId, db::DefDatabase, nameres::{DefMap, ModuleSource}, src::HasSource, - LocalModuleId, Lookup, ModuleDefId, ModuleId, }; #[salsa::db] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index 86a2d02a9f46e..f4729a4f8e0dc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -9,11 +9,11 @@ use syntax::ast; use triomphe::Arc; use crate::{ + ConstId, FunctionId, HasModule, LocalFieldId, LocalModuleId, ModuleId, VariantId, db::DefDatabase, nameres::DefMap, path::{ModPath, PathKind}, resolver::HasResolver, - ConstId, FunctionId, HasModule, LocalFieldId, LocalModuleId, ModuleId, VariantId, }; /// Visibility of an item, not yet resolved. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 6bfef1d28b720..862e3c7305f5d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -4,23 +4,23 @@ use std::{borrow::Cow, fmt, ops}; use base_db::Crate; use cfg::CfgExpr; use either::Either; -use intern::{sym, Interned, Symbol}; +use intern::{Interned, Symbol, sym}; use mbe::{DelimiterKind, Punct}; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use span::{Span, SyntaxContext}; use syntax::unescape; -use syntax::{ast, match_ast, AstNode, AstToken, SyntaxNode}; -use syntax_bridge::{desugar_doc_comment_text, syntax_node_to_token_tree, DocCommentDesugarMode}; +use syntax::{AstNode, AstToken, SyntaxNode, ast, match_ast}; +use syntax_bridge::{DocCommentDesugarMode, desugar_doc_comment_text, syntax_node_to_token_tree}; use triomphe::ThinArc; use crate::name::Name; use crate::{ + InFile, db::ExpandDatabase, mod_path::ModPath, span_map::SpanMapRef, - tt::{self, token_to_literal, TopSubtree}, - InFile, + tt::{self, TopSubtree, token_to_literal}, }; /// Syntactical attributes, without filtering of `cfg_attr`s. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs index 7b9b7f36e2cdb..0bf4943b60cec 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs @@ -7,9 +7,9 @@ mod derive_macro; mod fn_macro; pub use self::{ - attr_macro::{find_builtin_attr, pseudo_derive_attr_expansion, BuiltinAttrExpander}, - derive_macro::{find_builtin_derive, BuiltinDeriveExpander}, + attr_macro::{BuiltinAttrExpander, find_builtin_attr, pseudo_derive_attr_expansion}, + derive_macro::{BuiltinDeriveExpander, find_builtin_derive}, fn_macro::{ - find_builtin_macro, include_input_to_file_id, BuiltinFnLikeExpander, EagerExpander, + BuiltinFnLikeExpander, EagerExpander, find_builtin_macro, include_input_to_file_id, }, }; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs index e9dc17a28f688..0463ce11f6791 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs @@ -2,7 +2,7 @@ use intern::sym; use span::{MacroCallId, Span}; -use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind}; +use crate::{ExpandResult, MacroCallKind, db::ExpandDatabase, name, tt}; use super::quote; @@ -130,7 +130,7 @@ fn derive_expand( return ExpandResult::ok(tt::TopSubtree::empty(tt::DelimSpan { open: span, close: span, - })) + })); } }; pseudo_derive_attr_expansion(tt, derives, span) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs index 149ab73ec5477..b6181e8ce8c90 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs @@ -1,7 +1,7 @@ //! Builtin derives. use intern::sym; -use itertools::{izip, Itertools}; +use itertools::{Itertools, izip}; use parser::SyntaxKind; use rustc_hash::FxHashSet; use span::{Edition, MacroCallId, Span, SyntaxContext}; @@ -10,17 +10,18 @@ use syntax_bridge::DocCommentDesugarMode; use tracing::debug; use crate::{ + ExpandError, ExpandResult, builtin::quote::{dollar_crate, quote}, db::ExpandDatabase, hygiene::span_with_def_site_ctxt, name::{self, AsName, Name}, span_map::ExpansionSpanMap, - tt, ExpandError, ExpandResult, + tt, }; use syntax::{ ast::{ - self, edit_in_place::GenericParamsOwnerEdit, make, AstNode, FieldList, HasAttrs, - HasGenericArgs, HasGenericParams, HasModuleItem, HasName, HasTypeBounds, + self, AstNode, FieldList, HasAttrs, HasGenericArgs, HasGenericParams, HasModuleItem, + HasName, HasTypeBounds, edit_in_place::GenericParamsOwnerEdit, make, }, ted, }; @@ -464,7 +465,7 @@ fn expand_simple_derive( return ExpandResult::new( tt::TopSubtree::empty(tt::DelimSpan { open: invoc_span, close: invoc_span }), e, - ) + ); } }; ExpandResult::ok(expand_simple_derive_with_parsed( @@ -1072,7 +1073,7 @@ fn coerce_pointee_expand( "exactly one generic type parameter must be marked \ as `#[pointee]` to derive `CoercePointee` traits", ), - ) + ); } (Some(_), Some(_)) => { return ExpandResult::new( @@ -1082,7 +1083,7 @@ fn coerce_pointee_expand( "only one type parameter can be marked as `#[pointee]` \ when deriving `CoercePointee` traits", ), - ) + ); } } }; @@ -1120,7 +1121,9 @@ fn coerce_pointee_expand( tt::TopSubtree::empty(tt::DelimSpan::from_single(span)), ExpandError::other( span, - format!("`derive(CoercePointee)` requires `{pointee_param_name}` to be marked `?Sized`"), + format!( + "`derive(CoercePointee)` requires `{pointee_param_name}` to be marked `?Sized`" + ), ), ); } @@ -1335,7 +1338,7 @@ fn coerce_pointee_expand( let info = match parse_adt_from_syntax(&adt, &span_map, span) { Ok(it) => it, Err(err) => { - return ExpandResult::new(tt::TopSubtree::empty(tt::DelimSpan::from_single(span)), err) + return ExpandResult::new(tt::TopSubtree::empty(tt::DelimSpan::from_single(span)), err); } }; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 2fb1f96350cd5..e83d9abf83b79 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -4,26 +4,26 @@ use base_db::AnchoredPath; use cfg::CfgExpr; use either::Either; use intern::{ - sym::{self}, Symbol, + sym::{self}, }; -use mbe::{expect_fragment, DelimiterKind}; +use mbe::{DelimiterKind, expect_fragment}; use span::{Edition, EditionedFileId, FileId, Span}; use stdx::format_to; use syntax::{ format_smolstr, - unescape::{unescape_byte, unescape_char, unescape_unicode, Mode}, + unescape::{Mode, unescape_byte, unescape_char, unescape_unicode}, }; use syntax_bridge::syntax_node_to_token_tree; use crate::{ - builtin::quote::{dollar_crate, quote, WithDelimiter}, + ExpandError, ExpandResult, HirFileIdExt, Lookup as _, MacroCallId, + builtin::quote::{WithDelimiter, dollar_crate, quote}, db::ExpandDatabase, hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt}, name, span_map::SpanMap, tt::{self, DelimSpan, TtElement, TtIter}, - ExpandError, ExpandResult, HirFileIdExt, Lookup as _, MacroCallId, }; macro_rules! register_builtin { @@ -427,12 +427,15 @@ fn compile_error_expand( span: Span, ) -> ExpandResult { let err = match &*tt.0 { - [_, tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span: _, - kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), - suffix: _, - }))] => ExpandError::other(span, Box::from(unescape_str(text).as_str())), + [ + _, + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + symbol: text, + span: _, + kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), + suffix: _, + })), + ] => ExpandError::other(span, Box::from(unescape_str(text).as_str())), _ => ExpandError::other(span, "`compile_error!` argument must be a string"), }; @@ -736,7 +739,7 @@ fn include_expand( return ExpandResult::new( tt::TopSubtree::empty(DelimSpan { open: span, close: span }), e, - ) + ); } }; let span_map = db.real_span_map(editioned_file_id); @@ -789,7 +792,7 @@ fn include_str_expand( return ExpandResult::new( tt::TopSubtree::empty(DelimSpan { open: span, close: span }), e, - ) + ); } }; @@ -827,7 +830,7 @@ fn env_expand( return ExpandResult::new( tt::TopSubtree::empty(DelimSpan { open: span, close: span }), e, - ) + ); } }; @@ -865,7 +868,7 @@ fn option_env_expand( return ExpandResult::new( tt::TopSubtree::empty(DelimSpan { open: call_site, close: call_site }), e, - ) + ); } }; let dollar_crate = dollar_crate(call_site); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs index 9dd2b77b525c4..859f6f7b1449d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs @@ -1,7 +1,7 @@ //! A simplified version of quote-crate like quasi quote macro #![allow(clippy::crate_in_macro_def)] -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use span::Span; use syntax::ToSmolStr; use tt::IdentIsRaw; @@ -226,7 +226,7 @@ mod tests { use ::tt::IdentIsRaw; use expect_test::expect; use intern::Symbol; - use span::{Edition, SpanAnchor, SyntaxContext, ROOT_ERASED_FILE_AST_ID}; + use span::{Edition, ROOT_ERASED_FILE_AST_ID, SpanAnchor, SyntaxContext}; use syntax::{TextRange, TextSize}; use super::quote; @@ -324,6 +324,9 @@ mod tests { } }; - assert_eq!(quoted.to_string(), "impl Clone for Foo {fn clone (& self) -> Self {Self {name : self . name . clone () , id : self . id . clone () ,}}}"); + assert_eq!( + quoted.to_string(), + "impl Clone for Foo {fn clone (& self) -> Self {Self {name : self . name . clone () , id : self . id . clone () ,}}}" + ); } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs index 0ceab3c890217..c6ea4a3a33db8 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs @@ -3,15 +3,15 @@ use std::iter::Peekable; use base_db::Crate; use cfg::{CfgAtom, CfgExpr}; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use rustc_hash::FxHashSet; use syntax::{ - ast::{self, Attr, HasAttrs, Meta, TokenTree, VariantList}, AstNode, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, T, + ast::{self, Attr, HasAttrs, Meta, TokenTree, VariantList}, }; use tracing::{debug, warn}; -use crate::{db::ExpandDatabase, proc_macro::ProcMacroKind, MacroCallLoc, MacroDefKind}; +use crate::{MacroCallLoc, MacroDefKind, db::ExpandDatabase, proc_macro::ProcMacroKind}; fn check_cfg(db: &dyn ExpandDatabase, attr: &Attr, krate: Crate) -> Option { if !attr.simple_name().as_deref().map(|v| v == "cfg")? { @@ -344,8 +344,8 @@ where #[cfg(test)] mod tests { use cfg::DnfExpr; - use expect_test::{expect, Expect}; - use syntax::{ast::Attr, AstNode, SourceFile}; + use expect_test::{Expect, expect}; + use syntax::{AstNode, SourceFile, ast::Attr}; use crate::cfg_process::parse_from_attr_token_tree; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 85c242a790fc9..2fe251d298907 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -9,25 +9,26 @@ use span::{ AstIdMap, Edition, EditionedFileId, HirFileId, HirFileIdRepr, MacroCallId, MacroFileId, Span, SyntaxContext, }; -use syntax::{ast, AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T}; -use syntax_bridge::{syntax_node_to_token_tree, DocCommentDesugarMode}; +use syntax::{AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T, ast}; +use syntax_bridge::{DocCommentDesugarMode, syntax_node_to_token_tree}; use triomphe::Arc; use crate::{ - attrs::{collect_attrs, AttrId}, + AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo, + EagerExpander, ExpandError, ExpandResult, ExpandTo, MacroCallKind, MacroCallLoc, MacroDefId, + MacroDefKind, + attrs::{AttrId, collect_attrs}, builtin::pseudo_derive_attr_expansion, cfg_process, declarative::DeclarativeMacroExpander, fixup::{self, SyntaxFixupUndoInfo}, hygiene::{ - span_with_call_site_ctxt, span_with_def_site_ctxt, span_with_mixed_site_ctxt, - SyntaxContextExt as _, + SyntaxContextExt as _, span_with_call_site_ctxt, span_with_def_site_ctxt, + span_with_mixed_site_ctxt, }, proc_macro::{CrateProcMacros, CustomProcMacroExpander, ProcMacros}, span_map::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef}, - tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo, - EagerExpander, ExpandError, ExpandResult, ExpandTo, MacroCallKind, MacroCallLoc, MacroDefId, - MacroDefKind, + tt, }; /// This is just to ensure the types of smart_macro_arg and macro_arg are the same type MacroArgResult = (Arc, SyntaxFixupUndoInfo, Span); @@ -397,11 +398,7 @@ fn parse_macro_expansion_error( ) -> Option>>> { let e: ExpandResult> = db.parse_macro_expansion(MacroFileId { macro_call_id }).map(|it| Arc::from(it.0.errors())); - if e.value.is_empty() && e.err.is_none() { - None - } else { - Some(Arc::new(e)) - } + if e.value.is_empty() && e.err.is_none() { None } else { Some(Arc::new(e)) } } pub(crate) fn parse_with_map( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index a0b614add4974..063410230d438 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -4,15 +4,16 @@ use base_db::Crate; use intern::sym; use span::{Edition, HirFileIdRepr, MacroCallId, Span, SyntaxContext}; use stdx::TupleExt; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use syntax_bridge::DocCommentDesugarMode; use triomphe::Arc; use crate::{ + AstId, ExpandError, ExpandErrorKind, ExpandResult, Lookup, attrs::RawAttrs, db::ExpandDatabase, - hygiene::{apply_mark, Transparency}, - tt, AstId, ExpandError, ExpandErrorKind, ExpandResult, Lookup, + hygiene::{Transparency, apply_mark}, + tt, }; /// Old-style `macro_rules` or the new macros 2.0 diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs index fcf3929eaab06..dd824e6fd0408 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs @@ -20,16 +20,16 @@ //! See the full discussion : use base_db::Crate; use span::SyntaxContext; -use syntax::{ted, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent}; +use syntax::{Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent, ted}; use syntax_bridge::DocCommentDesugarMode; use triomphe::Arc; use crate::{ + AstId, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, InFile, + MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, ast::{self, AstNode}, db::ExpandDatabase, mod_path::ModPath, - AstId, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, InFile, - MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, }; pub fn expand_eager_macro_input( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs index 3a26c62e1f200..c34570fcb5cf9 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs @@ -9,8 +9,9 @@ use span::{ use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize}; use crate::{ + MacroFileIdExt, MacroKind, db::{self, ExpandDatabase}, - map_node_range_up, map_node_range_up_rooted, span_for_offset, MacroFileIdExt, MacroKind, + map_node_range_up, map_node_range_up_rooted, span_for_offset, }; /// `InFile` stores a value of `T` inside a particular file/syntax tree. @@ -365,11 +366,7 @@ impl InFile { // FIXME: Figure out an API that makes proper use of ctx, this only exists to // keep pre-token map rewrite behaviour. - if ctxt.is_root() { - Some(range) - } else { - None - } + if ctxt.is_root() { Some(range) } else { None } } } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index 076dd75cde35f..740152892b8b4 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -4,13 +4,14 @@ use intern::sym; use rustc_hash::{FxHashMap, FxHashSet}; use span::{ - ErasedFileAstId, Span, SpanAnchor, SyntaxContext, FIXUP_ERASED_FILE_AST_ID_MARKER, - ROOT_ERASED_FILE_AST_ID, + ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, + SyntaxContext, }; use stdx::never; use syntax::{ + SyntaxElement, SyntaxKind, SyntaxNode, TextRange, TextSize, ast::{self, AstNode, HasLoopBody}, - match_ast, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, TextSize, + match_ast, }; use syntax_bridge::DocCommentDesugarMode; use triomphe::Arc; @@ -465,7 +466,7 @@ fn reverse_fixups_(tt: &mut TopSubtree, undo_info: &[TopSubtree]) { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use span::{Edition, EditionedFileId, FileId}; use syntax::TextRange; use syntax_bridge::DocCommentDesugarMode; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs index 20694e7d6b80b..d684a2f9ce7ab 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs @@ -147,7 +147,7 @@ pub trait SyntaxContextExt { fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; fn remove_mark(&mut self, db: &dyn ExpandDatabase) - -> (Option, Transparency); + -> (Option, Transparency); fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency); fn marks(self, db: &dyn ExpandDatabase) -> Vec<(span::MacroCallId, Transparency)>; fn is_opaque(self, db: &dyn ExpandDatabase) -> bool; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index ca5c40c9fac34..d089d4c49eb9c 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -40,15 +40,15 @@ use span::{ SyntaxContext, }; use syntax::{ - ast::{self, AstNode}, SyntaxNode, SyntaxToken, TextRange, TextSize, + ast::{self, AstNode}, }; use crate::{ attrs::AttrId, builtin::{ - include_input_to_file_id, BuiltinAttrExpander, BuiltinDeriveExpander, - BuiltinFnLikeExpander, EagerExpander, + BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander, + include_input_to_file_id, }, db::ExpandDatabase, mod_path::ModPath, @@ -67,7 +67,7 @@ pub use span::{HirFileId, MacroCallId, MacroFileId}; pub mod tt { pub use span::Span; - pub use tt::{token_to_literal, DelimiterKind, IdentIsRaw, LitKind, Spacing}; + pub use tt::{DelimiterKind, IdentIsRaw, LitKind, Spacing, token_to_literal}; pub type Delimiter = ::tt::Delimiter; pub type DelimSpan = ::tt::DelimSpan; @@ -207,7 +207,9 @@ impl ExpandErrorKind { kind: RenderedExpandError::GENERAL_KIND, }, None => RenderedExpandError { - message: format!("internal error: proc-macro map is missing error entry for crate {def_crate:?}"), + message: format!( + "internal error: proc-macro map is missing error entry for crate {def_crate:?}" + ), error: true, kind: RenderedExpandError::GENERAL_KIND, }, @@ -389,7 +391,7 @@ impl HirFileIdExt for HirFileId { loop { match call.file_id.repr() { HirFileIdRepr::FileId(file_id) => { - break Some(InRealFile { file_id, value: call.value }) + break Some(InRealFile { file_id, value: call.value }); } HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => { call = db.lookup_intern_macro_call(macro_call_id).to_node(db); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 5c160240a2ba2..7f8dc0dba6ff6 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -7,7 +7,7 @@ use std::{ use crate::{ db::ExpandDatabase, - hygiene::{marks_rev, SyntaxContextExt, Transparency}, + hygiene::{SyntaxContextExt, Transparency, marks_rev}, name::{AsName, Name}, tt, }; @@ -15,7 +15,7 @@ use base_db::Crate; use intern::sym; use smallvec::SmallVec; use span::{Edition, SyntaxContext}; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ModPath { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 79860a002afe7..23ca77f5a0d84 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -2,7 +2,7 @@ use std::fmt; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use span::{Edition, SyntaxContext}; use syntax::utils::is_raw_identifier; use syntax::{ast, format_smolstr}; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs index f398b070f791b..953aea65b2cd9 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs @@ -3,7 +3,7 @@ use base_db::Crate; use rustc_hash::FxHashMap; use syntax::NodeOrToken; -use syntax::{ast::make, SyntaxNode}; +use syntax::{SyntaxNode, ast::make}; use crate::{db::ExpandDatabase, span_map::ExpansionSpanMap}; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs index 1330f6af9fd37..9dcd5ef1ef03e 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs @@ -10,7 +10,7 @@ use rustc_hash::FxHashMap; use span::Span; use triomphe::Arc; -use crate::{db::ExpandDatabase, tt, ExpandError, ExpandErrorKind, ExpandResult}; +use crate::{ExpandError, ExpandErrorKind, ExpandResult, db::ExpandDatabase, tt}; #[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug, Hash)] pub enum ProcMacroKind { @@ -298,7 +298,7 @@ impl CustomProcMacroExpander { call_site, "internal error: no proc macros for crate", ), - ) + ); } }; let proc_macro = match proc_macros.get(id, call_site) { @@ -310,7 +310,7 @@ impl CustomProcMacroExpander { close: call_site, }), e, - ) + ); } }; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs index 55fe42e271f4d..1965e767074a2 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs @@ -2,7 +2,7 @@ use span::{EditionedFileId, HirFileId, HirFileIdRepr, MacroFileId, Span, SyntaxContext}; use stdx::TupleExt; -use syntax::{ast, AstNode, TextRange}; +use syntax::{AstNode, TextRange, ast}; use triomphe::Arc; pub use span::RealSpanMap; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs index 2c27f5e3bbf18..8f3526f1d4905 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs @@ -12,8 +12,8 @@ use intern::sym; use triomphe::Arc; use crate::{ - db::HirDatabase, infer::unify::InferenceTable, Canonical, Goal, Interner, ProjectionTyExt, - TraitEnvironment, Ty, TyBuilder, TyKind, + Canonical, Goal, Interner, ProjectionTyExt, TraitEnvironment, Ty, TyBuilder, TyKind, + db::HirDatabase, infer::unify::InferenceTable, }; const AUTODEREF_RECURSION_LIMIT: usize = 20; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs index 4c35db0c9b98c..2898ab7b49f52 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs @@ -3,21 +3,21 @@ use std::iter; use chalk_ir::{ + AdtId, DebruijnIndex, Scalar, cast::{Cast, CastTo, Caster}, fold::TypeFoldable, interner::HasInterner, - AdtId, DebruijnIndex, Scalar, }; use hir_def::{ - builtin_type::BuiltinType, DefWithBodyId, GenericDefId, GenericParamId, TraitId, TypeAliasId, + DefWithBodyId, GenericDefId, GenericParamId, TraitId, TypeAliasId, builtin_type::BuiltinType, }; use smallvec::SmallVec; use crate::{ - consteval::unknown_const_as_generic, db::HirDatabase, error_lifetime, generics::generics, - infer::unify::InferenceTable, primitive, to_assoc_type_id, to_chalk_trait_id, Binders, - BoundVar, CallableSig, GenericArg, GenericArgData, Interner, ProjectionTy, Substitution, - TraitRef, Ty, TyDefId, TyExt, TyKind, + Binders, BoundVar, CallableSig, GenericArg, GenericArgData, Interner, ProjectionTy, + Substitution, TraitRef, Ty, TyDefId, TyExt, TyKind, consteval::unknown_const_as_generic, + db::HirDatabase, error_lifetime, generics::generics, infer::unify::InferenceTable, primitive, + to_assoc_type_id, to_chalk_trait_id, }; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index acaca24f54f9b..e0975b5aeb40b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -8,31 +8,32 @@ use intern::sym; use span::Edition; use tracing::debug; -use chalk_ir::{cast::Caster, fold::shift::Shift, CanonicalVarKinds}; +use chalk_ir::{CanonicalVarKinds, cast::Caster, fold::shift::Shift}; use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; use base_db::Crate; use hir_def::{ - data::{adt::StructFlags, TraitFlags}, - hir::Movability, - lang_item::{LangItem, LangItemTarget}, AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup, TypeAliasId, VariantId, + data::{TraitFlags, adt::StructFlags}, + hir::Movability, + lang_item::{LangItem, LangItemTarget}, }; use crate::{ + AliasEq, AliasTy, BoundVar, DebruijnIndex, FnDefId, Interner, ProjectionTy, ProjectionTyExt, + QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, + WhereClause, db::{HirDatabase, InternedCoroutine}, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, generics::generics, make_binders, make_single_type_binders, - mapping::{from_chalk, ToChalk, TypeAliasAsValue}, - method_resolution::{TraitImpls, TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, + mapping::{ToChalk, TypeAliasAsValue, from_chalk}, + method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TraitImpls, TyFingerprint}, to_assoc_type_id, to_chalk_trait_id, traits::ChalkContext, utils::ClosureSubst, - wrap_empty_binders, AliasEq, AliasTy, BoundVar, DebruijnIndex, FnDefId, Interner, ProjectionTy, - ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, - TyExt, TyKind, WhereClause, + wrap_empty_binders, }; pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs index 51c178b90d72b..49dde303099b6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs @@ -1,22 +1,22 @@ //! Various extensions traits for Chalk types. use chalk_ir::{ - cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, TypeOutlives, UintTy, + FloatTy, IntTy, Mutability, Scalar, TyVariableKind, TypeOutlives, UintTy, cast::Cast, }; use hir_def::{ + DefWithBodyId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId, builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint}, generics::TypeOrConstParamData, lang_item::LangItem, type_ref::Rawness, - DefWithBodyId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId, }; use crate::{ - db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, - from_placeholder_idx, generics::generics, to_chalk_trait_id, utils::ClosureSubst, AdtId, - AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, ClosureId, - DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy, + AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, + ClosureId, DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause, + db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, + from_placeholder_idx, generics::generics, to_chalk_trait_id, utils::ClosureSubst, }; pub trait TyExt { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index ec8f9b7c31186..48c23aff78880 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -1,14 +1,14 @@ //! Constant evaluation details use base_db::Crate; -use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; +use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast}; use hir_def::{ + ConstBlockLoc, EnumVariantId, GeneralConstId, HasModule as _, StaticId, expr_store::{Body, HygieneId}, hir::{Expr, ExprId}, path::Path, resolver::{Resolver, ValueNs}, type_ref::LiteralConstRef, - ConstBlockLoc, EnumVariantId, GeneralConstId, HasModule as _, StaticId, }; use hir_expand::Lookup; use salsa::Cycle; @@ -16,17 +16,18 @@ use stdx::never; use triomphe::Arc; use crate::{ + Const, ConstData, ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, + TraitEnvironment, Ty, TyBuilder, db::{HirDatabase, HirDatabaseData}, display::DisplayTarget, generics::Generics, infer::InferenceContext, lower::ParamLoweringMode, mir::monomorphize_mir_body_bad, - to_placeholder_idx, Const, ConstData, ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, - Substitution, TraitEnvironment, Ty, TyBuilder, + to_placeholder_idx, }; -use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError}; +use super::mir::{MirEvalError, MirLowerError, interpret_mir, lower_to_mir, pad16}; /// Extension trait for [`Const`] pub trait ConstExt { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index d679f9dd7ca42..8049897f31f08 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -2,16 +2,16 @@ use base_db::RootQueryDb; use chalk_ir::Substitution; use hir_def::db::DefDatabase; use rustc_apfloat::{ - ieee::{Half as f16, Quad as f128}, Float, + ieee::{Half as f16, Quad as f128}, }; use span::EditionedFileId; use test_fixture::WithFixture; use test_utils::skip_slow_tests; use crate::{ - consteval::try_const_usize, db::HirDatabase, display::DisplayTarget, mir::pad16, - test_db::TestDB, Const, ConstScalar, Interner, MemoryMap, + Const, ConstScalar, Interner, MemoryMap, consteval::try_const_usize, db::HirDatabase, + display::DisplayTarget, mir::pad16, test_db::TestDB, }; use super::{ diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 8f48cfc4327ff..6c619794753b0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -3,11 +3,12 @@ use std::sync; -use base_db::{impl_intern_key, Crate, Upcast}; +use base_db::{Crate, Upcast, impl_intern_key}; use hir_def::{ - db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId, - ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, - LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId, + AdtId, BlockId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, + GeneralConstId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, + TypeAliasId, TypeOrConstParamId, VariantId, db::DefDatabase, hir::ExprId, + layout::TargetDataLayout, }; use hir_expand::name::Name; use la_arena::ArenaMap; @@ -16,7 +17,8 @@ use smallvec::SmallVec; use triomphe::Arc; use crate::{ - chalk_db, + Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner, + PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId, chalk_db, consteval::ConstEvalError, drop::DropGlue, dyn_compatibility::DynCompatibilityViolation, @@ -24,8 +26,6 @@ use crate::{ lower::{Diagnostics, GenericDefaults, GenericPredicates}, method_resolution::{InherentImpls, TraitImpls, TyFingerprint}, mir::{BorrowckResult, MirBody, MirLowerError}, - Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner, - PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId, }; #[query_group::query_group] @@ -262,7 +262,7 @@ pub trait HirDatabase: DefDatabase + Upcast + std::fmt::Debug { #[salsa::invoke(chalk_db::impl_datum_query)] fn impl_datum(&self, krate: Crate, impl_id: chalk_db::ImplId) - -> sync::Arc; + -> sync::Arc; #[salsa::invoke(chalk_db::fn_def_datum_query)] fn fn_def_datum(&self, fn_def_id: FnDefId) -> sync::Arc; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs index 845d333335365..047a348fb09a7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs @@ -5,12 +5,12 @@ mod match_check; mod unsafe_check; pub use crate::diagnostics::{ - decl_check::{incorrect_case, CaseType, IncorrectCase}, + decl_check::{CaseType, IncorrectCase, incorrect_case}, expr::{ - record_literal_missing_fields, record_pattern_missing_fields, BodyValidationDiagnostic, + BodyValidationDiagnostic, record_literal_missing_fields, record_pattern_missing_fields, }, unsafe_check::{ - missing_unsafe, unsafe_operations, unsafe_operations_for_body, InsideUnsafeBlock, - UnsafetyReason, + InsideUnsafeBlock, UnsafetyReason, missing_unsafe, unsafe_operations, + unsafe_operations_for_body, }, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 5106056d40971..ce0ffb1792641 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -16,20 +16,20 @@ mod case_conv; use std::fmt; use hir_def::{ - data::adt::VariantData, db::DefDatabase, hir::Pat, src::HasSource, AdtId, ConstId, EnumId, - EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, ModuleDefId, ModuleId, StaticId, - StructId, TraitId, TypeAliasId, + AdtId, ConstId, EnumId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, + ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, data::adt::VariantData, + db::DefDatabase, hir::Pat, src::HasSource, }; use hir_expand::{ - name::{AsName, Name}, HirFileId, HirFileIdExt, + name::{AsName, Name}, }; use intern::sym; use stdx::{always, never}; use syntax::{ + AstNode, AstPtr, ToSmolStr, ast::{self, HasName}, utils::is_raw_identifier, - AstNode, AstPtr, ToSmolStr, }; use crate::db::HirDatabase; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check/case_conv.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check/case_conv.rs index 348f8a0f4a856..234c7e4b03c3c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check/case_conv.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check/case_conv.rs @@ -97,7 +97,7 @@ fn is_snake_case bool>(ident: &str, wrong_case: F) -> bool { #[cfg(test)] mod tests { use super::*; - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; fn check Option>(fun: F, input: &str, expect: Expect) { // `None` is translated to empty string, meaning that there is nothing to fix. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 6096439565cba..51b404be8130e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -8,36 +8,36 @@ use base_db::Crate; use chalk_solve::rust_ir::AdtKind; use either::Either; use hir_def::{ + AdtId, AssocItemId, DefWithBodyId, HasModule, ItemContainerId, Lookup, lang_item::LangItem, resolver::{HasResolver, ValueNs}, - AdtId, AssocItemId, DefWithBodyId, HasModule, ItemContainerId, Lookup, }; use intern::sym; use itertools::Itertools; use rustc_hash::FxHashSet; use rustc_pattern_analysis::constructor::Constructor; use syntax::{ - ast::{self, UnaryOp}, AstNode, + ast::{self, UnaryOp}, }; use tracing::debug; use triomphe::Arc; use typed_arena::Arena; use crate::{ + Adjust, InferenceResult, Interner, Ty, TyExt, TyKind, db::HirDatabase, diagnostics::match_check::{ self, pat_analysis::{self, DeconstructedPat, MatchCheckCtx, WitnessPat}, }, display::{DisplayTarget, HirDisplay}, - Adjust, InferenceResult, Interner, Ty, TyExt, TyKind, }; pub(crate) use hir_def::{ + LocalFieldId, VariantId, expr_store::Body, hir::{Expr, ExprId, MatchArm, Pat, PatId, Statement}, - LocalFieldId, VariantId, }; pub enum BodyValidationDiagnostic { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs index b0f9fc53e29ee..1c58485eb97fc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs @@ -11,19 +11,19 @@ pub(crate) mod pat_analysis; use chalk_ir::Mutability; use hir_def::{ - data::adt::VariantData, expr_store::Body, hir::PatId, AdtId, EnumVariantId, LocalFieldId, - VariantId, + AdtId, EnumVariantId, LocalFieldId, VariantId, data::adt::VariantData, expr_store::Body, + hir::PatId, }; use hir_expand::name::Name; use span::Edition; use stdx::{always, never}; use crate::{ + InferenceResult, Interner, Substitution, Ty, TyExt, TyKind, db::HirDatabase, display::{HirDisplay, HirDisplayError, HirFormatter}, infer::BindingMode, lang_items::is_box, - InferenceResult, Interner, Substitution, Ty, TyExt, TyKind, }; use self::pat_util::EnumerateAndAdjustIterator; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index b7f8a0c610c54..683a48bfc9e5b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -6,21 +6,21 @@ use std::fmt; use hir_def::{DefWithBodyId, EnumId, EnumVariantId, HasModule, LocalFieldId, ModuleId, VariantId}; use intern::sym; use rustc_pattern_analysis::{ - constructor::{Constructor, ConstructorSet, VariantVisibility}, - usefulness::{compute_match_usefulness, PlaceValidity, UsefulnessReport}, Captures, IndexVec, PatCx, PrivateUninhabitedField, + constructor::{Constructor, ConstructorSet, VariantVisibility}, + usefulness::{PlaceValidity, UsefulnessReport, compute_match_usefulness}, }; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use stdx::never; use crate::{ + AdtId, Interner, Scalar, Ty, TyExt, TyKind, db::HirDatabase, infer::normalize, inhabitedness::{is_enum_variant_uninhabited_from, is_ty_uninhabited_from}, - AdtId, Interner, Scalar, Ty, TyExt, TyKind, }; -use super::{is_box, FieldPat, Pat, PatKind}; +use super::{FieldPat, Pat, PatKind, is_box}; use Constructor::*; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs index 84dd4be67fe8d..562a9aa085a1f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -5,18 +5,18 @@ use std::mem; use either::Either; use hir_def::{ + AdtId, DefWithBodyId, FieldId, FunctionId, VariantId, expr_store::Body, hir::{Expr, ExprId, ExprOrPatId, Pat, PatId, Statement, UnaryOp}, path::Path, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, type_ref::Rawness, - AdtId, DefWithBodyId, FieldId, FunctionId, VariantId, }; use span::Edition; use crate::{ - db::HirDatabase, utils::is_fn_unsafe_to_call, InferenceResult, Interner, TargetFeatures, TyExt, - TyKind, + InferenceResult, Interner, TargetFeatures, TyExt, TyKind, db::HirDatabase, + utils::is_fn_unsafe_to_call, }; #[derive(Debug, Default)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 7bce23f398a60..b2e13ba69201e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -11,6 +11,8 @@ use base_db::Crate; use chalk_ir::{BoundVar, Safety, TyKind}; use either::Either; use hir_def::{ + GenericDefId, HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, + ModuleId, TraitId, data::adt::VariantData, db::DefDatabase, find_path::{self, PrefixKind}, @@ -23,16 +25,14 @@ use hir_def::{ TraitBoundModifier, TypeBound, TypeRef, TypeRefId, TypesMap, TypesSourceMap, UseArgRef, }, visibility::Visibility, - GenericDefId, HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, - ModuleId, TraitId, }; use hir_expand::name::Name; -use intern::{sym, Internable, Interned}; +use intern::{Internable, Interned, sym}; use itertools::Itertools; use la_arena::ArenaMap; use rustc_apfloat::{ - ieee::{Half as f16, Quad as f128}, Float, + ieee::{Half as f16, Quad as f128}, }; use rustc_hash::FxHashSet; use smallvec::SmallVec; @@ -41,6 +41,11 @@ use stdx::never; use triomphe::Arc; use crate::{ + AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, ConcreteConst, Const, + ConstScalar, ConstValue, DomainGoal, FnAbi, GenericArg, ImplTraitId, Interner, Lifetime, + LifetimeData, LifetimeOutlives, MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, + QuantifiedWhereClause, Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, + TyExt, WhereClause, consteval::try_const_usize, db::{HirDatabase, InternedClosure}, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, @@ -51,12 +56,7 @@ use crate::{ mapping::from_chalk, mir::pad16, primitive, to_assoc_type_id, - utils::{self, detect_variant_from_bytes, ClosureSubst}, - AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, ConcreteConst, Const, - ConstScalar, ConstValue, DomainGoal, FnAbi, GenericArg, ImplTraitId, Interner, Lifetime, - LifetimeData, LifetimeOutlives, MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, - QuantifiedWhereClause, Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, - TyExt, WhereClause, + utils::{self, ClosureSubst, detect_variant_from_bytes}, }; pub trait HirWrite: fmt::Write { @@ -529,7 +529,9 @@ where Err(HirDisplayError::FmtError) => Err(fmt::Error), Err(HirDisplayError::DisplaySourceCodeError(_)) => { // This should never happen - panic!("HirDisplay::hir_fmt failed with DisplaySourceCodeError when calling Display::fmt!") + panic!( + "HirDisplay::hir_fmt failed with DisplaySourceCodeError when calling Display::fmt!" + ) } } } @@ -1381,7 +1383,7 @@ impl HirDisplay for Ty { match f.closure_style { ClosureStyle::Hide => return write!(f, "{TYPE_HINT_TRUNCATION}"), ClosureStyle::ClosureWithId => { - return write!(f, "{{closure#{:?}}}", id.0.as_u32()) + return write!(f, "{{closure#{:?}}}", id.0.as_u32()); } ClosureStyle::ClosureWithSubst => { write!(f, "{{closure#{:?}}}", id.0.as_u32())?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index ab17f86b5b2cb..5484a39324f93 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -1,16 +1,16 @@ //! Utilities for computing drop info about types. use chalk_ir::cast::Cast; +use hir_def::AdtId; use hir_def::data::adt::StructFlags; use hir_def::lang_item::LangItem; -use hir_def::AdtId; use stdx::never; use triomphe::Arc; use crate::db::HirDatabaseData; use crate::{ - db::HirDatabase, method_resolution::TyFingerprint, AliasTy, Canonical, CanonicalVarKinds, - InEnvironment, Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, + AliasTy, Canonical, CanonicalVarKinds, InEnvironment, Interner, ProjectionTy, TraitEnvironment, + Ty, TyBuilder, TyKind, db::HirDatabase, method_resolution::TyFingerprint, }; use crate::{ConcreteConst, ConstScalar, ConstValue}; @@ -176,11 +176,7 @@ fn projection_has_drop_glue( let normalized = db.normalize_projection(projection, env.clone()); match normalized.kind(Interner) { TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..) => { - if is_copy(db, ty, env) { - DropGlue::None - } else { - DropGlue::DependOnParams - } + if is_copy(db, ty, env) { DropGlue::None } else { DropGlue::DependOnParams } } _ => db.has_drop_glue(normalized, env), } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index af16a2499ba08..cb186c45ad00e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -3,28 +3,27 @@ use std::ops::ControlFlow; use chalk_ir::{ + DebruijnIndex, cast::Cast, visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, - DebruijnIndex, }; use chalk_solve::rust_ir::InlineBound; use hir_def::{ - data::TraitFlags, lang_item::LangItem, AssocItemId, ConstId, FunctionId, GenericDefId, - HasModule, TraitId, TypeAliasId, + AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId, + data::TraitFlags, lang_item::LangItem, }; use rustc_hash::FxHashSet; use smallvec::SmallVec; use crate::{ - all_super_traits, + AliasEq, AliasTy, Binders, BoundVar, CallableSig, GoalData, ImplTraitId, Interner, OpaqueTyId, + ProjectionTyExt, Solution, Substitution, TraitRef, Ty, TyKind, WhereClause, all_super_traits, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, generics::{generics, trait_self_param_idx}, lower::callable_item_sig, to_assoc_type_id, to_chalk_trait_id, utils::elaborate_clause_supertraits, - AliasEq, AliasTy, Binders, BoundVar, CallableSig, GoalData, ImplTraitId, Interner, OpaqueTyId, - ProjectionTyExt, Solution, Substitution, TraitRef, Ty, TyKind, WhereClause, }; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -558,11 +557,7 @@ fn receiver_for_self_ty(db: &dyn HirDatabase, func: FunctionId, ty: Ty) -> Optio let subst = Substitution::from_iter( Interner, subst.iter(Interner).enumerate().map(|(idx, arg)| { - if idx == trait_self_idx { - ty.clone().cast(Interner) - } else { - arg.clone() - } + if idx == trait_self_idx { ty.clone().cast(Interner) } else { arg.clone() } }), ); let sig = callable_item_sig(db, func.into()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs index 18cf6e5ce36ef..9ed9817dfa077 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs @@ -9,22 +9,22 @@ //! where parent follows the same scheme. use std::ops; -use chalk_ir::{cast::Cast as _, BoundVar, DebruijnIndex}; +use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast as _}; use hir_def::{ + ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId, + LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, db::DefDatabase, generics::{ GenericParamDataRef, GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance, }, type_ref::TypesMap, - ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId, - LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, }; use itertools::chain; use stdx::TupleExt; use triomphe::Arc; -use crate::{db::HirDatabase, lt_to_placeholder_idx, to_placeholder_idx, Interner, Substitution}; +use crate::{Interner, Substitution, db::HirDatabase, lt_to_placeholder_idx, to_placeholder_idx}; pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics { let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def))); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index ecadfccf00299..7388d2ab43cc7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -26,14 +26,16 @@ pub(crate) mod unify; use std::{cell::OnceCell, convert::identity, iter, ops::Index}; use chalk_ir::{ + DebruijnIndex, Mutability, Safety, Scalar, TyKind, TypeFlags, Variance, cast::Cast, fold::TypeFoldable, interner::HasInterner, visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, - DebruijnIndex, Mutability, Safety, Scalar, TyKind, TypeFlags, Variance, }; use either::Either; use hir_def::{ + AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ImplId, ItemContainerId, Lookup, + TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, data::{ConstData, StaticData}, expr_store::{Body, HygieneId}, @@ -43,8 +45,6 @@ use hir_def::{ path::{ModPath, Path}, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, type_ref::{LifetimeRef, TypeRefId, TypesMap}, - AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ImplId, ItemContainerId, Lookup, - TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, }; use hir_expand::name::Name; use indexmap::IndexSet; @@ -55,6 +55,9 @@ use stdx::{always, never}; use triomphe::Arc; use crate::{ + AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId, + ImplTraitIdx, InEnvironment, Interner, Lifetime, OpaqueTyId, ParamLoweringMode, + PathLoweringDiagnostic, ProjectionTy, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, db::HirDatabase, fold_tys, generics::Generics, @@ -64,14 +67,11 @@ use crate::{ expr::ExprIsRead, unify::InferenceTable, }, - lower::{diagnostics::TyLoweringDiagnostic, ImplTraitLoweringMode}, + lower::{ImplTraitLoweringMode, diagnostics::TyLoweringDiagnostic}, mir::MirSpan, to_assoc_type_id, traits::FnTrait, utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder}, - AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId, - ImplTraitIdx, InEnvironment, Interner, Lifetime, OpaqueTyId, ParamLoweringMode, - PathLoweringDiagnostic, ProjectionTy, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, }; // This lint has a false positive here. See the link below for details. @@ -1190,11 +1190,7 @@ impl<'a> InferenceContext<'a> { if let Some(impl_id) = impl_id { taits.extend(collector.assocs.into_iter().filter_map(|(id, (impl_, ty))| { - if impl_ == impl_id { - Some((id, ty)) - } else { - None - } + if impl_ == impl_id { Some((id, ty)) } else { None } })); } @@ -1914,11 +1910,7 @@ impl Expectation { match self { Expectation::HasType(ety) => { let ety = table.resolve_ty_shallow(ety); - if ety.is_ty_var() { - Expectation::None - } else { - Expectation::HasType(ety) - } + if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) } } Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()), _ => Expectation::None, @@ -2044,7 +2036,7 @@ impl chalk_ir::zip::Zipper for UnknownMismatch<'_> { | (_, TyKind::Error) | (TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _), _) | (_, TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)) => { - return Err(chalk_ir::NoSolution) + return Err(chalk_ir::NoSolution); } _ => (), } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index 8b43d0188a9de..d3de86f038721 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs @@ -1,13 +1,13 @@ //! Type cast logic. Basically coercion + additional casts. use chalk_ir::{Mutability, Scalar, TyVariableKind, UintTy}; -use hir_def::{hir::ExprId, AdtId}; +use hir_def::{AdtId, hir::ExprId}; use stdx::never; use crate::{ - infer::{coerce::CoerceNever, unify::InferenceTable}, Adjustment, Binders, DynTy, InferenceDiagnostic, Interner, PlaceholderIndex, QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause, + infer::{coerce::CoerceNever, unify::InferenceTable}, }; #[derive(Debug)] @@ -431,8 +431,8 @@ fn contains_dyn_trait(ty: &Ty) -> bool { use std::ops::ControlFlow; use chalk_ir::{ - visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, DebruijnIndex, + visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, }; struct DynTraitVisitor; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index 9ae6e0a174443..69de555214d2b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -3,12 +3,13 @@ use std::{cmp, convert::Infallible, mem}; use chalk_ir::{ + BoundVar, DebruijnIndex, FnSubst, Mutability, TyKind, cast::Cast, fold::{FallibleTypeFolder, TypeFoldable}, - BoundVar, DebruijnIndex, FnSubst, Mutability, TyKind, }; use either::Either; use hir_def::{ + DefWithBodyId, FieldId, HasModule, TupleFieldId, TupleId, VariantId, data::adt::VariantData, hir::{ Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, ExprOrPatId, Pat, PatId, @@ -17,16 +18,18 @@ use hir_def::{ lang_item::LangItem, path::Path, resolver::ValueNs, - DefWithBodyId, FieldId, HasModule, TupleFieldId, TupleId, VariantId, }; use hir_expand::name::Name; use intern::sym; use rustc_hash::FxHashMap; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use stdx::{format_to, never}; use syntax::utils::is_raw_identifier; use crate::{ + Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, + DynTyExt, FnAbi, FnPointer, FnSig, Interner, OpaqueTy, ProjectionTyExt, Substitution, Ty, + TyExt, WhereClause, db::{HirDatabase, InternedClosure}, error_lifetime, from_chalk_trait_id, from_placeholder_idx, generics::Generics, @@ -36,9 +39,6 @@ use crate::{ to_chalk_trait_id, traits::FnTrait, utils::{self, elaborate_clause_supertraits}, - Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, - DynTyExt, FnAbi, FnPointer, FnSig, Interner, OpaqueTy, ProjectionTyExt, Substitution, Ty, - TyExt, WhereClause, }; use super::{Expectation, InferenceContext}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index acd86b1f3ed8a..b0fb01a84d18d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -7,7 +7,7 @@ use std::iter; -use chalk_ir::{cast::Cast, BoundVar, Goal, Mutability, TyKind, TyVariableKind}; +use chalk_ir::{BoundVar, Goal, Mutability, TyKind, TyVariableKind, cast::Cast}; use hir_def::{ hir::ExprId, lang_item::{LangItem, LangItemTarget}, @@ -16,6 +16,8 @@ use stdx::always; use triomphe::Arc; use crate::{ + Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Lifetime, + Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, autoderef::{Autoderef, AutoderefKind}, db::HirDatabase, infer::{ @@ -23,8 +25,6 @@ use crate::{ TypeError, TypeMismatch, }, utils::ClosureSubst, - Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Lifetime, - Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, }; use super::unify::InferenceTable; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs index e4f5b5ed378dc..563c5699cff63 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs @@ -6,13 +6,13 @@ use std::cell::RefCell; use std::ops::{Deref, DerefMut}; use either::Either; -use hir_def::{hir::ExprOrPatId, path::Path, resolver::Resolver, type_ref::TypesMap, TypeOwnerId}; +use hir_def::{TypeOwnerId, hir::ExprOrPatId, path::Path, resolver::Resolver, type_ref::TypesMap}; use la_arena::{Idx, RawIdx}; use crate::{ + InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringContext, TyLoweringDiagnostic, db::HirDatabase, lower::path::{PathDiagnosticCallback, PathLoweringContext}, - InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringContext, TyLoweringDiagnostic, }; // Unfortunately, this struct needs to use interior mutability (but we encapsulate it) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index d0cbce70a2f14..c5a6c21d29b29 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -5,9 +5,10 @@ use std::{ mem, }; -use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex, Mutability, TyVariableKind}; +use chalk_ir::{DebruijnIndex, Mutability, TyVariableKind, cast::Cast, fold::Shift}; use either::Either; use hir_def::{ + BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId, hir::{ ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, ClosureKind, Expr, ExprId, ExprOrPatId, LabelId, Literal, Pat, PatId, Statement, UnaryOp, @@ -15,7 +16,6 @@ use hir_def::{ lang_item::{LangItem, LangItemTarget}, path::{GenericArg, GenericArgs, Path}, resolver::ValueNs, - BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId, }; use hir_expand::name::Name; use intern::sym; @@ -23,34 +23,34 @@ use stdx::always; use syntax::ast::RangeOp; use crate::{ - autoderef::{builtin_deref, deref_by_trait, Autoderef}, + Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, CallableSig, DeclContext, + DeclOrigin, FnAbi, FnPointer, FnSig, FnSubst, Interner, Rawness, Scalar, Substitution, + TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, + autoderef::{Autoderef, builtin_deref, deref_by_trait}, consteval, db::{InternedClosure, InternedCoroutine}, error_lifetime, - generics::{generics, Generics}, + generics::{Generics, generics}, infer::{ + BreakableKind, coerce::{CoerceMany, CoerceNever, CoercionCause}, find_continuable, pat::contains_explicit_ref_binding, - BreakableKind, }, lang_items::lang_items_for_bin_op, lower::{ - const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, ParamLoweringMode, + ParamLoweringMode, const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, }, - mapping::{from_chalk, ToChalk}, + mapping::{ToChalk, from_chalk}, method_resolution::{self, VisibleFromModule}, primitive::{self, UintTy}, static_lifetime, to_chalk_trait_id, traits::FnTrait, - Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, CallableSig, DeclContext, - DeclOrigin, FnAbi, FnPointer, FnSig, FnSubst, Interner, Rawness, Scalar, Substitution, - TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, }; use super::{ - cast::CastCheck, coerce::auto_deref_adjust_steps, find_breakable, BreakableContext, Diverges, - Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch, + BreakableContext, Diverges, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch, + cast::CastCheck, coerce::auto_deref_adjust_steps, find_breakable, }; #[derive(Clone, Copy, PartialEq, Eq)] @@ -1556,11 +1556,7 @@ impl InferenceContext<'_> { target_is_read, ) }; - if type_ref.is_some() { - decl_ty - } else { - ty - } + if type_ref.is_some() { decl_ty } else { ty } } else { decl_ty }; @@ -2402,11 +2398,7 @@ impl InferenceContext<'_> { BinaryOp::Assignment { .. } => unreachable!("handled above"), }; - if is_assign { - self.result.standard_types.unit.clone() - } else { - output_ty - } + if is_assign { self.result.standard_types.unit.clone() } else { output_ty } } fn is_builtin_binop(&mut self, lhs: &Ty, rhs: &Ty, op: BinaryOp) -> bool { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs index 96d84cad9394c..aeaecc2831c25 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs @@ -1,7 +1,7 @@ //! Finds if an expression is an immutable context or a mutable context, which is used in selecting //! between `Deref` and `DerefMut` or `Index` and `IndexMut` or similar. -use chalk_ir::{cast::Cast, Mutability}; +use chalk_ir::{Mutability, cast::Cast}; use hir_def::{ hir::{ Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Statement, @@ -13,9 +13,9 @@ use hir_expand::name::Name; use intern::sym; use crate::{ - infer::{expr::ExprIsRead, Expectation, InferenceContext}, - lower::lower_to_chalk_mutability, Adjust, Adjustment, AutoBorrow, Interner, OverloadedDeref, TyBuilder, TyKind, + infer::{Expectation, InferenceContext, expr::ExprIsRead}, + lower::lower_to_chalk_mutability, }; impl InferenceContext<'_> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index db93116f1071a..6d2811635eea6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs @@ -3,24 +3,25 @@ use std::iter::repeat_with; use hir_def::{ + HasModule, expr_store::Body, hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId}, path::Path, - HasModule, }; use hir_expand::name::Name; use stdx::TupleExt; use crate::{ + DeclContext, DeclOrigin, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty, + TyBuilder, TyExt, TyKind, consteval::{self, try_const_usize, usize_const}, infer::{ - coerce::CoerceNever, expr::ExprIsRead, BindingMode, Expectation, InferenceContext, - TypeMismatch, + BindingMode, Expectation, InferenceContext, TypeMismatch, coerce::CoerceNever, + expr::ExprIsRead, }, lower::lower_to_chalk_mutability, primitive::UintTy, - static_lifetime, DeclContext, DeclOrigin, InferenceDiagnostic, Interner, Mutability, Scalar, - Substitution, Ty, TyBuilder, TyExt, TyKind, + static_lifetime, }; impl InferenceContext<'_> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 8ff0cf308224c..04d1ea97f938a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -2,21 +2,22 @@ use chalk_ir::cast::Cast; use hir_def::{ + AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup, path::{Path, PathSegment}, resolver::{ResolveValueResult, TypeNs, ValueNs}, - AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup, }; use hir_expand::name::Name; use stdx::never; use crate::{ + InferenceDiagnostic, Interner, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, + TyKind, ValueTyDefId, builder::ParamKind, consteval, error_lifetime, generics::generics, infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext, method_resolution::{self, VisibleFromModule}, - to_chalk_trait_id, InferenceDiagnostic, Interner, Substitution, TraitRef, TraitRefExt, Ty, - TyBuilder, TyExt, TyKind, ValueTyDefId, + to_chalk_trait_id, }; use super::{ExprOrPatId, InferenceContext, InferenceTyDiagnosticSource}; @@ -63,7 +64,7 @@ impl InferenceContext<'_> { never!("uninferred pattern?"); None } - } + }; } ValueNs::ImplSelf(impl_id) => { let generics = crate::generics::generics(self.db.upcast(), impl_id.into()); @@ -81,7 +82,7 @@ impl InferenceContext<'_> { }; } ValueNs::GenericParam(it) => { - return Some(ValuePathResolution::NonGeneric(self.db.const_param_ty(it))) + return Some(ValuePathResolution::NonGeneric(self.db.const_param_ty(it))); } }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index 6d80bfc38e5b7..903097ee2f8f7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -3,13 +3,13 @@ use std::{fmt, mem}; use chalk_ir::{ - cast::Cast, fold::TypeFoldable, interner::HasInterner, zip::Zip, CanonicalVarKind, FloatTy, - IntTy, TyVariableKind, UniverseIndex, + CanonicalVarKind, FloatTy, IntTy, TyVariableKind, UniverseIndex, cast::Cast, + fold::TypeFoldable, interner::HasInterner, zip::Zip, }; use chalk_solve::infer::ParameterEnaVariableExt; use either::Either; use ena::unify::UnifyKey; -use hir_def::{lang_item::LangItem, AdtId}; +use hir_def::{AdtId, lang_item::LangItem}; use hir_expand::name::Name; use intern::sym; use rustc_hash::FxHashMap; @@ -18,12 +18,12 @@ use triomphe::Arc; use super::{InferOk, InferResult, InferenceContext, TypeError}; use crate::{ + AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue, DebruijnIndex, DomainGoal, + GenericArg, GenericArgData, Goal, GoalData, Guidance, InEnvironment, InferenceVar, Interner, + Lifetime, OpaqueTyId, ParamKind, ProjectionTy, ProjectionTyExt, Scalar, Solution, Substitution, + TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, VariableKind, WhereClause, consteval::unknown_const, db::HirDatabase, fold_generic_args, fold_tys_and_consts, - to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue, - DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData, Guidance, InEnvironment, - InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy, ProjectionTyExt, Scalar, - Solution, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, VariableKind, - WhereClause, + to_chalk_trait_id, traits::FnTrait, }; impl InferenceContext<'_> { @@ -890,11 +890,7 @@ impl<'a> InferenceTable<'a> { TyKind::Error => self.new_type_var(), TyKind::InferenceVar(..) => { let ty_resolved = self.resolve_ty_shallow(&ty); - if ty_resolved.is_unknown() { - self.new_type_var() - } else { - ty - } + if ty_resolved.is_unknown() { self.new_type_var() } else { ty } } _ => ty, } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs index 800ba0d454490..c153bf3e34f1b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs @@ -2,14 +2,14 @@ use std::ops::ControlFlow::{self, Break, Continue}; use chalk_ir::{ - visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, DebruijnIndex, + visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, }; -use hir_def::{visibility::Visibility, AdtId, EnumVariantId, ModuleId, VariantId}; +use hir_def::{AdtId, EnumVariantId, ModuleId, VariantId, visibility::Visibility}; use rustc_hash::FxHashSet; use crate::{ - consteval::try_const_usize, db::HirDatabase, Binders, Interner, Substitution, Ty, TyKind, + Binders, Interner, Substitution, Ty, TyKind, consteval::try_const_usize, db::HirDatabase, }; // FIXME: Turn this into a query, it can be quite slow diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs index 832a00e1e5e7b..bd4a53603d1ae 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs @@ -2,15 +2,15 @@ //! representation of the various objects Chalk deals with (types, goals etc.). use crate::{ - chalk_db, tls, AliasTy, CanonicalVarKind, CanonicalVarKinds, ClosureId, Const, ConstData, - ConstScalar, Constraint, Constraints, FnAbi, FnDefId, GenericArg, GenericArgData, Goal, - GoalData, Goals, InEnvironment, Lifetime, LifetimeData, OpaqueTy, OpaqueTyId, ProgramClause, - ProgramClauseData, ProgramClauses, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, - Substitution, Ty, TyData, TyKind, VariableKind, VariableKinds, + AliasTy, CanonicalVarKind, CanonicalVarKinds, ClosureId, Const, ConstData, ConstScalar, + Constraint, Constraints, FnAbi, FnDefId, GenericArg, GenericArgData, Goal, GoalData, Goals, + InEnvironment, Lifetime, LifetimeData, OpaqueTy, OpaqueTyId, ProgramClause, ProgramClauseData, + ProgramClauses, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, Substitution, Ty, + TyData, TyKind, VariableKind, VariableKinds, chalk_db, tls, }; use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variance}; use hir_def::TypeAliasId; -use intern::{impl_internable, Interned}; +use intern::{Interned, impl_internable}; use smallvec::SmallVec; use std::fmt; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs index ff9c52fbb6c17..d638d50f8e344 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs @@ -1,6 +1,6 @@ //! Functions to detect special lang items -use hir_def::{data::adt::StructFlags, lang_item::LangItem, AdtId}; +use hir_def::{AdtId, data::adt::StructFlags, lang_item::LangItem}; use hir_expand::name::Name; use intern::sym; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 2f7ad2b99d25b..0cb868d273f04 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -4,11 +4,11 @@ use std::fmt; use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; use hir_def::{ + LocalFieldId, StructId, layout::{ Float, Integer, LayoutCalculator, LayoutCalculatorError, LayoutData, Primitive, ReprOptions, Scalar, StructKind, TargetDataLayout, WrappingRange, }, - LocalFieldId, StructId, }; use la_arena::{Idx, RawIdx}; use rustc_abi::AddressSpace; @@ -18,11 +18,11 @@ use salsa::Cycle; use triomphe::Arc; use crate::{ + Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, consteval::try_const_usize, db::{HirDatabase, HirDatabaseData, InternedClosure}, infer::normalize, utils::ClosureSubst, - Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, }; pub(crate) use self::adt::layout_of_adt_recover; @@ -320,7 +320,7 @@ pub fn layout_of_ty_query( return Err(LayoutError::NotImplemented); } crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => { - return Err(LayoutError::NotImplemented) + return Err(LayoutError::NotImplemented); } } } @@ -342,7 +342,7 @@ pub fn layout_of_ty_query( cx.calc.univariant(&fields, &ReprOptions::default(), StructKind::AlwaysSized)? } TyKind::Coroutine(_, _) | TyKind::CoroutineWitness(_, _) => { - return Err(LayoutError::NotImplemented) + return Err(LayoutError::NotImplemented); } TyKind::Error => return Err(LayoutError::HasErrorType), TyKind::AssociatedType(id, subst) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index 9f453162e30c5..efff875dec68b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -3,9 +3,9 @@ use std::{cmp, ops::Bound}; use hir_def::{ + AdtId, VariantId, data::adt::VariantData, layout::{Integer, ReprOptions, TargetDataLayout}, - AdtId, VariantId, }; use intern::sym; use rustc_index::IndexVec; @@ -14,10 +14,10 @@ use smallvec::SmallVec; use triomphe::Arc; use crate::{ + Substitution, TraitEnvironment, db::HirDatabase, lang_items::is_unsafe_cell, - layout::{field_ty, Layout, LayoutError}, - Substitution, TraitEnvironment, + layout::{Layout, LayoutError, field_ty}, }; use super::{HirDatabaseData, LayoutCx}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 8b74b7328bd83..f671b30380724 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -1,17 +1,17 @@ use chalk_ir::{AdtId, TyKind}; use either::Either; use hir_def::db::DefDatabase; -use project_model::{toolchain_info::QueryConfig, Sysroot}; +use project_model::{Sysroot, toolchain_info::QueryConfig}; use rustc_hash::FxHashMap; use syntax::ToSmolStr; use test_fixture::WithFixture; use triomphe::Arc; use crate::{ + Interner, Substitution, db::HirDatabase, layout::{Layout, LayoutError}, test_db::TestDB, - Interner, Substitution, }; mod closure; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 836319431dfb4..8292e80c1e197 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -57,19 +57,19 @@ mod variance; use std::hash::Hash; use chalk_ir::{ + NoSolution, fold::{Shift, TypeFoldable}, interner::HasInterner, - NoSolution, }; use either::Either; -use hir_def::{hir::ExprId, type_ref::Rawness, CallableDefId, GeneralConstId, TypeOrConstParamId}; +use hir_def::{CallableDefId, GeneralConstId, TypeOrConstParamId, hir::ExprId, type_ref::Rawness}; use hir_expand::name::Name; -use indexmap::{map::Entry, IndexMap}; -use intern::{sym, Symbol}; +use indexmap::{IndexMap, map::Entry}; +use intern::{Symbol, sym}; use la_arena::{Arena, Idx}; use mir::{MirEvalError, VTableMap}; use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; -use syntax::ast::{make, ConstArg}; +use syntax::ast::{ConstArg, make}; use traits::FnTrait; use triomphe::Arc; @@ -86,16 +86,16 @@ pub use builder::{ParamKind, TyBuilder}; pub use chalk_ext::*; pub use drop::DropGlue; pub use infer::{ + Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic, InferenceResult, + InferenceTyDiagnosticSource, OverloadedDeref, PointerCast, cast::CastError, closure::{CaptureKind, CapturedItem}, - could_coerce, could_unify, could_unify_deeply, Adjust, Adjustment, AutoBorrow, BindingMode, - InferenceDiagnostic, InferenceResult, InferenceTyDiagnosticSource, OverloadedDeref, - PointerCast, + could_coerce, could_unify, could_unify_deeply, }; pub use interner::Interner; pub use lower::{ - associated_type_shorthand_candidates, diagnostics::*, ImplTraitLoweringMode, ParamLoweringMode, - TyDefId, TyLoweringContext, ValueTyDefId, + ImplTraitLoweringMode, ParamLoweringMode, TyDefId, TyLoweringContext, ValueTyDefId, + associated_type_shorthand_candidates, diagnostics::*, }; pub use mapping::{ from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx, @@ -105,13 +105,13 @@ pub use mapping::{ pub use method_resolution::check_orphan_rules; pub use target_feature::TargetFeatures; pub use traits::TraitEnvironment; -pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call, Unsafety}; +pub use utils::{Unsafety, all_super_traits, direct_super_traits, is_fn_unsafe_to_call}; pub use variance::Variance; pub use chalk_ir::{ + AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind, cast::Cast, visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, - AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind, }; pub type ForeignDefId = chalk_ir::ForeignDefId; @@ -645,10 +645,8 @@ pub(crate) fn fold_free_vars + TypeFoldable< F1: FnMut(BoundVar, DebruijnIndex) -> Ty, F2: FnMut(Ty, BoundVar, DebruijnIndex) -> Const, >(F1, F2); - impl< - F1: FnMut(BoundVar, DebruijnIndex) -> Ty, - F2: FnMut(Ty, BoundVar, DebruijnIndex) -> Const, - > TypeFolder for FreeVarFolder + impl Ty, F2: FnMut(Ty, BoundVar, DebruijnIndex) -> Const> + TypeFolder for FreeVarFolder { fn as_dyn(&mut self) -> &mut dyn TypeFolder { self @@ -778,8 +776,8 @@ where T: HasInterner + TypeFoldable + Clone, { use chalk_ir::{ - fold::{FallibleTypeFolder, TypeSuperFoldable}, Fallible, + fold::{FallibleTypeFolder, TypeSuperFoldable}, }; struct ErrorReplacer { vars: usize, @@ -840,11 +838,7 @@ where _var: InferenceVar, _outer_binder: DebruijnIndex, ) -> Fallible { - if cfg!(debug_assertions) { - Err(NoSolution) - } else { - Ok(unknown_const(ty)) - } + if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(unknown_const(ty)) } } fn try_fold_free_var_const( @@ -853,11 +847,7 @@ where _bound_var: BoundVar, _outer_binder: DebruijnIndex, ) -> Fallible { - if cfg!(debug_assertions) { - Err(NoSolution) - } else { - Ok(unknown_const(ty)) - } + if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(unknown_const(ty)) } } fn try_fold_inference_lifetime( @@ -865,11 +855,7 @@ where _var: InferenceVar, _outer_binder: DebruijnIndex, ) -> Fallible { - if cfg!(debug_assertions) { - Err(NoSolution) - } else { - Ok(error_lifetime()) - } + if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(error_lifetime()) } } fn try_fold_free_var_lifetime( @@ -877,11 +863,7 @@ where _bound_var: BoundVar, _outer_binder: DebruijnIndex, ) -> Fallible { - if cfg!(debug_assertions) { - Err(NoSolution) - } else { - Ok(error_lifetime()) - } + if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(error_lifetime()) } } } let mut error_replacer = ErrorReplacer { vars: 0 }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 12f3a1138fcc0..e5f3c4cfc8fc9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -16,16 +16,19 @@ use std::{ use base_db::Crate; use chalk_ir::{ + Mutability, Safety, TypeOutlives, cast::Cast, fold::{Shift, TypeFoldable}, interner::HasInterner, - Mutability, Safety, TypeOutlives, }; use either::Either; use hir_def::{ + AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, + FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, LocalFieldId, + Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, UnionId, VariantId, builtin_type::BuiltinType, - data::{adt::StructKind, TraitFlags}, + data::{TraitFlags, adt::StructKind}, expander::Expander, generics::{ GenericParamDataRef, TypeOrConstParamData, TypeParamProvenance, WherePredicate, @@ -39,11 +42,8 @@ use hir_def::{ ConstRef, LifetimeRef, PathId, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId, TypesMap, TypesSourceMap, }, - AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, - FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, LocalFieldId, - Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, UnionId, VariantId, }; -use hir_expand::{name::Name, ExpandResult}; +use hir_expand::{ExpandResult, name::Name}; use la_arena::{Arena, ArenaMap}; use rustc_hash::FxHashSet; use rustc_pattern_analysis::Captures; @@ -53,27 +53,26 @@ use syntax::ast; use triomphe::{Arc, ThinArc}; use crate::{ - all_super_traits, + AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy, FnAbi, + FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, + LifetimeData, LifetimeOutlives, ParamKind, PolyFnSig, ProgramClause, QuantifiedWhereClause, + QuantifiedWhereClauses, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, + TyKind, WhereClause, all_super_traits, consteval::{ intern_const_ref, intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic, }, db::{HirDatabase, HirDatabaseData}, error_lifetime, - generics::{generics, trait_self_param_idx, Generics}, + generics::{Generics, generics, trait_self_param_idx}, lower::{ diagnostics::*, path::{PathDiagnosticCallback, PathLoweringContext}, }, make_binders, - mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk}, + mapping::{ToChalk, from_chalk_trait_id, lt_to_placeholder_idx}, static_lifetime, to_chalk_trait_id, to_placeholder_idx, - utils::{all_super_trait_refs, InTypeConstIdMetadata}, - AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy, FnAbi, - FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, - LifetimeData, LifetimeOutlives, ParamKind, PolyFnSig, ProgramClause, QuantifiedWhereClause, - QuantifiedWhereClauses, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, - TyKind, WhereClause, + utils::{InTypeConstIdMetadata, all_super_trait_refs}, }; #[derive(Debug, Default)] @@ -1301,11 +1300,7 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>( .enumerate() .filter_map( move |(idx, generic_arg)| { - if Some(idx) == trait_self_idx { - None - } else { - Some(generic_arg) - } + if Some(idx) == trait_self_idx { None } else { Some(generic_arg) } }, ) .filter_map(|generic_arg| generic_arg.ty(Interner)) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index a9e9e83e871ff..960cb533713ee 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -2,32 +2,32 @@ use std::iter; -use chalk_ir::{cast::Cast, fold::Shift, BoundVar}; +use chalk_ir::{BoundVar, cast::Cast, fold::Shift}; use either::Either; use hir_def::{ + GenericDefId, GenericParamId, ItemContainerId, Lookup, TraitId, data::TraitFlags, expr_store::HygieneId, generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, path::{GenericArg, GenericArgs, Path, PathSegment, PathSegments}, resolver::{ResolveValueResult, TypeNs, ValueNs}, type_ref::{TypeBound, TypeRef, TypesMap}, - GenericDefId, GenericParamId, ItemContainerId, Lookup, TraitId, }; use smallvec::SmallVec; use stdx::never; use crate::{ + AliasEq, AliasTy, GenericArgsProhibitedReason, ImplTraitLoweringMode, Interner, + ParamLoweringMode, PathLoweringDiagnostic, ProjectionTy, QuantifiedWhereClause, Substitution, + TraitRef, Ty, TyBuilder, TyDefId, TyKind, TyLoweringContext, ValueTyDefId, WhereClause, consteval::unknown_const_as_generic, error_lifetime, generics::generics, lower::{ - generic_arg_to_chalk, named_associated_type_shorthand_candidates, ImplTraitLoweringState, + ImplTraitLoweringState, generic_arg_to_chalk, named_associated_type_shorthand_candidates, }, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, utils::associated_type_by_name_including_super_traits, - AliasEq, AliasTy, GenericArgsProhibitedReason, ImplTraitLoweringMode, Interner, - ParamLoweringMode, PathLoweringDiagnostic, ProjectionTy, QuantifiedWhereClause, Substitution, - TraitRef, Ty, TyBuilder, TyDefId, TyKind, TyLoweringContext, ValueTyDefId, WhereClause, }; type CallbackData<'a> = Either< diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs index cfa2a49b79c53..f7511e5f63a3f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs @@ -7,13 +7,13 @@ use chalk_solve::rust_ir; use hir_def::{LifetimeParamId, TraitId, TypeAliasId, TypeOrConstParamId}; use salsa::{ - plumbing::{AsId, FromId}, Id, + plumbing::{AsId, FromId}, }; use crate::{ - chalk_db, db::HirDatabase, AssocTypeId, CallableDefId, ChalkTraitId, FnDefId, ForeignDefId, - Interner, OpaqueTyId, PlaceholderIndex, + AssocTypeId, CallableDefId, ChalkTraitId, FnDefId, ForeignDefId, Interner, OpaqueTyId, + PlaceholderIndex, chalk_db, db::HirDatabase, }; pub(crate) trait ToChalk { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index bb3aaef20b76c..d887013b6ff30 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -6,33 +6,33 @@ use std::ops::ControlFlow; use arrayvec::ArrayVec; use base_db::Crate; -use chalk_ir::{cast::Cast, UniverseIndex, WithKind}; +use chalk_ir::{UniverseIndex, WithKind, cast::Cast}; use hir_def::{ - data::{adt::StructFlags, TraitFlags}, - nameres::{assoc::ImplItems, DefMap}, AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, ModuleId, TraitId, + data::{TraitFlags, adt::StructFlags}, + nameres::{DefMap, assoc::ImplItems}, }; use hir_expand::name::Name; use intern::sym; use rustc_hash::{FxHashMap, FxHashSet}; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use stdx::never; use triomphe::Arc; use crate::{ + AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData, + Goal, Guidance, InEnvironment, Interner, Mutability, Scalar, Solution, Substitution, + TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, TyVariableKind, + VariableKind, WhereClause, autoderef::{self, AutoderefKind}, db::HirDatabase, error_lifetime, from_chalk_trait_id, from_foreign_def_id, - infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast}, + infer::{Adjust, Adjustment, OverloadedDeref, PointerCast, unify::InferenceTable}, lang_items::is_box, primitive::{FloatTy, IntTy, UintTy}, to_chalk_trait_id, utils::all_super_traits, - AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData, - Goal, Guidance, InEnvironment, Interner, Mutability, Scalar, Solution, Substitution, - TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, TyVariableKind, - VariableKind, WhereClause, }; /// This is used as a key for indexing impls. @@ -166,11 +166,7 @@ impl TraitImpls { Self::collect_def_map(db, &mut impls, &db.block_def_map(block)); - if impls.is_empty() { - None - } else { - Some(Arc::new(Self::finish(impls))) - } + if impls.is_empty() { None } else { Some(Arc::new(Self::finish(impls))) } } pub(crate) fn trait_impls_in_deps_query( @@ -698,11 +694,7 @@ pub(crate) fn lookup_impl_method_query( let name = &db.function_data(func).name; let Some((impl_fn, impl_subst)) = lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name).and_then(|assoc| { - if let (AssocItemId::FunctionId(id), subst) = assoc { - Some((id, subst)) - } else { - None - } + if let (AssocItemId::FunctionId(id), subst) = assoc { Some((id, subst)) } else { None } }) else { return (func, fn_subst); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index 7faa23f818b8f..247f0ec429fc8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -3,22 +3,22 @@ use std::{collections::hash_map::Entry, fmt::Display, iter}; use crate::{ + CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap, + Substitution, TraitEnvironment, Ty, TyExt, TyKind, consteval::usize_const, db::HirDatabase, display::{DisplayTarget, HirDisplay}, - infer::{normalize, PointerCast}, + infer::{PointerCast, normalize}, lang_items::is_box, mapping::ToChalk, - CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap, - Substitution, TraitEnvironment, Ty, TyExt, TyKind, }; use base_db::Crate; use chalk_ir::Mutability; use either::Either; use hir_def::{ + DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId, expr_store::Body, hir::{BindingAnnotation, BindingId, Expr, ExprId, Ordering, PatId}, - DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId, }; use la_arena::{Arena, ArenaMap, Idx, RawIdx}; @@ -28,17 +28,17 @@ mod lower; mod monomorphization; mod pretty; -pub use borrowck::{borrowck_query, BorrowckResult, MutabilityReason}; +pub use borrowck::{BorrowckResult, MutabilityReason, borrowck_query}; pub use eval::{ - interpret_mir, pad16, render_const_using_debug_impl, Evaluator, MirEvalError, VTableMap, + Evaluator, MirEvalError, VTableMap, interpret_mir, pad16, render_const_using_debug_impl, }; -pub use lower::{lower_to_mir, mir_body_for_closure_query, mir_body_query, MirLowerError}; +pub use lower::{MirLowerError, lower_to_mir, mir_body_for_closure_query, mir_body_query}; pub use monomorphization::{ monomorphize_mir_body_bad, monomorphized_mir_body_for_closure_query, monomorphized_mir_body_query, }; use rustc_hash::FxHashMap; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use stdx::{impl_from, never}; pub(crate) use lower::mir_body_recover; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index fd1e724ee88ec..d9938fc60cd76 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -12,11 +12,11 @@ use stdx::never; use triomphe::Arc; use crate::{ + ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags, db::{HirDatabase, InternedClosure}, display::DisplayTarget, mir::Operand, utils::ClosureSubst, - ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags, }; use super::{ @@ -376,11 +376,7 @@ fn place_case(db: &dyn HirDatabase, body: &MirBody, lvalue: &Place) -> Projectio body.owner.module(db.upcast()).krate(), ); } - if is_part_of { - ProjectionCase::DirectPart - } else { - ProjectionCase::Direct - } + if is_part_of { ProjectionCase::DirectPart } else { ProjectionCase::Direct } } /// Returns a map from basic blocks to the set of locals that might be ever initialized before diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index be0a79f1dd394..ee412dd00b3a9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -3,25 +3,25 @@ use std::{borrow::Cow, cell::RefCell, fmt::Write, iter, mem, ops::Range}; use base_db::Crate; -use chalk_ir::{cast::Cast, Mutability}; +use chalk_ir::{Mutability, cast::Cast}; use either::Either; use hir_def::{ + AdtId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, StaticId, + VariantId, builtin_type::BuiltinType, data::adt::{StructFlags, VariantData}, expr_store::HygieneId, lang_item::LangItem, layout::{TagEncoding, Variants}, resolver::{HasResolver, TypeNs, ValueNs}, - AdtId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, StaticId, - VariantId, }; -use hir_expand::{mod_path::path, name::Name, HirFileIdExt, InFile}; +use hir_expand::{HirFileIdExt, InFile, mod_path::path, name::Name}; use intern::sym; use la_arena::ArenaMap; use rustc_abi::TargetDataLayout; use rustc_apfloat::{ - ieee::{Half as f16, Quad as f128}, Float, + ieee::{Half as f16, Quad as f128}, }; use rustc_hash::{FxHashMap, FxHashSet}; use span::FileId; @@ -30,7 +30,9 @@ use syntax::{SyntaxNodePtr, TextRange}; use triomphe::Arc; use crate::{ - consteval::{intern_const_scalar, try_const_usize, ConstEvalError}, + CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId, Interner, + MemoryMap, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, + consteval::{ConstEvalError, intern_const_scalar, try_const_usize}, db::{HirDatabase, InternedClosure}, display::{ClosureStyle, DisplayTarget, HirDisplay}, infer::PointerCast, @@ -39,15 +41,13 @@ use crate::{ method_resolution::{is_dyn_method, lookup_impl_const}, static_lifetime, traits::FnTrait, - utils::{detect_variant_from_bytes, ClosureSubst}, - CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId, Interner, - MemoryMap, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, + utils::{ClosureSubst, detect_variant_from_bytes}, }; use super::{ - return_slot, AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, - MirSpan, Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind, - TerminatorKind, UnOp, + AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan, + Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind, + TerminatorKind, UnOp, return_slot, }; mod shim; @@ -825,7 +825,7 @@ impl Evaluator<'_> { _ => { return Err(MirEvalError::InternalError( "mismatched layout".into(), - )) + )); } }] } @@ -1864,7 +1864,7 @@ impl Evaluator<'_> { "encoded tag ({offset}, {size}, {value}) is out of bounds 0..{size}" ) .into(), - )) + )); } } } @@ -1876,7 +1876,7 @@ impl Evaluator<'_> { None => { return Err(MirEvalError::InternalError( format!("field offset ({offset}) is out of bounds 0..{size}").into(), - )) + )); } } } @@ -2054,7 +2054,7 @@ impl Evaluator<'_> { _ => { return Err(MirEvalError::UndefinedBehavior(format!( "invalid memory write at address {addr:?}" - ))) + ))); } } @@ -2618,13 +2618,10 @@ impl Evaluator<'_> { let ty = ty.clone().cast(Interner); let generics_for_target = Substitution::from_iter( Interner, - generic_args.iter(Interner).enumerate().map(|(i, it)| { - if i == self_ty_idx { - &ty - } else { - it - } - }), + generic_args + .iter(Interner) + .enumerate() + .map(|(i, it)| if i == self_ty_idx { &ty } else { it }), ); self.exec_fn_with_args( def, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index edd028cdeb26c..a1cff20f9296d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -10,19 +10,19 @@ use hir_def::{ resolver::HasResolver, }; use hir_expand::name::Name; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use stdx::never; use crate::{ + DropGlue, display::DisplayTarget, error_lifetime, mir::eval::{ - pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay, + Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution, - Ty, TyBuilder, TyExt, + Ty, TyBuilder, TyExt, pad16, }, - DropGlue, }; mod simd; @@ -1357,7 +1357,7 @@ impl Evaluator<'_> { _ => { return Err(MirEvalError::InternalError( "three_way_compare expects an integral type".into(), - )) + )); } }; let rhs = rhs.get(self)?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs index 54754045c98aa..2387c19cdb517 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs @@ -2,8 +2,8 @@ use std::cmp::Ordering; -use crate::consteval::try_const_usize; use crate::TyKind; +use crate::consteval::try_const_usize; use super::*; @@ -164,7 +164,7 @@ impl Evaluator<'_> { None => { return Err(MirEvalError::InternalError( "simd type with unevaluatable len param".into(), - )) + )); } }; let (left_len, _) = self.detect_simd_ty(&left.ty)?; @@ -179,7 +179,7 @@ impl Evaluator<'_> { None => { return Err(MirEvalError::InternalError( "out of bound access in simd shuffle".into(), - )) + )); } }; result.extend(val); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs index 084c391d26cbb..cd490c3b48e5a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs @@ -4,9 +4,9 @@ use syntax::{TextRange, TextSize}; use test_fixture::WithFixture; use crate::display::DisplayTarget; -use crate::{db::HirDatabase, mir::MirLowerError, test_db::TestDB, Interner, Substitution}; +use crate::{Interner, Substitution, db::HirDatabase, mir::MirLowerError, test_db::TestDB}; -use super::{interpret_mir, MirEvalError}; +use super::{MirEvalError, interpret_mir}; fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError> { let module_id = db.module_for_file(file_id); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 38924d7c95495..95c93b5f3edd8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -2,9 +2,11 @@ use std::{fmt::Write, iter, mem}; -use base_db::{salsa::Cycle, Crate}; +use base_db::{Crate, salsa::Cycle}; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ + AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId, + Lookup, TraitId, TupleId, TypeOrConstParamId, data::adt::{StructKind, VariantData}, expr_store::{Body, HygieneId}, hir::{ @@ -15,8 +17,6 @@ use hir_def::{ path::Path, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, type_ref::TypesMap, - AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId, - Lookup, TraitId, TupleId, TypeOrConstParamId, }; use hir_expand::name::Name; use la_arena::ArenaMap; @@ -27,27 +27,27 @@ use syntax::TextRange; use triomphe::Arc; use crate::{ + Adjust, Adjustment, AutoBorrow, CallableDefId, TyBuilder, TyExt, consteval::ConstEvalError, db::{HirDatabase, InternedClosure}, - display::{hir_display_with_types_map, DisplayTarget, HirDisplay}, + display::{DisplayTarget, HirDisplay, hir_display_with_types_map}, error_lifetime, generics::generics, - infer::{cast::CastTy, unify::InferenceTable, CaptureKind, CapturedItem, TypeMismatch}, + infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy, unify::InferenceTable}, inhabitedness::is_ty_uninhabited_from, layout::LayoutError, mapping::ToChalk, mir::{ - intern_const_scalar, return_slot, AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, - BorrowKind, CastKind, ClosureId, ConstScalar, Either, Expr, FieldId, Idx, InferenceResult, - Interner, Local, LocalId, MemoryMap, MirBody, MirSpan, Mutability, Operand, Place, - PlaceElem, PointerCast, ProjectionElem, ProjectionStore, RawIdx, Rvalue, Statement, - StatementKind, Substitution, SwitchTargets, Terminator, TerminatorKind, TupleFieldId, Ty, - UnOp, VariantId, + AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, BorrowKind, CastKind, ClosureId, + ConstScalar, Either, Expr, FieldId, Idx, InferenceResult, Interner, Local, LocalId, + MemoryMap, MirBody, MirSpan, Mutability, Operand, Place, PlaceElem, PointerCast, + ProjectionElem, ProjectionStore, RawIdx, Rvalue, Statement, StatementKind, Substitution, + SwitchTargets, Terminator, TerminatorKind, TupleFieldId, Ty, UnOp, VariantId, + intern_const_scalar, return_slot, }, static_lifetime, traits::FnTrait, utils::ClosureSubst, - Adjust, Adjustment, AutoBorrow, CallableDefId, TyBuilder, TyExt, }; mod as_place; @@ -1278,7 +1278,7 @@ impl<'ctx> MirLowerCtx<'ctx> { _ => { return Err(MirLowerError::TypeError( "Array expression with non array type", - )) + )); } }; let Some(values) = elements @@ -1310,7 +1310,7 @@ impl<'ctx> MirLowerCtx<'ctx> { _ => { return Err(MirLowerError::TypeError( "Array repeat expression with non array type", - )) + )); } }; let r = Rvalue::Repeat(init, len); @@ -1441,7 +1441,7 @@ impl<'ctx> MirLowerCtx<'ctx> { _ => { return Err(MirLowerError::TypeError( "float with size other than 2, 4, 8 or 16 bytes", - )) + )); } }, }; @@ -2173,11 +2173,7 @@ pub fn lower_to_mir( ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr) }); let binding_picker = |b: BindingId| { let owner = ctx.body.binding_owners.get(&b).copied(); - if root_expr == body.body_expr { - owner.is_none() - } else { - owner == Some(root_expr) - } + if root_expr == body.body_expr { owner.is_none() } else { owner == Some(root_expr) } }; // 1 to param_len is for params // FIXME: replace with let chain once it becomes stable diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs index 1c6dc4fecd81e..d6b2100253f6b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -1,9 +1,11 @@ //! MIR lowering for patterns -use hir_def::{hir::ExprId, AssocItemId}; +use hir_def::{AssocItemId, hir::ExprId}; use crate::{ + BindingMode, mir::{ + LocalId, MutBorrowKind, lower::{ BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner, MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Operand, Pat, PatId, Place, @@ -11,9 +13,7 @@ use crate::{ Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind, ValueNs, VariantData, VariantId, }, - LocalId, MutBorrowKind, }, - BindingMode, }; macro_rules! not_supported { @@ -139,7 +139,7 @@ impl MirLowerCtx<'_> { _ => { return Err(MirLowerError::TypeError( "non tuple type matched with tuple pattern", - )) + )); } }; self.pattern_match_tuple_like( @@ -615,7 +615,7 @@ impl MirLowerCtx<'_> { mode, )?, VariantId::UnionId(_) => { - return Err(MirLowerError::TypeError("pattern matching on union")) + return Err(MirLowerError::TypeError("pattern matching on union")); } }) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs index 6d1e9a1ea1972..c733c7ed845a4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs @@ -10,19 +10,19 @@ use std::mem; use chalk_ir::{ - fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}, ConstData, DebruijnIndex, + fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}, }; use hir_def::DefWithBodyId; use triomphe::Arc; use crate::{ + ClosureId, Const, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, TyKind, consteval::{intern_const_scalar, unknown_const}, db::{HirDatabase, HirDatabaseData, InternedClosure}, from_placeholder_idx, - generics::{generics, Generics}, + generics::{Generics, generics}, infer::normalize, - ClosureId, Const, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, TyKind, }; use super::{MirBody, MirLowerError, Operand, Rvalue, StatementKind, TerminatorKind}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs index 7d7d4106cb955..d9c0000fffd01 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs @@ -7,14 +7,14 @@ use std::{ use either::Either; use hir_def::{expr_store::Body, hir::BindingId}; -use hir_expand::{name::Name, Lookup}; +use hir_expand::{Lookup, name::Name}; use la_arena::ArenaMap; use crate::{ + ClosureId, db::HirDatabase, display::{ClosureStyle, DisplayTarget, HirDisplay}, mir::{PlaceElem, ProjectionElem, StatementKind, TerminatorKind}, - ClosureId, }; use super::{ diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs index fe9416c6cfc69..01e4160edb8dd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs @@ -4,7 +4,7 @@ use std::sync::LazyLock; use hir_def::attr::Attrs; use hir_def::tt; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use rustc_hash::{FxHashMap, FxHashSet}; #[derive(Debug, Default)] @@ -38,15 +38,17 @@ impl TargetFeatures { let enabled = attrs .by_key(&sym::target_feature) .tt_values() - .filter_map(|tt| { - match tt.token_trees().flat_tokens() { - [ - tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), - tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })), - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })), - ] if enable_ident.sym == sym::enable => Some(features), - _ => None, - } + .filter_map(|tt| match tt.token_trees().flat_tokens() { + [ + tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), + tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })), + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + kind: tt::LitKind::Str, + symbol: features, + .. + })), + ] if enable_ident.sym == sym::enable => Some(features), + _ => None, }) .flat_map(|features| features.as_str().split(',').map(Symbol::intern)) .collect(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs index 68d0c8cd5a312..5f1bd57af80ac 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs @@ -7,7 +7,7 @@ use base_db::{ SourceRoot, SourceRootId, SourceRootInput, Upcast, }; -use hir_def::{db::DefDatabase, ModuleId}; +use hir_def::{ModuleId, db::DefDatabase}; use hir_expand::db::ExpandDatabase; use rustc_hash::FxHashMap; use salsa::{AsDynDatabase, Durability}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index 13d74264c560d..8790a31562e23 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -18,33 +18,33 @@ use std::sync::LazyLock; use base_db::{Crate, SourceDatabase}; use expect_test::Expect; use hir_def::{ + AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId, SyntheticSyntax, db::DefDatabase, expr_store::{Body, BodySourceMap}, hir::{ExprId, Pat, PatId}, item_scope::ItemScope, nameres::DefMap, src::HasSource, - AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId, SyntheticSyntax, }; -use hir_expand::{db::ExpandDatabase, FileRange, InFile}; +use hir_expand::{FileRange, InFile, db::ExpandDatabase}; use itertools::Itertools; use rustc_hash::FxHashMap; use stdx::format_to; use syntax::{ - ast::{self, AstNode, HasName}, SyntaxNode, + ast::{self, AstNode, HasName}, }; use test_fixture::WithFixture; -use tracing_subscriber::{layer::SubscriberExt, Registry}; +use tracing_subscriber::{Registry, layer::SubscriberExt}; use tracing_tree::HierarchicalLayer; use triomphe::Arc; use crate::{ + InferenceResult, Ty, db::HirDatabase, display::{DisplayTarget, HirDisplay}, infer::{Adjustment, TypeMismatch}, test_db::TestDB, - InferenceResult, Ty, }; // These tests compare the inference results for all expressions in a file diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index efb1728d0561d..7d4218939ed36 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -1,4 +1,4 @@ -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use hir_def::db::DefDatabase; use hir_expand::files::InFileWrapper; use itertools::Itertools; @@ -384,7 +384,9 @@ fn main() { }; } "#, - expect!["57..149;20..25;78..80,98..100,118..124,134..135 ByRef(Mut { kind: Default }) a &'? mut bool"], + expect![ + "57..149;20..25;78..80,98..100,118..124,134..135 ByRef(Mut { kind: Default }) a &'? mut bool" + ], ); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs index 6cb59491fac82..b718556c8ae03 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs @@ -5,8 +5,8 @@ use itertools::Itertools; use span::Edition; use crate::{ - chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk, - CallableDefId, Interner, ProjectionTyExt, + CallableDefId, Interner, ProjectionTyExt, chalk_db, db::HirDatabase, from_assoc_type_id, + from_chalk_trait_id, mapping::from_chalk, }; use hir_def::{AdtId, ItemContainerId, Lookup, TypeAliasId}; @@ -131,11 +131,7 @@ mod unsafe_tls { pub(crate) fn with_current_program( op: impl for<'a> FnOnce(Option<&'a DebugContext<'a>>) -> R, ) -> R { - if PROGRAM.is_set() { - PROGRAM.with(|prog| op(Some(prog))) - } else { - op(None) - } + if PROGRAM.is_set() { PROGRAM.with(|prog| op(Some(prog))) } else { op(None) } } pub(crate) fn set_current_program(p: &dyn HirDatabase, op: OP) -> R diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index f8db6a8298f6b..92dea02c7bf72 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -3,14 +3,14 @@ use core::fmt; use std::env::var; -use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData}; +use chalk_ir::{DebruijnIndex, GoalData, fold::TypeFoldable}; use chalk_recursive::Cache; -use chalk_solve::{logging_db::LoggingRustIrDatabase, rust_ir, Solver}; +use chalk_solve::{Solver, logging_db::LoggingRustIrDatabase, rust_ir}; use base_db::Crate; use hir_def::{ - lang_item::{LangItem, LangItemTarget}, BlockId, TraitId, + lang_item::{LangItem, LangItemTarget}, }; use hir_expand::name::Name; use intern::sym; @@ -19,9 +19,9 @@ use stdx::{never, panic_context}; use triomphe::Arc; use crate::{ - db::HirDatabase, infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, AliasEq, - AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy, - ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, TypeFlags, WhereClause, + AliasEq, AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy, + ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, TypeFlags, WhereClause, db::HirDatabase, + infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, }; /// This controls how much 'time' we give the Chalk solver before giving up. @@ -190,11 +190,7 @@ fn solve( // don't set the TLS for Chalk unless Chalk debugging is active, to make // extra sure we only use it for debugging - if is_chalk_debug() { - crate::tls::set_current_program(db, solve) - } else { - solve() - } + if is_chalk_debug() { crate::tls::set_current_program(db, solve) } else { solve() } } struct LoggingRustIrDatabaseLoggingOnDrop<'a>(LoggingRustIrDatabase>); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index 3bd04b21b285d..695527444db05 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -5,33 +5,33 @@ use std::{hash::Hash, iter}; use base_db::Crate; use chalk_ir::{ - fold::{FallibleTypeFolder, Shift}, DebruijnIndex, + fold::{FallibleTypeFolder, Shift}, }; use hir_def::{ + EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, + TypeOrConstParamId, db::DefDatabase, generics::{WherePredicate, WherePredicateTypeTarget}, lang_item::LangItem, resolver::{HasResolver, TypeNs}, type_ref::{TraitBoundModifier, TypeRef}, - EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, - TypeOrConstParamId, }; use hir_expand::name::Name; use intern::sym; use rustc_abi::TargetDataLayout; use rustc_hash::FxHashSet; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use span::Edition; use stdx::never; use crate::{ + ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TargetFeatures, TraitRef, + TraitRefExt, Ty, WhereClause, consteval::unknown_const, db::HirDatabase, layout::{Layout, TagEncoding}, mir::pad16, - ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TargetFeatures, TraitRef, - TraitRefExt, Ty, WhereClause, }; pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator + '_ { @@ -315,11 +315,7 @@ pub fn is_fn_unsafe_to_call( } else { // Function in an `extern` block are always unsafe to call, except when // it is marked as `safe`. - if data.is_safe() { - Unsafety::Safe - } else { - Unsafety::Unsafe - } + if data.is_safe() { Unsafety::Safe } else { Unsafety::Unsafe } } } _ => Unsafety::Safe, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index ab3d098908893..e8744e4629e80 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -14,7 +14,7 @@ //! while installing firewall per item queries to prevent invalidation issues. use crate::db::HirDatabase; -use crate::generics::{generics, Generics}; +use crate::generics::{Generics, generics}; use crate::{ AliasTy, Const, ConstScalar, DynTyExt, GenericArg, GenericArgData, Interner, Lifetime, LifetimeData, Ty, TyKind, @@ -487,13 +487,13 @@ impl Context<'_> { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use hir_def::{ - generics::GenericParamDataRef, src::HasSource, AdtId, GenericDefId, ModuleDefId, + AdtId, GenericDefId, ModuleDefId, generics::GenericParamDataRef, src::HasSource, }; use itertools::Itertools; use stdx::format_to; - use syntax::{ast::HasName, AstNode}; + use syntax::{AstNode, ast::HasName}; use test_fixture::WithFixture; use hir_def::Lookup; diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index 1c88e79933fba..70637028eff98 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -3,12 +3,12 @@ use std::ops::ControlFlow; use hir_def::{ + AssocItemId, AttrDefId, ModuleDefId, attr::AttrsWithOwner, item_scope::ItemInNs, path::{ModPath, Path}, per_ns::Namespace, resolver::{HasResolver, Resolver, TypeNs}, - AssocItemId, AttrDefId, ModuleDefId, }; use hir_expand::{mod_path::PathKind, name::Name}; use hir_ty::{db::HirDatabase, method_resolution}; @@ -273,11 +273,7 @@ fn resolve_impl_trait_item( // disambiguation) so we just pick the first one we find as well. result = as_module_def_if_namespace_matches(assoc_item_id.into(), ns); - if result.is_some() { - ControlFlow::Break(()) - } else { - ControlFlow::Continue(()) - } + if result.is_some() { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } }, ); diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs index 1ed0daa375630..a9893e741d54d 100644 --- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs @@ -6,22 +6,23 @@ use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_def::{ + DefWithBodyId, SyntheticSyntax, expr_store::ExprOrPatPtr, hir::ExprOrPatId, - path::{hir_segment_to_ast_segment, ModPath}, + path::{ModPath, hir_segment_to_ast_segment}, type_ref::TypesSourceMap, - DefWithBodyId, SyntheticSyntax, }; -use hir_expand::{name::Name, HirFileId, InFile}; +use hir_expand::{HirFileId, InFile, name::Name}; use hir_ty::{ - db::HirDatabase, - diagnostics::{BodyValidationDiagnostic, UnsafetyReason}, CastError, InferenceDiagnostic, InferenceTyDiagnosticSource, PathLoweringDiagnostic, TyLoweringDiagnostic, TyLoweringDiagnosticKind, + db::HirDatabase, + diagnostics::{BodyValidationDiagnostic, UnsafetyReason}, }; use syntax::{ + AstNode, AstPtr, SyntaxError, SyntaxNodePtr, TextRange, ast::{self, HasGenericArgs}, - match_ast, AstNode, AstPtr, SyntaxError, SyntaxNodePtr, TextRange, + match_ast, }; use triomphe::Arc; @@ -29,8 +30,8 @@ use crate::{AssocItem, Field, Function, Local, Trait, Type}; pub use hir_def::VariantId; pub use hir_ty::{ - diagnostics::{CaseType, IncorrectCase}, GenericArgsProhibitedReason, + diagnostics::{CaseType, IncorrectCase}, }; macro_rules! diagnostics { diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index 6f4168ab0867d..ec34fd80ad689 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -1,9 +1,10 @@ //! HirDisplay implementations for various hir types. use either::Either; use hir_def::{ + AdtId, GenericDefId, data::{ - adt::{StructKind, VariantData}, TraitFlags, + adt::{StructKind, VariantData}, }, generics::{ GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate, @@ -11,14 +12,13 @@ use hir_def::{ }, lang_item::LangItem, type_ref::{TypeBound, TypeRef}, - AdtId, GenericDefId, }; use hir_ty::{ + AliasEq, AliasTy, Interner, ProjectionTyExt, TraitRefExt, TyKind, WhereClause, display::{ - hir_display_with_types_map, write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError, HirDisplayWithTypesMap, HirFormatter, SizedByDefault, + hir_display_with_types_map, write_bounds_like_dyn_trait_with_prefix, write_visibility, }, - AliasEq, AliasTy, Interner, ProjectionTyExt, TraitRefExt, TyKind, WhereClause, }; use itertools::Itertools; @@ -854,7 +854,7 @@ impl HirDisplay for Module { return match self.krate(f.db).display_name(f.db) { Some(name) => write!(f, "extern crate {name}"), None => f.write_str("extern crate {unknown}"), - } + }; } } match self.name(f.db) { diff --git a/src/tools/rust-analyzer/crates/hir/src/from_id.rs b/src/tools/rust-analyzer/crates/hir/src/from_id.rs index 891d2fd2ba5dc..ab4b4a8dae541 100644 --- a/src/tools/rust-analyzer/crates/hir/src/from_id.rs +++ b/src/tools/rust-analyzer/crates/hir/src/from_id.rs @@ -4,9 +4,9 @@ //! are splitting the hir. use hir_def::{ - hir::{BindingId, LabelId}, AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, GenericParamId, ModuleDefId, VariantId, + hir::{BindingId, LabelId}, }; use crate::{ diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index b4468178fbede..3d9c04d387483 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs @@ -2,9 +2,9 @@ use either::Either; use hir_def::{ + CallableDefId, Lookup, MacroId, VariantId, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource as _}, - CallableDefId, Lookup, MacroId, VariantId, }; use hir_expand::{HirFileId, InFile}; use hir_ty::db::InternedClosure; @@ -13,9 +13,10 @@ use syntax::ast; use tt::TextRange; use crate::{ - db::HirDatabase, Adt, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl, + Adt, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl, InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static, Struct, Trait, TraitAlias, TypeAlias, TypeOrConstParam, Union, Variant, VariantDef, + db::HirDatabase, }; pub trait HasSource { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index caf00665a1e6b..b3bb4a0a33a2b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -42,7 +42,12 @@ use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ - data::{adt::VariantData, TraitFlags}, + AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId, + CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, + FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId, + LifetimeParamId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, + SyntheticSyntax, TraitAliasId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, + data::{TraitFlags, adt::VariantData}, expr_store::ExpressionStoreDiagnostics, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat}, @@ -54,30 +59,24 @@ use hir_def::{ per_ns::PerNs, resolver::{HasResolver, Resolver}, type_ref::TypesSourceMap, - AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId, - CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, - FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId, - LifetimeParamId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, - SyntheticSyntax, TraitAliasId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, }; use hir_expand::{ - attrs::collect_attrs, proc_macro::ProcMacroKind, AstId, MacroCallKind, RenderedExpandError, - ValueResult, + AstId, MacroCallKind, RenderedExpandError, ValueResult, attrs::collect_attrs, + proc_macro::ProcMacroKind, }; use hir_ty::{ - all_super_traits, autoderef, check_orphan_rules, - consteval::{try_const_usize, unknown_const_as_generic, ConstExt}, + AliasTy, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg, + GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution, + TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyLoweringDiagnostic, + ValueTyDefId, WhereClause, all_super_traits, autoderef, check_orphan_rules, + consteval::{ConstExt, try_const_usize, unknown_const_as_generic}, diagnostics::BodyValidationDiagnostic, direct_super_traits, error_lifetime, known_const_to_ast, layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding}, method_resolution, - mir::{interpret_mir, MutBorrowKind}, + mir::{MutBorrowKind, interpret_mir}, primitive::UintTy, traits::FnTrait, - AliasTy, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg, - GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution, - TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyLoweringDiagnostic, - ValueTyDefId, WhereClause, }; use itertools::Itertools; use nameres::diagnostics::DefDiagnosticKind; @@ -86,15 +85,16 @@ use smallvec::SmallVec; use span::{Edition, EditionedFileId, FileId, MacroCallId}; use stdx::{format_to, impl_from, never}; use syntax::{ + AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, T, TextRange, ToSmolStr, ast::{self, HasAttrs as _, HasGenericParams, HasName}, - format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, T, + format_smolstr, }; use triomphe::{Arc, ThinArc}; use crate::db::{DefDatabase, HirDatabase}; pub use crate::{ - attrs::{resolve_doc_path_on, HasAttrs}, + attrs::{HasAttrs, resolve_doc_path_on}, diagnostics::*, has_source::HasSource, semantics::{ @@ -114,6 +114,7 @@ pub use crate::{ pub use { cfg::{CfgAtom, CfgExpr, CfgOptions}, hir_def::{ + ImportPathConfig, attr::{AttrSourceMap, Attrs, AttrsWithOwner}, data::adt::StructKind, find_path::PrefixKind, @@ -124,12 +125,12 @@ pub use { per_ns::Namespace, type_ref::{Mutability, TypeRef}, visibility::Visibility, - ImportPathConfig, // FIXME: This is here since some queries take it as input that are used // outside of hir. {ModuleDefId, TraitId}, }, hir_expand::{ + ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, MacroKind, attrs::{Attr, AttrId}, change::ChangeWithProcMacros, files::{ @@ -137,15 +138,16 @@ pub use { HirFileRange, InFile, InFileWrapper, InMacroFile, InRealFile, MacroFilePosition, MacroFileRange, }, - hygiene::{marks_rev, SyntaxContextExt}, + hygiene::{SyntaxContextExt, marks_rev}, inert_attr_macro::AttributeTemplate, mod_path::tool_path, name::Name, prettify_macro_expansion, proc_macro::{ProcMacros, ProcMacrosBuilder}, - tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, MacroKind, + tt, }, hir_ty::{ + CastError, DropGlue, FnAbi, PointerCast, Safety, Variance, consteval::ConstEvalError, diagnostics::UnsafetyReason, display::{ClosureStyle, DisplayTarget, HirDisplay, HirDisplayError, HirWrite}, @@ -153,11 +155,10 @@ pub use { layout::LayoutError, method_resolution::TyFingerprint, mir::{MirEvalError, MirLowerError}, - CastError, DropGlue, FnAbi, PointerCast, Safety, Variance, }, // FIXME: Properly encapsulate mir - hir_ty::{mir, Interner as ChalkTyInterner}, - intern::{sym, Symbol}, + hir_ty::{Interner as ChalkTyInterner, mir}, + intern::{Symbol, sym}, }; // These are negative re-exports: pub using these names is forbidden, they @@ -587,11 +588,7 @@ impl Module { if let Some(m) = visible_from { let filtered = def.filter_visibility(|vis| vis.is_visible_from(db.upcast(), m.id)); - if filtered.is_none() && !def.is_none() { - None - } else { - Some((name, filtered)) - } + if filtered.is_none() && !def.is_none() { None } else { Some((name, filtered)) } } else { Some((name, def)) } @@ -1759,19 +1756,11 @@ impl Adt { } pub fn as_struct(&self) -> Option { - if let Self::Struct(v) = self { - Some(*v) - } else { - None - } + if let Self::Struct(v) = self { Some(*v) } else { None } } pub fn as_enum(&self) -> Option { - if let Self::Enum(v) = self { - Some(*v) - } else { - None - } + if let Self::Enum(v) = self { Some(*v) } else { None } } } @@ -5080,11 +5069,7 @@ impl Type { let projection = TyBuilder::assoc_type_projection(db, alias.id, Some(parent_subst)).build(); let ty = db.normalize_projection(projection, self.env.clone()); - if ty.is_unknown() { - None - } else { - Some(self.derived(ty)) - } + if ty.is_unknown() { None } else { Some(self.derived(ty)) } } pub fn is_copy(&self, db: &dyn HirDatabase) -> bool { @@ -5261,7 +5246,10 @@ impl Type { /// Returns types that this type dereferences to (including this type itself). The returned /// iterator won't yield the same type more than once even if the deref chain contains a cycle. - pub fn autoderef<'db>(&self, db: &'db dyn HirDatabase) -> impl Iterator + use<'_, 'db> { + pub fn autoderef<'db>( + &self, + db: &'db dyn HirDatabase, + ) -> impl Iterator + use<'_, 'db> { self.autoderef_(db).map(move |ty| self.derived(ty)) } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index a1c0521a5eb57..604099aaa5566 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -12,6 +12,7 @@ use std::{ use either::Either; use hir_def::{ + AsMacroCall, DefWithBodyId, FunctionId, MacroId, StructId, TraitId, VariantId, expr_store::{Body, ExprOrPatSource}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, lower::LowerCtx, @@ -19,9 +20,9 @@ use hir_def::{ path::ModPath, resolver::{self, HasResolver, Resolver, TypeNs}, type_ref::{Mutability, TypesMap, TypesSourceMap}, - AsMacroCall, DefWithBodyId, FunctionId, MacroId, StructId, TraitId, VariantId, }; use hir_expand::{ + ExpandResult, FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, attrs::collect_attrs, builtin::{BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, @@ -29,32 +30,31 @@ use hir_expand::{ hygiene::SyntaxContextExt as _, inert_attr_macro::find_builtin_attr_idx, name::AsName, - ExpandResult, FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, }; use hir_ty::diagnostics::unsafe_operations_for_body; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use span::{AstIdMap, EditionedFileId, FileId, HirFileIdRepr, SyntaxContext}; use stdx::TupleExt; use syntax::{ - algo::skip_trivia_token, - ast::{self, HasAttrs as _, HasGenericParams}, AstNode, AstToken, Direction, SyntaxKind, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize, + algo::skip_trivia_token, + ast::{self, HasAttrs as _, HasGenericParams}, }; use triomphe::Arc; use crate::{ - db::HirDatabase, - semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, - source_analyzer::{name_hygiene, resolve_hir_path, SourceAnalyzer}, Adjust, Adjustment, Adt, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, ConstParam, Crate, DefWithBody, DeriveHelper, Enum, Field, Function, GenericSubstitution, HasSource, HirFileId, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef, Static, Struct, ToolModule, Trait, TraitAlias, TupleField, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, + db::HirDatabase, + semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, + source_analyzer::{SourceAnalyzer, name_hygiene, resolve_hir_path}, }; const CONTINUE_NO_BREAKS: ControlFlow = ControlFlow::Continue(()); @@ -963,11 +963,7 @@ impl<'db> SemanticsImpl<'db> { || kind.is_any_identifier() && value.kind().is_any_identifier(); let matches = (kind == mapped_kind || any_ident_match()) && text == value.text(); - if matches { - ControlFlow::Break(value) - } else { - ControlFlow::Continue(()) - } + if matches { ControlFlow::Break(value) } else { ControlFlow::Continue(()) } }, ) } else { @@ -1780,7 +1776,7 @@ impl<'db> SemanticsImpl<'db> { SourceAnalyzer::new_for_body(self.db, def, node, offset) } else { SourceAnalyzer::new_for_body_no_infer(self.db, def, node, offset) - }) + }); } ChildContainer::TraitId(it) => it.resolver(self.db.upcast()), ChildContainer::TraitAliasId(it) => it.resolver(self.db.upcast()), diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index b89d332238b65..f172eec32a4ca 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -5,22 +5,22 @@ //! node for a *child*, and get its hir. use either::Either; -use hir_expand::{attrs::collect_attrs, HirFileId}; -use syntax::{ast, AstPtr}; +use hir_expand::{HirFileId, attrs::collect_attrs}; +use syntax::{AstPtr, ast}; use hir_def::{ + AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, GenericDefId, ImplId, ItemTreeLoc, + LifetimeParamId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, TypeOrConstParamId, + VariantId, db::DefDatabase, dyn_map::{ - keys::{self, Key}, DynMap, + keys::{self, Key}, }, item_scope::ItemScope, item_tree::ItemTreeNode, nameres::DefMap, src::{HasChildSource, HasSource}, - AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, GenericDefId, ImplId, ItemTreeLoc, - LifetimeParamId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, TypeOrConstParamId, - VariantId, }; pub(crate) trait ChildBySource { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 4ec0739656076..d5695f1c21a6d 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -88,30 +88,30 @@ use base_db::{RootQueryDb, Upcast}; use either::Either; use hir_def::{ - dyn_map::{ - keys::{self, Key}, - DynMap, - }, - hir::{BindingId, Expr, LabelId}, AdtId, BlockId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeParamId, UnionId, UseId, VariantId, + dyn_map::{ + DynMap, + keys::{self, Key}, + }, + hir::{BindingId, Expr, LabelId}, }; use hir_expand::{ - attrs::AttrId, name::AsName, ExpansionInfo, HirFileId, HirFileIdExt, InMacroFile, MacroCallId, - MacroFileId, MacroFileIdExt, + ExpansionInfo, HirFileId, HirFileIdExt, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, + attrs::AttrId, name::AsName, }; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::{EditionedFileId, FileId}; use stdx::impl_from; use syntax::{ - ast::{self, HasName}, AstNode, AstPtr, SyntaxNode, + ast::{self, HasName}, }; -use crate::{db::HirDatabase, semantics::child_by_source::ChildBySource, InFile, InlineAsmOperand}; +use crate::{InFile, InlineAsmOperand, db::HirDatabase, semantics::child_by_source::ChildBySource}; #[derive(Default)] pub(super) struct SourceToDefCache { diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index e390fb0b935ff..ce9f56993e3cf 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -8,48 +8,49 @@ use std::iter::{self, once}; use crate::{ - db::HirDatabase, semantics::PathResolution, Adt, AssocItem, BindingMode, BuiltinAttr, - BuiltinType, Callable, Const, DeriveHelper, Field, Function, GenericSubstitution, Local, Macro, - ModuleDef, Static, Struct, ToolModule, Trait, TraitAlias, TupleField, Type, TypeAlias, Variant, + Adt, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const, DeriveHelper, Field, + Function, GenericSubstitution, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, + TraitAlias, TupleField, Type, TypeAlias, Variant, db::HirDatabase, semantics::PathResolution, }; use either::Either; use hir_def::{ + AsMacroCall, AssocItemId, CallableDefId, ConstId, DefWithBodyId, FieldId, FunctionId, + ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StructId, TraitId, VariantId, expr_store::{ - scope::{ExprScopes, ScopeId}, Body, BodySourceMap, HygieneId, + scope::{ExprScopes, ScopeId}, }, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, lang_item::LangItem, lower::LowerCtx, nameres::MacroSubNs, path::{ModPath, Path, PathKind}, - resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, + resolver::{Resolver, TypeNs, ValueNs, resolver_for_scope}, type_ref::{Mutability, TypesMap, TypesSourceMap}, - AsMacroCall, AssocItemId, CallableDefId, ConstId, DefWithBodyId, FieldId, FunctionId, - ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StructId, TraitId, VariantId, }; use hir_expand::{ + HirFileId, InFile, InMacroFile, MacroFileId, MacroFileIdExt, mod_path::path, name::{AsName, Name}, - HirFileId, InFile, InMacroFile, MacroFileId, MacroFileIdExt, }; use hir_ty::{ + Adjustment, InferenceResult, Interner, Substitution, TraitEnvironment, Ty, TyExt, TyKind, + TyLoweringContext, diagnostics::{ - record_literal_missing_fields, record_pattern_missing_fields, unsafe_operations, - InsideUnsafeBlock, + InsideUnsafeBlock, record_literal_missing_fields, record_pattern_missing_fields, + unsafe_operations, }, from_assoc_type_id, lang_items::lang_items_for_bin_op, - method_resolution, Adjustment, InferenceResult, Interner, Substitution, TraitEnvironment, Ty, - TyExt, TyKind, TyLoweringContext, + method_resolution, }; use intern::sym; use itertools::Itertools; use smallvec::SmallVec; use syntax::ast::{RangeItem, RangeOp}; use syntax::{ - ast::{self, AstNode}, SyntaxKind, SyntaxNode, TextRange, TextSize, + ast::{self, AstNode}, }; use triomphe::Arc; @@ -147,11 +148,7 @@ impl SourceAnalyzer { fn binding_id_of_pat(&self, pat: &ast::IdentPat) -> Option { let pat_id = self.pat_id(&pat.clone().into())?; - if let Pat::Bind { id, .. } = self.body()?.pats[pat_id.as_pat()?] { - Some(id) - } else { - None - } + if let Pat::Bind { id, .. } = self.body()?.pats[pat_id.as_pat()?] { Some(id) } else { None } } fn expand_expr( @@ -504,11 +501,7 @@ impl SourceAnalyzer { LangItem::DerefMut, &Name::new_symbol_root(sym::deref_mut.clone()), )?; - if func == deref_mut { - Some((deref_mut_trait, deref_mut)) - } else { - None - } + if func == deref_mut { Some((deref_mut_trait, deref_mut)) } else { None } }) .unwrap_or((deref_trait, deref)) } @@ -550,11 +543,7 @@ impl SourceAnalyzer { LangItem::IndexMut, &Name::new_symbol_root(sym::index_mut.clone()), )?; - if func == index_mut_fn { - Some((index_mut_trait, index_mut_fn)) - } else { - None - } + if func == index_mut_fn { Some((index_mut_trait, index_mut_fn)) } else { None } }) .unwrap_or((index_trait, index_fn)); // HACK: subst for all methods coincides with that for their trait because the methods diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 853df7ee2d88a..ae70f6f0ecc05 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -2,22 +2,22 @@ use either::Either; use hir_def::{ + AdtId, AssocItemId, DefWithBodyId, ExternCrateId, HasModule, ImplId, Lookup, MacroId, + ModuleDefId, ModuleId, TraitId, db::DefDatabase, item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob}, per_ns::Item, src::{HasChildSource, HasSource}, visibility::{Visibility, VisibilityExplicitness}, - AdtId, AssocItemId, DefWithBodyId, ExternCrateId, HasModule, ImplId, Lookup, MacroId, - ModuleDefId, ModuleId, TraitId, }; -use hir_expand::{name::Name, HirFileId}; +use hir_expand::{HirFileId, name::Name}; use hir_ty::{ db::HirDatabase, - display::{hir_display_with_types_map, DisplayTarget, HirDisplay}, + display::{DisplayTarget, HirDisplay, hir_display_with_types_map}, }; use intern::Symbol; use rustc_hash::FxHashMap; -use syntax::{ast::HasName, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr}; +use syntax::{AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName}; use crate::{Module, ModuleDef, Semantics}; diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs index 847304d503a84..bcff44fcd016e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs @@ -10,9 +10,9 @@ use std::iter; +use hir_ty::TyBuilder; use hir_ty::db::HirDatabase; use hir_ty::mir::BorrowKind; -use hir_ty::TyBuilder; use itertools::Itertools; use rustc_hash::FxHashSet; use span::Edition; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs index 05105c8c92c5e..2de0013bb126d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs @@ -5,7 +5,7 @@ //! assists if we are allowed to. use hir::ImportPathConfig; -use ide_db::{imports::insert_use::InsertUseConfig, SnippetCap}; +use ide_db::{SnippetCap, imports::insert_use::InsertUseConfig}; use crate::AssistKind; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs index c4e98c0742358..afb2229d3e2f6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs @@ -1,18 +1,18 @@ //! See [`AssistContext`]. use hir::{FileRange, Semantics}; -use ide_db::base_db::salsa::AsDynDatabase; use ide_db::EditionedFileId; -use ide_db::{label::Label, FileId, RootDatabase}; +use ide_db::base_db::salsa::AsDynDatabase; +use ide_db::{FileId, RootDatabase, label::Label}; use syntax::Edition; use syntax::{ - algo::{self, find_node_at_offset, find_node_at_range}, AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange, TextSize, TokenAtOffset, + algo::{self, find_node_at_offset, find_node_at_range}, }; use crate::{ - assist_config::AssistConfig, Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel, + Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel, assist_config::AssistConfig, }; pub(crate) use ide_db::source_change::{SourceChangeBuilder, TreeMutator}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs index 42f615e71daf6..f9124d2d46551 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs @@ -1,6 +1,6 @@ use syntax::{ - ast::{self, edit_in_place::Indent, syntax_factory::SyntaxFactory}, AstNode, + ast::{self, edit_in_place::Indent, syntax_factory::SyntaxFactory}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs index 1a5de9cb071bb..c8a6f9e65caf5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs @@ -1,10 +1,10 @@ use hir::Semantics; use ide_db::{ + RootDatabase, assists::{AssistId, AssistKind}, source_change::SourceChangeBuilder, - RootDatabase, }; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use crate::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs index 001f1e8bb1585..fc10501543b47 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs @@ -1,7 +1,7 @@ use ide_db::syntax_helpers::node_ext::for_each_break_and_continue_expr; use syntax::{ - ast::{self, AstNode, HasLoopBody}, T, + ast::{self, AstNode, HasLoopBody}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs index 43c0a72fa4774..c3e05b8fb0839 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs @@ -99,11 +99,7 @@ fn fetch_borrowed_types(node: &ast::Adt) -> Option> { } }; - if ref_types.is_empty() { - None - } else { - Some(ref_types) - } + if ref_types.is_empty() { None } else { Some(ref_types) } } fn find_ref_types_from_field_list(field_list: &ast::FieldList) -> Option> { @@ -134,11 +130,7 @@ fn find_ref_types_from_field_list(field_list: &ast::FieldList) -> Option) -> Opti let def = match NameRefClass::classify(&ctx.sema, &name_ref)? { NameRefClass::Definition(def, _) => def, NameRefClass::FieldShorthand { .. } | NameRefClass::ExternCrateShorthand { .. } => { - return None + return None; } }; let fun = match def { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 67bf8eed23df1..e584c709a94a4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -6,19 +6,18 @@ use ide_db::{ syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ + SyntaxKind, T, ast::{ - self, - prec::{precedence, ExprPrecedence}, - syntax_factory::SyntaxFactory, - AstNode, + self, AstNode, Expr::BinExpr, HasArgList, + prec::{ExprPrecedence, precedence}, + syntax_factory::SyntaxFactory, }, syntax_editor::{Position, SyntaxEditor}, - SyntaxKind, T, }; -use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::invert_boolean_expression}; // Assist: apply_demorgan // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index a92a000c3fbd3..f491b9375c33b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs @@ -1,14 +1,14 @@ use std::cmp::Reverse; -use hir::{db::HirDatabase, Module}; +use hir::{Module, db::HirDatabase}; use ide_db::{ helpers::mod_path_to_ast, imports::{ import_assets::{ImportAssets, ImportCandidate, LocatedImport}, - insert_use::{insert_use, insert_use_as_alias, ImportScope}, + insert_use::{ImportScope, insert_use, insert_use_as_alias}, }, }; -use syntax::{ast, AstNode, Edition, NodeOrToken, SyntaxElement}; +use syntax::{AstNode, Edition, NodeOrToken, SyntaxElement, ast}; use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; @@ -279,12 +279,12 @@ mod tests { use super::*; use hir::{FileRange, Semantics}; - use ide_db::{assists::AssistResolveStrategy, RootDatabase}; + use ide_db::{RootDatabase, assists::AssistResolveStrategy}; use test_fixture::WithFixture; use crate::tests::{ - check_assist, check_assist_by_label, check_assist_not_applicable, check_assist_target, - TEST_CONFIG, + TEST_CONFIG, check_assist, check_assist_by_label, check_assist_not_applicable, + check_assist_target, }; fn check_auto_import_order(before: &str, order: &[&str]) { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs index 8f053f4df949f..5048ff5163abf 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs @@ -1,12 +1,12 @@ use crate::assist_context::{AssistContext, Assists}; use ide_db::{ + LineIndexDatabase, assists::{AssistId, AssistKind}, defs::Definition, - LineIndexDatabase, }; use syntax::{ - ast::{self, edit_in_place::Indent}, AstNode, + ast::{self, edit_in_place::Indent}, }; // Assist: bind_unused_param diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/change_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/change_visibility.rs index 07fd5e34181ef..8af9121fc8d13 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/change_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/change_visibility.rs @@ -1,14 +1,14 @@ use syntax::{ - ast::{self, HasName, HasVisibility}, AstNode, SyntaxKind::{ self, ASSOC_ITEM_LIST, CONST, ENUM, FN, MACRO_DEF, MODULE, SOURCE_FILE, STATIC, STRUCT, TRAIT, TYPE_ALIAS, USE, VISIBILITY, }, SyntaxNode, T, + ast::{self, HasName, HasVisibility}, }; -use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::vis_offset}; // Assist: change_visibility // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index 151c71c0a767e..c4a2189f696ea 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -1,21 +1,21 @@ -use hir::{sym, AsAssocItem, Semantics}; +use hir::{AsAssocItem, Semantics, sym}; use ide_db::{ + RootDatabase, famous_defs::FamousDefs, syntax_helpers::node_ext::{ block_as_lone_tail, for_each_tail_expr, is_pattern_cond, preorder_expr, }, - RootDatabase, }; use itertools::Itertools; use syntax::{ - ast::{self, edit::AstNodeEdit, syntax_factory::SyntaxFactory, HasArgList}, - syntax_editor::SyntaxEditor, AstNode, SyntaxNode, + ast::{self, HasArgList, edit::AstNodeEdit, syntax_factory::SyntaxFactory}, + syntax_editor::SyntaxEditor, }; use crate::{ - utils::{invert_boolean_expression, unwrap_trivial_block}, AssistContext, AssistId, AssistKind, Assists, + utils::{invert_boolean_expression, unwrap_trivial_block}, }; // Assist: convert_if_to_bool_then diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs index 9cb14e8d9a007..8200ad75df5ff 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs @@ -2,23 +2,23 @@ use either::Either; use hir::ModuleDef; use ide_db::text_edit::TextRange; use ide_db::{ + FxHashSet, assists::{AssistId, AssistKind}, defs::Definition, helpers::mod_path_to_ast, - imports::insert_use::{insert_use, ImportScope}, + imports::insert_use::{ImportScope, insert_use}, search::{FileReference, UsageSearchResult}, source_change::SourceChangeBuilder, - FxHashSet, }; use itertools::Itertools; use syntax::{ + AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T, ast::{ - self, + self, HasName, edit::IndentLevel, edit_in_place::{AttrsOwnerEdit, Indent}, - make, HasName, + make, }, - AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T, }; use crate::{ diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs index 54826f03884f3..c11a411fb9c2c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs @@ -1,23 +1,24 @@ use either::Either; use hir::{CaptureKind, ClosureCapture, FileRangeWrapper, HirDisplay}; use ide_db::{ + FxHashSet, assists::{AssistId, AssistKind}, base_db::SourceDatabase, defs::Definition, search::FileReferenceNode, source_change::SourceChangeBuilder, - FxHashSet, }; use stdx::format_to; use syntax::{ + AstNode, Direction, SyntaxKind, SyntaxNode, T, TextSize, ToSmolStr, algo::{skip_trivia_token, skip_whitespace_token}, ast::{ - self, + self, HasArgList, HasGenericParams, HasName, edit::{AstNodeEdit, IndentLevel}, - make, HasArgList, HasGenericParams, HasName, + make, }, hacks::parse_expr_from_str, - ted, AstNode, Direction, SyntaxKind, SyntaxNode, TextSize, ToSmolStr, T, + ted, }; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs index fbc0b9f6739ff..92b86cee356e8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use syntax::{ - ast::{self, edit::IndentLevel, Comment, CommentKind, CommentShape, Whitespace}, AstToken, Direction, SyntaxElement, TextRange, + ast::{self, Comment, CommentKind, CommentShape, Whitespace, edit::IndentLevel}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -167,11 +167,7 @@ pub(crate) fn line_comment_text(indentation: IndentLevel, comm: ast::Comment) -> let contents = contents_without_prefix.strip_prefix(' ').unwrap_or(contents_without_prefix); // Don't add the indentation if the line is empty - if contents.is_empty() { - contents.to_owned() - } else { - indentation.to_string() + contents - } + if contents.is_empty() { contents.to_owned() } else { indentation.to_string() + contents } } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs index 5a9db67a5fb68..7b4d27100f15d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use syntax::{ - ast::{self, edit::IndentLevel, Comment, CommentPlacement, Whitespace}, AstToken, Direction, SyntaxElement, TextRange, + ast::{self, Comment, CommentPlacement, Whitespace, edit::IndentLevel}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs index 2d2751de99d87..03041f3551d39 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs @@ -1,12 +1,12 @@ use hir::{ - sym::{self}, Name, + sym::{self}, }; use ide_db::{famous_defs::FamousDefs, syntax_helpers::suggest_name}; use syntax::{ - ast::{self, edit::IndentLevel, make, syntax_factory::SyntaxFactory, HasLoopBody}, - syntax_editor::Position, AstNode, + ast::{self, HasLoopBody, edit::IndentLevel, make, syntax_factory::SyntaxFactory}, + syntax_editor::Position, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs index dd2e9cbcb5f2d..07ad5a695b3c3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs @@ -1,7 +1,7 @@ use ide_db::{famous_defs::FamousDefs, traits::resolve_target_trait}; use itertools::Itertools; use syntax::{ - ast::{self, make, AstNode, HasGenericArgs, HasName}, + ast::{self, AstNode, HasGenericArgs, HasName, make}, ted, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs index fd3378e8c2636..270eecd83b06e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs @@ -1,4 +1,4 @@ -use syntax::{ast, ast::Radix, AstToken}; +use syntax::{AstToken, ast, ast::Radix}; use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index 3c9a91741047e..713d215f1209e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -1,9 +1,9 @@ -use hir::{sym, Name}; +use hir::{Name, sym}; use ide_db::famous_defs::FamousDefs; use stdx::format_to; use syntax::{ - ast::{self, edit_in_place::Indent, make, HasArgList, HasLoopBody}, AstNode, + ast::{self, HasArgList, HasLoopBody, edit_in_place::Indent, make}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs index 79c34c14da720..9f71031a1e68a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs @@ -1,8 +1,8 @@ use hir::Semantics; use ide_db::RootDatabase; -use syntax::ast::RangeItem; -use syntax::ast::{edit::AstNodeEdit, AstNode, HasName, LetStmt, Name, Pat}; use syntax::T; +use syntax::ast::RangeItem; +use syntax::ast::{AstNode, HasName, LetStmt, Name, Pat, edit::AstNodeEdit}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -162,11 +162,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String { .iter() .map( |(ident, ismut)| { - if *ismut && addmut { - format!("mut {ident}") - } else { - ident.to_string() - } + if *ismut && addmut { format!("mut {ident}") } else { ident.to_string() } }, ) .collect::>() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs index fd159eb824d6d..2db78f412d740 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs @@ -1,12 +1,13 @@ use ide_db::defs::{Definition, NameRefClass}; use syntax::{ + AstNode, SyntaxNode, ast::{self, HasName, Name}, - ted, AstNode, SyntaxNode, + ted, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: convert_match_to_let_else diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 8d4ff84084bd3..7b8804e53f087 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -2,11 +2,12 @@ use either::Either; use ide_db::{defs::Definition, search::FileReference}; use itertools::Itertools; use syntax::{ + SyntaxKind, ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility}, - match_ast, ted, SyntaxKind, + match_ast, ted, }; -use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, assist_context::SourceChangeBuilder}; // Assist: convert_named_struct_to_tuple_struct // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index b7a77644496fa..bd829d1e24bf9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -5,20 +5,21 @@ use ide_db::{ ty_filter::TryEnum, }; use syntax::{ + AstNode, + SyntaxKind::{FN, FOR_EXPR, LOOP_EXPR, WHILE_EXPR, WHITESPACE}, + T, ast::{ self, edit::{AstNodeEdit, IndentLevel}, make, }, - ted, AstNode, - SyntaxKind::{FN, FOR_EXPR, LOOP_EXPR, WHILE_EXPR, WHITESPACE}, - T, + ted, }; use crate::{ + AssistId, AssistKind, assist_context::{AssistContext, Assists}, utils::invert_boolean_expression_legacy, - AssistId, AssistKind, }; // Assist: convert_to_guarded_return diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index 91af9b05bbb85..0d79937885717 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -1,18 +1,19 @@ use either::Either; use hir::ModuleDef; use ide_db::{ + FxHashSet, assists::{AssistId, AssistKind}, defs::Definition, helpers::mod_path_to_ast, - imports::insert_use::{insert_use, ImportScope}, + imports::insert_use::{ImportScope, insert_use}, search::{FileReference, UsageSearchResult}, source_change::SourceChangeBuilder, syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, - FxHashSet, }; use syntax::{ - ast::{self, edit::IndentLevel, edit_in_place::Indent, make, HasName}, - match_ast, ted, AstNode, SyntaxNode, + AstNode, SyntaxNode, + ast::{self, HasName, edit::IndentLevel, edit_in_place::Indent, make}, + match_ast, ted, }; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index f6e516db88835..83e4737350c07 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -1,11 +1,12 @@ use either::Either; use ide_db::defs::{Definition, NameRefClass}; use syntax::{ + SyntaxKind, SyntaxNode, ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility}, - match_ast, ted, SyntaxKind, SyntaxNode, + match_ast, ted, }; -use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, assist_context::SourceChangeBuilder}; // Assist: convert_tuple_struct_to_named_struct // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs index beec64d13b689..724de1969cb53 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs @@ -3,18 +3,18 @@ use std::iter; use either::Either; use ide_db::syntax_helpers::node_ext::is_pattern_cond; use syntax::{ + AstNode, T, ast::{ - self, + self, HasLoopBody, edit::{AstNodeEdit, IndentLevel}, - make, HasLoopBody, + make, }, - AstNode, T, }; use crate::{ + AssistId, AssistKind, assist_context::{AssistContext, Assists}, utils::invert_boolean_expression_legacy, - AssistId, AssistKind, }; // Assist: convert_while_to_loop diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index e34e50904875d..a8a3a8c927f81 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -1,14 +1,14 @@ -use hir::{sym, HasVisibility}; +use hir::{HasVisibility, sym}; use ide_db::text_edit::TextRange; use ide_db::{ + FxHashMap, FxHashSet, assists::{AssistId, AssistKind}, defs::Definition, helpers::mod_path_to_ast, search::{FileReference, SearchScope}, - FxHashMap, FxHashSet, }; use itertools::Itertools; -use syntax::{ast, ted, AstNode, Edition, SmolStr, SyntaxNode, ToSmolStr}; +use syntax::{AstNode, Edition, SmolStr, SyntaxNode, ToSmolStr, ast, ted}; use crate::{ assist_context::{AssistContext, Assists, SourceChangeBuilder}, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs index 39142d606207c..95eb88fa86878 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs @@ -7,7 +7,7 @@ use ide_db::{ }; use itertools::Itertools; use syntax::{ - ast::{self, make, AstNode, FieldExpr, HasName, IdentPat}, + ast::{self, AstNode, FieldExpr, HasName, IdentPat, make}, ted, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_doc_comment.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_doc_comment.rs index d264928046707..9d0797d32a82f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_doc_comment.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_doc_comment.rs @@ -1,14 +1,14 @@ use either::Either; use itertools::Itertools; use syntax::{ - ast::{self, edit::IndentLevel, CommentPlacement, Whitespace}, AstToken, TextRange, + ast::{self, CommentPlacement, Whitespace, edit::IndentLevel}, }; use crate::{ + AssistContext, AssistId, AssistKind, Assists, handlers::convert_comment_block::{line_comment_text, relevant_line_comments}, utils::required_hashes, - AssistContext, AssistId, AssistKind, Assists, }; // Assist: desugar_doc_comment diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs index 0b95d6177f904..fae5530f99528 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs @@ -7,13 +7,14 @@ use ide_db::{ }; use stdx::never; use syntax::{ - ast::{self, make, Use, UseTree, VisibilityKind}, - ted, AstNode, Direction, SyntaxNode, SyntaxToken, T, + AstNode, Direction, SyntaxNode, SyntaxToken, T, + ast::{self, Use, UseTree, VisibilityKind, make}, + ted, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: expand_glob_import diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs index c79a982c38d09..e437e7eb75122 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs @@ -1,8 +1,9 @@ use hir::{PathResolution, StructKind}; use ide_db::syntax_helpers::suggest_name::NameGenerator; use syntax::{ + AstNode, ToSmolStr, ast::{self, make}, - match_ast, AstNode, ToSmolStr, + match_ast, }; use crate::{AssistContext, AssistId, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs index e4d347ef16bd6..c9eb7c52379fc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs @@ -1,14 +1,15 @@ -use crate::{utils, AssistContext, Assists}; +use crate::{AssistContext, Assists, utils}; use ide_db::{ assists::{AssistId, AssistKind}, - syntax_helpers::format_string_exprs::{parse_format_exprs, Arg}, + syntax_helpers::format_string_exprs::{Arg, parse_format_exprs}, }; use itertools::Itertools; use syntax::{ - ast::{self, make}, - ted, AstNode, AstToken, NodeOrToken, + AstNode, AstToken, NodeOrToken, SyntaxKind::WHITESPACE, T, + ast::{self, make}, + ted, }; // Assist: extract_expressions_from_format_string @@ -61,21 +62,28 @@ pub(crate) fn extract_expressions_from_format_string( // Extract existing arguments in macro let tokens = tt.token_trees_and_tokens().collect_vec(); - let existing_args = if let [_opening_bracket, NodeOrToken::Token(_format_string), _args_start_comma, tokens @ .., NodeOrToken::Token(_end_bracket)] = - tokens.as_slice() + let existing_args = if let [ + _opening_bracket, + NodeOrToken::Token(_format_string), + _args_start_comma, + tokens @ .., + NodeOrToken::Token(_end_bracket), + ] = tokens.as_slice() { - let args = tokens.split(|it| matches!(it, NodeOrToken::Token(t) if t.kind() == T![,])).map(|arg| { - // Strip off leading and trailing whitespace tokens - let arg = match arg.split_first() { - Some((NodeOrToken::Token(t), rest)) if t.kind() == WHITESPACE => rest, - _ => arg, - }; - let arg = match arg.split_last() { - Some((NodeOrToken::Token(t), rest)) if t.kind() == WHITESPACE => rest, - _ => arg, - }; - arg - }); + let args = tokens + .split(|it| matches!(it, NodeOrToken::Token(t) if t.kind() == T![,])) + .map(|arg| { + // Strip off leading and trailing whitespace tokens + let arg = match arg.split_first() { + Some((NodeOrToken::Token(t), rest)) if t.kind() == WHITESPACE => rest, + _ => arg, + }; + let arg = match arg.split_last() { + Some((NodeOrToken::Token(t), rest)) if t.kind() == WHITESPACE => rest, + _ => arg, + }; + arg + }); args.collect() } else { @@ -100,7 +108,8 @@ pub(crate) fn extract_expressions_from_format_string( Arg::Expr(s) => { // insert arg // FIXME: use the crate's edition for parsing - let expr = ast::Expr::parse(&s, syntax::Edition::CURRENT_FIXME).syntax_node(); + let expr = + ast::Expr::parse(&s, syntax::Edition::CURRENT_FIXME).syntax_node(); let mut expr_tt = utils::tt_from_syntax(expr); new_tt_bits.append(&mut expr_tt); } @@ -120,7 +129,6 @@ pub(crate) fn extract_expressions_from_format_string( } } - // Insert new args let new_tt = make::token_tree(tt_delimiter, new_tt_bits).clone_for_update(); ted::replace(tt.syntax(), new_tt.syntax()); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 330587e0dbfbe..6b535a289776f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -7,33 +7,34 @@ use hir::{ TypeInfo, TypeParam, }; use ide_db::{ + FxIndexSet, RootDatabase, assists::GroupLabel, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::mod_path_to_ast, - imports::insert_use::{insert_use, ImportScope}, + imports::insert_use::{ImportScope, insert_use}, search::{FileReference, ReferenceCategory, SearchScope}, source_change::SourceChangeBuilder, syntax_helpers::node_ext::{ for_each_tail_expr, preorder_expr, walk_expr, walk_pat, walk_patterns_in_expr, }, - FxIndexSet, RootDatabase, }; use itertools::Itertools; use syntax::{ + Edition, SyntaxElement, + SyntaxKind::{self, COMMENT}, + SyntaxNode, SyntaxToken, T, TextRange, TextSize, TokenAtOffset, WalkEvent, ast::{ - self, edit::IndentLevel, edit_in_place::Indent, AstNode, AstToken, HasGenericParams, - HasName, + self, AstNode, AstToken, HasGenericParams, HasName, edit::IndentLevel, + edit_in_place::Indent, }, - match_ast, ted, Edition, SyntaxElement, - SyntaxKind::{self, COMMENT}, - SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T, + match_ast, ted, }; use crate::{ + AssistId, assist_context::{AssistContext, Assists, TreeMutator}, utils::generate_impl, - AssistId, }; // Assist: extract_function @@ -1689,11 +1690,7 @@ fn make_where_clause( }) .peekable(); - if predicates.peek().is_some() { - Some(make::where_clause(predicates)) - } else { - None - } + if predicates.peek().is_some() { Some(make::where_clause(predicates)) } else { None } } fn pred_is_required( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs index b94422b13c1bc..8a7bb5a1f0d8b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs @@ -4,23 +4,24 @@ use either::Either; use hir::{HasSource, HirFileIdExt, ModuleSource}; use ide_db::base_db::salsa::AsDynDatabase; use ide_db::{ + FileId, FxHashMap, FxHashSet, assists::{AssistId, AssistKind}, defs::{Definition, NameClass, NameRefClass}, search::{FileReference, SearchScope}, - FileId, FxHashMap, FxHashSet, }; use itertools::Itertools; use smallvec::SmallVec; use syntax::{ + AstNode, + SyntaxKind::{self, WHITESPACE}, + SyntaxNode, TextRange, TextSize, algo::find_node_at_range, ast::{ - self, + self, HasVisibility, edit::{AstNodeEdit, IndentLevel}, - make, HasVisibility, + make, }, - match_ast, ted, AstNode, - SyntaxKind::{self, WHITESPACE}, - SyntaxNode, TextRange, TextSize, + match_ast, ted, }; use crate::{AssistContext, Assists}; @@ -1167,8 +1168,8 @@ mod modname { } #[test] - fn test_extract_module_for_impl_not_having_corresponding_adt_in_selection_and_not_in_same_mod_but_with_super( - ) { + fn test_extract_module_for_impl_not_having_corresponding_adt_in_selection_and_not_in_same_mod_but_with_super() + { check_assist( extract_module, r" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index d4f2ea3bd941b..7fba75f9e56d4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -3,25 +3,26 @@ use std::iter; use either::Either; use hir::{HasCrate, Module, ModuleDef, Name, Variant}; use ide_db::{ + FxHashSet, RootDatabase, defs::Definition, helpers::mod_path_to_ast, - imports::insert_use::{insert_use, ImportScope, InsertUseConfig}, + imports::insert_use::{ImportScope, InsertUseConfig, insert_use}, path_transform::PathTransform, search::FileReference, - FxHashSet, RootDatabase, }; use itertools::Itertools; use syntax::{ - ast::{ - self, edit::IndentLevel, edit_in_place::Indent, make, AstNode, HasAttrs, HasGenericParams, - HasName, HasVisibility, - }, - match_ast, ted, Edition, SyntaxElement, + Edition, SyntaxElement, SyntaxKind::*, SyntaxNode, T, + ast::{ + self, AstNode, HasAttrs, HasGenericParams, HasName, HasVisibility, edit::IndentLevel, + edit_in_place::Indent, make, + }, + match_ast, ted, }; -use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, assist_context::SourceChangeBuilder}; // Assist: extract_struct_from_enum_variant // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs index 67b8f5e505031..e6fb4d40d46b5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs @@ -1,7 +1,7 @@ use either::Either; use ide_db::syntax_helpers::node_ext::walk_ty; use syntax::{ - ast::{self, edit::IndentLevel, make, AstNode, HasGenericArgs, HasGenericParams, HasName}, + ast::{self, AstNode, HasGenericArgs, HasGenericParams, HasName, edit::IndentLevel, make}, syntax_editor, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 7b6f76d00452e..2e58e62ab0ccc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -1,19 +1,19 @@ use hir::{HirDisplay, TypeInfo}; use ide_db::{ assists::GroupLabel, - syntax_helpers::{suggest_name, LexedStr}, + syntax_helpers::{LexedStr, suggest_name}, }; use syntax::{ + NodeOrToken, SyntaxKind, SyntaxNode, T, algo::ancestors_at_offset, ast::{ - self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory, - AstNode, + self, AstNode, edit::IndentLevel, edit_in_place::Indent, make, + syntax_factory::SyntaxFactory, }, syntax_editor::Position, - NodeOrToken, SyntaxKind, SyntaxNode, T, }; -use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::is_body_const}; // Assist: extract_variable // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs index 47e4a68293f0c..51dbce2973179 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs @@ -1,10 +1,10 @@ use hir::{ - db::HirDatabase, HasSource, HasVisibility, HirFileIdExt, ModuleDef, PathResolution, ScopeDef, + HasSource, HasVisibility, HirFileIdExt, ModuleDef, PathResolution, ScopeDef, db::HirDatabase, }; use ide_db::FileId; use syntax::{ - ast::{self, edit_in_place::HasVisibilityEdit, make, HasVisibility as _}, AstNode, TextRange, + ast::{self, HasVisibility as _, edit_in_place::HasVisibilityEdit, make}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs index 818a868fe3449..75133c3a023b8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs @@ -1,6 +1,6 @@ use syntax::{ - ast::{self, syntax_factory::SyntaxFactory, AstNode, BinExpr}, SyntaxKind, T, + ast::{self, AstNode, BinExpr, syntax_factory::SyntaxFactory}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs index dd27269b001c6..6900e94bdd23b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs @@ -1,8 +1,8 @@ use syntax::{ + AstNode, Direction, NodeOrToken, SyntaxKind, SyntaxToken, T, algo::non_trivia_sibling, ast::{self, syntax_factory::SyntaxFactory}, syntax_editor::SyntaxMapping, - AstNode, Direction, NodeOrToken, SyntaxKind, SyntaxToken, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs index d9fa03e7191b3..6ef8aa6a739e0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs @@ -1,7 +1,7 @@ use syntax::{ + Direction, T, algo::non_trivia_sibling, ast::{self, AstNode}, - Direction, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs index 3528f5e81324d..af40b09643a33 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs @@ -1,7 +1,7 @@ use syntax::{ + Direction, T, algo::non_trivia_sibling, ast::{self, AstNode}, - Direction, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs index 7f7db07152d34..2f4b6a0421bbf 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs @@ -1,14 +1,14 @@ use crate::assist_context::{AssistContext, Assists}; use hir::{HasVisibility, HirDisplay, HirFileIdExt, Module}; use ide_db::{ + FileId, assists::{AssistId, AssistKind}, base_db::Upcast, defs::{Definition, NameRefClass}, - FileId, }; use syntax::{ - ast::{self, edit::IndentLevel, NameRef}, AstNode, Direction, SyntaxKind, TextSize, + ast::{self, NameRef, edit::IndentLevel}, }; // Assist: generate_constant diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs index a6e3d49e0d1ae..c6725a013e3b6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs @@ -1,4 +1,4 @@ -use ide_db::{famous_defs::FamousDefs, RootDatabase}; +use ide_db::{RootDatabase, famous_defs::FamousDefs}; use syntax::ast::{self, AstNode, HasName}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -77,11 +77,7 @@ fn existing_default_impl( let default_trait = FamousDefs(sema, krate).core_default_Default()?; let enum_type = enum_.ty(sema.db); - if enum_type.impls_trait(sema.db, default_trait, &[]) { - Some(()) - } else { - None - } + if enum_type.impls_trait(sema.db, default_trait, &[]) { Some(()) } else { None } } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs index dc27af5cbed20..1a4349cfea91b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs @@ -1,13 +1,13 @@ use ide_db::famous_defs::FamousDefs; use stdx::format_to; use syntax::{ - ast::{self, make, HasGenericParams, HasName, Impl}, AstNode, + ast::{self, HasGenericParams, HasName, Impl, make}, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, + assist_context::{AssistContext, Assists}, }; // Assist: generate_default_from_new diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs index 220259451e860..750f160ec2d23 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs @@ -1,15 +1,15 @@ use hir::{HasCrate, HasVisibility}; -use ide_db::{path_transform::PathTransform, FxHashSet}; +use ide_db::{FxHashSet, path_transform::PathTransform}; use syntax::{ ast::{ - self, edit_in_place::Indent, make, AstNode, HasGenericParams, HasName, HasVisibility as _, + self, AstNode, HasGenericParams, HasName, HasVisibility as _, edit_in_place::Indent, make, }, ted, }; use crate::{ - utils::{convert_param_list_to_arg_list, find_struct_impl}, AssistContext, AssistId, AssistKind, Assists, GroupLabel, + utils::{convert_param_list_to_arg_list, find_struct_impl}, }; // Assist: generate_delegate_methods diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs index 55b860d0ff545..5c39214617e49 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -5,25 +5,25 @@ use crate::{ utils::convert_param_list_to_arg_list, }; use either::Either; -use hir::{db::HirDatabase, HasVisibility}; +use hir::{HasVisibility, db::HirDatabase}; use ide_db::{ + FxHashMap, FxHashSet, assists::{AssistId, GroupLabel}, path_transform::PathTransform, syntax_helpers::suggest_name, - FxHashMap, FxHashSet, }; use itertools::Itertools; use syntax::{ + AstNode, Edition, NodeOrToken, SmolStr, SyntaxKind, ToSmolStr, ast::{ - self, - edit::{self, AstNodeEdit}, - edit_in_place::AttrsOwnerEdit, - make, AssocItem, GenericArgList, GenericParamList, HasAttrs, HasGenericArgs, + self, AssocItem, GenericArgList, GenericParamList, HasAttrs, HasGenericArgs, HasGenericParams, HasName, HasTypeBounds, HasVisibility as astHasVisibility, Path, WherePred, + edit::{self, AstNodeEdit}, + edit_in_place::AttrsOwnerEdit, + make, }, ted::{self, Position}, - AstNode, Edition, NodeOrToken, SmolStr, SyntaxKind, ToSmolStr, }; // Assist: generate_delegate_trait diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index e558bb6da89bc..7bf29978128e0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs @@ -1,16 +1,16 @@ use std::fmt::Display; use hir::{ModPath, ModuleDef}; -use ide_db::{famous_defs::FamousDefs, RootDatabase}; +use ide_db::{RootDatabase, famous_defs::FamousDefs}; use syntax::{ - ast::{self, HasName}, AstNode, Edition, SyntaxNode, + ast::{self, HasName}, }; use crate::{ + AssistId, AssistKind, assist_context::{AssistContext, Assists, SourceChangeBuilder}, utils::generate_trait_impl_text, - AssistId, AssistKind, }; // Assist: generate_deref diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs index 53ba144ba9e3b..8b4dbeff7cf48 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs @@ -1,6 +1,6 @@ use syntax::{ - ast::{self, edit_in_place::AttrsOwnerEdit, make, AstNode, HasAttrs}, T, + ast::{self, AstNode, HasAttrs, edit_in_place::AttrsOwnerEdit, make}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs index 862be791d1737..df05c0d6b2f35 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs @@ -3,9 +3,10 @@ use ide_db::assists::{AssistId, AssistKind}; use itertools::Itertools; use stdx::{format_to, to_lower_snake_case}; use syntax::{ + AstNode, AstToken, Edition, algo::skip_whitespace_token, - ast::{self, edit::IndentLevel, HasDocComments, HasGenericArgs, HasName}, - match_ast, AstNode, AstToken, Edition, + ast::{self, HasDocComments, HasGenericArgs, HasName, edit::IndentLevel}, + match_ast, }; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs index b5d3ed4369708..78fdca910c7a2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs @@ -4,8 +4,8 @@ use syntax::ast::HasVisibility; use syntax::ast::{self, AstNode, HasName}; use crate::{ - utils::{add_method_to_adt, find_struct_impl}, AssistContext, AssistId, AssistKind, Assists, + utils::{add_method_to_adt, find_struct_impl}, }; // Assist: generate_enum_is_method diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs index ee643ce9a4ac3..e96be673a1b6b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs @@ -5,8 +5,8 @@ use syntax::ast::HasVisibility; use syntax::ast::{self, AstNode, HasName}; use crate::{ - utils::{add_method_to_adt, find_struct_impl}, AssistContext, AssistId, AssistKind, Assists, + utils::{add_method_to_adt, find_struct_impl}, }; // Assist: generate_enum_try_into_method diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs index bb08cb904ead7..51b6a4be019dd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs @@ -1,8 +1,9 @@ use hir::{HasSource, HirDisplay, InRealFile}; use ide_db::assists::{AssistId, AssistKind}; use syntax::{ - ast::{self, syntax_factory::SyntaxFactory, HasArgList}, - match_ast, AstNode, SyntaxNode, + AstNode, SyntaxNode, + ast::{self, HasArgList, syntax_factory::SyntaxFactory}, + match_ast, }; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs index 9d01ec00f836c..bc890ac53b88b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs @@ -1,8 +1,9 @@ use either::Either; use ide_db::assists::{AssistId, AssistKind, GroupLabel}; use syntax::{ - ast::{self, edit::IndentLevel, make, HasGenericParams, HasName}, - syntax_editor, AstNode, + AstNode, + ast::{self, HasGenericParams, HasName, edit::IndentLevel, make}, + syntax_editor, }; use crate::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs index 6091f06b96699..88226820cf274 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs @@ -1,8 +1,8 @@ -use ide_db::{famous_defs::FamousDefs, RootDatabase}; +use ide_db::{RootDatabase, famous_defs::FamousDefs}; use syntax::ast::{self, AstNode, HasName}; use crate::{ - utils::generate_trait_impl_text_intransitive, AssistContext, AssistId, AssistKind, Assists, + AssistContext, AssistId, AssistKind, Assists, utils::generate_trait_impl_text_intransitive, }; // Assist: generate_from_impl_for_enum @@ -92,11 +92,7 @@ fn existing_from_impl( let wrapped_type = variant.fields(sema.db).first()?.ty(sema.db); - if enum_type.impls_trait(sema.db, from_trait, &[wrapped_type]) { - Some(()) - } else { - None - } + if enum_type.impls_trait(sema.db, from_trait, &[wrapped_type]) { Some(()) } else { None } } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 29bd8cf0d1a65..a74d477ec8950 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -4,26 +4,27 @@ use hir::{ }; use ide_db::base_db::salsa::AsDynDatabase; use ide_db::{ + FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::is_editable_crate, path_transform::PathTransform, source_change::SourceChangeBuilder, - FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap, }; use itertools::Itertools; use stdx::to_lower_snake_case; use syntax::{ + Edition, SyntaxKind, SyntaxNode, T, TextRange, ast::{ - self, edit::IndentLevel, edit_in_place::Indent, make, AstNode, BlockExpr, CallExpr, - HasArgList, HasGenericParams, HasModuleItem, HasTypeBounds, + self, AstNode, BlockExpr, CallExpr, HasArgList, HasGenericParams, HasModuleItem, + HasTypeBounds, edit::IndentLevel, edit_in_place::Indent, make, }, - ted, Edition, SyntaxKind, SyntaxNode, TextRange, T, + ted, }; use crate::{ - utils::{convert_reference_type, find_struct_impl}, AssistContext, AssistId, AssistKind, Assists, + utils::{convert_reference_type, find_struct_impl}, }; // Assist: generate_function @@ -179,9 +180,8 @@ fn add_func_to_accumulator( let edition = function_builder.target_edition; let func = function_builder.render(ctx.config.snippet_cap, edit); - if let Some(adt) = - adt_info - .and_then(|adt_info| if adt_info.impl_exists { None } else { Some(adt_info.adt) }) + if let Some(adt) = adt_info + .and_then(|adt_info| if adt_info.impl_exists { None } else { Some(adt_info.adt) }) { let name = make::ty_path(make::ext::ident_path(&format!( "{}", diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs index 1b16ba5fc8ff3..8183a11e1ba0c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs @@ -1,13 +1,14 @@ use ide_db::{famous_defs::FamousDefs, source_change::SourceChangeBuilder}; use stdx::{format_to, to_lower_snake_case}; use syntax::{ - ast::{self, edit_in_place::Indent, make, AstNode, HasName, HasVisibility}, - ted, TextRange, + TextRange, + ast::{self, AstNode, HasName, HasVisibility, edit_in_place::Indent, make}, + ted, }; use crate::{ - utils::{convert_reference_type, find_struct_impl, generate_impl}, AssistContext, AssistId, AssistKind, Assists, GroupLabel, + utils::{convert_reference_type, find_struct_impl, generate_impl}, }; // Assist: generate_setter diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs index 4439830947ade..ff4f388e39cb0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs @@ -1,9 +1,9 @@ use syntax::{ - ast::{self, edit_in_place::Indent, make, AstNode, HasName}, + ast::{self, AstNode, HasName, edit_in_place::Indent, make}, ted, }; -use crate::{utils, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils}; fn insert_impl(impl_: ast::Impl, nominal: &ast::Adt) { let indent = nominal.indent_level(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs index ad422b25c39e0..d9ed8111c6f8d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs @@ -1,12 +1,12 @@ -use hir::{sym, HasSource, Name}; +use hir::{HasSource, Name, sym}; use syntax::{ - ast::{self, HasName}, AstNode, + ast::{self, HasName}, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: generate_is_empty_from_len diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs index 6aa561ad7f037..8d107e412896e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs @@ -1,7 +1,8 @@ use ide_db::famous_defs::FamousDefs; use syntax::{ + AstNode, ast::{self, make}, - ted, AstNode, + ted, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs index 70d14d6b95d85..f14a4c1070751 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs @@ -2,13 +2,13 @@ use ide_db::{ imports::import_assets::item_for_path_search, use_trivial_constructor::use_trivial_constructor, }; use syntax::{ - ast::{self, edit_in_place::Indent, make, AstNode, HasName, HasVisibility, StructKind}, + ast::{self, AstNode, HasName, HasVisibility, StructKind, edit_in_place::Indent, make}, ted, }; use crate::{ - utils::{find_struct_impl, generate_impl}, AssistContext, AssistId, AssistKind, Assists, + utils::{find_struct_impl, generate_impl}, }; // Assist: generate_new diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs index 5f7350bc2812b..3470a4d660dce 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs @@ -1,13 +1,13 @@ use crate::assist_context::{AssistContext, Assists}; use ide_db::assists::AssistId; use syntax::{ + AstNode, SyntaxKind, T, ast::{ - self, + self, HasGenericParams, HasName, edit_in_place::{HasVisibilityEdit, Indent}, - make, HasGenericParams, HasName, + make, }, ted::{self, Position}, - AstNode, SyntaxKind, T, }; // NOTES : diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs index 5a791c58bfd52..b8381a8cce100 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs @@ -3,10 +3,12 @@ use std::collections::BTreeSet; use ast::make; use either::Either; use hir::{ + FileRange, PathResolution, Semantics, TypeInfo, db::{ExpandDatabase, HirDatabase}, - sym, FileRange, PathResolution, Semantics, TypeInfo, + sym, }; use ide_db::{ + EditionedFileId, RootDatabase, base_db::Crate, defs::Definition, imports::insert_use::remove_path_if_in_use_stmt, @@ -14,19 +16,19 @@ use ide_db::{ search::{FileReference, FileReferenceNode, SearchScope}, source_change::SourceChangeBuilder, syntax_helpers::{node_ext::expr_as_name_ref, prettify_macro_expansion}, - EditionedFileId, RootDatabase, }; -use itertools::{izip, Itertools}; +use itertools::{Itertools, izip}; use syntax::{ + AstNode, NodeOrToken, SyntaxKind, ast::{ - self, edit::IndentLevel, edit_in_place::Indent, HasArgList, HasGenericArgs, Pat, PathExpr, + self, HasArgList, HasGenericArgs, Pat, PathExpr, edit::IndentLevel, edit_in_place::Indent, }, - ted, AstNode, NodeOrToken, SyntaxKind, + ted, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: inline_into_callers diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs index ca5882d0313ac..10f9652cfe91e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs @@ -1,5 +1,5 @@ use hir::HasCrate; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index 36eed290dc88d..8b7aa8f4af34f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -1,17 +1,17 @@ use hir::{PathResolution, Semantics}; use ide_db::{ + EditionedFileId, RootDatabase, defs::Definition, search::{FileReference, FileReferenceNode, UsageSearchResult}, - EditionedFileId, RootDatabase, }; use syntax::{ - ast::{self, syntax_factory::SyntaxFactory, AstNode, AstToken, HasName}, SyntaxElement, TextRange, + ast::{self, AstNode, AstToken, HasName, syntax_factory::SyntaxFactory}, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: inline_local_variable diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs index 76d465b011039..936b09d5a46ca 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -10,13 +10,14 @@ use ide_db::{ }; use itertools::Itertools; use syntax::{ - ast::{self, make, HasGenericParams, HasName}, - ted, AstNode, NodeOrToken, SyntaxNode, + AstNode, NodeOrToken, SyntaxNode, + ast::{self, HasGenericParams, HasName, make}, + ted, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; use super::inline_call::split_refs_and_uses; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs index e405af5533d5e..c8ec3da180b8f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs @@ -3,7 +3,7 @@ use ide_db::{ assists::{AssistId, AssistKind}, famous_defs::FamousDefs, }; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs index 62909c586e3d4..587e76585f14a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs @@ -1,11 +1,11 @@ use ide_db::FxHashSet; use syntax::{ - ast::{self, edit_in_place::GenericParamsOwnerEdit, make, HasGenericParams}, - ted::{self, Position}, AstNode, TextRange, + ast::{self, HasGenericParams, edit_in_place::GenericParamsOwnerEdit, make}, + ted::{self, Position}, }; -use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, assist_context::SourceChangeBuilder}; static ASSIST_NAME: &str = "introduce_named_lifetime"; static ASSIST_LABEL: &str = "Introduce named lifetime"; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs index 994e4a0eddaf6..d60106cc80423 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs @@ -1,6 +1,6 @@ use ide_db::syntax_helpers::suggest_name; use itertools::Itertools; -use syntax::ast::{self, syntax_factory::SyntaxFactory, AstNode, HasGenericParams, HasName}; +use syntax::ast::{self, AstNode, HasGenericParams, HasName, syntax_factory::SyntaxFactory}; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs index ac710503d8a0d..4273a85df5a6a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs @@ -1,13 +1,13 @@ use ide_db::syntax_helpers::node_ext::is_pattern_cond; use syntax::{ - ast::{self, AstNode}, T, + ast::{self, AstNode}, }; use crate::{ + AssistId, AssistKind, assist_context::{AssistContext, Assists}, utils::invert_boolean_expression_legacy, - AssistId, AssistKind, }; // Assist: invert_if diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs index 4171230836908..aae007577c245 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs @@ -1,19 +1,20 @@ use either::Either; use ide_db::imports::{ insert_use::{ImportGranularity, InsertUseConfig}, - merge_imports::{try_merge_imports, try_merge_trees, try_normalize_use_tree, MergeBehavior}, + merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees, try_normalize_use_tree}, }; use itertools::Itertools; use syntax::{ + AstNode, SyntaxElement, SyntaxNode, algo::neighbor, ast::{self, edit_in_place::Removable}, - match_ast, ted, AstNode, SyntaxElement, SyntaxNode, + match_ast, ted, }; use crate::{ + AssistId, AssistKind, assist_context::{AssistContext, Assists}, utils::next_prev, - AssistId, AssistKind, }; use Edit::*; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs index f83de931eaba7..be73377070f3f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs @@ -2,9 +2,9 @@ use hir::Type; use ide_db::FxHashMap; use std::iter::successors; use syntax::{ + Direction, algo::neighbor, ast::{self, AstNode, HasName}, - Direction, }; use crate::{AssistContext, AssistId, AssistKind, Assists, TextRange}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs index 7a0037fa202bb..89bd62a084a3c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs @@ -1,12 +1,12 @@ use ide_db::syntax_helpers::node_ext::is_pattern_cond; use syntax::{ - ast::{self, AstNode, BinaryOp}, T, + ast::{self, AstNode, BinaryOp}, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: merge_nested_if // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs index 5101d8fa0a9e3..35571ed8341d7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs @@ -1,8 +1,8 @@ use syntax::{ ast::{ - self, + self, AstNode, HasName, HasTypeBounds, edit_in_place::{GenericParamsOwnerEdit, Removable}, - make, AstNode, HasName, HasTypeBounds, + make, }, match_ast, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs index 743ea9476150d..71b1461a6ea6c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs @@ -1,8 +1,8 @@ use hir::{AsAssocItem, AssocItemContainer, FileRange, HasCrate, HasSource}; use ide_db::{assists::AssistId, defs::Definition, search::SearchScope}; use syntax::{ - ast::{self, edit::IndentLevel, edit_in_place::Indent, AstNode}, SyntaxKind, + ast::{self, AstNode, edit::IndentLevel, edit_in_place::Indent}, }; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs index 10915f8aafb8d..0d6fc49e5fe3d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs @@ -2,7 +2,7 @@ use ide_db::{ assists::{AssistId, AssistKind}, base_db::AnchoredPathBuf, }; -use syntax::{ast, AstNode, ToSmolStr}; +use syntax::{AstNode, ToSmolStr, ast}; use crate::{ assist_context::{AssistContext, Assists}, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index a487960d8d4c5..abba3de4a1fa1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -1,6 +1,6 @@ use syntax::{ - ast::{edit::AstNodeEdit, make, AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat}, SyntaxKind::WHITESPACE, + ast::{AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs index bbf18e21948eb..5f547593b43a9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs @@ -1,13 +1,13 @@ use std::iter; use ast::edit::IndentLevel; -use hir::{sym, HasAttrs}; +use hir::{HasAttrs, sym}; use ide_db::base_db::AnchoredPathBuf; use itertools::Itertools; use stdx::format_to; use syntax::{ - ast::{self, edit::AstNodeEdit, HasName}, AstNode, SmolStr, TextRange, + ast::{self, HasName, edit::AstNodeEdit}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs index 7b38c795dc80f..a19c122ddf078 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs @@ -2,7 +2,7 @@ use ide_db::{ assists::{AssistId, AssistKind}, base_db::AnchoredPathBuf, }; -use syntax::{ast, AstNode, ToSmolStr}; +use syntax::{AstNode, ToSmolStr, ast}; use crate::{ assist_context::{AssistContext, Assists}, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/normalize_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/normalize_import.rs index 0b91eb676df01..813c2dd191dbd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/normalize_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/normalize_import.rs @@ -1,9 +1,9 @@ use ide_db::imports::merge_imports::try_normalize_import; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: normalize_import diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs index a13799f9b1317..9b81aecd7da84 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs @@ -1,4 +1,4 @@ -use syntax::{ast, ast::Radix, AstToken}; +use syntax::{AstToken, ast, ast::Radix}; use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs index 0cc771ff39791..04a19d7869c5e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs @@ -5,8 +5,9 @@ use ide_db::{ }; use stdx::to_upper_snake_case; use syntax::{ - ast::{self, make, HasName}, - ted, AstNode, + AstNode, + ast::{self, HasName, make}, + ted, }; use crate::{ diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs index f222b3eb903c4..d9e71ec763d01 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs @@ -1,11 +1,12 @@ use syntax::{ + AstNode, ast::{self, make}, - ted, AstNode, + ted, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: pull_assignment_up diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs index c3600af5a6c58..d8ade0eb8718f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs @@ -1,6 +1,6 @@ -use hir::{db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, ItemInNs, ModuleDef}; +use hir::{AsAssocItem, AssocItem, AssocItemContainer, ItemInNs, ModuleDef, db::HirDatabase}; use ide_db::assists::{AssistId, AssistKind}; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use crate::{ assist_context::{AssistContext, Assists}, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs index 2a8465f634cfb..a4f066ad364f8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs @@ -7,18 +7,17 @@ use ide_db::{ helpers::mod_path_to_ast, imports::import_assets::{ImportCandidate, LocatedImport}, }; -use syntax::ast::HasGenericArgs; use syntax::Edition; +use syntax::ast::HasGenericArgs; use syntax::{ - ast, - ast::{make, HasArgList}, - AstNode, NodeOrToken, + AstNode, NodeOrToken, ast, + ast::{HasArgList, make}, }; use crate::{ + AssistId, AssistKind, GroupLabel, assist_context::{AssistContext, Assists}, handlers::auto_import::find_importable_node, - AssistId, AssistKind, GroupLabel, }; // Assist: qualify_path diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs index 5a197f23d0e3a..21c697f538694 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; -use syntax::{ast, ast::IsString, AstToken, TextRange, TextSize}; +use syntax::{AstToken, TextRange, TextSize, ast, ast::IsString}; -use crate::{utils::required_hashes, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::required_hashes}; // Assist: make_raw_string // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs index 1f57f7d3d3765..cbc2e4f004733 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs @@ -1,7 +1,8 @@ use itertools::Itertools; use syntax::{ - ast::{self, make, AstNode, AstToken}, - match_ast, ted, Edition, NodeOrToken, SyntaxElement, TextRange, TextSize, T, + Edition, NodeOrToken, SyntaxElement, T, TextRange, TextSize, + ast::{self, AstNode, AstToken, make}, + match_ast, ted, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs index e7beb23bf8e7f..9bd8decbedcdb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -1,7 +1,7 @@ use syntax::{ + AstNode, SyntaxKind, T, ast::{self, syntax_factory::SyntaxFactory}, syntax_editor::Position, - AstNode, SyntaxKind, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs index 0570b447782ec..01c4eedd3e2d2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs @@ -3,13 +3,13 @@ use std::collections::hash_map::Entry; use hir::{FileRange, HirFileIdExt, InFile, InRealFile, Module, ModuleSource}; use ide_db::text_edit::TextRange; use ide_db::{ + FxHashMap, RootDatabase, defs::Definition, search::{FileReference, ReferenceCategory, SearchScope}, - FxHashMap, RootDatabase, }; use syntax::{ - ast::{self, Rename}, AstNode, + ast::{self, Rename}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs index 2d7722a654e8e..6ebc9007cf1cb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs @@ -1,18 +1,18 @@ use ide_db::{ - base_db::salsa::AsDynDatabase, defs::Definition, search::FileReference, EditionedFileId, + EditionedFileId, base_db::salsa::AsDynDatabase, defs::Definition, search::FileReference, }; use syntax::{ + AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, T, TextRange, algo::{find_node_at_range, least_common_ancestor_element}, ast::{self, HasArgList}, syntax_editor::Element, - AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T, }; use SyntaxKind::WHITESPACE; use crate::{ - assist_context::SourceChangeBuilder, utils::next_prev, AssistContext, AssistId, AssistKind, - Assists, + AssistContext, AssistId, AssistKind, Assists, assist_context::SourceChangeBuilder, + utils::next_prev, }; // Assist: remove_unused_param diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs index a79a82be45079..410e2bbbdffcd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs @@ -1,7 +1,7 @@ use either::Either; use ide_db::FxHashMap; use itertools::Itertools; -use syntax::{ast, syntax_editor::SyntaxEditor, AstNode, SmolStr, SyntaxElement, ToSmolStr}; +use syntax::{AstNode, SmolStr, SyntaxElement, ToSmolStr, ast, syntax_editor::SyntaxEditor}; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs index c3404173eafe6..e254fb9949d49 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs @@ -2,8 +2,8 @@ use hir::{PathResolution, Semantics}; use ide_db::{FxHashMap, RootDatabase}; use itertools::Itertools; use syntax::{ - ast::{self, HasName}, AstNode, SyntaxElement, + ast::{self, HasName}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs index 4b20b35c44624..39f350fb68d5e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs @@ -1,7 +1,7 @@ use ide_db::assists::{AssistId, AssistKind, GroupLabel}; use syntax::{ - ast::{self, ArithOp, BinaryOp}, AstNode, TextRange, + ast::{self, ArithOp, BinaryOp}, }; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 31e828eae2712..7696a14a4f592 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -2,19 +2,19 @@ use hir::{InFile, MacroFileIdExt, ModuleDef}; use ide_db::{helpers::mod_path_to_ast, imports::import_assets::NameToImport, items_locator}; use itertools::Itertools; use syntax::{ - ast::{self, make, AstNode, HasName}, - ted, SyntaxKind::WHITESPACE, T, + ast::{self, AstNode, HasName, make}, + ted, }; use crate::{ + AssistId, AssistKind, assist_context::{AssistContext, Assists, SourceChangeBuilder}, utils::{ - add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_fn_body, generate_trait_impl, - DefaultMethods, IgnoreAssocItems, + DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl, filter_assoc_items, + gen_trait_fn_body, generate_trait_impl, }, - AssistId, AssistKind, }; // Assist: replace_derive_with_manual_impl diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index e324d6eaaad2f..c3b753653c212 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -2,19 +2,19 @@ use std::iter::successors; use either::Either; use ide_db::{ + RootDatabase, defs::NameClass, syntax_helpers::node_ext::{is_pattern_cond, single_let}, ty_filter::TryEnum, - RootDatabase, }; use syntax::{ - ast::{self, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory, HasName}, - AstNode, TextRange, T, + AstNode, T, TextRange, + ast::{self, HasName, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory}, }; use crate::{ - utils::{does_pat_match_variant, does_pat_variant_nested_or_literal, unwrap_trivial_block}, AssistContext, AssistId, AssistKind, Assists, + utils::{does_pat_match_variant, does_pat_variant_nested_or_literal, unwrap_trivial_block}, }; // Assist: replace_if_let_with_match diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs index 47972ff619acb..c49f285d8e9d3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs @@ -1,6 +1,6 @@ use ide_db::syntax_helpers::suggest_name; use syntax::{ - ast::{self, make, AstNode}, + ast::{self, AstNode, make}, ted, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs index c071d3022d251..34bbd6ba5be7b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs @@ -1,7 +1,7 @@ use ide_db::ty_filter::TryEnum; use syntax::{ - ast::{self, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory}, AstNode, T, + ast::{self, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs index 12d025f07594e..88b56ebb4b1cd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs @@ -1,7 +1,7 @@ use ide_db::assists::{AssistId, AssistKind}; use syntax::{ - ast::{self, make, Expr, HasArgList}, AstNode, + ast::{self, Expr, HasArgList, make}, }; use crate::{AssistContext, Assists}; @@ -74,11 +74,7 @@ pub(crate) fn replace_with_lazy_method(acc: &mut Assists, ctx: &AssistContext<'_ fn into_closure(param: &Expr) -> Expr { (|| { if let ast::Expr::CallExpr(call) = param { - if call.arg_list()?.args().count() == 0 { - Some(call.expr()?) - } else { - None - } + if call.arg_list()?.args().count() == 0 { Some(call.expr()?) } else { None } } else { None } @@ -154,11 +150,7 @@ pub(crate) fn replace_with_eager_method(acc: &mut Assists, ctx: &AssistContext<' fn into_call(param: &Expr) -> Expr { (|| { if let ast::Expr::ClosureExpr(closure) = param { - if closure.param_list()?.params().count() == 0 { - Some(closure.body()?) - } else { - None - } + if closure.param_list()?.params().count() == 0 { Some(closure.body()?) } else { None } } else { None } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs index 26fd887cc99e9..f99394e8775e0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs @@ -1,16 +1,17 @@ use hir::{FileRange, Semantics}; use ide_db::text_edit::TextRange; use ide_db::{ + EditionedFileId, RootDatabase, defs::Definition, search::{SearchScope, UsageSearchResult}, - EditionedFileId, RootDatabase, }; use syntax::{ + AstNode, ast::{ - self, make::impl_trait_type, HasGenericParams, HasName, HasTypeBounds, Name, NameLike, - PathType, + self, HasGenericParams, HasName, HasTypeBounds, Name, NameLike, PathType, + make::impl_trait_type, }, - match_ast, ted, AstNode, + match_ast, ted, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index f026b3230dd6d..08a4d28e9fea9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs @@ -1,11 +1,12 @@ use hir::AsAssocItem; use ide_db::{ helpers::mod_path_to_ast, - imports::insert_use::{insert_use, ImportScope}, + imports::insert_use::{ImportScope, insert_use}, }; use syntax::{ - ast::{self, make, HasGenericArgs}, - match_ast, ted, AstNode, Edition, SyntaxNode, + AstNode, Edition, SyntaxNode, + ast::{self, HasGenericArgs, make}, + match_ast, ted, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_string_with_char.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_string_with_char.rs index a48b20acbcac8..176b4e4af088d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_string_with_char.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_string_with_char.rs @@ -1,9 +1,8 @@ use syntax::{ - ast, - ast::IsString, AstToken, SyntaxKind::{CHAR, STRING}, - TextRange, TextSize, + TextRange, TextSize, ast, + ast::IsString, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs index 88b50543dda87..93dfe48ebcab8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs @@ -5,12 +5,12 @@ use ide_db::{ ty_filter::TryEnum, }; use syntax::{ + AstNode, T, ast::{ self, edit::{AstNodeEdit, IndentLevel}, make, }, - AstNode, T, }; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs index 3a6391cd38006..39ebca25a90f6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs @@ -1,12 +1,12 @@ use hir::HirDisplay; use syntax::{ - ast::{Expr, GenericArg, GenericArgList, HasGenericArgs, LetStmt, Type::InferType}, AstNode, TextRange, + ast::{Expr, GenericArg, GenericArgList, HasGenericArgs, LetStmt, Type::InferType}, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: replace_turbofish_with_explicit_type diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs index 54e16d4d80a4c..73dfbf023792c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs @@ -3,11 +3,11 @@ use std::cmp::Ordering; use itertools::Itertools; use syntax::{ - ast::{self, HasName}, AstNode, SyntaxNode, + ast::{self, HasName}, }; -use crate::{utils::get_methods, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::get_methods}; // Assist: sort_items // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/split_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/split_import.rs index 775ededecbcc8..63371ddf9fbc5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/split_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/split_import.rs @@ -1,4 +1,4 @@ -use syntax::{ast, AstNode, T}; +use syntax::{AstNode, T, ast}; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs index e10897b3bef75..7b2598b45575d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs @@ -6,7 +6,7 @@ use ide_db::{ }; use itertools::Itertools; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use crate::assist_context::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs index 8f937a04122d6..9f45b2898a769 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs @@ -4,8 +4,8 @@ use ide_db::{ famous_defs::FamousDefs, }; use syntax::{ - ast::{self, HasGenericArgs, HasVisibility}, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, + ast::{self, HasGenericArgs, HasVisibility}, }; use crate::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs index 264a2f0326ecf..c1ea7dc4c78c5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs @@ -1,9 +1,9 @@ use syntax::{ - ast::{self, HasAttrs}, AstNode, AstToken, + ast::{self, HasAttrs}, }; -use crate::{utils::test_related_attribute_syn, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::test_related_attribute_syn}; // Assist: toggle_ignore // diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs index e452b5f77870c..80834abecc95a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs @@ -1,7 +1,8 @@ use ide_db::assists::{AssistId, AssistKind}; use syntax::{ + AstNode, T, ast::{self, make}, - ted, AstNode, T, + ted, }; use crate::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs index 6b9f661d4de54..8b6aef02eccd0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs @@ -1,8 +1,8 @@ use syntax::{ + Direction, SyntaxKind, T, algo::neighbor, - ast::{self, edit::IndentLevel, make, AstNode}, + ast::{self, AstNode, edit::IndentLevel, make}, ted::{self, Position}, - Direction, SyntaxKind, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs index 38ca572fa6609..7f2dd19ce0755 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs @@ -1,12 +1,12 @@ use syntax::{ - ast::{self, edit_in_place::Removable, make, HasVisibility}, - ted::{self, Position}, AstNode, SyntaxKind, + ast::{self, HasVisibility, edit_in_place::Removable, make}, + ted::{self, Position}, }; use crate::{ - assist_context::{AssistContext, Assists}, AssistId, AssistKind, + assist_context::{AssistContext, Assists}, }; // Assist: unmerge_use diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs index abe7fb132f0b3..f3ae70160bf3a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs @@ -1,13 +1,13 @@ use ide_db::{ + EditionedFileId, assists::{AssistId, AssistKind}, defs::Definition, search::{FileReference, FileReferenceNode}, syntax_helpers::node_ext::full_path_of_name_ref, - EditionedFileId, }; use syntax::{ - ast::{self, NameRef}, AstNode, SyntaxKind, TextRange, + ast::{self, NameRef}, }; use crate::{AssistContext, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs index baf4ddae2fbc9..712c8c3d14d0f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs @@ -1,7 +1,7 @@ use ide_db::imports::insert_use::ImportScope; use syntax::{ - ast::{self, prec::ExprPrecedence, AstNode, HasArgList}, TextRange, + ast::{self, AstNode, HasArgList, prec::ExprPrecedence}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs index fd37140e9c2bf..80d8cebff5bb3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs @@ -1,10 +1,10 @@ use syntax::{ + AstNode, SyntaxKind, T, TextRange, ast::{ self, edit::{AstNodeEdit, IndentLevel}, make, }, - AstNode, SyntaxKind, TextRange, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs index f647b531b7742..f6eb68524f2df 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs @@ -4,8 +4,9 @@ use ide_db::{ syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - ast::{self, syntax_factory::SyntaxFactory, HasArgList, HasGenericArgs}, - match_ast, AstNode, NodeOrToken, SyntaxKind, + AstNode, NodeOrToken, SyntaxKind, + ast::{self, HasArgList, HasGenericArgs, syntax_factory::SyntaxFactory}, + match_ast, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs index d09614c51127e..55053ac97dc6e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs @@ -1,6 +1,6 @@ use syntax::{ - ast::{self, edit::AstNodeEdit}, AstNode, T, + ast::{self, edit::AstNodeEdit}, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs index 0b145dcb06ba3..8857c446f6d53 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs @@ -7,8 +7,9 @@ use ide_db::{ syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - ast::{self, syntax_factory::SyntaxFactory, Expr, HasGenericArgs, HasGenericParams}, - match_ast, AstNode, + AstNode, + ast::{self, Expr, HasGenericArgs, HasGenericParams, syntax_factory::SyntaxFactory}, + match_ast, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 149cb4c43849d..717c68d04e05b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs @@ -1,10 +1,9 @@ use ide_db::source_change::SourceChangeBuilder; use itertools::Itertools; use syntax::{ - algo, - ast::{self, make, AstNode}, + NodeOrToken, SyntaxToken, T, TextRange, algo, + ast::{self, AstNode, make}, ted::{self, Position}, - NodeOrToken, SyntaxToken, TextRange, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -296,11 +295,7 @@ fn unwrap_cfg_attr(acc: &mut Assists, attr: ast::Attr) -> Option<()> { continue; } let Some(attr_name) = tt.into_token().and_then(|token| { - if token.kind() == T![ident] { - Some(make::ext::ident_path(token.text())) - } else { - None - } + if token.kind() == T![ident] { Some(make::ext::ident_path(token.text())) } else { None } }) else { continue; }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 4f751b68e7f0b..a23461e69a5fc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -3,10 +3,10 @@ mod generated; use expect_test::expect; use hir::{FileRange, Semantics}; use ide_db::{ + EditionedFileId, RootDatabase, SnippetCap, base_db::SourceDatabase, imports::insert_use::{ImportGranularity, InsertUseConfig}, source_change::FileSystemEdit, - EditionedFileId, RootDatabase, SnippetCap, }; use stdx::{format_to, trim_indent}; use syntax::TextRange; @@ -14,8 +14,8 @@ use test_fixture::WithFixture; use test_utils::{assert_eq_text, extract_offset}; use crate::{ - assists, handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, - AssistResolveStrategy, Assists, SingleResolve, + Assist, AssistConfig, AssistContext, AssistKind, AssistResolveStrategy, Assists, SingleResolve, + assists, handlers::Handler, }; pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index a6fa1706710d1..0806d5feb13b2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -2,29 +2,29 @@ pub(crate) use gen_trait_fn_body::gen_trait_fn_body; use hir::{ - db::{ExpandDatabase, HirDatabase}, DisplayTarget, HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, Semantics, + db::{ExpandDatabase, HirDatabase}, }; use ide_db::{ + RootDatabase, famous_defs::FamousDefs, path_transform::PathTransform, syntax_helpers::{node_ext::preorder_expr, prettify_macro_expansion}, - RootDatabase, }; use stdx::format_to; use syntax::{ + AstNode, AstToken, Direction, NodeOrToken, SourceFile, + SyntaxKind::*, + SyntaxNode, SyntaxToken, T, TextRange, TextSize, WalkEvent, ast::{ - self, + self, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, edit::{AstNodeEdit, IndentLevel}, edit_in_place::{AttrsOwnerEdit, Indent, Removable}, make, syntax_factory::SyntaxFactory, - HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, - ted, AstNode, AstToken, Direction, NodeOrToken, SourceFile, - SyntaxKind::*, - SyntaxNode, SyntaxToken, TextRange, TextSize, WalkEvent, T, + ted, }; use crate::assist_context::{AssistContext, SourceChangeBuilder}; @@ -82,11 +82,7 @@ pub fn test_related_attribute_syn(fn_def: &ast::Fn) -> Option { fn_def.attrs().find_map(|attr| { let path = attr.path()?; let text = path.syntax().text().to_string(); - if text.starts_with("test") || text.ends_with("test") { - Some(attr) - } else { - None - } + if text.starts_with("test") || text.ends_with("test") { Some(attr) } else { None } }) } @@ -498,11 +494,7 @@ pub(crate) fn find_struct_impl( }; let not_trait_impl = blk.trait_(db).is_none(); - if !(same_ty && not_trait_impl) { - None - } else { - Some(impl_blk) - } + if !(same_ty && not_trait_impl) { None } else { Some(impl_blk) } }); if let Some(ref impl_blk) = block { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs index 7a9bdfe1ecc24..5c2e27b3430f4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs @@ -2,7 +2,7 @@ use hir::TraitRef; use syntax::{ - ast::{self, edit::AstNodeEdit, make, AstNode, BinaryOp, CmpOp, HasName, LogicOp}, + ast::{self, AstNode, BinaryOp, CmpOp, HasName, LogicOp, edit::AstNodeEdit, make}, ted, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs index d434872ea595e..28830cf2f92b3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs @@ -4,8 +4,8 @@ //! It determines whether to deref the new expression and/or wrap it in parentheses, //! based on the parent of the existing expression. use syntax::{ - ast::{self, make, FieldExpr, MethodCallExpr}, AstNode, T, + ast::{self, FieldExpr, MethodCallExpr, make}, }; use crate::AssistContext; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index a22e7b272ea05..c8cdad594978d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -24,17 +24,19 @@ pub(crate) mod vis; use std::iter; -use hir::{sym, HasAttrs, Name, ScopeDef, Variant}; -use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind}; -use syntax::{ast, SmolStr, ToSmolStr}; +use hir::{HasAttrs, Name, ScopeDef, Variant, sym}; +use ide_db::{RootDatabase, SymbolKind, imports::import_assets::LocatedImport}; +use syntax::{SmolStr, ToSmolStr, ast}; use crate::{ + CompletionContext, CompletionItem, CompletionItemKind, context::{ DotAccess, ItemListKind, NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PatternContext, TypeLocation, Visible, }, item::Builder, render::{ + RenderContext, const_::render_const, function::{render_fn, render_method}, literal::{render_struct_literal, render_variant_lit}, @@ -44,9 +46,7 @@ use crate::{ render_tuple_field, type_alias::{render_type_alias, render_type_alias_with_eq}, union_literal::render_union_literal, - RenderContext, }, - CompletionContext, CompletionItem, CompletionItemKind, }; /// Represents an in-progress set of completions being built. diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs index cf5427bae38de..fb7df8cc7f448 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs @@ -5,22 +5,22 @@ use std::sync::LazyLock; use ide_db::{ + FxHashMap, SymbolKind, generated::lints::{ - Lint, CLIPPY_LINTS, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, FEATURES, RUSTDOC_LINTS, + CLIPPY_LINT_GROUPS, CLIPPY_LINTS, DEFAULT_LINTS, FEATURES, Lint, RUSTDOC_LINTS, }, syntax_helpers::node_ext::parse_tt_as_comma_sep_paths, - FxHashMap, SymbolKind, }; use itertools::Itertools; use syntax::{ - ast::{self, AttrKind}, AstNode, Edition, SyntaxKind, T, + ast::{self, AttrKind}, }; use crate::{ + Completions, context::{AttrCtx, CompletionContext, PathCompletionCtx, Qualified}, item::CompletionItem, - Completions, }; mod cfg; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs index cda0da13b26eb..1676a8467c85f 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs @@ -2,9 +2,9 @@ use ide_db::SymbolKind; use itertools::Itertools; -use syntax::{algo, ast::Ident, AstToken, Direction, NodeOrToken, SyntaxKind}; +use syntax::{AstToken, Direction, NodeOrToken, SyntaxKind, algo, ast::Ident}; -use crate::{completions::Completions, context::CompletionContext, CompletionItem}; +use crate::{CompletionItem, completions::Completions, context::CompletionContext}; pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { let add_completion = |item: &str| { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs index 1f8927401b2f8..2fc07e0138280 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs @@ -1,13 +1,13 @@ //! Completion for derives use hir::ScopeDef; -use ide_db::{documentation::HasDocs, SymbolKind}; +use ide_db::{SymbolKind, documentation::HasDocs}; use itertools::Itertools; use syntax::{SmolStr, ToSmolStr}; use crate::{ + Completions, context::{CompletionContext, ExistingDerives, PathCompletionCtx, Qualified}, item::CompletionItem, - Completions, }; pub(crate) fn complete_derive_path( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs index 04f40e805ad68..c87c46d98127b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs @@ -1,8 +1,8 @@ //! Completion for lints -use ide_db::{documentation::Documentation, generated::lints::Lint, SymbolKind}; +use ide_db::{SymbolKind, documentation::Documentation, generated::lints::Lint}; use syntax::ast; -use crate::{context::CompletionContext, item::CompletionItem, Completions}; +use crate::{Completions, context::CompletionContext, item::CompletionItem}; pub(super) fn complete_lint( acc: &mut Completions, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs index deb12282c025b..0641a4f6c3fe5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs @@ -3,7 +3,7 @@ use hir::ModuleDef; use ide_db::SymbolKind; use syntax::ast; -use crate::{context::CompletionContext, item::CompletionItem, Completions}; +use crate::{Completions, context::CompletionContext, item::CompletionItem}; pub(super) fn complete_macro_use( acc: &mut Completions, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/repr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/repr.rs index 12652b448925b..cb7ccf7373123 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/repr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/repr.rs @@ -3,7 +3,7 @@ use ide_db::SymbolKind; use syntax::ast; -use crate::{context::CompletionContext, item::CompletionItem, Completions}; +use crate::{Completions, context::CompletionContext, item::CompletionItem}; pub(super) fn complete_repr( acc: &mut Completions, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs index b38b9ac1f5391..dea983b6ea812 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs @@ -7,11 +7,11 @@ use ide_db::FxHashSet; use syntax::SmolStr; use crate::{ + CompletionItem, CompletionItemKind, Completions, context::{ CompletionContext, DotAccess, DotAccessExprCtx, DotAccessKind, PathCompletionCtx, PathExprCtx, Qualified, }, - CompletionItem, CompletionItemKind, Completions, }; /// Complete dot accesses, i.e. fields or methods. diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/env_vars.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/env_vars.rs index 40af5203e9c32..ab8d8a6169c94 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/env_vars.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/env_vars.rs @@ -3,34 +3,46 @@ use hir::MacroFileIdExt; use ide_db::syntax_helpers::node_ext::macro_call_for_string_token; use syntax::{ - ast::{self, IsString}, AstToken, + ast::{self, IsString}, }; use crate::{ - completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind, + CompletionItem, CompletionItemKind, completions::Completions, context::CompletionContext, }; const CARGO_DEFINED_VARS: &[(&str, &str)] = &[ - ("CARGO","Path to the cargo binary performing the build"), - ("CARGO_MANIFEST_DIR","The directory containing the manifest of your package"), - ("CARGO_PKG_VERSION","The full version of your package"), - ("CARGO_PKG_VERSION_MAJOR","The major version of your package"), - ("CARGO_PKG_VERSION_MINOR","The minor version of your package"), - ("CARGO_PKG_VERSION_PATCH","The patch version of your package"), - ("CARGO_PKG_VERSION_PRE","The pre-release version of your package"), - ("CARGO_PKG_AUTHORS","Colon separated list of authors from the manifest of your package"), - ("CARGO_PKG_NAME","The name of your package"), - ("CARGO_PKG_DESCRIPTION","The description from the manifest of your package"), - ("CARGO_PKG_HOMEPAGE","The home page from the manifest of your package"), - ("CARGO_PKG_REPOSITORY","The repository from the manifest of your package"), - ("CARGO_PKG_LICENSE","The license from the manifest of your package"), - ("CARGO_PKG_LICENSE_FILE","The license file from the manifest of your package"), - ("CARGO_PKG_RUST_VERSION","The Rust version from the manifest of your package. Note that this is the minimum Rust version supported by the package, not the current Rust version"), - ("CARGO_CRATE_NAME","The name of the crate that is currently being compiled"), - ("CARGO_BIN_NAME","The name of the binary that is currently being compiled (if it is a binary). This name does not include any file extension, such as .exe"), - ("CARGO_PRIMARY_PACKAGE","This environment variable will be set if the package being built is primary. Primary packages are the ones the user selected on the command-line, either with -p flags or the defaults based on the current directory and the default workspace members. This environment variable will not be set when building dependencies. This is only set when compiling the package (not when running binaries or tests)"), - ("CARGO_TARGET_TMPDIR","Only set when building integration test or benchmark code. This is a path to a directory inside the target directory where integration tests or benchmarks are free to put any data needed by the tests/benches. Cargo initially creates this directory but doesn't manage its content in any way, this is the responsibility of the test code") + ("CARGO", "Path to the cargo binary performing the build"), + ("CARGO_MANIFEST_DIR", "The directory containing the manifest of your package"), + ("CARGO_PKG_VERSION", "The full version of your package"), + ("CARGO_PKG_VERSION_MAJOR", "The major version of your package"), + ("CARGO_PKG_VERSION_MINOR", "The minor version of your package"), + ("CARGO_PKG_VERSION_PATCH", "The patch version of your package"), + ("CARGO_PKG_VERSION_PRE", "The pre-release version of your package"), + ("CARGO_PKG_AUTHORS", "Colon separated list of authors from the manifest of your package"), + ("CARGO_PKG_NAME", "The name of your package"), + ("CARGO_PKG_DESCRIPTION", "The description from the manifest of your package"), + ("CARGO_PKG_HOMEPAGE", "The home page from the manifest of your package"), + ("CARGO_PKG_REPOSITORY", "The repository from the manifest of your package"), + ("CARGO_PKG_LICENSE", "The license from the manifest of your package"), + ("CARGO_PKG_LICENSE_FILE", "The license file from the manifest of your package"), + ( + "CARGO_PKG_RUST_VERSION", + "The Rust version from the manifest of your package. Note that this is the minimum Rust version supported by the package, not the current Rust version", + ), + ("CARGO_CRATE_NAME", "The name of the crate that is currently being compiled"), + ( + "CARGO_BIN_NAME", + "The name of the binary that is currently being compiled (if it is a binary). This name does not include any file extension, such as .exe", + ), + ( + "CARGO_PRIMARY_PACKAGE", + "This environment variable will be set if the package being built is primary. Primary packages are the ones the user selected on the command-line, either with -p flags or the defaults based on the current directory and the default workspace members. This environment variable will not be set when building dependencies. This is only set when compiling the package (not when running binaries or tests)", + ), + ( + "CARGO_TARGET_TMPDIR", + "Only set when building integration test or benchmark code. This is a path to a directory inside the target directory where integration tests or benchmarks are free to put any data needed by the tests/benches. Cargo initially creates this directory but doesn't manage its content in any way, this is the responsibility of the test code", + ), ]; pub(crate) fn complete_cargo_env_vars( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index b28b6e50e2284..eb26543a4bd39 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -2,14 +2,14 @@ use std::ops::ControlFlow; -use hir::{sym, Name, PathCandidateCallback, ScopeDef}; +use hir::{Name, PathCandidateCallback, ScopeDef, sym}; use ide_db::FxHashSet; use syntax::ast; use crate::{ + CompletionContext, Completions, completions::record::add_default_update, context::{BreakableKind, PathCompletionCtx, PathExprCtx, Qualified}, - CompletionContext, Completions, }; struct PathCallback<'a, F> { @@ -79,11 +79,7 @@ pub(crate) fn complete_expr_path( let wants_const_token = ref_expr_parent.is_some() && has_raw_token && !has_const_token && !has_mut_token; let wants_mut_token = if ref_expr_parent.is_some() { - if has_raw_token { - !has_const_token && !has_mut_token - } else { - !has_mut_token - } + if has_raw_token { !has_const_token && !has_mut_token } else { !has_mut_token } } else { false }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs index 7c2cc2a6c1d8f..570d1a0a2db8a 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs @@ -1,11 +1,11 @@ //! Completes function abi strings. use syntax::{ - ast::{self, IsString}, AstNode, AstToken, SmolStr, + ast::{self, IsString}, }; use crate::{ - completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind, + CompletionItem, CompletionItemKind, completions::Completions, context::CompletionContext, }; // Most of these are feature gated, we should filter/add feature gate completions once we have them. diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs index 7cb710c2d963c..71a3e4eb4ed6d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs @@ -1,10 +1,10 @@ //! Completion for extern crates use hir::Name; -use ide_db::{documentation::HasDocs, SymbolKind}; +use ide_db::{SymbolKind, documentation::HasDocs}; use syntax::ToSmolStr; -use crate::{context::CompletionContext, CompletionItem, CompletionItemKind}; +use crate::{CompletionItem, CompletionItemKind, context::CompletionContext}; use super::Completions; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/field.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/field.rs index b795bbd872a0a..1441b0e3a01ae 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/field.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/field.rs @@ -1,8 +1,8 @@ //! Completion of field list position. use crate::{ - context::{PathCompletionCtx, Qualified}, CompletionContext, Completions, + context::{PathCompletionCtx, Qualified}, }; pub(crate) fn complete_field_list_tuple_variant( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs index b5555e6610240..b3ba076489307 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs @@ -5,16 +5,16 @@ use ide_db::imports::{ insert_use::ImportScope, }; use itertools::Itertools; -use syntax::{ast, AstNode, SyntaxNode}; +use syntax::{AstNode, SyntaxNode, ast}; use crate::{ + Completions, config::AutoImportExclusionType, context::{ CompletionContext, DotAccess, PathCompletionCtx, PathKind, PatternContext, Qualified, TypeLocation, }, - render::{render_resolution_with_import, render_resolution_with_import_pat, RenderContext}, - Completions, + render::{RenderContext, render_resolution_with_import, render_resolution_with_import_pat}, }; // Feature: Completion With Autoimport @@ -404,11 +404,7 @@ fn import_on_the_fly_method( fn import_name(ctx: &CompletionContext<'_>) -> String { let token_kind = ctx.token.kind(); - if token_kind.is_any_identifier() { - ctx.token.to_string() - } else { - String::new() - } + if token_kind.is_any_identifier() { ctx.token.to_string() } else { String::new() } } fn import_assets_for_path( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs index e86eaad4d0f24..6d1e973dc4c5c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs @@ -3,14 +3,14 @@ use hir::HirDisplay; use ide_db::FxHashMap; use syntax::{ - algo, + AstNode, Direction, SyntaxKind, TextRange, TextSize, algo, ast::{self, HasModuleItem}, - match_ast, AstNode, Direction, SyntaxKind, TextRange, TextSize, + match_ast, }; use crate::{ - context::{ParamContext, ParamKind, PatternContext}, CompletionContext, CompletionItem, CompletionItemKind, Completions, + context::{ParamContext, ParamKind, PatternContext}, }; // FIXME: Make this a submodule of [`pattern`] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs index dcd40c3412c70..5ae65b05bc42e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs @@ -1,11 +1,11 @@ //! Completes identifiers in format string literals. use hir::{ModuleDef, ScopeDef}; -use ide_db::{syntax_helpers::format_string::is_format_string, SymbolKind}; +use ide_db::{SymbolKind, syntax_helpers::format_string::is_format_string}; use itertools::Itertools; -use syntax::{ast, AstToken, TextRange, TextSize, ToSmolStr}; +use syntax::{AstToken, TextRange, TextSize, ToSmolStr, ast}; -use crate::{context::CompletionContext, CompletionItem, CompletionItemKind, Completions}; +use crate::{CompletionItem, CompletionItemKind, Completions, context::CompletionContext}; /// Complete identifiers in format strings. pub(crate) fn format_string( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs index 3ab341e4eded4..4ae00ccd81bc6 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs @@ -1,8 +1,8 @@ //! Completion of paths and keywords at item list position. use crate::{ - context::{ItemListKind, PathCompletionCtx, PathExprCtx, Qualified}, CompletionContext, Completions, + context::{ItemListKind, PathCompletionCtx, PathExprCtx, Qualified}, }; pub(crate) mod trait_impl; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs index 831f5665f4aa0..e08271f39a325 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -31,20 +31,21 @@ //! } //! ``` -use hir::{db::ExpandDatabase, MacroFileId, Name}; +use hir::{MacroFileId, Name, db::ExpandDatabase}; use ide_db::text_edit::TextEdit; use ide_db::{ - documentation::HasDocs, path_transform::PathTransform, - syntax_helpers::prettify_macro_expansion, traits::get_missing_assoc_items, SymbolKind, + SymbolKind, documentation::HasDocs, path_transform::PathTransform, + syntax_helpers::prettify_macro_expansion, traits::get_missing_assoc_items, }; use syntax::{ - ast::{self, edit_in_place::AttrsOwnerEdit, make, HasGenericArgs, HasTypeBounds}, - format_smolstr, ted, AstNode, SmolStr, SyntaxElement, SyntaxKind, TextRange, ToSmolStr, T, + AstNode, SmolStr, SyntaxElement, SyntaxKind, T, TextRange, ToSmolStr, + ast::{self, HasGenericArgs, HasTypeBounds, edit_in_place::AttrsOwnerEdit, make}, + format_smolstr, ted, }; use crate::{ - context::PathCompletionCtx, CompletionContext, CompletionItem, CompletionItemKind, - CompletionRelevance, Completions, + CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, Completions, + context::PathCompletionCtx, }; #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs index 53a62fe49c5aa..9bb2bea74b7d4 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs @@ -7,7 +7,7 @@ //! there is no value in lifting these out into the outline module test since they will either not //! show up for normal completions, or they won't show completions other than lifetimes depending //! on the fixture input. -use hir::{sym, Name, ScopeDef}; +use hir::{Name, ScopeDef, sym}; use crate::{ completions::Completions, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs index fad7c92d8aecb..dc81e49c531f3 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs @@ -4,12 +4,12 @@ use std::iter; use hir::{HirFileIdExt, Module}; use ide_db::{ - base_db::{SourceDatabase, VfsPath}, FxHashSet, RootDatabase, SymbolKind, + base_db::{SourceDatabase, VfsPath}, }; -use syntax::{ast, AstNode, SyntaxKind}; +use syntax::{AstNode, SyntaxKind, ast}; -use crate::{context::CompletionContext, CompletionItem, Completions}; +use crate::{CompletionItem, Completions, context::CompletionContext}; /// Complete mod declaration, i.e. `mod $0;` pub(crate) fn complete_mod( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs index 9df13c5a4ef53..59ef94d83b30e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs @@ -5,8 +5,8 @@ use ide_db::syntax_helpers::suggest_name; use syntax::ast::Pat; use crate::{ - context::{PathCompletionCtx, PatternContext, PatternRefutability, Qualified}, CompletionContext, Completions, + context::{PathCompletionCtx, PatternContext, PatternRefutability, Qualified}, }; /// Completes constants and paths in unqualified patterns. diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs index 611f8a2873d7b..eb84debcafb35 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs @@ -5,24 +5,24 @@ mod format_like; use base_db::SourceDatabase; use hir::{ItemInNs, Semantics}; use ide_db::{ + RootDatabase, SnippetCap, documentation::{Documentation, HasDocs}, imports::insert_use::ImportScope, text_edit::TextEdit, ty_filter::TryEnum, - RootDatabase, SnippetCap, }; use stdx::never; use syntax::{ - ast::{self, AstNode, AstToken}, SyntaxKind::{BLOCK_EXPR, EXPR_STMT, FOR_EXPR, IF_EXPR, LOOP_EXPR, STMT_LIST, WHILE_EXPR}, TextRange, TextSize, + ast::{self, AstNode, AstToken}, }; use crate::{ + CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope, completions::postfix::format_like::add_format_like_completions, context::{BreakableKind, CompletionContext, DotAccess, DotAccessKind}, item::{Builder, CompletionRelevancePostfixMatch}, - CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope, }; pub(crate) fn complete_postfix( @@ -414,8 +414,8 @@ mod tests { use expect_test::expect; use crate::{ - tests::{check, check_edit, check_edit_with_config, TEST_CONFIG}, CompletionConfig, Snippet, + tests::{TEST_CONFIG, check, check_edit, check_edit_with_config}, }; #[test] @@ -697,15 +697,17 @@ fn main() { #[test] fn custom_postfix_completion() { let config = CompletionConfig { - snippets: vec![Snippet::new( - &[], - &["break".into()], - &["ControlFlow::Break(${receiver})".into()], - "", - &["core::ops::ControlFlow".into()], - crate::SnippetScope::Expr, - ) - .unwrap()], + snippets: vec![ + Snippet::new( + &[], + &["break".into()], + &["ControlFlow::Break(${receiver})".into()], + "", + &["core::ops::ControlFlow".into()], + crate::SnippetScope::Expr, + ) + .unwrap(), + ], ..TEST_CONFIG }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs index c612170eb54bc..7faa1139595f8 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs @@ -17,15 +17,15 @@ // ![Format String Completion](https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif) use ide_db::{ - syntax_helpers::format_string_exprs::{parse_format_exprs, with_placeholders, Arg}, SnippetCap, + syntax_helpers::format_string_exprs::{Arg, parse_format_exprs, with_placeholders}, }; -use syntax::{ast, AstToken}; +use syntax::{AstToken, ast}; use crate::{ + Completions, completions::postfix::{build_postfix_snippet_builder, escape_snippet_bits}, context::CompletionContext, - Completions, }; /// Mapping ("postfix completion item" => "macro to use") diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs index d0c4c24d060f8..c18aab007b2cf 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs @@ -1,14 +1,14 @@ //! Complete fields in record literals and patterns. use ide_db::SymbolKind; use syntax::{ - ast::{self, Expr}, SmolStr, + ast::{self, Expr}, }; use crate::{ - context::{DotAccess, DotAccessExprCtx, DotAccessKind, PatternContext}, CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch, Completions, + context::{DotAccess, DotAccessExprCtx, DotAccessKind, PatternContext}, }; pub(crate) fn complete_record_pattern_fields( @@ -144,8 +144,8 @@ mod tests { use ide_db::SnippetCap; use crate::{ - tests::{check_edit, check_edit_with_config, TEST_CONFIG}, CompletionConfig, + tests::{TEST_CONFIG, check_edit, check_edit_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs index 357709e0c1fde..31aae11676228 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs @@ -1,11 +1,11 @@ //! This file provides snippet completions, like `pd` => `eprintln!(...)`. -use ide_db::{documentation::Documentation, imports::insert_use::ImportScope, SnippetCap}; +use ide_db::{SnippetCap, documentation::Documentation, imports::insert_use::ImportScope}; use crate::{ + CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope, context::{ItemListKind, PathCompletionCtx, PathExprCtx, Qualified}, item::Builder, - CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope, }; pub(crate) fn complete_expr_snippet( @@ -153,23 +153,25 @@ fn add_custom_completions( #[cfg(test)] mod tests { use crate::{ - tests::{check_edit_with_config, TEST_CONFIG}, CompletionConfig, Snippet, + tests::{TEST_CONFIG, check_edit_with_config}, }; #[test] fn custom_snippet_completion() { check_edit_with_config( CompletionConfig { - snippets: vec![Snippet::new( - &["break".into()], - &[], - &["ControlFlow::Break(())".into()], - "", - &["core::ops::ControlFlow".into()], - crate::SnippetScope::Expr, - ) - .unwrap()], + snippets: vec![ + Snippet::new( + &["break".into()], + &[], + &["ControlFlow::Break(())".into()], + "", + &["core::ops::ControlFlow".into()], + crate::SnippetScope::Expr, + ) + .unwrap(), + ], ..TEST_CONFIG }, "break", diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs index b07148809323f..79db705af495d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs @@ -1,12 +1,12 @@ //! Completion of names from the current scope in type position. use hir::{HirDisplay, ScopeDef}; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; use crate::{ + CompletionContext, Completions, context::{PathCompletionCtx, Qualified, TypeAscriptionTarget, TypeLocation}, render::render_type_inference, - CompletionContext, Completions, }; pub(crate) fn complete_type_path( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs index b384987c51ce1..4d6d0b758a381 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs @@ -2,12 +2,12 @@ use hir::ScopeDef; use ide_db::{FxHashSet, SymbolKind}; -use syntax::{ast, format_smolstr, AstNode}; +use syntax::{AstNode, ast, format_smolstr}; use crate::{ + CompletionItem, CompletionItemKind, CompletionRelevance, Completions, context::{CompletionContext, PathCompletionCtx, Qualified}, item::Builder, - CompletionItem, CompletionItemKind, CompletionRelevance, Completions, }; pub(crate) fn complete_use_path( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs index 0ea5157fb46fe..d15c35ac84991 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs @@ -1,8 +1,8 @@ //! Completion for visibility specifiers. use crate::{ - context::{CompletionContext, PathCompletionCtx, Qualified}, Completions, + context::{CompletionContext, PathCompletionCtx, Qualified}, }; pub(crate) fn complete_vis_path( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/config.rs b/src/tools/rust-analyzer/crates/ide-completion/src/config.rs index 45aab38e8ea09..844fce5ef8019 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/config.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/config.rs @@ -5,9 +5,9 @@ //! completions if we are allowed to. use hir::ImportPathConfig; -use ide_db::{imports::insert_use::InsertUseConfig, SnippetCap}; +use ide_db::{SnippetCap, imports::insert_use::InsertUseConfig}; -use crate::{snippet::Snippet, CompletionFieldsToResolve}; +use crate::{CompletionFieldsToResolve, snippet::Snippet}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct CompletionConfig<'a> { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 54620bbad1bce..aa0b6060f6f1d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -6,26 +6,27 @@ mod tests; use std::{iter, ops::ControlFlow}; -use base_db::{salsa::AsDynDatabase, RootQueryDb as _}; +use base_db::{RootQueryDb as _, salsa::AsDynDatabase}; use hir::{ DisplayTarget, HasAttrs, Local, ModPath, ModuleDef, ModuleSource, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Symbol, Type, TypeInfo, }; use ide_db::{ - famous_defs::FamousDefs, helpers::is_editable_crate, FilePosition, FxHashMap, FxHashSet, - RootDatabase, + FilePosition, FxHashMap, FxHashSet, RootDatabase, famous_defs::FamousDefs, + helpers::is_editable_crate, }; use syntax::{ - ast::{self, AttrKind, NameOrNameRef}, - match_ast, AstNode, Edition, SmolStr, + AstNode, Edition, SmolStr, SyntaxKind::{self, *}, - SyntaxToken, TextRange, TextSize, T, + SyntaxToken, T, TextRange, TextSize, + ast::{self, AttrKind, NameOrNameRef}, + match_ast, }; use crate::{ - config::AutoImportExclusionType, - context::analysis::{expand_and_analyze, AnalysisResult}, CompletionConfig, + config::AutoImportExclusionType, + context::analysis::{AnalysisResult, expand_and_analyze}, }; const COMPLETION_MARKER: &str = "raCompletionMarker"; @@ -676,11 +677,7 @@ impl CompletionContext<'_> { }; } - if self.is_doc_hidden(attrs, defining_crate) { - Visible::No - } else { - Visible::Yes - } + if self.is_doc_hidden(attrs, defining_crate) { Visible::No } else { Visible::Yes } } pub(crate) fn is_doc_hidden(&self, attrs: &hir::Attrs, defining_crate: hir::Crate) -> bool { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index 1a34548f70824..8f58c2181ef45 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -2,24 +2,25 @@ use std::iter; use hir::{ExpandResult, Semantics, Type, TypeInfo, Variant}; -use ide_db::{active_parameter::ActiveParameter, RootDatabase}; +use ide_db::{RootDatabase, active_parameter::ActiveParameter}; use itertools::Either; use syntax::{ + AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, + T, TextRange, TextSize, algo::{self, ancestors_at_offset, find_node_at_offset, non_trivia_sibling}, ast::{ self, AttrKind, HasArgList, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, NameOrNameRef, }, - match_ast, AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, - SyntaxToken, TextRange, TextSize, T, + match_ast, }; use crate::context::{ - AttrCtx, BreakableKind, CompletionAnalysis, DotAccess, DotAccessExprCtx, DotAccessKind, - ItemListKind, LifetimeContext, LifetimeKind, NameContext, NameKind, NameRefContext, - NameRefKind, ParamContext, ParamKind, PathCompletionCtx, PathExprCtx, PathKind, PatternContext, - PatternRefutability, Qualified, QualifierCtx, TypeAscriptionTarget, TypeLocation, - COMPLETION_MARKER, + AttrCtx, BreakableKind, COMPLETION_MARKER, CompletionAnalysis, DotAccess, DotAccessExprCtx, + DotAccessKind, ItemListKind, LifetimeContext, LifetimeKind, NameContext, NameKind, + NameRefContext, NameRefKind, ParamContext, ParamKind, PathCompletionCtx, PathExprCtx, PathKind, + PatternContext, PatternRefutability, Qualified, QualifierCtx, TypeAscriptionTarget, + TypeLocation, }; #[derive(Debug)] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs index a03f632cdfdfa..72bcbf366d2ed 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs @@ -1,9 +1,9 @@ -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use hir::HirDisplay; use crate::{ context::CompletionContext, - tests::{position, TEST_CONFIG}, + tests::{TEST_CONFIG, position}, }; fn check_expected_type_and_name(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs index 8d6dc4c801301..e208b9fd41ae2 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs @@ -5,17 +5,17 @@ use std::{fmt, mem}; use hir::Mutability; use ide_db::text_edit::TextEdit; use ide_db::{ - documentation::Documentation, imports::import_assets::LocatedImport, RootDatabase, SnippetCap, - SymbolKind, + RootDatabase, SnippetCap, SymbolKind, documentation::Documentation, + imports::import_assets::LocatedImport, }; use itertools::Itertools; use smallvec::SmallVec; use stdx::{format_to, impl_from, never}; -use syntax::{format_smolstr, Edition, SmolStr, TextRange, TextSize}; +use syntax::{Edition, SmolStr, TextRange, TextSize, format_smolstr}; use crate::{ context::{CompletionContext, PathCompletionCtx}, - render::{render_path_resolution, RenderContext}, + render::{RenderContext, render_path_resolution}, }; /// `CompletionItem` describes a single completion entity which expands to 1 or more entries in the diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index c9fc5ae152400..8d8dfb083e405 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -11,11 +11,11 @@ mod snippet; mod tests; use ide_db::{ + FilePosition, FxHashSet, RootDatabase, base_db::salsa::AsDynDatabase, imports::insert_use::{self, ImportScope}, syntax_helpers::tree_diff::diff, text_edit::TextEdit, - FilePosition, FxHashSet, RootDatabase, }; use syntax::ast::make; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 0f0fa115af0b3..54094a8f8e3ba 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -10,17 +10,19 @@ pub(crate) mod type_alias; pub(crate) mod union_literal; pub(crate) mod variant; -use hir::{sym, AsAssocItem, HasAttrs, HirDisplay, ModuleDef, ScopeDef, Type}; +use hir::{AsAssocItem, HasAttrs, HirDisplay, ModuleDef, ScopeDef, Type, sym}; use ide_db::text_edit::TextEdit; use ide_db::{ + RootDatabase, SnippetCap, SymbolKind, documentation::{Documentation, HasDocs}, helpers::item_name, imports::import_assets::LocatedImport, - RootDatabase, SnippetCap, SymbolKind, }; -use syntax::{ast, format_smolstr, AstNode, SmolStr, SyntaxKind, TextRange, ToSmolStr}; +use syntax::{AstNode, SmolStr, SyntaxKind, TextRange, ToSmolStr, ast, format_smolstr}; use crate::{ + CompletionContext, CompletionItem, CompletionItemKind, CompletionItemRefMode, + CompletionRelevance, context::{DotAccess, DotAccessKind, PathCompletionCtx, PathKind, PatternContext}, item::{Builder, CompletionRelevanceTypeMatch}, render::{ @@ -28,8 +30,6 @@ use crate::{ literal::render_variant_lit, macro_::{render_macro, render_macro_pat}, }, - CompletionContext, CompletionItem, CompletionItemKind, CompletionItemRefMode, - CompletionRelevance, }; /// Interface for data and methods required for items rendering. #[derive(Debug, Clone)] @@ -683,14 +683,14 @@ fn path_ref_match( mod tests { use std::cmp; - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use ide_db::SymbolKind; use itertools::Itertools; use crate::{ - item::CompletionRelevanceTypeMatch, - tests::{check_edit, do_completion, get_all_items, TEST_CONFIG}, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch, + item::CompletionRelevanceTypeMatch, + tests::{TEST_CONFIG, check_edit, do_completion, get_all_items}, }; #[track_caller] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index 4693bdc047f97..dd0f24522fc9b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs @@ -1,12 +1,13 @@ //! Renderer for function calls. -use hir::{db::HirDatabase, AsAssocItem, HirDisplay}; +use hir::{AsAssocItem, HirDisplay, db::HirDatabase}; use ide_db::{SnippetCap, SymbolKind}; use itertools::Itertools; use stdx::{format_to, to_lower_snake_case}; -use syntax::{format_smolstr, AstNode, SmolStr, ToSmolStr}; +use syntax::{AstNode, SmolStr, ToSmolStr, format_smolstr}; use crate::{ + CallableSnippets, context::{ CompleteSemicolon, CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind, }, @@ -15,9 +16,8 @@ use crate::{ CompletionRelevanceReturnType, CompletionRelevanceTraitInfo, }, render::{ - compute_exact_name_match, compute_ref_match, compute_type_match, match_types, RenderContext, + RenderContext, compute_exact_name_match, compute_ref_match, compute_type_match, match_types, }, - CallableSnippets, }; #[derive(Debug)] @@ -293,11 +293,7 @@ fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type) -> &'sta for (name, local) in ctx.locals.iter().sorted_by_key(|&(k, _)| k.clone()) { if name.as_str() == arg { return if local.ty(ctx.db) == derefed_ty { - if ty.is_mutable_reference() { - "&mut " - } else { - "&" - } + if ty.is_mutable_reference() { "&mut " } else { "&" } } else { "" }; @@ -398,8 +394,8 @@ fn params( #[cfg(test)] mod tests { use crate::{ - tests::{check_edit, check_edit_with_config, TEST_CONFIG}, CallableSnippets, CompletionConfig, + tests::{TEST_CONFIG, check_edit, check_edit_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs index ffda52fb47852..5a9e35a7290bf 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs @@ -1,23 +1,22 @@ //! Renderer for `enum` variants. -use hir::{db::HirDatabase, StructKind}; +use hir::{StructKind, db::HirDatabase}; use ide_db::{ - documentation::{Documentation, HasDocs}, SymbolKind, + documentation::{Documentation, HasDocs}, }; use crate::{ + CompletionItemKind, CompletionRelevance, CompletionRelevanceReturnType, context::{CompletionContext, PathCompletionCtx, PathKind}, item::{Builder, CompletionItem, CompletionRelevanceFn}, render::{ - compute_type_match, + RenderContext, compute_type_match, variant::{ - format_literal_label, format_literal_lookup, render_record_lit, render_tuple_lit, - visible_fields, RenderedLiteral, + RenderedLiteral, format_literal_label, format_literal_lookup, render_record_lit, + render_tuple_lit, visible_fields, }, - RenderContext, }, - CompletionItemKind, CompletionRelevance, CompletionRelevanceReturnType, }; pub(crate) fn render_variant_lit( @@ -164,11 +163,7 @@ impl Variant { Variant::Struct(it) => visible_fields(ctx, &fields, it)?, Variant::EnumVariant(it) => visible_fields(ctx, &fields, it)?, }; - if !fields_omitted { - Some(visible_fields) - } else { - None - } + if !fields_omitted { Some(visible_fields) } else { None } } fn kind(self, db: &dyn HirDatabase) -> StructKind { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs index 8b2476d153f1f..4674dae031440 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs @@ -1,8 +1,8 @@ //! Renderer for macro invocations. use hir::HirDisplay; -use ide_db::{documentation::Documentation, SymbolKind}; -use syntax::{format_smolstr, SmolStr, ToSmolStr}; +use ide_db::{SymbolKind, documentation::Documentation}; +use syntax::{SmolStr, ToSmolStr, format_smolstr}; use crate::{ context::{PathCompletionCtx, PathKind, PatternContext}, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs index 124abb17b6a1c..93e6c5237948f 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs @@ -1,17 +1,17 @@ //! Renderer for patterns. -use hir::{db::HirDatabase, Name, StructKind}; -use ide_db::{documentation::HasDocs, SnippetCap}; +use hir::{Name, StructKind, db::HirDatabase}; +use ide_db::{SnippetCap, documentation::HasDocs}; use itertools::Itertools; use syntax::{Edition, SmolStr, ToSmolStr}; use crate::{ + CompletionItem, CompletionItemKind, context::{ParamContext, ParamKind, PathCompletionCtx, PatternContext}, render::{ - variant::{format_literal_label, format_literal_lookup, visible_fields}, RenderContext, + variant::{format_literal_label, format_literal_lookup, visible_fields}, }, - CompletionItem, CompletionItemKind, }; pub(crate) fn render_struct_pat( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs index 09154e81c0304..23f0d4e06f2c8 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs @@ -6,11 +6,11 @@ use itertools::Itertools; use syntax::ToSmolStr; use crate::{ + CompletionItem, CompletionItemKind, render::{ - variant::{format_literal_label, format_literal_lookup, visible_fields}, RenderContext, + variant::{format_literal_label, format_literal_lookup, visible_fields}, }, - CompletionItem, CompletionItemKind, }; pub(crate) fn render_union_literal( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs index 83718e57229a5..5d7d68bb3d660 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs @@ -1,7 +1,7 @@ //! Code common to structs, unions, and enum variants. use crate::context::CompletionContext; -use hir::{sym, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; +use hir::{HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind, sym}; use ide_db::SnippetCap; use itertools::Itertools; use syntax::SmolStr; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs index 2984348a3278d..85987f0de59ff 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs @@ -28,8 +28,8 @@ use base_db::SourceDatabase; use expect_test::Expect; use hir::PrefixKind; use ide_db::{ - imports::insert_use::{ImportGranularity, InsertUseConfig}, FilePosition, RootDatabase, SnippetCap, + imports::insert_use::{ImportGranularity, InsertUseConfig}, }; use itertools::Itertools; use stdx::{format_to, trim_indent}; @@ -37,8 +37,8 @@ use test_fixture::ChangeFixture; use test_utils::assert_eq_text; use crate::{ - resolve_completion_edits, CallableSnippets, CompletionConfig, CompletionFieldsToResolve, - CompletionItem, CompletionItemKind, + CallableSnippets, CompletionConfig, CompletionFieldsToResolve, CompletionItem, + CompletionItemKind, resolve_completion_edits, }; /// Lots of basic item definitions diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs index 9b3c676c48a1f..61823811dcc7d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs @@ -1,13 +1,13 @@ //! Completion tests for expressions. -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use crate::{ + CompletionConfig, config::AutoImportExclusionType, tests::{ - check, check_edit, check_with_base_items, completion_list_with_config, BASE_ITEMS_FIXTURE, - TEST_CONFIG, + BASE_ITEMS_FIXTURE, TEST_CONFIG, check, check_edit, check_with_base_items, + completion_list_with_config, }, - CompletionConfig, }; fn check_with_config( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index 2e7c53def7fc5..8bba44c12bf60 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -1,9 +1,9 @@ -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use crate::{ - context::{CompletionAnalysis, NameContext, NameKind, NameRefKind}, - tests::{check_edit, check_edit_with_config, TEST_CONFIG}, CompletionConfig, + context::{CompletionAnalysis, NameContext, NameKind, NameRefKind}, + tests::{TEST_CONFIG, check_edit, check_edit_with_config}, }; fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs index 823cc8c3d8c55..00977ea4e533b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs @@ -1,8 +1,8 @@ use base_db::SourceDatabase; -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use itertools::Itertools; -use crate::tests::{completion_list_with_config_raw, position, TEST_CONFIG}; +use crate::tests::{TEST_CONFIG, completion_list_with_config_raw, position}; fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let completions = completion_list_with_config_raw(TEST_CONFIG, ra_fixture, true, None); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs index 005263d100a5b..355f04bf0aa88 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs @@ -1,14 +1,14 @@ //! Tests that don't fit into a specific category. -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use ide_db::SymbolKind; use crate::{ + CompletionItemKind, tests::{ - check, check_edit, check_no_kw, check_with_trigger_character, do_completion_with_config, - TEST_CONFIG, + TEST_CONFIG, check, check_edit, check_no_kw, check_with_trigger_character, + do_completion_with_config, }, - CompletionItemKind, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs index 11808fed3be6a..06ed4afdf9be3 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs @@ -4,8 +4,9 @@ use either::Either; use hir::{InFile, Semantics, Type}; use parser::T; use syntax::{ + AstNode, NodeOrToken, SyntaxToken, ast::{self, AstChildren, HasArgList, HasAttrs, HasName}, - match_ast, AstNode, NodeOrToken, SyntaxToken, + match_ast, }; use crate::RootDatabase; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs index 4e058bb0106a2..36745b012b00d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs @@ -6,7 +6,7 @@ use rustc_hash::FxHashSet; use salsa::{Database as _, Durability}; use triomphe::Arc; -use crate::{symbol_index::SymbolsDatabase, ChangeWithProcMacros, RootDatabase}; +use crate::{ChangeWithProcMacros, RootDatabase, symbol_index::SymbolsDatabase}; impl RootDatabase { pub fn request_cancellation(&mut self) { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index 502314ed1e0ec..18126f616c9ec 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs @@ -5,9 +5,9 @@ // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). +use crate::RootDatabase; use crate::documentation::{Documentation, HasDocs}; use crate::famous_defs::FamousDefs; -use crate::RootDatabase; use arrayvec::ArrayVec; use either::Either; use hir::{ @@ -21,8 +21,9 @@ use hir::{ use span::Edition; use stdx::{format_to, impl_from}; use syntax::{ + SyntaxKind, SyntaxNode, SyntaxToken, ast::{self, AstNode}, - match_ast, SyntaxKind, SyntaxNode, SyntaxToken, + match_ast, }; // FIXME: a more precise name would probably be `Symbol`? diff --git a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs index b83efcd02f772..96654a2416b65 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs @@ -1,14 +1,15 @@ //! Documentation attribute related utilities. use either::Either; use hir::{ + AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile, db::{DefDatabase, HirDatabase}, - resolve_doc_path_on, sym, AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile, + resolve_doc_path_on, sym, }; use itertools::Itertools; use span::{TextRange, TextSize}; use syntax::{ - ast::{self, IsString}, AstToken, + ast::{self, IsString}, }; /// Holds documentation @@ -151,11 +152,7 @@ pub fn docs_from_attrs(attrs: &hir::Attrs) -> Option { buf.push('\n'); } buf.pop(); - if buf.is_empty() { - None - } else { - Some(buf) - } + if buf.is_empty() { None } else { Some(buf) } } macro_rules! impl_has_docs { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs index fe4662785af11..994150b1ac4c2 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs @@ -220,11 +220,7 @@ impl FamousDefs<'_, '_> { for segment in path { module = module.children(db).find_map(|child| { let name = child.name(db)?; - if name.as_str() == segment { - Some(child) - } else { - None - } + if name.as_str() == segment { Some(child) } else { None } })?; } let def = diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs index ebafc8876f249..340429037e67a 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs @@ -6,13 +6,14 @@ use base_db::SourceDatabase; use hir::{Crate, ItemInNs, ModuleDef, Name, Semantics}; use span::{Edition, FileId}; use syntax::{ - ast::{self, make}, AstToken, SyntaxKind, SyntaxToken, ToSmolStr, TokenAtOffset, + ast::{self, make}, }; use crate::{ + RootDatabase, defs::{Definition, IdentClass}, - generated, RootDatabase, + generated, }; pub fn item_name(db: &RootDatabase, item: ItemInNs) -> Option { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 77fc59b4eccb5..0fc287c57e7c3 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -3,20 +3,20 @@ use std::ops::ControlFlow; use hir::{ - db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig, - ItemInNs, ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, - SemanticsScope, Trait, TyFingerprint, Type, + AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig, ItemInNs, + ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, + SemanticsScope, Trait, TyFingerprint, Type, db::HirDatabase, }; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ - ast::{self, make, HasName}, AstNode, SyntaxNode, + ast::{self, HasName, make}, }; use crate::{ - items_locator::{self, AssocSearchMode, DEFAULT_QUERY_SEARCH_LIMIT}, FxIndexSet, RootDatabase, + items_locator::{self, AssocSearchMode, DEFAULT_QUERY_SEARCH_LIMIT}, }; /// A candidate for import, derived during various IDE activities: @@ -433,7 +433,7 @@ fn validate_resolvable( false => ControlFlow::Continue(()), }, ) - .map(|item| LocatedImport::new(import_path_candidate, resolved_qualifier, item)) + .map(|item| LocatedImport::new(import_path_candidate, resolved_qualifier, item)); } // FIXME ModuleDef::Trait(_) => return None, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs index 8e25ad3472d3b..d26e5d62ced51 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs @@ -6,20 +6,20 @@ use std::cmp::Ordering; use hir::Semantics; use syntax::{ - algo, + Direction, NodeOrToken, SyntaxKind, SyntaxNode, algo, ast::{ - self, edit_in_place::Removable, make, AstNode, HasAttrs, HasModuleItem, HasVisibility, - PathSegmentKind, + self, AstNode, HasAttrs, HasModuleItem, HasVisibility, PathSegmentKind, + edit_in_place::Removable, make, }, - ted, Direction, NodeOrToken, SyntaxKind, SyntaxNode, + ted, }; use crate::{ + RootDatabase, imports::merge_imports::{ - common_prefix, eq_attrs, eq_visibility, try_merge_imports, use_tree_cmp, MergeBehavior, - NormalizationStyle, + MergeBehavior, NormalizationStyle, common_prefix, eq_attrs, eq_visibility, + try_merge_imports, use_tree_cmp, }, - RootDatabase, }; pub use hir::PrefixKind; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs index 39810c615bb77..541f6c379e874 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs @@ -1,7 +1,7 @@ use salsa::AsDynDatabase; use stdx::trim_indent; use test_fixture::WithFixture; -use test_utils::{assert_eq_text, CURSOR_MARKER}; +use test_utils::{CURSOR_MARKER, assert_eq_text}; use super::*; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs index 9e89dfe87abe5..61962e593476c 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs @@ -5,13 +5,12 @@ use itertools::{EitherOrBoth, Itertools}; use parser::T; use stdx::is_upper_snake_case; use syntax::{ - algo, + Direction, SyntaxElement, algo, ast::{ - self, edit_in_place::Removable, make, AstNode, HasAttrs, HasName, HasVisibility, - PathSegmentKind, + self, AstNode, HasAttrs, HasName, HasVisibility, PathSegmentKind, edit_in_place::Removable, + make, }, ted::{self, Position}, - Direction, SyntaxElement, }; use crate::syntax_helpers::node_ext::vis_eq; @@ -191,7 +190,7 @@ fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) && !use_trees.is_empty() && rhs_t.use_tree_list().is_some() => { - return None + return None; } Err(insert_idx) => { use_trees.insert(insert_idx, rhs_t.clone()); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs index 4d9c051354a61..80881829800e5 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs @@ -5,12 +5,12 @@ use std::ops::ControlFlow; use either::Either; -use hir::{import_map, Crate, ItemInNs, Module, Semantics}; +use hir::{Crate, ItemInNs, Module, Semantics, import_map}; use crate::{ + RootDatabase, imports::import_assets::NameToImport, symbol_index::{self, SymbolsDatabase as _}, - RootDatabase, }; /// A value to use, when uncertain which limit to pick. diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 414cc6cd18fa9..c6bd8031281c1 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -51,12 +51,12 @@ use salsa::Durability; use std::{fmt, mem::ManuallyDrop}; use base_db::{ - query_group, CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, Files, RootQueryDb, - SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, Upcast, + CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, Files, RootQueryDb, + SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, Upcast, query_group, }; use hir::{ - db::{DefDatabase, ExpandDatabase, HirDatabase}, FilePositionWrapper, FileRangeWrapper, + db::{DefDatabase, ExpandDatabase, HirDatabase}, }; use triomphe::Arc; @@ -360,11 +360,7 @@ pub struct SnippetCap { impl SnippetCap { pub const fn new(allow_snippets: bool) -> Option { - if allow_snippets { - Some(SnippetCap { _private: () }) - } else { - None - } + if allow_snippets { Some(SnippetCap { _private: () }) } else { None } } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index a348a4ef7d3fb..5aef2a6e020c3 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -7,8 +7,9 @@ use itertools::Itertools; use rustc_hash::FxHashMap; use span::Edition; use syntax::{ - ast::{self, make, AstNode, HasGenericArgs}, - ted, NodeOrToken, SyntaxNode, + NodeOrToken, SyntaxNode, + ast::{self, AstNode, HasGenericArgs, make}, + ted, }; #[derive(Default)] diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs index cd3099fe93819..17c3f75ce1731 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs @@ -6,14 +6,14 @@ mod topologic_sort; use std::time::Duration; -use hir::{db::DefDatabase, Symbol}; +use hir::{Symbol, db::DefDatabase}; use itertools::Itertools; use salsa::{Cancelled, Database}; use crate::{ + FxIndexMap, RootDatabase, base_db::{Crate, RootQueryDb}, symbol_index::SymbolsDatabase, - FxIndexMap, RootDatabase, }; /// We're indexing many crates. diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index 902ead977e582..4a5a28e8248ce 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -30,20 +30,20 @@ use base_db::AnchoredPathBuf; use either::Either; use hir::{FieldSource, FileRange, HirFileIdExt, InFile, ModuleSource, Semantics}; use span::{Edition, EditionedFileId, FileId, SyntaxContext}; -use stdx::{never, TupleExt}; +use stdx::{TupleExt, never}; use syntax::{ + AstNode, SyntaxKind, T, TextRange, ast::{self, HasName}, utils::is_raw_identifier, - AstNode, SyntaxKind, TextRange, T, }; use crate::{ + RootDatabase, defs::Definition, search::{FileReference, FileReferenceNode}, source_change::{FileSystemEdit, SourceChange}, syntax_helpers::node_ext::expr_as_name_ref, traits::convert_to_def_in_trait, - RootDatabase, }; pub type Result = std::result::Result; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 4f9ef05b20e79..bb4bee91bbe8a 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -10,9 +10,9 @@ use std::{cell::LazyCell, cmp::Reverse}; use base_db::{RootQueryDb, SourceDatabase}; use either::Either; use hir::{ - sym, Adt, AsAssocItem, DefWithBody, FileRange, FileRangeWrapper, HasAttrs, HasContainer, - HasSource, HirFileIdExt, InFile, InFileWrapper, InRealFile, InlineAsmOperand, ItemContainer, - ModuleSource, PathResolution, Semantics, Visibility, + Adt, AsAssocItem, DefWithBody, FileRange, FileRangeWrapper, HasAttrs, HasContainer, HasSource, + HirFileIdExt, InFile, InFileWrapper, InRealFile, InlineAsmOperand, ItemContainer, ModuleSource, + PathResolution, Semantics, Visibility, sym, }; use memchr::memmem::Finder; use parser::SyntaxKind; @@ -20,16 +20,16 @@ use rustc_hash::{FxHashMap, FxHashSet}; use salsa::Database; use span::EditionedFileId; use syntax::{ + AstNode, AstToken, SmolStr, SyntaxElement, SyntaxNode, TextRange, TextSize, ToSmolStr, ast::{self, HasName, Rename}, - match_ast, AstNode, AstToken, SmolStr, SyntaxElement, SyntaxNode, TextRange, TextSize, - ToSmolStr, + match_ast, }; use triomphe::Arc; use crate::{ + RootDatabase, defs::{Definition, NameClass, NameRefClass}, traits::{as_trait_assoc_def, convert_to_def_in_trait}, - RootDatabase, }; #[derive(Debug, Default, Clone)] @@ -1292,7 +1292,7 @@ impl<'a> FindUsages<'a> { if convert_to_def_in_trait(self.sema.db, def) != convert_to_def_in_trait(self.sema.db, self.def) => { - return false + return false; } (Some(_), Definition::TypeAlias(_)) => {} // We looking at an assoc item of a trait definition, so reference all the diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs index b4d0b0dc9f0af..741dc6bb3c88a 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs @@ -6,7 +6,7 @@ use std::{collections::hash_map::Entry, fmt, iter, mem}; use crate::text_edit::{TextEdit, TextEditBuilder}; -use crate::{assists::Command, syntax_helpers::tree_diff::diff, SnippetCap}; +use crate::{SnippetCap, assists::Command, syntax_helpers::tree_diff::diff}; use base_db::AnchoredPathBuf; use itertools::Itertools; use nohash_hasher::IntMap; @@ -14,8 +14,8 @@ use rustc_hash::FxHashMap; use span::FileId; use stdx::never; use syntax::{ - syntax_editor::{SyntaxAnnotation, SyntaxEditor}, AstNode, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize, + syntax_editor::{SyntaxAnnotation, SyntaxEditor}, }; /// An annotation ID associated with an indel, to describe changes. @@ -479,13 +479,14 @@ impl SourceChangeBuilder { self.commit(); // Only one file can have snippet edits - stdx::never!(self - .source_change - .source_file_edits - .iter() - .filter(|(_, (_, snippet_edit))| snippet_edit.is_some()) - .at_most_one() - .is_err()); + stdx::never!( + self.source_change + .source_file_edits + .iter() + .filter(|(_, (_, snippet_edit))| snippet_edit.is_some()) + .at_most_one() + .is_err() + ); mem::take(&mut self.source_change) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index 5fea97b32dbde..e681a6d17ce34 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -28,12 +28,12 @@ use std::{ }; use base_db::{RootQueryDb, SourceDatabase, SourceRootId, Upcast}; -use fst::{raw::IndexedValue, Automaton, Streamer}; +use fst::{Automaton, Streamer, raw::IndexedValue}; use hir::{ + Crate, Module, db::HirDatabase, import_map::{AssocSearchMode, SearchMode}, symbols::{FileSymbol, SymbolCollector}, - Crate, Module, }; use rayon::prelude::*; use rustc_hash::FxHashSet; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs index 92478ef480d6a..7e8c921d9ed39 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs @@ -1,7 +1,7 @@ //! Tools to work with format string literals for the `format_args!` family of macros. use syntax::{ - ast::{self, IsString}, AstNode, AstToken, TextRange, TextSize, + ast::{self, IsString}, }; // FIXME: This can probably be re-implemented via the HIR? diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs index c104aa571894d..8f25833fffb8d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs @@ -183,7 +183,7 @@ pub fn parse_format_exprs(input: &str) -> Result<(String, Vec), ()> { #[cfg(test)] mod tests { use super::*; - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; fn check(input: &str, expect: &Expect) { let (output, exprs) = parse_format_exprs(input).unwrap_or(("-".to_owned(), vec![])); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs index 0b2e8aa6836f2..f0aa3daf55b63 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs @@ -5,8 +5,8 @@ use itertools::Itertools; use parser::T; use span::Edition; use syntax::{ - ast::{self, HasLoopBody, MacroCall, PathSegmentKind, VisibilityKind}, AstNode, AstToken, Preorder, RustLanguage, WalkEvent, + ast::{self, HasLoopBody, MacroCall, PathSegmentKind, VisibilityKind}, }; pub fn expr_as_name_ref(expr: &ast::Expr) -> Option { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs index 21dd098781a85..6801856e5b80b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs @@ -7,8 +7,9 @@ use itertools::Itertools; use rustc_hash::FxHashMap; use stdx::to_lower_snake_case; use syntax::{ + AstNode, Edition, SmolStr, SmolStrBuilder, ToSmolStr, ast::{self, HasName}, - match_ast, AstNode, Edition, SmolStr, SmolStrBuilder, ToSmolStr, + match_ast, }; use crate::RootDatabase; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/tree_diff.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/tree_diff.rs index 02e24c47761c9..7163c08e1e317 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/tree_diff.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/tree_diff.rs @@ -2,7 +2,7 @@ use rustc_hash::FxHashMap; use syntax::{NodeOrToken, SyntaxElement, SyntaxNode}; -use crate::{text_edit::TextEditBuilder, FxIndexMap}; +use crate::{FxIndexMap, text_edit::TextEditBuilder}; #[derive(Debug, Hash, PartialEq, Eq)] enum TreeDiffInsertPos { @@ -153,7 +153,7 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use itertools::Itertools; use parser::{Edition, SyntaxKind}; use syntax::{AstNode, SourceFile, SyntaxElement}; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs index fb231393a473d..22a695c9a82ce 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs @@ -1,9 +1,9 @@ //! Functionality for obtaining data related to traits from the DB. -use crate::{defs::Definition, RootDatabase}; -use hir::{db::HirDatabase, AsAssocItem, Semantics}; +use crate::{RootDatabase, defs::Definition}; +use hir::{AsAssocItem, Semantics, db::HirDatabase}; use rustc_hash::FxHashSet; -use syntax::{ast, AstNode}; +use syntax::{AstNode, ast}; /// Given the `impl` block, attempts to find the trait this `impl` corresponds to. pub fn resolve_target_trait( @@ -113,7 +113,7 @@ fn assoc_item_of_trait( #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use hir::FilePosition; use hir::Semantics; use salsa::AsDynDatabase; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs b/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs index 2fdd8358637df..63ce0ddbb8fc2 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs @@ -5,7 +5,7 @@ use std::iter; use hir::Semantics; -use syntax::ast::{self, make, Pat}; +use syntax::ast::{self, Pat, make}; use crate::RootDatabase; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs index c3f0bf3706904..a4a93e36f0e1a 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs @@ -3,8 +3,8 @@ use hir::StructKind; use span::Edition; use syntax::{ - ast::{make, Expr, Path}, ToSmolStr, + ast::{Expr, Path, make}, }; /// given a type return the trivial constructor (if one exists) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/await_outside_of_async.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/await_outside_of_async.rs index 92b6e748ca5ed..92ca7a74184fb 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/await_outside_of_async.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/await_outside_of_async.rs @@ -1,4 +1,4 @@ -use crate::{adjusted_display_range, Diagnostic, DiagnosticsContext}; +use crate::{Diagnostic, DiagnosticsContext, adjusted_display_range}; // Diagnostic: await-outside-of-async // diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs index 876c2ccd49d7a..f7020a2c50e18 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs @@ -2,10 +2,10 @@ //! expressions and patterns. use ide_db::text_edit::TextEdit; -use ide_db::{source_change::SourceChange, EditionedFileId, FileRange}; -use syntax::{ast, match_ast, AstNode, SyntaxNode}; +use ide_db::{EditionedFileId, FileRange, source_change::SourceChange}; +use syntax::{AstNode, SyntaxNode, ast, match_ast}; -use crate::{fix, Diagnostic, DiagnosticCode}; +use crate::{Diagnostic, DiagnosticCode, fix}; pub(crate) fn field_shorthand( acc: &mut Vec, diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs index 7d62daf716c47..3fa8c0133ae86 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs @@ -3,9 +3,9 @@ use hir::GenericArgsProhibitedReason; use ide_db::assists::Assist; use ide_db::source_change::SourceChange; use ide_db::text_edit::TextEdit; -use syntax::{ast, AstNode, TextRange}; +use syntax::{AstNode, TextRange, ast}; -use crate::{fix, Diagnostic, DiagnosticCode, DiagnosticsContext}; +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, fix}; // Diagnostic: generic-args-prohibited // diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs index 96a368eb0ea3f..80ea6f5893505 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs @@ -39,7 +39,7 @@ pub(crate) fn inactive_code( #[cfg(test)] mod tests { - use crate::{tests::check_diagnostics_with_config, DiagnosticsConfig}; + use crate::{DiagnosticsConfig, tests::check_diagnostics_with_config}; pub(crate) fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) { let config = DiagnosticsConfig { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incoherent_impl.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incoherent_impl.rs index d3f302077528a..0b9a2ec9db3dd 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incoherent_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incoherent_impl.rs @@ -1,7 +1,7 @@ use hir::InFile; use syntax::{AstNode, TextRange}; -use crate::{adjusted_display_range, Diagnostic, DiagnosticCode, DiagnosticsContext}; +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_range}; // Diagnostic: incoherent-impl // diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs index 246330e6efaac..72619445b5dcf 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -1,13 +1,13 @@ -use hir::{db::ExpandDatabase, CaseType, InFile}; +use hir::{CaseType, InFile, db::ExpandDatabase}; use ide_db::{assists::Assist, defs::NameClass}; use syntax::AstNode; use crate::{ - // references::rename::rename_with_semantics, - unresolved_fix, Diagnostic, DiagnosticCode, DiagnosticsContext, + // references::rename::rename_with_semantics, + unresolved_fix, }; // Diagnostic: incorrect-ident-case diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs index f22041ebe233b..38eeecb29b71e 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs @@ -4,19 +4,19 @@ use hir::{ImportPathConfig, PathResolution, Semantics}; use ide_db::text_edit::TextEdit; use ide_db::{ + EditionedFileId, FileRange, FxHashMap, RootDatabase, helpers::mod_path_to_ast, - imports::insert_use::{insert_use, ImportScope}, + imports::insert_use::{ImportScope, insert_use}, source_change::SourceChangeBuilder, - EditionedFileId, FileRange, FxHashMap, RootDatabase, }; use itertools::Itertools; use stdx::{format_to, never}; use syntax::{ - ast::{self, make}, Edition, SyntaxKind, SyntaxNode, + ast::{self, make}, }; -use crate::{fix, Diagnostic, DiagnosticCode, DiagnosticsConfig, Severity}; +use crate::{Diagnostic, DiagnosticCode, DiagnosticsConfig, Severity, fix}; #[derive(Default)] struct State { @@ -196,8 +196,8 @@ pub(crate) fn json_in_items( #[cfg(test)] mod tests { use crate::{ - tests::{check_diagnostics_with_config, check_fix, check_no_fix}, DiagnosticsConfig, + tests::{check_diagnostics_with_config, check_fix, check_no_fix}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs index 2f132985895c6..9efe251c9ae94 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs @@ -38,8 +38,8 @@ pub(crate) fn macro_def_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroDefErr #[cfg(test)] mod tests { use crate::{ - tests::{check_diagnostics, check_diagnostics_with_config}, DiagnosticsConfig, + tests::{check_diagnostics, check_diagnostics_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs index 0520bb3fe9b9b..63fd9b4e3f06b 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs @@ -2,11 +2,11 @@ use either::Either; use hir::InFile; use ide_db::FileRange; use syntax::{ - ast::{self, HasArgList}, AstNode, AstPtr, + ast::{self, HasArgList}, }; -use crate::{adjusted_display_range, Diagnostic, DiagnosticCode, DiagnosticsContext}; +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_range}; // Diagnostic: mismatched-tuple-struct-pat-arg-count // diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index 938b7182bc946..ac68f4186cc57 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -1,20 +1,22 @@ use either::Either; use hir::{ + AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type, db::{ExpandDatabase, HirDatabase}, - sym, AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type, + sym, }; use ide_db::{ - assists::Assist, famous_defs::FamousDefs, imports::import_assets::item_for_path_search, - source_change::SourceChange, syntax_helpers::tree_diff::diff, text_edit::TextEdit, - use_trivial_constructor::use_trivial_constructor, FxHashMap, + FxHashMap, assists::Assist, famous_defs::FamousDefs, + imports::import_assets::item_for_path_search, source_change::SourceChange, + syntax_helpers::tree_diff::diff, text_edit::TextEdit, + use_trivial_constructor::use_trivial_constructor, }; use stdx::format_to; use syntax::{ - ast::{self, make}, AstNode, Edition, SyntaxNode, SyntaxNodePtr, ToSmolStr, + ast::{self, make}, }; -use crate::{fix, Diagnostic, DiagnosticCode, DiagnosticsContext}; +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, fix}; // Diagnostic: missing-fields // @@ -140,11 +142,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option, d: &hir::TypeMismatch) -> Option, d: &hir::TypedHole) -> Option }) .collect(); - if !assists.is_empty() { - Some(assists) - } else { - None - } + if !assists.is_empty() { Some(assists) } else { None } } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs index 550751b6c01c4..2602aa011f0ac 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -2,21 +2,21 @@ use std::iter; -use hir::{db::DefDatabase, DefMap, InFile, ModuleSource}; +use hir::{DefMap, InFile, ModuleSource, db::DefDatabase}; use ide_db::base_db::RootQueryDb; use ide_db::text_edit::TextEdit; use ide_db::{ + FileId, FileRange, LineIndexDatabase, base_db::{SourceDatabase, Upcast}, source_change::SourceChange, - FileId, FileRange, LineIndexDatabase, }; use paths::Utf8Component; use syntax::{ - ast::{self, edit::IndentLevel, HasModuleItem, HasName}, AstNode, TextRange, + ast::{self, HasModuleItem, HasName, edit::IndentLevel}, }; -use crate::{fix, Assist, Diagnostic, DiagnosticCode, DiagnosticsContext, Severity}; +use crate::{Assist, Diagnostic, DiagnosticCode, DiagnosticsContext, Severity, fix}; // Diagnostic: unlinked-file // @@ -37,7 +37,9 @@ pub(crate) fn unlinked_file( "This file is not included anywhere in the module tree, so rust-analyzer can't offer IDE services." }; - let message = format!("{message}\n\nIf you're intentionally working on unowned files, you can silence this warning by adding \"unlinked-file\" to rust-analyzer.diagnostics.disabled in your settings."); + let message = format!( + "{message}\n\nIf you're intentionally working on unowned files, you can silence this warning by adding \"unlinked-file\" to rust-analyzer.diagnostics.disabled in your settings." + ); let mut unused = true; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 6ab713a5896c9..7020fce24ff3a 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -1,7 +1,7 @@ use std::iter; use either::Either; -use hir::{db::ExpandDatabase, Adt, FileRange, HasSource, HirDisplay, InFile, Struct, Union}; +use hir::{Adt, FileRange, HasSource, HirDisplay, InFile, Struct, Union, db::ExpandDatabase}; use ide_db::text_edit::TextEdit; use ide_db::{ assists::{Assist, AssistId, AssistKind}, @@ -10,16 +10,15 @@ use ide_db::{ source_change::{SourceChange, SourceChangeBuilder}, }; use syntax::{ - algo, - ast::{self, edit::IndentLevel, make, FieldList, Name, Visibility}, - AstNode, AstPtr, Direction, SyntaxKind, TextSize, + AstNode, AstPtr, Direction, SyntaxKind, TextSize, algo, + ast::{self, FieldList, Name, Visibility, edit::IndentLevel, make}, }; use syntax::{ - ast::{edit::AstNodeEdit, Type}, SyntaxNode, + ast::{Type, edit::AstNodeEdit}, }; -use crate::{adjusted_display_range, Diagnostic, DiagnosticCode, DiagnosticsContext}; +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_range}; // Diagnostic: unresolved-field // @@ -62,11 +61,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option, d: &hir::UnresolvedMethodCall) -> Option< fixes.push(assoc_func_fix); } - if fixes.is_empty() { - None - } else { - Some(fixes) - } + if fixes.is_empty() { None } else { Some(fixes) } } fn field_fix( diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs index 2bd8e484f8537..7b9dd55e01c6e 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs @@ -1,9 +1,9 @@ -use hir::{db::ExpandDatabase, HirFileIdExt}; +use hir::{HirFileIdExt, db::ExpandDatabase}; use ide_db::{assists::Assist, base_db::AnchoredPathBuf, source_change::FileSystemEdit}; use itertools::Itertools; use syntax::AstNode; -use crate::{fix, Diagnostic, DiagnosticCode, DiagnosticsContext}; +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, fix}; // Diagnostic: unresolved-module // diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs index d5caf4de3367e..c412536d749e0 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs @@ -1,10 +1,10 @@ use hir::Name; use ide_db::text_edit::TextEdit; use ide_db::{ + FileRange, RootDatabase, assists::{Assist, AssistId, AssistKind}, label::Label, source_change::SourceChange, - FileRange, RootDatabase, }; use syntax::{Edition, TextRange}; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs index e5c2eca171ae4..ac9b34f416b44 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs @@ -1,10 +1,10 @@ use hir::InFile; use ide_db::text_edit::TextEdit; -use ide_db::{source_change::SourceChange, EditionedFileId, FileRange}; +use ide_db::{EditionedFileId, FileRange, source_change::SourceChange}; use itertools::Itertools; -use syntax::{ast, AstNode, SyntaxNode, SyntaxNodePtr}; +use syntax::{AstNode, SyntaxNode, SyntaxNodePtr, ast}; -use crate::{fix, Diagnostic, DiagnosticCode}; +use crate::{Diagnostic, DiagnosticCode, fix}; // Diagnostic: unnecessary-braces // @@ -56,8 +56,8 @@ pub(crate) fn useless_braces( #[cfg(test)] mod tests { use crate::{ - tests::{check_diagnostics, check_diagnostics_with_config, check_fix}, DiagnosticsConfig, + tests::{check_diagnostics, check_diagnostics_with_config, check_fix}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index c6f60a9a9654e..e801ec50cff91 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -82,24 +82,24 @@ use std::{collections::hash_map, iter, sync::LazyLock}; use either::Either; use hir::{ - db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, DisplayTarget, HirFileId, InFile, - Semantics, + Crate, DisplayTarget, HirFileId, InFile, Semantics, db::ExpandDatabase, + diagnostics::AnyDiagnostic, }; use ide_db::base_db::salsa::AsDynDatabase; use ide_db::{ + EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap, assists::{Assist, AssistId, AssistKind, AssistResolveStrategy}, base_db::{ReleaseChannel, RootQueryDb as _}, - generated::lints::{Lint, LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, DEFAULT_LINT_GROUPS}, + generated::lints::{CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS, DEFAULT_LINTS, Lint, LintGroup}, imports::insert_use::InsertUseConfig, label::Label, source_change::SourceChange, syntax_helpers::node_ext::parse_tt_as_comma_sep_paths, - EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap, }; use itertools::Itertools; use syntax::{ + AstPtr, Edition, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxNodePtr, T, TextRange, ast::{self, AstNode, HasAttrs}, - AstPtr, Edition, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxNodePtr, TextRange, T, }; // FIXME: Make this an enum @@ -781,9 +781,8 @@ fn fill_lint_attrs( }); let lints = lint_groups(&diag.code, edition); - let all_matching_groups = lints - .iter() - .filter_map(|lint_group| cached.get(lint_group)); + let all_matching_groups = + lints.iter().filter_map(|lint_group| cached.get(lint_group)); let cached_severity = all_matching_groups.min_by_key(|it| it.depth).map(|it| it.severity); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs index 7b33bbdaa22c4..6e4ce1ea1840c 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs @@ -3,12 +3,12 @@ mod overly_long_real_world_cases; use ide_db::{ - assists::AssistResolveStrategy, base_db::SourceDatabase, LineIndexDatabase, RootDatabase, + LineIndexDatabase, RootDatabase, assists::AssistResolveStrategy, base_db::SourceDatabase, }; use itertools::Itertools; use stdx::trim_indent; use test_fixture::WithFixture; -use test_utils::{assert_eq_text, extract_annotations, MiniCore}; +use test_utils::{MiniCore, assert_eq_text, extract_annotations}; use crate::{DiagnosticsConfig, ExprFillDefaultMode, Severity}; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/fragments.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/fragments.rs index ca937a03f82d2..8d6b7c637d730 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/fragments.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/fragments.rs @@ -6,7 +6,7 @@ //! needs to determine it somehow. We do this in a stupid way -- by pasting SSR //! rule into different contexts and checking what works. -use syntax::{ast, AstNode, SyntaxNode}; +use syntax::{AstNode, SyntaxNode, ast}; pub(crate) fn ty(s: &str) -> Result { fragment::("type T = {};", s) diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs index f6fe705a98741..5921a5df5312d 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs @@ -2,12 +2,12 @@ //! from a comment. use ide_db::{ - base_db::{salsa::AsDynDatabase, RootQueryDb}, EditionedFileId, FilePosition, FileRange, RootDatabase, + base_db::{RootQueryDb, salsa::AsDynDatabase}, }; use syntax::{ - ast::{self, AstNode, AstToken}, TextRange, + ast::{self, AstNode, AstToken}, }; use crate::MatchFinder; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs index 971547ca1f8e6..757c77b67371b 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs @@ -83,11 +83,11 @@ use hir::{FileRange, Semantics}; use ide_db::symbol_index::SymbolsDatabase; use ide_db::text_edit::TextEdit; use ide_db::{ - base_db::{salsa::AsDynDatabase, SourceDatabase}, EditionedFileId, FileId, FxHashMap, RootDatabase, + base_db::{SourceDatabase, salsa::AsDynDatabase}, }; use resolving::ResolvedRule; -use syntax::{ast, AstNode, SyntaxNode, TextRange}; +use syntax::{AstNode, SyntaxNode, TextRange, ast}; // A structured search replace rule. Create by calling `parse` on a str. #[derive(Debug)] diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index a76516f44f03b..0776b8bc5e43a 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -2,16 +2,16 @@ //! process of matching, placeholder values are recorded. use crate::{ + SsrMatches, parsing::{Constraint, NodeKind, Placeholder, Var}, resolving::{ResolvedPattern, ResolvedRule, UfcsCallInfo}, - SsrMatches, }; use hir::{FileRange, ImportPathConfig, Semantics}; -use ide_db::{base_db::RootQueryDb, FxHashMap}; +use ide_db::{FxHashMap, base_db::RootQueryDb}; use std::{cell::Cell, iter::Peekable}; use syntax::{ - ast::{self, AstNode, AstToken, HasGenericArgs}, SmolStr, SyntaxElement, SyntaxElementChildren, SyntaxKind, SyntaxNode, SyntaxToken, + ast::{self, AstNode, AstToken, HasGenericArgs}, }; // Creates a match error. If we're currently attempting to match some code that we thought we were diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs index ea40d5b815ef3..2c0f1658d837f 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs @@ -9,7 +9,7 @@ use std::{fmt::Display, str::FromStr}; use syntax::{SmolStr, SyntaxKind, SyntaxNode, T}; use crate::errors::bail; -use crate::{fragments, SsrError, SsrPattern, SsrRule}; +use crate::{SsrError, SsrPattern, SsrRule, fragments}; #[derive(Debug)] pub(crate) struct ParsedRule { diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs index 11c1615a560eb..2ad562f2427aa 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs @@ -5,11 +5,11 @@ use ide_db::{FxHashMap, FxHashSet}; use itertools::Itertools; use parser::Edition; use syntax::{ - ast::{self, AstNode, AstToken}, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, + ast::{self, AstNode, AstToken}, }; -use crate::{fragments, resolving::ResolvedRule, Match, SsrMatches}; +use crate::{Match, SsrMatches, fragments, resolving::ResolvedRule}; /// Returns a text edit that will replace each match in `matches` with its corresponding replacement /// template. Placeholders in the template will have been substituted with whatever they matched to diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs index 8c98d8de9183e..ba6d981b8c153 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs @@ -1,14 +1,14 @@ //! This module is responsible for resolving paths within rules. use hir::AsAssocItem; -use ide_db::{base_db::salsa::AsDynDatabase, FxHashMap}; +use ide_db::{FxHashMap, base_db::salsa::AsDynDatabase}; use parsing::Placeholder; use syntax::{ - ast::{self, HasGenericArgs}, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken, + ast::{self, HasGenericArgs}, }; -use crate::{errors::error, parsing, SsrError}; +use crate::{SsrError, errors::error, parsing}; pub(crate) struct ResolutionScope<'db> { scope: hir::SemanticsScope<'db>, diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs index b094712e1bd56..73dbefb51b22e 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs @@ -1,18 +1,17 @@ //! Searching for matches. use crate::{ - matching, + Match, MatchFinder, matching, resolving::{ResolvedPath, ResolvedPattern, ResolvedRule}, - Match, MatchFinder, }; use hir::FileRange; use ide_db::{ + EditionedFileId, FileId, FxHashSet, base_db::salsa::AsDynDatabase, defs::Definition, search::{SearchScope, UsageSearchResult}, - EditionedFileId, FileId, FxHashSet, }; -use syntax::{ast, AstNode, SyntaxKind, SyntaxNode}; +use syntax::{AstNode, SyntaxKind, SyntaxNode, ast}; /// A cache for the results of find_usages. This is for when we have multiple patterns that have the /// same path. e.g. if the pattern was `foo::Bar` that can parse as a path, an expression, a type diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs index 0b510c9c6b244..b26ea35f02a93 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs @@ -1,8 +1,8 @@ -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use hir::{FilePosition, FileRange}; use ide_db::{ - base_db::{salsa::Durability, SourceDatabase}, EditionedFileId, FxHashSet, + base_db::{SourceDatabase, salsa::Durability}, }; use test_utils::RangeOrOffset; use triomphe::Arc; @@ -67,7 +67,7 @@ fn parser_undefined_placeholder_in_replacement() { /// the start of the file. If there's a second cursor marker, then we'll return a single range. pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Vec) { use ide_db::symbol_index::SymbolsDatabase; - use test_fixture::{WithFixture, WORKSPACE}; + use test_fixture::{WORKSPACE, WithFixture}; let (mut db, file_id, range_or_offset) = if code.contains(test_utils::CURSOR_MARKER) { ide_db::RootDatabase::with_range_or_offset(code) } else { diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs index e47891bbdfe7e..d44d4bfd2be7b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs +++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs @@ -1,17 +1,17 @@ use hir::{HasSource, InFile, InRealFile, Semantics}; use ide_db::{ - defs::Definition, helpers::visit_file_defs, FileId, FilePosition, FileRange, FxIndexSet, - RootDatabase, + FileId, FilePosition, FileRange, FxIndexSet, RootDatabase, defs::Definition, + helpers::visit_file_defs, }; use itertools::Itertools; -use syntax::{ast::HasName, AstNode, TextRange}; +use syntax::{AstNode, TextRange, ast::HasName}; use crate::{ + NavigationTarget, RunnableKind, annotations::fn_references::find_all_methods, goto_implementation::goto_implementation, references::find_all_refs, - runnables::{runnables, Runnable}, - NavigationTarget, RunnableKind, + runnables::{Runnable, runnables}, }; mod fn_references; @@ -209,9 +209,9 @@ fn should_skip_runnable(kind: &RunnableKind, binary_target: bool) -> bool { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; - use crate::{fixture, Annotation, AnnotationConfig}; + use crate::{Annotation, AnnotationConfig, fixture}; use super::AnnotationLocation; diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs b/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs index 08cc10509cb8a..427a2eff82017 100644 --- a/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs @@ -4,7 +4,7 @@ use hir::Semantics; use ide_assists::utils::test_related_attribute_syn; use ide_db::RootDatabase; -use syntax::{ast, ast::HasName, AstNode, SyntaxNode, TextRange}; +use syntax::{AstNode, SyntaxNode, TextRange, ast, ast::HasName}; use crate::FileId; @@ -34,8 +34,8 @@ fn method_range(item: SyntaxNode) -> Option<(TextRange, Option)> { mod tests { use syntax::TextRange; - use crate::fixture; use crate::TextSize; + use crate::fixture; use std::ops::RangeInclusive; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs index afd6f740c42c6..5c0e113d5c6a7 100644 --- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs +++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs @@ -4,14 +4,14 @@ use std::iter; use hir::Semantics; use ide_db::{ + FileRange, FxIndexMap, RootDatabase, defs::{Definition, NameClass, NameRefClass}, helpers::pick_best_token, search::FileReference, - FileRange, FxIndexMap, RootDatabase, }; -use syntax::{ast, AstNode, SyntaxKind::IDENT}; +use syntax::{AstNode, SyntaxKind::IDENT, ast}; -use crate::{goto_definition, FilePosition, NavigationTarget, RangeInfo, TryToNav}; +use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav, goto_definition}; #[derive(Debug, Clone)] pub struct CallItem { @@ -165,7 +165,7 @@ impl CallLocations { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use ide_db::FilePosition; use itertools::Itertools; diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 9bdc2e7d13337..a01afd242e3b3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -6,28 +6,29 @@ mod tests; mod intra_doc_links; use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; -use pulldown_cmark_to_cmark::{cmark_resume_with_options, Options as CMarkOptions}; +use pulldown_cmark_to_cmark::{Options as CMarkOptions, cmark_resume_with_options}; use stdx::format_to; use url::Url; -use hir::{db::HirDatabase, sym, Adt, AsAssocItem, AssocItem, AssocItemContainer, HasAttrs}; +use hir::{Adt, AsAssocItem, AssocItem, AssocItemContainer, HasAttrs, db::HirDatabase, sym}; use ide_db::{ + RootDatabase, base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, RootQueryDb}, defs::{Definition, NameClass, NameRefClass}, - documentation::{docs_with_rangemap, Documentation, HasDocs}, + documentation::{Documentation, HasDocs, docs_with_rangemap}, helpers::pick_best_token, - RootDatabase, }; use syntax::{ - ast::{self, IsString}, - match_ast, AstNode, AstToken, + AstNode, AstToken, SyntaxKind::*, - SyntaxNode, SyntaxToken, TextRange, TextSize, T, + SyntaxNode, SyntaxToken, T, TextRange, TextSize, + ast::{self, IsString}, + match_ast, }; use crate::{ - doc_links::intra_doc_links::{parse_intra_doc_link, strip_prefixes_suffixes}, FilePosition, Semantics, + doc_links::intra_doc_links::{parse_intra_doc_link, strip_prefixes_suffixes}, }; /// Web and local links to an item's documentation. diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/intra_doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/intra_doc_links.rs index 6cc240d652499..c331734c785ed 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/intra_doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/intra_doc_links.rs @@ -53,7 +53,7 @@ pub(super) fn strip_prefixes_suffixes(s: &str) -> &str { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use super::*; diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs index d70a3f9706cfd..91785be8d8bad 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs @@ -1,18 +1,19 @@ use std::iter; -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use hir::Semantics; use ide_db::{ + FilePosition, FileRange, RootDatabase, defs::Definition, documentation::{Documentation, HasDocs}, - FilePosition, FileRange, RootDatabase, }; use itertools::Itertools; -use syntax::{ast, match_ast, AstNode, SyntaxNode}; +use syntax::{AstNode, SyntaxNode, ast, match_ast}; use crate::{ + TryToNav, doc_links::{extract_definitions_from_docs, resolve_doc_path_for_def, rewrite_links}, - fixture, TryToNav, + fixture, }; fn check_external_docs( @@ -683,7 +684,9 @@ fn rewrite_intra_doc_link_with_anchor() { //! $0[PartialEq#derivable] fn main() {} "#, - expect!["[PartialEq#derivable](https://doc.rust-lang.org/stable/core/cmp/trait.PartialEq.html#derivable)"], + expect![ + "[PartialEq#derivable](https://doc.rust-lang.org/stable/core/cmp/trait.PartialEq.html#derivable)" + ], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index a18eb9049ff67..4811f1f691c8c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -1,12 +1,12 @@ use hir::db::ExpandDatabase; use hir::{ExpandResult, InFile, MacroFileIdExt, Semantics}; use ide_db::{ - base_db::Crate, helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, - RootDatabase, + FileId, RootDatabase, base_db::Crate, helpers::pick_best_token, + syntax_helpers::prettify_macro_expansion, }; use span::{Edition, SpanMap, SyntaxContext, TextRange, TextSize}; use stdx::format_to; -use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T}; +use syntax::{AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T, ast, ted}; use crate::FilePosition; @@ -289,7 +289,7 @@ fn _format( #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs index 76414854e91ef..a374f9752fcfa 100644 --- a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs +++ b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs @@ -3,11 +3,11 @@ use std::iter::successors; use hir::Semantics; use ide_db::RootDatabase; use syntax::{ - algo::{self, skip_trivia_token}, - ast::{self, AstNode, AstToken}, Direction, NodeOrToken, SyntaxKind::{self, *}, - SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, T, + SyntaxNode, SyntaxToken, T, TextRange, TextSize, TokenAtOffset, + algo::{self, skip_trivia_token}, + ast::{self, AstNode, AstToken}, }; use crate::FileRange; @@ -178,11 +178,7 @@ fn extend_tokens_from_range( .last()?; let range = first.text_range().cover(last.text_range()); - if range.contains_range(original_range) && original_range != range { - Some(range) - } else { - None - } + if range.contains_range(original_range) && original_range != range { Some(range) } else { None } } /// Find the shallowest node with same range, which allows us to traverse siblings. @@ -216,11 +212,7 @@ fn extend_single_word_in_comment_or_string( let to: TextSize = (cursor_position + end_idx).into(); let range = TextRange::new(from, to); - if range.is_empty() { - None - } else { - Some(range + leaf.text_range().start()) - } + if range.is_empty() { None } else { Some(range + leaf.text_range().start()) } } fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextSize) -> TextRange { diff --git a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs index b682c4bc0f791..956379e722d53 100644 --- a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs +++ b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs @@ -1,6 +1,6 @@ use ide_db::{ - base_db::{CrateOrigin, RootQueryDb}, FileId, FxIndexSet, RootDatabase, + base_db::{CrateOrigin, RootQueryDb}, }; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/src/tools/rust-analyzer/crates/ide/src/file_structure.rs b/src/tools/rust-analyzer/crates/ide/src/file_structure.rs index 52fbab6fa12b1..347da4e85b4aa 100644 --- a/src/tools/rust-analyzer/crates/ide/src/file_structure.rs +++ b/src/tools/rust-analyzer/crates/ide/src/file_structure.rs @@ -1,8 +1,8 @@ use ide_db::SymbolKind; use syntax::{ + AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, TextRange, WalkEvent, ast::{self, HasAttrs, HasGenericParams, HasName}, - match_ast, AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, TextRange, - WalkEvent, + match_ast, }; #[derive(Debug, Clone)] @@ -250,7 +250,7 @@ fn structure_token(token: SyntaxToken) -> Option { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use super::*; diff --git a/src/tools/rust-analyzer/crates/ide/src/fixture.rs b/src/tools/rust-analyzer/crates/ide/src/fixture.rs index a0612f48d37e8..73b7e771ca954 100644 --- a/src/tools/rust-analyzer/crates/ide/src/fixture.rs +++ b/src/tools/rust-analyzer/crates/ide/src/fixture.rs @@ -1,6 +1,6 @@ //! Utilities for creating `Analysis` instances for tests. use test_fixture::ChangeFixture; -use test_utils::{extract_annotations, RangeOrOffset}; +use test_utils::{RangeOrOffset, extract_annotations}; use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange}; diff --git a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs index e5a94ff9fe964..194e8c968f758 100755 --- a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs +++ b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs @@ -1,9 +1,10 @@ -use ide_db::{syntax_helpers::node_ext::vis_eq, FxHashSet}; +use ide_db::{FxHashSet, syntax_helpers::node_ext::vis_eq}; use syntax::{ - ast::{self, AstNode, AstToken}, - match_ast, Direction, NodeOrToken, SourceFile, + Direction, NodeOrToken, SourceFile, SyntaxKind::{self, *}, TextRange, TextSize, + ast::{self, AstNode, AstToken}, + match_ast, }; use std::hash::Hash; diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs index 3742edc8db84b..a022f1cede871 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs @@ -1,13 +1,13 @@ use hir::{AsAssocItem, Semantics}; use ide_db::{ - defs::{Definition, NameClass, NameRefClass}, RootDatabase, + defs::{Definition, NameClass, NameRefClass}, }; -use syntax::{ast, match_ast, AstNode, SyntaxKind::*, T}; +use syntax::{AstNode, SyntaxKind::*, T, ast, match_ast}; use crate::{ - goto_definition::goto_definition, navigation_target::TryToNav, FilePosition, NavigationTarget, - RangeInfo, + FilePosition, NavigationTarget, RangeInfo, goto_definition::goto_definition, + navigation_target::TryToNav, }; // Feature: Go to Declaration @@ -52,7 +52,7 @@ pub(crate) fn goto_declaration( }; let assoc = match def? { Definition::Module(module) => { - return Some(NavigationTarget::from_module_to_decl(db, module)) + return Some(NavigationTarget::from_module_to_decl(db, module)); } Definition::Const(c) => c.as_assoc_item(db), Definition::TypeAlias(ta) => ta.as_assoc_item(db), @@ -69,11 +69,7 @@ pub(crate) fn goto_declaration( .flatten() .collect(); - if info.is_empty() { - goto_definition(db, position) - } else { - Some(RangeInfo::new(range, info)) - } + if info.is_empty() { goto_definition(db, position) } else { Some(RangeInfo::new(range, info)) } } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs index 84138986f66ba..e920ff5ab4c24 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs @@ -1,28 +1,29 @@ use std::{iter, mem::discriminant}; use crate::{ + FilePosition, NavigationTarget, RangeInfo, TryToNav, UpmappingResult, doc_links::token_as_doc_comment, navigation_target::{self, ToNav}, - FilePosition, NavigationTarget, RangeInfo, TryToNav, UpmappingResult, }; use hir::{ - sym, AsAssocItem, AssocItem, CallableKind, FileRange, HasCrate, InFile, MacroFileIdExt, - ModuleDef, Semantics, + AsAssocItem, AssocItem, CallableKind, FileRange, HasCrate, InFile, MacroFileIdExt, ModuleDef, + Semantics, sym, }; use ide_db::{ + RootDatabase, SymbolKind, base_db::{AnchoredPath, RootQueryDb, SourceDatabase, Upcast}, defs::{Definition, IdentClass}, famous_defs::FamousDefs, helpers::pick_best_token, - RootDatabase, SymbolKind, }; use itertools::Itertools; use span::{Edition, FileId}; use syntax::{ - ast::{self, HasLoopBody}, - match_ast, AstNode, AstToken, + AstNode, AstToken, SyntaxKind::*, - SyntaxNode, SyntaxToken, TextRange, T, + SyntaxNode, SyntaxToken, T, TextRange, + ast::{self, HasLoopBody}, + match_ast, }; // Feature: Go to Definition diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs index e1d834b5d1c69..1bc28f28b6f57 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs @@ -1,10 +1,10 @@ use hir::{AsAssocItem, Impl, Semantics}; use ide_db::{ + RootDatabase, defs::{Definition, NameClass, NameRefClass}, helpers::pick_best_token, - RootDatabase, }; -use syntax::{ast, AstNode, SyntaxKind::*, T}; +use syntax::{AstNode, SyntaxKind::*, T, ast}; use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav}; diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs index ddc274a830352..bf48a6e23227e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs @@ -1,6 +1,6 @@ use hir::GenericParam; -use ide_db::{base_db::Upcast, defs::Definition, helpers::pick_best_token, RootDatabase}; -use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, T}; +use ide_db::{RootDatabase, base_db::Upcast, defs::Definition, helpers::pick_best_token}; +use syntax::{AstNode, SyntaxKind::*, SyntaxToken, T, ast, match_ast}; use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav}; diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs index 0ef7eb503f64a..f367d76a126dd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs +++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs @@ -1,7 +1,8 @@ use std::iter; -use hir::{db, FilePosition, FileRange, HirFileId, InFile, Semantics}; +use hir::{FilePosition, FileRange, HirFileId, InFile, Semantics, db}; use ide_db::{ + FxHashMap, FxHashSet, RootDatabase, base_db::salsa::AsDynDatabase, defs::{Definition, IdentClass}, helpers::pick_best_token, @@ -10,17 +11,17 @@ use ide_db::{ eq_label_lt, for_each_tail_expr, full_path_of_name_ref, is_closure_or_blk_with_modif, preorder_expr_with_ctx_checker, }, - FxHashMap, FxHashSet, RootDatabase, }; use span::EditionedFileId; use syntax::{ - ast::{self, HasLoopBody}, - match_ast, AstNode, + AstNode, SyntaxKind::{self, IDENT, INT_NUMBER}, - SyntaxToken, TextRange, WalkEvent, T, + SyntaxToken, T, TextRange, WalkEvent, + ast::{self, HasLoopBody}, + match_ast, }; -use crate::{goto_definition, navigation_target::ToNav, NavigationTarget, TryToNav}; +use crate::{NavigationTarget, TryToNav, goto_definition, navigation_target::ToNav}; #[derive(PartialEq, Eq, Hash)] pub struct HighlightedRange { @@ -156,7 +157,7 @@ fn highlight_references( match resolution.map(Definition::from) { Some(def) => iter::once(def).collect(), None => { - return Some(vec![HighlightedRange { range, category: ReferenceCategory::empty() }]) + return Some(vec![HighlightedRange { range, category: ReferenceCategory::empty() }]); } } } else { @@ -278,11 +279,7 @@ fn highlight_references( } res.extend(usages); - if res.is_empty() { - None - } else { - Some(res.into_iter().collect()) - } + if res.is_empty() { None } else { Some(res.into_iter().collect()) } } fn hl_exit_points( diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 04189ed52aa79..ea1f673e5be1a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -7,26 +7,26 @@ use std::{iter, ops::Not}; use either::Either; use hir::{ - db::DefDatabase, DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, - Semantics, + DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics, + db::DefDatabase, }; use ide_db::{ + FileRange, FxIndexSet, Ranker, RootDatabase, defs::{Definition, IdentClass, NameRefClass, OperatorClass}, famous_defs::FamousDefs, helpers::pick_best_token, - FileRange, FxIndexSet, Ranker, RootDatabase, }; -use itertools::{multizip, Itertools}; +use itertools::{Itertools, multizip}; use span::Edition; -use syntax::{ast, AstNode, SyntaxKind::*, SyntaxNode, T}; +use syntax::{AstNode, SyntaxKind::*, SyntaxNode, T, ast}; use crate::{ + FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, TryToNav, doc_links::token_as_doc_comment, markdown_remove::remove_markdown, markup::Markup, navigation_target::UpmappingResult, runnables::{runnable_fn, runnable_mod}, - FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, TryToNav, }; #[derive(Clone, Debug, PartialEq, Eq)] pub struct HoverConfig { @@ -512,7 +512,7 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option { - return it.try_to_nav(db).map(UpmappingResult::call_site).map(to_action) + return it.try_to_nav(db).map(UpmappingResult::call_site).map(to_action); } Definition::Adt(it) => Some(it), Definition::SelfType(it) => it.self_ty(db).as_adt(), diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index 1d807fb14c7bf..cf2ff1c9560dc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -3,33 +3,34 @@ use std::{env, mem, ops::Not}; use either::Either; use hir::{ - db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DisplayTarget, DropGlue, + Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DisplayTarget, DropGlue, DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError, MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, + db::ExpandDatabase, }; use ide_db::{ + RootDatabase, defs::Definition, documentation::HasDocs, famous_defs::FamousDefs, generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES}, syntax_helpers::prettify_macro_expansion, - RootDatabase, }; use itertools::Itertools; use rustc_apfloat::{ - ieee::{Half as f16, Quad as f128}, Float, + ieee::{Half as f16, Quad as f128}, }; use span::Edition; use stdx::format_to; -use syntax::{algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxToken, T}; +use syntax::{AstNode, AstToken, Direction, SyntaxToken, T, algo, ast, match_ast}; use crate::{ - doc_links::{remove_links, rewrite_links}, - hover::{notable_traits, walk_and_push_ty, SubstTyLen}, - interpret::render_const_eval_error, HoverAction, HoverConfig, HoverResult, Markup, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, + doc_links::{remove_links, rewrite_links}, + hover::{SubstTyLen, notable_traits, walk_and_push_ty}, + interpret::render_const_eval_error, }; pub(super) fn type_info_of( @@ -345,11 +346,7 @@ pub(super) fn try_for_lint(attr: &ast::Attr, token: &SyntaxToken) -> Option return None, }; @@ -417,7 +414,7 @@ fn definition_owner_name(db: &RootDatabase, def: Definition, edition: Edition) - "{}::{}", name.display(db, edition), it.name(db).display(db, edition) - )) + )); } None => Some(it.name(db)), } @@ -435,7 +432,7 @@ fn definition_owner_name(db: &RootDatabase, def: Definition, edition: Edition) - "{}::{}", name.display(db, edition), it.name(db)?.display(db, edition) - )) + )); } None => it.name(db), } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index afddeb6deaa62..0266b87499da2 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -1,9 +1,9 @@ -use expect_test::{expect, Expect}; -use ide_db::{base_db::SourceDatabase, FileRange}; +use expect_test::{Expect, expect}; +use ide_db::{FileRange, base_db::SourceDatabase}; use syntax::TextRange; use crate::{ - fixture, HoverConfig, HoverDocFormat, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, + HoverConfig, HoverDocFormat, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, fixture, }; const HOVER_BASE_CONFIG: HoverConfig = HoverConfig { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 57adf3e2a4721..a260944d05536 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -5,21 +5,22 @@ use std::{ use either::Either; use hir::{ - sym, ClosureStyle, DisplayTarget, HasVisibility, HirDisplay, HirDisplayError, HirWrite, - ModuleDef, ModuleDefId, Semantics, + ClosureStyle, DisplayTarget, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef, + ModuleDefId, Semantics, sym, }; -use ide_db::{base_db::salsa::AsDynDatabase, famous_defs::FamousDefs, FileRange, RootDatabase}; -use ide_db::{text_edit::TextEdit, FxHashSet}; +use ide_db::{FileRange, RootDatabase, base_db::salsa::AsDynDatabase, famous_defs::FamousDefs}; +use ide_db::{FxHashSet, text_edit::TextEdit}; use itertools::Itertools; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use span::EditionedFileId; use stdx::never; use syntax::{ + SmolStr, SyntaxNode, TextRange, TextSize, WalkEvent, ast::{self, AstNode, HasGenericParams}, - format_smolstr, match_ast, SmolStr, SyntaxNode, TextRange, TextSize, WalkEvent, + format_smolstr, match_ast, }; -use crate::{navigation_target::TryToNav, FileId}; +use crate::{FileId, navigation_target::TryToNav}; mod adjustment; mod bind_pat; @@ -843,9 +844,9 @@ mod tests { use itertools::Itertools; use test_utils::extract_annotations; - use crate::inlay_hints::{AdjustmentHints, AdjustmentHintsMode}; use crate::DiscriminantHints; - use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints}; + use crate::inlay_hints::{AdjustmentHints, AdjustmentHintsMode}; + use crate::{LifetimeElisionHints, fixture, inlay_hints::InlayHintsConfig}; use super::{ClosureReturnTypeHints, GenericParameterHints, InlayFieldsToResolve}; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs index 91b8187295236..f2844a2eaa614 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs @@ -13,7 +13,7 @@ use hir::{ use ide_db::famous_defs::FamousDefs; use ide_db::text_edit::TextEditBuilder; -use syntax::ast::{self, prec::ExprPrecedence, AstNode}; +use syntax::ast::{self, AstNode, prec::ExprPrecedence}; use crate::{ AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintLabel, InlayHintLabelPart, @@ -224,7 +224,7 @@ fn mode_and_needs_parens_for_adjustment_hints( expr: &ast::Expr, mode: AdjustmentHintsMode, ) -> (bool, bool, bool) { - use {std::cmp::Ordering::*, AdjustmentHintsMode::*}; + use {AdjustmentHintsMode::*, std::cmp::Ordering::*}; match mode { Prefix | Postfix => { @@ -284,8 +284,8 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check_with_config, DISABLED_CONFIG}, AdjustmentHints, AdjustmentHintsMode, InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index aab8a3f873994..10cb91713d259 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -4,7 +4,7 @@ //! let _x /* i32 */= f(4, 4); //! ``` use hir::{DisplayTarget, Semantics}; -use ide_db::{famous_defs::FamousDefs, RootDatabase}; +use ide_db::{RootDatabase, famous_defs::FamousDefs}; use itertools::Itertools; use syntax::{ @@ -13,8 +13,8 @@ use syntax::{ }; use crate::{ - inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, + inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, }; pub(super) fn hints( @@ -181,10 +181,10 @@ mod tests { use syntax::{TextRange, TextSize}; use test_utils::extract_annotations; - use crate::{fixture, inlay_hints::InlayHintsConfig, ClosureReturnTypeHints}; + use crate::{ClosureReturnTypeHints, fixture, inlay_hints::InlayHintsConfig}; use crate::inlay_hints::tests::{ - check, check_edit, check_no_edit, check_with_config, DISABLED_CONFIG, TEST_CONFIG, + DISABLED_CONFIG, TEST_CONFIG, check, check_edit, check_no_edit, check_with_config, }; #[track_caller] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs index 5bbb4fe4e66e3..d29173206889d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs @@ -128,8 +128,8 @@ mod tests { use expect_test::expect; use crate::{ - inlay_hints::tests::{check_edit, check_with_config, DISABLED_CONFIG}, InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_edit, check_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs index e9b728bcaa75d..8ddbfaeffe879 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs @@ -1,7 +1,7 @@ //! Implementation of trait bound hints. //! //! Currently this renders the implied `Sized` bound. -use ide_db::{famous_defs::FamousDefs, FileRange}; +use ide_db::{FileRange, famous_defs::FamousDefs}; use span::EditionedFileId; use syntax::ast::{self, AstNode, HasTypeBounds}; @@ -86,7 +86,7 @@ mod tests { use crate::inlay_hints::InlayHintsConfig; - use crate::inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG}; + use crate::inlay_hints::tests::{DISABLED_CONFIG, check_expect, check_with_config}; #[track_caller] fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs index 604719bc366f5..ff157fa171b50 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs @@ -2,8 +2,8 @@ use hir::DisplayTarget; use ide_db::famous_defs::FamousDefs; use syntax::{ - ast::{self, AstNode}, Direction, NodeOrToken, SyntaxKind, T, + ast::{self, AstNode}, }; use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -76,16 +76,15 @@ pub(super) fn hints( #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use ide_db::text_edit::{TextRange, TextSize}; use crate::{ - fixture, + InlayHintsConfig, fixture, inlay_hints::{ - tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG}, LazyProperty, + tests::{DISABLED_CONFIG, TEST_CONFIG, check_expect, check_with_config}, }, - InlayHintsConfig, }; #[track_caller] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs index bec6d38ee9cac..de9ca8c000f0b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs @@ -7,13 +7,14 @@ use hir::{DisplayTarget, HirDisplay, Semantics}; use ide_db::{FileRange, RootDatabase}; use span::EditionedFileId; use syntax::{ + SyntaxKind, SyntaxNode, T, ast::{self, AstNode, HasLoopBody, HasName}, - match_ast, SyntaxKind, SyntaxNode, T, + match_ast, }; use crate::{ - inlay_hints::LazyProperty, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, - InlayKind, + InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind, + inlay_hints::LazyProperty, }; pub(super) fn hints( @@ -159,8 +160,8 @@ pub(super) fn hints( #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check_with_config, DISABLED_CONFIG}, InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs index 9b981c0a3acf7..07a86b2c9d3f4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs @@ -4,7 +4,7 @@ use ide_db::famous_defs::FamousDefs; use ide_db::text_edit::{TextRange, TextSize}; use span::EditionedFileId; -use stdx::{never, TupleExt}; +use stdx::{TupleExt, never}; use syntax::ast::{self, AstNode}; use crate::{ @@ -96,8 +96,8 @@ pub(super) fn hints( #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check_with_config, DISABLED_CONFIG}, InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs index 61c9c25fe7396..16551b64f7ef6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs @@ -6,8 +6,8 @@ use ide_db::famous_defs::FamousDefs; use syntax::ast::{self, AstNode}; use crate::{ - inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, ClosureReturnTypeHints, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, + inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, }; pub(super) fn hints( @@ -80,7 +80,7 @@ pub(super) fn hints( #[cfg(test)] mod tests { - use crate::inlay_hints::tests::{check_with_config, DISABLED_CONFIG}; + use crate::inlay_hints::tests::{DISABLED_CONFIG, check_with_config}; use super::*; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs index f1e1955d14ca7..827a0438dd022 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs @@ -6,7 +6,7 @@ //! ``` use hir::Semantics; use ide_db::text_edit::TextEdit; -use ide_db::{famous_defs::FamousDefs, RootDatabase}; +use ide_db::{RootDatabase, famous_defs::FamousDefs}; use span::EditionedFileId; use syntax::ast::{self, AstNode, HasName}; @@ -107,8 +107,8 @@ mod tests { use expect_test::expect; use crate::inlay_hints::{ - tests::{check_edit, check_with_config, DISABLED_CONFIG}, DiscriminantHints, InlayHintsConfig, + tests::{DISABLED_CONFIG, check_edit, check_with_config}, }; #[track_caller] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs index 652dff0bc56e7..20f54b2cd19d6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs @@ -1,7 +1,7 @@ //! Extern block hints use ide_db::{famous_defs::FamousDefs, text_edit::TextEdit}; use span::EditionedFileId; -use syntax::{ast, AstNode, SyntaxToken}; +use syntax::{AstNode, SyntaxToken, ast}; use crate::{InlayHint, InlayHintsConfig}; @@ -98,7 +98,7 @@ fn item_hint( #[cfg(test)] mod tests { - use crate::inlay_hints::tests::{check_with_config, DISABLED_CONFIG}; + use crate::inlay_hints::tests::{DISABLED_CONFIG, check_with_config}; #[test] fn unadorned() { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs index 762a4c2655181..fc1083fdca657 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs @@ -1,12 +1,12 @@ //! Implementation of inlay hints for generic parameters. use ide_db::{active_parameter::generic_def_for_node, famous_defs::FamousDefs}; use syntax::{ - ast::{self, AnyHasGenericArgs, HasGenericArgs, HasName}, AstNode, + ast::{self, AnyHasGenericArgs, HasGenericArgs, HasName}, }; use crate::{ - inlay_hints::GenericParameterHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, + InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, inlay_hints::GenericParameterHints, }; use super::param_name::is_argument_similar_to_param_name; @@ -145,11 +145,11 @@ fn get_string_representation(arg: &ast::GenericArg) -> Option { #[cfg(test)] mod tests { use crate::{ + InlayHintsConfig, inlay_hints::{ - tests::{check_with_config, DISABLED_CONFIG}, GenericParameterHints, + tests::{DISABLED_CONFIG, check_with_config}, }, - InlayHintsConfig, }; #[track_caller] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs index 390139d214eb0..668232d301c95 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs @@ -6,16 +6,17 @@ //! } //! ``` use hir::{ + ChalkTyInterner, DefWithBody, db::{DefDatabase as _, HirDatabase as _}, mir::{MirSpan, TerminatorKind}, - ChalkTyInterner, DefWithBody, }; -use ide_db::{famous_defs::FamousDefs, FileRange}; +use ide_db::{FileRange, famous_defs::FamousDefs}; use span::EditionedFileId; use syntax::{ + ToSmolStr, ast::{self, AstNode}, - match_ast, ToSmolStr, + match_ast, }; use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -143,8 +144,8 @@ fn nearest_token_after_node( #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check_with_config, DISABLED_CONFIG}, InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, }; const ONLY_DROP_CONFIG: InlayHintsConfig = diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs index ae5b519b43d00..f3be09f30a135 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs @@ -7,8 +7,8 @@ use ide_db::famous_defs::FamousDefs; use ide_db::text_edit::TextEdit; use span::EditionedFileId; use syntax::{ - ast::{self, AstNode}, SyntaxKind, + ast::{self, AstNode}, }; use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, LifetimeElisionHints}; @@ -56,8 +56,8 @@ pub(super) fn hints( #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check_with_config, TEST_CONFIG}, InlayHintsConfig, LifetimeElisionHints, + inlay_hints::tests::{TEST_CONFIG, check_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs index 7b0b3e19f2f08..baba49a427d19 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs @@ -4,18 +4,18 @@ //! ``` use std::iter; -use ide_db::{famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty, FxHashMap}; +use ide_db::{FxHashMap, famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty}; use itertools::Itertools; use span::EditionedFileId; +use syntax::{SmolStr, format_smolstr}; use syntax::{ - ast::{self, AstNode, HasGenericParams, HasName}, SyntaxKind, SyntaxToken, + ast::{self, AstNode, HasGenericParams, HasName}, }; -use syntax::{format_smolstr, SmolStr}; use crate::{ - inlay_hints::InlayHintCtx, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, - LifetimeElisionHints, + InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, LifetimeElisionHints, + inlay_hints::InlayHintCtx, }; pub(super) fn fn_hints( @@ -274,7 +274,8 @@ fn hints_( }); let ctx = &*ctx; move || { - generic.by_ref() + generic + .by_ref() .find(|s| ctx.lifetime_stacks.iter().flat_map(|it| it.iter()).all(|n| n != s)) .unwrap_or_default() } @@ -406,8 +407,8 @@ fn hints_( #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check, check_with_config, TEST_CONFIG}, InlayHintsConfig, LifetimeElisionHints, + inlay_hints::tests::{TEST_CONFIG, check, check_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs index 8f01b1bd38b50..44ea5351fbdd6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs @@ -6,13 +6,13 @@ use either::Either; use hir::{Callable, Semantics}; -use ide_db::{famous_defs::FamousDefs, RootDatabase}; +use ide_db::{RootDatabase, famous_defs::FamousDefs}; use span::EditionedFileId; use stdx::to_lower_snake_case; use syntax::{ - ast::{self, AstNode, HasArgList, HasName, UnaryOp}, ToSmolStr, + ast::{self, AstNode, HasArgList, HasName, UnaryOp}, }; use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -257,8 +257,8 @@ fn is_adt_constructor_similar_to_param_name( #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check_with_config, DISABLED_CONFIG}, InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, }; #[track_caller] diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs index de9b0e98a4beb..d67d84588402e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs @@ -5,7 +5,7 @@ //! ``` use ide_db::famous_defs::FamousDefs; use span::EditionedFileId; -use syntax::{ast, SyntaxToken, T}; +use syntax::{SyntaxToken, T, ast}; use crate::{InlayHint, InlayHintsConfig}; @@ -41,8 +41,8 @@ fn inlay_hint(token: SyntaxToken) -> InlayHint { #[cfg(test)] mod tests { use crate::{ - inlay_hints::tests::{check_with_config, DISABLED_CONFIG}, InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, }; #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs index 0499d8a447fbf..8f9d2d6bf111b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -1,8 +1,8 @@ use hir::{ConstEvalError, DefWithBody, DisplayTarget, Semantics}; -use ide_db::{base_db::SourceDatabase, FilePosition, LineIndexDatabase, RootDatabase}; +use ide_db::{FilePosition, LineIndexDatabase, RootDatabase, base_db::SourceDatabase}; use std::time::{Duration, Instant}; use stdx::format_to; -use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; +use syntax::{AstNode, TextRange, algo::ancestors_at_offset, ast}; // Feature: Interpret A Function, Static Or Const. // diff --git a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs index ea18a97070c3a..0188c105faa78 100644 --- a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs +++ b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs @@ -2,10 +2,10 @@ use ide_assists::utils::extract_trivial_expression; use ide_db::syntax_helpers::node_ext::expr_as_name_ref; use itertools::Itertools; use syntax::{ - ast::{self, AstNode, AstToken, IsString}, NodeOrToken, SourceFile, SyntaxElement, SyntaxKind::{self, USE_TREE, WHITESPACE}, - SyntaxToken, TextRange, TextSize, T, + SyntaxToken, T, TextRange, TextSize, + ast::{self, AstNode, AstToken, IsString}, }; use ide_db::text_edit::{TextEdit, TextEditBuilder}; diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index 79863f4680d80..f8eb676bfc442 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -61,19 +61,20 @@ use std::panic::UnwindSafe; use cfg::CfgOptions; use fetch_crates::CrateInfo; -use hir::{sym, ChangeWithProcMacros}; +use hir::{ChangeWithProcMacros, sym}; use ide_db::{ + FxHashMap, FxIndexSet, LineIndexDatabase, base_db::{ - salsa::{AsDynDatabase, Cancelled}, CrateOrigin, CrateWorkspaceData, Env, FileSet, RootQueryDb, SourceDatabase, Upcast, VfsPath, + salsa::{AsDynDatabase, Cancelled}, }, - prime_caches, symbol_index, FxHashMap, FxIndexSet, LineIndexDatabase, + prime_caches, symbol_index, }; use span::EditionedFileId; use syntax::SourceFile; use triomphe::Arc; -use view_memory_layout::{view_memory_layout, RecursiveMemoryLayout}; +use view_memory_layout::{RecursiveMemoryLayout, view_memory_layout}; use crate::navigation_target::ToNav; @@ -110,8 +111,8 @@ pub use crate::{ StaticIndex, StaticIndexedFile, TokenId, TokenStaticData, VendoredLibrariesConfig, }, syntax_highlighting::{ - tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag}, HighlightConfig, HlRange, + tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag}, }, test_explorer::{TestItem, TestItemKind}, }; @@ -125,6 +126,7 @@ pub use ide_completion::{ }; pub use ide_db::text_edit::{Indel, TextEdit}; pub use ide_db::{ + FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind, base_db::{Crate, CrateGraphBuilder, FileChange, SourceRoot, SourceRootId}, documentation::Documentation, label::Label, @@ -133,7 +135,6 @@ pub use ide_db::{ search::{ReferenceCategory, SearchScope}, source_change::{FileSystemEdit, SnippetEdit, SourceChange}, symbol_index::Query, - FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind, }; pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode}; pub use ide_ssr::SsrError; diff --git a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs index 67346ea9cf90f..b2b91d6e3cf34 100644 --- a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs +++ b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs @@ -1,6 +1,6 @@ use syntax::{ + SourceFile, SyntaxKind, T, TextSize, ast::{self, AstNode}, - SourceFile, SyntaxKind, TextSize, T, }; // Feature: Matching Brace diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 5754b4fa82f43..4a06cd919fc3b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs @@ -5,15 +5,15 @@ use core::fmt; use hir::{Adt, AsAssocItem, Crate, HirDisplay, MacroKind, Semantics}; use ide_db::{ + FilePosition, RootDatabase, base_db::{CrateOrigin, LangCrateOrigin}, defs::{Definition, IdentClass}, helpers::pick_best_token, - FilePosition, RootDatabase, }; use itertools::Itertools; use syntax::{AstNode, SyntaxKind::*, T}; -use crate::{doc_links::token_as_doc_comment, parent_module::crates_for, RangeInfo}; +use crate::{RangeInfo, doc_links::token_as_doc_comment, parent_module::crates_for}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum MonikerDescriptorKind { @@ -194,11 +194,7 @@ pub(crate) fn def_to_kind(db: &RootDatabase, def: Definition) -> SymbolInformati Definition::Function(it) => { if it.as_assoc_item(db).is_some() { if it.has_self_param(db) { - if it.has_body(db) { - Method - } else { - TraitMethod - } + if it.has_body(db) { Method } else { TraitMethod } } else { StaticMethod } @@ -405,7 +401,7 @@ fn display(db: &RootDatabase, module: hir::Module, it: T) -> Stri #[cfg(test)] mod tests { - use crate::{fixture, MonikerResult}; + use crate::{MonikerResult, fixture}; use super::MonikerKind; diff --git a/src/tools/rust-analyzer/crates/ide/src/move_item.rs b/src/tools/rust-analyzer/crates/ide/src/move_item.rs index 3fb3a788b9182..f3bb3df1cd8d7 100644 --- a/src/tools/rust-analyzer/crates/ide/src/move_item.rs +++ b/src/tools/rust-analyzer/crates/ide/src/move_item.rs @@ -3,9 +3,9 @@ use std::{iter::once, mem}; use hir::Semantics; use ide_db::syntax_helpers::tree_diff::diff; use ide_db::text_edit::{TextEdit, TextEditBuilder}; -use ide_db::{helpers::pick_best_token, FileRange, RootDatabase}; +use ide_db::{FileRange, RootDatabase, helpers::pick_best_token}; use itertools::Itertools; -use syntax::{ast, match_ast, AstNode, SyntaxElement, SyntaxKind, SyntaxNode, TextRange}; +use syntax::{AstNode, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, ast, match_ast}; #[derive(Copy, Clone, Debug)] pub enum Direction { @@ -174,7 +174,7 @@ fn replace_nodes<'a>( #[cfg(test)] mod tests { use crate::fixture; - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use crate::Direction; diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index d67aaac06fb95..4679794287b2e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -5,19 +5,20 @@ use std::fmt; use arrayvec::ArrayVec; use either::Either; use hir::{ - db::ExpandDatabase, symbols::FileSymbol, AssocItem, FieldSource, HasContainer, HasCrate, - HasSource, HirDisplay, HirFileId, InFile, LocalSource, ModuleSource, + AssocItem, FieldSource, HasContainer, HasCrate, HasSource, HirDisplay, HirFileId, InFile, + LocalSource, ModuleSource, db::ExpandDatabase, symbols::FileSymbol, }; use ide_db::{ + FileId, FileRange, RootDatabase, SymbolKind, defs::Definition, documentation::{Documentation, HasDocs}, - FileId, FileRange, RootDatabase, SymbolKind, }; use span::Edition; use stdx::never; use syntax::{ + AstNode, SmolStr, SyntaxNode, TextRange, ToSmolStr, ast::{self, HasName}, - format_smolstr, AstNode, SmolStr, SyntaxNode, TextRange, ToSmolStr, + format_smolstr, }; /// `NavigationTarget` represents an element in the editor's UI which you can @@ -953,7 +954,7 @@ fn orig_range_r( mod tests { use expect_test::expect; - use crate::{fixture, Query}; + use crate::{Query, fixture}; #[test] fn test_nav_for_symbol() { diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs index 06ab4750ac5b9..4e70bf3af3aaa 100644 --- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs +++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs @@ -1,7 +1,7 @@ -use hir::{db::DefDatabase, Semantics}; +use hir::{Semantics, db::DefDatabase}; use ide_db::{ - base_db::{Crate, RootQueryDb, Upcast}, FileId, FilePosition, RootDatabase, + base_db::{Crate, RootQueryDb, Upcast}, }; use itertools::Itertools; use syntax::{ diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs index 069818d50e76a..71c42cc8b579e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/references.rs @@ -11,21 +11,22 @@ use hir::{PathResolution, Semantics}; use ide_db::{ + FileId, RootDatabase, defs::{Definition, NameClass, NameRefClass}, search::{ReferenceCategory, SearchScope, UsageSearchResult}, - FileId, RootDatabase, }; use itertools::Itertools; use nohash_hasher::IntMap; use span::Edition; use syntax::{ - ast::{self, HasName}, - match_ast, AstNode, + AstNode, SyntaxKind::*, - SyntaxNode, TextRange, TextSize, T, + SyntaxNode, T, TextRange, TextSize, + ast::{self, HasName}, + match_ast, }; -use crate::{highlight_related, FilePosition, HighlightedRange, NavigationTarget, TryToNav}; +use crate::{FilePosition, HighlightedRange, NavigationTarget, TryToNav, highlight_related}; #[derive(Debug, Clone)] pub struct ReferenceSearchResult { @@ -336,12 +337,12 @@ fn handle_control_flow_keywords( #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use ide_db::FileId; use span::EditionedFileId; use stdx::format_to; - use crate::{fixture, SearchScope}; + use crate::{SearchScope, fixture}; #[test] fn exclude_tests() { diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index 57d297700ad37..8fdd460a09f8e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -6,15 +6,15 @@ use hir::{AsAssocItem, HirFileIdExt, InFile, Semantics}; use ide_db::{ + FileId, FileRange, RootDatabase, base_db::salsa::AsDynDatabase, defs::{Definition, NameClass, NameRefClass}, - rename::{bail, format_err, source_edit_from_references, IdentifierKind}, + rename::{IdentifierKind, bail, format_err, source_edit_from_references}, source_change::SourceChangeBuilder, - FileId, FileRange, RootDatabase, }; use itertools::Itertools; use stdx::{always, never}; -use syntax::{ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize}; +use syntax::{AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize, ast}; use ide_db::text_edit::TextEdit; @@ -446,7 +446,7 @@ fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Opt #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use ide_db::source_change::SourceChange; use ide_db::text_edit::TextEdit; use itertools::Itertools; diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index f2cb3c1f991a7..44dd38ed9c99d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -4,28 +4,29 @@ use arrayvec::ArrayVec; use ast::HasName; use cfg::{CfgAtom, CfgExpr}; use hir::{ - db::HirDatabase, sym, symbols::FxIndexSet, AsAssocItem, AttrsWithOwner, HasAttrs, HasCrate, - HasSource, HirFileIdExt, ModPath, Name, PathKind, Semantics, Symbol, + AsAssocItem, AttrsWithOwner, HasAttrs, HasCrate, HasSource, HirFileIdExt, ModPath, Name, + PathKind, Semantics, Symbol, db::HirDatabase, sym, symbols::FxIndexSet, }; use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn}; use ide_db::{ + FilePosition, FxHashMap, FxIndexMap, RootDatabase, SymbolKind, base_db::RootQueryDb, defs::Definition, documentation::docs_from_attrs, helpers::visit_file_defs, search::{FileReferenceNode, SearchScope}, - FilePosition, FxHashMap, FxIndexMap, RootDatabase, SymbolKind, }; use itertools::Itertools; use smallvec::SmallVec; use span::{Edition, TextSize}; use stdx::format_to; use syntax::{ + SmolStr, SyntaxNode, ToSmolStr, ast::{self, AstNode}, - format_smolstr, SmolStr, SyntaxNode, ToSmolStr, + format_smolstr, }; -use crate::{references, FileId, NavigationTarget, ToNav, TryToNav}; +use crate::{FileId, NavigationTarget, ToNav, TryToNav, references}; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Runnable { @@ -752,7 +753,7 @@ impl UpdateTest { #[cfg(test)] mod tests { - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index ce3c4238b5b18..bd14f830dd4d3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -8,17 +8,17 @@ use hir::{ AssocItem, DisplayTarget, GenericParam, HirDisplay, ModuleDef, PathResolution, Semantics, Trait, }; use ide_db::{ + FilePosition, FxIndexMap, active_parameter::{callable_for_node, generic_def_for_node}, documentation::{Documentation, HasDocs}, - FilePosition, FxIndexMap, }; use span::Edition; use stdx::format_to; use syntax::{ - algo, + AstNode, Direction, NodeOrToken, SyntaxElementChildren, SyntaxNode, SyntaxToken, T, TextRange, + TextSize, ToSmolStr, algo, ast::{self, AstChildren, HasArgList}, - match_ast, AstNode, Direction, NodeOrToken, SyntaxElementChildren, SyntaxNode, SyntaxToken, - TextRange, TextSize, ToSmolStr, T, + match_ast, }; use crate::RootDatabase; @@ -327,7 +327,7 @@ fn signature_help_for_generics( } // These don't have generic args that can be specified hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) | hir::GenericDef::Static(_) => { - return None + return None; } } @@ -695,9 +695,8 @@ fn signature_help_for_tuple_pat_ish( } #[cfg(test)] mod tests { - - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use ide_db::FilePosition; use stdx::format_to; use test_fixture::ChangeFixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/ssr.rs b/src/tools/rust-analyzer/crates/ide/src/ssr.rs index 81b5988126519..5e439bd38a58a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/ssr.rs +++ b/src/tools/rust-analyzer/crates/ide/src/ssr.rs @@ -3,7 +3,7 @@ //! depend on the ide_ssr crate. use ide_assists::{Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel}; -use ide_db::{label::Label, source_change::SourceChange, FileRange, RootDatabase}; +use ide_db::{FileRange, RootDatabase, label::Label, source_change::SourceChange}; pub(crate) fn ssr_assists( db: &RootDatabase, @@ -59,8 +59,8 @@ mod tests { use expect_test::expect; use ide_assists::{Assist, AssistResolveStrategy}; use ide_db::{ - base_db::salsa::Durability, symbol_index::SymbolsDatabase, FileRange, FxHashSet, - RootDatabase, + FileRange, FxHashSet, RootDatabase, base_db::salsa::Durability, + symbol_index::SymbolsDatabase, }; use test_fixture::WithFixture; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index c1562769309ed..1244132065045 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -1,25 +1,25 @@ //! This module provides `StaticIndex` which is used for powering //! read-only code browsers and emitting LSIF -use hir::{db::HirDatabase, Crate, HirFileIdExt, Module, Semantics}; +use hir::{Crate, HirFileIdExt, Module, Semantics, db::HirDatabase}; use ide_db::{ + FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, base_db::{RootQueryDb, SourceDatabase, VfsPath}, defs::Definition, documentation::Documentation, famous_defs::FamousDefs, helpers::get_definition, - FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, }; use span::Edition; -use syntax::{AstNode, SyntaxKind::*, SyntaxNode, TextRange, T}; +use syntax::{AstNode, SyntaxKind::*, SyntaxNode, T, TextRange}; use crate::navigation_target::UpmappingResult; use crate::{ - hover::{hover_for_definition, SubstTyLen}, + Analysis, Fold, HoverConfig, HoverResult, InlayHint, InlayHintsConfig, TryToNav, + hover::{SubstTyLen, hover_for_definition}, inlay_hints::{AdjustmentHintsMode, InlayFieldsToResolve}, - moniker::{def_to_kind, def_to_moniker, MonikerResult, SymbolInformationKind}, + moniker::{MonikerResult, SymbolInformationKind, def_to_kind, def_to_moniker}, parent_module::crates_for, - Analysis, Fold, HoverConfig, HoverResult, InlayHint, InlayHintsConfig, TryToNav, }; /// A static representation of fully analyzed source code. @@ -307,8 +307,8 @@ impl StaticIndex<'_> { #[cfg(test)] mod tests { - use crate::{fixture, StaticIndex}; - use ide_db::{base_db::VfsPath, FileRange, FxHashSet}; + use crate::{StaticIndex, fixture}; + use ide_db::{FileRange, FxHashSet, base_db::VfsPath}; use syntax::TextSize; use super::VendoredLibrariesConfig; diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index 52d38041ec125..55a0db2d82046 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -1,5 +1,5 @@ -use ide_db::base_db::{BuiltCrateData, ExtraCrateData}; use ide_db::RootDatabase; +use ide_db::base_db::{BuiltCrateData, ExtraCrateData}; use itertools::Itertools; use span::FileId; use stdx::format_to; diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index ef5d480b49c70..79e5baf4a77d3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -19,24 +19,24 @@ use hir::{ DefWithBody, HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics, }; use ide_db::{ - base_db::salsa::AsDynDatabase, FxHashMap, FxHashSet, Ranker, RootDatabase, SymbolKind, + FxHashMap, FxHashSet, Ranker, RootDatabase, SymbolKind, base_db::salsa::AsDynDatabase, }; use span::EditionedFileId; use syntax::{ - ast::{self, IsString}, AstNode, AstToken, NodeOrToken, SyntaxKind::*, - SyntaxNode, SyntaxToken, TextRange, WalkEvent, T, + SyntaxNode, SyntaxToken, T, TextRange, WalkEvent, + ast::{self, IsString}, }; use crate::{ + FileId, HlMod, HlOperator, HlPunct, HlTag, syntax_highlighting::{ escape::{highlight_escape_byte, highlight_escape_char, highlight_escape_string}, format::highlight_format_string, highlights::Highlights, tags::Highlight, }, - FileId, HlMod, HlOperator, HlPunct, HlTag, }; pub(crate) use html::highlight_as_html; diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs index cc02aff2acf8a..00f5b3264cbac 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs @@ -1,15 +1,15 @@ //! Syntax highlighting for format macro strings. use ide_db::{ - defs::Definition, - syntax_helpers::format_string::{is_format_string, lex_format_specifiers, FormatSpecifier}, SymbolKind, + defs::Definition, + syntax_helpers::format_string::{FormatSpecifier, is_format_string, lex_format_specifiers}, }; use span::Edition; -use syntax::{ast, AstToken}; +use syntax::{AstToken, ast}; use crate::{ - syntax_highlighting::{highlight::highlight_def, highlights::Highlights}, HlRange, HlTag, + syntax_highlighting::{highlight::highlight_def, highlights::Highlights}, }; pub(super) fn highlight_format_string( diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index 2b7c871a386d2..fb25f0015585e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -5,21 +5,21 @@ use std::ops::ControlFlow; use either::Either; use hir::{AsAssocItem, HasVisibility, MacroFileIdExt, Semantics}; use ide_db::{ + FxHashMap, RootDatabase, SymbolKind, defs::{Definition, IdentClass, NameClass, NameRefClass}, syntax_helpers::node_ext::walk_pat, - FxHashMap, RootDatabase, SymbolKind, }; use span::Edition; use stdx::hash_once; use syntax::{ - ast, match_ast, AstNode, AstPtr, AstToken, NodeOrToken, + AstNode, AstPtr, AstToken, NodeOrToken, SyntaxKind::{self, *}, - SyntaxNode, SyntaxNodePtr, SyntaxToken, T, + SyntaxNode, SyntaxNodePtr, SyntaxToken, T, ast, match_ast, }; use crate::{ - syntax_highlighting::tags::{HlOperator, HlPunct}, Highlight, HlMod, HlTag, + syntax_highlighting::tags::{HlOperator, HlPunct}, }; pub(super) fn token( @@ -143,11 +143,7 @@ fn punctuation( let ptr = operator_parent .as_ref() .and_then(|it| AstPtr::try_from_raw(SyntaxNodePtr::new(it))); - if ptr.is_some_and(is_unsafe_node) { - h | HlMod::Unsafe - } else { - h - } + if ptr.is_some_and(is_unsafe_node) { h | HlMod::Unsafe } else { h } } (T![-], PREFIX_EXPR) => { let prefix_expr = @@ -223,11 +219,7 @@ fn punctuation( let is_unsafe = is_unsafe_macro || operator_parent .and_then(|it| { - if ast::ArgList::can_cast(it.kind()) { - it.parent() - } else { - Some(it) - } + if ast::ArgList::can_cast(it.kind()) { it.parent() } else { Some(it) } }) .and_then(|it| AstPtr::try_from_raw(SyntaxNodePtr::new(&it))) .is_some_and(is_unsafe_node); @@ -296,7 +288,7 @@ fn highlight_name_ref( let name_class = match NameRefClass::classify(sema, &name_ref) { Some(name_kind) => name_kind, None if syntactic_name_ref_highlighting => { - return highlight_name_ref_by_syntax(name_ref, sema, krate, is_unsafe_node) + return highlight_name_ref_by_syntax(name_ref, sema, krate, is_unsafe_node); } // FIXME: This is required for helper attributes used by proc-macros, as those do not map down // to anything when used. @@ -818,11 +810,7 @@ fn highlight_name_ref_by_syntax( let h = HlTag::Symbol(SymbolKind::Field); let is_unsafe = ast::Expr::cast(parent) .is_some_and(|it| is_unsafe_node(AstPtr::new(&it).wrap_left())); - if is_unsafe { - h | HlMod::Unsafe - } else { - h.into() - } + if is_unsafe { h | HlMod::Unsafe } else { h.into() } } RECORD_EXPR_FIELD | RECORD_PAT_FIELD => HlTag::Symbol(SymbolKind::Field).into(), PATH_SEGMENT => { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs index 6a03da6a6eaa5..cd69a6eb23994 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs @@ -8,8 +8,8 @@ use stdx::format_to; use syntax::AstNode; use crate::{ - syntax_highlighting::{highlight, HighlightConfig}, FileId, RootDatabase, + syntax_highlighting::{HighlightConfig, highlight}, }; pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs index 1be90ad6a1ebc..13922eba19194 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs @@ -3,21 +3,21 @@ use std::mem; use either::Either; -use hir::{sym, HirFileId, InFile, Semantics}; +use hir::{HirFileId, InFile, Semantics, sym}; use ide_db::{ - active_parameter::ActiveParameter, defs::Definition, documentation::docs_with_rangemap, - rust_doc::is_rust_fence, SymbolKind, + SymbolKind, active_parameter::ActiveParameter, defs::Definition, + documentation::docs_with_rangemap, rust_doc::is_rust_fence, }; use span::EditionedFileId; use syntax::{ - ast::{self, AstNode, IsString, QuoteOffsets}, AstToken, NodeOrToken, SyntaxNode, TextRange, TextSize, + ast::{self, AstNode, IsString, QuoteOffsets}, }; use crate::{ - doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def}, - syntax_highlighting::{highlights::Highlights, injector::Injector, HighlightConfig}, Analysis, HlMod, HlRange, HlTag, RootDatabase, + doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def}, + syntax_highlighting::{HighlightConfig, highlights::Highlights, injector::Injector}, }; pub(super) fn ra_fixture( diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/injector.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/injector.rs index a902fd717f099..c30f797324967 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/injector.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/injector.rs @@ -53,11 +53,7 @@ impl Delta { where T: Ord + Sub, { - if to >= from { - Delta::Add(to - from) - } else { - Delta::Sub(from - to) - } + if to >= from { Delta::Add(to - from) } else { Delta::Sub(from - to) } } } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index 9e8af4bac2277..4b3fec1d2f7c9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -1,11 +1,11 @@ use std::time::Instant; -use expect_test::{expect_file, ExpectFile}; +use expect_test::{ExpectFile, expect_file}; use ide_db::SymbolKind; use span::Edition; -use test_utils::{bench, bench_fixture, skip_slow_tests, AssertLinear}; +use test_utils::{AssertLinear, bench, bench_fixture, skip_slow_tests}; -use crate::{fixture, FileRange, HighlightConfig, HlTag, TextRange}; +use crate::{FileRange, HighlightConfig, HlTag, TextRange, fixture}; const HL_CONFIG: HighlightConfig = HighlightConfig { strings: true, diff --git a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs index d22133c856587..06cbd50e946ac 100644 --- a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs +++ b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs @@ -2,10 +2,10 @@ use hir::{Crate, Module, ModuleDef, Semantics}; use ide_db::base_db; -use ide_db::{base_db::RootQueryDb, FileId, RootDatabase}; +use ide_db::{FileId, RootDatabase, base_db::RootQueryDb}; use syntax::TextRange; -use crate::{runnables::runnable_fn, NavigationTarget, Runnable, TryToNav}; +use crate::{NavigationTarget, Runnable, TryToNav, runnables::runnable_fn}; #[derive(Debug)] pub enum TestItemKind { diff --git a/src/tools/rust-analyzer/crates/ide/src/typing.rs b/src/tools/rust-analyzer/crates/ide/src/typing.rs index f583aa801eaac..bb04fdbe88af7 100644 --- a/src/tools/rust-analyzer/crates/ide/src/typing.rs +++ b/src/tools/rust-analyzer/crates/ide/src/typing.rs @@ -16,16 +16,16 @@ mod on_enter; use ide_db::{ - base_db::{salsa::AsDynDatabase, RootQueryDb}, FilePosition, RootDatabase, + base_db::{RootQueryDb, salsa::AsDynDatabase}, }; use span::{Edition, EditionedFileId}; use std::iter; use syntax::{ - algo::{ancestors_at_offset, find_node_at_offset}, - ast::{self, edit::IndentLevel, AstToken}, AstNode, Parse, SourceFile, SyntaxKind, TextRange, TextSize, + algo::{ancestors_at_offset, find_node_at_offset}, + ast::{self, AstToken, edit::IndentLevel}, }; use ide_db::text_edit::TextEdit; diff --git a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs index 8cadb61040390..d684b0efc5149 100644 --- a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs +++ b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs @@ -2,14 +2,14 @@ //! comments, but should handle indent some time in the future as well. use ide_db::base_db::RootQueryDb; -use ide_db::{base_db::salsa::AsDynDatabase, FilePosition, RootDatabase}; +use ide_db::{FilePosition, RootDatabase, base_db::salsa::AsDynDatabase}; use span::EditionedFileId; use syntax::{ - algo::find_node_at_offset, - ast::{self, edit::IndentLevel, AstToken}, AstNode, SmolStr, SourceFile, SyntaxKind::*, SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, + algo::find_node_at_offset, + ast::{self, AstToken, edit::IndentLevel}, }; use ide_db::text_edit::TextEdit; diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs index 09f21ecfe41cc..e878c9afee2b1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs @@ -1,9 +1,9 @@ use dot::{Id, LabelText}; use ide_db::{ + FxHashMap, RootDatabase, base_db::{ BuiltCrateData, BuiltDependency, Crate, ExtraCrateData, RootQueryDb, SourceDatabase, }, - FxHashMap, RootDatabase, }; // Feature: View Crate Graph diff --git a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs index bfdf9d0f3374e..954917d4c09ee 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs @@ -1,6 +1,6 @@ use hir::{DefWithBody, Semantics}; use ide_db::{FilePosition, RootDatabase}; -use syntax::{algo::ancestors_at_offset, ast, AstNode}; +use syntax::{AstNode, algo::ancestors_at_offset, ast}; // Feature: View Hir // diff --git a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs index 67c241cbb9153..a230b30ed3712 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs @@ -1,4 +1,4 @@ -use hir::{db::DefDatabase, Semantics}; +use hir::{Semantics, db::DefDatabase}; use ide_db::{FileId, RootDatabase}; use span::EditionedFileId; diff --git a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs index 02e3b1d500f26..140ae4265be7d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs @@ -2,9 +2,9 @@ use std::fmt; use hir::{DisplayTarget, Field, HirDisplay, Layout, Semantics, Type}; use ide_db::{ + RootDatabase, defs::Definition, helpers::{get_definition, pick_best_token}, - RootDatabase, }; use syntax::{AstNode, SyntaxKind}; diff --git a/src/tools/rust-analyzer/crates/ide/src/view_mir.rs b/src/tools/rust-analyzer/crates/ide/src/view_mir.rs index aa4ff64a819e1..6ca231c7a81a6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_mir.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_mir.rs @@ -1,6 +1,6 @@ use hir::{DefWithBody, Semantics}; use ide_db::{FilePosition, RootDatabase}; -use syntax::{algo::ancestors_at_offset, ast, AstNode}; +use syntax::{AstNode, algo::ancestors_at_offset, ast}; // Feature: View Mir // diff --git a/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs b/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs index 407720864bfdb..ecd93e8b28190 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs @@ -1,13 +1,13 @@ use hir::Semantics; use ide_db::{ - line_index::{LineCol, LineIndex}, FileId, LineIndexDatabase, RootDatabase, + line_index::{LineCol, LineIndex}, }; use span::{TextRange, TextSize}; use stdx::format_to; use syntax::{ - ast::{self, IsString}, AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, WalkEvent, + ast::{self, IsString}, }; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/intern/src/lib.rs b/src/tools/rust-analyzer/crates/intern/src/lib.rs index 58327419f6314..6548bb18269b3 100644 --- a/src/tools/rust-analyzer/crates/intern/src/lib.rs +++ b/src/tools/rust-analyzer/crates/intern/src/lib.rs @@ -10,7 +10,7 @@ use std::{ }; use dashmap::{DashMap, SharedValue}; -use hashbrown::{hash_map::RawEntryMut, HashMap}; +use hashbrown::{HashMap, hash_map::RawEntryMut}; use rustc_hash::FxHasher; use triomphe::Arc; @@ -21,7 +21,7 @@ type Guard = dashmap::RwLockWriteGuard< >; mod symbol; -pub use self::symbol::{symbols as sym, Symbol}; +pub use self::symbol::{Symbol, symbols as sym}; pub struct Interned { arc: Arc, diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index f6a74d97416ef..f02fb6d14f17b 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -11,7 +11,7 @@ use std::{ }; use dashmap::{DashMap, SharedValue}; -use hashbrown::{hash_map::RawEntryMut, HashMap}; +use hashbrown::{HashMap, hash_map::RawEntryMut}; use rustc_hash::FxHasher; use triomphe::Arc; @@ -160,7 +160,7 @@ impl Symbol { SharedValue::new(()), ) .0 - .0, + .0, ), }, } @@ -236,7 +236,7 @@ impl Symbol { RawEntryMut::Vacant(_) => unreachable!(), } .0 - .0; + .0; // SAFETY: We're dropping, we have ownership. ManuallyDrop::into_inner(unsafe { ptr.try_as_arc_owned().unwrap() }); debug_assert_eq!(Arc::count(arc), 1); diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 6b77c72cee897..cc9b3ef457366 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -7,8 +7,8 @@ use dashmap::{DashMap, SharedValue}; use rustc_hash::FxHasher; use crate::{ - symbol::{SymbolProxy, TaggedArcPtr}, Symbol, + symbol::{SymbolProxy, TaggedArcPtr}, }; macro_rules! define_symbols { diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 01d29d88df4a2..243619bb09fd2 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -4,23 +4,24 @@ // to run rust-analyzer as a library. use std::{collections::hash_map::Entry, mem, path::Path, sync}; -use crossbeam_channel::{unbounded, Receiver}; +use crossbeam_channel::{Receiver, unbounded}; use hir_expand::proc_macro::{ ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacroLoadResult, ProcMacrosBuilder, }; use ide_db::{ + ChangeWithProcMacros, FxHashMap, RootDatabase, base_db::{CrateGraphBuilder, Env, SourceRoot, SourceRootId}, - prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase, + prime_caches, }; use itertools::Itertools; use proc_macro_api::{MacroDylib, ProcMacroClient}; use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; use span::Span; use vfs::{ + AbsPath, AbsPathBuf, VfsPath, file_set::FileSetConfig, loader::{Handle, LoadingProgress}, - AbsPath, AbsPathBuf, VfsPath, }; #[derive(Debug)] @@ -626,7 +627,7 @@ mod tests { let fsc = builder.build(); let src = SourceRootConfig { fsc, local_filesets: vec![0, 1, 2, 3] }; let mut vc = src.source_root_parent_map().into_iter().collect::>(); - vc.sort_by(|x, y| x.0 .0.cmp(&y.0 .0)); + vc.sort_by(|x, y| x.0.0.cmp(&y.0.0)); assert_eq!(vc, vec![(SourceRootId(2), SourceRootId(1)), (SourceRootId(3), SourceRootId(1))]) } @@ -641,7 +642,7 @@ mod tests { let fsc = builder.build(); let src = SourceRootConfig { fsc, local_filesets: vec![0, 1, 3] }; let mut vc = src.source_root_parent_map().into_iter().collect::>(); - vc.sort_by(|x, y| x.0 .0.cmp(&y.0 .0)); + vc.sort_by(|x, y| x.0.0.cmp(&y.0.0)); assert_eq!(vc, vec![(SourceRootId(3), SourceRootId(1)),]) } @@ -656,7 +657,7 @@ mod tests { let fsc = builder.build(); let src = SourceRootConfig { fsc, local_filesets: vec![0, 1, 3] }; let mut vc = src.source_root_parent_map().into_iter().collect::>(); - vc.sort_by(|x, y| x.0 .0.cmp(&y.0 .0)); + vc.sort_by(|x, y| x.0.0.cmp(&y.0.0)); assert_eq!(vc, vec![(SourceRootId(3), SourceRootId(1)),]) } @@ -672,7 +673,7 @@ mod tests { let fsc = builder.build(); let src = SourceRootConfig { fsc, local_filesets: vec![0, 1] }; let mut vc = src.source_root_parent_map().into_iter().collect::>(); - vc.sort_by(|x, y| x.0 .0.cmp(&y.0 .0)); + vc.sort_by(|x, y| x.0.0.cmp(&y.0.0)); assert_eq!(vc, vec![(SourceRootId(1), SourceRootId(0)),]) } @@ -688,7 +689,7 @@ mod tests { let fsc = builder.build(); let src = SourceRootConfig { fsc, local_filesets: vec![0, 1] }; let mut vc = src.source_root_parent_map().into_iter().collect::>(); - vc.sort_by(|x, y| x.0 .0.cmp(&y.0 .0)); + vc.sort_by(|x, y| x.0.0.cmp(&y.0.0)); assert_eq!(vc, vec![(SourceRootId(1), SourceRootId(0)),]) } diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs index 89c300300379c..db75dceae1cb9 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs @@ -5,18 +5,19 @@ use rustc_hash::FxHashMap; use span::{Edition, Span}; use stdx::itertools::Itertools; use syntax::{ - ast::{self, HasName}, AstNode, + ast::{self, HasName}, }; use syntax_bridge::{ - dummy_test_span_utils::{DummyTestSpanMap, DUMMY}, - syntax_node_to_token_tree, DocCommentDesugarMode, + DocCommentDesugarMode, + dummy_test_span_utils::{DUMMY, DummyTestSpanMap}, + syntax_node_to_token_tree, }; use test_utils::{bench, bench_fixture, skip_slow_tests}; use crate::{ - parser::{MetaVarKind, Op, RepeatKind, Separator}, DeclarativeMacro, + parser::{MetaVarKind, Op, RepeatKind, Separator}, }; #[test] @@ -53,7 +54,7 @@ fn benchmark_expand_macro_rules() { .map(|(id, tt)| { let res = rules[&id].expand(&tt, |_| (), DUMMY, Edition::CURRENT); assert!(res.err.is_none()); - res.value.0 .0.len() + res.value.0.0.len() }) .sum() }; diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander.rs b/src/tools/rust-analyzer/crates/mbe/src/expander.rs index 5539a88c707d1..f910f9f9d753f 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander.rs @@ -9,7 +9,7 @@ use intern::Symbol; use rustc_hash::FxHashMap; use span::{Edition, Span}; -use crate::{parser::MetaVarKind, ExpandError, ExpandErrorKind, ExpandResult, MatchedArmIndex}; +use crate::{ExpandError, ExpandErrorKind, ExpandResult, MatchedArmIndex, parser::MetaVarKind}; pub(crate) fn expand_rules( rules: &[crate::Rule], diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs index b7f25aa380961..940aaacb02ed5 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs @@ -61,19 +61,19 @@ use std::{rc::Rc, sync::Arc}; -use intern::{sym, Symbol}; -use smallvec::{smallvec, SmallVec}; +use intern::{Symbol, sym}; +use smallvec::{SmallVec, smallvec}; use span::{Edition, Span}; use tt::{ - iter::{TtElement, TtIter}, DelimSpan, + iter::{TtElement, TtIter}, }; use crate::{ + ExpandError, ExpandErrorKind, MetaTemplate, ValueResult, expander::{Binding, Bindings, ExpandResult, Fragment}, expect_fragment, parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator}, - ExpandError, ExpandErrorKind, MetaTemplate, ValueResult, }; impl<'a> Bindings<'a> { diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index 7710ea7938951..b1f542eac7cef 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -1,14 +1,14 @@ //! Transcriber takes a template, like `fn $ident() {}`, a set of bindings like //! `$ident => foo`, interpolates variables in the template, to get `fn foo() {}` -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use span::{Edition, Span}; -use tt::{iter::TtElement, Delimiter, TopSubtreeBuilder}; +use tt::{Delimiter, TopSubtreeBuilder, iter::TtElement}; use crate::{ + ExpandError, ExpandErrorKind, ExpandResult, MetaTemplate, expander::{Binding, Bindings, Fragment}, parser::{ConcatMetaVarExprElem, MetaVarKind, Op, RepeatKind, Separator}, - ExpandError, ExpandErrorKind, ExpandResult, MetaTemplate, }; impl<'t> Bindings<'t> { @@ -331,7 +331,10 @@ fn expand_subtree( } _ => { if err.is_none() { - err = Some(ExpandError::binding_error(var.span, "metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`")) + err = Some(ExpandError::binding_error( + var.span, + "metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`", + )) } continue; } diff --git a/src/tools/rust-analyzer/crates/mbe/src/lib.rs b/src/tools/rust-analyzer/crates/mbe/src/lib.rs index 6bc019bf333e9..9f9fa36abd46a 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/lib.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/lib.rs @@ -23,8 +23,8 @@ mod tests; use span::{Edition, Span, SyntaxContext}; use syntax_bridge::to_parser_input; -use tt::iter::TtIter; use tt::DelimSpan; +use tt::iter::TtIter; use std::fmt; use std::sync::Arc; diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index 9d91387a07417..7be49cbc7e112 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use arrayvec::ArrayVec; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use span::{Edition, Span, SyntaxContext}; use tt::iter::{TtElement, TtIter}; @@ -194,7 +194,7 @@ fn next_op( let mut res = ArrayVec::new(); res.push(*p); Box::new(res) - })) + })); } Some(it) => it, }; @@ -212,13 +212,13 @@ fn next_op( Mode::Pattern => { return Err(ParseError::unexpected( "`${}` metavariable expressions are not allowed in matchers", - )) + )); } }, _ => { return Err(ParseError::expected( "expected `$()` repetition or `${}` expression", - )) + )); } }, TtElement::Leaf(leaf) => match leaf { @@ -246,7 +246,7 @@ fn next_op( Mode::Pattern => { return Err(ParseError::unexpected( "`$$` is not allowed on the pattern side", - )) + )); } Mode::Template => Op::Punct({ let mut res = ArrayVec::new(); @@ -255,7 +255,7 @@ fn next_op( }), }, tt::Leaf::Punct(_) | tt::Leaf::Literal(_) => { - return Err(ParseError::expected("expected ident")) + return Err(ParseError::expected("expected ident")); } }, } @@ -348,7 +348,7 @@ fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option, Repeat }; match tt { tt::Leaf::Ident(_) | tt::Leaf::Literal(_) if has_sep => { - return Err(ParseError::InvalidRepeat) + return Err(ParseError::InvalidRepeat); } tt::Leaf::Ident(ident) => separator = Separator::Ident(ident.clone()), tt::Leaf::Literal(lit) => separator = Separator::Literal(lit.clone()), diff --git a/src/tools/rust-analyzer/crates/parser/src/event.rs b/src/tools/rust-analyzer/crates/parser/src/event.rs index b197b086f377a..5be9cb2a24699 100644 --- a/src/tools/rust-analyzer/crates/parser/src/event.rs +++ b/src/tools/rust-analyzer/crates/parser/src/event.rs @@ -5,8 +5,8 @@ use std::mem; use crate::{ - output::Output, SyntaxKind::{self, *}, + output::Output, }; /// `Parser` produces a flat list of `Event`s. diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs index fe6b904bd889a..8ddf50db043a6 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs @@ -39,9 +39,9 @@ mod patterns; mod types; use crate::{ - parser::{CompletedMarker, Marker, Parser}, SyntaxKind::{self, *}, - TokenSet, T, + T, TokenSet, + parser::{CompletedMarker, Marker, Parser}, }; pub(crate) mod entry { diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs index fe1316c9bfde3..5b0085fc2a0b9 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs @@ -4,8 +4,8 @@ use crate::grammar::attributes::ATTRIBUTE_FIRST; use super::*; +pub(super) use atom::{LITERAL_FIRST, literal}; pub(crate) use atom::{block_expr, match_arm_list}; -pub(super) use atom::{literal, LITERAL_FIRST}; #[derive(PartialEq, Eq)] pub(super) enum Semicolon { diff --git a/src/tools/rust-analyzer/crates/parser/src/parser.rs b/src/tools/rust-analyzer/crates/parser/src/parser.rs index b058686276444..36a363afe93a7 100644 --- a/src/tools/rust-analyzer/crates/parser/src/parser.rs +++ b/src/tools/rust-analyzer/crates/parser/src/parser.rs @@ -5,11 +5,11 @@ use std::cell::Cell; use drop_bomb::DropBomb; use crate::{ - event::Event, - input::Input, Edition, SyntaxKind::{self, EOF, ERROR, TOMBSTONE}, - TokenSet, T, + T, TokenSet, + event::Event, + input::Input, }; /// `Parser` struct provides the low-level API for diff --git a/src/tools/rust-analyzer/crates/paths/src/lib.rs b/src/tools/rust-analyzer/crates/paths/src/lib.rs index 3d722b1ff1155..2c6a82bf0c3fc 100644 --- a/src/tools/rust-analyzer/crates/paths/src/lib.rs +++ b/src/tools/rust-analyzer/crates/paths/src/lib.rs @@ -248,7 +248,9 @@ impl AbsPath { } pub fn canonicalize(&self) -> ! { - panic!("We explicitly do not provide canonicalization API, as that is almost always a wrong solution, see #14430") + panic!( + "We explicitly do not provide canonicalization API, as that is almost always a wrong solution, see #14430" + ) } /// Equivalent of [`Utf8Path::strip_prefix`] for `AbsPath`. diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs index 4178b04767a99..3d84dc8b24da9 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs @@ -10,7 +10,7 @@ use serde_derive::{Deserialize, Serialize}; use crate::ProcMacroKind; pub use self::flat::{ - deserialize_span_data_index_map, serialize_span_data_index_map, FlatTree, SpanDataIndexMap, + FlatTree, SpanDataIndexMap, deserialize_span_data_index_map, serialize_span_data_index_map, }; pub use span::TokenId; @@ -158,7 +158,7 @@ type ProtocolWrite = for<'o, 'msg> fn(out: &'o mut W, msg: &'msg str) #[cfg(test)] mod tests { - use intern::{sym, Symbol}; + use intern::{Symbol, sym}; use span::{Edition, ErasedFileAstId, Span, SpanAnchor, SyntaxContext, TextRange, TextSize}; use tt::{ Delimiter, DelimiterKind, Ident, Leaf, Literal, Punct, Spacing, TopSubtree, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 571ceaabe62cd..11acbd4e64c24 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -17,9 +17,9 @@ use std::{fmt, io, sync::Arc, time::SystemTime}; use crate::{ legacy_protocol::msg::{ - deserialize_span_data_index_map, flat::serialize_span_data_index_map, ExpandMacro, - ExpandMacroData, ExpnGlobals, FlatTree, PanicMessage, Request, Response, SpanDataIndexMap, - HAS_GLOBAL_SPANS, RUST_ANALYZER_SPAN_SUPPORT, + ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, HAS_GLOBAL_SPANS, PanicMessage, + RUST_ANALYZER_SPAN_SUPPORT, Request, Response, SpanDataIndexMap, + deserialize_span_data_index_map, flat::serialize_span_data_index_map, }, process::ProcMacroServerProcess, }; @@ -102,7 +102,7 @@ impl ProcMacroClient { pub fn spawn( process_path: &AbsPath, env: impl IntoIterator, impl AsRef)> - + Clone, + + Clone, ) -> io::Result { let process = ProcMacroServerProcess::run(process_path, env)?; Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index d998b23d3bbef..dd1f5a2420c9f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -11,14 +11,14 @@ use paths::AbsPath; use stdx::JodChild; use crate::{ + ProcMacroKind, ServerError, legacy_protocol::{ json::{read_json, write_json}, msg::{ - Message, Request, Response, ServerConfig, SpanMode, CURRENT_API_VERSION, - RUST_ANALYZER_SPAN_SUPPORT, + CURRENT_API_VERSION, Message, RUST_ANALYZER_SPAN_SUPPORT, Request, Response, + ServerConfig, SpanMode, }, }, - ProcMacroKind, ServerError, }; #[derive(Debug)] @@ -43,7 +43,7 @@ impl ProcMacroServerProcess { pub(crate) fn run( process_path: &AbsPath, env: impl IntoIterator, impl AsRef)> - + Clone, + + Clone, ) -> io::Result { let create_srv = || { let mut process = Process::run(process_path, env.clone())?; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index de59e88aac40c..0e6b18ecaef19 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -14,7 +14,9 @@ use main_loop::run; fn main() -> std::io::Result<()> { let v = std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE"); if v.is_err() { - eprintln!("This is an IDE implementation detail, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE."); + eprintln!( + "This is an IDE implementation detail, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE." + ); eprintln!( "Note that this tool's API is highly unstable and may break without prior notice" ); diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 569070766f1c6..f54dff1f2d822 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -4,8 +4,8 @@ use std::io; use proc_macro_api::legacy_protocol::{ json::{read_json, write_json}, msg::{ - self, deserialize_span_data_index_map, serialize_span_data_index_map, ExpandMacroData, - ExpnGlobals, Message, SpanMode, TokenId, CURRENT_API_VERSION, + self, CURRENT_API_VERSION, ExpandMacroData, ExpnGlobals, Message, SpanMode, TokenId, + deserialize_span_data_index_map, serialize_span_data_index_map, }, }; use proc_macro_srv::EnvSnapshot; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index cbf7a277bfae6..245b064387e59 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -9,7 +9,7 @@ use libloading::Library; use object::Object; use paths::{Utf8Path, Utf8PathBuf}; -use crate::{proc_macros::ProcMacros, server_impl::TopSubtree, ProcMacroKind, ProcMacroSrvSpan}; +use crate::{ProcMacroKind, ProcMacroSrvSpan, proc_macros::ProcMacros, server_impl::TopSubtree}; /// Loads dynamic library in platform dependent manner. /// diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index f28821b4afc5c..4f817b6bc0a58 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -30,7 +30,7 @@ mod proc_macros; mod server_impl; use std::{ - collections::{hash_map::Entry, HashMap}, + collections::{HashMap, hash_map::Entry}, env, ffi::OsString, fs, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs index 58f5e80dc4ea6..a5fa7f6e71a6d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs @@ -5,7 +5,7 @@ use proc_macro::bridge; use libloading::Library; use crate::{ - dylib::LoadProcMacroDylibError, server_impl::TopSubtree, ProcMacroKind, ProcMacroSrvSpan, + ProcMacroKind, ProcMacroSrvSpan, dylib::LoadProcMacroDylibError, server_impl::TopSubtree, }; #[repr(transparent)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index f7cb0ab4655fa..62540183cb5e9 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -11,10 +11,10 @@ use std::{ use intern::Symbol; use proc_macro::bridge::{self, server}; -use span::{FileId, Span, FIXUP_ERASED_FILE_AST_ID_MARKER}; +use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, FileId, Span}; use tt::{TextRange, TextSize}; -use crate::server_impl::{literal_kind_to_internal, token_stream::TokenStreamBuilder, TopSubtree}; +use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder}; mod tt { pub use tt::*; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 409cf3cc78134..d0c7f23a38a04 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -5,7 +5,7 @@ use std::ops::{Bound, Range}; use intern::Symbol; use proc_macro::bridge::{self, server}; -use crate::server_impl::{literal_kind_to_internal, token_stream::TokenStreamBuilder, TopSubtree}; +use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder}; mod tt { pub use span::TokenId; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs index 645f7e7c59a32..a3cf76d37bacf 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs @@ -2,7 +2,7 @@ use proc_macro::bridge; -use crate::server_impl::{delim_to_external, literal_kind_to_external, TopSubtree}; +use crate::server_impl::{TopSubtree, delim_to_external, literal_kind_to_external}; #[derive(Clone)] pub struct TokenStream { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 584a27468f847..a476a70a74095 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -4,7 +4,7 @@ use expect_test::Expect; use span::{EditionedFileId, ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContext, TokenId}; use tt::TextRange; -use crate::{dylib, proc_macro_test_dylib_path, EnvSnapshot, ProcMacroSrv}; +use crate::{EnvSnapshot, ProcMacroSrv, dylib, proc_macro_test_dylib_path}; fn parse_string(call_site: TokenId, src: &str) -> crate::server_impl::TokenStream { crate::server_impl::TokenStream::with_subtree(crate::server_impl::TopSubtree( diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs b/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs index b0939229f93e2..aa0099d0e57e3 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs @@ -9,7 +9,7 @@ use std::{cell::RefCell, io, mem, process::Command}; use base_db::Env; -use cargo_metadata::{camino::Utf8Path, Message}; +use cargo_metadata::{Message, camino::Utf8Path}; use cfg::CfgAtom; use itertools::Itertools; use la_arena::ArenaMap; @@ -19,8 +19,8 @@ use serde::Deserialize as _; use toolchain::Tool; use crate::{ - utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationStrategy, ManifestPath, - Package, Sysroot, TargetKind, + CargoConfig, CargoFeatures, CargoWorkspace, InvocationStrategy, ManifestPath, Package, Sysroot, + TargetKind, utf8_stdout, }; /// Output of the build script and proc-macro building steps for a workspace. diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 014028a0b63e2..054312835a8cf 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -596,7 +596,7 @@ impl CargoWorkspace { // this pkg is inside this cargo workspace, fallback to workspace root if found { return Some(vec![ - ManifestPath::try_from(self.workspace_root().join("Cargo.toml")).ok()? + ManifestPath::try_from(self.workspace_root().join("Cargo.toml")).ok()?, ]); } diff --git a/src/tools/rust-analyzer/crates/project-model/src/env.rs b/src/tools/rust-analyzer/crates/project-model/src/env.rs index 37fffba295590..08d51c0d0888d 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/env.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/env.rs @@ -4,7 +4,7 @@ use paths::Utf8Path; use rustc_hash::FxHashMap; use toolchain::Tool; -use crate::{utf8_stdout, ManifestPath, PackageData, Sysroot, TargetKind}; +use crate::{ManifestPath, PackageData, Sysroot, TargetKind, utf8_stdout}; /// Recreates the compile-time environment variables that Cargo sets. /// diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index 21a993c5a5ed1..436af64cf1326 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -48,12 +48,12 @@ mod tests; use std::{ fmt, - fs::{self, read_dir, ReadDir}, + fs::{self, ReadDir, read_dir}, io, process::Command, }; -use anyhow::{bail, format_err, Context}; +use anyhow::{Context, bail, format_err}; use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::FxHashSet; @@ -102,7 +102,9 @@ impl ProjectManifest { if path.extension().unwrap_or_default() == "rs" { return Ok(ProjectManifest::CargoScript(path)); } - bail!("project root must point to a Cargo.toml, rust-project.json or