diff --git a/src/Draco.Compiler/Internal/Binding/Binder_Type.cs b/src/Draco.Compiler/Internal/Binding/Binder_Type.cs index 20218daca..d36a62295 100644 --- a/src/Draco.Compiler/Internal/Binding/Binder_Type.cs +++ b/src/Draco.Compiler/Internal/Binding/Binder_Type.cs @@ -89,9 +89,7 @@ private Symbol BindGenericType(GenericTypeSyntax syntax, DiagnosticBag diagnosti { var instantiated = this.BindType(syntax.Instantiated, diagnostics); var args = syntax.Arguments.Values - .Select(arg => this.BindType(arg, diagnostics)) - // TODO: Why do we even need this cast? - .Cast() + .Select(arg => this.BindTypeToTypeSymbol(arg, diagnostics)) .ToImmutableArray(); if (instantiated.GenericParameters.Length != args.Length) diff --git a/src/Draco.Compiler/Internal/Binding/LocalBinder.cs b/src/Draco.Compiler/Internal/Binding/LocalBinder.cs index 9dfde811a..2435a7d4c 100644 --- a/src/Draco.Compiler/Internal/Binding/LocalBinder.cs +++ b/src/Draco.Compiler/Internal/Binding/LocalBinder.cs @@ -76,7 +76,11 @@ public ImmutableArray LocalDeclarations public override IEnumerable DeclaredSymbols => this.Declarations .Concat(this.LocalDeclarations.Select(d => d.Symbol)); - public override Symbol ContainingSymbol => base.ContainingSymbol ?? throw new InvalidOperationException(); + public override FunctionSymbol ContainingSymbol => base.ContainingSymbol switch + { + FunctionSymbol f => f, + _ => throw new InvalidOperationException(), + }; // IMPORTANT: The choice of flag field is important because of write order private bool NeedsBuild => Volatile.Read(ref this.relativePositions) is null; diff --git a/src/Draco.Compiler/Internal/Solver/ConstraintSolver_Utils.cs b/src/Draco.Compiler/Internal/Solver/ConstraintSolver_Utils.cs index a76c6df41..f0f4b3486 100644 --- a/src/Draco.Compiler/Internal/Solver/ConstraintSolver_Utils.cs +++ b/src/Draco.Compiler/Internal/Solver/ConstraintSolver_Utils.cs @@ -15,7 +15,8 @@ internal sealed partial class ConstraintSolver private FunctionTypeSymbol MakeMismatchedFunctionType(ImmutableArray args, TypeSymbol returnType) => new( args - .Select(a => new SynthetizedParameterSymbol(null, a.Type)) + // TODO: We are passing null here... + .Select(a => new SynthetizedParameterSymbol(null!, a.Type)) .Cast() .ToImmutableArray(), returnType); diff --git a/src/Draco.Compiler/Internal/Symbols/Generic/ParameterInstanceSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Generic/ParameterInstanceSymbol.cs index f1e425b33..a2742e461 100644 --- a/src/Draco.Compiler/Internal/Symbols/Generic/ParameterInstanceSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Generic/ParameterInstanceSymbol.cs @@ -12,12 +12,12 @@ internal sealed class ParameterInstanceSymbol : ParameterSymbol, IGenericInstanc public override bool IsVariadic => this.GenericDefinition.IsVariadic; public override string Name => this.GenericDefinition.Name; - public override Symbol? ContainingSymbol { get; } + public override FunctionSymbol ContainingSymbol { get; } public override ParameterSymbol GenericDefinition { get; } public GenericContext Context { get; } - public ParameterInstanceSymbol(Symbol? containingSymbol, ParameterSymbol genericDefinition, GenericContext context) + public ParameterInstanceSymbol(FunctionSymbol containingSymbol, ParameterSymbol genericDefinition, GenericContext context) { this.ContainingSymbol = containingSymbol; this.GenericDefinition = genericDefinition; diff --git a/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataParameterSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataParameterSymbol.cs index 75a5ada43..131f8569b 100644 --- a/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataParameterSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataParameterSymbol.cs @@ -12,7 +12,7 @@ internal sealed class MetadataParameterSymbol : ParameterSymbol, IMetadataSymbol public override string MetadataName => this.MetadataReader.GetString(this.parameterDefinition.Name); public override TypeSymbol Type { get; } - public override Symbol ContainingSymbol { get; } + public override FunctionSymbol ContainingSymbol { get; } // NOTE: thread-safety does not matter, same instance public MetadataAssemblySymbol Assembly => this.assembly ??= this.AncestorChain.OfType().First(); @@ -22,7 +22,7 @@ internal sealed class MetadataParameterSymbol : ParameterSymbol, IMetadataSymbol private readonly Parameter parameterDefinition; - public MetadataParameterSymbol(Symbol containingSymbol, Parameter parameterDefinition, TypeSymbol type) + public MetadataParameterSymbol(FunctionSymbol containingSymbol, Parameter parameterDefinition, TypeSymbol type) { this.ContainingSymbol = containingSymbol; this.Type = type; diff --git a/src/Draco.Compiler/Internal/Symbols/ParameterSymbol.cs b/src/Draco.Compiler/Internal/Symbols/ParameterSymbol.cs index 0b639a5ca..06ce1dfd2 100644 --- a/src/Draco.Compiler/Internal/Symbols/ParameterSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/ParameterSymbol.cs @@ -9,6 +9,8 @@ namespace Draco.Compiler.Internal.Symbols; /// internal abstract partial class ParameterSymbol : LocalSymbol { + public override abstract FunctionSymbol ContainingSymbol { get; } + /// /// True, if this a variadic parameter. /// @@ -22,7 +24,7 @@ internal abstract partial class ParameterSymbol : LocalSymbol public override ParameterSymbol GenericInstantiate(Symbol? containingSymbol, ImmutableArray arguments) => (ParameterSymbol)base.GenericInstantiate(containingSymbol, arguments); public override ParameterSymbol GenericInstantiate(Symbol? containingSymbol, GenericContext context) => - new ParameterInstanceSymbol(containingSymbol, this, context); + new ParameterInstanceSymbol((FunctionSymbol)containingSymbol!, this, context); public override IParameterSymbol ToApiSymbol() => new Api.Semantics.ParameterSymbol(this); diff --git a/src/Draco.Compiler/Internal/Symbols/Source/SourceParameterSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Source/SourceParameterSymbol.cs index a4cabdd0f..55568979d 100644 --- a/src/Draco.Compiler/Internal/Symbols/Source/SourceParameterSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Source/SourceParameterSymbol.cs @@ -12,7 +12,7 @@ internal sealed class SourceParameterSymbol : ParameterSymbol, ISourceSymbol public override TypeSymbol Type => this.BindTypeIfNeeded(this.DeclaringCompilation!); private TypeSymbol? type; - public override Symbol ContainingSymbol { get; } + public override FunctionSymbol ContainingSymbol { get; } public override bool IsVariadic => this.DeclaringSyntax.Variadic is not null; public override string Name => this.DeclaringSyntax.Name.Text; @@ -20,7 +20,7 @@ internal sealed class SourceParameterSymbol : ParameterSymbol, ISourceSymbol // TODO: Extracting parameter docs involves looking into the function docs and searching in the MD - public SourceParameterSymbol(Symbol containingSymbol, ParameterSyntax syntax) + public SourceParameterSymbol(FunctionSymbol containingSymbol, ParameterSyntax syntax) { this.ContainingSymbol = containingSymbol; this.DeclaringSyntax = syntax; diff --git a/src/Draco.Compiler/Internal/Symbols/Synthetized/ArrayConstructorSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Synthetized/ArrayConstructorSymbol.cs index 35e2b1cfd..c5c901a18 100644 --- a/src/Draco.Compiler/Internal/Symbols/Synthetized/ArrayConstructorSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Synthetized/ArrayConstructorSymbol.cs @@ -1,7 +1,7 @@ using System.Collections.Immutable; using System.Linq; using Draco.Compiler.Internal.BoundTree; -using static Draco.Compiler.Internal.BoundTree.BoundTreeFactory; +using static Draco.Compiler.Internal.OptimizingIr.InstructionFactory; namespace Draco.Compiler.Internal.Symbols.Synthetized; @@ -38,9 +38,11 @@ internal sealed class ArrayConstructorSymbol : FunctionSymbol InterlockedUtils.InitializeNull(ref this.elementType, this.BuildElementType); private TypeParameterSymbol? elementType; - public override BoundStatement Body => - InterlockedUtils.InitializeNull(ref this.body, this.BuildBody); - private BoundStatement? body; + public override CodegenDelegate Codegen => (codegen, target, operands) => + { + var elementType = target.Type.Substitution.GenericArguments[0]; + codegen.Write(NewArray(target, elementType, operands)); + }; private readonly ArrayTypeSymbol genericArrayType; @@ -61,13 +63,4 @@ public ArrayConstructorSymbol(ArrayTypeSymbol genericArrayType) private TypeSymbol BuildReturnType() => this.genericArrayType.GenericInstantiate(this.ElementType); private TypeParameterSymbol BuildElementType() => new SynthetizedTypeParameterSymbol(this, "T"); - - private BoundStatement BuildBody() => ExpressionStatement(ReturnExpression( - value: ArrayCreationExpression( - elementType: this.ElementType, - sizes: this.Parameters - .Select(ParameterExpression) - .Cast() - .ToImmutableArray(), - type: this.ReturnType))); } diff --git a/src/Draco.Compiler/Internal/Symbols/Synthetized/ConstructorFunctionSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Synthetized/ConstructorFunctionSymbol.cs index 6de40356a..8a0d39262 100644 --- a/src/Draco.Compiler/Internal/Symbols/Synthetized/ConstructorFunctionSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Synthetized/ConstructorFunctionSymbol.cs @@ -12,6 +12,7 @@ internal sealed class ConstructorFunctionSymbol : FunctionSymbol { public override string Name => this.InstantiatedType.Name; public override bool IsSpecialName => true; + public override Api.Semantics.Visibility Visibility => this.ctorDefinition.Visibility; public override ImmutableArray GenericParameters => InterlockedUtils.InitializeDefault(ref this.genericParameters, this.BuildGenericParameters); diff --git a/src/Draco.Compiler/Internal/Symbols/Synthetized/IntrinsicFunctionSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Synthetized/IntrinsicFunctionSymbol.cs index ac16ebcdb..8d2a4e117 100644 --- a/src/Draco.Compiler/Internal/Symbols/Synthetized/IntrinsicFunctionSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Synthetized/IntrinsicFunctionSymbol.cs @@ -13,6 +13,7 @@ internal sealed class IntrinsicFunctionSymbol : FunctionSymbol public override TypeSymbol ReturnType { get; } public override bool IsSpecialName => true; + public override Api.Semantics.Visibility Visibility => Api.Semantics.Visibility.Private; public override string Name { get; } diff --git a/src/Draco.Compiler/Internal/Symbols/Synthetized/SynthetizedParameterSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Synthetized/SynthetizedParameterSymbol.cs index 92daa88ce..b13cb5c98 100644 --- a/src/Draco.Compiler/Internal/Symbols/Synthetized/SynthetizedParameterSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Synthetized/SynthetizedParameterSymbol.cs @@ -8,16 +8,16 @@ internal sealed class SynthetizedParameterSymbol : ParameterSymbol public override string Name { get; } public override TypeSymbol Type { get; } - public override Symbol? ContainingSymbol { get; } + public override FunctionSymbol ContainingSymbol { get; } - public SynthetizedParameterSymbol(Symbol? containingSymbol, string name, TypeSymbol type) + public SynthetizedParameterSymbol(FunctionSymbol containingSymbol, string name, TypeSymbol type) { this.ContainingSymbol = containingSymbol; this.Name = name; this.Type = type; } - public SynthetizedParameterSymbol(Symbol? containingSymbol, TypeSymbol type) + public SynthetizedParameterSymbol(FunctionSymbol containingSymbol, TypeSymbol type) : this(containingSymbol, string.Empty, type) { } diff --git a/src/Draco.Compiler/Internal/Symbols/TypeSymbol.cs b/src/Draco.Compiler/Internal/Symbols/TypeSymbol.cs index f550786f7..3ee1570f9 100644 --- a/src/Draco.Compiler/Internal/Symbols/TypeSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/TypeSymbol.cs @@ -102,7 +102,7 @@ public IEnumerable BaseTypes public override bool CanBeShadowedBy(Symbol other) { - if (other is not TypeSymbol type) return false; + if (other is not TypeSymbol) return false; if (this.Name != other.Name) return false; return this.GenericParameters.Length == other.GenericParameters.Length; }