Skip to content

Linter needs to warn about single-item records #59311

Open
@lukehutch

Description

@lukehutch

For the following code:

abstract class X {
  Future<String?> getNameOrNull(
    String database,
    String table,
  );

  Future<String> getName(String database, String table) async {
    final name = (
      await getNameOrNull(
        database,
        table,
      ),                // (1)
    );
    if (name == null) {    // (2)
      throw Exception('Name is null');
    } else {
      return name;    // (3)
    }
  }
}

The line marked (2) has the warning The operand can't be null, so the condition is always 'false'.

The line marked (3) has the warning A value of type '(String?)' can't be returned from the method 'getName' because it has a return type of 'Future<String>'

The type of name is (String?), which looks deceptively like String?, but it is actually a single-item record, because of the stray comma on line (1)!

It took me a while to figure out what was going on here, because I assumed that the type (String?) was in fact the same as the type String?...

It is very easy to make this sort of mistake, because it is customary to put a trailing literally everywhere you can put one in Dart, especially in Flutter code, because then the formatter makes the structure of the code much clearer.

In my opinion, it shouldn't be possible to create single-item records. Actually, Dart wouldn't interpret (value) as a record. But apparently it does recognize (value,) as a record.

I think the best fix here would be to ignore the empty field at the end of a record definition that ends in a comma before the closing parenthesis, and proceed as if the comma weren't there. That would make (value,) act the same as (value). Although the downside of this is that before record syntax existed, (value,) would not have been valid syntax for a parenthesized expression...

Therefore, maybe the best thing to do here is simply give the user a warning if they try to declare a single-field record.

  • Dart version and tooling diagnostic info (dart info):
$ dart info

If providing this information as part of reporting a bug, please review the information
below to ensure it only contains things you're comfortable posting publicly.

#### General info

- Dart 3.1.2 (stable) (Tue Sep 12 16:26:23 2023 +0000) on "linux_x64"
- on linux / Linux 6.4.12-200.fc38.x86_64 dart-lang/sdk#1 SMP PREEMPT_DYNAMIC Wed Aug 23 17:46:49 UTC 2023
- locale is en_US.utf8

#### Project info

- sdk constraint: '>=3.0.0 <4.0.0'
- dependencies: process_run
- dev_dependencies: lints
- elided dependencies: 2

#### Process info

|  Memory |  CPU | Elapsed time | Command line                                                                               |
| ------: | ---: | -----------: | ------------------------------------------------------------------------------------------ |
|  447 MB | 0.0% |   1-05:03:59 | dart --enable-vm-service=0 --pause_isolates_on_start --disable-dart-dev -DSILENT_VM_SERVICE=true --write-service-info=file:<path>/vm.json --pause_isolates_on_exit --enable-asserts <path>/main.dart |
|  680 MB | 0.0% |   6-21:13:05 | dart ..<path>/serverpod_cli.dart generate --watch                                          |
|  661 MB | 0.0% |   1-05:11:35 | dart ..<path>/serverpod_cli.dart generate --watch                                          |
|   93 MB | 0.0% |   1-05:03:59 | dart debug_adapter                                                                         |
|   72 MB | 0.0% |  29-08:17:43 | dart devtools --machine --try-ports 10 --allow-embedding                                   |
|   77 MB | 0.0% |  29-08:17:24 | dart devtools --machine --try-ports 10 --allow-embedding                                   |
|   77 MB | 0.0% |  29-07:48:17 | dart devtools --machine --try-ports 10 --allow-embedding                                   |
|   77 MB | 0.0% |  28-04:43:12 | dart devtools --machine --try-ports 10 --allow-embedding                                   |
|   76 MB | 0.0% |   1-05:33:23 | dart devtools --machine --try-ports 10 --allow-embedding                                   |
|  907 MB | 0.0% |   4-23:04:24 | dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.72.2            |
| 1281 MB | 0.2% |   1-05:33:23 | dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.72.2            |
|  105 MB | 0.0% |   1-05:33:23 | flutter_tools.snapshot daemon                                                              |
  • Whether you are using Windows, macOS, or Linux (if applicable): Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2A bug or feature request we're likely to work onarea-devexpFor issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.devexp-linterIssues with the analyzer's support for the linter packagelinter-lint-requesttype-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions