Skip to content

Commit dc07b4b

Browse files
orpuente-MSidavis
authored andcommitted
Fix bug in const evaluator (#2296)
Fixes #2294
1 parent a540d6b commit dc07b4b

File tree

3 files changed

+151
-2
lines changed

3 files changed

+151
-2
lines changed

compiler/qsc_qasm3/src/parser/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub enum ErrorKind {
122122
#[error("missing switch statement case labels")]
123123
#[diagnostic(code("Qasm3.Parse.MissingSwitchCaseLabels"))]
124124
MissingSwitchCaseLabels(#[label] Span),
125-
#[error("missing switch statement case labels")]
125+
#[error("missing gate call operands")]
126126
#[diagnostic(code("Qasm3.Parse.MissingGateCallOperands"))]
127127
MissingGateCallOperands(#[label] Span),
128128
#[error("expected an item or closing brace, found {0}")]

compiler/qsc_qasm3/src/semantic/ast/const_eval.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,13 @@ impl BinaryOpExpr {
161161
fn const_eval(&self, ctx: &mut Lowerer) -> Option<LiteralKind> {
162162
use LiteralKind::{Angle, Bit, Bitstring, Bool, Float, Int};
163163

164-
assert_binary_op_ty_invariant(self.op, &self.lhs.ty, &self.rhs.ty);
165164
let lhs = self.lhs.const_eval(ctx);
166165
let rhs = self.rhs.const_eval(ctx);
167166
let (lhs, rhs) = (lhs?, rhs?);
168167
let lhs_ty = &self.lhs.ty;
169168

169+
assert_binary_op_ty_invariant(self.op, &self.lhs.ty, &self.rhs.ty);
170+
170171
match &self.op {
171172
// Bit Shifts
172173
BinOp::Shl => {

compiler/qsc_qasm3/src/tests/statement/const_eval.rs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,3 +1982,151 @@ fn cast_to_bit() -> miette::Result<(), Vec<Report>> {
19821982
.assert_eq(&qsharp);
19831983
Ok(())
19841984
}
1985+
1986+
#[test]
1987+
fn binary_op_err_type_fails() {
1988+
let source = r#"
1989+
int[a + b] x = 2;
1990+
"#;
1991+
1992+
let Err(errs) = compile_qasm_to_qsharp(source) else {
1993+
panic!("should have generated an error");
1994+
};
1995+
let errs: Vec<_> = errs.iter().map(|e| format!("{e:?}")).collect();
1996+
let errs_string = errs.join("\n");
1997+
expect![[r#"
1998+
Qsc.Qasm3.Lowerer.UndefinedSymbol
1999+
2000+
x undefined symbol: a
2001+
,-[Test.qasm:2:13]
2002+
1 |
2003+
2 | int[a + b] x = 2;
2004+
: ^
2005+
3 |
2006+
`----
2007+
2008+
Qsc.Qasm3.Lowerer.UndefinedSymbol
2009+
2010+
x undefined symbol: b
2011+
,-[Test.qasm:2:17]
2012+
1 |
2013+
2 | int[a + b] x = 2;
2014+
: ^
2015+
3 |
2016+
`----
2017+
2018+
Qsc.Qasm3.Lowerer.CannotCast
2019+
2020+
x cannot cast expression of type Err to type UInt(None, true)
2021+
,-[Test.qasm:2:13]
2022+
1 |
2023+
2 | int[a + b] x = 2;
2024+
: ^^^^^
2025+
3 |
2026+
`----
2027+
2028+
Qsc.Qasm3.Compile.ExprMustBeConst
2029+
2030+
x expression must be const
2031+
,-[Test.qasm:2:13]
2032+
1 |
2033+
2 | int[a + b] x = 2;
2034+
: ^^^^^
2035+
3 |
2036+
`----
2037+
2038+
Qsc.Qasm3.Lowerer.ExprMustBeConst
2039+
2040+
x designator must be a const expression
2041+
,-[Test.qasm:2:13]
2042+
1 |
2043+
2 | int[a + b] x = 2;
2044+
: ^^^^^
2045+
3 |
2046+
`----
2047+
2048+
Qsc.Qasm3.Lowerer.CannotCastLiteral
2049+
2050+
x cannot cast literal expression of type Int(None, true) to type Err
2051+
,-[Test.qasm:2:9]
2052+
1 |
2053+
2 | int[a + b] x = 2;
2054+
: ^^^^^^^^^^^^^^^^^
2055+
3 |
2056+
`----
2057+
"#]]
2058+
.assert_eq(&errs_string);
2059+
}
2060+
2061+
#[test]
2062+
fn fuzzer_issue_2294() {
2063+
let source = r#"
2064+
ctrl(5/_)@l
2065+
"#;
2066+
2067+
let Err(errs) = compile_qasm_to_qsharp(source) else {
2068+
panic!("should have generated an error");
2069+
};
2070+
let errs: Vec<_> = errs.iter().map(|e| format!("{e:?}")).collect();
2071+
let errs_string = errs.join("\n");
2072+
expect![[r#"
2073+
Qasm3.Parse.Token
2074+
2075+
x expected `;`, found EOF
2076+
,-[Test.qasm:3:5]
2077+
2 | ctrl(5/_)@l
2078+
3 |
2079+
`----
2080+
2081+
Qasm3.Parse.MissingGateCallOperands
2082+
2083+
x missing gate call operands
2084+
,-[Test.qasm:2:9]
2085+
1 |
2086+
2 | ctrl(5/_)@l
2087+
: ^^^^^^^^^^^
2088+
3 |
2089+
`----
2090+
2091+
Qsc.Qasm3.Lowerer.UndefinedSymbol
2092+
2093+
x undefined symbol: _
2094+
,-[Test.qasm:2:16]
2095+
1 |
2096+
2 | ctrl(5/_)@l
2097+
: ^
2098+
3 |
2099+
`----
2100+
2101+
Qsc.Qasm3.Lowerer.CannotCast
2102+
2103+
x cannot cast expression of type Err to type Float(None, true)
2104+
,-[Test.qasm:2:16]
2105+
1 |
2106+
2 | ctrl(5/_)@l
2107+
: ^
2108+
3 |
2109+
`----
2110+
2111+
Qsc.Qasm3.Compile.ExprMustBeConst
2112+
2113+
x expression must be const
2114+
,-[Test.qasm:2:16]
2115+
1 |
2116+
2 | ctrl(5/_)@l
2117+
: ^
2118+
3 |
2119+
`----
2120+
2121+
Qsc.Qasm3.Lowerer.ExprMustBeConst
2122+
2123+
x ctrl modifier argument must be a const expression
2124+
,-[Test.qasm:2:14]
2125+
1 |
2126+
2 | ctrl(5/_)@l
2127+
: ^^^
2128+
3 |
2129+
`----
2130+
"#]]
2131+
.assert_eq(&errs_string);
2132+
}

0 commit comments

Comments
 (0)