[latex3-commits] [git/latex3] master: Detect local assignments to global variables and vice-versa (see #410) (ad41c2b)

Bruno Le Floch bruno at le-floch.fr
Wed Nov 29 00:57:04 CET 2017


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/ad41c2b6947bcbed389694f9e7cef2e827477111

>---------------------------------------------------------------

commit ad41c2b6947bcbed389694f9e7cef2e827477111
Author: Bruno Le Floch <bruno at le-floch.fr>
Date:   Tue Nov 28 18:42:49 2017 -0500

    Detect local assignments to global variables and vice-versa (see #410)


>---------------------------------------------------------------

ad41c2b6947bcbed389694f9e7cef2e827477111
 l3kernel/l3basics.dtx                   |  196 +++++++++++++++++++++++--------
 l3kernel/l3candidates.dtx               |   15 ++-
 l3kernel/l3coffins.dtx                  |   54 ++++-----
 l3kernel/l3msg.dtx                      |    9 ++
 l3kernel/l3prg.dtx                      |   12 +-
 l3kernel/l3tl.dtx                       |   50 ++++----
 l3kernel/testfiles/m3basics003.lvt      |   65 ++++++++++
 l3kernel/testfiles/m3basics003.tlg      |  123 +++++++++++++++++++
 l3kernel/testfiles/m3clist002.tlg       |   32 +++++
 l3kernel/testfiles/m3expl001.luatex.tlg |    1 +
 l3kernel/testfiles/m3expl001.ptex.tlg   |    1 +
 l3kernel/testfiles/m3expl001.tlg        |    1 +
 l3kernel/testfiles/m3expl001.uptex.tlg  |    1 +
 l3kernel/testfiles/m3expl001.xetex.tlg  |    1 +
 l3kernel/testfiles/m3expl003.luatex.tlg |    1 +
 l3kernel/testfiles/m3expl003.ptex.tlg   |    1 +
 l3kernel/testfiles/m3expl003.tlg        |    1 +
 l3kernel/testfiles/m3expl003.uptex.tlg  |    1 +
 l3kernel/testfiles/m3expl003.xetex.tlg  |    1 +
 l3kernel/testfiles/m3file002.tlg        |   70 ++++++++++-
 l3kernel/testfiles/m3prg002.tlg         |   32 +++++
 21 files changed, 552 insertions(+), 116 deletions(-)

diff --git a/l3kernel/l3basics.dtx b/l3kernel/l3basics.dtx
index 078db98..f9450c3 100644
--- a/l3kernel/l3basics.dtx
+++ b/l3kernel/l3basics.dtx
@@ -1259,6 +1259,23 @@
 %   \cs{cs_if_exist_p:N}, and if not raises a kernel-level error.
 % \end{function}
 %
+% \begin{function}{\__debug_chk_var_local:N, \__debug_chk_var_global:N}
+%   \begin{syntax}
+%     \cs{__debug_chk_var_local:N} \meta{var}
+%     \cs{__debug_chk_var_global:N} \meta{var}
+%   \end{syntax}
+%   These functions are only created if debugging is enabled.  They
+%   check that \meta{var} is a local/global variable, and if not raises
+%   a kernel-level error.  More precisely, if the variable name starts
+%   with a letter and an underscore (normal \pkg{expl3} convention) the
+%   functions check that this single letter is |l| or |g| as
+%   appropriate.  Otherwise the functions cannot know the first time
+%   whether \meta{var} is local or global: instead, they define
+%   |\__debug_chk_/|\meta{var name} to store the information, and if
+%   both \cs{__debug_chk_var_local:N} and \cs{__debug_chk_var_global:N}
+%   are called on the same variable a kernel-level error is raised.
+% \end{function}
+%
 % \begin{function}{\__debug_log:x}
 %   \begin{syntax}
 %     \cs{__debug_log:x} \Arg{message text}
@@ -1269,15 +1286,6 @@
 %   This function is only created if debugging is enabled.
 % \end{function}
 %
-% \begin{function}{\__debug_suspend_log:, \__debug_resume_log:}
-%   \begin{syntax}
-%     \cs{__debug_suspend_log:} \ldots{} \cs{__debug_log:x} \ldots{} \cs{__debug_resume_log:}
-%   \end{syntax}
-%   Any \cs{__debug_log:x} command between \cs{__debug_suspend_log:} and
-%   \cs{__debug_resume_log:} is suppressed.  These two commands can be
-%   nested.  These functions are only created if debugging is enabled.
-% \end{function}
-%
 % \begin{function}{\__debug_patch:nnNNpn}
 %   \begin{syntax}
 %     \cs{__debug_patch:nnNNpn} \Arg{before} \Arg{after}
@@ -1798,15 +1806,57 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[int]{\debug_suspend:, \debug_resume:}
+% \begin{macro}[int]{\@@_suspended:T}
+% \begin{macro}[aux]{\l_@@_suspended_tl}
+%   Suspend and resume locally all debug-related errors and logging
+%   except deprecation errors.  The \cs{debug_suspend:} and \cs{debug_resume:}
+%   pairs can be nested.  We keep track of nesting in a token list
+%   containing a number of periods.  At first begin with the
+%   \enquote{non-suspended} version of \cs{@@_suspended:T}.
+%    \begin{macrocode}
+\@@:TF
+  {
+    \cs_set_nopar:Npn \l_@@_suspended_tl { }
+    \cs_set_protected:Npn \debug_suspend:
+      {
+        \tl_put_right:Nn \l_@@_suspended_tl { . }
+        \cs_set_eq:NN \@@_suspended:T \use:n
+      }
+    \cs_set_protected:Npn \debug_resume:
+      {
+        \tl_set:Nx \l_@@_suspended_tl
+          { \tl_tail:N \l_@@_suspended_tl }
+        \tl_if_empty:NT \l_@@_suspended_tl
+          {
+            \cs_set_eq:NN \@@_suspended:T \use_none:n
+          }
+      }
+    \cs_set:Npn \@@_suspended:T #1 { }
+  }
+  {
+    \cs_set_protected:Npn \debug_suspend: { }
+    \cs_set_protected:Npn \debug_resume: { }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}[aux]
 %   {\@@_check-declarations_on:, \@@_check-declarations_off:}
 % \begin{macro}[int]{\@@_chk_var_exist:N}
 % \begin{macro}[int]{\@@_chk_cs_exist:N, \@@_chk_cs_exist:c}
-%   When debugging is enabled these two functions
-%   set up \cs{@@_chk_var_exist:N} and
-%   \cs{@@_chk_cs_exist:N}, two functions that test (when
-%   \texttt{check-declarations} is active) that their argument is
-%   defined.
+% \begin{macro}[int]{\@@_chk_var_local:N, \@@_chk_var_global:N}
+%   When debugging is enabled these two functions set up functions that
+%   test their argument (when \texttt{check-declarations} is active)
+%   \begin{itemize}
+%     \item \cs{@@_chk_var_exist:N} and \cs{@@_chk_cs_exist:N}, two
+%       functions that test that their argument is defined;
+%     \item \cs{@@_chk_var_local:N} and \cs{@@_chk_var_global:N}, two
+%       functions that check that their argument is a local (resp.\@
+%       global) variable.
+%   \end{itemize}
 %    \begin{macrocode}
 \@@:TF
   {
@@ -1814,6 +1864,7 @@
       {
         \cs_set_protected:Npn \@@_chk_var_exist:N ##1
           {
+            \@@_suspended:T \use_none:nnn
             \cs_if_exist:NF ##1
               {
                 \__msg_kernel_error:nnx { kernel } { non-declared-variable }
@@ -1822,17 +1873,34 @@
           }
         \cs_set_protected:Npn \@@_chk_cs_exist:N ##1
           {
+            \@@_suspended:T \use_none:nnn
             \cs_if_exist:NF ##1
               {
                 \__msg_kernel_error:nnx { kernel } { command-not-defined }
                   { \token_to_str:N ##1 }
               }
           }
+        \cs_set_protected:Npn \@@_chk_var_local:N ##1
+          {
+            \@@_suspended:T \use_none:nnnnn
+            \@@_chk_var_exist:N ##1
+            \@@_chk_var_local_aux:NN l ##1
+          }
+        \cs_set_protected:Npn \@@_chk_var_global:N ##1
+          {
+            \@@_suspended:T \use_none:nnnnn
+            \@@_chk_var_exist:N ##1
+            \@@_chk_var_local_aux:NN g ##1
+          }
       }
     \exp_args:Nc \cs_set_protected:Npn { @@_check-declarations_off: }
       {
         \cs_set_protected:Npn \@@_chk_var_exist:N ##1 { }
         \cs_set_protected:Npn \@@_chk_cs_exist:N ##1 { }
+        \cs_set_protected:Npn \@@_chk_var_local:N ##1
+          { \@@_chk_var_exist:N ##1 }
+        \cs_set_protected:Npn \@@_chk_var_global:N ##1
+          { \@@_chk_var_exist:N ##1 }
       }
     \cs_set_protected:Npn \@@_chk_cs_exist:c
       { \exp_args:Nc \@@_chk_cs_exist:N }
@@ -1847,6 +1915,58 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_chk_var_local_aux:NN}
+% \begin{macro}[aux]{\@@_chk_var_local_aux:Nn}
+% \begin{macro}[aux]{\@@_chk_var_local_aux:NNn}
+%   First check whether the name of the variable |#2| starts with
+%   \meta{letter}|_|.  If it does then pass that letter, the target
+%   letter |l| or |g|, and the variable name to
+%   \cs{@@_chk_var_local_aux:NNn}.  That function compares the two
+%   letters and triggers an error if they differ (the \cs{scan_stop:}
+%   case is not reachable here).  If the second character was not |_|
+%   then pass the same data to the same auxiliary, except for its first
+%   argument which is now a control sequence.  That control sequence is
+%   actually a token list (but to avoid triggering the checking code we
+%   manipulate it using \cs{cs_set_nopar:Npn}) containing a single
+%   letter |l| or |g| according to what the first assignment to the
+%   given variable was.
+%    \begin{macrocode}
+\@@:TF
+  {
+    \cs_set_protected:Npn \@@_chk_var_local_aux:NN #1#2
+      { \exp_args:NNf \@@_chk_var_local_aux:Nn #1 { \cs_to_str:N #2 } }
+    \cs_set_protected:Npn \@@_chk_var_local_aux:Nn #1#2
+      {
+        \if:w _ \use_i:nn \tl_head:w #2 ? ? \q_stop
+          \exp_after:wN \@@_chk_var_local_aux:NNn
+            \tl_head:w #2 ? \q_stop
+            #1 {#2}
+        \else:
+          \exp_args:Nc \@@_chk_var_local_aux:NNn
+            { @@_chk_/ #2 }
+            #1 {#2}
+        \fi:
+      }
+    \cs_set_protected:Npn \@@_chk_var_local_aux:NNn #1#2#3
+      {
+        \if:w #1 #2
+        \else:
+          \if:w #1 \scan_stop:
+            \cs_gset_nopar:Npn #1 {#2}
+          \else:
+            \__msg_kernel_error:nnxxx { kernel } { local-global }
+              {#1} {#2} { \iow_char:N \\ #3 }
+          \fi:
+        \fi:
+      }
+  }
+  { }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}[aux]
 %   {\@@_check-expressions_on:, \@@_check-expressions_off:}
@@ -1877,6 +1997,7 @@
       {
         \cs_set:Npn \@@_chk_expr:nNnN ##1##2
           {
+            \@@_suspended:T { ##1 \use_none:nnnnnnn }
             \exp_after:wN \@@_chk_expr_aux:nNnN
             \exp_after:wN { \tex_the:D ##2 ##1 \tex_relax:D }
             ##2
@@ -1907,47 +2028,24 @@
 % \end{macro}
 %
 % \begin{macro}[aux]{\@@_log-functions_on:, \@@_log-functions_off:}
-% \begin{macro}[int]{\@@_log:x, \@@_suspend_log:, \@@_resume_log:}
-%   These two functions
-%   (corresponding to the \pkg{expl3} option \texttt{log-functions})
-%   control whether \cs{@@_log:x} writes to the log file or not.
-%   Since \cs{iow_log:x} does not yet have its final definition we do
-%   not use \cs{cs_set_eq:NN} (not defined yet anyway).  The
-%   \cs{@@_suspend_log:} function disables \cs{@@_log:x} until
-%   the matching \cs{@@_resume_log:}.  These two commands are used
-%   to improve the logging for datatypes with multiple parts, currently
-%   only coffins.  They should come in pairs, which can be nested (this
-%   complicates the code here and is currently unused).  The function
-%   \cs{exp_not:o} is defined in \pkg{l3expan} later on but
-%   \cs{@@_suspend_log:} and \cs{@@_resume_log:} are not used
-%   before that point.  Once everything is defined, turn logging on or
-%   off depending on what option was given.
-%   When debugging is not enabled, simply produce an error.
+% \begin{macro}[int]{\@@_log:x}
+%   These two functions (corresponding to the \pkg{expl3} option
+%   \texttt{log-functions}) control whether \cs{@@_log:x} writes to the
+%   log file or not.  Since \cs{iow_log:x} does not yet have its final
+%   definition we do not use \cs{cs_set_eq:NN} (not defined yet anyway).
+%   Once everything is defined, turn logging on or off depending on what
+%   option was given.  When debugging is not enabled, simply produce an
+%   error.
 %    \begin{macrocode}
 \@@:TF
   {
     \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_on: }
       {
-        \cs_set_protected:Npn \@@_log:x { \iow_log:x }
-        \cs_set_protected:Npn \@@_suspend_log:
-          {
-            \cs_set_protected:Npx \@@_resume_log:
-              {
-                \cs_set_protected:Npn \@@_resume_log:
-                  { \exp_not:o { \@@_resume_log: } }
-                \cs_set_protected:Npn \@@_log:x
-                  { \exp_not:o { \@@_log:x } }
-              }
-            \cs_set_protected:Npn \@@_log:x { \use_none:n }
-          }
-        \cs_set_protected:Npn \@@_resume_log: { }
+        \cs_set_protected:Npn \@@_log:x
+          { \@@_suspended:T \use_none:nn \iow_log:x }
       }
     \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_off: }
-      {
-        \cs_set_protected:Npn \@@_log:x { \use_none:n }
-        \cs_set_protected:Npn \@@_suspend_log: { }
-        \cs_set_protected:Npn \@@_resume_log: { }
-      }
+      { \cs_set_protected:Npn \@@_log:x { \use_none:n } }
     \tex_ifodd:D \l at expl@log at functions@bool
       \use:c { @@_log-functions_on: }
     \else:
@@ -1963,7 +2061,7 @@
 % \begin{variable}{\g_@@_deprecation_on_tl, \g_@@_deprecation_off_tl}
 %   Some commands were more recently deprecated and not yet removed;
 %   only make these into errors if the user requests it.  This relies on
-%   two token lists, filled up by calls to
+%   two token lists, mostly filled up by calls to
 %   \cs{@@_deprecation:nnNNpn} in each module.
 %    \begin{macrocode}
 \@@:TF
diff --git a/l3kernel/l3candidates.dtx b/l3kernel/l3candidates.dtx
index 2ddf658..5990bd4 100644
--- a/l3kernel/l3candidates.dtx
+++ b/l3kernel/l3candidates.dtx
@@ -94,7 +94,9 @@
 %   can be used in the \meta{list} are
 %   \begin{itemize}
 %     \item \texttt{check-declarations} that checks all \pkg{expl3}
-%       variables used were previously declared;
+%       variables used were previously declared and that local/global
+%       variables (based on their name or on their first assignment) are
+%       only locally/globally assigned;
 %     \item \texttt{check-expressions} that checks integer, dimension,
 %       skip, and muskip expressions are not terminated prematurely;
 %     \item \texttt{deprecation} that makes soon-to-be-deprecated commands produce errors;
@@ -107,6 +109,17 @@
 %   loaded with \texttt{enable-debug} or another option implying it.
 % \end{function}
 %
+% \begin{function}[added = 2017-11-28]{\debug_suspend:, \debug_resume:}
+%   \begin{syntax}
+%     \cs{debug_suspend:} \ldots{} \cs{debug_resume:}
+%   \end{syntax}
+%   Suppress (locally) errors and logging from \texttt{debug} commands,
+%   except for the \texttt{deprecation} errors or warnings.  These pairs
+%   of commands can be nested.  This can be used around pieces of code
+%   that are known to fail checks, if such failures should be ignored.
+%   See for instance \pkg{l3coffins}.
+% \end{function}
+%
 % \begin{function}[added = 2017-07-04]{\mode_leave_vertical:}
 %   \begin{syntax}
 %     \cs{mode_leave_vertical:}
diff --git a/l3kernel/l3coffins.dtx b/l3kernel/l3coffins.dtx
index e312125..929ced5 100644
--- a/l3kernel/l3coffins.dtx
+++ b/l3kernel/l3coffins.dtx
@@ -356,21 +356,25 @@
 % \begin{variable}{\c_@@_corners_prop}
 %   The \enquote{corners}; of a coffin define the real content, as
 %   opposed to the \TeX{} bounding box. They all start off in the same
-%   place, of course.
+%   place, of course.  The \cs{debug_suspend:} and \cs{debug_resume:}
+%   are needed because we are assigning to a constant variable.
 %    \begin{macrocode}
 \prop_new:N \c_@@_corners_prop
+\debug_suspend:
 \prop_put:Nnn \c_@@_corners_prop { tl } { { 0pt } { 0pt } }
 \prop_put:Nnn \c_@@_corners_prop { tr } { { 0pt } { 0pt } }
 \prop_put:Nnn \c_@@_corners_prop { bl } { { 0pt } { 0pt } }
 \prop_put:Nnn \c_@@_corners_prop { br } { { 0pt } { 0pt } }
+\debug_resume:
 %    \end{macrocode}
 % \end{variable}
 %
 % \begin{variable}{\c_@@_poles_prop}
 %   Pole positions are given for horizontal, vertical and reference-point
-%   based values.
+%   based values.  Again, need \cs{debug_suspend:} and \cs{debug_resume:}.
 %    \begin{macrocode}
 \prop_new:N \c_@@_poles_prop
+\debug_suspend:
 \tl_set:Nn \l_@@_internal_tl { { 0pt } { 0pt } { 0pt } { 1000pt } }
 \prop_put:Nno \c_@@_poles_prop { l }  { \l_@@_internal_tl }
 \prop_put:Nno \c_@@_poles_prop { hc } { \l_@@_internal_tl }
@@ -382,6 +386,7 @@
 \prop_put:Nno \c_@@_poles_prop { B }  { \l_@@_internal_tl }
 \prop_put:Nno \c_@@_poles_prop { H }  { \l_@@_internal_tl }
 \prop_put:Nno \c_@@_poles_prop { T }  { \l_@@_internal_tl }
+\debug_resume:
 %    \end{macrocode}
 % \end{variable}
 %
@@ -506,38 +511,23 @@
 %   Creating a new coffin means making the underlying box and adding the
 %   data structures. These are created globally, as there is a need to
 %   avoid any strange effects if the coffin is created inside a group.
-%   This means that the usual rule about \cs[no-index]{l_\ldots} variables has
-%   to be broken.  The \cs{__debug_suspend_log:} and
-%   \cs{__debug_resume_log:} functions prevent \cs{prop_clear_new:c}
-%   from writing useless information to the log file; however they only
-%   exist if debugging is enabled.
+%   This means that the usual rule about \cs[no-index]{l_\ldots}
+%   variables has to be broken.  The \cs{debug_suspend:} and
+%   \cs{debug_resume:} functions prevent these checks.  They also
+%   prevent \cs{prop_clear_new:c} from writing useless information to
+%   the log file.
 %    \begin{macrocode}
-\__debug:TF
+\cs_new_protected:Npn \coffin_new:N #1
   {
-    \cs_new_protected:Npn \coffin_new:N #1
-      {
-        \box_new:N #1
-        \__debug_suspend_log:
-        \prop_clear_new:c { l_@@_corners_ \__int_value:w #1 _prop }
-        \prop_clear_new:c { l_@@_poles_   \__int_value:w #1 _prop }
-        \prop_gset_eq:cN { l_@@_corners_ \__int_value:w #1 _prop }
-          \c_@@_corners_prop
-        \prop_gset_eq:cN { l_@@_poles_ \__int_value:w #1 _prop }
-          \c_@@_poles_prop
-        \__debug_resume_log:
-      }
-  }
-  {
-    \cs_new_protected:Npn \coffin_new:N #1
-      {
-        \box_new:N #1
-        \prop_clear_new:c { l_@@_corners_ \__int_value:w #1 _prop }
-        \prop_clear_new:c { l_@@_poles_   \__int_value:w #1 _prop }
-        \prop_gset_eq:cN { l_@@_corners_ \__int_value:w #1 _prop }
-          \c_@@_corners_prop
-        \prop_gset_eq:cN { l_@@_poles_ \__int_value:w #1 _prop }
-          \c_@@_poles_prop
-      }
+    \box_new:N #1
+    \debug_suspend:
+    \prop_clear_new:c { l_@@_corners_ \__int_value:w #1 _prop }
+    \prop_clear_new:c { l_@@_poles_   \__int_value:w #1 _prop }
+    \prop_gset_eq:cN { l_@@_corners_ \__int_value:w #1 _prop }
+      \c_@@_corners_prop
+    \prop_gset_eq:cN { l_@@_poles_ \__int_value:w #1 _prop }
+      \c_@@_poles_prop
+    \debug_resume:
   }
 \cs_generate_variant:Nn \coffin_new:N { c }
 %    \end{macrocode}
diff --git a/l3kernel/l3msg.dtx b/l3kernel/l3msg.dtx
index 83f3786..ec4d48b 100644
--- a/l3kernel/l3msg.dtx
+++ b/l3kernel/l3msg.dtx
@@ -1960,6 +1960,15 @@
         'check-declarations',~'deprecation',~'log-functions',~not~'#1'.
       }
     \@@_kernel_new:nnn { kernel } { expr } { '#2'~in~#1 }
+    \@@_kernel_new:nnnn { kernel } { local-global }
+      { Inconsistent~local/global~assignment }
+      {
+        \c_@@_coding_error_text_tl
+        \if:w l #2 Local \else: Global \fi: \
+        assignment~to~a~
+        \if:w l #1 local \else: \if:w g #1 global \else: constant \fi: \fi: \
+        variable~'#3'.
+      }
     \@@_kernel_new:nnnn { kernel } { non-declared-variable }
       { The~variable~#1~has~not~been~declared~\msg_line_context:. }
       {
diff --git a/l3kernel/l3prg.dtx b/l3kernel/l3prg.dtx
index b4c0d7d..ab3fce8 100644
--- a/l3kernel/l3prg.dtx
+++ b/l3kernel/l3prg.dtx
@@ -811,16 +811,16 @@
 %   make sure the boolean exists.  This is needed because booleans are
 %   not based on token lists nor on \TeX{} registers.
 %    \begin{macrocode}
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \bool_set_true:N #1
   { \cs_set_eq:NN #1 \c_true_bool }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \bool_set_false:N #1
   { \cs_set_eq:NN #1 \c_false_bool }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \bool_gset_true:N #1
   { \cs_gset_eq:NN #1 \c_true_bool }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \bool_gset_false:N #1
   { \cs_gset_eq:NN #1 \c_false_bool }
 \cs_generate_variant:Nn \bool_set_true:N   { c }
@@ -855,10 +855,10 @@
 %   argument the meaning \cs{c_true_bool} or \cs{c_false_bool}.
 %   Again, we include some checking code.
 %    \begin{macrocode}
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \bool_set:Nn #1#2
   { \tex_chardef:D #1 = \bool_if_p:n {#2} }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \bool_gset:Nn #1#2
   { \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} }
 \cs_generate_variant:Nn \bool_set:Nn  { c }
diff --git a/l3kernel/l3tl.dtx b/l3kernel/l3tl.dtx
index 9cd720d..3e18f8d 100644
--- a/l3kernel/l3tl.dtx
+++ b/l3kernel/l3tl.dtx
@@ -1184,13 +1184,13 @@
 \tex_ifodd:D \l at expl@enable at debug@bool
   \cs_new_protected:Npn \tl_set_eq:NN #1#2
     {
-      \__debug_chk_var_exist:N #1
+      \__debug_chk_var_local:N #1
       \__debug_chk_var_exist:N #2
       \cs_set_eq:NN #1 #2
     }
   \cs_new_protected:Npn \tl_gset_eq:NN #1#2
     {
-      \__debug_chk_var_exist:N #1
+      \__debug_chk_var_global:N #1
       \__debug_chk_var_exist:N #2
       \cs_gset_eq:NN #1 #2
     }
@@ -1212,7 +1212,6 @@
 %    \begin{macrocode}
 \__debug_patch:nnNNpn
   {
-    \__debug_chk_var_exist:N #1
     \__debug_chk_var_exist:N #2
     \__debug_chk_var_exist:N #3
   }
@@ -1221,7 +1220,6 @@
   { \tl_set:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } }
 \__debug_patch:nnNNpn
   {
-    \__debug_chk_var_exist:N #1
     \__debug_chk_var_exist:N #2
     \__debug_chk_var_exist:N #3
   }
@@ -1295,22 +1293,22 @@
 %   prefixed by a call to \cs{__debug_patch:nnNNpn} which adds an
 %   existence check to the definition.
 %    \begin{macrocode}
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_set:Nn #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:n {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_set:No #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:o {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_set:Nx #1#2
   { \cs_set_nopar:Npx #1 {#2} }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gset:Nn #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gset:No #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gset:Nx #1#2
   { \cs_gset_nopar:Npx #1 {#2} }
 \cs_generate_variant:Nn \tl_set:Nn  {         NV , Nv , Nf }
@@ -1335,28 +1333,28 @@
 %   }
 % Adding to the left is done directly to gain a little performance.
 %    \begin{macrocode}
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_left:Nn #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_left:NV #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_left:No #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_left:Nx #1#2
   { \cs_set_nopar:Npx #1 { #2 \exp_not:o #1 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_left:Nn #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_left:NV #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_left:No #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_left:Nx #1#2
   { \cs_gset_nopar:Npx #1 { #2 \exp_not:o {#1} } }
 \cs_generate_variant:Nn \tl_put_left:Nn  { c }
@@ -1385,28 +1383,28 @@
 %   }
 % The same on the right.
 %    \begin{macrocode}
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_right:Nn #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_right:NV #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_right:No #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
 \cs_new_protected:Npn \tl_put_right:Nx #1#2
   { \cs_set_nopar:Npx #1 { \exp_not:o #1 #2 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_right:Nn #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_right:NV #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_right:No #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
-\__debug_patch:nnNNpn { \__debug_chk_var_exist:N #1 } { }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
 \cs_new_protected:Npn \tl_gput_right:Nx #1#2
   { \cs_gset_nopar:Npx #1 { \exp_not:o {#1} #2 } }
 \cs_generate_variant:Nn \tl_put_right:Nn  { c }
diff --git a/l3kernel/testfiles/m3basics003.lvt b/l3kernel/testfiles/m3basics003.lvt
new file mode 100644
index 0000000..7a193ab
--- /dev/null
+++ b/l3kernel/testfiles/m3basics003.lvt
@@ -0,0 +1,65 @@
+%
+% Copyright (C) 2017 The LaTeX3 Project
+%
+
+\documentclass{minimal}
+\input{regression-test}
+
+
+
+% Leave some padding so that the line numbers
+% of the tests don't change later on.
+
+
+
+\RequirePackage[check-declarations,log-functions,native-drivers]{expl3}
+
+\START
+\AUTHOR{Bruno Le Floch}
+\ExplSyntaxOn
+
+\OMIT
+\tl_new:N \l_A_tl
+\tl_new:N \g_B_tl
+\tl_const:Nn \c_C_tl { }
+\quark_new:N \q_test
+\tl_new:N \gfoo
+\tl_new:N \lfoobar
+\TIMO
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { Local/global~assignments~without~checking }
+  {
+    \debug_suspend:
+    \tl_gset_eq:NN \l_A_tl \g_B_tl
+    \tl_set_eq:NN \l_A_tl \g_B_tl
+    \tl_set:Nn \g_B_tl { }
+    \tl_gconcat:NNN \g_B_tl \l_A_tl \c_C_tl
+    \tl_gconcat:NNN \l_A_tl \g_B_tl \g_B_tl
+    \tl_set:Nn \c_C_tl { }
+    \tl_set:Nn \q_test { }
+    \tl_gset:Nn \gfoo { }
+    \tl_set:Nn \lfoobar { }
+    \debug_resume:
+  }
+
+\TEST { Local/global~assignments~checked }
+  {
+    \tl_gset_eq:NN \l_A_tl \g_B_tl
+    \tl_set_eq:NN \l_A_tl \g_B_tl
+    \tl_set:Nn \g_B_tl { }
+    \tl_gconcat:NNN \g_B_tl \l_A_tl \c_C_tl
+    \tl_gconcat:NNN \l_A_tl \g_B_tl \g_B_tl
+    \tl_set:Nn \c_C_tl { }
+    \tl_set:Nn \q_test { }
+    \group_begin:
+      \tl_set:Nn \gfoo { }
+    \group_end:
+    \tl_gset:Nn \gfoo { }
+    \group_begin:
+      \tl_gset:Nn \lfoobar { }
+    \group_end:
+    \tl_set:Nn \lfoobar { }
+  }
+
+\END
diff --git a/l3kernel/testfiles/m3basics003.tlg b/l3kernel/testfiles/m3basics003.tlg
new file mode 100644
index 0000000..7cad011
--- /dev/null
+++ b/l3kernel/testfiles/m3basics003.tlg
@@ -0,0 +1,123 @@
+This is a generated file for the LaTeX (2e + expl3) validation system.
+Don't change this file in any respect.
+Author: Bruno Le Floch
+============================================================
+TEST 1: Local/global assignments without checking
+============================================================
+============================================================
+============================================================
+TEST 2: Local/global assignments checked
+============================================================
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\l_A_tl'.
+|...............................................
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Local assignment to a global variable '\g_B_tl'.
+|...............................................
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\l_A_tl'.
+|...............................................
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Local assignment to a constant variable '\c_C_tl'.
+|...............................................
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Local assignment to a constant variable '\q_test'.
+|...............................................
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\gfoo'.
+|...............................................
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Local assignment to a global variable '\lfoobar'.
+|...............................................
+============================================================
diff --git a/l3kernel/testfiles/m3clist002.tlg b/l3kernel/testfiles/m3clist002.tlg
index 4b93cdb..fb2893e 100644
--- a/l3kernel/testfiles/m3clist002.tlg
+++ b/l3kernel/testfiles/m3clist002.tlg
@@ -59,6 +59,22 @@ l. ...}
 | 
 | LaTeX will create the variable and continue.
 |...............................................
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...}
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Local assignment to a global variable '\g_undefined_clist'.
+|...............................................
 macro:->
 macro:->
 undefined
@@ -392,6 +408,22 @@ TEST 28: remove_duplicates
 ============================================================
 b\par ,c\par ,a\par 
 b\par ,c\par ,a\par ,c\par ,b\par ,a\par 
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...}
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\l_tmpa_clist'.
+|...............................................
 b\par ,c\par ,a\par 
 b\par ,c\par ,a\par 
 ============================================================
diff --git a/l3kernel/testfiles/m3expl001.luatex.tlg b/l3kernel/testfiles/m3expl001.luatex.tlg
index 6114e74..d4d2e9c 100644
--- a/l3kernel/testfiles/m3expl001.luatex.tlg
+++ b/l3kernel/testfiles/m3expl001.luatex.tlg
@@ -2864,6 +2864,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl001.ptex.tlg b/l3kernel/testfiles/m3expl001.ptex.tlg
index e1277b5..c2e08f9 100644
--- a/l3kernel/testfiles/m3expl001.ptex.tlg
+++ b/l3kernel/testfiles/m3expl001.ptex.tlg
@@ -2852,6 +2852,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl001.tlg b/l3kernel/testfiles/m3expl001.tlg
index a77b8c2..cdaf7a8 100644
--- a/l3kernel/testfiles/m3expl001.tlg
+++ b/l3kernel/testfiles/m3expl001.tlg
@@ -2852,6 +2852,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl001.uptex.tlg b/l3kernel/testfiles/m3expl001.uptex.tlg
index 99d2e67..16bcd69 100644
--- a/l3kernel/testfiles/m3expl001.uptex.tlg
+++ b/l3kernel/testfiles/m3expl001.uptex.tlg
@@ -2852,6 +2852,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl001.xetex.tlg b/l3kernel/testfiles/m3expl001.xetex.tlg
index 6cbb39c..a913d87 100644
--- a/l3kernel/testfiles/m3expl001.xetex.tlg
+++ b/l3kernel/testfiles/m3expl001.xetex.tlg
@@ -2862,6 +2862,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl003.luatex.tlg b/l3kernel/testfiles/m3expl003.luatex.tlg
index 6114e74..d4d2e9c 100644
--- a/l3kernel/testfiles/m3expl003.luatex.tlg
+++ b/l3kernel/testfiles/m3expl003.luatex.tlg
@@ -2864,6 +2864,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl003.ptex.tlg b/l3kernel/testfiles/m3expl003.ptex.tlg
index e1277b5..c2e08f9 100644
--- a/l3kernel/testfiles/m3expl003.ptex.tlg
+++ b/l3kernel/testfiles/m3expl003.ptex.tlg
@@ -2852,6 +2852,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl003.tlg b/l3kernel/testfiles/m3expl003.tlg
index a77b8c2..cdaf7a8 100644
--- a/l3kernel/testfiles/m3expl003.tlg
+++ b/l3kernel/testfiles/m3expl003.tlg
@@ -2852,6 +2852,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl003.uptex.tlg b/l3kernel/testfiles/m3expl003.uptex.tlg
index 99d2e67..16bcd69 100644
--- a/l3kernel/testfiles/m3expl003.uptex.tlg
+++ b/l3kernel/testfiles/m3expl003.uptex.tlg
@@ -2852,6 +2852,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3expl003.xetex.tlg b/l3kernel/testfiles/m3expl003.xetex.tlg
index 6cbb39c..a913d87 100644
--- a/l3kernel/testfiles/m3expl003.xetex.tlg
+++ b/l3kernel/testfiles/m3expl003.xetex.tlg
@@ -2862,6 +2862,7 @@ Defining message LaTeX/kernel/variant-too-long on line ...
 Defining message LaTeX/kernel/invalid-variant on line ...
 Defining message LaTeX/kernel/debug on line ...
 Defining message LaTeX/kernel/expr on line ...
+Defining message LaTeX/kernel/local-global on line ...
 Defining message LaTeX/kernel/non-declared-variable on line ...
 Defining message LaTeX/kernel/bad-exp-end-f on line ...
 Defining message LaTeX/kernel/bad-variable on line ...
diff --git a/l3kernel/testfiles/m3file002.tlg b/l3kernel/testfiles/m3file002.tlg
index b0e1b0b..5215e3d 100644
--- a/l3kernel/testfiles/m3file002.tlg
+++ b/l3kernel/testfiles/m3file002.tlg
@@ -5,7 +5,40 @@ Author: Bruno Le Floch
 TEST 1: Set tl from a file
 ============================================================
 \g__file_internal_ior=\read1
-(filetest.txt) (filetest.txt) (filetest.txt)
+(filetest.txt)
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\l_A_tl'.
+|...............................................
+(filetest.txt) (filetest.txt)
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\l_C_tl'.
+|...............................................
 |\ExplSyntaxOff Thisfileisneededbym3file001.lvt
 m3ior001.lvtandm3ior002.lvt:Pleaseleaveitalone!\ExplSyntaxOn |
 |\ExplSyntaxOff This file is needed by m3file001.lvt
@@ -16,7 +49,40 @@ m3ior001.lvtandm3ior002.lvt:Pleaseleaveitalone!\ExplSyntaxOn |
 ============================================================
 TEST 2: Set tl from a file with expansion
 ============================================================
-(filetest.txt) (filetest.txt) (filetest.txt)
+(filetest.txt)
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\l_A_tl'.
+|...............................................
+(filetest.txt) (filetest.txt)
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\l_C_tl'.
+|...............................................
 |\ExplSyntaxOff Thisfileisneededbym3file001.lvt
 m3ior001.lvtandm3ior002.lvt:Pleaseleaveitalone!\ExplSyntaxOn |
 |\ExplSyntaxOff This file is needed by m3file001.lvt
diff --git a/l3kernel/testfiles/m3prg002.tlg b/l3kernel/testfiles/m3prg002.tlg
index 1f2888b..38f9354 100644
--- a/l3kernel/testfiles/m3prg002.tlg
+++ b/l3kernel/testfiles/m3prg002.tlg
@@ -42,6 +42,22 @@ TEST 3: Set true/false
 ============================================================
 TRUE
 FALSE
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...}
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\myboolb'.
+|...............................................
 A:
 TRUE
 B:
@@ -52,6 +68,22 @@ FALSE
 B:
 FALSE
 ============================================================
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/local-global"
+! 
+! Inconsistent local/global assignment
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...}
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| This is a coding error.
+| 
+| Global assignment to a local variable '\myboolb'.
+|...............................................
 A:
 TRUE
 B:





More information about the latex3-commits mailing list