Skip to content

Commit

Permalink
Check type arguments for bad bounds
Browse files Browse the repository at this point in the history
Fixes #15569
  • Loading branch information
odersky committed Jul 2, 2022
1 parent 6062192 commit ea03640
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/inlines/InlineReducer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import util.SimpleIdentityMap

import collection.mutable

/** A utility object offering methods for rewriting inlined code */
/** A utility class offering methods for rewriting inlined code */
class InlineReducer(inliner: Inliner)(using Context):
import tpd.*
import Inliner.{isElideableExpr, DefBuffer}
Expand Down
12 changes: 11 additions & 1 deletion compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Decorators._
import Symbols._, SymUtils._, NameOps._
import ContextFunctionResults.annotateContextResults
import config.Printers.typr
import util.SrcPos
import reporting._

object PostTyper {
Expand Down Expand Up @@ -180,6 +181,13 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
=> Checking.checkAppliedTypesIn(tree)
case _ =>

private def checkGoodBounds(tpe: Type, pos: SrcPos)(using Context): Unit = tpe.dealias match
case tpe: TypeRef =>
checkGoodBounds(tpe.info, pos)
case TypeBounds(lo, hi) if !(lo <:< hi) =>
report.error(i"type argument has unrealizable bounds $tpe", pos)
case _ =>

private def removeUnwantedAnnotations(sym: Symbol, metaAnnotSym: Symbol,
metaAnnotSymBackup: Symbol, keepIfNoRelevantAnnot: Boolean)(using Context): Unit =
def shouldKeep(annot: Annotation): Boolean =
Expand Down Expand Up @@ -342,7 +350,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
if tree.symbol.is(Inline) then
ctx.compilationUnit.needsInlining = true
val tree1 @ TypeApply(fn, args) = normalizeTypeArgs(tree)
args.foreach(checkInferredWellFormed)
for arg <- args do
checkInferredWellFormed(arg)
checkGoodBounds(arg.tpe, arg.srcPos)
if (fn.symbol != defn.ChildAnnot.primaryConstructor)
// Make an exception for ChildAnnot, which should really have AnyKind bounds
Checking.checkBounds(args, fn.tpe.widen.asInstanceOf[PolyType])
Expand Down
15 changes: 15 additions & 0 deletions tests/neg/i15569.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
trait Foo[X >: Any <: Nothing]

def andThenSub[A, B, C](f: A <:< B, g: B <:< C): A <:< C =
f.andThen(g)

@main def Test = (None: Option[Foo[?]]) match {
case _: Option[Foo[t]] =>
val unsound: Any <:< Nothing = andThenSub[Any, t, Nothing](summon, summon) // error
unsound("hi :)")
}
@main def Test2 =
type t >: Any <: Nothing
val unsound: Any <:< Nothing = andThenSub[Any, t, Nothing](summon, summon) // error
unsound("hi :)")

0 comments on commit ea03640

Please sign in to comment.