Skip to content

Commit a417733

Browse files
Move attribute processing functions to kani_middle. (rust-lang#1838)
Co-authored-by: Celina G. Val <[email protected]>
1 parent 7e7f518 commit a417733

File tree

3 files changed

+64
-58
lines changed

3 files changed

+64
-58
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/function.rs

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
//! This file contains functions related to codegenning MIR functions into gotoc
55
66
use crate::codegen_cprover_gotoc::GotocCtx;
7+
use crate::kani_middle::attributes::{extract_integer_argument, partition_kanitool_attributes};
78
use cbmc::goto_program::{Expr, Stmt, Symbol};
89
use cbmc::InternString;
910
use kani_metadata::HarnessMetadata;
10-
use rustc_ast::ast;
11-
use rustc_ast::{Attribute, LitKind};
11+
use rustc_ast::Attribute;
1212
use rustc_hir::def::DefKind;
1313
use rustc_hir::def_id::DefId;
1414
use rustc_middle::mir::{HasLocalDecls, Local};
@@ -436,59 +436,3 @@ impl<'tcx> GotocCtx<'tcx> {
436436
}
437437
}
438438
}
439-
440-
/// If the attribute is named `kanitool::name`, this extracts `name`
441-
fn kanitool_attr_name(attr: &ast::Attribute) -> Option<String> {
442-
match &attr.kind {
443-
ast::AttrKind::Normal(normal) => {
444-
let segments = &normal.item.path.segments;
445-
if (!segments.is_empty()) && segments[0].ident.as_str() == "kanitool" {
446-
Some(segments[1].ident.as_str().to_string())
447-
} else {
448-
None
449-
}
450-
}
451-
_ => None,
452-
}
453-
}
454-
455-
/// Partition all the attributes into two buckets, proof_attributes and other_attributes
456-
fn partition_kanitool_attributes(
457-
all_attributes: &[Attribute],
458-
) -> (Vec<&Attribute>, Vec<(String, &Attribute)>) {
459-
let mut proof_attributes = vec![];
460-
let mut other_attributes = vec![];
461-
462-
for attr in all_attributes {
463-
// Get the string the appears after "kanitool::" in each attribute string.
464-
// Ex - "proof" | "unwind" etc.
465-
if let Some(attribute_string) = kanitool_attr_name(attr).as_deref() {
466-
if attribute_string == "proof" {
467-
proof_attributes.push(attr);
468-
} else {
469-
other_attributes.push((attribute_string.to_string(), attr));
470-
}
471-
}
472-
}
473-
474-
(proof_attributes, other_attributes)
475-
}
476-
477-
/// Extracts the integer value argument from the attribute provided
478-
/// For example, `unwind(8)` return `Some(8)`
479-
fn extract_integer_argument(attr: &Attribute) -> Option<u128> {
480-
// Vector of meta items , that contain the arguments given the attribute
481-
let attr_args = attr.meta_item_list()?;
482-
// Only extracts one integer value as argument
483-
if attr_args.len() == 1 {
484-
let x = attr_args[0].literal()?;
485-
match x.kind {
486-
LitKind::Int(y, ..) => Some(y),
487-
_ => None,
488-
}
489-
}
490-
// Return none if there are no attributes or if there's too many attributes
491-
else {
492-
None
493-
}
494-
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//! This module contains code for processing Rust attributes (like `kani::proof`).
4+
5+
use rustc_ast::{AttrKind, Attribute, LitKind};
6+
7+
/// Partition all the attributes into two buckets, proof_attributes and other_attributes
8+
pub fn partition_kanitool_attributes(
9+
all_attributes: &[Attribute],
10+
) -> (Vec<&Attribute>, Vec<(String, &Attribute)>) {
11+
let mut proof_attributes = vec![];
12+
let mut other_attributes = vec![];
13+
14+
for attr in all_attributes {
15+
// Get the string the appears after "kanitool::" in each attribute string.
16+
// Ex - "proof" | "unwind" etc.
17+
if let Some(attribute_string) = kanitool_attr_name(attr).as_deref() {
18+
if attribute_string == "proof" {
19+
proof_attributes.push(attr);
20+
} else {
21+
other_attributes.push((attribute_string.to_string(), attr));
22+
}
23+
}
24+
}
25+
26+
(proof_attributes, other_attributes)
27+
}
28+
29+
/// Extracts the integer value argument from the attribute provided
30+
/// For example, `unwind(8)` return `Some(8)`
31+
pub fn extract_integer_argument(attr: &Attribute) -> Option<u128> {
32+
// Vector of meta items , that contain the arguments given the attribute
33+
let attr_args = attr.meta_item_list()?;
34+
// Only extracts one integer value as argument
35+
if attr_args.len() == 1 {
36+
let x = attr_args[0].literal()?;
37+
match x.kind {
38+
LitKind::Int(y, ..) => Some(y),
39+
_ => None,
40+
}
41+
}
42+
// Return none if there are no attributes or if there's too many attributes
43+
else {
44+
None
45+
}
46+
}
47+
48+
/// If the attribute is named `kanitool::name`, this extracts `name`
49+
fn kanitool_attr_name(attr: &Attribute) -> Option<String> {
50+
match &attr.kind {
51+
AttrKind::Normal(normal) => {
52+
let segments = &normal.item.path.segments;
53+
if (!segments.is_empty()) && segments[0].ident.as_str() == "kanitool" {
54+
Some(segments[1].ident.as_str().to_string())
55+
} else {
56+
None
57+
}
58+
}
59+
_ => None,
60+
}
61+
}

kani-compiler/src/kani_middle/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33
//! This module contains code that are backend agnostic. For example, MIR analysis
44
//! and transformations.
5+
pub mod attributes;
56
pub mod reachability;

0 commit comments

Comments
 (0)