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

Support implicit scope augmentation for Mirror #6879

Merged
merged 6 commits into from Jul 25, 2019

Conversation

@milessabin
Copy link
Contributor

commented Jul 17, 2019

Mirrors can now be materialized with additional type member refinements. Any additional type members will contribute to the implicit scope of any searches involving the type of the summoned Mirror. Typically such types will be the singleton types of objects containing implicit extension methods for the Mirror, or other related implicit definitions.

Given,

case class Foo(i: Int)

the[Mirror.Product { type MirroredType = Foo ; type Phantom = Other.type }]

then requested type (formal in the code) will be,

Mirror.Product { type MirroredType = Foo ; type Phantom = Other }

and the core synthesized mirror type will be,

Mirror.Product {
  type MirroredType = Foo
  type MirroedMonoType = Foo
  type Label = "Foo"
  type MirroredElemTypes = Tuple1[Int]
  type MirroredElemLabels = Tuple1["i"]
}

The result of intersecting these two is then,

Mirror.Product {
  type MirroredType = Foo
  type MirroedMonoType = Foo
  type Label = "Foo"
  type MirroredElemTypes = Tuple1[Int]
  type MirroredElemLabels = Tuple1["i"]
  type Phantom = Other.type
}

That's the refined type that we'll get for the mirror as a given argument, so if we have an object Other containing extension methods like so,

object Other {
  given Ops {
    def (m: Mirror.Product { type MirroredType = T }) extension [T]
  }
}

they will be found because the contents of Other is included in the implicit scope for the extension method search via the parts of the refined type of the mirror.

@milessabin milessabin requested a review from odersky Jul 17, 2019

@milessabin milessabin force-pushed the milessabin:topic/mirror-implicit-scope branch 2 times, most recently from a2ed239 to b26f555 Jul 18, 2019

@milessabin

This comment has been minimized.

Copy link
Contributor Author

commented Jul 18, 2019

Rebased.

.refinedWith(tpnme.MirroredMonoType, TypeAlias(monoType))
.refinedWith(tpnme.MirroredType, TypeAlias(mirroredType))
.refinedWith(tpnme.MirroredLabel, TypeAlias(ConstantType(Constant(label.toString))))

extras.foldLeft(m) { case (m, (tpnme, tpe)) => m.refinedWith(tpnme, tpe) }

This comment has been minimized.

Copy link
@smarter

smarter Jul 18, 2019

Member

Would it make sense to just do formal & m ?

This comment has been minimized.

Copy link
@milessabin

milessabin Jul 18, 2019

Author Contributor

I'll have a look ...

This comment has been minimized.

Copy link
@milessabin

milessabin Jul 18, 2019

Author Contributor

Yes, it makes sense, and simplifies things significantly. Good call :-)

milessabin added 2 commits Jul 17, 2019
Mirrors can now be materialized with additional type member refinements.
Any additional type members will contribute to the implicit scope of any
searches involving the type of the summoned Mirror.  Typically such
types will be the singleton types of objects containing implicit
extension methods for the Mirror, or other related implicit definitions.

Pass through all extra refinements

@milessabin milessabin force-pushed the milessabin:topic/mirror-implicit-scope branch from 0bfc9d2 to f6d4ddb Jul 18, 2019

@milessabin

This comment has been minimized.

Copy link
Contributor Author

commented Jul 18, 2019

Rebased for #6886.

@smarter

This comment has been minimized.

Actually what happens if formal is of the form SomeClass & Mirror ..., do we get a value casted to that type or a type mismatch error ?

@milessabin

This comment has been minimized.

Copy link
Contributor Author

commented Jul 19, 2019

the[SomeClass & Mirror.ProductOf[ISB]]

gives me,

no implicit argument of type Test.SomeClass & deriving.Mirror.ProductOf[Test.ISB] was found ...

which I think is what we want.

@smarter

This comment has been minimized.

Copy link
Member

commented Jul 19, 2019

Some neg tests exercising this and other weird combinations (e.g. refining with a def) would be nice

@milessabin

This comment has been minimized.

Copy link
Contributor Author

commented Jul 19, 2019

Added check rejecting methodic refinements and some neg tests.

@smarter

This comment has been minimized.

You can have vals in refinements too, I think you want to reject any refinement which is not a TypeBounds.

@milessabin

This comment has been minimized.

Copy link
Contributor Author

commented Jul 19, 2019

@smarter done.

if (!checkFormal(formal)) EmptyTree
else
formal.member(tpnme.MirroredType).info match {
case TypeBounds(mirroredType, _) if checkFormal(formal) => mirrorFor(mirroredType)

This comment has been minimized.

Copy link
@odersky

odersky Jul 19, 2019

Contributor

checkFormal(formal) is always true here

This comment has been minimized.

Copy link
@milessabin

milessabin Jul 19, 2019

Author Contributor

I don't think that can be the case. It being false for formals which include def/val definitions is what's responsible for the (intended) neg test failures.

This comment has been minimized.

Copy link
@odersky

odersky Jul 21, 2019

Contributor

But it just got tested in line 968, so to reach the else part, it must be true.

This comment has been minimized.

Copy link
@milessabin

milessabin Jul 22, 2019

Author Contributor

Oh! Yes, sorry ... I completely missed the redundant guard there. Removed.

@milessabin

This comment has been minimized.

Copy link
Contributor Author

commented Jul 23, 2019

@odersky I think this is ready to merge now.

@milessabin milessabin merged commit 8095c23 into lampepfl:master Jul 25, 2019

2 checks passed

CLA User signed CLA
Details
continuous-integration/drone/pr Build is passing
Details
@milessabin milessabin referenced this pull request Jul 26, 2019

@anatoliykmetyuk anatoliykmetyuk added this to the 0.18 Tech Preview milestone Aug 28, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.