Skip to content

Commit b672e9b

Browse files
committed
Finish migration of compiler-interface
1 parent 3b3c43e commit b672e9b

File tree

5 files changed

+68
-48
lines changed

5 files changed

+68
-48
lines changed

kani-compiler/src/kani_compiler.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,14 @@ mod tests {
446446
use rustc_hir::definitions::DefPathHash;
447447
use std::collections::HashMap;
448448

449-
fn mock_next_id() -> HarnessId {
449+
fn mock_next_harness() -> HarnessId {
450+
static mut COUNTER: u64 = 0;
451+
unsafe { COUNTER += 1 };
452+
let id = unsafe { COUNTER };
453+
format!("mod::harness-{id}").intern()
454+
}
455+
456+
fn mock_next_stub() -> DefPathHash {
450457
static mut COUNTER: u64 = 0;
451458
unsafe { COUNTER += 1 };
452459
let id = unsafe { COUNTER };
@@ -473,15 +480,15 @@ mod tests {
473480
#[test]
474481
fn test_group_by_stubs_works() {
475482
// Set up the inputs
476-
let harness_1 = mock_next_id();
477-
let harness_2 = mock_next_id();
478-
let harness_3 = mock_next_id();
483+
let harness_1 = mock_next_harness();
484+
let harness_2 = mock_next_harness();
485+
let harness_3 = mock_next_harness();
479486
let harnesses = vec![harness_1, harness_2, harness_3];
480487

481-
let stub_1 = (mock_next_id(), mock_next_id());
482-
let stub_2 = (mock_next_id(), mock_next_id());
483-
let stub_3 = (mock_next_id(), mock_next_id());
484-
let stub_4 = (stub_3.0, mock_next_id());
488+
let stub_1 = (mock_next_stub(), mock_next_stub());
489+
let stub_2 = (mock_next_stub(), mock_next_stub());
490+
let stub_3 = (mock_next_stub(), mock_next_stub());
491+
let stub_4 = (stub_3.0, mock_next_stub());
485492

486493
let set_1 = Stubs::from([stub_1, stub_2, stub_3]);
487494
let set_2 = Stubs::from([stub_1, stub_2, stub_4]);
@@ -516,7 +523,7 @@ mod tests {
516523

517524
let mut info = mock_info_with_stubs(Stubs::default());
518525
info.metadata.attributes.proof = true;
519-
let id = mock_next_id();
526+
let id = mock_next_harness();
520527
let all_harnesses = HashMap::from([(id, info.clone())]);
521528

522529
// Call generate metadata.
@@ -553,7 +560,7 @@ mod tests {
553560
let infos = harnesses.map(|harness| {
554561
let mut metadata = mock_metadata(harness.to_string(), krate.clone());
555562
metadata.attributes.proof = true;
556-
(mock_next_id(), HarnessInfo { stub_map: Stubs::default(), metadata })
563+
(mock_next_harness(), HarnessInfo { stub_map: Stubs::default(), metadata })
557564
});
558565
let all_harnesses = HashMap::from(infos.clone());
559566

kani-compiler/src/kani_middle/metadata.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ pub fn gen_proof_metadata(tcx: TyCtxt, instance: Instance, base_name: &Path) ->
2323
let mangled_name =
2424
if pretty_name == "main" { pretty_name.clone() } else { instance.mangled_name() };
2525

26-
let loc = SourceLocation::new(&instance.def.span());
26+
// We get the body span to include the entire function definition.
27+
// This is required for concrete playback to properly position the generated test.
28+
let loc = SourceLocation::new(instance.body().unwrap().span);
2729
let file_stem = format!("{}_{mangled_name}", base_name.file_stem().unwrap().to_str().unwrap());
2830
let model_file = base_name.with_file_name(file_stem).with_extension(ArtifactType::SymTabGoto);
2931

@@ -50,7 +52,7 @@ pub fn gen_test_metadata(
5052
) -> HarnessMetadata {
5153
let pretty_name = test_harness_name(tcx, &test_desc);
5254
let mangled_name = test_fn.mangled_name();
53-
let loc = SourceLocation::new(&test_desc.span());
55+
let loc = SourceLocation::new(test_desc.span());
5456
let file_stem = format!("{}_{mangled_name}", base_name.file_stem().unwrap().to_str().unwrap());
5557
let model_file = base_name.with_file_name(file_stem).with_extension(ArtifactType::SymTabGoto);
5658

kani-compiler/src/kani_middle/mod.rs

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ use rustc_middle::ty::layout::{
1414
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError,
1515
LayoutOfHelpers, TyAndLayout,
1616
};
17-
use rustc_middle::ty::{self, Instance as InstanceInternal, Ty, TyCtxt};
17+
use rustc_middle::ty::{self, Instance as InstanceInternal, Ty as TyInternal, TyCtxt};
1818
use rustc_session::config::OutputType;
1919
use rustc_smir::rustc_internal;
2020
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};
2424
use stable_mir::mir::mono::{Instance, InstanceKind, MonoItem};
25-
use stable_mir::ty::{BoundVariableKind, Span as SpanStable};
25+
use stable_mir::mir::pretty::pretty_ty;
26+
use stable_mir::ty::{BoundVariableKind, RigidTy, Span as SpanStable, Ty, TyKind};
27+
use stable_mir::visitor::{Visitable, Visitor as TypeVisitor};
2628
use stable_mir::{CrateDef, DefId};
2729
use std::fs::File;
2830
use std::io::BufWriter;
@@ -104,10 +106,9 @@ pub fn check_reachable_items(tcx: TyCtxt, queries: &QueryDb, items: &[MonoItem])
104106
/// This is a temporary safety measure because contracts cannot yet reason
105107
/// about the heap.
106108
fn check_is_contract_safe(tcx: TyCtxt, instance: Instance) {
107-
use ty::TypeVisitor;
108109
struct NoMutPtr<'tcx> {
109110
tcx: TyCtxt<'tcx>,
110-
is_prohibited: fn(ty::Ty<'tcx>) -> bool,
111+
is_prohibited: fn(Ty) -> bool,
111112
/// Where (top level) did the type we're analyzing come from. Used for
112113
/// composing error messages.
113114
r#where: &'static str,
@@ -116,14 +117,15 @@ fn check_is_contract_safe(tcx: TyCtxt, instance: Instance) {
116117
what: &'static str,
117118
}
118119

119-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for NoMutPtr<'tcx> {
120-
fn visit_ty(&mut self, t: ty::Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
121-
use ty::TypeSuperVisitable;
122-
if (self.is_prohibited)(t) {
120+
impl<'tcx> TypeVisitor for NoMutPtr<'tcx> {
121+
type Break = ();
122+
fn visit_ty(&mut self, ty: &Ty) -> std::ops::ControlFlow<Self::Break> {
123+
if (self.is_prohibited)(*ty) {
123124
// TODO make this more user friendly
124125
self.tcx.sess.err(format!(
125-
"{} contains a {}pointer ({t:?}). This is prohibited for functions with contracts, \
126-
as they cannot yet reason about the pointer behavior.", self.r#where, self.what));
126+
"{} contains a {}pointer ({}). This is prohibited for functions with contracts, \
127+
as they cannot yet reason about the pointer behavior.", self.r#where, self.what,
128+
pretty_ty(ty.kind())));
127129
}
128130

129131
// Rust's type visitor only recurses into type arguments, (e.g.
@@ -134,28 +136,28 @@ fn check_is_contract_safe(tcx: TyCtxt, instance: Instance) {
134136
// Since the field types also must contain in some form all the type
135137
// arguments the visitor will see them as it inspects the fields and
136138
// we don't need to call back to `super`.
137-
if let ty::TyKind::Adt(adt_def, generics) = t.kind() {
139+
if let TyKind::RigidTy(RigidTy::Adt(adt_def, generics)) = ty.kind() {
138140
for variant in adt_def.variants() {
139-
for field in &variant.fields {
140-
let ctrl = self.visit_ty(field.ty(self.tcx, generics));
141-
if ctrl.is_break() {
142-
// Technically we can just ignore this because we
143-
// know this case will never happen, but just to be
144-
// safe.
145-
return ctrl;
146-
}
141+
for field in &variant.fields() {
142+
self.visit_ty(&field.ty_with_args(&generics))?;
147143
}
148144
}
149145
std::ops::ControlFlow::Continue(())
150146
} else {
151147
// For every other type.
152-
t.super_visit_with(self)
148+
ty.super_visit(self)
153149
}
154150
}
155151
}
156152

157-
fn is_raw_mutable_ptr(t: ty::Ty) -> bool {
158-
matches!(t.kind(), ty::TyKind::RawPtr(tmut) if tmut.mutbl == rustc_ast::Mutability::Mut)
153+
fn is_raw_mutable_ptr(ty: Ty) -> bool {
154+
let kind = ty.kind();
155+
kind.is_raw_ptr() && kind.is_mutable_ptr()
156+
}
157+
158+
fn is_raw_ptr(ty: Ty) -> bool {
159+
let kind = ty.kind();
160+
kind.is_raw_ptr()
159161
}
160162

161163
// TODO: Replace this with fn_abi.
@@ -173,15 +175,15 @@ fn check_is_contract_safe(tcx: TyCtxt, instance: Instance) {
173175

174176
let fn_typ = bound_fn_sig.skip_binder();
175177

176-
for (typ, (is_prohibited, r#where, what)) in fn_typ
178+
for (input_ty, (is_prohibited, r#where, what)) in fn_typ
177179
.inputs()
178180
.iter()
179181
.copied()
180182
.zip(std::iter::repeat((is_raw_mutable_ptr as fn(_) -> _, "This argument", "mutable ")))
181-
.chain([(fn_typ.output(), (ty::Ty::is_unsafe_ptr as fn(_) -> _, "The return", ""))])
183+
.chain([(fn_typ.output(), (is_raw_ptr as fn(_) -> _, "The return", ""))])
182184
{
183185
let mut v = NoMutPtr { tcx, is_prohibited, r#where, what };
184-
v.visit_ty(rustc_internal::internal(typ));
186+
v.visit_ty(&input_ty);
185187
}
186188
}
187189

@@ -226,7 +228,7 @@ pub struct SourceLocation {
226228
}
227229

228230
impl SourceLocation {
229-
pub fn new(span: &SpanStable) -> Self {
231+
pub fn new(span: SpanStable) -> Self {
230232
let loc = span.get_lines();
231233
let filename = span.get_filename().to_string();
232234
let start_line = loc.start_line;
@@ -243,7 +245,7 @@ impl SourceLocation {
243245
pub fn fn_abi<'tcx>(
244246
tcx: TyCtxt<'tcx>,
245247
instance: InstanceInternal<'tcx>,
246-
) -> &'tcx FnAbi<'tcx, Ty<'tcx>> {
248+
) -> &'tcx FnAbi<'tcx, TyInternal<'tcx>> {
247249
let helper = CompilerHelpers { tcx };
248250
helper.fn_abi_of_instance(instance, ty::List::empty())
249251
}
@@ -274,14 +276,14 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CompilerHelpers<'tcx> {
274276
type LayoutOfResult = TyAndLayout<'tcx>;
275277

276278
#[inline]
277-
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
279+
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: TyInternal<'tcx>) -> ! {
278280
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
279281
}
280282
}
281283

282284
/// Implement error handling for extracting function ABI information.
283285
impl<'tcx> FnAbiOfHelpers<'tcx> for CompilerHelpers<'tcx> {
284-
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
286+
type FnAbiOfResult = &'tcx FnAbi<'tcx, TyInternal<'tcx>>;
285287

286288
#[inline]
287289
fn handle_fn_abi_err(

kani-compiler/src/kani_middle/reachability.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ use stable_mir::mir::{
3131
TerminatorKind,
3232
};
3333
use stable_mir::ty::{Allocation, ClosureKind, ConstantKind, RigidTy, Ty, TyKind};
34-
use stable_mir::CrateDef;
3534
use stable_mir::{self, CrateItem};
35+
use stable_mir::{CrateDef, ItemKind};
3636

3737
use crate::kani_middle::coercion;
3838
use crate::kani_middle::coercion::CoercionBase;
@@ -73,10 +73,19 @@ where
7373
crate_items
7474
.iter()
7575
.filter_map(|item| {
76+
tracing::warn!(?item, name = item.name(), "crate_item");
77+
tracing::warn!(body=?item.body().blocks.len(), "crate_item");
7678
// Only collect monomorphic items.
77-
Instance::try_from(*item)
78-
.ok()
79-
.and_then(|instance| predicate(tcx, instance).then_some(instance))
79+
// TODO: Remove the def_kind check once https://github.com/rust-lang/rust/pull/119135 has been released.
80+
let def_id = rustc_internal::internal(item.def_id());
81+
(matches!(tcx.def_kind(def_id), rustc_hir::def::DefKind::Ctor(..))
82+
|| matches!(item.kind(), ItemKind::Fn))
83+
.then(|| {
84+
Instance::try_from(*item)
85+
.ok()
86+
.and_then(|instance| predicate(tcx, instance).then_some(instance))
87+
})
88+
.flatten()
8089
})
8190
.collect::<Vec<_>>()
8291
}

tests/cargo-kani/assess-workspace-artifacts/expected

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ Analyzed 2 packages
1111
unsupported_construct | 3
1212
none (success) | 3
1313
=========================================
14-
=======================================================================================================================
14+
=================================================
1515
Candidate for proof harness | Location
16-
--------------------------------------+--------------------------------------------------------------------------------
16+
--------------------------------------+----------
1717
a_supported_test_from_tests |
1818
a_supported_test_from_the_lib |
1919
a_supported_test_from_the_subpackage |
20-
=======================================================================================================================
20+
==================================================

0 commit comments

Comments
 (0)