Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d7eb0ed

Browse files
committedApr 17, 2023
syntax: add 'std' feature
In effect, this adds support for no_std by depending on only core and alloc. There is still currently some benefit to enabling std support, namely, getting the 'std::error::Error' trait impls for the various error types. (Although, it seems like the 'Error' trait is going to get moved to 'core' finally.) Otherwise, the only 'std' things we use are in tests for tweaking stack sizes. This is the first step in an effort to make 'regex' itself work without depending on 'std'. 'regex' itself will be more precarious since it uses things like HashMap and Mutex that we'll need to find a way around. Getting around HashMap is easy (just use BTreeMap), but figuring out how to synchronize the threadpool will be interesting. Ref #476, Ref #477
1 parent 5a5e2b3 commit d7eb0ed

18 files changed

+245
-179
lines changed
 

Diff for: ‎Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ finite automata and guarantees linear time matching on all inputs.
1414
categories = ["text-processing"]
1515
autotests = false
1616
exclude = ["/scripts/*", "/.github/*"]
17-
edition = "2018"
17+
edition = "2021"
1818
rust-version = "1.60.0"
1919

2020
[workspace]

Diff for: ‎regex-syntax/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ rust-version = "1.60.0"
1414
# Features are documented in the "Crate features" section of the crate docs:
1515
# https://docs.rs/regex-syntax/*/#crate-features
1616
[features]
17-
default = ["unicode"]
17+
default = ["std", "unicode"]
18+
std = []
1819

1920
unicode = [
2021
"unicode-age",

Diff for: ‎regex-syntax/src/ast/mod.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
Defines an abstract syntax for regular expressions.
33
*/
44

5-
use std::cmp::Ordering;
6-
use std::fmt;
5+
use core::cmp::Ordering;
6+
7+
use alloc::{boxed::Box, string::String, vec, vec::Vec};
78

89
pub use crate::ast::visitor::{visit, Visitor};
910

@@ -174,23 +175,24 @@ pub enum ErrorKind {
174175
UnsupportedLookAround,
175176
}
176177

178+
#[cfg(feature = "std")]
177179
impl std::error::Error for Error {}
178180

179-
impl fmt::Display for Error {
180-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181+
impl core::fmt::Display for Error {
182+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
181183
crate::error::Formatter::from(self).fmt(f)
182184
}
183185
}
184186

185-
impl fmt::Display for ErrorKind {
186-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187+
impl core::fmt::Display for ErrorKind {
188+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
187189
use self::ErrorKind::*;
188190
match *self {
189191
CaptureLimitExceeded => write!(
190192
f,
191193
"exceeded the maximum number of \
192194
capturing groups ({})",
193-
::std::u32::MAX
195+
u32::MAX
194196
),
195197
ClassEscapeInvalid => {
196198
write!(f, "invalid escape sequence found in character class")
@@ -283,8 +285,8 @@ pub struct Span {
283285
pub end: Position,
284286
}
285287

286-
impl fmt::Debug for Span {
287-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
288+
impl core::fmt::Debug for Span {
289+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
288290
write!(f, "Span({:?}, {:?})", self.start, self.end)
289291
}
290292
}
@@ -316,8 +318,8 @@ pub struct Position {
316318
pub column: usize,
317319
}
318320

319-
impl fmt::Debug for Position {
320-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
321+
impl core::fmt::Debug for Position {
322+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
321323
write!(
322324
f,
323325
"Position(o: {:?}, l: {:?}, c: {:?})",
@@ -497,8 +499,8 @@ impl Ast {
497499
///
498500
/// This implementation uses constant stack space and heap space proportional
499501
/// to the size of the `Ast`.
500-
impl fmt::Display for Ast {
501-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
502+
impl core::fmt::Display for Ast {
503+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
502504
use crate::ast::print::Printer;
503505
Printer::new().print(self, f)
504506
}
@@ -1315,7 +1317,7 @@ pub enum Flag {
13151317
/// space but heap space proportional to the depth of the `Ast`.
13161318
impl Drop for Ast {
13171319
fn drop(&mut self) {
1318-
use std::mem;
1320+
use core::mem;
13191321

13201322
match *self {
13211323
Ast::Empty(_)
@@ -1365,7 +1367,7 @@ impl Drop for Ast {
13651367
/// stack space but heap space proportional to the depth of the `ClassSet`.
13661368
impl Drop for ClassSet {
13671369
fn drop(&mut self) {
1368-
use std::mem;
1370+
use core::mem;
13691371

13701372
match *self {
13711373
ClassSet::Item(ref item) => match *item {

Diff for: ‎regex-syntax/src/ast/parse.rs

+30-27
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,26 @@
22
This module provides a regular expression parser.
33
*/
44

5-
use std::borrow::Borrow;
6-
use std::cell::{Cell, RefCell};
7-
use std::mem;
8-
use std::result;
9-
10-
use crate::ast::{self, Ast, Position, Span};
11-
use crate::either::Either;
12-
13-
use crate::is_meta_character;
14-
15-
type Result<T> = result::Result<T, ast::Error>;
5+
use core::{
6+
borrow::Borrow,
7+
cell::{Cell, RefCell},
8+
mem,
9+
};
10+
11+
use alloc::{
12+
boxed::Box,
13+
string::{String, ToString},
14+
vec,
15+
vec::Vec,
16+
};
17+
18+
use crate::{
19+
ast::{self, Ast, Position, Span},
20+
either::Either,
21+
is_meta_character,
22+
};
23+
24+
type Result<T> = core::result::Result<T, ast::Error>;
1625

1726
/// A primitive is an expression with no sub-expressions. This includes
1827
/// literals, assertions and non-set character classes. This representation
@@ -1533,9 +1542,6 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
15331542
/// Assuming the preconditions are met, this routine can never fail.
15341543
#[inline(never)]
15351544
fn parse_octal(&self) -> ast::Literal {
1536-
use std::char;
1537-
use std::u32;
1538-
15391545
assert!(self.parser().octal);
15401546
assert!('0' <= self.char() && self.char() <= '7');
15411547
let start = self.pos();
@@ -1600,9 +1606,6 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
16001606
&self,
16011607
kind: ast::HexLiteralKind,
16021608
) -> Result<ast::Literal> {
1603-
use std::char;
1604-
use std::u32;
1605-
16061609
let mut scratch = self.parser().scratch.borrow_mut();
16071610
scratch.clear();
16081611

@@ -1646,9 +1649,6 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
16461649
&self,
16471650
kind: ast::HexLiteralKind,
16481651
) -> Result<ast::Literal> {
1649-
use std::char;
1650-
use std::u32;
1651-
16521652
let mut scratch = self.parser().scratch.borrow_mut();
16531653
scratch.clear();
16541654

@@ -2146,7 +2146,7 @@ impl<'p, 's, P: Borrow<Parser>> NestLimiter<'p, 's, P> {
21462146
let new = self.depth.checked_add(1).ok_or_else(|| {
21472147
self.p.error(
21482148
span.clone(),
2149-
ast::ErrorKind::NestLimitExceeded(::std::u32::MAX),
2149+
ast::ErrorKind::NestLimitExceeded(u32::MAX),
21502150
)
21512151
})?;
21522152
let limit = self.p.parser().nest_limit;
@@ -2297,11 +2297,14 @@ fn specialize_err<T>(
22972297

22982298
#[cfg(test)]
22992299
mod tests {
2300-
use std::ops::Range;
2300+
use core::ops::Range;
2301+
2302+
use alloc::format;
23012303

2302-
use super::{Parser, ParserBuilder, ParserI, Primitive};
23032304
use crate::ast::{self, Ast, Position, Span};
23042305

2306+
use super::*;
2307+
23052308
// Our own assert_eq, which has slightly better formatting (but honestly
23062309
// still kind of crappy).
23072310
macro_rules! assert_eq {
@@ -4272,7 +4275,7 @@ bar
42724275
Ok(Primitive::Literal(ast::Literal {
42734276
span: span(0..pat.len()),
42744277
kind: ast::LiteralKind::Octal,
4275-
c: ::std::char::from_u32(i).unwrap(),
4278+
c: char::from_u32(i).unwrap(),
42764279
}))
42774280
);
42784281
}
@@ -4347,7 +4350,7 @@ bar
43474350
Ok(Primitive::Literal(ast::Literal {
43484351
span: span(0..pat.len()),
43494352
kind: ast::LiteralKind::HexFixed(ast::HexLiteralKind::X),
4350-
c: ::std::char::from_u32(i).unwrap(),
4353+
c: char::from_u32(i).unwrap(),
43514354
}))
43524355
);
43534356
}
@@ -4378,7 +4381,7 @@ bar
43784381
#[test]
43794382
fn parse_hex_four() {
43804383
for i in 0..65536 {
4381-
let c = match ::std::char::from_u32(i) {
4384+
let c = match char::from_u32(i) {
43824385
None => continue,
43834386
Some(c) => c,
43844387
};
@@ -4442,7 +4445,7 @@ bar
44424445
#[test]
44434446
fn parse_hex_eight() {
44444447
for i in 0..65536 {
4445-
let c = match ::std::char::from_u32(i) {
4448+
let c = match char::from_u32(i) {
44464449
None => continue,
44474450
Some(c) => c,
44484451
};

Diff for: ‎regex-syntax/src/ast/print.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
This module provides a regular expression printer for `Ast`.
33
*/
44

5-
use std::fmt;
5+
use core::fmt;
66

7-
use crate::ast::visitor::{self, Visitor};
8-
use crate::ast::{self, Ast};
7+
use crate::ast::{
8+
self,
9+
visitor::{self, Visitor},
10+
Ast,
11+
};
912

1013
/// A builder for constructing a printer.
1114
///
@@ -395,9 +398,12 @@ impl<W: fmt::Write> Writer<W> {
395398

396399
#[cfg(test)]
397400
mod tests {
398-
use super::Printer;
401+
use alloc::string::String;
402+
399403
use crate::ast::parse::ParserBuilder;
400404

405+
use super::*;
406+
401407
fn roundtrip(given: &str) {
402408
roundtrip_with(|b| b, given);
403409
}

Diff for: ‎regex-syntax/src/ast/visitor.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::fmt;
1+
use alloc::{vec, vec::Vec};
22

33
use crate::ast::{self, Ast};
44

@@ -475,8 +475,8 @@ impl<'a> ClassInduct<'a> {
475475
}
476476
}
477477

478-
impl<'a> fmt::Debug for ClassFrame<'a> {
479-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
478+
impl<'a> core::fmt::Debug for ClassFrame<'a> {
479+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
480480
let x = match *self {
481481
ClassFrame::Union { .. } => "Union",
482482
ClassFrame::Binary { .. } => "Binary",
@@ -487,8 +487,8 @@ impl<'a> fmt::Debug for ClassFrame<'a> {
487487
}
488488
}
489489

490-
impl<'a> fmt::Debug for ClassInduct<'a> {
491-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
490+
impl<'a> core::fmt::Debug for ClassInduct<'a> {
491+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
492492
let x = match *self {
493493
ClassInduct::Item(it) => match *it {
494494
ast::ClassSetItem::Empty(_) => "Item(Empty)",

Diff for: ‎regex-syntax/src/error.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
use std::cmp;
2-
use std::fmt;
3-
use std::result;
1+
use core::{cmp, fmt, result};
42

5-
use crate::ast;
6-
use crate::hir;
3+
use alloc::{
4+
format,
5+
string::{String, ToString},
6+
vec,
7+
vec::Vec,
8+
};
9+
10+
use crate::{ast, hir};
711

812
/// A type alias for dealing with errors returned by this crate.
913
pub type Result<T> = result::Result<T, Error>;
@@ -35,6 +39,7 @@ impl From<hir::Error> for Error {
3539
}
3640
}
3741

42+
#[cfg(feature = "std")]
3843
impl std::error::Error for Error {}
3944

4045
impl fmt::Display for Error {
@@ -266,11 +271,13 @@ impl<'p> Spans<'p> {
266271
}
267272

268273
fn repeat_char(c: char, count: usize) -> String {
269-
::std::iter::repeat(c).take(count).collect()
274+
core::iter::repeat(c).take(count).collect()
270275
}
271276

272277
#[cfg(test)]
273278
mod tests {
279+
use alloc::string::ToString;
280+
274281
use crate::ast::parse::Parser;
275282

276283
fn assert_panic_message(pattern: &str, expected_msg: &str) {

Diff for: ‎regex-syntax/src/hir/interval.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use std::char;
2-
use std::cmp;
3-
use std::fmt::Debug;
4-
use std::slice;
5-
use std::u8;
1+
use core::{char, cmp, fmt::Debug, slice};
2+
3+
use alloc::vec::Vec;
64

75
use crate::unicode;
86

Diff for: ‎regex-syntax/src/hir/literal/mod.rs

+30-24
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22
Provides routines for extracting literal prefixes and suffixes from an `Hir`.
33
*/
44

5-
use std::cmp;
6-
use std::fmt;
7-
use std::iter;
8-
use std::mem;
9-
use std::ops;
5+
use core::{cmp, iter, mem, ops};
6+
7+
use alloc::{
8+
boxed::Box,
9+
format,
10+
string::{String, ToString},
11+
vec,
12+
vec::Vec,
13+
};
1014

1115
use crate::hir::{self, Hir, HirKind};
1216

@@ -408,7 +412,7 @@ impl Literals {
408412
}
409413
if self.lits.is_empty() {
410414
let i = cmp::min(self.limit_size, bytes.len());
411-
self.lits.push(Literal::new(bytes[..i].to_owned()));
415+
self.lits.push(Literal::new(bytes[..i].to_vec()));
412416
self.lits[0].cut = i < bytes.len();
413417
return !self.lits[0].is_cut();
414418
}
@@ -465,8 +469,6 @@ impl Literals {
465469
cls: &hir::ClassUnicode,
466470
reverse: bool,
467471
) -> bool {
468-
use std::char;
469-
470472
if self.class_exceeds_limits(cls_char_count(cls)) {
471473
return false;
472474
}
@@ -837,8 +839,8 @@ fn alternate_literals<F: FnMut(&Hir, &mut Literals)>(
837839
}
838840
}
839841

840-
impl fmt::Debug for Literals {
841-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
842+
impl core::fmt::Debug for Literals {
843+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
842844
f.debug_struct("Literals")
843845
.field("lits", &self.lits)
844846
.field("limit_size", &self.limit_size)
@@ -881,8 +883,8 @@ impl PartialOrd for Literal {
881883
}
882884
}
883885

884-
impl fmt::Debug for Literal {
885-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
886+
impl core::fmt::Debug for Literal {
887+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
886888
if self.is_cut() {
887889
write!(f, "Cut({})", escape_unicode(&self.v))
888890
} else {
@@ -923,7 +925,7 @@ fn position(needle: &[u8], mut haystack: &[u8]) -> Option<usize> {
923925
}
924926

925927
fn escape_unicode(bytes: &[u8]) -> String {
926-
let show = match ::std::str::from_utf8(bytes) {
928+
let show = match core::str::from_utf8(bytes) {
927929
Ok(v) => v.to_string(),
928930
Err(_) => escape_bytes(bytes),
929931
};
@@ -955,7 +957,7 @@ fn escape_bytes(bytes: &[u8]) -> String {
955957
}
956958

957959
fn escape_byte(byte: u8) -> String {
958-
use std::ascii::escape_default;
960+
use core::ascii::escape_default;
959961

960962
let escaped: Vec<u8> = escape_default(byte).collect();
961963
String::from_utf8_lossy(&escaped).into_owned()
@@ -971,11 +973,15 @@ fn cls_byte_count(cls: &hir::ClassBytes) -> usize {
971973

972974
#[cfg(test)]
973975
mod tests {
974-
use std::fmt;
976+
use alloc::{
977+
string::{String, ToString},
978+
vec,
979+
vec::Vec,
980+
};
981+
982+
use crate::{hir::Hir, ParserBuilder};
975983

976-
use super::{escape_bytes, Literal, Literals};
977-
use crate::hir::Hir;
978-
use crate::ParserBuilder;
984+
use super::*;
979985

980986
// To make test failures easier to read.
981987
#[derive(Debug, Eq, PartialEq)]
@@ -1013,8 +1019,8 @@ mod tests {
10131019
}
10141020
}
10151021

1016-
impl fmt::Debug for ULiteral {
1017-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1022+
impl core::fmt::Debug for ULiteral {
1023+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10181024
if self.is_cut() {
10191025
write!(f, "Cut({})", self.v)
10201026
} else {
@@ -1037,11 +1043,11 @@ mod tests {
10371043

10381044
#[allow(non_snake_case)]
10391045
fn C(s: &'static str) -> ULiteral {
1040-
ULiteral { v: s.to_owned(), cut: true }
1046+
ULiteral { v: s.to_string(), cut: true }
10411047
}
10421048
#[allow(non_snake_case)]
10431049
fn M(s: &'static str) -> ULiteral {
1044-
ULiteral { v: s.to_owned(), cut: false }
1050+
ULiteral { v: s.to_string(), cut: false }
10451051
}
10461052

10471053
fn prefixes(lits: &mut Literals, expr: &Hir) {
@@ -1626,7 +1632,7 @@ mod tests {
16261632
let given: Vec<Literal> = $given
16271633
.into_iter()
16281634
.map(|s: &str| Literal {
1629-
v: s.to_owned().into_bytes(),
1635+
v: s.to_string().into_bytes(),
16301636
cut: false,
16311637
})
16321638
.collect();
@@ -1661,7 +1667,7 @@ mod tests {
16611667
let given: Vec<Literal> = $given
16621668
.into_iter()
16631669
.map(|s: &str| Literal {
1664-
v: s.to_owned().into_bytes(),
1670+
v: s.to_string().into_bytes(),
16651671
cut: false,
16661672
})
16671673
.collect();

Diff for: ‎regex-syntax/src/hir/mod.rs

+34-25
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
/*!
22
Defines a high-level intermediate representation for regular expressions.
33
*/
4-
use std::char;
5-
use std::cmp;
6-
use std::fmt;
7-
use std::result;
8-
use std::u8;
94

10-
use crate::ast::Span;
11-
use crate::hir::interval::{Interval, IntervalSet, IntervalSetIter};
12-
use crate::unicode;
5+
use core::{char, cmp};
136

14-
pub use crate::hir::visitor::{visit, Visitor};
15-
pub use crate::unicode::CaseFoldError;
7+
use alloc::{
8+
boxed::Box,
9+
format,
10+
string::{String, ToString},
11+
vec,
12+
vec::Vec,
13+
};
14+
15+
use crate::{
16+
ast::Span,
17+
hir::interval::{Interval, IntervalSet, IntervalSetIter},
18+
unicode,
19+
};
20+
21+
pub use crate::{
22+
hir::visitor::{visit, Visitor},
23+
unicode::CaseFoldError,
24+
};
1625

1726
mod interval;
1827
pub mod literal;
@@ -80,16 +89,17 @@ pub enum ErrorKind {
8089
UnicodeCaseUnavailable,
8190
}
8291

92+
#[cfg(feature = "std")]
8393
impl std::error::Error for Error {}
8494

85-
impl fmt::Display for Error {
86-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95+
impl core::fmt::Display for Error {
96+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8797
crate::error::Formatter::from(self).fmt(f)
8898
}
8999
}
90100

91-
impl fmt::Display for ErrorKind {
92-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101+
impl core::fmt::Display for ErrorKind {
102+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93103
use self::ErrorKind::*;
94104

95105
let msg = match *self {
@@ -197,8 +207,7 @@ impl Hir {
197207
/// Consumes ownership of this HIR expression and returns its underlying
198208
/// `HirKind`.
199209
pub fn into_kind(mut self) -> HirKind {
200-
use std::mem;
201-
mem::replace(&mut self.kind, HirKind::Empty)
210+
core::mem::replace(&mut self.kind, HirKind::Empty)
202211
}
203212

204213
/// Returns an empty HIR expression.
@@ -704,8 +713,8 @@ impl HirKind {
704713
///
705714
/// This implementation uses constant stack space and heap space proportional
706715
/// to the size of the `Hir`.
707-
impl fmt::Display for Hir {
708-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
716+
impl core::fmt::Display for Hir {
717+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
709718
use crate::hir::print::Printer;
710719
Printer::new().print(self, f)
711720
}
@@ -800,7 +809,7 @@ impl Class {
800809
/// Unicode oriented.
801810
pub fn try_case_fold_simple(
802811
&mut self,
803-
) -> result::Result<(), CaseFoldError> {
812+
) -> core::result::Result<(), CaseFoldError> {
804813
match *self {
805814
Class::Unicode(ref mut x) => x.try_case_fold_simple()?,
806815
Class::Bytes(ref mut x) => x.case_fold_simple(),
@@ -909,7 +918,7 @@ impl ClassUnicode {
909918
/// `unicode-case` feature is not enabled.
910919
pub fn try_case_fold_simple(
911920
&mut self,
912-
) -> result::Result<(), CaseFoldError> {
921+
) -> core::result::Result<(), CaseFoldError> {
913922
self.set.case_fold_simple()
914923
}
915924

@@ -981,8 +990,8 @@ pub struct ClassUnicodeRange {
981990
end: char,
982991
}
983992

984-
impl fmt::Debug for ClassUnicodeRange {
985-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
993+
impl core::fmt::Debug for ClassUnicodeRange {
994+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
986995
let start = if !self.start.is_whitespace() && !self.start.is_control()
987996
{
988997
self.start.to_string()
@@ -1285,8 +1294,8 @@ impl ClassBytesRange {
12851294
}
12861295
}
12871296

1288-
impl fmt::Debug for ClassBytesRange {
1289-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1297+
impl core::fmt::Debug for ClassBytesRange {
1298+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12901299
let mut debug = f.debug_struct("ClassBytesRange");
12911300
if self.start <= 0x7F {
12921301
let ch = char::try_from(self.start).unwrap();
@@ -1459,7 +1468,7 @@ pub enum RepetitionRange {
14591468
/// space but heap space proportional to the depth of the total `Hir`.
14601469
impl Drop for Hir {
14611470
fn drop(&mut self) {
1462-
use std::mem;
1471+
use core::mem;
14631472

14641473
match *self.kind() {
14651474
HirKind::Empty

Diff for: ‎regex-syntax/src/hir/print.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
This module provides a regular expression printer for `Hir`.
33
*/
44

5-
use std::fmt;
5+
use core::fmt;
66

7-
use crate::hir::visitor::{self, Visitor};
8-
use crate::hir::{self, Hir, HirKind};
9-
use crate::is_meta_character;
7+
use crate::{
8+
hir::{
9+
self,
10+
visitor::{self, Visitor},
11+
Hir, HirKind,
12+
},
13+
is_meta_character,
14+
};
1015

1116
/// A builder for constructing a printer.
1217
///
@@ -235,9 +240,12 @@ impl<W: fmt::Write> Writer<W> {
235240

236241
#[cfg(test)]
237242
mod tests {
238-
use super::Printer;
243+
use alloc::string::String;
244+
239245
use crate::ParserBuilder;
240246

247+
use super::*;
248+
241249
fn roundtrip(given: &str, expected: &str) {
242250
roundtrip_with(|b| b, given, expected);
243251
}

Diff for: ‎regex-syntax/src/hir/translate.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
Defines a translator that converts an `Ast` to an `Hir`.
33
*/
44

5-
use std::cell::{Cell, RefCell};
6-
use std::result;
5+
use core::cell::{Cell, RefCell};
76

8-
use crate::ast::{self, Ast, Span, Visitor};
9-
use crate::hir::{self, Error, ErrorKind, Hir};
10-
use crate::unicode::{self, ClassQuery};
7+
use alloc::{boxed::Box, string::ToString, vec, vec::Vec};
118

12-
type Result<T> = result::Result<T, Error>;
9+
use crate::{
10+
ast::{self, Ast, Span, Visitor},
11+
hir::{self, Error, ErrorKind, Hir},
12+
unicode::{self, ClassQuery},
13+
};
14+
15+
type Result<T> = core::result::Result<T, Error>;
1316

1417
/// A builder for constructing an AST->HIR translator.
1518
#[derive(Clone, Debug)]
@@ -1119,12 +1122,13 @@ fn ascii_class_as_chars(
11191122

11201123
#[cfg(test)]
11211124
mod tests {
1122-
use crate::ast::parse::ParserBuilder;
1123-
use crate::ast::{self, Ast, Position, Span};
1124-
use crate::hir::{self, Hir, HirKind};
1125-
use crate::unicode::{self, ClassQuery};
1125+
use crate::{
1126+
ast::{self, parse::ParserBuilder, Ast, Position, Span},
1127+
hir::{self, Hir, HirKind},
1128+
unicode::{self, ClassQuery},
1129+
};
11261130

1127-
use super::{ascii_class, ascii_class_as_chars, TranslatorBuilder};
1131+
use super::*;
11281132

11291133
// We create these errors to compare with real hir::Errors in the tests.
11301134
// We define equality between TestError and hir::Error to disregard the

Diff for: ‎regex-syntax/src/hir/visitor.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use alloc::{vec, vec::Vec};
2+
13
use crate::hir::{self, Hir, HirKind};
24

35
/// A trait for visiting the high-level IR (HIR) in depth first order.

Diff for: ‎regex-syntax/src/lib.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ match semantics of a regular expression.
116116
117117
The following features are available:
118118
119+
* **std** -
120+
Enables support for the standard library. This feature is enabled by default.
121+
When disabled, only `core` and `alloc` are used. Otherwise, enabling `std`
122+
generally just enables `std::error::Error` trait impls for the various error
123+
types.
119124
* **unicode** -
120125
Enables all Unicode features. This feature is enabled by default, and will
121126
always cover all Unicode features, even if more are added in the future.
@@ -154,13 +159,23 @@ The following features are available:
154159
`\p{sb=ATerm}`.
155160
*/
156161

162+
#![forbid(unsafe_code)]
157163
#![deny(missing_docs)]
158164
#![warn(missing_debug_implementations)]
159-
#![forbid(unsafe_code)]
165+
#![no_std]
166+
167+
#[cfg(any(test, feature = "std"))]
168+
extern crate std;
160169

161-
pub use crate::error::{Error, Result};
162-
pub use crate::parser::{Parser, ParserBuilder};
163-
pub use crate::unicode::UnicodeWordError;
170+
extern crate alloc;
171+
172+
pub use crate::{
173+
error::{Error, Result},
174+
parser::{Parser, ParserBuilder},
175+
unicode::UnicodeWordError,
176+
};
177+
178+
use alloc::string::String;
164179

165180
pub mod ast;
166181
mod either;
@@ -248,7 +263,7 @@ pub fn is_word_character(c: char) -> bool {
248263
/// returns an error.
249264
pub fn try_is_word_character(
250265
c: char,
251-
) -> std::result::Result<bool, UnicodeWordError> {
266+
) -> core::result::Result<bool, UnicodeWordError> {
252267
unicode::is_word_character(c)
253268
}
254269

@@ -265,6 +280,8 @@ pub fn is_word_byte(c: u8) -> bool {
265280

266281
#[cfg(test)]
267282
mod tests {
283+
use alloc::string::ToString;
284+
268285
use super::*;
269286

270287
#[test]

Diff for: ‎regex-syntax/src/parser.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use crate::ast;
2-
use crate::hir;
3-
4-
use crate::Result;
1+
use crate::{ast, hir, Result};
52

63
/// A builder for a regular expression parser.
74
///

Diff for: ‎regex-syntax/src/unicode.rs

+41-35
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use std::error;
2-
use std::fmt;
3-
use std::result;
1+
use alloc::{
2+
string::{String, ToString},
3+
vec::Vec,
4+
};
45

56
use crate::hir;
67

78
/// A type alias for errors specific to Unicode handling of classes.
8-
pub type Result<T> = result::Result<T, Error>;
9+
pub type Result<T> = core::result::Result<T, Error>;
910

1011
/// An inclusive range of codepoints from a generated file (hence the static
1112
/// lifetime).
@@ -25,7 +26,7 @@ pub enum Error {
2526
}
2627

2728
/// A type alias for errors specific to Unicode case folding.
28-
pub type FoldResult<T> = result::Result<T, CaseFoldError>;
29+
pub type FoldResult<T> = core::result::Result<T, CaseFoldError>;
2930

3031
/// An error that occurs when Unicode-aware simple case folding fails.
3132
///
@@ -35,10 +36,11 @@ pub type FoldResult<T> = result::Result<T, CaseFoldError>;
3536
#[derive(Debug)]
3637
pub struct CaseFoldError(());
3738

38-
impl error::Error for CaseFoldError {}
39+
#[cfg(feature = "std")]
40+
impl std::error::Error for CaseFoldError {}
3941

40-
impl fmt::Display for CaseFoldError {
41-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42+
impl core::fmt::Display for CaseFoldError {
43+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4244
write!(
4345
f,
4446
"Unicode-aware case folding is not available \
@@ -55,10 +57,11 @@ impl fmt::Display for CaseFoldError {
5557
#[derive(Debug)]
5658
pub struct UnicodeWordError(());
5759

58-
impl error::Error for UnicodeWordError {}
60+
#[cfg(feature = "std")]
61+
impl std::error::Error for UnicodeWordError {}
5962

60-
impl fmt::Display for UnicodeWordError {
61-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63+
impl core::fmt::Display for UnicodeWordError {
64+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6265
write!(
6366
f,
6467
"Unicode-aware \\w class is not available \
@@ -80,21 +83,24 @@ impl fmt::Display for UnicodeWordError {
8083
/// This returns an error if the Unicode case folding tables are not available.
8184
pub fn simple_fold(
8285
c: char,
83-
) -> FoldResult<result::Result<impl Iterator<Item = char>, Option<char>>> {
86+
) -> FoldResult<core::result::Result<impl Iterator<Item = char>, Option<char>>>
87+
{
8488
#[cfg(not(feature = "unicode-case"))]
8589
fn imp(
8690
_: char,
87-
) -> FoldResult<result::Result<impl Iterator<Item = char>, Option<char>>>
88-
{
89-
use std::option::IntoIter;
90-
Err::<result::Result<IntoIter<char>, _>, _>(CaseFoldError(()))
91+
) -> FoldResult<
92+
core::result::Result<impl Iterator<Item = char>, Option<char>>,
93+
> {
94+
use core::option::IntoIter;
95+
Err::<core::result::Result<IntoIter<char>, _>, _>(CaseFoldError(()))
9196
}
9297

9398
#[cfg(feature = "unicode-case")]
9499
fn imp(
95100
c: char,
96-
) -> FoldResult<result::Result<impl Iterator<Item = char>, Option<char>>>
97-
{
101+
) -> FoldResult<
102+
core::result::Result<impl Iterator<Item = char>, Option<char>>,
103+
> {
98104
use crate::unicode_tables::case_folding_simple::CASE_FOLDING_SIMPLE;
99105

100106
Ok(CASE_FOLDING_SIMPLE
@@ -130,8 +136,9 @@ pub fn contains_simple_case_mapping(
130136

131137
#[cfg(feature = "unicode-case")]
132138
fn imp(start: char, end: char) -> FoldResult<bool> {
139+
use core::cmp::Ordering;
140+
133141
use crate::unicode_tables::case_folding_simple::CASE_FOLDING_SIMPLE;
134-
use std::cmp::Ordering;
135142

136143
assert!(start <= end);
137144
Ok(CASE_FOLDING_SIMPLE
@@ -407,24 +414,26 @@ pub fn hir_class(ranges: &[(char, char)]) -> hir::ClassUnicode {
407414
/// Returns true only if the given codepoint is in the `\w` character class.
408415
///
409416
/// If the `unicode-perl` feature is not enabled, then this returns an error.
410-
pub fn is_word_character(c: char) -> result::Result<bool, UnicodeWordError> {
417+
pub fn is_word_character(
418+
c: char,
419+
) -> core::result::Result<bool, UnicodeWordError> {
411420
#[cfg(not(feature = "unicode-perl"))]
412-
fn imp(_: char) -> result::Result<bool, UnicodeWordError> {
421+
fn imp(_: char) -> core::result::Result<bool, UnicodeWordError> {
413422
Err(UnicodeWordError(()))
414423
}
415424

416425
#[cfg(feature = "unicode-perl")]
417-
fn imp(c: char) -> result::Result<bool, UnicodeWordError> {
418-
use crate::is_word_byte;
419-
use crate::unicode_tables::perl_word::PERL_WORD;
420-
use std::cmp::Ordering;
426+
fn imp(c: char) -> core::result::Result<bool, UnicodeWordError> {
427+
use crate::{is_word_byte, unicode_tables::perl_word::PERL_WORD};
421428

422429
// MSRV(1.59): Use 'u8::try_from(c)' instead.
423430
if u8::try_from(u32::from(c)).map_or(false, is_word_byte) {
424431
return Ok(true);
425432
}
426433
Ok(PERL_WORD
427434
.binary_search_by(|&(start, end)| {
435+
use core::cmp::Ordering;
436+
428437
if start <= c && c <= end {
429438
Ordering::Equal
430439
} else if start > c {
@@ -583,7 +592,7 @@ fn property_set(
583592
fn ages(canonical_age: &str) -> Result<impl Iterator<Item = Range>> {
584593
#[cfg(not(feature = "unicode-age"))]
585594
fn imp(_: &str) -> Result<impl Iterator<Item = Range>> {
586-
use std::option::IntoIter;
595+
use core::option::IntoIter;
587596
Err::<IntoIter<Range>, _>(Error::PropertyNotFound)
588597
}
589598

@@ -884,10 +893,7 @@ fn symbolic_name_normalize_bytes(slice: &mut [u8]) -> &mut [u8] {
884893

885894
#[cfg(test)]
886895
mod tests {
887-
use super::{
888-
contains_simple_case_mapping, simple_fold, symbolic_name_normalize,
889-
symbolic_name_normalize_bytes,
890-
};
896+
use super::*;
891897

892898
#[cfg(feature = "unicode-case")]
893899
fn simple_fold_ok(c: char) -> impl Iterator<Item = char> {
@@ -911,23 +917,23 @@ mod tests {
911917
#[cfg(feature = "unicode-case")]
912918
fn simple_fold_k() {
913919
let xs: Vec<char> = simple_fold_ok('k').collect();
914-
assert_eq!(xs, vec!['K', 'K']);
920+
assert_eq!(xs, alloc::vec!['K', 'K']);
915921

916922
let xs: Vec<char> = simple_fold_ok('K').collect();
917-
assert_eq!(xs, vec!['k', 'K']);
923+
assert_eq!(xs, alloc::vec!['k', 'K']);
918924

919925
let xs: Vec<char> = simple_fold_ok('K').collect();
920-
assert_eq!(xs, vec!['K', 'k']);
926+
assert_eq!(xs, alloc::vec!['K', 'k']);
921927
}
922928

923929
#[test]
924930
#[cfg(feature = "unicode-case")]
925931
fn simple_fold_a() {
926932
let xs: Vec<char> = simple_fold_ok('a').collect();
927-
assert_eq!(xs, vec!['A']);
933+
assert_eq!(xs, alloc::vec!['A']);
928934

929935
let xs: Vec<char> = simple_fold_ok('A').collect();
930-
assert_eq!(xs, vec!['a']);
936+
assert_eq!(xs, alloc::vec!['a']);
931937
}
932938

933939
#[test]

Diff for: ‎regex-syntax/src/utf8.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,9 @@ I also got the idea from
8080
which uses it for executing automata on their term index.
8181
*/
8282

83-
#![deny(missing_docs)]
83+
use core::{char, fmt, iter::FusedIterator, slice};
8484

85-
use std::char;
86-
use std::fmt;
87-
use std::iter::FusedIterator;
88-
use std::slice;
85+
use alloc::{vec, vec::Vec};
8986

9087
const MAX_UTF8_BYTES: usize = 4;
9188

@@ -457,7 +454,9 @@ fn max_scalar_value(nbytes: usize) -> u32 {
457454

458455
#[cfg(test)]
459456
mod tests {
460-
use std::char;
457+
use core::char;
458+
459+
use alloc::{vec, vec::Vec};
461460

462461
use crate::utf8::{Utf8Range, Utf8Sequences};
463462

Diff for: ‎regex-syntax/test

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ echo "===== DEFAULT FEATURES ==="
77
cargo test
88

99
features=(
10+
std
1011
unicode
1112
unicode-age
1213
unicode-bool

0 commit comments

Comments
 (0)
Please sign in to comment.