-
Notifications
You must be signed in to change notification settings - Fork 3.1k
spurious cyclic error in type selection #5762
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
|
Cool! I think this is way more sensible than my fix; the equivalence with Looks a lot nicer though; thanks! I'll close mine out for now. |
| if ((qualTp eq null) || qualTp.isError) setError(tree) | ||
| else if (name.isTypeName && qualTp.isVolatile) // TODO: use same error message for volatileType#T and volatilePath.T? | ||
| if (tree.isInstanceOf[SelectFromTypeTree]) TypeSelectionFromVolatileTypeError(tree, qual) | ||
| else UnstableTreeError(qual) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nested braceless style made me instinctively reach out for something to hold onto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really hated my braces as a teenager. I guess it still shows.
|
To clarify, is this fix going to break shapeless's current use of this mechanism? |
|
As I understand it, no... @adriaanm mentioned considering that we could stop considering |
|
Indeed. At the earliest we would consider this change for 2.13. I can see its utility, though -- not saying we definitely will plug the hole. (From a soundness/IDE perspective, I think we should, but tbd.) |
|
Rebased. |
|
Re-rebased. |
|
no idea why cla check is failing, others are green |
| // note: on error, we discard the work we did in type checking tree.qualifier into qual | ||
| // (tree is either Select or SelectFromTypeTree, and qual may be different from tree.qualifier because it has been type checked) | ||
| val qualTp = qual.tpe | ||
| if ((qualTp eq null) || qualTp.isError) setError(tree) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking qual.tpe.isError for selections from term trees appears to be new. I haven't figured out how that case was handled before. The new formulation (checking early and bailing out) appears sane, but I need to connect a few more dots to feel comfortable.
I haven't found any example where the compiler before/after this change differs in behaviour, so I'm probably just being paranoid. I focussed on error cases.
|
/synch |
|
Comparative benchmark results coming soon here |
|
Reassigning to 2.12.4. While I think the change looks good, the bug is pretty esoteric, and this touches core part of the typechecker, so I'd rather we merge it after the impending 2.12.3 release. |
|
Rebased. Ping @retronym. Let's decide this week whether we feel this is ok for 2.12.4 |
|
merge error in the rebase, it would seem: |
|
ugh, i've gotten too lazy with IJ's magic "resolve all" |
The bug report analysis correctly identified an unexpected cyclic error, which was triggered by implicit search. Implicit search is not expected while type checking the qualifier of a type selection node. Fixing this also removes the cyclic error. Thus, align `typedSelect` to be more consistent in dealing with `Select` and `SelectFromTypeTree` nodes. The spec is clear on the equivalence between `p.T` (`Select(p, T)`) and `p.type#T` (`SelectFromTypeTree(SingletonTypeTree(p), T)`). This bug gets even more intriguing, in that it shows that you can sneak a macro call into a path using `selectDynamic`. (See the test in next commit.) Eventually, we should disable applyDynamic in paths. It wasn't explicitly disallowed, since we assumed the stability check would rule out method calls. However, a macro application will dissolve into its rhs before stability is checked...
NOTE: the fix in the parent was inspired by allisonhb's analysis. This commit was amended to reuse the test case. Original commit message: Previously, while the implicit would rightly be discarded, `typedInternal` would catch the CyclicReference error and call `reportTypeError` before rethrowing, which would cause compilation to fail.
|
Benchmark scheduled. |
|
Let me know if there's anything I can do to help with this ... |
|
As far as I can tell, benchmarks look unaffected -- right, @retronym? |
No conflict, include PRs scala#5762, scala#6034
Based on @allisonhb's excellent analysis in milessabin/shapeless#679 (original fix in #5656), here's my proposed fix.
The bug report analysis correctly identified an unexpected cyclic error, which was triggered by implicit search. Implicit search is not expected while type checking the qualifier of a type selection node. Fixing this also removes the cyclic error.
Thus, align
typedSelectto be more consistent in dealing withSelectandSelectFromTypeTreenodes. The spec is clear on the equivalence betweenp.T(Select(p, T)) andp.type#T(SelectFromTypeTree(SingletonTypeTree(p), T)).This bug gets even more intriguing, in that it shows that you can sneak a macro call into a path using
selectDynamic. (See the test in next commit.)Eventually, we should disable applyDynamic in paths. It wasn't explicitly disallowed, since we assumed the stability check would rule out method calls. However, a macro application will dissolve into its rhs before stability is checked...
Fixes scala/bug#10159