Skip to content

Retire implicit shadower in favour of post-hoc analysis of typedImplicit#7757

Closed
retronym wants to merge 2 commits intoscala:2.12.xfrom
retronym:topic/retire-shadower-again
Closed

Retire implicit shadower in favour of post-hoc analysis of typedImplicit#7757
retronym wants to merge 2 commits intoscala:2.12.xfrom
retronym:topic/retire-shadower-again

Conversation

@retronym
Copy link
Member

The motivations are:

  • performance (the HashSet in LocalShadower is an allocation hotspot)
  • correctness (further aligning typedIdent and inferImplicit)

@scala-jenkins scala-jenkins added this to the 2.12.9 milestone Feb 15, 2019
@retronym retronym added the WIP label Feb 15, 2019
@retronym retronym force-pushed the topic/retire-shadower-again branch from 1192539 to fb27e4d Compare February 15, 2019 11:31
@retronym retronym force-pushed the topic/retire-shadower-again branch from fb27e4d to 7c2d2bd Compare February 16, 2019 04:57
@retronym retronym force-pushed the topic/retire-shadower-again branch from 7c2d2bd to 86ecd0a Compare March 1, 2019 04:19
@retronym retronym force-pushed the topic/retire-shadower-again branch from 6050707 to 593999b Compare March 4, 2019 03:12
@retronym retronym requested a review from adriaanm March 7, 2019 05:22
@adriaanm adriaanm self-assigned this Mar 7, 2019
Some(collectImplicits(owner.thisType.implicitMembers, owner.thisType))
}
} else if (scope != nextOuter.scope && !owner.isPackageClass) {
} else if (scope != nextOuter.scope && !owner.isPackageClass && !(owner.isClass && owner.isInitialized)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we check whether this is local in one shot? Since isClass covers isPackageClass?

@adriaanm
Copy link
Contributor

adriaanm commented Mar 7, 2019

Let's see what the community build says, and if it looks good -- port to 2.13. Too late in the 2.12 cycle to tweak implicit search

@SethTisue
Copy link
Member

SethTisue commented Mar 7, 2019

@retronym
Copy link
Member Author

I'm investigating a failure in the community build:

[scalaz] [error] /home/jenkins/workspace/scala-2.12.x-integrate-community-build/target-0.9.16/project-builds/scalaz-6ccf456dfa5e8117267ec550148b70622d949700/tests/src/test/scala/scalaz/TraverseTest.scala:45: ambiguous implicit values:
[scalaz] [error]  both value idInstance in package scalaz of type => scalaz.Traverse1[scalaz.Id.Id] with scalaz.Monad[scalaz.Id.Id] with scalaz.BindRec[scalaz.Id.Id] with scalaz.Comonad[scalaz.Id.Id] with scalaz.Distributive[scalaz.Id.Id] with scalaz.Zip[scalaz.Id.Id] with scalaz.Unzip[scalaz.Id.Id] with scalaz.Align[scalaz.Id.Id] with scalaz.Cozip[scalaz.Id.Id] with scalaz.Optional[scalaz.Id.Id]
[scalaz] [error]  and value idInstance in package scalaz of type => scalaz.Traverse1[scalaz.Id.Id] with scalaz.Monad[scalaz.Id.Id] with scalaz.BindRec[scalaz.Id.Id] with scalaz.Comonad[scalaz.Id.Id] with scalaz.Distributive[scalaz.Id.Id] with scalaz.Zip[scalaz.Id.Id] with scalaz.Unzip[scalaz.Id.Id] with scalaz.Align[scalaz.Id.Id] with scalaz.Cozip[scalaz.Id.Id] with scalaz.Optional[scalaz.Id.Id]
[scalaz] [error]  match expected type scalaz.Monad[scalaz.Id.Id]
[scalaz] [error]       List.range(0,N).traverseS(x => modify((x: Int) => x+1))(0) must_=== (
[scalaz] [error]                                                              ^

@retronym
Copy link
Member Author

retronym commented Mar 19, 2019

Minimized the regression to:

$ tail test/files/pos/implicit-my-package-object-two-files/*.scala
==> test/files/pos/implicit-my-package-object-two-files/A.scala <==
package a

package object b {
  implicit def foo: String = ""
}

==> test/files/pos/implicit-my-package-object-two-files/B.scala <==
package b

object Test {
  import b._

  foo
  implicitly[String]
}

The implicit foo appears twice in context.implicitss, and the leniency around package prefixes in hasMatchingSymbol means that we think that both of them are eligible candidates, but they then are deemed ambiguous. Previously, LocalShadower ruled out the candidate provided from the enclosing package's this-type.

@retronym retronym force-pushed the topic/retire-shadower-again branch from 593999b to 42403cf Compare March 19, 2019 06:14
@retronym
Copy link
Member Author

I've pushed a fix that still reinstates a simpler form of shadowing checks into the search. Because of the improvements to hasMatchingSymbol, all this needs to do is post-filter the eligible candidates. That list if often empty, so we're not paying the cost to allocate the HashSet anywhere near as much.

…typedImplicit

I'm not 100% sure about neg/t729.scala, which I've converted to
a pos test.

The original bug report is archived:

  https://lrytz.github.io/scala-aladdin-bugtracker/displayItem.do%3Fid=729.html
Mark the input `Ident` with an attachment and search for that
to find the corresponding tree in the type checked output.

`itree2` does _not_ have macros expanded (even whitebox), that
comes later in `itree3`. I added a test for such cases to be sure.
@retronym retronym force-pushed the topic/retire-shadower-again branch from 42403cf to 87aab31 Compare March 19, 2019 06:34
@retronym
Copy link
Member Author

@diesalbla
Copy link
Contributor

@retronym Now that #7890 has been merged, do you still want to push for this one?

@retronym
Copy link
Member Author

@diesalbla It is still worthwhile. I realise now that simply re-using the java.util.HashSet doesn't avoid allocation of its internal Node classes.

I'm now also considering a different change (retronym#49) that doesn't change current semantics. I'll close this PR now and do my benchmarking over there :)

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.

5 participants