Skip to content

Commit e99802f

Browse files
refactor(dfir_lang): more precise span on generic diagnostics (#2676)
1 parent 0fe74c4 commit e99802f

File tree

7 files changed

+67
-15
lines changed

7 files changed

+67
-15
lines changed

dfir_lang/src/graph/meta_graph.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ impl DfirGraph {
308308
.contains(&generics.persistence_args.len())
309309
{
310310
diagnostics.push(Diagnostic::spanned(
311-
generics_span,
311+
generics.persistence_args_span().unwrap_or(generics_span),
312312
Level::Error,
313313
format!(
314314
"`{}` should have {} persistence lifetime arguments, actually has {}.",
@@ -320,7 +320,7 @@ impl DfirGraph {
320320
}
321321
if !op_constraints.type_args.contains(&generics.type_args.len()) {
322322
diagnostics.push(Diagnostic::spanned(
323-
generics_span,
323+
generics.type_args_span().unwrap_or(generics_span),
324324
Level::Error,
325325
format!(
326326
"`{}` should have {} generic type arguments, actually has {}.",

dfir_lang/src/graph/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,45 @@ pub struct OpInstGenerics {
213213
pub type_args: Vec<Type>,
214214
}
215215

216+
impl OpInstGenerics {
217+
/// Helper to join a sequence of spans into a single span, if possible.
218+
///
219+
/// Returns `None` if there are no spans or if any `Span::join` call fails
220+
/// (for example, when spans are not contiguous).
221+
fn join_spans<I>(mut spans: I) -> Option<Span>
222+
where
223+
I: Iterator<Item = Span>,
224+
{
225+
let mut span = spans.next()?;
226+
for s in spans {
227+
span = span.join(s)?;
228+
}
229+
Some(span)
230+
}
231+
232+
/// Returns a [`Span`] containing all persistence (lifetime) args if possible.
233+
pub fn persistence_args_span(&self) -> Option<Span> {
234+
self.generic_args.as_ref().and_then(|args| {
235+
Self::join_spans(
236+
args.iter()
237+
.filter(|a| matches!(a, GenericArgument::Lifetime(_)))
238+
.map(|a| a.span()),
239+
)
240+
})
241+
}
242+
243+
/// Returns a [`Span`] containing all type args if possible.
244+
pub fn type_args_span(&self) -> Option<Span> {
245+
self.generic_args.as_ref().and_then(|args| {
246+
Self::join_spans(
247+
args.iter()
248+
.filter(|a| matches!(a, GenericArgument::Type(_)))
249+
.map(|a| a.span()),
250+
)
251+
})
252+
}
253+
}
254+
216255
/// Gets the generic arguments for the operator.
217256
///
218257
/// This helper method is useful due to the special handling of persistence lifetimes (`'static`,
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
error: `lattice_fold` should have exactly 0 generic type arguments, actually has 1.
2-
--> tests/compile-fail-stable/surface_lattice_fold_wronggeneric.rs:6:31
2+
--> tests/compile-fail-stable/surface_lattice_fold_wronggeneric.rs:7:40
33
|
4-
6 | ... -> lattice_fold::<'static, dfir_rs::lattices::set_union::SetUnionHashSet<u32>>(dfir_rs::lattices::set_union::SetUnionHashSet::<u32>...
5-
| ^^^^^^^
4+
7 | -> lattice_fold::<'static, SetUnionHashSet<u32>>(SetUnionHashSet::<u32>::default())
5+
| ^^^^^^^^^^^^^^^
6+
7+
warning: unused import: `dfir_rs::lattices::set_union::SetUnionHashSet`
8+
--> tests/compile-fail-stable/surface_lattice_fold_wronggeneric.rs:2:5
9+
|
10+
2 | use dfir_rs::lattices::set_union::SetUnionHashSet;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
|
13+
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
error: `lattice_reduce` should have exactly 0 generic type arguments, actually has 1.
2-
--> tests/compile-fail-stable/surface_lattice_reduce_wronggeneric.rs:6:33
2+
--> tests/compile-fail-stable/surface_lattice_reduce_wronggeneric.rs:7:42
33
|
4-
6 | -> lattice_reduce::<'static, dfir_rs::lattices::set_union::SetUnionHashSet<u32>>()
5-
| ^^^^^^^
4+
7 | -> lattice_reduce::<'static, SetUnionHashSet<u32>>()
5+
| ^^^^^^^^^^^^^^^
6+
7+
warning: unused import: `dfir_rs::lattices::set_union::SetUnionHashSet`
8+
--> tests/compile-fail-stable/surface_lattice_reduce_wronggeneric.rs:2:5
9+
|
10+
2 | use dfir_rs::lattices::set_union::SetUnionHashSet;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
|
13+
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default

dfir_rs/tests/compile-fail/surface_lattice_fold_wronggeneric.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use dfir_rs::dfir_syntax;
2+
use dfir_rs::lattices::set_union::SetUnionHashSet;
23

34
fn main() {
45
let mut df = dfir_syntax! {
56
source_iter([1,2,3,4,5])
6-
-> lattice_fold::<'static, dfir_rs::lattices::set_union::SetUnionHashSet<u32>>(dfir_rs::lattices::set_union::SetUnionHashSet::<u32>::default())
7+
-> lattice_fold::<'static, SetUnionHashSet<u32>>(SetUnionHashSet::<u32>::default())
78
-> for_each(|x| println!("Least upper bound: {:?}", x));
89
};
910
df.run_available_sync();

dfir_rs/tests/compile-fail/surface_lattice_fold_wronggeneric.stderr

Lines changed: 0 additions & 5 deletions
This file was deleted.

dfir_rs/tests/compile-fail/surface_lattice_reduce_wronggeneric.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use dfir_rs::dfir_syntax;
2+
use dfir_rs::lattices::set_union::SetUnionHashSet;
23

34
fn main() {
45
let mut df = dfir_syntax! {
56
source_iter([1,2,3,4,5])
6-
-> lattice_reduce::<'static, dfir_rs::lattices::set_union::SetUnionHashSet<u32>>()
7+
-> lattice_reduce::<'static, SetUnionHashSet<u32>>()
78
-> for_each(|x| println!("Least upper bound: {:?}", x));
89
};
910
df.run_available_sync();

0 commit comments

Comments
 (0)