-
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
Changes from all commits
09eb5f7
77f75b7
297c216
5597dd0
de58653
a6ba33b
64e36f1
f7c46af
f8f5176
5ad42d1
c3bd95a
5f9f3a7
690321d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,9 +142,12 @@ object Types { | |
/** Is this type a value type? */ | ||
final def isValueType: Boolean = this.isInstanceOf[ValueType] | ||
|
||
/** Is the is value type or type lambda? */ | ||
/** Is this a value type or a type lambda? */ | ||
final def isValueTypeOrLambda: Boolean = isValueType || this.isInstanceOf[TypeLambda] | ||
|
||
/** Is this a value type or a wildcard? */ | ||
final def isValueTypeOrWildcard: Boolean = isValueType || this.isInstanceOf[WildcardType] | ||
|
||
/** Does this type denote a stable reference (i.e. singleton type)? */ | ||
final def isStable(implicit ctx: Context): Boolean = stripTypeVar match { | ||
case tp: TermRef => tp.termSymbol.isStable && tp.prefix.isStable || tp.info.isStable | ||
|
@@ -589,13 +592,14 @@ object Types { | |
|
||
def goRefined(tp: RefinedType) = { | ||
val pdenot = go(tp.parent) | ||
val pinfo = pdenot.info | ||
val rinfo = tp.refinedInfo | ||
if (name.isTypeName) { // simplified case that runs more efficiently | ||
if (name.isTypeName && !pinfo.isInstanceOf[ClassInfo]) { // simplified case that runs more efficiently | ||
val jointInfo = | ||
if (rinfo.isAlias) rinfo | ||
else if (pdenot.info.isAlias) pdenot.info | ||
else if (ctx.pendingMemberSearches.contains(name)) pdenot.info safe_& rinfo | ||
else pdenot.info recoverable_& rinfo | ||
else if (pinfo.isAlias) pinfo | ||
else if (ctx.pendingMemberSearches.contains(name)) pinfo safe_& rinfo | ||
else pinfo recoverable_& rinfo | ||
pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, jointInfo) | ||
} else { | ||
pdenot & ( | ||
|
@@ -1523,11 +1527,8 @@ object Types { | |
/** A marker trait for types that can be types of values or prototypes of value types */ | ||
trait ValueTypeOrProto extends TermType | ||
|
||
/** A marker trait for types that can be types of values or wildcards */ | ||
trait ValueTypeOrWildcard extends TermType | ||
|
||
/** A marker trait for types that can be types of values or that are higher-kinded */ | ||
trait ValueType extends ValueTypeOrProto with ValueTypeOrWildcard | ||
trait ValueType extends ValueTypeOrProto | ||
|
||
/** A marker trait for types that are guaranteed to contain only a | ||
* single non-null value (they might contain null in addition). | ||
|
@@ -2479,8 +2480,8 @@ object Types { | |
|
||
object AndType { | ||
def apply(tp1: Type, tp2: Type)(implicit ctx: Context): AndType = { | ||
assert(tp1.isInstanceOf[ValueTypeOrWildcard] && | ||
tp2.isInstanceOf[ValueTypeOrWildcard], i"$tp1 & $tp2 / " + s"$tp1 & $tp2") | ||
assert(tp1.isValueTypeOrWildcard && | ||
tp2.isValueTypeOrWildcard, i"$tp1 & $tp2 / " + s"$tp1 & $tp2") | ||
unchecked(tp1, tp2) | ||
} | ||
|
||
|
@@ -2524,8 +2525,8 @@ object Types { | |
myBaseClasses | ||
} | ||
|
||
assert(tp1.isInstanceOf[ValueTypeOrWildcard] && | ||
tp2.isInstanceOf[ValueTypeOrWildcard], s"$tp1 $tp2") | ||
assert(tp1.isValueTypeOrWildcard && | ||
tp2.isValueTypeOrWildcard, s"$tp1 $tp2") | ||
|
||
private[this] var myJoin: Type = _ | ||
private[this] var myJoinPeriod: Period = Nowhere | ||
|
@@ -3477,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 commentThe 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 commentThe 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 commentThe 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. |
||
else if (cls is Module) given | ||
else if (ctx.erasedTypes) appliedRef | ||
else AndType(given, appliedRef) | ||
|
@@ -3756,7 +3757,7 @@ object Types { | |
object TryDynamicCallType extends FlexType | ||
|
||
/** Wildcard type, possibly with bounds */ | ||
abstract case class WildcardType(optBounds: Type) extends CachedGroundType with ValueTypeOrWildcard { | ||
abstract case class WildcardType(optBounds: Type) extends CachedGroundType with TermType { | ||
def derivedWildcardType(optBounds: Type)(implicit ctx: Context) = | ||
if (optBounds eq this.optBounds) this | ||
else if (!optBounds.exists) WildcardType | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -472,16 +472,18 @@ object ProtoTypes { | |
} | ||
|
||
/** Create a new TypeVar that represents a dependent method parameter singleton */ | ||
def newDepTypeVar(tp: Type)(implicit ctx: Context): TypeVar = | ||
def newDepTypeVar(tp: Type)(implicit ctx: Context): TypeVar = { | ||
newTypeVar(TypeBounds.upper(AndType(tp.widenExpr, defn.SingletonClass.typeRef))) | ||
|
||
} | ||
/** 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 commentThe 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 commentThe 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. |
||
else newDepTypeVar(tp) | ||
mt.resultType.substParams(mt, mt.paramInfos.map(replacement)) | ||
} | ||
else mt.resultType | ||
|
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.