@@ -7,7 +7,7 @@ import util.Spans._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags
77import Symbols ._ , StdNames ._ , Trees ._
88import Decorators ._ , transform .SymUtils ._
99import NameKinds .{UniqueName , EvidenceParamName , DefaultGetterName }
10- import typer .FrontEnd
10+ import typer .{ FrontEnd , Namer }
1111import util .{Property , SourceFile , SourcePosition }
1212import util .NameTransformer .avoidIllegalChars
1313import collection .mutable .ListBuffer
@@ -74,46 +74,45 @@ object desugar {
7474 def derivedTree (sym : Symbol )(implicit ctx : Context ): tpd.Tree = tpd.ref(sym)
7575 }
7676
77- /** A type tree that computes its type from an existing parameter.
78- * @param suffix String difference between existing parameter (call it `P`) and parameter owning the
79- * DerivedTypeTree (call it `O`). We have: `O.name == P.name + suffix`.
80- */
81- class DerivedFromParamTree (suffix : String )(implicit @ constructorOnly src : SourceFile ) extends DerivedTypeTree {
77+ /** A type tree that computes its type from an existing parameter. */
78+ class DerivedFromParamTree ()(implicit @ constructorOnly src : SourceFile ) extends DerivedTypeTree {
8279
83- /** Make sure that for all enclosing module classes their companion classes
84- * are completed. Reason: We need the constructor of such companion classes to
85- * be completed so that OriginalSymbol attachments are pushed to DerivedTypeTrees
86- * in apply/unapply methods.
80+ /** Complete the appropriate constructors so that OriginalSymbol attachments are
81+ * pushed to DerivedTypeTrees.
8782 */
88- override def ensureCompletions (implicit ctx : Context ): Unit =
83+ override def ensureCompletions (implicit ctx : Context ): Unit = {
84+ def completeConstructor (sym : Symbol ) =
85+ sym.infoOrCompleter match {
86+ case completer : Namer # ClassCompleter =>
87+ completer.completeConstructor(sym)
88+ case _ =>
89+ }
90+
8991 if (! ctx.owner.is(Package ))
9092 if (ctx.owner.isClass) {
91- ctx.owner.ensureCompleted( )
93+ completeConstructor( ctx.owner)
9294 if (ctx.owner.is(ModuleClass ))
93- ctx.owner.linkedClass.ensureCompleted( )
95+ completeConstructor( ctx.owner.linkedClass)
9496 }
9597 else ensureCompletions(ctx.outer)
98+ }
9699
97100 /** Return info of original symbol, where all references to siblings of the
98101 * original symbol (i.e. sibling and original symbol have the same owner)
99- * are rewired to like -named* parameters or accessors in the scope enclosing
102+ * are rewired to same -named parameters or accessors in the scope enclosing
100103 * the current scope. The current scope is the scope owned by the defined symbol
101104 * itself, that's why we have to look one scope further out. If the resulting
102105 * type is an alias type, dealias it. This is necessary because the
103106 * accessor of a type parameter is a private type alias that cannot be accessed
104107 * from subclasses.
105- *
106- * (*) like-named means:
107- *
108- * parameter name == reference name ++ suffix
109108 */
110109 def derivedTree (sym : Symbol )(implicit ctx : Context ): tpd.TypeTree = {
111110 val relocate = new TypeMap {
112111 val originalOwner = sym.owner
113112 def apply (tp : Type ) = tp match {
114113 case tp : NamedType if tp.symbol.exists && (tp.symbol.owner eq originalOwner) =>
115114 val defctx = ctx.outersIterator.dropWhile(_.scope eq ctx.scope).next()
116- var local = defctx.denotNamed(tp.name ++ suffix ).suchThat(_.isParamOrAccessor).symbol
115+ var local = defctx.denotNamed(tp.name).suchThat(_.isParamOrAccessor).symbol
117116 if (local.exists) (defctx.owner.thisType select local).dealiasKeepAnnots
118117 else {
119118 def msg =
@@ -129,20 +128,19 @@ object desugar {
129128 }
130129
131130 /** A type definition copied from `tdef` with a rhs typetree derived from it */
132- def derivedTypeParam (tdef : TypeDef , suffix : String = " " )(implicit ctx : Context ): TypeDef =
131+ def derivedTypeParam (tdef : TypeDef )(implicit ctx : Context ): TypeDef =
133132 cpy.TypeDef (tdef)(
134- name = tdef.name ++ suffix,
135- rhs = DerivedFromParamTree (suffix).withSpan(tdef.rhs.span).watching(tdef)
133+ rhs = DerivedFromParamTree ().withSpan(tdef.rhs.span).watching(tdef)
136134 )
137135
138136 /** A derived type definition watching `sym` */
139137 def derivedTypeParam (sym : TypeSymbol )(implicit ctx : Context ): TypeDef =
140- TypeDef (sym.name, DerivedFromParamTree (" " ).watching(sym)).withFlags(TypeParam )
138+ TypeDef (sym.name, DerivedFromParamTree ().watching(sym)).withFlags(TypeParam )
141139
142140 /** A value definition copied from `vdef` with a tpt typetree derived from it */
143141 def derivedTermParam (vdef : ValDef )(implicit ctx : Context ): ValDef =
144142 cpy.ValDef (vdef)(
145- tpt = DerivedFromParamTree (" " ).withSpan(vdef.tpt.span).watching(vdef))
143+ tpt = DerivedFromParamTree ().withSpan(vdef.tpt.span).watching(vdef))
146144
147145// ----- Desugar methods -------------------------------------------------
148146
@@ -269,8 +267,8 @@ object desugar {
269267 def defaultGetter : DefDef =
270268 DefDef (
271269 name = DefaultGetterName (methName, n),
272- tparams = meth.tparams.map(tparam => dropContextBounds(toDefParam(tparam))),
273- vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam), n),
270+ tparams = meth.tparams.map(tparam => dropContextBounds(toDefParam(tparam, keepAnnotations = true ))),
271+ vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam(_, keepAnnotations = true ) ), n),
274272 tpt = TypeTree (),
275273 rhs = vparam.rhs
276274 )
@@ -374,10 +372,16 @@ object desugar {
374372
375373 @ sharable private val synthetic = Modifiers (Synthetic )
376374
377- private def toDefParam (tparam : TypeDef ): TypeDef =
378- tparam.withMods(tparam.rawMods & EmptyFlags | Param )
379- private def toDefParam (vparam : ValDef ): ValDef =
380- vparam.withMods(vparam.rawMods & (GivenOrImplicit | Erased ) | Param )
375+ private def toDefParam (tparam : TypeDef , keepAnnotations : Boolean ): TypeDef = {
376+ var mods = tparam.rawMods
377+ if (! keepAnnotations) mods = mods.withAnnotations(Nil )
378+ tparam.withMods(mods & EmptyFlags | Param )
379+ }
380+ private def toDefParam (vparam : ValDef , keepAnnotations : Boolean ): ValDef = {
381+ var mods = vparam.rawMods
382+ if (! keepAnnotations) mods = mods.withAnnotations(Nil )
383+ vparam.withMods(mods & (GivenOrImplicit | Erased ) | Param )
384+ }
381385
382386 /** The expansion of a class definition. See inline comments for what is involved */
383387 def classDef (cdef : TypeDef )(implicit ctx : Context ): Tree = {
@@ -439,7 +443,7 @@ object desugar {
439443 else originalTparams
440444 }
441445 else originalTparams
442- val constrTparams = impliedTparams.map(toDefParam)
446+ val constrTparams = impliedTparams.map(toDefParam(_, keepAnnotations = false ) )
443447 val constrVparamss =
444448 if (originalVparamss.isEmpty) { // ensure parameter list is non-empty
445449 if (isCaseClass && originalTparams.isEmpty)
@@ -449,7 +453,7 @@ object desugar {
449453 ctx.error(" Case classes should have a non-implicit parameter list" , namePos)
450454 ListOfNil
451455 }
452- else originalVparamss.nestedMap(toDefParam)
456+ else originalVparamss.nestedMap(toDefParam(_, keepAnnotations = false ) )
453457 val constr = cpy.DefDef (constr1)(tparams = constrTparams, vparamss = constrVparamss)
454458
455459 val (normalizedBody, enumCases, enumCompanionRef) = {
@@ -461,7 +465,7 @@ object desugar {
461465 defDef(
462466 addEvidenceParams(
463467 cpy.DefDef (ddef)(tparams = constrTparams),
464- evidenceParams(constr1).map(toDefParam))))
468+ evidenceParams(constr1).map(toDefParam(_, keepAnnotations = false ) ))))
465469 case stat =>
466470 stat
467471 }
@@ -484,8 +488,19 @@ object desugar {
484488
485489 def anyRef = ref(defn.AnyRefAlias .typeRef)
486490
487- val derivedTparams = constrTparams.map(derivedTypeParam(_))
488- val derivedVparamss = constrVparamss.nestedMap(derivedTermParam(_))
491+ // Annotations are dropped from the constructor parameters but should be
492+ // preserved in all derived parameters.
493+ val derivedTparams = {
494+ val impliedTparamsIt = impliedTparams.toIterator
495+ constrTparams.map(tparam => derivedTypeParam(tparam)
496+ .withAnnotations(impliedTparamsIt.next().mods.annotations))
497+ }
498+ val derivedVparamss = {
499+ val constrVparamsIt = constrVparamss.toIterator.flatten
500+ constrVparamss.nestedMap(vparam => derivedTermParam(vparam)
501+ .withAnnotations(constrVparamsIt.next().mods.annotations))
502+ }
503+
489504 val arity = constrVparamss.head.length
490505
491506 val classTycon : Tree = TypeRefTree () // watching is set at end of method
@@ -774,16 +789,20 @@ object desugar {
774789 }
775790
776791 val cdef1 = addEnumFlags {
777- val originalTparamsIt = impliedTparams.toIterator
778- val originalVparamsIt = originalVparamss.toIterator.flatten
779- val tparamAccessors = derivedTparams.map(_.withMods(originalTparamsIt.next().mods))
792+ val tparamAccessors = {
793+ val impliedTparamsIt = impliedTparams.toIterator
794+ derivedTparams.map(_.withMods(impliedTparamsIt.next().mods))
795+ }
780796 val caseAccessor = if (isCaseClass) CaseAccessor else EmptyFlags
781- val vparamAccessors = derivedVparamss match {
782- case first :: rest =>
783- first.map(_.withMods(originalVparamsIt.next().mods | caseAccessor)) ++
784- rest.flatten.map(_.withMods(originalVparamsIt.next().mods))
785- case _ =>
786- Nil
797+ val vparamAccessors = {
798+ val originalVparamsIt = originalVparamss.toIterator.flatten
799+ derivedVparamss match {
800+ case first :: rest =>
801+ first.map(_.withMods(originalVparamsIt.next().mods | caseAccessor)) ++
802+ rest.flatten.map(_.withMods(originalVparamsIt.next().mods))
803+ case _ =>
804+ Nil
805+ }
787806 }
788807 cpy.TypeDef (cdef : TypeDef )(
789808 name = className,
0 commit comments