@@ -172,8 +172,19 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
172
172
"{}{}{}" ,
173
173
self . temp_variable_prefix, name, self . temp_variable_suffix
174
174
) ;
175
- let l_value = self . generate_element_pointer ( expression) ?;
176
- Ok ( self . llvm . load_pointer ( & l_value, load_name. as_str ( ) ) )
175
+ if let Some ( StatementAnnotation :: Variable {
176
+ qualified_name,
177
+ constant : true ,
178
+ ..
179
+ } ) = self . annotations . get ( expression)
180
+ {
181
+ // constant propagation
182
+ self . generate_constant_expression ( qualified_name, expression)
183
+ } else {
184
+ // general reference generation
185
+ let l_value = self . generate_element_pointer ( expression) ?;
186
+ Ok ( self . llvm . load_pointer ( & l_value, load_name. as_str ( ) ) )
187
+ }
177
188
}
178
189
AstStatement :: QualifiedReference { elements, .. } => {
179
190
//If direct access, don't load pointers
@@ -212,6 +223,40 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
212
223
}
213
224
}
214
225
226
+ /// Propagate the constant value of the constant reference to `qualified_name`.
227
+ /// - `qualified _name` the qualified name of the referenced constant variable we want to propagate
228
+ /// - `expression` the original expression
229
+ fn generate_constant_expression (
230
+ & self ,
231
+ qualified_name : & str ,
232
+ expression : & AstStatement ,
233
+ ) -> Result < BasicValueEnum < ' ink > , Diagnostic > {
234
+ let const_expression = self
235
+ . index
236
+ // try to find a constant variable
237
+ . find_variable ( None , & [ qualified_name] )
238
+ // or else try to find an enum element
239
+ . or_else ( || self . index . find_qualified_enum_element ( qualified_name) )
240
+ // if this is no constant we have a problem
241
+ . filter ( |v| v. is_constant ( ) )
242
+ . and_then ( |v| v. initial_value )
243
+ // fetch the constant's initial value fron the const-expressions arena
244
+ . and_then ( |constant_variable| {
245
+ self . index
246
+ . get_const_expressions ( )
247
+ . get_resolved_constant_statement ( & constant_variable)
248
+ } )
249
+ . ok_or_else ( || {
250
+ Diagnostic :: codegen_error (
251
+ format ! ( "Cannot propagate constant value for '{:}'" , qualified_name) . as_str ( ) ,
252
+ expression. get_location ( ) ,
253
+ )
254
+ } ) ?;
255
+
256
+ // generate the resulting constant-expression (which should be a Value, no ptr-reference)
257
+ self . generate_expression ( const_expression)
258
+ }
259
+
215
260
/// generates a binary expression (e.g. a + b, x AND y, etc.) and returns the resulting `BasicValueEnum`
216
261
/// - `left` the AstStatement left of the operator
217
262
/// - `right` the AstStatement right of the operator
0 commit comments