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

Analyzer and CFE disagree on inferred Future.value type with nullable argument #3304

Closed
srawlins opened this issue Aug 23, 2023 · 7 comments
Closed
Labels
question Further information is requested

Comments

@srawlins
Copy link
Member

Take this code:

Object? f(int? x) { return Future.value(x)..foo; }

void main() {
  print(f(null));
}
  • Analyzer says: "The getter 'foo' isn't defined for the type 'Future<int>'."
  • CFE says: "Error: The getter 'foo' isn't defined for the class 'Future<int?>'."

Who is correct? It would be less breaking to change analyzer's behavior 😁

This is a blocker for implementing dart-lang/sdk#53253. As things stand, the analyzer would report a new Warning, claiming that a nullable value, x should not be passed to Future<int>.value, but there is actually no error thrown at runtime, so it should always be OK to pass this nullable value.

@srawlins
Copy link
Member Author

CC @dart-lang/language-team

@natebosch
Copy link
Member

natebosch commented Aug 24, 2023

Who is correct?

Both are - The getter isn't defined for either of those types 😉

I don't see a reason that it should be inferred as Future<int> though - the CFE error makes more sense to me.

Edit: I forgot about the nullable argument to Future.value so it's not clear to me that CFE is more correct.
Is this an example of #3269 ?

@srawlins
Copy link
Member Author

Is this an example of #3269 ?

I don't think this is tightly related, because downward inference gives no info in this case. However, as @eernstg says over there:

we could choose to say that X must be a subtype of T, or that X must be a subtype of T?.

This might be the same choice? I think it's essentially:

  • The Future.value constructor has a return type of Future<T>.
  • The context type is Object? (same issue if context type is Object).
  • It has a FutureOr<T>? parameter.
  • The argument for that parameter has type int?.

Luckily for me, I'm not looking for a language change. I'm just looking to figure out which implementation is not spec-compliant :D.

@lrhn
Copy link
Member

lrhn commented Aug 25, 2023

The "Who is right" should be answered by the inference specification. In particular which, if I read it correctly, means that the only introduced constraint is _ <: T <: int.
Then, when we solve that for T, the result becomes int.

So, analyzer is correct, as I read it.

@leafpetersen
Copy link
Member

I agree with @lrhn - the analyzer is correct here.

@eernstg
Copy link
Member

eernstg commented Aug 29, 2023

@natebosch wrote:

Is this an example of #3269 ?

#3269 refers to the same inference rule, here, and it would be applicable during downward inference as well as upward inference. It seems fair to say that the two issues are at least closely related.

@srawlins
Copy link
Member Author

Resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants