Description
I've discovered that using pattern matching with sealed classes works perfectly in global functions and class methods, but attempting the exact same code in a nested function crashes the Dart analyzer completely with error code -32013.
Steps to Reproduce
A simple implementation of Option type.
For the None type we use Never
to avoid setting it.
So for reproduce the error is important to set a default type for the parent class.
I use Never
but T
can be any type.
class None extends Option<Never> {
const None();
}
If we use a implementation like this, it will work.
class None<T> extends Option<T> {
const None();
}
Code Example
sealed class Option<T> {
const Option();
}
class Some<T> extends Option<T> {
final T value;
const Some(this.value);
}
class None extends Option<Never> {
// T can be any type
const None();
/// Placeholder get, to use it in switch in this example
bool get noneProp => false;
}
/// Global const.
const none = None();
/// Works as expected
void fun<T>(Option<T> option) {
switch (option) {
case Some():
final _ = option.value;
case None():
final _ = option.noneProp;
}
}
/// Works as expected
class MyClass {
void fun<T>(Option<T> option) {
switch (option) {
case Some():
final _ = option.value;
case None():
final _ = option.noneProp;
}
}
}
void globalFunWithNestedFun() {
// **************************
// Uncomment to crash the analyzer.
// This is the same as the function
// above but nested
// **************************
// void fun<T>(Option<T> option) {
// switch (option) {
// case Some():
// final _ = option.value;
// case None():
// final _ = option.noneProp;
// }
// }
// **************************
// After uncommenting the code above,
// you can write any bad syntax,
// and usually the editor will not show any error.
// **************************
}
Expected Behavior
Should work consistently regardless of where the function is defined.
Dart analyzer logs
When uncommenting the nested function, the analyzer immediately crashes. The log shows that uncommenting the function (by removing comment markers) causes the analyzer to fail:
// Log timestamp when the comment markers are removed
[9:56:31 AM] [Analyzer] [Info] ==> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"...","version":741},"contentChanges":[
{"range":{"start":{"line":56,"character":2},"end":{"line":56,"character":5}},"rangeLength":3,"text":""},
{"range":{"start":{"line":55,"character":2},"end":{"line":55,"character":5}},"rangeLength":3,"text":""},
// ...more removals of comment markers...
]},"clientRequestTime":1741272991134}
// Immediately after, the analyzer starts failing with error code -32013
[9:56:31 AM] [Analyzer] [Info] <== {"id":3039,"jsonrpc":"2.0","error":{"code":-32013,"data":"...","message":"Analysis failed for file"}}
The analyzer repeatedly fails with the same error for all subsequent operations:
- textDocument/inlayHint:
{"code":-32013,"data":"...","message":"Analysis failed for file"}
- textDocument/codeLens:
{"code":-32013,"data":"...","message":"Analysis failed for file"}
- textDocument/documentSymbol:
{"code":-32013,"data":"...","message":"Analysis failed for file"}
- textDocument/documentColor:
{"code":-32013,"data":"...","message":"Analysis failed for file"}
The editor becomes unusable until the nested function is removed or commented out again.
Environment
- Dart SDK version: 3.7.0
- Flutter version: 3.29.0
- Platform: macOS