Auto merge of #39818 - frewsxcv:rollup, r=frewsxcv
Rollup of 8 pull requests - Successful merges: #39659, #39730, #39754, #39772, #39785, #39788, #39790, #39813 - Failed merges:
This commit is contained in:
30
.travis.yml
30
.travis.yml
@@ -74,6 +74,20 @@ matrix:
|
|||||||
osx_image: xcode8.2
|
osx_image: xcode8.2
|
||||||
install: *osx_install_sccache
|
install: *osx_install_sccache
|
||||||
|
|
||||||
|
# "alternate" deployments, these are "nightlies" but don't have assertions
|
||||||
|
# turned on, they're deployed to a different location primarily for projects
|
||||||
|
# which are stuck on nightly and don't want llvm assertions in the artifacts
|
||||||
|
# that they use.
|
||||||
|
- env: IMAGE=dist-x86-linux DEPLOY_ALT=1
|
||||||
|
- env: >
|
||||||
|
RUST_CHECK_TARGET=dist
|
||||||
|
RUST_CONFIGURE_ARGS="--enable-extended"
|
||||||
|
SRC=.
|
||||||
|
DEPLOY_ALT=1
|
||||||
|
os: osx
|
||||||
|
osx_image: xcode8.2
|
||||||
|
install: *osx_install_sccache
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- SCCACHE_BUCKET=rust-lang-ci-sccache
|
- SCCACHE_BUCKET=rust-lang-ci-sccache
|
||||||
@@ -134,3 +148,19 @@ deploy:
|
|||||||
on:
|
on:
|
||||||
branch: auto
|
branch: auto
|
||||||
condition: $DEPLOY = 1
|
condition: $DEPLOY = 1
|
||||||
|
|
||||||
|
# this is the same as the above deployment provider except that it uploads to
|
||||||
|
# a slightly different directory and has a different trigger
|
||||||
|
- provider: s3
|
||||||
|
bucket: rust-lang-ci
|
||||||
|
skip_cleanup: true
|
||||||
|
local_dir: deploy
|
||||||
|
upload_dir: rustc-builds-alt
|
||||||
|
acl: public_read
|
||||||
|
region: us-east-1
|
||||||
|
access_key_id: AKIAIPQVNYF2T3DTYIWQ
|
||||||
|
secret_access_key:
|
||||||
|
secure: "FBqDqOTeIPMu6v/WYPf4CFSlh9rLRZGKVtpLa5KkyuOhXRTrnEzBduEtS8/FMIxdQImvurhSvxWvqRybMOi4qoVfjMqqpHAI7uBbidbrvAcJoHNsx6BgUNVCIoH6a0UsAjTUtm6/YPIpzbHoLZXPL0GrHPMk6Mu04qVSmcYNWn4="
|
||||||
|
on:
|
||||||
|
branch: auto
|
||||||
|
condition: $DEPLOY_ALT = 1
|
||||||
|
|||||||
22
appveyor.yml
22
appveyor.yml
@@ -60,6 +60,12 @@ environment:
|
|||||||
MINGW_DIR: mingw64
|
MINGW_DIR: mingw64
|
||||||
DEPLOY: 1
|
DEPLOY: 1
|
||||||
|
|
||||||
|
# "alternate" deployment, see .travis.yml for more info
|
||||||
|
- MSYS_BITS: 64
|
||||||
|
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended
|
||||||
|
SCRIPT: python x.py dist
|
||||||
|
DEPLOY_ALT: 1
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
@@ -145,6 +151,22 @@ deploy:
|
|||||||
branch: auto
|
branch: auto
|
||||||
DEPLOY: 1
|
DEPLOY: 1
|
||||||
|
|
||||||
|
# This provider is the same as the one above except that it has a slightly
|
||||||
|
# different upload directory and a slightly different trigger
|
||||||
|
- provider: S3
|
||||||
|
skip_cleanup: true
|
||||||
|
access_key_id: AKIAIPQVNYF2T3DTYIWQ
|
||||||
|
secret_access_key:
|
||||||
|
secure: +11jsUNFTQ9dq5Ad1i2+PeUJaXluFJ0zIJAXESE1dFT3Kdjku4/eDdgyjgsB6GnV
|
||||||
|
bucket: rust-lang-ci
|
||||||
|
set_public: true
|
||||||
|
region: us-east-1
|
||||||
|
artifact: /.*/
|
||||||
|
folder: rustc-builds-alt
|
||||||
|
on:
|
||||||
|
branch: auto
|
||||||
|
DEPLOY_ALT: 1
|
||||||
|
|
||||||
# init:
|
# init:
|
||||||
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
# on_finish:
|
# on_finish:
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ exec docker \
|
|||||||
$args \
|
$args \
|
||||||
--env CARGO_HOME=/cargo \
|
--env CARGO_HOME=/cargo \
|
||||||
--env DEPLOY=$DEPLOY \
|
--env DEPLOY=$DEPLOY \
|
||||||
|
--env DEPLOY_ALT=$DEPLOY_ALT \
|
||||||
--env LOCAL_USER_ID=`id -u` \
|
--env LOCAL_USER_ID=`id -u` \
|
||||||
--volume "$HOME/.cargo:/cargo" \
|
--volume "$HOME/.cargo:/cargo" \
|
||||||
--rm \
|
--rm \
|
||||||
|
|||||||
@@ -31,12 +31,14 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps"
|
|||||||
#
|
#
|
||||||
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
||||||
# either automatically or manually.
|
# either automatically or manually.
|
||||||
if [ "$DEPLOY" != "" ]; then
|
if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
|
||||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=nightly"
|
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=nightly"
|
||||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
|
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
|
||||||
|
|
||||||
if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then
|
if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then
|
||||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
|
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
|
||||||
|
elif [ "$DEPLOY_ALT" != "" ]; then
|
||||||
|
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-debug-assertions"
|
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-debug-assertions"
|
||||||
|
|||||||
@@ -117,22 +117,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCamelCaseTypes {
|
|||||||
|
|
||||||
match it.node {
|
match it.node {
|
||||||
hir::ItemTy(..) |
|
hir::ItemTy(..) |
|
||||||
|
hir::ItemEnum(..) |
|
||||||
hir::ItemStruct(..) |
|
hir::ItemStruct(..) |
|
||||||
hir::ItemUnion(..) => self.check_case(cx, "type", it.name, it.span),
|
hir::ItemUnion(..) => self.check_case(cx, "type", it.name, it.span),
|
||||||
hir::ItemTrait(..) => self.check_case(cx, "trait", it.name, it.span),
|
hir::ItemTrait(..) => self.check_case(cx, "trait", it.name, it.span),
|
||||||
hir::ItemEnum(ref enum_definition, _) => {
|
|
||||||
if has_extern_repr {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.check_case(cx, "type", it.name, it.span);
|
|
||||||
for variant in &enum_definition.variants {
|
|
||||||
self.check_case(cx, "variant", variant.node.name, variant.span);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_variant(&mut self, cx: &LateContext, v: &hir::Variant, _: &hir::Generics) {
|
||||||
|
self.check_case(cx, "variant", v.node.name, v.span);
|
||||||
|
}
|
||||||
|
|
||||||
fn check_generics(&mut self, cx: &LateContext, it: &hir::Generics) {
|
fn check_generics(&mut self, cx: &LateContext, it: &hir::Generics) {
|
||||||
for gen in it.ty_params.iter() {
|
for gen in it.ty_params.iter() {
|
||||||
self.check_case(cx, "type parameter", gen.name, gen.span);
|
self.check_case(cx, "type parameter", gen.name, gen.span);
|
||||||
|
|||||||
@@ -155,7 +155,8 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
|||||||
let mut opts = TestOptions::default();
|
let mut opts = TestOptions::default();
|
||||||
opts.no_crate_inject = true;
|
opts.no_crate_inject = true;
|
||||||
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
|
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
|
||||||
true, opts, maybe_sysroot, None);
|
true, opts, maybe_sysroot, None,
|
||||||
|
Some(input.to_owned()));
|
||||||
find_testable_code(&input_str, &mut collector, DUMMY_SP);
|
find_testable_code(&input_str, &mut collector, DUMMY_SP);
|
||||||
test_args.insert(0, "rustdoctest".to_string());
|
test_args.insert(0, "rustdoctest".to_string());
|
||||||
testing::test_main(&test_args, collector.tests);
|
testing::test_main(&test_args, collector.tests);
|
||||||
|
|||||||
@@ -104,7 +104,8 @@ pub fn run(input: &str,
|
|||||||
false,
|
false,
|
||||||
opts,
|
opts,
|
||||||
maybe_sysroot,
|
maybe_sysroot,
|
||||||
Some(codemap));
|
Some(codemap),
|
||||||
|
None);
|
||||||
|
|
||||||
{
|
{
|
||||||
let dep_graph = DepGraph::new(false);
|
let dep_graph = DepGraph::new(false);
|
||||||
@@ -391,12 +392,13 @@ pub struct Collector {
|
|||||||
maybe_sysroot: Option<PathBuf>,
|
maybe_sysroot: Option<PathBuf>,
|
||||||
position: Span,
|
position: Span,
|
||||||
codemap: Option<Rc<CodeMap>>,
|
codemap: Option<Rc<CodeMap>>,
|
||||||
|
filename: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collector {
|
impl Collector {
|
||||||
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||||
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
|
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
|
||||||
codemap: Option<Rc<CodeMap>>) -> Collector {
|
codemap: Option<Rc<CodeMap>>, filename: Option<String>) -> Collector {
|
||||||
Collector {
|
Collector {
|
||||||
tests: Vec::new(),
|
tests: Vec::new(),
|
||||||
names: Vec::new(),
|
names: Vec::new(),
|
||||||
@@ -411,6 +413,7 @@ impl Collector {
|
|||||||
maybe_sysroot: maybe_sysroot,
|
maybe_sysroot: maybe_sysroot,
|
||||||
position: DUMMY_SP,
|
position: DUMMY_SP,
|
||||||
codemap: codemap,
|
codemap: codemap,
|
||||||
|
filename: filename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,6 +486,8 @@ impl Collector {
|
|||||||
pub fn get_filename(&self) -> String {
|
pub fn get_filename(&self) -> String {
|
||||||
if let Some(ref codemap) = self.codemap {
|
if let Some(ref codemap) = self.codemap {
|
||||||
codemap.span_to_filename(self.position)
|
codemap.span_to_filename(self.position)
|
||||||
|
} else if let Some(ref filename) = self.filename {
|
||||||
|
filename.clone()
|
||||||
} else {
|
} else {
|
||||||
"<input>".to_owned()
|
"<input>".to_owned()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,368 @@ pub trait AsciiExt {
|
|||||||
/// [`to_ascii_lowercase`]: #tymethod.to_ascii_lowercase
|
/// [`to_ascii_lowercase`]: #tymethod.to_ascii_lowercase
|
||||||
#[stable(feature = "ascii", since = "1.9.0")]
|
#[stable(feature = "ascii", since = "1.9.0")]
|
||||||
fn make_ascii_lowercase(&mut self);
|
fn make_ascii_lowercase(&mut self);
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII alphabetic character:
|
||||||
|
/// U+0041 'A' ... U+005A 'Z' or U+0061 'a' ... U+007A 'z'.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII alphabetic.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(A.is_ascii_alphabetic());
|
||||||
|
/// assert!(G.is_ascii_alphabetic());
|
||||||
|
/// assert!(a.is_ascii_alphabetic());
|
||||||
|
/// assert!(g.is_ascii_alphabetic());
|
||||||
|
/// assert!(!zero.is_ascii_alphabetic());
|
||||||
|
/// assert!(!percent.is_ascii_alphabetic());
|
||||||
|
/// assert!(!space.is_ascii_alphabetic());
|
||||||
|
/// assert!(!lf.is_ascii_alphabetic());
|
||||||
|
/// assert!(!esc.is_ascii_alphabetic());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_alphabetic(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII uppercase character:
|
||||||
|
/// U+0041 'A' ... U+005A 'Z'.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII uppercase.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(A.is_ascii_uppercase());
|
||||||
|
/// assert!(G.is_ascii_uppercase());
|
||||||
|
/// assert!(!a.is_ascii_uppercase());
|
||||||
|
/// assert!(!g.is_ascii_uppercase());
|
||||||
|
/// assert!(!zero.is_ascii_uppercase());
|
||||||
|
/// assert!(!percent.is_ascii_uppercase());
|
||||||
|
/// assert!(!space.is_ascii_uppercase());
|
||||||
|
/// assert!(!lf.is_ascii_uppercase());
|
||||||
|
/// assert!(!esc.is_ascii_uppercase());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_uppercase(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII lowercase character:
|
||||||
|
/// U+0061 'a' ... U+007A 'z'.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII lowercase.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(!A.is_ascii_lowercase());
|
||||||
|
/// assert!(!G.is_ascii_lowercase());
|
||||||
|
/// assert!(a.is_ascii_lowercase());
|
||||||
|
/// assert!(g.is_ascii_lowercase());
|
||||||
|
/// assert!(!zero.is_ascii_lowercase());
|
||||||
|
/// assert!(!percent.is_ascii_lowercase());
|
||||||
|
/// assert!(!space.is_ascii_lowercase());
|
||||||
|
/// assert!(!lf.is_ascii_lowercase());
|
||||||
|
/// assert!(!esc.is_ascii_lowercase());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_lowercase(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII alphanumeric character:
|
||||||
|
/// U+0041 'A' ... U+005A 'Z', U+0061 'a' ... U+007A 'z', or
|
||||||
|
/// U+0030 '0' ... U+0039 '9'.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII alphanumeric.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(A.is_ascii_alphanumeric());
|
||||||
|
/// assert!(G.is_ascii_alphanumeric());
|
||||||
|
/// assert!(a.is_ascii_alphanumeric());
|
||||||
|
/// assert!(g.is_ascii_alphanumeric());
|
||||||
|
/// assert!(zero.is_ascii_alphanumeric());
|
||||||
|
/// assert!(!percent.is_ascii_alphanumeric());
|
||||||
|
/// assert!(!space.is_ascii_alphanumeric());
|
||||||
|
/// assert!(!lf.is_ascii_alphanumeric());
|
||||||
|
/// assert!(!esc.is_ascii_alphanumeric());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_alphanumeric(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII decimal digit:
|
||||||
|
/// U+0030 '0' ... U+0039 '9'.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII digits.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(!A.is_ascii_digit());
|
||||||
|
/// assert!(!G.is_ascii_digit());
|
||||||
|
/// assert!(!a.is_ascii_digit());
|
||||||
|
/// assert!(!g.is_ascii_digit());
|
||||||
|
/// assert!(zero.is_ascii_digit());
|
||||||
|
/// assert!(!percent.is_ascii_digit());
|
||||||
|
/// assert!(!space.is_ascii_digit());
|
||||||
|
/// assert!(!lf.is_ascii_digit());
|
||||||
|
/// assert!(!esc.is_ascii_digit());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_digit(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII hexadecimal digit:
|
||||||
|
/// U+0030 '0' ... U+0039 '9', U+0041 'A' ... U+0046 'F', or
|
||||||
|
/// U+0061 'a' ... U+0066 'f'.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII hex digits.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(A.is_ascii_hexdigit());
|
||||||
|
/// assert!(!G.is_ascii_hexdigit());
|
||||||
|
/// assert!(a.is_ascii_hexdigit());
|
||||||
|
/// assert!(!g.is_ascii_hexdigit());
|
||||||
|
/// assert!(zero.is_ascii_hexdigit());
|
||||||
|
/// assert!(!percent.is_ascii_hexdigit());
|
||||||
|
/// assert!(!space.is_ascii_hexdigit());
|
||||||
|
/// assert!(!lf.is_ascii_hexdigit());
|
||||||
|
/// assert!(!esc.is_ascii_hexdigit());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_hexdigit(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII punctuation character:
|
||||||
|
/// U+0021 ... U+002F `! " # $ % & ' ( ) * + , - . /`
|
||||||
|
/// U+003A ... U+0040 `: ; < = > ? @`
|
||||||
|
/// U+005B ... U+0060 `[ \\ ] ^ _ \``
|
||||||
|
/// U+007B ... U+007E `{ | } ~`
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII punctuation.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(!A.is_ascii_punctuation());
|
||||||
|
/// assert!(!G.is_ascii_punctuation());
|
||||||
|
/// assert!(!a.is_ascii_punctuation());
|
||||||
|
/// assert!(!g.is_ascii_punctuation());
|
||||||
|
/// assert!(!zero.is_ascii_punctuation());
|
||||||
|
/// assert!(percent.is_ascii_punctuation());
|
||||||
|
/// assert!(!space.is_ascii_punctuation());
|
||||||
|
/// assert!(!lf.is_ascii_punctuation());
|
||||||
|
/// assert!(!esc.is_ascii_punctuation());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_punctuation(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII graphic character:
|
||||||
|
/// U+0021 '@' ... U+007E '~'.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII punctuation.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(A.is_ascii_graphic());
|
||||||
|
/// assert!(G.is_ascii_graphic());
|
||||||
|
/// assert!(a.is_ascii_graphic());
|
||||||
|
/// assert!(g.is_ascii_graphic());
|
||||||
|
/// assert!(zero.is_ascii_graphic());
|
||||||
|
/// assert!(percent.is_ascii_graphic());
|
||||||
|
/// assert!(!space.is_ascii_graphic());
|
||||||
|
/// assert!(!lf.is_ascii_graphic());
|
||||||
|
/// assert!(!esc.is_ascii_graphic());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_graphic(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII whitespace character:
|
||||||
|
/// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
|
||||||
|
/// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
|
||||||
|
/// For strings, true if all characters in the string are
|
||||||
|
/// ASCII whitespace.
|
||||||
|
///
|
||||||
|
/// Rust uses the WhatWG Infra Standard's [definition of ASCII
|
||||||
|
/// whitespace][infra-aw]. There are several other definitions in
|
||||||
|
/// wide use. For instance, [the POSIX locale][pct] includes
|
||||||
|
/// U+000B VERTICAL TAB as well as all the above characters,
|
||||||
|
/// but—from the very same specification—[the default rule for
|
||||||
|
/// "field splitting" in the Bourne shell][bfs] considers *only*
|
||||||
|
/// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
|
||||||
|
///
|
||||||
|
/// If you are writing a program that will process an existing
|
||||||
|
/// file format, check what that format's definition of whitespace is
|
||||||
|
/// before using this function.
|
||||||
|
///
|
||||||
|
/// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
|
||||||
|
/// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
|
||||||
|
/// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(!A.is_ascii_whitespace());
|
||||||
|
/// assert!(!G.is_ascii_whitespace());
|
||||||
|
/// assert!(!a.is_ascii_whitespace());
|
||||||
|
/// assert!(!g.is_ascii_whitespace());
|
||||||
|
/// assert!(!zero.is_ascii_whitespace());
|
||||||
|
/// assert!(!percent.is_ascii_whitespace());
|
||||||
|
/// assert!(space.is_ascii_whitespace());
|
||||||
|
/// assert!(lf.is_ascii_whitespace());
|
||||||
|
/// assert!(!esc.is_ascii_whitespace());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_whitespace(&self) -> bool { unimplemented!(); }
|
||||||
|
|
||||||
|
/// Checks if the value is an ASCII control character:
|
||||||
|
/// U+0000 NUL ... U+001F UNIT SEPARATOR, or U+007F DELETE.
|
||||||
|
/// Note that most ASCII whitespace characters are control
|
||||||
|
/// characters, but SPACE is not.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ascii_ctype)]
|
||||||
|
/// # #![allow(non_snake_case)]
|
||||||
|
/// use std::ascii::AsciiExt;
|
||||||
|
/// let A = 'A';
|
||||||
|
/// let G = 'G';
|
||||||
|
/// let a = 'a';
|
||||||
|
/// let g = 'g';
|
||||||
|
/// let zero = '0';
|
||||||
|
/// let percent = '%';
|
||||||
|
/// let space = ' ';
|
||||||
|
/// let lf = '\n';
|
||||||
|
/// let esc = '\u{001b}';
|
||||||
|
///
|
||||||
|
/// assert!(!A.is_ascii_control());
|
||||||
|
/// assert!(!G.is_ascii_control());
|
||||||
|
/// assert!(!a.is_ascii_control());
|
||||||
|
/// assert!(!g.is_ascii_control());
|
||||||
|
/// assert!(!zero.is_ascii_control());
|
||||||
|
/// assert!(!percent.is_ascii_control());
|
||||||
|
/// assert!(!space.is_ascii_control());
|
||||||
|
/// assert!(lf.is_ascii_control());
|
||||||
|
/// assert!(esc.is_ascii_control());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ascii_ctype", issue = "39658")]
|
||||||
|
fn is_ascii_control(&self) -> bool { unimplemented!(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@@ -225,6 +587,56 @@ impl AsciiExt for str {
|
|||||||
let me: &mut [u8] = unsafe { mem::transmute(self) };
|
let me: &mut [u8] = unsafe { mem::transmute(self) };
|
||||||
me.make_ascii_lowercase()
|
me.make_ascii_lowercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphabetic(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_alphabetic())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_uppercase(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_uppercase())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_lowercase(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_lowercase())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphanumeric(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_alphanumeric())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_digit(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_digit())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_hexdigit(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_hexdigit())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_punctuation(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_punctuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_graphic(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_graphic())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_whitespace(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_whitespace())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_control(&self) -> bool {
|
||||||
|
self.bytes().all(|b| b.is_ascii_control())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@@ -268,6 +680,56 @@ impl AsciiExt for [u8] {
|
|||||||
byte.make_ascii_lowercase();
|
byte.make_ascii_lowercase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphabetic(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_alphabetic())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_uppercase(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_uppercase())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_lowercase(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_lowercase())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphanumeric(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_alphanumeric())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_digit(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_digit())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_hexdigit(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_hexdigit())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_punctuation(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_punctuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_graphic(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_graphic())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_whitespace(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_whitespace())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_control(&self) -> bool {
|
||||||
|
self.iter().all(|b| b.is_ascii_control())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@@ -287,6 +749,96 @@ impl AsciiExt for u8 {
|
|||||||
fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
|
fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
|
fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphabetic(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false; }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
L|Lx|U|Ux => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_uppercase(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
U|Ux => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_lowercase(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
L|Lx => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphanumeric(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
D|L|Lx|U|Ux => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_digit(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
D => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_hexdigit(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
D|Lx|Ux => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_punctuation(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
P => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_graphic(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false; }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
Ux|U|Lx|L|D|P => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_whitespace(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false; }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
Cw|W => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_control(&self) -> bool {
|
||||||
|
if *self >= 0x80 { return false; }
|
||||||
|
match ASCII_CHARACTER_CLASS[*self as usize] {
|
||||||
|
C|Cw => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@@ -324,6 +876,56 @@ impl AsciiExt for char {
|
|||||||
fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
|
fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
|
fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphabetic(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_alphabetic()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_uppercase(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_uppercase()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_lowercase(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_lowercase()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_alphanumeric(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_alphanumeric()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_digit(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_digit()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_hexdigit(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_hexdigit()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_punctuation(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_punctuation()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_graphic(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_graphic()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_whitespace(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_whitespace()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_ascii_control(&self) -> bool {
|
||||||
|
(*self as u32 <= 0x7f) && (*self as u8).is_ascii_control()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over the escaped version of a byte, constructed via
|
/// An iterator over the escaped version of a byte, constructed via
|
||||||
@@ -485,6 +1087,30 @@ static ASCII_UPPERCASE_MAP: [u8; 256] = [
|
|||||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
enum AsciiCharacterClass {
|
||||||
|
C, // control
|
||||||
|
Cw, // control whitespace
|
||||||
|
W, // whitespace
|
||||||
|
D, // digit
|
||||||
|
L, // lowercase
|
||||||
|
Lx, // lowercase hex digit
|
||||||
|
U, // uppercase
|
||||||
|
Ux, // uppercase hex digit
|
||||||
|
P, // punctuation
|
||||||
|
}
|
||||||
|
use self::AsciiCharacterClass::*;
|
||||||
|
|
||||||
|
static ASCII_CHARACTER_CLASS: [AsciiCharacterClass; 128] = [
|
||||||
|
// _0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f
|
||||||
|
C, C, C, C, C, C, C, C, C, Cw,Cw,C, Cw,Cw,C, C, // 0_
|
||||||
|
C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, // 1_
|
||||||
|
W, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, // 2_
|
||||||
|
D, D, D, D, D, D, D, D, D, D, P, P, P, P, P, P, // 3_
|
||||||
|
P, Ux,Ux,Ux,Ux,Ux,Ux,U, U, U, U, U, U, U, U, U, // 4_
|
||||||
|
U, U, U, U, U, U, U, U, U, U, U, P, P, P, P, P, // 5_
|
||||||
|
P, Lx,Lx,Lx,Lx,Lx,Lx,L, L, L, L, L, L, L, L, L, // 6_
|
||||||
|
L, L, L, L, L, L, L, L, L, L, L, P, P, P, P, C, // 7_
|
||||||
|
];
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -606,4 +1232,236 @@ mod tests {
|
|||||||
let x = "a".to_string();
|
let x = "a".to_string();
|
||||||
x.eq_ignore_ascii_case("A");
|
x.eq_ignore_ascii_case("A");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shorthands used by the is_ascii_* tests.
|
||||||
|
macro_rules! assert_all {
|
||||||
|
($what:ident, $($str:tt),+) => {{
|
||||||
|
$(
|
||||||
|
for b in $str.chars() {
|
||||||
|
if !b.$what() {
|
||||||
|
panic!("expected {}({}) but it isn't",
|
||||||
|
stringify!($what), b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for b in $str.as_bytes().iter() {
|
||||||
|
if !b.$what() {
|
||||||
|
panic!("expected {}(0x{:02x})) but it isn't",
|
||||||
|
stringify!($what), b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!($str.$what());
|
||||||
|
assert!($str.as_bytes().$what());
|
||||||
|
)+
|
||||||
|
}};
|
||||||
|
($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+))
|
||||||
|
}
|
||||||
|
macro_rules! assert_none {
|
||||||
|
($what:ident, $($str:tt),+) => {{
|
||||||
|
$(
|
||||||
|
for b in $str.chars() {
|
||||||
|
if b.$what() {
|
||||||
|
panic!("expected not-{}({}) but it is",
|
||||||
|
stringify!($what), b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for b in $str.as_bytes().iter() {
|
||||||
|
if b.$what() {
|
||||||
|
panic!("expected not-{}(0x{:02x})) but it is",
|
||||||
|
stringify!($what), b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}};
|
||||||
|
($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_alphabetic() {
|
||||||
|
assert_all!(is_ascii_alphabetic,
|
||||||
|
"",
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_alphabetic,
|
||||||
|
"0123456789",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_uppercase() {
|
||||||
|
assert_all!(is_ascii_uppercase,
|
||||||
|
"",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_uppercase,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"0123456789",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_lowercase() {
|
||||||
|
assert_all!(is_ascii_lowercase,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_lowercase,
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"0123456789",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_alphanumeric() {
|
||||||
|
assert_all!(is_ascii_alphanumeric,
|
||||||
|
"",
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"0123456789",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_alphanumeric,
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_digit() {
|
||||||
|
assert_all!(is_ascii_digit,
|
||||||
|
"",
|
||||||
|
"0123456789",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_digit,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_hexdigit() {
|
||||||
|
assert_all!(is_ascii_hexdigit,
|
||||||
|
"",
|
||||||
|
"0123456789",
|
||||||
|
"abcdefABCDEF",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_hexdigit,
|
||||||
|
"ghijklmnopqrstuvwxyz",
|
||||||
|
"GHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_punctuation() {
|
||||||
|
assert_all!(is_ascii_punctuation,
|
||||||
|
"",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_punctuation,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"0123456789",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_graphic() {
|
||||||
|
assert_all!(is_ascii_graphic,
|
||||||
|
"",
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"0123456789",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_graphic,
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_whitespace() {
|
||||||
|
assert_all!(is_ascii_whitespace,
|
||||||
|
"",
|
||||||
|
" \t\n\x0c\r",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_whitespace,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"0123456789",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x0b\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ascii_control() {
|
||||||
|
assert_all!(is_ascii_control,
|
||||||
|
"",
|
||||||
|
"\x00\x01\x02\x03\x04\x05\x06\x07",
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17",
|
||||||
|
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
||||||
|
"\x7f",
|
||||||
|
);
|
||||||
|
assert_none!(is_ascii_control,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
|
||||||
|
"0123456789",
|
||||||
|
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
|
||||||
|
" ",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,11 +302,20 @@ impl<'a> Parser<'a> {
|
|||||||
if i + 1 < tts.len() {
|
if i + 1 < tts.len() {
|
||||||
self.tts.push((tts, i + 1));
|
self.tts.push((tts, i + 1));
|
||||||
}
|
}
|
||||||
if let TokenTree::Token(sp, tok) = tt {
|
// FIXME(jseyfried): remove after fixing #39390 in #39419.
|
||||||
TokenAndSpan { tok: tok, sp: sp }
|
if self.quote_depth > 0 {
|
||||||
} else {
|
if let TokenTree::Sequence(sp, _) = tt {
|
||||||
self.tts.push((tt, 0));
|
self.span_err(sp, "attempted to repeat an expression containing no \
|
||||||
continue
|
syntax variables matched as repeating at this depth");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match tt {
|
||||||
|
TokenTree::Token(sp, tok) => TokenAndSpan { tok: tok, sp: sp },
|
||||||
|
_ if tt.len() > 0 => {
|
||||||
|
self.tts.push((tt, 0));
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TokenAndSpan { tok: token::Eof, sp: self.span }
|
TokenAndSpan { tok: token::Eof, sp: self.span }
|
||||||
|
|||||||
24
src/test/compile-fail/feature-gate-staged_api.rs
Normal file
24
src/test/compile-fail/feature-gate-staged_api.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![stable(feature = "a", since = "b")]
|
||||||
|
//~^ ERROR stability attributes may not be used outside of the standard library
|
||||||
|
mod inner_private_module {
|
||||||
|
// UnnameableTypeAlias isn't marked as reachable, so no stability annotation is required here
|
||||||
|
pub type UnnameableTypeAlias = u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "a", since = "b")]
|
||||||
|
//~^ ERROR stability attributes may not be used outside of the standard library
|
||||||
|
pub fn f() -> inner_private_module::UnnameableTypeAlias {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
@@ -8,14 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
static mut ANSWER: i32 = 0;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let t1 = thread::spawn(|| unsafe { ANSWER = 42 });
|
println!("{}", { macro_rules! x { ($()*) => {} } 33 });
|
||||||
unsafe {
|
//~^ ERROR no syntax variables matched as repeating at this depth
|
||||||
ANSWER = 24;
|
|
||||||
}
|
|
||||||
t1.join().ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
-include ../tools.mk
|
|
||||||
|
|
||||||
ifdef SANITIZER_SUPPORT
|
|
||||||
all:
|
|
||||||
$(RUSTC) -g -Z sanitizer=thread -Z print-link-args racy.rs | grep -q librustc_tsan
|
|
||||||
$(TMPDIR)/racy 2>&1 | grep -q 'data race'
|
|
||||||
else
|
|
||||||
all:
|
|
||||||
|
|
||||||
endif
|
|
||||||
18
src/test/run-pass/test-allow-non-camel-case-variant.rs
Normal file
18
src/test/run-pass/test-allow-non-camel-case-variant.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![deny(non_camel_case_types)]
|
||||||
|
|
||||||
|
pub enum Foo {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
bar
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
@@ -167,7 +167,7 @@ pub fn check(path: &Path, bad: &mut bool) {
|
|||||||
// FIXME get this whitelist empty.
|
// FIXME get this whitelist empty.
|
||||||
let whitelist = vec![
|
let whitelist = vec![
|
||||||
"abi_ptx", "simd", "static_recursion",
|
"abi_ptx", "simd", "static_recursion",
|
||||||
"cfg_target_has_atomic", "staged_api",
|
"cfg_target_has_atomic",
|
||||||
"unboxed_closures", "stmt_expr_attributes",
|
"unboxed_closures", "stmt_expr_attributes",
|
||||||
"cfg_target_thread_local", "unwind_attributes",
|
"cfg_target_thread_local", "unwind_attributes",
|
||||||
"inclusive_range_syntax"
|
"inclusive_range_syntax"
|
||||||
|
|||||||
@@ -38,6 +38,60 @@ http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|||||||
option. This file may not be copied, modified, or distributed
|
option. This file may not be copied, modified, or distributed
|
||||||
except according to those terms.";
|
except according to those terms.";
|
||||||
|
|
||||||
|
/// Parser states for line_is_url.
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
enum LIUState { EXP_COMMENT_START,
|
||||||
|
EXP_LINK_LABEL_OR_URL,
|
||||||
|
EXP_URL,
|
||||||
|
EXP_END }
|
||||||
|
|
||||||
|
/// True if LINE appears to be a line comment containing an URL,
|
||||||
|
/// possibly with a Markdown link label in front, and nothing else.
|
||||||
|
/// The Markdown link label, if present, may not contain whitespace.
|
||||||
|
/// Lines of this form are allowed to be overlength, because Markdown
|
||||||
|
/// offers no way to split a line in the middle of a URL, and the lengths
|
||||||
|
/// of URLs to external references are beyond our control.
|
||||||
|
fn line_is_url(line: &str) -> bool {
|
||||||
|
use self::LIUState::*;
|
||||||
|
let mut state: LIUState = EXP_COMMENT_START;
|
||||||
|
|
||||||
|
for tok in line.split_whitespace() {
|
||||||
|
match (state, tok) {
|
||||||
|
(EXP_COMMENT_START, "//") => state = EXP_LINK_LABEL_OR_URL,
|
||||||
|
(EXP_COMMENT_START, "///") => state = EXP_LINK_LABEL_OR_URL,
|
||||||
|
(EXP_COMMENT_START, "//!") => state = EXP_LINK_LABEL_OR_URL,
|
||||||
|
|
||||||
|
(EXP_LINK_LABEL_OR_URL, w)
|
||||||
|
if w.len() >= 4 && w.starts_with("[") && w.ends_with("]:")
|
||||||
|
=> state = EXP_URL,
|
||||||
|
|
||||||
|
(EXP_LINK_LABEL_OR_URL, w)
|
||||||
|
if w.starts_with("http://") || w.starts_with("https://")
|
||||||
|
=> state = EXP_END,
|
||||||
|
|
||||||
|
(EXP_URL, w)
|
||||||
|
if w.starts_with("http://") || w.starts_with("https://")
|
||||||
|
=> state = EXP_END,
|
||||||
|
|
||||||
|
(_, _) => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state == EXP_END
|
||||||
|
}
|
||||||
|
|
||||||
|
/// True if LINE is allowed to be longer than the normal limit.
|
||||||
|
/// Currently there is only one exception, for long URLs, but more
|
||||||
|
/// may be added in the future.
|
||||||
|
fn long_line_is_ok(line: &str) -> bool {
|
||||||
|
if line_is_url(line) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check(path: &Path, bad: &mut bool) {
|
pub fn check(path: &Path, bad: &mut bool) {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
super::walk(path, &mut super::filter_dirs, &mut |file| {
|
super::walk(path, &mut super::filter_dirs, &mut |file| {
|
||||||
@@ -61,8 +115,9 @@ pub fn check(path: &Path, bad: &mut bool) {
|
|||||||
println!("{}:{}: {}", file.display(), i + 1, msg);
|
println!("{}:{}: {}", file.display(), i + 1, msg);
|
||||||
*bad = true;
|
*bad = true;
|
||||||
};
|
};
|
||||||
if line.chars().count() > COLS && !skip_length {
|
if !skip_length && line.chars().count() > COLS
|
||||||
err(&format!("line longer than {} chars", COLS));
|
&& !long_line_is_ok(line) {
|
||||||
|
err(&format!("line longer than {} chars", COLS));
|
||||||
}
|
}
|
||||||
if line.contains("\t") && !skip_tab {
|
if line.contains("\t") && !skip_tab {
|
||||||
err("tab character");
|
err("tab character");
|
||||||
|
|||||||
Reference in New Issue
Block a user