-
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
@@ -287,11 +287,19 @@ class Objects(using Context @constructorOnly): | |||
def toScopeSet: ScopeSet = ScopeSet(values.asInstanceOf[Set[Scope]]) | |||
|
|||
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
?
@@ -1969,6 +1977,11 @@ class Objects(using Context @constructorOnly): | |||
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
scope
inConfig
to beRef
? The same question forFun
.These are the only place where the type
Scope
appears. 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 likeEnvAddr
orEnvRef
?
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.this
in a child class, and removes the assertions that fail in community build projects[test_scala2_library_tasty]