Skip to content

Commit 27a6595

Browse files
committed
Add "maybe" language import
1 parent 001c53b commit 27a6595

5 files changed

Lines changed: 36 additions & 7 deletions

File tree

compiler/src/dotty/tools/dotc/config/Feature.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ object Feature:
4545
val magic = experimental("magic")
4646
val inlineTraits = experimental("inlineTraits")
4747
val specializedTraits = experimental("specializedTraits")
48+
val maybe = experimental("maybe")
4849

4950
val nonViralExperimentalFeatures: Set[TermName] =
5051
Set(captureChecking, separationChecking, safe, magic)
@@ -86,6 +87,7 @@ object Feature:
8687
(magic, "Enable extensions for working with coding agents"),
8788
(inlineTraits, "Allow inline traits"),
8889
(specializedTraits, "Allow specialized traits"),
90+
(maybe, "Allow T? and T ? E types"),
8991
)
9092

9193
/** Features that are now standard; the language import / -language choice is
@@ -193,10 +195,13 @@ object Feature:
193195
|| enabledBySetting(specializedTraits)
194196
|| ctx.compilationUnit.knowsInlineTraits
195197

198+
def maybeEnabled(using Context) =
199+
enabled(maybe) || magicEnabled
200+
196201
/** Is pureFunctions enabled for this compilation unit? */
197202
def pureFunsEnabled(using Context) =
198203
enabledBySetting(pureFunctions)
199-
|| ctx.compilationUnit.knowsPureFuns
204+
|| ctx.originalCompilationUnit.knowsPureFuns
200205
|| ccEnabled
201206

202207
/** Is capture checking enabled by a command-line setting? */

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,7 +2116,7 @@ object Parsers {
21162116
if in.token == LBRACE
21172117
then makeRetaining(t, captureSet(), tpnme.retains)
21182118
else makeRetaining(t, Nil, tpnme.retainsCap)
2119-
else if in.isIdent(nme.?) && Feature.magicEnabled && isPostfixQmark(isType = true) then
2119+
else if in.isIdent(nme.?) && Feature.maybeEnabled && isPostfixQmark(isType = true) then
21202120
atSpan(t.span.start):
21212121
PostfixOp(t, typeIdent())
21222122
else
@@ -2678,7 +2678,7 @@ object Parsers {
26782678

26792679
def expr1(location: Location = Location.Elsewhere): Tree = in.token match
26802680
case IF =>
2681-
ifExpr(in.offset, If, canOmitThen = Feature.magicEnabled && location == Location.InBlock)
2681+
ifExpr(in.offset, If, canOmitThen = Feature.maybeEnabled && location == Location.InBlock)
26822682
case WHILE =>
26832683
atSpan(in.skipToken()) {
26842684
val cond = condExpr(DO)
@@ -3127,7 +3127,7 @@ object Parsers {
31273127
case USCORE =>
31283128
atSpan(startOffset(t), in.skipToken()) { PostfixOp(t, Ident(nme.WILDCARD)) }
31293129
case _ =>
3130-
if in.isIdent(nme.?) && Feature.magicEnabled && isPostfixQmark(isType = false) then
3130+
if in.isIdent(nme.?) && Feature.maybeEnabled && isPostfixQmark(isType = false) then
31313131
atSpan(t.span.start):
31323132
PostfixOp(t, termIdent())
31333133
else if in.isColon && location == Location.InParens && followingIsLambdaParams() then

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ object PatternMatcher {
894894
false
895895

896896
override def apply(plan: SeqPlan): Plan = {
897-
if Feature.magicEnabled then
897+
if Feature.maybeEnabled then
898898
plan.head = apply(plan.head)
899899
plan.tail = apply(plan.tail)
900900
plan.head match

library/src/scala/language.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ object language {
270270
object erasedDefinitions
271271

272272
/** Experimental support for specialized traits
273-
*
273+
*
274274
* @see [[docs/_docs/internals/specialized-traits.md]]
275275
*/
276276
@compileTimeOnly("`specializedTraits` can only be used at compile time in import statements")
@@ -425,7 +425,11 @@ object language {
425425
@compileTimeOnly("`magic` can only be used at compile time in import statements")
426426
object magic
427427

428-
428+
/** Experimental support for maybe types `T?` and result types `T ? E`.
429+
*/
430+
@compileTimeOnly("`maybe` can only be used at compile time in import statements")
431+
object maybe
432+
429433
/** Experimental support for inline traits
430434
*/
431435
@compileTimeOnly("`inlineTraits` can only be used at compile time in import statements")

tests/pos/i16342-maybe.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//> using options -Yexplicit-nulls
2+
import language.experimental.maybe
3+
type Opaque = Base & Tag
4+
5+
type Base = Any {
6+
type Hack
7+
}
8+
9+
trait Tag
10+
11+
object Opaque {
12+
def apply(value: String): Opaque = value.asInstanceOf[Opaque]
13+
14+
def unapply(userId: Opaque): String? = userId.value
15+
def unappy2(userId: Base & Tag): Option[String] = Option(userId).map(_.value)
16+
}
17+
18+
final implicit class Ops(private val userId: Opaque) extends AnyVal {
19+
def value: String = userId.asInstanceOf[String]
20+
}

0 commit comments

Comments
 (0)