Skip to content

Commit ab4a67e

Browse files
committed
Extend compiler diagnostics with info-based diagnostics.
1 parent fe9bbe3 commit ab4a67e

File tree

15 files changed

+169
-37
lines changed

15 files changed

+169
-37
lines changed

forc-pkg/src/manifest/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ impl PackageManifestFile {
478478
let parse_res = parse_tree_type(&handler, entry_string);
479479

480480
parse_res.map_err(|_| {
481-
let (errors, _warnings) = handler.consume();
481+
let (errors, _warnings, _infos) = handler.consume();
482482
parsing_failed(&self.project.name, &errors)
483483
})
484484
}

forc-pkg/src/pkg.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use anyhow::{anyhow, bail, Context, Error, Result};
99
use byte_unit::{Byte, UnitType};
1010
use forc_tracing::{println_action_green, println_warning};
1111
use forc_util::{
12-
default_output_directory, find_file_name, kebab_to_snake_case, print_compiling,
12+
default_output_directory, find_file_name, kebab_to_snake_case, print_compiling, print_infos,
1313
print_on_failure, print_warnings,
1414
};
1515
use petgraph::{
@@ -1701,10 +1701,11 @@ pub fn compile(
17011701
let terse_mode = profile.terse;
17021702
let reverse_results = profile.reverse_results;
17031703
let fail = |handler: Handler| {
1704-
let (errors, warnings) = handler.consume();
1704+
let (errors, warnings, infos) = handler.consume();
17051705
print_on_failure(
17061706
engines.se(),
17071707
terse_mode,
1708+
&infos,
17081709
&warnings,
17091710
&errors,
17101711
reverse_results,
@@ -1862,8 +1863,9 @@ pub fn compile(
18621863
_ => return fail(handler),
18631864
};
18641865

1865-
let (_, warnings) = handler.consume();
1866+
let (_, warnings, infos) = handler.consume();
18661867

1868+
print_infos(engines.se(), terse_mode, &infos);
18671869
print_warnings(engines.se(), terse_mode, &pkg.name, &warnings, &tree_type);
18681870

18691871
// Metadata to be placed into the binary.
@@ -2420,10 +2422,11 @@ pub fn build(
24202422
manifest_file: manifest.clone(),
24212423
};
24222424

2423-
let fail = |warnings, errors| {
2425+
let fail = |infos, warnings, errors| {
24242426
print_on_failure(
24252427
engines.se(),
24262428
profile.terse,
2429+
infos,
24272430
warnings,
24282431
errors,
24292432
profile.reverse_results,
@@ -2467,7 +2470,7 @@ pub fn build(
24672470
dbg_generation,
24682471
) {
24692472
Ok(o) => o,
2470-
Err(errs) => return fail(&[], &errs),
2473+
Err(errs) => return fail(&[], &[], &errs),
24712474
};
24722475

24732476
let compiled_without_tests = compile(
@@ -2544,6 +2547,7 @@ pub fn build(
25442547
engines.se(),
25452548
profile.terse,
25462549
&[],
2550+
&[],
25472551
&errs,
25482552
profile.reverse_results,
25492553
);

forc-util/src/lib.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use sway_core::language::parsed::TreeType;
1818
use sway_error::{
1919
diagnostic::{Diagnostic, Issue, Label, LabelType, Level, ToDiagnostic},
2020
error::CompileError,
21-
warning::CompileWarning,
21+
warning::{CompileInfo, CompileWarning},
2222
};
2323
use sway_types::{LineCol, LineColRange, SourceEngine, Span};
2424
use sway_utils::constants;
@@ -295,6 +295,18 @@ pub fn print_compiling(ty: Option<&TreeType>, name: &str, src: &dyn std::fmt::Di
295295
);
296296
}
297297

298+
pub fn print_infos(source_engine: &SourceEngine, terse_mode: bool, infos: &[CompileInfo]) {
299+
if infos.is_empty() {
300+
return;
301+
}
302+
303+
if !terse_mode {
304+
infos
305+
.iter()
306+
.for_each(|n| format_diagnostic(&n.to_diagnostic(source_engine)));
307+
}
308+
}
309+
298310
pub fn print_warnings(
299311
source_engine: &SourceEngine,
300312
terse_mode: bool,
@@ -329,10 +341,13 @@ pub fn print_warnings(
329341
pub fn print_on_failure(
330342
source_engine: &SourceEngine,
331343
terse_mode: bool,
344+
infos: &[CompileInfo],
332345
warnings: &[CompileWarning],
333346
errors: &[CompileError],
334347
reverse_results: bool,
335348
) {
349+
print_infos(source_engine, terse_mode, infos);
350+
336351
let e_len = errors.len();
337352
let w_len = warnings.len();
338353

sway-core/src/ir_generation/compile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ fn compile_encoding_v0_abi_method(
768768
let ast_fn_decl = engines.de().get_function(ast_fn_decl);
769769

770770
let get_selector_result = ast_fn_decl.to_fn_selector_value(&handler, engines);
771-
let (errors, _warnings) = handler.consume();
771+
let (errors, _warnings, _infos) = handler.consume();
772772
let selector = match get_selector_result.ok() {
773773
Some(selector) => selector,
774774
None => {

sway-core/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use std::sync::Arc;
5151
use sway_ast::AttributeDecl;
5252
use sway_error::convert_parse_tree_error::ConvertParseTreeError;
5353
use sway_error::handler::{ErrorEmitted, Handler};
54-
use sway_error::warning::{CompileWarning, Warning};
54+
use sway_error::warning::{CollectedTraitImpl, CompileInfo, CompileWarning, Info, Warning};
5555
use sway_features::ExperimentalFeatures;
5656
use sway_ir::{
5757
create_o1_pass_group, register_known_passes, Context, Kind, Module, PassGroup, PassManager,
@@ -1017,8 +1017,8 @@ pub fn compile_to_ast(
10171017
let mut entry = query_engine.get_programs_cache_entry(&path).unwrap();
10181018
entry.programs.metrics.reused_programs += 1;
10191019

1020-
let (warnings, errors) = entry.handler_data;
1021-
let new_handler = Handler::from_parts(warnings, errors);
1020+
let (warnings, errors, infos) = entry.handler_data;
1021+
let new_handler = Handler::from_parts(warnings, errors, infos);
10221022
handler.append(new_handler);
10231023
return Ok(entry.programs);
10241024
};

sway-core/src/query_engine/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use std::{
66
sync::Arc,
77
time::SystemTime,
88
};
9-
use sway_error::{error::CompileError, warning::CompileWarning};
9+
use sway_error::{
10+
error::CompileError,
11+
warning::{CompileInfo, CompileWarning},
12+
};
1013
use sway_types::{IdentUnique, ProgramId, SourceId, Spanned};
1114

1215
use crate::{
@@ -131,7 +134,7 @@ pub type FunctionsCacheMap = HashMap<(IdentUnique, String), FunctionCacheEntry>;
131134
pub struct ProgramsCacheEntry {
132135
pub path: Arc<PathBuf>,
133136
pub programs: Programs,
134-
pub handler_data: (Vec<CompileError>, Vec<CompileWarning>),
137+
pub handler_data: (Vec<CompileError>, Vec<CompileWarning>, Vec<CompileInfo>),
135138
}
136139

137140
#[derive(Clone, Debug)]

sway-core/src/semantic_analysis/ast_node/expression/typed_expression/if_expression.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ pub(crate) fn instantiate_if_expression(
8484
}));
8585
}
8686

87-
let (new_errors, new_warnings) = h.consume();
87+
let (new_errors, new_warnings, new_infos) = h.consume();
88+
for info in new_infos {
89+
handler.emit_info(info);
90+
}
8891
for warn in new_warnings {
8992
handler.emit_warn(warn);
9093
}

sway-core/src/semantic_analysis/namespace/contract_helpers.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ pub fn package_with_contract_id(
4040
dbg_generation,
4141
)
4242
.map_err(|_| {
43-
let (errors, warnings) = handler.consume();
43+
let (errors, warnings, infos) = handler.consume();
4444
assert!(warnings.is_empty());
45+
assert!(infos.is_empty());
4546

4647
// Invariant: `.value == None` => `!errors.is_empty()`.
4748
vec1::Vec1::try_from_vec(errors).unwrap()

sway-core/src/type_system/unify/unifier.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,11 @@ impl<'a> Unifier<'a> {
617617
span,
618618
false,
619619
);
620-
let (new_errors, warnings) = h.consume();
620+
let (new_errors, warnings, infos) = h.consume();
621+
622+
for info in infos {
623+
handler.emit_info(info);
624+
}
621625

622626
for warn in warnings {
623627
handler.emit_warn(warn);

sway-error/src/handler.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,41 @@
1-
use crate::{error::CompileError, warning::CompileWarning};
1+
use crate::{
2+
error::CompileError,
3+
warning::{CompileInfo, CompileWarning},
4+
};
25
use core::cell::RefCell;
36

47
/// A handler with which you can emit diagnostics.
58
#[derive(Default, Debug, Clone)]
69
pub struct Handler {
710
/// The inner handler.
811
/// This construction is used to avoid `&mut` all over the compiler.
9-
inner: RefCell<HandlerInner>,
12+
inner: RefCell<HandlerDiagnostics>,
1013
}
1114

1215
/// Contains the actual data for `Handler`.
1316
/// Modelled this way to afford an API using interior mutability.
1417
#[derive(Default, Debug, Clone)]
15-
struct HandlerInner {
18+
struct HandlerDiagnostics {
1619
/// The sink through which errors will be emitted.
1720
errors: Vec<CompileError>,
1821
/// The sink through which warnings will be emitted.
1922
warnings: Vec<CompileWarning>,
23+
/// The sink through which infos will be emitted.
24+
infos: Vec<CompileInfo>,
2025
}
2126

2227
impl Handler {
23-
pub fn from_parts(errors: Vec<CompileError>, warnings: Vec<CompileWarning>) -> Self {
28+
pub fn from_parts(
29+
errors: Vec<CompileError>,
30+
warnings: Vec<CompileWarning>,
31+
infos: Vec<CompileInfo>,
32+
) -> Self {
2433
Self {
25-
inner: RefCell::new(HandlerInner { errors, warnings }),
34+
inner: RefCell::new(HandlerDiagnostics {
35+
errors,
36+
warnings,
37+
infos,
38+
}),
2639
}
2740
}
2841

@@ -42,6 +55,11 @@ impl Handler {
4255
self.inner.borrow_mut().warnings.push(warn);
4356
}
4457

58+
/// Emit the info `info`.
59+
pub fn emit_info(&self, info: CompileInfo) {
60+
self.inner.borrow_mut().infos.push(info);
61+
}
62+
4563
pub fn has_errors(&self) -> bool {
4664
!self.inner.borrow().errors.is_empty()
4765
}
@@ -67,22 +85,25 @@ impl Handler {
6785
}
6886
}
6987

70-
/// Extract all the warnings and errors from this handler.
71-
pub fn consume(self) -> (Vec<CompileError>, Vec<CompileWarning>) {
88+
/// Extract all the diagnostics from this handler.
89+
pub fn consume(self) -> (Vec<CompileError>, Vec<CompileWarning>, Vec<CompileInfo>) {
7290
let inner = self.inner.into_inner();
73-
(inner.errors, inner.warnings)
91+
(inner.errors, inner.warnings, inner.infos)
7492
}
7593

7694
pub fn append(&self, other: Handler) -> Option<ErrorEmitted> {
7795
let other_has_errors = other.has_errors();
7896

79-
let (errors, warnings) = other.consume();
97+
let (errors, warnings, infos) = other.consume();
8098
for warn in warnings {
8199
self.emit_warn(warn);
82100
}
83101
for err in errors {
84102
self.emit_err(err);
85103
}
104+
for inf in infos {
105+
self.emit_info(inf);
106+
}
86107

87108
if other_has_errors {
88109
Some(ErrorEmitted { _priv: () })
@@ -118,7 +139,7 @@ impl Handler {
118139
) -> Result<(), ErrorEmitted> {
119140
let mut emitted = Ok(());
120141

121-
let (errs, _) = other.consume();
142+
let (errs, _, _) = other.consume();
122143
for err in errs {
123144
if let Some(err) = (f)(err) {
124145
emitted = Err(self.emit_err(err));

0 commit comments

Comments
 (0)