microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
billt/mac-intel-cryptography

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc/src/compile.rs

172lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use miette::{Diagnostic, Report};
5use qsc_data_structures::{
6 error::WithSource, language_features::LanguageFeatures, source::SourceMap, span::Span,
7 target::TargetCapabilityFlags,
8};
9pub use qsc_frontend::compile::Dependencies;
10use qsc_frontend::compile::{CompileUnit, PackageStore};
11use qsc_passes::{PackageType, run_core_passes, run_default_passes};
12use thiserror::Error;
13
14pub type Error = WithSource<ErrorKind>;
15
16#[derive(Clone, Debug, Diagnostic, Error)]
17#[error(transparent)]
18/// `ErrorKind` represents the different kinds of errors that can occur in the compiler.
19/// Each variant of the enum corresponds to a different stage of the compilation process.
20pub enum ErrorKind {
21 /// `Frontend` variant represents errors that occur during the frontend stage of the compiler.
22 /// These errors are typically related to syntax and semantic checks.
23 #[diagnostic(transparent)]
24 Frontend(#[from] qsc_frontend::compile::Error),
25
26 /// `Pass` variant represents errors that occur during the `qsc_passes` stage of the compiler.
27 /// These errors are typically related to optimization, transformation, code generation, passes,
28 /// and static analysis passes.
29 #[diagnostic(transparent)]
30 Pass(#[from] qsc_passes::Error),
31
32 /// Errors from FIR-level transforms (return unification, defunctionalization,
33 /// monomorphization) that run before capability checking.
34 #[diagnostic(transparent)]
35 FirTransform(#[from] qsc_fir_transforms::PipelineError),
36
37 /// `Lint` variant represents lints generated during the linting stage. These diagnostics are
38 /// typically emitted from the language server and happens after all other compilation passes.
39 #[diagnostic(transparent)]
40 Lint(#[from] qsc_linter::Lint),
41
42 #[error("Cycle in dependency graph")]
43 /// `DependencyCycle` occurs when there is a cycle in the dependency graph.
44 DependencyCycle,
45
46 #[error("{0}")]
47 /// `CircuitParse` variant represents errors that occur while parsing circuit files.
48 CircuitParse(String),
49
50 /// `OpenQASM` compilation errors.
51 #[diagnostic(transparent)]
52 OpenQasm(#[from] crate::openqasm::error::Error),
53
54 #[error(
55 "The @EntryPoint attribute with a profile argument is not allowed in a Q# project (with qsharp.json). Please specify the profile in qsharp.json instead."
56 )]
57 EntryPointProfileInProject(#[label] Span),
58}
59
60/// Compiles a package from its AST representation.
61#[must_use]
62#[allow(clippy::module_name_repetitions)]
63pub fn compile_ast(
64 store: &PackageStore,
65 dependencies: &Dependencies,
66 ast_package: qsc_ast::ast::Package,
67 sources: SourceMap,
68 package_type: PackageType,
69 capabilities: TargetCapabilityFlags,
70) -> (CompileUnit, Vec<Error>) {
71 let unit = qsc_frontend::compile::compile_ast(
72 store,
73 dependencies,
74 ast_package,
75 sources,
76 capabilities,
77 vec![],
78 );
79 process_compile_unit(store, package_type, unit)
80}
81
82/// Compiles a package from its source representation.
83#[must_use]
84pub fn compile(
85 store: &PackageStore,
86 dependencies: &Dependencies,
87 sources: SourceMap,
88 package_type: PackageType,
89 capabilities: TargetCapabilityFlags,
90 language_features: LanguageFeatures,
91) -> (CompileUnit, Vec<Error>) {
92 let unit = qsc_frontend::compile::compile(
93 store,
94 dependencies,
95 sources,
96 capabilities,
97 language_features,
98 );
99 process_compile_unit(store, package_type, unit)
100}
101
102#[must_use]
103#[allow(clippy::module_name_repetitions)]
104fn process_compile_unit(
105 store: &PackageStore,
106 package_type: PackageType,
107 mut unit: CompileUnit,
108) -> (CompileUnit, Vec<Error>) {
109 let mut errors = Vec::new();
110 for error in unit.errors.drain(..) {
111 errors.push(WithSource::from_map(&unit.sources, error.into()));
112 }
113
114 if errors.is_empty() {
115 for error in run_default_passes(store.core(), &mut unit, package_type) {
116 errors.push(WithSource::from_map(&unit.sources, error.into()));
117 }
118 }
119
120 (unit, errors)
121}
122
123#[must_use]
124pub fn package_store_with_stdlib(
125 capabilities: TargetCapabilityFlags,
126) -> (qsc_hir::hir::PackageId, PackageStore) {
127 let mut store = PackageStore::new(core());
128 let std_id = store.insert(std(&store, capabilities));
129 (std_id, store)
130}
131
132/// Compiles the core library.
133///
134/// # Panics
135///
136/// Panics if the core library compiles with errors.
137#[must_use]
138pub fn core() -> CompileUnit {
139 let mut unit = qsc_frontend::compile::core();
140 let pass_errors = run_core_passes(&mut unit);
141 if pass_errors.is_empty() {
142 unit
143 } else {
144 for error in pass_errors {
145 let report = Report::new(WithSource::from_map(&unit.sources, error));
146 eprintln!("{report:?}");
147 }
148
149 panic!("could not compile core library")
150 }
151}
152
153/// Compiles the standard library.
154///
155/// # Panics
156///
157/// Panics if the standard library does not compile without errors.
158#[must_use]
159pub fn std(store: &PackageStore, capabilities: TargetCapabilityFlags) -> CompileUnit {
160 let mut unit = qsc_frontend::compile::std(store, capabilities);
161 let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib);
162 if pass_errors.is_empty() {
163 unit
164 } else {
165 for error in pass_errors {
166 let report = Report::new(WithSource::from_map(&unit.sources, error));
167 eprintln!("{report:?}");
168 }
169
170 panic!("could not compile standard library")
171 }
172}
173