@@ -443,13 +443,13 @@ object desugar {
443443 private def toDefParam (tparam : TypeDef , keepAnnotations : Boolean ): TypeDef = {
444444 var mods = tparam.rawMods
445445 if (! keepAnnotations) mods = mods.withAnnotations(Nil )
446- tparam.withMods(mods & ( EmptyFlags | Sealed ) | Param )
446+ tparam.withMods(mods & EmptyFlags | Param )
447447 }
448448 private def toDefParam (vparam : ValDef , keepAnnotations : Boolean , keepDefault : Boolean ): ValDef = {
449449 var mods = vparam.rawMods
450450 if (! keepAnnotations) mods = mods.withAnnotations(Nil )
451451 val hasDefault = if keepDefault then HasDefault else EmptyFlags
452- vparam.withMods(mods & (GivenOrImplicit | Erased | hasDefault) | Param )
452+ vparam.withMods(mods & (GivenOrImplicit | Erased | hasDefault | Tracked ) | Param )
453453 }
454454
455455 def mkApply (fn : Tree , paramss : List [ParamClause ])(using Context ): Tree =
@@ -535,7 +535,7 @@ object desugar {
535535 // but not on the constructor parameters. The reverse is true for
536536 // annotations on class _value_ parameters.
537537 val constrTparams = impliedTparams.map(toDefParam(_, keepAnnotations = false ))
538- val constrVparamss =
538+ def defVparamss =
539539 if (originalVparamss.isEmpty) { // ensure parameter list is non-empty
540540 if (isCaseClass)
541541 report.error(CaseClassMissingParamList (cdef), namePos)
@@ -546,6 +546,10 @@ object desugar {
546546 ListOfNil
547547 }
548548 else originalVparamss.nestedMap(toDefParam(_, keepAnnotations = true , keepDefault = true ))
549+ val constrVparamss = defVparamss
550+ // defVparamss also needed as separate tree nodes in implicitWrappers below.
551+ // Need to be separate because they are `watch`ed in addParamRefinements.
552+ // See parsercombinators-givens.scala for a test case.
549553 val derivedTparams =
550554 constrTparams.zipWithConserve(impliedTparams)((tparam, impliedParam) =>
551555 derivedTypeParam(tparam).withAnnotations(impliedParam.mods.annotations))
@@ -623,6 +627,11 @@ object desugar {
623627 case _ => false
624628 }
625629
630+ def isRepeated (tree : Tree ): Boolean = stripByNameType(tree) match {
631+ case PostfixOp (_, Ident (tpnme.raw.STAR )) => true
632+ case _ => false
633+ }
634+
626635 def appliedRef (tycon : Tree , tparams : List [TypeDef ] = constrTparams, widenHK : Boolean = false ) = {
627636 val targs = for (tparam <- tparams) yield {
628637 val targ = refOfDef(tparam)
@@ -639,10 +648,13 @@ object desugar {
639648 appliedTypeTree(tycon, targs)
640649 }
641650
642- def isRepeated (tree : Tree ): Boolean = stripByNameType(tree) match {
643- case PostfixOp (_, Ident (tpnme.raw.STAR )) => true
644- case _ => false
645- }
651+ def addParamRefinements (core : Tree , paramss : List [List [ValDef ]]): Tree =
652+ val refinements =
653+ for params <- paramss; param <- params; if param.mods.is(Tracked ) yield
654+ ValDef (param.name, SingletonTypeTree (TermRefTree ().watching(param)), EmptyTree )
655+ .withSpan(param.span)
656+ if refinements.isEmpty then core
657+ else RefinedTypeTree (core, refinements).showing(i " refined result: $result" , Printers .desugar)
646658
647659 // a reference to the class type bound by `cdef`, with type parameters coming from the constructor
648660 val classTypeRef = appliedRef(classTycon)
@@ -864,18 +876,17 @@ object desugar {
864876 Nil
865877 }
866878 else {
867- val defParamss = constrVparamss match {
879+ val defParamss = defVparamss match
868880 case Nil :: paramss =>
869881 paramss // drop leading () that got inserted by class
870882 // TODO: drop this once we do not silently insert empty class parameters anymore
871883 case paramss => paramss
872- }
873884 val finalFlag = if ctx.settings.YcompileScala2Library .value then EmptyFlags else Final
874885 // implicit wrapper is typechecked in same scope as constructor, so
875886 // we can reuse the constructor parameters; no derived params are needed.
876887 DefDef (
877888 className.toTermName, joinParams(constrTparams, defParamss),
878- classTypeRef, creatorExpr)
889+ addParamRefinements( classTypeRef, defParamss) , creatorExpr)
879890 .withMods(companionMods | mods.flags.toTermFlags & (GivenOrImplicit | Inline ) | finalFlag)
880891 .withSpan(cdef.span) :: Nil
881892 }
@@ -904,7 +915,9 @@ object desugar {
904915 }
905916 if mods.isAllOf(Given | Inline | Transparent ) then
906917 report.error(" inline given instances cannot be trasparent" , cdef)
907- val classMods = if mods.is(Given ) then mods &~ (Inline | Transparent ) | Synthetic else mods
918+ var classMods = if mods.is(Given ) then mods &~ (Inline | Transparent ) | Synthetic else mods
919+ if vparamAccessors.exists(_.mods.is(Tracked )) then
920+ classMods |= Dependent
908921 cpy.TypeDef (cdef : TypeDef )(
909922 name = className,
910923 rhs = cpy.Template (impl)(constr, parents1, clsDerived, self1,
0 commit comments