Skip to content

Commit d3f5185

Browse files
committed
Do not stop analyzing ambiguous names
1 parent 6c2281c commit d3f5185

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

vhdl_lang/src/analysis/names.rs

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
//
55
// Copyright (c) 2022, Olof Kraigher [email protected]
66

7+
use fnv::FnvHashSet;
8+
79
use super::analyze::*;
810
use super::expression::ExpressionType;
911
use super::named_entity::*;
@@ -855,9 +857,18 @@ impl<'a> AnalyzeContext<'a> {
855857

856858
if let Some(disambiguated) = disambiguated {
857859
match disambiguated {
858-
Disambiguated::Ambiguous(_) => {
860+
Disambiguated::Ambiguous(ents) => {
859861
// @TODO ambiguous error
860-
return Err(EvalError::Unknown);
862+
if let Some(types) = ambiguous_functions_to_types(ents) {
863+
resolved =
864+
ResolvedName::Expression(DisambiguatedType::Ambiguous(types));
865+
} else {
866+
diagnostics.error(
867+
&prefix.pos,
868+
"Procedure calls are not valid in names and expressions",
869+
);
870+
return Err(EvalError::Unknown);
871+
}
861872
}
862873
Disambiguated::Unambiguous(ent) => {
863874
if let Some(typ) = ent.return_type() {
@@ -996,9 +1007,18 @@ impl<'a> AnalyzeContext<'a> {
9961007
overloaded.entities().collect(),
9971008
diagnostics,
9981009
))? {
999-
Some(Disambiguated::Ambiguous(_)) => {
1010+
Some(Disambiguated::Ambiguous(ents)) => {
10001011
// @TODO ambiguous error
1001-
return Err(EvalError::Unknown);
1012+
if let Some(types) = ambiguous_functions_to_types(ents) {
1013+
resolved =
1014+
ResolvedName::Expression(DisambiguatedType::Ambiguous(types));
1015+
} else {
1016+
diagnostics.error(
1017+
&prefix.pos,
1018+
"Procedure calls are not valid in names and expressions",
1019+
);
1020+
return Err(EvalError::Unknown);
1021+
}
10021022
}
10031023
Some(Disambiguated::Unambiguous(ent)) => {
10041024
prefix.set_unique_reference(&ent);
@@ -1652,6 +1672,20 @@ fn check_single_argument<'a>(
16521672
}
16531673
}
16541674

1675+
fn ambiguous_functions_to_types(overloaded: Vec<OverloadedEnt>) -> Option<FnvHashSet<BaseType>> {
1676+
let types: FnvHashSet<_> = overloaded
1677+
.iter()
1678+
.filter_map(|ent| ent.return_type())
1679+
.map(|typ| typ.base())
1680+
.collect();
1681+
1682+
if !types.is_empty() {
1683+
Some(types)
1684+
} else {
1685+
None
1686+
}
1687+
}
1688+
16551689
#[cfg(test)]
16561690
mod test {
16571691
use super::*;
@@ -2714,4 +2748,24 @@ type enum_t is (alpha, beta);
27142748
)))
27152749
);
27162750
}
2751+
2752+
#[test]
2753+
fn ambiguous_function() {
2754+
let test = TestSetup::new();
2755+
test.declarative_part(
2756+
"
2757+
function myfun(arg: integer) return integer;
2758+
function myfun(arg: integer) return real;
2759+
",
2760+
);
2761+
let code = test.snippet("myfun(0)");
2762+
assert_eq!(
2763+
test.name_resolve(&code, None, &mut NoDiagnostics),
2764+
Ok(ResolvedName::Expression(DisambiguatedType::Ambiguous(
2765+
vec![test.ctx().real().base(), test.ctx().integer().base()]
2766+
.into_iter()
2767+
.collect()
2768+
)))
2769+
);
2770+
}
27172771
}

0 commit comments

Comments
 (0)