diff --git a/compiler/src/dotty/tools/dotc/inlines/InlineReducer.scala b/compiler/src/dotty/tools/dotc/inlines/InlineReducer.scala index cda74e710047..3be249eadc79 100644 --- a/compiler/src/dotty/tools/dotc/inlines/InlineReducer.scala +++ b/compiler/src/dotty/tools/dotc/inlines/InlineReducer.scala @@ -373,22 +373,16 @@ class InlineReducer(inliner: Inliner)(using Context): def reduceCase(cdef: CaseDef): MatchReduxWithGuard = { val caseBindingMap = new mutable.ListBuffer[(Symbol, MemberDef)]() - def substBindings( - bindings: List[(Symbol, MemberDef)], - bbuf: mutable.ListBuffer[MemberDef], - from: List[Symbol], to: List[Symbol]): (List[MemberDef], List[Symbol], List[Symbol]) = - bindings match { - case (sym, binding) :: rest => - bbuf += binding.subst(from, to).asInstanceOf[MemberDef] - if (sym.exists) substBindings(rest, bbuf, sym :: from, binding.symbol :: to) - else substBindings(rest, bbuf, from, to) - case Nil => (bbuf.toList, from, to) - } + def substBindings(bindings: List[(Symbol, MemberDef)]): (List[MemberDef], List[Symbol], List[Symbol]) = + val (from, to) = bindings.collect { case (sym, bnd) if sym.exists => (sym, bnd.symbol) }.unzip + to.foreach(sym => sym.info = sym.info.substSym(from, to)) + val substituted = bindings.map { case (sym, bnd) => bnd.subst(from, to) } + (substituted, from, to) if (!isImplicit) caseBindingMap += ((NoSymbol, scrutineeBinding)) val gadtCtx = ctx.fresh.setFreshGADTBounds.addMode(Mode.GadtConstraintInference) if (reducePattern(caseBindingMap, scrutineeSym.termRef, cdef.pat)(using gadtCtx)) { - val (caseBindings, from, to) = substBindings(caseBindingMap.toList, mutable.ListBuffer(), Nil, Nil) + val (caseBindings, from, to) = substBindings(caseBindingMap.toList) val (guardOK, canReduceGuard) = if cdef.guard.isEmpty then (true, true) else stripInlined(typer.typed(cdef.guard.subst(from, to), defn.BooleanType)) match { @@ -400,8 +394,8 @@ class InlineReducer(inliner: Inliner)(using Context): else cdef.body.subst(from, to) match case t: SubMatch => // a sub match of an inline match is also inlined reduceInlineMatch(t.selector, t.selector.tpe, t.cases, typer).map: - (subCaseBindings, rhs) => (caseBindings.map(_.subst(from, to)) ++ subCaseBindings, rhs, true) - case b => Some((caseBindings.map(_.subst(from, to)), b, true)) + (subCaseBindings, rhs) => (caseBindings ++ subCaseBindings, rhs, true) + case b => Some((caseBindings, b, true)) } else None } diff --git a/tests/pos/i24813.scala b/tests/pos/i24813.scala new file mode 100644 index 000000000000..3724d9d2b991 --- /dev/null +++ b/tests/pos/i24813.scala @@ -0,0 +1,8 @@ +object test { + class Seq[T] + inline def f[T]: T = scala.compiletime.summonFrom { + case given (Seq[t] =:= T) => new Seq[t] + } + + f[Seq[Int]] +}