Skip to content

Exhaustivity fails on Result<T, E> with Ok<T> and Err<E> where the other generic is Never #60260

Open
@TekExplorer

Description

@TekExplorer

Using the following sealed class

sealed class Result<T, E extends Object> {}

final class Ok<T> implements Result<T, Never> {
  const Ok(this.value);
  final T value;
}

final class Err<E extends Object> implements Result<Never, E> {
  Err(this.error, this.stackTrace);

  final E error;
  final StackTrace stackTrace;
}

See the following:

// this is ok, but we lose type information in the generics
check(Result<String, Exception> r) {
  return switch (r) {
    Ok<dynamic>() => throw UnimplementedError(),
    Err<Object>() => throw UnimplementedError(),
  };
}
// this SHOULD be ok, but the analyzer complains that we don't handle Ok<dynamic> and Err<Object>
check(Result<String, Exception> r) {
  return switch (r) {
    Ok<String>() => throw UnimplementedError(),
    Err<Exception>() => throw UnimplementedError(),
  };
}

I think there was an issue about this prior, but I can't seem to find it, so I'll make it here.

I noticed this issue as I was messing around with Result<T> and wanted to try specifying the specific error type

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-dart-modelFor issues related to conformance to the language spec in the parser, compilers or the CLI analyzer.model-exhaustivenessImplementation of exhaustiveness checking

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions