Skip to content

Commit b6ac5ae

Browse files
fix mismatch_assignment error reported for generic arguments using items imported at an enclosing scope
(refs: #3120)
1 parent 283e237 commit b6ac5ae

9 files changed

Lines changed: 116 additions & 23 deletions

File tree

crates/analyzer/src/scope.rs

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -861,27 +861,55 @@ pub fn import_package_path(
861861
None
862862
}
863863

864+
/// Whether `scope` is a container `import` is declared directly under, i.e. the
865+
/// point the import-visibility walk stops at.
866+
fn is_import_container(scope: ScopeId) -> bool {
867+
SCOPE_ARENA.with(|f| {
868+
f.borrow().scopes.get(scope.0 as usize).is_some_and(|s| {
869+
matches!(
870+
s.kind,
871+
ScopeKind::Module | ScopeKind::Interface | ScopeKind::Package
872+
)
873+
})
874+
})
875+
}
876+
864877
/// Whether `symbol` (named `name`, declared under `symbol_define_context`) is
865-
/// imported directly into `namespace`, matching its exact paths and ifdef
866-
/// context. Wildcard members are additionally gated by the source container's
867-
/// ifdef context, mirroring the resolver's `Tier 2` wildcard visibility so an
878+
/// imported into `namespace`, matching its exact paths and ifdef context.
879+
/// Wildcard members are additionally gated by the source container's ifdef
880+
/// context, mirroring the resolver's `Tier 2` wildcard visibility so an
868881
/// ifdef-excluded member is not treated as imported.
882+
///
883+
/// An `import` under a module/interface/package takes effect across all of it,
884+
/// so a nested scope (generate block, function) also sees the bindings of the
885+
/// scopes enclosing it up to and including that container. The walk stops there
886+
/// because `import` is not visible across a container boundary.
869887
pub fn is_imported(
870888
namespace: &Namespace,
871889
symbol: SymbolId,
872890
name: StrId,
873891
symbol_define_context: &DefineContext,
874892
) -> bool {
875-
let scope = intern_namespace(namespace);
876893
let dctx = &namespace.define_context;
877-
imports_get(scope, name)
878-
.iter()
879-
.any(|b| b.symbol == symbol && &b.define_context == dctx)
880-
|| wildcards_get(scope).iter().any(|w| {
881-
&w.define_context == dctx
882-
&& !symbol_define_context.exclusive(&w.source_define_context)
883-
&& locals_get(w.source, name).contains(&symbol)
884-
})
894+
let mut current = Some(intern_namespace(namespace));
895+
while let Some(scope) = current {
896+
let imported = imports_get(scope, name)
897+
.iter()
898+
.any(|b| b.symbol == symbol && &b.define_context == dctx)
899+
|| wildcards_get(scope).iter().any(|w| {
900+
&w.define_context == dctx
901+
&& !symbol_define_context.exclusive(&w.source_define_context)
902+
&& locals_get(w.source, name).contains(&symbol)
903+
});
904+
if imported {
905+
return true;
906+
}
907+
if is_import_container(scope) {
908+
break;
909+
}
910+
current = parent(scope);
911+
}
912+
false
885913
}
886914

887915
/// Returns the wildcard imports declared directly in `scope`.

testcases/map/25_dependency_1.sv.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testcases/map/25_dependency_2.sv.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testcases/sample/src/baz_if.veryl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub interface baz_if::<PKG: baz_proto_pkg> {
2+
var baz_0: logic<PKG::BAZ_0>;
3+
var baz_1: logic<PKG::BAZ_1>;
4+
modport mp {
5+
..output
6+
}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub module baz_module::<PKG: baz_proto_pkg> (
2+
baz: modport baz_if::<PKG>::mp,
3+
) {
4+
assign baz.baz_0 = 0;
5+
assign baz.baz_1 = 1;
6+
}

testcases/sample/src/baz_pkg.veryl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
pub proto package baz_proto_pkg {
2-
const BAZ: u32;
2+
const BAZ_0: u32;
3+
const BAZ_1: u32;
34
}
45

5-
pub package baz_pkg::<V: u32> for baz_proto_pkg {
6-
const BAZ: u32 = V;
6+
pub package baz_pkg::<V0: u32, V1: u32> for baz_proto_pkg {
7+
const BAZ_0: u32 = V0;
8+
const BAZ_1: u32 = V1;
79
}

testcases/sv/25_dependency_1.sv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,10 @@ package veryl_testcase___Package25__1;
66
logic [C-1:0] s;
77
} S;
88
endpackage
9+
package veryl_testcase___Package25__2;
10+
localparam int unsigned C = 2;
11+
typedef struct packed {
12+
logic [C-1:0] s;
13+
} S;
14+
endpackage
915
//# sourceMappingURL=../map/25_dependency_1.sv.map

testcases/sv/25_dependency_2.sv

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
module veryl_testcase_Module25A
66
import veryl_sample4___bar_pkg__32::*;
7-
import veryl_sample4___baz_pkg__veryl_testcase___Package25__1_C::*;
7+
import veryl_sample4___baz_pkg__veryl_testcase___Package25__1_C__veryl_testcase___Package25__2_C::*;
88
(
99
input var logic i_clk ,
1010
input var logic i_rst_n,
@@ -101,8 +101,31 @@ module veryl_testcase_Module25F #(
101101
endmodule
102102

103103
module veryl_testcase_Module25G;
104-
import veryl_sample4___baz_pkg__veryl_testcase___Package25__1_C::BAZ;
104+
import veryl_sample4___baz_pkg__veryl_testcase___Package25__1_C__veryl_testcase___Package25__2_C::BAZ_0;
105+
import veryl_sample4___baz_pkg__veryl_testcase___Package25__1_C__veryl_testcase___Package25__2_C::BAZ_1;
105106

106-
int unsigned _f; always_comb _f = BAZ;
107+
108+
int unsigned _f0; always_comb _f0 = BAZ_0;
109+
int unsigned _f1; always_comb _f1 = BAZ_1;
110+
endmodule
111+
112+
package veryl_testcase_Pacakge25H;
113+
114+
115+
116+
117+
endpackage
118+
119+
module veryl_testcase_Module25I;
120+
121+
122+
123+
124+
veryl_sample4___baz_if__veryl_sample4___baz_pkg__veryl_sample4___baz_pkg__1__2_BAZ_0__3 baz ();
125+
if (1) begin :g
126+
veryl_sample4___baz_module__veryl_sample4___baz_pkg__veryl_sample4___baz_pkg__1__2_BAZ_0__3 u (
127+
.baz (baz)
128+
);
129+
end
107130
endmodule
108131
//# sourceMappingURL=../map/25_dependency_2.sv.map

testcases/veryl/25_dependency_2.veryl

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
alias package barpkg = veryl_sample4::bar_pkg::<32>;
22
alias package foopkg = veryl_sample4::foo_pkg::<barpkg::BAR>;
3-
alias package bazpkg = veryl_sample4::baz_pkg::<Package25::<1>::C>;
3+
alias package bazpkg = veryl_sample4::baz_pkg::<Package25::<1>::C, Package25::<2>::C>;
44

55
module Module25A (
66
i_clk : input clock ,
@@ -87,6 +87,27 @@ module Module25F #(
8787
}
8888

8989
module Module25G {
90-
import bazpkg::BAZ;
91-
let _f: u32 = BAZ;
90+
import bazpkg::BAZ_0;
91+
import bazpkg::BAZ_1;
92+
let _f0: u32 = BAZ_0;
93+
let _f1: u32 = BAZ_1;
94+
}
95+
96+
package Pacakge25H {
97+
gen BAZ_0_VALUE: u32 = 1;
98+
gen BAZ_1_VALUE: u32 = 2;
99+
alias package baz_1_2 = veryl_sample4::baz_pkg::<BAZ_0_VALUE, BAZ_1_VALUE>;
100+
}
101+
102+
module Module25I {
103+
import Pacakge25H::baz_1_2;
104+
105+
alias package baz_1_3 = veryl_sample4::baz_pkg::<baz_1_2::BAZ_0, 3>;
106+
107+
inst baz: veryl_sample4::baz_if::<baz_1_3>;
108+
:g {
109+
inst u: veryl_sample4::baz_module::<baz_1_3> (
110+
baz: baz,
111+
);
112+
}
92113
}

0 commit comments

Comments
 (0)