Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
pkskpro committed Jan 9, 2025
2 parents 2ca1be3 + 285cd40 commit 52ddc3b
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 172 deletions.
11 changes: 5 additions & 6 deletions compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ object TypeTestsCasts {
* 9. if `X` is `T1 | T2`, checkable(T1, P) && checkable(T2, P).
* 10. otherwise, ""
*/
def whyUncheckable(X: Type, P: Type, span: Span)(using Context): String = atPhase(Phases.refchecksPhase.next) {
def whyUncheckable(X: Type, P: Type, span: Span, trustTypeApplication: Boolean)(using Context): String = atPhase(Phases.refchecksPhase.next) {
extension (inline s1: String) inline def &&(inline s2: String): String = if s1 == "" then s2 else s1
extension (inline b: Boolean) inline def |||(inline s: String): String = if b then "" else s

Expand Down Expand Up @@ -143,7 +143,7 @@ object TypeTestsCasts {
case defn.ArrayOf(tpE) => recur(tpE, tpT)
case _ => recur(defn.AnyType, tpT)
}
case tpe @ AppliedType(tycon, targs) =>
case tpe @ AppliedType(tycon, targs) if !trustTypeApplication =>
X.widenDealias match {
case OrType(tp1, tp2) =>
// This case is required to retrofit type inference,
Expand Down Expand Up @@ -366,8 +366,7 @@ object TypeTestsCasts {
if (sym.isTypeTest) {
val argType = tree.args.head.tpe
val isTrusted = tree.hasAttachment(PatternMatcher.TrustedTypeTestKey)
if !isTrusted then
checkTypePattern(expr.tpe, argType, expr.srcPos)
checkTypePattern(expr.tpe, argType, expr.srcPos, isTrusted)
transformTypeTest(expr, argType,
flagUnrelated = enclosingInlineds.isEmpty) // if test comes from inlined code, dont't flag it even if it always false
}
Expand All @@ -392,10 +391,10 @@ object TypeTestsCasts {
def checkBind(tree: Bind)(using Context) =
checkTypePattern(defn.ThrowableType, tree.body.tpe, tree.srcPos)

private def checkTypePattern(exprTpe: Type, castTpe: Type, pos: SrcPos)(using Context) =
private def checkTypePattern(exprTpe: Type, castTpe: Type, pos: SrcPos, trustTypeApplication: Boolean = false)(using Context) =
val isUnchecked = exprTpe.widenTermRefExpr.hasAnnotation(defn.UncheckedAnnot)
if !isUnchecked then
val whyNot = whyUncheckable(exprTpe, castTpe, pos.span)
val whyNot = whyUncheckable(exprTpe, castTpe, pos.span, trustTypeApplication)
if whyNot.nonEmpty then
report.uncheckedWarning(UncheckedTypePattern(castTpe, whyNot), pos)

Expand Down
2 changes: 1 addition & 1 deletion docs/_spec/01-lexical-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Otherwise, soft keywords are treated as actual keywords in the following situati
- `as`, if it appears in a renaming import clause.
- `derives`, if it appears after an extension clause or after the name and possibly parameters of a class, trait, object, or enum definition.
- `end`, if it appears at the start of a line following a statement (i.e. definition or toplevel expression) and is followed on the same line by a single non-comment token that is:
- one of the keywords `for`, `given`, `if`, `match`, `new`, `this`, `throw`, `try`, `val`, `while`, or
- one of the keywords `for`, `given`, `if`, `match`, `new`, `this`, `throw`, `try`, `val`, `while`, `extension` or
- an identifier.
- `extension`, if it appears at the start of a statement and is followed by `(` or `[`.
- `inline`, if it is followed by any token that can start an expression.
Expand Down
76 changes: 38 additions & 38 deletions tests/bench/inductive-implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -174,49 +174,49 @@ object Test extends App {
Int ::
Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// //
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// //
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// //
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// //
// Int ::
// Int ::
Expand Down
12 changes: 12 additions & 0 deletions tests/neg/i22320.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- [E008] Not Found Error: tests/neg/i22320.scala:19:19 ----------------------------------------------------------------
19 | val z = system.z // error
| ^^^^^^^^
| value z is not a member of a.System.
| An extension method was tried, but could not be fully constructed:
|
| a.z(system)
|
| failed with:
|
| Found: (system : a.System)
| Required: a.SimulatedSystem
19 changes: 19 additions & 0 deletions tests/neg/i22320.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package a:
opaque type System = Any
opaque type SimulatedSystem <: System = System

extension (system: System)
def x: BigInt = ???
def y: BigInt = ???
end extension

extension (system: SimulatedSystem)
def z: BigInt = ???
end extension

package b:
import a.*
def issue(system: System) =
val x = system.x
val y = system.y
val z = system.z // error
127 changes: 0 additions & 127 deletions tests/pos-deep-subtype/inductive-implicits-bench.scala

This file was deleted.

17 changes: 17 additions & 0 deletions tests/warn/i22051.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
def boundary[T](body: (T => RuntimeException) => T): T =
case class Break(value: T) extends RuntimeException
try body(Break.apply)
catch case Break(t) => t // warn: pattern matching on local classes is unsound currently

def test =
boundary[Int]: EInt =>
val v: String = boundary[String]: EString =>
throw EInt(3)
v.length // a runtime error: java.lang.ClassCastException

def boundaryCorrectBehaviour[T](body: (T => RuntimeException) => T): T =
object local:
// A correct implementation, but is still treated as a local class right now
case class Break(value: T) extends RuntimeException
try body(local.Break.apply)
catch case local.Break(t) => t // warn

0 comments on commit 52ddc3b

Please sign in to comment.