Skip to content

Commit f51e6b0

Browse files
committed
Insert mappings for interface packages.
Closes #403
1 parent 4be8227 commit f51e6b0

2 files changed

Lines changed: 70 additions & 1 deletion

File tree

vhdl_lang/src/analysis/association.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,29 @@ impl<'a> AnalyzeContext<'a, '_> {
654654
},
655655
InterfaceEnt::Package(_) => match expr {
656656
Expression::Name(name) => {
657-
self.name_resolve(scope, actual.span, name, diagnostics)?;
657+
let resolved =
658+
self.name_resolve(scope, actual.span, name, diagnostics)?;
659+
// When a formal generic package is mapped to an actual package,
660+
// populate the type mapping so that types from the formal package's
661+
// region resolve to the corresponding types in the actual package.
662+
if let ResolvedName::Design(actual_pkg) = resolved {
663+
let actual_region = match actual_pkg.kind() {
664+
Design::PackageInstance(r)
665+
| Design::InterfacePackageInstance(r) => Some(r),
666+
_ => None,
667+
};
668+
if let Some(actual_region) = actual_region {
669+
for named_entities in actual_region.entities.values() {
670+
if let Some(actual_ent) = named_entities.as_unique() {
671+
if let (Some(actual_type), Related::InstanceOf(uninst)) =
672+
(TypeEnt::from_any(actual_ent), &actual_ent.related)
673+
{
674+
mapping.insert(uninst.id(), actual_type);
675+
}
676+
}
677+
}
678+
}
679+
}
658680
}
659681
_ => diagnostics.add(
660682
actual.pos(self.ctx),

vhdl_lang/src/analysis/tests/package_instance.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,3 +822,50 @@ end architecture;
822822
let diagnostics = builder.analyze();
823823
check_no_diagnostics(&diagnostics);
824824
}
825+
826+
// Regression test for https://github.com/VHDL-LS/rust_hdl/issues/403
827+
#[test]
828+
fn type_from_generic_package_formal_is_compatible_with_actual() {
829+
let mut builder = LibraryBuilder::new();
830+
builder.code(
831+
"libname",
832+
"
833+
package base_pkg is
834+
generic(n : natural);
835+
type t is range 0 to n;
836+
end package;
837+
838+
use work.base_pkg;
839+
package wrapper_pkg is
840+
generic(package i_base is new base_pkg generic map(<>));
841+
function get return i_base.t;
842+
end package;
843+
844+
package body wrapper_pkg is
845+
function get return i_base.t is
846+
begin
847+
return 0;
848+
end function;
849+
end package body;
850+
851+
use work.base_pkg;
852+
use work.wrapper_pkg;
853+
entity tb is end entity;
854+
855+
architecture arch of tb is
856+
package my_base is new base_pkg generic map(10);
857+
package my_wrapper is new wrapper_pkg generic map(my_base);
858+
begin
859+
process
860+
variable v : my_base.t;
861+
begin
862+
v := my_wrapper.get;
863+
wait;
864+
end process;
865+
end architecture;
866+
",
867+
);
868+
869+
let diagnostics = builder.analyze();
870+
check_no_diagnostics(&diagnostics);
871+
}

0 commit comments

Comments
 (0)