about summary refs log tree commit diff
diff options
context:
space:
mode:
authorben <benlewisj@gmail.com>2019-10-02 20:29:16 +1300
committerben <benlewisj@gmail.com>2019-10-09 05:10:00 +1300
commita59eb6d55483e68f790c048efcfc8cdec26db32c (patch)
tree3237289c439a632275c4130a258aff70168173a8
parent2afd277bc3ad53ddb6064b7f2a739583e8b4820a (diff)
downloadrust-a59eb6d55483e68f790c048efcfc8cdec26db32c.tar.gz
rust-a59eb6d55483e68f790c048efcfc8cdec26db32c.zip
Pretty print function pointer const values.
-rw-r--r--src/librustc/mir/interpret/mod.rs8
-rw-r--r--src/librustc/ty/print/pretty.rs12
-rw-r--r--src/librustc/ty/relate.rs14
-rw-r--r--src/test/ui/const-generics/fn-const-param-call.rs2
-rw-r--r--src/test/ui/const-generics/fn-const-param-infer.rs2
-rw-r--r--src/test/ui/const-generics/fn-const-param-infer.stderr4
6 files changed, 27 insertions, 15 deletions
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index e925d7429ff..6c31d54e081 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -470,6 +470,14 @@ impl<'tcx> AllocMap<'tcx> {
         }
     }
 
+    /// Panics if the `AllocId` does not refer to a function
+    pub fn unwrap_fn(&self, id: AllocId) -> Instance<'tcx> {
+        match self.get(id) {
+            Some(GlobalAlloc::Function(instance)) => instance,
+            _ => bug!("expected allocation ID {} to point to a function", id),
+        }
+    }
+
     /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
     /// call this function twice, even with the same `Allocation` will ICE the compiler.
     pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 07c63a92b39..7694d529aa3 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -980,6 +980,18 @@ pub trait PrettyPrinter<'tcx>:
                 return Ok(self);
             }
         }
+
+        if let ty::FnPtr(_) = ct.ty.kind {
+            if let ConstValue::Scalar(Scalar::Ptr(ptr)) = ct.val {
+                let instance = {
+                    let alloc_map = self.tcx().alloc_map.lock();
+                    alloc_map.unwrap_fn(ptr.alloc_id)
+                };
+                p!(print_value_path(instance.def_id(), instance.substs));
+                return Ok(self);
+            }
+        }
+
         p!(write("{:?} : ", ct.val), print(ct.ty));
 
         Ok(self)
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 2d811a83c10..41f34703622 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
 use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
 use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::{ConstValue, get_slice_bytes, Scalar, GlobalAlloc};
+use crate::mir::interpret::{ConstValue, get_slice_bytes};
 use std::rc::Rc;
 use std::iter;
 use rustc_target::spec::abi;
@@ -577,16 +577,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
                 Ok(ConstValue::Scalar(a_val))
             } else if let ty::FnPtr(_) = a.ty.kind {
                 let alloc_map = tcx.alloc_map.lock();
-                let get_fn_instance = |val: Scalar| {
-                    let ptr = val.to_ptr().unwrap();
-                    if let Some(GlobalAlloc::Function(instance)) = alloc_map.get(ptr.alloc_id) {
-                        instance
-                    } else {
-                        bug!("Allocation for FnPtr isn't a function");
-                    }
-                };
-                let a_instance = get_fn_instance(a_val);
-                let b_instance = get_fn_instance(b_val);
+                let a_instance = alloc_map.unwrap_fn(a_val.to_ptr().unwrap().alloc_id);
+                let b_instance = alloc_map.unwrap_fn(b_val.to_ptr().unwrap().alloc_id);
                 if a_instance == b_instance {
                     Ok(ConstValue::Scalar(a_val))
                 } else {
diff --git a/src/test/ui/const-generics/fn-const-param-call.rs b/src/test/ui/const-generics/fn-const-param-call.rs
index 9f64d4bd086..1fb57897e28 100644
--- a/src/test/ui/const-generics/fn-const-param-call.rs
+++ b/src/test/ui/const-generics/fn-const-param-call.rs
@@ -17,4 +17,4 @@ impl<const F: fn() -> u32> Wrapper<{F}> {
 
 fn main() {
     assert_eq!(Wrapper::<{function}>::call(), 17);
-}
\ No newline at end of file
+}
diff --git a/src/test/ui/const-generics/fn-const-param-infer.rs b/src/test/ui/const-generics/fn-const-param-infer.rs
index ac48ccc26e1..65a1523a354 100644
--- a/src/test/ui/const-generics/fn-const-param-infer.rs
+++ b/src/test/ui/const-generics/fn-const-param-infer.rs
@@ -23,4 +23,4 @@ fn main() {
     let _ = Checked::<{generic::<u16>}>;
     let _: Checked<{generic::<u16>}> = Checked::<{generic::<u16>}>;
     let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>; //~ mismatched types
-}
\ No newline at end of file
+}
diff --git a/src/test/ui/const-generics/fn-const-param-infer.stderr b/src/test/ui/const-generics/fn-const-param-infer.stderr
index 4ef55fd22d4..8598cd95b81 100644
--- a/src/test/ui/const-generics/fn-const-param-infer.stderr
+++ b/src/test/ui/const-generics/fn-const-param-infer.stderr
@@ -10,7 +10,7 @@ error[E0308]: mismatched types
   --> $DIR/fn-const-param-infer.rs:16:33
    |
 LL |     let _: Checked<{not_one}> = Checked::<{not_two}>;
-   |                                 ^^^^^^^^^^^^^^^^^^^^ expected `Scalar(AllocId(1).0x0) : fn(usize) -> bool`, found `Scalar(AllocId(10).0x0) : fn(usize) -> bool`
+   |                                 ^^^^^^^^^^^^^^^^^^^^ expected `not_one`, found `not_two`
    |
    = note: expected type `Checked<>`
               found type `Checked<>`
@@ -34,7 +34,7 @@ error[E0308]: mismatched types
   --> $DIR/fn-const-param-infer.rs:25:40
    |
 LL |     let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>;
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Scalar(AllocId(7).0x0) : fn(usize) -> bool`, found `Scalar(AllocId(20).0x0) : fn(usize) -> bool`
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `generic::<u32>`, found `generic::<u16>`
    |
    = note: expected type `Checked<>`
               found type `Checked<>`