Skip to content

Commit 047e5b7

Browse files
authored
Merge pull request #1003 from rust-lang/macro-expansion
Migrate macro expansion to the orchestrator
2 parents dde4408 + ed60203 commit 047e5b7

File tree

5 files changed

+324
-305
lines changed

5 files changed

+324
-305
lines changed

compiler/base/orchestrator/src/coordinator.rs

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,56 @@ pub struct MiriResponse {
506506
pub exit_detail: String,
507507
}
508508

509+
#[derive(Debug, Clone)]
510+
pub struct MacroExpansionRequest {
511+
pub channel: Channel,
512+
pub crate_type: CrateType,
513+
pub edition: Edition,
514+
pub code: String,
515+
}
516+
517+
impl MacroExpansionRequest {
518+
pub(crate) fn delete_previous_main_request(&self) -> DeleteFileRequest {
519+
delete_previous_primary_file_request(self.crate_type)
520+
}
521+
522+
pub(crate) fn write_main_request(&self) -> WriteFileRequest {
523+
write_primary_file_request(self.crate_type, &self.code)
524+
}
525+
526+
pub(crate) fn execute_cargo_request(&self) -> ExecuteCommandRequest {
527+
ExecuteCommandRequest {
528+
cmd: "cargo".to_owned(),
529+
args: ["rustc", "--", "-Zunpretty=expanded"]
530+
.map(str::to_owned)
531+
.to_vec(),
532+
envs: Default::default(),
533+
cwd: None,
534+
}
535+
}
536+
}
537+
538+
impl CargoTomlModifier for MacroExpansionRequest {
539+
fn modify_cargo_toml(&self, mut cargo_toml: toml::Value) -> toml::Value {
540+
if self.edition == Edition::Rust2024 {
541+
cargo_toml = modify_cargo_toml::set_feature_edition2024(cargo_toml);
542+
}
543+
544+
cargo_toml = modify_cargo_toml::set_edition(cargo_toml, self.edition.to_cargo_toml_key());
545+
546+
if let Some(crate_type) = self.crate_type.to_library_cargo_toml_key() {
547+
cargo_toml = modify_cargo_toml::set_crate_type(cargo_toml, crate_type);
548+
}
549+
cargo_toml
550+
}
551+
}
552+
553+
#[derive(Debug, Clone)]
554+
pub struct MacroExpansionResponse {
555+
pub success: bool,
556+
pub exit_detail: String,
557+
}
558+
509559
#[derive(Debug, Clone)]
510560
pub struct WithOutput<T> {
511561
pub response: T,
@@ -721,6 +771,33 @@ where
721771
.await
722772
}
723773

774+
pub async fn macro_expansion(
775+
&self,
776+
request: MacroExpansionRequest,
777+
) -> Result<WithOutput<MacroExpansionResponse>, MacroExpansionError> {
778+
use macro_expansion_error::*;
779+
780+
self.select_channel(request.channel)
781+
.await
782+
.context(CouldNotStartContainerSnafu)?
783+
.macro_expansion(request)
784+
.await
785+
}
786+
787+
pub async fn begin_macro_expansion(
788+
&self,
789+
token: CancellationToken,
790+
request: MacroExpansionRequest,
791+
) -> Result<ActiveMacroExpansion, MacroExpansionError> {
792+
use macro_expansion_error::*;
793+
794+
self.select_channel(request.channel)
795+
.await
796+
.context(CouldNotStartContainerSnafu)?
797+
.begin_macro_expansion(token, request)
798+
.await
799+
}
800+
724801
pub async fn idle(&mut self) -> Result<()> {
725802
let Self {
726803
stable,
@@ -1217,6 +1294,78 @@ impl Container {
12171294
})
12181295
}
12191296

1297+
async fn macro_expansion(
1298+
&self,
1299+
request: MacroExpansionRequest,
1300+
) -> Result<WithOutput<MacroExpansionResponse>, MacroExpansionError> {
1301+
let token = Default::default();
1302+
1303+
let ActiveMacroExpansion {
1304+
task,
1305+
stdout_rx,
1306+
stderr_rx,
1307+
} = self.begin_macro_expansion(token, request).await?;
1308+
1309+
WithOutput::try_absorb(task, stdout_rx, stderr_rx).await
1310+
}
1311+
1312+
async fn begin_macro_expansion(
1313+
&self,
1314+
token: CancellationToken,
1315+
request: MacroExpansionRequest,
1316+
) -> Result<ActiveMacroExpansion, MacroExpansionError> {
1317+
use macro_expansion_error::*;
1318+
1319+
let delete_previous_main = request.delete_previous_main_request();
1320+
let write_main = request.write_main_request();
1321+
let execute_cargo = request.execute_cargo_request();
1322+
1323+
let delete_previous_main = self.commander.one(delete_previous_main);
1324+
let write_main = self.commander.one(write_main);
1325+
let modify_cargo_toml = self.modify_cargo_toml.modify_for(&request);
1326+
1327+
let (delete_previous_main, write_main, modify_cargo_toml) =
1328+
join!(delete_previous_main, write_main, modify_cargo_toml);
1329+
1330+
delete_previous_main.context(CouldNotDeletePreviousCodeSnafu)?;
1331+
write_main.context(CouldNotWriteCodeSnafu)?;
1332+
modify_cargo_toml.context(CouldNotModifyCargoTomlSnafu)?;
1333+
1334+
let SpawnCargo {
1335+
task,
1336+
stdin_tx,
1337+
stdout_rx,
1338+
stderr_rx,
1339+
} = self
1340+
.spawn_cargo_task(token, execute_cargo)
1341+
.await
1342+
.context(CouldNotStartCargoSnafu)?;
1343+
1344+
drop(stdin_tx);
1345+
1346+
let task = async move {
1347+
let ExecuteCommandResponse {
1348+
success,
1349+
exit_detail,
1350+
} = task
1351+
.await
1352+
.context(CargoTaskPanickedSnafu)?
1353+
.context(CargoFailedSnafu)?;
1354+
1355+
Ok(MacroExpansionResponse {
1356+
success,
1357+
exit_detail,
1358+
})
1359+
}
1360+
.boxed();
1361+
1362+
Ok(ActiveMacroExpansion {
1363+
task,
1364+
stdout_rx,
1365+
stderr_rx,
1366+
})
1367+
}
1368+
12201369
async fn spawn_cargo_task(
12211370
&self,
12221371
token: CancellationToken,
@@ -1528,6 +1677,47 @@ pub enum MiriError {
15281677
CargoFailed { source: SpawnCargoError },
15291678
}
15301679

1680+
pub struct ActiveMacroExpansion {
1681+
pub task: BoxFuture<'static, Result<MacroExpansionResponse, MacroExpansionError>>,
1682+
pub stdout_rx: mpsc::Receiver<String>,
1683+
pub stderr_rx: mpsc::Receiver<String>,
1684+
}
1685+
1686+
impl fmt::Debug for ActiveMacroExpansion {
1687+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1688+
f.debug_struct("ActiveMacroExpansion")
1689+
.field("task", &"<future>")
1690+
.field("stdout_rx", &self.stdout_rx)
1691+
.field("stderr_rx", &self.stderr_rx)
1692+
.finish()
1693+
}
1694+
}
1695+
1696+
#[derive(Debug, Snafu)]
1697+
#[snafu(module)]
1698+
pub enum MacroExpansionError {
1699+
#[snafu(display("Could not start the container"))]
1700+
CouldNotStartContainer { source: Error },
1701+
1702+
#[snafu(display("Could not modify Cargo.toml"))]
1703+
CouldNotModifyCargoToml { source: ModifyCargoTomlError },
1704+
1705+
#[snafu(display("Could not delete previous source code"))]
1706+
CouldNotDeletePreviousCode { source: CommanderError },
1707+
1708+
#[snafu(display("Could not write source code"))]
1709+
CouldNotWriteCode { source: CommanderError },
1710+
1711+
#[snafu(display("Could not start Cargo task"))]
1712+
CouldNotStartCargo { source: SpawnCargoError },
1713+
1714+
#[snafu(display("The Cargo task panicked"))]
1715+
CargoTaskPanicked { source: tokio::task::JoinError },
1716+
1717+
#[snafu(display("Cargo task failed"))]
1718+
CargoFailed { source: SpawnCargoError },
1719+
}
1720+
15311721
struct SpawnCargo {
15321722
task: JoinHandle<Result<ExecuteCommandResponse, SpawnCargoError>>,
15331723
stdin_tx: mpsc::Sender<String>,
@@ -3129,6 +3319,42 @@ mod tests {
31293319
Ok(())
31303320
}
31313321

3322+
const ARBITRARY_MACRO_EXPANSION_REQUEST: MacroExpansionRequest = MacroExpansionRequest {
3323+
channel: Channel::Nightly,
3324+
crate_type: CrateType::Library(LibraryType::Cdylib),
3325+
edition: Edition::Rust2018,
3326+
code: String::new(),
3327+
};
3328+
3329+
#[tokio::test]
3330+
#[snafu::report]
3331+
async fn macro_expansion() -> Result<()> {
3332+
let coordinator = new_coordinator().await;
3333+
3334+
let req = MacroExpansionRequest {
3335+
code: r#"
3336+
#[derive(Debug)]
3337+
struct Dummy;
3338+
3339+
fn main() { println!("Hello!"); }
3340+
"#
3341+
.into(),
3342+
..ARBITRARY_MACRO_EXPANSION_REQUEST
3343+
};
3344+
3345+
let response = coordinator
3346+
.macro_expansion(req)
3347+
.with_timeout()
3348+
.await
3349+
.unwrap();
3350+
3351+
assert!(response.success, "stderr: {}", response.stderr);
3352+
assert_contains!(response.stdout, "impl ::core::fmt::Debug for Dummy");
3353+
assert_contains!(response.stdout, "Formatter::write_str");
3354+
3355+
Ok(())
3356+
}
3357+
31323358
// The next set of tests are broader than the functionality of a
31333359
// single operation.
31343360

ui/src/main.rs

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::env::{PLAYGROUND_GITHUB_TOKEN, PLAYGROUND_UI_ROOT};
44
use serde::{Deserialize, Serialize};
55
use snafu::prelude::*;
66
use std::{
7-
convert::TryFrom,
87
net::SocketAddr,
98
path::{Path, PathBuf},
109
sync::Arc,
@@ -165,8 +164,6 @@ impl MetricsToken {
165164
enum Error {
166165
#[snafu(display("Sandbox creation failed: {}", source))]
167166
SandboxCreation { source: sandbox::Error },
168-
#[snafu(display("Expansion operation failed: {}", source))]
169-
Expansion { source: sandbox::Error },
170167
#[snafu(display("Caching operation failed: {}", source))]
171168
Caching { source: sandbox::Error },
172169
#[snafu(display("Gist creation failed: {}", source))]
@@ -210,10 +207,11 @@ enum Error {
210207
source: server_axum::api_orchestrator_integration_impls::ParseMiriRequestError,
211208
},
212209

213-
// Remove at a later point. From here ...
214-
#[snafu(display("The value {:?} is not a valid edition", value))]
215-
InvalidEdition { value: String },
216-
// ... to here
210+
#[snafu(context(false))]
211+
MacroExpansionRequest {
212+
source: server_axum::api_orchestrator_integration_impls::ParseMacroExpansionRequestError,
213+
},
214+
217215
#[snafu(display("No request was provided"))]
218216
RequestMissing,
219217
#[snafu(display("The cache has been poisoned"))]
@@ -256,6 +254,11 @@ enum Error {
256254
source: orchestrator::coordinator::MiriError,
257255
},
258256

257+
#[snafu(display("Unable to convert the macro expansion request"))]
258+
MacroExpansion {
259+
source: orchestrator::coordinator::MacroExpansionError,
260+
},
261+
259262
#[snafu(display("The operation timed out"))]
260263
Timeout { source: tokio::time::error::Elapsed },
261264

@@ -400,6 +403,7 @@ struct MacroExpansionRequest {
400403
#[derive(Debug, Clone, Serialize)]
401404
struct MacroExpansionResponse {
402405
success: bool,
406+
exit_detail: String,
403407
stdout: String,
404408
stderr: String,
405409
}
@@ -452,27 +456,6 @@ struct EvaluateResponse {
452456
error: Option<String>,
453457
}
454458

455-
impl TryFrom<MacroExpansionRequest> for sandbox::MacroExpansionRequest {
456-
type Error = Error;
457-
458-
fn try_from(me: MacroExpansionRequest) -> Result<Self> {
459-
Ok(sandbox::MacroExpansionRequest {
460-
code: me.code,
461-
edition: parse_edition(&me.edition)?,
462-
})
463-
}
464-
}
465-
466-
impl From<sandbox::MacroExpansionResponse> for MacroExpansionResponse {
467-
fn from(me: sandbox::MacroExpansionResponse) -> Self {
468-
MacroExpansionResponse {
469-
success: me.success,
470-
stdout: me.stdout,
471-
stderr: me.stderr,
472-
}
473-
}
474-
}
475-
476459
impl From<Vec<sandbox::CrateInformation>> for MetaCratesResponse {
477460
fn from(me: Vec<sandbox::CrateInformation>) -> Self {
478461
let crates = me
@@ -508,17 +491,6 @@ impl From<gist::Gist> for MetaGistResponse {
508491
}
509492
}
510493

511-
fn parse_edition(s: &str) -> Result<Option<sandbox::Edition>> {
512-
Ok(match s {
513-
"" => None,
514-
"2015" => Some(sandbox::Edition::Rust2015),
515-
"2018" => Some(sandbox::Edition::Rust2018),
516-
"2021" => Some(sandbox::Edition::Rust2021),
517-
"2024" => Some(sandbox::Edition::Rust2024),
518-
value => InvalidEditionSnafu { value }.fail()?,
519-
})
520-
}
521-
522494
fn default_crate_type() -> String {
523495
"bin".into()
524496
}

0 commit comments

Comments
 (0)