Skip to content

Commit dda3a76

Browse files
committed
Prioritize trait method spec keys
1 parent 673081f commit dda3a76

3 files changed

Lines changed: 84 additions & 2 deletions

File tree

src/analyze/crate_.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,41 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
6060
}
6161

6262
fn refine_local_defs(&mut self) {
63+
// Prioritize trait method specs so that they are always available when refining trait impl
64+
// functions; see the partialeq_impl.rs case.
6365
let mut keys = self.tcx.mir_keys(()).clone();
66+
let mut formula_fn_keys = HashSet::new();
67+
let mut trait_method_spec_keys = HashSet::new();
6468
for local_def_id in self.tcx.mir_keys(()) {
6569
let analyzer = self.ctx.local_def_analyzer(*local_def_id);
6670
if analyzer.is_annotated_as_extern_spec_fn() {
67-
if let Some(target_def_id) = analyzer.extern_spec_fn_target_def_id().as_local() {
71+
let target_def_id = analyzer.extern_spec_fn_target_def_id();
72+
if let Some(local_target_def_id) = target_def_id.as_local() {
6873
self.skip_analysis.insert(local_target_def_id);
69-
keys.swap_remove(&target_def_id);
74+
keys.swap_remove(&local_target_def_id);
7075
}
76+
if matches!(
77+
self.tcx.def_kind(target_def_id),
78+
rustc_hir::def::DefKind::AssocFn
79+
) {
80+
trait_method_spec_keys.insert(*local_def_id);
81+
keys.swap_remove(local_def_id);
82+
}
83+
}
84+
if analyzer.is_annotated_as_formula_fn() {
85+
formula_fn_keys.insert(*local_def_id);
86+
keys.swap_remove(local_def_id);
7187
}
7288
if !self.tcx.def_kind(*local_def_id).is_fn_like() {
7389
keys.swap_remove(local_def_id);
7490
}
7591
}
92+
for local_def_id in &formula_fn_keys {
93+
self.refine_fn_def(*local_def_id);
94+
}
95+
for local_def_id in &trait_method_spec_keys {
96+
self.refine_fn_def(*local_def_id);
97+
}
7698
for local_def_id in &keys {
7799
self.refine_fn_def(*local_def_id);
78100
}

tests/ui/fail/partialeq_impl.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@error-in-other-file: Unsat
2+
//@compile-flags: -C debug-assertions=off
3+
4+
enum X {
5+
A(i32),
6+
}
7+
8+
impl thrust_models::Model for X {
9+
type Ty = Self;
10+
}
11+
12+
impl PartialEq for X {
13+
fn eq(&self, other: &X) -> bool {
14+
match (self, other) {
15+
(Self::A(lhs), Self::A(rhs)) => !lhs.eq(rhs),
16+
}
17+
}
18+
}
19+
20+
#[thrust::trusted]
21+
#[thrust_macros::requires(true)]
22+
#[thrust_macros::ensures(true)]
23+
fn rand() -> X {
24+
unimplemented!()
25+
}
26+
27+
fn main() {
28+
let x = rand();
29+
assert!(x == x);
30+
}

tests/ui/pass/partialeq_impl.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@check-pass
2+
//@compile-flags: -C debug-assertions=off
3+
4+
enum X {
5+
A(i32),
6+
}
7+
8+
impl thrust_models::Model for X {
9+
type Ty = Self;
10+
}
11+
12+
impl PartialEq for X {
13+
fn eq(&self, other: &X) -> bool {
14+
match (self, other) {
15+
(Self::A(lhs), Self::A(rhs)) => lhs.eq(rhs),
16+
}
17+
}
18+
}
19+
20+
#[thrust::trusted]
21+
#[thrust_macros::requires(true)]
22+
#[thrust_macros::ensures(true)]
23+
fn rand() -> X {
24+
unimplemented!()
25+
}
26+
27+
fn main() {
28+
let x = rand();
29+
assert!(x == x);
30+
}

0 commit comments

Comments
 (0)