Skip to content

Commit 97bca8b

Browse files
Auto merge of #146128 - bvanjoi:issue-145741, r=<try>
privacy: cache for trait ref in projection
2 parents a2c8b0b + e82aa32 commit 97bca8b

File tree

2 files changed

+235
-1
lines changed

2 files changed

+235
-1
lines changed

compiler/rustc_privacy/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub trait DefIdVisitor<'tcx> {
8383
DefIdVisitorSkeleton {
8484
def_id_visitor: self,
8585
visited_opaque_tys: Default::default(),
86+
visited_trait_ref_in_projection: Default::default(),
8687
dummy: Default::default(),
8788
}
8889
}
@@ -103,6 +104,7 @@ pub trait DefIdVisitor<'tcx> {
103104
pub struct DefIdVisitorSkeleton<'v, 'tcx, V: ?Sized> {
104105
def_id_visitor: &'v mut V,
105106
visited_opaque_tys: FxHashSet<DefId>,
107+
visited_trait_ref_in_projection: FxHashSet<ty::TraitRef<'tcx>>,
106108
dummy: PhantomData<TyCtxt<'tcx>>,
107109
}
108110

@@ -123,7 +125,9 @@ where
123125
fn visit_projection_term(&mut self, projection: ty::AliasTerm<'tcx>) -> V::Result {
124126
let tcx = self.def_id_visitor.tcx();
125127
let (trait_ref, assoc_args) = projection.trait_ref_and_own_args(tcx);
126-
try_visit!(self.visit_trait(trait_ref));
128+
if self.visited_trait_ref_in_projection.insert(trait_ref) {
129+
try_visit!(self.visit_trait(trait_ref));
130+
}
127131
if V::SHALLOW {
128132
V::Result::output()
129133
} else {
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
//@check-pass
2+
3+
// issue#145741
4+
5+
use std::marker::PhantomData;
6+
7+
pub struct Fn2<A: ?Sized, B: ?Sized, R: ?Sized> {
8+
_0: PhantomData<fn() -> A>,
9+
_1: PhantomData<fn() -> B>,
10+
_2: PhantomData<fn() -> R>,
11+
}
12+
13+
impl<A: ?Sized + Tag, B: ?Sized + Tag, R: ?Sized + Tag> Tag for Fn2<A, B, R> {
14+
type MaskProjection = MaskToProjection<
15+
MaskOr<
16+
ProjectMask<MaskAllOn, <A as Tag>::MaskProjection>,
17+
MaskOr<
18+
ProjectMask<MaskAllOn, <B as Tag>::MaskProjection>,
19+
MaskOr<ProjectMask<MaskAllOn, <R as Tag>::MaskProjection>, Mask>,
20+
>,
21+
>,
22+
>;
23+
}
24+
25+
// Add 1 generic (and it's part of the associated type)
26+
pub struct Fn3<A: ?Sized, B: ?Sized, C: ?Sized, R: ?Sized> {
27+
_0: PhantomData<fn() -> A>,
28+
_1: PhantomData<fn() -> B>,
29+
_2: PhantomData<fn() -> C>,
30+
_3: PhantomData<fn() -> R>,
31+
}
32+
33+
impl<A: ?Sized + Tag, B: ?Sized + Tag, C: ?Sized + Tag, R: ?Sized + Tag> Tag for Fn3<A, B, C, R> {
34+
type MaskProjection = MaskToProjection<
35+
MaskOr<
36+
ProjectMask<MaskAllOn, <A as Tag>::MaskProjection>,
37+
MaskOr<
38+
ProjectMask<MaskAllOn, <B as Tag>::MaskProjection>,
39+
MaskOr<
40+
ProjectMask<MaskAllOn, <C as Tag>::MaskProjection>,
41+
MaskOr<ProjectMask<MaskAllOn, <R as Tag>::MaskProjection>, Mask>,
42+
>,
43+
>,
44+
>,
45+
>;
46+
}
47+
48+
pub struct TypeTuple<_0, _1, _2, _3, _4, _5>(_0, _1, _2, _3, _4, _5);
49+
50+
pub trait TypeTupleAccess {
51+
type _0;
52+
type _1;
53+
type _2;
54+
type _3;
55+
type _4;
56+
type _5;
57+
}
58+
59+
impl<_0, _1, _2, _3, _4, _5> TypeTupleAccess for TypeTuple<_0, _1, _2, _3, _4, _5> {
60+
type _0 = _0;
61+
type _1 = _1;
62+
type _2 = _2;
63+
type _3 = _3;
64+
type _4 = _4;
65+
type _5 = _5;
66+
}
67+
68+
pub trait Projection:
69+
TypeTupleAccess<
70+
_0: SlotPicker,
71+
_1: SlotPicker,
72+
_2: SlotPicker,
73+
_3: SlotPicker,
74+
_4: SlotPicker,
75+
_5: SlotPicker,
76+
>
77+
{
78+
}
79+
80+
impl<_0, _1, _2, _3, _4, _5> Projection for TypeTuple<_0, _1, _2, _3, _4, _5>
81+
where
82+
_0: SlotPicker,
83+
_1: SlotPicker,
84+
_2: SlotPicker,
85+
_3: SlotPicker,
86+
_4: SlotPicker,
87+
_5: SlotPicker,
88+
{
89+
}
90+
91+
pub trait Tag: 'static {
92+
type MaskProjection: Projection;
93+
}
94+
95+
pub trait Tagged {
96+
type Tag: Tag;
97+
}
98+
99+
pub struct Pick<const I: u8>;
100+
101+
pub trait SlotPicker: 'static {
102+
type Mask<B: MaskBit>: MaskBits;
103+
}
104+
105+
impl SlotPicker for Pick<0> {
106+
type Mask<B: MaskBit> = TypeTuple<B, Off, Off, Off, Off, Off>;
107+
}
108+
109+
impl SlotPicker for Pick<1> {
110+
type Mask<B: MaskBit> = TypeTuple<Off, B, Off, Off, Off, Off>;
111+
}
112+
113+
impl SlotPicker for Pick<2> {
114+
type Mask<B: MaskBit> = TypeTuple<Off, Off, B, Off, Off, Off>;
115+
}
116+
117+
impl SlotPicker for Pick<3> {
118+
type Mask<B: MaskBit> = TypeTuple<Off, Off, Off, B, Off, Off>;
119+
}
120+
121+
impl SlotPicker for Pick<4> {
122+
type Mask<B: MaskBit> = TypeTuple<Off, Off, Off, Off, B, Off>;
123+
}
124+
125+
impl SlotPicker for Pick<5> {
126+
type Mask<B: MaskBit> = TypeTuple<Off, Off, Off, Off, Off, B>;
127+
}
128+
129+
pub struct Static;
130+
131+
impl SlotPicker for Static {
132+
type Mask<B: MaskBit> = TypeTuple<Off, Off, Off, Off, Off, Off>;
133+
}
134+
135+
pub type Projector<
136+
_0 = Static,
137+
_1 = Static,
138+
_2 = Static,
139+
_3 = Static,
140+
_4 = Static,
141+
_5 = Static
142+
> =
143+
TypeTuple<_0, _1, _2, _3, _4, _5>;
144+
145+
pub trait MaskBit {
146+
type Or<T: MaskBit>: MaskBit;
147+
148+
type Pick<T: SlotPicker>: SlotPicker;
149+
}
150+
151+
pub type Mask<_0 = Off, _1 = Off, _2 = Off, _3 = Off, _4 = Off, _5 = Off> =
152+
TypeTuple<_0, _1, _2, _3, _4, _5>;
153+
154+
pub trait MaskBits:
155+
TypeTupleAccess<_0: MaskBit, _1: MaskBit, _2: MaskBit, _3: MaskBit, _4: MaskBit, _5: MaskBit>
156+
{
157+
}
158+
159+
impl<_0, _1, _2, _3, _4, _5> MaskBits for TypeTuple<_0, _1, _2, _3, _4, _5>
160+
where
161+
_0: MaskBit,
162+
_1: MaskBit,
163+
_2: MaskBit,
164+
_3: MaskBit,
165+
_4: MaskBit,
166+
_5: MaskBit,
167+
{
168+
}
169+
170+
pub struct On;
171+
pub struct Off;
172+
173+
impl MaskBit for On {
174+
type Or<T: MaskBit> = Self;
175+
176+
type Pick<T: SlotPicker> = T;
177+
}
178+
179+
impl MaskBit for Off {
180+
type Or<T: MaskBit> = T;
181+
182+
type Pick<T: SlotPicker> = Static;
183+
}
184+
185+
pub type MaskAllOn = TypeTuple<On, On, On, On, On, On>;
186+
187+
pub type MaskOr<MaskA, MaskB> = TypeTuple<
188+
<<MaskA as TypeTupleAccess>::_0 as MaskBit>::Or<<MaskB as TypeTupleAccess>::_0>,
189+
<<MaskA as TypeTupleAccess>::_1 as MaskBit>::Or<<MaskB as TypeTupleAccess>::_1>,
190+
<<MaskA as TypeTupleAccess>::_2 as MaskBit>::Or<<MaskB as TypeTupleAccess>::_2>,
191+
<<MaskA as TypeTupleAccess>::_3 as MaskBit>::Or<<MaskB as TypeTupleAccess>::_3>,
192+
<<MaskA as TypeTupleAccess>::_4 as MaskBit>::Or<<MaskB as TypeTupleAccess>::_4>,
193+
<<MaskA as TypeTupleAccess>::_5 as MaskBit>::Or<<MaskB as TypeTupleAccess>::_5>,
194+
>;
195+
196+
pub type ProjectMask<Mask, Projection> = MaskOr<
197+
MaskOr<
198+
MaskOr<
199+
<<Projection as TypeTupleAccess>::_0 as SlotPicker>::Mask<
200+
<Mask as TypeTupleAccess>::_0,
201+
>,
202+
<<Projection as TypeTupleAccess>::_1 as SlotPicker>::Mask<
203+
<Mask as TypeTupleAccess>::_1,
204+
>,
205+
>,
206+
MaskOr<
207+
<<Projection as TypeTupleAccess>::_2 as SlotPicker>::Mask<
208+
<Mask as TypeTupleAccess>::_2,
209+
>,
210+
<<Projection as TypeTupleAccess>::_3 as SlotPicker>::Mask<
211+
<Mask as TypeTupleAccess>::_3,
212+
>,
213+
>,
214+
>,
215+
MaskOr<
216+
<<Projection as TypeTupleAccess>::_4 as SlotPicker>::Mask<<Mask as TypeTupleAccess>::_4>,
217+
<<Projection as TypeTupleAccess>::_5 as SlotPicker>::Mask<<Mask as TypeTupleAccess>::_5>,
218+
>,
219+
>;
220+
221+
pub type MaskToProjection<Mask> = TypeTuple<
222+
<<Mask as TypeTupleAccess>::_0 as MaskBit>::Pick<Pick<0>>,
223+
<<Mask as TypeTupleAccess>::_1 as MaskBit>::Pick<Pick<1>>,
224+
<<Mask as TypeTupleAccess>::_2 as MaskBit>::Pick<Pick<2>>,
225+
<<Mask as TypeTupleAccess>::_3 as MaskBit>::Pick<Pick<3>>,
226+
<<Mask as TypeTupleAccess>::_4 as MaskBit>::Pick<Pick<4>>,
227+
<<Mask as TypeTupleAccess>::_5 as MaskBit>::Pick<Pick<5>>,
228+
>;
229+
230+
fn main() {}

0 commit comments

Comments
 (0)