Skip to content

Commit 194280b

Browse files
authored
feat(hydro_lang): introduce sliced! syntax for processing with anonymous ticks (#2256)
1 parent 48fa7f8 commit 194280b

22 files changed

Lines changed: 850 additions & 99 deletions

File tree

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# See "Adding new crates" and "Moving crates" addendum sections in `RELEASING.md`
44
members = [
55
"benches",
6+
"copy_span",
67
"dfir_lang",
78
"dfir_macro",
89
"dfir_rs",

copy_span/Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "copy_span"
3+
publish = true
4+
version = "0.1.0"
5+
documentation = "https://docs.rs/copy_span/"
6+
description = "Macro emitting tokens with the span of another set of tokens."
7+
edition = { workspace = true }
8+
repository = { workspace = true }
9+
license = { workspace = true }
10+
11+
[lints]
12+
workspace = true
13+
14+
[lib]
15+
proc-macro = true
16+
17+
[dependencies]
18+
proc-macro2 = "1.0.95"
19+
syn = { version = "2", features = [ "parsing", "extra-traits" ] }

copy_span/src/lib.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use syn::spanned::Spanned;
2+
3+
struct CopySpanInput {
4+
source: syn::Expr,
5+
target: proc_macro2::TokenStream,
6+
}
7+
8+
impl syn::parse::Parse for CopySpanInput {
9+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
10+
let source: syn::Expr = input.parse()?;
11+
input.parse::<syn::Token![,]>()?;
12+
let target: proc_macro2::TokenStream = input.parse()?;
13+
Ok(CopySpanInput { source, target })
14+
}
15+
}
16+
17+
fn recursively_set_span(token: &mut proc_macro2::TokenTree, span: proc_macro2::Span) {
18+
match token {
19+
proc_macro2::TokenTree::Group(group) => {
20+
let new_stream = group
21+
.stream()
22+
.into_iter()
23+
.map(|mut inner_token| {
24+
recursively_set_span(&mut inner_token, span);
25+
inner_token
26+
})
27+
.collect();
28+
29+
let mut new_group = proc_macro2::Group::new(group.delimiter(), new_stream);
30+
new_group.set_span(span);
31+
*group = new_group;
32+
}
33+
_ => {
34+
token.set_span(span);
35+
}
36+
}
37+
}
38+
39+
#[proc_macro]
40+
pub fn copy_span(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
41+
let CopySpanInput { source, target } = syn::parse_macro_input!(input as CopySpanInput);
42+
43+
let mut inner_source = source;
44+
while let syn::Expr::Group(g) = inner_source {
45+
inner_source = *g.expr;
46+
}
47+
48+
let output = target
49+
.into_iter()
50+
.fold(proc_macro2::TokenStream::new(), |mut acc, mut token| {
51+
recursively_set_span(&mut token, inner_source.span());
52+
acc.extend(std::iter::once(token));
53+
acc
54+
});
55+
56+
proc_macro::TokenStream::from(output)
57+
}

hydro_lang/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ bincode = "1.3.1"
6060
clap = { version = "4.0", features = ["derive"], optional = true }
6161
hydro_deploy = { path = "../hydro_deploy/core", version = "^0.14.0", optional = true }
6262
hydro_deploy_integration = { path = "../hydro_deploy/hydro_deploy_integration", version = "^0.14.0", optional = true }
63+
copy_span = { path = "../copy_span", version = "^0.1.0" }
6364
dfir_rs = { path = "../dfir_rs", version = "^0.14.0", default-features = false, optional = true }
6465
dfir_lang = { path = "../dfir_lang", version = "^0.14.0", optional = true }
6566
futures = "0.3.0"

hydro_lang/src/compile/ir/backtrace.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,34 @@ pub struct Backtrace;
1717
#[derive(Clone)]
1818
pub struct Backtrace {
1919
skip_count: usize,
20+
col_offset: usize, // whether this is from `sliced!` which requires an offset
2021
inner: RefCell<backtrace::Backtrace>,
2122
resolved: RefCell<Option<Vec<BacktraceElement>>>,
2223
}
2324

25+
#[cfg(stageleft_runtime)]
26+
#[cfg(feature = "build")]
27+
#[doc(hidden)]
28+
pub fn __macro_get_backtrace(col_offset: usize) -> Backtrace {
29+
let mut out = Backtrace::get_backtrace(1);
30+
out.col_offset = col_offset;
31+
out
32+
}
33+
34+
#[cfg(not(feature = "build"))]
35+
#[doc(hidden)]
36+
pub fn __macro_get_backtrace(_col_offset: usize) -> Backtrace {
37+
panic!();
38+
}
39+
2440
impl Backtrace {
2541
#[cfg(feature = "build")]
2642
#[inline(never)]
2743
pub(crate) fn get_backtrace(skip_count: usize) -> Backtrace {
2844
let backtrace = backtrace::Backtrace::new_unresolved();
2945
Backtrace {
3046
skip_count,
47+
col_offset: 0,
3148
inner: RefCell::new(backtrace),
3249
resolved: RefCell::new(None),
3350
}
@@ -50,7 +67,7 @@ impl Backtrace {
5067
.get_or_insert_with(|| {
5168
let mut inner_borrow = self.inner.borrow_mut();
5269
inner_borrow.resolve();
53-
inner_borrow
70+
let mut collected: Vec<_> = inner_borrow
5471
.frames()
5572
.iter()
5673
.skip_while(|f| {
@@ -84,7 +101,17 @@ impl Backtrace {
84101
addr: symbol.addr().map(|a| a as usize),
85102
}
86103
})
87-
.collect()
104+
.collect();
105+
106+
if self.col_offset > 0
107+
&& let Some(first) = collected.first_mut()
108+
{
109+
first.colno = first
110+
.colno
111+
.map(|c| c.saturating_sub(self.col_offset as u32));
112+
}
113+
114+
collected
88115
})
89116
.clone()
90117
}

hydro_lang/src/compile/ir/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3775,12 +3775,12 @@ mod test {
37753775

37763776
#[test]
37773777
fn hydro_node_size() {
3778-
assert_eq!(size_of::<HydroNode>(), 264);
3778+
assert_eq!(size_of::<HydroNode>(), 272);
37793779
}
37803780

37813781
#[test]
37823782
fn hydro_root_size() {
3783-
assert_eq!(size_of::<HydroRoot>(), 160);
3783+
assert_eq!(size_of::<HydroRoot>(), 168);
37843784
}
37853785

37863786
#[test]

hydro_lang/src/compile/ir/snapshots/hydro_lang__compile__ir__backtrace__tests__backtrace.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ expression: elements
66
BacktraceElement {
77
fn_name: "hydro_lang::compile::ir::backtrace::tests::test_backtrace",
88
lineno: Some(
9-
128,
9+
155,
1010
),
1111
colno: Some(
1212
25,
@@ -15,7 +15,7 @@ expression: elements
1515
BacktraceElement {
1616
fn_name: "hydro_lang::compile::ir::backtrace::tests::test_backtrace::{{closure}}",
1717
lineno: Some(
18-
127,
18+
154,
1919
),
2020
colno: Some(
2121
24,

hydro_lang/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ pub mod runtime_support {
2424
pub mod resource_measurement;
2525
}
2626

27+
#[doc(hidden)]
28+
pub mod macro_support {
29+
pub use copy_span;
30+
}
31+
2732
pub mod prelude {
2833
// taken from `tokio`
2934
//! A "prelude" for users of the `hydro_lang` crate.
@@ -44,6 +49,7 @@ pub mod prelude {
4449
pub use crate::live_collections::keyed_stream::KeyedStream;
4550
pub use crate::live_collections::optional::Optional;
4651
pub use crate::live_collections::singleton::Singleton;
52+
pub use crate::live_collections::sliced::sliced;
4753
pub use crate::live_collections::stream::Stream;
4854
pub use crate::location::{Cluster, External, Location as _, Process, Tick};
4955
pub use crate::nondet::{NonDet, nondet};

hydro_lang/src/live_collections/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,5 @@ pub use singleton::Singleton;
3535
pub mod stream;
3636
#[doc(inline)]
3737
pub use stream::Stream;
38+
39+
pub mod sliced;

0 commit comments

Comments
 (0)