Skip to content

Tweak implicit resolution #6034

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 2 commits into from
Mar 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,9 @@ object Types {
ctx.typeComparer.isSameType(this, that)
}

final def frozen_=:=(that: Type)(implicit ctx: Context): Boolean =
ctx.typeComparer.isSameTypeWhenFrozen(this, that)

/** Is this type a primitive value type which can be widened to the primitive value type `that`? */
def isValueSubType(that: Type)(implicit ctx: Context): Boolean = widen match {
case self: TypeRef if self.symbol.isPrimitiveValueClass =>
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
else tp

private def sameBound(lo: Type, hi: Type): Boolean =
try ctx.typeComparer.isSameTypeWhenFrozen(lo, hi)
catch { case NonFatal(ex) => false }
try lo frozen_=:= hi catch { case NonFatal(ex) => false }

private def homogenizeArg(tp: Type) = tp match {
case TypeBounds(lo, hi) if homogenizedView && sameBound(lo, hi) => homogenize(hi)
Expand Down
11 changes: 7 additions & 4 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1370,11 +1370,14 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val strippedType2 = stripImplicit(fullType2, +1)

val result = compareWithTypes(strippedType1, strippedType2)
if (result != 0) result
else if (implicitBalance != 0) -implicitBalance.signum
if (result != 0 || !ctx.typerState.test(implicit ctx => strippedType1 =:= strippedType2))
result
else if (implicitBalance != 0)
-implicitBalance.signum
else if ((strippedType1 `ne` fullType1) || (strippedType2 `ne` fullType2))
compareWithTypes(fullType1, fullType2)
else 0
else
0
}}

def narrowMostSpecific(alts: List[TermRef])(implicit ctx: Context): List[TermRef] = track("narrowMostSpecific") {
Expand Down Expand Up @@ -1637,7 +1640,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
// ps(i) = List(p_i_1, ..., p_i_n) -- i.e. a column
// If all p_i_k's are the same, assume the type as formal parameter
// type of the i'th parameter of the closure.
if (isUniform(ps)(ctx.typeComparer.isSameTypeWhenFrozen(_, _))) ps.head
if (isUniform(ps)(_ frozen_=:= _)) ps.head
else WildcardType)
def isPartial = // we should generate a partial function for the arg
fn.get.isInstanceOf[untpd.Match] &&
Expand Down
6 changes: 4 additions & 2 deletions docs/docs/reference/changed-features/implicit-resolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,10 @@ affect implicits on the language level.
An alternative A is _more specific_ than an alternative B if

- the relative weight of A over B is greater than the relative weight of B over A, or
- the relative weights are the same and A takes more inferable parameters than B, or
- the relative weights and the number of inferable parameters are the same and
- the relative weights are the same, and the returned types of A and B are
unifiable, and A takes more inferable parameters than B, or
- the relative weights and the number of inferable parameters are the same, and
the returned types of A and B are unifiable, and
A is more specific than B if all inferable parameters in either alternative are
replaced by regular parameters.

Expand Down
2 changes: 2 additions & 0 deletions tests/neg/i3430.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<44..44> in i3430.scala
ambiguous implicit arguments: both object Long in object Ordering and object Short in object Ordering match type Ordering[B] of parameter cmp of method min in trait TraversableOnce
2 changes: 1 addition & 1 deletion tests/neg/i3430.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Test extends App {

println(Nil.min) // error: no implicit found
println(Nil.min) // error: ambiguous

}