Merge branch 'main' into warnings

This commit is contained in:
Geoffrey White
2024-10-03 12:53:07 +01:00
39 changed files with 1366 additions and 282 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added several models of standard library functions and classes, in anticipation of no longer extracting the standard library in a future release.

View File

@@ -46,8 +46,6 @@ private module Cached {
or
containerStep(nodeFrom, nodeTo)
or
copyStep(nodeFrom, nodeTo)
or
DataFlowPrivate::forReadStep(nodeFrom, _, nodeTo)
or
DataFlowPrivate::iterableUnpackingReadStep(nodeFrom, _, nodeTo)
@@ -191,18 +189,6 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
DataFlowPrivate::comprehensionStoreStep(nodeFrom, _, nodeTo)
}
/**
* Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to copying.
*/
predicate copyStep(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) {
exists(DataFlow::CallCfgNode call | call = nodeTo |
call = API::moduleImport("copy").getMember(["copy", "deepcopy"]).getACall() and
call.getArg(0) = nodeFrom
)
or
nodeTo.(DataFlow::MethodCallNode).calls(nodeFrom, "copy")
}
/**
* Holds if taint can flow from `nodeFrom` to `nodeTo` with an `await`-step,
* such that the whole expression `await x` is tainted if `x` is tainted.

View File

@@ -21,9 +21,161 @@ extensions:
- ['argparse.ArgumentParser', 'Member[parse_args,parse_known_args].WithArity[0].ReturnValue', 'commandargs']
- ['os', 'Member[read].ReturnValue', 'file']
- addsTo:
pack: codeql/python-all
extensible: sinkModel
data:
- ["zipfile.ZipFile","Member[extractall].Argument[0,path:]", "path-injection"]
- addsTo:
pack: codeql/python-all
extensible: summaryModel
data:
- ['argparse.ArgumentParser', 'Member[parse_args,parse_known_args]', 'Argument[0,args:]', 'ReturnValue', 'taint']
# note: taint of attribute lookups is handled in QL
# See https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser
# note: taint flow for attribute lookups on `argparse.ArgumentParser` is handled in QL
- ["argparse.ArgumentParser", "Member[_parse_known_args,_read_args_from_files]", "Argument[0,arg_strings:]", "ReturnValue", "taint"]
- ["argparse.ArgumentParser", "Member[parse_args,parse_known_args]", "Argument[0,args:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/cgi.html#higher-level-interface
- ["cgi.FieldStorage", "Member[getfirst,getlist,getvalue]", "Argument[self]", "ReturnValue", "taint"]
# See
# - https://docs.python.org/3/glossary.html#term-mapping
# - https://docs.python.org/3/library/stdtypes.html#dict.get
- ["collections.abc.Mapping", "Member[get]", "Argument[1,default:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack
- ["contextlib.ExitStack", "Member[enter_context]", "Argument[0,cm:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/copy.html#copy.deepcopy
- ["copy", "Member[copy,deepcopy]", "Argument[0,x:]", "ReturnValue", "value"]
# See
# - https://docs.python.org/3/library/ctypes.html#ctypes.create_string_buffer
# - https://docs.python.org/3/library/ctypes.html#ctypes.create_unicode_buffer
- ["ctypes", "Member[create_string_buffer,create_unicode_buffer]", "Argument[0,init:,init_or_size:]", "ReturnValue", "taint"]
# See https://docs.python.org/3.11/distutils/apiref.html#distutils.util.change_root
- ["distutils", "Member[util].Member[change_root]", "Argument[0,new_root:,1,pathname:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/email.header.html#email.header.Header
- ["email.header.Header!", "Subclass.Call", "Argument[0,s:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/email.utils.html#email.utils.parseaddr
- ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue", "taint"]
- ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue.TupleElement[0,1]", "taint"]
# See See https://docs.python.org/3/library/fnmatch.html#fnmatch.filter
- ["fnmatch", "Member[filter]", "Argument[0,names:].ListElement", "ReturnValue.ListElement", "value"]
- ["fnmatch", "Member[filter]", "Argument[0,names:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/getopt.html#getopt.getopt
- ["getopt", "Member[getopt]", "Argument[0,args:]", "ReturnValue.TupleElement[1]", "taint"]
- ["getopt", "Member[getopt]", "Argument[1,shortopts:,2,longopts:]", "ReturnValue.TupleElement[0].ListElement.TupleElement[0]", "taint"]
# See https://docs.python.org/3/library/gettext.html#gettext.gettext
- ["gettext", "Member[gettext]", "Argument[0,message:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/gzip.html#gzip.GzipFile
- ["gzip.GzipFile!", "Subclass.Call", "Argument[0,filename:]", "ReturnValue", "taint"]
# See
# - https://docs.python.org/3/library/html.html#html.escape
# - https://docs.python.org/3/library/html.html#html.unescape
- ["html", "Member[escape,unescape]", "Argument[0,s:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/html.parser.html#html.parser.HTMLParser.feed
- ["html.parser.HTMLParser", "Member[feed]", "Argument[0,data:]", "Argument[self]", "taint"]
# See https://docs.python.org/3.11/library/imp.html#imp.find_module
- ["imp", "Member[find_module]", "Argument[0,name:,1,path:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/logging.html#logging.getLevelName
# specifically the no matching case
- ["logging", "Member[getLevelName]", "Argument[0,level:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/logging.html#logging.LogRecord.getMessage
- ["logging.LogRecord", "Member[getMessage]", "Argument[self]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/mimetypes.html#mimetypes.guess_type
- ["mimetypes", "Member[guess_type]", "Argument[0,url:]", "ReturnValue", "taint"]
# See https://github.com/python/cpython/blob/main/Lib/nturl2path.py
# No user-facing documentation, unfortunately.
- ["nturl2path", "Member[pathname2url]", "Argument[0,p:]", "ReturnValue", "taint"]
- ["nturl2path", "Member[url2pathname]", "Argument[0,url:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/optparse.html#optparse.OptionParser.parse_args
- ["optparse.OptionParser", "Member[parse_args]", "Argument[0,args:,1,values:]", "ReturnValue.TupleElement[0,1]", "taint"]
# See https://github.com/python/cpython/blob/3.10/Lib/pathlib.py#L972-L973
- ["pathlib.Path", ".Member[__enter__]", "Argument[self]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/os.html#os.PathLike.__fspath__
- ["pathlib.PurePath", "Member[__fspath__]", "Argument[self]", "ReturnValue", "taint"]
# See
# - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get
# - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get_nowait
- ["queue.Queue", "Member[get,get_nowait]", "Argument[self].ListElement", "ReturnValue", "value"]
- ["queue.Queue", "Member[get,get_nowait]", "Argument[self]", "ReturnValue", "taint"]
# See
# - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put
# - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put_nowait
- ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self].ListElement", "value"]
- ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self]", "taint"]
# See
# - https://docs.python.org/3/library/random.html#random.choice
# - https://docs.python.org/3/library/random.html#module-random
- ["random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"]
- ["random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"]
- ["random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"]
- ["random.Random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"]
- ["random.Random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"]
- ["random.Random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/shlex.html#shlex.quote
- ["shlex", "Member[quote]", "Argument[0,s:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/shutil.html#shutil.rmtree
- ["shutil", "Member[rmtree]", "Argument[0,path:]", "Argument[2,onerror:,onexc:].Parameter[1]", "taint"]
# See https://docs.python.org/3/library/shutil.html#shutil.which
- ["shutil", "Member[which]", "Argument[0,cmd:,2,path:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/subprocess.html#subprocess.Popen
- ["subprocess.Popen!", "Subclass.Call", "Argument[0,args:]", "ReturnValue", "taint"]
# See
# - https://docs.python.org/3/library/tarfile.html#tarfile.open
# - https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.open
- ["tarfile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"]
- ["tarfile.TarFile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/tempfile.html#tempfile.mkdtemp
- ["tempfile", "Member[mkdtemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp
- ["tempfile", "Member[mkstemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue.TupleElement[0,1]", "taint"]
# See https://docs.python.org/3/library/textwrap.html#textwrap.dedent
- ["textwrap", "Member[dedent]", "Argument[0,text:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/traceback.html#traceback.StackSummary.from_list
- ["traceback.StackSummary", "Member[from_list]", "Argument[0,a_list:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/typing.html#typing.cast
- ["typing", "Member[cast]", "Argument[1,val:]", "ReturnValue", "value"]
# See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote
- ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus
- ["urllib", "Member[parse].Member[quote_plus]", "Argument[0,string:]", "ReturnValue", "taint"]
# See https://epydoc.sourceforge.net/stdlib/urllib-module.html
- ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[0,1]", "taint"]
# See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote
- ["urllib", "Member[parse].Member[unquote]", "Argument[0,string:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote_plus
- ["urllib", "Member[parse].Member[unquote_plus]", "Argument[0,string:]", "ReturnValue", "taint"]
# We could consider a more precise source than the first argument, namely tuple or dict content.
# See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
- ["urllib", "Member[parse].Member[urlencode]", "Argument[0,query:]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin
- ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:,1,url:]", "ReturnValue", "taint"]
# See the internal documentation
# https://github.com/python/cpython/blob/3.12/Lib/zipfile/_path/__init__.py#L103-L105
- ["zipfile.CompleteDirs", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"]
# See https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile
# it may be necessary to read the code to understand the taint propagation
# Constructor: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1266
- ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue", "taint"]
- ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue.Attribute[filelist].ListElement.Attribute[filename]", "value"]
# _extract_member: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1761
- ["zipfile.ZipFile", "Member[_extract_member]", "Argument[1,targetpath:]", "ReturnValue", "taint"]
# infolist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1498-L1501
- ["zipfile.ZipFile", "Member[infolist]", "Argument[self]", "ReturnValue", "taint"]
- ["zipfile.ZipFile", "Member[infolist]", "Argument[self].Attribute[filelist]", "ReturnValue", "value"]
# namelist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1494-L1496
- ["zipfile.ZipFile", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"]
- addsTo:
pack: codeql/python-all
extensible: neutralModel
data: []
- addsTo:
pack: codeql/python-all
extensible: typeModel
data: []
- addsTo:
pack: codeql/python-all
extensible: typeVariableModel
data: []

View File

@@ -254,10 +254,14 @@ module Stdlib {
* See https://docs.python.org/3.9/library/logging.html#logging.Logger.
*/
module Logger {
private import semmle.python.dataflow.new.internal.DataFlowDispatch as DD
/** Gets a reference to the `logging.Logger` class or any subclass. */
API::Node subclassRef() {
result = API::moduleImport("logging").getMember("Logger").getASubclass*()
or
result = API::moduleImport("logging").getMember("getLoggerClass").getReturn().getASubclass*()
or
result = ModelOutput::getATypeNode("logging.Logger~Subclass").getASubclass*()
}
@@ -277,6 +281,13 @@ module Stdlib {
ClassInstantiation() {
this = subclassRef().getACall()
or
this =
DD::selfTracker(subclassRef()
.getAValueReachableFromSource()
.asExpr()
.(ClassExpr)
.getInnerScope())
or
this = API::moduleImport("logging").getMember("root").asSource()
or
this = API::moduleImport("logging").getMember("getLogger").getACall()
@@ -1492,6 +1503,9 @@ module StdlibPrivate {
or
// io.open is a special case, since it is an alias for the builtin `open`
result = API::moduleImport("io").getMember("open")
or
// similarly, coecs.open calls the builtin `open`: https://github.com/python/cpython/blob/3.12/Lib/codecs.py#L918
result = API::moduleImport("codecs").getMember("open")
}
/**
@@ -3260,8 +3274,13 @@ module StdlibPrivate {
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input in ["Argument[0]", "Argument[pattern:]"] and
output = "ReturnValue.Attribute[pattern]" and
preservesValue = true
(
output = "ReturnValue.Attribute[pattern]" and
preservesValue = true
or
output = "ReturnValue" and
preservesValue = false
)
}
}

View File

@@ -45,6 +45,7 @@ module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) {
node instanceof Sanitizer or
node instanceof CommandInjection::Sanitizer // using all sanitizers from `py/command-injection`
}

View File

@@ -8,7 +8,7 @@
private import python
import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.internal.TaintTrackingPrivate as TTP
private import semmle.python.ApiGraphs
/**
* Provides a data-flow configuration for detecting modifications of a parameters default value.
@@ -73,7 +73,13 @@ module ModificationOfParameterWithDefault {
or
// the target of a copy step is (presumably) a different object, and hence modifications of
// this object no longer matter for the purposes of this query.
TTP::copyStep(_, node) and state in [true, false]
copyTarget(node) and state in [true, false]
}
private predicate copyTarget(DataFlow::Node node) {
node = API::moduleImport("copy").getMember(["copy", "deepcopy"]).getACall()
or
node.(DataFlow::MethodCallNode).calls(_, "copy")
}
}

View File

@@ -75,6 +75,7 @@ edges
| UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | provenance | |
| UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | provenance | |
| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | Config |
| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:67 |
| UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | provenance | |
| UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | provenance | |
| UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | provenance | |

View File

@@ -1,13 +1,23 @@
edges
| test.py:10:16:10:24 | ControlFlowNode for file_path | test.py:11:21:11:29 | ControlFlowNode for file_path | provenance | |
| test.py:11:5:11:35 | ControlFlowNode for Attribute() | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:82 |
| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:12:21:12:29 | ControlFlowNode for file_path | provenance | |
| test.py:12:5:12:35 | ControlFlowNode for Attribute() | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:82 |
| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:14:26:14:34 | ControlFlowNode for file_path | provenance | |
| test.py:14:10:14:35 | ControlFlowNode for Attribute() | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:82 |
| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:18:26:18:34 | ControlFlowNode for file_path | provenance | |
| test.py:18:10:18:35 | ControlFlowNode for Attribute() | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:82 |
| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:22:21:22:29 | ControlFlowNode for file_path | provenance | |
| test.py:22:5:22:30 | ControlFlowNode for Attribute() | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:82 |
| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config |
| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:24:18:24:26 | ControlFlowNode for file_path | provenance | |
| test.py:24:18:24:26 | ControlFlowNode for file_path | test.py:24:5:24:52 | ControlFlowNode for Attribute() | provenance | Config |
@@ -37,14 +47,19 @@ edges
| test.py:28:26:28:34 | ControlFlowNode for file_path | test.py:64:36:64:44 | ControlFlowNode for file_path | provenance | |
nodes
| test.py:10:16:10:24 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path |
| test.py:11:5:11:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:11:5:11:52 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:11:21:11:29 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path |
| test.py:12:5:12:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:12:5:12:48 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:12:21:12:29 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path |
| test.py:14:10:14:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:14:26:14:34 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path |
| test.py:15:14:15:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:18:10:18:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:18:26:18:34 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path |
| test.py:19:14:19:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:22:5:22:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:22:5:22:60 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:22:21:22:29 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path |
| test.py:24:5:24:52 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |

View File

@@ -43,3 +43,12 @@ class MyLogger(logging.Logger):
pass
MyLogger("bar").info("hello") # $ loggingInput="hello"
class CustomLogger(logging.getLoggerClass()):
pass
CustomLogger("baz").info("hello") # $ loggingInput="hello"
class LoggerSubClassUsingSelf(logging.Logger):
def foo(self):
self.info("hello") # $ loggingInput="hello"

View File

@@ -183,7 +183,6 @@ lib/codeql/rust/elements/internal/BlockExprImpl.qll 36ac09e4a6eeeec22919b62b1d00
lib/codeql/rust/elements/internal/BoxPatConstructor.qll 153f110ba25fd6c889092bfd16f73bb610fa60d6e0c8965d5f44d2446fcd48a2 9324cf0d8aa29945551bf8ab64801d598f57aab8cd4e19bcd4e9ef8a4a4e06eb
lib/codeql/rust/elements/internal/BoxPatImpl.qll d62a3cc1d5bab6bd258f702ec731ec57f0e5ef2672ab9de4b6f3b558078629eb 26b4fabb676adbbdb0d7f81449e493ee49380ea04d131f779714ac2434bb323a
lib/codeql/rust/elements/internal/BreakExprConstructor.qll 356be043c28e0b34fdf925a119c945632ee883c6f5ebb9a27003c6a8d250afd9 bb77e66b04bb9489340e7506931559b94285c6904b6f9d2f83b214cba4f3cfd5
lib/codeql/rust/elements/internal/BreakExprImpl.qll 883ac0e2c0856c91f50747cf10cbcb3ecab535f6858913f2fa34236db8d211d6 5b20db08f16ea5ea3554ffbf6a2a69107e1ec8e3f31dd3935f8839b9a498f4bb
lib/codeql/rust/elements/internal/CallExprConstructor.qll 742b38e862e2cf82fd1ecc4d4fc5b4782a9c7c07f031452b2bae7aa59d5aa13a cad6e0a8be21d91b20ac2ec16cab9c30eae810b452c0f1992ed87d5c7f4144dc
lib/codeql/rust/elements/internal/CallExprImpl.qll 7e48610680ba6f2876a1a005ab0743496dd2364b9c44aca441bd33e11317e2d7 bb12c3c28156b40796fe3ba112760f87bb5abb323aab3c5b7bb3e0facaef8d35
lib/codeql/rust/elements/internal/CastExprConstructor.qll f3d6e10c4731f38a384675aeab3fba47d17b9e15648293787092bb3247ed808d d738a7751dbadb70aa1dcffcf8af7fa61d4cf8029798369a7e8620013afff4ed
@@ -202,7 +201,6 @@ lib/codeql/rust/elements/internal/ConstImpl.qll 7aac2b441a41f21b7d788e3eb042554f
lib/codeql/rust/elements/internal/ConstParamConstructor.qll f6645f952aac87c7e00e5e9661275312a1df47172088b4de6b5a253d5c4ed048 eda737470a7b89cf6a02715c9147d074041d6d00fd50d5b2d70266add6e4b571
lib/codeql/rust/elements/internal/ConstParamImpl.qll 909d85d857dfb973cd8e148744d3a88506d113d193d35ab0243be745d004ad45 c9e18170c5b4e4d5fca9f175bb139a248055b608ceafdd90c7182d06d67c3cba
lib/codeql/rust/elements/internal/ContinueExprConstructor.qll cd93f1b35ccdb031d7e8deba92f6a76187f6009c454f3ea07e89ba459de57ca6 6f658e7d580c4c9068b01d6dd6f72888b8800860668a6653f8c3b27dc9996935
lib/codeql/rust/elements/internal/ContinueExprImpl.qll 976890d17681315d2297b600a58c655ccc7c4db44cf587d7b5c359303f309acf 1ecae04df07ee20dcea4f00a9af33c108a0e15ed2ccf8b936804ad88ed66f883
lib/codeql/rust/elements/internal/DynTraitTypeConstructor.qll 2bfd81fdf116b76f4a62b47bed5f0a730c04ce79747ecd1d3b683b8de22ff4aa 375c57350c432351396b92f28fded1e95a8002e3a1b31f3b66039f9b3d9bdea9
lib/codeql/rust/elements/internal/DynTraitTypeImpl.qll 8ccf27db0b898f518874ae094e5c97206384ad2fd3f82f81a5ecaad953278f71 e28ab56b8814a804e23afa790ca0f9a2665195b0b316d6cc52936e76ce5c0011
lib/codeql/rust/elements/internal/EnumConstructor.qll eca1a13937faacb1db50e4cf69d175f992f2204a5aaed9144bb6f3cb63814ac5 1bafba78b2729fdb052a25a1ba3f4f70871564aa4df632b4a1d467858a437924

2
rust/ql/.gitattributes generated vendored
View File

@@ -185,7 +185,6 @@
/lib/codeql/rust/elements/internal/BoxPatConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/BoxPatImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/BreakExprConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/BreakExprImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/CallExprConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/CallExprImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/CastExprConstructor.qll linguist-generated
@@ -204,7 +203,6 @@
/lib/codeql/rust/elements/internal/ConstParamConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/ConstParamImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/ContinueExprConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/ContinueExprImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/DynTraitTypeConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/DynTraitTypeImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/EnumConstructor.qll linguist-generated

View File

@@ -51,7 +51,7 @@ class File extends Container, Impl::File {
loc = node.getLocation()
|
node.getFile() = this and
line = [loc.getStartLine(), loc.getEndLine()] and
line = [/*loc.getStartLine(), */ loc.getEndLine()] and // ignore start locations for now as we're getting them wrong for things with a comment attached
not loc instanceof EmptyLocation
)
)

View File

@@ -19,7 +19,9 @@ final class BooleanSuccessor = BooleanSuccessorImpl;
final class MatchSuccessor = MatchSuccessorImpl;
final class LoopJumpSuccessor = LoopJumpSuccessorImpl;
final class BreakSuccessor = BreakSuccessorImpl;
final class ContinueSuccessor = ContinueSuccessorImpl;
final class ReturnSuccessor = ReturnSuccessorImpl;

View File

@@ -7,13 +7,8 @@ newtype TCompletion =
TSimpleCompletion() or
TBooleanCompletion(Boolean b) or
TMatchCompletion(Boolean isMatch) or
TLoopCompletion(TLoopJumpType kind, TLabelType label) {
label = TNoLabel()
or
kind = TBreakJump() and label = TLabel(any(BreakExpr b).getLifetime().getText())
or
kind = TContinueJump() and label = TLabel(any(ContinueExpr b).getLifetime().getText())
} or
TBreakCompletion() or
TContinueCompletion() or
TReturnCompletion()
/** A completion of a statement or an expression. */
@@ -148,42 +143,23 @@ class MatchCompletion extends TMatchCompletion, ConditionalCompletion {
}
/**
* A completion that represents a break or a continue.
* A completion that represents a `break`.
*/
class LoopJumpCompletion extends TLoopCompletion, Completion {
override LoopJumpSuccessor getAMatchingSuccessorType() {
result = TLoopSuccessor(this.getKind(), this.getLabelType())
}
class BreakCompletion extends TBreakCompletion, Completion {
override BreakSuccessor getAMatchingSuccessorType() { any() }
final TLoopJumpType getKind() { this = TLoopCompletion(result, _) }
override predicate isValidForSpecific(AstNode e) { e instanceof BreakExpr }
final TLabelType getLabelType() { this = TLoopCompletion(_, result) }
override string toString() { result = this.getAMatchingSuccessorType().toString() }
}
final predicate hasLabel() { this.getLabelType() = TLabel(_) }
/**
* A completion that represents a `continue`.
*/
class ContinueCompletion extends TContinueCompletion, Completion {
override ContinueSuccessor getAMatchingSuccessorType() { any() }
final string getLabelName() { TLabel(result) = this.getLabelType() }
final predicate isContinue() { this.getKind() = TContinueJump() }
final predicate isBreak() { this.getKind() = TBreakJump() }
override predicate isValidForSpecific(AstNode e) {
this.isBreak() and
e instanceof BreakExpr and
(
not e.(BreakExpr).hasLifetime() and not this.hasLabel()
or
e.(BreakExpr).getLifetime().getText() = this.getLabelName()
)
or
this.isContinue() and
e instanceof ContinueExpr and
(
not e.(ContinueExpr).hasLifetime() and not this.hasLabel()
or
e.(ContinueExpr).getLifetime().getText() = this.getLabelName()
)
}
override predicate isValidForSpecific(AstNode e) { e instanceof ContinueExpr }
override string toString() { result = this.getAMatchingSuccessorType().toString() }
}

View File

@@ -145,44 +145,26 @@ class BlockExprTree extends StandardPostOrderTree, BlockExpr {
result = super.getStmtList().getTailExpr()
}
override predicate propagatesAbnormal(AstNode child) { none() }
/** Holds if this block captures the break completion `c`. */
private predicate capturesBreakCompletion(LoopJumpCompletion c) {
c.isBreak() and
c.getLabelName() = this.getLabel().getLifetime().getText()
}
override predicate succ(AstNode pred, AstNode succ, Completion c) {
super.succ(pred, succ, c)
or
// Edge for exiting the block with a break expressions
last(this.getChildNode(_), pred, c) and
this.capturesBreakCompletion(c) and
succ = this
}
override predicate last(AstNode last, Completion c) {
super.last(last, c)
or
// Any abnormal completions that this block does not capture should propagate
last(this.getChildNode(_), last, c) and
not completionIsNormal(c) and
not this.capturesBreakCompletion(c)
}
override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) }
}
class BreakExprTree extends PostOrderTree instanceof BreakExpr {
override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() }
class BreakExprTree extends PostOrderTree, BreakExpr {
override predicate propagatesAbnormal(AstNode child) { child = this.getExpr() }
override predicate first(AstNode node) {
first(super.getExpr(), node)
first(this.getExpr(), node)
or
not super.hasExpr() and node = this
not this.hasExpr() and node = this
}
override predicate last(AstNode last, Completion c) { none() }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
last(super.getExpr(), pred, c) and succ = this
or
pred = this and
c.isValidFor(pred) and
succ = this.getTarget()
}
}
@@ -200,7 +182,15 @@ class CastExprTree extends StandardPostOrderTree instanceof CastExpr {
class ClosureExprTree extends LeafTree instanceof ClosureExpr { }
class ContinueExprTree extends LeafTree instanceof ContinueExpr { }
class ContinueExprTree extends LeafTree, ContinueExpr {
override predicate last(AstNode last, Completion c) { none() }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
pred = this and
c.isValidFor(pred) and
first(this.getTarget().(LoopingExprTree).getLoopContinue(), succ)
}
}
class ExprStmtTree extends StandardPreOrderTree instanceof ExprStmt {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
@@ -310,57 +300,27 @@ class LetStmtTree extends PreOrderTree instanceof LetStmt {
class LiteralExprTree extends LeafTree instanceof LiteralExpr { }
abstract class LoopingExprTree extends PostOrderTree {
override predicate propagatesAbnormal(AstNode child) { none() }
override predicate propagatesAbnormal(AstNode child) { child = this.getLoopBody() }
abstract BlockExpr getLoopBody();
abstract Label getLabel();
/**
* Gets the node to execute when continuing the loop; either after
* executing the last node in the body or after an explicit `continue`.
*/
abstract AstNode getLoopContinue();
/** Holds if this loop captures the `c` completion. */
private predicate capturesLoopJumpCompletion(LoopJumpCompletion c) {
not c.hasLabel()
or
c.getLabelName() = this.getLabel().getLifetime().getText()
}
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge for exiting the loop with a break expressions
last(this.getLoopBody(), pred, c) and
c.(LoopJumpCompletion).isBreak() and
this.capturesLoopJumpCompletion(c) and
succ = this
or
// Edge back to the start for final expression and continue expressions
last(this.getLoopBody(), pred, c) and
(
completionIsNormal(c)
or
c.(LoopJumpCompletion).isContinue() and this.capturesLoopJumpCompletion(c)
) and
completionIsNormal(c) and
first(this.getLoopContinue(), succ)
}
override predicate last(AstNode last, Completion c) {
super.last(last, c)
or
// Any abnormal completions that this loop does not capture should propagate
last(this.getLoopBody(), last, c) and
not completionIsNormal(c) and
not this.capturesLoopJumpCompletion(c)
}
}
class LoopExprTree extends LoopingExprTree instanceof LoopExpr {
override BlockExpr getLoopBody() { result = LoopExpr.super.getLoopBody() }
override Label getLabel() { result = LoopExpr.super.getLabel() }
override AstNode getLoopContinue() { result = this.getLoopBody() }
override predicate first(AstNode node) { first(this.getLoopBody(), node) }
@@ -369,11 +329,13 @@ class LoopExprTree extends LoopingExprTree instanceof LoopExpr {
class WhileExprTree extends LoopingExprTree instanceof WhileExpr {
override BlockExpr getLoopBody() { result = WhileExpr.super.getLoopBody() }
override Label getLabel() { result = WhileExpr.super.getLabel() }
override AstNode getLoopContinue() { result = super.getCondition() }
override predicate propagatesAbnormal(AstNode child) { child = super.getCondition() }
override predicate propagatesAbnormal(AstNode child) {
super.propagatesAbnormal(child)
or
child = super.getCondition()
}
override predicate first(AstNode node) { first(super.getCondition(), node) }
@@ -399,11 +361,13 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr {
class ForExprTree extends LoopingExprTree instanceof ForExpr {
override BlockExpr getLoopBody() { result = ForExpr.super.getLoopBody() }
override Label getLabel() { result = ForExpr.super.getLabel() }
override AstNode getLoopContinue() { result = super.getPat() }
override predicate propagatesAbnormal(AstNode child) { child = super.getIterable() }
override predicate propagatesAbnormal(AstNode child) {
super.propagatesAbnormal(child)
or
child = super.getIterable()
}
override predicate first(AstNode node) { first(super.getIterable(), node) }

View File

@@ -15,7 +15,8 @@ newtype TSuccessorType =
TSuccessorSuccessor() or
TBooleanSuccessor(Boolean b) or
TMatchSuccessor(Boolean b) or
TLoopSuccessor(TLoopJumpType kind, TLabelType label) { exists(TLoopCompletion(kind, label)) } or
TBreakSuccessor() or
TContinueSuccessor() or
TReturnSuccessor()
/** The type of a control flow successor. */
@@ -59,28 +60,17 @@ class MatchSuccessorImpl extends ConditionalSuccessorImpl, TMatchSuccessor {
}
/**
* A control flow successor of a loop control flow expression, `continue` or `break`.
* A control flow successor of a `break` expression.
*/
class LoopJumpSuccessorImpl extends SuccessorTypeImpl, TLoopSuccessor {
private TLoopJumpType getKind() { this = TLoopSuccessor(result, _) }
class BreakSuccessorImpl extends SuccessorTypeImpl, TBreakSuccessor {
override string toString() { result = "break" }
}
private TLabelType getLabelType() { this = TLoopSuccessor(_, result) }
predicate hasLabel() { this.getLabelType() = TLabel(_) }
string getLabelName() { this = TLoopSuccessor(_, TLabel(result)) }
predicate isContinue() { this.getKind() = TContinueJump() }
predicate isBreak() { this.getKind() = TBreakJump() }
override string toString() {
exists(string kind, string label |
(if this.isContinue() then kind = "continue" else kind = "break") and
(if this.hasLabel() then label = "(" + this.getLabelName() + ")" else label = "") and
result = kind + label
)
}
/**
* A control flow successor of a `continue` expression.
*/
class ContinueSuccessorImpl extends SuccessorTypeImpl, TContinueSuccessor {
override string toString() { result = "continue" }
}
/**

View File

@@ -7,3 +7,7 @@ private import internal.VariableImpl
final class Variable = Impl::Variable;
final class VariableAccess = Impl::VariableAccess;
final class VariableWriteAccess = Impl::VariableWriteAccess;
final class VariableReadAccess = Impl::VariableReadAccess;

View File

@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `BreakExpr`.
*
@@ -12,6 +11,58 @@ private import codeql.rust.elements.internal.generated.BreakExpr
* be referenced directly.
*/
module Impl {
private import rust
private import codeql.rust.elements.internal.generated.ParentChild
/** Holds if `e` is a loop labelled `label`. */
pragma[nomagic]
predicate isLabelledLoop(Expr e, string label) {
e =
any(LoopExpr le |
label = le.getLabel().getLifetime().getText()
or
label = ""
)
or
e =
any(ForExpr fe |
label = fe.getLabel().getLifetime().getText()
or
label = ""
)
or
e =
any(WhileExpr we |
label = we.getLabel().getLifetime().getText()
or
label = ""
)
}
pragma[nomagic]
private predicate isLabelled(Expr e, string label) {
isLabelledLoop(e, label)
or
label = e.(BlockExpr).getLabel().getLifetime().getText()
}
pragma[nomagic]
private AstNode getABreakAncestor(BreakExpr be, string label) {
(
label = be.getLifetime().getText()
or
not be.hasLifetime() and
label = ""
) and
exists(AstNode n0 | result = getImmediateParent(n0) |
n0 = be
or
n0 = getABreakAncestor(be, label) and
not isLabelled(n0, label)
)
}
// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* A break expression. For example:
* ```rust
@@ -37,5 +88,19 @@ module Impl {
* };
* ```
*/
class BreakExpr extends Generated::BreakExpr { }
class BreakExpr extends Generated::BreakExpr {
/**
* Gets the target of this `break` expression.
*
* The target is either a `LoopExpr`, a `ForExpr`, a `WhileExpr`, or a
* `BlockExpr`.
*/
pragma[nomagic]
Expr getTarget() {
exists(string label |
result = getABreakAncestor(this, label) and
isLabelled(result, label)
)
}
}
}

View File

@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `ContinueExpr`.
*
@@ -12,6 +11,26 @@ private import codeql.rust.elements.internal.generated.ContinueExpr
* be referenced directly.
*/
module Impl {
private import codeql.rust.elements.internal.BreakExprImpl::Impl as BreakExprImpl
private import codeql.rust.elements.internal.generated.ParentChild
pragma[nomagic]
private AstNode getAContinueAncestor(ContinueExpr ce, string label) {
(
label = ce.getLifetime().getText()
or
not ce.hasLifetime() and
label = ""
) and
exists(AstNode n0 | result = getImmediateParent(n0) |
n0 = ce
or
n0 = getAContinueAncestor(ce, label) and
not BreakExprImpl::isLabelledLoop(n0, label)
)
}
// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* A continue expression. For example:
* ```rust
@@ -29,5 +48,18 @@ module Impl {
* }
* ```
*/
class ContinueExpr extends Generated::ContinueExpr { }
class ContinueExpr extends Generated::ContinueExpr {
/**
* Gets the target of this `continue` expression.
*
* The target is either a `LoopExpr`, a `ForExpr`, or a `WhileExpr`.
*/
pragma[nomagic]
Expr getTarget() {
exists(string label |
result = getAContinueAncestor(this, label) and
BreakExprImpl::isLabelledLoop(result, label)
)
}
}
}

View File

@@ -98,6 +98,27 @@ module Impl {
/** Gets an access to this variable. */
VariableAccess getAnAccess() { result.getVariable() = this }
/**
* Gets the pattern that declares this variable.
*
* Normally, the pattern is unique, except when introduced in an or pattern:
*
* ```rust
* match either {
* Either::Left(x) | Either::Right(x) => println!(x),
* }
* ```
*/
IdentPat getPat() { variableDecl(definingNode, result, name) }
/** Gets the initial value of this variable, if any. */
Expr getInitializer() {
exists(LetStmt let |
this.getPat() = let.getPat() and
result = let.getInitializer()
)
}
}
/** A path expression that may access a local variable. */
@@ -366,6 +387,38 @@ module Impl {
override string getAPrimaryQlClass() { result = "VariableAccess" }
}
/** Holds if `e` occurs in the LHS of an assignment or compound assignment. */
private predicate assignLhs(Expr e, boolean compound) {
exists(BinaryExpr be, string op |
op = be.getOperatorName().regexpCapture("(.*)=", 1) and
e = be.getLhs()
|
op = "" and compound = false
or
op != "" and compound = true
)
or
exists(Expr mid |
assignLhs(mid, compound) and
getImmediateParent(e) = mid
)
}
/** A variable write. */
class VariableWriteAccess extends VariableAccess {
VariableWriteAccess() { assignLhs(this, _) }
}
/** A variable read. */
class VariableReadAccess extends VariableAccess {
VariableReadAccess() {
not this instanceof VariableWriteAccess
or
// consider LHS in compound assignments both reads and writes
assignLhs(this, true)
}
}
cached
private module Cached {
cached

View File

@@ -3,13 +3,16 @@
* @description Unused variables may be an indication that the code is incomplete or has a typo.
* @kind problem
* @problem.severity recommendation
* @precision medium
* @precision high
* @id rust/unused-variable
* @tags maintainability
*/
import rust
from Locatable e
where none() // TODO: implement query
select e, "Variable is not used."
from Variable v
where
not exists(v.getAnAccess()) and
not exists(v.getInitializer()) and
not v.getName().charAt(0) = "_"
select v, "Variable is not used."

View File

@@ -1,3 +1,4 @@
edges
| test.rs:1:1:4:1 | enter test_call | test.rs:2:5:2:41 | ExprStmt | |
| test.rs:1:1:4:1 | exit test_call (normal) | test.rs:1:1:4:1 | exit test_call | |
| test.rs:1:24:4:1 | BlockExpr | test.rs:1:1:4:1 | exit test_call (normal) | |
@@ -76,9 +77,9 @@
| test.rs:31:24:33:17 | IfExpr | test.rs:29:17:33:17 | IfExpr | |
| test.rs:31:27:31:27 | b | test.rs:31:24:33:17 | IfExpr | false |
| test.rs:31:27:31:27 | b | test.rs:32:21:32:33 | ExprStmt | true |
| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | break('outer) |
| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | break |
| test.rs:32:21:32:33 | ExprStmt | test.rs:32:21:32:32 | BreakExpr | |
| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break('inner) |
| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break |
| test.rs:34:17:34:29 | ExprStmt | test.rs:34:17:34:28 | BreakExpr | |
| test.rs:37:9:37:12 | true | test.rs:26:48:38:5 | BlockExpr | |
| test.rs:40:5:52:5 | enter test_continue_with_labels | test.rs:42:13:42:14 | ExprStmt | |
@@ -93,9 +94,9 @@
| test.rs:46:24:48:17 | IfExpr | test.rs:44:17:48:17 | IfExpr | |
| test.rs:46:27:46:27 | b | test.rs:46:24:48:17 | IfExpr | false |
| test.rs:46:27:46:27 | b | test.rs:47:21:47:36 | ExprStmt | true |
| test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | continue('outer) |
| test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | continue |
| test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | |
| test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue('inner) |
| test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue |
| test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | |
| test.rs:54:5:66:5 | enter test_loop_label_shadowing | test.rs:56:13:56:14 | ExprStmt | |
| test.rs:56:13:56:13 | 1 | test.rs:58:17:62:17 | ExprStmt | |
@@ -109,9 +110,9 @@
| test.rs:60:24:62:17 | IfExpr | test.rs:58:17:62:17 | IfExpr | |
| test.rs:60:27:60:27 | b | test.rs:60:24:62:17 | IfExpr | false |
| test.rs:60:27:60:27 | b | test.rs:61:21:61:35 | ExprStmt | true |
| test.rs:61:21:61:34 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue('loop) |
| test.rs:61:21:61:34 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue |
| test.rs:61:21:61:35 | ExprStmt | test.rs:61:21:61:34 | ContinueExpr | |
| test.rs:63:17:63:30 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue('loop) |
| test.rs:63:17:63:30 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue |
| test.rs:63:17:63:31 | ExprStmt | test.rs:63:17:63:30 | ContinueExpr | |
| test.rs:68:5:77:5 | enter test_while | test.rs:69:9:69:25 | LetStmt | |
| test.rs:68:5:77:5 | exit test_while (normal) | test.rs:68:5:77:5 | exit test_while | |
@@ -337,7 +338,7 @@
| test.rs:182:16:182:20 | ... > ... | test.rs:182:13:184:13 | IfExpr | false |
| test.rs:182:16:182:20 | ... > ... | test.rs:183:17:183:36 | ExprStmt | true |
| test.rs:182:20:182:20 | 0 | test.rs:182:16:182:20 | ... > ... | |
| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr | break('label) |
| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr | break |
| test.rs:183:17:183:36 | ExprStmt | test.rs:183:30:183:30 | a | |
| test.rs:183:30:183:30 | a | test.rs:183:34:183:35 | 10 | |
| test.rs:183:30:183:35 | ... > ... | test.rs:183:17:183:35 | BreakExpr | |
@@ -356,7 +357,7 @@
| test.rs:194:9:200:9 | IfExpr | test.rs:193:43:201:5 | BlockExpr | |
| test.rs:194:13:196:9 | BlockExpr | test.rs:197:13:197:13 | 1 | true |
| test.rs:194:13:196:9 | BlockExpr | test.rs:199:13:199:13 | 0 | false |
| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr | break('block) |
| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr | break |
| test.rs:195:13:195:31 | ExprStmt | test.rs:195:26:195:26 | a | |
| test.rs:195:26:195:26 | a | test.rs:195:30:195:30 | 0 | |
| test.rs:195:26:195:30 | ... > ... | test.rs:195:13:195:30 | BreakExpr | |
@@ -510,7 +511,7 @@
| test.rs:283:12:283:28 | PathExpr | test.rs:283:12:283:30 | CallExpr | |
| test.rs:283:12:283:30 | CallExpr | test.rs:283:9:285:9 | IfExpr | false |
| test.rs:283:12:283:30 | CallExpr | test.rs:284:13:284:27 | ExprStmt | true |
| test.rs:284:13:284:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break('block) |
| test.rs:284:13:284:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break |
| test.rs:284:13:284:27 | ExprStmt | test.rs:284:26:284:26 | 1 | |
| test.rs:284:26:284:26 | 1 | test.rs:284:13:284:26 | BreakExpr | |
| test.rs:286:9:286:21 | PathExpr | test.rs:286:9:286:23 | CallExpr | |
@@ -521,7 +522,7 @@
| test.rs:287:12:287:28 | PathExpr | test.rs:287:12:287:30 | CallExpr | |
| test.rs:287:12:287:30 | CallExpr | test.rs:287:9:289:9 | IfExpr | false |
| test.rs:287:12:287:30 | CallExpr | test.rs:288:13:288:27 | ExprStmt | true |
| test.rs:288:13:288:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break('block) |
| test.rs:288:13:288:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break |
| test.rs:288:13:288:27 | ExprStmt | test.rs:288:26:288:26 | 2 | |
| test.rs:288:26:288:26 | 2 | test.rs:288:13:288:26 | BreakExpr | |
| test.rs:290:9:290:21 | PathExpr | test.rs:290:9:290:23 | CallExpr | |
@@ -541,7 +542,29 @@
| test.rs:298:13:298:19 | TupleStructPat | test.rs:299:13:299:27 | ExprStmt | no-match |
| test.rs:298:13:298:19 | TupleStructPat | test.rs:301:9:301:9 | x | match |
| test.rs:298:23:298:23 | x | test.rs:298:13:298:19 | TupleStructPat | |
| test.rs:299:13:299:26 | BreakExpr | test.rs:296:18:302:5 | BlockExpr | break('block) |
| test.rs:299:13:299:26 | BreakExpr | test.rs:296:18:302:5 | BlockExpr | break |
| test.rs:299:13:299:27 | ExprStmt | test.rs:299:26:299:26 | 1 | |
| test.rs:299:26:299:26 | 1 | test.rs:299:13:299:26 | BreakExpr | |
| test.rs:301:9:301:9 | x | test.rs:296:18:302:5 | BlockExpr | |
breakTarget
| test.rs:16:17:16:21 | BreakExpr | test.rs:10:9:22:9 | LoopExpr |
| test.rs:30:21:30:25 | BreakExpr | test.rs:28:13:35:13 | LoopExpr |
| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr |
| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr |
| test.rs:73:17:73:21 | BreakExpr | test.rs:70:9:76:9 | WhileExpr |
| test.rs:83:17:83:21 | BreakExpr | test.rs:81:9:85:9 | WhileExpr |
| test.rs:91:17:91:21 | BreakExpr | test.rs:89:9:94:9 | ForExpr |
| test.rs:170:17:170:28 | BreakExpr | test.rs:168:13:173:9 | LoopExpr |
| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr |
| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr |
| test.rs:284:13:284:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr |
| test.rs:288:13:288:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr |
| test.rs:299:13:299:26 | BreakExpr | test.rs:296:18:302:5 | BlockExpr |
continueTarget
| test.rs:19:17:19:24 | ContinueExpr | test.rs:10:9:22:9 | LoopExpr |
| test.rs:45:21:45:28 | ContinueExpr | test.rs:43:13:50:13 | LoopExpr |
| test.rs:47:21:47:35 | ContinueExpr | test.rs:41:9:51:9 | LoopExpr |
| test.rs:49:17:49:31 | ContinueExpr | test.rs:43:13:50:13 | LoopExpr |
| test.rs:59:21:59:28 | ContinueExpr | test.rs:57:13:64:13 | LoopExpr |
| test.rs:61:21:61:34 | ContinueExpr | test.rs:57:13:64:13 | LoopExpr |
| test.rs:63:17:63:30 | ContinueExpr | test.rs:57:13:64:13 | LoopExpr |

View File

@@ -0,0 +1 @@
query: utils/Cfg.ql

View File

@@ -0,0 +1,597 @@
edges
| variables.rs:1:1:3:1 | enter print_str | variables.rs:2:5:2:22 | ExprStmt | |
| variables.rs:1:1:3:1 | exit print_str (normal) | variables.rs:1:1:3:1 | exit print_str | |
| variables.rs:1:23:3:1 | BlockExpr | variables.rs:1:1:3:1 | exit print_str (normal) | |
| variables.rs:2:5:2:21 | MacroExpr | variables.rs:1:23:3:1 | BlockExpr | |
| variables.rs:2:5:2:22 | ExprStmt | variables.rs:2:5:2:21 | MacroExpr | |
| variables.rs:5:1:7:1 | enter print_i64 | variables.rs:6:5:6:22 | ExprStmt | |
| variables.rs:5:1:7:1 | exit print_i64 (normal) | variables.rs:5:1:7:1 | exit print_i64 | |
| variables.rs:5:22:7:1 | BlockExpr | variables.rs:5:1:7:1 | exit print_i64 (normal) | |
| variables.rs:6:5:6:21 | MacroExpr | variables.rs:5:22:7:1 | BlockExpr | |
| variables.rs:6:5:6:22 | ExprStmt | variables.rs:6:5:6:21 | MacroExpr | |
| variables.rs:9:1:12:1 | enter immutable_variable | variables.rs:10:5:10:17 | LetStmt | |
| variables.rs:9:1:12:1 | exit immutable_variable (normal) | variables.rs:9:1:12:1 | exit immutable_variable | |
| variables.rs:9:25:12:1 | BlockExpr | variables.rs:9:1:12:1 | exit immutable_variable (normal) | |
| variables.rs:10:5:10:17 | LetStmt | variables.rs:10:14:10:16 | "a" | |
| variables.rs:10:9:10:10 | x1 | variables.rs:11:5:11:18 | ExprStmt | match, no-match |
| variables.rs:10:14:10:16 | "a" | variables.rs:10:9:10:10 | x1 | |
| variables.rs:11:5:11:13 | PathExpr | variables.rs:11:15:11:16 | x1 | |
| variables.rs:11:5:11:17 | CallExpr | variables.rs:9:25:12:1 | BlockExpr | |
| variables.rs:11:5:11:18 | ExprStmt | variables.rs:11:5:11:13 | PathExpr | |
| variables.rs:11:15:11:16 | x1 | variables.rs:11:5:11:17 | CallExpr | |
| variables.rs:14:1:19:1 | enter mutable_variable | variables.rs:15:5:15:19 | LetStmt | |
| variables.rs:14:1:19:1 | exit mutable_variable (normal) | variables.rs:14:1:19:1 | exit mutable_variable | |
| variables.rs:14:23:19:1 | BlockExpr | variables.rs:14:1:19:1 | exit mutable_variable (normal) | |
| variables.rs:15:5:15:19 | LetStmt | variables.rs:15:18:15:18 | 4 | |
| variables.rs:15:9:15:14 | x2 | variables.rs:16:5:16:18 | ExprStmt | match, no-match |
| variables.rs:15:18:15:18 | 4 | variables.rs:15:9:15:14 | x2 | |
| variables.rs:16:5:16:13 | PathExpr | variables.rs:16:15:16:16 | x2 | |
| variables.rs:16:5:16:17 | CallExpr | variables.rs:17:5:17:11 | ExprStmt | |
| variables.rs:16:5:16:18 | ExprStmt | variables.rs:16:5:16:13 | PathExpr | |
| variables.rs:16:15:16:16 | x2 | variables.rs:16:5:16:17 | CallExpr | |
| variables.rs:17:5:17:6 | x2 | variables.rs:17:10:17:10 | 5 | |
| variables.rs:17:5:17:10 | ... = ... | variables.rs:18:5:18:18 | ExprStmt | |
| variables.rs:17:5:17:11 | ExprStmt | variables.rs:17:5:17:6 | x2 | |
| variables.rs:17:10:17:10 | 5 | variables.rs:17:5:17:10 | ... = ... | |
| variables.rs:18:5:18:13 | PathExpr | variables.rs:18:15:18:16 | x2 | |
| variables.rs:18:5:18:17 | CallExpr | variables.rs:14:23:19:1 | BlockExpr | |
| variables.rs:18:5:18:18 | ExprStmt | variables.rs:18:5:18:13 | PathExpr | |
| variables.rs:18:15:18:16 | x2 | variables.rs:18:5:18:17 | CallExpr | |
| variables.rs:21:1:27:1 | enter variable_shadow1 | variables.rs:22:5:22:15 | LetStmt | |
| variables.rs:21:1:27:1 | exit variable_shadow1 (normal) | variables.rs:21:1:27:1 | exit variable_shadow1 | |
| variables.rs:21:23:27:1 | BlockExpr | variables.rs:21:1:27:1 | exit variable_shadow1 (normal) | |
| variables.rs:22:5:22:15 | LetStmt | variables.rs:22:14:22:14 | 1 | |
| variables.rs:22:9:22:10 | x3 | variables.rs:23:5:23:18 | ExprStmt | match, no-match |
| variables.rs:22:14:22:14 | 1 | variables.rs:22:9:22:10 | x3 | |
| variables.rs:23:5:23:13 | PathExpr | variables.rs:23:15:23:16 | x3 | |
| variables.rs:23:5:23:17 | CallExpr | variables.rs:24:5:25:15 | LetStmt | |
| variables.rs:23:5:23:18 | ExprStmt | variables.rs:23:5:23:13 | PathExpr | |
| variables.rs:23:15:23:16 | x3 | variables.rs:23:5:23:17 | CallExpr | |
| variables.rs:24:5:25:15 | LetStmt | variables.rs:25:9:25:10 | x3 | |
| variables.rs:24:9:24:10 | x3 | variables.rs:26:5:26:18 | ExprStmt | match, no-match |
| variables.rs:25:9:25:10 | x3 | variables.rs:25:14:25:14 | 1 | |
| variables.rs:25:9:25:14 | ... + ... | variables.rs:24:9:24:10 | x3 | |
| variables.rs:25:14:25:14 | 1 | variables.rs:25:9:25:14 | ... + ... | |
| variables.rs:26:5:26:13 | PathExpr | variables.rs:26:15:26:16 | x3 | |
| variables.rs:26:5:26:17 | CallExpr | variables.rs:21:23:27:1 | BlockExpr | |
| variables.rs:26:5:26:18 | ExprStmt | variables.rs:26:5:26:13 | PathExpr | |
| variables.rs:26:15:26:16 | x3 | variables.rs:26:5:26:17 | CallExpr | |
| variables.rs:29:1:37:1 | enter variable_shadow2 | variables.rs:30:5:30:17 | LetStmt | |
| variables.rs:29:1:37:1 | exit variable_shadow2 (normal) | variables.rs:29:1:37:1 | exit variable_shadow2 | |
| variables.rs:29:23:37:1 | BlockExpr | variables.rs:29:1:37:1 | exit variable_shadow2 (normal) | |
| variables.rs:30:5:30:17 | LetStmt | variables.rs:30:14:30:16 | "a" | |
| variables.rs:30:9:30:10 | x4 | variables.rs:31:5:31:18 | ExprStmt | match, no-match |
| variables.rs:30:14:30:16 | "a" | variables.rs:30:9:30:10 | x4 | |
| variables.rs:31:5:31:13 | PathExpr | variables.rs:31:15:31:16 | x4 | |
| variables.rs:31:5:31:17 | CallExpr | variables.rs:32:5:35:5 | ExprStmt | |
| variables.rs:31:5:31:18 | ExprStmt | variables.rs:31:5:31:13 | PathExpr | |
| variables.rs:31:15:31:16 | x4 | variables.rs:31:5:31:17 | CallExpr | |
| variables.rs:32:5:35:5 | BlockExpr | variables.rs:36:5:36:18 | ExprStmt | |
| variables.rs:32:5:35:5 | ExprStmt | variables.rs:33:9:33:21 | LetStmt | |
| variables.rs:33:9:33:21 | LetStmt | variables.rs:33:18:33:20 | "b" | |
| variables.rs:33:13:33:14 | x4 | variables.rs:34:9:34:22 | ExprStmt | match, no-match |
| variables.rs:33:18:33:20 | "b" | variables.rs:33:13:33:14 | x4 | |
| variables.rs:34:9:34:17 | PathExpr | variables.rs:34:19:34:20 | x4 | |
| variables.rs:34:9:34:21 | CallExpr | variables.rs:32:5:35:5 | BlockExpr | |
| variables.rs:34:9:34:22 | ExprStmt | variables.rs:34:9:34:17 | PathExpr | |
| variables.rs:34:19:34:20 | x4 | variables.rs:34:9:34:21 | CallExpr | |
| variables.rs:36:5:36:13 | PathExpr | variables.rs:36:15:36:16 | x4 | |
| variables.rs:36:5:36:17 | CallExpr | variables.rs:29:23:37:1 | BlockExpr | |
| variables.rs:36:5:36:18 | ExprStmt | variables.rs:36:5:36:13 | PathExpr | |
| variables.rs:36:15:36:16 | x4 | variables.rs:36:5:36:17 | CallExpr | |
| variables.rs:44:1:59:1 | enter let_pattern1 | variables.rs:45:5:54:47 | LetStmt | |
| variables.rs:44:1:59:1 | exit let_pattern1 (normal) | variables.rs:44:1:59:1 | exit let_pattern1 | |
| variables.rs:44:19:59:1 | BlockExpr | variables.rs:44:1:59:1 | exit let_pattern1 (normal) | |
| variables.rs:45:5:54:47 | LetStmt | variables.rs:54:11:54:13 | "a" | |
| variables.rs:45:9:54:5 | TuplePat | variables.rs:55:5:55:18 | ExprStmt | match |
| variables.rs:54:9:54:46 | TupleExpr | variables.rs:45:9:54:5 | TuplePat | |
| variables.rs:54:10:54:19 | TupleExpr | variables.rs:54:33:54:35 | "x" | |
| variables.rs:54:11:54:13 | "a" | variables.rs:54:16:54:18 | "b" | |
| variables.rs:54:16:54:18 | "b" | variables.rs:54:10:54:19 | TupleExpr | |
| variables.rs:54:22:54:45 | RecordExpr | variables.rs:54:9:54:46 | TupleExpr | |
| variables.rs:54:33:54:35 | "x" | variables.rs:54:41:54:43 | "y" | |
| variables.rs:54:41:54:43 | "y" | variables.rs:54:22:54:45 | RecordExpr | |
| variables.rs:55:5:55:13 | PathExpr | variables.rs:55:15:55:16 | a1 | |
| variables.rs:55:5:55:17 | CallExpr | variables.rs:56:5:56:18 | ExprStmt | |
| variables.rs:55:5:55:18 | ExprStmt | variables.rs:55:5:55:13 | PathExpr | |
| variables.rs:55:15:55:16 | a1 | variables.rs:55:5:55:17 | CallExpr | |
| variables.rs:56:5:56:13 | PathExpr | variables.rs:56:15:56:16 | b1 | |
| variables.rs:56:5:56:17 | CallExpr | variables.rs:57:5:57:17 | ExprStmt | |
| variables.rs:56:5:56:18 | ExprStmt | variables.rs:56:5:56:13 | PathExpr | |
| variables.rs:56:15:56:16 | b1 | variables.rs:56:5:56:17 | CallExpr | |
| variables.rs:57:5:57:13 | PathExpr | variables.rs:57:15:57:15 | x | |
| variables.rs:57:5:57:16 | CallExpr | variables.rs:58:5:58:17 | ExprStmt | |
| variables.rs:57:5:57:17 | ExprStmt | variables.rs:57:5:57:13 | PathExpr | |
| variables.rs:57:15:57:15 | x | variables.rs:57:5:57:16 | CallExpr | |
| variables.rs:58:5:58:13 | PathExpr | variables.rs:58:15:58:15 | y | |
| variables.rs:58:5:58:16 | CallExpr | variables.rs:44:19:59:1 | BlockExpr | |
| variables.rs:58:5:58:17 | ExprStmt | variables.rs:58:5:58:13 | PathExpr | |
| variables.rs:58:15:58:15 | y | variables.rs:58:5:58:16 | CallExpr | |
| variables.rs:61:1:69:1 | enter let_pattern2 | variables.rs:62:5:62:38 | LetStmt | |
| variables.rs:61:1:69:1 | exit let_pattern2 (normal) | variables.rs:61:1:69:1 | exit let_pattern2 | |
| variables.rs:61:19:69:1 | BlockExpr | variables.rs:61:1:69:1 | exit let_pattern2 (normal) | |
| variables.rs:62:5:62:38 | LetStmt | variables.rs:62:25:62:27 | "a" | |
| variables.rs:62:9:62:10 | p1 | variables.rs:63:5:66:11 | LetStmt | match, no-match |
| variables.rs:62:14:62:37 | RecordExpr | variables.rs:62:9:62:10 | p1 | |
| variables.rs:62:25:62:27 | "a" | variables.rs:62:33:62:35 | "b" | |
| variables.rs:62:33:62:35 | "b" | variables.rs:62:14:62:37 | RecordExpr | |
| variables.rs:63:5:66:11 | LetStmt | variables.rs:66:9:66:10 | p1 | |
| variables.rs:63:9:66:5 | RecordPat | variables.rs:67:5:67:18 | ExprStmt | match |
| variables.rs:66:9:66:10 | p1 | variables.rs:63:9:66:5 | RecordPat | |
| variables.rs:67:5:67:13 | PathExpr | variables.rs:67:15:67:16 | a2 | |
| variables.rs:67:5:67:17 | CallExpr | variables.rs:68:5:68:18 | ExprStmt | |
| variables.rs:67:5:67:18 | ExprStmt | variables.rs:67:5:67:13 | PathExpr | |
| variables.rs:67:15:67:16 | a2 | variables.rs:67:5:67:17 | CallExpr | |
| variables.rs:68:5:68:13 | PathExpr | variables.rs:68:15:68:16 | b2 | |
| variables.rs:68:5:68:17 | CallExpr | variables.rs:61:19:69:1 | BlockExpr | |
| variables.rs:68:5:68:18 | ExprStmt | variables.rs:68:5:68:13 | PathExpr | |
| variables.rs:68:15:68:16 | b2 | variables.rs:68:5:68:17 | CallExpr | |
| variables.rs:71:1:78:1 | enter let_pattern3 | variables.rs:72:5:72:42 | LetStmt | |
| variables.rs:71:1:78:1 | exit let_pattern3 (normal) | variables.rs:71:1:78:1 | exit let_pattern3 | |
| variables.rs:71:19:78:1 | BlockExpr | variables.rs:71:1:78:1 | exit let_pattern3 (normal) | |
| variables.rs:72:5:72:42 | LetStmt | variables.rs:72:14:72:17 | PathExpr | |
| variables.rs:72:9:72:10 | s1 | variables.rs:74:8:75:12 | LetExpr | match, no-match |
| variables.rs:72:14:72:17 | PathExpr | variables.rs:72:19:72:30 | PathExpr | |
| variables.rs:72:14:72:41 | CallExpr | variables.rs:72:9:72:10 | s1 | |
| variables.rs:72:19:72:30 | PathExpr | variables.rs:72:32:72:39 | "Hello!" | |
| variables.rs:72:19:72:40 | CallExpr | variables.rs:72:14:72:41 | CallExpr | |
| variables.rs:72:32:72:39 | "Hello!" | variables.rs:72:19:72:40 | CallExpr | |
| variables.rs:74:5:77:5 | IfExpr | variables.rs:71:19:78:1 | BlockExpr | |
| variables.rs:74:8:75:12 | LetExpr | variables.rs:74:12:74:23 | TupleStructPat | |
| variables.rs:74:12:74:23 | TupleStructPat | variables.rs:74:5:77:5 | IfExpr | no-match |
| variables.rs:74:12:74:23 | TupleStructPat | variables.rs:76:9:76:22 | ExprStmt | match |
| variables.rs:75:14:77:5 | BlockExpr | variables.rs:74:5:77:5 | IfExpr | |
| variables.rs:76:9:76:17 | PathExpr | variables.rs:76:19:76:20 | s2 | |
| variables.rs:76:9:76:21 | CallExpr | variables.rs:75:14:77:5 | BlockExpr | |
| variables.rs:76:9:76:22 | ExprStmt | variables.rs:76:9:76:17 | PathExpr | |
| variables.rs:76:19:76:20 | s2 | variables.rs:76:9:76:21 | CallExpr | |
| variables.rs:80:1:86:1 | enter let_pattern4 | variables.rs:81:5:84:6 | LetStmt | |
| variables.rs:80:1:86:1 | exit let_pattern4 (normal) | variables.rs:80:1:86:1 | exit let_pattern4 | |
| variables.rs:80:19:86:1 | BlockExpr | variables.rs:80:1:86:1 | exit let_pattern4 (normal) | |
| variables.rs:81:5:84:6 | LetStmt | variables.rs:81:34:81:37 | PathExpr | |
| variables.rs:81:9:81:16 | TupleStructPat | variables.rs:83:9:83:15 | MacroExpr | no-match |
| variables.rs:81:9:81:16 | TupleStructPat | variables.rs:85:5:85:18 | ExprStmt | match |
| variables.rs:81:34:81:37 | PathExpr | variables.rs:81:39:81:42 | "x5" | |
| variables.rs:81:34:81:43 | CallExpr | variables.rs:81:9:81:16 | TupleStructPat | |
| variables.rs:81:39:81:42 | "x5" | variables.rs:81:34:81:43 | CallExpr | |
| variables.rs:83:9:83:15 | MacroExpr | variables.rs:81:50:84:5 | BlockExpr | |
| variables.rs:85:5:85:13 | PathExpr | variables.rs:85:15:85:16 | x5 | |
| variables.rs:85:5:85:17 | CallExpr | variables.rs:80:19:86:1 | BlockExpr | |
| variables.rs:85:5:85:18 | ExprStmt | variables.rs:85:5:85:13 | PathExpr | |
| variables.rs:85:15:85:16 | x5 | variables.rs:85:5:85:17 | CallExpr | |
| variables.rs:88:1:103:1 | enter match_pattern1 | variables.rs:89:5:89:21 | LetStmt | |
| variables.rs:88:1:103:1 | exit match_pattern1 (normal) | variables.rs:88:1:103:1 | exit match_pattern1 | |
| variables.rs:88:21:103:1 | BlockExpr | variables.rs:88:1:103:1 | exit match_pattern1 (normal) | |
| variables.rs:89:5:89:21 | LetStmt | variables.rs:89:14:89:17 | PathExpr | |
| variables.rs:89:9:89:10 | x6 | variables.rs:90:5:90:16 | LetStmt | match, no-match |
| variables.rs:89:14:89:17 | PathExpr | variables.rs:89:19:89:19 | 5 | |
| variables.rs:89:14:89:20 | CallExpr | variables.rs:89:9:89:10 | x6 | |
| variables.rs:89:19:89:19 | 5 | variables.rs:89:14:89:20 | CallExpr | |
| variables.rs:90:5:90:16 | LetStmt | variables.rs:90:14:90:15 | 10 | |
| variables.rs:90:9:90:10 | y1 | variables.rs:92:5:100:5 | ExprStmt | match, no-match |
| variables.rs:90:14:90:15 | 10 | variables.rs:90:9:90:10 | y1 | |
| variables.rs:92:5:100:5 | ExprStmt | variables.rs:92:11:92:12 | x6 | |
| variables.rs:92:5:100:5 | MatchExpr | variables.rs:102:5:102:18 | ExprStmt | |
| variables.rs:92:11:92:12 | x6 | variables.rs:93:9:93:16 | TupleStructPat | |
| variables.rs:93:9:93:16 | TupleStructPat | variables.rs:93:21:93:29 | PathExpr | match |
| variables.rs:93:9:93:16 | TupleStructPat | variables.rs:94:9:94:16 | TupleStructPat | no-match |
| variables.rs:93:21:93:29 | PathExpr | variables.rs:93:31:93:38 | "Got 50" | |
| variables.rs:93:21:93:39 | CallExpr | variables.rs:92:5:100:5 | MatchExpr | |
| variables.rs:93:31:93:38 | "Got 50" | variables.rs:93:21:93:39 | CallExpr | |
| variables.rs:94:9:94:16 | TupleStructPat | variables.rs:97:13:97:21 | PathExpr | match |
| variables.rs:94:9:94:16 | TupleStructPat | variables.rs:99:9:99:12 | None | no-match |
| variables.rs:96:9:98:9 | BlockExpr | variables.rs:92:5:100:5 | MatchExpr | |
| variables.rs:97:13:97:21 | PathExpr | variables.rs:97:23:97:24 | y1 | |
| variables.rs:97:13:97:25 | CallExpr | variables.rs:96:9:98:9 | BlockExpr | |
| variables.rs:97:23:97:24 | y1 | variables.rs:97:13:97:25 | CallExpr | |
| variables.rs:99:9:99:12 | None | variables.rs:99:17:99:25 | PathExpr | match |
| variables.rs:99:17:99:25 | PathExpr | variables.rs:99:27:99:32 | "NONE" | |
| variables.rs:99:17:99:33 | CallExpr | variables.rs:92:5:100:5 | MatchExpr | |
| variables.rs:99:27:99:32 | "NONE" | variables.rs:99:17:99:33 | CallExpr | |
| variables.rs:102:5:102:13 | PathExpr | variables.rs:102:15:102:16 | y1 | |
| variables.rs:102:5:102:17 | CallExpr | variables.rs:88:21:103:1 | BlockExpr | |
| variables.rs:102:5:102:18 | ExprStmt | variables.rs:102:5:102:13 | PathExpr | |
| variables.rs:102:15:102:16 | y1 | variables.rs:102:5:102:17 | CallExpr | |
| variables.rs:105:1:130:1 | enter match_pattern2 | variables.rs:106:5:106:36 | LetStmt | |
| variables.rs:105:1:130:1 | exit match_pattern2 (normal) | variables.rs:105:1:130:1 | exit match_pattern2 | |
| variables.rs:105:21:130:1 | BlockExpr | variables.rs:105:1:130:1 | exit match_pattern2 (normal) | |
| variables.rs:106:5:106:36 | LetStmt | variables.rs:106:20:106:20 | 2 | |
| variables.rs:106:9:106:15 | numbers | variables.rs:108:5:118:5 | ExprStmt | match, no-match |
| variables.rs:106:19:106:35 | TupleExpr | variables.rs:106:9:106:15 | numbers | |
| variables.rs:106:20:106:20 | 2 | variables.rs:106:23:106:23 | 4 | |
| variables.rs:106:23:106:23 | 4 | variables.rs:106:26:106:26 | 8 | |
| variables.rs:106:26:106:26 | 8 | variables.rs:106:29:106:30 | 16 | |
| variables.rs:106:29:106:30 | 16 | variables.rs:106:33:106:34 | 32 | |
| variables.rs:106:33:106:34 | 32 | variables.rs:106:19:106:35 | TupleExpr | |
| variables.rs:108:5:118:5 | ExprStmt | variables.rs:108:11:108:17 | numbers | |
| variables.rs:108:5:118:5 | MatchExpr | variables.rs:120:11:120:17 | numbers | |
| variables.rs:108:11:108:17 | numbers | variables.rs:109:9:113:9 | TuplePat | |
| variables.rs:109:9:113:9 | TuplePat | variables.rs:114:13:114:29 | ExprStmt | match |
| variables.rs:113:14:117:9 | BlockExpr | variables.rs:108:5:118:5 | MatchExpr | |
| variables.rs:114:13:114:21 | PathExpr | variables.rs:114:23:114:27 | first | |
| variables.rs:114:13:114:28 | CallExpr | variables.rs:115:13:115:29 | ExprStmt | |
| variables.rs:114:13:114:29 | ExprStmt | variables.rs:114:13:114:21 | PathExpr | |
| variables.rs:114:23:114:27 | first | variables.rs:114:13:114:28 | CallExpr | |
| variables.rs:115:13:115:21 | PathExpr | variables.rs:115:23:115:27 | third | |
| variables.rs:115:13:115:28 | CallExpr | variables.rs:116:13:116:29 | ExprStmt | |
| variables.rs:115:13:115:29 | ExprStmt | variables.rs:115:13:115:21 | PathExpr | |
| variables.rs:115:23:115:27 | third | variables.rs:115:13:115:28 | CallExpr | |
| variables.rs:116:13:116:21 | PathExpr | variables.rs:116:23:116:27 | fifth | |
| variables.rs:116:13:116:28 | CallExpr | variables.rs:113:14:117:9 | BlockExpr | |
| variables.rs:116:13:116:29 | ExprStmt | variables.rs:116:13:116:21 | PathExpr | |
| variables.rs:116:23:116:27 | fifth | variables.rs:116:13:116:28 | CallExpr | |
| variables.rs:120:5:129:5 | MatchExpr | variables.rs:105:21:130:1 | BlockExpr | |
| variables.rs:120:11:120:17 | numbers | variables.rs:121:9:125:9 | TuplePat | |
| variables.rs:121:9:125:9 | TuplePat | variables.rs:126:13:126:29 | ExprStmt | match |
| variables.rs:125:14:128:9 | BlockExpr | variables.rs:120:5:129:5 | MatchExpr | |
| variables.rs:126:13:126:21 | PathExpr | variables.rs:126:23:126:27 | first | |
| variables.rs:126:13:126:28 | CallExpr | variables.rs:127:13:127:28 | ExprStmt | |
| variables.rs:126:13:126:29 | ExprStmt | variables.rs:126:13:126:21 | PathExpr | |
| variables.rs:126:23:126:27 | first | variables.rs:126:13:126:28 | CallExpr | |
| variables.rs:127:13:127:21 | PathExpr | variables.rs:127:23:127:26 | last | |
| variables.rs:127:13:127:27 | CallExpr | variables.rs:125:14:128:9 | BlockExpr | |
| variables.rs:127:13:127:28 | ExprStmt | variables.rs:127:13:127:21 | PathExpr | |
| variables.rs:127:23:127:26 | last | variables.rs:127:13:127:27 | CallExpr | |
| variables.rs:132:1:140:1 | enter match_pattern3 | variables.rs:133:5:133:38 | LetStmt | |
| variables.rs:132:1:140:1 | exit match_pattern3 (normal) | variables.rs:132:1:140:1 | exit match_pattern3 | |
| variables.rs:132:21:140:1 | BlockExpr | variables.rs:132:1:140:1 | exit match_pattern3 (normal) | |
| variables.rs:133:5:133:38 | LetStmt | variables.rs:133:25:133:27 | "x" | |
| variables.rs:133:9:133:10 | p2 | variables.rs:135:11:135:12 | p2 | match, no-match |
| variables.rs:133:14:133:37 | RecordExpr | variables.rs:133:9:133:10 | p2 | |
| variables.rs:133:25:133:27 | "x" | variables.rs:133:33:133:35 | "y" | |
| variables.rs:133:33:133:35 | "y" | variables.rs:133:14:133:37 | RecordExpr | |
| variables.rs:135:5:139:5 | MatchExpr | variables.rs:132:21:140:1 | BlockExpr | |
| variables.rs:135:11:135:12 | p2 | variables.rs:136:9:138:9 | RecordPat | |
| variables.rs:136:9:138:9 | RecordPat | variables.rs:138:14:138:22 | PathExpr | match |
| variables.rs:138:14:138:22 | PathExpr | variables.rs:138:24:138:25 | x7 | |
| variables.rs:138:14:138:26 | CallExpr | variables.rs:135:5:139:5 | MatchExpr | |
| variables.rs:138:24:138:25 | x7 | variables.rs:138:14:138:26 | CallExpr | |
| variables.rs:146:1:159:1 | enter match_pattern4 | variables.rs:147:5:147:39 | LetStmt | |
| variables.rs:146:1:159:1 | exit match_pattern4 (normal) | variables.rs:146:1:159:1 | exit match_pattern4 | |
| variables.rs:146:21:159:1 | BlockExpr | variables.rs:146:1:159:1 | exit match_pattern4 (normal) | |
| variables.rs:147:5:147:39 | LetStmt | variables.rs:147:36:147:36 | 0 | |
| variables.rs:147:9:147:11 | msg | variables.rs:149:11:149:13 | msg | match, no-match |
| variables.rs:147:15:147:38 | RecordExpr | variables.rs:147:9:147:11 | msg | |
| variables.rs:147:36:147:36 | 0 | variables.rs:147:15:147:38 | RecordExpr | |
| variables.rs:149:5:158:5 | MatchExpr | variables.rs:146:21:159:1 | BlockExpr | |
| variables.rs:149:11:149:13 | msg | variables.rs:150:9:152:9 | RecordPat | |
| variables.rs:150:9:152:9 | RecordPat | variables.rs:152:14:152:22 | PathExpr | match |
| variables.rs:150:9:152:9 | RecordPat | variables.rs:153:9:153:38 | RecordPat | no-match |
| variables.rs:152:14:152:22 | PathExpr | variables.rs:152:24:152:34 | id_variable | |
| variables.rs:152:14:152:35 | CallExpr | variables.rs:149:5:158:5 | MatchExpr | |
| variables.rs:152:24:152:34 | id_variable | variables.rs:152:14:152:35 | CallExpr | |
| variables.rs:153:9:153:38 | RecordPat | variables.rs:154:13:154:52 | MacroExpr | match |
| variables.rs:153:9:153:38 | RecordPat | variables.rs:156:9:156:29 | RecordPat | no-match |
| variables.rs:153:43:155:9 | BlockExpr | variables.rs:149:5:158:5 | MatchExpr | |
| variables.rs:154:13:154:52 | MacroExpr | variables.rs:153:43:155:9 | BlockExpr | |
| variables.rs:156:9:156:29 | RecordPat | variables.rs:157:13:157:21 | PathExpr | match |
| variables.rs:157:13:157:21 | PathExpr | variables.rs:157:23:157:24 | id | |
| variables.rs:157:13:157:25 | CallExpr | variables.rs:149:5:158:5 | MatchExpr | |
| variables.rs:157:23:157:24 | id | variables.rs:157:13:157:25 | CallExpr | |
| variables.rs:166:1:172:1 | enter match_pattern5 | variables.rs:167:5:167:34 | LetStmt | |
| variables.rs:166:1:172:1 | exit match_pattern5 (normal) | variables.rs:166:1:172:1 | exit match_pattern5 | |
| variables.rs:166:21:172:1 | BlockExpr | variables.rs:166:1:172:1 | exit match_pattern5 (normal) | |
| variables.rs:167:5:167:34 | LetStmt | variables.rs:167:18:167:29 | PathExpr | |
| variables.rs:167:9:167:14 | either | variables.rs:168:11:168:16 | either | match, no-match |
| variables.rs:167:18:167:29 | PathExpr | variables.rs:167:31:167:32 | 32 | |
| variables.rs:167:18:167:33 | CallExpr | variables.rs:167:9:167:14 | either | |
| variables.rs:167:31:167:32 | 32 | variables.rs:167:18:167:33 | CallExpr | |
| variables.rs:168:5:171:5 | MatchExpr | variables.rs:166:21:172:1 | BlockExpr | |
| variables.rs:168:11:168:16 | either | variables.rs:169:9:169:44 | OrPat | |
| variables.rs:169:9:169:44 | OrPat | variables.rs:170:16:170:24 | PathExpr | match |
| variables.rs:170:16:170:24 | PathExpr | variables.rs:170:26:170:27 | a3 | |
| variables.rs:170:16:170:28 | CallExpr | variables.rs:168:5:171:5 | MatchExpr | |
| variables.rs:170:26:170:27 | a3 | variables.rs:170:16:170:28 | CallExpr | |
| variables.rs:180:1:194:1 | enter match_pattern6 | variables.rs:181:5:181:37 | LetStmt | |
| variables.rs:180:1:194:1 | exit match_pattern6 (normal) | variables.rs:180:1:194:1 | exit match_pattern6 | |
| variables.rs:180:21:194:1 | BlockExpr | variables.rs:180:1:194:1 | exit match_pattern6 (normal) | |
| variables.rs:181:5:181:37 | LetStmt | variables.rs:181:14:181:32 | PathExpr | |
| variables.rs:181:9:181:10 | tv | variables.rs:182:5:185:5 | ExprStmt | match, no-match |
| variables.rs:181:14:181:32 | PathExpr | variables.rs:181:34:181:35 | 62 | |
| variables.rs:181:14:181:36 | CallExpr | variables.rs:181:9:181:10 | tv | |
| variables.rs:181:34:181:35 | 62 | variables.rs:181:14:181:36 | CallExpr | |
| variables.rs:182:5:185:5 | ExprStmt | variables.rs:182:11:182:12 | tv | |
| variables.rs:182:5:185:5 | MatchExpr | variables.rs:186:5:189:5 | ExprStmt | |
| variables.rs:182:11:182:12 | tv | variables.rs:183:9:183:81 | OrPat | |
| variables.rs:183:9:183:81 | OrPat | variables.rs:184:16:184:24 | PathExpr | match |
| variables.rs:184:16:184:24 | PathExpr | variables.rs:184:26:184:27 | a4 | |
| variables.rs:184:16:184:28 | CallExpr | variables.rs:182:5:185:5 | MatchExpr | |
| variables.rs:184:26:184:27 | a4 | variables.rs:184:16:184:28 | CallExpr | |
| variables.rs:186:5:189:5 | ExprStmt | variables.rs:186:11:186:12 | tv | |
| variables.rs:186:5:189:5 | MatchExpr | variables.rs:190:11:190:12 | tv | |
| variables.rs:186:11:186:12 | tv | variables.rs:187:9:187:83 | OrPat | |
| variables.rs:187:9:187:83 | OrPat | variables.rs:188:16:188:24 | PathExpr | match |
| variables.rs:188:16:188:24 | PathExpr | variables.rs:188:26:188:27 | a5 | |
| variables.rs:188:16:188:28 | CallExpr | variables.rs:186:5:189:5 | MatchExpr | |
| variables.rs:188:26:188:27 | a5 | variables.rs:188:16:188:28 | CallExpr | |
| variables.rs:190:5:193:5 | MatchExpr | variables.rs:180:21:194:1 | BlockExpr | |
| variables.rs:190:11:190:12 | tv | variables.rs:191:9:191:83 | OrPat | |
| variables.rs:191:9:191:83 | OrPat | variables.rs:192:16:192:24 | PathExpr | match |
| variables.rs:192:16:192:24 | PathExpr | variables.rs:192:26:192:27 | a6 | |
| variables.rs:192:16:192:28 | CallExpr | variables.rs:190:5:193:5 | MatchExpr | |
| variables.rs:192:26:192:27 | a6 | variables.rs:192:16:192:28 | CallExpr | |
| variables.rs:196:1:204:1 | enter match_pattern7 | variables.rs:197:5:197:34 | LetStmt | |
| variables.rs:196:1:204:1 | exit match_pattern7 (normal) | variables.rs:196:1:204:1 | exit match_pattern7 | |
| variables.rs:196:21:204:1 | BlockExpr | variables.rs:196:1:204:1 | exit match_pattern7 (normal) | |
| variables.rs:197:5:197:34 | LetStmt | variables.rs:197:18:197:29 | PathExpr | |
| variables.rs:197:9:197:14 | either | variables.rs:198:11:198:16 | either | match, no-match |
| variables.rs:197:18:197:29 | PathExpr | variables.rs:197:31:197:32 | 32 | |
| variables.rs:197:18:197:33 | CallExpr | variables.rs:197:9:197:14 | either | |
| variables.rs:197:31:197:32 | 32 | variables.rs:197:18:197:33 | CallExpr | |
| variables.rs:198:5:203:5 | MatchExpr | variables.rs:196:21:204:1 | BlockExpr | |
| variables.rs:198:11:198:16 | either | variables.rs:199:9:199:44 | OrPat | |
| variables.rs:199:9:199:44 | OrPat | variables.rs:200:16:200:17 | a7 | match |
| variables.rs:199:9:199:44 | OrPat | variables.rs:202:9:202:9 | WildcardPat | no-match |
| variables.rs:200:16:200:17 | a7 | variables.rs:200:21:200:21 | 0 | |
| variables.rs:200:16:200:21 | ... > ... | variables.rs:201:16:201:24 | PathExpr | true |
| variables.rs:200:16:200:21 | ... > ... | variables.rs:202:9:202:9 | WildcardPat | false |
| variables.rs:200:21:200:21 | 0 | variables.rs:200:16:200:21 | ... > ... | |
| variables.rs:201:16:201:24 | PathExpr | variables.rs:201:26:201:27 | a7 | |
| variables.rs:201:16:201:28 | CallExpr | variables.rs:198:5:203:5 | MatchExpr | |
| variables.rs:201:26:201:27 | a7 | variables.rs:201:16:201:28 | CallExpr | |
| variables.rs:202:9:202:9 | WildcardPat | variables.rs:202:14:202:15 | TupleExpr | match |
| variables.rs:202:14:202:15 | TupleExpr | variables.rs:198:5:203:5 | MatchExpr | |
| variables.rs:206:1:221:1 | enter match_pattern8 | variables.rs:207:5:207:34 | LetStmt | |
| variables.rs:206:1:221:1 | exit match_pattern8 (normal) | variables.rs:206:1:221:1 | exit match_pattern8 | |
| variables.rs:206:21:221:1 | BlockExpr | variables.rs:206:1:221:1 | exit match_pattern8 (normal) | |
| variables.rs:207:5:207:34 | LetStmt | variables.rs:207:18:207:29 | PathExpr | |
| variables.rs:207:9:207:14 | either | variables.rs:209:11:209:16 | either | match, no-match |
| variables.rs:207:18:207:29 | PathExpr | variables.rs:207:31:207:32 | 32 | |
| variables.rs:207:18:207:33 | CallExpr | variables.rs:207:9:207:14 | either | |
| variables.rs:207:31:207:32 | 32 | variables.rs:207:18:207:33 | CallExpr | |
| variables.rs:209:5:220:5 | MatchExpr | variables.rs:206:21:221:1 | BlockExpr | |
| variables.rs:209:11:209:16 | either | variables.rs:210:9:211:52 | e | |
| variables.rs:210:9:211:52 | e | variables.rs:213:13:213:27 | ExprStmt | match |
| variables.rs:210:9:211:52 | e | variables.rs:219:9:219:9 | WildcardPat | no-match |
| variables.rs:212:12:218:9 | BlockExpr | variables.rs:209:5:220:5 | MatchExpr | |
| variables.rs:213:13:213:21 | PathExpr | variables.rs:213:23:213:25 | a11 | |
| variables.rs:213:13:213:26 | CallExpr | variables.rs:214:16:215:15 | LetExpr | |
| variables.rs:213:13:213:27 | ExprStmt | variables.rs:213:13:213:21 | PathExpr | |
| variables.rs:213:23:213:25 | a11 | variables.rs:213:13:213:26 | CallExpr | |
| variables.rs:214:13:217:13 | IfExpr | variables.rs:212:12:218:9 | BlockExpr | |
| variables.rs:214:16:215:15 | LetExpr | variables.rs:214:20:214:36 | TupleStructPat | |
| variables.rs:214:20:214:36 | TupleStructPat | variables.rs:214:13:217:13 | IfExpr | no-match |
| variables.rs:214:20:214:36 | TupleStructPat | variables.rs:216:17:216:32 | ExprStmt | match |
| variables.rs:215:17:217:13 | BlockExpr | variables.rs:214:13:217:13 | IfExpr | |
| variables.rs:216:17:216:25 | PathExpr | variables.rs:216:28:216:30 | a12 | |
| variables.rs:216:17:216:31 | CallExpr | variables.rs:215:17:217:13 | BlockExpr | |
| variables.rs:216:17:216:32 | ExprStmt | variables.rs:216:17:216:25 | PathExpr | |
| variables.rs:216:27:216:30 | * ... | variables.rs:216:17:216:31 | CallExpr | |
| variables.rs:216:28:216:30 | a12 | variables.rs:216:27:216:30 | * ... | |
| variables.rs:219:9:219:9 | WildcardPat | variables.rs:219:14:219:15 | TupleExpr | match |
| variables.rs:219:14:219:15 | TupleExpr | variables.rs:209:5:220:5 | MatchExpr | |
| variables.rs:230:1:236:1 | enter match_pattern9 | variables.rs:231:5:231:36 | LetStmt | |
| variables.rs:230:1:236:1 | exit match_pattern9 (normal) | variables.rs:230:1:236:1 | exit match_pattern9 | |
| variables.rs:230:21:236:1 | BlockExpr | variables.rs:230:1:236:1 | exit match_pattern9 (normal) | |
| variables.rs:231:5:231:36 | LetStmt | variables.rs:231:14:231:31 | PathExpr | |
| variables.rs:231:9:231:10 | fv | variables.rs:232:11:232:12 | fv | match, no-match |
| variables.rs:231:14:231:31 | PathExpr | variables.rs:231:33:231:34 | 62 | |
| variables.rs:231:14:231:35 | CallExpr | variables.rs:231:9:231:10 | fv | |
| variables.rs:231:33:231:34 | 62 | variables.rs:231:14:231:35 | CallExpr | |
| variables.rs:232:5:235:5 | MatchExpr | variables.rs:230:21:236:1 | BlockExpr | |
| variables.rs:232:11:232:12 | fv | variables.rs:233:9:233:109 | OrPat | |
| variables.rs:233:9:233:109 | OrPat | variables.rs:234:16:234:24 | PathExpr | match |
| variables.rs:234:16:234:24 | PathExpr | variables.rs:234:26:234:28 | a13 | |
| variables.rs:234:16:234:29 | CallExpr | variables.rs:232:5:235:5 | MatchExpr | |
| variables.rs:234:26:234:28 | a13 | variables.rs:234:16:234:29 | CallExpr | |
| variables.rs:238:1:247:1 | enter param_pattern1 | variables.rs:244:5:244:18 | ExprStmt | |
| variables.rs:238:1:247:1 | exit param_pattern1 (normal) | variables.rs:238:1:247:1 | exit param_pattern1 | |
| variables.rs:243:28:247:1 | BlockExpr | variables.rs:238:1:247:1 | exit param_pattern1 (normal) | |
| variables.rs:244:5:244:13 | PathExpr | variables.rs:244:15:244:16 | a8 | |
| variables.rs:244:5:244:17 | CallExpr | variables.rs:245:5:245:18 | ExprStmt | |
| variables.rs:244:5:244:18 | ExprStmt | variables.rs:244:5:244:13 | PathExpr | |
| variables.rs:244:15:244:16 | a8 | variables.rs:244:5:244:17 | CallExpr | |
| variables.rs:245:5:245:13 | PathExpr | variables.rs:245:15:245:16 | b3 | |
| variables.rs:245:5:245:17 | CallExpr | variables.rs:246:5:246:18 | ExprStmt | |
| variables.rs:245:5:245:18 | ExprStmt | variables.rs:245:5:245:13 | PathExpr | |
| variables.rs:245:15:245:16 | b3 | variables.rs:245:5:245:17 | CallExpr | |
| variables.rs:246:5:246:13 | PathExpr | variables.rs:246:15:246:16 | c1 | |
| variables.rs:246:5:246:17 | CallExpr | variables.rs:243:28:247:1 | BlockExpr | |
| variables.rs:246:5:246:18 | ExprStmt | variables.rs:246:5:246:13 | PathExpr | |
| variables.rs:246:15:246:16 | c1 | variables.rs:246:5:246:17 | CallExpr | |
| variables.rs:249:1:253:1 | enter param_pattern2 | variables.rs:252:5:252:18 | ExprStmt | |
| variables.rs:249:1:253:1 | exit param_pattern2 (normal) | variables.rs:249:1:253:1 | exit param_pattern2 | |
| variables.rs:251:9:253:1 | BlockExpr | variables.rs:249:1:253:1 | exit param_pattern2 (normal) | |
| variables.rs:252:5:252:13 | PathExpr | variables.rs:252:15:252:16 | a9 | |
| variables.rs:252:5:252:17 | CallExpr | variables.rs:251:9:253:1 | BlockExpr | |
| variables.rs:252:5:252:18 | ExprStmt | variables.rs:252:5:252:13 | PathExpr | |
| variables.rs:252:15:252:16 | a9 | variables.rs:252:5:252:17 | CallExpr | |
| variables.rs:255:1:290:1 | enter destruct_assignment | variables.rs:256:5:260:18 | LetStmt | |
| variables.rs:255:1:290:1 | exit destruct_assignment (normal) | variables.rs:255:1:290:1 | exit destruct_assignment | |
| variables.rs:255:26:290:1 | BlockExpr | variables.rs:255:1:290:1 | exit destruct_assignment (normal) | |
| variables.rs:256:5:260:18 | LetStmt | variables.rs:260:10:260:10 | 1 | |
| variables.rs:256:9:260:5 | TuplePat | variables.rs:261:5:261:19 | ExprStmt | match |
| variables.rs:260:9:260:17 | TupleExpr | variables.rs:256:9:260:5 | TuplePat | |
| variables.rs:260:10:260:10 | 1 | variables.rs:260:13:260:13 | 2 | |
| variables.rs:260:13:260:13 | 2 | variables.rs:260:16:260:16 | 3 | |
| variables.rs:260:16:260:16 | 3 | variables.rs:260:9:260:17 | TupleExpr | |
| variables.rs:261:5:261:13 | PathExpr | variables.rs:261:15:261:17 | a10 | |
| variables.rs:261:5:261:18 | CallExpr | variables.rs:262:5:262:18 | ExprStmt | |
| variables.rs:261:5:261:19 | ExprStmt | variables.rs:261:5:261:13 | PathExpr | |
| variables.rs:261:15:261:17 | a10 | variables.rs:261:5:261:18 | CallExpr | |
| variables.rs:262:5:262:13 | PathExpr | variables.rs:262:15:262:16 | b4 | |
| variables.rs:262:5:262:17 | CallExpr | variables.rs:263:5:263:18 | ExprStmt | |
| variables.rs:262:5:262:18 | ExprStmt | variables.rs:262:5:262:13 | PathExpr | |
| variables.rs:262:15:262:16 | b4 | variables.rs:262:5:262:17 | CallExpr | |
| variables.rs:263:5:263:13 | PathExpr | variables.rs:263:15:263:16 | c2 | |
| variables.rs:263:5:263:17 | CallExpr | variables.rs:265:5:273:6 | ExprStmt | |
| variables.rs:263:5:263:18 | ExprStmt | variables.rs:263:5:263:13 | PathExpr | |
| variables.rs:263:15:263:16 | c2 | variables.rs:263:5:263:17 | CallExpr | |
| variables.rs:265:5:269:5 | TupleExpr | variables.rs:270:9:270:11 | a10 | |
| variables.rs:265:5:273:5 | ... = ... | variables.rs:274:5:274:19 | ExprStmt | |
| variables.rs:265:5:273:6 | ExprStmt | variables.rs:266:9:266:10 | c2 | |
| variables.rs:266:9:266:10 | c2 | variables.rs:267:9:267:10 | b4 | |
| variables.rs:267:9:267:10 | b4 | variables.rs:268:9:268:11 | a10 | |
| variables.rs:268:9:268:11 | a10 | variables.rs:265:5:269:5 | TupleExpr | |
| variables.rs:269:9:273:5 | TupleExpr | variables.rs:265:5:273:5 | ... = ... | |
| variables.rs:270:9:270:11 | a10 | variables.rs:271:9:271:10 | b4 | |
| variables.rs:271:9:271:10 | b4 | variables.rs:272:9:272:10 | c2 | |
| variables.rs:272:9:272:10 | c2 | variables.rs:269:9:273:5 | TupleExpr | |
| variables.rs:274:5:274:13 | PathExpr | variables.rs:274:15:274:17 | a10 | |
| variables.rs:274:5:274:18 | CallExpr | variables.rs:275:5:275:18 | ExprStmt | |
| variables.rs:274:5:274:19 | ExprStmt | variables.rs:274:5:274:13 | PathExpr | |
| variables.rs:274:15:274:17 | a10 | variables.rs:274:5:274:18 | CallExpr | |
| variables.rs:275:5:275:13 | PathExpr | variables.rs:275:15:275:16 | b4 | |
| variables.rs:275:5:275:17 | CallExpr | variables.rs:276:5:276:18 | ExprStmt | |
| variables.rs:275:5:275:18 | ExprStmt | variables.rs:275:5:275:13 | PathExpr | |
| variables.rs:275:15:275:16 | b4 | variables.rs:275:5:275:17 | CallExpr | |
| variables.rs:276:5:276:13 | PathExpr | variables.rs:276:15:276:16 | c2 | |
| variables.rs:276:5:276:17 | CallExpr | variables.rs:278:5:286:5 | ExprStmt | |
| variables.rs:276:5:276:18 | ExprStmt | variables.rs:276:5:276:13 | PathExpr | |
| variables.rs:276:15:276:16 | c2 | variables.rs:276:5:276:17 | CallExpr | |
| variables.rs:278:5:286:5 | ExprStmt | variables.rs:278:12:278:12 | 4 | |
| variables.rs:278:5:286:5 | MatchExpr | variables.rs:288:5:288:19 | ExprStmt | |
| variables.rs:278:11:278:16 | TupleExpr | variables.rs:279:9:282:9 | TuplePat | |
| variables.rs:278:12:278:12 | 4 | variables.rs:278:15:278:15 | 5 | |
| variables.rs:278:15:278:15 | 5 | variables.rs:278:11:278:16 | TupleExpr | |
| variables.rs:279:9:282:9 | TuplePat | variables.rs:283:13:283:27 | ExprStmt | match |
| variables.rs:282:14:285:9 | BlockExpr | variables.rs:278:5:286:5 | MatchExpr | |
| variables.rs:283:13:283:21 | PathExpr | variables.rs:283:23:283:25 | a10 | |
| variables.rs:283:13:283:26 | CallExpr | variables.rs:284:13:284:26 | ExprStmt | |
| variables.rs:283:13:283:27 | ExprStmt | variables.rs:283:13:283:21 | PathExpr | |
| variables.rs:283:23:283:25 | a10 | variables.rs:283:13:283:26 | CallExpr | |
| variables.rs:284:13:284:21 | PathExpr | variables.rs:284:23:284:24 | b4 | |
| variables.rs:284:13:284:25 | CallExpr | variables.rs:282:14:285:9 | BlockExpr | |
| variables.rs:284:13:284:26 | ExprStmt | variables.rs:284:13:284:21 | PathExpr | |
| variables.rs:284:23:284:24 | b4 | variables.rs:284:13:284:25 | CallExpr | |
| variables.rs:288:5:288:13 | PathExpr | variables.rs:288:15:288:17 | a10 | |
| variables.rs:288:5:288:18 | CallExpr | variables.rs:289:5:289:18 | ExprStmt | |
| variables.rs:288:5:288:19 | ExprStmt | variables.rs:288:5:288:13 | PathExpr | |
| variables.rs:288:15:288:17 | a10 | variables.rs:288:5:288:18 | CallExpr | |
| variables.rs:289:5:289:13 | PathExpr | variables.rs:289:15:289:16 | b4 | |
| variables.rs:289:5:289:17 | CallExpr | variables.rs:255:26:290:1 | BlockExpr | |
| variables.rs:289:5:289:18 | ExprStmt | variables.rs:289:5:289:13 | PathExpr | |
| variables.rs:289:15:289:16 | b4 | variables.rs:289:5:289:17 | CallExpr | |
| variables.rs:292:1:307:1 | enter closure_variable | variables.rs:293:5:295:10 | LetStmt | |
| variables.rs:292:1:307:1 | exit closure_variable (normal) | variables.rs:292:1:307:1 | exit closure_variable | |
| variables.rs:292:23:307:1 | BlockExpr | variables.rs:292:1:307:1 | exit closure_variable (normal) | |
| variables.rs:293:5:295:10 | LetStmt | variables.rs:294:9:295:9 | ClosureExpr | |
| variables.rs:293:9:293:23 | example_closure | variables.rs:296:5:297:27 | LetStmt | match, no-match |
| variables.rs:294:9:295:9 | ClosureExpr | variables.rs:293:9:293:23 | example_closure | |
| variables.rs:294:9:295:9 | enter ClosureExpr | variables.rs:295:9:295:9 | x | |
| variables.rs:294:9:295:9 | exit ClosureExpr (normal) | variables.rs:294:9:295:9 | exit ClosureExpr | |
| variables.rs:295:9:295:9 | x | variables.rs:294:9:295:9 | exit ClosureExpr (normal) | |
| variables.rs:296:5:297:27 | LetStmt | variables.rs:297:9:297:23 | example_closure | |
| variables.rs:296:9:296:10 | n1 | variables.rs:298:5:298:18 | ExprStmt | match, no-match |
| variables.rs:297:9:297:23 | example_closure | variables.rs:297:25:297:25 | 5 | |
| variables.rs:297:9:297:26 | CallExpr | variables.rs:296:9:296:10 | n1 | |
| variables.rs:297:25:297:25 | 5 | variables.rs:297:9:297:26 | CallExpr | |
| variables.rs:298:5:298:13 | PathExpr | variables.rs:298:15:298:16 | n1 | |
| variables.rs:298:5:298:17 | CallExpr | variables.rs:300:5:300:25 | ExprStmt | |
| variables.rs:298:5:298:18 | ExprStmt | variables.rs:298:5:298:13 | PathExpr | |
| variables.rs:298:15:298:16 | n1 | variables.rs:298:5:298:17 | CallExpr | |
| variables.rs:300:5:300:22 | PathExpr | variables.rs:300:5:300:24 | CallExpr | |
| variables.rs:300:5:300:24 | CallExpr | variables.rs:301:5:303:10 | LetStmt | |
| variables.rs:300:5:300:25 | ExprStmt | variables.rs:300:5:300:22 | PathExpr | |
| variables.rs:301:5:303:10 | LetStmt | variables.rs:302:9:303:9 | ClosureExpr | |
| variables.rs:301:9:301:26 | immutable_variable | variables.rs:304:5:305:30 | LetStmt | match, no-match |
| variables.rs:302:9:303:9 | ClosureExpr | variables.rs:301:9:301:26 | immutable_variable | |
| variables.rs:302:9:303:9 | enter ClosureExpr | variables.rs:303:9:303:9 | x | |
| variables.rs:302:9:303:9 | exit ClosureExpr (normal) | variables.rs:302:9:303:9 | exit ClosureExpr | |
| variables.rs:303:9:303:9 | x | variables.rs:302:9:303:9 | exit ClosureExpr (normal) | |
| variables.rs:304:5:305:30 | LetStmt | variables.rs:305:9:305:26 | immutable_variable | |
| variables.rs:304:9:304:10 | n2 | variables.rs:306:5:306:18 | ExprStmt | match, no-match |
| variables.rs:305:9:305:26 | immutable_variable | variables.rs:305:28:305:28 | 6 | |
| variables.rs:305:9:305:29 | CallExpr | variables.rs:304:9:304:10 | n2 | |
| variables.rs:305:28:305:28 | 6 | variables.rs:305:9:305:29 | CallExpr | |
| variables.rs:306:5:306:13 | PathExpr | variables.rs:306:15:306:16 | n2 | |
| variables.rs:306:5:306:17 | CallExpr | variables.rs:292:23:307:1 | BlockExpr | |
| variables.rs:306:5:306:18 | ExprStmt | variables.rs:306:5:306:13 | PathExpr | |
| variables.rs:306:15:306:16 | n2 | variables.rs:306:5:306:17 | CallExpr | |
| variables.rs:309:1:316:1 | enter for_variable | variables.rs:310:5:310:42 | LetStmt | |
| variables.rs:309:1:316:1 | exit for_variable (normal) | variables.rs:309:1:316:1 | exit for_variable | |
| variables.rs:309:19:316:1 | BlockExpr | variables.rs:309:1:316:1 | exit for_variable (normal) | |
| variables.rs:310:5:310:42 | LetStmt | variables.rs:310:15:310:22 | "apples" | |
| variables.rs:310:9:310:9 | v | variables.rs:313:12:313:12 | v | match, no-match |
| variables.rs:310:13:310:41 | RefExpr | variables.rs:310:9:310:9 | v | |
| variables.rs:310:14:310:41 | ArrayExpr | variables.rs:310:13:310:41 | RefExpr | |
| variables.rs:310:15:310:22 | "apples" | variables.rs:310:25:310:30 | "cake" | |
| variables.rs:310:25:310:30 | "cake" | variables.rs:310:33:310:40 | "coffee" | |
| variables.rs:310:33:310:40 | "coffee" | variables.rs:310:14:310:41 | ArrayExpr | |
| variables.rs:312:5:315:5 | ForExpr | variables.rs:309:19:316:1 | BlockExpr | |
| variables.rs:312:9:312:12 | text | variables.rs:312:5:315:5 | ForExpr | no-match |
| variables.rs:312:9:312:12 | text | variables.rs:314:9:314:24 | ExprStmt | match |
| variables.rs:313:12:313:12 | v | variables.rs:312:9:312:12 | text | |
| variables.rs:313:14:315:5 | BlockExpr | variables.rs:312:9:312:12 | text | |
| variables.rs:314:9:314:17 | PathExpr | variables.rs:314:19:314:22 | text | |
| variables.rs:314:9:314:23 | CallExpr | variables.rs:313:14:315:5 | BlockExpr | |
| variables.rs:314:9:314:24 | ExprStmt | variables.rs:314:9:314:17 | PathExpr | |
| variables.rs:314:19:314:22 | text | variables.rs:314:9:314:23 | CallExpr | |
| variables.rs:318:1:341:1 | enter main | variables.rs:319:5:319:25 | ExprStmt | |
| variables.rs:318:1:341:1 | exit main (normal) | variables.rs:318:1:341:1 | exit main | |
| variables.rs:318:11:341:1 | BlockExpr | variables.rs:318:1:341:1 | exit main (normal) | |
| variables.rs:319:5:319:22 | PathExpr | variables.rs:319:5:319:24 | CallExpr | |
| variables.rs:319:5:319:24 | CallExpr | variables.rs:320:5:320:23 | ExprStmt | |
| variables.rs:319:5:319:25 | ExprStmt | variables.rs:319:5:319:22 | PathExpr | |
| variables.rs:320:5:320:20 | PathExpr | variables.rs:320:5:320:22 | CallExpr | |
| variables.rs:320:5:320:22 | CallExpr | variables.rs:321:5:321:23 | ExprStmt | |
| variables.rs:320:5:320:23 | ExprStmt | variables.rs:320:5:320:20 | PathExpr | |
| variables.rs:321:5:321:20 | PathExpr | variables.rs:321:5:321:22 | CallExpr | |
| variables.rs:321:5:321:22 | CallExpr | variables.rs:322:5:322:23 | ExprStmt | |
| variables.rs:321:5:321:23 | ExprStmt | variables.rs:321:5:321:20 | PathExpr | |
| variables.rs:322:5:322:20 | PathExpr | variables.rs:322:5:322:22 | CallExpr | |
| variables.rs:322:5:322:22 | CallExpr | variables.rs:323:5:323:19 | ExprStmt | |
| variables.rs:322:5:322:23 | ExprStmt | variables.rs:322:5:322:20 | PathExpr | |
| variables.rs:323:5:323:16 | PathExpr | variables.rs:323:5:323:18 | CallExpr | |
| variables.rs:323:5:323:18 | CallExpr | variables.rs:324:5:324:19 | ExprStmt | |
| variables.rs:323:5:323:19 | ExprStmt | variables.rs:323:5:323:16 | PathExpr | |
| variables.rs:324:5:324:16 | PathExpr | variables.rs:324:5:324:18 | CallExpr | |
| variables.rs:324:5:324:18 | CallExpr | variables.rs:325:5:325:19 | ExprStmt | |
| variables.rs:324:5:324:19 | ExprStmt | variables.rs:324:5:324:16 | PathExpr | |
| variables.rs:325:5:325:16 | PathExpr | variables.rs:325:5:325:18 | CallExpr | |
| variables.rs:325:5:325:18 | CallExpr | variables.rs:326:5:326:19 | ExprStmt | |
| variables.rs:325:5:325:19 | ExprStmt | variables.rs:325:5:325:16 | PathExpr | |
| variables.rs:326:5:326:16 | PathExpr | variables.rs:326:5:326:18 | CallExpr | |
| variables.rs:326:5:326:18 | CallExpr | variables.rs:327:5:327:21 | ExprStmt | |
| variables.rs:326:5:326:19 | ExprStmt | variables.rs:326:5:326:16 | PathExpr | |
| variables.rs:327:5:327:18 | PathExpr | variables.rs:327:5:327:20 | CallExpr | |
| variables.rs:327:5:327:20 | CallExpr | variables.rs:328:5:328:21 | ExprStmt | |
| variables.rs:327:5:327:21 | ExprStmt | variables.rs:327:5:327:18 | PathExpr | |
| variables.rs:328:5:328:18 | PathExpr | variables.rs:328:5:328:20 | CallExpr | |
| variables.rs:328:5:328:20 | CallExpr | variables.rs:329:5:329:21 | ExprStmt | |
| variables.rs:328:5:328:21 | ExprStmt | variables.rs:328:5:328:18 | PathExpr | |
| variables.rs:329:5:329:18 | PathExpr | variables.rs:329:5:329:20 | CallExpr | |
| variables.rs:329:5:329:20 | CallExpr | variables.rs:330:5:330:21 | ExprStmt | |
| variables.rs:329:5:329:21 | ExprStmt | variables.rs:329:5:329:18 | PathExpr | |
| variables.rs:330:5:330:18 | PathExpr | variables.rs:330:5:330:20 | CallExpr | |
| variables.rs:330:5:330:20 | CallExpr | variables.rs:331:5:331:21 | ExprStmt | |
| variables.rs:330:5:330:21 | ExprStmt | variables.rs:330:5:330:18 | PathExpr | |
| variables.rs:331:5:331:18 | PathExpr | variables.rs:331:5:331:20 | CallExpr | |
| variables.rs:331:5:331:20 | CallExpr | variables.rs:332:5:332:21 | ExprStmt | |
| variables.rs:331:5:331:21 | ExprStmt | variables.rs:331:5:331:18 | PathExpr | |
| variables.rs:332:5:332:18 | PathExpr | variables.rs:332:5:332:20 | CallExpr | |
| variables.rs:332:5:332:20 | CallExpr | variables.rs:333:5:333:21 | ExprStmt | |
| variables.rs:332:5:332:21 | ExprStmt | variables.rs:332:5:332:18 | PathExpr | |
| variables.rs:333:5:333:18 | PathExpr | variables.rs:333:5:333:20 | CallExpr | |
| variables.rs:333:5:333:20 | CallExpr | variables.rs:334:5:334:21 | ExprStmt | |
| variables.rs:333:5:333:21 | ExprStmt | variables.rs:333:5:333:18 | PathExpr | |
| variables.rs:334:5:334:18 | PathExpr | variables.rs:334:5:334:20 | CallExpr | |
| variables.rs:334:5:334:20 | CallExpr | variables.rs:335:5:335:21 | ExprStmt | |
| variables.rs:334:5:334:21 | ExprStmt | variables.rs:334:5:334:18 | PathExpr | |
| variables.rs:335:5:335:18 | PathExpr | variables.rs:335:5:335:20 | CallExpr | |
| variables.rs:335:5:335:20 | CallExpr | variables.rs:336:5:336:36 | ExprStmt | |
| variables.rs:335:5:335:21 | ExprStmt | variables.rs:335:5:335:18 | PathExpr | |
| variables.rs:336:5:336:18 | PathExpr | variables.rs:336:20:336:22 | "a" | |
| variables.rs:336:5:336:35 | CallExpr | variables.rs:337:5:337:37 | ExprStmt | |
| variables.rs:336:5:336:36 | ExprStmt | variables.rs:336:5:336:18 | PathExpr | |
| variables.rs:336:20:336:22 | "a" | variables.rs:336:26:336:28 | "b" | |
| variables.rs:336:25:336:34 | TupleExpr | variables.rs:336:5:336:35 | CallExpr | |
| variables.rs:336:26:336:28 | "b" | variables.rs:336:31:336:33 | "c" | |
| variables.rs:336:31:336:33 | "c" | variables.rs:336:25:336:34 | TupleExpr | |
| variables.rs:337:5:337:18 | PathExpr | variables.rs:337:20:337:31 | PathExpr | |
| variables.rs:337:5:337:36 | CallExpr | variables.rs:338:5:338:26 | ExprStmt | |
| variables.rs:337:5:337:37 | ExprStmt | variables.rs:337:5:337:18 | PathExpr | |
| variables.rs:337:20:337:31 | PathExpr | variables.rs:337:33:337:34 | 45 | |
| variables.rs:337:20:337:35 | CallExpr | variables.rs:337:5:337:36 | CallExpr | |
| variables.rs:337:33:337:34 | 45 | variables.rs:337:20:337:35 | CallExpr | |
| variables.rs:338:5:338:23 | PathExpr | variables.rs:338:5:338:25 | CallExpr | |
| variables.rs:338:5:338:25 | CallExpr | variables.rs:339:5:339:23 | ExprStmt | |
| variables.rs:338:5:338:26 | ExprStmt | variables.rs:338:5:338:23 | PathExpr | |
| variables.rs:339:5:339:20 | PathExpr | variables.rs:339:5:339:22 | CallExpr | |
| variables.rs:339:5:339:22 | CallExpr | variables.rs:340:5:340:19 | ExprStmt | |
| variables.rs:339:5:339:23 | ExprStmt | variables.rs:339:5:339:20 | PathExpr | |
| variables.rs:340:5:340:16 | PathExpr | variables.rs:340:5:340:18 | CallExpr | |
| variables.rs:340:5:340:18 | CallExpr | variables.rs:318:11:341:1 | BlockExpr | |
| variables.rs:340:5:340:19 | ExprStmt | variables.rs:340:5:340:16 | PathExpr | |
breakTarget
continueTarget

View File

@@ -0,0 +1 @@
query: utils/Cfg.ql

View File

@@ -146,3 +146,109 @@ variableAccess
| variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 |
| variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v |
| variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text |
variableWriteAccess
| variables.rs:17:5:17:6 | x2 | variables.rs:15:13:15:14 | x2 |
| variables.rs:266:9:266:10 | c2 | variables.rs:259:13:259:14 | c2 |
| variables.rs:267:9:267:10 | b4 | variables.rs:258:13:258:14 | b4 |
| variables.rs:268:9:268:11 | a10 | variables.rs:257:13:257:15 | a10 |
variableReadAccess
| variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 |
| variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 |
| variables.rs:18:15:18:16 | x2 | variables.rs:15:13:15:14 | x2 |
| variables.rs:23:15:23:16 | x3 | variables.rs:22:9:22:10 | x3 |
| variables.rs:25:9:25:10 | x3 | variables.rs:22:9:22:10 | x3 |
| variables.rs:26:15:26:16 | x3 | variables.rs:24:9:24:10 | x3 |
| variables.rs:31:15:31:16 | x4 | variables.rs:30:9:30:10 | x4 |
| variables.rs:34:19:34:20 | x4 | variables.rs:33:13:33:14 | x4 |
| variables.rs:36:15:36:16 | x4 | variables.rs:30:9:30:10 | x4 |
| variables.rs:55:15:55:16 | a1 | variables.rs:47:13:47:14 | a1 |
| variables.rs:56:15:56:16 | b1 | variables.rs:48:13:48:14 | b1 |
| variables.rs:57:15:57:15 | x | variables.rs:51:13:51:13 | x |
| variables.rs:58:15:58:15 | y | variables.rs:52:13:52:13 | y |
| variables.rs:66:9:66:10 | p1 | variables.rs:62:9:62:10 | p1 |
| variables.rs:67:15:67:16 | a2 | variables.rs:64:12:64:13 | a2 |
| variables.rs:68:15:68:16 | b2 | variables.rs:65:12:65:13 | b2 |
| variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 |
| variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 |
| variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 |
| variables.rs:92:11:92:12 | x6 | variables.rs:89:9:89:10 | x6 |
| variables.rs:97:23:97:24 | y1 | variables.rs:94:14:94:15 | y1 |
| variables.rs:102:15:102:16 | y1 | variables.rs:90:9:90:10 | y1 |
| variables.rs:108:11:108:17 | numbers | variables.rs:106:9:106:15 | numbers |
| variables.rs:114:23:114:27 | first | variables.rs:110:13:110:17 | first |
| variables.rs:115:23:115:27 | third | variables.rs:111:13:111:17 | third |
| variables.rs:116:23:116:27 | fifth | variables.rs:112:13:112:17 | fifth |
| variables.rs:120:11:120:17 | numbers | variables.rs:106:9:106:15 | numbers |
| variables.rs:126:23:126:27 | first | variables.rs:122:13:122:17 | first |
| variables.rs:127:23:127:26 | last | variables.rs:124:13:124:16 | last |
| variables.rs:135:11:135:12 | p2 | variables.rs:133:9:133:10 | p2 |
| variables.rs:138:24:138:25 | x7 | variables.rs:137:16:137:17 | x7 |
| variables.rs:149:11:149:13 | msg | variables.rs:147:9:147:11 | msg |
| variables.rs:152:24:152:34 | id_variable | variables.rs:151:17:151:27 | id_variable |
| variables.rs:157:23:157:24 | id | variables.rs:156:26:156:27 | id |
| variables.rs:168:11:168:16 | either | variables.rs:167:9:167:14 | either |
| variables.rs:170:26:170:27 | a3 | variables.rs:169:9:169:44 | a3 |
| variables.rs:182:11:182:12 | tv | variables.rs:181:9:181:10 | tv |
| variables.rs:184:26:184:27 | a4 | variables.rs:183:9:183:81 | a4 |
| variables.rs:186:11:186:12 | tv | variables.rs:181:9:181:10 | tv |
| variables.rs:188:26:188:27 | a5 | variables.rs:187:9:187:83 | a5 |
| variables.rs:190:11:190:12 | tv | variables.rs:181:9:181:10 | tv |
| variables.rs:192:26:192:27 | a6 | variables.rs:191:9:191:83 | a6 |
| variables.rs:198:11:198:16 | either | variables.rs:197:9:197:14 | either |
| variables.rs:200:16:200:17 | a7 | variables.rs:199:9:199:44 | a7 |
| variables.rs:201:26:201:27 | a7 | variables.rs:199:9:199:44 | a7 |
| variables.rs:209:11:209:16 | either | variables.rs:207:9:207:14 | either |
| variables.rs:213:23:213:25 | a11 | variables.rs:211:14:211:51 | a11 |
| variables.rs:215:15:215:15 | e | variables.rs:210:13:210:13 | e |
| variables.rs:216:28:216:30 | a12 | variables.rs:214:33:214:35 | a12 |
| variables.rs:232:11:232:12 | fv | variables.rs:231:9:231:10 | fv |
| variables.rs:234:26:234:28 | a13 | variables.rs:233:9:233:109 | a13 |
| variables.rs:244:15:244:16 | a8 | variables.rs:239:5:239:6 | a8 |
| variables.rs:245:15:245:16 | b3 | variables.rs:241:9:241:10 | b3 |
| variables.rs:246:15:246:16 | c1 | variables.rs:242:9:242:10 | c1 |
| variables.rs:252:15:252:16 | a9 | variables.rs:250:6:250:41 | a9 |
| variables.rs:261:15:261:17 | a10 | variables.rs:257:13:257:15 | a10 |
| variables.rs:262:15:262:16 | b4 | variables.rs:258:13:258:14 | b4 |
| variables.rs:263:15:263:16 | c2 | variables.rs:259:13:259:14 | c2 |
| variables.rs:270:9:270:11 | a10 | variables.rs:257:13:257:15 | a10 |
| variables.rs:271:9:271:10 | b4 | variables.rs:258:13:258:14 | b4 |
| variables.rs:272:9:272:10 | c2 | variables.rs:259:13:259:14 | c2 |
| variables.rs:274:15:274:17 | a10 | variables.rs:257:13:257:15 | a10 |
| variables.rs:275:15:275:16 | b4 | variables.rs:258:13:258:14 | b4 |
| variables.rs:276:15:276:16 | c2 | variables.rs:259:13:259:14 | c2 |
| variables.rs:283:23:283:25 | a10 | variables.rs:280:13:280:15 | a10 |
| variables.rs:284:23:284:24 | b4 | variables.rs:281:13:281:14 | b4 |
| variables.rs:288:15:288:17 | a10 | variables.rs:257:13:257:15 | a10 |
| variables.rs:289:15:289:16 | b4 | variables.rs:258:13:258:14 | b4 |
| variables.rs:295:9:295:9 | x | variables.rs:294:10:294:10 | x |
| variables.rs:297:9:297:23 | example_closure | variables.rs:293:9:293:23 | example_closure |
| variables.rs:298:15:298:16 | n1 | variables.rs:296:9:296:10 | n1 |
| variables.rs:303:9:303:9 | x | variables.rs:302:10:302:10 | x |
| variables.rs:305:9:305:26 | immutable_variable | variables.rs:301:9:301:26 | immutable_variable |
| variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 |
| variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v |
| variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text |
variableInitializer
| variables.rs:10:9:10:10 | x1 | variables.rs:10:14:10:16 | "a" |
| variables.rs:15:13:15:14 | x2 | variables.rs:15:18:15:18 | 4 |
| variables.rs:22:9:22:10 | x3 | variables.rs:22:14:22:14 | 1 |
| variables.rs:24:9:24:10 | x3 | variables.rs:25:9:25:14 | ... + ... |
| variables.rs:30:9:30:10 | x4 | variables.rs:30:14:30:16 | "a" |
| variables.rs:33:13:33:14 | x4 | variables.rs:33:18:33:20 | "b" |
| variables.rs:62:9:62:10 | p1 | variables.rs:62:14:62:37 | RecordExpr |
| variables.rs:72:9:72:10 | s1 | variables.rs:72:14:72:41 | CallExpr |
| variables.rs:89:9:89:10 | x6 | variables.rs:89:14:89:20 | CallExpr |
| variables.rs:90:9:90:10 | y1 | variables.rs:90:14:90:15 | 10 |
| variables.rs:106:9:106:15 | numbers | variables.rs:106:19:106:35 | TupleExpr |
| variables.rs:133:9:133:10 | p2 | variables.rs:133:14:133:37 | RecordExpr |
| variables.rs:147:9:147:11 | msg | variables.rs:147:15:147:38 | RecordExpr |
| variables.rs:167:9:167:14 | either | variables.rs:167:18:167:33 | CallExpr |
| variables.rs:181:9:181:10 | tv | variables.rs:181:14:181:36 | CallExpr |
| variables.rs:197:9:197:14 | either | variables.rs:197:18:197:33 | CallExpr |
| variables.rs:207:9:207:14 | either | variables.rs:207:18:207:33 | CallExpr |
| variables.rs:231:9:231:10 | fv | variables.rs:231:14:231:35 | CallExpr |
| variables.rs:293:9:293:23 | example_closure | variables.rs:294:9:295:9 | ClosureExpr |
| variables.rs:296:9:296:10 | n1 | variables.rs:297:9:297:26 | CallExpr |
| variables.rs:301:9:301:26 | immutable_variable | variables.rs:302:9:303:9 | ClosureExpr |
| variables.rs:304:9:304:10 | n2 | variables.rs:305:9:305:29 | CallExpr |
| variables.rs:310:9:310:9 | v | variables.rs:310:13:310:41 | RefExpr |

View File

@@ -5,6 +5,12 @@ query predicate variable(Variable v) { any() }
query predicate variableAccess(VariableAccess va, Variable v) { v = va.getVariable() }
query predicate variableWriteAccess(VariableWriteAccess va, Variable v) { v = va.getVariable() }
query predicate variableReadAccess(VariableReadAccess va, Variable v) { v = va.getVariable() }
query predicate variableInitializer(Variable v, Expr e) { e = v.getInitializer() }
module VariableAccessTest implements TestSig {
string getARelevantTag() { result = "access" }

View File

@@ -1,3 +1,4 @@
| comments.rs:0:0:0:0 | comments.rs | File successfully extracted. |
| does_not_compile.rs:0:0:0:0 | does_not_compile.rs | File successfully extracted. |
| error.rs:0:0:0:0 | error.rs | File successfully extracted. |
| lib.rs:0:0:0:0 | lib.rs | File successfully extracted. |

View File

@@ -1 +1 @@
| 48 |
| 61 |

View File

@@ -1 +1 @@
| 48 |
| 61 |

View File

@@ -1,6 +1,7 @@
| my_struct.rs:0:0:0:0 | my_struct.rs | 21 |
| my_macro.rs:0:0:0:0 | my_macro.rs | 8 |
| main.rs:0:0:0:0 | main.rs | 7 |
| lib.rs:0:0:0:0 | lib.rs | 6 |
| my_struct.rs:0:0:0:0 | my_struct.rs | 20 |
| comments.rs:0:0:0:0 | comments.rs | 13 |
| main.rs:0:0:0:0 | main.rs | 8 |
| lib.rs:0:0:0:0 | lib.rs | 7 |
| my_macro.rs:0:0:0:0 | my_macro.rs | 7 |
| does_not_compile.rs:0:0:0:0 | does_not_compile.rs | 3 |
| error.rs:0:0:0:0 | error.rs | 3 |

View File

@@ -1,9 +1,9 @@
| Elements extracted | 210 |
| Elements extracted | 290 |
| Elements unextracted | 0 |
| Extraction errors | 0 |
| Extraction warnings | 6 |
| Files extracted - total | 6 |
| Files extracted - total | 7 |
| Files extracted - with errors | 1 |
| Files extracted - without errors | 5 |
| Lines of code extracted | 48 |
| Lines of user code extracted | 48 |
| Files extracted - without errors | 6 |
| Lines of code extracted | 61 |
| Lines of user code extracted | 61 |

View File

@@ -0,0 +1,60 @@
/**
* total lines in this file: 61
* of which code: 16
* of which only comments: 33
* of which blank: 12
*/
// a comment
/**
* Comment attached to a struct.
*/
struct StructWithComments
{
/**
* Another attached comment.
*/
a: i32,
// And another attached comment.
b: i32,
/*
* And yet another attached comment.
*/
c: i32,
// informal
// comment
// block.
cd: i32,
// Just a comment.
}
pub fn my_simple_func()
{
}
/**
* Comment attached to a function.
*/
pub fn my_func_with_comments()
{
// comment
let a = 1; // comment
// comment
let b = 2;
// comment
/*
* Comment.
*/
my_simple_func();
}
/*
* Comment.
*/

View File

@@ -1,17 +1,16 @@
/**
* total lines in this file: 18
* of which code: 7
* of which only comments: 7
* of which code: 8
* of which only comments: 6
* of which blank: 4
*/
mod my_struct;
mod my_macro;
mod comments;
// another comment
fn main() { // another comment
//println!("Hello, world!"); // currently causes consistency issues
fn main() {
println!("Hello, world!");
my_struct::my_func();
my_macro::my_func();

View File

@@ -7,7 +7,7 @@
macro_rules! myMacro {
() => {
//println!("Hello, world!"); // currently causes consistency issues
println!("Hello, world!");
};
}

View File

@@ -0,0 +1,4 @@
| main.rs:23:9:23:9 | a | Variable is not used. |
| main.rs:88:13:88:13 | d | Variable is not used. |
| main.rs:112:9:112:9 | k | Variable is not used. |
| main.rs:139:5:139:5 | y | Variable is not used. |

View File

@@ -1,118 +1,119 @@
//fn cond() -> bool;
// --- locals ---
fn locals_1() {
let a = 1; // BAD: unused value [NOT DETECTED]
let b = 1;
let c = 1;
let d = String::from("a"); // BAD: unused value [NOT DETECTED]
let e = String::from("b");
let _ = 1; // (deliberately unused)
let a = 1; // BAD: unused value [NOT DETECTED]
let b = 1;
let c = 1;
let d = String::from("a"); // BAD: unused value [NOT DETECTED]
let e = String::from("b");
let _ = 1; // (deliberately unused)
println!("use {}", b);
println!("use {}", b);
if cond() {
println!("use {}", c);
}
if cond() {
println!("use {}", c);
}
println!("use {}", e);
println!("use {}", e);
}
fn locals_2() {
let a: i32;
let b: i32; // BAD: unused variable [NOT DETECTED]
let mut c: i32;
let mut d: i32;
let mut e: i32;
let mut f: i32;
let g: i32;
let h: i32;
let i: i32;
let a: i32; // BAD: unused variable
let b: i32;
let mut c: i32;
let mut d: i32;
let mut e: i32;
let mut f: i32;
let g: i32;
let h: i32;
let i: i32;
b = 1; // BAD: unused value [NOT DETECTED]
b = 1; // BAD: unused value [NOT DETECTED]
c = 1; // BAD: unused value [NOT DETECTED]
c = 2;
println!("use {}", c);
c = 3; // BAD: unused value [NOT DETECTED]
c = 1; // BAD: unused value [NOT DETECTED]
c = 2;
println!("use {}", c);
c = 3; // BAD: unused value [NOT DETECTED]
d = 1;
if cond() {
d = 2; // BAD: unused value [NOT DETECTED]
d = 3;
} else {
}
println!("use {}", d);
d = 1;
if cond() {
d = 2; // BAD: unused value [NOT DETECTED]
d = 3;
} else {
}
println!("use {}", d);
e = 1; // BAD: unused value [NOT DETECTED]
if cond() {
e = 2;
} else {
e = 3;
}
println!("use {}", e);
e = 1; // BAD: unused value [NOT DETECTED]
if cond() {
e = 2;
} else {
e = 3;
}
println!("use {}", e);
f = 1;
f += 1;
println!("use {}", f);
f += 1; // BAD: unused value [NOT DETECTED]
f = 1;
f += 1; // BAD: unused value [NOT DETECTED]
f = 1;
f += 1;
println!("use {}", f);
f += 1; // BAD: unused value [NOT DETECTED]
f = 1;
f += 1; // BAD: unused value [NOT DETECTED]
g = if cond() { 1 } else { 2 }; // BAD: unused value (x2) [NOT DETECTED]
h = if cond() { 3 } else { 4 };
i = if cond() { h } else { 5 };
println!("use {}", i);
g = if cond() { 1 } else { 2 }; // BAD: unused value (x2) [NOT DETECTED]
h = if cond() { 3 } else { 4 };
i = if cond() { h } else { 5 };
println!("use {}", i);
_ = 1; // (deliberately unused) [NOT DETECTED]
_ = 1; // (deliberately unused) [NOT DETECTED]
}
// --- structs ---
#[derive(Debug)]
struct MyStruct {
val: i64
val: i64,
}
impl MyStruct {
fn my_get(&mut self) -> i64 {
return self.val;
}
fn my_get(&mut self) -> i64 {
return self.val;
}
}
fn structs() {
let a = MyStruct {val : 1 }; // BAD: unused value [NOT DETECTED]
let b = MyStruct {val : 2 };
let c = MyStruct {val : 3 };
let mut d : MyStruct; // BAD: unused variable [NOT DETECTED]
let mut e : MyStruct;
let mut f : MyStruct;
let a = MyStruct { val: 1 }; // BAD: unused value [NOT DETECTED]
let b = MyStruct { val: 2 };
let c = MyStruct { val: 3 };
let mut d: MyStruct; // BAD: unused variable
let mut e: MyStruct;
let mut f: MyStruct;
println!("lets use {:?} and {}", b, c.val);
println!("lets use {:?} and {}", b, c.val);
e = MyStruct {val : 4 };
println!("lets use {}", e.my_get());
e.val = 5;
println!("lets use {}", e.my_get());
e = MyStruct { val: 4 };
println!("lets use {}", e.my_get());
e.val = 5;
println!("lets use {}", e.my_get());
f = MyStruct {val : 6 }; // BAD: unused value [NOT DETECTED]
f.val = 7; // BAD: unused value [NOT DETECTED]
f = MyStruct { val: 6 }; // BAD: unused value [NOT DETECTED]
f.val = 7; // BAD: unused value [NOT DETECTED]
}
// --- arrays ---
fn arrays() {
let is = [1, 2, 3]; // BAD: unused values (x3) [NOT DETECTED]
let js = [1, 2, 3];
let ks = [1, 2, 3];
let is = [1, 2, 3]; // BAD: unused values (x3) [NOT DETECTED]
let js = [1, 2, 3];
let ks = [1, 2, 3];
println!("lets use {:?}", js);
println!("lets use {:?}", js);
for k in ks {
println!("lets use {}", k);
}
for k // SPURIOUS: unused variable [macros not yet supported]
in ks
{
println!("lets use {}", k);
}
}
// --- constants and statics ---
@@ -123,30 +124,29 @@ static mut STAT1: i32 = 1;
static mut STAT2: i32 = 2; // BAD: unused value [NOT DETECTED]
fn statics() {
static mut STAT3: i32 = 0;
static mut STAT4: i32 = 0; // BAD: unused value [NOT DETECTED]
static mut STAT3: i32 = 0;
static mut STAT4: i32 = 0; // BAD: unused value [NOT DETECTED]
unsafe
{
let total = CON1 + STAT1 + STAT3;
}
unsafe {
let total = CON1 + STAT1 + STAT3;
}
}
// --- parameters ---
fn parameters(
x: i32,
y: i32, // BAD: unused variable [NOT DETECTED]
_z: i32 // (`_` is asking the compiler, and by extension us, to not warn that this is unused)
) -> i32 {
return x;
x: i32,
y: i32, // BAD: unused variable
_z: i32, // (`_` is asking the compiler, and by extension us, to not warn that this is unused)
) -> i32 {
return x;
}
fn main() {
locals_1();
locals_2();
structs();
arrays();
statics();
println!("lets use result {}", parameters(1, 2, 3));
locals_1();
locals_2();
structs();
arrays();
statics();
println!("lets use result {}", parameters(1, 2, 3));
}

View File

@@ -0,0 +1,3 @@
edges
breakTarget
continueTarget

View File

@@ -7,3 +7,7 @@ class MyRelevantNode extends CfgNode {
}
import codeql.rust.controlflow.internal.ControlFlowGraphImpl::TestOutput<MyRelevantNode>
query predicate breakTarget(BreakExpr be, Expr target) { target = be.getTarget() }
query predicate continueTarget(ContinueExpr ce, Expr target) { target = ce.getTarget() }