Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutation of const List should be compile time error #34551

Closed
Cat-sushi opened this issue Sep 23, 2018 · 5 comments
Closed

Mutation of const List should be compile time error #34551

Cat-sushi opened this issue Sep 23, 2018 · 5 comments
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. type-enhancement A request for a change that isn't a bug

Comments

@Cat-sushi
Copy link

const a = [1, 2, 3];
a[0] = 1;

The snippet above doesn't emit compile time error but runtime exception.

I'm not sure, but think this issue is related to #27755, #23327, #1869 and #236.
That said, In constant context, I also think it is much easier to fix along with Dart 2 compiler, because const object/ identifier is deeply const.

Dart VM version: 2.1.0-dev.5.0 (Unknown timestamp) on "linux_x64"

@lrhn
Copy link
Member

lrhn commented Sep 24, 2018

This is not a compile-time error because Dart doesn't track whether operations mutate an object.
The language doesn't know that a.removeFirst() will throw and a.first will not, that's a library choice, and the language specification is mostly indifferent to what libraries do (not entirely, though, and the operators of platform types are mentioned, so it wouldn't be completely unprecedented to know about List.[]=).

To figure out that this is an error, the analyzer would have to know that List.[]= is an operation which always throw on a const object. That's definitely possible - the list of mutating list and map operations is short enough, and the analyzer can already recognize whether an expression is constant.

It's not something we plan to build into the language in general. It's too specific - it would only work for constant lists and maps, and only when referenced directly as a const variable, and hard-coding specific members in the specification is just begging to get out-of-date - so I'm filing as an analyzer feature request.

@lrhn lrhn added area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. type-enhancement A request for a change that isn't a bug labels Sep 24, 2018
@Cat-sushi
Copy link
Author

I understand.
Thanks.

@Cat-sushi
Copy link
Author

By the way, setters are compile time errors.
Likewise, I think operator []= could be an error, exceptionally.

@lrhn
Copy link
Member

lrhn commented Sep 24, 2018

The difference is that assignment to a const variable is caught by there not being any setter. That is statically detectable.
Assignment to a const object's index-operator is handled by the object itself. It's possible to write a program where that is not an error, say:

class SetLog {
  const SetLog();
  void operator[]=(String key, String value) {
    print("LOG($key): $value");
  }
}
main() {
  const s = SetLog();
  s["line 1"] = "Error!";
}

This program compiles and runs, even though it "assigns" to the []= operator of a const object.

So, to reject a program, the language needs to know that a library function will always throw on a particular invocation, and the language specification doesn't know that much about the libraries.

@Cat-sushi
Copy link
Author

Cat-sushi commented Sep 24, 2018

Sorry, I misunderstood the behavior of setter.
I've just found that setters against const are also allowed.

class Hello {
  const Hello();
  set hello(String value) {
    print("Hello $value");
  }
}

main() {
  const h = Hello();
  h.hello = "world"; // => Hello world
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

2 participants