Skip to content

Commit 1e09221

Browse files
authored
Merge pull request #15393 from dotty-staging/fix-15365-partial
Handle AvoidMap recursions
2 parents 6f84c1e + ac0100d commit 1e09221

File tree

2 files changed

+52
-31
lines changed

2 files changed

+52
-31
lines changed

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

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -423,38 +423,42 @@ object TypeOps:
423423
sym.is(Package) || sym.isStatic && isStaticPrefix(pre.prefix)
424424
case _ => true
425425

426-
override def apply(tp: Type): Type = tp match
427-
case tp: TermRef
428-
if toAvoid(tp) =>
429-
tp.info.widenExpr.dealias match {
430-
case info: SingletonType => apply(info)
431-
case info => range(defn.NothingType, apply(info))
432-
}
433-
case tp: TypeRef if toAvoid(tp) =>
434-
tp.info match {
435-
case info: AliasingBounds =>
436-
apply(info.alias)
437-
case TypeBounds(lo, hi) =>
438-
range(atVariance(-variance)(apply(lo)), apply(hi))
439-
case info: ClassInfo =>
440-
range(defn.NothingType, apply(classBound(info)))
426+
override def apply(tp: Type): Type =
427+
try
428+
tp match
429+
case tp: TermRef
430+
if toAvoid(tp) =>
431+
tp.info.widenExpr.dealias match {
432+
case info: SingletonType => apply(info)
433+
case info => range(defn.NothingType, apply(info))
434+
}
435+
case tp: TypeRef if toAvoid(tp) =>
436+
tp.info match {
437+
case info: AliasingBounds =>
438+
apply(info.alias)
439+
case TypeBounds(lo, hi) =>
440+
range(atVariance(-variance)(apply(lo)), apply(hi))
441+
case info: ClassInfo =>
442+
range(defn.NothingType, apply(classBound(info)))
443+
case _ =>
444+
emptyRange // should happen only in error cases
445+
}
446+
case tp: ThisType =>
447+
// ThisType is only used inside a class.
448+
// Therefore, either they don't appear in the type to be avoided, or
449+
// it must be a class that encloses the block whose type is to be avoided.
450+
tp
451+
case tp: LazyRef =>
452+
if localParamRefs.contains(tp.ref) then tp
453+
else if isExpandingBounds then emptyRange
454+
else mapOver(tp)
455+
case tl: HKTypeLambda =>
456+
localParamRefs ++= tl.paramRefs
457+
mapOver(tl)
441458
case _ =>
442-
emptyRange // should happen only in error cases
443-
}
444-
case tp: ThisType =>
445-
// ThisType is only used inside a class.
446-
// Therefore, either they don't appear in the type to be avoided, or
447-
// it must be a class that encloses the block whose type is to be avoided.
448-
tp
449-
case tp: LazyRef =>
450-
if localParamRefs.contains(tp.ref) then tp
451-
else if isExpandingBounds then emptyRange
452-
else mapOver(tp)
453-
case tl: HKTypeLambda =>
454-
localParamRefs ++= tl.paramRefs
455-
mapOver(tl)
456-
case _ =>
457-
super.apply(tp)
459+
super.apply(tp)
460+
catch case ex: Throwable =>
461+
handleRecursive("traversing for avoiding local references", s"${tp.show}" , ex)
458462
end apply
459463

460464
/** Three deviations from standard derivedSelect:
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
trait Tagged[U]
2+
type WithTag[+TT, UU] = TT & Tagged[UU]
3+
4+
trait FromInput[Val]
5+
implicit def coercedScalaInput[Tc1]: FromInput[WithTag[Tc1, Int]] = ???
6+
implicit def optionInput[To](implicit ev: FromInput[To]): FromInput[Option[To]] = ???
7+
8+
trait WithoutInputTypeTags[TW]
9+
implicit def coercedOptArgTpe[Tc]: WithoutInputTypeTags[Option[WithTag[Tc, Int]]] = ???
10+
11+
trait InputType[+TI]
12+
class OptionInputType[TO](ofType: InputType[TO]) extends InputType[Option[TO]]
13+
14+
type Argument[TA]
15+
def argument[Ta](argumentType: InputType[Ta])(implicit fromInput: FromInput[Ta], res: WithoutInputTypeTags[Ta]): Argument[Option[Ta]] = ???
16+
17+
def test = argument(OptionInputType(??? : InputType[WithTag[Boolean, Int]])) :: Nil // error

0 commit comments

Comments
 (0)