libregex: Remove all uses of ~str
from libregex
This commit is contained in:
parent
62cf95f674
commit
ec5911b2a6
5 changed files with 50 additions and 45 deletions
|
@ -83,12 +83,12 @@ pub struct Program {
|
||||||
/// If the regular expression requires a literal prefix in order to have a
|
/// If the regular expression requires a literal prefix in order to have a
|
||||||
/// match, that prefix is stored here. (It's used in the VM to implement
|
/// match, that prefix is stored here. (It's used in the VM to implement
|
||||||
/// an optimization.)
|
/// an optimization.)
|
||||||
pub prefix: ~str,
|
pub prefix: StrBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Program {
|
impl Program {
|
||||||
/// Compiles a Regex given its AST.
|
/// Compiles a Regex given its AST.
|
||||||
pub fn new(ast: parse::Ast) -> (Program, Vec<Option<~str>>) {
|
pub fn new(ast: parse::Ast) -> (Program, Vec<Option<StrBuf>>) {
|
||||||
let mut c = Compiler {
|
let mut c = Compiler {
|
||||||
insts: Vec::with_capacity(100),
|
insts: Vec::with_capacity(100),
|
||||||
names: Vec::with_capacity(10),
|
names: Vec::with_capacity(10),
|
||||||
|
@ -113,7 +113,7 @@ impl Program {
|
||||||
let Compiler { insts, names } = c;
|
let Compiler { insts, names } = c;
|
||||||
let prog = Program {
|
let prog = Program {
|
||||||
insts: insts,
|
insts: insts,
|
||||||
prefix: pre.into_owned(),
|
prefix: pre,
|
||||||
};
|
};
|
||||||
(prog, names)
|
(prog, names)
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ impl Program {
|
||||||
|
|
||||||
struct Compiler<'r> {
|
struct Compiler<'r> {
|
||||||
insts: Vec<Inst>,
|
insts: Vec<Inst>,
|
||||||
names: Vec<Option<~str>>,
|
names: Vec<Option<StrBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The compiler implemented here is extremely simple. Most of the complexity
|
// The compiler implemented here is extremely simple. Most of the complexity
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub struct Error {
|
||||||
/// The *approximate* character index of where the error occurred.
|
/// The *approximate* character index of where the error occurred.
|
||||||
pub pos: uint,
|
pub pos: uint,
|
||||||
/// A message describing the error.
|
/// A message describing the error.
|
||||||
pub msg: ~str,
|
pub msg: StrBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for Error {
|
impl fmt::Show for Error {
|
||||||
|
@ -59,7 +59,7 @@ pub enum Ast {
|
||||||
Begin(Flags),
|
Begin(Flags),
|
||||||
End(Flags),
|
End(Flags),
|
||||||
WordBoundary(Flags),
|
WordBoundary(Flags),
|
||||||
Capture(uint, Option<~str>, Box<Ast>),
|
Capture(uint, Option<StrBuf>, Box<Ast>),
|
||||||
// Represent concatenation as a flat vector to avoid blowing the
|
// Represent concatenation as a flat vector to avoid blowing the
|
||||||
// stack in the compiler.
|
// stack in the compiler.
|
||||||
Cat(Vec<Ast>),
|
Cat(Vec<Ast>),
|
||||||
|
@ -104,7 +104,7 @@ impl Greed {
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
enum BuildAst {
|
enum BuildAst {
|
||||||
Ast(Ast),
|
Ast(Ast),
|
||||||
Paren(Flags, uint, ~str), // '('
|
Paren(Flags, uint, StrBuf), // '('
|
||||||
Bar, // '|'
|
Bar, // '|'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ impl BuildAst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn capture_name(&self) -> Option<~str> {
|
fn capture_name(&self) -> Option<StrBuf> {
|
||||||
match *self {
|
match *self {
|
||||||
Paren(_, 0, _) => None,
|
Paren(_, 0, _) => None,
|
||||||
Paren(_, _, ref name) => {
|
Paren(_, _, ref name) => {
|
||||||
|
@ -185,7 +185,7 @@ struct Parser<'a> {
|
||||||
// opening a capture group).
|
// opening a capture group).
|
||||||
caps: uint,
|
caps: uint,
|
||||||
// A set of all capture group names used only to detect duplicates.
|
// A set of all capture group names used only to detect duplicates.
|
||||||
names: Vec<~str>,
|
names: Vec<StrBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(s: &str) -> Result<Ast, Error> {
|
pub fn parse(s: &str) -> Result<Ast, Error> {
|
||||||
|
@ -222,7 +222,7 @@ impl<'a> Parser<'a> {
|
||||||
self.caps += 1;
|
self.caps += 1;
|
||||||
self.stack.push(Paren(self.flags,
|
self.stack.push(Paren(self.flags,
|
||||||
self.caps,
|
self.caps,
|
||||||
"".to_owned()))
|
"".to_strbuf()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
')' => {
|
')' => {
|
||||||
|
@ -470,7 +470,7 @@ impl<'a> Parser<'a> {
|
||||||
FLAG_EMPTY
|
FLAG_EMPTY
|
||||||
};
|
};
|
||||||
let name = self.slice(name_start, closer - 1);
|
let name = self.slice(name_start, closer - 1);
|
||||||
match find_class(ASCII_CLASSES, name) {
|
match find_class(ASCII_CLASSES, name.as_slice()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(ranges) => {
|
Some(ranges) => {
|
||||||
self.chari = closer;
|
self.chari = closer;
|
||||||
|
@ -611,7 +611,7 @@ impl<'a> Parser<'a> {
|
||||||
// character).
|
// character).
|
||||||
fn parse_unicode_name(&mut self) -> Result<Ast, Error> {
|
fn parse_unicode_name(&mut self) -> Result<Ast, Error> {
|
||||||
let negated = if self.cur() == 'P' { FLAG_NEGATED } else { FLAG_EMPTY };
|
let negated = if self.cur() == 'P' { FLAG_NEGATED } else { FLAG_EMPTY };
|
||||||
let mut name: ~str;
|
let mut name: StrBuf;
|
||||||
if self.peek_is(1, '{') {
|
if self.peek_is(1, '{') {
|
||||||
try!(self.expect('{'))
|
try!(self.expect('{'))
|
||||||
let closer =
|
let closer =
|
||||||
|
@ -633,7 +633,7 @@ impl<'a> Parser<'a> {
|
||||||
name = self.slice(self.chari + 1, self.chari + 2);
|
name = self.slice(self.chari + 1, self.chari + 2);
|
||||||
self.chari += 1;
|
self.chari += 1;
|
||||||
}
|
}
|
||||||
match find_class(UNICODE_CLASSES, name) {
|
match find_class(UNICODE_CLASSES, name.as_slice()) {
|
||||||
None => return self.err(format!(
|
None => return self.err(format!(
|
||||||
"Could not find Unicode class '{}'", name)),
|
"Could not find Unicode class '{}'", name)),
|
||||||
Some(ranges) => {
|
Some(ranges) => {
|
||||||
|
@ -657,7 +657,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let s = self.slice(start, end);
|
let s = self.slice(start, end);
|
||||||
match num::from_str_radix::<u32>(s, 8) {
|
match num::from_str_radix::<u32>(s.as_slice(), 8) {
|
||||||
Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
|
Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
|
||||||
None => self.err(format!(
|
None => self.err(format!(
|
||||||
"Could not parse '{}' as octal number.", s)),
|
"Could not parse '{}' as octal number.", s)),
|
||||||
|
@ -679,7 +679,7 @@ impl<'a> Parser<'a> {
|
||||||
Some(i) => i,
|
Some(i) => i,
|
||||||
};
|
};
|
||||||
self.chari = closer;
|
self.chari = closer;
|
||||||
self.parse_hex_digits(self.slice(start, closer))
|
self.parse_hex_digits(self.slice(start, closer).as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a two-digit hex number.
|
// Parses a two-digit hex number.
|
||||||
|
@ -690,7 +690,7 @@ impl<'a> Parser<'a> {
|
||||||
let (start, end) = (self.chari, self.chari + 2);
|
let (start, end) = (self.chari, self.chari + 2);
|
||||||
let bad = self.slice(start - 2, self.chars.len());
|
let bad = self.slice(start - 2, self.chars.len());
|
||||||
try!(self.noteof(format!("Invalid hex escape sequence '{}'", bad)))
|
try!(self.noteof(format!("Invalid hex escape sequence '{}'", bad)))
|
||||||
self.parse_hex_digits(self.slice(start, end))
|
self.parse_hex_digits(self.slice(start, end).as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses `s` as a hexadecimal number.
|
// Parses `s` as a hexadecimal number.
|
||||||
|
@ -717,7 +717,7 @@ impl<'a> Parser<'a> {
|
||||||
return self.err("Capture names must have at least 1 character.")
|
return self.err("Capture names must have at least 1 character.")
|
||||||
}
|
}
|
||||||
let name = self.slice(self.chari, closer);
|
let name = self.slice(self.chari, closer);
|
||||||
if !name.chars().all(is_valid_cap) {
|
if !name.as_slice().chars().all(is_valid_cap) {
|
||||||
return self.err(
|
return self.err(
|
||||||
"Capture names can only have underscores, letters and digits.")
|
"Capture names can only have underscores, letters and digits.")
|
||||||
}
|
}
|
||||||
|
@ -771,7 +771,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
if self.cur() == ':' {
|
if self.cur() == ':' {
|
||||||
// Save the old flags with the opening paren.
|
// Save the old flags with the opening paren.
|
||||||
self.stack.push(Paren(self.flags, 0, "".to_owned()));
|
self.stack.push(Paren(self.flags, 0, "".to_strbuf()));
|
||||||
}
|
}
|
||||||
self.flags = flags;
|
self.flags = flags;
|
||||||
return Ok(())
|
return Ok(())
|
||||||
|
@ -892,7 +892,7 @@ impl<'a> Parser<'a> {
|
||||||
fn err<T>(&self, msg: &str) -> Result<T, Error> {
|
fn err<T>(&self, msg: &str) -> Result<T, Error> {
|
||||||
Err(Error {
|
Err(Error {
|
||||||
pos: self.chari,
|
pos: self.chari,
|
||||||
msg: msg.to_owned(),
|
msg: msg.to_strbuf(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,8 +911,8 @@ impl<'a> Parser<'a> {
|
||||||
*self.chars.get(self.chari)
|
*self.chars.get(self.chari)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slice(&self, start: uint, end: uint) -> ~str {
|
fn slice(&self, start: uint, end: uint) -> StrBuf {
|
||||||
str::from_chars(self.chars.as_slice().slice(start, end))
|
str::from_chars(self.chars.as_slice().slice(start, end)).to_strbuf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use vm::{CaptureLocs, MatchKind, Exists, Location, Submatches};
|
||||||
|
|
||||||
/// Escapes all regular expression meta characters in `text` so that it may be
|
/// Escapes all regular expression meta characters in `text` so that it may be
|
||||||
/// safely used in a regular expression as a literal string.
|
/// safely used in a regular expression as a literal string.
|
||||||
pub fn quote(text: &str) -> ~str {
|
pub fn quote(text: &str) -> StrBuf {
|
||||||
let mut quoted = StrBuf::with_capacity(text.len());
|
let mut quoted = StrBuf::with_capacity(text.len());
|
||||||
for c in text.chars() {
|
for c in text.chars() {
|
||||||
if parse::is_punct(c) {
|
if parse::is_punct(c) {
|
||||||
|
@ -28,7 +28,7 @@ pub fn quote(text: &str) -> ~str {
|
||||||
}
|
}
|
||||||
quoted.push_char(c);
|
quoted.push_char(c);
|
||||||
}
|
}
|
||||||
quoted.into_owned()
|
quoted
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests if the given regular expression matches somewhere in the text given.
|
/// Tests if the given regular expression matches somewhere in the text given.
|
||||||
|
@ -107,9 +107,9 @@ pub struct Regex {
|
||||||
/// See the comments for the `program` module in `lib.rs` for a more
|
/// See the comments for the `program` module in `lib.rs` for a more
|
||||||
/// detailed explanation for what `regex!` requires.
|
/// detailed explanation for what `regex!` requires.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub original: ~str,
|
pub original: StrBuf,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub names: Vec<Option<~str>>,
|
pub names: Vec<Option<StrBuf>>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub p: MaybeNative,
|
pub p: MaybeNative,
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,10 @@ impl Regex {
|
||||||
pub fn new(re: &str) -> Result<Regex, parse::Error> {
|
pub fn new(re: &str) -> Result<Regex, parse::Error> {
|
||||||
let ast = try!(parse::parse(re));
|
let ast = try!(parse::parse(re));
|
||||||
let (prog, names) = Program::new(ast);
|
let (prog, names) = Program::new(ast);
|
||||||
Ok(Regex { original: re.to_owned(), names: names, p: Dynamic(prog) })
|
Ok(Regex {
|
||||||
|
original: re.to_strbuf(),
|
||||||
|
names: names, p: Dynamic(prog),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if and only if the regex matches the string given.
|
/// Returns true if and only if the regex matches the string given.
|
||||||
|
@ -404,7 +407,7 @@ impl Regex {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// But anything satisfying the `Replacer` trait will work. For example,
|
/// But anything satisfying the `Replacer` trait will work. For example,
|
||||||
/// a closure of type `|&Captures| -> ~str` provides direct access to the
|
/// a closure of type `|&Captures| -> StrBuf` provides direct access to the
|
||||||
/// captures corresponding to a match. This allows one to access
|
/// captures corresponding to a match. This allows one to access
|
||||||
/// submatches easily:
|
/// submatches easily:
|
||||||
///
|
///
|
||||||
|
@ -414,7 +417,7 @@ impl Regex {
|
||||||
/// # use regex::Captures; fn main() {
|
/// # use regex::Captures; fn main() {
|
||||||
/// let re = regex!(r"([^,\s]+),\s+(\S+)");
|
/// let re = regex!(r"([^,\s]+),\s+(\S+)");
|
||||||
/// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
|
/// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
|
||||||
/// format!("{} {}", caps.at(2), caps.at(1))
|
/// format_strbuf!("{} {}", caps.at(2), caps.at(1))
|
||||||
/// });
|
/// });
|
||||||
/// assert_eq!(result.as_slice(), "Bruce Springsteen");
|
/// assert_eq!(result.as_slice(), "Bruce Springsteen");
|
||||||
/// # }
|
/// # }
|
||||||
|
@ -526,7 +529,7 @@ impl<'t> Replacer for &'t str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Replacer for |&Captures|: 'a -> ~str {
|
impl<'a> Replacer for |&Captures|: 'a -> StrBuf {
|
||||||
fn reg_replace<'r>(&'r mut self, caps: &Captures) -> MaybeOwned<'r> {
|
fn reg_replace<'r>(&'r mut self, caps: &Captures) -> MaybeOwned<'r> {
|
||||||
Owned((*self)(caps).into_owned())
|
Owned((*self)(caps).into_owned())
|
||||||
}
|
}
|
||||||
|
@ -605,7 +608,7 @@ impl<'r, 't> Iterator<&'t str> for RegexSplitsN<'r, 't> {
|
||||||
pub struct Captures<'t> {
|
pub struct Captures<'t> {
|
||||||
text: &'t str,
|
text: &'t str,
|
||||||
locs: CaptureLocs,
|
locs: CaptureLocs,
|
||||||
named: Option<HashMap<~str, uint>>,
|
named: Option<HashMap<StrBuf, uint>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> Captures<'t> {
|
impl<'t> Captures<'t> {
|
||||||
|
@ -624,7 +627,7 @@ impl<'t> Captures<'t> {
|
||||||
match name {
|
match name {
|
||||||
&None => {},
|
&None => {},
|
||||||
&Some(ref name) => {
|
&Some(ref name) => {
|
||||||
named.insert(name.to_owned(), i);
|
named.insert(name.to_strbuf(), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -707,12 +710,14 @@ impl<'t> Captures<'t> {
|
||||||
// How evil can you get?
|
// How evil can you get?
|
||||||
// FIXME: Don't use regexes for this. It's completely unnecessary.
|
// FIXME: Don't use regexes for this. It's completely unnecessary.
|
||||||
let re = Regex::new(r"(^|[^$]|\b)\$(\w+)").unwrap();
|
let re = Regex::new(r"(^|[^$]|\b)\$(\w+)").unwrap();
|
||||||
let text = re.replace_all(text, |refs: &Captures| -> ~str {
|
let text = re.replace_all(text, |refs: &Captures| -> StrBuf {
|
||||||
let (pre, name) = (refs.at(1), refs.at(2));
|
let (pre, name) = (refs.at(1), refs.at(2));
|
||||||
pre + match from_str::<uint>(name) {
|
format_strbuf!("{}{}",
|
||||||
None => self.name(name).to_owned(),
|
pre,
|
||||||
Some(i) => self.at(i).to_owned(),
|
match from_str::<uint>(name.as_slice()) {
|
||||||
}
|
None => self.name(name).to_strbuf(),
|
||||||
|
Some(i) => self.at(i).to_strbuf(),
|
||||||
|
})
|
||||||
});
|
});
|
||||||
let re = Regex::new(r"\$\$").unwrap();
|
let re = Regex::new(r"\$\$").unwrap();
|
||||||
re.replace_all(text.as_slice(), NoExpand("$"))
|
re.replace_all(text.as_slice(), NoExpand("$"))
|
||||||
|
|
|
@ -140,7 +140,7 @@ macro_rules! throughput(
|
||||||
fn $name(b: &mut Bencher) {
|
fn $name(b: &mut Bencher) {
|
||||||
let text = gen_text($size);
|
let text = gen_text($size);
|
||||||
b.bytes = $size;
|
b.bytes = $size;
|
||||||
b.iter(|| if $regex.is_match(text) { fail!("match") });
|
b.iter(|| if $regex.is_match(text.as_slice()) { fail!("match") });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
)
|
)
|
||||||
|
@ -151,7 +151,7 @@ fn medium() -> Regex { regex!("[XYZ]ABCDEFGHIJKLMNOPQRSTUVWXYZ$") }
|
||||||
fn hard() -> Regex { regex!("[ -~]*ABCDEFGHIJKLMNOPQRSTUVWXYZ$") }
|
fn hard() -> Regex { regex!("[ -~]*ABCDEFGHIJKLMNOPQRSTUVWXYZ$") }
|
||||||
|
|
||||||
#[allow(deprecated_owned_vector)]
|
#[allow(deprecated_owned_vector)]
|
||||||
fn gen_text(n: uint) -> ~str {
|
fn gen_text(n: uint) -> StrBuf {
|
||||||
let mut rng = task_rng();
|
let mut rng = task_rng();
|
||||||
let mut bytes = rng.gen_ascii_str(n).into_bytes();
|
let mut bytes = rng.gen_ascii_str(n).into_bytes();
|
||||||
for (i, b) in bytes.mut_iter().enumerate() {
|
for (i, b) in bytes.mut_iter().enumerate() {
|
||||||
|
@ -159,7 +159,7 @@ fn gen_text(n: uint) -> ~str {
|
||||||
*b = '\n' as u8
|
*b = '\n' as u8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str::from_utf8(bytes).unwrap().to_owned()
|
str::from_utf8(bytes).unwrap().to_strbuf()
|
||||||
}
|
}
|
||||||
|
|
||||||
throughput!(easy0_32, easy0(), 32)
|
throughput!(easy0_32, easy0(), 32)
|
||||||
|
|
|
@ -105,8 +105,8 @@ struct NfaGen<'a> {
|
||||||
cx: &'a ExtCtxt<'a>,
|
cx: &'a ExtCtxt<'a>,
|
||||||
sp: codemap::Span,
|
sp: codemap::Span,
|
||||||
prog: Program,
|
prog: Program,
|
||||||
names: Vec<Option<~str>>,
|
names: Vec<Option<StrBuf>>,
|
||||||
original: ~str,
|
original: StrBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> NfaGen<'a> {
|
impl<'a> NfaGen<'a> {
|
||||||
|
@ -119,7 +119,7 @@ impl<'a> NfaGen<'a> {
|
||||||
|cx, name| match *name {
|
|cx, name| match *name {
|
||||||
Some(ref name) => {
|
Some(ref name) => {
|
||||||
let name = name.as_slice();
|
let name = name.as_slice();
|
||||||
quote_expr!(cx, Some($name.to_owned()))
|
quote_expr!(cx, Some($name.to_strbuf()))
|
||||||
}
|
}
|
||||||
None => cx.expr_none(self.sp),
|
None => cx.expr_none(self.sp),
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
|
||||||
}
|
}
|
||||||
|
|
||||||
::regex::Regex {
|
::regex::Regex {
|
||||||
original: $regex.to_owned(),
|
original: $regex.to_strbuf(),
|
||||||
names: vec!$cap_names,
|
names: vec!$cap_names,
|
||||||
p: ::regex::native::Native(exec),
|
p: ::regex::native::Native(exec),
|
||||||
}
|
}
|
||||||
|
@ -601,14 +601,14 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
|
||||||
|
|
||||||
/// Looks for a single string literal and returns it.
|
/// Looks for a single string literal and returns it.
|
||||||
/// Otherwise, logs an error with cx.span_err and returns None.
|
/// Otherwise, logs an error with cx.span_err and returns None.
|
||||||
fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<~str> {
|
fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<StrBuf> {
|
||||||
let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
|
let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
|
||||||
Vec::from_slice(tts));
|
Vec::from_slice(tts));
|
||||||
let entry = cx.expand_expr(parser.parse_expr());
|
let entry = cx.expand_expr(parser.parse_expr());
|
||||||
let regex = match entry.node {
|
let regex = match entry.node {
|
||||||
ast::ExprLit(lit) => {
|
ast::ExprLit(lit) => {
|
||||||
match lit.node {
|
match lit.node {
|
||||||
ast::LitStr(ref s, _) => s.to_str(),
|
ast::LitStr(ref s, _) => s.to_str().to_strbuf(),
|
||||||
_ => {
|
_ => {
|
||||||
cx.span_err(entry.span, format!(
|
cx.span_err(entry.span, format!(
|
||||||
"expected string literal but got `{}`",
|
"expected string literal but got `{}`",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue