microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/fix-2145

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/interpret/debug.rs

91lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#[cfg(test)]
5mod tests;
6
7use qsc_eval::debug::Frame;
8use qsc_fir::fir::{Global, PackageStoreLookup, StoreItemId};
9use qsc_frontend::compile::PackageStore;
10use qsc_hir::hir;
11use qsc_hir::hir::{Item, ItemKind};
12use qsc_lowerer::map_fir_package_to_hir;
13use std::fmt::Write;
14use std::rc::Rc;
15
16#[must_use]
17pub(crate) fn format_call_stack(
18 store: &PackageStore,
19 globals: &impl PackageStoreLookup,
20 frames: Vec<Frame>,
21 error: &dyn std::error::Error,
22) -> String {
23 let mut trace = String::new();
24 writeln!(trace, "Error: {error}").expect("writing to string should succeed");
25 trace.push_str("Call stack:\n");
26
27 let mut frames = frames;
28 frames.reverse();
29
30 for frame in frames {
31 let Some(Global::Callable(call)) = globals.get_global(frame.id) else {
32 panic!("missing global");
33 };
34
35 trace.push_str(" at ");
36 if frame.functor.adjoint {
37 trace.push_str("Adjoint ");
38 }
39 if frame.functor.controlled > 0 {
40 write!(trace, "Controlled({}) ", frame.functor.controlled)
41 .expect("writing to string should succeed");
42 }
43 if let Some(item) = get_item_parent(store, frame.id) {
44 if let Some(ns) = get_ns_name(&item) {
45 write!(trace, "{ns}.").expect("writing to string should succeed");
46 }
47 }
48 write!(trace, "{}", call.name.name).expect("writing to string should succeed");
49
50 let name = get_item_file_name(store, frame.id);
51 write!(trace, " in {}", name.unwrap_or("<expression>".to_string()))
52 .expect("writing to string should succeed");
53
54 trace.push('\n');
55 }
56 trace
57}
58
59#[must_use]
60fn get_item_parent(store: &PackageStore, id: StoreItemId) -> Option<Item> {
61 let package = map_fir_package_to_hir(id.package);
62 let item = hir::LocalItemId::from(usize::from(id.item));
63 store.get(package).and_then(|unit| {
64 let item = unit.package.items.get(item)?;
65 if let Some(parent) = item.parent {
66 let parent = unit.package.items.get(parent)?;
67 Some(parent.clone())
68 } else {
69 None
70 }
71 })
72}
73
74#[must_use]
75fn get_item_file_name(store: &PackageStore, id: StoreItemId) -> Option<String> {
76 let package = map_fir_package_to_hir(id.package);
77 let item = hir::LocalItemId::from(usize::from(id.item));
78 store.get(package).and_then(|unit| {
79 let item = unit.package.items.get(item)?;
80 let source = unit.sources.find_by_offset(item.span.lo);
81 source.map(|s| s.name.to_string())
82 })
83}
84
85#[must_use]
86fn get_ns_name(item: &Item) -> Option<Rc<str>> {
87 let ItemKind::Namespace(ns, _) = &item.kind else {
88 return None;
89 };
90 Some(ns.name())
91}
92