I’m learning how to build a compiler through a YouTube video, and there’s a part where there’s a type conversion error, in the locals.Add(parameter, value);
section there’s this error from Visual Studio for Mac, saying that the variable parameter
with the type ParameterSymbol
can’t be converted to VariableSymbol
.
Argument 1: cannot convert from 'Compiler.SupportedExpressions.Symbols.ParameterSymbol' to 'Compiler.VariableSymbol'
Dictionary<VariableSymbol, object> locals = new Dictionary<VariableSymbol, object>();
for (int i = 0; i < node.Arguments.Length; i++)
{
ParameterSymbol? parameter = node.Function.Parameters[i];
object value = EvaluateExpression(node.Arguments[i]);
locals.Add(parameter, value);
}
The variable node
refers to the class below
internal sealed class BoundCallExpression : BoundExpression
{
public BoundCallExpression(FunctionSymbol function, ImmutableArray<BoundExpression> arguments)
{
Function = function;
Arguments = arguments;
}
public override BoundNodeKind Kind => BoundNodeKind.CallExpression;
public override TypeSymbol Type => Function.Type;
public FunctionSymbol Function { get; }
public ImmutableArray<BoundExpression> Arguments { get; }
}
I can’t understand the reason for the conversion error, given that one class is inheriting another, could this be a covariance problem? Below are the classes from top to bottom on the hierarchy scale, this happens with other types, but I believe that by solving this case, I can solve the other cases by myself.
I made a clone of the original project and this error doesn’t occur. The instructor uses .NET 3.1 and I’m using .NET 7, could it be something?
public sealed class ParameterSymbol : LocalVariableSymbol
{
public ParameterSymbol(string name, TypeSymbol type)
: base(name, isReadOnly: true, type)
{
}
public override SymbolKind Kind => SymbolKind.Parameter;
}
public class LocalVariableSymbol : VariableSymbol
{
internal LocalVariableSymbol(string name, bool isReadOnly, TypeSymbol type)
: base(name, isReadOnly, type)
{
}
public override SymbolKind Kind => SymbolKind.LocalVariable;
}
public abstract class VariableSymbol : Symbol
{
internal VariableSymbol(string name, bool isReadOnly, TypeSymbol type)
: base(name)
{
IsReadOnly = isReadOnly;
Type = type;
}
public bool IsReadOnly { get; }
public TypeSymbol Type { get; }
}
public abstract class Symbol
{
private protected Symbol(string name)
{
Name = name;
}
public abstract SymbolKind Kind { get; }
public string Name { get; }
public override string ToString() => Name;
}
Link of github repository – https://github.com/vagnerwentz/cthulhu-compiler
What I tried
- Forced cast.
- Create more than one constructor with different types.
I tried forced cast and create more than one constructor and my expectation it is that we can resolve together the problem.
>Solution :
ParameterSymbol
inherits Compiler.SupportedExpressions.Symbols.VariableSymbol
, not Compiler.VariableSymbol
.
From the error message you are casting it to the non-related one.