From 327e19744099d7b1854ddb2cf91cb9ca7b80403a Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Wed, 11 Dec 2024 13:20:50 -0800 Subject: [PATCH] try_emit --- .github/workflows/ci.yml | 44 +++++++++++++++---------------- Cargo.lock | 1 + hydroflow/Cargo.toml | 3 +-- hydroflow/src/lib.rs | 6 +---- hydroflow_datalog/src/lib.rs | 14 +++++++--- hydroflow_datalog_core/src/lib.rs | 1 + hydroflow_lang/src/diagnostic.rs | 14 ++++------ hydroflow_macro/Cargo.toml | 1 + hydroflow_macro/build.rs | 9 +++++++ hydroflow_macro/src/lib.rs | 33 +++++++++-------------- 10 files changed, 64 insertions(+), 62 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82eda5e7febf..7af071b226a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,13 +36,13 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - rust_release: [pinned-nightly, latest-stable] + rust_release: [pinned-nightly, latest-nightly] exclude: # For non-pull requests, event_name != 'pull_request' will be true, and 'nothing' is # truthy, so the entire && operator will resolve to 'nothing'. Then the || operator will # resolve to 'nothing' so we will exclude 'nothing'. https://stackoverflow.com/a/73822998 - rust_release: ${{ (needs.pre_job.outputs.should_skip != 'true' && 'nothing') || 'pinned-nightly' }} - - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-stable' }} + - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-nightly' }} env: CARGO_TERM_COLOR: always @@ -55,12 +55,12 @@ jobs: - name: Checkout sources uses: actions/checkout@v3 - - name: Install toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: stable - override: ${{ matrix.rust_release == 'latest-stable' }} + toolchain: nightly + override: ${{ matrix.rust_release == 'latest-nightly' }} components: rustfmt, clippy - name: Run sccache-cache @@ -96,25 +96,25 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust_release: [pinned-nightly, latest-stable] + rust_release: [pinned-nightly, latest-nightly] exclude: # For non-pull requests, event_name != 'pull_request' will be true, and 'nothing' is # truthy, so the entire && operator will resolve to 'nothing'. Then the || operator will # resolve to 'nothing' so we will exclude 'nothing'. https://stackoverflow.com/a/73822998 - rust_release: ${{ (needs.pre_job.outputs.should_skip != 'true' && 'nothing') || 'pinned-nightly' }} - - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-stable' }} + - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-nightly' }} steps: - name: Checkout sources uses: actions/checkout@v3 - - name: Install toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: stable + toolchain: nightly target: wasm32-unknown-unknown - override: ${{ matrix.rust_release == 'latest-stable' }} + override: ${{ matrix.rust_release == 'latest-nightly' }} - name: Check hydroflow_lang uses: actions-rs/cargo@v1 @@ -132,13 +132,13 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - rust_release: [pinned-nightly, latest-stable] + rust_release: [pinned-nightly, latest-nightly] exclude: # For non-pull requests, event_name != 'pull_request' will be true, and 'nothing' is # truthy, so the entire && operator will resolve to 'nothing'. Then the || operator will # resolve to 'nothing' so we will exclude 'nothing'. https://stackoverflow.com/a/73822998 - rust_release: ${{ (needs.pre_job.outputs.should_skip != 'true' && 'nothing') || 'pinned-nightly' }} - - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-stable' }} + - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-nightly' }} - os: ${{ (github.event_name != 'pull_request' && 'nothing') || 'windows-latest' }} env: @@ -152,12 +152,12 @@ jobs: - name: Checkout sources uses: actions/checkout@v3 - - name: Install toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: stable - override: ${{ matrix.rust_release == 'latest-stable' }} + toolchain: nightly + override: ${{ matrix.rust_release == 'latest-nightly' }} - name: Run sccache-cache if: matrix.rust_release == 'pinned-nightly' @@ -235,25 +235,25 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust_release: [pinned-nightly, latest-stable] + rust_release: [pinned-nightly, latest-nightly] exclude: # For non-pull requests, event_name != 'pull_request' will be true, and 'nothing' is # truthy, so the entire && operator will resolve to 'nothing'. Then the || operator will # resolve to 'nothing' so we will exclude 'nothing'. https://stackoverflow.com/a/73822998 - rust_release: ${{ (needs.pre_job.outputs.should_skip != 'true' && 'nothing') || 'pinned-nightly' }} - - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-stable' }} + - rust_release: ${{ (github.event_name != 'pull_request' && 'nothing') || 'latest-nightly' }} steps: - name: Checkout sources uses: actions/checkout@v3 - - name: Install toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: stable + toolchain: nightly target: wasm32-unknown-unknown - override: ${{ matrix.rust_release == 'latest-stable' }} + override: ${{ matrix.rust_release == 'latest-nightly' }} - name: Get wasm-bindgen version id: wasm-bindgen-version @@ -299,7 +299,7 @@ jobs: - name: Checkout sources uses: actions/checkout@v3 - - name: Install toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal @@ -366,7 +366,7 @@ jobs: - name: Checkout sources uses: actions/checkout@v3 - - name: Install toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal diff --git a/Cargo.lock b/Cargo.lock index e762579e1353..d97a41f0818c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1577,6 +1577,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", + "rustc_version 0.4.1", "syn 2.0.75", ] diff --git a/hydroflow/Cargo.toml b/hydroflow/Cargo.toml index e55322b13168..e8d74c3a8a5a 100644 --- a/hydroflow/Cargo.toml +++ b/hydroflow/Cargo.toml @@ -11,9 +11,8 @@ description = "Hydro's low-level dataflow runtime and IR" workspace = true [features] -default = [ "macros", "nightly", "debugging" ] +default = [ "macros", "debugging" ] -nightly = [] macros = [ "hydroflow_macro", "hydroflow_datalog" ] hydroflow_macro = [ "dep:hydroflow_macro" ] hydroflow_datalog = [ "dep:hydroflow_datalog" ] diff --git a/hydroflow/src/lib.rs b/hydroflow/src/lib.rs index 2970b129f08d..effc596dc57b 100644 --- a/hydroflow/src/lib.rs +++ b/hydroflow/src/lib.rs @@ -1,4 +1,3 @@ -#![cfg_attr(feature = "nightly", feature(never_type))] #![warn(missing_docs)] //! Hydroflow is a low-level dataflow-based runtime system for the [Hydro Project](https://hydro.run/). @@ -39,12 +38,9 @@ pub use hydroflow_macro::{ hydroflow_test as test, monotonic_fn, morphism, DemuxEnum, }; +// TODO(mingwei): Use the [nightly "never" type `!`](https://doc.rust-lang.org/std/primitive.never.html) /// Stand-in for the [nightly "never" type `!`](https://doc.rust-lang.org/std/primitive.never.html) -#[cfg(not(feature = "nightly"))] pub type Never = std::convert::Infallible; -/// The [nightly "never" type `!`](https://doc.rust-lang.org/std/primitive.never.html) -#[cfg(feature = "nightly")] -pub type Never = !; #[cfg(doctest)] mod booktest { diff --git a/hydroflow_datalog/src/lib.rs b/hydroflow_datalog/src/lib.rs index f1bd816360f9..919115bd986b 100644 --- a/hydroflow_datalog/src/lib.rs +++ b/hydroflow_datalog/src/lib.rs @@ -1,3 +1,4 @@ +use hydroflow_datalog_core::diagnostic::Diagnostic; use hydroflow_datalog_core::{gen_hydroflow_graph, hydroflow_graph_to_program}; use proc_macro2::Span; use quote::{quote, ToTokens}; @@ -31,10 +32,15 @@ pub fn datalog(item: proc_macro::TokenStream) -> proc_macro::TokenStream { program.to_token_stream().into() } Err(diagnostics) => { - for diagnostic in diagnostics { - diagnostic.emit(); - } - proc_macro::TokenStream::from(quote!(hydroflow::scheduled::graph::Hydroflow::new())) + let diagnostic_tokens = Diagnostic::try_emit_all(diagnostics.iter()) + .err() + .unwrap_or_default(); + proc_macro::TokenStream::from(quote! { + { + #diagnostic_tokens + hydroflow::scheduled::graph::Hydroflow::new() + } + }) } } } diff --git a/hydroflow_datalog_core/src/lib.rs b/hydroflow_datalog_core/src/lib.rs index 27203bdd6a3c..64835e74ab6e 100644 --- a/hydroflow_datalog_core/src/lib.rs +++ b/hydroflow_datalog_core/src/lib.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet}; use std::ops::Deref; +pub use hydroflow_lang::diagnostic; use hydroflow_lang::diagnostic::{Diagnostic, Level}; use hydroflow_lang::graph::{ eliminate_extra_unions_tees, partition_graph, FlatGraphBuilder, HydroflowGraph, diff --git a/hydroflow_lang/src/diagnostic.rs b/hydroflow_lang/src/diagnostic.rs index 0941bfc319c1..518fce44d48a 100644 --- a/hydroflow_lang/src/diagnostic.rs +++ b/hydroflow_lang/src/diagnostic.rs @@ -194,19 +194,15 @@ pub struct SerdeSpan { impl From for SerdeSpan { fn from(span: Span) -> Self { #[cfg(nightly)] - let path = span - .unwrap() - .source_file() - .path() - .display() - .to_string() - .into(); + let path = std::panic::catch_unwind(|| span.unwrap()) + .map(|span| span.source_file().path().display().to_string()) + .ok(); #[cfg(not(nightly))] - let path = "unknown".into(); + let path = None::; Self { - path, + path: path.map_or(Cow::Borrowed("unknown"), Cow::Owned), line: span.start().line, column: span.start().column, } diff --git a/hydroflow_macro/Cargo.toml b/hydroflow_macro/Cargo.toml index 16c9450b7fdd..4581adb99608 100644 --- a/hydroflow_macro/Cargo.toml +++ b/hydroflow_macro/Cargo.toml @@ -27,3 +27,4 @@ syn = { version = "2.0.46", features = [ "parsing", "extra-traits" ] } hydroflow_lang = { path = "../hydroflow_lang", version = "^0.10.0" } itertools = "0.10.0" quote = "1.0.35" +rustc_version = "0.4.0" diff --git a/hydroflow_macro/build.rs b/hydroflow_macro/build.rs index adf5e9459b2f..3fa4cb3c6f8e 100644 --- a/hydroflow_macro/build.rs +++ b/hydroflow_macro/build.rs @@ -10,6 +10,7 @@ use hydroflow_lang::graph::ops::{PortListSpec, OPERATORS}; use hydroflow_lang::graph::PortIndexValue; use itertools::Itertools; use quote::ToTokens; +use rustc_version::{version_meta, Channel}; const FILENAME: &str = "surface_ops_gen.md"; @@ -207,6 +208,14 @@ fn update_book() -> Result<()> { } fn main() { + println!("cargo::rustc-check-cfg=cfg(nightly)"); + if matches!( + version_meta().map(|meta| meta.channel), + Ok(Channel::Nightly) + ) { + println!("cargo:rustc-cfg=nightly"); + } + if Err(VarError::NotPresent) != std::env::var("CARGO_CFG_HYDROFLOW_GENERATE_DOCS") { if let Err(err) = update_book() { eprintln!("hydroflow_macro/build.rs error: {:?}", err); diff --git a/hydroflow_macro/src/lib.rs b/hydroflow_macro/src/lib.rs index 96ff839cd7d1..f03ae0dc87e0 100644 --- a/hydroflow_macro/src/lib.rs +++ b/hydroflow_macro/src/lib.rs @@ -1,5 +1,5 @@ #![cfg_attr( - feature = "diagnostics", + nightly, feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site) )] @@ -72,25 +72,16 @@ fn hydroflow_syntax_internal( .iter() .filter(|diag: &&Diagnostic| Some(diag.level) <= min_diagnostic_level); - #[cfg(feature = "diagnostics")] - { - diagnostics.for_each(Diagnostic::emit); - tokens.into() - } - - #[cfg(not(feature = "diagnostics"))] - { - let diagnostics = diagnostics.map(Diagnostic::to_tokens); - quote! { - { - #( - #diagnostics - )* - #tokens - } + let diagnostic_tokens = Diagnostic::try_emit_all(diagnostics) + .err() + .unwrap_or_default(); + quote! { + { + #diagnostic_tokens + #tokens } - .into() } + .into() } /// Parse Hydroflow "surface syntax" without emitting code. @@ -123,8 +114,10 @@ pub fn hydroflow_parser(input: proc_macro::TokenStream) -> proc_macro::TokenStre } } - diagnostics.iter().for_each(Diagnostic::emit); - quote! {}.into() + Diagnostic::try_emit_all(diagnostics.iter()) + .err() + .unwrap_or_default() + .into() } #[doc(hidden)]