@@ -593,7 +593,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
593593    typr.println(s " typed ident  $kind$name in  ${ctx.owner}" )
594594    if  ctx.mode.is(Mode .Pattern ) then 
595595      if  name ==  nme.WILDCARD  then 
596-         return  tree.withType(pt)
596+         val  wpt  =  pt match 
597+           case  pt : TermRef  =>  pt.widen
598+           case  pt =>  pt
599+         return  tree.withType(wpt)
597600      if  name ==  tpnme.WILDCARD  then 
598601        return  tree.withType(defn.AnyType )
599602      if  untpd.isVarPattern(tree) &&  name.isTermName then 
@@ -2031,7 +2034,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
20312034        val  rawSelectorTpe  =  fullyDefinedType(sel1.tpe, " pattern selector" 
20322035        val  selType  =  rawSelectorTpe match 
20332036          case  c : ConstantType  if  tree.isInline =>  c
2037+           case  ref : TermRef  =>  ref
20342038          case  otherTpe =>  otherTpe.widen
2039+         val  selTypeW  =  selType match 
2040+           case  tr : TermRef  =>  tr.widen
2041+           case  _ =>  selType
2042+ 
20352043
20362044        /**  Does `tree` has the same shape as the given match type? 
20372045         *  We only support typed patterns with empty guards, but 
@@ -2049,7 +2057,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
20492057                //  To check that pattern types correspond we need to type
20502058                //  check `pat` here and throw away the result.
20512059                val  gadtCtx :  Context  =  ctx.fresh.setFreshGADTBounds
2052-                 val  pat1  =  typedPattern(pat, selType )(using  gadtCtx)
2060+                 val  pat1  =  typedPattern(pat, selTypeW )(using  gadtCtx)
20532061                val  tpt  =  tpd.unbind(tpd.unsplice(pat1)) match 
20542062                  case  Typed (_, tpt) =>  tpt
20552063                  case  UnApply (fun, _, p1 ::  _) if  fun.symbol ==  defn.TypeTest_unapply  =>  p1
@@ -2067,7 +2075,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
20672075
20682076        val  result  =  pt.underlyingNormalizable match  {
20692077          case  mt : MatchType  if  isMatchTypeShaped(mt) => 
2070-             typedDependentMatchFinish(tree, sel1, selType , tree.cases, mt)
2078+             typedDependentMatchFinish(tree, sel1, selTypeW , tree.cases, mt)
20712079          case  _ => 
20722080            typedMatchFinish(tree, sel1, selType, tree.cases, pt)
20732081        }
@@ -2677,6 +2685,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
26772685  def  typedBind (tree : untpd.Bind , pt : Type )(using  Context ):  Tree  =  {
26782686    if  ! isFullyDefined(pt, ForceDegree .all) then 
26792687      return  errorTree(tree, em " expected type of  $tree is not fully defined " )
2688+     val  wpt  =  pt match 
2689+       case  pt : TermRef  =>  pt.widen
2690+       case  _ =>  pt
26802691    val  body1  =  typed(tree.body, pt)
26812692    body1 match  {
26822693      case  UnApply (fn, Nil , arg ::  Nil )
@@ -2705,9 +2716,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
27052716          val  symTp  = 
27062717            if  isStableIdentifierOrLiteral ||  pt.isNamedTupleType then  pt
27072718              //  need to combine tuple element types with expected named type
2708-             else  if  isWildcardStarArg(body1)
2709-                      ||  pt  ==  defn. ImplicitScrutineeTypeRef 
2710-                      ||   body1.tpe <:<  pt   //  There is some strange interaction with gadt matching.
2719+             else  if  isWildcardStarArg(body1)  ||  pt  ==  defn. ImplicitScrutineeTypeRef 
2720+             then  body1.tpe 
2721+             else   if   body1.tpe <:<  wpt   //  There is some strange interaction with gadt matching.
27112722                                         //  and implicit scopes.
27122723                                         //  run/t2755.scala fails to compile if this subtype test is omitted
27132724                                         //  and the else clause is changed to `body1.tpe & pt`. What
@@ -2717,14 +2728,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
27172728                                         //  it is Array[T] we get an implicit not found. To avoid fragility
27182729                                         //  wrt to operand order for `&`, we include the explicit subtype test here.
27192730                                         //  See also #5649.
2720-             then  body1.tpe
2731+             then 
2732+               if  ctx.mode.is(Mode .Pattern ) &&  (pt ne wpt) //  && !(body1.tpe <:< pt)
2733+               then  AndType (pt, body1.tpe)
2734+               //  then pt & body1.tpe
2735+               else  body1.tpe
27212736            else  body1.tpe match 
27222737              case  btpe : TypeRef 
27232738              if  btpe.symbol ==  defn.TupleXXLClass  &&  pt.tupleElementTypes.isDefined => 
27242739                //  leave the original tuple type; don't mix with & TupleXXL which would only obscure things
27252740                pt
27262741              case  _ => 
2727-                 pt  &  body1.tpe
2742+                 wpt  &  body1.tpe
27282743          val  sym  =  newPatternBoundSymbol(name, symTp, tree.span)
27292744          if  (pt ==  defn.ImplicitScrutineeTypeRef  ||  tree.mods.is(Given )) sym.setFlag(Given )
27302745          if  (ctx.mode.is(Mode .InPatternAlternative ))
0 commit comments