Skip to content

Commit 183f13c

Browse files
committed
Translate and register formula_fn
1 parent bc616af commit 183f13c

6 files changed

Lines changed: 68 additions & 1 deletion

File tree

src/analyze.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_index::IndexVec;
1515
use rustc_middle::mir::{self, BasicBlock, Local};
1616
use rustc_middle::ty::{self as mir_ty, TyCtxt};
1717
use rustc_span::def_id::{DefId, LocalDefId};
18+
use rustc_span::symbol::Symbol;
1819

1920
use crate::analyze;
2021
use crate::annot::{AnnotFormula, AnnotParser, Resolver};
@@ -24,11 +25,38 @@ use crate::refine::{self, BasicBlockType, TypeBuilder};
2425
use crate::rty;
2526

2627
mod annot;
28+
mod annot_fn;
2729
mod basic_block;
2830
mod crate_;
2931
mod did_cache;
3032
mod local_def;
3133

34+
pub fn mir_borrowck_skip_formula_fn(
35+
tcx: rustc_middle::ty::TyCtxt<'_>,
36+
local_def_id: rustc_span::def_id::LocalDefId,
37+
) -> rustc_middle::query::queries::mir_borrowck::ProvidedValue {
38+
// TODO: unify impl with local_def::Analyzer
39+
let is_annotated_as_formula_fn = tcx
40+
.get_attrs_by_path(local_def_id.to_def_id(), &analyze::annot::formula_fn_path())
41+
.next()
42+
.is_some();
43+
44+
if is_annotated_as_formula_fn {
45+
tracing::debug!(?local_def_id, "skipping borrow check for formula fn");
46+
let dummy_result = rustc_middle::mir::BorrowCheckResult {
47+
concrete_opaque_types: Default::default(),
48+
closure_requirements: None,
49+
used_mut_upvars: Default::default(),
50+
tainted_by_errors: None,
51+
};
52+
return tcx.arena.alloc(dummy_result);
53+
}
54+
55+
(rustc_interface::DEFAULT_QUERY_PROVIDERS
56+
.queries
57+
.mir_borrowck)(tcx, local_def_id)
58+
}
59+
3260
pub fn local_of_function_param(idx: rty::FunctionParamIdx) -> Local {
3361
Local::from(idx.index() + 1)
3462
}
@@ -155,6 +183,9 @@ pub struct Analyzer<'tcx> {
155183
/// (at least for every defs referenced by local def bodies)
156184
defs: HashMap<DefId, DefTy<'tcx>>,
157185

186+
/// Collection of functions with `#[thrust::formula_fn]` attribute.
187+
formula_fns: HashMap<DefId, annot_fn::FormulaFn<'tcx>>,
188+
158189
/// Resulting CHC system.
159190
system: Rc<RefCell<chc::System>>,
160191

@@ -181,12 +212,14 @@ impl<'tcx> Analyzer<'tcx> {
181212
impl<'tcx> Analyzer<'tcx> {
182213
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
183214
let defs = Default::default();
215+
let formula_fns = Default::default();
184216
let system = Default::default();
185217
let basic_blocks = Default::default();
186218
let enum_defs = Default::default();
187219
Self {
188220
tcx,
189221
defs,
222+
formula_fns,
190223
system,
191224
basic_blocks,
192225
def_ids: did_cache::DefIdCache::new(tcx),
@@ -346,6 +379,11 @@ impl<'tcx> Analyzer<'tcx> {
346379
Some(expected)
347380
}
348381

382+
pub fn register_formula_fn(&mut self, def_id: DefId, formula_fn: annot_fn::FormulaFn<'tcx>) {
383+
tracing::info!(def_id = ?def_id, formula_fn = %formula_fn.display(), "register_formula_fn");
384+
self.formula_fns.insert(def_id, formula_fn);
385+
}
386+
349387
pub fn register_basic_block_ty(
350388
&mut self,
351389
def_id: LocalDefId,

src/analyze/annot.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ pub fn predicate_path() -> [Symbol; 2] {
4545
[Symbol::intern("thrust"), Symbol::intern("predicate")]
4646
}
4747

48+
pub fn formula_fn_path() -> [Symbol; 2] {
49+
[Symbol::intern("thrust"), Symbol::intern("formula_fn")]
50+
}
51+
4852
/// A [`annot::Resolver`] implementation for resolving function parameters.
4953
///
5054
/// The parameter names and their sorts needs to be configured via

src/analyze/crate_.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hir::def_id::CRATE_DEF_ID;
66
use rustc_middle::ty::{self as mir_ty, TyCtxt};
77
use rustc_span::def_id::{DefId, LocalDefId};
88

9-
use crate::analyze;
9+
use crate::analyze::{self, annot_fn::AnnotFnTranslator};
1010
use crate::chc;
1111
use crate::rty::{self, ClauseBuilderExt as _};
1212

@@ -88,6 +88,14 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
8888
analyzer.analyze_predicate_definition(local_def_id);
8989
}
9090

91+
if analyzer.is_annotated_as_formula_fn() {
92+
self.trusted.insert(local_def_id.to_def_id());
93+
let formula_fn = AnnotFnTranslator::new(self.tcx, local_def_id).to_formula_fn();
94+
self.ctx
95+
.register_formula_fn(local_def_id.to_def_id(), formula_fn);
96+
return;
97+
}
98+
9199
use mir_ty::TypeVisitableExt as _;
92100
if sig.has_param() && !analyzer.is_fully_annotated() {
93101
self.ctx.register_deferred_def(local_def_id.to_def_id());

src/analyze/local_def.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,16 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
202202
.is_some()
203203
}
204204

205+
pub fn is_annotated_as_formula_fn(&self) -> bool {
206+
self.tcx
207+
.get_attrs_by_path(
208+
self.local_def_id.to_def_id(),
209+
&analyze::annot::formula_fn_path(),
210+
)
211+
.next()
212+
.is_some()
213+
}
214+
205215
// TODO: unify this logic with extraction functions above
206216
pub fn is_fully_annotated(&self) -> bool {
207217
let has_require = self

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#![feature(rustc_private)]
22

33
extern crate rustc_ast;
4+
extern crate rustc_borrowck;
45
extern crate rustc_data_structures;
56
extern crate rustc_hir;
67
extern crate rustc_index;
8+
extern crate rustc_interface;
79
extern crate rustc_middle;
810
extern crate rustc_mir_dataflow;
911
extern crate rustc_span;
@@ -23,4 +25,5 @@ mod rty;
2325
// utility
2426
mod pretty;
2527

28+
pub use analyze::mir_borrowck_skip_formula_fn;
2629
pub use analyze::Analyzer;

src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ impl Callbacks for CompilerCalls {
1818
let attrs = &mut config.opts.unstable_opts.crate_attr;
1919
attrs.push("feature(register_tool)".to_owned());
2020
attrs.push("register_tool(thrust)".to_owned());
21+
22+
config.override_queries = Some(|_sess, providers| {
23+
providers.mir_borrowck = thrust::mir_borrowck_skip_formula_fn;
24+
});
2125
}
2226

2327
fn after_crate_root_parsing<'tcx>(

0 commit comments

Comments
 (0)