Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changelog/fix-generated-trailing-whitespace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
applies_to:
- server
authors:
- jlizen
references:
- smithy-rs#4634
breaking: false
new_feature: false
bug_fix: true
---

Strip trailing whitespace from generated Rust code. Smithy's `AbstractCodeWriter` adds indentation to blank lines, producing whitespace-only lines that cause `cargo fmt` to fail with `error[internal]: left behind trailing whitespace`.
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,8 @@ class RustWriter private constructor(
) :
SymbolWriter<RustWriter, UseDeclarations>(UseDeclarations(namespace)) {
companion object {
private val TRAILING_WHITESPACE_RE = Regex("[ \\t]+\\n")

fun root() = forModule(null)

fun forModule(module: String?): RustWriter =
Expand Down Expand Up @@ -925,6 +927,7 @@ class RustWriter private constructor(
null
}
return listOfNotNull(preheader, header, useDecls, contents).joinToString(separator = "\n", postfix = "\n")
.replace(TRAILING_WHITESPACE_RE, "\n")
}

fun format(r: Any) = formatter.apply(r, "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,37 @@ class RustWriterTest {
val sut = RustWriter.forModule("src/module_name")
sut.module().shouldBe("module_name")
}

// Regression test for https://github.com/smithy-lang/smithy-rs/issues/4634
@Test
fun `output does not contain trailing whitespace`() {
val sut = RustWriter.root()
// Reproduce the two patterns from the issue:
sut.rustBlock("fn example()") {
// join("\n") separator creates a blank line that gets indented
val writables =
listOf(
writable { rust("let a = 1;") },
writable { rust("let b = 2;") },
)
writables.join("\n")(this)

// Empty string interpolation leaves a blank line that gets indented
val empty = ""
rust(
"""
something
.method()
$empty
.chain()
""",
)
}
val output = sut.toString()
val trailingWhitespaceLines =
output.lines().filter { line ->
line != line.trimEnd()
}
trailingWhitespaceLines shouldBe emptyList()
}
}
Loading