-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[Experiment] Introduce hard ConstantTypes #14360
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
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1217,7 +1217,7 @@ object Types { | |
case _: TypeRef | _: MethodOrPoly => this // fast path for most frequent cases | ||
case tp: TermRef => // fast path for next most frequent case | ||
if tp.isOverloaded then tp else tp.underlying.widen | ||
case tp: SingletonType => tp.underlying.widen | ||
case tp: SingletonType if tp.isSoft => tp.underlying.widen | ||
case tp: ExprType => tp.resultType.widen | ||
case tp => | ||
val tp1 = tp.stripped | ||
|
@@ -1230,7 +1230,7 @@ object Types { | |
* base type by applying one or more `underlying` dereferences. | ||
*/ | ||
final def widenSingleton(using Context): Type = stripped match { | ||
case tp: SingletonType if !tp.isOverloaded => tp.underlying.widenSingleton | ||
case tp: SingletonType if tp.isSoft && !tp.isOverloaded => tp.underlying.widenSingleton | ||
case _ => this | ||
} | ||
|
||
|
@@ -2025,8 +2025,12 @@ object Types { | |
/** A marker trait for types that are guaranteed to contain only a | ||
* single non-null value (they might contain null in addition). | ||
*/ | ||
trait SingletonType extends TypeProxy with ValueType { | ||
trait SingletonType extends TypeProxy with ValueType with Softenable { | ||
def isOverloaded(using Context): Boolean = false | ||
|
||
/** Overriden in [[ConstantType]]. | ||
*/ | ||
override def isSoft = true | ||
} | ||
|
||
/** A trait for types that bind other types that refer to them. | ||
|
@@ -2074,6 +2078,10 @@ object Types { | |
} | ||
} | ||
|
||
trait Softenable { | ||
def isSoft: Boolean | ||
} | ||
|
||
// --- NamedTypes ------------------------------------------------------------------ | ||
|
||
abstract class NamedType extends CachedProxyType with ValueType { self => | ||
|
@@ -2855,15 +2863,15 @@ object Types { | |
abstract case class ConstantType(value: Constant) extends CachedProxyType with SingletonType { | ||
override def underlying(using Context): Type = value.tpe | ||
|
||
override def computeHash(bs: Binders): Int = doHash(value) | ||
override def computeHash(bs: Binders): Int = doHash(value, if isSoft then 0 else 1) | ||
} | ||
|
||
final class CachedConstantType(value: Constant) extends ConstantType(value) | ||
final class CachedConstantType(value: Constant, override val isSoft: Boolean = true) extends ConstantType(value) | ||
|
||
object ConstantType { | ||
def apply(value: Constant)(using Context): ConstantType = { | ||
def apply(value: Constant, soft: Boolean = true)(using Context): ConstantType = { | ||
assertUnerased() | ||
unique(new CachedConstantType(value)) | ||
unique(new CachedConstantType(value, soft)) | ||
} | ||
} | ||
|
||
|
@@ -3206,9 +3214,8 @@ object Types { | |
TypeComparer.liftIfHK(tp1, tp2, AndType.make(_, _, checkValid = false), makeHk, _ | _) | ||
} | ||
|
||
abstract case class OrType(tp1: Type, tp2: Type) extends AndOrType { | ||
abstract case class OrType(tp1: Type, tp2: Type) extends AndOrType, Softenable { | ||
def isAnd: Boolean = false | ||
def isSoft: Boolean | ||
private var myBaseClassesPeriod: Period = Nowhere | ||
private var myBaseClasses: List[ClassSymbol] = _ | ||
/** Base classes of are the intersection of the operand base classes. */ | ||
|
@@ -3282,7 +3289,12 @@ object Types { | |
else tp1.atoms | tp2.atoms | ||
val tp1w = tp1.widenSingletons | ||
val tp2w = tp2.widenSingletons | ||
myWidened = if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else tp1w | tp2w | ||
myWidened = | ||
if isSoft then | ||
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. With this change, |
||
if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else tp1w | tp2w | ||
else | ||
derivedOrType(tp1w, tp2w) | ||
|
||
atomsRunId = ctx.runId | ||
|
||
override def atoms(using Context): Atoms = | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
object Test: | ||
def is2(x: 2) = true | ||
|
||
def testValType() = | ||
val x: 2 = 2 | ||
val v = x | ||
is2(v) | ||
|
||
def testDefReturnType() = | ||
def f(): 2 = 2 | ||
val v = f() | ||
is2(v) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back 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.
Do we need a trait for that? Or could
isSoft
be a method ofType
directly, returningtrue
by default?To do:
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.
It's never consumed as its upper type, and there's no "shared implementation". So I'd just define/redefine it on SingletonType/ConstantType, and maybe link the docs if they're extensive. Just IMO 😄
Oh, otherwise I'd call it
Softness
or justIsSoft
.