@@ -730,35 +730,40 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
730730 val gadtSyms = typer.gadtSyms(scrutType)
731731
732732 /** Try to match pattern `pat` against scrutinee reference `scrut`. If successful add
733- * bindings for variables bound in this pattern to `bindingsBuf `.
733+ * bindings for variables bound in this pattern to `caseBindingMap `.
734734 */
735735 def reducePattern (
736- bindingsBuf : mutable.ListBuffer [ValOrDefDef ],
737- fromBuf : mutable.ListBuffer [TypeSymbol ],
738- toBuf : mutable.ListBuffer [TypeSymbol ],
736+ caseBindingMap : mutable.ListBuffer [(Symbol , MemberDef )],
739737 scrut : TermRef ,
740738 pat : Tree
741739 )(implicit ctx : Context ): Boolean = {
742740
743741 /** Create a binding of a pattern bound variable with matching part of
744742 * scrutinee as RHS and type that corresponds to RHS.
745743 */
746- def newBinding (sym : TermSymbol , rhs : Tree ): Unit = {
747- sym.info = rhs.tpe.widenTermRefExpr
748- bindingsBuf += ValDef (sym, constToLiteral(rhs)).withSpan(sym.span)
744+ def newTermBinding (sym : TermSymbol , rhs : Tree ): Unit = {
745+ val copied = sym.copy(info = rhs.tpe.widenTermRefExpr, coord = sym.coord).asTerm
746+ caseBindingMap += ((sym, ValDef (copied, constToLiteral(rhs)).withSpan(sym.span)))
747+ }
748+
749+ def newTypeBinding (sym : TypeSymbol , alias : Type ): Unit = {
750+ val copied = sym.copy(info = TypeAlias (alias), coord = sym.coord).asType
751+ caseBindingMap += ((sym, TypeDef (copied)))
749752 }
750753
751754 def searchImplicit (sym : TermSymbol , tpt : Tree ) = {
752755 val evTyper = new Typer
753- val evidence = evTyper.inferImplicitArg(tpt.tpe, tpt.span)(ctx.fresh.setTyper(evTyper))
756+ val evCtx = ctx.fresh.setTyper(evTyper)
757+ val evidence = evTyper.inferImplicitArg(tpt.tpe, tpt.span)(evCtx)
754758 evidence.tpe match {
755759 case fail : Implicits .AmbiguousImplicits =>
756760 ctx.error(evTyper.missingArgMsg(evidence, tpt.tpe, " " ), tpt.sourcePos)
757761 true // hard error: return true to stop implicit search here
758762 case fail : Implicits .SearchFailureType =>
759763 false
760764 case _ =>
761- newBinding(sym, evidence)
765+ // inliner.println(i"inferred implicit $sym: ${sym.info} with $evidence: ${evidence.tpe.widen}, ${evCtx.gadt.constraint}, ${evCtx.typerState.constraint}")
766+ newTermBinding(sym, evidence)
762767 true
763768 }
764769 }
@@ -808,27 +813,25 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
808813 extractBindVariance(SimpleIdentityMap .Empty , tpt.tpe)
809814 }
810815
816+ def addTypeBindings (typeBinds : TypeBindsMap )(implicit ctx : Context ): Unit =
817+ typeBinds.foreachBinding { case (sym, shouldBeMinimized) =>
818+ newTypeBinding(sym, ctx.gadt.approximation(sym, fromBelow = shouldBeMinimized))
819+ }
820+
811821 def registerAsGadtSyms (typeBinds : TypeBindsMap )(implicit ctx : Context ): Unit =
812822 typeBinds.foreachBinding { case (sym, _) =>
813823 val TypeBounds (lo, hi) = sym.info.bounds
814824 ctx.gadt.addBound(sym, lo, isUpper = false )
815825 ctx.gadt.addBound(sym, hi, isUpper = true )
816826 }
817827
818- def addTypeBindings (typeBinds : TypeBindsMap )(implicit ctx : Context ): Unit =
819- typeBinds.foreachBinding { case (sym, shouldBeMinimized) =>
820- val copied = sym.copy(info = TypeAlias (ctx.gadt.approximation(sym, fromBelow = shouldBeMinimized))).asType
821- fromBuf += sym
822- toBuf += copied
823- }
824-
825828 pat match {
826829 case Typed (pat1, tpt) =>
827830 val typeBinds = getTypeBindsMap(pat1, tpt)
828831 registerAsGadtSyms(typeBinds)
829832 scrut <:< tpt.tpe && {
830833 addTypeBindings(typeBinds)
831- reducePattern(bindingsBuf, fromBuf, toBuf , scrut, pat1)
834+ reducePattern(caseBindingMap , scrut, pat1)
832835 }
833836 case pat @ Bind (name : TermName , Typed (_, tpt)) if isImplicit =>
834837 val typeBinds = getTypeBindsMap(tpt, tpt)
@@ -838,8 +841,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
838841 true
839842 }
840843 case pat @ Bind (name : TermName , body) =>
841- reducePattern(bindingsBuf, fromBuf, toBuf , scrut, body) && {
842- if (name != nme.WILDCARD ) newBinding (pat.symbol.asTerm, ref(scrut))
844+ reducePattern(caseBindingMap , scrut, body) && {
845+ if (name != nme.WILDCARD ) newTermBinding (pat.symbol.asTerm, ref(scrut))
843846 true
844847 }
845848 case Ident (nme.WILDCARD ) =>
@@ -862,8 +865,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
862865 case (Nil , Nil ) => true
863866 case (pat :: pats1, selector :: selectors1) =>
864867 val elem = newSym(InlineBinderName .fresh(), Synthetic , selector.tpe.widenTermRefExpr).asTerm
865- newBinding( elem, selector)
866- reducePattern(bindingsBuf, fromBuf, toBuf , elem.termRef, pat) &&
868+ caseBindingMap += (( NoSymbol , ValDef ( elem, constToLiteral( selector)).withSpan(elem.span)) )
869+ reducePattern(caseBindingMap , elem.termRef, pat) &&
867870 reduceSubPatterns(pats1, selectors1)
868871 case _ => false
869872 }
@@ -890,7 +893,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
890893 false
891894 }
892895 case Inlined (EmptyTree , Nil , ipat) =>
893- reducePattern(bindingsBuf, fromBuf, toBuf , scrut, ipat)
896+ reducePattern(caseBindingMap , scrut, ipat)
894897 case _ => false
895898 }
896899 }
@@ -900,30 +903,34 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
900903 val scrutineeBinding = normalizeBinding(ValDef (scrutineeSym, scrutinee))
901904
902905 def reduceCase (cdef : CaseDef ): MatchRedux = {
903- val caseBindingsBuf = new mutable.ListBuffer [ValOrDefDef ]()
904- def guardOK (implicit ctx : Context ) = cdef.guard.isEmpty || {
905- typer.typed(cdef.guard, defn.BooleanType ) match {
906- case ConstantValue (true ) => true
907- case _ => false
906+ val caseBindingMap = new mutable.ListBuffer [(Symbol , MemberDef )]()
907+
908+ def substBindings (
909+ bindings : List [(Symbol , MemberDef )],
910+ bbuf : mutable.ListBuffer [MemberDef ],
911+ from : List [Symbol ], to : List [Symbol ]): (List [MemberDef ], List [Symbol ], List [Symbol ]) =
912+ bindings match {
913+ case (sym, binding) :: rest =>
914+ bbuf += binding.subst(from, to).asInstanceOf [MemberDef ]
915+ if (sym.exists) substBindings(rest, bbuf, sym :: from, binding.symbol :: to)
916+ else substBindings(rest, bbuf, from, to)
917+ case Nil => (bbuf.toList, from, to)
908918 }
909- }
910- if (! isImplicit) caseBindingsBuf += scrutineeBinding
919+
920+ if (! isImplicit) caseBindingMap += (( NoSymbol , scrutineeBinding))
911921 val gadtCtx = typer.gadtContext(gadtSyms).addMode(Mode .GADTflexible )
912- val fromBuf = mutable.ListBuffer .empty[TypeSymbol ]
913- val toBuf = mutable.ListBuffer .empty[TypeSymbol ]
914- if (reducePattern(caseBindingsBuf, fromBuf, toBuf, scrutineeSym.termRef, cdef.pat)(gadtCtx) && guardOK) {
915- val caseBindings = caseBindingsBuf.toList
916- val from = fromBuf.toList
917- val to = toBuf.toList
918- if (from.isEmpty) Some ((caseBindings, cdef.body))
919- else {
920- val Block (stats, expr) = tpd.Block (caseBindings, cdef.body).subst(from, to)
921- val typeDefs = to.collect { case sym if sym.name != tpnme.WILDCARD => tpd.TypeDef (sym).withSpan(sym.span) }
922- Some ((typeDefs ::: stats.asInstanceOf [List [MemberDef ]], expr))
922+ if (reducePattern(caseBindingMap, scrutineeSym.termRef, cdef.pat)(gadtCtx)) {
923+ val (caseBindings, from, to) = substBindings(caseBindingMap.toList, mutable.ListBuffer (), Nil , Nil )
924+ val guardOK = cdef.guard.isEmpty || {
925+ typer.typed(cdef.guard.subst(from, to), defn.BooleanType ) match {
926+ case ConstantValue (true ) => true
927+ case _ => false
928+ }
923929 }
930+ if (guardOK) Some ((caseBindings, cdef.body.subst(from, to)))
931+ else None
924932 }
925- else
926- None
933+ else None
927934 }
928935
929936 def recur (cases : List [CaseDef ]): MatchRedux = cases match {
0 commit comments