From 2715f3e845604b7ce8335b166e341449425efce5 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Mon, 18 Oct 2021 10:41:15 -0400 Subject: [PATCH] tamer: sym: Expose raw SymbolId for static symbols This provides a child `raw` module that exposes a SymbolId representing the inner value of each of the static newtypes. This is needed in situations where the type must match and the type of the static symbol is not important. In particular, when comparing against runtime-allocated symbols in `match` expressions. It is also worth noting that this commit managed to hit a bug in Rustc that was fixed on 10/1/2021. We use nightly, and it doesn't seem that this occurred in stable, from bug reports. - https://github.com/rust-lang/rust/issues/89393 - https://github.com/rust-lang/rust/commit/5ab1245303c26d3ae33b1adaa89fef2b8d9fb9ca - Original issue: https://github.com/rust-lang/rust/issues/72476 The error was: compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs:1191:22: Unexpected type for `Single` constructor: ::NonZero thread 'rustc' panicked at 'Box', compiler/rustc_errors/src/lib.rs:1146:9 This occurred because we were trying to use `SymbolId` as the type, which uses a projected type as its inner value: `SymbolId(Ix::NonZero)`. This was not a problem with the static newtypes because their inner type was simply `SymbolId`, which is not projected. This is one of the risks of using nightly. But, the point is: if you receive this error, upgrade your toolchain. --- tamer/src/sym/prefill.rs | 51 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/tamer/src/sym/prefill.rs b/tamer/src/sym/prefill.rs index be1b9ed5..ce5f55fe 100644 --- a/tamer/src/sym/prefill.rs +++ b/tamer/src/sym/prefill.rs @@ -199,6 +199,12 @@ macro_rules! static_symbol_consts { $str, "\"`." )] + #[doc=""] + #[doc=concat!( + "For the raw (untyped) version, see [`raw::", + stringify!($name), + "`]." + )] pub const $name: static_symbol_ty!($ty) = ::new($i); @@ -239,6 +245,36 @@ macro_rules! static_symbols { )* } + /// Expose each of the [typed static symbols](super) as raw + /// [`SymbolId`] values. + /// + /// These constants are useful for `match` expressions and any other + /// contexts where the type of the symbol must match, + /// and where the static type metadata is unimportant. + /// + /// This is equivalent to calling `as_sym` on the static newtype, + /// or using [`st_as_sym`](super::super::st_as_sym). + pub mod raw { + use super::SymbolId; + + $( + #[doc=concat!( + "Raw (untyped) interned `", + stringify!($ty), + "` string `\"", + $str, + "\"`." + )] + #[doc=""] + #[doc=concat!( + "For the typed version, see [`super::", + stringify!($name), + "`]." + )] + pub const $name: SymbolId<$size> = super::$name.as_sym(); + )* + } + /// Fill a new interner with static symbols. /// /// Panics @@ -317,6 +353,11 @@ static_symbol_newtypes! { /// These contexts are intended for use in generated code where a better /// context cannot be derived. ctx: ContextStaticSymbolId, + + /// This symbol serves only as a marker in the internment pool to + /// delimit symbol ranges; + /// its string value is incidental and should not be relied upon. + mark16: Mark16StaticSymbolId, } /// Static symbols (pre-allocated). @@ -374,7 +415,7 @@ pub mod st { } static_symbols! { - ; + ; // Decimal strings are expected to be at index (n+1). // See `decimal1`. @@ -476,7 +517,7 @@ pub mod st16 { // Marker indicating the end of the static symbols // (this must always be last). - END_STATIC: mark "{{end}}" + END_STATIC: mark16 "{{end}}" } } @@ -525,6 +566,12 @@ mod test { assert_eq!(st::L_FALSE.as_sym(), "false".intern()); } + // Just ensure raw symbols are available and match. + #[test] + fn sanity_check_st_raw() { + assert_eq!(st::L_TRUE.as_sym(), st::raw::L_TRUE); + } + #[test] fn global_sanity_check_st16() { // If we _don't_ prefill, make sure we're not starting at the first