Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1718,7 +1718,19 @@ trait Applications extends Compatibility {
def typedUnApply(tree: untpd.Apply, selType0: Type)(using Context): Tree = {
record("typedUnApply")
val Apply(qual, unadaptedArgs) = tree
val selType = selType0.stripNamedTuple
// If the selector type is a tuple, then try using the element types from the tree if it's itself a tuple,
// e.g., if `(a: Any, b: Any)` is matched with `x @ (_, y: Int)` then `x` should be of type `(Any, Int)`
val selType = selType0 match
case AppliedType(selCon, selArgs) if defn.isTupleClass(selCon.typeSymbol) && unadaptedArgs.length == selArgs.length =>
val newSelArgs = unadaptedArgs.zip(selArgs).map:
case (Typed(_, tpt: AppliedTypeTree), t) =>
// However, we can't do that if the args changed, e.g., if the args were patterns
typed(tpt) match
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compared to take 1, we at least use the result of this, and no longer need to check hasType

case tpt2: AppliedTypeTree if tpt.args == tpt2.args => tpt2.tpe
case _ => t
case (_, t) => t
AppliedType(selCon, newSelArgs)
case st => st.stripNamedTuple

def notAnExtractor(tree: Tree): Tree =
// prefer inner errors
Expand Down
15 changes: 15 additions & 0 deletions tests/pos/match-precise-type-unchecked.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.collection.*
import scala.util.*

val (ss: Seq[Success[Int] @unchecked], fs: Seq[Failure[Int] @unchecked]) =
Seq.empty[Try[Int]].partition(_.isSuccess).runtimeChecked

val (ss2: Seq[Success[Int]], fs2: Seq[Failure[Int]]) = Seq.empty[Try[Int]].partition(_.isSuccess).runtimeChecked match
case (s: Seq[Success[Int] @unchecked], f: Seq[Failure[Int] @unchecked]) => (s, f)

val (ss3: Seq[Success[Int]], fs3: Seq[Failure[Int]]) = Seq.empty[Try[Int]].partition(_.isSuccess).runtimeChecked match
case x @ (s: Seq[Success[Int] @unchecked], f: Seq[Failure[Int] @unchecked]) => x

val (ss4, fs4: Seq[Failure[Int]]) = Seq.empty[Try[Int]].partition(_.isSuccess).runtimeChecked match
case x @ (_, f: Seq[Failure[Int] @unchecked]) => x

4 changes: 2 additions & 2 deletions tests/semanticdb/metac.expect
Original file line number Diff line number Diff line change
Expand Up @@ -5059,8 +5059,8 @@ _empty_/Txn# => trait Txn [typeparam T <: Txn[T]] extends Object { self: Txn[T]
_empty_/Txn#[T] => typeparam T <: Txn[T]
_empty_/Txn#`<init>`(). => primary ctor <init> [typeparam T <: Txn[T]](): Txn[T]
local0 => val local out: Repr[Out]
local1 => val local inObj: Obj[In] & Repr[In]
local2 => val local outObj: Obj[Out] & Repr[Out]
local1 => val local inObj: Obj[In]
local2 => val local outObj: Obj[Out]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the source is case (inObj: Obj[In], outObj: Obj[Out]) so this makes sense to me


Occurrences:
[1:6..1:9): Txn <- _empty_/Txn#
Expand Down
Loading