@@ -11,7 +11,10 @@ use crate::{
1111 } ,
1212 hir:: {
1313 def_collector:: {
14- dc_crate:: { CompilationError , UnresolvedStruct , UnresolvedTrait , UnresolvedTypeAlias } ,
14+ dc_crate:: {
15+ filter_literal_globals, CompilationError , UnresolvedGlobal , UnresolvedStruct ,
16+ UnresolvedTrait , UnresolvedTypeAlias ,
17+ } ,
1518 errors:: DuplicateType ,
1619 } ,
1720 resolution:: { errors:: ResolverError , path_resolver:: PathResolver , resolver:: LambdaContext } ,
@@ -25,13 +28,14 @@ use crate::{
2528 HirInfixExpression , HirLambda , HirMemberAccess , HirMethodCallExpression ,
2629 HirMethodReference , HirPrefixExpression ,
2730 } ,
31+ stmt:: HirLetStatement ,
2832 traits:: TraitConstraint ,
2933 } ,
3034 macros_api:: {
3135 BlockExpression , CallExpression , CastExpression , Expression , ExpressionKind , HirExpression ,
3236 HirLiteral , HirStatement , Ident , IndexExpression , Literal , MemberAccessExpression ,
33- MethodCallExpression , NodeInterner , NoirFunction , NoirStruct , PrefixExpression , Statement ,
34- StatementKind , StructId ,
37+ MethodCallExpression , NodeInterner , NoirFunction , NoirStruct , Pattern , PrefixExpression ,
38+ SecondaryAttribute , Statement , StatementKind , StructId ,
3539 } ,
3640 node_interner:: { DefinitionKind , DependencyId , ExprId , FuncId , StmtId , TraitId , TypeAliasId } ,
3741 Shared , StructType , Type , TypeVariable ,
@@ -207,25 +211,48 @@ impl<'context> Elaborator<'context> {
207211 ) -> Vec < ( CompilationError , FileId ) > {
208212 let mut this = Self :: new ( context, crate_id) ;
209213
210- // the resolver filters literal globals first
211- for global in items. globals { }
214+ // We must first resolve and intern the globals before we can resolve any stmts inside each function.
215+ // Each function uses its own resolver with a newly created ScopeForest, and must be resolved again to be within a function's scope
216+ //
217+ // Additionally, we must resolve integer globals before structs since structs may refer to
218+ // the values of integer globals as numeric generics.
219+ let ( literal_globals, non_literal_globals) = filter_literal_globals ( items. globals ) ;
220+
221+ for global in literal_globals {
222+ this. elaborate_global ( global) ;
223+ }
212224
213225 for ( alias_id, alias) in items. type_aliases {
214226 this. define_type_alias ( alias_id, alias) ;
215227 }
216228
217229 this. collect_traits ( items. traits ) ;
230+
231+ // Must resolve structs before we resolve globals.
218232 this. collect_struct_definitions ( items. types ) ;
219233
234+ // Bind trait impls to their trait. Collect trait functions, that have a
235+ // default implementation, which hasn't been overridden.
220236 for trait_impl in & mut items. trait_impls {
221237 this. collect_trait_impl ( trait_impl) ;
222238 }
223239
240+ // Before we resolve any function symbols we must go through our impls and
241+ // re-collect the methods within into their proper module. This cannot be
242+ // done during def collection since we need to be able to resolve the type of
243+ // the impl since that determines the module we should collect into.
244+ //
245+ // These are resolved after trait impls so that struct methods are chosen
246+ // over trait methods if there are name conflicts.
224247 for ( ( typ, module) , impls) in & items. impls {
225248 this. collect_impls ( typ, * module, impls) ;
226249 }
227250
228- // resolver resolves non-literal globals here
251+ // We must wait to resolve non-literal globals until after we resolve structs since struct
252+ // globals will need to reference the struct type they're initialized to to ensure they are valid.
253+ for global in non_literal_globals {
254+ this. elaborate_global ( global) ;
255+ }
229256
230257 for functions in items. functions {
231258 this. elaborate_functions ( functions) ;
@@ -1173,4 +1200,33 @@ impl<'context> Elaborator<'context> {
11731200
11741201 ( generics, fields)
11751202 }
1203+
1204+ fn elaborate_global ( & mut self , global : UnresolvedGlobal ) {
1205+ self . local_module = global. module_id ;
1206+ self . file = global. file_id ;
1207+
1208+ let global_id = global. global_id ;
1209+ self . current_item = Some ( DependencyId :: Global ( global_id) ) ;
1210+
1211+ let definition_kind = DefinitionKind :: Global ( global_id) ;
1212+ let let_stmt = global. stmt_def ;
1213+
1214+ if !self . in_contract
1215+ && let_stmt. attributes . iter ( ) . any ( |attr| matches ! ( attr, SecondaryAttribute :: Abi ( _) ) )
1216+ {
1217+ let span = let_stmt. pattern . span ( ) ;
1218+ self . push_err ( ResolverError :: AbiAttributeOutsideContract { span } ) ;
1219+ }
1220+
1221+ if !let_stmt. comptime && matches ! ( let_stmt. pattern, Pattern :: Mutable ( ..) ) {
1222+ let span = let_stmt. pattern . span ( ) ;
1223+ self . push_err ( ResolverError :: MutableGlobal { span } ) ;
1224+ }
1225+
1226+ let ( let_statement, _typ) = self . elaborate_let ( let_stmt) ;
1227+
1228+ let statement_id = self . interner . get_global ( global_id) . let_statement ;
1229+ self . interner . get_global_definition_mut ( global_id) . kind = definition_kind;
1230+ self . interner . replace_statement ( statement_id, let_statement) ;
1231+ }
11761232}
0 commit comments