Skip to content

Commit b63d05a

Browse files
committed
Auto merge of #78683 - Nemo157:issue-78673, r=lcnr
Check predicates from blanket trait impls while testing if they apply fixes #78673
2 parents 74f7e32 + 0e2af5c commit b63d05a

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

src/librustdoc/clean/blanket_impl.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,30 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
6262
"invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
6363
param_env, trait_ref, ty
6464
);
65-
match infcx.evaluate_obligation(&traits::Obligation::new(
66-
cause,
67-
param_env,
68-
trait_ref.without_const().to_predicate(infcx.tcx),
69-
)) {
70-
Ok(eval_result) => eval_result.may_apply(),
71-
Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no
65+
let predicates = self
66+
.cx
67+
.tcx
68+
.predicates_of(impl_def_id)
69+
.instantiate(self.cx.tcx, impl_substs)
70+
.predicates
71+
.into_iter()
72+
.chain(Some(trait_ref.without_const().to_predicate(infcx.tcx)));
73+
for predicate in predicates {
74+
debug!("testing predicate {:?}", predicate);
75+
let obligation = traits::Obligation::new(
76+
traits::ObligationCause::dummy(),
77+
param_env,
78+
predicate,
79+
);
80+
match infcx.evaluate_obligation(&obligation) {
81+
Ok(eval_result) if eval_result.may_apply() => {}
82+
Err(traits::OverflowError) => {}
83+
_ => {
84+
return false;
85+
}
86+
}
7287
}
88+
true
7389
} else {
7490
false
7591
}

src/test/rustdoc/issue-78673.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![crate_name = "issue_78673"]
2+
3+
pub trait Something {}
4+
5+
pub trait AnAmazingTrait {}
6+
7+
impl<T: Something> AnAmazingTrait for T {}
8+
9+
// @has 'issue_78673/struct.MyStruct.html'
10+
// @has - '//*[@class="impl"]' 'AnAmazingTrait for MyStruct'
11+
// @!has - '//*[@class="impl"]' 'AnAmazingTrait for T'
12+
pub struct MyStruct;
13+
14+
impl AnAmazingTrait for MyStruct {}
15+
16+
// generic structs may have _both_ specific and blanket impls that apply
17+
18+
// @has 'issue_78673/struct.AnotherStruct.html'
19+
// @has - '//*[@class="impl"]' 'AnAmazingTrait for AnotherStruct<()>'
20+
// @has - '//*[@class="impl"]' 'AnAmazingTrait for T'
21+
pub struct AnotherStruct<T>(T);
22+
23+
impl<T: Something> Something for AnotherStruct<T> {}
24+
impl AnAmazingTrait for AnotherStruct<()> {}

0 commit comments

Comments
 (0)