Skip to content

Commit 792469b

Browse files
committed
Don't replace typevars by their f-bounds in error messages
Fixes #14363
1 parent 5587767 commit 792469b

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,15 @@ import transform.SymUtils._
245245
extends TypeMismatchMsg(found, expected)(TypeMismatchID):
246246

247247
// replace constrained TypeParamRefs and their typevars by their bounds where possible
248-
// the idea is that if the bounds are also not-subtypes of each other to report
248+
// and the bounds are not f-bounds.
249+
// The idea is that if the bounds are also not-subtypes of each other to report
249250
// the type mismatch on the bounds instead of the original TypeParamRefs, since
250-
// these are usually easier to analyze.
251+
// these are usually easier to analyze. We exclude F-bounds since these would
252+
// lead to a recursive infinite expansion.
251253
object reported extends TypeMap:
252254
def setVariance(v: Int) = variance = v
253255
val constraint = mapCtx.typerState.constraint
256+
var fbounded = false
254257
def apply(tp: Type): Type = tp match
255258
case tp: TypeParamRef =>
256259
constraint.entry(tp) match
@@ -260,15 +263,21 @@ import transform.SymUtils._
260263
else tp
261264
case NoType => tp
262265
case instType => apply(instType)
263-
case tp: TypeVar => apply(tp.stripTypeVar)
264-
case _ => mapOver(tp)
266+
case tp: TypeVar =>
267+
apply(tp.stripTypeVar)
268+
case tp: LazyRef =>
269+
fbounded = true
270+
tp
271+
case _ =>
272+
mapOver(tp)
265273

266274
def msg =
267275
val found1 = reported(found)
268276
reported.setVariance(-1)
269277
val expected1 = reported(expected)
270278
val (found2, expected2) =
271-
if (found1 frozen_<:< expected1) (found, expected) else (found1, expected1)
279+
if (found1 frozen_<:< expected1) || reported.fbounded then (found, expected)
280+
else (found1, expected1)
272281
val postScript = addenda.find(!_.isEmpty) match
273282
case Some(p) => p
274283
case None =>

tests/neg/i14363.check

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- [E007] Type Mismatch Error: tests/neg/i14363.scala:2:13 -------------------------------------------------------------
2+
2 |def test = f(1) // error
3+
| ^
4+
| Found: (1 : Int)
5+
| Required: T
6+
|
7+
| where: T is a type variable with constraint <: Ordered[T]
8+
|
9+
|
10+
| One of the following imports might fix the problem:
11+
|
12+
| import math.BigDecimal.int2bigDecimal
13+
| import math.BigInt.int2bigInt
14+
|
15+
|
16+
| longer explanation available when compiling with `-explain`

tests/neg/i14363.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def f[T <: Ordered[T]](t: T): T = t
2+
def test = f(1) // error

0 commit comments

Comments
 (0)