Skip to content

internal: Simplify #16704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/flycheck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ impl CommandHandle {
let (sender, receiver) = unbounded();
let actor = CargoActor::new(sender, stdout, stderr);
let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
.name("CargoHandle".to_owned())
.name("CommandHandle".to_owned())
.spawn(move || actor.run())
.expect("failed to spawn thread");
Ok(CommandHandle { program, arguments, current_dir, child, thread, receiver })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use hir::{self, HasVisibility};
use hir::HasVisibility;
use ide_db::{
assists::{AssistId, AssistKind},
defs::Definition,
Expand Down
1 change: 1 addition & 0 deletions crates/ide-db/src/prime_caches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub fn parallel_prime_caches(

stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
.allow_leak(true)
.name("PrimeCaches".to_owned())
.spawn(move || Cancelled::catch(|| worker(db)))
.expect("failed to spawn thread");
}
Expand Down
54 changes: 22 additions & 32 deletions crates/proc-macro-srv/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,33 +54,33 @@ fn spacing_to_external(spacing: Spacing) -> proc_macro::Spacing {
}
}

struct LiteralFormatter<S>(bridge::Literal<S, Symbol>);

impl<S> LiteralFormatter<S> {
/// Invokes the callback with a `&[&str]` consisting of each part of the
/// literal's representation. This is done to allow the `ToString` and
/// `Display` implementations to borrow references to symbol values, and
/// both be optimized to reduce overhead.
fn with_stringify_parts<R>(
&self,
interner: SymbolInternerRef,
f: impl FnOnce(&[&str]) -> R,
) -> R {
/// Returns a string containing exactly `num` '#' characters.
/// Uses a 256-character source string literal which is always safe to
/// index with a `u8` index.
fn get_hashes_str(num: u8) -> &'static str {
const HASHES: &str = "\
/// Invokes the callback with a `&[&str]` consisting of each part of the
/// literal's representation. This is done to allow the `ToString` and
/// `Display` implementations to borrow references to symbol values, and
/// both be optimized to reduce overhead.
fn literal_with_stringify_parts<S, R>(
literal: &bridge::Literal<S, Symbol>,
interner: SymbolInternerRef,
f: impl FnOnce(&[&str]) -> R,
) -> R {
/// Returns a string containing exactly `num` '#' characters.
/// Uses a 256-character source string literal which is always safe to
/// index with a `u8` index.
fn get_hashes_str(num: u8) -> &'static str {
const HASHES: &str = "\
################################################################\
################################################################\
################################################################\
################################################################\
";
const _: () = assert!(HASHES.len() == 256);
&HASHES[..num as usize]
}
const _: () = assert!(HASHES.len() == 256);
&HASHES[..num as usize]
}

self.with_symbol_and_suffix(interner, |symbol, suffix| match self.0.kind {
{
let symbol = &*literal.symbol.text(interner);
let suffix = &*literal.suffix.map(|s| s.text(interner)).unwrap_or_default();
match literal.kind {
bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]),
bridge::LitKind::Char => f(&["'", symbol, "'", suffix]),
bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]),
Expand All @@ -101,16 +101,6 @@ impl<S> LiteralFormatter<S> {
bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
f(&[symbol, suffix])
}
})
}

fn with_symbol_and_suffix<R>(
&self,
interner: SymbolInternerRef,
f: impl FnOnce(&str, &str) -> R,
) -> R {
let symbol = self.0.symbol.text(interner);
let suffix = self.0.suffix.map(|s| s.text(interner)).unwrap_or_default();
f(symbol.as_str(), suffix.as_str())
}
}
}
35 changes: 23 additions & 12 deletions crates/proc-macro-srv/src/server/rust_analyzer_span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use proc_macro::bridge::{self, server};
use span::{Span, FIXUP_ERASED_FILE_AST_ID_MARKER};

use crate::server::{
delim_to_external, delim_to_internal, token_stream::TokenStreamBuilder, LiteralFormatter,
Symbol, SymbolInternerRef, SYMBOL_INTERNER,
delim_to_external, delim_to_internal, literal_with_stringify_parts,
token_stream::TokenStreamBuilder, Symbol, SymbolInternerRef, SYMBOL_INTERNER,
};
mod tt {
pub use ::tt::*;
Expand Down Expand Up @@ -180,12 +180,11 @@ impl server::TokenStream for RaSpanServer {
}

bridge::TokenTree::Literal(literal) => {
let literal = LiteralFormatter(literal);
let text = literal.with_stringify_parts(self.interner, |parts| {
let text = literal_with_stringify_parts(&literal, self.interner, |parts| {
::tt::SmolStr::from_iter(parts.iter().copied())
});

let literal = tt::Literal { text, span: literal.0.span };
let literal = tt::Literal { text, span: literal.span };
let leaf: tt::Leaf = tt::Leaf::from(literal);
let tree = tt::TokenTree::from(leaf);
Self::TokenStream::from_iter(iter::once(tree))
Expand Down Expand Up @@ -251,10 +250,17 @@ impl server::TokenStream for RaSpanServer {
.into_iter()
.map(|tree| match tree {
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
bridge::TokenTree::Ident(bridge::Ident {
sym: Symbol::intern(self.interner, ident.text.trim_start_matches("r#")),
is_raw: ident.text.starts_with("r#"),
span: ident.span,
bridge::TokenTree::Ident(match ident.text.strip_prefix("r#") {
Some(text) => bridge::Ident {
sym: Symbol::intern(self.interner, text),
is_raw: true,
span: ident.span,
},
None => bridge::Ident {
sym: Symbol::intern(self.interner, &ident.text),
is_raw: false,
span: ident.span,
},
})
}
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
Expand Down Expand Up @@ -285,11 +291,12 @@ impl server::TokenStream for RaSpanServer {
}

impl server::SourceFile for RaSpanServer {
// FIXME these are all stubs
fn eq(&mut self, _file1: &Self::SourceFile, _file2: &Self::SourceFile) -> bool {
// FIXME
true
}
fn path(&mut self, _file: &Self::SourceFile) -> String {
// FIXME
String::new()
}
fn is_real(&mut self, _file: &Self::SourceFile) -> bool {
Expand All @@ -306,11 +313,15 @@ impl server::Span for RaSpanServer {
SourceFile {}
}
fn save_span(&mut self, _span: Self::Span) -> usize {
// FIXME stub, requires builtin quote! implementation
// FIXME, quote is incompatible with third-party tools
// This is called by the quote proc-macro which is expanded when the proc-macro is compiled
// As such, r-a will never observe this
0
}
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
// FIXME stub, requires builtin quote! implementation
// FIXME, quote is incompatible with third-party tools
// This is called by the expansion of quote!, r-a will observe this, but we don't have
// access to the spans that were encoded
self.call_site
}
/// Recent feature, not yet in the proc_macro
Expand Down
10 changes: 5 additions & 5 deletions crates/proc-macro-srv/src/server/token_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use std::{
use proc_macro::bridge::{self, server};

use crate::server::{
delim_to_external, delim_to_internal, token_stream::TokenStreamBuilder, LiteralFormatter,
Symbol, SymbolInternerRef, SYMBOL_INTERNER,
delim_to_external, delim_to_internal, literal_with_stringify_parts,
token_stream::TokenStreamBuilder, Symbol, SymbolInternerRef, SYMBOL_INTERNER,
};
mod tt {
pub use proc_macro_api::msg::TokenId;
Expand Down Expand Up @@ -171,12 +171,12 @@ impl server::TokenStream for TokenIdServer {
}

bridge::TokenTree::Literal(literal) => {
let literal = LiteralFormatter(literal);
let text = literal.with_stringify_parts(self.interner, |parts| {
let text = literal_with_stringify_parts(&literal, self.interner, |parts| {
::tt::SmolStr::from_iter(parts.iter().copied())
});

let literal = tt::Literal { text, span: literal.0.span };
let literal = tt::Literal { text, span: literal.span };

let leaf = tt::Leaf::from(literal);
let tree = TokenTree::from(leaf);
Self::TokenStream::from_iter(iter::once(tree))
Expand Down
36 changes: 15 additions & 21 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ config_data! {
// FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
// than `checkOnSave_target`
cargo_target: Option<String> = "null",
/// Optional path to a rust-analyzer specific target directory.
/// This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
/// building from locking the `Cargo.lock` at the expense of duplicating build artifacts.
///
/// Set to `true` to use a subdirectory of the existing target directory or
/// set to a path relative to the workspace to use that path.
cargo_targetDir | rust_analyzerTargetDir: Option<TargetDirectory> = "null",
/// Unsets the implicit `#[cfg(test)]` for the specified crates.
cargo_unsetTest: Vec<String> = "[\"core\"]",

Expand Down Expand Up @@ -518,14 +525,6 @@ config_data! {
/// tests or binaries. For example, it may be `--release`.
runnables_extraArgs: Vec<String> = "[]",

/// Optional path to a rust-analyzer specific target directory.
/// This prevents rust-analyzer's `cargo check` from locking the `Cargo.lock`
/// at the expense of duplicating build artifacts.
///
/// Set to `true` to use a subdirectory of the existing target directory or
/// set to a path relative to the workspace to use that path.
rust_analyzerTargetDir: Option<TargetDirectory> = "null",

/// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
/// projects, or "discover" to try to automatically find it if the `rustc-dev` component
/// is installed.
Expand Down Expand Up @@ -1401,14 +1400,12 @@ impl Config {
}
}

// FIXME: This should be an AbsolutePathBuf
fn target_dir_from_config(&self) -> Option<PathBuf> {
self.data.rust_analyzerTargetDir.as_ref().and_then(|target_dir| match target_dir {
TargetDirectory::UseSubdirectory(yes) if *yes => {
Some(PathBuf::from("target/rust-analyzer"))
}
TargetDirectory::UseSubdirectory(_) => None,
TargetDirectory::Directory(dir) => Some(dir.clone()),
self.data.cargo_targetDir.as_ref().and_then(|target_dir| match target_dir {
TargetDirectory::UseSubdirectory(true) => Some(PathBuf::from("target/rust-analyzer")),
TargetDirectory::UseSubdirectory(false) => None,
TargetDirectory::Directory(dir) if dir.is_relative() => Some(dir.clone()),
TargetDirectory::Directory(_) => None,
})
}

Expand Down Expand Up @@ -2745,7 +2742,7 @@ mod tests {
"rust": { "analyzerTargetDir": null }
}))
.unwrap();
assert_eq!(config.data.rust_analyzerTargetDir, None);
assert_eq!(config.data.cargo_targetDir, None);
assert!(
matches!(config.flycheck(), FlycheckConfig::CargoCommand { target_dir, .. } if target_dir.is_none())
);
Expand All @@ -2764,10 +2761,7 @@ mod tests {
"rust": { "analyzerTargetDir": true }
}))
.unwrap();
assert_eq!(
config.data.rust_analyzerTargetDir,
Some(TargetDirectory::UseSubdirectory(true))
);
assert_eq!(config.data.cargo_targetDir, Some(TargetDirectory::UseSubdirectory(true)));
assert!(
matches!(config.flycheck(), FlycheckConfig::CargoCommand { target_dir, .. } if target_dir == Some(PathBuf::from("target/rust-analyzer")))
);
Expand All @@ -2787,7 +2781,7 @@ mod tests {
}))
.unwrap();
assert_eq!(
config.data.rust_analyzerTargetDir,
config.data.cargo_targetDir,
Some(TargetDirectory::Directory(PathBuf::from("other_folder")))
);
assert!(
Expand Down
17 changes: 6 additions & 11 deletions crates/rust-analyzer/src/handlers/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,13 @@ pub(crate) fn handle_did_change_text_document(
let _p = tracing::span!(tracing::Level::INFO, "handle_did_change_text_document").entered();

if let Ok(path) = from_proto::vfs_path(&params.text_document.uri) {
let data = match state.mem_docs.get_mut(&path) {
Some(doc) => {
// The version passed in DidChangeTextDocument is the version after all edits are applied
// so we should apply it before the vfs is notified.
doc.version = params.text_document.version;
&mut doc.data
}
None => {
tracing::error!("unexpected DidChangeTextDocument: {}", path);
return Ok(());
}
let Some(DocumentData { version, data }) = state.mem_docs.get_mut(&path) else {
tracing::error!(?path, "unexpected DidChangeTextDocument");
return Ok(());
};
// The version passed in DidChangeTextDocument is the version after all edits are applied
// so we should apply it before the vfs is notified.
*version = params.text_document.version;

let new_contents = apply_document_changes(
state.config.position_encoding(),
Expand Down
20 changes: 10 additions & 10 deletions docs/user/generated_config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ This option does not take effect until rust-analyzer is restarted.
--
Compilation target override (target triple).
--
[[rust-analyzer.cargo.targetDir]]rust-analyzer.cargo.targetDir (default: `null`)::
+
--
Optional path to a rust-analyzer specific target directory.
This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
building from locking the `Cargo.lock` at the expense of duplicating build artifacts.

Set to `true` to use a subdirectory of the existing target directory or
set to a path relative to the workspace to use that path.
--
[[rust-analyzer.cargo.unsetTest]]rust-analyzer.cargo.unsetTest (default: `["core"]`)::
+
--
Expand Down Expand Up @@ -814,16 +824,6 @@ Command to be executed instead of 'cargo' for runnables.
Additional arguments to be passed to cargo for runnables such as
tests or binaries. For example, it may be `--release`.
--
[[rust-analyzer.rust.analyzerTargetDir]]rust-analyzer.rust.analyzerTargetDir (default: `null`)::
+
--
Optional path to a rust-analyzer specific target directory.
This prevents rust-analyzer's `cargo check` from locking the `Cargo.lock`
at the expense of duplicating build artifacts.

Set to `true` to use a subdirectory of the existing target directory or
set to a path relative to the workspace to use that path.
--
[[rust-analyzer.rustc.source]]rust-analyzer.rustc.source (default: `null`)::
+
--
Expand Down
30 changes: 15 additions & 15 deletions editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,21 @@
"string"
]
},
"rust-analyzer.cargo.targetDir": {
"markdownDescription": "Optional path to a rust-analyzer specific target directory.\nThis prevents rust-analyzer's `cargo check` and initial build-script and proc-macro\nbuilding from locking the `Cargo.lock` at the expense of duplicating build artifacts.\n\nSet to `true` to use a subdirectory of the existing target directory or\nset to a path relative to the workspace to use that path.",
"default": null,
"anyOf": [
{
"type": "null"
},
{
"type": "boolean"
},
{
"type": "string"
}
]
},
"rust-analyzer.cargo.unsetTest": {
"markdownDescription": "Unsets the implicit `#[cfg(test)]` for the specified crates.",
"default": [
Expand Down Expand Up @@ -1543,21 +1558,6 @@
"type": "string"
}
},
"rust-analyzer.rust.analyzerTargetDir": {
"markdownDescription": "Optional path to a rust-analyzer specific target directory.\nThis prevents rust-analyzer's `cargo check` from locking the `Cargo.lock`\nat the expense of duplicating build artifacts.\n\nSet to `true` to use a subdirectory of the existing target directory or\nset to a path relative to the workspace to use that path.",
"default": null,
"anyOf": [
{
"type": "null"
},
{
"type": "boolean"
},
{
"type": "string"
}
]
},
"rust-analyzer.rustc.source": {
"markdownDescription": "Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private\nprojects, or \"discover\" to try to automatically find it if the `rustc-dev` component\nis installed.\n\nAny project which uses rust-analyzer with the rustcPrivate\ncrates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it.\n\nThis option does not take effect until rust-analyzer is restarted.",
"default": null,
Expand Down
Loading