Skip to content

Commit 46a2259

Browse files
committed
Skip analysis of extern_spec target only when trusted or ignored
Stopping the extern_spec_fn target from re-registering its own key (by removing it from the refine set) also dropped its `refine_fn_def`, which is where a trusted/ignored target is added to `skip_analysis`. Inserting every local target into `skip_analysis` instead sent the extern spec down the NoAnalyze branch of `refine_fn_def` for all targets, so a non-trusted target's body was never checked against the spec: a `#[context]` trait method's `ensures` (e.g. tests/ui/fail/trait_assoc_type_spec.rs) became a trusted assumption and the program verified even though the body cannot establish it. Only insert the target into `skip_analysis` when it is itself trusted or ignored (e.g. a `#[thrust::trusted]` `rand` whose `unimplemented!()` body must not be analyzed). Non-trusted targets stay out of `skip_analysis`, so the extern spec is registered in Analyze mode and their bodies are checked against the spec. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VowL2RdawM4Xch4tsdbSf3
1 parent dda3a76 commit 46a2259

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

src/analyze/crate_.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,26 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
7070
if analyzer.is_annotated_as_extern_spec_fn() {
7171
let target_def_id = analyzer.extern_spec_fn_target_def_id();
7272
if let Some(local_target_def_id) = target_def_id.as_local() {
73-
self.skip_analysis.insert(local_target_def_id);
73+
// Drop the plain target from the refine loop so it does not re-register the
74+
// key this extern spec owns. The target's own `refine_fn_def` would have
75+
// added it to `skip_analysis` only when it is trusted/ignored; replicate that
76+
// decision here. Otherwise the extern spec is registered in NoAnalyze mode for
77+
// every local target, and a non-trusted target's body (e.g. a `#[context]`
78+
// trait method) would never be checked against the spec.
79+
let target = local_target_def_id.to_def_id();
80+
let is_trusted_or_ignored = self
81+
.tcx
82+
.get_attrs_by_path(target, &analyze::annot::trusted_path())
83+
.next()
84+
.is_some()
85+
|| self
86+
.tcx
87+
.get_attrs_by_path(target, &analyze::annot::ignored_path())
88+
.next()
89+
.is_some();
90+
if is_trusted_or_ignored {
91+
self.skip_analysis.insert(local_target_def_id);
92+
}
7493
keys.swap_remove(&local_target_def_id);
7594
}
7695
if matches!(

0 commit comments

Comments
 (0)