@@ -3,6 +3,7 @@ use crate::arena::{Arena, Handle};
3
3
4
4
pub struct ExpressionTracer < ' tracer > {
5
5
pub constants : & ' tracer Arena < crate :: Constant > ,
6
+ pub overrides : & ' tracer Arena < crate :: Override > ,
6
7
7
8
/// The arena in which we are currently tracing expressions.
8
9
pub expressions : & ' tracer Arena < crate :: Expression > ,
@@ -13,6 +14,9 @@ pub struct ExpressionTracer<'tracer> {
13
14
/// The used map for `constants`.
14
15
pub constants_used : & ' tracer mut HandleSet < crate :: Constant > ,
15
16
17
+ /// The used map for `overrides`.
18
+ pub overrides_used : & ' tracer mut HandleSet < crate :: Override > ,
19
+
16
20
/// The used set for `arena`.
17
21
///
18
22
/// This points to whatever arena holds the expressions we are
@@ -78,25 +82,32 @@ impl ExpressionTracer<'_> {
78
82
| Ex :: SubgroupBallotResult
79
83
| Ex :: RayQueryProceedResult => { }
80
84
85
+ // Expressions can refer to constants and overrides, which can refer
86
+ // in turn to expressions, which complicates our nice one-pass
87
+ // algorithm. But since constants and overrides don't refer to each
88
+ // other directly, only via expressions, we can get around this by
89
+ // looking *through* each constant/override and marking its
90
+ // initializer expression as used immediately. Since `expr` refers
91
+ // to the constant/override, which then refers to the initializer,
92
+ // the initializer must precede `expr` in the arena, so we know we
93
+ // have yet to visit the initializer, so it's not too late to mark
94
+ // it.
81
95
Ex :: Constant ( handle) => {
82
96
self . constants_used . insert ( handle) ;
83
- // Constants and expressions are mutually recursive, which
84
- // complicates our nice one-pass algorithm. However, since
85
- // constants don't refer to each other, we can get around
86
- // this by looking *through* each constant and marking its
87
- // initializer as used. Since `expr` refers to the constant,
88
- // and the constant refers to the initializer, it must
89
- // precede `expr` in the arena.
90
97
let init = self . constants [ handle] . init ;
91
98
match self . global_expressions_used {
92
99
Some ( ref mut used) => used. insert ( init) ,
93
100
None => self . expressions_used . insert ( init) ,
94
101
} ;
95
102
}
96
- Ex :: Override ( _) => {
97
- // All overrides are considered used by definition. We mark
98
- // their types and initialization expressions as used in
99
- // `compact::compact`, so we have no more work to do here.
103
+ Ex :: Override ( handle) => {
104
+ self . overrides_used . insert ( handle) ;
105
+ if let Some ( init) = self . overrides [ handle] . init {
106
+ match self . global_expressions_used {
107
+ Some ( ref mut used) => used. insert ( init) ,
108
+ None => self . expressions_used . insert ( init) ,
109
+ } ;
110
+ }
100
111
}
101
112
Ex :: ZeroValue ( ty) => {
102
113
self . types_used . insert ( ty) ;
@@ -256,11 +267,9 @@ impl ModuleMap {
256
267
| Ex :: SubgroupBallotResult
257
268
| Ex :: RayQueryProceedResult => { }
258
269
259
- // All overrides are retained, so their handles never change.
260
- Ex :: Override ( _) => { }
261
-
262
270
// Expressions that contain handles that need to be adjusted.
263
271
Ex :: Constant ( ref mut constant) => self . constants . adjust ( constant) ,
272
+ Ex :: Override ( ref mut r#override) => self . overrides . adjust ( r#override) ,
264
273
Ex :: ZeroValue ( ref mut ty) => self . types . adjust ( ty) ,
265
274
Ex :: Compose {
266
275
ref mut ty,
0 commit comments