Skip to content

Commit 18042d9

Browse files
committed
Elaborate projection predicates
1 parent e012a19 commit 18042d9

File tree

3 files changed

+80
-2
lines changed

3 files changed

+80
-2
lines changed

compiler/rustc_infer/src/traits/util.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,46 @@ impl<'tcx> Elaborator<'tcx> {
179179
// Currently, we do not "elaborate" predicates like `X -> Y`,
180180
// though conceivably we might.
181181
}
182-
ty::PredicateKind::Projection(..) => {
183-
// Nothing to elaborate in a projection predicate.
182+
ty::PredicateKind::Projection(projection_pred) => {
183+
let predicates = tcx.explicit_item_bounds(projection_pred.projection_ty.item_def_id);
184+
185+
debug!(?projection_pred, ?predicates);
186+
//dbg!(&predicates);
187+
188+
use crate::rustc_middle::ty::subst::Subst;
189+
let obligations = predicates.iter().filter_map(|&(pred, _)| {
190+
let predicate = tcx.mk_predicate(bound_predicate.map_bound(|_| pred.kind().skip_binder().subst(tcx, projection_pred.projection_ty.substs)));
191+
192+
let predicate = match predicate.kind().skip_binder() {
193+
ty::PredicateKind::Trait(trait_predicate) => {
194+
let mut substs: smallvec::SmallVec<[_; 4]> = trait_predicate.trait_ref.substs.iter().collect();
195+
substs[0] = projection_pred.ty.into();
196+
let substs = tcx.mk_substs(substs.into_iter());
197+
let trait_predicate = ty::TraitPredicate {
198+
constness: trait_predicate.constness,
199+
polarity: trait_predicate.polarity,
200+
trait_ref: ty::TraitRef {
201+
def_id: trait_predicate.def_id(),
202+
substs,
203+
},
204+
};
205+
tcx.mk_predicate(predicate.kind().map_bound(|_| ty::PredicateKind::Trait(trait_predicate)))
206+
}
207+
ty::PredicateKind::Projection(_projection_predicate) => return None,
208+
_ => return None,
209+
};
210+
//dbg!(projection_pred, predicate, bound_predicate);
211+
Some(predicate_obligation(
212+
predicate,
213+
obligation.param_env,
214+
obligation.cause.clone(),
215+
))
216+
});
217+
218+
let visited = &mut self.visited;
219+
let obligations = obligations.filter(|o| visited.insert(o.predicate));
220+
221+
self.stack.extend(obligations);
184222
}
185223
ty::PredicateKind::ClosureKind(..) => {
186224
// Nothing to elaborate when waiting for a closure's kind to be inferred.

issue-91985

3.85 MB
Binary file not shown.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#![feature(generic_associated_types)]
2+
3+
pub trait Trait1 {
4+
type Associated;
5+
}
6+
7+
pub trait Trait2 {
8+
type Associated: Clone;
9+
}
10+
11+
pub trait GatTrait {
12+
type Gat<T: Clone>;
13+
}
14+
15+
pub struct GatStruct;
16+
17+
impl GatTrait for GatStruct {
18+
type Gat<T: Clone> = Box<T>;
19+
}
20+
21+
pub struct OuterStruct<T1: Trait1, T2: Trait2> {
22+
_inner: InnerStruct<T2, GatStruct>,
23+
_t1: T1,
24+
}
25+
26+
pub struct InnerStruct<T: Trait2, G: GatTrait> {
27+
pub gat: G::Gat<T::Associated>,
28+
}
29+
30+
impl<T1, T2> OuterStruct<T1, T2>
31+
where
32+
T1: Trait1,
33+
T2: Trait2<Associated = T1::Associated>,
34+
{
35+
pub fn new() -> Self {
36+
todo!()
37+
}
38+
}
39+
40+
fn main() {}

0 commit comments

Comments
 (0)