Skip to content

Commit

Permalink
Fix: views in generic packages no longer cause type mismatch (#334)
Browse files Browse the repository at this point in the history
  • Loading branch information
Schottkyc137 authored Aug 18, 2024
1 parent 14a4d27 commit 3b91037
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 251 deletions.
1 change: 1 addition & 0 deletions vhdl_lang/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mod types;

#[cfg(test)]
pub(crate) mod tests;

pub(crate) use root::{Library, LockedUnit};

pub use self::root::{DesignRoot, EntHierarchy};
88 changes: 41 additions & 47 deletions vhdl_lang/src/analysis/declarative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,11 +714,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
colon_token: _,
} = attr_spec;

let attr_ent = match scope.lookup(
self.ctx,
ident.item.token,
&Designator::Identifier(ident.item.name().clone()),
) {
let attr_ent = match scope.lookup(&Designator::Identifier(ident.item.name().clone())) {
Ok(NamedEntities::Single(ent)) => {
ident.set_unique_reference(ent);
if let Some(attr_ent) = AttributeEnt::from_any(ent) {
Expand Down Expand Up @@ -748,7 +744,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
return Ok(());
}
Err(err) => {
diagnostics.push(err);
diagnostics.push(err.into_diagnostic(self.ctx, ident.item.token));
return Ok(());
}
};
Expand All @@ -758,55 +754,53 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
signature,
}) = entity_name
{
let ent: EntRef<'_> =
match scope.lookup(self.ctx, designator.token, &designator.item.item) {
Ok(NamedEntities::Single(ent)) => {
designator.set_unique_reference(ent);
let ent: EntRef<'_> = match scope.lookup(&designator.item.item) {
Ok(NamedEntities::Single(ent)) => {
designator.set_unique_reference(ent);

if let Some(signature) = signature {
diagnostics.push(Diagnostic::should_not_have_signature(
"Attribute specification",
signature.pos(self.ctx),
));
}
ent
if let Some(signature) = signature {
diagnostics.push(Diagnostic::should_not_have_signature(
"Attribute specification",
signature.pos(self.ctx),
));
}
Ok(NamedEntities::Overloaded(overloaded)) => {
if let Some(signature) = signature {
match as_fatal(self.resolve_signature(scope, signature, diagnostics))? {
Some(signature_key) => {
if let Some(ent) =
overloaded.get(&SubprogramKey::Normal(signature_key))
{
designator.set_unique_reference(&ent);
ent.into()
} else {
diagnostics.push(Diagnostic::no_overloaded_with_signature(
designator.pos(self.ctx),
&designator.item.item,
&overloaded,
));
return Ok(());
}
}
None => {
ent
}
Ok(NamedEntities::Overloaded(overloaded)) => {
if let Some(signature) = signature {
match as_fatal(self.resolve_signature(scope, signature, diagnostics))? {
Some(signature_key) => {
if let Some(ent) =
overloaded.get(&SubprogramKey::Normal(signature_key))
{
designator.set_unique_reference(&ent);
ent.into()
} else {
diagnostics.push(Diagnostic::no_overloaded_with_signature(
designator.pos(self.ctx),
&designator.item.item,
&overloaded,
));
return Ok(());
}
}
} else if let Some(ent) = overloaded.as_unique() {
designator.set_unique_reference(ent);
ent
} else {
diagnostics
.push(Diagnostic::signature_required(designator.pos(self.ctx)));
return Ok(());
None => {
return Ok(());
}
}
}
Err(err) => {
diagnostics.push(err);
} else if let Some(ent) = overloaded.as_unique() {
designator.set_unique_reference(ent);
ent
} else {
diagnostics.push(Diagnostic::signature_required(designator.pos(self.ctx)));
return Ok(());
}
};
}
Err(err) => {
diagnostics.push(err.into_diagnostic(self.ctx, designator.token));
return Ok(());
}
};

// Attributes affect the underlying entity and cannot be set directly on aliases
let ent = ent.as_actual();
Expand Down
3 changes: 2 additions & 1 deletion vhdl_lang/src/analysis/design_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,8 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
}
Name::Designator(designator) => {
let visible = scope
.lookup(self.ctx, name.span, designator.designator())
.lookup(designator.designator())
.map_err(|err| err.into_diagnostic(self.ctx, name.span))
.into_eval_result(diagnostics)?;
designator.set_reference(&visible);
Ok(UsedNames::Single(visible))
Expand Down
43 changes: 21 additions & 22 deletions vhdl_lang/src/analysis/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
expr.pos(self.ctx),
"Ambiguous expression. You can use a qualified expression type'(expr) to disambiguate.",
ErrorCode::AmbiguousExpression,
);
);
Err(EvalError::Unknown)
}
}
Expand All @@ -254,7 +254,8 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
) -> EvalResult<Vec<OverloadedEnt<'a>>> {
let designator = Designator::OperatorSymbol(op);
match scope
.lookup(self.ctx, op_pos, &designator)
.lookup(&designator)
.map_err(|err| err.into_diagnostic(self.ctx, op_pos))
.into_eval_result(diagnostics)?
{
NamedEntities::Single(ent) => {
Expand Down Expand Up @@ -503,7 +504,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
Literal::String(_) => Ok(ExpressionType::String),
Literal::BitString(_) => Ok(ExpressionType::String),
Literal::Character(chr) => {
match scope.lookup(self.ctx, span, &Designator::Character(*chr)) {
match scope.lookup(&Designator::Character(*chr)) {
Ok(NamedEntities::Single(ent)) => {
// Should never happen but better know if it does
diagnostics.add(
Expand Down Expand Up @@ -543,7 +544,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
}
}
Err(e) => {
diagnostics.push(e);
diagnostics.push(e.into_diagnostic(self.ctx, span));
Err(EvalError::Unknown)
}
}
Expand Down Expand Up @@ -624,12 +625,10 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
self.expr_pos_with_ttyp(scope, target_type, expr.span, &mut expr.item, diagnostics)
}

fn implicit_bool_types(&self, scope: &Scope<'a>, span: TokenSpan) -> FnvHashSet<BaseType<'a>> {
if let Ok(NamedEntities::Overloaded(overloaded)) = scope.lookup(
self.ctx,
span,
&Designator::OperatorSymbol(Operator::QueQue),
) {
fn implicit_bool_types(&self, scope: &Scope<'a>) -> FnvHashSet<BaseType<'a>> {
if let Ok(NamedEntities::Overloaded(overloaded)) =
scope.lookup(&Designator::OperatorSymbol(Operator::QueQue))
{
overloaded
.entities()
.filter_map(|ent| ent.formals().nth(0).map(|typ| typ.type_mark().base()))
Expand All @@ -650,7 +649,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
match types {
ExpressionType::Unambiguous(typ) => {
if typ.base() != self.boolean().base() {
let implicit_bools = self.implicit_bool_types(scope, expr.span);
let implicit_bools = self.implicit_bool_types(scope);
if !implicit_bools.contains(&typ.base()) {
diagnostics.add(
expr.pos(self.ctx),
Expand All @@ -659,7 +658,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
typ.describe(),
self.boolean().describe()
),
ErrorCode::NoImplicitConversion
ErrorCode::NoImplicitConversion,
);
}
}
Expand All @@ -669,7 +668,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
self.expr_with_ttyp(scope, self.boolean(), expr, diagnostics)?;
} else {
let implicit_bool_types: FnvHashSet<_> = self
.implicit_bool_types(scope, expr.span)
.implicit_bool_types(scope)
.intersection(&types)
.cloned()
.collect();
Expand Down Expand Up @@ -1012,18 +1011,18 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
Diagnostic::new(
choice.pos(self.ctx),
format!(
"All elements of record '{}' are already associated",
record_type.designator()
),
"All elements of record '{}' are already associated",
record_type.designator()
),
ErrorCode::AlreadyAssociated,
)
.opt_related(
record_type.decl_pos(),
format!(
"Record '{}' defined here",
record_type.designator()
.opt_related(
record_type.decl_pos(),
format!(
"Record '{}' defined here",
record_type.designator()
),
),
),
)
}

Expand Down
9 changes: 4 additions & 5 deletions vhdl_lang/src/analysis/literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,10 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
scope: &Scope<'a>,
unit: &mut WithRef<Ident>,
) -> Result<TypeEnt<'a>, Diagnostic> {
match scope.lookup(
self.ctx,
unit.item.token,
&Designator::Identifier(unit.item.item.clone()),
)? {
match scope
.lookup(&Designator::Identifier(unit.item.item.clone()))
.map_err(|err| err.into_diagnostic(self.ctx, unit.item.token))?
{
NamedEntities::Single(unit_ent) => {
unit.set_unique_reference(unit_ent);
if let AnyEntKind::PhysicalLiteral(physical_ent) = unit_ent.actual_kind() {
Expand Down
5 changes: 3 additions & 2 deletions vhdl_lang/src/analysis/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ impl<'a> ResolvedName<'a> {
}
AnyEntKind::Overloaded(_) => {
return Err((
"Internal error. Unreachable as overloded is handled outside this function"
"Internal error. Unreachable as overloaded is handled outside this function"
.to_string(),
ErrorCode::Internal,
));
Expand Down Expand Up @@ -1213,7 +1213,8 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
let mut resolved = match SplitName::from_name(name) {
SplitName::Designator(designator) => {
let name = scope
.lookup(self.ctx, span, designator.designator())
.lookup(designator.designator())
.map_err(|err| err.into_diagnostic(self.ctx, span))
.into_eval_result(diagnostics)?;
return Ok(match name {
NamedEntities::Single(ent) => {
Expand Down
6 changes: 2 additions & 4 deletions vhdl_lang/src/analysis/overloaded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,10 +453,8 @@ mod tests {
panic!("Expected designator")
};

let overloaded = if let NamedEntities::Overloaded(overloaded) = self
.scope
.lookup(&self.tokens, fcall.span, &des.item)
.unwrap()
let overloaded = if let NamedEntities::Overloaded(overloaded) =
self.scope.lookup(&des.item).unwrap()
{
overloaded
} else {
Expand Down
Loading

0 comments on commit 3b91037

Please sign in to comment.