diff --git a/crates/analyzer/src/symbol_path.rs b/crates/analyzer/src/symbol_path.rs index ef587082c..aa3e609f5 100644 --- a/crates/analyzer/src/symbol_path.rs +++ b/crates/analyzer/src/symbol_path.rs @@ -434,6 +434,7 @@ impl GenericSymbolPath { && let Some(mut alias_target) = symbol.found.alias_target() { alias_target.apply_map(&generic_maps); + alias_target.resolve_imported(&namespace, Some(&generic_maps)); if (i + 1) < self.paths.len() { for j in (i + 1)..self.paths.len() { alias_target.paths.push(self.paths[j].clone()); @@ -561,11 +562,20 @@ impl GenericSymbolPath { return; } if let Ok(symbol) = symbol_table::resolve((&self.generic_path(), namespace)) { - if matches!(symbol.found.kind, SymbolKind::EnumMember(_)) { + if self.len() > 1 + && matches!( + symbol.found.kind, + SymbolKind::EnumMember(_) + | SymbolKind::StructMember(_) + | SymbolKind::UnionMember(_) + ) + { // The parent enum declaration is imported but not the enum member. // Therefore, we need to execute `resolve_imported` to the parent enum declaration. // see: // https://github.com/veryl-lang/veryl/issues/1721#issuecomment-2986758880 + // + // This is also applied for struct/union member. let member_path = self.paths.pop().unwrap(); if namespace.matched(&symbol.found.namespace) { // For case that the given namespace is matched with the enum declaration diff --git a/crates/emitter/src/tests.rs b/crates/emitter/src/tests.rs index 9af006402..6c813bb8c 100644 --- a/crates/emitter/src/tests.rs +++ b/crates/emitter/src/tests.rs @@ -2294,3 +2294,80 @@ endmodule println!("ret\n{}exp\n{}", ret, expect); assert_eq!(ret, expect); } + +#[test] +fn package_alias_defined_in_module() { + let code = r#" +proto package a_proto_pkg { + struct a_struct { + a: u32, + } + const A: a_struct; +} +package a_pkg:: for a_proto_pkg { + struct a_struct { + a: u32, + } + const A: a_struct = a_struct'{ a: A_VALUE }; +} + +proto package b_proto_pkg { + const B: u32; +} +package b_pkg:: for b_proto_pkg { + const B: u32 = B_VALUE; +} + +module c_module:: { +} + +module d_module:: { + import A_PKG::*; + alias package B_PKG = b_pkg::; + inst u: c_module::; +} + +alias package A_PKG = a_pkg::<32>; +alias module D_MODULE = d_module::; +"#; + + let expect = r#" + +package prj___a_pkg__32; + typedef struct packed { + int unsigned a; + } a_struct; + localparam a_struct A = '{a: 32}; +endpackage + + +package prj___b_pkg____a_pkg__32_A_a; + localparam int unsigned B = prj___a_pkg__32::A.a; +endpackage + +module prj___c_module____b_pkg____a_pkg__32_A_a; +endmodule + +module prj___d_module____a_pkg__32; + import prj___a_pkg__32::*; + + + + prj___c_module____b_pkg____a_pkg__32_A_a u (); +endmodule + + +//# sourceMappingURL=test.sv.map +"#; + + let metadata = Metadata::create_default("prj").unwrap(); + + let ret = if cfg!(windows) { + emit(&metadata, code).replace("\r\n", "\n") + } else { + emit(&metadata, code) + }; + + println!("ret\n{}exp\n{}", ret, expect); + assert_eq!(ret, expect); +}