Skip to content

Commit 1122a51

Browse files
authored
Merge pull request #3107 from taichi-ishitani/fix_unknown_member
Fix `unknown_member` error reported for items imported from generic packages defined in other projects
2 parents 4f4182e + 704126b commit 1122a51

15 files changed

Lines changed: 110 additions & 49 deletions

crates/analyzer/src/ir/signature.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,21 +119,29 @@ impl Signature {
119119
};
120120

121121
if !context.in_generic {
122-
// Apply default value
122+
let namespace = scope::namespace(scope, &define_context);
123+
123124
for (i, id) in symbol.full_path.iter().enumerate() {
124125
let path_symbol = if (i + 1) == symbol.full_path.len() {
125126
symbol_table::get(sig.symbol).unwrap()
126127
} else {
127128
symbol_table::get(*id).unwrap()
128129
};
129130

131+
// Apply default value
130132
let params = path_symbol.generic_parameters();
131133
let n_args = path.paths[i].arguments.len();
132134
for (_, default_value) in params.iter().skip(n_args) {
133135
if let Some(default_value) = &default_value.default_value {
134136
path.paths[i].arguments.push(default_value.clone())
135137
}
136138
}
139+
140+
if !path_symbol.is_global_function() {
141+
for arg in path.paths[i].arguments.iter_mut() {
142+
arg.append_namespace_path(&namespace, &path_symbol.namespace);
143+
}
144+
}
137145
}
138146

139147
if path.is_generic() {

crates/analyzer/src/reference_table.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,21 @@ impl ReferenceTable {
277277
) {
278278
let mut path = path.clone();
279279
let mut generic_maps = generic_maps.cloned().unwrap_or_default();
280-
281280
let orig_len = path.len();
282-
path.resolve_imported(scope, define_context, Some(&generic_maps));
283281

284-
// Prefix paths added by `resolve_imported` have already been resolved.
285-
// They should be skipped.
282+
path.resolve_imported(scope, define_context, Some(&generic_maps));
286283
let prefix_len = path.len() - orig_len;
287-
for i in prefix_len..path.len() {
284+
285+
for i in 0..path.len() {
286+
// Checks for paths added by 'resolve_imported' should be skipped beucase
287+
// they have already been done.
288+
let impoted_path = i < prefix_len;
288289
match symbol_table::resolve_base_path(&path, i, (scope, define_context.clone())) {
289290
Ok(symbol) => {
290-
self.check_pacakge_reference(&symbol.found, &path.range);
291-
symbol_table::add_reference(symbol.found.id, &path.paths[0].base);
291+
if !impoted_path {
292+
self.check_pacakge_reference(&symbol.found, &path.range);
293+
symbol_table::add_reference(symbol.found.id, &path.paths[0].base);
294+
}
292295

293296
// A user-defined component takes its parameters as
294297
// generic arguments in the `var` form; they are
@@ -304,9 +307,6 @@ impl ReferenceTable {
304307
continue;
305308
}
306309

307-
// Check number of arguments
308-
let params = symbol.found.generic_parameters();
309-
310310
let mut inference_attempted_failed = false;
311311
if i + 1 == path.paths.len() {
312312
use generic_inference_table::InferredApply;
@@ -317,6 +317,8 @@ impl ReferenceTable {
317317
}
318318
}
319319

320+
// Check number of arguments
321+
let params = symbol.found.generic_parameters();
320322
let n_args = path.paths[i].arguments.len();
321323

322324
if in_import_declaration
@@ -329,7 +331,7 @@ impl ReferenceTable {
329331
// Generic function, struct and union should be imorted as-is
330332
// but not as thier instances.
331333
// https://github.com/veryl-lang/veryl/issues/1619
332-
if n_args != 0 {
334+
if !impoted_path && n_args != 0 {
333335
self.errors.push(AnalyzerError::invalid_import(&path.range))
334336
}
335337
continue;
@@ -341,18 +343,20 @@ impl ReferenceTable {
341343
params.len() == n_args
342344
};
343345
if !match_artiy {
344-
if inference_attempted_failed {
345-
self.errors.push(AnalyzerError::generic_inference_failed(
346-
&path.paths[i].base.to_string(),
347-
&path.range,
348-
));
349-
} else {
350-
self.errors.push(AnalyzerError::mismatch_generics_arity(
351-
&path.paths[i].base.to_string(),
352-
params.len(),
353-
n_args,
354-
&path.range,
355-
));
346+
if !impoted_path {
347+
if inference_attempted_failed {
348+
self.errors.push(AnalyzerError::generic_inference_failed(
349+
&path.paths[i].base.to_string(),
350+
&path.range,
351+
));
352+
} else {
353+
self.errors.push(AnalyzerError::mismatch_generics_arity(
354+
&path.paths[i].base.to_string(),
355+
params.len(),
356+
n_args,
357+
&path.range,
358+
));
359+
}
356360
}
357361
continue;
358362
}

crates/analyzer/src/symbol_path.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,6 @@ impl GenericSymbolPath {
736736
if let Some(maps) = generic_maps {
737737
package_path.apply_map(maps);
738738
}
739-
package_path.unalias(None);
740739

741740
if let Ok(package_symbol) = symbol_table::resolve(SymbolPathNamespace::from_scope(
742741
package_path.generic_path(),

crates/tests/benches/benchmark.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ use veryl_parser::Parser;
1111
#[cfg(target_os = "linux")]
1212
mod perf;
1313

14-
const EXCLUDES: [&str; 7] = [
14+
const EXCLUDES: [&str; 8] = [
1515
r"25_dependency_1.veryl",
1616
r"25_dependency_2.veryl",
1717
r"52_include.veryl",
1818
r"67_cocotb.veryl",
19-
r"68_std.veryl",
19+
r"68_std_1.veryl",
20+
r"68_std_2.veryl",
2021
r"84_package_self_ref_1.veryl",
2122
r"84_package_self_ref_2.veryl",
2223
];

crates/tests/src/lib.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
const DEPENDENCY_TESTS: [&str; 2] = ["25_dependency_1", "25_dependency_2"];
33

44
#[cfg(test)]
5-
const STD_TESTS: [&str; 1] = ["68_std"];
5+
const STD_TESTS: [&str; 2] = ["68_std_1", "68_std_2"];
66

77
#[cfg(test)]
88
const PACKAGE_SELF_REF_TESTS: [&str; 2] = ["84_package_self_ref_1", "84_package_self_ref_2"];
@@ -28,6 +28,21 @@ mod parser {
2828
include!(concat!(env!("OUT_DIR"), "/test.rs"));
2929
}
3030

31+
#[cfg(test)]
32+
fn skip_test(name: &str) -> bool {
33+
(crate::DEPENDENCY_TESTS.contains(&name) && crate::DEPENDENCY_TESTS[0] != name)
34+
|| (crate::STD_TESTS.contains(&name) && crate::STD_TESTS[0] != name)
35+
|| (crate::PACKAGE_SELF_REF_TESTS.contains(&name)
36+
&& crate::PACKAGE_SELF_REF_TESTS[0] == name)
37+
}
38+
39+
#[cfg(test)]
40+
fn needs_sub_project(name: &str) -> bool {
41+
crate::DEPENDENCY_TESTS.contains(&name)
42+
|| crate::STD_TESTS.contains(&name)
43+
|| crate::PACKAGE_SELF_REF_TESTS.contains(&name)
44+
}
45+
3146
#[cfg(test)]
3247
mod analyzer {
3348
use std::fs;
@@ -36,17 +51,11 @@ mod analyzer {
3651
use veryl_parser::Parser;
3752

3853
fn test(name: &str) {
39-
if (crate::DEPENDENCY_TESTS.contains(&name) && crate::DEPENDENCY_TESTS[0] != name)
40-
|| (crate::PACKAGE_SELF_REF_TESTS.contains(&name)
41-
&& crate::PACKAGE_SELF_REF_TESTS[0] == name)
42-
{
54+
if crate::skip_test(name) {
4355
return;
4456
}
4557

46-
let needs_sub_project = crate::DEPENDENCY_TESTS.contains(&name)
47-
|| crate::STD_TESTS.contains(&name)
48-
|| crate::PACKAGE_SELF_REF_TESTS.contains(&name);
49-
let _lock = if needs_sub_project {
58+
let _lock = if crate::needs_sub_project(name) {
5059
Some(crate::DEPENDENCY_LOCK.lock())
5160
} else {
5261
None
@@ -55,7 +64,7 @@ mod analyzer {
5564
let metadata_path = Metadata::search_from_current().unwrap();
5665
let mut metadata = Metadata::load(&metadata_path).unwrap();
5766

58-
if needs_sub_project {
67+
if crate::needs_sub_project(name) {
5968
let paths = metadata.paths::<&str>(&[], false, true).unwrap();
6069
let dependency_path = metadata.project_dependencies_path();
6170
for path in paths {
@@ -70,6 +79,8 @@ mod analyzer {
7079

7180
let files = if crate::DEPENDENCY_TESTS.contains(&name) {
7281
crate::DEPENDENCY_TESTS.to_vec()
82+
} else if crate::STD_TESTS.contains(&name) {
83+
crate::STD_TESTS.to_vec()
7384
} else if crate::PACKAGE_SELF_REF_TESTS.contains(&name) {
7485
crate::PACKAGE_SELF_REF_TESTS.to_vec()
7586
} else {
@@ -215,17 +226,11 @@ mod emitter {
215226
use veryl_parser::Parser;
216227

217228
fn test(name: &str) {
218-
if (crate::DEPENDENCY_TESTS.contains(&name) && crate::DEPENDENCY_TESTS[0] != name)
219-
|| (crate::PACKAGE_SELF_REF_TESTS.contains(&name)
220-
&& crate::PACKAGE_SELF_REF_TESTS[0] == name)
221-
{
229+
if crate::skip_test(name) {
222230
return;
223231
}
224232

225-
let needs_sub_project = crate::DEPENDENCY_TESTS.contains(&name)
226-
|| crate::STD_TESTS.contains(&name)
227-
|| crate::PACKAGE_SELF_REF_TESTS.contains(&name);
228-
let _lock = if needs_sub_project {
233+
let _lock = if crate::needs_sub_project(name) {
229234
Some(crate::DEPENDENCY_LOCK.lock())
230235
} else {
231236
None
@@ -234,7 +239,7 @@ mod emitter {
234239
let metadata_path = Metadata::search_from_current().unwrap();
235240
let mut metadata = Metadata::load(&metadata_path).unwrap();
236241

237-
if needs_sub_project {
242+
if crate::needs_sub_project(name) {
238243
let paths = metadata.paths::<&str>(&[], false, true).unwrap();
239244
let dependency_path = metadata.project_dependencies_path();
240245
for path in paths {
@@ -249,6 +254,8 @@ mod emitter {
249254

250255
let names = if crate::DEPENDENCY_TESTS.contains(&name) {
251256
crate::DEPENDENCY_TESTS.to_vec()
257+
} else if crate::STD_TESTS.contains(&name) {
258+
crate::STD_TESTS.to_vec()
252259
} else if crate::PACKAGE_SELF_REF_TESTS.contains(&name) {
253260
crate::PACKAGE_SELF_REF_TESTS.to_vec()
254261
} else {

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.

0 commit comments

Comments
 (0)