Skip to content

Commit

Permalink
Support byte string keys in phf_macros (fixes rust-phf#76)
Browse files Browse the repository at this point in the history
Because of rust-lang/rust#31260, a cast must be inserted
explicitly instead of letting rustc implicitly coercing the type.
  • Loading branch information
nox committed Jan 31, 2016
1 parent ae5ee38 commit 652beae
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
26 changes: 25 additions & 1 deletion phf_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ extern crate phf_generator;

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use syntax::ast::{self, TokenTree, Expr, ExprLit, ExprVec};
use syntax::ast::{self, Expr, ExprLit, ExprVec, MutImmutable, TokenTree, TyVec};
use syntax::codemap::{Span, Spanned};
use syntax::ext::base::{DummyResult, ExtCtxt, MacResult};
use syntax::ext::build::AstBuilder;
use syntax::fold::Folder;
use syntax::parse;
use syntax::parse::token::{InternedString, Comma, Eof, FatArrow};
use syntax::print::pprust;
use syntax::ptr::P;
use rustc_plugin::Registry;
use phf_generator::HashState;
use std::env;
Expand Down Expand Up @@ -166,6 +168,7 @@ fn parse_map(cx: &mut ExtCtxt, tts: &[TokenTree]) -> Option<Vec<Entry>> {
bad = true;
Key::Str(InternedString::new(""))
});
let key = adjust_key(cx, key);

if !parser.eat(&FatArrow) {
cx.span_err(parser.span, "expected `=>`");
Expand Down Expand Up @@ -205,6 +208,7 @@ fn parse_set(cx: &mut ExtCtxt, tts: &[TokenTree]) -> Option<Vec<Entry>> {
bad = true;
Key::Str(InternedString::new(""))
});
let key = adjust_key(cx, key);

entries.push(Entry {
key_contents: key_contents,
Expand Down Expand Up @@ -285,6 +289,26 @@ fn parse_key(cx: &mut ExtCtxt, e: &Expr) -> Option<Key> {
}
}

fn adjust_key(cx: &mut ExtCtxt, e: P<Expr>) -> P<Expr> {
let coerce_as_slice = match e.node {
ExprLit(ref lit) => {
match lit.node {
ast::LitByteStr(_) => true,
_ => false,
}
},
_ => false,
};
if coerce_as_slice {
let u8_type = cx.ty_path(cx.path_ident(e.span, cx.ident_of("u8")));
let array_type = cx.ty(e.span, TyVec(u8_type));
let slice_type = cx.ty_rptr(e.span, array_type, None, MutImmutable);
cx.expr_cast(e.span, e, slice_type)
} else {
e
}
}

fn has_duplicates(cx: &mut ExtCtxt, sp: Span, entries: &[Entry]) -> bool {
let mut dups = false;
let mut strings = HashMap::new();
Expand Down
5 changes: 5 additions & 0 deletions phf_macros/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ mod map {
"foo" => 10
);

#[allow(dead_code)]
static BYTE_STRING_KEY: phf::Map<&'static [u8], &'static str> = phf_map!(
b"camembert" => "delicious",
);

#[test]
fn test_two() {
static MAP: phf::Map<&'static str, isize> = phf_map!(
Expand Down

0 comments on commit 652beae

Please sign in to comment.