Merge branch 'main' into unusedvar8

This commit is contained in:
Geoffrey White
2024-11-08 11:20:12 +00:00
314 changed files with 22520 additions and 21478 deletions

View File

@@ -1,14 +1,18 @@
use crate::rust_analyzer::path_to_file_id;
use anyhow::Context;
use archive::Archiver;
use log::info;
use ra_ap_hir::Semantics;
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
use ra_ap_ide_db::RootDatabase;
use ra_ap_project_model::ProjectManifest;
use ra_ap_vfs::Vfs;
use rust_analyzer::{ParseResult, RustAnalyzer};
use std::{
collections::HashMap,
path::{Path, PathBuf},
};
mod archive;
mod config;
pub mod generated;
@@ -17,54 +21,71 @@ mod rust_analyzer;
mod translate;
pub mod trap;
fn extract(
rust_analyzer: &rust_analyzer::RustAnalyzer,
archiver: &Archiver,
traps: &trap::TrapFileProvider,
file: &std::path::Path,
) {
archiver.archive(file);
struct Extractor<'a> {
archiver: &'a Archiver,
traps: &'a trap::TrapFileProvider,
}
let ParseResult {
ast,
text,
errors,
file_id,
} = rust_analyzer.parse(file);
let line_index = LineIndex::new(text.as_ref());
let display_path = file.to_string_lossy();
let mut trap = traps.create("source", file);
let label = trap.emit_file(file);
let mut translator = translate::Translator::new(
trap,
display_path.as_ref(),
label,
line_index,
file_id,
file_id.and(rust_analyzer.semantics()),
);
impl Extractor<'_> {
fn extract(&self, rust_analyzer: &rust_analyzer::RustAnalyzer, file: &std::path::Path) {
self.archiver.archive(file);
for err in errors {
translator.emit_parse_error(&ast, &err);
}
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
if translator.semantics.is_none() {
translator.emit_diagnostic(
trap::DiagnosticSeverity::Warning,
"semantics".to_owned(),
"semantic analyzer unavailable".to_owned(),
"semantic analyzer unavailable: macro expansion, call graph, and type inference will be skipped.".to_owned(),
no_location,
let ParseResult {
ast,
text,
errors,
semantics_info,
} = rust_analyzer.parse(file);
let line_index = LineIndex::new(text.as_ref());
let display_path = file.to_string_lossy();
let mut trap = self.traps.create("source", file);
let label = trap.emit_file(file);
let mut translator = translate::Translator::new(
trap,
display_path.as_ref(),
label,
line_index,
semantics_info.as_ref().ok(),
);
for err in errors {
translator.emit_parse_error(&ast, &err);
}
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
if let Err(reason) = semantics_info {
let message = format!("semantic analyzer unavailable ({reason})");
let full_message = format!(
"{message}: macro expansion, call graph, and type inference will be skipped."
);
translator.emit_diagnostic(
trap::DiagnosticSeverity::Warning,
"semantics".to_owned(),
message,
full_message,
no_location,
);
}
translator.emit_source_file(ast);
translator.trap.commit().unwrap_or_else(|err| {
log::error!(
"Failed to write trap file for: {}: {}",
display_path,
err.to_string()
)
});
}
pub fn extract_with_semantics(
&self,
file: &Path,
semantics: &Semantics<'_, RootDatabase>,
vfs: &Vfs,
) {
self.extract(&RustAnalyzer::new(vfs, semantics), file);
}
pub fn extract_without_semantics(&self, file: &Path, reason: &str) {
self.extract(&RustAnalyzer::WithoutSemantics { reason }, file);
}
translator.emit_source_file(ast);
translator.trap.commit().unwrap_or_else(|err| {
log::error!(
"Failed to write trap file for: {}: {}",
display_path,
err.to_string()
)
});
}
fn main() -> anyhow::Result<()> {
@@ -82,6 +103,10 @@ fn main() -> anyhow::Result<()> {
let archiver = archive::Archiver {
root: cfg.source_archive_dir.clone(),
};
let extractor = Extractor {
archiver: &archiver,
traps: &traps,
};
let files: Vec<PathBuf> = cfg
.inputs
.iter()
@@ -95,38 +120,39 @@ fn main() -> anyhow::Result<()> {
.iter()
.map(|x| (x.manifest_path().parent().as_ref(), (x, Vec::new())))
.collect();
let mut other_files = Vec::new();
'outer: for file in &files {
let mut p = file.as_path();
while let Some(parent) = p.parent() {
p = parent;
if let Some((_, files)) = map.get_mut(parent) {
for ancestor in file.as_path().ancestors() {
if let Some((_, files)) = map.get_mut(ancestor) {
files.push(file);
continue 'outer;
}
}
other_files.push(file);
extractor.extract_without_semantics(file, "no manifest found");
}
for (manifest, files) in map.values() {
if files.is_empty() {
break;
}
for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) {
if let Some((ref db, ref vfs)) = RustAnalyzer::load_workspace(manifest, &cfg.scratch_dir) {
let semantics = Semantics::new(db);
let rust_analyzer = RustAnalyzer::new(vfs, semantics);
for file in files {
extract(&rust_analyzer, &archiver, &traps, file);
let Some(id) = path_to_file_id(file, vfs) else {
extractor.extract_without_semantics(
file,
"not included in files loaded from manifest",
);
continue;
};
if semantics.file_to_module_def(id).is_none() {
extractor.extract_without_semantics(file, "not included as a module");
continue;
}
extractor.extract_with_semantics(file, &semantics, vfs);
}
} else {
for file in files {
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
extractor.extract_without_semantics(file, "unable to load manifest");
}
}
}
for file in other_files {
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
}
Ok(())
}

View File

@@ -14,25 +14,34 @@ use ra_ap_span::TextRange;
use ra_ap_span::TextSize;
use ra_ap_syntax::SourceFile;
use ra_ap_syntax::SyntaxError;
use ra_ap_vfs::AbsPathBuf;
use ra_ap_vfs::Vfs;
use ra_ap_vfs::VfsPath;
use ra_ap_vfs::{AbsPathBuf, FileId};
use std::borrow::Cow;
use std::path::{Path, PathBuf};
use triomphe::Arc;
pub enum RustAnalyzer<'a> {
WithSemantics {
vfs: &'a Vfs,
semantics: Semantics<'a, RootDatabase>,
semantics: &'a Semantics<'a, RootDatabase>,
},
WithoutSemantics {
reason: &'a str,
},
WithoutSemantics,
}
pub struct ParseResult {
pub struct FileSemanticInformation<'a> {
pub file_id: EditionedFileId,
pub semantics: &'a Semantics<'a, RootDatabase>,
}
pub struct ParseResult<'a> {
pub ast: SourceFile,
pub text: Arc<str>,
pub errors: Vec<SyntaxError>,
pub file_id: Option<EditionedFileId>,
pub semantics_info: Result<FileSemanticInformation<'a>, &'a str>,
}
impl<'a> RustAnalyzer<'a> {
pub fn load_workspace(
project: &ProjectManifest,
@@ -61,47 +70,45 @@ impl<'a> RustAnalyzer<'a> {
}
}
}
pub fn new(vfs: &'a Vfs, semantics: Semantics<'a, RootDatabase>) -> Self {
pub fn new(vfs: &'a Vfs, semantics: &'a Semantics<'a, RootDatabase>) -> Self {
RustAnalyzer::WithSemantics { vfs, semantics }
}
pub fn semantics(&'a self) -> Option<&'a Semantics<'a, RootDatabase>> {
match self {
RustAnalyzer::WithSemantics { vfs: _, semantics } => Some(semantics),
RustAnalyzer::WithoutSemantics => None,
}
}
pub fn parse(&self, path: &Path) -> ParseResult {
if let RustAnalyzer::WithSemantics { vfs, semantics } = self {
if let Some(file_id) = Utf8PathBuf::from_path_buf(path.to_path_buf())
.ok()
.and_then(|x| AbsPathBuf::try_from(x).ok())
.map(VfsPath::from)
.and_then(|x| vfs.file_id(&x))
{
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id)) {
let file_id = EditionedFileId::current_edition(file_id);
let source_file = semantics.parse(file_id);
let errors = semantics
.db
.parse_errors(file_id)
.into_iter()
.flat_map(|x| x.to_vec())
.collect();
let no_semantics_reason;
match self {
RustAnalyzer::WithSemantics { vfs, semantics } => {
if let Some(file_id) = path_to_file_id(path, vfs) {
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id))
{
let file_id = EditionedFileId::current_edition(file_id);
let source_file = semantics.parse(file_id);
let errors = semantics
.db
.parse_errors(file_id)
.into_iter()
.flat_map(|x| x.to_vec())
.collect();
return ParseResult {
ast: source_file,
text: input,
errors,
file_id: Some(file_id),
};
} else {
log::debug!(
return ParseResult {
ast: source_file,
text: input,
errors,
semantics_info: Ok(FileSemanticInformation { file_id, semantics }),
};
}
debug!(
"No text available for file_id '{:?}', falling back to loading file '{}' from disk.",
file_id,
path.to_string_lossy()
)
);
no_semantics_reason = "no text available for the file in the project";
} else {
no_semantics_reason = "file not found in project";
}
}
RustAnalyzer::WithoutSemantics { reason } => {
no_semantics_reason = reason;
}
}
let mut errors = Vec::new();
let input = match std::fs::read(path) {
@@ -123,7 +130,7 @@ impl<'a> RustAnalyzer<'a> {
ast: parse.tree(),
text: input.as_ref().into(),
errors,
file_id: None,
semantics_info: Err(no_semantics_reason),
}
}
}
@@ -187,3 +194,11 @@ fn from_utf8_lossy(v: &[u8]) -> (Cow<'_, str>, Option<SyntaxError>) {
(Cow::Owned(res), Some(error))
}
pub(crate) fn path_to_file_id(path: &Path, vfs: &Vfs) -> Option<FileId> {
Utf8PathBuf::from_path_buf(path.to_path_buf())
.ok()
.and_then(|x| AbsPathBuf::try_from(x).ok())
.map(VfsPath::from)
.and_then(|x| vfs.file_id(&x))
}

View File

@@ -1,6 +1,7 @@
use super::mappings::{AddressableAst, AddressableHir};
use crate::generated::MacroCall;
use crate::generated::{self};
use crate::rust_analyzer::FileSemanticInformation;
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
use crate::trap::{Label, TrapClass};
use codeql_extractor::trap::{self};
@@ -64,16 +65,15 @@ impl<'a> Translator<'a> {
path: &'a str,
label: trap::Label,
line_index: LineIndex,
file_id: Option<EditionedFileId>,
semantics: Option<&'a Semantics<'a, RootDatabase>>,
semantic_info: Option<&FileSemanticInformation<'a>>,
) -> Translator<'a> {
Translator {
trap,
path,
label,
line_index,
file_id,
semantics,
file_id: semantic_info.map(|i| i.file_id),
semantics: semantic_info.map(|i| i.semantics),
}
}
fn location(&self, range: TextRange) -> (LineCol, LineCol) {
@@ -160,7 +160,7 @@ impl<'a> Translator<'a> {
self.path,
start.line + 1,
start.col + 1,
&message
&full_message
);
if severity > DiagnosticSeverity::Debug {
let location = self.trap.emit_location_label(self.label, start, end);
@@ -284,7 +284,8 @@ impl<'a> Translator<'a> {
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
));
}
} else {
} else if self.semantics.is_some() {
// let's not spam warnings if we don't have semantics, we already emitted one
let range = self.text_range_for_node(mcall);
self.emit_parse_error(
mcall,

View File

@@ -1,3 +1,10 @@
/**
* @name Data flow inconsistencies
* @description Lists the data flow inconsistencies in the database. This query is intended for internal use.
* @kind table
* @id rust/diagnostics/data-flow-consistency
*/
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
private import rust
private import codeql.rust.dataflow.internal.DataFlowImpl

View File

@@ -0,0 +1,30 @@
/**
* Provides subclasses of `CfgNode` that represents different types of nodes in
* the control flow graph.
*/
private import rust
private import ControlFlowGraph
private import internal.ControlFlowGraphImpl
/** A CFG node that corresponds to an element in the AST. */
class AstCfgNode extends CfgNode {
AstNode node;
AstCfgNode() { node = this.getAstNode() }
}
/** A CFG node that corresponds to an expression in the AST. */
class ExprCfgNode extends AstCfgNode {
override Expr node;
/** Gets the underlying expression. */
Expr getExpr() { result = node }
}
/** A CFG node that corresponds to a call in the AST. */
class CallCfgNode extends ExprCfgNode {
override CallExpr node;
}
final class ExitCfgNode = ExitNode;

View File

@@ -611,7 +611,7 @@ module ExprTrees {
* Provides `ControlFlowTree`s for patterns.
*
* Since patterns destruct values, they are modeled in pre-order, except for
* `OrPat`s and `IdentPat`s.
* `LiteralPat`s, `OrPat`s, and `IdentPat`s.
*/
module PatternTrees {
abstract class StandardPatTree extends StandardTree {
@@ -665,7 +665,9 @@ module PatternTrees {
class RestPatTree extends LeafTree, RestPat { }
class LiteralPatTree extends LeafTree, LiteralPat { }
class LiteralPatTree extends StandardPostOrderTree, LiteralPat {
override AstNode getChildNode(int i) { i = 0 and result = this.getLiteral() }
}
class MacroPatTree extends PreOrderPatTree, MacroPat {
override Pat getPat(int i) { i = 0 and result = this.getMacroCall().getExpanded() }

View File

@@ -7,9 +7,70 @@ private import codeql.util.Unit
private import codeql.dataflow.DataFlow
private import codeql.dataflow.internal.DataFlowImpl
private import rust
private import SsaImpl as SsaImpl
private import codeql.rust.controlflow.ControlFlowGraph
private import codeql.rust.controlflow.CfgNodes
private import codeql.rust.dataflow.Ssa
private newtype TReturnKind = TNormalReturnKind()
/**
* A return kind. A return kind describes how a value can be returned from a
* callable.
*
* The only return kind is a "normal" return from a `return` statement or an
* expression body.
*/
final class ReturnKind extends TNormalReturnKind {
string toString() { result = "return" }
}
/**
* A callable. This includes callables from source code, as well as callables
* defined in library code.
*/
final class DataFlowCallable extends TDataFlowCallable {
/**
* Gets the underlying CFG scope, if any.
*/
CfgScope asCfgScope() { this = TCfgScope(result) }
/** Gets a textual representation of this callable. */
string toString() { result = this.asCfgScope().toString() }
/** Gets the location of this callable. */
Location getLocation() { result = this.asCfgScope().getLocation() }
}
abstract class DataFlowCall extends TDataFlowCall {
/** Gets the enclosing callable. */
abstract DataFlowCallable getEnclosingCallable();
/** Gets the underlying source code call, if any. */
abstract CallCfgNode asCall();
/** Gets a textual representation of this call. */
abstract string toString();
/** Gets the location of this call. */
abstract Location getLocation();
}
final class NormalCall extends DataFlowCall, TNormalCall {
private CallCfgNode c;
NormalCall() { this = TNormalCall(c) }
/** Gets the underlying call in the CFG, if any. */
override CallCfgNode asCall() { result = c }
override DataFlowCallable getEnclosingCallable() { none() }
override string toString() { result = c.toString() }
override Location getLocation() { result = c.getLocation() }
}
module Node {
/**
* An element, viewed as a node in a data flow graph. Either an expression
@@ -27,6 +88,12 @@ module Node {
*/
Expr asExpr() { none() }
/** Gets the enclosing callable. */
DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) }
/** Do not call: use `getEnclosingCallable()` instead. */
abstract CfgScope getCfgScope();
/**
* Gets the control flow node that corresponds to this data flow node.
*/
@@ -47,32 +114,99 @@ module Node {
final class NaNode extends Node {
NaNode() { none() }
override CfgScope getCfgScope() { none() }
override string toString() { result = "N/A" }
override Location getLocation() { none() }
}
/**
* A node in the data flow graph that corresponds to an expression in the
* AST.
*
* Note that because of control-flow splitting, one `Expr` may correspond
* to multiple `ExprNode`s, just like it may correspond to multiple
* `ControlFlow::Node`s.
*/
class ExprNode extends Node, TExprNode {
ExprCfgNode n;
ExprNode() { this = TExprNode(n) }
override CfgScope getCfgScope() { result = this.asExpr().getEnclosingCallable() }
override Location getLocation() { result = n.getExpr().getLocation() }
override string toString() { result = n.getExpr().toString() }
override Expr asExpr() { result = n.getExpr() }
override CfgNode getCfgNode() { result = n }
}
/**
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
final class ParameterNode extends Node {
Param param;
final class ParameterNode extends Node, TParameterNode {
Param parameter;
ParameterNode() { this = TSourceParameterNode(param) }
ParameterNode() { this = TParameterNode(parameter) }
override Location getLocation() { result = param.getLocation() }
override CfgScope getCfgScope() { result = parameter.getEnclosingCallable() }
override string toString() { result = param.toString() }
override Location getLocation() { result = parameter.getLocation() }
override string toString() { result = parameter.toString() }
/** Gets the parameter in the AST that this node corresponds to. */
Param getParameter() { result = parameter }
}
final class ArgumentNode = NaNode;
final class ReturnNode extends NaNode {
RustDataFlow::ReturnKind getKind() { none() }
/** An SSA node. */
class SsaNode extends Node, TSsaNode {
SsaImpl::DataFlowIntegration::SsaNode node;
SsaImpl::DefinitionExt def;
SsaNode() {
this = TSsaNode(node) and
def = node.getDefinitionExt()
}
override CfgScope getCfgScope() { result = def.getBasicBlock().getScope() }
SsaImpl::DefinitionExt getDefinitionExt() { result = def }
/** Holds if this node should be hidden from path explanations. */
abstract predicate isHidden();
override Location getLocation() { result = node.getLocation() }
override string toString() { result = node.toString() }
}
final class OutNode = NaNode;
/** A data flow node that represents a value returned by a callable. */
final class ReturnNode extends ExprNode {
ReturnNode() { this.getCfgNode().getASuccessor() instanceof ExitCfgNode }
ReturnKind getKind() { any() }
}
/** A data-flow node that represents the output of a call. */
abstract class OutNode extends Node, ExprNode {
/** Gets the underlying call for this node. */
abstract DataFlowCall getCall();
}
final private class ExprOutNode extends OutNode {
ExprOutNode() { this.asExpr() instanceof CallExpr }
/** Gets the underlying call CFG node that includes this out node. */
override DataFlowCall getCall() { result.(NormalCall).asCall() = this.getCfgNode() }
}
/**
* A node associated with an object after an operation that might have
@@ -93,6 +227,70 @@ module Node {
final class CastNode = NaNode;
}
final class Node = Node::Node;
/** Provides logic related to SSA. */
module SsaFlow {
private module Impl = SsaImpl::DataFlowIntegration;
private Node::ParameterNode toParameterNode(Param p) { result = TParameterNode(p) }
/** Converts a control flow node into an SSA control flow node. */
Impl::Node asNode(Node n) {
n = TSsaNode(result)
or
result.(Impl::ExprNode).getExpr() = n.(Node::ExprNode).getCfgNode()
or
n = toParameterNode(result.(Impl::ParameterNode).getParameter())
}
predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep)
}
predicate localMustFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
Impl::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo))
}
}
/**
* Holds for expressions `e` that evaluate to the value of any last (in
* evaluation order) subexpressions within it. E.g., expressions that propagate
* a values from a subexpression.
*
* For instance, the predicate holds for if expressions as `if b { e1 } else {
* e2 }` evalates to the value of one of the subexpressions `e1` or `e2`.
*/
private predicate propagatesValue(Expr e) {
e instanceof IfExpr or
e instanceof LoopExpr or
e instanceof ReturnExpr or
e instanceof BreakExpr or
e.(BlockExpr).getStmtList().hasTailExpr() or
e instanceof MatchExpr
}
/**
* Gets a node that may execute last in `n`, and which, when it executes last,
* will be the value of `n`.
*/
private ExprCfgNode getALastEvalNode(ExprCfgNode n) {
propagatesValue(n.getExpr()) and result.getASuccessor() = n
}
module LocalFlow {
pragma[nomagic]
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
nodeFrom.getCfgNode() = getALastEvalNode(nodeTo.getCfgNode())
}
}
private class DataFlowCallableAlias = DataFlowCallable;
private class ReturnKindAlias = ReturnKind;
private class DataFlowCallAlias = DataFlowCall;
module RustDataFlow implements InputSig<Location> {
/**
* An element, viewed as a node in a data flow graph. Either an expression
@@ -116,38 +314,36 @@ module RustDataFlow implements InputSig<Location> {
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { none() }
DataFlowCallable nodeGetEnclosingCallable(Node node) { none() }
DataFlowCallable nodeGetEnclosingCallable(Node node) { result = node.getEnclosingCallable() }
DataFlowType getNodeType(Node node) { none() }
DataFlowType getNodeType(Node node) { any() }
predicate nodeIsHidden(Node node) { none() }
class DataFlowExpr = Void;
class DataFlowExpr = ExprCfgNode;
/** Gets the node corresponding to `e`. */
Node exprNode(DataFlowExpr e) { none() }
Node exprNode(DataFlowExpr e) { result.getCfgNode() = e }
final class DataFlowCall extends TNormalCall {
private CallExpr c;
final class DataFlowCall = DataFlowCallAlias;
DataFlowCall() { this = TNormalCall(c) }
final class DataFlowCallable = DataFlowCallableAlias;
DataFlowCallable getEnclosingCallable() { none() }
string toString() { result = c.toString() }
Location getLocation() { result = c.getLocation() }
}
final class DataFlowCallable = CfgScope;
final class ReturnKind = Void;
final class ReturnKind = ReturnKindAlias;
/** Gets a viable implementation of the target of the given `Call`. */
DataFlowCallable viableCallable(DataFlowCall c) { none() }
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { none() }
/**
* Gets a node that can read the value returned from `call` with return kind
* `kind`.
*/
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
call = result.getCall() and exists(kind)
}
// NOTE: For now we use the type `Unit` and do not benefit from type
// information in the data flow analysis.
final class DataFlowType = Unit;
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() }
@@ -191,7 +387,7 @@ module RustDataFlow implements InputSig<Location> {
* Holds if there is a simple local flow step from `node1` to `node2`. These
* are the value-preserving intra-callable flow steps.
*/
predicate simpleLocalFlowStep(Node node1, Node node2, string model) { none() }
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) { none() }
/**
* Holds if data can flow from `node1` to `node2` through a non-local step
@@ -256,7 +452,9 @@ module RustDataFlow implements InputSig<Location> {
* `node2` must be visited along a flow path, then any type known for `node2`
* must also apply to `node1`.
*/
predicate localMustFlowStep(Node node1, Node node2) { none() }
predicate localMustFlowStep(Node node1, Node node2) {
SsaFlow::localMustFlowStep(_, node1, node2)
}
class LambdaCallKind = Void;
@@ -267,7 +465,7 @@ module RustDataFlow implements InputSig<Location> {
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() }
/** Extra data-flow steps needed for lambda flow analysis. */
/** Extra data flow steps needed for lambda flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
predicate knownSourceModel(Node source, string model) { none() }
@@ -286,11 +484,12 @@ cached
private module Cached {
cached
newtype TNode =
TExprNode(CfgNode n, Expr e) { n.getAstNode() = e } or
TSourceParameterNode(Param param)
TExprNode(ExprCfgNode n) or
TParameterNode(Param p) or
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node)
cached
newtype TDataFlowCall = TNormalCall(CallExpr c)
newtype TDataFlowCall = TNormalCall(CallCfgNode c)
cached
newtype TOptionalContentSet =
@@ -300,9 +499,16 @@ private module Cached {
cached
class TContentSet = TAnyElementContent or TAnyContent;
cached
newtype TDataFlowCallable = TCfgScope(CfgScope scope)
/** This is the local flow predicate that is exposed. */
cached
predicate localFlowStepImpl(Node::Node nodeFrom, Node::Node nodeTo) { none() }
predicate localFlowStepImpl(Node::Node nodeFrom, Node::Node nodeTo) {
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
}
}
import Cached

View File

@@ -2,6 +2,7 @@ private import rust
private import codeql.rust.controlflow.BasicBlocks as BasicBlocks
private import BasicBlocks
private import codeql.rust.controlflow.ControlFlowGraph as Cfg
private import codeql.rust.controlflow.CfgNodes as CfgNodes
private import Cfg
private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl
private import codeql.ssa.Ssa as SsaImplCommon
@@ -395,6 +396,38 @@ private module Cached {
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
Impl::uncertainWriteDefinitionInput(def, result)
}
cached
module DataFlowIntegration {
import DataFlowIntegrationImpl
cached
predicate localFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
DataFlowIntegrationImpl::localFlowStep(def, nodeFrom, nodeTo, isUseStep)
}
cached
predicate localMustFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo) {
DataFlowIntegrationImpl::localMustFlowStep(def, nodeFrom, nodeTo)
}
signature predicate guardChecksSig(CfgNodes::AstCfgNode g, Cfg::CfgNode e, boolean branch);
cached // nothing is actually cached
module BarrierGuard<guardChecksSig/3 guardChecks> {
private predicate guardChecksAdjTypes(
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
) {
guardChecks(g, e, branch)
}
private Node getABarrierNodeImpl() {
result = DataFlowIntegrationImpl::BarrierGuard<guardChecksAdjTypes/3>::getABarrierNode()
}
predicate getABarrierNode = getABarrierNodeImpl/0;
}
}
}
import Cached
@@ -426,3 +459,46 @@ class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
override Location getLocation() { result = Impl::PhiReadNode.super.getLocation() }
}
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
class Expr extends CfgNodes::AstCfgNode {
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
}
Expr getARead(Definition def) { result = Cached::getARead(def) }
/** Holds if SSA definition `def` assigns `value` to the underlying variable. */
predicate ssaDefAssigns(WriteDefinition def, Expr value) {
exists(BasicBlock bb, int i | def.definesAt(_, bb, i) and value = bb.getNode(i))
}
class Parameter = Param;
/** Holds if SSA definition `def` initializes parameter `p` at function entry. */
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) {
exists(BasicBlock bb, int i | bb.getNode(i).getAstNode() = p and def.definesAt(_, bb, i))
}
class Guard extends CfgNodes::AstCfgNode {
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
exists(ConditionBlock conditionBlock, ConditionalSuccessor s |
guard = conditionBlock.getLastNode() and
s.getValue() = branch and
conditionBlock.controls(bb, s)
)
}
/** Gets an immediate conditional successor of basic block `bb`, if any. */
SsaInput::BasicBlock getAConditionalBasicBlockSuccessor(SsaInput::BasicBlock bb, boolean branch) {
exists(Cfg::ConditionalSuccessor s |
result = bb.getASuccessor(s) and
s.getValue() = branch
)
}
}
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

View File

@@ -0,0 +1,21 @@
/**
* @name Data flow inconsistency counts
* @description Counts the number of data flow inconsistencies of each type. This query is intended for internal use.
* @kind diagnostic
* @id rust/diagnostics/data-flow-consistency-counts
*/
private import rust
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.dataflow.internal.DataFlowImplConsistency
private module Input implements InputSig<Location, RustDataFlow> { }
// see also `rust/diagnostics/data-flow-consistency`, which lists the
// individual inconsistency results.
from string type, int num
where
num =
MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
select type, num

View File

@@ -3,8 +3,11 @@
*/
import rust
import codeql.rust.AstConsistency as AstConsistency
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.rust.AstConsistency as AstConsistency
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
private import codeql.dataflow.internal.DataFlowImplConsistency as DataFlowImplConsistency
/**
* Gets a count of the total number of lines of code in the database.
@@ -31,3 +34,16 @@ int getTotalAstInconsistencies() {
int getTotalCfgInconsistencies() {
result = sum(string type | | CfgConsistency::getCfgInconsistencyCounts(type))
}
private module Input implements DataFlowImplConsistency::InputSig<Location, RustDataFlow> { }
/**
* Gets a count of the total number of data flow inconsistencies in the database.
*/
int getTotalDataFlowInconsistencies() {
result =
sum(string type |
|
DataFlowImplConsistency::MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
)
}

View File

@@ -35,4 +35,6 @@ where
key = "Inconsistencies - AST" and value = getTotalAstInconsistencies()
or
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies()
or
key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies()
select key, value

View File

@@ -1,8 +1,2 @@
uniqueEnclosingCallable
| gen_become_expr.rs:4:11:4:16 | Param | Node should have one enclosing callable but has 0. |
| gen_become_expr.rs:4:19:4:24 | Param | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| gen_become_expr.rs:8:17:8:36 | CallExpr | Call should have one enclosing callable but has 0. |
uniqueType
| gen_become_expr.rs:4:11:4:16 | Param | Node should have one type but has 0. |
| gen_become_expr.rs:4:19:4:24 | Param | Node should have one type but has 0. |

View File

@@ -1,14 +0,0 @@
uniqueEnclosingCallable
| gen_closure_expr.rs:5:6:5:6 | Param | Node should have one enclosing callable but has 0. |
| gen_closure_expr.rs:6:11:6:16 | Param | Node should have one enclosing callable but has 0. |
| gen_closure_expr.rs:7:12:7:17 | Param | Node should have one enclosing callable but has 0. |
| gen_closure_expr.rs:7:20:7:20 | Param | Node should have one enclosing callable but has 0. |
| gen_closure_expr.rs:9:6:9:6 | Param | Node should have one enclosing callable but has 0. |
| gen_closure_expr.rs:11:14:11:14 | Param | Node should have one enclosing callable but has 0. |
uniqueType
| gen_closure_expr.rs:5:6:5:6 | Param | Node should have one type but has 0. |
| gen_closure_expr.rs:6:11:6:16 | Param | Node should have one type but has 0. |
| gen_closure_expr.rs:7:12:7:17 | Param | Node should have one type but has 0. |
| gen_closure_expr.rs:7:20:7:20 | Param | Node should have one type but has 0. |
| gen_closure_expr.rs:9:6:9:6 | Param | Node should have one type but has 0. |
| gen_closure_expr.rs:11:14:11:14 | Param | Node should have one type but has 0. |

View File

@@ -1,3 +1,2 @@
uniqueCallEnclosingCallable
| gen_continue_expr.rs:6:12:6:22 | CallExpr | Call should have one enclosing callable but has 0. |
| gen_continue_expr.rs:11:12:11:22 | CallExpr | Call should have one enclosing callable but has 0. |

View File

@@ -1,4 +0,0 @@
uniqueEnclosingCallable
| gen_function.rs:4:8:4:13 | Param | Node should have one enclosing callable but has 0. |
uniqueType
| gen_function.rs:4:8:4:13 | Param | Node should have one type but has 0. |

View File

@@ -1,6 +1,2 @@
uniqueEnclosingCallable
| gen_let_expr.rs:3:18:3:43 | Param | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| gen_let_expr.rs:6:18:6:24 | CallExpr | Call should have one enclosing callable but has 0. |
uniqueType
| gen_let_expr.rs:3:18:3:43 | Param | Node should have one type but has 0. |

View File

@@ -1,3 +1,2 @@
uniqueCallEnclosingCallable
| gen_loop_expr.rs:6:18:6:40 | CallExpr | Call should have one enclosing callable but has 0. |
| gen_loop_expr.rs:9:18:9:39 | CallExpr | Call should have one enclosing callable but has 0. |

View File

@@ -1,10 +1,8 @@
uniqueEnclosingCallable
| common_definitions.rs:3:15:3:25 | Param | Node should have one enclosing callable but has 0. |
| file://:0:0:0:0 | Param | Node should have one enclosing callable but has 0. |
uniqueType
| common_definitions.rs:3:15:3:25 | Param | Node should have one type but has 0. |
| file://:0:0:0:0 | Param | Node should have one type but has 0. |
uniqueNodeLocation
| file://:0:0:0:0 | BlockExpr | Node should have one location but has 0. |
| file://:0:0:0:0 | MethodCallExpr | Node should have one location but has 0. |
| file://:0:0:0:0 | MethodCallExpr | Node should have one location but has 0. |
| file://:0:0:0:0 | Param | Node should have one location but has 0. |
| file://:0:0:0:0 | PathExpr | Node should have one location but has 0. |
missingLocation
| Nodes without location: 1 |
| Nodes without location: 5 |

View File

@@ -1,4 +0,0 @@
uniqueEnclosingCallable
| gen_match_arm.rs:3:19:3:24 | Param | Node should have one enclosing callable but has 0. |
uniqueType
| gen_match_arm.rs:3:19:3:24 | Param | Node should have one type but has 0. |

View File

@@ -1,4 +0,0 @@
uniqueEnclosingCallable
| gen_match_expr.rs:3:20:3:25 | Param | Node should have one enclosing callable but has 0. |
uniqueType
| gen_match_expr.rs:3:20:3:25 | Param | Node should have one type but has 0. |

View File

@@ -1,4 +1,2 @@
uniqueEnclosingCallable
| gen_trait.rs:7:32:7:60 | Param | Node should have one enclosing callable but has 0. |
uniqueType
| gen_trait.rs:7:32:7:60 | Param | Node should have one type but has 0. |

View File

@@ -1,51 +1,4 @@
uniqueEnclosingCallable
| test.rs:18:32:18:37 | Param | Node should have one enclosing callable but has 0. |
| test.rs:36:31:36:37 | Param | Node should have one enclosing callable but has 0. |
| test.rs:50:34:50:40 | Param | Node should have one enclosing callable but has 0. |
| test.rs:64:34:64:40 | Param | Node should have one enclosing callable but has 0. |
| test.rs:78:19:78:24 | Param | Node should have one enclosing callable but has 0. |
| test.rs:98:17:98:22 | Param | Node should have one enclosing callable but has 0. |
| test.rs:114:25:114:30 | Param | Node should have one enclosing callable but has 0. |
| test.rs:115:20:115:20 | Param | Node should have one enclosing callable but has 0. |
| test.rs:121:21:121:26 | Param | Node should have one enclosing callable but has 0. |
| test.rs:129:25:129:38 | Param | Node should have one enclosing callable but has 0. |
| test.rs:137:20:137:33 | Param | Node should have one enclosing callable but has 0. |
| test.rs:144:23:144:28 | Param | Node should have one enclosing callable but has 0. |
| test.rs:152:29:152:34 | Param | Node should have one enclosing callable but has 0. |
| test.rs:163:29:163:34 | Param | Node should have one enclosing callable but has 0. |
| test.rs:174:27:174:32 | Param | Node should have one enclosing callable but has 0. |
| test.rs:183:22:183:27 | Param | Node should have one enclosing callable but has 0. |
| test.rs:196:22:196:27 | Param | Node should have one enclosing callable but has 0. |
| test.rs:209:28:209:33 | Param | Node should have one enclosing callable but has 0. |
| test.rs:222:26:222:32 | Param | Node should have one enclosing callable but has 0. |
| test.rs:222:35:222:41 | Param | Node should have one enclosing callable but has 0. |
| test.rs:222:44:222:50 | Param | Node should have one enclosing callable but has 0. |
| test.rs:227:25:227:31 | Param | Node should have one enclosing callable but has 0. |
| test.rs:227:34:227:40 | Param | Node should have one enclosing callable but has 0. |
| test.rs:227:43:227:49 | Param | Node should have one enclosing callable but has 0. |
| test.rs:232:27:232:33 | Param | Node should have one enclosing callable but has 0. |
| test.rs:232:36:232:41 | Param | Node should have one enclosing callable but has 0. |
| test.rs:232:44:232:50 | Param | Node should have one enclosing callable but has 0. |
| test.rs:237:26:237:32 | Param | Node should have one enclosing callable but has 0. |
| test.rs:242:29:242:35 | Param | Node should have one enclosing callable but has 0. |
| test.rs:242:38:242:43 | Param | Node should have one enclosing callable but has 0. |
| test.rs:242:46:242:52 | Param | Node should have one enclosing callable but has 0. |
| test.rs:250:28:250:34 | Param | Node should have one enclosing callable but has 0. |
| test.rs:250:37:250:42 | Param | Node should have one enclosing callable but has 0. |
| test.rs:250:45:250:51 | Param | Node should have one enclosing callable but has 0. |
| test.rs:258:29:258:35 | Param | Node should have one enclosing callable but has 0. |
| test.rs:269:38:269:44 | Param | Node should have one enclosing callable but has 0. |
| test.rs:273:38:273:52 | Param | Node should have one enclosing callable but has 0. |
| test.rs:283:19:283:42 | Param | Node should have one enclosing callable but has 0. |
| test.rs:291:44:291:67 | Param | Node should have one enclosing callable but has 0. |
| test.rs:302:23:302:32 | Param | Node should have one enclosing callable but has 0. |
| test.rs:302:35:302:48 | Param | Node should have one enclosing callable but has 0. |
| test.rs:309:35:309:58 | Param | Node should have one enclosing callable but has 0. |
| test.rs:319:23:319:36 | Param | Node should have one enclosing callable but has 0. |
| test.rs:324:29:324:42 | Param | Node should have one enclosing callable but has 0. |
| test.rs:335:28:335:35 | Param | Node should have one enclosing callable but has 0. |
| test.rs:342:29:342:40 | Param | Node should have one enclosing callable but has 0. |
| test.rs:401:15:401:25 | Param | Node should have one enclosing callable but has 0. |
| test.rs:408:16:408:19 | Param | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| test.rs:6:9:6:44 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -63,52 +16,3 @@ uniqueCallEnclosingCallable
| test.rs:381:12:381:30 | CallExpr | Call should have one enclosing callable but has 0. |
| test.rs:384:9:384:23 | CallExpr | Call should have one enclosing callable but has 0. |
| test.rs:404:5:404:18 | CallExpr | Call should have one enclosing callable but has 0. |
uniqueType
| test.rs:18:32:18:37 | Param | Node should have one type but has 0. |
| test.rs:36:31:36:37 | Param | Node should have one type but has 0. |
| test.rs:50:34:50:40 | Param | Node should have one type but has 0. |
| test.rs:64:34:64:40 | Param | Node should have one type but has 0. |
| test.rs:78:19:78:24 | Param | Node should have one type but has 0. |
| test.rs:98:17:98:22 | Param | Node should have one type but has 0. |
| test.rs:114:25:114:30 | Param | Node should have one type but has 0. |
| test.rs:115:20:115:20 | Param | Node should have one type but has 0. |
| test.rs:121:21:121:26 | Param | Node should have one type but has 0. |
| test.rs:129:25:129:38 | Param | Node should have one type but has 0. |
| test.rs:137:20:137:33 | Param | Node should have one type but has 0. |
| test.rs:144:23:144:28 | Param | Node should have one type but has 0. |
| test.rs:152:29:152:34 | Param | Node should have one type but has 0. |
| test.rs:163:29:163:34 | Param | Node should have one type but has 0. |
| test.rs:174:27:174:32 | Param | Node should have one type but has 0. |
| test.rs:183:22:183:27 | Param | Node should have one type but has 0. |
| test.rs:196:22:196:27 | Param | Node should have one type but has 0. |
| test.rs:209:28:209:33 | Param | Node should have one type but has 0. |
| test.rs:222:26:222:32 | Param | Node should have one type but has 0. |
| test.rs:222:35:222:41 | Param | Node should have one type but has 0. |
| test.rs:222:44:222:50 | Param | Node should have one type but has 0. |
| test.rs:227:25:227:31 | Param | Node should have one type but has 0. |
| test.rs:227:34:227:40 | Param | Node should have one type but has 0. |
| test.rs:227:43:227:49 | Param | Node should have one type but has 0. |
| test.rs:232:27:232:33 | Param | Node should have one type but has 0. |
| test.rs:232:36:232:41 | Param | Node should have one type but has 0. |
| test.rs:232:44:232:50 | Param | Node should have one type but has 0. |
| test.rs:237:26:237:32 | Param | Node should have one type but has 0. |
| test.rs:242:29:242:35 | Param | Node should have one type but has 0. |
| test.rs:242:38:242:43 | Param | Node should have one type but has 0. |
| test.rs:242:46:242:52 | Param | Node should have one type but has 0. |
| test.rs:250:28:250:34 | Param | Node should have one type but has 0. |
| test.rs:250:37:250:42 | Param | Node should have one type but has 0. |
| test.rs:250:45:250:51 | Param | Node should have one type but has 0. |
| test.rs:258:29:258:35 | Param | Node should have one type but has 0. |
| test.rs:269:38:269:44 | Param | Node should have one type but has 0. |
| test.rs:273:38:273:52 | Param | Node should have one type but has 0. |
| test.rs:283:19:283:42 | Param | Node should have one type but has 0. |
| test.rs:291:44:291:67 | Param | Node should have one type but has 0. |
| test.rs:302:23:302:32 | Param | Node should have one type but has 0. |
| test.rs:302:35:302:48 | Param | Node should have one type but has 0. |
| test.rs:309:35:309:58 | Param | Node should have one type but has 0. |
| test.rs:319:23:319:36 | Param | Node should have one type but has 0. |
| test.rs:324:29:324:42 | Param | Node should have one type but has 0. |
| test.rs:335:28:335:35 | Param | Node should have one type but has 0. |
| test.rs:342:29:342:40 | Param | Node should have one type but has 0. |
| test.rs:401:15:401:25 | Param | Node should have one type but has 0. |
| test.rs:408:16:408:19 | Param | Node should have one type but has 0. |

View File

@@ -313,7 +313,8 @@ edges
| test.rs:153:9:160:9 | IfExpr | test.rs:152:44:161:5 | BlockExpr | |
| test.rs:153:13:156:9 | [boolean(false)] MatchExpr | test.rs:159:13:159:13 | 0 | false |
| test.rs:153:13:156:9 | [boolean(true)] MatchExpr | test.rs:157:13:157:13 | 1 | true |
| test.rs:153:19:153:19 | a | test.rs:154:13:154:13 | LiteralPat | |
| test.rs:153:19:153:19 | a | test.rs:154:13:154:13 | 0 | |
| test.rs:154:13:154:13 | 0 | test.rs:154:13:154:13 | LiteralPat | |
| test.rs:154:13:154:13 | LiteralPat | test.rs:154:18:154:21 | true | match |
| test.rs:154:13:154:13 | LiteralPat | test.rs:155:13:155:13 | WildcardPat | no-match |
| test.rs:154:18:154:21 | true | test.rs:153:13:156:9 | [boolean(true)] MatchExpr | true |
@@ -590,13 +591,15 @@ edges
| test.rs:274:9:277:9 | MatchExpr | test.rs:273:71:278:5 | BlockExpr | |
| test.rs:274:15:274:15 | b | test.rs:274:15:274:16 | TryExpr | |
| test.rs:274:15:274:16 | TryExpr | test.rs:273:5:278:5 | exit test_question_mark_operator_2 (normal) | return |
| test.rs:274:15:274:16 | TryExpr | test.rs:275:13:275:16 | LiteralPat | match |
| test.rs:274:15:274:16 | TryExpr | test.rs:275:13:275:16 | true | match |
| test.rs:275:13:275:16 | LiteralPat | test.rs:275:21:275:24 | PathExpr | match |
| test.rs:275:13:275:16 | LiteralPat | test.rs:276:13:276:17 | LiteralPat | no-match |
| test.rs:275:13:275:16 | LiteralPat | test.rs:276:13:276:17 | false | no-match |
| test.rs:275:13:275:16 | true | test.rs:275:13:275:16 | LiteralPat | |
| test.rs:275:21:275:24 | PathExpr | test.rs:275:26:275:30 | false | |
| test.rs:275:21:275:31 | CallExpr | test.rs:274:9:277:9 | MatchExpr | |
| test.rs:275:26:275:30 | false | test.rs:275:21:275:31 | CallExpr | |
| test.rs:276:13:276:17 | LiteralPat | test.rs:276:22:276:25 | PathExpr | match |
| test.rs:276:13:276:17 | false | test.rs:276:13:276:17 | LiteralPat | |
| test.rs:276:22:276:25 | PathExpr | test.rs:276:27:276:30 | true | |
| test.rs:276:22:276:31 | CallExpr | test.rs:274:9:277:9 | MatchExpr | |
| test.rs:276:27:276:30 | true | test.rs:276:22:276:31 | CallExpr | |
@@ -735,21 +738,25 @@ edges
| test.rs:348:31:355:5 | BlockExpr | test.rs:348:5:355:5 | exit range_pattern (normal) | |
| test.rs:349:9:354:9 | MatchExpr | test.rs:348:31:355:5 | BlockExpr | |
| test.rs:349:15:349:16 | 42 | test.rs:350:13:350:15 | RangePat | |
| test.rs:350:13:350:15 | RangePat | test.rs:350:15:350:15 | LiteralPat | match |
| test.rs:350:13:350:15 | RangePat | test.rs:350:15:350:15 | 0 | match |
| test.rs:350:13:350:15 | RangePat | test.rs:351:13:351:16 | RangePat | no-match |
| test.rs:350:15:350:15 | 0 | test.rs:350:15:350:15 | LiteralPat | |
| test.rs:350:15:350:15 | LiteralPat | test.rs:350:20:350:20 | 1 | match |
| test.rs:350:15:350:15 | LiteralPat | test.rs:351:13:351:16 | RangePat | no-match |
| test.rs:350:20:350:20 | 1 | test.rs:349:9:354:9 | MatchExpr | |
| test.rs:351:13:351:13 | LiteralPat | test.rs:351:16:351:16 | LiteralPat | match |
| test.rs:351:13:351:13 | 1 | test.rs:351:13:351:13 | LiteralPat | |
| test.rs:351:13:351:13 | LiteralPat | test.rs:351:16:351:16 | 2 | match |
| test.rs:351:13:351:13 | LiteralPat | test.rs:352:13:352:15 | RangePat | no-match |
| test.rs:351:13:351:16 | RangePat | test.rs:351:13:351:13 | LiteralPat | match |
| test.rs:351:13:351:16 | RangePat | test.rs:351:13:351:13 | 1 | match |
| test.rs:351:13:351:16 | RangePat | test.rs:352:13:352:15 | RangePat | no-match |
| test.rs:351:16:351:16 | 2 | test.rs:351:16:351:16 | LiteralPat | |
| test.rs:351:16:351:16 | LiteralPat | test.rs:351:21:351:21 | 2 | match |
| test.rs:351:16:351:16 | LiteralPat | test.rs:352:13:352:15 | RangePat | no-match |
| test.rs:351:21:351:21 | 2 | test.rs:349:9:354:9 | MatchExpr | |
| test.rs:352:13:352:13 | 5 | test.rs:352:13:352:13 | LiteralPat | |
| test.rs:352:13:352:13 | LiteralPat | test.rs:352:20:352:20 | 3 | match |
| test.rs:352:13:352:13 | LiteralPat | test.rs:353:13:353:14 | RestPat | no-match |
| test.rs:352:13:352:15 | RangePat | test.rs:352:13:352:13 | LiteralPat | match |
| test.rs:352:13:352:15 | RangePat | test.rs:352:13:352:13 | 5 | match |
| test.rs:352:13:352:15 | RangePat | test.rs:353:13:353:14 | RestPat | no-match |
| test.rs:352:20:352:20 | 3 | test.rs:349:9:354:9 | MatchExpr | |
| test.rs:353:13:353:14 | RestPat | test.rs:353:19:353:19 | 4 | match |

View File

@@ -1,6 +1,3 @@
uniqueEnclosingCallable
| main.rs:5:9:5:15 | Param | Node should have one enclosing callable but has 0. |
| main.rs:9:13:9:19 | Param | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| main.rs:6:14:6:20 | CallExpr | Call should have one enclosing callable but has 0. |
| main.rs:17:13:17:20 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -10,6 +7,3 @@ uniqueCallEnclosingCallable
| main.rs:24:5:24:11 | CallExpr | Call should have one enclosing callable but has 0. |
| main.rs:28:13:28:20 | CallExpr | Call should have one enclosing callable but has 0. |
| main.rs:29:5:29:11 | CallExpr | Call should have one enclosing callable but has 0. |
uniqueType
| main.rs:5:9:5:15 | Param | Node should have one type but has 0. |
| main.rs:9:13:9:19 | Param | Node should have one type but has 0. |

View File

@@ -1,3 +1,4 @@
uniqueCallEnclosingCallable
| main.rs:3:14:3:33 | CallExpr | Call should have one enclosing callable but has 0. |
| main.rs:7:5:7:14 | CallExpr | Call should have one enclosing callable but has 0. |
| main.rs:39:5:39:14 | CallExpr | Call should have one enclosing callable but has 0. |
| main.rs:40:5:40:23 | CallExpr | Call should have one enclosing callable but has 0. |

View File

@@ -0,0 +1,24 @@
| main.rs:2:9:2:9 | s | main.rs:3:33:3:33 | s |
| main.rs:6:18:6:21 | cond | main.rs:9:16:9:19 | cond |
| main.rs:7:9:7:9 | a | main.rs:10:9:10:9 | a |
| main.rs:8:9:8:9 | b | main.rs:12:9:12:9 | b |
| main.rs:9:9:9:9 | c | main.rs:14:5:14:5 | c |
| main.rs:9:21:11:5 | BlockExpr | main.rs:9:13:13:5 | IfExpr |
| main.rs:10:9:10:9 | a | main.rs:9:21:11:5 | BlockExpr |
| main.rs:11:12:13:5 | BlockExpr | main.rs:9:13:13:5 | IfExpr |
| main.rs:12:9:12:9 | b | main.rs:11:12:13:5 | BlockExpr |
| main.rs:14:5:14:5 | c | main.rs:6:37:15:1 | BlockExpr |
| main.rs:18:9:18:9 | a | main.rs:20:15:20:15 | a |
| main.rs:19:9:19:9 | b | main.rs:22:5:22:5 | b |
| main.rs:20:9:20:15 | BreakExpr | main.rs:19:13:21:5 | LoopExpr |
| main.rs:20:15:20:15 | a | main.rs:20:9:20:15 | BreakExpr |
| main.rs:22:5:22:5 | b | main.rs:17:29:23:1 | BlockExpr |
| main.rs:27:5:27:5 | i | main.rs:27:5:27:5 | i |
| main.rs:27:5:27:5 | i | main.rs:28:5:28:5 | i |
| main.rs:28:5:28:5 | i | main.rs:25:24:29:1 | BlockExpr |
| main.rs:31:21:31:21 | a | main.rs:33:20:33:20 | a |
| main.rs:31:29:31:29 | b | main.rs:34:17:34:17 | b |
| main.rs:31:37:31:37 | c | main.rs:32:11:32:11 | c |
| main.rs:32:5:35:5 | MatchExpr | main.rs:31:60:36:1 | BlockExpr |
| main.rs:33:20:33:20 | a | main.rs:32:5:35:5 | MatchExpr |
| main.rs:34:17:34:17 | b | main.rs:32:5:35:5 | MatchExpr |

View File

@@ -3,6 +3,39 @@ fn variable() {
println!("{:?} data flow!", s);
}
fn if_expression(cond: bool) -> i64 {
let a = 1;
let b = 2;
let c = if cond {
a
} else {
b
};
c
}
fn loop_expression() -> i64 {
let a = 1;
let b = loop {
break a;
};
b
}
fn assignment() -> i64 {
let mut i = 1;
i = 2;
i
}
fn match_expression(a: i64, b: i64, c: Option<i64>) -> i64 {
match c {
Some(_) => a,
None => b,
}
}
fn main() {
variable();
if_expression(true);
}

View File

@@ -1,18 +1,3 @@
uniqueEnclosingCallable
| variables.rs:3:14:3:20 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:7:14:7:19 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:11:18:11:24 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:261:5:261:12 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:262:5:265:19 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:272:5:272:50 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:316:10:316:15 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:324:10:324:15 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:356:17:356:28 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:363:22:363:36 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:363:39:363:57 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:435:8:435:15 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:451:13:451:21 | Param | Node should have one enclosing callable but has 0. |
| variables.rs:451:24:451:32 | Param | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| variables.rs:4:14:4:20 | CallExpr | Call should have one enclosing callable but has 0. |
| variables.rs:8:14:8:20 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -158,18 +143,3 @@ uniqueCallEnclosingCallable
| variables.rs:542:5:542:13 | CallExpr | Call should have one enclosing callable but has 0. |
| variables.rs:543:5:543:13 | CallExpr | Call should have one enclosing callable but has 0. |
| variables.rs:544:5:544:29 | CallExpr | Call should have one enclosing callable but has 0. |
uniqueType
| variables.rs:3:14:3:20 | Param | Node should have one type but has 0. |
| variables.rs:7:14:7:19 | Param | Node should have one type but has 0. |
| variables.rs:11:18:11:24 | Param | Node should have one type but has 0. |
| variables.rs:261:5:261:12 | Param | Node should have one type but has 0. |
| variables.rs:262:5:265:19 | Param | Node should have one type but has 0. |
| variables.rs:272:5:272:50 | Param | Node should have one type but has 0. |
| variables.rs:316:10:316:15 | Param | Node should have one type but has 0. |
| variables.rs:324:10:324:15 | Param | Node should have one type but has 0. |
| variables.rs:356:17:356:28 | Param | Node should have one type but has 0. |
| variables.rs:363:22:363:36 | Param | Node should have one type but has 0. |
| variables.rs:363:39:363:57 | Param | Node should have one type but has 0. |
| variables.rs:435:8:435:15 | Param | Node should have one type but has 0. |
| variables.rs:451:13:451:21 | Param | Node should have one type but has 0. |
| variables.rs:451:24:451:32 | Param | Node should have one type but has 0. |

View File

@@ -260,8 +260,9 @@ edges
| variables.rs:114:5:122:5 | ExprStmt | variables.rs:114:11:114:12 | x6 | |
| variables.rs:114:5:122:5 | MatchExpr | variables.rs:124:5:124:18 | ExprStmt | |
| variables.rs:114:11:114:12 | x6 | variables.rs:115:9:115:16 | TupleStructPat | |
| variables.rs:115:9:115:16 | TupleStructPat | variables.rs:115:14:115:15 | LiteralPat | match |
| variables.rs:115:9:115:16 | TupleStructPat | variables.rs:115:14:115:15 | 50 | match |
| variables.rs:115:9:115:16 | TupleStructPat | variables.rs:116:9:116:16 | TupleStructPat | no-match |
| variables.rs:115:14:115:15 | 50 | variables.rs:115:14:115:15 | LiteralPat | |
| variables.rs:115:14:115:15 | LiteralPat | variables.rs:115:21:115:29 | PathExpr | match |
| variables.rs:115:14:115:15 | LiteralPat | variables.rs:116:9:116:16 | TupleStructPat | no-match |
| variables.rs:115:21:115:29 | PathExpr | variables.rs:115:31:115:38 | "Got 50" | |
@@ -358,10 +359,12 @@ edges
| variables.rs:172:9:174:9 | RecordPat | variables.rs:173:31:173:35 | RangePat | match |
| variables.rs:172:9:174:9 | RecordPat | variables.rs:175:9:175:38 | RecordPat | no-match |
| variables.rs:173:17:173:35 | [match(true)] id_variable | variables.rs:174:14:174:22 | PathExpr | match |
| variables.rs:173:31:173:31 | LiteralPat | variables.rs:173:35:173:35 | LiteralPat | match |
| variables.rs:173:31:173:31 | 3 | variables.rs:173:31:173:31 | LiteralPat | |
| variables.rs:173:31:173:31 | LiteralPat | variables.rs:173:35:173:35 | 7 | match |
| variables.rs:173:31:173:31 | LiteralPat | variables.rs:175:9:175:38 | RecordPat | no-match |
| variables.rs:173:31:173:35 | RangePat | variables.rs:173:31:173:31 | LiteralPat | match |
| variables.rs:173:31:173:35 | RangePat | variables.rs:173:31:173:31 | 3 | match |
| variables.rs:173:31:173:35 | RangePat | variables.rs:175:9:175:38 | RecordPat | no-match |
| variables.rs:173:35:173:35 | 7 | variables.rs:173:35:173:35 | LiteralPat | |
| variables.rs:173:35:173:35 | LiteralPat | variables.rs:173:17:173:35 | [match(true)] id_variable | match |
| variables.rs:173:35:173:35 | LiteralPat | variables.rs:175:9:175:38 | RecordPat | no-match |
| variables.rs:174:14:174:22 | PathExpr | variables.rs:174:24:174:34 | id_variable | |
@@ -369,10 +372,12 @@ edges
| variables.rs:174:24:174:34 | id_variable | variables.rs:174:14:174:35 | CallExpr | |
| variables.rs:175:9:175:38 | RecordPat | variables.rs:175:30:175:36 | RangePat | match |
| variables.rs:175:9:175:38 | RecordPat | variables.rs:178:9:178:29 | RecordPat | no-match |
| variables.rs:175:30:175:31 | LiteralPat | variables.rs:175:35:175:36 | LiteralPat | match |
| variables.rs:175:30:175:31 | 10 | variables.rs:175:30:175:31 | LiteralPat | |
| variables.rs:175:30:175:31 | LiteralPat | variables.rs:175:35:175:36 | 12 | match |
| variables.rs:175:30:175:31 | LiteralPat | variables.rs:178:9:178:29 | RecordPat | no-match |
| variables.rs:175:30:175:36 | RangePat | variables.rs:175:30:175:31 | LiteralPat | match |
| variables.rs:175:30:175:36 | RangePat | variables.rs:175:30:175:31 | 10 | match |
| variables.rs:175:30:175:36 | RangePat | variables.rs:178:9:178:29 | RecordPat | no-match |
| variables.rs:175:35:175:36 | 12 | variables.rs:175:35:175:36 | LiteralPat | |
| variables.rs:175:35:175:36 | LiteralPat | variables.rs:176:22:176:51 | MacroStmts | match |
| variables.rs:175:35:175:36 | LiteralPat | variables.rs:178:9:178:29 | RecordPat | no-match |
| variables.rs:175:43:177:9 | BlockExpr | variables.rs:171:5:180:5 | MatchExpr | |

View File

@@ -0,0 +1,29 @@
| ArgumentNode is missing PostUpdateNode | 0 |
| Call context for isUnreachableInCall is inconsistent with call graph | 0 |
| Call context too large | 0 |
| Call should have one enclosing callable | 7 |
| Callable mismatch for parameter | 0 |
| Lambda call enclosing callable mismatch | 0 |
| Local flow step does not preserve enclosing callable | 0 |
| Missing call for argument node | 0 |
| Multiple calls for argument node | 0 |
| Node and call does not share enclosing callable | 0 |
| Node has multiple PostUpdateNodes | 0 |
| Node should have one enclosing callable | 0 |
| Node should have one location | 0 |
| Node should have one toString | 0 |
| Node should have one type | 0 |
| Node steps to itself | 0 |
| Nodes without location | 0 |
| Non-unique content approximation | 0 |
| Origin of readStep is missing a PostUpdateNode | 0 |
| Parameter node with multiple positions | 0 |
| Parameters with overlapping positions | 0 |
| PostUpdateNode does not share callable with its pre-update node | 0 |
| PostUpdateNode should have one pre-update node | 0 |
| PostUpdateNode should not be the target of local flow | 0 |
| PostUpdateNode should not equal its pre-update node | 0 |
| Read step does not preserve enclosing callable | 0 |
| Speculative step already hasM Model | 0 |
| Store step does not preserve enclosing callable | 0 |
| Type compatibility predicate is not reflexive | 0 |

View File

@@ -0,0 +1 @@
queries/diagnostics/DataFlowConsistencyCounts.ql

View File

@@ -7,5 +7,6 @@
| Files extracted - without errors | 5 |
| Inconsistencies - AST | 0 |
| Inconsistencies - CFG | 0 |
| Inconsistencies - data flow | 7 |
| Lines of code extracted | 59 |
| Lines of user code extracted | 59 |

View File

@@ -26,11 +26,11 @@ uniqueEnclosingCallable
| main.rs:496:12:496:17 | Param | Node should have one enclosing callable but has 0. |
| main.rs:499:18:499:23 | Param | Node should have one enclosing callable but has 0. |
| main.rs:502:24:502:29 | Param | Node should have one enclosing callable but has 0. |
| main.rs:382:19:382:21 | Param | Node should have one enclosing callable but has 0. |
| main.rs:430:29:430:38 | Param | Node should have one enclosing callable but has 0. |
| main.rs:430:41:430:56 | Param | Node should have one enclosing callable but has 0. |
| more.rs:4:23:4:28 | Param | Node should have one enclosing callable but has 0. |
| more.rs:8:19:8:24 | Param | Node should have one enclosing callable but has 0. |
| more.rs:16:23:16:28 | Param | Node should have one enclosing callable but has 0. |
| more.rs:24:9:24:14 | Param | Node should have one enclosing callable but has 0. |
| unreachable.rs:10:34:10:34 | Param | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| main.rs:13:13:13:29 | CallExpr | Call should have one enclosing callable but has 0. |
| main.rs:14:13:14:29 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -128,17 +128,13 @@ uniqueCallEnclosingCallable
| unreachable.rs:2:5:2:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:6:5:6:24 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:10:5:10:20 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:19:9:19:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:21:9:21:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:25:9:25:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:27:9:27:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:30:13:30:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:33:13:33:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:37:8:37:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:39:9:39:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:42:8:42:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:43:9:43:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:46:9:46:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:48:5:48:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:50:8:50:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:51:17:51:22 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -146,7 +142,6 @@ uniqueCallEnclosingCallable
| unreachable.rs:56:17:56:30 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:58:13:58:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:62:8:62:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:67:5:67:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:71:8:71:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:72:9:72:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:73:16:73:25 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -173,7 +168,6 @@ uniqueCallEnclosingCallable
| unreachable.rs:111:8:111:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:112:9:112:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:114:13:114:20 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:114:13:114:20 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:115:9:115:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:116:22:116:29 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:116:22:116:29 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -181,7 +175,6 @@ uniqueCallEnclosingCallable
| unreachable.rs:120:8:120:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:121:9:121:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:123:13:123:20 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:123:13:123:20 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:124:9:124:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:125:21:125:28 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:125:21:125:28 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -190,36 +183,24 @@ uniqueCallEnclosingCallable
| unreachable.rs:136:13:136:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:139:5:139:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:141:11:141:24 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:149:5:149:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:154:9:154:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:156:9:156:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:159:8:159:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:160:15:160:20 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:161:13:161:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:165:13:165:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:169:13:169:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:171:9:171:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:175:12:175:17 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:177:13:177:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:179:9:179:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:183:12:183:17 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:185:13:185:26 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:188:5:188:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:189:5:189:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:190:5:190:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:198:22:198:41 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:199:9:199:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:202:9:202:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:205:5:205:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:207:16:207:29 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:209:9:209:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:212:9:212:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:215:5:215:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:219:19:219:38 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:220:9:220:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:224:5:224:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:226:13:226:32 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:228:9:228:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:232:5:232:18 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:236:8:236:13 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:237:9:237:22 | CallExpr | Call should have one enclosing callable but has 0. |
@@ -228,6 +209,7 @@ uniqueCallEnclosingCallable
| unreachable.rs:247:9:247:14 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:248:9:248:22 | CallExpr | Call should have one enclosing callable but has 0. |
| unreachable.rs:252:5:252:18 | CallExpr | Call should have one enclosing callable but has 0. |
<<<<<<< HEAD
uniqueType
| main.rs:142:5:142:10 | Param | Node should have one type but has 0. |
| main.rs:143:5:143:10 | Param | Node should have one type but has 0. |
@@ -261,3 +243,5 @@ uniqueType
| more.rs:16:23:16:28 | Param | Node should have one type but has 0. |
| more.rs:24:9:24:14 | Param | Node should have one type but has 0. |
| unreachable.rs:10:34:10:34 | Param | Node should have one type but has 0. |
=======
>>>>>>> main