@@ -22,10 +22,10 @@ import NameKinds.DefaultGetterName
22
22
import ProtoTypes ._
23
23
import Inferencing ._
24
24
import transform .TypeUtils ._
25
- import Nullables .given
25
+ import Nullables .{ postProcessByNameArgs , given }
26
26
27
27
import collection .mutable
28
- import config .Printers .{overload , typr , unapp , nullables }
28
+ import config .Printers .{overload , typr , unapp }
29
29
import TypeApplications ._
30
30
31
31
import reporting .diagnostic .Message
@@ -1047,73 +1047,6 @@ trait Applications extends Compatibility {
1047
1047
tree
1048
1048
}
1049
1049
1050
- /** Post process all arguments to by-name parameters by removing any not-null
1051
- * info that was used when typing them. Concretely:
1052
- * If an argument corresponds to a call-by-name parameter, drop all
1053
- * embedded not-null assertions of the form `x.$asInstanceOf[x.type & T]`
1054
- * where `x` is a reference to a mutable variable. If the argument still typechecks
1055
- * with the removed assertions and is still compatible with the formal parameter,
1056
- * keep it. Otherwise issue an error that the call-by-name argument was typed using
1057
- * flow assumptions about mutable variables and suggest that it is enclosed
1058
- * in a `byName(...)` call instead.
1059
- */
1060
- private def postProcessByNameArgs (fn : TermRef , app : Tree )(given ctx : Context ): Tree =
1061
- fn.widen match
1062
- case mt : MethodType if mt.paramInfos.exists(_.isInstanceOf [ExprType ]) =>
1063
- app match
1064
- case Apply (fn, args) =>
1065
- val dropNotNull = new TreeMap with
1066
- override def transform (t : Tree )(given Context ) = t match
1067
- case AssertNotNull (t0) if t0.symbol.is(Mutable ) =>
1068
- nullables.println(i " dropping $t" )
1069
- transform(t0)
1070
- case t : ValDef if ! t.symbol.is(Lazy ) => super .transform(t)
1071
- case t : MemberDef =>
1072
- // stop here since embedded references to mutable variables would be
1073
- // out of order, so they would not asserted ot be not-null anyway.
1074
- // @see Nullables.usedOutOfOrder
1075
- t
1076
- case _ => super .transform(t)
1077
-
1078
- object retyper extends ReTyper with
1079
- override def typedUnadapted (t : untpd.Tree , pt : Type , locked : TypeVars )(implicit ctx : Context ): Tree = t match
1080
- case t : ValDef if ! t.symbol.is(Lazy ) => super .typedUnadapted(t, pt, locked)
1081
- case t : MemberDef => promote(t)
1082
- case _ => super .typedUnadapted(t, pt, locked)
1083
-
1084
- def postProcess (formal : Type , arg : Tree ): Tree =
1085
- val arg1 = dropNotNull.transform(arg)
1086
- if arg1 eq arg then arg
1087
- else
1088
- val nestedCtx = ctx.fresh.setNewTyperState()
1089
- val arg2 = retyper.typed(arg1, formal)(given nestedCtx )
1090
- if nestedCtx.reporter.hasErrors || ! (arg2.tpe <:< formal) then
1091
- ctx.error(em """ This argument was typed using flow assumptions about mutable variables
1092
- |but it is passed to a by-name parameter where such flow assumptions are unsound.
1093
- |Wrapping the argument in `byName(...)` fixes the problem by disabling the flow assumptions.
1094
- |
1095
- |`byName` needs to be imported from the `scala.compiletime` package. """ ,
1096
- arg.sourcePos)
1097
- arg
1098
- else
1099
- nestedCtx.typerState.commit()
1100
- arg2
1101
-
1102
- def recur (formals : List [Type ], args : List [Tree ]): List [Tree ] = (formals, args) match
1103
- case (formal :: formalsRest, arg :: argsRest) =>
1104
- val arg1 = postProcess(formal.widenExpr.repeatedToSingle, arg)
1105
- val argsRest1 = recur(
1106
- if formal.isRepeatedParam then formals else formalsRest,
1107
- argsRest)
1108
- if (arg1 eq arg) && (argsRest1 eq argsRest) then args
1109
- else arg1 :: argsRest1
1110
- case _ => args
1111
-
1112
- tpd.cpy.Apply (app)(fn, recur(mt.paramInfos, args))
1113
- case _ => app
1114
- case _ => app
1115
- end postProcessByNameArgs
1116
-
1117
1050
def typedUnApply (tree : untpd.Apply , selType : Type )(implicit ctx : Context ): Tree = {
1118
1051
record(" typedUnApply" )
1119
1052
val Apply (qual, args) = tree
0 commit comments