]> git.lizzy.rs Git - rust.git/commitdiff
Support signed integers and `char` in v0 mangling
authorvarkor <github@varkor.com>
Sun, 4 Oct 2020 23:28:05 +0000 (00:28 +0100)
committervarkor <github@varkor.com>
Wed, 21 Oct 2020 20:05:38 +0000 (21:05 +0100)
compiler/rustc_symbol_mangling/src/v0.rs
src/test/ui/symbol-names/const-generics.rs [new file with mode: 0644]

index 16d0b86903ea889e9ad054f07fc179fc02249ed8..8c6ed7bd1407197d83a0ee3761104ef0aa3fff14 100644 (file)
@@ -4,6 +4,7 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::mir::interpret::sign_extend;
 use rustc_middle::ty::print::{Print, Printer};
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
@@ -527,17 +528,30 @@ fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self:
         }
         let start = self.out.len();
 
-        match ct.ty.kind() {
-            ty::Uint(_) => {}
-            ty::Bool => {}
+        let mut neg = false;
+        let val = match ct.ty.kind() {
+            ty::Uint(_) | ty::Bool | ty::Char => {
+                ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty)
+            }
+            ty::Int(_) => {
+                let param_env = ty::ParamEnv::reveal_all();
+                ct.try_eval_bits(self.tcx, param_env, ct.ty).and_then(|b| {
+                    let sz = self.tcx.layout_of(param_env.and(ct.ty)).ok()?.size;
+                    let val = sign_extend(b, sz) as i128;
+                    if val < 0 {
+                        neg = true;
+                    }
+                    Some(val.wrapping_abs() as u128)
+                })
+            }
             _ => {
                 bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct);
             }
-        }
+        };
         self = ct.ty.print(self)?;
 
-        if let Some(bits) = ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty) {
-            let _ = write!(self.out, "{:x}_", bits);
+        if let Some(bits) = val {
+            let _ = write!(self.out, "{}{:x}_", if neg { "n" } else { "" }, bits);
         } else {
             // NOTE(eddyb) despite having the path, we need to
             // encode a placeholder, as the path could refer
diff --git a/src/test/ui/symbol-names/const-generics.rs b/src/test/ui/symbol-names/const-generics.rs
new file mode 100644 (file)
index 0000000..ad87000
--- /dev/null
@@ -0,0 +1,87 @@
+// check-pass
+// revisions: legacy v0
+//[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib
+    //[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib
+
+    #![feature(min_const_generics)]
+
+    // `char`
+    pub struct Char<const F: char>;
+
+    impl Char<'A'> {
+        pub fn foo() {}
+    }
+
+    impl<const F: char> Char<F> {
+        pub fn bar() {}
+    }
+
+    // `i8`
+    pub struct I8<const F: i8>;
+
+    impl I8<{std::i8::MIN}> {
+        pub fn foo() {}
+    }
+
+    impl I8<{std::i8::MAX}> {
+        pub fn foo() {}
+    }
+
+    impl<const F: i8> I8<F> {
+        pub fn bar() {}
+    }
+
+    // `i16`
+    pub struct I16<const F: i16>;
+
+    impl I16<{std::i16::MIN}> {
+        pub fn foo() {}
+    }
+
+    impl<const F: i16> I16<F> {
+        pub fn bar() {}
+    }
+
+    // `i32`
+    pub struct I32<const F: i32>;
+
+    impl I32<{std::i32::MIN}> {
+        pub fn foo() {}
+    }
+
+    impl<const F: i32> I32<F> {
+        pub fn bar() {}
+    }
+
+    // `i64`
+    pub struct I64<const F: i64>;
+
+    impl I64<{std::i64::MIN}> {
+        pub fn foo() {}
+    }
+
+    impl<const F: i64> I64<F> {
+        pub fn bar() {}
+    }
+
+    // `i128`
+    pub struct I128<const F: i128>;
+
+    impl I128<{std::i128::MIN}> {
+        pub fn foo() {}
+    }
+
+    impl<const F: i128> I128<F> {
+        pub fn bar() {}
+    }
+
+    // `isize`
+    pub struct ISize<const F: isize>;
+
+    impl ISize<3> {
+        pub fn foo() {}
+    }
+
+    impl<const F: isize> ISize<F> {
+        pub fn bar() {}
+    }