Skip to content

Rust: Add inline expectations test for type inference #19198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions rust/ql/lib/codeql/rust/elements/internal/FunctionImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
* INTERNAL: Do not use.
*/

private import codeql.files.FileSystem
private import codeql.rust.elements.internal.generated.Function
private import codeql.rust.elements.Comment

/**
* INTERNAL: This module contains the customizable definition of `Function` and should not
Expand All @@ -26,5 +28,46 @@ module Impl {
*/
class Function extends Generated::Function {
override string toStringImpl() { result = "fn " + this.getName().getText() }

pragma[nomagic]
private predicate hasPotentialCommentAt(File f, int line) {
f = this.getLocation().getFile() and
// When a function is preceded by comments its start line is the line of
// the first comment. Hence all relevant comments are found by including
// comments from the start line and up to the line with the function
// name.
line in [this.getLocation().getStartLine() .. this.getName().getLocation().getStartLine()]
}

/**
* Gets a comment preceding this function.
*
* A comment is considered preceding if it occurs immediately before this
* function or if only other comments occur between the comment and this
* function.
*/
Comment getAPrecedingComment() {
exists(File f, int line |
this.hasPotentialCommentAt(f, line) and
result.getLocation().hasLocationFileInfo(f, line, _, _, _)
)
}

/**
* Gets a comment preceding this function.
*
* A comment is considered preceding if it occurs immediately before this
* function or if only other comments occur between the comment and this
* function.
*/
Comment getPrecedingComment() {
result.getLocation().getFile() = this.getLocation().getFile() and
// When a function is preceded by comments its start line is the line of
// the first comment. Hence all relevant comments are found by including
// comments from the start line and up to the line with the function
// name.
this.getLocation().getStartLine() <= result.getLocation().getStartLine() and
result.getLocation().getStartLine() <= this.getName().getLocation().getStartLine()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,22 @@ module Impl {
)
}

private string toStringPart(int index) {
index = 0 and
result = this.getReceiver().toAbbreviatedString()
or
index = 1 and
(if this.getReceiver().toAbbreviatedString() = "..." then result = " ." else result = ".")
or
index = 2 and
result = this.getIdentifier().toStringImpl()
or
index = 3 and
if this.getArgList().getNumberOfArgs() = 0 then result = "()" else result = "(...)"
}

override string toStringImpl() {
Copy link
Contributor

Choose a reason for hiding this comment

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

It would have been nice to have all toString changes (including changes in .expected files) in a separate commit.

exists(string base, string separator |
base = this.getReceiver().toAbbreviatedString() and
(if base = "..." then separator = " ." else separator = ".") and
result = base + separator + this.getIdentifier().toStringImpl() + "(...)"
)
result = strictconcat(int i | | this.toStringPart(i) order by i)
}
}
}
4 changes: 2 additions & 2 deletions rust/ql/lib/codeql/rust/internal/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class StructType extends StructOrEnumType, TStruct {
result = TTypeParamTypeParameter(struct.getGenericParamList().getTypeParam(i))
}

override string toString() { result = struct.toString() }
override string toString() { result = struct.getName().getText() }

override Location getLocation() { result = struct.getLocation() }
}
Expand All @@ -125,7 +125,7 @@ class EnumType extends StructOrEnumType, TEnum {
result = TTypeParamTypeParameter(enum.getGenericParamList().getTypeParam(i))
}

override string toString() { result = enum.toString() }
override string toString() { result = enum.getName().getText() }

override Location getLocation() { result = enum.getLocation() }
}
Expand Down
11 changes: 1 addition & 10 deletions rust/ql/lib/utils/test/InlineMadTest.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,7 @@ private module InlineMadTestLang implements InlineMadTestLangSig {
class Callable = R::Function;

string getComment(R::Function callable) {
exists(R::Comment comment |
result = comment.getCommentText() and
comment.getLocation().getFile() = callable.getLocation().getFile() and
// When a function is preceded by comments its start line is the line of
// the first comment. Hence all relevant comments are found by including
// comments from the start line and up to the line with the function
// name.
callable.getLocation().getStartLine() <= comment.getLocation().getStartLine() and
comment.getLocation().getStartLine() <= callable.getName().getLocation().getStartLine()
)
result = callable.getAPrecedingComment().getCommentText()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
multipleStaticCallTargets
| regular.rs:29:5:29:9 | s.g(...) | anonymous.rs:15:9:15:22 | fn g |
| regular.rs:29:5:29:9 | s.g(...) | regular.rs:13:5:13:18 | fn g |
| regular.rs:29:5:29:9 | s.g() | anonymous.rs:15:9:15:22 | fn g |
| regular.rs:29:5:29:9 | s.g() | regular.rs:13:5:13:18 | fn g |
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ canonicalPaths
resolvedPaths
| anonymous.rs:27:17:27:30 | OtherStruct {...} | None | None |
| anonymous.rs:28:9:28:9 | s | None | None |
| anonymous.rs:28:9:28:13 | s.f(...) | None | None |
| anonymous.rs:28:9:28:13 | s.f() | None | None |
| anonymous.rs:29:9:29:9 | s | None | None |
| anonymous.rs:29:9:29:13 | s.g(...) | None | None |
| anonymous.rs:29:9:29:13 | s.g() | None | None |
| anonymous.rs:30:9:30:14 | nested | None | None |
| regular.rs:27:13:27:21 | Struct {...} | repo::test | crate::regular::Struct |
| regular.rs:28:5:28:5 | s | None | None |
| regular.rs:28:5:28:9 | s.f(...) | repo::test | <crate::regular::Struct as crate::regular::Trait>::f |
| regular.rs:28:5:28:9 | s.f() | repo::test | <crate::regular::Struct as crate::regular::Trait>::f |
| regular.rs:29:5:29:5 | s | None | None |
| regular.rs:29:5:29:9 | s.g(...) | repo::test | <crate::regular::Struct>::g |
| regular.rs:29:5:29:9 | s.g() | repo::test | <crate::regular::Struct>::g |
| regular.rs:30:5:30:5 | s | None | None |
| regular.rs:30:5:30:9 | s.h(...) | repo::test | <_ as crate::regular::TraitWithBlanketImpl>::h |
| regular.rs:30:5:30:9 | s.h() | repo::test | <_ as crate::regular::TraitWithBlanketImpl>::h |
| regular.rs:31:5:31:8 | free | repo::test | crate::regular::free |
| regular.rs:41:9:41:26 | ...::None::<...> | lang:core | crate::option::Option::None |
| regular.rs:42:9:42:20 | ...::Some | lang:core | crate::option::Option::Some |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
multipleStaticCallTargets
| regular.rs:32:5:32:9 | s.g(...) | anonymous.rs:18:9:18:22 | fn g |
| regular.rs:32:5:32:9 | s.g(...) | regular.rs:16:5:16:18 | fn g |
| regular.rs:32:5:32:9 | s.g() | anonymous.rs:18:9:18:22 | fn g |
| regular.rs:32:5:32:9 | s.g() | regular.rs:16:5:16:18 | fn g |
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ canonicalPaths
resolvedPaths
| anonymous.rs:30:17:30:30 | OtherStruct {...} | None | None |
| anonymous.rs:31:9:31:9 | s | None | None |
| anonymous.rs:31:9:31:13 | s.f(...) | None | None |
| anonymous.rs:31:9:31:13 | s.f() | None | None |
| anonymous.rs:32:9:32:9 | s | None | None |
| anonymous.rs:32:9:32:13 | s.g(...) | None | None |
| anonymous.rs:32:9:32:13 | s.g() | None | None |
| anonymous.rs:33:9:33:14 | nested | None | None |
| regular.rs:30:13:30:21 | Struct {...} | None | None |
| regular.rs:31:5:31:5 | s | None | None |
| regular.rs:31:5:31:9 | s.f(...) | None | None |
| regular.rs:31:5:31:9 | s.f() | None | None |
| regular.rs:32:5:32:5 | s | None | None |
| regular.rs:32:5:32:9 | s.g(...) | None | None |
| regular.rs:32:5:32:9 | s.g() | None | None |
| regular.rs:33:5:33:5 | s | None | None |
| regular.rs:33:5:33:9 | s.h(...) | None | None |
| regular.rs:33:5:33:9 | s.h() | None | None |
| regular.rs:34:5:34:8 | free | None | None |
| regular.rs:44:9:44:26 | ...::None::<...> | None | None |
| regular.rs:45:9:45:20 | ...::Some | None | None |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
noLocation
| file://:0:0:0:0 | ... .unwrap(...) |
| file://:0:0:0:0 | ... .unwrap() |
| file://:0:0:0:0 | ...: ... |
| file://:0:0:0:0 | ...::Path |
| file://:0:0:0:0 | ...::Path |
Expand Down Expand Up @@ -32,7 +32,7 @@ noLocation
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path.parent(...) |
| file://:0:0:0:0 | path.parent() |
| file://:0:0:0:0 | std |
| file://:0:0:0:0 | std |
| file://:0:0:0:0 | std |
Expand Down
8 changes: 4 additions & 4 deletions rust/ql/test/library-tests/controlflow/Cfg.expected
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ edges
| test.rs:99:19:99:25 | Some(...) | test.rs:99:24:99:24 | x | match |
| test.rs:99:24:99:24 | x | test.rs:99:24:99:24 | x | |
| test.rs:99:24:99:24 | x | test.rs:100:17:100:17 | x | match |
| test.rs:99:29:99:32 | iter | test.rs:99:29:99:39 | iter.next(...) | |
| test.rs:99:29:99:39 | iter.next(...) | test.rs:99:19:99:25 | Some(...) | |
| test.rs:99:29:99:32 | iter | test.rs:99:29:99:39 | iter.next() | |
| test.rs:99:29:99:39 | iter.next() | test.rs:99:19:99:25 | Some(...) | |
| test.rs:99:41:103:9 | { ... } | test.rs:99:15:99:39 | let ... = ... | |
| test.rs:100:13:102:13 | if ... {...} | test.rs:99:41:103:9 | { ... } | |
| test.rs:100:17:100:17 | x | test.rs:100:22:100:22 | 5 | |
Expand Down Expand Up @@ -760,8 +760,8 @@ edges
| test.rs:311:87:313:5 | { ... } | test.rs:311:5:313:5 | exit fn test_question_mark_operator_1 (normal) | |
| test.rs:312:9:312:10 | Ok | test.rs:312:12:312:12 | s | |
| test.rs:312:9:312:33 | Ok(...) | test.rs:311:87:313:5 | { ... } | |
| test.rs:312:12:312:12 | s | test.rs:312:12:312:27 | s.parse(...) | |
| test.rs:312:12:312:27 | s.parse(...) | test.rs:312:12:312:28 | TryExpr | |
| test.rs:312:12:312:12 | s | test.rs:312:12:312:27 | s.parse() | |
| test.rs:312:12:312:27 | s.parse() | test.rs:312:12:312:28 | TryExpr | |
| test.rs:312:12:312:28 | TryExpr | test.rs:311:5:313:5 | exit fn test_question_mark_operator_1 (normal) | return |
| test.rs:312:12:312:28 | TryExpr | test.rs:312:32:312:32 | 4 | match |
| test.rs:312:12:312:32 | ... + ... | test.rs:312:9:312:33 | Ok(...) | |
Expand Down
22 changes: 11 additions & 11 deletions rust/ql/test/library-tests/dataflow/global/inline-flow.expected
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ edges
| main.rs:38:23:38:31 | source(...) | main.rs:26:28:26:33 | ...: i64 | provenance | |
| main.rs:38:23:38:31 | source(...) | main.rs:38:6:38:11 | [post] &mut a [&ref, MyStruct] | provenance | |
| main.rs:39:10:39:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | provenance | |
| main.rs:39:10:39:10 | a [MyStruct] | main.rs:39:10:39:21 | a.get_data(...) | provenance | |
| main.rs:39:10:39:10 | a [MyStruct] | main.rs:39:10:39:21 | a.get_data() | provenance | |
| main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] | main.rs:44:17:44:17 | [post] a [MyStruct] | provenance | |
| main.rs:44:17:44:17 | [post] a [MyStruct] | main.rs:45:10:45:10 | a [MyStruct] | provenance | |
| main.rs:44:30:44:38 | source(...) | main.rs:26:28:26:33 | ...: i64 | provenance | |
| main.rs:44:30:44:38 | source(...) | main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] | provenance | |
| main.rs:45:10:45:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | provenance | |
| main.rs:45:10:45:10 | a [MyStruct] | main.rs:45:10:45:21 | a.get_data(...) | provenance | |
| main.rs:45:10:45:10 | a [MyStruct] | main.rs:45:10:45:21 | a.get_data() | provenance | |
| main.rs:48:12:48:17 | ...: i64 | main.rs:49:10:49:10 | n | provenance | |
| main.rs:53:9:53:9 | a | main.rs:54:13:54:13 | a | provenance | |
| main.rs:53:13:53:21 | source(...) | main.rs:53:9:53:9 | a | provenance | |
Expand All @@ -48,11 +48,11 @@ edges
| main.rs:82:26:82:26 | a | main.rs:78:21:78:26 | ...: i64 | provenance | |
| main.rs:82:26:82:26 | a | main.rs:82:13:82:27 | pass_through(...) | provenance | |
| main.rs:94:22:94:27 | ...: i64 | main.rs:95:14:95:14 | n | provenance | |
| main.rs:98:30:104:5 | { ... } | main.rs:117:13:117:25 | mn.get_data(...) | provenance | |
| main.rs:98:30:104:5 | { ... } | main.rs:117:13:117:25 | mn.get_data() | provenance | |
| main.rs:102:13:102:21 | source(...) | main.rs:98:30:104:5 | { ... } | provenance | |
| main.rs:106:27:106:32 | ...: i64 | main.rs:106:42:112:5 | { ... } | provenance | |
| main.rs:117:9:117:9 | a | main.rs:118:10:118:10 | a | provenance | |
| main.rs:117:13:117:25 | mn.get_data(...) | main.rs:117:9:117:9 | a | provenance | |
| main.rs:117:13:117:25 | mn.get_data() | main.rs:117:9:117:9 | a | provenance | |
| main.rs:123:9:123:9 | a | main.rs:124:16:124:16 | a | provenance | |
| main.rs:123:13:123:21 | source(...) | main.rs:123:9:123:9 | a | provenance | |
| main.rs:124:16:124:16 | a | main.rs:94:22:94:27 | ...: i64 | provenance | |
Expand Down Expand Up @@ -115,12 +115,12 @@ nodes
| main.rs:38:11:38:11 | [post] a [MyStruct] | semmle.label | [post] a [MyStruct] |
| main.rs:38:23:38:31 | source(...) | semmle.label | source(...) |
| main.rs:39:10:39:10 | a [MyStruct] | semmle.label | a [MyStruct] |
| main.rs:39:10:39:21 | a.get_data(...) | semmle.label | a.get_data(...) |
| main.rs:39:10:39:21 | a.get_data() | semmle.label | a.get_data() |
| main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] | semmle.label | [post] &mut a [&ref, MyStruct] |
| main.rs:44:17:44:17 | [post] a [MyStruct] | semmle.label | [post] a [MyStruct] |
| main.rs:44:30:44:38 | source(...) | semmle.label | source(...) |
| main.rs:45:10:45:10 | a [MyStruct] | semmle.label | a [MyStruct] |
| main.rs:45:10:45:21 | a.get_data(...) | semmle.label | a.get_data(...) |
| main.rs:45:10:45:21 | a.get_data() | semmle.label | a.get_data() |
| main.rs:48:12:48:17 | ...: i64 | semmle.label | ...: i64 |
| main.rs:49:10:49:10 | n | semmle.label | n |
| main.rs:53:9:53:9 | a | semmle.label | a |
Expand Down Expand Up @@ -154,7 +154,7 @@ nodes
| main.rs:106:27:106:32 | ...: i64 | semmle.label | ...: i64 |
| main.rs:106:42:112:5 | { ... } | semmle.label | { ... } |
| main.rs:117:9:117:9 | a | semmle.label | a |
| main.rs:117:13:117:25 | mn.get_data(...) | semmle.label | mn.get_data(...) |
| main.rs:117:13:117:25 | mn.get_data() | semmle.label | mn.get_data() |
| main.rs:118:10:118:10 | a | semmle.label | a |
| main.rs:123:9:123:9 | a | semmle.label | a |
| main.rs:123:13:123:21 | source(...) | semmle.label | source(...) |
Expand Down Expand Up @@ -204,9 +204,9 @@ nodes
| main.rs:239:14:239:14 | c | semmle.label | c |
subpaths
| main.rs:38:23:38:31 | source(...) | main.rs:26:28:26:33 | ...: i64 | main.rs:26:17:26:25 | SelfParam [Return] [&ref, MyStruct] | main.rs:38:6:38:11 | [post] &mut a [&ref, MyStruct] |
| main.rs:39:10:39:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:30:31:32:5 | { ... } | main.rs:39:10:39:21 | a.get_data(...) |
| main.rs:39:10:39:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:30:31:32:5 | { ... } | main.rs:39:10:39:21 | a.get_data() |
| main.rs:44:30:44:38 | source(...) | main.rs:26:28:26:33 | ...: i64 | main.rs:26:17:26:25 | SelfParam [Return] [&ref, MyStruct] | main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] |
| main.rs:45:10:45:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:30:31:32:5 | { ... } | main.rs:45:10:45:21 | a.get_data(...) |
| main.rs:45:10:45:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:30:31:32:5 | { ... } | main.rs:45:10:45:21 | a.get_data() |
| main.rs:63:26:63:26 | a | main.rs:57:17:57:22 | ...: i64 | main.rs:57:32:59:1 | { ... } | main.rs:63:13:63:27 | pass_through(...) |
| main.rs:68:26:71:5 | { ... } | main.rs:57:17:57:22 | ...: i64 | main.rs:57:32:59:1 | { ... } | main.rs:68:13:71:6 | pass_through(...) |
| main.rs:82:26:82:26 | a | main.rs:78:21:78:26 | ...: i64 | main.rs:78:36:80:5 | { ... } | main.rs:82:13:82:27 | pass_through(...) |
Expand All @@ -217,8 +217,8 @@ subpaths
testFailures
#select
| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) | source(...) |
| main.rs:39:10:39:21 | a.get_data(...) | main.rs:38:23:38:31 | source(...) | main.rs:39:10:39:21 | a.get_data(...) | $@ | main.rs:38:23:38:31 | source(...) | source(...) |
| main.rs:45:10:45:21 | a.get_data(...) | main.rs:44:30:44:38 | source(...) | main.rs:45:10:45:21 | a.get_data(...) | $@ | main.rs:44:30:44:38 | source(...) | source(...) |
| main.rs:39:10:39:21 | a.get_data() | main.rs:38:23:38:31 | source(...) | main.rs:39:10:39:21 | a.get_data() | $@ | main.rs:38:23:38:31 | source(...) | source(...) |
| main.rs:45:10:45:21 | a.get_data() | main.rs:44:30:44:38 | source(...) | main.rs:45:10:45:21 | a.get_data() | $@ | main.rs:44:30:44:38 | source(...) | source(...) |
| main.rs:49:10:49:10 | n | main.rs:53:13:53:21 | source(...) | main.rs:49:10:49:10 | n | $@ | main.rs:53:13:53:21 | source(...) | source(...) |
| main.rs:64:10:64:10 | b | main.rs:62:13:62:21 | source(...) | main.rs:64:10:64:10 | b | $@ | main.rs:62:13:62:21 | source(...) | source(...) |
| main.rs:72:10:72:10 | a | main.rs:70:9:70:18 | source(...) | main.rs:72:10:72:10 | a | $@ | main.rs:70:9:70:18 | source(...) | source(...) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
| main.rs:17:13:17:23 | get_data(...) | main.rs:12:1:14:1 | fn get_data |
| main.rs:18:5:18:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:37:5:37:22 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:37:10:37:21 | a.get_data(...) | main.rs:30:5:32:5 | fn get_data |
| main.rs:37:10:37:21 | a.get_data() | main.rs:30:5:32:5 | fn get_data |
| main.rs:38:5:38:32 | ... .set_data(...) | main.rs:26:5:28:5 | fn set_data |
| main.rs:38:23:38:31 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:39:5:39:22 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:39:10:39:21 | a.get_data(...) | main.rs:30:5:32:5 | fn get_data |
| main.rs:39:10:39:21 | a.get_data() | main.rs:30:5:32:5 | fn get_data |
| main.rs:44:5:44:39 | ... .set_data(...) | main.rs:26:5:28:5 | fn set_data |
| main.rs:44:30:44:38 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:45:5:45:22 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:45:10:45:21 | a.get_data(...) | main.rs:30:5:32:5 | fn get_data |
| main.rs:45:10:45:21 | a.get_data() | main.rs:30:5:32:5 | fn get_data |
| main.rs:49:5:49:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:53:13:53:21 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:54:5:54:14 | data_in(...) | main.rs:48:1:50:1 | fn data_in |
Expand All @@ -25,7 +25,7 @@
| main.rs:83:5:83:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:95:9:95:15 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:102:13:102:21 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:117:13:117:25 | mn.get_data(...) | main.rs:98:5:104:5 | fn get_data |
| main.rs:117:13:117:25 | mn.get_data() | main.rs:98:5:104:5 | fn get_data |
| main.rs:118:5:118:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:123:13:123:21 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:124:5:124:17 | mn.data_in(...) | main.rs:94:5:96:5 | fn data_in |
Expand Down
Loading