From 7f0b4097352f429c31526c31b281c78b7ba4d8c9 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 2 Aug 2026 11:54:31 +0100 Subject: Generate proper errors when arbitrary value cannot be found --- .../compiler/analysis/ArbitraryValueAnalysis.java | 15 ++++++++++++--- .../analysis/errors/SumTypeHasNoVariantsError.java | 18 ++++++++++++++++++ .../compiler/analysis/errors/TypeIsInfiniteError.java | 18 ++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/SumTypeHasNoVariantsError.java create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/TypeIsInfiniteError.java (limited to 'src/main') diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java index c1d7cc3..ecfdd76 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java @@ -1,5 +1,8 @@ package org.zwobble.hobgoblin.compiler.analysis; +import org.zwobble.hobgoblin.compiler.analysis.errors.SumTypeHasNoVariantsError; +import org.zwobble.hobgoblin.compiler.analysis.errors.TypeIsInfiniteError; +import org.zwobble.hobgoblin.compiler.sources.NullSource; import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo; import org.zwobble.hobgoblin.compiler.types.*; @@ -9,13 +12,19 @@ import java.util.Set; public class ArbitraryValueAnalysis { public static Type selectArbitraryVariant(SumType sumType, TypesInfo typesInfo) { + var sumVariants = typesInfo.sumVariants(sumType); + if (sumVariants.isEmpty()) { + // TODO: proper source + throw new SumTypeHasNoVariantsError(sumType, NullSource.INSTANCE); + } + var seenTypes = new HashSet(); seenTypes.add(sumType); - // TODO: better error - return typesInfo.sumVariants(sumType).stream() + return sumVariants.stream() .filter(variant -> isNonRecursivelyConstructable(variant.valueType(), seenTypes, typesInfo)) .findFirst() - .orElseThrow() + // TODO: proper source + .orElseThrow(() -> new TypeIsInfiniteError(sumType, NullSource.INSTANCE)) .containerType(); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/SumTypeHasNoVariantsError.java b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/SumTypeHasNoVariantsError.java new file mode 100644 index 0000000..7624767 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/SumTypeHasNoVariantsError.java @@ -0,0 +1,18 @@ +package org.zwobble.hobgoblin.compiler.analysis.errors; + +import org.zwobble.hobgoblin.compiler.errors.SourceError; +import org.zwobble.hobgoblin.compiler.sources.Source; +import org.zwobble.hobgoblin.compiler.types.SumType; + +public class SumTypeHasNoVariantsError extends SourceError { + private final SumType type; + + public SumTypeHasNoVariantsError(SumType type, Source source) { + super(type + " has no variants", source); + this.type = type; + } + + public SumType type() { + return type; + } +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/TypeIsInfiniteError.java b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/TypeIsInfiniteError.java new file mode 100644 index 0000000..87e96cc --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/errors/TypeIsInfiniteError.java @@ -0,0 +1,18 @@ +package org.zwobble.hobgoblin.compiler.analysis.errors; + +import org.zwobble.hobgoblin.compiler.errors.SourceError; +import org.zwobble.hobgoblin.compiler.sources.Source; +import org.zwobble.hobgoblin.compiler.types.Type; + +public class TypeIsInfiniteError extends SourceError { + private final Type type; + + public TypeIsInfiniteError(Type type, Source source) { + super(type.describe() + " is infinite", source); + this.type = type; + } + + public Type type() { + return type; + } +} -- cgit v1.2.3