Is type conversion having a covariance error?

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.

Leave a Reply