summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/named.rs34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/ir/named.rs b/src/ir/named.rs
index 2bab5e4e..39fa2201 100644
--- a/src/ir/named.rs
+++ b/src/ir/named.rs
@@ -426,6 +426,9 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
.expect("Should maintain the invariant that all used template param \
sets are `Some` upon entry of `constrain`");
+ debug!("constrain {:?}", id);
+ debug!(" initially, used set is {:?}", used_by_this_id);
+
let original_len = used_by_this_id.len();
let item = self.ctx.resolve_item(id);
@@ -433,6 +436,7 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
match ty_kind {
// Named template type parameters trivially use themselves.
Some(&TypeKind::Named) => {
+ debug!(" named type, trivially uses itself");
used_by_this_id.insert(id);
}
@@ -443,6 +447,9 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
// parameters, but we can push the issue down the line to them.
Some(&TypeKind::TemplateInstantiation(ref inst))
if !self.whitelisted_items.contains(&inst.template_definition()) => {
+ debug!(" instantiation of blacklisted template, uses all template \
+ arguments");
+
let args = inst.template_arguments()
.iter()
.filter_map(|a| a.as_named(self.ctx, &()));
@@ -453,18 +460,29 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
// only used if the template declaration uses the
// corresponding template parameter.
Some(&TypeKind::TemplateInstantiation(ref inst)) => {
+ debug!(" template instantiation");
+
let decl = self.ctx.resolve_type(inst.template_definition());
let args = inst.template_arguments();
let params = decl.self_template_params(self.ctx)
.unwrap_or(vec![]);
+ let used_by_def = self.used[&inst.template_definition()]
+ .as_ref()
+ .unwrap();
+
for (arg, param) in args.iter().zip(params.iter()) {
- let used_by_def = self.used[&inst.template_definition()]
- .as_ref()
- .unwrap();
+ debug!(" instantiation's argument {:?} is used if definition's \
+ parameter {:?} is used",
+ arg,
+ param);
+
if used_by_def.contains(param) {
+ debug!(" param is used by template definition");
+
if let Some(named) = arg.as_named(self.ctx, &()) {
+ debug!(" arg is a type parameter, marking used");
used_by_this_id.insert(named);
}
}
@@ -474,6 +492,8 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
// Otherwise, add the union of each of its referent item's template
// parameter usage.
_ => {
+ debug!(" other item: join with successors' usage");
+
item.trace(self.ctx, &mut |sub_id, edge_kind| {
// Ignore ourselves, since union with ourself is a
// no-op. Ignore edges that aren't relevant to the
@@ -492,11 +512,18 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
`Some`")
.iter()
.cloned();
+
+ debug!(" union with {:?}'s usage: {:?}",
+ sub_id,
+ used_by_sub_id.clone().collect::<Vec<_>>());
+
used_by_this_id.extend(used_by_sub_id);
}, &());
}
}
+ debug!(" finally, used set is {:?}", used_by_this_id);
+
let new_len = used_by_this_id.len();
assert!(new_len >= original_len,
"This is the property that ensures this function is monotone -- \
@@ -515,6 +542,7 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
{
if let Some(edges) = self.dependencies.get(&item) {
for item in edges {
+ debug!("enqueue {:?} into worklist", item);
f(*item);
}
}