From 3d718037dcddd2aa56bd2727dee074ac9b6a6f0e Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 24 Aug 2019 16:25:55 +0100 Subject: [PATCH] Add default serialization for `Ident`s Add tests for -Zast-json and -Zast-json-noexpand, which need this impl. --- src/librustc/ty/query/on_disk_cache.rs | 25 ++++++++++++- src/libsyntax_pos/symbol.rs | 24 +++++++++++- src/test/ui/ast-json/ast-json-ice.rs | 41 +++++++++++++++++++++ src/test/ui/ast-json/ast-json-output.rs | 9 +++++ src/test/ui/ast-json/ast-json-output.stdout | 1 + 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/ast-json/ast-json-ice.rs create mode 100644 src/test/ui/ast-json/ast-json-output.rs create mode 100644 src/test/ui/ast-json/ast-json-output.stdout diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index c21639d0dcaee..674f8944f261a 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -20,7 +20,7 @@ use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use std::mem; -use syntax::ast::NodeId; +use syntax::ast::{Ident, NodeId}; use syntax::source_map::{SourceMap, StableSourceFileId}; use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile}; use syntax_pos::hygiene::{ExpnId, SyntaxContext}; @@ -591,7 +591,8 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { // FIXME(mw): This method does not restore `ExpnData::parent` or // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things // don't seem to be used after HIR lowering, so everything should be fine - // as long as incremental compilation does not kick in before that. + // until we want incremental compilation to serialize Spans that we need + // full hygiene information for. let location = || Span::with_root_ctxt(lo, hi); let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| { let span = location().fresh_expansion_with_transparency(expn_data, transparency); @@ -626,6 +627,13 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { } } +impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { + fn specialized_decode(&mut self) -> Result { + // FIXME: Handle hygiene in incremental + bug!("Trying to decode Ident for incremental"); + } +} + // This impl makes sure that we get a runtime error when we try decode a // DefIndex that is not contained in a DefId. Such a case would be problematic // because we would not know how to transform the DefIndex to the current @@ -833,6 +841,19 @@ where } } +impl<'a, 'tcx, E> SpecializedEncoder for CacheEncoder<'a, 'tcx, E> +where + E: 'a + ty_codec::TyEncoder, +{ + fn specialized_encode(&mut self, _: &Ident) -> Result<(), Self::Error> { + // We don't currently encode enough information to ensure hygiene works + // with incremental, so panic rather than risk incremental bugs. + + // FIXME: Handle hygiene in incremental + bug!("Trying to encode Ident for incremental") + } +} + impl<'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'a, 'tcx, E> where E: 'a + ty_codec::TyEncoder, diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 0b8f16bbc3b99..2d8e97c1800f7 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -849,9 +849,29 @@ impl fmt::Display for Ident { } } -impl UseSpecializedEncodable for Ident {} +impl UseSpecializedEncodable for Ident { + fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_struct("Ident", 2, |s| { + s.emit_struct_field("name", 0, |s| { + self.name.encode(s) + })?; + s.emit_struct_field("span", 1, |s| { + self.span.encode(s) + }) + }) + } +} -impl UseSpecializedDecodable for Ident {} +impl UseSpecializedDecodable for Ident { + fn default_decode(d: &mut D) -> Result { + d.read_struct("Ident", 2, |d| { + Ok(Ident { + name: d.read_struct_field("name", 0, Decodable::decode)?, + span: d.read_struct_field("span", 1, Decodable::decode)?, + }) + }) + } +} /// A symbol is an interned or gensymed string. A gensym is a symbol that is /// never equal to any other symbol. diff --git a/src/test/ui/ast-json/ast-json-ice.rs b/src/test/ui/ast-json/ast-json-ice.rs new file mode 100644 index 0000000000000..e8a622e1b8772 --- /dev/null +++ b/src/test/ui/ast-json/ast-json-ice.rs @@ -0,0 +1,41 @@ +// Test that AST json serialization doesn't ICE (#63728). + +// revisions: expand noexpand + +//[expand] compile-flags: -Zast-json +//[noexpand] compile-flags: -Zast-json-noexpand + +// check-pass +// dont-check-compiler-stdout - don't check for any AST change. + +#![feature(asm)] + +enum V { + A(i32), + B { f: [i64; 3 + 4] } +} + +trait X { + type Output; + fn read(&self) -> Self::Output; + fn write(&mut self, _: Self::Output); +} + +macro_rules! call_println { + ($y:ident) => { println!("{}", $y) } +} + +fn main() { + #[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64"))] + unsafe { asm!(""::::); } + + let x: (i32) = 35; + let y = x as i64<> + 5; + + call_println!(y); + + struct A; +} diff --git a/src/test/ui/ast-json/ast-json-output.rs b/src/test/ui/ast-json/ast-json-output.rs new file mode 100644 index 0000000000000..e444a07460248 --- /dev/null +++ b/src/test/ui/ast-json/ast-json-output.rs @@ -0,0 +1,9 @@ +// Check that AST json printing works. + +// check-pass +// compile-flags: -Zast-json-noexpand +// normalize-stdout-test ":\d+" -> ":0" + +// Only include a single item to reduce how often the test output needs +// updating. +extern crate core; diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout new file mode 100644 index 0000000000000..d23cbe0240ee1 --- /dev/null +++ b/src/test/ui/ast-json/ast-json-output.stdout @@ -0,0 +1 @@ +{"module":{"inner":{"lo":0,"hi":0},"items":[{"ident":{"name":"core","span":{"lo":0,"hi":0}},"attrs":[],"id":0,"node":{"variant":"ExternCrate","fields":[null]},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"span":{"lo":0,"hi":0},"tokens":[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]}]}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}}