From 12bd4f42a71e0cffdc0f6527e37d9c7b44524075 Mon Sep 17 00:00:00 2001 From: Zachary Pierce Date: Mon, 7 May 2018 09:11:53 -0700 Subject: [PATCH 1/5] Add nominal no_std + alloc support to regex-syntax Introduces feature flags and associated conditional compilation configuration to alloc use in no_std builds for environments with access to a heap. Note that until ucd-util is updated and the relevant feature flags piped through, this mode will not be practically usable. --- regex-syntax/Cargo.toml | 8 ++++ regex-syntax/src/ast/mod.rs | 32 ++++++++++++-- regex-syntax/src/ast/parse.rs | 65 ++++++++++++++++++++++++----- regex-syntax/src/ast/print.rs | 4 ++ regex-syntax/src/ast/visitor.rs | 6 +++ regex-syntax/src/error.rs | 32 +++++++++++--- regex-syntax/src/hir/interval.rs | 27 +++++++++--- regex-syntax/src/hir/literal/mod.rs | 43 ++++++++++++++++--- regex-syntax/src/hir/mod.rs | 34 ++++++++++++--- regex-syntax/src/hir/print.rs | 4 ++ regex-syntax/src/hir/translate.rs | 18 +++++++- regex-syntax/src/hir/visitor.rs | 2 + regex-syntax/src/lib.rs | 22 ++++++++++ regex-syntax/src/unicode.rs | 22 ++++++++-- 14 files changed, 278 insertions(+), 41 deletions(-) diff --git a/regex-syntax/Cargo.toml b/regex-syntax/Cargo.toml index 2128945bb5..ce4ae10f5d 100644 --- a/regex-syntax/Cargo.toml +++ b/regex-syntax/Cargo.toml @@ -9,5 +9,13 @@ homepage = "https://github.com/rust-lang/regex" description = "A regular expression parser." workspace = ".." +[features] +default = ["std"] +# Disable this on-by-default feature and add "alloc" to allow use in no_std builds +std = [] +# Required for use in no_std builds, presently nightly-only +alloc = [] + [dependencies] +cfg-if = "0.1" ucd-util = "0.1.0" diff --git a/regex-syntax/src/ast/mod.rs b/regex-syntax/src/ast/mod.rs index 884fcfa35c..54838e3af0 100644 --- a/regex-syntax/src/ast/mod.rs +++ b/regex-syntax/src/ast/mod.rs @@ -12,9 +12,22 @@ Defines an abstract syntax for regular expressions. */ -use std::cmp::Ordering; -use std::error; -use std::fmt; +cfg_if! { + if #[cfg(feature = "std")] { + use std::cmp::Ordering; + use std::error; + use std::fmt; + } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { + use alloc::boxed::Box; + use alloc::string::String; + use alloc::vec::Vec; + use core::cmp::Ordering; + use core::fmt; + } else { + use core::cmp::Ordering; + use core::fmt; + } +} pub use ast::visitor::{Visitor, visit}; @@ -179,6 +192,7 @@ pub enum ErrorKind { __Nonexhaustive, } +#[cfg(feature = "std")] impl error::Error for Error { fn description(&self) -> &str { use self::ErrorKind::*; @@ -226,10 +240,14 @@ impl fmt::Display for Error { impl fmt::Display for ErrorKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::ErrorKind::*; + #[cfg(feature = "std")] + use std::u32; + #[cfg(not(feature = "std"))] + use core::u32; match *self { CaptureLimitExceeded => { write!(f, "exceeded the maximum number of \ - capturing groups ({})", ::std::u32::MAX) + capturing groups ({})", u32::MAX) } ClassEscapeInvalid => { write!(f, "invalid escape sequence found in character class") @@ -1366,7 +1384,10 @@ pub enum Flag { /// space but heap space proportional to the depth of the `Ast`. impl Drop for Ast { fn drop(&mut self) { + #[cfg(feature = "std")] use std::mem; + #[cfg(not(feature = "std"))] + use core::mem; match *self { Ast::Empty(_) @@ -1416,7 +1437,10 @@ impl Drop for Ast { /// stack space but heap space proportional to the depth of the `ClassSet`. impl Drop for ClassSet { fn drop(&mut self) { + #[cfg(feature = "std")] use std::mem; + #[cfg(not(feature = "std"))] + use core::mem; match *self { ClassSet::Item(ref item) => { diff --git a/regex-syntax/src/ast/parse.rs b/regex-syntax/src/ast/parse.rs index b73baee735..3b203ffb59 100644 --- a/regex-syntax/src/ast/parse.rs +++ b/regex-syntax/src/ast/parse.rs @@ -12,10 +12,27 @@ This module provides a regular expression parser. */ -use std::borrow::Borrow; -use std::cell::{Cell, RefCell}; -use std::mem; -use std::result; +cfg_if! { + if #[cfg(feature = "std")] { + use std::borrow::Borrow; + use std::cell::{Cell, RefCell}; + use std::mem; + use std::result; + } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { + use alloc::borrow::Borrow; + use alloc::boxed::Box; + use alloc::string::{String, ToString}; + use alloc::vec::Vec; + use core::cell::{Cell, RefCell}; + use core::mem; + use core::result; + } else { + use core::cell::{Cell, RefCell}; + use core::mem; + use core::result; + } +} + use ast::{self, Ast, Position, Span}; use either::Either; @@ -1530,8 +1547,15 @@ impl<'s, P: Borrow> ParserI<'s, P> { /// /// Assuming the preconditions are met, this routine can never fail. fn parse_octal(&self) -> ast::Literal { - use std::char; - use std::u32; + cfg_if! { + if #[cfg(feature = "std")] { + use std::char; + use std::u32; + } else if #[cfg(not(feature = "std"))] { + use core::char; + use core::u32; + } + } assert!(self.parser().octal); assert!('0' <= self.char() && self.char() <= '7'); @@ -1596,8 +1620,15 @@ impl<'s, P: Borrow> ParserI<'s, P> { &self, kind: ast::HexLiteralKind, ) -> Result { - use std::char; - use std::u32; + cfg_if! { + if #[cfg(feature = "std")] { + use std::char; + use std::u32; + } else if #[cfg(not(feature = "std"))] { + use core::char; + use core::u32; + } + } let mut scratch = self.parser().scratch.borrow_mut(); scratch.clear(); @@ -1643,8 +1674,15 @@ impl<'s, P: Borrow> ParserI<'s, P> { &self, kind: ast::HexLiteralKind, ) -> Result { - use std::char; - use std::u32; + cfg_if! { + if #[cfg(feature = "std")] { + use std::char; + use std::u32; + } else if #[cfg(not(feature = "std"))] { + use core::char; + use core::u32; + } + } let mut scratch = self.parser().scratch.borrow_mut(); scratch.clear(); @@ -2121,9 +2159,13 @@ impl<'p, 's, P: Borrow> NestLimiter<'p, 's, P> { } fn increment_depth(&mut self, span: &Span) -> Result<()> { + #[cfg(feature = "std")] + use std::u32; + #[cfg(not(feature = "std"))] + use core::u32; let new = self.depth.checked_add(1).ok_or_else(|| self.p.error( span.clone(), - ast::ErrorKind::NestLimitExceeded(::std::u32::MAX), + ast::ErrorKind::NestLimitExceeded(u32::MAX), ))?; let limit = self.p.parser().nest_limit; if new > limit { @@ -2255,6 +2297,7 @@ impl<'p, 's, P: Borrow> ast::Visitor for NestLimiter<'p, 's, P> { #[cfg(test)] mod tests { + use std::prelude::v1::*; use std::ops::Range; use ast::{self, Ast, Position, Span}; diff --git a/regex-syntax/src/ast/print.rs b/regex-syntax/src/ast/print.rs index 4441b4d580..f64ad20c36 100644 --- a/regex-syntax/src/ast/print.rs +++ b/regex-syntax/src/ast/print.rs @@ -12,7 +12,10 @@ This module provides a regular expression printer for `Ast`. */ +#[cfg(feature = "std")] use std::fmt; +#[cfg(not(feature = "std"))] +use core::fmt; use ast::{self, Ast}; use ast::visitor::{self, Visitor}; @@ -415,6 +418,7 @@ impl<'p, W: fmt::Write> Writer<'p, W> { #[cfg(test)] mod tests { use ast::parse::ParserBuilder; + use std::prelude::v1::*; use super::Printer; fn roundtrip(given: &str) { diff --git a/regex-syntax/src/ast/visitor.rs b/regex-syntax/src/ast/visitor.rs index 9b93a1ae15..c8f3beb955 100644 --- a/regex-syntax/src/ast/visitor.rs +++ b/regex-syntax/src/ast/visitor.rs @@ -8,7 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[cfg(feature = "std")] use std::fmt; +#[cfg(not(feature = "std"))] +use core::fmt; + +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use ast::{self, Ast}; diff --git a/regex-syntax/src/error.rs b/regex-syntax/src/error.rs index 1f5b8f817d..e0a09246b6 100644 --- a/regex-syntax/src/error.rs +++ b/regex-syntax/src/error.rs @@ -1,7 +1,22 @@ -use std::cmp; -use std::error; -use std::fmt; -use std::result; +cfg_if! { + if #[cfg(feature = "std")] { + use std::cmp; + use std::error; + use std::fmt; + use std::result; + } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { + use alloc::slice::SliceConcatExt; + use alloc::string::{String, ToString}; + use alloc::vec::Vec; + use core::cmp; + use core::fmt; + use core::result; + } else { + use core::cmp; + use core::fmt; + use core::result; + } +} use ast; use hir; @@ -39,6 +54,7 @@ impl From for Error { } } +#[cfg(feature = "std")] impl error::Error for Error { fn description(&self) -> &str { match *self { @@ -280,11 +296,17 @@ impl<'p> Spans<'p> { } fn repeat_char(c: char, count: usize) -> String { - ::std::iter::repeat(c).take(count).collect() + #[cfg(feature = "std")] + use std::iter; + #[cfg(not(feature = "std"))] + use core::iter; + + iter::repeat(c).take(count).collect() } #[cfg(test)] mod tests { + use std::prelude::v1::*; use ast::parse::Parser; // See: https://github.com/rust-lang/regex/issues/464 diff --git a/regex-syntax/src/hir/interval.rs b/regex-syntax/src/hir/interval.rs index a7e70ef596..7ca99b2540 100644 --- a/regex-syntax/src/hir/interval.rs +++ b/regex-syntax/src/hir/interval.rs @@ -1,8 +1,25 @@ -use std::char; -use std::cmp; -use std::fmt::Debug; -use std::slice; -use std::u8; +cfg_if! { + if #[cfg(feature = "std")] { + use std::char; + use std::cmp; + use std::fmt::Debug; + use std::slice; + use std::u8; + } else if #[cfg(not(feature = "std"))] { + use alloc::vec::Vec; + use core::char; + use core::cmp; + use core::fmt::Debug; + use core::slice; + use core::u8; + } else { + use core::char; + use core::cmp; + use core::fmt::Debug; + use core::slice; + use core::u8; + } +} // This module contains an *internal* implementation of interval sets. // diff --git a/regex-syntax/src/hir/literal/mod.rs b/regex-syntax/src/hir/literal/mod.rs index b7d9c1db27..06429f61b3 100644 --- a/regex-syntax/src/hir/literal/mod.rs +++ b/regex-syntax/src/hir/literal/mod.rs @@ -12,11 +12,31 @@ Provides routines for extracting literal prefixes and suffixes from an `Hir`. */ -use std::cmp; -use std::fmt; -use std::iter; -use std::mem; -use std::ops; +cfg_if! { + if #[cfg(feature = "std")] { + use std::cmp; + use std::fmt; + use std::iter; + use std::mem; + use std::ops; + } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { + use alloc::borrow::ToOwned; + use alloc::boxed::Box; + use alloc::string::{String, ToString}; + use alloc::vec::Vec; + use core::cmp; + use core::fmt; + use core::iter; + use core::mem; + use core::ops; + } else { + use core::cmp; + use core::fmt; + use core::iter; + use core::mem; + use core::ops; + } +} use hir::{self, Hir, HirKind}; @@ -483,7 +503,10 @@ impl Literals { cls: &hir::ClassUnicode, reverse: bool, ) -> bool { + #[cfg(feature = "std")] use std::char; + #[cfg(not(feature = "std"))] + use core::char; if self.class_exceeds_limits(cls_char_count(cls)) { return false; @@ -946,7 +969,11 @@ fn position(needle: &[u8], mut haystack: &[u8]) -> Option { } fn escape_unicode(bytes: &[u8]) -> String { - let show = match ::std::str::from_utf8(bytes) { + #[cfg(feature = "std")] + use std::str; + #[cfg(not(feature = "std"))] + use core::str; + let show = match str::from_utf8(bytes) { Ok(v) => v.to_string(), Err(_) => escape_bytes(bytes), }; @@ -979,7 +1006,10 @@ fn escape_bytes(bytes: &[u8]) -> String { } fn escape_byte(byte: u8) -> String { + #[cfg(feature = "std")] use std::ascii::escape_default; + #[cfg(not(feature = "std"))] + use core::ascii::escape_default; let escaped: Vec = escape_default(byte).collect(); String::from_utf8_lossy(&escaped).into_owned() @@ -999,6 +1029,7 @@ fn cls_byte_count(cls: &hir::ClassBytes) -> usize { #[cfg(test)] mod tests { + use std::prelude::v1::*; use std::fmt; use ParserBuilder; diff --git a/regex-syntax/src/hir/mod.rs b/regex-syntax/src/hir/mod.rs index 903e6085be..39b9c24f0c 100644 --- a/regex-syntax/src/hir/mod.rs +++ b/regex-syntax/src/hir/mod.rs @@ -11,11 +11,28 @@ /*! Defines a high-level intermediate representation for regular expressions. */ -use std::char; -use std::cmp; -use std::error; -use std::fmt; -use std::u8; +cfg_if! { + if #[cfg(feature = "std")] { + use std::char; + use std::cmp; + use std::error; + use std::fmt; + use std::u8; + } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { + use alloc::boxed::Box; + use alloc::string::{String, ToString}; + use alloc::vec::Vec; + use core::char; + use core::cmp; + use core::fmt; + use core::u8; + } else { + use core::char; + use core::cmp; + use core::fmt; + use core::u8; + } +} use ast::Span; use hir::interval::{Interval, IntervalSet, IntervalSetIter}; @@ -104,6 +121,7 @@ impl ErrorKind { } } +#[cfg(feature = "std")] impl error::Error for Error { fn description(&self) -> &str { self.kind.description() @@ -209,7 +227,10 @@ impl Hir { /// Consumes ownership of this HIR expression and returns its underlying /// `HirKind`. pub fn into_kind(mut self) -> HirKind { + #[cfg(feature = "std")] use std::mem; + #[cfg(not(feature = "std"))] + use core::mem; mem::replace(&mut self.kind, HirKind::Empty) } @@ -1249,7 +1270,10 @@ pub enum RepetitionRange { /// space but heap space proportional to the depth of the total `Hir`. impl Drop for Hir { fn drop(&mut self) { + #[cfg(feature = "std")] use std::mem; + #[cfg(not(feature = "std"))] + use core::mem; match *self.kind() { HirKind::Empty diff --git a/regex-syntax/src/hir/print.rs b/regex-syntax/src/hir/print.rs index a40a670bf7..8c7c6101e8 100644 --- a/regex-syntax/src/hir/print.rs +++ b/regex-syntax/src/hir/print.rs @@ -2,7 +2,10 @@ This module provides a regular expression printer for `Hir`. */ +#[cfg(feature = "std")] use std::fmt; +#[cfg(not(feature = "std"))] +use core::fmt; use hir::{self, Hir, HirKind}; use hir::visitor::{self, Visitor}; @@ -247,6 +250,7 @@ impl<'p, W: fmt::Write> Writer<'p, W> { #[cfg(test)] mod tests { use ParserBuilder; + use std::prelude::v1::*; use super::Printer; fn roundtrip(given: &str, expected: &str) { diff --git a/regex-syntax/src/hir/translate.rs b/regex-syntax/src/hir/translate.rs index 7939ab59ad..d192acdafb 100644 --- a/regex-syntax/src/hir/translate.rs +++ b/regex-syntax/src/hir/translate.rs @@ -12,8 +12,21 @@ Defines a translator that converts an `Ast` to an `Hir`. */ -use std::cell::{Cell, RefCell}; -use std::result; +cfg_if! { + if #[cfg(feature = "std")] { + use std::cell::{Cell, RefCell}; + use std::result; + } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { + use alloc::boxed::Box; + use alloc::string::ToString; + use alloc::vec::Vec; + use core::cell::{Cell, RefCell}; + use core::result; + } else { + use core::cell::{Cell, RefCell}; + use core::result; + } +} use ast::{self, Ast, Span, Visitor}; use hir::{self, Error, ErrorKind, Hir}; @@ -1094,6 +1107,7 @@ mod tests { use ast::{self, Ast, Position, Span}; use ast::parse::ParserBuilder; use hir::{self, Hir, HirKind}; + use std::prelude::v1::*; use unicode::{self, ClassQuery}; use super::{TranslatorBuilder, ascii_class}; diff --git a/regex-syntax/src/hir/visitor.rs b/regex-syntax/src/hir/visitor.rs index 58be7ad078..aaa531c586 100644 --- a/regex-syntax/src/hir/visitor.rs +++ b/regex-syntax/src/hir/visitor.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use hir::{self, Hir, HirKind}; /// A trait for visiting the high-level IR (HIR) in depth first order. diff --git a/regex-syntax/src/lib.rs b/regex-syntax/src/lib.rs index 2c785bfc5f..daa9bccc64 100644 --- a/regex-syntax/src/lib.rs +++ b/regex-syntax/src/lib.rs @@ -105,8 +105,23 @@ done automatically in the `regex` crate. #![deny(missing_docs)] +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))] +#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(slice_concat_ext))] + +#[cfg(all(test, not(feature = "std")))] +#[macro_use] +extern crate std; + +#[cfg(all(feature = "alloc", not(feature = "std")))] +#[macro_use] +extern crate alloc; + extern crate ucd_util; +#[macro_use] +extern crate cfg_if; + pub use error::{Error, Result}; pub use parser::{Parser, ParserBuilder}; @@ -118,6 +133,9 @@ mod parser; mod unicode; mod unicode_tables; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::string::String; + /// Escapes all regular expression meta characters in `text`. /// /// The string returned may be safely used as a literal in a regular @@ -168,7 +186,10 @@ pub fn is_meta_character(c: char) -> bool { /// `Join_Control` properties, or is in one of the `Decimal_Number`, `Mark` /// or `Connector_Punctuation` general categories. pub fn is_word_character(c: char) -> bool { + #[cfg(feature = "std")] use std::cmp::Ordering; + #[cfg(not(feature = "std"))] + use core::cmp::Ordering; use unicode_tables::perl_word::PERL_WORD; if c <= 0x7F as char && is_word_byte(c as u8) { @@ -199,6 +220,7 @@ pub fn is_word_byte(c: u8) -> bool { #[cfg(test)] mod tests { + use std::prelude::v1::*; use super::*; #[test] diff --git a/regex-syntax/src/unicode.rs b/regex-syntax/src/unicode.rs index ed84d98b07..3d56f7ab1f 100644 --- a/regex-syntax/src/unicode.rs +++ b/regex-syntax/src/unicode.rs @@ -1,5 +1,20 @@ -use std::cmp::Ordering; -use std::result; +cfg_if! { + if #[cfg(feature = "std")] { + use std::cmp::Ordering; + use std::result; + use std::slice; + } else if #[cfg(not(feature = "std"))] { + use alloc::vec::Vec; + use alloc::string::{String, ToString}; + use core::cmp::Ordering; + use core::result; + use core::slice; + } else { + use core::cmp::Ordering; + use core::result; + use core::slice; + } +} use ucd_util::{self, PropertyValues}; @@ -27,7 +42,7 @@ pub enum Error { /// An iterator over a codepoint's simple case equivalence class. #[derive(Debug)] -pub struct SimpleFoldIter(::std::slice::Iter<'static, char>); +pub struct SimpleFoldIter(slice::Iter<'static, char>); impl Iterator for SimpleFoldIter { type Item = char; @@ -372,6 +387,7 @@ impl Iterator for AgeIter { #[cfg(test)] mod tests { + use std::prelude::v1::*; use super::{contains_simple_case_mapping, simple_fold}; #[test] From 42def74d3a0bb2205d08cfc6f2fbb7fe53b392f2 Mon Sep 17 00:00:00 2001 From: Zachary Pierce Date: Mon, 7 May 2018 18:30:50 -0700 Subject: [PATCH 2/5] Remove cfg-if; Apply std-as-core renaming to reduce clutter --- regex-syntax/Cargo.toml | 1 - regex-syntax/src/ast/mod.rs | 38 ++++--------- regex-syntax/src/ast/parse.rs | 88 ++++++++++------------------- regex-syntax/src/ast/print.rs | 2 +- regex-syntax/src/ast/visitor.rs | 3 - regex-syntax/src/error.rs | 42 ++++++-------- regex-syntax/src/hir/interval.rs | 29 +++------- regex-syntax/src/hir/literal/mod.rs | 54 ++++++------------ regex-syntax/src/hir/mod.rs | 48 ++++++---------- regex-syntax/src/hir/print.rs | 5 +- regex-syntax/src/hir/translate.rs | 25 +++----- regex-syntax/src/lib.rs | 15 ++--- regex-syntax/src/unicode.rs | 26 +++------ 13 files changed, 120 insertions(+), 256 deletions(-) diff --git a/regex-syntax/Cargo.toml b/regex-syntax/Cargo.toml index ce4ae10f5d..f14d3f8a66 100644 --- a/regex-syntax/Cargo.toml +++ b/regex-syntax/Cargo.toml @@ -17,5 +17,4 @@ std = [] alloc = [] [dependencies] -cfg-if = "0.1" ucd-util = "0.1.0" diff --git a/regex-syntax/src/ast/mod.rs b/regex-syntax/src/ast/mod.rs index 54838e3af0..eee591ecfb 100644 --- a/regex-syntax/src/ast/mod.rs +++ b/regex-syntax/src/ast/mod.rs @@ -12,22 +12,14 @@ Defines an abstract syntax for regular expressions. */ -cfg_if! { - if #[cfg(feature = "std")] { - use std::cmp::Ordering; - use std::error; - use std::fmt; - } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { - use alloc::boxed::Box; - use alloc::string::String; - use alloc::vec::Vec; - use core::cmp::Ordering; - use core::fmt; - } else { - use core::cmp::Ordering; - use core::fmt; - } -} +use core::cmp::Ordering; +use core::fmt; +#[cfg(feature = "std")] +use core::error; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::boxed::Box; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::{String, Vec}; pub use ast::visitor::{Visitor, visit}; @@ -240,14 +232,10 @@ impl fmt::Display for Error { impl fmt::Display for ErrorKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::ErrorKind::*; - #[cfg(feature = "std")] - use std::u32; - #[cfg(not(feature = "std"))] - use core::u32; match *self { CaptureLimitExceeded => { write!(f, "exceeded the maximum number of \ - capturing groups ({})", u32::MAX) + capturing groups ({})", ::core::u32::MAX) } ClassEscapeInvalid => { write!(f, "invalid escape sequence found in character class") @@ -1384,9 +1372,6 @@ pub enum Flag { /// space but heap space proportional to the depth of the `Ast`. impl Drop for Ast { fn drop(&mut self) { - #[cfg(feature = "std")] - use std::mem; - #[cfg(not(feature = "std"))] use core::mem; match *self { @@ -1437,9 +1422,6 @@ impl Drop for Ast { /// stack space but heap space proportional to the depth of the `ClassSet`. impl Drop for ClassSet { fn drop(&mut self) { - #[cfg(feature = "std")] - use std::mem; - #[cfg(not(feature = "std"))] use core::mem; match *self { @@ -1512,7 +1494,7 @@ mod tests { #[test] #[cfg(any(unix, windows))] fn no_stack_overflow_on_drop() { - use std::thread; + use std_test::thread; let run = || { let span = || Span::splat(Position::new(0, 0, 0)); diff --git a/regex-syntax/src/ast/parse.rs b/regex-syntax/src/ast/parse.rs index 3b203ffb59..aa9f6a5898 100644 --- a/regex-syntax/src/ast/parse.rs +++ b/regex-syntax/src/ast/parse.rs @@ -12,27 +12,22 @@ This module provides a regular expression parser. */ -cfg_if! { - if #[cfg(feature = "std")] { - use std::borrow::Borrow; - use std::cell::{Cell, RefCell}; - use std::mem; - use std::result; - } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { - use alloc::borrow::Borrow; - use alloc::boxed::Box; - use alloc::string::{String, ToString}; - use alloc::vec::Vec; - use core::cell::{Cell, RefCell}; - use core::mem; - use core::result; - } else { - use core::cell::{Cell, RefCell}; - use core::mem; - use core::result; - } -} - +use core::cell::{Cell, RefCell}; +use core::mem; +use core::result; +#[cfg(feature = "std")] +use core::prelude::v1::*; +#[cfg(feature = "std")] +use core::borrow::Borrow; + +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::borrow::Borrow; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::boxed::Box; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::string::{String, ToString}; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use ast::{self, Ast, Position, Span}; use either::Either; @@ -1547,15 +1542,8 @@ impl<'s, P: Borrow> ParserI<'s, P> { /// /// Assuming the preconditions are met, this routine can never fail. fn parse_octal(&self) -> ast::Literal { - cfg_if! { - if #[cfg(feature = "std")] { - use std::char; - use std::u32; - } else if #[cfg(not(feature = "std"))] { - use core::char; - use core::u32; - } - } + use core::char; + use core::u32; assert!(self.parser().octal); assert!('0' <= self.char() && self.char() <= '7'); @@ -1620,15 +1608,8 @@ impl<'s, P: Borrow> ParserI<'s, P> { &self, kind: ast::HexLiteralKind, ) -> Result { - cfg_if! { - if #[cfg(feature = "std")] { - use std::char; - use std::u32; - } else if #[cfg(not(feature = "std"))] { - use core::char; - use core::u32; - } - } + use core::char; + use core::u32; let mut scratch = self.parser().scratch.borrow_mut(); scratch.clear(); @@ -1674,15 +1655,8 @@ impl<'s, P: Borrow> ParserI<'s, P> { &self, kind: ast::HexLiteralKind, ) -> Result { - cfg_if! { - if #[cfg(feature = "std")] { - use std::char; - use std::u32; - } else if #[cfg(not(feature = "std"))] { - use core::char; - use core::u32; - } - } + use core::char; + use core::u32; let mut scratch = self.parser().scratch.borrow_mut(); scratch.clear(); @@ -2159,13 +2133,9 @@ impl<'p, 's, P: Borrow> NestLimiter<'p, 's, P> { } fn increment_depth(&mut self, span: &Span) -> Result<()> { - #[cfg(feature = "std")] - use std::u32; - #[cfg(not(feature = "std"))] - use core::u32; let new = self.depth.checked_add(1).ok_or_else(|| self.p.error( span.clone(), - ast::ErrorKind::NestLimitExceeded(u32::MAX), + ast::ErrorKind::NestLimitExceeded(::core::u32::MAX), ))?; let limit = self.p.parser().nest_limit; if new > limit { @@ -2297,8 +2267,8 @@ impl<'p, 's, P: Borrow> ast::Visitor for NestLimiter<'p, 's, P> { #[cfg(test)] mod tests { - use std::prelude::v1::*; - use std::ops::Range; + use std_test::prelude::v1::*; + use core::ops::Range; use ast::{self, Ast, Position, Span}; use super::{Parser, ParserI, ParserBuilder, Primitive}; @@ -3892,7 +3862,7 @@ bar Ok(Primitive::Literal(ast::Literal { span: span(0..pat.len()), kind: ast::LiteralKind::Octal, - c: ::std::char::from_u32(i).unwrap(), + c: ::core::char::from_u32(i).unwrap(), }))); } assert_eq!( @@ -3961,7 +3931,7 @@ bar Ok(Primitive::Literal(ast::Literal { span: span(0..pat.len()), kind: ast::LiteralKind::HexFixed(ast::HexLiteralKind::X), - c: ::std::char::from_u32(i).unwrap(), + c: ::core::char::from_u32(i).unwrap(), }))); } @@ -3988,7 +3958,7 @@ bar #[test] fn parse_hex_four() { for i in 0..65536 { - let c = match ::std::char::from_u32(i) { + let c = match ::core::char::from_u32(i) { None => continue, Some(c) => c, }; @@ -4044,7 +4014,7 @@ bar #[test] fn parse_hex_eight() { for i in 0..65536 { - let c = match ::std::char::from_u32(i) { + let c = match ::core::char::from_u32(i) { None => continue, Some(c) => c, }; diff --git a/regex-syntax/src/ast/print.rs b/regex-syntax/src/ast/print.rs index f64ad20c36..0503528023 100644 --- a/regex-syntax/src/ast/print.rs +++ b/regex-syntax/src/ast/print.rs @@ -418,7 +418,7 @@ impl<'p, W: fmt::Write> Writer<'p, W> { #[cfg(test)] mod tests { use ast::parse::ParserBuilder; - use std::prelude::v1::*; + use std_test::prelude::v1::*; use super::Printer; fn roundtrip(given: &str) { diff --git a/regex-syntax/src/ast/visitor.rs b/regex-syntax/src/ast/visitor.rs index c8f3beb955..93f5d5cf1c 100644 --- a/regex-syntax/src/ast/visitor.rs +++ b/regex-syntax/src/ast/visitor.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[cfg(feature = "std")] -use std::fmt; -#[cfg(not(feature = "std"))] use core::fmt; #[cfg(all(feature = "alloc", not(feature = "std")))] diff --git a/regex-syntax/src/error.rs b/regex-syntax/src/error.rs index e0a09246b6..b42031c5b0 100644 --- a/regex-syntax/src/error.rs +++ b/regex-syntax/src/error.rs @@ -1,22 +1,17 @@ -cfg_if! { - if #[cfg(feature = "std")] { - use std::cmp; - use std::error; - use std::fmt; - use std::result; - } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { - use alloc::slice::SliceConcatExt; - use alloc::string::{String, ToString}; - use alloc::vec::Vec; - use core::cmp; - use core::fmt; - use core::result; - } else { - use core::cmp; - use core::fmt; - use core::result; - } -} +use core::cmp; +use core::fmt; +use core::result; +#[cfg(feature = "std")] +use std::error; +#[cfg(feature = "std")] +use std::prelude::v1::*; + +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::slice::SliceConcatExt; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::string::{String, ToString}; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use ast; use hir; @@ -296,17 +291,12 @@ impl<'p> Spans<'p> { } fn repeat_char(c: char, count: usize) -> String { - #[cfg(feature = "std")] - use std::iter; - #[cfg(not(feature = "std"))] - use core::iter; - - iter::repeat(c).take(count).collect() + ::core::iter::repeat(c).take(count).collect() } #[cfg(test)] mod tests { - use std::prelude::v1::*; + use std_test::prelude::v1::*; use ast::parse::Parser; // See: https://github.com/rust-lang/regex/issues/464 diff --git a/regex-syntax/src/hir/interval.rs b/regex-syntax/src/hir/interval.rs index 7ca99b2540..a4ad30d774 100644 --- a/regex-syntax/src/hir/interval.rs +++ b/regex-syntax/src/hir/interval.rs @@ -1,25 +1,10 @@ -cfg_if! { - if #[cfg(feature = "std")] { - use std::char; - use std::cmp; - use std::fmt::Debug; - use std::slice; - use std::u8; - } else if #[cfg(not(feature = "std"))] { - use alloc::vec::Vec; - use core::char; - use core::cmp; - use core::fmt::Debug; - use core::slice; - use core::u8; - } else { - use core::char; - use core::cmp; - use core::fmt::Debug; - use core::slice; - use core::u8; - } -} +use core::char; +use core::cmp; +use core::fmt::Debug; +use core::slice; +use core::u8; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; // This module contains an *internal* implementation of interval sets. // diff --git a/regex-syntax/src/hir/literal/mod.rs b/regex-syntax/src/hir/literal/mod.rs index 06429f61b3..3313702db6 100644 --- a/regex-syntax/src/hir/literal/mod.rs +++ b/regex-syntax/src/hir/literal/mod.rs @@ -12,31 +12,19 @@ Provides routines for extracting literal prefixes and suffixes from an `Hir`. */ -cfg_if! { - if #[cfg(feature = "std")] { - use std::cmp; - use std::fmt; - use std::iter; - use std::mem; - use std::ops; - } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { - use alloc::borrow::ToOwned; - use alloc::boxed::Box; - use alloc::string::{String, ToString}; - use alloc::vec::Vec; - use core::cmp; - use core::fmt; - use core::iter; - use core::mem; - use core::ops; - } else { - use core::cmp; - use core::fmt; - use core::iter; - use core::mem; - use core::ops; - } -} +use core::cmp; +use core::fmt; +use core::iter; +use core::mem; +use core::ops; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::borrow::ToOwned; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::boxed::Box; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::string::{String, ToString}; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use hir::{self, Hir, HirKind}; @@ -503,9 +491,6 @@ impl Literals { cls: &hir::ClassUnicode, reverse: bool, ) -> bool { - #[cfg(feature = "std")] - use std::char; - #[cfg(not(feature = "std"))] use core::char; if self.class_exceeds_limits(cls_char_count(cls)) { @@ -969,11 +954,7 @@ fn position(needle: &[u8], mut haystack: &[u8]) -> Option { } fn escape_unicode(bytes: &[u8]) -> String { - #[cfg(feature = "std")] - use std::str; - #[cfg(not(feature = "std"))] - use core::str; - let show = match str::from_utf8(bytes) { + let show = match ::core::str::from_utf8(bytes) { Ok(v) => v.to_string(), Err(_) => escape_bytes(bytes), }; @@ -1006,9 +987,6 @@ fn escape_bytes(bytes: &[u8]) -> String { } fn escape_byte(byte: u8) -> String { - #[cfg(feature = "std")] - use std::ascii::escape_default; - #[cfg(not(feature = "std"))] use core::ascii::escape_default; let escaped: Vec = escape_default(byte).collect(); @@ -1029,8 +1007,8 @@ fn cls_byte_count(cls: &hir::ClassBytes) -> usize { #[cfg(test)] mod tests { - use std::prelude::v1::*; - use std::fmt; + use std_test::prelude::v1::*; + use core::fmt; use ParserBuilder; use hir::Hir; diff --git a/regex-syntax/src/hir/mod.rs b/regex-syntax/src/hir/mod.rs index 39b9c24f0c..c7b46ad60b 100644 --- a/regex-syntax/src/hir/mod.rs +++ b/regex-syntax/src/hir/mod.rs @@ -11,28 +11,21 @@ /*! Defines a high-level intermediate representation for regular expressions. */ -cfg_if! { - if #[cfg(feature = "std")] { - use std::char; - use std::cmp; - use std::error; - use std::fmt; - use std::u8; - } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { - use alloc::boxed::Box; - use alloc::string::{String, ToString}; - use alloc::vec::Vec; - use core::char; - use core::cmp; - use core::fmt; - use core::u8; - } else { - use core::char; - use core::cmp; - use core::fmt; - use core::u8; - } -} + +use core::char; +use core::cmp; +use core::fmt; +use core::u8; + +#[cfg(feature = "std")] +use core::error; + +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::boxed::Box; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::string::{String, ToString}; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use ast::Span; use hir::interval::{Interval, IntervalSet, IntervalSetIter}; @@ -227,11 +220,7 @@ impl Hir { /// Consumes ownership of this HIR expression and returns its underlying /// `HirKind`. pub fn into_kind(mut self) -> HirKind { - #[cfg(feature = "std")] - use std::mem; - #[cfg(not(feature = "std"))] - use core::mem; - mem::replace(&mut self.kind, HirKind::Empty) + ::core::mem::replace(&mut self.kind, HirKind::Empty) } /// Returns an empty HIR expression. @@ -1270,9 +1259,6 @@ pub enum RepetitionRange { /// space but heap space proportional to the depth of the total `Hir`. impl Drop for Hir { fn drop(&mut self) { - #[cfg(feature = "std")] - use std::mem; - #[cfg(not(feature = "std"))] use core::mem; match *self.kind() { @@ -2040,7 +2026,7 @@ mod tests { #[test] #[cfg(any(unix, windows))] fn no_stack_overflow_on_drop() { - use std::thread; + use std_test::thread; let run = || { let mut expr = Hir::empty(); diff --git a/regex-syntax/src/hir/print.rs b/regex-syntax/src/hir/print.rs index 8c7c6101e8..beacc2c380 100644 --- a/regex-syntax/src/hir/print.rs +++ b/regex-syntax/src/hir/print.rs @@ -2,9 +2,6 @@ This module provides a regular expression printer for `Hir`. */ -#[cfg(feature = "std")] -use std::fmt; -#[cfg(not(feature = "std"))] use core::fmt; use hir::{self, Hir, HirKind}; @@ -250,7 +247,7 @@ impl<'p, W: fmt::Write> Writer<'p, W> { #[cfg(test)] mod tests { use ParserBuilder; - use std::prelude::v1::*; + use std_test::prelude::v1::*; use super::Printer; fn roundtrip(given: &str, expected: &str) { diff --git a/regex-syntax/src/hir/translate.rs b/regex-syntax/src/hir/translate.rs index d192acdafb..ed047c0837 100644 --- a/regex-syntax/src/hir/translate.rs +++ b/regex-syntax/src/hir/translate.rs @@ -12,21 +12,14 @@ Defines a translator that converts an `Ast` to an `Hir`. */ -cfg_if! { - if #[cfg(feature = "std")] { - use std::cell::{Cell, RefCell}; - use std::result; - } else if #[cfg(all(feature = "alloc", not(feature = "std")))] { - use alloc::boxed::Box; - use alloc::string::ToString; - use alloc::vec::Vec; - use core::cell::{Cell, RefCell}; - use core::result; - } else { - use core::cell::{Cell, RefCell}; - use core::result; - } -} +use core::cell::{Cell, RefCell}; +use core::result; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::boxed::Box; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::string::ToString; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use ast::{self, Ast, Span, Visitor}; use hir::{self, Error, ErrorKind, Hir}; @@ -1107,7 +1100,7 @@ mod tests { use ast::{self, Ast, Position, Span}; use ast::parse::ParserBuilder; use hir::{self, Hir, HirKind}; - use std::prelude::v1::*; + use std_test::prelude::v1::*; use unicode::{self, ClassQuery}; use super::{TranslatorBuilder, ascii_class}; diff --git a/regex-syntax/src/lib.rs b/regex-syntax/src/lib.rs index daa9bccc64..8fa5b20bc4 100644 --- a/regex-syntax/src/lib.rs +++ b/regex-syntax/src/lib.rs @@ -109,9 +109,12 @@ done automatically in the `regex` crate. #![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))] #![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(slice_concat_ext))] -#[cfg(all(test, not(feature = "std")))] +#[cfg(test)] +extern crate std as std_test; + +#[cfg(feature = "std")] #[macro_use] -extern crate std; +extern crate std as core; #[cfg(all(feature = "alloc", not(feature = "std")))] #[macro_use] @@ -119,9 +122,6 @@ extern crate alloc; extern crate ucd_util; -#[macro_use] -extern crate cfg_if; - pub use error::{Error, Result}; pub use parser::{Parser, ParserBuilder}; @@ -186,9 +186,6 @@ pub fn is_meta_character(c: char) -> bool { /// `Join_Control` properties, or is in one of the `Decimal_Number`, `Mark` /// or `Connector_Punctuation` general categories. pub fn is_word_character(c: char) -> bool { - #[cfg(feature = "std")] - use std::cmp::Ordering; - #[cfg(not(feature = "std"))] use core::cmp::Ordering; use unicode_tables::perl_word::PERL_WORD; @@ -220,7 +217,7 @@ pub fn is_word_byte(c: u8) -> bool { #[cfg(test)] mod tests { - use std::prelude::v1::*; + use std_test::prelude::v1::*; use super::*; #[test] diff --git a/regex-syntax/src/unicode.rs b/regex-syntax/src/unicode.rs index 3d56f7ab1f..11b281913e 100644 --- a/regex-syntax/src/unicode.rs +++ b/regex-syntax/src/unicode.rs @@ -1,20 +1,10 @@ -cfg_if! { - if #[cfg(feature = "std")] { - use std::cmp::Ordering; - use std::result; - use std::slice; - } else if #[cfg(not(feature = "std"))] { - use alloc::vec::Vec; - use alloc::string::{String, ToString}; - use core::cmp::Ordering; - use core::result; - use core::slice; - } else { - use core::cmp::Ordering; - use core::result; - use core::slice; - } -} +use core::cmp::Ordering; +use core::result; +use core::slice; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::string::{String, ToString}; +#[cfg(all(feature = "alloc", not(feature = "std")))] +use alloc::vec::Vec; use ucd_util::{self, PropertyValues}; @@ -387,7 +377,7 @@ impl Iterator for AgeIter { #[cfg(test)] mod tests { - use std::prelude::v1::*; + use std_test::prelude::v1::*; use super::{contains_simple_case_mapping, simple_fold}; #[test] From 2cee073b4d10f87f982f5f99b9f23522f8049cb6 Mon Sep 17 00:00:00 2001 From: Zachary Pierce Date: Mon, 4 Jun 2018 19:33:29 -0700 Subject: [PATCH 3/5] Add prelude to conceal std/no-std cfg differences --- regex-syntax/src/ast/mod.rs | 17 ++++----- regex-syntax/src/ast/parse.rs | 44 +++++++++-------------- regex-syntax/src/ast/print.rs | 3 -- regex-syntax/src/ast/visitor.rs | 6 ++-- regex-syntax/src/error.rs | 18 +++------- regex-syntax/src/hir/interval.rs | 13 ++++--- regex-syntax/src/hir/literal/mod.rs | 27 ++++++--------- regex-syntax/src/hir/mod.rs | 23 +++++------- regex-syntax/src/hir/print.rs | 2 +- regex-syntax/src/hir/translate.rs | 12 ++----- regex-syntax/src/hir/visitor.rs | 3 +- regex-syntax/src/lib.rs | 10 +++--- regex-syntax/src/prelude.rs | 54 +++++++++++++++++++++++++++++ regex-syntax/src/unicode.rs | 12 +++---- 14 files changed, 122 insertions(+), 122 deletions(-) create mode 100644 regex-syntax/src/prelude.rs diff --git a/regex-syntax/src/ast/mod.rs b/regex-syntax/src/ast/mod.rs index eee591ecfb..e41cd92b58 100644 --- a/regex-syntax/src/ast/mod.rs +++ b/regex-syntax/src/ast/mod.rs @@ -12,14 +12,11 @@ Defines an abstract syntax for regular expressions. */ -use core::cmp::Ordering; -use core::fmt; +use std::cmp::Ordering; #[cfg(feature = "std")] -use core::error; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::{String, Vec}; +use std::error; +use std::fmt; +use prelude::*; pub use ast::visitor::{Visitor, visit}; @@ -235,7 +232,7 @@ impl fmt::Display for ErrorKind { match *self { CaptureLimitExceeded => { write!(f, "exceeded the maximum number of \ - capturing groups ({})", ::core::u32::MAX) + capturing groups ({})", ::std::u32::MAX) } ClassEscapeInvalid => { write!(f, "invalid escape sequence found in character class") @@ -1372,7 +1369,7 @@ pub enum Flag { /// space but heap space proportional to the depth of the `Ast`. impl Drop for Ast { fn drop(&mut self) { - use core::mem; + use std::mem; match *self { Ast::Empty(_) @@ -1422,7 +1419,7 @@ impl Drop for Ast { /// stack space but heap space proportional to the depth of the `ClassSet`. impl Drop for ClassSet { fn drop(&mut self) { - use core::mem; + use std::mem; match *self { ClassSet::Item(ref item) => { diff --git a/regex-syntax/src/ast/parse.rs b/regex-syntax/src/ast/parse.rs index aa9f6a5898..8762658f45 100644 --- a/regex-syntax/src/ast/parse.rs +++ b/regex-syntax/src/ast/parse.rs @@ -12,22 +12,10 @@ This module provides a regular expression parser. */ -use core::cell::{Cell, RefCell}; -use core::mem; -use core::result; -#[cfg(feature = "std")] -use core::prelude::v1::*; -#[cfg(feature = "std")] -use core::borrow::Borrow; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::borrow::Borrow; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::string::{String, ToString}; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use prelude::{Borrow, Box, String, ToString, Vec}; +use std::cell::{Cell, RefCell}; +use std::mem; +use std::result; use ast::{self, Ast, Position, Span}; use either::Either; @@ -1542,8 +1530,8 @@ impl<'s, P: Borrow> ParserI<'s, P> { /// /// Assuming the preconditions are met, this routine can never fail. fn parse_octal(&self) -> ast::Literal { - use core::char; - use core::u32; + use std::char; + use std::u32; assert!(self.parser().octal); assert!('0' <= self.char() && self.char() <= '7'); @@ -1608,8 +1596,8 @@ impl<'s, P: Borrow> ParserI<'s, P> { &self, kind: ast::HexLiteralKind, ) -> Result { - use core::char; - use core::u32; + use std::char; + use std::u32; let mut scratch = self.parser().scratch.borrow_mut(); scratch.clear(); @@ -1655,8 +1643,8 @@ impl<'s, P: Borrow> ParserI<'s, P> { &self, kind: ast::HexLiteralKind, ) -> Result { - use core::char; - use core::u32; + use std::char; + use std::u32; let mut scratch = self.parser().scratch.borrow_mut(); scratch.clear(); @@ -2135,7 +2123,7 @@ impl<'p, 's, P: Borrow> NestLimiter<'p, 's, P> { fn increment_depth(&mut self, span: &Span) -> Result<()> { let new = self.depth.checked_add(1).ok_or_else(|| self.p.error( span.clone(), - ast::ErrorKind::NestLimitExceeded(::core::u32::MAX), + ast::ErrorKind::NestLimitExceeded(::std::u32::MAX), ))?; let limit = self.p.parser().nest_limit; if new > limit { @@ -2268,7 +2256,7 @@ impl<'p, 's, P: Borrow> ast::Visitor for NestLimiter<'p, 's, P> { #[cfg(test)] mod tests { use std_test::prelude::v1::*; - use core::ops::Range; + use std::ops::Range; use ast::{self, Ast, Position, Span}; use super::{Parser, ParserI, ParserBuilder, Primitive}; @@ -3862,7 +3850,7 @@ bar Ok(Primitive::Literal(ast::Literal { span: span(0..pat.len()), kind: ast::LiteralKind::Octal, - c: ::core::char::from_u32(i).unwrap(), + c: ::std::char::from_u32(i).unwrap(), }))); } assert_eq!( @@ -3931,7 +3919,7 @@ bar Ok(Primitive::Literal(ast::Literal { span: span(0..pat.len()), kind: ast::LiteralKind::HexFixed(ast::HexLiteralKind::X), - c: ::core::char::from_u32(i).unwrap(), + c: ::std::char::from_u32(i).unwrap(), }))); } @@ -3958,7 +3946,7 @@ bar #[test] fn parse_hex_four() { for i in 0..65536 { - let c = match ::core::char::from_u32(i) { + let c = match ::std::char::from_u32(i) { None => continue, Some(c) => c, }; @@ -4014,7 +4002,7 @@ bar #[test] fn parse_hex_eight() { for i in 0..65536 { - let c = match ::core::char::from_u32(i) { + let c = match ::std::char::from_u32(i) { None => continue, Some(c) => c, }; diff --git a/regex-syntax/src/ast/print.rs b/regex-syntax/src/ast/print.rs index 0503528023..63a44b9b90 100644 --- a/regex-syntax/src/ast/print.rs +++ b/regex-syntax/src/ast/print.rs @@ -12,10 +12,7 @@ This module provides a regular expression printer for `Ast`. */ -#[cfg(feature = "std")] use std::fmt; -#[cfg(not(feature = "std"))] -use core::fmt; use ast::{self, Ast}; use ast::visitor::{self, Visitor}; diff --git a/regex-syntax/src/ast/visitor.rs b/regex-syntax/src/ast/visitor.rs index 93f5d5cf1c..c0bb4a3025 100644 --- a/regex-syntax/src/ast/visitor.rs +++ b/regex-syntax/src/ast/visitor.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::fmt; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use std::fmt; +use prelude::Vec; use ast::{self, Ast}; diff --git a/regex-syntax/src/error.rs b/regex-syntax/src/error.rs index b42031c5b0..ef8877045c 100644 --- a/regex-syntax/src/error.rs +++ b/regex-syntax/src/error.rs @@ -1,17 +1,9 @@ -use core::cmp; -use core::fmt; -use core::result; +use std::cmp; #[cfg(feature = "std")] use std::error; -#[cfg(feature = "std")] -use std::prelude::v1::*; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::slice::SliceConcatExt; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::string::{String, ToString}; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use std::fmt; +use std::result; +use prelude::*; use ast; use hir; @@ -291,7 +283,7 @@ impl<'p> Spans<'p> { } fn repeat_char(c: char, count: usize) -> String { - ::core::iter::repeat(c).take(count).collect() + ::std::iter::repeat(c).take(count).collect() } #[cfg(test)] diff --git a/regex-syntax/src/hir/interval.rs b/regex-syntax/src/hir/interval.rs index a4ad30d774..ea46ef04b6 100644 --- a/regex-syntax/src/hir/interval.rs +++ b/regex-syntax/src/hir/interval.rs @@ -1,10 +1,9 @@ -use core::char; -use core::cmp; -use core::fmt::Debug; -use core::slice; -use core::u8; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use std::char; +use std::cmp; +use std::fmt::Debug; +use std::slice; +use std::u8; +use prelude::Vec; // This module contains an *internal* implementation of interval sets. // diff --git a/regex-syntax/src/hir/literal/mod.rs b/regex-syntax/src/hir/literal/mod.rs index 3313702db6..33185b535f 100644 --- a/regex-syntax/src/hir/literal/mod.rs +++ b/regex-syntax/src/hir/literal/mod.rs @@ -12,19 +12,12 @@ Provides routines for extracting literal prefixes and suffixes from an `Hir`. */ -use core::cmp; -use core::fmt; -use core::iter; -use core::mem; -use core::ops; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::borrow::ToOwned; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::string::{String, ToString}; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use std::cmp; +use std::fmt; +use std::iter; +use std::mem; +use std::ops; +use prelude::*; use hir::{self, Hir, HirKind}; @@ -491,7 +484,7 @@ impl Literals { cls: &hir::ClassUnicode, reverse: bool, ) -> bool { - use core::char; + use std::char; if self.class_exceeds_limits(cls_char_count(cls)) { return false; @@ -954,7 +947,7 @@ fn position(needle: &[u8], mut haystack: &[u8]) -> Option { } fn escape_unicode(bytes: &[u8]) -> String { - let show = match ::core::str::from_utf8(bytes) { + let show = match ::std::str::from_utf8(bytes) { Ok(v) => v.to_string(), Err(_) => escape_bytes(bytes), }; @@ -987,7 +980,7 @@ fn escape_bytes(bytes: &[u8]) -> String { } fn escape_byte(byte: u8) -> String { - use core::ascii::escape_default; + use std::ascii::escape_default; let escaped: Vec = escape_default(byte).collect(); String::from_utf8_lossy(&escaped).into_owned() @@ -1008,7 +1001,7 @@ fn cls_byte_count(cls: &hir::ClassBytes) -> usize { #[cfg(test)] mod tests { use std_test::prelude::v1::*; - use core::fmt; + use std::fmt; use ParserBuilder; use hir::Hir; diff --git a/regex-syntax/src/hir/mod.rs b/regex-syntax/src/hir/mod.rs index c7b46ad60b..269273e5fd 100644 --- a/regex-syntax/src/hir/mod.rs +++ b/regex-syntax/src/hir/mod.rs @@ -12,20 +12,13 @@ Defines a high-level intermediate representation for regular expressions. */ -use core::char; -use core::cmp; -use core::fmt; -use core::u8; - +use std::char; +use std::cmp; #[cfg(feature = "std")] -use core::error; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::string::{String, ToString}; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use std::error; +use std::fmt; +use std::u8; +use prelude::*; use ast::Span; use hir::interval::{Interval, IntervalSet, IntervalSetIter}; @@ -220,7 +213,7 @@ impl Hir { /// Consumes ownership of this HIR expression and returns its underlying /// `HirKind`. pub fn into_kind(mut self) -> HirKind { - ::core::mem::replace(&mut self.kind, HirKind::Empty) + ::std::mem::replace(&mut self.kind, HirKind::Empty) } /// Returns an empty HIR expression. @@ -1259,7 +1252,7 @@ pub enum RepetitionRange { /// space but heap space proportional to the depth of the total `Hir`. impl Drop for Hir { fn drop(&mut self) { - use core::mem; + use std::mem; match *self.kind() { HirKind::Empty diff --git a/regex-syntax/src/hir/print.rs b/regex-syntax/src/hir/print.rs index beacc2c380..6da438192d 100644 --- a/regex-syntax/src/hir/print.rs +++ b/regex-syntax/src/hir/print.rs @@ -2,7 +2,7 @@ This module provides a regular expression printer for `Hir`. */ -use core::fmt; +use std::fmt; use hir::{self, Hir, HirKind}; use hir::visitor::{self, Visitor}; diff --git a/regex-syntax/src/hir/translate.rs b/regex-syntax/src/hir/translate.rs index ed047c0837..b4228fe47d 100644 --- a/regex-syntax/src/hir/translate.rs +++ b/regex-syntax/src/hir/translate.rs @@ -12,15 +12,9 @@ Defines a translator that converts an `Ast` to an `Hir`. */ -use core::cell::{Cell, RefCell}; -use core::result; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::string::ToString; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; - +use std::cell::{Cell, RefCell}; +use std::result; +use prelude::{Box, ToString, Vec}; use ast::{self, Ast, Span, Visitor}; use hir::{self, Error, ErrorKind, Hir}; use unicode::{self, ClassQuery}; diff --git a/regex-syntax/src/hir/visitor.rs b/regex-syntax/src/hir/visitor.rs index aaa531c586..134e6fb5ec 100644 --- a/regex-syntax/src/hir/visitor.rs +++ b/regex-syntax/src/hir/visitor.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use prelude::Vec; use hir::{self, Hir, HirKind}; /// A trait for visiting the high-level IR (HIR) in depth first order. diff --git a/regex-syntax/src/lib.rs b/regex-syntax/src/lib.rs index 8fa5b20bc4..d4514bd4d3 100644 --- a/regex-syntax/src/lib.rs +++ b/regex-syntax/src/lib.rs @@ -112,9 +112,9 @@ done automatically in the `regex` crate. #[cfg(test)] extern crate std as std_test; -#[cfg(feature = "std")] +#[cfg(not(feature = "std"))] #[macro_use] -extern crate std as core; +extern crate core as std; #[cfg(all(feature = "alloc", not(feature = "std")))] #[macro_use] @@ -130,11 +130,11 @@ mod either; mod error; pub mod hir; mod parser; +mod prelude; mod unicode; mod unicode_tables; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::string::String; +use prelude::String; /// Escapes all regular expression meta characters in `text`. /// @@ -186,7 +186,7 @@ pub fn is_meta_character(c: char) -> bool { /// `Join_Control` properties, or is in one of the `Decimal_Number`, `Mark` /// or `Connector_Punctuation` general categories. pub fn is_word_character(c: char) -> bool { - use core::cmp::Ordering; + use std::cmp::Ordering; use unicode_tables::perl_word::PERL_WORD; if c <= 0x7F as char && is_word_byte(c as u8) { diff --git a/regex-syntax/src/prelude.rs b/regex-syntax/src/prelude.rs new file mode 100644 index 0000000000..918f856e5c --- /dev/null +++ b/regex-syntax/src/prelude.rs @@ -0,0 +1,54 @@ +//! This module provides access to items available in both the standard library +//! and the `alloc` facade crate while concealing the feature-flag based compile +//! time selection between those options. +#![allow(unused_imports)] + +macro_rules! multiplex_alloc { + ($($alloc: path, $std: path),*) => { + $( + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub(crate) use $alloc; + #[cfg(feature = "std")] + pub(crate) use $std; + )* + }; +} + +macro_rules! multiplex_core { + ($($core: path, $std: path),*) => { + $( + #[cfg(not(feature = "std"))] + pub(crate) use $core; + #[cfg(feature = "std")] + pub(crate) use $std; + )* + }; +} + +macro_rules! alloc_only { + ($($alloc: path),*) => { + $( + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub(crate) use $alloc; + )* + }; +} + +multiplex_alloc! { + alloc::borrow::Borrow, ::std::borrow::Borrow, + alloc::borrow::ToOwned, ::std::borrow::ToOwned, + alloc::boxed::Box, ::std::boxed::Box, + alloc::String, ::std::string::String, + alloc::string::ToString, ::std::string::ToString, + alloc::Vec, ::std::vec::Vec +} + +multiplex_core! { + core::fmt, ::std::fmt, + core::slice, ::std::slice +} + +alloc_only! { + alloc::slice::SliceConcatExt +} + diff --git a/regex-syntax/src/unicode.rs b/regex-syntax/src/unicode.rs index 11b281913e..1818061395 100644 --- a/regex-syntax/src/unicode.rs +++ b/regex-syntax/src/unicode.rs @@ -1,10 +1,6 @@ -use core::cmp::Ordering; -use core::result; -use core::slice; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::string::{String, ToString}; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::vec::Vec; +use std::cmp::Ordering; +use std::result; +use prelude::{String, ToString, Vec}; use ucd_util::{self, PropertyValues}; @@ -32,7 +28,7 @@ pub enum Error { /// An iterator over a codepoint's simple case equivalence class. #[derive(Debug)] -pub struct SimpleFoldIter(slice::Iter<'static, char>); +pub struct SimpleFoldIter(::std::slice::Iter<'static, char>); impl Iterator for SimpleFoldIter { type Item = char; From 060e9a448230ae86ad45531b0813e511c537fd5e Mon Sep 17 00:00:00 2001 From: Zachary Pierce Date: Mon, 4 Jun 2018 19:47:05 -0700 Subject: [PATCH 4/5] Also run regex-syntax tests in no_std mode for ci --- ci/script.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/script.sh b/ci/script.sh index 64fafc0d37..072d9ad1b6 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -20,6 +20,7 @@ ci/run-shootout-test # Run tests on regex-syntax crate. cargo test --verbose --manifest-path regex-syntax/Cargo.toml +cargo test --verbose --manifest-path regex-syntax/Cargo.toml --no-default-features --features "alloc" cargo doc --verbose --manifest-path regex-syntax/Cargo.toml # Run tests on regex-capi crate. From 23d053325069ac513a921a4cc7b78158d69ea912 Mon Sep 17 00:00:00 2001 From: Zachary Pierce Date: Mon, 4 Jun 2018 20:01:49 -0700 Subject: [PATCH 5/5] Only run the regex-syntax no_std tests on nightly --- ci/script.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/script.sh b/ci/script.sh index 072d9ad1b6..664349c374 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -20,9 +20,12 @@ ci/run-shootout-test # Run tests on regex-syntax crate. cargo test --verbose --manifest-path regex-syntax/Cargo.toml -cargo test --verbose --manifest-path regex-syntax/Cargo.toml --no-default-features --features "alloc" cargo doc --verbose --manifest-path regex-syntax/Cargo.toml +if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then + cargo test --verbose --manifest-path regex-syntax/Cargo.toml --no-default-features --features "alloc" +fi + # Run tests on regex-capi crate. cargo build --verbose --manifest-path regex-capi/Cargo.toml (cd regex-capi/ctest && ./compile && LD_LIBRARY_PATH=../../target/debug ./test)