Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion crates/analyzer/src/symbol_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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
Expand Down
77 changes: 77 additions & 0 deletions crates/emitter/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<A_VALUE: u32> 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::<B_VALUE: u32> for b_proto_pkg {
const B: u32 = B_VALUE;
}

module c_module::<PKG: b_proto_pkg> {
}

module d_module::<A_PKG: a_proto_pkg> {
import A_PKG::*;
alias package B_PKG = b_pkg::<A.a>;
inst u: c_module::<B_PKG>;
}

alias package A_PKG = a_pkg::<32>;
alias module D_MODULE = d_module::<A_PKG>;
"#;

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);
}
Loading