Skip to content

Commit 7ea0d97

Browse files
committed
Make simplify replace type parameters inside method types
Simplify usually replaces a constrained TypeParamRef with the associated TypeVar, which is necessary so that the TypeParamRef is properly instantiated afterwards. But it did not recurse inside method types, since that might change signatures. This commit adds an auxiliary TypeMap over method types that just instantiates TypeParamRefs without applying any of the other transformations of simplify.
1 parent 267a7e4 commit 7ea0d97

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,13 @@ object TypeOps:
175175
val normed = tp.tryNormalize
176176
if (normed.exists) normed else mapOver
177177
case tp: MethodicType =>
178-
tp // See documentation of `Types#simplified`
178+
// See documentation of `Types#simplified`
179+
val addTypeVars = new TypeMap:
180+
val constraint = ctx.typerState.constraint
181+
def apply(t: Type): Type = t match
182+
case t: TypeParamRef => constraint.typeVarOfParam(t).orElse(t)
183+
case _ => this.mapOver(t)
184+
addTypeVars(tp)
179185
case tp: SkolemType =>
180186
// Mapping over a skolem creates a new skolem which by definition won't
181187
// be =:= to the original one.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,8 @@ object Types {
18901890
* but its simplification is `Serializable`). This means that simplification
18911891
* should never be used in a `MethodicType`, because that could
18921892
* lead to a different `signature`. Since this isn't very useful anyway,
1893-
* this method handles this by never simplifying inside a `MethodicType`.
1893+
* this method handles this by never simplifying inside a `MethodicType`,
1894+
* except for replacing type parameters with associated type variables.
18941895
*/
18951896
def simplified(using Context): Type = TypeOps.simplify(this, null)
18961897

tests/pos/i15428.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import reflect.Selectable.reflectiveSelectable
2+
3+
trait Foo:
4+
def f(): Long
5+
6+
def h() = k((_: Foo) => ???)
7+
8+
trait Bar[TB]
9+
given Bar[Foo] = ???
10+
11+
def k[Tk, Ptr <: { def f(): Tk }](function: Ptr => Int)(using alloc: Bar[Ptr]): Tk = ???

0 commit comments

Comments
 (0)