Skip to content

nightly rustc -Z ast-json generates malformed json #31025

Closed
@erickt

Description

@erickt

In #30565, @michaelwoerister changed the encoding of syntax::codemap::Span from serializing the value as a single u64 into serializing two sequential u32 values. Unfortunately this violates the serialization protocol, and causes a span like mk_sp(0, 10) to be serialized as 010. Here's the current implementation:

impl Encodable for Span {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        try!(s.emit_u32(self.lo.0));
        s.emit_u32(self.hi.0)
    }
}

impl Decodable for Span {
    fn decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> {
        let lo = BytePos(try! { d.read_u32() });
        let hi = BytePos(try! { d.read_u32() });
        Ok(mk_sp(lo, hi))
    }
}

Semantically speaking these spans should be serialized as a tuple, which would properly delimit the two values, but since that'd add a bunch of tagging overhead to the output, it'd probably be more efficient to just restore the old encoding:

impl Encodable for Span {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        // Encode spans as a single u64 in order to cut down on tagging overhead
        // added by the RBML metadata encoding. The should be solved differently
        // altogether some time (FIXME #21482)
        s.emit_u64( (self.lo.0 as u64) | ((self.hi.0 as u64) << 32) )
    }
}

impl Decodable for Span {
    fn decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> {
        let lo_hi: u64 = try! { d.read_u64() };
        let lo = BytePos(lo_hi as u32);
        let hi = BytePos((lo_hi >> 32) as u32);
        Ok(mk_sp(lo, hi))
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions