Skip to content

Commit 7d34049

Browse files
authored
Merge pull request #2493 from dotty-staging/change-simplify-implicits
Don't use tryWithFallback
2 parents 79d4e3e + 119a6cf commit 7d34049

File tree

6 files changed

+11
-54
lines changed

6 files changed

+11
-54
lines changed

compiler/src/dotty/tools/dotc/core/TyperState.scala

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ class TyperState(r: Reporter) extends DotClass with Showable {
7676
/** Can this state be transitively committed until the top-level? */
7777
def isGlobalCommittable: Boolean = false
7878

79-
def tryWithFallback[T](op: => T)(fallback: => T)(implicit ctx: Context): T = unsupported("tryWithFallBack")
80-
8179
override def toText(printer: Printer): Text = "ImmutableTyperState"
8280

8381
/** A string showing the hashes of all nested mutable typerstates */
@@ -170,45 +168,6 @@ extends TyperState(r) {
170168
constraint = constraint.remove(poly)
171169
}
172170

173-
/** Try operation `op`; if it produces errors, execute `fallback` with constraint and
174-
* reporter as they were before `op` was executed. This is similar to `typer/tryEither`,
175-
* but with one important difference: Any type variable instantiations produced by `op`
176-
* are persisted even if `op` fails. This is normally not what one wants and therefore
177-
* it is recommended to use
178-
*
179-
* tryEither { implicit ctx => op } { (_, _) => fallBack }
180-
*
181-
* instead of
182-
*
183-
* ctx.tryWithFallback(op)(fallBack)
184-
*
185-
* `tryWithFallback` is only used when an implicit parameter search fails
186-
* and the whole expression is subsequently retype-checked with a Wildcard
187-
* expected type (so as to allow an implicit conversion on the result and
188-
* avoid over-constraining the implicit parameter search). In this case,
189-
* the only type variables that might be falsely instantiated by `op` but
190-
* not by `fallBack` are type variables in the typed expression itself, and
191-
* these will be thrown away and new ones will be created on re-typing.
192-
* So `tryWithFallback` is safe. It is also necessary because without it
193-
* we do not propagate enough instantiation information into the implicit search
194-
* and this might lead to a missing parameter type error. This is exhibited
195-
* at several places in the test suite (for instance in `pos_typers`).
196-
* Overall, this is rather ugly, but despite trying for 2 days I have not
197-
* found a better solution.
198-
*/
199-
override def tryWithFallback[T](op: => T)(fallback: => T)(implicit ctx: Context): T = {
200-
val storeReporter = new StoreReporter(myReporter)
201-
val savedReporter = myReporter
202-
myReporter = storeReporter
203-
val savedConstraint = myConstraint
204-
val result = try op finally myReporter = savedReporter
205-
if (!storeReporter.hasErrors) result
206-
else {
207-
myConstraint = savedConstraint
208-
fallback
209-
}
210-
}
211-
212171
override def toText(printer: Printer): Text = constraint.toText(printer)
213172

214173
override def hashesStr: String = hashCode.toString + " -> " + previous.hashesStr

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
193193
val bounds =
194194
if (constr.contains(tp)) constr.fullBounds(tp.origin)(ctx.addMode(Mode.Printing))
195195
else TypeBounds.empty
196-
if (ctx.settings.YshowVarBounds.value) "(" ~ toText(tp.origin) ~ "?" ~ toText(bounds) ~ ")"
196+
if (bounds.isAlias) toText(bounds.lo) ~ "^"
197+
else if (ctx.settings.YshowVarBounds.value) "(" ~ toText(tp.origin) ~ "?" ~ toText(bounds) ~ ")"
197198
else toText(tp.origin)
198199
}
199200
case tp: LazyRef =>
@@ -487,9 +488,9 @@ class PlainPrinter(_ctx: Context) extends Printer {
487488
def toText(result: SearchResult): Text = result match {
488489
case result: SearchSuccess =>
489490
"SearchSuccess: " ~ toText(result.ref) ~ " via " ~ toText(result.tree)
490-
case result: NonMatchingImplicit =>
491+
case _: NonMatchingImplicit | NoImplicitMatches =>
491492
"NoImplicitMatches"
492-
case result: DivergingImplicit =>
493+
case _: DivergingImplicit | DivergingImplicit =>
493494
"Diverging Implicit"
494495
case result: ShadowedImplicit =>
495496
"Shadowed Implicit"
@@ -498,7 +499,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
498499
case result: AmbiguousImplicits =>
499500
"Ambiguous Implicit: " ~ toText(result.alt1) ~ " and " ~ toText(result.alt2)
500501
case _ =>
501-
"?Unknown Implicit Result?"
502+
"?Unknown Implicit Result?" + result.getClass
502503
}
503504

504505
def toText(importInfo: ImportInfo): Text = {

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ trait Implicits { self: Typer =>
680680
result match {
681681
case result: SearchSuccess =>
682682
result.tstate.commit()
683+
implicits.println(i"success: $result")
683684
implicits.println(i"committing ${result.tstate.constraint} yielding ${ctx.typerState.constraint} ${ctx.typerState.hashesStr}")
684685
result
685686
case result: AmbiguousImplicits =>

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,11 +1911,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
19111911
}
19121912
else adapt(tpd.Apply(tree, args), pt)
19131913
}
1914-
if ((pt eq WildcardType) || original.isEmpty) addImplicitArgs(argCtx(tree))
1915-
else
1916-
ctx.typerState.tryWithFallback(addImplicitArgs(argCtx(tree))) {
1917-
adapt(typed(original, WildcardType), pt, EmptyTree)
1918-
}
1914+
addImplicitArgs(argCtx(tree))
19191915
case wtp: MethodType if !pt.isInstanceOf[SingletonType] =>
19201916
// Follow proxies and approximate type paramrefs by their upper bound
19211917
// in the current constraint in order to figure out robustly

tests/neg/i1802.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ object Exception {
1616

1717
def mkThrowableCatcher[T](isDef: Throwable => Boolean, f: Throwable => T) = mkCatcher(isDef, f) // error: undetermined ClassTag
1818

19-
implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassTag, T](pf: PartialFunction[Ex, T]) =
19+
implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassTag, T](pf: PartialFunction[Ex, T]) = // error: result type needs to be given
2020
mkCatcher(pf.isDefinedAt _, pf.apply _)
2121
}

tests/pos/t2429.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ object Msg {
1616
}
1717
}
1818
}
19-
} /*: Seq[T] Adding this type annotation avoids the compile error.*/)
19+
}: Seq[T] /* Adding this type annotation avoids the compile error.*/)
2020
}
2121
}
2222
object Oops {
23-
implicit def someImplicit(s: Seq[_]): String = sys.error("stub")
24-
def item: String = Nil map { case e: Any => e }
23+
// implicit def someImplicit(s: Seq[_]): String = sys.error("stub")
24+
// def item: String = Nil map { case e: Any => e }
2525
}

0 commit comments

Comments
 (0)