Is Dart compiler able to infer the usage of const constructor?

375

Solution 1

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.

Solution 2

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.

Share:
375
Daniel Gomez Rico
Author by

Daniel Gomez Rico

Me

Updated on December 12, 2022

Comments

  • Daniel Gomez Rico
    Daniel Gomez Rico over 1 year

    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
    Daniel Gomez Rico about 3 years
    Why for a SizedBox it can infer that? if you see the Container does not have a const constructor but Retry does have it
  • Christopher Moore
    Christopher Moore about 3 years
    @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.
  • Daniel Gomez Rico
    Daniel Gomez Rico about 3 years
    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
  • Christopher Moore
    Christopher Moore about 3 years
    @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.
  • Daniel Gomez Rico
    Daniel Gomez Rico about 3 years
    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.
  • Christopher Moore
    Christopher Moore about 3 years
    @DanielGomezRico What are you trying to check exactly? I wouldn't know how to get an compilation intermediates.
  • Daniel Gomez Rico
    Daniel Gomez Rico about 3 years
    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.
  • Christopher Moore
    Christopher Moore about 3 years
    @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.
  • Daniel Gomez Rico
    Daniel Gomez Rico about 3 years
    I tried that but I can not see the const keyword in the IDE bubble
  • Christopher Moore
    Christopher Moore about 3 years
    @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.
  • Daniel Gomez Rico
    Daniel Gomez Rico about 3 years
    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
  • sérgio brito
    sérgio brito almost 2 years
    @ChristopherMoore, why can't const be inferred, if we get warnings from Lint to use it?
  • Christopher Moore
    Christopher Moore almost 2 years
    @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.