Skip to content

Instantly share code, notes, and snippets.

@lqd
Created August 5, 2020 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lqd/1358b95bccb5e4c3672a61517bda471b to your computer and use it in GitHub Desktop.
Save lqd/1358b95bccb5e4c3672a61517bda471b to your computer and use it in GitHub Desktop.
diff --git a/polonius-engine/src/output/datafrog_opt.rs b/polonius-engine/src/output/datafrog_opt.rs
index 8140535..7cd39e0 100644
--- a/polonius-engine/src/output/datafrog_opt.rs
+++ b/polonius-engine/src/output/datafrog_opt.rs
@@ -26,6 +26,11 @@ pub(super) fn compute<T: FactTypes>(
let cfg_edge_rel = &ctx.cfg_edge;
let killed_rel = &ctx.killed;
+ let cfg_node = ctx.cfg_node;
+ let known_contains = &ctx.known_contains;
+ let placeholder_origin = &ctx.placeholder_origin;
+ let placeholder_loan = &ctx.placeholder_loan;
+
// Create a new iteration context, ...
let mut iteration = Iteration::new();
@@ -125,6 +130,7 @@ pub(super) fn compute<T: FactTypes>(
// .decl errors(loan, point)
let errors = iteration.variable("errors");
+ let subset_errors = iteration.variable::<(T::Origin, T::Origin, T::Point)>("subset_errors");
// Make "variable" versions of the relations, needed for joins.
borrow_region_op.extend(
@@ -157,6 +163,20 @@ pub(super) fn compute<T: FactTypes>(
.map(|&(origin, loan, point)| ((origin, point), loan)),
);
+ // Placeholder loans are contained by their placeholder origin at all points of the CFG.
+ //
+ // contains(Origin, Loan, Node) :-
+ // cfg_node(Node),
+ // placeholder(Origin, Loan).
+ let mut placeholder_loans = Vec::with_capacity(placeholder_loan.len() * cfg_node.len());
+ for &(loan, origin) in placeholder_loan.iter() {
+ for &node in cfg_node.iter() {
+ placeholder_loans.push(((origin, node), loan));
+ }
+ }
+
+ requires_op.extend(placeholder_loans);
+
// .. and then start iterating rules!
while iteration.changed() {
// Cleanup step: remove symmetries
@@ -372,6 +392,25 @@ pub(super) fn compute<T: FactTypes>(
errors.from_join(&invalidates, &borrow_live_at, |&(loan, point), _, _| {
(loan, point)
});
+
+ // subset_errors(Origin1, Origin2, Point) :-
+ // requires(Origin2, Loan1, Point),
+ // placeholder(Origin2, _),
+ // placeholder(Origin1, Loan1),
+ // !known_contains(Origin2, Loan1).
+ subset_errors.from_leapjoin(
+ &requires_op,
+ (
+ placeholder_origin.filter_with(|&((origin2, _point), _loan1)| (origin2, ())),
+ placeholder_loan.extend_with(|&((_origin2, _point), loan1)| loan1),
+ known_contains.filter_anti(|&((origin2, _point), loan1)| (origin2, loan1)),
+ // remove symmetries:
+ datafrog::ValueFilter::from(|&((origin2, _point), _loan1), &origin1| {
+ origin2 != origin1
+ }),
+ ),
+ |&((origin2, point), _loan1), &origin1| (origin1, origin2, point),
+ );
}
if result.dump_enabled {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment