X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Fproc_macro_api%2Fsrc%2Fmsg.rs;h=899895578682cd4d2e92a686bc768391fd2f8748;hb=c9b4ac5be4daaabc062ab1ee663eba8594750003;hp=f84ebdbc5744287f103c260f4e9ecac6c91f6294;hpb=2119dc23e80d77f1abc789e3d99c34d429e17905;p=rust.git diff --git a/crates/proc_macro_api/src/msg.rs b/crates/proc_macro_api/src/msg.rs index f84ebdbc574..89989557868 100644 --- a/crates/proc_macro_api/src/msg.rs +++ b/crates/proc_macro_api/src/msg.rs @@ -55,10 +55,16 @@ pub enum ErrorCode { } pub trait Message: Serialize + DeserializeOwned { - fn read(inp: &mut impl BufRead) -> io::Result> { - Ok(match read_json(inp)? { + fn read(inp: &mut impl BufRead, buf: &mut String) -> io::Result> { + Ok(match read_json(inp, buf)? { None => None, - Some(text) => Some(serde_json::from_str(&text)?), + Some(text) => { + let mut deserializer = serde_json::Deserializer::from_str(text); + // Note that some proc-macro generate very deep syntax tree + // We have to disable the current limit of serde here + deserializer.disable_recursion_limit(); + Some(Self::deserialize(&mut deserializer)?) + } }) } fn write(self, out: &mut impl Write) -> io::Result<()> { @@ -70,14 +76,29 @@ fn write(self, out: &mut impl Write) -> io::Result<()> { impl Message for Request {} impl Message for Response {} -fn read_json(inp: &mut impl BufRead) -> io::Result> { - let mut buf = String::new(); - inp.read_line(&mut buf)?; - buf.pop(); // Remove traling '\n' - Ok(match buf.len() { - 0 => None, - _ => Some(buf), - }) +fn read_json<'a>( + inp: &mut impl BufRead, + mut buf: &'a mut String, +) -> io::Result> { + loop { + buf.clear(); + + inp.read_line(&mut buf)?; + buf.pop(); // Remove trailing '\n' + + if buf.is_empty() { + return Ok(None); + } + + // Some ill behaved macro try to use stdout for debugging + // We ignore it here + if !buf.starts_with('{') { + log::error!("proc-macro tried to print : {}", buf); + continue; + } + + return Ok(Some(buf)); + } } fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {