@@ -2727,7 +2727,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
27272727 assert(! clsPrivateWithin.exists || clsPrivateWithin.isType, " clsPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
27282728 assert(! conPrivateWithin.exists || conPrivateWithin.isType, " consPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
27292729 checkValidFlags(clsFlags.toTypeFlags, Flags .validClassFlags)
2730- checkValidFlags(conFlags, Flags .validClassConstructorFlags)
2730+ checkValidFlags(conFlags.toTermFlags , Flags .validClassConstructorFlags)
27312731 val cls = dotc.core.Symbols .newNormalizedClassSymbolUsingClassSymbolinParents(
27322732 owner,
27332733 name.toTypeName,
@@ -2750,33 +2750,58 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
27502750 if (conParamFlags.length <= clauseIdx) throwShapeException()
27512751 if (conParamFlags(clauseIdx).length != params.length) throwShapeException()
27522752 checkMethodOrPolyShape(res, clauseIdx + 1 )
2753- case _ =>
2753+ case other =>
2754+ xCheckMacroAssert(
2755+ other.typeSymbol == cls,
2756+ " Incorrect type returned from the innermost PolyOrMethod."
2757+ )
2758+ (other, methodType) match
2759+ case (AppliedType (tycon, args), pt : PolyType ) =>
2760+ xCheckMacroAssert(
2761+ args.length == pt.typeParams.length &&
2762+ args.zip(pt.typeParams).forall {
2763+ case (arg, param) => arg == param.paramRef
2764+ },
2765+ " Constructor result type does not correspond to the declared type parameters"
2766+ )
2767+ case _ =>
2768+ xCheckMacroAssert(
2769+ ! (other.isInstanceOf [AppliedType ] || methodType.isInstanceOf [PolyType ]),
2770+ " AppliedType has to be the innermost resultTypeExp result if and only if conMethodType returns a PolyType"
2771+ )
27542772 checkMethodOrPolyShape(methodType, clauseIdx = 0 )
2773+
27552774 cls.enter(dotc.core.Symbols .newSymbol(cls, nme.CONSTRUCTOR , Flags .Synthetic | Flags .Method | conFlags, methodType, conPrivateWithin, dotty.tools.dotc.util.Spans .NoCoord ))
2756- def getParamAccessors (methodType : TypeRepr , clauseIdx : Int ): List [((String , TypeRepr , Boolean , Int ), Int )] =
2775+
2776+ case class ParamSymbolData (name : String , tpe : TypeRepr , isTypeParam : Boolean , clauseIdx : Int , elementIdx : Int )
2777+ def getParamSymbolsData (methodType : TypeRepr , clauseIdx : Int ): List [ParamSymbolData ] =
27572778 methodType match
27582779 case MethodType (paramInfosExp, resultTypeExp, res) =>
2759- paramInfosExp.zip(resultTypeExp).map(_ :* false :* clauseIdx).zipWithIndex ++ getParamAccessors(res, clauseIdx + 1 )
2780+ paramInfosExp.zip(resultTypeExp).zipWithIndex.map { case ((name, tpe), elementIdx) =>
2781+ ParamSymbolData (name, tpe, isTypeParam = false , clauseIdx, elementIdx)
2782+ } ++ getParamSymbolsData(res, clauseIdx + 1 )
27602783 case pt @ PolyType (paramNames, paramBounds, res) =>
2761- paramNames.zip(paramBounds).map(_ :* true :* clauseIdx).zipWithIndex ++ getParamAccessors(res, clauseIdx + 1 )
2784+ paramNames.zip(paramBounds).zipWithIndex.map {case ((name, tpe), elementIdx) =>
2785+ ParamSymbolData (name, tpe, isTypeParam = true , clauseIdx, elementIdx)
2786+ } ++ getParamSymbolsData(res, clauseIdx + 1 )
27622787 case result =>
27632788 List ()
2764- // Maps PolyType indexes to type parameter symbols
2789+ // Maps PolyType indexes to type parameter symbol typerefs
27652790 val paramRefMap = collection.mutable.HashMap [Int , Symbol ]()
27662791 val paramRefRemapper = new Types .TypeMap {
27672792 def apply (tp : Types .Type ) = tp match {
27682793 case pRef : ParamRef if pRef.binder == methodType => paramRefMap(pRef.paramNum).typeRef
27692794 case _ => mapOver(tp)
27702795 }
27712796 }
2772- for (( name, tpe, isType , clauseIdx) , elementIdx) <- getParamAccessors (methodType, 0 ) do
2773- if isType then
2774- checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags .validClassTypeParamFlags)
2797+ for case ParamSymbolData ( name, tpe, isTypeParam , clauseIdx, elementIdx) <- getParamSymbolsData (methodType, 0 ) do
2798+ if isTypeParam then
2799+ checkValidFlags(conParamFlags(clauseIdx)(elementIdx).toTypeFlags , Flags .validClassTypeParamFlags)
27752800 val symbol = dotc.core.Symbols .newSymbol(cls, name.toTypeName, Flags .Param | Flags .Deferred | Flags .Private | Flags .PrivateLocal | Flags .Local | conParamFlags(clauseIdx)(elementIdx), tpe, conParamPrivateWithins(clauseIdx)(elementIdx))
27762801 paramRefMap.addOne(elementIdx, symbol)
27772802 cls.enter(symbol)
27782803 else
2779- checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags .validClassTermParamFlags)
2804+ checkValidFlags(conParamFlags(clauseIdx)(elementIdx).toTermFlags , Flags .validClassTermParamFlags)
27802805 val fixedType = paramRefRemapper(tpe)
27812806 cls.enter(dotc.core.Symbols .newSymbol(cls, name.toTermName, Flags .ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, conParamPrivateWithins(clauseIdx)(elementIdx)))
27822807 for sym <- decls(cls) do cls.enter(sym)
0 commit comments