Skip to content

Provide better diagnostics for assertions in the template analysis #621

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 1 commit into from
Apr 7, 2017
Merged
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
25 changes: 17 additions & 8 deletions src/ir/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,13 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
// on other hash map entries. We *must* put it back into the hash map at
// the end of this method. This allows us to side-step HashMap's lack of
// an analog to slice::split_at_mut.
let mut used_by_this_id =
self.used.get_mut(&id).unwrap().take().unwrap();
let mut used_by_this_id = self.used
.get_mut(&id)
.expect("Should have a set of used template params for every item \
id")
.take()
.expect("Should maintain the invariant that all used template param \
sets are `Some` upon entry of `constrain`");

let original_len = used_by_this_id.len();

Expand Down Expand Up @@ -415,27 +420,31 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
// Otherwise, add the union of each of its referent item's template
// parameter usage.
_ => {
item.trace(self.ctx,
&mut |sub_id, edge_kind| {
item.trace(self.ctx, &mut |sub_id, edge_kind| {
if sub_id == id || !Self::consider_edge(edge_kind) {
return;
}

let used_by_sub_id = self.used[&sub_id]
.as_ref()
.unwrap()
.expect("Because sub_id != id, and all used template \
param sets other than id's are `Some`, \
sub_id's used template param set should be \
`Some`")
.iter()
.cloned();
used_by_this_id.extend(used_by_sub_id);
},
&());
}, &());
}
}

let new_len = used_by_this_id.len();
assert!(new_len >= original_len);
assert!(new_len >= original_len,
"This is the property that ensures this function is monotone -- \
if it doesn't hold, the analysis might never terminate!");

// Put the set back in the hash map and restore our invariant.
debug_assert!(self.used[&id].is_none());
self.used.insert(id, Some(used_by_this_id));
debug_assert!(self.used.values().all(|v| v.is_some()));

Expand Down