From d3d82b0f80f039fca88540529e90f5cb1f3fbd5f Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 11:14:45 -0400 Subject: [PATCH 01/24] Add "type_name" support in emulate_intrinsic() It was suggested by /u/YatoRust on Reddit that I open a PR for this, so I am. --- src/librustc_mir/interpret/intrinsics.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 34e9b4972a16d..0740f5de88d88 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -78,6 +78,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> let id_val = Scalar::from_uint(type_id, dest.layout.size); self.write_scalar(id_val, dest)?; } + + "type_name" => { + let ty = substs.type_at(0); + let ty_name = ty.to_string(); + let value = self.str_to_immediate(&ty_name)?; + self.write_immediate(value, dest)?; + } | "ctpop" | "cttz" | "cttz_nonzero" From 271cf97edd8bc120b457e554d00c07ff0dcf1628 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 14:16:37 -0400 Subject: [PATCH 02/24] Fix whitespace, change "value" to "name_val" "name_val" seem more consistent with the variable naming in the surrounding code. --- src/librustc_mir/interpret/intrinsics.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 0740f5de88d88..bbf177ee1f4be 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -78,13 +78,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> let id_val = Scalar::from_uint(type_id, dest.layout.size); self.write_scalar(id_val, dest)?; } - + "type_name" => { let ty = substs.type_at(0); let ty_name = ty.to_string(); - let value = self.str_to_immediate(&ty_name)?; - self.write_immediate(value, dest)?; - } + let name_val = self.str_to_immediate(&ty_name)?; + self.write_immediate(name_val, dest)?; + } | "ctpop" | "cttz" | "cttz_nonzero" From 67b3fdea4e7d760619a6facb08a8fd15eff636d1 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 15:03:56 -0400 Subject: [PATCH 03/24] Add a test, as suggested. --- src/test/run-pass/ctfe/const-fn-type-name.rs | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/run-pass/ctfe/const-fn-type-name.rs diff --git a/src/test/run-pass/ctfe/const-fn-type-name.rs b/src/test/run-pass/ctfe/const-fn-type-name.rs new file mode 100644 index 0000000000000..418faab309545 --- /dev/null +++ b/src/test/run-pass/ctfe/const-fn-type-name.rs @@ -0,0 +1,38 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(const_fn)] +#![allow(dead_code)] + +const fn type_name_wrapper(_: &T) -> &'static str { + unsafe { std::intrinsics::type_name::() } +} + +struct Struct { + a: TA, + b: TB, + c: TC, +} + +type StructInstantiation = Struct; + +const CONST_STRUCT: StructInstantiation = StructInstantiation { + a: 12, + b: 13.7, + c: false, +}; + +const CONST_STRUCT_NAME: &'static str = type_name_wrapper(&CONST_STRUCT); + +fn main() { + println!("{}", CONST_STRUCT_NAME); + + let non_const_struct = StructInstantiation { + a: 87, + b: 65.99, + c: true, + }; + let non_const_struct_name = type_name_wrapper(&non_const_struct); + + println!("{}", non_const_struct_name); +} From d0cc41d5edaf9208d27c6658948ffdf22e330c91 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 15:46:39 -0400 Subject: [PATCH 04/24] Do an actual check with assert_eq, as suggested. Also, use core::intrinsics::type_name instead of std::intrinsics::type_name, which I don't think makes any real difference but seems like it's probably more logical. --- src/test/run-pass/ctfe/const-fn-type-name.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/ctfe/const-fn-type-name.rs b/src/test/run-pass/ctfe/const-fn-type-name.rs index 418faab309545..2ee6415aa68b7 100644 --- a/src/test/run-pass/ctfe/const-fn-type-name.rs +++ b/src/test/run-pass/ctfe/const-fn-type-name.rs @@ -5,7 +5,7 @@ #![allow(dead_code)] const fn type_name_wrapper(_: &T) -> &'static str { - unsafe { std::intrinsics::type_name::() } + unsafe { core::intrinsics::type_name::() } } struct Struct { @@ -25,14 +25,13 @@ const CONST_STRUCT: StructInstantiation = StructInstantiation { const CONST_STRUCT_NAME: &'static str = type_name_wrapper(&CONST_STRUCT); fn main() { - println!("{}", CONST_STRUCT_NAME); - let non_const_struct = StructInstantiation { a: 87, b: 65.99, c: true, }; + let non_const_struct_name = type_name_wrapper(&non_const_struct); - println!("{}", non_const_struct_name); + assert_eq!(CONST_STRUCT_NAME, non_const_struct_name); } From d6e63a3f8bb354fee95016a579c1a74b9f7f0a53 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 18:32:25 -0400 Subject: [PATCH 05/24] Adapt implementation to "deterministic type_name" Hopefully I didn't miss anything here. --- src/librustc_mir/interpret/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index bbf177ee1f4be..5176560d28032 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -81,7 +81,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> "type_name" => { let ty = substs.type_at(0); - let ty_name = ty.to_string(); + let ty_name = type_name(self.tcx, ty).ty.to_string(); let name_val = self.str_to_immediate(&ty_name)?; self.write_immediate(name_val, dest)?; } From cce1392a3048af37b29a441417c3d5a2f15706c9 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 20:26:48 -0400 Subject: [PATCH 06/24] We need "tcx.tcx", not just "tcx" --- src/librustc_mir/interpret/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 5176560d28032..c8ac0e2656c9a 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -81,7 +81,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> "type_name" => { let ty = substs.type_at(0); - let ty_name = type_name(self.tcx, ty).ty.to_string(); + let ty_name = type_name(self.tcx.tcx, ty).ty.to_string(); let name_val = self.str_to_immediate(&ty_name)?; self.write_immediate(name_val, dest)?; } From 82215e2d02024759e29644cc5d4fd976b2c41963 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 23:10:41 -0400 Subject: [PATCH 07/24] The last commit certainly didn't do what I thought it did. I *think* this actually does, though! --- src/librustc_mir/interpret/intrinsics.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index c8ac0e2656c9a..a4d9268fd1c10 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -80,10 +80,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> } "type_name" => { - let ty = substs.type_at(0); - let ty_name = type_name(self.tcx.tcx, ty).ty.to_string(); - let name_val = self.str_to_immediate(&ty_name)?; - self.write_immediate(name_val, dest)?; + let const_val = type_name(self.tcx.tcx, substs.type_at(0)).val; + if let ConstValue::Slice { + data: slice_val, + start: _, + end: _, + } = const_val + { + // unsafe for from_utf8_unchecked() + unsafe { + let str_val = core::str::from_utf8_unchecked(&slice_val.bytes); + let name_val = self.str_to_immediate(str_val)?; + self.write_immediate(name_val, dest)?; + } + } else { + bug!("type_name() somehow failed to return a ConstValue::Slice"); + } } | "ctpop" | "cttz" From 0f0ad45098e7203451da99f7df4bfdbe22c9edf9 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Fri, 31 May 2019 23:12:58 -0400 Subject: [PATCH 08/24] Can't have ConstValue without ConstValue! --- src/librustc_mir/interpret/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index a4d9268fd1c10..9ea5174e31d29 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -7,7 +7,7 @@ use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ - EvalResult, InterpError, Scalar, + EvalResult, InterpError, Scalar, ConstValue }; use super::{ From 892bc65245f01dafec914a57f3be158d0d2a1b5b Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 15:55:06 -0400 Subject: [PATCH 09/24] Move a brace up to be more consistent. Also make it more clear we're talking about the `librustc_mir`-specific function called `type_name()` in the bug message. --- src/librustc_mir/interpret/intrinsics.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 9ea5174e31d29..9342e3c677553 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -85,8 +85,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> data: slice_val, start: _, end: _, - } = const_val - { + } = const_val { // unsafe for from_utf8_unchecked() unsafe { let str_val = core::str::from_utf8_unchecked(&slice_val.bytes); @@ -94,7 +93,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> self.write_immediate(name_val, dest)?; } } else { - bug!("type_name() somehow failed to return a ConstValue::Slice"); + bug!("type_name::type_name() somehow failed to return a ConstValue::Slice"); } } | "ctpop" From 19a3814478517f255023c5e5527142d4b9327464 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 20:02:15 -0400 Subject: [PATCH 10/24] Add the suggested utility function to type_name.rs --- src/librustc_mir/interpret/intrinsics/type_name.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index 48b02d8e11b60..d54757bc2d475 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -226,3 +226,10 @@ pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx t ty: tcx.mk_static_str(), }) } + +/// Directly returns an `Allocation` containing an absolute path representation of the given type. +pub(super) fn alloc_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation { + let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; + let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); + tcx.intern_const_alloc(alloc) +} From 11da537444ca23ac0df1a2d291f93d827fd43682 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 20:07:29 -0400 Subject: [PATCH 11/24] Use the new function to implement type_name I hope this works like I think it does! --- src/librustc_mir/interpret/intrinsics.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 9342e3c677553..12fed646db467 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -80,21 +80,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> } "type_name" => { - let const_val = type_name(self.tcx.tcx, substs.type_at(0)).val; - if let ConstValue::Slice { - data: slice_val, - start: _, - end: _, - } = const_val { - // unsafe for from_utf8_unchecked() - unsafe { - let str_val = core::str::from_utf8_unchecked(&slice_val.bytes); - let name_val = self.str_to_immediate(str_val)?; - self.write_immediate(name_val, dest)?; - } - } else { - bug!("type_name::type_name() somehow failed to return a ConstValue::Slice"); - } + let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0)); + let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); + let id_ptr = self.memory.tag_static_base_pointer(Pointer::new(name_id, Size::ZERO)); + let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc.bytes.len() as u64, self); + self.write_immediate(name_val, dest)?; } | "ctpop" | "cttz" From 78d5c3849f14ca40f146ec99c56e55f8609b9315 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 20:16:04 -0400 Subject: [PATCH 12/24] Use Immediate and Pointer, but not ConstValue I knew I forgot something. --- src/librustc_mir/interpret/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 12fed646db467..730cfb13ee65a 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -7,7 +7,7 @@ use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ - EvalResult, InterpError, Scalar, ConstValue + EvalResult, InterpError, Scalar, Immediate, Pointer }; use super::{ From fe401016a5296a584000b6be25c24d4b531ca149 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 20:19:37 -0400 Subject: [PATCH 13/24] Actually for real use Immediate and Pointer That is, from the crate where they exist at all! --- src/librustc_mir/interpret/intrinsics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 730cfb13ee65a..743301559c6f1 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -7,11 +7,11 @@ use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ - EvalResult, InterpError, Scalar, Immediate, Pointer + EvalResult, InterpError, Scalar }; use super::{ - Machine, PlaceTy, OpTy, InterpretCx, + Machine, PlaceTy, OpTy, InterpretCx, Immediate, Pointer }; mod type_name; From dfb8dbd923f3d5c8b39b13fab21ba5e347a9dc7f Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 21:10:12 -0400 Subject: [PATCH 14/24] Make Tidy happy I feel like the function name is good, so just knocking it down a line seems like the right way to go. --- src/librustc_mir/interpret/intrinsics/type_name.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index d54757bc2d475..7e900055d36ae 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -228,7 +228,8 @@ pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx t } /// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(super) fn alloc_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation { +pub(super) +fn alloc_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation { let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); tcx.intern_const_alloc(alloc) From 04736f5000e1521b4b5df8fb985775b83e7ba4cd Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 21:13:09 -0400 Subject: [PATCH 15/24] Make Tidy happy --- src/librustc_mir/interpret/intrinsics.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 743301559c6f1..f0389929500a3 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -83,7 +83,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0)); let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); let id_ptr = self.memory.tag_static_base_pointer(Pointer::new(name_id, Size::ZERO)); - let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc.bytes.len() as u64, self); + let alloc_len = alloc.bytes.len() as u64; + let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self); self.write_immediate(name_val, dest)?; } | "ctpop" From c326ef1696a07a7a092c21ced89f1d00faf55c5a Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 21:32:41 -0400 Subject: [PATCH 16/24] Literally just remove a single space --- src/librustc_mir/interpret/intrinsics/type_name.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index 7e900055d36ae..8b487e921e479 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -228,7 +228,7 @@ pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx t } /// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(super) +pub(super) fn alloc_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation { let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); From a58a557e454f43a3a4119d79fa4da1a5ca073a08 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Sun, 2 Jun 2019 21:56:19 -0400 Subject: [PATCH 17/24] Don't need to use Pointer if we do name_id.into() Within `tag_static_base_pointer`, that is. The separate `id_ptr` variable *does* seem to be necessary in general, however. Trying to do `name_id.into()` *directly* inside of `Scalar::Ptr()` in this context fails to compile, as `rustc` wants this super-specific specialization of `Pointer` which it apparently doesn't get from that. --- src/librustc_mir/interpret/intrinsics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index f0389929500a3..c293c4a1d0205 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -11,7 +11,7 @@ use rustc::mir::interpret::{ }; use super::{ - Machine, PlaceTy, OpTy, InterpretCx, Immediate, Pointer + Machine, PlaceTy, OpTy, InterpretCx, Immediate }; mod type_name; @@ -82,7 +82,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> "type_name" => { let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0)); let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); - let id_ptr = self.memory.tag_static_base_pointer(Pointer::new(name_id, Size::ZERO)); + let id_ptr = self.memory.tag_static_base_pointer(name_id.into()); let alloc_len = alloc.bytes.len() as u64; let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self); self.write_immediate(name_val, dest)?; From 04946c701ca60ce7e7d5c10e5ec5972bfdb756a1 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Mon, 3 Jun 2019 09:21:33 -0400 Subject: [PATCH 18/24] Add line break as suggested --- src/librustc_mir/interpret/intrinsics.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index c293c4a1d0205..5860b6b124e1f 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -87,6 +87,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self); self.write_immediate(name_val, dest)?; } + | "ctpop" | "cttz" | "cttz_nonzero" From 9a0c77c1d995bad216956d7ee30a13bfa69764e7 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Mon, 3 Jun 2019 09:37:27 -0400 Subject: [PATCH 19/24] Use alloc_type_name() in type_name() And also fix the formatting. --- src/librustc_mir/interpret/intrinsics/type_name.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index 8b487e921e479..1270b35ebb955 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -213,23 +213,22 @@ impl Write for AbsolutePathPrinter<'_, '_> { /// Produces an absolute path representation of the given type. See also the documentation on /// `std::any::type_name` pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { - let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; - let len = path.len(); - let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes(), ()); - let alloc = tcx.intern_const_alloc(alloc); + let alloc = alloc_type_name(tcx, ty); tcx.mk_const(ty::Const { val: ConstValue::Slice { data: alloc, start: 0, - end: len, + end: alloc.bytes.len(), }, ty: tcx.mk_static_str(), }) } /// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(super) -fn alloc_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation { +pub(super) fn alloc_type_name<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: Ty<'tcx> +) -> &'tcx Allocation { let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); tcx.intern_const_alloc(alloc) From 9b2d6482a0143410c143448ebf62da3f703fde9e Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Mon, 3 Jun 2019 10:09:32 -0400 Subject: [PATCH 20/24] Maybe it will merge this way? --- .../interpret/intrinsics/type_name.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index 1270b35ebb955..d02c8a3b85fb1 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -210,6 +210,16 @@ impl Write for AbsolutePathPrinter<'_, '_> { } } +/// Directly returns an `Allocation` containing an absolute path representation of the given type. +pub(super) fn alloc_type_name<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: Ty<'tcx> +) -> &'tcx Allocation { + let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; + let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); + tcx.intern_const_alloc(alloc) +} + /// Produces an absolute path representation of the given type. See also the documentation on /// `std::any::type_name` pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { @@ -223,13 +233,3 @@ pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx t ty: tcx.mk_static_str(), }) } - -/// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(super) fn alloc_type_name<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx> -) -> &'tcx Allocation { - let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; - let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); - tcx.intern_const_alloc(alloc) -} From 0a9047b2045f827d4af2527e31b7f695b1ff0704 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Mon, 3 Jun 2019 12:04:56 -0400 Subject: [PATCH 21/24] Change this back temporarily --- .../interpret/intrinsics/type_name.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index d02c8a3b85fb1..456fc70fc0d1d 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -210,25 +210,18 @@ impl Write for AbsolutePathPrinter<'_, '_> { } } -/// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(super) fn alloc_type_name<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx> -) -> &'tcx Allocation { - let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; - let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); - tcx.intern_const_alloc(alloc) -} - /// Produces an absolute path representation of the given type. See also the documentation on /// `std::any::type_name` pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { - let alloc = alloc_type_name(tcx, ty); + let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; + let len = path.len(); + let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); + let alloc = tcx.intern_const_alloc(alloc); tcx.mk_const(ty::Const { val: ConstValue::Slice { data: alloc, start: 0, - end: alloc.bytes.len(), + end: len, }, ty: tcx.mk_static_str(), }) From 43ba61a683c028abafe72dba015be7dd9f603fb2 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Mon, 3 Jun 2019 12:09:39 -0400 Subject: [PATCH 22/24] Put my changes back in --- .../interpret/intrinsics/type_name.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index 456fc70fc0d1d..1270b35ebb955 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -213,16 +213,23 @@ impl Write for AbsolutePathPrinter<'_, '_> { /// Produces an absolute path representation of the given type. See also the documentation on /// `std::any::type_name` pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { - let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; - let len = path.len(); - let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); - let alloc = tcx.intern_const_alloc(alloc); + let alloc = alloc_type_name(tcx, ty); tcx.mk_const(ty::Const { val: ConstValue::Slice { data: alloc, start: 0, - end: len, + end: alloc.bytes.len(), }, ty: tcx.mk_static_str(), }) } + +/// Directly returns an `Allocation` containing an absolute path representation of the given type. +pub(super) fn alloc_type_name<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: Ty<'tcx> +) -> &'tcx Allocation { + let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; + let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); + tcx.intern_const_alloc(alloc) +} From 1c8ce6defefbb17b9d105e8a3a5ab47ad7ea5899 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Mon, 3 Jun 2019 14:14:39 -0400 Subject: [PATCH 23/24] Fix duplicated bounds printing in rustdoc (#4) --- src/librustdoc/html/format.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 58e55d570a4f3..1b38d4879050e 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -9,6 +9,7 @@ use std::borrow::Cow; use std::fmt; use rustc::hir::def_id::DefId; +use rustc::util::nodemap::FxHashSet; use rustc_target::spec::abi::Abi; use rustc::hir; @@ -107,8 +108,10 @@ impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> { impl<'a> fmt::Display for GenericBounds<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut bounds_dup = FxHashSet::default(); let &GenericBounds(bounds) = self; - for (i, bound) in bounds.iter().enumerate() { + + for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(b.to_string())).enumerate() { if i > 0 { f.write_str(" + ")?; } @@ -206,16 +209,13 @@ impl<'a> fmt::Display for WhereClause<'a> { clause.push_str(&format!("{}: {}", ty, GenericBounds(bounds))); } } - &clean::WherePredicate::RegionPredicate { ref lifetime, - ref bounds } => { - clause.push_str(&format!("{}: ", lifetime)); - for (i, lifetime) in bounds.iter().enumerate() { - if i > 0 { - clause.push_str(" + "); - } - - clause.push_str(&lifetime.to_string()); - } + &clean::WherePredicate::RegionPredicate { ref lifetime, ref bounds } => { + clause.push_str(&format!("{}: {}", + lifetime, + bounds.iter() + .map(|b| b.to_string()) + .collect::>() + .join(" + "))); } &clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => { if f.alternate() { From 430f4a6f477d23772af15bd84d9413b7b0679719 Mon Sep 17 00:00:00 2001 From: TankhouseAle <51239665+TankhouseAle@users.noreply.github.com> Date: Mon, 3 Jun 2019 14:19:26 -0400 Subject: [PATCH 24/24] Update from master