- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1.1k
 
Rewrite resolveThis in global init checker #23282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
798fd49    to
    1e0eb9f      
    Compare
  
    | 
               | 
          ||
| case class ScopeSet(scopes: Set[Scope]): | ||
| assert(scopes.forall(_.isRef) || scopes.forall(_.isEnv), "All scopes should have the same type!") | ||
| def isRefSet = scopes.forall(_.isRef) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we keep an assertion that isRefSet || isEnvSet?
| case _ => | ||
| report.warning("[Internal error] unexpected thisV = " + thisV + ", target = " + target.show + Trace.show, Trace.position) | ||
| Bottom | ||
| if resolveResult == Bottom && thisV.filterClass(target) == thisV then | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible that target could be a parent class of an outer class?
| 
           Here's an example of a  class A {
  var x = 42
  def change = (x = 44)
  class B {
    val i = 5
    def fooz = A.this.x // if this is an instance of class C, does A.this resolve to the C outer or to the B outer ???
    def fooz2 = A.this.x
    class D {
       def bar = fooz
       def bar2 = fooz2
    }
  }
}
class AA extends A {
  def foo = {
    //val y = 43
    val a = if(*) new A else new AAA
    class C /*outer AA*/ extends a.B /*outer A or AAA*/ {
       override val i = 6
       override def fooz2 = x
    }
    val bb: B = if(false) new a.B else new C
    val d =  new bb.D
    d.bar   // reads AA.x
    d.bar2 // reads AA.x
    }
}
d --outer-> {B or C} --outer-> {A or foo} --outer --> {A}  | 
    
1e0eb9f    to
    8b89ae9      
    Compare
  
    | 
           @olhotak @liufengyun I have added two rather complex tests, feel free to run them with scala-cli. 
 
  | 
    
| 
           The second test   | 
    
          
 It's not clear why  The following comment might help: scala3/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala Lines 1207 to 1216 in 0be2091 
  | 
    
8b89ae9    to
    f2f9df3      
    Compare
  
    | 
           [test_scala2_library_tasty]  | 
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I only have a few minor comments for consideration.
| * valsMap = sym -> val // maps variables to their values | ||
| * outersMap = sym -> ScopeSet // maps the possible outer scopes for a corresponding (parent) class | ||
| * heap.MutableData = Scope -> (valsMap, outersMap) // heap is mutable | ||
| * Config ::= (thisV: Value, scope: Scope, Heap, EnvMap) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for scope in Config to be Ref? The same question for Fun.
These are the only place where the type Scope appears. If we can remove one concept, that would be nice (Occam's razor).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: regarding the name LocalEnv, maybe we can use something like EnvAddr or EnvRef?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for
scopeinConfigto beRef? The same question forFun.These are the only place where the type
Scopeappears. If we can remove one concept, that would be nice (Occam's razor).
When evaluating the field initializers, the scope in Config would be Ref; the same holds when creating a Fun in a field initializer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: regarding the name
LocalEnv, maybe we can use something likeEnvAddrorEnvRef?
Has renamed it to EnvRef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When evaluating the field initializers, the scope in Config would be Ref; the same holds when creating a Fun in a field initializer
Thanks for explaining. In later PRs, we can consider creating an empty Env with the primary constructor for evaluating field initializers if that works.
| def initVar(field: Symbol, value: Value)(using Context, EnvMap.EnvMapMutableData) = log("Initialize " + field.show + " = " + value + " for " + this, printer) { | ||
| assert(field.is(Flags.Mutable), "Field is not mutable: " + field.show) | ||
| EnvMap.writeJoinVal(this, field, value) | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor (for future): Given that Var and Val have same logic, we can consider generalize a little the code.
f2f9df3    to
    b1d5eae      
    Compare
  
    | 
           Does anyone know why Test CLI Launchers failed? Should I push again?  | 
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM now. @EnzeXing we can merge when you think you're done with @liufengyun 's minor comments.
          
 It timed out. I restarted the job.  | 
    
b1d5eae    to
    414bd24      
    Compare
  
    | 
           I've addressed Fengyun's comments, and I think it's ready to be merged  | 
    
This PR resolves bugs in the redesigned global initialization checker; specifically, it now correctly resolves the value of
parent.thisin a child class, and removes the assertions that fail in community build projects[test_scala2_library_tasty]