about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir/src/hir.rs3
-rw-r--r--compiler/rustc_hir/src/hir/tests.rs83
2 files changed, 86 insertions, 0 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 6f31f6ba2f4..e8d596d8f71 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -4637,3 +4637,6 @@ fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Deb
     }
     DebugFn(f)
 }
+
+#[cfg(test)]
+mod tests;
diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs
new file mode 100644
index 00000000000..300d4435530
--- /dev/null
+++ b/compiler/rustc_hir/src/hir/tests.rs
@@ -0,0 +1,83 @@
+use rustc_span::def_id::DefIndex;
+
+use super::*;
+
+macro_rules! define_tests {
+    ($($name:ident $kind:ident $variant:ident {$($init:tt)*})*) => {$(
+        #[test]
+        fn $name() {
+            let unambig = $kind::$variant::<'_, ()> { $($init)* };
+            let unambig_to_ambig = unsafe { std::mem::transmute::<_, $kind<'_, AmbigArg>>(unambig) };
+
+            assert!(matches!(&unambig_to_ambig, $kind::$variant { $($init)* }));
+
+            let ambig_to_unambig = unsafe { std::mem::transmute::<_, $kind<'_, ()>>(unambig_to_ambig) };
+
+            assert!(matches!(&ambig_to_unambig, $kind::$variant { $($init)* }));
+        }
+    )*};
+}
+
+define_tests! {
+    cast_never TyKind Never {}
+    cast_tup TyKind Tup { 0: &[Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }] }
+    cast_ptr TyKind Ptr { 0: MutTy { ty: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, mutbl: Mutability::Not }}
+    cast_array TyKind Array {
+        0: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never },
+        1: &ConstArg { hir_id: HirId::INVALID, kind: ConstArgKind::Anon(&AnonConst {
+            hir_id: HirId::INVALID,
+            def_id: LocalDefId { local_def_index: DefIndex::ZERO },
+            body: BodyId { hir_id: HirId::INVALID },
+            span: DUMMY_SP,
+        })}
+    }
+
+    cast_anon ConstArgKind Anon {
+        0: &AnonConst {
+            hir_id: HirId::INVALID,
+            def_id: LocalDefId { local_def_index: DefIndex::ZERO },
+            body: BodyId { hir_id: HirId::INVALID },
+            span: DUMMY_SP,
+        }
+    }
+}
+
+#[test]
+fn trait_object_roundtrips() {
+    trait_object_roundtrips_impl(TraitObjectSyntax::Dyn);
+    trait_object_roundtrips_impl(TraitObjectSyntax::DynStar);
+    trait_object_roundtrips_impl(TraitObjectSyntax::None);
+}
+
+fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) {
+    let unambig = TyKind::TraitObject::<'_, ()>(
+        &[],
+        TaggedRef::new(
+            &const {
+                Lifetime {
+                    hir_id: HirId::INVALID,
+                    ident: Ident::new(sym::name, DUMMY_SP),
+                    res: LifetimeName::Static,
+                }
+            },
+            syntax,
+        ),
+    );
+    let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) };
+
+    match unambig_to_ambig {
+        TyKind::TraitObject(_, tagged_ref) => {
+            assert!(tagged_ref.tag() == syntax)
+        }
+        _ => panic!("`TyKind::TraitObject` did not roundtrip"),
+    };
+
+    let ambig_to_unambig = unsafe { std::mem::transmute::<_, TyKind<'_, ()>>(unambig_to_ambig) };
+
+    match ambig_to_unambig {
+        TyKind::TraitObject(_, tagged_ref) => {
+            assert!(tagged_ref.tag() == syntax)
+        }
+        _ => panic!("`TyKind::TraitObject` did not roundtrip"),
+    };
+}