Skip to content

Commit 58141e1

Browse files
committed
Fix implcit use check and override check on repeared
1 parent ae3690b commit 58141e1

File tree

5 files changed

+19
-13
lines changed

5 files changed

+19
-13
lines changed

compiler/src/dotty/tools/dotc/core/NullOpsDecorator.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ object NullOpsDecorator {
3333
if (tp1s ne tp1) && (tp2s ne tp2) then
3434
tp.derivedAndType(tp1s, tp2s)
3535
else tp
36+
case tp @ TypeBounds(lo, hi) =>
37+
tp.derivedTypeBounds(strip(lo), strip(hi))
3638
case tp => tp
3739
}
3840
if tpStriped ne tpWiden then tpStriped else tp

compiler/src/dotty/tools/dotc/core/TypeErasure.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import transform.ValueClasses._
1111
import transform.TypeUtils._
1212
import transform.ContextFunctionResults._
1313
import Decorators._
14+
import NullOpsDecorator._
1415
import Definitions.MaxImplementedFunctionArity
1516
import scala.annotation.tailrec
1617

@@ -514,8 +515,11 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
514515
private def eraseArray(tp: Type)(implicit ctx: Context) = {
515516
val defn.ArrayOf(elemtp) = tp
516517
if (classify(elemtp).derivesFrom(defn.NullClass)) JavaArrayType(defn.ObjectType)
517-
else if (isUnboundedGeneric(elemtp) && !isJava) defn.ObjectType
518-
else JavaArrayType(erasureFn(isJava, semiEraseVCs = false, isConstructor, wildcardOK)(elemtp))
518+
else {
519+
val elemtp1 = if (ctx.explicitNulls) elemtp.stripNull else elemtp
520+
if (isUnboundedGeneric(elemtp1) && !isJava) defn.ObjectType
521+
else JavaArrayType(erasureFn(isJava, semiEraseVCs = false, isConstructor, wildcardOK)(elemtp1))
522+
}
519523
}
520524

521525
private def erasePair(tp: Type)(implicit ctx: Context): Type = {

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import TreeInfo._
1515
import ProtoTypes._
1616
import Scopes._
1717
import CheckRealizable._
18+
import NullOpsDecorator._
1819
import ErrorReporting.errorTree
1920
import rewrites.Rewrites.patch
2021
import util.Spans.Span
@@ -775,17 +776,18 @@ trait Checking {
775776
* - it is defined in Predef
776777
* - it is the scala.reflect.Selectable.reflectiveSelectable conversion
777778
*/
778-
def checkImplicitConversionUseOK(sym: Symbol, posd: Positioned)(using Context): Unit =
779+
def checkImplicitConversionUseOK(sym: Symbol, tpe: Type, posd: Positioned)(using Context): Unit =
779780
if (sym.exists) {
780781
val conv =
781782
if (sym.isOneOf(GivenOrImplicit) || sym.info.isErroneous) sym
782783
else {
783784
assert(sym.name == nme.apply || ctx.reporter.errorsReported)
784785
sym.owner
785786
}
787+
val tpe1 = if ctx.explicitNulls then tpe.stripNull else tpe
786788
val conversionOK =
787789
conv.is(Synthetic) ||
788-
sym.info.finalResultType.classSymbols.exists(_.isLinkedWith(conv.owner)) ||
790+
tpe1.classSymbols.exists(_.isLinkedWith(conv.owner)) ||
789791
defn.isPredefClass(conv.owner) ||
790792
conv.name == nme.reflectiveSelectable && conv.maybeOwner.maybeOwner.maybeOwner == defn.ScalaPackageClass
791793
if (!conversionOK)
@@ -1220,7 +1222,7 @@ trait NoChecking extends ReChecking {
12201222
override def checkStable(tp: Type, pos: SourcePosition, kind: String)(using Context): Unit = ()
12211223
override def checkClassType(tp: Type, pos: SourcePosition, traitReq: Boolean, stablePrefixReq: Boolean)(using Context): Type = tp
12221224
override def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit = ()
1223-
override def checkImplicitConversionUseOK(sym: Symbol, posd: Positioned)(using Context): Unit = ()
1225+
override def checkImplicitConversionUseOK(sym: Symbol, tpe: Type, posd: Positioned)(using Context): Unit = ()
12241226
override def checkFeasibleParent(tp: Type, pos: SourcePosition, where: => String = "")(using Context): Type = tp
12251227
override def checkInlineConformant(tpt: Tree, tree: Tree, sym: Symbol)(using Context): Unit = ()
12261228
override def checkNoAlphaConflict(stats: List[Tree])(using Context): Unit = ()

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,15 +3437,15 @@ class Typer extends Namer
34373437
case SearchSuccess(found: ExtMethodApply, _, _) =>
34383438
found // nothing to check or adapt for extension method applications
34393439
case SearchSuccess(found, ref, _) =>
3440-
checkImplicitConversionUseOK(ref.symbol, t.posd)
3440+
checkImplicitConversionUseOK(ref.symbol, found.typeOpt, t.posd)
34413441
readapt(found)(using ctx.retractMode(Mode.ImplicitsEnabled))
34423442
case failure: SearchFailure =>
34433443
fail(failure)
34443444
}
34453445
}
34463446

34473447
def tryUnsafeNullConver(fail: => Tree): Tree =
3448-
// If explicitNulls and unsafeNulls are enabled, and
3448+
// If explicitNulls and unsafeNulls are enabled, and
34493449
if ctx.explicitNulls && config.Feature.enabled(nme.unsafeNulls) &&
34503450
tree.tpe.isUnsafeConvertable(pt) then {
34513451
tree.cast(pt)

tests/explicit-nulls/pos/override-java-varargs/S.scala

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
// TODO: currently, OverridingParis cannot find bar in S1
2-
//
3-
// class S1 extends J {
4-
// override def foo(x: (String | Null)*): Unit = ???
5-
// override def bar(x: String | Null, y: (String | Null)*): Unit = ???
6-
// }
1+
class S1 extends J {
2+
override def foo(x: (String | Null)*): Unit = ???
3+
override def bar(x: String | Null, y: (String | Null)*): Unit = ???
4+
}
75

86
class S2 extends J {
97
override def foo(x: String*): Unit = ???

0 commit comments

Comments
 (0)