3

I have in my mind that dart will use the const constructor if it is able to do it automatically, to explain the hypothesis lets assume that we have a widget that already have a const constructor like:

class Retry extends StatelessWidget {
  const Retry();
}

And then because dart "is able to infer the const ussage" both of the next codes will mean and be compiled into the same code:

1.

Container(
   child: Retry()
)
Container(
   child: const Retry()
)

Is this assumption that dart can infer that he must use the const constructor for a class that have that option declared? Or is not? How can I corroborate it?

Daniel Gomez Rico
  • 15,026
  • 20
  • 92
  • 162
  • The compiler in principle could, but it does not since automatically using `const` could lead to a change in behavior. Also see [Dart: Is there a disadvantage to using const constructor?](https://stackoverflow.com/q/57607745/). – jamesdlin Feb 15 '21 at 22:14

2 Answers2

5

No, Dart compiler does not infer const unless syntactic context requires constness e.g. if you write const [A()] that puts A() into the const context, which means const [A()] is the same as const [const A()], there are few other places where the same applies (e.g. metadata @A()).

In general Dart compiler can't infer const outside of places where language specification requires it to do so because it might potentially alter the semantics of the program. Consider:

class A {
  const A();
}

final Set<A> s = <A>{};
void foo(A a) {
  s.add(a);
}

void main() {
  foo(A());
  foo(A());
  print(s.length);
}

If compiler would just go around putting const on constructor invocations then this program would print 1, however it should print 2.

Vyacheslav Egorov
  • 10,302
  • 2
  • 43
  • 45
  • Thanks for the answer, but Since christoper added a lot of context to the answer in the comments I will mark that as the answer, but thanks – Daniel Gomez Rico Feb 17 '21 at 14:55
2

Dart cannot infer that you want that object to be const unless there is some context surrounding it that forces it to be const. This is not the case in the example you show. You must use the const keyword at some point if you want dart to make something const.

Example of inferred const:

const SizedBox(
  child: Retry(),
)

The const on the SizedBox forces Retry to be const. This and similar situations are the only places where const is implied.

Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
  • Why for a `SizedBox` it can infer that? if you see the Container does not have a `const constructor` but `Retry` does have it – Daniel Gomez Rico Feb 15 '21 at 21:08
  • @DanielGomezRico In order for the SizedBox to be const, all of its properties must also be const so it will use the const constructor of Retry. – Christopher Moore Feb 15 '21 at 21:09
  • I want the `Retry` to be threated as `const` but not the `Container`, I know that it does not have a `const` constructor, Im not sure if the question is not clear enought – Daniel Gomez Rico Feb 15 '21 at 21:11
  • 1
    @DanielGomezRico If you want `Retry` to be `const` you have to use the `const` keyword somewhere. So in your case you have to do `const Retry`. There's no getting around it. There are some linter rules/warnings you can enable to tell you where you could add const I think. – Christopher Moore Feb 15 '21 at 21:12
  • Thanks for that, I would like to know if there is some way that I can be sure about it, maybe checking intermediate compiled files? I came from android where we can see the compiled files and be sure what was generated after compilation. – Daniel Gomez Rico Feb 15 '21 at 21:23
  • @DanielGomezRico What are you trying to check exactly? I wouldn't know how to get an compilation intermediates. – Christopher Moore Feb 15 '21 at 21:34
  • I just wanted to verify if the compiler effectively inferred that or not, on Kotlin I can see the generated `.class` and see what the compiler inferred for example. – Daniel Gomez Rico Feb 15 '21 at 21:56
  • @DanielGomezRico Could you share the code where you believe it will be inferred? You have to explicitly use `const` somewhere in your code. Also, your IDE should show you any inferred keyword when you hover over the constructor. – Christopher Moore Feb 15 '21 at 21:58
  • I tried that but I can not see the const keyword in the IDE bubble – Daniel Gomez Rico Feb 16 '21 at 12:33
  • @DanielGomezRico Please share the code. Do you see `new` instead? If you have `const` anywhere above the thing you expect to be const, that thing will be const. If you explicitly typed it out, it will not be shown by the bubble. – Christopher Moore Feb 16 '21 at 13:53
  • @ChristopherMoore, why can't const be inferred, if we get warnings from Lint to use it? – sérgio brito Jun 09 '22 at 22:56
  • @sergio Because it might change the behavior of your code in some scenarios. The lint encourages the use of const but it forces you to think about the consequences of marking something as const. – Christopher Moore Jun 09 '22 at 23:11