Skip to content

Fix #4720 and #4721: account for type inference being too smart #4946

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

Conversation

Blaisorblade
Copy link
Contributor

@Blaisorblade Blaisorblade commented Aug 15, 2018

Fix #4720 and #4721: account for @smarter type inference. Some type arguments can be solved right away by looking at their bounds alone, so handle them gracefully.
#4720 was introduced by eeb5965, #4721 was earlier.

@Blaisorblade Blaisorblade self-assigned this Aug 15, 2018
@Blaisorblade Blaisorblade changed the title Fix 4720 4721 account for @smarter type inference Fix #4720 and #4721: account for type inference being too smart Aug 15, 2018
We're looping over indices and then indexing a *list*.
Fix regression in eeb5965. A type variable can
already be solved in addToConstraint, so don't assume it is unsolved (hence its
constraint entry is a TypeBounds) when first processing it.

Fix scala#4720.
@Blaisorblade Blaisorblade force-pushed the fix-4720-4721-account-for-smarter-type-inference branch from 5a081ae to d84922b Compare August 15, 2018 15:38
Be more defensive to handle other issues such as
scala#4720 (comment).

Code that needs to access the actual entry can call `entry` or `contains`
instead.
@@ -60,7 +60,7 @@ abstract class Constraint extends Showable {
* are not contained in the return bounds.
* @pre `param` is not part of the constraint domain.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment still correct?

Copy link
Contributor Author

@Blaisorblade Blaisorblade Aug 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't make sense of "@pre param is not part of the constraint domain." if that's a precondition. What's the "constraint domain"?

Otherwise, I suspect yes.

Poly params that are known to be smaller or greater than param are not contained in the return bounds.

IIUC, this suggests that in [Y<:String, Z>:Int, W>:Z<:Y], nonParamBounds(Y) and nonParamBounds(Z) don't include W. But nonParamBounds(W) should mention Z and Y, so it might never have been accurate.

EDIT: my patch doesn't affect it, and neither does yours; this comment means, concretely, that we only account for boundsMap but not lowerMap or upperMap. How information is partitioned between those map is another matter entirely (and might be affected by your patch).

@smarter
Copy link
Member

smarter commented Aug 16, 2018

72d7bc4

Not sure this is necessary, but it's not obvious that having another error
downstream is guaranteed, so giving one right away sounds safer.

This isn't great, if there really are cases where this message is the only one, it's likely to be very confusing to users.

@Blaisorblade
Copy link
Contributor Author

This isn't great, if there really are cases where this message is the only one, it's likely to be very confusing to users.

That's what I hoped to learn from you or @odersky. But I think that can't happen and I should drop the last commit. This is just inference, and we must check bounds also for type arguments written by users, or we have bigger issues, and hopefully that's checked by the same code. This is done by calling Checking.checkBounds in PostTyper, for both AppliedTypeTree and TypeApply.

So I'll drop last commit.

The resulting error is better, but it's designed for types written by the user, not synthesized by inference:

-- [E057] Type Mismatch Error: tests/neg/i4721a.scala:2:39 ---------------------
2 |  def main(args: Array[String]):Unit = m("1") // error
  |                                       ^
  |                 Type argument Int does not conform to upper bound String

Otherwise, I can propagate more info out of addToConstraint, or into it, but that might be invasive. And I'd have to assume it's safe to pretty-print types in Typer.

Maybe I can just detect if the type argument tree was inferred? With tree.pos.isSynthetic on the type argument, or otherwise?

@smarter
Copy link
Member

smarter commented Aug 17, 2018

Maybe I can just detect if the type argument tree was inferred? With tree.pos.isSynthetic on the type argument, or otherwise?

A synthetic tree can contain a user written tree. Use pos.isZeroExtent instead

@Blaisorblade Blaisorblade force-pushed the fix-4720-4721-account-for-smarter-type-inference branch from 72d7bc4 to 69957bb Compare August 20, 2018 16:56
@Blaisorblade
Copy link
Contributor Author

@smarter neither isSynthetic nor isZeroExtent works just so — I pushed my current attempts to #4970. After asking Martin, I'd merge this PR to fix the crashes (which actual users did report!) and postpone improved reporting to a separate PR.

@Blaisorblade Blaisorblade merged commit 3d3ed97 into scala:master Aug 21, 2018
@Blaisorblade Blaisorblade deleted the fix-4720-4721-account-for-smarter-type-inference branch August 21, 2018 02:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants