sdk
sdk copied to clipboard
Could error messages for incompatible function types be improved to show the conflicting parameters?
Hello!
While debugging some tests for a code-generator I'm working on, I faced the following error:
The redirected constructor '_FunctionParameter2 Function(int? Function(int?, {required int b, int c}), int? Function(int?, [int]), T? Function<T extends num>(T?), List<ImplementsAliasFirst> Function(ImplementsAliasFirst))' has incompatible parameters with 'FunctionParameter Function(int? Function(int?, {required int b, int c})?, int? Function(int?, [int]), T? Function<T extends num>(T?)?, List<ImplementsAliasFirst> Function(ImplementsAliasFirst)?)'.
Try redirecting to a different
Where the source is:
@freezed
class FunctionParameter with _$FunctionParameter {
// [...]
factory FunctionParameter.second(
int? simpleNamed(int? a, {required int b, int c})?,
int? simplePositional(int? a, [int b]),
T? generic<T extends num>(T? a)?,
List<ImplementsAliasFirst> generated(ImplementsAliasFirst a)?,
) = _FunctionParameter2;
}
...
class _FunctionParameter2 implements FunctionParameter {
_FunctionParameter2(
this.simpleNamed,
this.simplePositional,
this.generic,
this.generated,
);
final int? Function(int? a, {required int b, int c}) simpleNamed;
final int? Function(int? a, [int b]) simplePositional;
final T? Function<T extends num>(T? a) generic;
final List<ImplementsAliasFirst> Function(ImplementsAliasFirst a) generated;
}
Although the error is correct, it's not humanly readable (at least not without squinting eyes really hard 😛)
It'd be great if the error could be expanded a bit like when there's a pub get version conflict. When there's a version conflict, it creates a chain of problem/cause until it pinpoints one specific package.
The error could follow a similar logic to be:
The redirected constructor <...> has incompatible parameters with <...>.
-> The constructor FunctionParameter.second expects a parameter "simpleNamed" of type <...> but the redirected constructor expects the type <...>
-> The parameter simpleNamed of FunctionParameter.second is nullable, but _FunctionParameter2 defines simpleNamed as non-nullable
/* do the same with other conflicting parameters */
This would make it much easier to understand the error.
Another alternative is a possible "diff" between the types.
For example when there's a conflict between void Function(int?) and void Function(int), we could show:
I like the diff suggestion, but the diagnostics have to be displayable in contexts where we can't provide that kind of UI.
So what we should implement is the first suggestion: include a list of the places where the signatures differ. The diff algorithm should have some intelligence for degenerate cases. For example, if the signatures differ in almost every way, then it probably isn't worth trying to enumerate all of the differences. But if they differ in just one or two parameters, then calling out those places specifically would make sense.
Note: This probably applies equally to record types.