Skip to content

Commit b106de4

Browse files
authored
Merge pull request #15679 from dotty-staging/fix-15664
Don't ignore expected types of `New`.
2 parents e8d081c + 7c56358 commit b106de4

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed

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

+10-1
Original file line numberDiff line numberDiff line change
@@ -892,8 +892,17 @@ trait Applications extends Compatibility {
892892
def typedApply(tree: untpd.Apply, pt: Type)(using Context): Tree = {
893893

894894
def realApply(using Context): Tree = {
895+
val resultProto = tree.fun match
896+
case Select(New(_), _) if pt.isInstanceOf[ValueType] => pt
897+
// Don't ignore expected value types of `new` expressions. If we have a `new C()`
898+
// with expected type `C[T]` we want to use the type to instantiate `C`
899+
// immediately. This is necessary since `C` might _also_ have using clauses
900+
// that we want to instantiate with the best available type. See i15664.scala.
901+
case _ => IgnoredProto(pt)
902+
// Do ignore other expected result types, since there might be an implicit conversion
903+
// on the result. We could drop this if we disallow unrestricted implicit conversions.
895904
val originalProto =
896-
new FunProto(tree.args, IgnoredProto(pt))(this, tree.applyKind)(using argCtx(tree))
905+
new FunProto(tree.args, resultProto)(this, tree.applyKind)(using argCtx(tree))
897906
record("typedApply")
898907
val fun1 = typedExpr(tree.fun, originalProto)
899908

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

+17-19
Original file line numberDiff line numberDiff line change
@@ -3346,25 +3346,23 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
33463346
// try an implicit conversion or given extension
33473347
if ctx.mode.is(Mode.ImplicitsEnabled) && !tree.name.isConstructorName && qual.tpe.isValueType then
33483348
try
3349-
trace(i"try insert impl on qualifier $tree $pt") {
3350-
val selProto = selectionProto
3351-
inferView(qual, selProto) match
3352-
case SearchSuccess(found, _, _, isExtension) =>
3353-
if isExtension then return found
3354-
else
3355-
checkImplicitConversionUseOK(found)
3356-
return withoutMode(Mode.ImplicitsEnabled)(typedSelect(tree, pt, found))
3357-
case failure: SearchFailure =>
3358-
if failure.isAmbiguous then
3359-
return
3360-
if !inSelect // in a selection we will do the canDefineFurther afterwards
3361-
&& canDefineFurther(qual.tpe.widen)
3362-
then
3363-
tryExtensionOrConversion(tree, pt, mbrProto, qual, locked, compat, inSelect)
3364-
else
3365-
err.typeMismatch(qual, selProto, failure.reason) // TODO: report NotAMember instead, but need to be aware of failure
3366-
rememberSearchFailure(qual, failure)
3367-
}
3349+
val selProto = selectionProto
3350+
trace(i"try insert impl on qualifier $tree $pt") { inferView(qual, selProto) } match
3351+
case SearchSuccess(found, _, _, isExtension) =>
3352+
if isExtension then return found
3353+
else
3354+
checkImplicitConversionUseOK(found)
3355+
return withoutMode(Mode.ImplicitsEnabled)(typedSelect(tree, pt, found))
3356+
case failure: SearchFailure =>
3357+
if failure.isAmbiguous then
3358+
return
3359+
if !inSelect // in a selection we will do the canDefineFurther afterwards
3360+
&& canDefineFurther(qual.tpe.widen)
3361+
then
3362+
tryExtensionOrConversion(tree, pt, mbrProto, qual, locked, compat, inSelect)
3363+
else
3364+
err.typeMismatch(qual, selProto, failure.reason) // TODO: report NotAMember instead, but need to be aware of failure
3365+
rememberSearchFailure(qual, failure)
33683366
catch case ex: TypeError => nestedFailure(ex)
33693367

33703368
EmptyTree

tests/pos/i15664.scala

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
trait CpsMonad[F[_]]:
2+
type Context <: CpsMonadContext[F]
3+
type Aux[F[_], C <: CpsMonadContext[F]] = CpsMonad[F] { type Context = C }
4+
trait CpsMonadContext[F[_]]
5+
trait CpsMonadInstanceContext[F[_]] extends CpsMonad[F]:
6+
type Context = CpsMonadInstanceContextBody[F]
7+
class CpsMonadInstanceContextBody[F[_]](m: CpsMonadInstanceContext[F]) extends CpsMonadContext[F]
8+
class InferAsyncArg[F[_], C <: CpsMonadContext[F]](using val am: Aux[F, C])
9+
10+
sealed abstract class ZManaged[-R, +E, +A]
11+
type RManaged[-R, +A] = ZManaged[R, Throwable, A]
12+
13+
type ForZManaged[R, E] = [X] =>> ZManaged[R, E, X]
14+
given zManagedCpsMonad[R, E]: CpsMonadInstanceContext[ForZManaged[R, E]] = ???
15+
16+
// Usage
17+
def failing[R, E](using
18+
CpsMonad[ForZManaged[R, E]]
19+
): InferAsyncArg[ForZManaged[R, E], CpsMonadInstanceContextBody[ForZManaged[R, E]]] =
20+
new InferAsyncArg()
21+
22+
def compiling[R, E](using
23+
CpsMonad[ForZManaged[R, E]]
24+
) =
25+
new InferAsyncArg[ForZManaged[R, E], CpsMonadInstanceContextBody[ForZManaged[R, E]]]

0 commit comments

Comments
 (0)