-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improvements to implicits #1918
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
Changes from all commits
971b233
4086195
269be04
bc06d17
fe09e0d
56d32fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._, De | |
import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annotation | ||
import StdNames.{nme, tpnme} | ||
import ast.Trees._, ast._ | ||
import typer.Implicits._ | ||
import config.Config | ||
import java.lang.Integer.toOctalString | ||
import config.Config.summarizeDepth | ||
|
@@ -484,6 +485,23 @@ class PlainPrinter(_ctx: Context) extends Printer { | |
} | ||
}.close // todo: override in refined printer | ||
|
||
def toText(result: SearchResult): Text = result match { | ||
case result: SearchSuccess => | ||
"SearchSuccess: " ~ toText(result.ref) ~ " via " ~ toText(result.tree) | ||
case result: NonMatchingImplicit => | ||
"NoImplicitMatches" | ||
case result: DivergingImplicit => | ||
"Diverging Implicit" | ||
case result: ShadowedImplicit => | ||
"Shadowed Implicit" | ||
case result: FailedImplicit => | ||
"Failed Implicit" | ||
case result: AmbiguousImplicits => | ||
"Ambiguous Implicit: " ~ toText(result.alt1) ~ " and " ~ toText(result.alt2) | ||
case _ => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we seal There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, in fact we cannot. There are too many other cases we'd have to handle. E.g. ExplainedSearchResult. Sometimes it's better not to seal. |
||
"?Unknown Implicit Result?" | ||
} | ||
|
||
private var maxSummarized = Int.MaxValue | ||
|
||
def summarized[T](depth: Int)(op: => T): T = { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package generic | ||
|
||
import Shapes._ | ||
|
||
/** enum Color { | ||
* case Red | ||
* case Green | ||
* case Blue | ||
* } | ||
*/ | ||
sealed trait Color extends Enum | ||
|
||
object Color extends EnumValues[Color](3) { | ||
|
||
private def $new(tag: Int, name: String) = new Color { | ||
def enumTag = tag | ||
override def toString = name | ||
registerEnumValue(this) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have a named subclass of |
||
|
||
val Red: Color = $new(0, "Red") | ||
val Green: Color = $new(1, "Green") | ||
val Blue: Color = $new(2, "Blue") | ||
|
||
implicit val ColorShape: Color `shaped` EnumValue[Color] = | ||
new (Color `shaped` EnumValue[Color]) { | ||
def toShape(x: Color) = EnumValue(x.enumTag) | ||
def fromShape(x: EnumValue[Color]) = Color.value(x.tag) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package generic | ||
|
||
import Shapes.Singleton | ||
|
||
trait Enum { | ||
def enumTag: Int | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What use cases do you envision for |
||
} | ||
|
||
trait FiniteEnum extends Enum | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's that? |
||
|
||
abstract class EnumValues[E <: Enum](numVals: Int) { | ||
private var myValues = new Array[AnyRef](numVals) | ||
|
||
def registerEnumValue(v: E) = | ||
myValues(v.enumTag) = v | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we somehow restrict the visibility of this method? |
||
|
||
def value: IndexedSeq[E] = (myValues: IndexedSeq[AnyRef]).asInstanceOf[IndexedSeq[E]] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package generic | ||
|
||
import Shapes._ | ||
|
||
/** enum List[T] { | ||
* case Cons(x: T, xs: List[T]) | ||
* case Nil() | ||
* } | ||
*/ | ||
sealed trait List0[T] extends Enum | ||
object List0 { | ||
abstract case class Cons[T](hd: T, tl: List0[T]) extends List0[T] { | ||
def enumTag = 0 | ||
} | ||
object Cons { | ||
def apply[T](x: T, xs: List0[T]): List0[T] = new Cons(x, xs) {} | ||
implicit def ConsShape[T]: Cons[T] `shaped` Prod[T, List0[T]] = | ||
new (Cons[T] `shaped` Prod[T, List0[T]]) { | ||
def toShape(x: Cons[T]) = Prod(x.hd, x.tl) | ||
def fromShape(p: Prod[T, List0[T]]) = new Cons(p.fst, p.snd) {} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @odersky Am I right in thinking that you'd like the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And, in general, which parts of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @xeno-by The |
||
} | ||
|
||
abstract case class Nil[T]() extends List0[T] { | ||
def enumTag = 1 | ||
} | ||
object Nil { | ||
def apply[T](): List0[T] = new Nil[T]() {} | ||
implicit def NilShape[T]: Nil[T] `shaped` Unit = | ||
new (Nil[T] `shaped` Unit) { | ||
def toShape(x: Nil[T]) = () | ||
def fromShape(x: Unit) = new Nil[T]() {} | ||
} | ||
} | ||
|
||
implicit def List0Shape[T]: List0[T] `shaped` Sum[Cons[T], Nil[T]] = | ||
new (List0[T] `shaped` Sum[Cons[T], Nil[T]]) { | ||
def toShape(x: List0[T]) = x match { | ||
case x: Cons[T] => Fst(x) | ||
case x: Nil[T] => Snd(x) | ||
} | ||
def fromShape(x: Sum[Cons[T], Nil[T]]) = x match { | ||
case Fst(c) => c | ||
case Snd(n) => n | ||
} | ||
} | ||
} | ||
|
||
/** enum List[T] { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the variance modifier omitted here on purpose? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are actually two sources, one without variance for List0, the other with variance for List1. |
||
* case Cons(x: T, xs: List[T]) | ||
* case Nil extends List[Nothing] | ||
* } | ||
*/ | ||
sealed trait List[+T] extends Enum | ||
object List { | ||
abstract case class Cons[T](hd: T, tl: List[T]) extends List[T] { | ||
def enumTag = 0 | ||
} | ||
object Cons { | ||
def apply[T](x: T, xs: List[T]): List[T] = new Cons(x, xs) {} | ||
type Shape[T] = Prod[T, List[T]] | ||
implicit def ConsShape[T]: Cons[T] `shaped` Shape[T] = | ||
new (Cons[T] `shaped` Shape[T]) { | ||
def toShape(x: Cons[T]) = Prod(x.hd, x.tl) | ||
def fromShape(p: Shape[T]) = new Cons(p.fst, p.snd) {} | ||
} | ||
} | ||
|
||
val Nil = new List[Nothing] { | ||
def enumTag = 1 | ||
override def toString = "Nil" | ||
} | ||
|
||
implicit def NilSingleton: Singleton[Nil.type] = new Singleton[Nil.type](Nil) | ||
|
||
type Shape[T] = Sum[Cons[T], Nil.type] | ||
|
||
implicit def ListShape[T]: List[T] `unfolds` Shape[T] = | ||
new (List[T] `shaped` Shape[T]) { | ||
def toShape(x: List[T]) = x match { | ||
case x: Cons[T] => Fst(x) | ||
case Nil => Snd(Nil) | ||
} | ||
def fromShape(x: Shape[T]): List[T] = x match { | ||
case Fst(c) => c | ||
case Snd(n) => n | ||
} | ||
} | ||
} |
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.
Why was this prohibited in scalac?