Skip to content

Commit 3418759

Browse files
authored
Rust: avoid emitting trailing whitespace (bytecodealliance#878)
* Rust: avoid emitting trailing whitespace This works around what appears to be a bug in rustfmt when generating bindings for wasi-http. If the code is too complex, rustfmt appears to stops formatting, and then abort when it leaves behind trailing whitespace. * Set the indent to 0 when emitting a multi-line string literal.
1 parent efd511f commit 3418759

File tree

3 files changed

+42
-22
lines changed

3 files changed

+42
-22
lines changed

crates/core/src/source.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub struct Source {
3838
s: String,
3939
indent: usize,
4040
in_line_comment: bool,
41+
continuing_line: bool,
4142
}
4243

4344
impl Source {
@@ -50,6 +51,15 @@ impl Source {
5051
pub fn push_str(&mut self, src: &str) {
5152
let lines = src.lines().collect::<Vec<_>>();
5253
for (i, line) in lines.iter().enumerate() {
54+
if !self.continuing_line {
55+
if !line.is_empty() {
56+
for _ in 0..self.indent {
57+
self.s.push_str(" ");
58+
}
59+
}
60+
self.continuing_line = true;
61+
}
62+
5363
let trimmed = line.trim();
5464
if trimmed.starts_with("//") {
5565
self.in_line_comment = true;
@@ -92,12 +102,17 @@ impl Source {
92102
self.indent -= amt;
93103
}
94104

105+
/// Set the indentation level, and return the old level.
106+
pub fn set_indent(&mut self, amt: usize) -> usize {
107+
let old = self.indent;
108+
self.indent = amt;
109+
old
110+
}
111+
95112
fn newline(&mut self) {
96113
self.in_line_comment = false;
114+
self.continuing_line = false;
97115
self.s.push('\n');
98-
for _ in 0..self.indent {
99-
self.s.push_str(" ");
100-
}
101116
}
102117

103118
pub fn as_mut_string(&mut self) -> &mut String {

crates/rust/src/interface.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,11 @@ macro_rules! {macro_name} {{
334334
if self.return_pointer_area_align > 0 {
335335
uwrite!(
336336
self.src,
337-
"
337+
"\
338338
#[repr(align({align}))]
339339
struct _RetArea([::core::mem::MaybeUninit::<u8>; {size}]);
340340
static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); {size}]);
341-
",
341+
",
342342
align = self.return_pointer_area_align,
343343
size = self.return_pointer_area_size,
344344
);
@@ -393,7 +393,7 @@ macro_rules! {macro_name} {{
393393
let module = self.finish();
394394
let path_to_root = self.path_to_root();
395395
let module = format!(
396-
"
396+
"\
397397
#[allow(clippy::all)]
398398
pub mod {snake} {{
399399
#[used]
@@ -402,7 +402,7 @@ macro_rules! {macro_name} {{
402402
static __FORCE_SECTION_REF: fn() = {path_to_root}__link_custom_section_describing_imports;
403403
{module}
404404
}}
405-
",
405+
",
406406
);
407407
let map = if self.in_import {
408408
&mut self.gen.import_modules
@@ -461,11 +461,11 @@ macro_rules! {macro_name} {{
461461
if import_return_pointer_area_size > 0 {
462462
uwrite!(
463463
self.src,
464-
"
464+
"\
465465
#[repr(align({import_return_pointer_area_align}))]
466466
struct RetArea([::core::mem::MaybeUninit::<u8>; {import_return_pointer_area_size}]);
467467
let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); {import_return_pointer_area_size}]);
468-
",
468+
",
469469
);
470470
}
471471
self.src.push_str(&String::from(src));
@@ -485,11 +485,11 @@ macro_rules! {macro_name} {{
485485
let name_snake = func.name.to_snake_case().replace('.', "_");
486486
uwrite!(
487487
self.src,
488-
"
488+
"\
489489
#[doc(hidden)]
490490
#[allow(non_snake_case)]
491491
pub unsafe fn _export_{name_snake}_cabi<T: {trait_name}>\
492-
",
492+
",
493493
);
494494
let params = self.print_export_sig(func);
495495
self.push_str(" {");
@@ -498,7 +498,7 @@ macro_rules! {macro_name} {{
498498
let run_ctors_once = self.path_to_run_ctors_once();
499499
uwrite!(
500500
self.src,
501-
"
501+
"\
502502
// Before executing any other code, use this function to run all static
503503
// constructors, if they have not yet been run. This is a hack required
504504
// to work around wasi-libc ctors calling import functions to initialize
@@ -512,7 +512,7 @@ macro_rules! {macro_name} {{
512512
// for more details.
513513
#[cfg(target_arch=\"wasm32\")]
514514
{run_ctors_once}();
515-
",
515+
",
516516
);
517517
}
518518

@@ -541,11 +541,11 @@ macro_rules! {macro_name} {{
541541
if abi::guest_export_needs_post_return(self.resolve, func) {
542542
uwrite!(
543543
self.src,
544-
"
544+
"\
545545
#[doc(hidden)]
546546
#[allow(non_snake_case)]
547547
pub unsafe fn __post_return_{name_snake}<T: {trait_name}>\
548-
"
548+
"
549549
);
550550
let params = self.print_post_return_sig(func);
551551
self.src.push_str("{\n");
@@ -575,10 +575,10 @@ macro_rules! {macro_name} {{
575575
let export_name = func.core_export_name(wasm_module_export_name.as_deref());
576576
uwrite!(
577577
self.src,
578-
"
578+
"\
579579
#[export_name = \"{export_prefix}{export_name}\"]
580580
unsafe extern \"C\" fn export_{name_snake}\
581-
",
581+
",
582582
);
583583

584584
let params = self.print_export_sig(func);
@@ -594,10 +594,10 @@ macro_rules! {macro_name} {{
594594
let export_prefix = self.gen.opts.export_prefix.as_deref().unwrap_or("");
595595
uwrite!(
596596
self.src,
597-
"
597+
"\
598598
#[export_name = \"{export_prefix}cabi_post_{export_name}\"]
599599
unsafe extern \"C\" fn _post_return_{name_snake}\
600-
"
600+
"
601601
);
602602
let params = self.print_post_return_sig(func);
603603
self.src.push_str("{\n");
@@ -717,8 +717,11 @@ macro_rules! {macro_name} {{
717717
None => return,
718718
};
719719
for line in docs.trim().lines() {
720-
self.push_str("/// ");
721-
self.push_str(line);
720+
self.push_str("///");
721+
if !line.is_empty() {
722+
self.push_str(" ");
723+
self.push_str(line);
724+
}
722725
self.push_str("\n");
723726
}
724727
}
@@ -1462,7 +1465,7 @@ macro_rules! {macro_name} {{
14621465
}
14631466
self.push_str(&format!("pub enum {name}"));
14641467
self.print_generics(mode.lifetime);
1465-
self.push_str("{\n");
1468+
self.push_str(" {\n");
14661469
for (case_name, docs, payload) in cases.clone() {
14671470
self.rustdoc(docs);
14681471
self.push_str(&case_name);

crates/rust/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ macro_rules! __export_{world_name}_impl {{
739739
"pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; {}] = *b\"\\\n",
740740
component_type.len()
741741
));
742+
let old_indent = self.src.set_indent(0);
742743
let mut line_length = 0;
743744
let s = self.src.as_mut_string();
744745
for byte in component_type.iter() {
@@ -771,6 +772,7 @@ macro_rules! __export_{world_name}_impl {{
771772
}
772773

773774
self.src.push_str("\";\n");
775+
self.src.set_indent(old_indent);
774776

775777
if let Some(func_name) = func_name {
776778
let rt = self.runtime_path().to_string();

0 commit comments

Comments
 (0)