@@ -3028,7 +3028,49 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
30283028 typed(tree, pt, locked)(using ctx.withSource(tree.source))
30293029 else if ctx.run.nn.isCancelled then
30303030 tree.withType(WildcardType )
3031- else adapt(typedUnadapted(tree, pt, locked), pt, locked)
3031+ else
3032+ val tu = typedUnadapted(tree, pt, locked)
3033+ pt match
3034+ case pt : FunProto =>
3035+ extension (tpe : Type ) def getArgsPrecises : List [Boolean ] = tpe.widen match
3036+ case mt : MethodType =>
3037+ mt.paramInfos.map {
3038+ case v : TypeVar => v.origin.isPrecise
3039+ case _ => false
3040+ }
3041+ case _ => Nil
3042+ val argsPrecises = tu.tpe.getArgsPrecises
3043+ // if the function arguments are known to be precise, then we update the
3044+ // proto with this information and later propagate its state back to the
3045+ // original proto.
3046+ if (argsPrecises.contains(true ))
3047+ val ptPrecises = pt.derivedFunProto(argsPrecises = argsPrecises)
3048+ val adapted = adapt(tu, ptPrecises, locked)
3049+ pt.resetTo(ptPrecises.snapshot)
3050+ adapted
3051+ // otherwise, we need to check for overloaded function, because in that
3052+ // case we may not know if the final adapted function will be precise.
3053+ else tu.tpe match
3054+ // the function is overloaded, so we preserve the typer and proto state,
3055+ // adapt the tree, and then check if the arguments should be considered as
3056+ // precise. if so, then we need to recover the typer state and proto
3057+ // state, and re-adapt the tree with the precise enforcement.
3058+ case v : TermRef if v.isOverloaded =>
3059+ val savedTyperState = ctx.typerState.snapshot()
3060+ val savedProtoState = pt.snapshot
3061+ val adaptedMaybePrecise = adapt(tu, pt, locked)
3062+ val argsPrecises = adaptedMaybePrecise.tpe.getArgsPrecises
3063+ if (argsPrecises.contains(true ))
3064+ val ptPrecises = pt.derivedFunProto(argsPrecises = argsPrecises)
3065+ ctx.typerState.resetTo(savedTyperState)
3066+ pt.resetTo(savedProtoState)
3067+ val adapted = adapt(tu, ptPrecises, locked)
3068+ pt.resetTo(ptPrecises.snapshot)
3069+ adapted
3070+ else adaptedMaybePrecise
3071+ // the function is not overloaded or has precise arguments
3072+ case _ => adapt(tu, pt, locked)
3073+ case _ => adapt(tu, pt, locked)
30323074 }
30333075
30343076 def typed (tree : untpd.Tree , pt : Type = WildcardType )(using Context ): Tree =
0 commit comments