Skip to content

Commit c12de60

Browse files
committed
Don't use tryWithFallback
Why not? - It's a hack - It can add a factor of two for a failed implicit search, which can add up - It swallows up useful info for the first implicit search which caused the fallback. The only test failing after removal was t2429.scala. That test was originally for an issue where scalac crashed. It involves some fairly exotic code over List[Nothing]'s. I think we can ignore it for now, and just add the type annotation to make it compile.
1 parent 8a9aedc commit c12de60

File tree

5 files changed

+10
-53
lines changed

5 files changed

+10
-53
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/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)