Skip to content

safe_&: handle higher-kinded arguments like regular & #9470

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

Merged
merged 1 commit into from
Aug 10, 2020

Conversation

smarter
Copy link
Member

@smarter smarter commented Jul 30, 2020

Unfortunately, i9346.scala has to be put in pending because it
still crashes (due to a cycle involving a LazyRef) after this fix, and
because safe_& is only called from recoverable_& when there is some
sort of cycle in the first place, I haven't been able to make another
testcase that exercises this codepath.

It would be good if we could figure out how to get i9346.scala to
compile (see also #9346 for discussions). It is is a minimization of a pattern heavily used in
akka-stream, similar to the use of the CC type parameter in the
scala-library collections but using a type member instead.
Unfortunately, it seems that Dotty is not really prepared to handle
F-bounds in type members currently. I was able to get the testcase as
well as akka-stream to compile by tweaking findMember to not compute
an intersection when the refinement is an alias:

--- compiler/src/dotty/tools/dotc/core/Types.scala
+++ compiler/src/dotty/tools/dotc/core/Types.scala
@@ -671,7 +671,8 @@ object Types {
         val rinfo = tp.refinedInfo
         if (name.isTypeName && !pinfo.isInstanceOf[ClassInfo]) { // simplified case that runs more efficiently
           val jointInfo =
-            if (ctx.base.pendingMemberSearches.contains(name)) pinfo safe_& rinfo
+            if (rinfo.isInstanceOf[TypeAlias]) rinfo
+            else if (ctx.base.pendingMemberSearches.contains(name)) pinfo safe_& rinfo
             else pinfo recoverable_& rinfo
           pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, jointInfo)
         }

This seems to work, but to be sound it means that we need to check for
invalid bounds in PostTyper (see tests/neg/i5556.scala for an example where
this matter), like we do for type parameters in checkAppliedType.

Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM

@odersky odersky assigned smarter and unassigned odersky Aug 10, 2020
Unfortunately, i9346.scala has to be put in pending because it
still crashes (due to a cycle involving a LazyRef) after this fix, and
because `safe_&` is only called from `recoverable_&` when there is some
sort of cycle in the first place, I haven't been able to make another
testcase that exercises this codepath.

It would be good if we could figure out how to get i9346.scala to
compile (see also scala#9346 for discussions). It is is a minimization of a
pattern heavily used in akka-stream, similar to the use of the `CC` type
parameter in the scala-library collections but using a type member
instead. Unfortunately, it seems that Dotty is not really prepared to
handle F-bounds in type members currently. I was able to get the
testcase as well as akka-stream to compile by tweaking `findMember` to
not compute an intersection when the refinement is an alias:

```diff
--- compiler/src/dotty/tools/dotc/core/Types.scala
+++ compiler/src/dotty/tools/dotc/core/Types.scala
@@ -671,7 +671,8 @@ object Types {
         val rinfo = tp.refinedInfo
         if (name.isTypeName && !pinfo.isInstanceOf[ClassInfo]) { // simplified case that runs more efficiently
           val jointInfo =
-            if (ctx.base.pendingMemberSearches.contains(name)) pinfo safe_& rinfo
+            if (rinfo.isInstanceOf[TypeAlias]) rinfo
+            else if (ctx.base.pendingMemberSearches.contains(name)) pinfo safe_& rinfo
             else pinfo recoverable_& rinfo
           pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, jointInfo)
         }
```

This seems to work, but to be sound it means that we need to check for
invalid bounds in PostTyper (see tests/neg/i5556.scala for an example
where this matters), like we do for type parameters in
`checkAppliedType`.
@smarter smarter force-pushed the safe-intersection-hk branch from 15f3ac6 to f1faab6 Compare August 10, 2020 15:07
@smarter smarter merged commit 74ba21c into scala:master Aug 10, 2020
@smarter smarter deleted the safe-intersection-hk branch August 10, 2020 16:50
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.

2 participants