Skip to content

Commit db54783

Browse files
celinvaltautschnig
andauthored
Fix a few more issues with the std library (#3261)
- Enable Kani to use fallback fn body for intrinsics, so they can be verified. - Until <rust-lang/project-stable-mir#79> is implemented, we have to check has_body and must_be_overridden - Export all kani_macro definitions. Rename `unstable` to avoid conflict with the Rust standard library one. - Dump stable mir body since transformations are made at that level. - I just did this as I was debugging things. Co-authored-by: Michael Tautschnig <[email protected]>
1 parent 34b35d8 commit db54783

File tree

14 files changed

+80
-54
lines changed

14 files changed

+80
-54
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ impl<'tcx> GotocCtx<'tcx> {
614614

615615
/// Ensure that the given instance is in the symbol table, returning the symbol.
616616
fn codegen_func_symbol(&mut self, instance: Instance) -> &Symbol {
617-
let sym = if instance.is_foreign_item() {
617+
let sym = if instance.is_foreign_item() && !instance.has_body() {
618618
// Get the symbol that represents a foreign instance.
619619
self.codegen_foreign_fn(instance)
620620
} else {

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -518,13 +518,21 @@ impl<'tcx> GotocCtx<'tcx> {
518518
if let Some(instance) = instance_opt
519519
&& matches!(instance.kind, InstanceKind::Intrinsic)
520520
{
521-
return self.codegen_funcall_of_intrinsic(
522-
instance,
523-
&args,
524-
&destination,
525-
target.map(|bb| bb),
526-
span,
527-
);
521+
let TyKind::RigidTy(RigidTy::FnDef(def, _)) = instance.ty().kind() else {
522+
unreachable!("Expected function type for intrinsic: {instance:?}")
523+
};
524+
// The compiler is currently transitioning how to handle intrinsic fallback body.
525+
// Until https://github.com/rust-lang/project-stable-mir/issues/79 is implemented
526+
// we have to check `must_be_overridden` and `has_body`.
527+
if def.as_intrinsic().unwrap().must_be_overridden() || !instance.has_body() {
528+
return self.codegen_funcall_of_intrinsic(
529+
instance,
530+
&args,
531+
&destination,
532+
target.map(|bb| bb),
533+
span,
534+
);
535+
}
528536
}
529537

530538
let loc = self.codegen_span_stable(span);

kani-compiler/src/codegen_cprover_gotoc/compiler_interface.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl GotocCodegenBackend {
9393
|| collect_reachable_items(tcx, &mut transformer, starting_items),
9494
"codegen reachability analysis",
9595
);
96-
dump_mir_items(tcx, &items, &symtab_goto.with_extension("kani.mir"));
96+
dump_mir_items(tcx, &mut transformer, &items, &symtab_goto.with_extension("kani.mir"));
9797

9898
// Follow rustc naming convention (cx is abbrev for context).
9999
// https://rustc-dev-guide.rust-lang.org/conventions.html#naming-conventions

kani-compiler/src/kani_middle/attributes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,10 +782,10 @@ impl<'a> UnstableAttrParseError<'a> {
782782
tcx.dcx()
783783
.struct_span_err(
784784
self.attr.span,
785-
format!("failed to parse `#[kani::unstable]`: {}", self.reason),
785+
format!("failed to parse `#[kani::unstable_feature]`: {}", self.reason),
786786
)
787787
.with_note(format!(
788-
"expected format: #[kani::unstable({}, {}, {})]",
788+
"expected format: #[kani::unstable_feature({}, {}, {})]",
789789
r#"feature="<IDENTIFIER>""#, r#"issue="<ISSUE>""#, r#"reason="<DESCRIPTION>""#
790790
))
791791
.emit()

kani-compiler/src/kani_middle/mod.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
use std::collections::HashSet;
77
use std::path::Path;
88

9+
use crate::kani_middle::transform::BodyTransformation;
910
use crate::kani_queries::QueryDb;
1011
use rustc_hir::{def::DefKind, def_id::LOCAL_CRATE};
11-
use rustc_middle::mir::write_mir_pretty;
1212
use rustc_middle::span_bug;
1313
use rustc_middle::ty::layout::{
1414
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError,
@@ -21,9 +21,9 @@ use rustc_span::source_map::respan;
2121
use rustc_span::Span;
2222
use rustc_target::abi::call::FnAbi;
2323
use rustc_target::abi::{HasDataLayout, TargetDataLayout};
24-
use stable_mir::mir::mono::{InstanceKind, MonoItem};
24+
use stable_mir::mir::mono::{Instance, MonoItem};
2525
use stable_mir::ty::{FnDef, RigidTy, Span as SpanStable, TyKind};
26-
use stable_mir::{CrateDef, DefId};
26+
use stable_mir::CrateDef;
2727
use std::fs::File;
2828
use std::io::BufWriter;
2929
use std::io::Write;
@@ -93,17 +93,19 @@ pub fn check_reachable_items(tcx: TyCtxt, queries: &QueryDb, items: &[MonoItem])
9393
}
9494

9595
/// Print MIR for the reachable items if the `--emit mir` option was provided to rustc.
96-
pub fn dump_mir_items(tcx: TyCtxt, items: &[MonoItem], output: &Path) {
96+
pub fn dump_mir_items(
97+
tcx: TyCtxt,
98+
transformer: &mut BodyTransformation,
99+
items: &[MonoItem],
100+
output: &Path,
101+
) {
97102
/// Convert MonoItem into a DefId.
98103
/// Skip stuff that we cannot generate the MIR items.
99-
fn visible_item(item: &MonoItem) -> Option<(MonoItem, DefId)> {
104+
fn get_instance(item: &MonoItem) -> Option<Instance> {
100105
match item {
101106
// Exclude FnShims and others that cannot be dumped.
102-
MonoItem::Fn(instance) if matches!(instance.kind, InstanceKind::Item) => {
103-
Some((item.clone(), instance.def.def_id()))
104-
}
105-
MonoItem::Fn(..) => None,
106-
MonoItem::Static(def) => Some((item.clone(), def.def_id())),
107+
MonoItem::Fn(instance) => Some(*instance),
108+
MonoItem::Static(def) => Some((*def).into()),
107109
MonoItem::GlobalAsm(_) => None,
108110
}
109111
}
@@ -114,10 +116,10 @@ pub fn dump_mir_items(tcx: TyCtxt, items: &[MonoItem], output: &Path) {
114116
let mut writer = BufWriter::new(out_file);
115117

116118
// For each def_id, dump their MIR
117-
for (item, def_id) in items.iter().filter_map(visible_item) {
118-
writeln!(writer, "// Item: {item:?}").unwrap();
119-
write_mir_pretty(tcx, Some(rustc_internal::internal(tcx, def_id)), &mut writer)
120-
.unwrap();
119+
for instance in items.iter().filter_map(get_instance) {
120+
writeln!(writer, "// Item: {} ({})", instance.name(), instance.mangled_name()).unwrap();
121+
let body = transformer.body(tcx, instance);
122+
let _ = body.dump(&mut writer, &instance.name());
121123
}
122124
}
123125
}

kani-compiler/src/kani_middle/reachability.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,22 @@ impl<'a, 'tcx> MonoItemsFnCollector<'a, 'tcx> {
262262
/// Collect an instance depending on how it is used (invoked directly or via fn_ptr).
263263
fn collect_instance(&mut self, instance: Instance, is_direct_call: bool) {
264264
let should_collect = match instance.kind {
265-
InstanceKind::Virtual { .. } | InstanceKind::Intrinsic => {
265+
InstanceKind::Virtual { .. } => {
266266
// Instance definition has no body.
267267
assert!(is_direct_call, "Expected direct call {instance:?}");
268268
false
269269
}
270+
InstanceKind::Intrinsic => {
271+
// Intrinsics may have a fallback body.
272+
assert!(is_direct_call, "Expected direct call {instance:?}");
273+
let TyKind::RigidTy(RigidTy::FnDef(def, _)) = instance.ty().kind() else {
274+
unreachable!("Expected function type for intrinsic: {instance:?}")
275+
};
276+
// The compiler is currently transitioning how to handle intrinsic fallback body.
277+
// Until https://github.com/rust-lang/project-stable-mir/issues/79 is implemented
278+
// we have to check `must_be_overridden` and `has_body`.
279+
!def.as_intrinsic().unwrap().must_be_overridden() && instance.has_body()
280+
}
270281
InstanceKind::Shim | InstanceKind::Item => true,
271282
};
272283
if should_collect && should_codegen_locally(&instance) {

library/kani/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,4 +323,6 @@ pub use core::assert as __kani__workaround_core_assert;
323323
// Kani proc macros must be in a separate crate
324324
pub use kani_macros::*;
325325

326+
pub(crate) use kani_macros::unstable_feature as unstable;
327+
326328
pub mod contracts;

library/kani_core/src/arbitrary.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ macro_rules! generate_arbitrary {
7272
}
7373

7474
// Generate trivial arbitrary values
75+
trivial_arbitrary!(());
76+
7577
trivial_arbitrary!(u8);
7678
trivial_arbitrary!(u16);
7779
trivial_arbitrary!(u32);

library/kani_core/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ macro_rules! kani_lib {
3535
#[cfg(kani)]
3636
#[unstable(feature = "kani", issue = "none")]
3737
pub mod kani {
38-
pub use kani_core::{
39-
ensures, modifies, proof, proof_for_contract, requires, should_panic,
40-
};
38+
// We need to list them all today because there is conflict with unstable.
39+
pub use kani_core::*;
4140
kani_core::kani_intrinsics!(core);
4241
kani_core::generate_arbitrary!(core);
4342

library/kani_macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub fn solver(attr: TokenStream, item: TokenStream) -> TokenStream {
9696
/// See https://model-checking.github.io/kani/rfc/rfcs/0006-unstable-api.html for more details.
9797
#[doc(hidden)]
9898
#[proc_macro_attribute]
99-
pub fn unstable(attr: TokenStream, item: TokenStream) -> TokenStream {
99+
pub fn unstable_feature(attr: TokenStream, item: TokenStream) -> TokenStream {
100100
attr_impl::unstable(attr, item)
101101
}
102102

library/kani_macros/src/sysroot/contracts/shared.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ impl<'a> ContractConditionsHandler<'a> {
7373
.filter(|attr| {
7474
if let Some(ident) = attr.path().get_ident() {
7575
let name = ident.to_string();
76-
!name.starts_with("rustc") && !(name == "stable")
76+
!name.starts_with("rustc")
77+
&& !(name == "stable")
78+
&& !(name == "unstable")
7779
} else {
7880
true
7981
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// Copyright Kani Contributors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

4-
#[kani::unstable(feature = "always_fails", reason = "do not enable", issue = "<link>")]
4+
#[kani::unstable_feature(feature = "always_fails", reason = "do not enable", issue = "<link>")]
55
pub fn always_fails() {
66
assert!(false, "don't call me");
77
}
88

99
/// We use "gen-c" since it has to be an existing feature.
10-
#[kani::unstable(feature = "gen-c", reason = "internal fake api", issue = "<link>")]
10+
#[kani::unstable_feature(feature = "gen-c", reason = "internal fake api", issue = "<link>")]
1111
pub fn no_op() {
1212
kani::cover!(true);
1313
}
Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
error: failed to parse `#[kani::unstable]`: missing `feature` field\
1+
error: failed to parse `#[kani::unstable_feature]`: missing `feature` field\
22
lib.rs
33
|\
4-
9 | #[kani::unstable(reason = "just checking", issue = "<link>")]\
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
4+
9 | #[kani::unstable_feature(reason = "just checking", issue = "<link>")]\
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
66
|\
7-
= note: expected format: #[kani::unstable(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]\
8-
= note: this error originates in the attribute macro `kani::unstable` (in Nightly builds, run with -Z macro-backtrace for more info)
7+
= note: expected format: #[kani::unstable_feature(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]\
8+
= note: this error originates in the attribute macro `kani::unstable_feature` (in Nightly builds, run with -Z macro-backtrace for more info)
99

10-
error: failed to parse `#[kani::unstable]`: expected "key = value" pair, but found `feature("invalid_args")`\
10+
error: failed to parse `#[kani::unstable_feature]`: expected "key = value" pair, but found `feature("invalid_args")`\
1111
lib.rs\
1212
|\
13-
| #[kani::unstable(feature("invalid_args"))]\
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
13+
| #[kani::unstable_feature(feature("invalid_args"))]\
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
1515
|\
16-
= note: expected format: #[kani::unstable(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]
16+
= note: expected format: #[kani::unstable_feature(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]
1717

18-
error: failed to parse `#[kani::unstable]`: expected "key = value" pair, but found `feature`\
18+
error: failed to parse `#[kani::unstable_feature]`: expected "key = value" pair, but found `feature`\
1919
lib.rs\
2020
|\
21-
| #[kani::unstable(feature, issue)]\
22-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
21+
| #[kani::unstable_feature(feature, issue)]\
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
2323
|\
24-
= note: expected format: #[kani::unstable(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]
24+
= note: expected format: #[kani::unstable_feature(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]
2525

26-
error: failed to parse `#[kani::unstable]`: expected "key = value" pair, but found `1010`\
26+
error: failed to parse `#[kani::unstable_feature]`: expected "key = value" pair, but found `1010`\
2727
lib.rs\
2828
|\
29-
| #[kani::unstable(1010)]\
30-
| ^^^^^^^^^^^^^^^^^^^^^^^\
29+
| #[kani::unstable_feature(1010)]\
30+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
3131
|\
32-
= note: expected format: #[kani::unstable(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]
32+
= note: expected format: #[kani::unstable_feature(feature="<IDENTIFIER>", issue="<ISSUE>", reason="<DESCRIPTION>")]

tests/cargo-ui/unstable-attr/invalid/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66
//! we don't guarantee the order that these will be evaluated.
77
//! TODO: We should break down this test to ensure all of these fail.
88
9-
#[kani::unstable(reason = "just checking", issue = "<link>")]
9+
#[kani::unstable_feature(reason = "just checking", issue = "<link>")]
1010
pub fn missing_feature() {
1111
todo!()
1212
}
1313

14-
#[kani::unstable(feature("invalid_args"))]
14+
#[kani::unstable_feature(feature("invalid_args"))]
1515
pub fn invalid_fn_style() {}
1616

17-
#[kani::unstable(feature, issue)]
17+
#[kani::unstable_feature(feature, issue)]
1818
pub fn invalid_list() {}
1919

20-
#[kani::unstable(1010)]
20+
#[kani::unstable_feature(1010)]
2121
pub fn invalid_argument() {}
2222

2323
#[kani::proof]

0 commit comments

Comments
 (0)