@@ -468,44 +468,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
468468 else tp3
469469 end transformExplicitType
470470
471- /** Substitute parameter symbols in `from` to paramRefs in corresponding
472- * method or poly types `to`. We use a single BiTypeMap to do everything.
473- * @param from a list of lists of type or term parameter symbols of a curried method
474- * @param to a list of method or poly types corresponding one-to-one to the parameter lists
475- */
476- private class SubstParams (from : List [List [Symbol ]], to : List [LambdaType ])(using Context )
477- extends DeepTypeMap , BiTypeMap :
478-
479- def apply (t : Type ): Type = t match
480- case t : NamedType =>
481- if t.prefix == NoPrefix then
482- val sym = t.symbol
483- def outer (froms : List [List [Symbol ]], tos : List [LambdaType ]): Type =
484- def inner (from : List [Symbol ], to : List [ParamRef ]): Type =
485- if from.isEmpty then outer(froms.tail, tos.tail)
486- else if sym eq from.head then to.head
487- else inner(from.tail, to.tail)
488- if tos.isEmpty then t
489- else inner(froms.head, tos.head.paramRefs)
490- outer(from, to)
491- else t.derivedSelect(apply(t.prefix))
492- case _ =>
493- mapOver(t)
494-
495- lazy val inverse = new BiTypeMap :
496- override def toString = " SubstParams.inverse"
497- def apply (t : Type ): Type = t match
498- case t : ParamRef =>
499- def recur (from : List [LambdaType ], to : List [List [Symbol ]]): Type =
500- if from.isEmpty then t
501- else if t.binder eq from.head then to.head(t.paramNum).namedType
502- else recur(from.tail, to.tail)
503- recur(to, from)
504- case _ =>
505- mapOver(t)
506- def inverse = SubstParams .this
507- end SubstParams
508-
509471 /** Update info of `sym` for CheckCaptures phase only */
510472 private def updateInfo (sym : Symbol , info : Type )(using Context ) =
511473 toBeUpdated += sym
@@ -664,44 +626,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
664626 def signatureChanges =
665627 tree.tpt.hasNuType || paramSignatureChanges
666628
667- // Replace an existing symbol info with inferred types where capture sets of
668- // TypeParamRefs and TermParamRefs are put in correspondence by BiTypeMaps with the
669- // capture sets of the types of the method's parameter symbols and result type.
670- def integrateRT (
671- info : Type , // symbol info to replace
672- psymss : List [List [Symbol ]], // the local (type and term) parameter symbols corresponding to `info`
673- resType : Type , // the locally computed return type
674- prevPsymss : List [List [Symbol ]], // the local parameter symbols seen previously in reverse order
675- prevLambdas : List [LambdaType ] // the outer method and polytypes generated previously in reverse order
676- ): Type =
677- info match
678- case mt : MethodOrPoly =>
679- val psyms = psymss.head
680- // TODO: the substitution does not work for param-dependent method types.
681- // For example, `(x: T, y: x.f.type) => Unit`. In this case, when we
682- // substitute `x.f.type`, `x` becomes a `TermParamRef`. But the new method
683- // type is still under initialization and `paramInfos` is still `null`,
684- // so the new `NamedType` will not have a denotation.
685- def adaptedInfo (psym : Symbol , info : mt.PInfo ): mt.PInfo = mt.companion match
686- case mtc : MethodTypeCompanion => mtc.adaptParamInfo(psym, info).asInstanceOf [mt.PInfo ]
687- case _ => info
688- mt.companion(mt.paramNames)(
689- mt1 =>
690- if ! paramSignatureChanges && ! mt.isParamDependent && prevLambdas.isEmpty then
691- mt.paramInfos
692- else
693- val subst = SubstParams (psyms :: prevPsymss, mt1 :: prevLambdas)
694- psyms.map(psym => adaptedInfo(psym, subst(root.freshToCap(psym.nextInfo)).asInstanceOf [mt.PInfo ])),
695- mt1 =>
696- integrateRT(mt.resType, psymss.tail, resType, psyms :: prevPsymss, mt1 :: prevLambdas)
697- )
698- case info : ExprType =>
699- info.derivedExprType(resType =
700- integrateRT(info.resType, psymss, resType, prevPsymss, prevLambdas))
701- case info =>
702- if prevLambdas.isEmpty then resType
703- else SubstParams (prevPsymss, prevLambdas)(resType)
704-
705629 def paramsToCap (mt : Type )(using Context ): Type = mt match
706630 case mt : MethodType =>
707631 mt.derivedLambdaType(
@@ -714,52 +638,30 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
714638 // If there's a change in the signature, update the info of `sym`
715639 if sym.exists && signatureChanges then
716640 val updatedInfo =
717- if ccConfig.newScheme then
718- val paramSymss = sym.paramSymss
719- def newInfo (using Context ) = // will be run in this or next phase
720- root.toResultInResults(report.error(_, tree.srcPos)):
721- if sym.is(Method ) then
722- paramsToCap(methodType(paramSymss, localReturnType))
723- else tree.tpt.nuType
724- if tree.tpt.isInstanceOf [InferredTypeTree ]
725- && ! sym.is(Param ) && ! sym.is(ParamAccessor )
726- then
727- val prevInfo = sym.info
728- new LazyType :
729- def complete (denot : SymDenotation )(using Context ) =
730- assert(ctx.phase == thisPhase.next, i " $sym" )
731- sym.info = prevInfo // set info provisionally so we can analyze the symbol in recheck
732- completeDef(tree, sym, this )
733- sym.info = newInfo
734- .showing(i " new info of $sym = $result" , capt)
735- else if sym.is(Method ) then
736- new LazyType :
737- def complete (denot : SymDenotation )(using Context ) =
738- sym.info = newInfo
739- .showing(i " new info of $sym = $result" , capt)
740- else newInfo
741- else
742- val newInfo =
743- root.toResultInResults(report.error(_, tree.srcPos)):
744- integrateRT(sym.info, sym.paramSymss, localReturnType, Nil , Nil )
745- .showing(i " update info $sym: ${sym.info} = $result" , capt)
746- if sym.isAnonymousFunction
747- || sym.is(Param )
748- || sym.is(ParamAccessor )
749- || sym.isPrimaryConstructor
750- then
751- // closures are handled specially; the newInfo is constrained from
752- // the expected type and only afterwards we recheck the definition
753- newInfo
754- else new LazyType :
755- // infos of other methods are determined from their definitions, which
756- // are checked on demand
641+
642+ val paramSymss = sym.paramSymss
643+ def newInfo (using Context ) = // will be run in this or next phase
644+ root.toResultInResults(report.error(_, tree.srcPos)):
645+ if sym.is(Method ) then
646+ paramsToCap(methodType(paramSymss, localReturnType))
647+ else tree.tpt.nuType
648+ if tree.tpt.isInstanceOf [InferredTypeTree ]
649+ && ! sym.is(Param ) && ! sym.is(ParamAccessor )
650+ then
651+ val prevInfo = sym.info
652+ new LazyType :
757653 def complete (denot : SymDenotation )(using Context ) =
758654 assert(ctx.phase == thisPhase.next, i " $sym" )
759- capt.println(i " forcing $sym, printing = ${ctx.mode.is(Mode .Printing )}" )
760- // if ctx.mode.is(Mode.Printing) then new Error().printStackTrace()
761- sym.info = newInfo
655+ sym.info = prevInfo // set info provisionally so we can analyze the symbol in recheck
762656 completeDef(tree, sym, this )
657+ sym.info = newInfo
658+ .showing(i " new info of $sym = $result" , capt)
659+ else if sym.is(Method ) then
660+ new LazyType :
661+ def complete (denot : SymDenotation )(using Context ) =
662+ sym.info = newInfo
663+ .showing(i " new info of $sym = $result" , capt)
664+ else newInfo
763665 updateInfo(sym, updatedInfo)
764666
765667 case tree : Bind =>
0 commit comments