Skip to content

Commit 88ef51c

Browse files
mboveltgodzik
authored andcommitted
Avoid loosing denotations of named types during integrate
1 parent f6ab96d commit 88ef51c

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3730,9 +3730,35 @@ object Types extends TypeUtils {
37303730
def integrate(tparams: List[ParamInfo], tp: Type)(using Context): Type =
37313731
(tparams: @unchecked) match {
37323732
case LambdaParam(lam, _) :: _ => tp.subst(lam, this) // This is where the precondition is necessary.
3733-
case params: List[Symbol @unchecked] => tp.subst(params, paramRefs)
3733+
case params: List[Symbol @unchecked] => IntegrateMap(params, paramRefs)(tp)
37343734
}
37353735

3736+
/** A map that replaces references to symbols in `params` by the types in
3737+
* `paramRefs`.
3738+
*
3739+
* It is similar to [[Substituters#subst]] but avoids reloading denotations
3740+
* of named types by overriding `derivedSelect`.
3741+
*
3742+
* This is needed because during integration, [[TermParamRef]]s refer to a
3743+
* [[LambdaType]] that is not yet fully constructed, in particular for wich
3744+
* `paramInfos` is `null`. In that case all [[TermParamRef]]s have
3745+
* [[NoType]] as underlying type. Reloading denotions of selections
3746+
* involving such [[TermParamRef]]s in [[NamedType#withPrefix]] could then
3747+
* result in a [[NoDenotation]], which would make later disambiguation of
3748+
* overloads impossible. See `tests/pos/annot-17242.scala` for example.
3749+
*/
3750+
private class IntegrateMap(params: List[Symbol], paramRefs: List[Type])(using Context) extends TypeMap:
3751+
override def apply(tp: Type) =
3752+
tp match
3753+
case tp: NamedType if params.contains(tp.symbol) => paramRefs(params.indexOf(tp.symbol))
3754+
case _: BoundType | _: ThisType => tp
3755+
case _ => mapOver(tp)
3756+
3757+
override def derivedSelect(tp: NamedType, pre: Type): Type =
3758+
if tp.prefix eq pre then tp
3759+
else if tp.symbol.exists then NamedType(pre, tp.name, tp.denot.asSeenFrom(pre))
3760+
else NamedType(pre, tp.name)
3761+
37363762
final def derivedLambdaType(paramNames: List[ThisName] = this.paramNames,
37373763
paramInfos: List[PInfo] = this.paramInfos,
37383764
resType: Type = this.resType)(using Context): This =

tests/pos/annot-17242.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// See also tests/pos/annot-21595.scala
2-
31
class local(predicate: Int) extends annotation.StaticAnnotation
42

53
def failing1(x: Int, z: Int @local(x + x)) = ()

0 commit comments

Comments
 (0)