Skip to content

Commit 0080ba1

Browse files
committed
finish sanity check
1 parent 5b77b46 commit 0080ba1

File tree

7 files changed

+69
-22
lines changed

7 files changed

+69
-22
lines changed

source/rust_verify/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ pub(crate) struct ExternalAttrs {
961961
pub(crate) verify: bool,
962962
pub(crate) verus_macro: bool,
963963
pub(crate) size_of_global: bool,
964+
pub(crate) item_broadcast_use: bool,
964965
pub(crate) any_other_verus_specific_attribute: bool,
965966
pub(crate) internal_get_field_many_variants: bool,
966967
pub(crate) external_auto_derives: AutoDerivesAttr,
@@ -1079,6 +1080,7 @@ pub(crate) fn get_external_attrs(
10791080
sets_mode: false,
10801081
verus_macro: false,
10811082
size_of_global: false,
1083+
item_broadcast_use: false,
10821084
any_other_verus_specific_attribute: false,
10831085
internal_get_field_many_variants: false,
10841086
external_auto_derives: AutoDerivesAttr::Regular,
@@ -1096,6 +1098,7 @@ pub(crate) fn get_external_attrs(
10961098
Attr::Mode(_) => es.sets_mode = true,
10971099
Attr::VerusMacro => es.verus_macro = true,
10981100
Attr::SizeOfGlobal => es.size_of_global = true,
1101+
Attr::ItemBroadcastUse => es.item_broadcast_use = true,
10991102
Attr::InternalGetFieldManyVariants => es.internal_get_field_many_variants = true,
11001103
Attr::Trusted => {}
11011104
Attr::ExternalAutoDerives(None) => {

source/rust_verify/src/erase.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ use crate::verus_items::{DummyCaptureItem, VerusItem, VerusItems};
1010
use rustc_hir::def_id::LocalDefId;
1111
use rustc_mir_build_verus::verus::{
1212
BodyErasure, CallErasure, ExpectSpec, ExpectSpecArgs, NodeErase, VarErasure, VerusErasureCtxt,
13-
set_verus_erasure_ctxt,
13+
set_verus_aware_def_ids, set_verus_erasure_ctxt,
1414
};
1515
use rustc_span::Span;
1616
use std::collections::HashMap;
17+
use std::collections::HashSet;
1718
use std::sync::Arc;
1819
use vir::ast::VirErr;
1920

@@ -320,3 +321,27 @@ pub(crate) fn setup_verus_ctxt_for_thir_erasure(
320321

321322
Ok(())
322323
}
324+
325+
pub(crate) fn setup_verus_aware_ids(crate_items: &crate::external::CrateItems) {
326+
// Requirements:
327+
// - If a function requires Verus-erasure, then it MUST be in the set
328+
// - If a function has special properties (e.g., being const), that may cause Rust
329+
// to run mir_borrowck on it before Verus mode-checking, then it MUST NOT be in the set.
330+
// For anything else: it doesn't matter.
331+
//
332+
// Since most consts are marked external, we can just use the VerusAware set for this.
333+
// We carve out exceptions for some special directives.
334+
335+
let mut s = HashSet::<LocalDefId>::new();
336+
for item in crate_items.items.iter() {
337+
match &item.verif {
338+
crate::external::VerifOrExternal::VerusAware { const_directive, .. } => {
339+
if !*const_directive {
340+
s.insert(item.id.owner_id().def_id);
341+
}
342+
}
343+
crate::external::VerifOrExternal::External { .. } => {}
344+
}
345+
}
346+
set_verus_aware_def_ids(Arc::new(s));
347+
}

source/rust_verify/src/external.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub struct CrateItem {
7070
#[derive(Debug, Clone)]
7171
pub enum VerifOrExternal {
7272
/// Path is the *module path* containing this item
73-
VerusAware { module_path: Path },
73+
VerusAware { module_path: Path, const_directive: bool },
7474
/// Path/String to refer to this item for diagnostics
7575
/// Path is an Option because there are some items we can't compute a Path for
7676
External { path: Option<Path>, path_string: String, explicit: bool },
@@ -324,7 +324,10 @@ impl<'a, 'tcx> VisitMod<'a, 'tcx> {
324324
// Append this item to the items
325325

326326
let verif = if state_for_this_item == VerifState::Verify {
327-
VerifOrExternal::VerusAware { module_path: self.module_path.clone() }
327+
VerifOrExternal::VerusAware {
328+
module_path: self.module_path.clone(),
329+
const_directive: eattrs.size_of_global || eattrs.item_broadcast_use,
330+
}
328331
} else {
329332
let path_opt =
330333
def_id_to_vir_path_option(self.ctxt.tcx, Some(&self.ctxt.verus_items), def_id);
@@ -424,8 +427,10 @@ impl<'a, 'tcx> VisitMod<'a, 'tcx> {
424427
"In order to verify any items of this trait impl, the entire impl must be verified. Try wrapping the entire impl in the `verus!` macro.",
425428
));
426429
} else {
427-
self.items[this_item_idx].verif =
428-
VerifOrExternal::VerusAware { module_path: self.module_path.clone() }
430+
self.items[this_item_idx].verif = VerifOrExternal::VerusAware {
431+
module_path: self.module_path.clone(),
432+
const_directive: false,
433+
}
429434
}
430435
}
431436
}

source/rust_verify/src/rust_to_vir.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ pub fn crate_to_vir<'a, 'tcx>(
417417
let mut used_modules = HashSet::<Path>::new();
418418
for crate_item in crate_items.items.iter() {
419419
match &crate_item.verif {
420-
VerifOrExternal::VerusAware { module_path } => {
420+
VerifOrExternal::VerusAware { module_path, const_directive: _ } => {
421421
used_modules.insert(module_path.clone());
422422
}
423423
_ => {}
@@ -461,7 +461,7 @@ pub fn crate_to_vir<'a, 'tcx>(
461461

462462
for crate_item in crate_items.items.iter() {
463463
match &crate_item.verif {
464-
VerifOrExternal::VerusAware { module_path } => {
464+
VerifOrExternal::VerusAware { module_path, const_directive: _ } => {
465465
match crate_item.id {
466466
GeneralItemId::ItemId(item_id) => {
467467
let item = ctxt.tcx.hir_item(item_id);

source/rust_verify/src/verifier.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2627,6 +2627,10 @@ impl Verifier {
26272627
diagnostics: &impl air::messages::Diagnostics,
26282628
crate_name: String,
26292629
) -> Result<bool, (VirErr, Vec<vir::ast::VirErrAs>)> {
2630+
if self.args.no_lifetime {
2631+
rustc_mir_build_verus::verus::set_verus_aware_def_ids(Arc::new(HashSet::new()));
2632+
}
2633+
26302634
self.air_no_span = {
26312635
let no_span = tcx
26322636
.hir_crate(())
@@ -2694,6 +2698,9 @@ impl Verifier {
26942698
|err: VirErr| (err, ctxt_diagnostics.borrow_mut().drain(..).collect());
26952699

26962700
let crate_items = crate::external::get_crate_items(&ctxt).map_err(map_err_diagnostics)?;
2701+
if !self.args.no_lifetime {
2702+
crate::erase::setup_verus_aware_ids(&crate_items);
2703+
}
26972704

26982705
let time_hir0 = Instant::now();
26992706

@@ -2702,11 +2709,6 @@ impl Verifier {
27022709
return Ok(false);
27032710
}
27042711

2705-
tcx.ensure_ok().check_private_in_public(());
2706-
tcx.hir_for_each_module(|module| {
2707-
tcx.ensure_ok().check_mod_privacy(module);
2708-
});
2709-
27102712
let time_hir1 = Instant::now();
27112713
self.time_hir = time_hir1 - time_hir0;
27122714

source/rustc_mir_build/src/thir/cx/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ pub(crate) fn thir_body(
2727
if let Some(reported) = cx.typeck_results.tainted_by_errors {
2828
return Err(reported);
2929
}
30+
31+
crate::verus::check_this_query_isnt_running_early(owner_def);
32+
3033
let expr = if crate::verus::erase_body(&mut cx, owner_def) {
3134
crate::verus::erase_tree(&mut cx, body.value)
3235
} else {

source/rustc_mir_build_additional_files/verus.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,18 @@ static VERUS_AWARE_DEF_IDS: RwLock<Option<Arc<HashSet<LocalDefId>>>> = RwLock::n
115115
/// Used to communicate the VerusErasureCtxt
116116
static VERUS_ERASURE_CTXT: RwLock<Option<Arc<VerusErasureCtxt>>> = RwLock::new(None);
117117

118+
pub fn set_verus_aware_def_ids(ids: Arc<HashSet<LocalDefId>>) {
119+
let v: &mut Option<Arc<HashSet<LocalDefId>>> = &mut VERUS_AWARE_DEF_IDS.write().unwrap();
120+
if v.is_some() {
121+
panic!("VERUS_AWARE_DEF_IDS has already been set");
122+
}
123+
*v = Some(ids);
124+
}
125+
118126
pub fn set_verus_erasure_ctxt(erasure_ctxt: Arc<VerusErasureCtxt>) {
119127
let v: &mut Option<Arc<VerusErasureCtxt>> = &mut VERUS_ERASURE_CTXT.write().unwrap();
120128
if v.is_some() {
121-
panic!("VerusErasureCtxt has already been set");
129+
panic!("VERUS_ERASURE_CTXT has already been set");
122130
}
123131
*v = Some(erasure_ctxt);
124132
}
@@ -136,9 +144,9 @@ fn get_verus_erasure_ctxt_option() -> Option<Arc<VerusErasureCtxt>> {
136144
VERUS_ERASURE_CTXT.read().unwrap().clone()
137145
}
138146

139-
/// Our erasure scheme will fail if this query runs too early, before we initialize the VerusErasureCtxt.
140-
/// However, there are some items (e.g. consts) where this happens intentionally because consts may be evaluated
141-
/// during type-checking.
147+
/// Our erasure scheme will fail if this query runs too early, before we initialize the
148+
/// VerusErasureCtxt. However, there are some items where this happens
149+
/// intentionally (e.g., for consts, which may be evaluated during type-checking).
142150
///
143151
/// rust_verify needs to follow the scheme:
144152
///
@@ -147,22 +155,23 @@ fn get_verus_erasure_ctxt_option() -> Option<Arc<VerusErasureCtxt>> {
147155
/// 3. initialize the VERUS_ERASURE_CTXT
148156
/// 4. Run lifetime checking
149157
///
150-
/// As a result, thir_body is able to sanity check we're in a consistent state. If the VERUS_ERASURE_CTXT
151-
/// hasn't been initialized yet, we check that the given item is one that doesn't need it.
152-
fn check_this_query_isnt_running_early(local_def_id: LocalDefId) {
158+
/// As a result, thir_body is able to sanity check we're in a consistent state.
159+
/// If the VERUS_ERASURE_CTXT hasn't been initialized yet, we check that the given
160+
/// item is one that doesn't need it.
161+
pub(crate) fn check_this_query_isnt_running_early(local_def_id: LocalDefId) {
153162
if get_verus_erasure_ctxt_option().is_none() {
154163
match VERUS_AWARE_DEF_IDS.read().unwrap().clone() {
155164
Some(m) => {
156165
if m.contains(&local_def_id) {
157166
panic!(
158-
"Internal Verus Error: The thir_body query is running for item {:?} which may require erasure, but the VerusErasureCtxt has not been initialized. Please file a github issue for this error and consider using `--no-lifetime` to work around the issue.",
167+
"Internal Verus Error: The thir_body query is running for item {:?} which may require erasure, but the VerusErasureCtxt has not been initialized. Please file a github issue for this error and consider using `--no-lifetime` as a temperary measure to work around the issue.",
159168
local_def_id
160169
);
161170
}
162171
}
163172
None => {
164173
panic!(
165-
"Internal Verus Error: The thir_body query is running for item {:?}, but the VerusAwareDefIds map has not been initialized. Please file a github issue for this error and consider using `--no-lifetime` to work around the issue.",
174+
"Internal Verus Error: The thir_body query is running for item {:?}, but the VerusAwareDefIds map has not been initialized. Please file a github issue for this error and consider using `--no-lifetime` as a temporary measure to work around the issue.",
166175
local_def_id
167176
);
168177
}
@@ -277,7 +286,7 @@ impl ExpectSpecArgs {
277286
ExpectSpecArgs::AllNo => ExpectSpec::No,
278287
ExpectSpecArgs::AllYes => ExpectSpec::Yes,
279288
ExpectSpecArgs::AllPropagate => ExpectSpec::Propagate,
280-
ExpectSpecArgs::PerArg(args) => args[args.len() - 1],
289+
ExpectSpecArgs::PerArg(args) => *args.last().unwrap(),
281290
}
282291
}
283292
}

0 commit comments

Comments
 (0)