Skip to content

Commit ad8f820

Browse files
authored
Merge pull request #7 from os-checker/remove-attrs
Fix: Only extract kanitool attributes
2 parents 0680dc6 + c1258d7 commit ad8f820

File tree

7 files changed

+7153
-311
lines changed

7 files changed

+7153
-311
lines changed

src/functions/kani/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,16 @@ mod coercion;
22
mod reachability;
33

44
pub use reachability::{CallGraph, collect_reachable_items};
5+
6+
use std::sync::LazyLock;
7+
8+
/// `#[kanitool::xxx]` attributes.
9+
pub static KANI_TOOL_ATTRS: LazyLock<Vec<[String; 2]>> = LazyLock::new(|| {
10+
vec![
11+
["kanitool".into(), "proof".into()],
12+
["kanitool".into(), "proof_for_contract".into()],
13+
// attrs for contracts
14+
["kanitool".into(), "requires".into()],
15+
["kanitool".into(), "ensures".into()],
16+
]
17+
});

src/functions/mod.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use indexmap::IndexSet;
2-
use kani::{CallGraph, collect_reachable_items};
2+
use kani::{CallGraph, KANI_TOOL_ATTRS, collect_reachable_items};
33
use rustc_middle::ty::TyCtxt;
44
use rustc_smir::rustc_internal::internal;
55
use rustc_span::{Span, source_map::SourceMap};
66
use serde::Serialize;
77
use stable_mir::{
8-
CrateDef, DefId,
8+
CrateDef,
99
mir::mono::{Instance, MonoItem},
1010
ty::{FnDef, RigidTy, Ty, TyKind},
1111
};
@@ -20,7 +20,7 @@ pub fn analyze(tcx: TyCtxt, src_map: &SourceMap) -> Vec<Function> {
2020
let mut entries = Vec::with_capacity(cap);
2121

2222
for item in local_items {
23-
let _span = debug_span!("all_local_items", ?item).entered();
23+
let _span = error_span!("all_local_items", ?item).entered();
2424

2525
let Ok(inst) = Instance::try_from(item).inspect_err(|err| error!(?err)) else { continue };
2626
entries.push(MonoItem::from(inst));
@@ -72,14 +72,12 @@ impl Function {
7272
let func = source_code_with(body.span, tcx, src_map);
7373
info!(" - {:?} ({span:?}): {func}", inst_def.name());
7474

75-
// FIXME: kanitool and some other proc-macors attributes are generated by parsing,
76-
// and these generated attrs share with span of hand-written attrs in source code.
77-
// As a result, get_all_attributes through source span will emit duplicated attrs.
78-
// Need to fix this in the future, by analyzing Symbols of these attrs.
79-
// let attrs = get_all_attributes(inst_def.def_id(), tcx, src_map);
80-
let attrs = vec![];
81-
82-
// TODO: filter in kanitool kind: proof, proof_for_contract, contract, ...
75+
// Only need kanitool attrs: proof, proof_for_contract, contract, ...
76+
let attrs = KANI_TOOL_ATTRS
77+
.iter()
78+
.flat_map(|v| inst_def.tool_attrs(v))
79+
.map(|attr| attr.as_str().to_owned())
80+
.collect();
8381

8482
Some(Function { file, attrs, func, callees })
8583
}
@@ -113,15 +111,3 @@ fn source_code_with(
113111
let span = internal(tcx, stable_mir_span);
114112
source_code(span, src_map)
115113
}
116-
117-
/// Get all attributes for the item.
118-
///
119-
/// We don't call [`all_tool_attrs`], because it only gives tool attributes,
120-
/// we want as raw attributes as possible.
121-
///
122-
/// [`all_tool_attrs`]: https://doc.rust-lang.org/nightly/nightly-rustc/stable_mir/struct.CrateItem.html#impl-CrateDef-for-CrateItem
123-
fn get_all_attributes(stable_mir_def_id: DefId, tcx: TyCtxt, src_map: &SourceMap) -> Vec<String> {
124-
let def_id = internal(tcx, stable_mir_def_id);
125-
// dbg!(tcx.hir_body_owned_by(def_id.expect_local())); // HIR body
126-
tcx.get_all_attrs(def_id).map(|attr| source_code(attr.span(), src_map)).collect()
127-
}

tests/snapshots.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
use assert_cmd::Command;
22
use expect_test::expect_file;
33

4-
fn cmd() -> Command {
5-
Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap()
6-
}
7-
8-
#[test]
9-
fn standard_proof() {
10-
let output = cmd().args(["tests/standard_proof.rs"]).output().unwrap();
4+
fn cmd(args: &[&str]) -> String {
5+
let output = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap().args(args).output().unwrap();
116
assert!(
127
output.status.success(),
138
"Failed to test standard_proof.rs:\n{}",
149
std::str::from_utf8(&output.stderr).unwrap()
1510
);
1611

17-
let stdout = String::from_utf8_lossy(&output.stdout);
18-
expect_file!["./snapshots/standard_proof.json"].assert_eq(&stdout);
12+
String::from_utf8(output.stdout).unwrap()
13+
}
14+
15+
#[test]
16+
fn standard_proofs() {
17+
let json = cmd(&["tests/standard_proofs.rs"]);
18+
expect_file!["./snapshots/standard_proofs.json"].assert_eq(&json);
19+
}
20+
21+
#[test]
22+
fn standard_proofs_with_contracts() {
23+
let json = cmd(&["tests/standard_proofs_with_contracts.rs"]);
24+
expect_file!["./snapshots/standard_proofs_with_contracts.json"].assert_eq(&json);
1925
}

0 commit comments

Comments
 (0)