Skip to content

Commit 0a2278f

Browse files
committed
Handle ambigous argument to 'val attribute
1 parent 77a2b54 commit 0a2278f

File tree

2 files changed

+34
-36
lines changed

2 files changed

+34
-36
lines changed

vhdl_lang/src/analysis/expression.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -638,40 +638,6 @@ impl<'a> AnalyzeContext<'a> {
638638
}
639639
}
640640

641-
/// An expression of any integer type
642-
pub fn integer_expr(
643-
&self,
644-
scope: &Scope<'a>,
645-
expr: &mut WithPos<Expression>,
646-
diagnostics: &mut dyn DiagnosticHandler,
647-
) -> FatalResult {
648-
if let Some(types) = as_fatal(self.expr_type(scope, expr, diagnostics))? {
649-
match types {
650-
ExpressionType::Unambiguous(typ) => {
651-
if !typ.base().is_any_integer() {
652-
diagnostics.error(
653-
&expr.pos,
654-
format!("Expected integer type, got {}", typ.describe()),
655-
)
656-
}
657-
}
658-
ExpressionType::Ambiguous(types) => {
659-
// @TODO does not check if type is ambiguous
660-
if types.iter().any(|typ| !typ.is_any_integer()) {
661-
diagnostics.error(&expr.pos, "Expected integer type")
662-
}
663-
}
664-
ExpressionType::String | ExpressionType::Null | ExpressionType::Aggregate => {
665-
diagnostics.error(
666-
&expr.pos,
667-
format!("Expected integer type, got {}", types.describe()),
668-
)
669-
}
670-
}
671-
}
672-
Ok(())
673-
}
674-
675641
/// An expression that is either boolean or implicitly boolean via ?? operator
676642
pub fn boolean_expr(
677643
&self,

vhdl_lang/src/analysis/names.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,12 @@ impl<'a> AnalyzeContext<'a> {
846846

847847
if typ.base().is_discrete() {
848848
if let Some(ref mut expr) = check_single_argument(name_pos, attr, diagnostics) {
849-
self.integer_expr(scope, expr, diagnostics)?;
849+
self.expr_with_ttyp(
850+
scope,
851+
self.universal_integer().into(),
852+
expr,
853+
diagnostics,
854+
)?;
850855
}
851856
Ok(AttrResolveResult::Value(typ.base()))
852857
} else {
@@ -2554,7 +2559,7 @@ constant c0 : arr_t := (others => 0);
25542559
diagnostics,
25552560
vec![Diagnostic::error(
25562561
code.s1("'a'"),
2557-
"Expected integer type, got type 'CHARACTER'",
2562+
"character literal does not match type universal_integer",
25582563
)],
25592564
);
25602565

@@ -2591,6 +2596,33 @@ constant c0 : arr_t := (others => 0);
25912596
);
25922597
}
25932598

2599+
/// This is a regression test
2600+
#[test]
2601+
fn val_attribute_with_overloaded_name() {
2602+
let test = TestSetup::new();
2603+
2604+
test.declarative_part(
2605+
"
2606+
impure function pop return integer is
2607+
begin
2608+
end function;
2609+
2610+
impure function pop return boolean is
2611+
begin
2612+
end function;
2613+
2614+
type enum_t is (alpha, beta);
2615+
",
2616+
);
2617+
let code = test.snippet("enum_t'val(pop)");
2618+
assert_eq!(
2619+
test.name_resolve(&code, None, &mut NoDiagnostics),
2620+
Ok(ResolvedName::Expression(DisambiguatedType::Unambiguous(
2621+
test.lookup_type("enum_t")
2622+
)))
2623+
);
2624+
}
2625+
25942626
#[test]
25952627
fn signal_attributes_on_non_signal() {
25962628
let test = TestSetup::new();

0 commit comments

Comments
 (0)