Is @trusted the wrong direction?

anon5886 Me at nowhe.re
Sat Nov 9 23:44:06 UTC 2019


On Saturday, 9 November 2019 at 21:13:22 UTC, Dominikus Dittes 
Scherkl wrote:
> On Saturday, 9 November 2019 at 20:38:47 UTC, Alexandru 
> Ermicioi wrote:
>> ```d
>> import std.stdio;
>>
>> T trusted (T)(T delegate() @system dg) @trusted {
>>    return dg();
>> }
>>
>> void main() @safe
>> {
>>     writeln("Hello D");
>>
>>     ({
>>         writeln("C ", cast(void*) 1);
>>     }).trusted;
>> }
>> ```
>>
>> looks a lot better than anonymous functions that are called 
>> right away after being defined.
>
> Hmm. Only slightly better syntax, but more important doesn't 
> solve the other half of the problem: Forbidding non-lambda 
> trusted functions.
>
> The syntax I would prefer for trusted blocks is simply
>
> @trusted
> {
> }
>
> And everything between the @trusted and the opening bracket 
> (like function declarations) would be forbidden.

Implementation is trivial... I got tit to work in a small hour 
but the problem is that for now the safety really only works at 
the function level so the function properties have to be patch 
for the duration of the trusted block.

If someone wants to play a bit:

---
 From 8b4fc62610b54375b4824be28478dc11bd0023cf Mon Sep 17 00:00:00 
2001
From: Me <Me at nowhe.re>
Date: Sun, 10 Nov 2019 00:27:25 +0100
Subject: [PATCH] Allow partial trusting of a BlockStatment

- prevent usage of trusted delegates
- allow to infere @safe on func template containing these blocks
- reduce the scope of the manual verification, supposed to be 
done for @trusted
---
  src/dmd/parse.d        | 23 ++++++++++++++++++++++-
  src/dmd/statement.d    |  1 +
  src/dmd/statementsem.d | 17 +++++++++++++++++
  3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/dmd/parse.d b/src/dmd/parse.d
index 04cfc34e3..a57224b55 100644
--- a/src/dmd/parse.d
+++ b/src/dmd/parse.d
@@ -5383,6 +5383,27 @@ final class Parser(AST) : Lexer

          switch (token.value)
          {
+        case TOK.at:
+            auto n = peek(&token);
+            // @trusted { }
+            // ---
+            // ScopeBlockStatement:
+            //      Attributes? BlockStatement
+            //
+            if (n.value == TOK.identifier && 
isBuiltinAtAttribute(n.ident) == STC.trusted
+                && peekNext2 == TOK.leftCurly)
+            {
+                nextToken();
+                nextToken();
+                AST.Statement r = parseStatement(flags);
+                if (r.stmt == AST.STMT.Scope)
+                {
+                    (cast(AST.ScopeStatement) r).stc = 
AST.STC.trusted;
+                    // printf("trusted block parsed...\n");
+                }
+                return r;
+            }
+            goto Ldeclaration;
          case TOK.identifier:
              {
                  /* A leading identifier can be a declaration, 
label, or expression.
@@ -5565,7 +5586,7 @@ final class Parser(AST) : Lexer
          case TOK.pure_:
          case TOK.ref_:
          case TOK.gshared:
-        case TOK.at:
+        //case TOK.at:
          case TOK.struct_:
          case TOK.union_:
          case TOK.class_:
diff --git a/src/dmd/statement.d b/src/dmd/statement.d
index ea05cb75a..4a081e5a9 100644
--- a/src/dmd/statement.d
+++ b/src/dmd/statement.d
@@ -1009,6 +1009,7 @@ extern (C++) class ScopeStatement : 
Statement
  {
      Statement statement;
      Loc endloc;                 // location of closing curly 
bracket
+    STC stc;                    // indicate the block temporary 
attributes, @trusted only

      extern (D) this(const ref Loc loc, Statement statement, Loc 
endloc)
      {
diff --git a/src/dmd/statementsem.d b/src/dmd/statementsem.d
index 9276ffddb..ab1f1d234 100644
--- a/src/dmd/statementsem.d
+++ b/src/dmd/statementsem.d
@@ -420,6 +420,9 @@ private extern (C++) final class 
StatementSemanticVisitor : Visitor
      override void visit(ScopeStatement ss)
      {
          //printf("ScopeStatement::semantic(sc = %p)\n", sc);
+
+
+
          if (ss.statement)
          {
              ScopeDsymbol sym = new ScopeDsymbol();
@@ -427,6 +430,20 @@ private extern (C++) final class 
StatementSemanticVisitor : Visitor
              sym.endlinnum = ss.endloc.linnum;
              sc = sc.push(sym);

+            // patch the scope to apply a temporary trusting for 
@trusted { }
+            TypeFunction tf = sc.func ? 
sc.func.type.toTypeFunction() : null;
+            const TRUST tr = tf ? tf.trust : TRUST.init;
+            if (ss.stc == STC.trusted && tr != TRUST.init)
+            {
+                tf.trust = TRUST.trusted;
+                //printf("set block statement scope and parent 
func as trusted...\n");
+            }
+            scope(exit)
+            {
+                if (tf)
+                    tf.trust = tr;
+            }
+
              Statements* a = ss.statement.flatten(sc);
              if (a)
              {
--
2.17.2


---


More information about the Digitalmars-d mailing list