Skip to content

Commit

Permalink
Fix to RCA panic when mapping a tuple input pattern to a non-tuple ex…
Browse files Browse the repository at this point in the history
…pression (#2011)

This change fixes an RCA panic that occurs when a tuple input pattern
maps to a non-tuple expression.

---------

Co-authored-by: Mine Starks <16928427+minestarks@users.noreply.github.com>
  • Loading branch information
cesarzc and minestarks authored Nov 6, 2024
1 parent 5ac52cd commit 7159856
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
7 changes: 5 additions & 2 deletions compiler/qsc_rca/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,7 @@ fn map_input_pattern_to_input_expressions(
match &pat.kind {
PatKind::Bind(_) | PatKind::Discard => vec![expr_id.expr],
PatKind::Tuple(pats) => {
// Map each one of the elements in the pattern to an expression in the tuple.
let pats = &pats[skip_ahead..];
let expr = package_store.get_expr(expr_id);
if let ExprKind::Tuple(exprs) = &expr.kind {
Expand All @@ -2533,8 +2534,10 @@ fn map_input_pattern_to_input_expressions(
}
input_param_exprs
} else {
assert!(pats.len() == 1);
vec![expr_id.expr]
// All elements in the pattern map to the same expression.
// This is one of the boundaries where we can lose specific information since we are "unpacking" the
// tuple represented by a single expression.
vec![expr_id.expr; pats.len()]
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions compiler/qsc_rca/src/tests/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,46 @@ fn check_rca_for_call_to_operation_with_codegen_intrinsic_override_treated_as_in
dynamic_param_applications: <empty>"#]],
);
}

#[test]
fn check_rca_for_call_to_function_that_receives_tuple_with_a_non_tuple_classical_argument() {
let mut compilation_context = CompilationContext::default();
compilation_context.update(
r#"
function Foo() : (Result, Result) { (Zero, Zero) }
function Bar(a : Result, b : Result) : Bool { a == b }
Bar(Foo())"#,
);
let package_store_compute_properties = compilation_context.get_compute_properties();
check_last_statement_compute_properties(
package_store_compute_properties,
&expect![[r#"
ApplicationsGeneratorSet:
inherent: Classical
dynamic_param_applications: <empty>"#]],
);
}

#[test]
fn check_rca_for_call_to_function_that_receives_tuple_with_a_non_tuple_dynamic_argument() {
let mut compilation_context = CompilationContext::default();
compilation_context.update(
r#"
operation Foo() : (Result, Result) {
use q = Qubit();
(MResetZ(q), Zero)
}
function Bar(a : Result, b : Result) : Bool { a == b }
Bar(Foo())"#,
);
let package_store_compute_properties = compilation_context.get_compute_properties();
check_last_statement_compute_properties(
package_store_compute_properties,
&expect![[r#"
ApplicationsGeneratorSet:
inherent: Quantum: QuantumProperties:
runtime_features: RuntimeFeatureFlags(UseOfDynamicBool)
value_kind: Element(Dynamic)
dynamic_param_applications: <empty>"#]],
);
}

0 comments on commit 7159856

Please sign in to comment.