@@ -406,7 +406,6 @@ class Semantic {
406
406
given Trace = trace1
407
407
val cls = target.owner.enclosingClass.asClass
408
408
val ddef = target.defTree.asInstanceOf [DefDef ]
409
- // try early promotion here; if returns error, returns cold
410
409
val env2 = Env (ddef, args.map(_.value).widenArgs)
411
410
if target.isPrimaryConstructor then
412
411
given Env = env2
@@ -497,6 +496,48 @@ class Semantic {
497
496
Result (value2, errors)
498
497
}
499
498
}
499
+
500
+ def accessLocal (tmref : TermRef , klass : ClassSymbol , source : Tree ): Contextual [Result ] =
501
+ val sym = tmref.symbol
502
+
503
+ def default () = Result (Hot , Nil )
504
+
505
+ if sym.is(Flags .Param ) && sym.owner.isConstructor then
506
+ // instances of local classes inside secondary constructors cannot
507
+ // reach here, as those values are abstracted by Cold instead of Warm.
508
+ // This enables us to simplify the domain without sacrificing
509
+ // expressiveness nor soundess, as local classes inside secondary
510
+ // constructors are uncommon.
511
+ if sym.isContainedIn(klass) then
512
+ Result (env.lookup(sym), Nil )
513
+ else
514
+ // We don't know much about secondary constructor parameters in outer scope.
515
+ // It's always safe to approximate them with `Cold`.
516
+ Result (Cold , Nil )
517
+ else if sym.is(Flags .Param ) then
518
+ default()
519
+ else
520
+ sym.defTree match {
521
+ case vdef : ValDef =>
522
+ // resolve this for local variable
523
+ val enclosingClass = sym.owner.enclosingClass.asClass
524
+ val thisValue2 = resolveThis(enclosingClass, value, klass, source)
525
+ thisValue2 match {
526
+ case Hot => Result (Hot , Errors .empty)
527
+
528
+ case Cold => Result (Cold , Nil )
529
+
530
+ case addr : Addr =>
531
+ val res = eval(vdef.rhs, addr, klass)
532
+ if res.value.promote(" Try promote" , source).isEmpty then Result (Hot , Errors .empty) else res
533
+
534
+ case _ =>
535
+ report.error(" unexpected defTree when accessing local variable, sym = " + sym.show + " , defTree = " + sym.defTree.show, source)
536
+ default()
537
+ }
538
+
539
+ case _ => default()
540
+ }
500
541
end extension
501
542
502
543
// ----- Promotion ----------------------------------------------------
@@ -694,7 +735,7 @@ class Semantic {
694
735
}
695
736
696
737
/** Evaluate a list of expressions */
697
- def eval (exprs : List [Tree ], thisV : Addr , klass : ClassSymbol ): Contextual [List [Result ]] =
738
+ def eval (exprs : List [Tree ], thisV : Addr , klass : ClassSymbol ): Contextual [List [Result ]] =
698
739
exprs.map { expr => eval(expr, thisV, klass) }
699
740
700
741
/** Evaluate arguments of methods */
@@ -857,8 +898,7 @@ class Semantic {
857
898
case vdef : ValDef =>
858
899
// local val definition
859
900
// TODO: support explicit @cold annotation for local definitions
860
- eval(vdef.rhs, thisV, klass, true )
861
- // .ensureHot("Local definitions may only hold initialized values", vdef)
901
+ eval(vdef.rhs, thisV, klass, cacheResult = true )
862
902
863
903
case ddef : DefDef =>
864
904
// local method
@@ -886,43 +926,7 @@ class Semantic {
886
926
Result (Hot , Errors .empty)
887
927
888
928
case tmref : TermRef if tmref.prefix == NoPrefix =>
889
- val sym = tmref.symbol
890
-
891
- def default () = Result (Hot , Nil )
892
-
893
- if sym.is(Flags .Param ) && sym.owner.isConstructor then
894
- // instances of local classes inside secondary constructors cannot
895
- // reach here, as those values are abstracted by Cold instead of Warm.
896
- // This enables us to simplify the domain without sacrificing
897
- // expressiveness nor soundess, as local classes inside secondary
898
- // constructors are uncommon.
899
- if sym.isContainedIn(klass) then
900
- Result (env.lookup(sym), Nil )
901
- else
902
- // We don't know much about secondary constructor parameters in outer scope.
903
- // It's always safe to approximate them with `Cold`.
904
- Result (Cold , Nil )
905
- else
906
- sym.defTree match {
907
- case vdef : ValDef => {
908
- // resolve this for local variable
909
- val enclosingClass = sym.owner.enclosingClass.asClass
910
- val thisValue2 = resolveThis(enclosingClass, thisV, klass, source)
911
- thisValue2 match {
912
- case Hot => Result (Hot , Errors .empty)
913
- case Cold => {
914
- val error = AccessCold (sym, source, trace.toVector)
915
- Result (Hot , error :: Nil )
916
- }
917
- case addr : Addr => {
918
- val res = eval(vdef.rhs, addr, klass)
919
- if res.value.promote(" Try promote" , source).isEmpty then Result (Hot , Errors .empty) else res
920
- }
921
- case _ => ???
922
- }
923
- }
924
- case _ => default()
925
- }
929
+ thisV.accessLocal(tmref, klass, source)
926
930
927
931
case tmref : TermRef =>
928
932
cases(tmref.prefix, thisV, klass, source).select(tmref.symbol, source)
0 commit comments