about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2022-02-15 13:58:34 +0100
committerTomasz Miąsko <tomasz.miasko@gmail.com>2022-02-16 00:38:59 +0100
commit92d20c4aaddea9507f8ad37fe37c551219153bbf (patch)
tree12922a3d4bbc15f867ab89b344c994e62ab704da /compiler/rustc_middle/src
parentbfb2856f271fcb647b3cad1b88b29ec97bbab2a3 (diff)
downloadrust-92d20c4aaddea9507f8ad37fe37c551219153bbf.tar.gz
rust-92d20c4aaddea9507f8ad37fe37c551219153bbf.zip
Support pretty printing of invalid constants
Make it possible to pretty print invalid constants by introducing a
fallible variant of `destructure_const` and falling back to debug
formatting when it fails.
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs8
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs16
3 files changed, 25 insertions, 7 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index ec0f5b7d059..4a57f483c70 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -98,4 +98,12 @@ impl<'tcx> TyCtxt<'tcx> {
         let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
         Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
     }
+
+    /// Destructure a constant ADT or array into its variant index and its field values.
+    pub fn destructure_const(
+        self,
+        param_env_and_val: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>,
+    ) -> mir::DestructuredConst<'tcx> {
+        self.try_destructure_const(param_env_and_val).unwrap()
+    }
 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 77eda70bcd1..43cfe6f3b8a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -924,10 +924,12 @@ rustc_queries! {
     }
 
     /// Destructure a constant ADT or array into its variant index and its
-    /// field values.
-    query destructure_const(
+    /// field values or return `None` if constant is invalid.
+    ///
+    /// Use infallible `TyCtxt::destructure_const` when you know that constant is valid.
+    query try_destructure_const(
         key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
-    ) -> mir::DestructuredConst<'tcx> {
+    ) -> Option<mir::DestructuredConst<'tcx>> {
         desc { "destructure constant" }
         remap_env_constness
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 893df1a009c..ae838a46157 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1459,10 +1459,18 @@ pub trait PrettyPrinter<'tcx>:
             // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
             // correct `ty::ParamEnv` to allow printing *all* constant values.
             (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
-                let contents =
-                    self.tcx().destructure_const(ty::ParamEnv::reveal_all().and(
-                        self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty }),
-                    ));
+                let Some(contents) = self.tcx().try_destructure_const(
+                    ty::ParamEnv::reveal_all()
+                        .and(self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty })),
+                ) else {
+                    // Fall back to debug pretty printing for invalid constants.
+                    p!(write("{:?}", ct));
+                    if print_ty {
+                        p!(": ", print(ty));
+                    }
+                    return Ok(self);
+                };
+
                 let fields = contents.fields.iter().copied();
 
                 match *ty.kind() {