Skip to content

Commit 8be2dae

Browse files
authored
Implement a command to dump impls for a given type (#7322)
This adds a new `--dump-impls` CLI command that can be used to dump all the recognized trait impls for a given type name. This also extends the compiler diagnostic system to allow the emission of info diagnostics, as previously we could only emit either warnings of errors, which did not fit this use case. ## Description For example, here is the output of `cargo run --bin forc -- build --path _test-case --dump-impls=std::string::String`: <img width="677" height="958" alt="image" src="https://github.com/user-attachments/assets/42aeca94-bbf9-4dff-8bb3-d1a70000999a" /> And for enums: <img width="642" height="285" alt="image" src="https://github.com/user-attachments/assets/ac565fea-9ebe-4f1d-a9a8-d022617d23d0" /> Closes #7286. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
1 parent 13e4df8 commit 8be2dae

File tree

50 files changed

+648
-66
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+648
-66
lines changed

forc-pkg/src/manifest/build_profile.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use serde::{Deserialize, Serialize};
22
use sway_core::{Backtrace, OptLevel, PrintAsm, PrintIr};
33

4+
use crate::DumpOpts;
5+
46
/// Parameters to pass through to the `sway_core::BuildConfig` during compilation.
57
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
68
#[serde(rename_all = "kebab-case")]
@@ -11,6 +13,7 @@ pub struct BuildProfile {
1113
pub print_ast: bool,
1214
pub print_dca_graph: Option<String>,
1315
pub print_dca_graph_url_format: Option<String>,
16+
pub dump: DumpOpts,
1417
#[serde(default)]
1518
pub print_ir: PrintIr,
1619
#[serde(default)]
@@ -47,6 +50,7 @@ impl BuildProfile {
4750
pub fn debug() -> Self {
4851
Self {
4952
name: Self::DEBUG.into(),
53+
dump: DumpOpts::default(),
5054
print_ast: false,
5155
print_dca_graph: None,
5256
print_dca_graph_url_format: None,
@@ -69,6 +73,7 @@ impl BuildProfile {
6973
pub fn release() -> Self {
7074
Self {
7175
name: Self::RELEASE.to_string(),
76+
dump: DumpOpts::default(),
7277
print_ast: false,
7378
print_dca_graph: None,
7479
print_dca_graph_url_format: None,
@@ -101,7 +106,7 @@ impl Default for BuildProfile {
101106

102107
#[cfg(test)]
103108
mod tests {
104-
use crate::{BuildProfile, PackageManifest};
109+
use crate::{BuildProfile, DumpOpts, PackageManifest};
105110
use sway_core::{Backtrace, OptLevel, PrintAsm, PrintIr};
106111

107112
#[test]
@@ -154,6 +159,7 @@ mod tests {
154159
// Adapted release profile.
155160
let expected = BuildProfile {
156161
name: "".into(),
162+
dump: DumpOpts::default(),
157163
print_ast: true,
158164
print_dca_graph: Some("dca_graph".into()),
159165
print_dca_graph_url_format: Some("print_dca_graph_url_format".into()),

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: 28 additions & 6 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::{
@@ -279,12 +279,19 @@ pub struct MinifyOpts {
279279
/// Represents a compiled contract ID as a pub const in a contract.
280280
type ContractIdConst = String;
281281

282+
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq)]
283+
pub struct DumpOpts {
284+
/// Dump all trait implementations for the given type name.
285+
pub dump_impls: Option<String>,
286+
}
287+
282288
/// The set of options provided to the `build` functions.
283289
#[derive(Default, Clone)]
284290
pub struct BuildOpts {
285291
pub pkg: PkgOpts,
286292
pub print: PrintOpts,
287293
pub minify: MinifyOpts,
294+
pub dump: DumpOpts,
288295
/// If set, generates a JSON file containing the hex-encoded script binary.
289296
pub hex_outfile: Option<String>,
290297
/// If set, outputs a binary file representing the script bytes.
@@ -1701,10 +1708,11 @@ pub fn compile(
17011708
let terse_mode = profile.terse;
17021709
let reverse_results = profile.reverse_results;
17031710
let fail = |handler: Handler| {
1704-
let (errors, warnings) = handler.consume();
1711+
let (errors, warnings, infos) = handler.consume();
17051712
print_on_failure(
17061713
engines.se(),
17071714
terse_mode,
1715+
&infos,
17081716
&warnings,
17091717
&errors,
17101718
reverse_results,
@@ -1724,7 +1732,7 @@ pub fn compile(
17241732
&handler,
17251733
engines,
17261734
source,
1727-
namespace,
1735+
namespace.clone(),
17281736
Some(&sway_build_config),
17291737
&pkg.name,
17301738
None,
@@ -1754,6 +1762,15 @@ pub fn compile(
17541762
return fail(handler);
17551763
}
17561764

1765+
if let Some(typename) = &profile.dump.dump_impls {
1766+
let _ = sway_core::dump_trait_impls_for_typename(
1767+
&handler,
1768+
engines,
1769+
&typed_program.namespace,
1770+
typename,
1771+
);
1772+
}
1773+
17571774
let asm_res = time_expr!(
17581775
pkg.name,
17591776
"compile ast to asm",
@@ -1862,8 +1879,9 @@ pub fn compile(
18621879
_ => return fail(handler),
18631880
};
18641881

1865-
let (_, warnings) = handler.consume();
1882+
let (_, warnings, infos) = handler.consume();
18661883

1884+
print_infos(engines.se(), terse_mode, &infos);
18671885
print_warnings(engines.se(), terse_mode, &pkg.name, &warnings, &tree_type);
18681886

18691887
// Metadata to be placed into the binary.
@@ -2108,6 +2126,7 @@ fn build_profile_from_opts(
21082126
metrics_outfile,
21092127
tests,
21102128
error_on_warnings,
2129+
dump,
21112130
..
21122131
} = build_options;
21132132

@@ -2128,6 +2147,7 @@ fn build_profile_from_opts(
21282147
BuildProfile::default()
21292148
});
21302149
profile.name = selected_profile_name.into();
2150+
profile.dump = dump.clone();
21312151
profile.print_ast |= print.ast;
21322152
if profile.print_dca_graph.is_none() {
21332153
profile.print_dca_graph.clone_from(&print.dca_graph);
@@ -2420,10 +2440,11 @@ pub fn build(
24202440
manifest_file: manifest.clone(),
24212441
};
24222442

2423-
let fail = |warnings, errors| {
2443+
let fail = |infos, warnings, errors| {
24242444
print_on_failure(
24252445
engines.se(),
24262446
profile.terse,
2447+
infos,
24272448
warnings,
24282449
errors,
24292450
profile.reverse_results,
@@ -2467,7 +2488,7 @@ pub fn build(
24672488
dbg_generation,
24682489
) {
24692490
Ok(o) => o,
2470-
Err(errs) => return fail(&[], &errs),
2491+
Err(errs) => return fail(&[], &[], &errs),
24712492
};
24722493

24732494
let compiled_without_tests = compile(
@@ -2544,6 +2565,7 @@ pub fn build(
25442565
engines.se(),
25452566
profile.terse,
25462567
&[],
2568+
&[],
25472569
&errs,
25482570
profile.reverse_results,
25492571
);

forc-pkg/tests/sections/Forc.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ name = "sections"
77
[dependencies]
88

99
[build-profile.release]
10+
dump = {}
1011
print-ast = true
1112
print-dca-graph = "dca_graph"
1213
print-dca-graph-url-format = "print_dca_graph_url_format"
@@ -23,13 +24,16 @@ optimization-level = 0
2324
backtrace = "none"
2425

2526
[build-profile.custom_asm]
27+
dump = {}
2628
print-asm = { virtual = false, allocated = false, final = true }
2729

2830
[build-profile.custom_ir]
31+
dump = {}
2932
print-ir = { initial = true, final = false, modified = true, passes = [
3033
"dce",
3134
"sroa",
3235
] }
3336

3437
[build-profile.custom_backtrace]
3538
backtrace = "only_always"
39+
dump = {}

forc-plugins/forc-client/src/op/deploy.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
},
1313
};
1414
use anyhow::{bail, Context, Result};
15-
use forc_pkg::{self as pkg, PackageManifestFile};
15+
use forc_pkg::{self as pkg, DumpOpts, PackageManifestFile};
1616
use forc_pkg::{manifest::GenericManifestFile, MemberFilter};
1717
use forc_tracing::{println_action_green, println_warning};
1818
use forc_util::default_output_directory;
@@ -814,6 +814,7 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy, member_filter: pkg::MemberFilter) -> p
814814
ir: cmd.print.ir(),
815815
reverse_order: cmd.print.reverse_order,
816816
},
817+
dump: DumpOpts::default(),
817818
time_phases: cmd.print.time_phases,
818819
profile: cmd.print.profile,
819820
metrics_outfile: cmd.print.metrics_outfile.clone(),

forc-plugins/forc-client/src/op/run/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
},
99
};
1010
use anyhow::{anyhow, bail, Context, Result};
11-
use forc_pkg::{self as pkg, fuel_core_not_running, PackageManifestFile};
11+
use forc_pkg::{self as pkg, fuel_core_not_running, DumpOpts, PackageManifestFile};
1212
use forc_tracing::println_warning;
1313
use forc_util::tx_utils::format_log_receipts;
1414
use fuel_abi_types::abi::program::ProgramABI;
@@ -319,6 +319,7 @@ fn build_opts_from_cmd(cmd: &cmd::Run) -> pkg::BuildOpts {
319319
json_abi: cmd.minify.json_abi,
320320
json_storage_slots: cmd.minify.json_storage_slots,
321321
},
322+
dump: DumpOpts::default(),
322323
build_target: BuildTarget::default(),
323324
build_profile: cmd.build_profile.build_profile.clone(),
324325
release: cmd.build_profile.release,

forc-test/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::setup::{
77
ContractDeploymentSetup, ContractTestSetup, DeploymentSetup, ScriptTestSetup, TestSetup,
88
};
99
use ecal::EcalSyscallHandler;
10-
use forc_pkg::{self as pkg, BuildOpts};
10+
use forc_pkg::{self as pkg, BuildOpts, DumpOpts};
1111
use forc_util::tx_utils::RevertInfo;
1212
use fuel_abi_types::abi::program::ProgramABI;
1313
use fuel_tx as tx;
@@ -452,6 +452,7 @@ impl From<TestOpts> for pkg::BuildOpts {
452452
pkg: val.pkg,
453453
print: val.print,
454454
minify: val.minify,
455+
dump: DumpOpts::default(),
455456
binary_outfile: val.binary_outfile,
456457
debug_outfile: val.debug_outfile,
457458
hex_outfile: val.hex_outfile,
@@ -477,6 +478,7 @@ impl TestOpts {
477478
pkg: self.pkg,
478479
print: self.print,
479480
minify: self.minify,
481+
dump: DumpOpts::default(),
480482
binary_outfile: self.binary_outfile,
481483
debug_outfile: self.debug_outfile,
482484
hex_outfile: self.hex_outfile,

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

forc/src/cli/commands/check.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ pub struct Command {
4545
#[clap(long)]
4646
pub ipfs_node: Option<IPFSNode>,
4747

48+
/// Dump all trait implementations for the given type name.
49+
#[clap(long = "dump-impls", value_name = "TYPE")]
50+
pub dump_impls: Option<String>,
51+
4852
#[clap(flatten)]
4953
pub experimental: sway_features::CliFields,
5054
}

forc/src/cli/shared.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ pub struct Build {
9191
/// Build target to use for code generation.
9292
#[clap(long, value_enum, default_value_t = BuildTarget::default(), alias="target")]
9393
pub build_target: BuildTarget,
94+
#[clap(flatten)]
95+
pub dump: Dump,
9496
}
9597

9698
/// Build output file options.
@@ -126,6 +128,14 @@ pub struct BuildProfile {
126128
pub error_on_warnings: bool,
127129
}
128130

131+
/// Dump options.
132+
#[derive(Args, Debug, Default)]
133+
pub struct Dump {
134+
/// Dump all trait implementations for the given type name.
135+
#[clap(long = "dump-impls", value_name = "TYPE")]
136+
pub dump_impls: Option<String>,
137+
}
138+
129139
/// Options related to printing stages of compiler output.
130140
#[derive(Args, Debug, Default)]
131141
pub struct Print {

0 commit comments

Comments
 (0)