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
  - 5ab1245303
  - 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: <u32 as sym::symbol::SymbolIndexSize>::NonZero

  thread 'rustc' panicked at 'Box<dyn Any>', 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: SymbolIndexSize>(Ix::NonZero)`.
This was not a problem with the static newtypes because their inner type was
simply `SymbolId<Ix>`, 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.
main
Mike Gerwitz 2021-10-18 10:41:15 -04:00
parent 581b9d4e65
commit 2715f3e845
1 changed files with 49 additions and 2 deletions

View File

@ -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) =
<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<u16>,
/// 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<u16>,
}
/// Static symbols (pre-allocated).
@ -374,7 +415,7 @@ pub mod st {
}
static_symbols! {
<global::ProgSymSize>;
<crate::global::ProgSymSize>;
// 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