@@ -2727,7 +2727,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
2727
2727
assert(! clsPrivateWithin.exists || clsPrivateWithin.isType, " clsPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
2728
2728
assert(! conPrivateWithin.exists || conPrivateWithin.isType, " consPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
2729
2729
checkValidFlags(clsFlags.toTypeFlags, Flags .validClassFlags)
2730
- checkValidFlags(conFlags, Flags .validClassConstructorFlags)
2730
+ checkValidFlags(conFlags.toTermFlags , Flags .validClassConstructorFlags)
2731
2731
val cls = dotc.core.Symbols .newNormalizedClassSymbolUsingClassSymbolinParents(
2732
2732
owner,
2733
2733
name.toTypeName,
@@ -2750,33 +2750,58 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
2750
2750
if (conParamFlags.length <= clauseIdx) throwShapeException()
2751
2751
if (conParamFlags(clauseIdx).length != params.length) throwShapeException()
2752
2752
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
+ )
2754
2772
checkMethodOrPolyShape(methodType, clauseIdx = 0 )
2773
+
2755
2774
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 ] =
2757
2778
methodType match
2758
2779
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 )
2760
2783
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 )
2762
2787
case result =>
2763
2788
List ()
2764
- // Maps PolyType indexes to type parameter symbols
2789
+ // Maps PolyType indexes to type parameter symbol typerefs
2765
2790
val paramRefMap = collection.mutable.HashMap [Int , Symbol ]()
2766
2791
val paramRefRemapper = new Types .TypeMap {
2767
2792
def apply (tp : Types .Type ) = tp match {
2768
2793
case pRef : ParamRef if pRef.binder == methodType => paramRefMap(pRef.paramNum).typeRef
2769
2794
case _ => mapOver(tp)
2770
2795
}
2771
2796
}
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)
2775
2800
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))
2776
2801
paramRefMap.addOne(elementIdx, symbol)
2777
2802
cls.enter(symbol)
2778
2803
else
2779
- checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags .validClassTermParamFlags)
2804
+ checkValidFlags(conParamFlags(clauseIdx)(elementIdx).toTermFlags , Flags .validClassTermParamFlags)
2780
2805
val fixedType = paramRefRemapper(tpe)
2781
2806
cls.enter(dotc.core.Symbols .newSymbol(cls, name.toTermName, Flags .ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, conParamPrivateWithins(clauseIdx)(elementIdx)))
2782
2807
for sym <- decls(cls) do cls.enter(sym)
0 commit comments