import type { Environment, Frame } from "../env";
import type { Expr } from "../expr";
import type { FunctionValue } from "../function-value";
import type { Value } from "../value";
import { TypeTag } from "./tags";
export type TypeId = string;
export type ExternLanguage = "yo" | "c";
export interface Type {
    tag: TypeTag;
    id: TypeId;
    typeName?: string;
    isExtern?: ExternLanguage;
    externName?: string;
    cInclude?: string;
    trait?: TraitType;
    definedInModulePath?: string;
    ioBuiltin?: "io_async" | "io_await" | "io_state" | "io_spawn" | "join_handle_await";
}
export interface ExprType extends Type {
    tag: TypeTag.Expr;
    id: TypeTag.Expr;
    trait: TraitType;
}
export interface ComptimeListType extends Type {
    tag: TypeTag.ComptimeList;
    childType: Type;
    trait: TraitType;
}
export interface TypeHierarchyType extends Type {
    tag: TypeTag.Type;
    level: number;
    baseType?: Type;
    trait: TraitType;
}
export interface SomeType extends Type {
    tag: TypeTag.SomeType;
    name: string;
    definitionFrameLevel?: number;
    parentType: TypeHierarchyType;
    size: undefined;
    functionApplication?: Expr;
    resolvedConcreteType?: Type;
    requiredTraits: {
        traitType: TraitType;
        frameLevel: number;
    }[];
    negativeTraits: {
        traitType: TraitType;
        frameLevel: number;
    }[];
    trait: TraitType;
    recursiveTypeRef?: {
        functionValue: FunctionValue;
        argValues: Value[];
    };
    kindFunctionType?: FunctionType;
}
export interface TypeApplicationType extends Type {
    tag: TypeTag.TypeApplication;
    constructor: SomeType;
    args: Type[];
    resultKind: Type;
    trait: TraitType;
}
export interface ArrayType extends Type {
    tag: TypeTag.Array;
    childType: Type;
    length: Value;
    trait: TraitType;
}
export interface StrType extends Type {
    tag: TypeTag.Str;
    trait: TraitType;
}
export interface VoidType extends Type {
    tag: TypeTag.Void;
    trait: TraitType;
}
export type FieldExprs = {
    expr: Expr;
    labelExpr?: Expr;
    typeExpr?: Expr;
    defaultValueExpr?: Expr;
    assignedValueExpr?: Expr;
};
export interface TypeField {
    type: Type;
    label: string;
    isCompileTimeOnly?: boolean;
    defaultValue?: Value;
    assignedValue?: Value;
    exprs: FieldExprs;
    isEffectParam?: boolean;
    sourceModulePath?: string;
    docComment?: string;
}
export interface TupleType extends Type {
    tag: TypeTag.Tuple;
    fields: TypeField[];
    trait: TraitType;
}
export type FunctionParameterExprs = {
    expr: Expr;
    labelExpr?: Expr;
    typeExpr: Expr;
    defaultValueExpr?: Expr;
    assignedValueExpr?: Expr;
};
export interface FunctionParameter {
    label: string;
    type: Type;
    isCompileTimeOnly: boolean;
    isQuote: boolean;
    isOwningTheRcValue: boolean;
    isRef?: boolean;
    exprs: FunctionParameterExprs;
    assignedValue?: Value;
}
export type FunctionForallParameter = FunctionParameter & {
    isCompileTimeOnly: true;
};
export interface StructType extends Type {
    tag: TypeTag.Struct;
    isReferenceSemantics: boolean;
    isAtomicRc?: boolean;
    isNewtype: boolean;
    isSourceNamespace?: true;
    functionValue?: FunctionValue;
    fields: TypeField[];
    trait: TraitType;
    env: Environment;
}
export interface TraitField extends TypeField {
    unassignedSomeType?: SomeType;
}
export type SourceNamespaceType = StructType & {
    isSourceNamespace: true;
};
export interface TraitType extends Type {
    tag: TypeTag.Trait;
    functionValue?: FunctionValue;
    fields: TraitField[];
    trait: undefined;
    env: Environment;
    receiverType?: Type;
    isNegatedConstraint?: boolean;
    selfConstraints?: TraitType[];
    negativeSelfConstraints?: TraitType[];
    isFn?: {
        callType: FunctionType;
    };
    isFuture?: {
        outputType: Type;
        effect?: FutureEffect;
    };
    isConcrete?: {
        concreteType: Type;
    };
    definedInModulePath?: string;
    associatedTypeConstraints?: {
        label: string;
        constraintType: Type;
    }[];
    deriveRule?: FunctionValue;
}
export type FnTraitType = TraitType & {
    isFn: {
        callType: FunctionType;
    };
};
export interface FutureEffect {
    label: string;
    type: Type;
}
export type FutureTraitType = TraitType & {
    isFuture: {
        outputType: Type;
        effect?: FutureEffect;
    };
};
export type ConcreteTraitType = TraitType & {
    isConcrete: {
        concreteType: Type;
    };
};
export interface EnumVariant {
    name: string;
    fields?: TypeField[];
    discriminant?: bigint;
    gadtReturnTypeArgs?: Type[];
}
export interface EnumType extends Type {
    tag: TypeTag.Enum;
    functionValue?: FunctionValue;
    variants: EnumVariant[];
    trait: TraitType;
    env: Environment;
    selectedVariantName?: string;
    requiredVariantNames?: string[];
    typeConstructorArgs?: Type[];
    isGadt?: boolean;
}
export interface UnionType extends Type {
    tag: TypeTag.Union;
    functionValue?: FunctionValue;
    fields: TypeField[];
    trait: TraitType;
    env: Environment;
}
export interface FunctionReturn {
    type: Type;
    typeExpr: Expr;
    isCompileTimeOnly: boolean;
    isUnquote: boolean;
    label: string;
    isRef?: boolean;
}
export interface FunctionType extends Type {
    tag: TypeTag.Function;
    parameters: FunctionParameter[];
    forallParameters: FunctionForallParameter[];
    variadicParameter?: FunctionParameter;
    whereClauseExprs?: Expr[];
    requiresExprs?: Expr[];
    ensuresExprs?: Expr[];
    return: FunctionReturn;
    env: Environment;
    parametersFrame: Frame;
    SelfType?: Type;
    SelfTraitType?: Type;
    trait: TraitType;
    isClosure?: boolean;
    isControl?: boolean;
}
export interface PtrType extends Type {
    tag: TypeTag.Ptr;
    childType: Type;
    trait: TraitType;
}
export interface IsoType extends Type {
    tag: TypeTag.Iso;
    childType: Type;
    trait: TraitType;
    env: Environment;
}
export interface DynType extends Type {
    tag: TypeTag.Dyn;
    requiredTraits: {
        traitType: TraitType;
        frameLevel: number;
    }[];
    negativeTraits: {
        traitType: TraitType;
        frameLevel: number;
    }[];
    trait: TraitType;
    env: Environment;
}
