Skip to content

Commit 5dc1a90

Browse files
committed
Throw a better error when type arguments can't be inferred
1 parent 0369ff8 commit 5dc1a90

2 files changed

Lines changed: 24 additions & 7 deletions

File tree

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompileErrors.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ public static CompileError cannotThrowHere() {
134134
return new CompileError(CompileExceptionCode.CANNOT_THROW_HERE, "Cannot throw here");
135135
}
136136

137+
public static CompileError cannotInferTypeArguments() {
138+
return new CompileError(CompileExceptionCode.TYPE_ARGUMENTS_NOT_INFERRABLE, "Cannot infer type arguments");
139+
}
140+
137141
public static CompileError cannotInferEmptyArray() {
138142
return new CompileError(CompileExceptionCode.UNTYPED_EMPTY_ARRAY, "Cannot infer type of empty array");
139143
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/MatchedCallArguments.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.openzen.zencode.shared.CodePosition;
44
import org.openzen.zencode.shared.CompileError;
5+
import org.openzen.zencode.shared.CompileException;
56
import org.openzen.zenscript.codemodel.FunctionHeader;
67
import org.openzen.zenscript.codemodel.GenericMapper;
78
import org.openzen.zenscript.codemodel.compilation.expression.WrappedCompilingExpression;
@@ -31,8 +32,15 @@ public static <T extends AnyMethod> MatchedCallArguments<T> match(
3132
TypeID[] typeArguments,
3233
CompilingExpression... arguments
3334
) {
34-
final Map<CastedExpression.Level, List<MatchedCallArguments<T>>> methodsGroupedByMatchLevel = overloads.stream()
35-
.map(method -> match(compiler, position, method, asType, typeArguments, arguments))
35+
List<MatchedCallArguments<T>> matchedCalls = new ArrayList<>();
36+
for (T method : overloads) {
37+
try {
38+
matchedCalls.add(match(compiler, position, method, asType, typeArguments, arguments));
39+
} catch (CompileException e) {
40+
return new MatchedCallArguments<>(e.error);
41+
}
42+
}
43+
final Map<CastedExpression.Level, List<MatchedCallArguments<T>>> methodsGroupedByMatchLevel = matchedCalls.stream()
3644
.collect(Collectors.groupingBy(matched -> matched.arguments.level, Collectors.toList()));
3745

3846
for (final CastedExpression.Level level : candidateLevelsInOrderOfPriority) {
@@ -132,7 +140,7 @@ private static <T extends AnyMethod> MatchedCallArguments<T> match(
132140
TypeID result,
133141
TypeID[] typeArguments,
134142
CompilingExpression... arguments
135-
) {
143+
) throws CompileException {
136144
TypeID[] expansionTypeArguments = method.asMethod().map(MethodInstance::getExpansionTypeArguments).orElse(TypeID.NONE);
137145

138146
if (!method.getHeader().accepts(arguments.length)) {
@@ -144,7 +152,7 @@ private static <T extends AnyMethod> MatchedCallArguments<T> match(
144152
}
145153

146154
// Type inference
147-
Optional<TypeID[]> inferred = inferTypeArguments(expansionTypeArguments, method, result, typeArguments, compiler.getAvailableExpansions(), arguments);
155+
Optional<TypeID[]> inferred = inferTypeArguments(position, expansionTypeArguments, method, result, typeArguments, compiler.getAvailableExpansions(), arguments);
148156
if (!inferred.isPresent()) {
149157
return new MatchedCallArguments<>(
150158
method,
@@ -323,27 +331,32 @@ private static <T extends AnyMethod> Optional<MatchedCallArguments<T>> matchVarA
323331

324332

325333
private static <T extends AnyMethod> Optional<TypeID[]> inferTypeArguments(
334+
CodePosition position,
326335
TypeID[] expansionTypeArguments,
327336
T method,
328337
TypeID result,
329338
TypeID[] typeArguments,
330339
List<ExpansionSymbol> expansions,
331340
CompilingExpression... arguments
332-
) {
341+
) throws CompileException {
333342
int providedTypeArguments = typeArguments == null ? 0 : typeArguments.length;
334343

335344
if (providedTypeArguments == method.getHeader().typeParameters.length) {
336345
return Optional.of(typeArguments != null ? typeArguments : TypeID.NONE);
337346
}
338347

339-
if(providedTypeArguments != 0 && providedTypeArguments != method.getHeader().typeParameters.length) {
348+
if (providedTypeArguments != 0 && providedTypeArguments != method.getHeader().typeParameters.length) {
340349
return Optional.empty();
341350
}
342351

343352
// attempt to infer type arguments from the return type
344353
final Map<TypeParameter, TypeID> typeArgumentMap = new HashMap<>();
345354
if (result != null) {
346-
typeArgumentMap.putAll(method.getHeader().getReturnType().inferTypeParameters(result, expansions));
355+
Map<TypeParameter, TypeID> m = method.getHeader().getReturnType().inferTypeParameters(result, expansions);
356+
if (m == null) {
357+
throw new CompileException(position, CompileErrors.cannotInferTypeArguments());
358+
}
359+
typeArgumentMap.putAll(m);
347360
}
348361

349362
// create a mapping with everything found so far

0 commit comments

Comments
 (0)