@@ -2690,7 +2690,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
2690
2690
assert(! clsPrivateWithin.exists || clsPrivateWithin.isType, " clsPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
2691
2691
assert(! conPrivateWithin.exists || conPrivateWithin.isType, " consPrivateWithin must be a type symbol or `Symbol.noSymbol`" )
2692
2692
checkValidFlags(clsFlags.toTypeFlags, Flags .validClassFlags)
2693
- checkValidFlags(conFlags, Flags .validClassConstructorFlags)
2693
+ checkValidFlags(conFlags.toTermFlags , Flags .validClassConstructorFlags)
2694
2694
val cls = dotc.core.Symbols .newNormalizedClassSymbolUsingClassSymbolinParents(
2695
2695
owner,
2696
2696
name.toTypeName,
@@ -2713,33 +2713,58 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
2713
2713
if (conParamFlags.length <= clauseIdx) throwShapeException()
2714
2714
if (conParamFlags(clauseIdx).length != params.length) throwShapeException()
2715
2715
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
+ )
2717
2735
checkMethodOrPolyShape(methodType, clauseIdx = 0 )
2736
+
2718
2737
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 ] =
2720
2741
methodType match
2721
2742
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 )
2723
2746
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 )
2725
2750
case result =>
2726
2751
List ()
2727
- // Maps PolyType indexes to type parameter symbols
2752
+ // Maps PolyType indexes to type parameter symbol typerefs
2728
2753
val paramRefMap = collection.mutable.HashMap [Int , Symbol ]()
2729
2754
val paramRefRemapper = new Types .TypeMap {
2730
2755
def apply (tp : Types .Type ) = tp match {
2731
2756
case pRef : ParamRef if pRef.binder == methodType => paramRefMap(pRef.paramNum).typeRef
2732
2757
case _ => mapOver(tp)
2733
2758
}
2734
2759
}
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)
2738
2763
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))
2739
2764
paramRefMap.addOne(elementIdx, symbol)
2740
2765
cls.enter(symbol)
2741
2766
else
2742
- checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags .validClassTermParamFlags)
2767
+ checkValidFlags(conParamFlags(clauseIdx)(elementIdx).toTermFlags , Flags .validClassTermParamFlags)
2743
2768
val fixedType = paramRefRemapper(tpe)
2744
2769
cls.enter(dotc.core.Symbols .newSymbol(cls, name.toTermName, Flags .ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, conParamPrivateWithins(clauseIdx)(elementIdx)))
2745
2770
for sym <- decls(cls) do cls.enter(sym)
0 commit comments