Skip to content
Merged
Prev Previous commit
Next Next commit
Pretty print function pointer const values.
  • Loading branch information
skinnyBat committed Oct 8, 2019
commit a59eb6d55483e68f790c048efcfc8cdec26db32c
8 changes: 8 additions & 0 deletions src/librustc/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
12 changes: 12 additions & 0 deletions src/librustc/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 3 additions & 11 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/const-generics/fn-const-param-call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ impl<const F: fn() -> u32> Wrapper<{F}> {

fn main() {
assert_eq!(Wrapper::<{function}>::call(), 17);
}
}
2 changes: 1 addition & 1 deletion src/test/ui/const-generics/fn-const-param-infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
4 changes: 2 additions & 2 deletions src/test/ui/const-generics/fn-const-param-infer.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<>`
Expand All @@ -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<>`
Expand Down