Skip to content

Commit da2785d

Browse files
author
bors-servo
authored
Auto merge of rust-lang#1112 - emilio:always-gen, r=pepyakin
lib: Always generate bindings. Some cases in spawning rustfmt were not properly returning the source. Make it more reliable. This hit me when trying to update bindgen in Firefox.
2 parents a57d880 + 8a7f27a commit da2785d

File tree

1 file changed

+54
-56
lines changed

1 file changed

+54
-56
lines changed

src/lib.rs

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ use ir::item::Item;
8080
use parse::{ClangItemParser, ParseError};
8181
use regex_set::RegexSet;
8282

83+
use std::borrow::Cow;
8384
use std::fs::{File, OpenOptions};
8485
use std::io::{self, Write};
8586
use std::iter;
@@ -1678,30 +1679,32 @@ impl Bindings {
16781679

16791680
let bindings = self.module.as_str().to_string();
16801681

1681-
match self.rustfmt_generated_string(bindings) {
1682+
match self.rustfmt_generated_string(&bindings) {
16821683
Ok(rustfmt_bindings) => {
1683-
writer.write(rustfmt_bindings.as_str().as_bytes())?;
1684+
writer.write(rustfmt_bindings.as_bytes())?;
1685+
},
1686+
Err(err) => {
1687+
eprintln!("{:?}", err);
1688+
writer.write(bindings.as_str().as_bytes())?;
16841689
},
1685-
Err(err) => eprintln!("{:?}", err),
16861690
}
16871691
Ok(())
16881692
}
16891693

16901694
/// Checks if rustfmt_bindings is set and runs rustfmt on the string
1691-
fn rustfmt_generated_string(&self, source: String) -> io::Result<String> {
1695+
fn rustfmt_generated_string<'a>(
1696+
&self,
1697+
source: &'a str,
1698+
) -> io::Result<Cow<'a, str>> {
16921699
let _t = time::Timer::new("rustfmt_generated_string")
16931700
.with_output(self.options.time_phases);
16941701

16951702
if !self.options.rustfmt_bindings {
1696-
return Ok(source);
1703+
return Ok(Cow::Borrowed(source));
16971704
}
16981705

1699-
let rustfmt = if let Ok(rustfmt) = which::which("rustfmt") {
1700-
rustfmt
1701-
} else {
1702-
eprintln!("warning: could not find usable rustfmt to pretty print bindings");
1703-
return Ok(source);
1704-
};
1706+
let rustfmt = which::which("rustfmt")
1707+
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_owned()))?;
17051708

17061709
// Prefer using the `rustfmt-nightly` version of `rustmft`, if
17071710
// possible. It requires being run via `rustup run nightly ...`.
@@ -1726,52 +1729,47 @@ impl Bindings {
17261729
cmd.args(&["--config-path", path]);
17271730
}
17281731

1729-
match cmd.spawn() {
1730-
Ok(mut child) => {
1731-
let mut child_stdin = child.stdin.take().unwrap();
1732-
let mut child_stdout = child.stdout.take().unwrap();
1733-
1734-
// Write to stdin in a new thread, so that we can read from stdout on this
1735-
// thread. This keeps the child from blocking on writing to its stdout which
1736-
// might block us from writing to its stdin.
1737-
let stdin_handle = ::std::thread::spawn(move || {
1738-
let _ = child_stdin.write_all(source.as_bytes());
1739-
source
1740-
});
1741-
1742-
let mut output = vec![];
1743-
io::copy(&mut child_stdout, &mut output)?;
1744-
1745-
let status = child.wait()?;
1746-
let source = stdin_handle.join()
1747-
.expect("The thread writing to rustfmt's stdin doesn't do \
1748-
anything that could panic");
1749-
1750-
match String::from_utf8(output) {
1751-
Ok(bindings) => {
1752-
match status.code() {
1753-
Some(0) => Ok(bindings),
1754-
Some(2) => Err(io::Error::new(
1755-
io::ErrorKind::Other,
1756-
"Rustfmt parsing errors.".to_string(),
1757-
)),
1758-
Some(3) => {
1759-
warn!("Rustfmt could not format some lines.");
1760-
Ok(bindings)
1761-
}
1762-
_ => Err(io::Error::new(
1763-
io::ErrorKind::Other,
1764-
"Internal rustfmt error".to_string(),
1765-
)),
1766-
}
1767-
},
1768-
_ => Ok(source)
1732+
let mut child = cmd.spawn()?;
1733+
let mut child_stdin = child.stdin.take().unwrap();
1734+
let mut child_stdout = child.stdout.take().unwrap();
1735+
1736+
let source = source.to_owned();
1737+
1738+
// Write to stdin in a new thread, so that we can read from stdout on this
1739+
// thread. This keeps the child from blocking on writing to its stdout which
1740+
// might block us from writing to its stdin.
1741+
let stdin_handle = ::std::thread::spawn(move || {
1742+
let _ = child_stdin.write_all(source.as_bytes());
1743+
source
1744+
});
1745+
1746+
let mut output = vec![];
1747+
io::copy(&mut child_stdout, &mut output)?;
1748+
1749+
let status = child.wait()?;
1750+
let source = stdin_handle.join()
1751+
.expect("The thread writing to rustfmt's stdin doesn't do \
1752+
anything that could panic");
1753+
1754+
match String::from_utf8(output) {
1755+
Ok(bindings) => {
1756+
match status.code() {
1757+
Some(0) => Ok(Cow::Owned(bindings)),
1758+
Some(2) => Err(io::Error::new(
1759+
io::ErrorKind::Other,
1760+
"Rustfmt parsing errors.".to_string(),
1761+
)),
1762+
Some(3) => {
1763+
warn!("Rustfmt could not format some lines.");
1764+
Ok(Cow::Owned(bindings))
1765+
}
1766+
_ => Err(io::Error::new(
1767+
io::ErrorKind::Other,
1768+
"Internal rustfmt error".to_string(),
1769+
)),
17691770
}
1770-
}
1771-
Err(e) => {
1772-
eprintln!("Error spawning rustfmt: {}", e);
1773-
Ok(source)
1774-
}
1771+
},
1772+
_ => Ok(Cow::Owned(source))
17751773
}
17761774
}
17771775
}

0 commit comments

Comments
 (0)