Skip to content

Commit

Permalink
Auto merge of #17520 - Veykril:slim-proc-macro-api, r=Veykril
Browse files Browse the repository at this point in the history
internal: Cleanup proc-macro-srv some more
  • Loading branch information
bors committed Jun 30, 2024
2 parents cbd3a7a + 956c852 commit ea7fdad
Show file tree
Hide file tree
Showing 53 changed files with 351 additions and 348 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions crates/base-db/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! base_db defines basic database traits. The concrete DB is defined by ide.

#![warn(rust_2018_idioms, unused_lifetimes)]

mod change;
mod input;

Expand Down
2 changes: 0 additions & 2 deletions crates/cfg/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! cfg defines conditional compiling options, `cfg` attribute parser and evaluator

#![warn(rust_2018_idioms, unused_lifetimes)]

mod cfg_expr;
mod dnf;
#[cfg(test)]
Expand Down
2 changes: 0 additions & 2 deletions crates/flycheck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
// addition to `cargo check`. Either split it into 3 crates (one for test, one for check
// and one common utilities) or change its name and docs to reflect the current state.

#![warn(rust_2018_idioms, unused_lifetimes)]

use std::{fmt, io, process::Command, time::Duration};

use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
Expand Down
1 change: 0 additions & 1 deletion crates/hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//! Note that `hir_def` is a work in progress, so not all of the above is
//! actually true.

#![warn(rust_2018_idioms, unused_lifetimes)]
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]

#[cfg(feature = "in-rust-tree")]
Expand Down
1 change: 0 additions & 1 deletion crates/hir-expand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//! tree originates not from the text of some `FileId`, but from some macro
//! expansion.
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
#![warn(rust_2018_idioms, unused_lifetimes)]

pub mod attrs;
pub mod builtin_attr_macro;
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The type system. We currently use this to infer types for completion, hover
//! information and various assists.
#![warn(rust_2018_idioms, unused_lifetimes)]

#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]

#[cfg(feature = "in-rust-tree")]
Expand Down
1 change: 0 additions & 1 deletion crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
//! from the ide with completions, hovers, etc. It is a (soft, internal) boundary:
//! <https://www.tedinski.com/2018/02/06/system-boundaries.html>.

#![warn(rust_2018_idioms, unused_lifetimes)]
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
#![recursion_limit = "512"]

Expand Down
2 changes: 0 additions & 2 deletions crates/ide-assists/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@
//! See also this post:
//! <https://rust-analyzer.github.io/blog/2020/09/28/how-to-make-a-light-bulb.html>

#![warn(rust_2018_idioms, unused_lifetimes)]

mod assist_config;
mod assist_context;
#[cfg(test)]
Expand Down
2 changes: 0 additions & 2 deletions crates/ide-completion/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! `completions` crate provides utilities for generating completions of user input.

#![warn(rust_2018_idioms, unused_lifetimes)]

mod completions;
mod config;
mod context;
Expand Down
2 changes: 0 additions & 2 deletions crates/ide-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
//!
//! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.

#![warn(rust_2018_idioms, unused_lifetimes)]

mod apply_change;

pub mod active_parameter;
Expand Down
2 changes: 0 additions & 2 deletions crates/ide-diagnostics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
//! There are also a couple of ad-hoc diagnostics implemented directly here, we
//! don't yet have a great pattern for how to do them properly.

#![warn(rust_2018_idioms, unused_lifetimes)]

mod handlers {
pub(crate) mod break_outside_of_loop;
pub(crate) mod expected_function;
Expand Down
2 changes: 0 additions & 2 deletions crates/ide-ssr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
//! Allows searching the AST for code that matches one or more patterns and then replacing that code
//! based on a template.

#![warn(rust_2018_idioms, unused_lifetimes)]

// Feature: Structural Search and Replace
//
// Search and replace with named wildcards that will match any expression, type, path, pattern or item.
Expand Down
2 changes: 1 addition & 1 deletion crates/ide/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! in this crate.

// For proving that RootDatabase is RefUnwindSafe.
#![warn(rust_2018_idioms, unused_lifetimes)]

#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
#![recursion_limit = "128"]

Expand Down
2 changes: 0 additions & 2 deletions crates/limit/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! limit defines a struct to enforce limits.

#![warn(rust_2018_idioms, unused_lifetimes)]

#[cfg(feature = "tracking")]
use std::sync::atomic::AtomicUsize;

Expand Down
2 changes: 0 additions & 2 deletions crates/mbe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
//! The tests for this functionality live in another crate:
//! `hir_def::macro_expansion_tests::mbe`.

#![warn(rust_2018_idioms, unused_lifetimes)]

mod expander;
mod parser;
mod syntax_bridge;
Expand Down
1 change: 0 additions & 1 deletion crates/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
//!
//! [`Parser`]: crate::parser::Parser

#![warn(rust_2018_idioms, unused_lifetimes)]
#![allow(rustdoc::private_intra_doc_links)]
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]

Expand Down
2 changes: 0 additions & 2 deletions crates/paths/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! Thin wrappers around `std::path`/`camino::path`, distinguishing between absolute and
//! relative paths.

#![warn(rust_2018_idioms, unused_lifetimes)]

use std::{
borrow::Borrow,
ffi::OsStr,
Expand Down
1 change: 0 additions & 1 deletion crates/proc-macro-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ doctest = false
serde.workspace = true
serde_json = { workspace = true, features = ["unbounded_depth"] }
tracing.workspace = true
triomphe.workspace = true
rustc-hash.workspace = true
indexmap.workspace = true

Expand Down
35 changes: 35 additions & 0 deletions crates/proc-macro-api/src/json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Protocol functions for json.
use std::io::{self, BufRead, Write};

pub fn read_json<'a>(
inp: &mut impl BufRead,
buf: &'a mut String,
) -> io::Result<Option<&'a String>> {
loop {
buf.clear();

inp.read_line(buf)?;
buf.pop(); // Remove trailing '\n'

if buf.is_empty() {
return Ok(None);
}

// Some ill behaved macro try to use stdout for debugging
// We ignore it here
if !buf.starts_with('{') {
tracing::error!("proc-macro tried to print : {}", buf);
continue;
}

return Ok(Some(buf));
}
}

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(())
}
88 changes: 37 additions & 51 deletions crates/proc-macro-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,23 @@
//! is used to provide basic infrastructure for communication between two
//! processes: Client (RA itself), Server (the external program)

#![warn(rust_2018_idioms, unused_lifetimes)]

pub mod json;
pub mod msg;
mod process;

use base_db::Env;
use indexmap::IndexSet;
use paths::{AbsPath, AbsPathBuf};
use rustc_hash::FxHashMap;
use span::Span;
use std::{
fmt, io,
sync::{Arc, Mutex},
};
use std::{fmt, io, sync::Arc};
use tt::SmolStr;

use serde::{Deserialize, Serialize};

use crate::{
msg::{
deserialize_span_data_index_map, flat::serialize_span_data_index_map, ExpandMacro,
ExpnGlobals, FlatTree, PanicMessage, HAS_GLOBAL_SPANS, RUST_ANALYZER_SPAN_SUPPORT,
ExpnGlobals, FlatTree, PanicMessage, SpanDataIndexMap, HAS_GLOBAL_SPANS,
RUST_ANALYZER_SPAN_SUPPORT,
},
process::ProcMacroProcessSrv,
};
Expand All @@ -48,9 +44,7 @@ pub struct ProcMacroServer {
///
/// That means that concurrent salsa requests may block each other when expanding proc macros,
/// which is unfortunate, but simple and good enough for the time being.
///
/// Therefore, we just wrap the `ProcMacroProcessSrv` in a mutex here.
process: Arc<Mutex<ProcMacroProcessSrv>>,
process: Arc<ProcMacroProcessSrv>,
path: AbsPathBuf,
}

Expand All @@ -70,9 +64,9 @@ impl MacroDylib {
/// we share a single expander process for all macros.
#[derive(Debug, Clone)]
pub struct ProcMacro {
process: Arc<Mutex<ProcMacroProcessSrv>>,
dylib_path: AbsPathBuf,
name: String,
process: Arc<ProcMacroProcessSrv>,
dylib_path: Arc<AbsPathBuf>,
name: SmolStr,
kind: ProcMacroKind,
}

Expand All @@ -81,15 +75,14 @@ impl PartialEq for ProcMacro {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
&& self.kind == other.kind
&& self.dylib_path == other.dylib_path
&& Arc::ptr_eq(&self.dylib_path, &other.dylib_path)
&& Arc::ptr_eq(&self.process, &other.process)
}
}

#[derive(Clone, Debug)]
pub struct ServerError {
pub message: String,
// io::Error isn't Clone for some reason
pub io: Option<Arc<io::Error>>,
}

Expand All @@ -104,21 +97,15 @@ impl fmt::Display for ServerError {
}
}

pub struct MacroPanic {
pub message: String,
}

impl ProcMacroServer {
/// Spawns an external process as the proc macro server and returns a client connected to it.
pub fn spawn(
process_path: &AbsPath,
env: &FxHashMap<String, String>,
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
+ Clone,
) -> io::Result<ProcMacroServer> {
let process = ProcMacroProcessSrv::run(process_path, env)?;
Ok(ProcMacroServer {
process: Arc::new(Mutex::new(process)),
path: process_path.to_owned(),
})
Ok(ProcMacroServer { process: Arc::new(process), path: process_path.to_owned() })
}

pub fn path(&self) -> &AbsPath {
Expand All @@ -127,17 +114,17 @@ impl ProcMacroServer {

pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> {
let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered();
let macros =
self.process.lock().unwrap_or_else(|e| e.into_inner()).find_proc_macros(&dylib.path)?;
let macros = self.process.find_proc_macros(&dylib.path)?;

let dylib_path = Arc::new(dylib.path);
match macros {
Ok(macros) => Ok(macros
.into_iter()
.map(|(name, kind)| ProcMacro {
process: self.process.clone(),
name,
name: name.into(),
kind,
dylib_path: dylib.path.clone(),
dylib_path: dylib_path.clone(),
})
.collect()),
Err(message) => Err(ServerError { message, io: None }),
Expand All @@ -163,38 +150,37 @@ impl ProcMacro {
call_site: Span,
mixed_site: Span,
) -> Result<Result<tt::Subtree<Span>, PanicMessage>, ServerError> {
let version = self.process.lock().unwrap_or_else(|e| e.into_inner()).version();
let version = self.process.version();
let current_dir = env.get("CARGO_MANIFEST_DIR");

let mut span_data_table = IndexSet::default();
let mut span_data_table = SpanDataIndexMap::default();
let def_site = span_data_table.insert_full(def_site).0;
let call_site = span_data_table.insert_full(call_site).0;
let mixed_site = span_data_table.insert_full(mixed_site).0;
let task = ExpandMacro {
macro_body: FlatTree::new(subtree, version, &mut span_data_table),
macro_name: self.name.to_string(),
attributes: attr.map(|subtree| FlatTree::new(subtree, version, &mut span_data_table)),
data: msg::ExpandMacroData {
macro_body: FlatTree::new(subtree, version, &mut span_data_table),
macro_name: self.name.to_string(),
attributes: attr
.map(|subtree| FlatTree::new(subtree, version, &mut span_data_table)),
has_global_spans: ExpnGlobals {
serialize: version >= HAS_GLOBAL_SPANS,
def_site,
call_site,
mixed_site,
},
span_data_table: if version >= RUST_ANALYZER_SPAN_SUPPORT {
serialize_span_data_index_map(&span_data_table)
} else {
Vec::new()
},
},
lib: self.dylib_path.to_path_buf().into(),
env: env.into(),
current_dir,
has_global_spans: ExpnGlobals {
serialize: version >= HAS_GLOBAL_SPANS,
def_site,
call_site,
mixed_site,
},
span_data_table: if version >= RUST_ANALYZER_SPAN_SUPPORT {
serialize_span_data_index_map(&span_data_table)
} else {
Vec::new()
},
};

let response = self
.process
.lock()
.unwrap_or_else(|e| e.into_inner())
.send_task(msg::Request::ExpandMacro(Box::new(task)))?;
let response = self.process.send_task(msg::Request::ExpandMacro(Box::new(task)))?;

match response {
msg::Response::ExpandMacro(it) => {
Expand Down
Loading

0 comments on commit ea7fdad

Please sign in to comment.