Fix an issue with module declaration order
326c599dec28d013d4b4aaba5a7e107bdb328c7276286ed8d8ea1cbf89b539bf
1 parent
a74c66b8
lib/std.rad
+1 -5
| 1 | 1 | //! The Radiance Standard Library. |
|
| 2 | - | // TODO: The order of these module declarations matter, but they shouldn't. |
|
| 3 | - | ||
| 4 | - | // Nb: `testing` must come before all other modules so that `@test mod` |
|
| 5 | - | // submodules can `use std::testing` during resolution. |
|
| 6 | - | @test pub mod testing; |
|
| 7 | 2 | ||
| 8 | 3 | pub mod io; |
|
| 9 | 4 | pub mod collections; |
|
| 10 | 5 | pub mod lang; |
|
| 11 | 6 | pub mod sys; |
| 15 | 10 | pub mod mem; |
|
| 16 | 11 | pub mod vec; |
|
| 17 | 12 | pub mod intrinsics; |
|
| 18 | 13 | ||
| 19 | 14 | // Test modules. |
|
| 15 | + | @test pub mod testing; |
|
| 20 | 16 | @test pub mod tests; |
lib/std/lang/resolver.rad
+13 -11
| 5363 | 5363 | try setNodeType(self, root, Type::Void); |
|
| 5364 | 5364 | ||
| 5365 | 5365 | return Diagnostics { errors: self.errors }; |
|
| 5366 | 5366 | } |
|
| 5367 | 5367 | ||
| 5368 | - | /// Analyze the module graph. This pass doesn't process function, type or variable declarations, |
|
| 5369 | - | /// it only processes `mod` statements, creating symbols and scopes for them. |
|
| 5368 | + | /// Analyze the module graph. This pass processes `mod` statements, creating symbols |
|
| 5369 | + | /// and scopes for them, and also binds type names in each module so that cross-module |
|
| 5370 | + | /// type references work regardless of declaration order. |
|
| 5370 | 5371 | fn resolveModuleGraph(self: *mut Resolver, block: *ast::Block) throws (ResolveError) { |
|
| 5372 | + | try bindTypeNames(self, block); |
|
| 5373 | + | ||
| 5371 | 5374 | for i in 0..block.statements.len { |
|
| 5372 | 5375 | let node = block.statements.list[i]; |
|
| 5373 | 5376 | if let case ast::NodeValue::Mod(decl) = node.value { |
|
| 5374 | 5377 | try resolveModGraph(self, node, decl); |
|
| 5375 | 5378 | } |
|
| 5376 | 5379 | } |
|
| 5377 | 5380 | } |
|
| 5378 | 5381 | ||
| 5379 | 5382 | /// Bind all type names in a module. |
|
| 5383 | + | /// Skips declarations that have already been bound. |
|
| 5380 | 5384 | fn bindTypeNames(self: *mut Resolver, block: *ast::Block) throws (ResolveError) { |
|
| 5381 | 5385 | for i in 0..block.statements.len { |
|
| 5382 | 5386 | let node = block.statements.list[i]; |
|
| 5383 | 5387 | match node.value { |
|
| 5384 | 5388 | case ast::NodeValue::RecordDecl(decl) => { |
|
| 5385 | - | try bindTypeName(self, node, decl.name, decl.attrs) catch { |
|
| 5386 | - | // Continue binding other types even if one fails. |
|
| 5387 | - | }; |
|
| 5389 | + | if symbolFor(self, node) == nil { |
|
| 5390 | + | try bindTypeName(self, node, decl.name, decl.attrs) catch {}; |
|
| 5391 | + | } |
|
| 5388 | 5392 | } |
|
| 5389 | 5393 | case ast::NodeValue::UnionDecl(decl) => { |
|
| 5390 | - | try bindTypeName(self, node, decl.name, decl.attrs) catch { |
|
| 5391 | - | // Continue binding other types even if one fails. |
|
| 5392 | - | }; |
|
| 5393 | - | } |
|
| 5394 | - | else => { |
|
| 5395 | - | // Ignore other declarations. |
|
| 5394 | + | if symbolFor(self, node) == nil { |
|
| 5395 | + | try bindTypeName(self, node, decl.name, decl.attrs) catch {}; |
|
| 5396 | + | } |
|
| 5396 | 5397 | } |
|
| 5398 | + | else => {} |
|
| 5397 | 5399 | } |
|
| 5398 | 5400 | } |
|
| 5399 | 5401 | } |
|
| 5400 | 5402 | ||
| 5401 | 5403 | /// Resolve all type bodies in a module. |