-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix more problems detected by fuzzing in #4389 #4411
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
} | ||
recur(buf, remaining) |
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.
at this point remaining = Thicket(elems) :: remaining1
so isn't this call equivalent to the one in the else branch below?
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.
Indeed it is. Scope for simplification, then.
def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context): Tree = track("typedClassDef") { | ||
if (!cls.info.isInstanceOf[ClassInfo]) { | ||
assert(ctx.reporter.errorsReported) | ||
return cdef.withType(UnspecifiedErrorType) |
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.
I think ideally we should have a way to recursively set the type of the tree children to maintain the invariant that a typed tree only contains typed trees.
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.
Good point, yes.
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.
Actually, that's not so easy. Sometimes, there's simply no way to proceed. And we cannot just assign an ErrorType, because a lot of trees are not typed trees, so we'd have to replace them with something else.
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.
I guess they could be replaced by ErrorTrees.
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.
In fact, maybe cdef should just be replaced by an ErrorTree since it's unusable anyway.
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.
OK, yes. Let's do that.
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.
Hmm wait. What do you mean by ErrorTree? We only have errorTree
which gives an error type to an existing tree.
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.
OK, we can replace it with an EmptyTree instead.
`checkedParentType` tests that the underlying class symbol of a type is a class. So `computeBaseClasses` should assume exactly the same property.
Rebased to master |
Also: fix a cyclic reference caused by 5252b15
- Handle the case where Thickets can contain themselves Thickets - Make it tail recursive instead of using an outer while loop
In the face of previous errors: - Constant#classBound cannot assume all class parents have good types - dominator cannot assume that all classes in an OrType inherit from the same parent
These are sometimes detected after they are computed. Need to avoid a crash in AndType due to an operand that is not a value type.
@@ -3478,7 +3478,7 @@ object Types { | |||
if (selfTypeCache == null) | |||
selfTypeCache = { | |||
val given = cls.givenSelfType | |||
if (!given.exists) appliedRef | |||
if (!given.isValueType) appliedRef |
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.
Might be worth explicitly checking that an error happened like other commits in this PR do, e.g.:
if (!given.isValueType) {
assert(!given.exists || ctx.reporter.errorsReported)
appliedRef
}
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.
The given type might be higher-kinded (in fact that's what it was in the test) but this would be detected only later.
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.
OK, in that case maybe just add a comment explaining that non-value types self can only happen with erroneous code? Otherwise readers of this code might be puzzled.
/** The result type of `mt`, where all references to parameters of `mt` are | ||
* replaced by either wildcards (if typevarsMissContext) or TypeParamRefs. | ||
*/ | ||
def resultTypeApprox(mt: MethodType)(implicit ctx: Context): Type = | ||
if (mt.isResultDependent) { | ||
def replacement(tp: Type) = | ||
if (ctx.mode.is(Mode.TypevarsMissContext)) WildcardType else newDepTypeVar(tp) | ||
if (ctx.mode.is(Mode.TypevarsMissContext) || | ||
!tp.widenExpr.isValueTypeOrWildcard) WildcardType |
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.
Here too, the error recovery case could be more explicit:
if (!tp.widenExpr.isValueTypeOrWildcard) {
assert(ctx.reporter.errorsReported)
WildcardType
}
else if (ctx.mode.is(Mode.TypevarsMissContext))
WildcardType
else ...
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.
Same response: I am not sure the error would always be detected beforehand.
In the tested case, an unApply ended up with an inserted toplevel apply method, which confused the follow-on logic. This case is now rejected.
Parent types can be aliases, so .typeSymbol can be wrong.
// A test case is CompilationTests.compileMixed | ||
pcls match { | ||
for (p <- classParents) | ||
p.classSymbol match { |
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.
incorrect indentation.
So that's all bugs in #4389, except those that contain a |
if (ctx.reporter.errorsReported) ErrorType(msg) | ||
else throw new java.lang.Error(msg) | ||
} | ||
ErrorType(msg).assertingErrorsReported(msg) |
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.
Wrong indentation.
Fix more problems detected by fuzzing in #4389