diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e9aa17667d..40e4c9ad330 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -182,6 +182,10 @@ jobs: - name: Run cargo nextest on all targets run: cargo nextest run --no-fail-fast --features python --features deploy --all-targets + env: + # On stable the output messages will often not match pinned-nightly, so we set to 'overwrite'. + TRYBUILD: ${{ matrix.rust_release == 'pinned-nightly' && 'wip' || 'overwrite' }} + HYDROFLOW_EXPECT_WARNINGS: ${{ matrix.rust_release == 'pinned-nightly' && 'noop' || 'ignore' }} - name: Run doctests run: cargo test --no-fail-fast --features python --features deploy --doc diff --git a/hydroflow/src/declarative_macro.rs b/hydroflow/src/declarative_macro.rs index 54d790c9c7b..12f8d3ece97 100644 --- a/hydroflow/src/declarative_macro.rs +++ b/hydroflow/src/declarative_macro.rs @@ -55,24 +55,32 @@ macro_rules! hydroflow_expect_warnings { $( , )? ) => { { - let __file = std::file!(); - let __line = std::line!() as usize; - let __hf = hydroflow::hydroflow_syntax_noemit! $hf; + fn emit(msg: impl ::std::convert::AsRef) { + if Ok("ignore") == ::std::env::var("HYDROFLOW_EXPECT_WARNINGS").as_deref() { + eprintln!("{}", msg.as_ref()); + } else { + panic!("{}", msg.as_ref()); + } + } + + let __file = ::std::file!(); + let __line = ::std::line!() as usize; + let __hf = $crate::hydroflow_syntax_noemit! $hf; let actuals = __hf.diagnostics().expect("Expected `diagnostics()` to be set."); let actuals_len = actuals.len(); - let actuals = std::collections::BTreeSet::from_iter(actuals.iter().cloned().map(|mut actual| { + let actuals = ::std::collections::BTreeSet::from_iter(actuals.iter().cloned().map(|mut actual| { actual.span.line = actual.span.line.saturating_sub(__line); - std::borrow::Cow::<'static, str>::Owned(actual.to_string().replace(__file, "$FILE")) + ::std::borrow::Cow::<'static, str>::Owned(actual.to_string().replace(__file, "$FILE")) })); let expecteds = [ $( - std::borrow::Cow::Borrowed( $msg ), + ::std::borrow::Cow::Borrowed( $msg ), )* ]; let expecteds_len = expecteds.len(); - let expecteds = std::collections::BTreeSet::from(expecteds); + let expecteds = ::std::collections::BTreeSet::from(expecteds); let missing_errs = expecteds.difference(&actuals).map(|missing| { format!("Expected diagnostic `{}` was not emitted.", missing) @@ -80,13 +88,18 @@ macro_rules! hydroflow_expect_warnings { let extra_errs = actuals.difference(&expecteds).map(|extra| { format!("Unexpected extra diagnostic `{}` was emitted", extra) }); - let all_errs: Vec<_> = missing_errs.chain(extra_errs).collect(); + let all_errs: ::std::vec::Vec<_> = missing_errs.chain(extra_errs).collect(); if !all_errs.is_empty() { - panic!("{}", all_errs.join("\n")); + emit(all_errs.join("\n")); } - // TODO(mingwei): fix duplicates generated from multi-pass flow prop algorithm. - // assert_eq!(actuals_len, expecteds_len, "Wrong nubmer of diagnostics, were there duplicates?"); + if actuals_len != expecteds_len { + emit(format!( + "Number of expected warnings ({}) does not match number of actual warnings ({}), were there duplicates?", + expecteds_len, + actuals_len + )); + } __hf } diff --git a/hydroflow/tests/surface_warnings.rs b/hydroflow/tests/surface_warnings.rs index fa9826083cd..0b73113b271 100644 --- a/hydroflow/tests/surface_warnings.rs +++ b/hydroflow/tests/surface_warnings.rs @@ -1,7 +1,3 @@ -// TODO(mingwei): fix line numbers in tests -// https://github.com/hydro-project/hydroflow/issues/729 -// https://github.com/rust-lang/rust/pull/111571 - use std::cell::RefCell; use std::rc::Rc; diff --git a/hydroflow_lang/src/diagnostic.rs b/hydroflow_lang/src/diagnostic.rs index 06dca5c6905..1ac175d9e50 100644 --- a/hydroflow_lang/src/diagnostic.rs +++ b/hydroflow_lang/src/diagnostic.rs @@ -192,6 +192,10 @@ pub struct SerdeSpan { } impl From for SerdeSpan { fn from(span: Span) -> Self { + #[cfg_attr( + not(nightly), + expect(unused_labels, reason = "conditional compilation") + )] let path = 'a: { #[cfg(nightly)] if proc_macro::is_available() { @@ -204,7 +208,7 @@ impl From for SerdeSpan { .into(); } - break 'a "unknown".into(); + "unknown".into() }; Self { diff --git a/hydroflow_lang/src/graph/hydroflow_graph.rs b/hydroflow_lang/src/graph/hydroflow_graph.rs index 9f964f02dd2..13af7adb8e6 100644 --- a/hydroflow_lang/src/graph/hydroflow_graph.rs +++ b/hydroflow_lang/src/graph/hydroflow_graph.rs @@ -1008,6 +1008,10 @@ impl HydroflowGraph { subgraph_op_iter_code.push(write_iterator); if include_type_guards { + #[cfg_attr( + not(nightly), + expect(unused_labels, reason = "conditional compilation") + )] let source_info = 'a: { #[cfg(nightly)] if proc_macro::is_available() { @@ -1027,13 +1031,13 @@ impl HydroflowGraph { ); } - break 'a format!( + format!( "loc_nopath_{}_{}_{}_{}", op_span.start().line, op_span.start().column, op_span.end().line, op_span.end().column - ); + ) }; let fn_ident = format_ident!(