-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Labels
P3A lower priority bug or feature requestA lower priority bug or feature requestarea-devexpFor issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.devexp-linterIssues with the analyzer's support for the linter packageIssues with the analyzer's support for the linter package
Description
Hi everyone,
I am have encounter a problem about a common coding style which potential trigger runtime exception.
But I cannot really tell it is related to dart-core or linter issue.
My dart version is 3.5.1
I have read the 3.7.x lint rule and test case file for omit_obvious_local_variable_types and specify_nonobvious_local_variable_types.
Ref: #58773
Here is the code:
class Fruit
{
final String name;
const Fruit(String name) : this.name = name;
@override
String toString(){
return '(Fruit name: $name)';
}
}
List<Fruit> getFruitList(){
return <Fruit>[Fruit('pear'), Fruit('apple')];
}
List<Fruit>? getNullableFruitList(){
return <Fruit>[Fruit('pear'), Fruit('apple')];
}
Map<String, Fruit>? getNullableFruitMap(){
var map = <String, Fruit>{
'PEAR': Fruit('pear'),
'APPLE': Fruit('apple'),
};
return map;
}
void main(){
var fruitList = getFruitList();
var nullableFruitList = getNullableFruitList();
var nullableFruitMap = getNullableFruitMap();
//Case 1
for (var fruit in fruitList ?? []){ //$fruit inferenced as dynamic, even fruitList is not null
print(fruit.name);
print(fruit.non_exist_prop); //NO LINT, But Unhandled exception: NoSuchMethodError: Class 'Fruit' has no instance getter 'non_exist_prop'.
}
//Case 2
for (var fruit in nullableFruitList ?? <Fruit>[]){ //use implict typed list, $fruit inferenced as Fruit
print(fruit.name);
print(fruit.non_exist_prop); //LINT, undefined_getter
}
//Case 3
for (var fruit in nullableFruitList ?? []){ //$fruit is inferenced as dynamic
print(fruit.name);
print(fruit.non_exist_prop); //NO LINT, But Unhandled exception: NoSuchMethodError: Class 'Fruit' has no instance getter 'non_exist_prop'.
}
//Case 4
for (var fruit in nullableFruitList ?? []){ //$fruit is still inferenced as dynamic
print((fruit as Fruit).name);
}
//Case 5
for (Fruit fruit in nullableFruitList ?? []){
print(fruit.name);
print(fruit.non_exist_prop); //LINT, undefined_getter
}
//Case 6
var nonNullableFruitList = nullableFruitList ?? []; //$nonNullableFruitList is inferenced as List<Fruit>
for (var fruit in nonNullableFruitList){ //$fruit is inferenced as dynamic
print(fruit.name);
print(fruit.non_exist_prop); //LINT, undefined_getter
}
//Case 7
(nullableFruitList ?? []).forEach((f) {
print(f.name);
print(f.non_exist_prop); //LINT, undefined_getter
});
for (var mapEn in nullableFruitMap?.entries ?? {}){} //$mapEn is inferenced as Object? , because {} is Set<dynamic>
for (var mapEn in nullableFruitMap?.entries ?? []){} //$mapEn is inferenced as Object? , because {} is List<dynamic>
for (var mapEn in (nullableFruitMap ?? <String, Fruit>{}).entries){} //$mapEn is inferenced as MapEntry<String, Fruit>
}
Look at case 1, case 3 and case 6.
It seems that the for-loop declaration have its own type inference on null-coalesce logic.
Metadata
Metadata
Assignees
Labels
P3A lower priority bug or feature requestA lower priority bug or feature requestarea-devexpFor issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.devexp-linterIssues with the analyzer's support for the linter packageIssues with the analyzer's support for the linter package