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

Field-less mixins allowed for const constructors #32223

Closed
eernstg opened this issue Feb 19, 2018 · 7 comments
Closed

Field-less mixins allowed for const constructors #32223

eernstg opened this issue Feb 19, 2018 · 7 comments
Assignees
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. customer-flutter

Comments

@eernstg
Copy link
Member

eernstg commented Feb 19, 2018

In response to the request in #9745, #28492, and more, and cf. the language specification update in 63c6851, constructor forwarding should now support the creation of constant forwarding constructors in the case where the applied mixin does not declare any instance variables.

@noinskit
Copy link

noinskit commented Jun 4, 2019

Ping? Why is this closed? This is still (AFAIK) the best way towards allowing classes with mixins to have const constructors.

@chloestefantsova
Copy link
Contributor

Thanks for the ping, @noinskit. I believe the issue is closed because the described functionality is implemented. For example, the following bash session demonstrates a Dart program using const constructors in a subclass of anonymous mixin application:

$ dart --version
Dart VM version: 2.3.0 (Fri May 3 10:32:31 2019 +0200) on "linux_x64"

$ cat /tmp/asdf.dart 
class A {
  void foo() {}
}

class B {
  const B();
}

class C extends B with A {
  const C();
}

main() {
  print(identical(const C(), const C()));
}

$ dart /tmp/asdf.dart
true

@scheglov
Copy link
Contributor

scheglov commented Jan 5, 2020

@eernstg I have issues with understanding the spec change, the wording seems inconsistent, and confusing. For constructors with all required positional parameters its says C does not declare any instance variables; for constructors with optional positional parameters it says MC does not declare any instance variables; for constructors with named parameters it says M does not declare any fields. What is MC? Is there really a distinction for where instance variables are declared (C vs. M) depending on which formal parameters the constructor has? Should the variant with named parameters say any instance variables?

image

@eernstg
Copy link
Member Author

eernstg commented Jan 6, 2020

You're right, this part of the specification needs to be clarified. I've created dart-lang/language#769 in order to track this work.

For now, I hope the following will be helpful: $MC$ should be $M$; fields should be instance variables; $C$ does not declare any instance variables should be $M$ does not declare any instance variables.

At first sight it might seem unimportant whether we say $C$ or $M$: $C$ contains the declarations denoted by members, and so does $M$, as specified, and the answer is certainly the same when we ask whether there are any instance variable declarations. But that description needs to be clarified as well: It will not work to perform a textual copy of declarations from the library of $M$ to $L_C$ (where $C$ is located), because all accesses to private entities will be reinterpreted (to be an error, or to denote something else).

The intended semantics is that the code of members when added to $C$ must preserve the semantics that it has in the library of $M$: Declarations that are private to the library of $M$ must still be private to the library of $M$, and every name resolution result must be preserved (so _myPrivateTopLevelFunction(42) must still call that private function in the library of $M$).

@eernstg
Copy link
Member Author

eernstg commented Jan 6, 2020

@scheglov, I haven't reopened this issue: If the current behavior of the front end conflicts with the specification including the above sketch of a clarification I believe we might as well handle that in a new issue.

@EP-u-NW
Copy link

EP-u-NW commented Mar 9, 2020

Why does

class A{
  const A();
}

mixin B{

  static const int value=1; //Here is the problem

  void printStuff(){
    print('Hello from B!');
  }
}

class C extends A with B {
  const C();
}

result in

 Error: A constant constructor can't call a non-constant super constructor.
  const C();

If I remove the line with static const int value=1; it works. But why are constructors influenced by static variables? As I understand, only instance variables are a problem.

@eernstg
Copy link
Member Author

eernstg commented Mar 11, 2020

@EPNW, that seems to be a bug in the common front end (it doesn't occur with the analyzer). I've reported it as #40982, with a link to your comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. customer-flutter
Projects
None yet
Development

No branches or pull requests

5 participants