Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion compiler/src/dotty/tools/dotc/cc/SafeRefs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import Symbols.*
import Annotations.*
import util.Spans.NoSpan
import util.SrcPos
import Contexts.Context
import Contexts.{Context, ctx}
import Constants.Constant
import Decorators.*
import ast.tpd.*
import SymDenotations.*
import Flags.*
import Types.*
import config.Feature
import NameOps.isReplWrapperName
import Names.Name
import typer.ProtoTypes.SelectionProto

/** Check whether references from safe mode should be allowed */
Expand Down Expand Up @@ -160,4 +162,8 @@ object SafeRefs {
case _ =>
if Feature.safeEnabled then
tree.tpe.foreachPart(checkAnnotatedType(_))

/** Allow name in safe mode even though it contains `$` characters */
def allow(name: Name)(using Context): Boolean =
name.isReplWrapperName && ctx.mode.is(Mode.Interactive)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is checking for interactive mode the right call here? This is also used by the REPL, and tacit uses it IIRC. I.e., could this be used by an agent to bypass vital checks. cc @noti0na1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. The interactive mode check looks too relaxed for me.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are Tacit code snippets compiled in interactive mode? Not sure what's different between Tacit and general repl sessions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the code written by agent is compiled in interactive mode. There is no difference compared to typing in repl. Maybe the check here is ok. I can verify this PR with TACIT later.

}
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/parsing/Scanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import config.Feature.{migrateTo3, sourceVersion}
import config.SourceVersion.{`3.0`, `3.0-migration`}
import config.MigrationVersion
import reporting.{NoProfile, Profile, Message}
import cc.SafeRefs

import java.util.Objects
import dotty.tools.dotc.reporting.Message.rewriteNotice
Expand Down Expand Up @@ -150,6 +151,8 @@ object Scanners {
def finishNamedToken(idtoken: Token, target: TokenData): Unit =
target.name = termName(litBuf.chars, 0, litBuf.length)
litBuf.clear()
if target.name.contains('$') && Feature.safeEnabled && !SafeRefs.allow(name) then
report.error(em"Identifier may not contain '$$' in safe mode", sourcePos())
target.token = idtoken
if idtoken == IDENTIFIER then
val converted = toToken(target.name)
Expand Down
8 changes: 8 additions & 0 deletions tests/neg/unsafe-dollar-in-name-2.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Error: tests/neg/unsafe-dollar-in-name-2.scala:3:7 ------------------------------------------------------------------
3 |object Foo$ // error
| ^
| Identifier may not contain '$' in safe mode
-- Error: tests/neg/unsafe-dollar-in-name-2.scala:5:6 ------------------------------------------------------------------
5 |class `Bar$` // error
| ^
| Identifier may not contain '$' in safe mode
5 changes: 5 additions & 0 deletions tests/neg/unsafe-dollar-in-name-2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//> using options -language:experimental.safe

object Foo$ // error

class `Bar$` // error
8 changes: 8 additions & 0 deletions tests/neg/unsafe-dollar-in-name.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Error: tests/neg/unsafe-dollar-in-name.scala:3:7 --------------------------------------------------------------------
3 |object Foo$ // error
| ^
| Identifier may not contain '$' in safe mode
-- Error: tests/neg/unsafe-dollar-in-name.scala:5:6 --------------------------------------------------------------------
5 |class `Bar$` // error
| ^
| Identifier may not contain '$' in safe mode
5 changes: 5 additions & 0 deletions tests/neg/unsafe-dollar-in-name.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import language.experimental.safe

object Foo$ // error

class `Bar$` // error
Loading