about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs25
-rw-r--r--src/libsyntax_pos/symbol.rs24
-rw-r--r--src/test/ui/ast-json/ast-json-ice.rs41
-rw-r--r--src/test/ui/ast-json/ast-json-output.rs9
-rw-r--r--src/test/ui/ast-json/ast-json-output.stdout1
5 files changed, 96 insertions, 4 deletions
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index c21639d0dca..674f8944f26 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<Span> 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<Span> for CacheDecoder<'a, 'tcx> {
     }
 }
 
+impl<'a, 'tcx> SpecializedDecoder<Ident> for CacheDecoder<'a, 'tcx> {
+    fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
+        // 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<Ident> 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 0b8f16bbc3b..2d8e97c1800 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<S: Encoder>(&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: Decoder>(d: &mut D) -> Result<Self, D::Error> {
+        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 00000000000..e8a622e1b87
--- /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 00000000000..e444a074602
--- /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 00000000000..d23cbe0240e
--- /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}}