@@ -2690,7 +2690,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
26902690 assert(! clsPrivateWithin.exists || clsPrivateWithin.isType, " clsPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
26912691 assert(! conPrivateWithin.exists || conPrivateWithin.isType, " consPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
26922692 checkValidFlags(clsFlags.toTypeFlags, Flags .validClassFlags)
2693- checkValidFlags(conFlags, Flags .validClassConstructorFlags)
2693+ checkValidFlags(conFlags.toTermFlags , Flags .validClassConstructorFlags)
26942694 val cls = dotc.core.Symbols .newNormalizedClassSymbolUsingClassSymbolinParents(
26952695 owner,
26962696 name.toTypeName,
@@ -2713,33 +2713,58 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
27132713 if (conParamFlags.length <= clauseIdx) throwShapeException()
27142714 if (conParamFlags(clauseIdx).length != params.length) throwShapeException()
27152715 checkMethodOrPolyShape(res, clauseIdx + 1 )
2716- case _ =>
2716+ case other =>
2717+ xCheckMacroAssert(
2718+ other.typeSymbol == cls,
2719+ " Incorrect type returned from the innermost PolyOrMethod."
2720+ )
2721+ (other, methodType) match
2722+ case (AppliedType (tycon, args), pt : PolyType ) =>
2723+ xCheckMacroAssert(
2724+ args.length == pt.typeParams.length &&
2725+ args.zip(pt.typeParams).forall {
2726+ case (arg, param) => arg == param.paramRef
2727+ },
2728+ " Constructor result type does not correspond to the declared type parameters"
2729+ )
2730+ case _ =>
2731+ xCheckMacroAssert(
2732+ ! (other.isInstanceOf [AppliedType ] || methodType.isInstanceOf [PolyType ]),
2733+ " AppliedType has to be the innermost resultTypeExp result if and only if conMethodType returns a PolyType"
2734+ )
27172735 checkMethodOrPolyShape(methodType, clauseIdx = 0 )
2736+
27182737 cls.enter(dotc.core.Symbols .newSymbol(cls, nme.CONSTRUCTOR , Flags .Synthetic | Flags .Method | conFlags, methodType, conPrivateWithin, dotty.tools.dotc.util.Spans .NoCoord ))
2719- def getParamAccessors (methodType : TypeRepr , clauseIdx : Int ): List [((String , TypeRepr , Boolean , Int ), Int )] =
2738+
2739+ case class ParamSymbolData (name : String , tpe : TypeRepr , isTypeParam : Boolean , clauseIdx : Int , elementIdx : Int )
2740+ def getParamSymbolsData (methodType : TypeRepr , clauseIdx : Int ): List [ParamSymbolData ] =
27202741 methodType match
27212742 case MethodType (paramInfosExp, resultTypeExp, res) =>
2722- paramInfosExp.zip(resultTypeExp).map(_ :* false :* clauseIdx).zipWithIndex ++ getParamAccessors(res, clauseIdx + 1 )
2743+ paramInfosExp.zip(resultTypeExp).zipWithIndex.map { case ((name, tpe), elementIdx) =>
2744+ ParamSymbolData (name, tpe, isTypeParam = false , clauseIdx, elementIdx)
2745+ } ++ getParamSymbolsData(res, clauseIdx + 1 )
27232746 case pt @ PolyType (paramNames, paramBounds, res) =>
2724- paramNames.zip(paramBounds).map(_ :* true :* clauseIdx).zipWithIndex ++ getParamAccessors(res, clauseIdx + 1 )
2747+ paramNames.zip(paramBounds).zipWithIndex.map {case ((name, tpe), elementIdx) =>
2748+ ParamSymbolData (name, tpe, isTypeParam = true , clauseIdx, elementIdx)
2749+ } ++ getParamSymbolsData(res, clauseIdx + 1 )
27252750 case result =>
27262751 List ()
2727- // Maps PolyType indexes to type parameter symbols
2752+ // Maps PolyType indexes to type parameter symbol typerefs
27282753 val paramRefMap = collection.mutable.HashMap [Int , Symbol ]()
27292754 val paramRefRemapper = new Types .TypeMap {
27302755 def apply (tp : Types .Type ) = tp match {
27312756 case pRef : ParamRef if pRef.binder == methodType => paramRefMap(pRef.paramNum).typeRef
27322757 case _ => mapOver(tp)
27332758 }
27342759 }
2735- for (( name, tpe, isType , clauseIdx) , elementIdx) <- getParamAccessors (methodType, 0 ) do
2736- if isType then
2737- checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags .validClassTypeParamFlags)
2760+ for case ParamSymbolData ( name, tpe, isTypeParam , clauseIdx, elementIdx) <- getParamSymbolsData (methodType, 0 ) do
2761+ if isTypeParam then
2762+ checkValidFlags(conParamFlags(clauseIdx)(elementIdx).toTypeFlags , Flags .validClassTypeParamFlags)
27382763 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))
27392764 paramRefMap.addOne(elementIdx, symbol)
27402765 cls.enter(symbol)
27412766 else
2742- checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags .validClassTermParamFlags)
2767+ checkValidFlags(conParamFlags(clauseIdx)(elementIdx).toTermFlags , Flags .validClassTermParamFlags)
27432768 val fixedType = paramRefRemapper(tpe)
27442769 cls.enter(dotc.core.Symbols .newSymbol(cls, name.toTermName, Flags .ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, conParamPrivateWithins(clauseIdx)(elementIdx)))
27452770 for sym <- decls(cls) do cls.enter(sym)
0 commit comments