Skip to content

Commit

Permalink
refactor: feature gate all implementations with feat. full
Browse files Browse the repository at this point in the history
This PR adds a (default) feature `full` for the
`hax-frontend-exporter` crate. With this feature disabled, the crate
turns into a mostly type-only crate. The crate depends on rustc and
drive `sinto` only with `full` enabled.
  • Loading branch information
W95Psp committed Jun 12, 2024
1 parent 46bb5c1 commit f8dcefe
Show file tree
Hide file tree
Showing 20 changed files with 1,075 additions and 901 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions frontend/exporter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ description = "Provides mirrors of the algebraic data types used in the Rust com
rustc_private=true

[dependencies]
hax-adt-into.workspace = true
serde.workspace = true
serde_json.workspace = true
schemars.workspace = true
itertools.workspace = true
hax-frontend-exporter-options.workspace = true
tracing.workspace = true
hax-adt-into.workspace = true
paste = "1.0.11"
extension-traits = "1.0.1"
lazy_static = "1.4.0"

tracing = { workspace = true, optional = true }
itertools = { workspace = true, optional = true }
extension-traits = { version = "1.0.1", optional = true }
lazy_static = { version = "1.4.0", optional = true }
cfg-if = "1.0.0"

[features]
default = ["full"]
full = ["dep:tracing", "dep:itertools", "dep:extension-traits", "dep:lazy_static"]
1 change: 1 addition & 0 deletions frontend/exporter/adt-into/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ pub fn adt_into(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
};

quote! {
#[cfg(feature = "full")]
const _ : () = {
use #from as FROM_TYPE;
use #to as TO_TYPE;
Expand Down
167 changes: 89 additions & 78 deletions frontend/exporter/src/body.rs
Original file line number Diff line number Diff line change
@@ -1,99 +1,110 @@
use crate::prelude::*;
#[cfg(feature = "full")]
mod module {
use crate::prelude::*;

pub use rustc_hir::{
def_id::{DefId as RDefId, LocalDefId as RLocalDefId},
hir_id::OwnerId as ROwnerId,
};
pub use rustc_hir::{
def_id::{DefId as RDefId, LocalDefId as RLocalDefId},
hir_id::OwnerId as ROwnerId,
};

pub fn get_thir<'tcx, S: UnderOwnerState<'tcx>>(
did: RLocalDefId,
s: &S,
) -> (
Rc<rustc_middle::thir::Thir<'tcx>>,
rustc_middle::thir::ExprId,
) {
let base = s.base();
let msg = || fatal!(s[base.tcx.def_span(did)], "THIR not found for {:?}", did);
base.cached_thirs.get(&did).unwrap_or_else(msg).clone()
}
pub fn get_thir<'tcx, S: UnderOwnerState<'tcx>>(
did: RLocalDefId,
s: &S,
) -> (
Rc<rustc_middle::thir::Thir<'tcx>>,
rustc_middle::thir::ExprId,
) {
let base = s.base();
let msg = || fatal!(s[base.tcx.def_span(did)], "THIR not found for {:?}", did);
base.cached_thirs.get(&did).unwrap_or_else(msg).clone()
}

pub trait IsBody: Sized + Clone {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self;
}
pub trait IsBody: Sized + Clone {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self;
}

pub fn make_fn_def<'tcx, Body: IsBody, S: UnderOwnerState<'tcx>>(
fn_sig: &rustc_hir::FnSig,
body_id: &rustc_hir::BodyId,
s: &S,
) -> FnDef<Body> {
let hir_id = body_id.hir_id;
let ldid = hir_id.clone().owner.def_id;
pub fn make_fn_def<'tcx, Body: IsBody, S: UnderOwnerState<'tcx>>(
fn_sig: &rustc_hir::FnSig,
body_id: &rustc_hir::BodyId,
s: &S,
) -> FnDef<Body> {
let hir_id = body_id.hir_id;
let ldid = hir_id.clone().owner.def_id;

let (thir, expr_entrypoint) = get_thir(ldid, s);
let s = &with_owner_id(s.base(), thir.clone(), (), ldid.to_def_id());
FnDef {
params: thir.params.raw.sinto(s),
ret: thir.exprs[expr_entrypoint].ty.sinto(s),
body: Body::body(ldid, s),
sig_span: fn_sig.span.sinto(s),
header: fn_sig.header.sinto(s),
let (thir, expr_entrypoint) = get_thir(ldid, s);
let s = &with_owner_id(s.base(), thir.clone(), (), ldid.to_def_id());
FnDef {
params: thir.params.raw.sinto(s),
ret: thir.exprs[expr_entrypoint].ty.sinto(s),
body: Body::body(ldid, s),
sig_span: fn_sig.span.sinto(s),
header: fn_sig.header.sinto(s),
}
}
}

pub fn body_from_id<'tcx, Body: IsBody, S: UnderOwnerState<'tcx>>(
id: rustc_hir::BodyId,
s: &S,
) -> Body {
// **Important:**
// We need a local id here, and we get it from the owner id, which must
// be local. It is safe to do so, because if we have access to HIR objects,
// it necessarily means we are exploring a local item (we don't have
// access to the HIR of external objects, only their MIR).
Body::body(s.base().tcx.hir().body_owner_def_id(id), s)
}
pub fn body_from_id<'tcx, Body: IsBody, S: UnderOwnerState<'tcx>>(
id: rustc_hir::BodyId,
s: &S,
) -> Body {
// **Important:**
// We need a local id here, and we get it from the owner id, which must
// be local. It is safe to do so, because if we have access to HIR objects,
// it necessarily means we are exploring a local item (we don't have
// access to the HIR of external objects, only their MIR).
Body::body(s.base().tcx.hir().body_owner_def_id(id), s)
}

mod implementations {
use super::*;
impl IsBody for () {
fn body<'tcx, S: UnderOwnerState<'tcx>>(_did: RLocalDefId, _s: &S) -> Self {
()
mod implementations {
use super::*;
impl IsBody for () {
fn body<'tcx, S: UnderOwnerState<'tcx>>(_did: RLocalDefId, _s: &S) -> Self {
()
}
}
}
impl IsBody for ThirBody {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self {
let (thir, expr) = get_thir(did, s);
if *CORE_EXTRACTION_MODE {
let expr = &thir.exprs[expr.clone()];
Decorated {
contents: Box::new(ExprKind::Tuple { fields: vec![] }),
hir_id: None,
attributes: vec![],
ty: expr.ty.sinto(s),
span: expr.span.sinto(s),
impl IsBody for ThirBody {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self {
let (thir, expr) = get_thir(did, s);
if *CORE_EXTRACTION_MODE {
let expr = &thir.exprs[expr.clone()];
Decorated {
contents: Box::new(ExprKind::Tuple { fields: vec![] }),
hir_id: None,
attributes: vec![],
ty: expr.ty.sinto(s),
span: expr.span.sinto(s),
}
} else {
expr.sinto(&with_owner_id(s.base(), thir, (), did.to_def_id()))
}
} else {
expr.sinto(&with_owner_id(s.base(), thir, (), did.to_def_id()))
}
}
}

impl<A: IsBody, B: IsBody> IsBody for (A, B) {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self {
(A::body(did, s), B::body(did, s))
impl<A: IsBody, B: IsBody> IsBody for (A, B) {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self {
(A::body(did, s), B::body(did, s))
}
}

impl<MirKind: IsMirKind + Clone> IsBody for MirBody<MirKind> {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self {
let (thir, _) = get_thir(did, s);
let mir = Rc::new(s.base().tcx.mir_built(did).borrow().clone());
mir.sinto(&with_owner_id(s.base(), thir, mir.clone(), did.to_def_id()))
}
}
}

impl<MirKind: IsMirKind + Clone> IsBody for MirBody<MirKind> {
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RLocalDefId, s: &S) -> Self {
let (thir, _) = get_thir(did, s);
let mir = Rc::new(s.base().tcx.mir_built(did).borrow().clone());
mir.sinto(&with_owner_id(s.base(), thir, mir.clone(), did.to_def_id()))
impl<'tcx, S: UnderOwnerState<'tcx>, Body: IsBody> SInto<S, Body> for rustc_hir::BodyId {
fn sinto(&self, s: &S) -> Body {
body_from_id::<Body, _>(self.clone(), s)
}
}
}

impl<'tcx, S: UnderOwnerState<'tcx>, Body: IsBody> SInto<S, Body> for rustc_hir::BodyId {
fn sinto(&self, s: &S) -> Body {
body_from_id::<Body, _>(self.clone(), s)
}
#[cfg(not(feature = "full"))]
mod module {
pub trait IsBody: Sized + Clone {}
impl<T: Sized + Clone> IsBody for T {}
}

pub use module::*;
Loading

0 comments on commit f8dcefe

Please sign in to comment.