-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Named tuples second implementation #19174
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
9d1f20d
2395ece
64a79c9
cb95265
6ae8252
1f79b87
b9899b7
27d6288
5dd48f9
bd9bb8a
e0a11cd
b9d86fe
0fbdb49
6f53dcd
b44f15d
02aa578
b7115e7
5c9bb5f
4758830
18f600d
5513ed6
fb1541a
cf09b19
4baa509
702dcd5
1e31d16
22e6c89
d0888f6
69964b0
a3409e0
111674c
1fd5962
c0b792f
611861b
640da16
67c0af2
2cd5d7e
d8b7595
e0eb247
4279a58
c0bd1e4
b997f3d
2206d88
ca19f1a
984fe62
21bcfef
92d22c9
1613ee1
a04d3a7
37b1bd2
3f8f6c6
9627c08
8a4162f
0ab9e7b
075b7d1
c58c8c2
57b17ac
f427ec9
94b7c1f
5df2120
40c6138
03509b8
9047ac3
579e14a
8d6fa37
1e29c4f
0c89c92
f80a8dd
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 |
---|---|---|
|
@@ -107,7 +107,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { | |
def forwardTo: Tree = t | ||
} | ||
case class Tuple(trees: List[Tree])(implicit @constructorOnly src: SourceFile) extends Tree { | ||
override def isTerm: Boolean = trees.isEmpty || trees.head.isTerm | ||
override def isTerm: Boolean = trees.isEmpty || stripNamedArg(trees.head).isTerm | ||
override def isType: Boolean = !isTerm | ||
} | ||
case class Throw(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree | ||
|
@@ -528,15 +528,15 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { | |
def makeSelfDef(name: TermName, tpt: Tree)(using Context): ValDef = | ||
ValDef(name, tpt, EmptyTree).withFlags(PrivateLocal) | ||
|
||
def makeTupleOrParens(ts: List[Tree])(using Context): Tree = ts match { | ||
def makeTupleOrParens(ts: List[Tree])(using Context): Tree = ts match | ||
case (t: NamedArg) :: Nil => Tuple(t :: Nil) | ||
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. will probably need a warning of changing behaviour, before this would be considered an assignment in parens: scala> var x = 0
var x: Int = 0
scala> (x = 23)
scala> println(x)
23 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. Noted for further work. We need to think of this migration when named tuples become standard. |
||
case t :: Nil => Parens(t) | ||
case _ => Tuple(ts) | ||
} | ||
|
||
def makeTuple(ts: List[Tree])(using Context): Tree = ts match { | ||
def makeTuple(ts: List[Tree])(using Context): Tree = ts match | ||
case (t: NamedArg) :: Nil => Tuple(t :: Nil) | ||
case t :: Nil => t | ||
case _ => Tuple(ts) | ||
} | ||
|
||
def makeAndType(left: Tree, right: Tree)(using Context): AppliedTypeTree = | ||
AppliedTypeTree(ref(defn.andType.typeRef), left :: right :: Nil) | ||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -6,11 +6,14 @@ import Types.*, Contexts.*, Symbols.*, Constants.*, Decorators.* | |||||||
import config.Printers.typr | ||||||||
import reporting.trace | ||||||||
import StdNames.tpnme | ||||||||
import Flags.CaseClass | ||||||||
import TypeOps.nestedPairs | ||||||||
|
||||||||
object TypeEval: | ||||||||
|
||||||||
def tryCompiletimeConstantFold(tp: AppliedType)(using Context): Type = tp.tycon match | ||||||||
case tycon: TypeRef if defn.isCompiletimeAppliedType(tycon.symbol) => | ||||||||
|
||||||||
extension (tp: Type) def fixForEvaluation: Type = | ||||||||
tp.normalized.dealias match | ||||||||
// enable operations for constant singleton terms. E.g.: | ||||||||
|
@@ -94,6 +97,22 @@ object TypeEval: | |||||||
throw TypeError(em"${e.getMessage.nn}") | ||||||||
ConstantType(Constant(result)) | ||||||||
|
||||||||
def fieldsOf: Option[Type] = | ||||||||
expectArgsNum(1) | ||||||||
val arg = tp.args.head | ||||||||
val cls = arg.classSymbol | ||||||||
if cls.is(CaseClass) then | ||||||||
val fields = cls.caseAccessors | ||||||||
val fieldLabels = fields.map: field => | ||||||||
ConstantType(Constant(field.name.toString)) | ||||||||
val fieldTypes = fields.map(arg.memberInfo) | ||||||||
Some: | ||||||||
defn.NamedTupleTypeRef.appliedTo: | ||||||||
nestedPairs(fieldLabels) :: nestedPairs(fieldTypes) :: Nil | ||||||||
Comment on lines
+110
to
+111
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.
Suggested change
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 proposed replacement does not compiler. There is no 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. there's a |
||||||||
else arg.widenDealias match | ||||||||
case arg @ defn.NamedTuple(_, _) => Some(arg) | ||||||||
case _ => None | ||||||||
|
||||||||
def constantFold1[T](extractor: Type => Option[T], op: T => Any): Option[Type] = | ||||||||
expectArgsNum(1) | ||||||||
extractor(tp.args.head).map(a => runConstantOp(op(a))) | ||||||||
|
@@ -122,11 +141,14 @@ object TypeEval: | |||||||
yield runConstantOp(op(a, b, c)) | ||||||||
|
||||||||
trace(i"compiletime constant fold $tp", typr, show = true) { | ||||||||
val name = tycon.symbol.name | ||||||||
val owner = tycon.symbol.owner | ||||||||
val sym = tycon.symbol | ||||||||
val name = sym.name | ||||||||
val owner = sym.owner | ||||||||
val constantType = | ||||||||
if defn.isCompiletime_S(tycon.symbol) then | ||||||||
if defn.isCompiletime_S(sym) then | ||||||||
constantFold1(natValue, _ + 1) | ||||||||
else if defn.isNamedTuple_From(sym) then | ||||||||
fieldsOf | ||||||||
else if owner == defn.CompiletimeOpsAnyModuleClass then name match | ||||||||
case tpnme.Equals => constantFold2(constValue, _ == _) | ||||||||
case tpnme.NotEquals => constantFold2(constValue, _ != _) | ||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -385,7 +385,12 @@ object TypeOps: | |
(tp.tp1.dealias, tp.tp2.dealias) match | ||
case (tp1 @ AppliedType(tycon1, args1), tp2 @ AppliedType(tycon2, args2)) | ||
if tycon1.typeSymbol == tycon2.typeSymbol && (tycon1 =:= tycon2) => | ||
mergeRefinedOrApplied(tp1, tp2) | ||
mergeRefinedOrApplied(tp1, tp2) match | ||
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. its not obvious here how this change relates to NamedTuples, or which example needs this change |
||
case tp: AppliedType if tp.isUnreducibleWild => | ||
// fall back to or-dominators rather than inferring a type that would | ||
// cause an unreducible type error later. | ||
approximateOr(tp1, tp2) | ||
case tp => tp | ||
case (tp1, tp2) => | ||
approximateOr(tp1, tp2) | ||
case _ => | ||
|
Uh oh!
There was an error while loading. Please reload this page.