microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.1.3

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/lower.rs

676lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use qsc_data_structures::index_map::IndexMap;
5use qsc_fir::assigner::Assigner;
6use qsc_fir::fir::{Block, CallableImpl, Expr, Pat, SpecImpl, Stmt};
7use qsc_fir::{
8 fir::{self, BlockId, ExprId, LocalItemId, PatId, StmtId},
9 ty::{Arrow, InferFunctorId, ParamId, Ty},
10};
11use qsc_hir::hir::{self, SpecBody, SpecGen};
12use std::{clone::Clone, rc::Rc};
13
14pub struct Lowerer {
15 nodes: IndexMap<hir::NodeId, fir::NodeId>,
16 exprs: IndexMap<ExprId, Expr>,
17 pats: IndexMap<PatId, Pat>,
18 stmts: IndexMap<StmtId, Stmt>,
19 blocks: IndexMap<BlockId, Block>,
20 assigner: Assigner,
21}
22
23impl Default for Lowerer {
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29impl Lowerer {
30 #[must_use]
31 pub fn new() -> Self {
32 Self {
33 nodes: IndexMap::new(),
34 exprs: IndexMap::new(),
35 pats: IndexMap::new(),
36 stmts: IndexMap::new(),
37 blocks: IndexMap::new(),
38 assigner: Assigner::new(),
39 }
40 }
41
42 pub fn lower_package(&mut self, package: &hir::Package) -> fir::Package {
43 let entry = package.entry.as_ref().map(|e| self.lower_expr(e));
44 let items: IndexMap<LocalItemId, fir::Item> = package
45 .items
46 .values()
47 .map(|i| self.lower_item(i))
48 .map(|i| (i.id, i))
49 .collect();
50
51 // Lower top-level statements
52 for stmt in &package.stmts {
53 self.lower_stmt(stmt);
54 }
55
56 let blocks: IndexMap<_, _> = self.blocks.drain().collect();
57 let exprs: IndexMap<_, _> = self.exprs.drain().collect();
58 let pats: IndexMap<_, _> = self.pats.drain().collect();
59 let stmts: IndexMap<_, _> = self.stmts.drain().collect();
60
61 let package = fir::Package {
62 items,
63 entry,
64 blocks,
65 exprs,
66 pats,
67 stmts,
68 };
69 qsc_fir::validate::validate(&package);
70 package
71 }
72
73 /// Used to update the package with the lowered items.
74 /// Incremental compilation requires that we update the package
75 /// instead of returning a new one.
76 #[allow(clippy::similar_names)]
77 pub fn lower_and_update_package(
78 &mut self,
79 fir_package: &mut fir::Package,
80 hir_package: &hir::Package,
81 ) -> Vec<StmtId> {
82 let items: IndexMap<LocalItemId, fir::Item> = hir_package
83 .items
84 .values()
85 .map(|i| self.lower_item(i))
86 .map(|i| (i.id, i))
87 .collect();
88
89 let new_stmts = hir_package
90 .stmts
91 .iter()
92 .map(|s| self.lower_stmt(s))
93 .collect();
94
95 self.update_package(fir_package);
96
97 for (k, v) in items {
98 fir_package.items.insert(k, v);
99 }
100
101 qsc_fir::validate::validate(fir_package);
102
103 new_stmts
104 }
105
106 fn update_package(&mut self, package: &mut fir::Package) {
107 for (id, value) in self.blocks.drain() {
108 package.blocks.insert(id, value);
109 }
110
111 for (id, value) in self.exprs.drain() {
112 package.exprs.insert(id, value);
113 }
114
115 for (id, value) in self.pats.drain() {
116 package.pats.insert(id, value);
117 }
118
119 for (id, value) in self.stmts.drain() {
120 package.stmts.insert(id, value);
121 }
122 }
123
124 fn lower_item(&mut self, item: &hir::Item) -> fir::Item {
125 let kind = match &item.kind {
126 hir::ItemKind::Namespace(name, items) => {
127 let name = self.lower_ident(name);
128 let items = items.iter().map(|i| lower_local_item_id(*i)).collect();
129 fir::ItemKind::Namespace(name, items)
130 }
131 hir::ItemKind::Callable(callable) => {
132 let callable = self.lower_callable_decl(callable);
133
134 fir::ItemKind::Callable(callable)
135 }
136 hir::ItemKind::Ty(name, udt) => {
137 let name = self.lower_ident(name);
138 let udt = self.lower_udt(udt);
139
140 fir::ItemKind::Ty(name, udt)
141 }
142 };
143 let attrs = lower_attrs(&item.attrs);
144 fir::Item {
145 id: lower_local_item_id(item.id),
146 span: item.span,
147 parent: item.parent.map(lower_local_item_id),
148 doc: Rc::clone(&item.doc),
149 attrs,
150 visibility: lower_visibility(item.visibility),
151 kind,
152 }
153 }
154
155 fn lower_callable_decl(&mut self, decl: &hir::CallableDecl) -> fir::CallableDecl {
156 let id = self.lower_id(decl.id);
157 let kind = lower_callable_kind(decl.kind);
158 let name = self.lower_ident(&decl.name);
159 let input = self.lower_pat(&decl.input);
160 let generics = lower_generics(&decl.generics);
161 let output = self.lower_ty(&decl.output);
162 let functors = lower_functors(decl.functors);
163 let implementation = if decl.body.body == SpecBody::Gen(SpecGen::Intrinsic) {
164 assert!(
165 !(decl.adj.is_some() || decl.ctl.is_some() || decl.ctl_adj.is_some()),
166 "intrinsic callables should not have specializations"
167 );
168 CallableImpl::Intrinsic
169 } else {
170 let body = self.lower_spec_decl(&decl.body);
171 let adj = decl.adj.as_ref().map(|f| self.lower_spec_decl(f));
172 let ctl = decl.ctl.as_ref().map(|f| self.lower_spec_decl(f));
173 let ctl_adj = decl.ctl_adj.as_ref().map(|f| self.lower_spec_decl(f));
174 let specialized_implementation = SpecImpl {
175 body,
176 adj,
177 ctl,
178 ctl_adj,
179 };
180 CallableImpl::Spec(specialized_implementation)
181 };
182
183 fir::CallableDecl {
184 id,
185 span: decl.span,
186 kind,
187 name,
188 generics,
189 input,
190 output,
191 functors,
192 implementation,
193 }
194 }
195
196 fn lower_spec_decl(&mut self, decl: &hir::SpecDecl) -> fir::SpecDecl {
197 let SpecBody::Impl(pat, block) = &decl.body else {
198 panic!("if a SpecDecl is some, then it must be an implementation");
199 };
200 let input = pat.as_ref().map(|p| self.lower_spec_decl_pat(p));
201 let block = self.lower_block(block);
202 fir::SpecDecl {
203 id: self.lower_id(decl.id),
204 span: decl.span,
205 block,
206 input,
207 }
208 }
209
210 fn lower_spec_decl_pat(&mut self, pat: &hir::Pat) -> PatId {
211 let id = self.assigner.next_pat();
212 let span = pat.span;
213 let ty = self.lower_ty(&pat.ty);
214
215 let kind = match &pat.kind {
216 hir::PatKind::Bind(ident) => fir::PatKind::Bind(self.lower_ident(ident)),
217 hir::PatKind::Discard => fir::PatKind::Discard,
218 hir::PatKind::Tuple(elems) => {
219 fir::PatKind::Tuple(elems.iter().map(|pat| self.lower_pat(pat)).collect())
220 }
221 hir::PatKind::Err => unreachable!("error pat should not be present"),
222 };
223
224 let pat = fir::Pat { id, span, ty, kind };
225 self.pats.insert(id, pat);
226 id
227 }
228
229 fn lower_block(&mut self, block: &hir::Block) -> BlockId {
230 let id = self.assigner.next_block();
231 let block = fir::Block {
232 id,
233 span: block.span,
234 ty: self.lower_ty(&block.ty),
235 stmts: block.stmts.iter().map(|s| self.lower_stmt(s)).collect(),
236 };
237 self.blocks.insert(id, block);
238 id
239 }
240
241 fn lower_stmt(&mut self, stmt: &hir::Stmt) -> fir::StmtId {
242 let id = self.assigner.next_stmt();
243 let kind = match &stmt.kind {
244 hir::StmtKind::Expr(expr) => fir::StmtKind::Expr(self.lower_expr(expr)),
245 hir::StmtKind::Item(item) => fir::StmtKind::Item(lower_local_item_id(*item)),
246 hir::StmtKind::Local(mutability, pat, expr) => fir::StmtKind::Local(
247 lower_mutability(*mutability),
248 self.lower_pat(pat),
249 self.lower_expr(expr),
250 ),
251 hir::StmtKind::Qubit(_, _, _, _) => {
252 panic!("qubit statements should have been eliminated by passes");
253 }
254 hir::StmtKind::Semi(expr) => fir::StmtKind::Semi(self.lower_expr(expr)),
255 };
256 let stmt = fir::Stmt {
257 id,
258 span: stmt.span,
259 kind,
260 };
261 self.stmts.insert(id, stmt);
262 id
263 }
264
265 #[allow(clippy::too_many_lines)]
266 fn lower_expr(&mut self, expr: &hir::Expr) -> ExprId {
267 let id = self.assigner.next_expr();
268 let ty = self.lower_ty(&expr.ty);
269
270 let kind = match &expr.kind {
271 hir::ExprKind::Array(items) => {
272 fir::ExprKind::Array(items.iter().map(|i| self.lower_expr(i)).collect())
273 }
274 hir::ExprKind::ArrayRepeat(value, size) => {
275 fir::ExprKind::ArrayRepeat(self.lower_expr(value), self.lower_expr(size))
276 }
277 hir::ExprKind::Assign(lhs, rhs) => {
278 fir::ExprKind::Assign(self.lower_expr(lhs), self.lower_expr(rhs))
279 }
280 hir::ExprKind::AssignOp(op, lhs, rhs) => fir::ExprKind::AssignOp(
281 lower_binop(*op),
282 self.lower_expr(lhs),
283 self.lower_expr(rhs),
284 ),
285 hir::ExprKind::AssignField(container, field, replace) => {
286 let container = self.lower_expr(container);
287 let field = lower_field(field);
288 let replace = self.lower_expr(replace);
289 fir::ExprKind::AssignField(container, field, replace)
290 }
291 hir::ExprKind::AssignIndex(container, index, replace) => fir::ExprKind::AssignIndex(
292 self.lower_expr(container),
293 self.lower_expr(index),
294 self.lower_expr(replace),
295 ),
296 hir::ExprKind::BinOp(op, lhs, rhs) => {
297 fir::ExprKind::BinOp(lower_binop(*op), self.lower_expr(lhs), self.lower_expr(rhs))
298 }
299 hir::ExprKind::Block(block) => fir::ExprKind::Block(self.lower_block(block)),
300 hir::ExprKind::Call(callee, arg) => {
301 fir::ExprKind::Call(self.lower_expr(callee), self.lower_expr(arg))
302 }
303 hir::ExprKind::Fail(message) => fir::ExprKind::Fail(self.lower_expr(message)),
304 hir::ExprKind::Field(container, field) => {
305 let container = self.lower_expr(container);
306 let field = lower_field(field);
307 fir::ExprKind::Field(container, field)
308 }
309 hir::ExprKind::If(cond, if_true, if_false) => fir::ExprKind::If(
310 self.lower_expr(cond),
311 self.lower_expr(if_true),
312 if_false.as_ref().map(|e| self.lower_expr(e)),
313 ),
314 hir::ExprKind::Index(container, index) => {
315 fir::ExprKind::Index(self.lower_expr(container), self.lower_expr(index))
316 }
317 hir::ExprKind::Lit(lit) => lower_lit(lit),
318 hir::ExprKind::Range(start, step, end) => fir::ExprKind::Range(
319 start.as_ref().map(|s| self.lower_expr(s)),
320 step.as_ref().map(|s| self.lower_expr(s)),
321 end.as_ref().map(|e| self.lower_expr(e)),
322 ),
323 hir::ExprKind::Return(expr) => fir::ExprKind::Return(self.lower_expr(expr)),
324 hir::ExprKind::Tuple(items) => {
325 fir::ExprKind::Tuple(items.iter().map(|i| self.lower_expr(i)).collect())
326 }
327 hir::ExprKind::UnOp(op, operand) => {
328 fir::ExprKind::UnOp(lower_unop(*op), self.lower_expr(operand))
329 }
330 hir::ExprKind::While(cond, body) => {
331 fir::ExprKind::While(self.lower_expr(cond), self.lower_block(body))
332 }
333 hir::ExprKind::Closure(ids, id) => {
334 let ids = ids.iter().map(|id| self.lower_id(*id)).collect();
335 fir::ExprKind::Closure(ids, lower_local_item_id(*id))
336 }
337 hir::ExprKind::String(components) => fir::ExprKind::String(
338 components
339 .iter()
340 .map(|c| self.lower_string_component(c))
341 .collect(),
342 ),
343 hir::ExprKind::UpdateIndex(expr1, expr2, expr3) => fir::ExprKind::UpdateIndex(
344 self.lower_expr(expr1),
345 self.lower_expr(expr2),
346 self.lower_expr(expr3),
347 ),
348 hir::ExprKind::UpdateField(record, field, replace) => {
349 let record = self.lower_expr(record);
350 let field = lower_field(field);
351 let replace = self.lower_expr(replace);
352 fir::ExprKind::UpdateField(record, field, replace)
353 }
354 hir::ExprKind::Var(res, args) => {
355 let res = self.lower_res(res);
356 let args = args.iter().map(|arg| self.lower_generic_arg(arg)).collect();
357 fir::ExprKind::Var(res, args)
358 }
359 hir::ExprKind::Conjugate(..) => panic!("conjugate should be eliminated by passes"),
360 hir::ExprKind::Err => panic!("error expr should not be present"),
361 hir::ExprKind::For(..) => panic!("for-loop should be eliminated by passes"),
362 hir::ExprKind::Hole => fir::ExprKind::Hole, // allowed for discards
363 hir::ExprKind::Repeat(..) => panic!("repeat-loop should be eliminated by passes"),
364 };
365
366 let expr = fir::Expr {
367 id,
368 span: expr.span,
369 ty,
370 kind,
371 };
372 self.exprs.insert(id, expr);
373 id
374 }
375
376 fn lower_string_component(&mut self, component: &hir::StringComponent) -> fir::StringComponent {
377 match component {
378 hir::StringComponent::Expr(expr) => fir::StringComponent::Expr(self.lower_expr(expr)),
379 hir::StringComponent::Lit(str) => fir::StringComponent::Lit(Rc::clone(str)),
380 }
381 }
382
383 fn lower_pat(&mut self, pat: &hir::Pat) -> PatId {
384 let id = self.assigner.next_pat();
385 let ty = self.lower_ty(&pat.ty);
386 let kind = match &pat.kind {
387 hir::PatKind::Bind(name) => {
388 let name = self.lower_ident(name);
389 fir::PatKind::Bind(name)
390 }
391 hir::PatKind::Discard => fir::PatKind::Discard,
392 hir::PatKind::Tuple(items) => {
393 fir::PatKind::Tuple(items.iter().map(|i| self.lower_pat(i)).collect())
394 }
395 hir::PatKind::Err => unreachable!("error pat should not be present"),
396 };
397
398 let pat = fir::Pat {
399 id,
400 span: pat.span,
401 ty,
402 kind,
403 };
404 self.pats.insert(id, pat);
405 id
406 }
407
408 fn lower_id(&mut self, id: hir::NodeId) -> fir::NodeId {
409 self.nodes.get(id).copied().unwrap_or_else(|| {
410 let new_id = self.assigner.next_node();
411 self.nodes.insert(id, new_id);
412 new_id
413 })
414 }
415
416 fn lower_res(&mut self, res: &hir::Res) -> fir::Res {
417 match res {
418 hir::Res::Item(item) => fir::Res::Item(lower_item_id(item)),
419 hir::Res::Local(node) => fir::Res::Local(self.lower_id(*node)),
420 hir::Res::Err => fir::Res::Err,
421 }
422 }
423
424 fn lower_ident(&mut self, ident: &hir::Ident) -> fir::Ident {
425 fir::Ident {
426 id: self.lower_id(ident.id),
427 span: ident.span,
428 name: ident.name.clone(),
429 }
430 }
431
432 fn lower_udt(&mut self, udt: &qsc_hir::ty::Udt) -> qsc_fir::ty::Udt {
433 let span = udt.span;
434 let name = udt.name.clone();
435 let definition = self.lower_udt_defn(&udt.definition);
436 qsc_fir::ty::Udt {
437 span,
438 name,
439 definition,
440 }
441 }
442
443 fn lower_generic_arg(&mut self, arg: &qsc_hir::ty::GenericArg) -> qsc_fir::ty::GenericArg {
444 match &arg {
445 qsc_hir::ty::GenericArg::Ty(ty) => qsc_fir::ty::GenericArg::Ty(self.lower_ty(ty)),
446 qsc_hir::ty::GenericArg::Functor(functors) => {
447 qsc_fir::ty::GenericArg::Functor(lower_functor_set(functors))
448 }
449 }
450 }
451
452 fn lower_udt_defn(&mut self, definition: &qsc_hir::ty::UdtDef) -> qsc_fir::ty::UdtDef {
453 let span = definition.span;
454 let kind = match &definition.kind {
455 qsc_hir::ty::UdtDefKind::Field(field) => {
456 qsc_fir::ty::UdtDefKind::Field(self.lower_udt_field(field))
457 }
458 qsc_hir::ty::UdtDefKind::Tuple(tup) => qsc_fir::ty::UdtDefKind::Tuple(
459 tup.iter().map(|def| self.lower_udt_defn(def)).collect(),
460 ),
461 };
462 qsc_fir::ty::UdtDef { span, kind }
463 }
464
465 fn lower_arrow(&mut self, arrow: &qsc_hir::ty::Arrow) -> Arrow {
466 Arrow {
467 kind: lower_callable_kind(arrow.kind),
468 input: Box::new(self.lower_ty(&arrow.input)),
469 output: Box::new(self.lower_ty(&arrow.output)),
470 functors: lower_functor_set(&arrow.functors),
471 }
472 }
473
474 fn lower_ty(&mut self, ty: &qsc_hir::ty::Ty) -> Ty {
475 match ty {
476 qsc_hir::ty::Ty::Array(array) => qsc_fir::ty::Ty::Array(Box::new(self.lower_ty(array))),
477 qsc_hir::ty::Ty::Arrow(arrow) => {
478 qsc_fir::ty::Ty::Arrow(Box::new(self.lower_arrow(arrow)))
479 }
480 qsc_hir::ty::Ty::Infer(id) => {
481 qsc_fir::ty::Ty::Infer(qsc_fir::ty::InferTyId::from(usize::from(*id)))
482 }
483 qsc_hir::ty::Ty::Param(_, id) => {
484 qsc_fir::ty::Ty::Param(qsc_fir::ty::ParamId::from(usize::from(*id)))
485 }
486 qsc_hir::ty::Ty::Prim(prim) => qsc_fir::ty::Ty::Prim(lower_ty_prim(*prim)),
487 qsc_hir::ty::Ty::Tuple(tys) => {
488 qsc_fir::ty::Ty::Tuple(tys.iter().map(|ty| self.lower_ty(ty)).collect())
489 }
490 qsc_hir::ty::Ty::Udt(_, res) => qsc_fir::ty::Ty::Udt(self.lower_res(res)),
491 qsc_hir::ty::Ty::Err => qsc_fir::ty::Ty::Err,
492 }
493 }
494
495 fn lower_udt_field(&mut self, field: &qsc_hir::ty::UdtField) -> qsc_fir::ty::UdtField {
496 qsc_fir::ty::UdtField {
497 ty: self.lower_ty(&field.ty),
498 name: field.name.clone(),
499 name_span: field.name_span,
500 }
501 }
502}
503
504fn lower_generics(generics: &[qsc_hir::ty::GenericParam]) -> Vec<qsc_fir::ty::GenericParam> {
505 generics.iter().map(lower_generic_param).collect()
506}
507
508fn lower_attrs(attrs: &[hir::Attr]) -> Vec<fir::Attr> {
509 attrs.iter().map(|_| fir::Attr::EntryPoint).collect()
510}
511
512fn lower_functors(functors: qsc_hir::ty::FunctorSetValue) -> qsc_fir::ty::FunctorSetValue {
513 lower_functor_set_value(functors)
514}
515
516fn lower_generic_param(g: &qsc_hir::ty::GenericParam) -> qsc_fir::ty::GenericParam {
517 match g {
518 qsc_hir::ty::GenericParam::Ty(_) => qsc_fir::ty::GenericParam::Ty,
519 qsc_hir::ty::GenericParam::Functor(value) => {
520 qsc_fir::ty::GenericParam::Functor(lower_functor_set_value(*value))
521 }
522 }
523}
524
525fn lower_field(field: &hir::Field) -> fir::Field {
526 match field {
527 hir::Field::Err => fir::Field::Err,
528 hir::Field::Path(path) => fir::Field::Path(fir::FieldPath {
529 indices: path.indices.clone(),
530 }),
531 hir::Field::Prim(field) => fir::Field::Prim(lower_prim_field(*field)),
532 }
533}
534
535fn lower_functor_set(functors: &qsc_hir::ty::FunctorSet) -> qsc_fir::ty::FunctorSet {
536 match *functors {
537 qsc_hir::ty::FunctorSet::Value(v) => {
538 qsc_fir::ty::FunctorSet::Value(lower_functor_set_value(v))
539 }
540 qsc_hir::ty::FunctorSet::Param(p) => {
541 qsc_fir::ty::FunctorSet::Param(ParamId::from(usize::from(p)))
542 }
543 qsc_hir::ty::FunctorSet::Infer(i) => {
544 qsc_fir::ty::FunctorSet::Infer(InferFunctorId::from(usize::from(i)))
545 }
546 }
547}
548
549fn lower_prim_field(field: hir::PrimField) -> fir::PrimField {
550 match field {
551 hir::PrimField::Start => fir::PrimField::Start,
552 hir::PrimField::Step => fir::PrimField::Step,
553 hir::PrimField::End => fir::PrimField::End,
554 }
555}
556
557fn lower_item_id(id: &hir::ItemId) -> fir::ItemId {
558 fir::ItemId {
559 item: lower_local_item_id(id.item),
560 package: id.package.map(|p| fir::PackageId::from(usize::from(p))),
561 }
562}
563
564fn lower_ty_prim(prim: qsc_hir::ty::Prim) -> qsc_fir::ty::Prim {
565 match prim {
566 qsc_hir::ty::Prim::Bool => qsc_fir::ty::Prim::Bool,
567 qsc_hir::ty::Prim::Double => qsc_fir::ty::Prim::Double,
568 qsc_hir::ty::Prim::Int => qsc_fir::ty::Prim::Int,
569 qsc_hir::ty::Prim::Qubit => qsc_fir::ty::Prim::Qubit,
570 qsc_hir::ty::Prim::Result => qsc_fir::ty::Prim::Result,
571 qsc_hir::ty::Prim::String => qsc_fir::ty::Prim::String,
572 qsc_hir::ty::Prim::BigInt => qsc_fir::ty::Prim::BigInt,
573 qsc_hir::ty::Prim::RangeTo => qsc_fir::ty::Prim::RangeTo,
574 qsc_hir::ty::Prim::RangeFrom => qsc_fir::ty::Prim::RangeFrom,
575 qsc_hir::ty::Prim::Pauli => qsc_fir::ty::Prim::Pauli,
576 qsc_hir::ty::Prim::RangeFull => qsc_fir::ty::Prim::RangeFull,
577 qsc_hir::ty::Prim::Range => qsc_fir::ty::Prim::Range,
578 }
579}
580
581fn lower_visibility(visibility: hir::Visibility) -> fir::Visibility {
582 match visibility {
583 hir::Visibility::Public => fir::Visibility::Public,
584 hir::Visibility::Internal => fir::Visibility::Internal,
585 }
586}
587
588fn lower_callable_kind(kind: hir::CallableKind) -> fir::CallableKind {
589 match kind {
590 hir::CallableKind::Function => fir::CallableKind::Function,
591 hir::CallableKind::Operation => fir::CallableKind::Operation,
592 }
593}
594
595fn lower_mutability(mutability: hir::Mutability) -> fir::Mutability {
596 match mutability {
597 hir::Mutability::Immutable => fir::Mutability::Immutable,
598 hir::Mutability::Mutable => fir::Mutability::Mutable,
599 }
600}
601
602fn lower_unop(op: hir::UnOp) -> fir::UnOp {
603 match op {
604 hir::UnOp::Functor(f) => fir::UnOp::Functor(lower_functor(f)),
605 hir::UnOp::Neg => fir::UnOp::Neg,
606 hir::UnOp::NotB => fir::UnOp::NotB,
607 hir::UnOp::NotL => fir::UnOp::NotL,
608 hir::UnOp::Pos => fir::UnOp::Pos,
609 hir::UnOp::Unwrap => fir::UnOp::Unwrap,
610 }
611}
612
613fn lower_binop(op: hir::BinOp) -> fir::BinOp {
614 match op {
615 hir::BinOp::Add => fir::BinOp::Add,
616 hir::BinOp::AndB => fir::BinOp::AndB,
617 hir::BinOp::AndL => fir::BinOp::AndL,
618 hir::BinOp::Div => fir::BinOp::Div,
619 hir::BinOp::Eq => fir::BinOp::Eq,
620 hir::BinOp::Exp => fir::BinOp::Exp,
621 hir::BinOp::Gt => fir::BinOp::Gt,
622 hir::BinOp::Gte => fir::BinOp::Gte,
623 hir::BinOp::Lt => fir::BinOp::Lt,
624 hir::BinOp::Lte => fir::BinOp::Lte,
625 hir::BinOp::Mod => fir::BinOp::Mod,
626 hir::BinOp::Mul => fir::BinOp::Mul,
627 hir::BinOp::Neq => fir::BinOp::Neq,
628 hir::BinOp::OrB => fir::BinOp::OrB,
629 hir::BinOp::OrL => fir::BinOp::OrL,
630 hir::BinOp::Shl => fir::BinOp::Shl,
631 hir::BinOp::Shr => fir::BinOp::Shr,
632 hir::BinOp::Sub => fir::BinOp::Sub,
633 hir::BinOp::XorB => fir::BinOp::XorB,
634 }
635}
636
637fn lower_lit(lit: &hir::Lit) -> fir::ExprKind {
638 match lit {
639 hir::Lit::BigInt(value) => fir::ExprKind::Lit(fir::Lit::BigInt(value.clone())),
640 &hir::Lit::Bool(value) => fir::ExprKind::Lit(fir::Lit::Bool(value)),
641 &hir::Lit::Double(value) => fir::ExprKind::Lit(fir::Lit::Double(value)),
642 &hir::Lit::Int(value) => fir::ExprKind::Lit(fir::Lit::Int(value)),
643 hir::Lit::Pauli(hir::Pauli::I) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::I)),
644 hir::Lit::Pauli(hir::Pauli::X) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::X)),
645 hir::Lit::Pauli(hir::Pauli::Y) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::Y)),
646 hir::Lit::Pauli(hir::Pauli::Z) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::Z)),
647 hir::Lit::Result(hir::Result::One) => {
648 fir::ExprKind::Lit(fir::Lit::Result(fir::Result::One))
649 }
650 hir::Lit::Result(hir::Result::Zero) => {
651 fir::ExprKind::Lit(fir::Lit::Result(fir::Result::Zero))
652 }
653 }
654}
655
656fn lower_functor(functor: hir::Functor) -> fir::Functor {
657 match functor {
658 hir::Functor::Adj => fir::Functor::Adj,
659 hir::Functor::Ctl => fir::Functor::Ctl,
660 }
661}
662
663fn lower_functor_set_value(value: qsc_hir::ty::FunctorSetValue) -> qsc_fir::ty::FunctorSetValue {
664 match value {
665 qsc_hir::ty::FunctorSetValue::Empty => qsc_fir::ty::FunctorSetValue::Empty,
666 qsc_hir::ty::FunctorSetValue::Adj => qsc_fir::ty::FunctorSetValue::Adj,
667 qsc_hir::ty::FunctorSetValue::Ctl => qsc_fir::ty::FunctorSetValue::Ctl,
668 qsc_hir::ty::FunctorSetValue::CtlAdj => qsc_fir::ty::FunctorSetValue::CtlAdj,
669 }
670}
671
672#[must_use]
673#[allow(clippy::module_name_repetitions)]
674fn lower_local_item_id(id: qsc_hir::hir::LocalItemId) -> LocalItemId {
675 LocalItemId::from(usize::from(id))
676}
677