@@ -874,11 +874,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
874
874
* 3. Two method or poly types with different (type) parameters but the same
875
875
* signature are conflicting
876
876
*
877
- * In these cases, one of the types is picked (@see andConflict).
878
- * This is arbitrary, but I believe it is analogous to forming
879
- * infeasible TypeBounds (where low bound is not a subtype of high bound).
880
- * Such TypeBounds can also be arbitrarily instantiated. In both cases we need to
881
- * make sure that such types do not actually arise in source programs.
877
+ * In these cases, a MergeError is thrown.
882
878
*/
883
879
final def andType (tp1 : Type , tp2 : Type , erased : Boolean = ctx.erasedTypes) = ctx.traceIndented(s " glb( ${tp1.show}, ${tp2.show}) " , subtyping, show = true ) {
884
880
val t1 = distributeAnd(tp1, tp2)
@@ -943,13 +939,13 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
943
939
tp2 match {
944
940
case tp2 : TypeBounds => tp1 & tp2
945
941
case tp2 : ClassInfo if tp1 contains tp2.typeRef => tp2
946
- case _ => andConflict (tp1, tp2)
942
+ case _ => mergeConflict (tp1, tp2)
947
943
}
948
944
case tp1 : ClassInfo =>
949
945
tp2 match {
950
946
case tp2 : ClassInfo if tp1.cls eq tp2.cls => tp1.derivedClassInfo(tp1.prefix & tp2.prefix)
951
947
case tp2 : TypeBounds if tp2 contains tp1.typeRef => tp1
952
- case _ => andConflict (tp1, tp2)
948
+ case _ => mergeConflict (tp1, tp2)
953
949
}
954
950
case tp1 @ MethodType (names1, formals1) =>
955
951
tp2 match {
@@ -960,7 +956,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
960
956
mergeNames(names1, names2, nme.syntheticParamName),
961
957
formals1, tp1.resultType & tp2.resultType.subst(tp2, tp1))
962
958
case _ =>
963
- andConflict (tp1, tp2)
959
+ mergeConflict (tp1, tp2)
964
960
}
965
961
case tp1 : PolyType =>
966
962
tp2 match {
@@ -969,7 +965,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
969
965
mergeNames(tp1.paramNames, tp2.paramNames, tpnme.syntheticTypeParamName),
970
966
tp1.paramBounds, tp1.resultType & tp2.resultType.subst(tp2, tp1))
971
967
case _ =>
972
- andConflict (tp1, tp2)
968
+ mergeConflict (tp1, tp2)
973
969
}
974
970
case ExprType (rt1) =>
975
971
tp2 match {
@@ -1002,13 +998,13 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1002
998
tp2 match {
1003
999
case tp2 : TypeBounds => tp1 | tp2
1004
1000
case tp2 : ClassInfo if tp1 contains tp2.typeRef => tp1
1005
- case _ => orConflict (tp1, tp2)
1001
+ case _ => mergeConflict (tp1, tp2)
1006
1002
}
1007
1003
case tp1 : ClassInfo =>
1008
1004
tp2 match {
1009
1005
case tp2 : ClassInfo if tp1.cls eq tp2.cls => tp1.derivedClassInfo(tp1.prefix | tp2.prefix)
1010
1006
case tp2 : TypeBounds if tp2 contains tp1.typeRef => tp2
1011
- case _ => orConflict (tp1, tp2)
1007
+ case _ => mergeConflict (tp1, tp2)
1012
1008
}
1013
1009
case tp1 @ MethodType (names1, formals1) =>
1014
1010
tp2 match {
@@ -1019,7 +1015,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1019
1015
mergeNames(names1, names2, nme.syntheticParamName),
1020
1016
formals1, tp1.resultType | tp2.resultType.subst(tp2, tp1))
1021
1017
case _ =>
1022
- orConflict (tp1, tp2)
1018
+ mergeConflict (tp1, tp2)
1023
1019
}
1024
1020
case tp1 : PolyType =>
1025
1021
tp2 match {
@@ -1028,7 +1024,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1028
1024
mergeNames(tp1.paramNames, tp2.paramNames, tpnme.syntheticTypeParamName),
1029
1025
tp1.paramBounds, tp1.resultType | tp2.resultType.subst(tp2, tp1))
1030
1026
case _ =>
1031
- orConflict (tp1, tp2)
1027
+ mergeConflict (tp1, tp2)
1032
1028
}
1033
1029
case ExprType (rt1) =>
1034
1030
ExprType (rt1 | tp2.widenExpr)
@@ -1040,31 +1036,16 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1040
1036
NoType
1041
1037
}
1042
1038
1043
- /** Handle `&`-conflict. If `tp2` is strictly better than `tp1` as determined
1044
- * by @see `isAsGood`, pick `tp2` as the winner otherwise pick `tp1`.
1045
- * Issue a warning and return the winner.
1046
- */
1047
- private def andConflict (tp1 : Type , tp2 : Type ): Type = {
1048
- // println(disambiguated(implicit ctx => TypeComparer.explained(_.typeComparer.isSubType(tp1, tp2)))) !!!DEBUG
1049
- val winner = if (isAsGood(tp2, tp1) && ! isAsGood(tp1, tp2)) tp2 else tp1
1050
- def msg = disambiguated { implicit ctx =>
1051
- s " ${mergeErrorMsg(tp1, tp2)} as members of one type; keeping only ${showType(winner)}"
1039
+ /** Handle merge conflict by throwing a `MergeError` exception */
1040
+ private def mergeConflict (tp1 : Type , tp2 : Type ): Type = {
1041
+ def showType (tp : Type ) = tp match {
1042
+ case ClassInfo (_, cls, _, _, _) => cls.showLocated
1043
+ case bounds : TypeBounds => i " type bounds $bounds"
1044
+ case _ => tp.show
1052
1045
}
1053
- /* !!! DEBUG
1054
- println("right not a subtype of left because:")
1055
- println(TypeComparer.explained { implicit ctx => tp2 <:< tp1})
1056
- println("left not a subtype of right because:")
1057
- println(TypeComparer.explained { implicit ctx => tp1 <:< tp2})
1058
- assert(false, s"andConflict ${tp1.show} and ${tp2.show}")
1059
- */
1060
- ctx.warning(msg, ctx.tree.pos)
1061
- winner
1046
+ throw new MergeError (s " cannot merge ${showType(tp1)} with ${showType(tp2)}" )
1062
1047
}
1063
1048
1064
- /** Handle `|`-conflict by raising a `MergeError` exception */
1065
- private def orConflict (tp1 : Type , tp2 : Type ): Type =
1066
- throw new MergeError (mergeErrorMsg(tp1, tp2))
1067
-
1068
1049
/** Merge two lists of names. If names in corresponding positions match, keep them,
1069
1050
* otherwise generate new synthetic names.
1070
1051
*/
@@ -1080,10 +1061,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1080
1061
case _ => tp.show
1081
1062
}
1082
1063
1083
- /** The error message kernel for a merge conflict */
1084
- private def mergeErrorMsg (tp1 : Type , tp2 : Type )(implicit ctx : Context ) =
1085
- s " cannot merge ${showType(tp1)} with ${showType(tp2)}"
1086
-
1087
1064
/** A comparison function to pick a winner in case of a merge conflict */
1088
1065
private def isAsGood (tp1 : Type , tp2 : Type ): Boolean = tp1 match {
1089
1066
case tp1 : ClassInfo =>
0 commit comments