Skip to content

Commit 9470219

Browse files
authored
Merge pull request #1506 from cryspen/ocaml-spans-reviewable
Rust engine: Add spans to the Rust AST.
2 parents b82bd9c + f9dae86 commit 9470219

File tree

5 files changed

+56
-19
lines changed

5 files changed

+56
-19
lines changed

engine/lib/export_ast.ml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ module Make (FA : Features.T) = struct
241241
sub_pat = Option.map ~f:(fun (p, _) -> dpat p) subpat;
242242
}
243243

244-
and dspan (_span : span) : B.span = EmptyStructspan2
244+
and dspan : span -> B.span = Span.to_span2
245245

246246
and dbinding_mode (binding_mode : A.binding_mode) : B.binding_mode =
247247
match binding_mode with
@@ -458,12 +458,8 @@ module Make (FA : Features.T) = struct
458458
{
459459
attributes = List.map ~f:dattr p.attrs;
460460
pat = dpat p.pat;
461-
ty =
462-
{
463-
ty = dty p.typ;
464-
span =
465-
EmptyStructspan2 (* Should use dspan, but what if option is None*);
466-
};
461+
ty = dty p.typ;
462+
ty_span = Option.map ~f:dspan p.typ_span;
467463
}
468464

469465
let dvariant (v : A.variant) : B.variant =
@@ -513,7 +509,7 @@ module Make (FA : Features.T) = struct
513509
meta = dmetadata ~attrs:ii.ii_attrs ii.ii_span;
514510
}
515511

516-
let ditem' (item : A.item') : B.item_kind =
512+
let ditem' (item : A.item') (span : Types.span2) : B.item_kind =
517513
match item with
518514
| A.Fn { name; generics; body; params; safety } ->
519515
B.Fn
@@ -578,7 +574,7 @@ module Make (FA : Features.T) = struct
578574
| A.HaxError s ->
579575
let node : Types.fragment = Unknown "HaxError" in
580576
let info : B.diagnostic_info =
581-
{ context = Import; kind = Custom s; span = EmptyStructspan2 }
577+
{ context = Import; kind = Custom s; span }
582578
in
583579
Error { node; info }
584580
| A.NotImplementedYet -> B.NotImplementedYet
@@ -587,7 +583,7 @@ module Make (FA : Features.T) = struct
587583
[
588584
{
589585
ident = dconcrete_ident i.ident;
590-
kind = ditem' i.v;
586+
kind = ditem' i.v (dspan i.span);
591587
meta = dmetadata ~attrs:i.attrs i.span;
592588
};
593589
]

engine/lib/span.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,13 @@ let default = { id = 0; data = []; owner_hint = None }
151151
let owner_hint span =
152152
span.owner_hint
153153
|> Option.bind ~f:(fun (OwnerId id) -> List.nth !owner_id_list id)
154+
155+
let to_span2 span : Types.span2 =
156+
{
157+
data = List.map ~f:Imported.span_to_thir span.data;
158+
id = Int.to_string span.id;
159+
owner_hint =
160+
Option.map
161+
~f:(fun (OwnerId n) -> Types.Newtypeowner_id (Int.to_string n))
162+
span.owner_hint;
163+
}

engine/lib/span.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ enhance user reporting, not for any logic within the engine. *)
3434
val owner_hint : t -> Types.def_id option
3535
(** Looks up the owner hint for a span. This should be used for user
3636
reports only. *)
37+
38+
val to_span2 : t -> Types.span2
39+
(** Converts this span to a span2 for export to the Rust engine. *)

rust-printer/src/ast.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,9 @@ pub struct Param {
11731173
/// The pattern part (left-hand side) of a parameter (`(mut x, y)` in the example).
11741174
pub pat: Pat,
11751175
/// The type part (right-rand side) of a parameter (`(T, u8)` in the example).
1176-
pub ty: SpannedTy,
1176+
pub ty: Ty,
1177+
/// The span of the type part (if available).
1178+
pub ty_span: Option<Span>,
11771179
/// Optionally, some attributes present on the parameter.
11781180
pub attributes: Attributes,
11791181
}
@@ -1421,7 +1423,7 @@ pub mod traits {
14211423
}
14221424
impl<T: HasMetadata> HasSpan for T {
14231425
fn span(&self) -> Span {
1424-
self.metadata().span
1426+
self.metadata().span.clone()
14251427
}
14261428
}
14271429

@@ -1474,7 +1476,7 @@ pub mod traits {
14741476

14751477
impl HasSpan for SpannedTy {
14761478
fn span(&self) -> Span {
1477-
self.span
1479+
self.span.clone()
14781480
}
14791481
}
14801482

rust-printer/src/ast/span.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,41 @@
22
33
use hax_rust_engine_macros::*;
44

5-
// TODO: implement, interned (statically -- bumpalo or something)
6-
/// Position in the source code
5+
/// Creates a fresh identifier for a span.
6+
fn fresh_id() -> usize {
7+
use std::sync::atomic::{AtomicUsize, Ordering};
8+
static CURRENT_ID: AtomicUsize = AtomicUsize::new(0);
9+
CURRENT_ID.fetch_add(1, Ordering::Relaxed)
10+
}
11+
12+
/// Identifier used to track the origin Rust item of a span
713
#[derive_group_for_ast]
8-
#[derive(Copy)]
9-
pub struct Span(());
14+
pub struct OwnerId(usize);
15+
16+
/// Position of a Rust source
17+
#[derive_group_for_ast]
18+
pub struct Span {
19+
/// A vector of spans as defined by the frontend.
20+
/// This is useful for supporting in a trivial way union of spans.
21+
data: Vec<hax_frontend_exporter::Span>,
22+
/// A unique identifier. Since we store spans almost for every node of the
23+
/// AST, having a unique identifier for spans gives us a fine-grained way of
24+
/// refering to sub-nodes in debugging context. This id is indeed mostly
25+
/// used by the web debugger.
26+
id: usize,
27+
/// A reference to the item in which this span lives. This information is
28+
/// used for debugging and profiling purposes, e.g. for `cargo hax into
29+
/// --stats backend`.
30+
owner_hint: Option<OwnerId>,
31+
}
1032

1133
impl From<hax_frontend_exporter::Span> for Span {
12-
fn from(_span: hax_frontend_exporter::Span) -> Self {
13-
Self(())
34+
fn from(span: hax_frontend_exporter::Span) -> Self {
35+
Self {
36+
data: vec![span],
37+
id: fresh_id(),
38+
owner_hint: None, // TODO: this will be defined properly while addressing issue #1524
39+
}
1440
}
1541
}
1642

0 commit comments

Comments
 (0)