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

Add Subtyping tests for function types with covariant-by-declaration parameters #2087

Closed
sgrekhov opened this issue Jun 15, 2023 · 4 comments
Assignees
Labels
type-enhancement A request for a change that isn't a bug

Comments

@sgrekhov
Copy link
Contributor

Add Subtyping tests for function types with covariant-by-declaration parameters

@sgrekhov sgrekhov added the type-enhancement A request for a change that isn't a bug label Jun 15, 2023
@sgrekhov sgrekhov self-assigned this Jun 15, 2023
@eernstg
Copy link
Member

eernstg commented Jun 16, 2023

Ah, I'm afraid I don't understand what that would be. A function type that contains covariant is always a compile-time error, we can only put the modifier covariant on parameter declarations in instance method or instance setter declarations, and on instance variable declarations that have a setter.

Tear-offs of those instance methods do have a function type, but it doesn't contain covariant. Similarly, member signatures of such instance methods and setters do have a function type which is used for override checks and combined member signature computations, but we strip off covariant in order to compute that function type (and possibly change some parameter types, e.g., for override checks).

Could you clarify this a bit?

@sgrekhov
Copy link
Contributor Author

Ah, we strip covariant when we tear-off a method. I didn't know that. But ok, then let's have the test that the following is an error

class A {
  void foo(num n) {
    print("A");
  }
}

class C implements A {
  void foo(covariant int n) {
    print("C");
  }
}

main() {
  C c = C();
  void Function(num n) f = c.foo; // Error. `covariant` doesn't allow us to override function type restrictions
}

@sgrekhov
Copy link
Contributor Author

When I was filling this issue I supposed an opposite test. That tear-off of void foo(covariant int n) {} can be used everywhere where we expected void foo(num n). But ok, let's check that we are not allowed to do this

@eernstg
Copy link
Member

eernstg commented Jun 16, 2023

let's have the test that the following is an error

Yes, that's a compile-time error because the member c.foo is considered to have the function type void Function(int) (so for the computation of the static type we ignore covariant). However, it is not a run-time error, because the actual run-time type of the tear-off will have the parameter type Object? (because that's always the case for a covariant parameter). So we can do this:

class A {
  void foo(num n) => print("A");
}

class C implements A {
  void foo(covariant int n) => print("C");
}

main() {
  A a = C();
  void Function(num n) f = a.foo; // OK at compile time; succeeds at run time, too.
  f(1.5); // But this throws.
}

The unusual bit here is that the static type of the tear-off is different from the dynamic type of the tear-off, even in the case where the static type of the receiver is exactly the run-time type of the receiver as well. The reason for this is that it is safer to assign the tear-off to a variable whose type won't cause the built-in argument type check to throw.

In other words, we can assign a.foo to a variable of type void Function(Object?) (using void Function(Object?) f = a.foo as dynamic;) because the given function object does actually have that type at run time, but unless we treat it as a void Function(int), it will throw when it is called.

In some cases we don't know the exact type of the receiver and in that case we can't see the potential dynamic error at compile time (as in a.foo where a has type A), but we're at least giving the developer a heads-up in the cases where it is possible to see the problem at compile time.

sgrekhov added a commit to sgrekhov/co19 that referenced this issue Jun 21, 2023
eernstg pushed a commit that referenced this issue Jul 12, 2023
Add tests for parameters covariant-by-declaration
sgrekhov added a commit to sgrekhov/co19 that referenced this issue Jul 13, 2023
copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue Jul 14, 2023
2023-07-14 sgrekhov22@gmail.com Fixes dart-lang/co19#2132. Fix roll failures, add issue numbers (dart-lang/co19#2134)
2023-07-13 sgrekhov22@gmail.com Fixes dart-lang/co19#2130. Fix roll failures, add issues numbers (dart-lang/co19#2131)
2023-07-13 sgrekhov22@gmail.com Fixes dart-lang/co19#2125. Add more external functions tests (dart-lang/co19#2128)
2023-07-13 sgrekhov22@gmail.com Fixes dart-lang/co19#2087. Reorder covariance tests to make maintenance easier (dart-lang/co19#2129)
2023-07-12 sgrekhov22@gmail.com dart-lang/co19#2087. Add tests for parameters covariant-by-declaration (dart-lang/co19#2121)
2023-07-12 sgrekhov22@gmail.com Fixes dart-lang/co19#2117. Update assertions, add tests for external members (dart-lang/co19#2126)
2023-07-12 sgrekhov22@gmail.com Fixes dart-lang/co19#2123. Update Superclasses tests. (dart-lang/co19#2124)
2023-07-11 sgrekhov22@gmail.com dart-lang/co19#2117. Update accessible_instance_member_t* tests (dart-lang/co19#2122)
2023-07-10 sgrekhov22@gmail.com Fixes dart-lang/co19#2099. Add subtyping tests for function type with required named arguments (dart-lang/co19#2100)
2023-07-10 sgrekhov22@gmail.com dart-lang/co19#2112. Add missing tests for mixins. Part 2 (dart-lang/co19#2118)
2023-07-07 sgrekhov22@gmail.com dart-lang/co19#2119. Minor wording changes (dart-lang/co19#2120)

Change-Id: I310f2e0a660ac55a242bb9b2ed9a2f1917555d0f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313562
Reviewed-by: Alexander Thomas <athom@google.com>
osa1 pushed a commit to osa1/sdk that referenced this issue Jul 17, 2023
2023-07-14 sgrekhov22@gmail.com Fixes dart-lang/co19#2132. Fix roll failures, add issue numbers (dart-lang/co19#2134)
2023-07-13 sgrekhov22@gmail.com Fixes dart-lang/co19#2130. Fix roll failures, add issues numbers (dart-lang/co19#2131)
2023-07-13 sgrekhov22@gmail.com Fixes dart-lang/co19#2125. Add more external functions tests (dart-lang/co19#2128)
2023-07-13 sgrekhov22@gmail.com Fixes dart-lang/co19#2087. Reorder covariance tests to make maintenance easier (dart-lang/co19#2129)
2023-07-12 sgrekhov22@gmail.com dart-lang/co19#2087. Add tests for parameters covariant-by-declaration (dart-lang/co19#2121)
2023-07-12 sgrekhov22@gmail.com Fixes dart-lang/co19#2117. Update assertions, add tests for external members (dart-lang/co19#2126)
2023-07-12 sgrekhov22@gmail.com Fixes dart-lang/co19#2123. Update Superclasses tests. (dart-lang/co19#2124)
2023-07-11 sgrekhov22@gmail.com dart-lang/co19#2117. Update accessible_instance_member_t* tests (dart-lang/co19#2122)
2023-07-10 sgrekhov22@gmail.com Fixes dart-lang/co19#2099. Add subtyping tests for function type with required named arguments (dart-lang/co19#2100)
2023-07-10 sgrekhov22@gmail.com dart-lang/co19#2112. Add missing tests for mixins. Part 2 (dart-lang/co19#2118)
2023-07-07 sgrekhov22@gmail.com dart-lang/co19#2119. Minor wording changes (dart-lang/co19#2120)

Change-Id: I310f2e0a660ac55a242bb9b2ed9a2f1917555d0f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313562
Reviewed-by: Alexander Thomas <athom@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

2 participants