Pretty print function pointer const values.

This commit is contained in:
ben 2019-10-02 20:29:16 +13:00
parent 2afd277bc3
commit a59eb6d554
6 changed files with 27 additions and 15 deletions

View File

@ -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 /// 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. /// 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) { pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {

View File

@ -980,6 +980,18 @@ pub trait PrettyPrinter<'tcx>:
return Ok(self); 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)); p!(write("{:?} : ", ct.val), print(ct.ty));
Ok(self) Ok(self)

View File

@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError}; 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::rc::Rc;
use std::iter; use std::iter;
use rustc_target::spec::abi; use rustc_target::spec::abi;
@ -577,16 +577,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
Ok(ConstValue::Scalar(a_val)) Ok(ConstValue::Scalar(a_val))
} else if let ty::FnPtr(_) = a.ty.kind { } else if let ty::FnPtr(_) = a.ty.kind {
let alloc_map = tcx.alloc_map.lock(); let alloc_map = tcx.alloc_map.lock();
let get_fn_instance = |val: Scalar| { let a_instance = alloc_map.unwrap_fn(a_val.to_ptr().unwrap().alloc_id);
let ptr = val.to_ptr().unwrap(); let b_instance = alloc_map.unwrap_fn(b_val.to_ptr().unwrap().alloc_id);
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);
if a_instance == b_instance { if a_instance == b_instance {
Ok(ConstValue::Scalar(a_val)) Ok(ConstValue::Scalar(a_val))
} else { } else {

View File

@ -17,4 +17,4 @@ impl<const F: fn() -> u32> Wrapper<{F}> {
fn main() { fn main() {
assert_eq!(Wrapper::<{function}>::call(), 17); assert_eq!(Wrapper::<{function}>::call(), 17);
} }

View File

@ -23,4 +23,4 @@ fn main() {
let _ = Checked::<{generic::<u16>}>; let _ = Checked::<{generic::<u16>}>;
let _: Checked<{generic::<u16>}> = Checked::<{generic::<u16>}>; let _: Checked<{generic::<u16>}> = Checked::<{generic::<u16>}>;
let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>; //~ mismatched types let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>; //~ mismatched types
} }

View File

@ -10,7 +10,7 @@ error[E0308]: mismatched types
--> $DIR/fn-const-param-infer.rs:16:33 --> $DIR/fn-const-param-infer.rs:16:33
| |
LL | let _: Checked<{not_one}> = Checked::<{not_two}>; 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<>` = note: expected type `Checked<>`
found type `Checked<>` found type `Checked<>`
@ -34,7 +34,7 @@ error[E0308]: mismatched types
--> $DIR/fn-const-param-infer.rs:25:40 --> $DIR/fn-const-param-infer.rs:25:40
| |
LL | let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>; 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<>` = note: expected type `Checked<>`
found type `Checked<>` found type `Checked<>`