Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lint to favor ..= over ... range patterns; migrate to ..= throughout codebase #51149

Merged
merged 3 commits into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libcore/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,15 @@ pub fn escape_default(c: u8) -> EscapeDefault {
b'\\' => ([b'\\', b'\\', 0, 0], 2),
b'\'' => ([b'\\', b'\'', 0, 0], 2),
b'"' => ([b'\\', b'"', 0, 0], 2),
b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1),
b'\x20' ..= b'\x7e' => ([c, 0, 0, 0], 1),
_ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
};

return EscapeDefault { range: 0..len, data };

fn hexify(b: u8) -> u8 {
match b {
0 ... 9 => b'0' + b,
0 ..= 9 => b'0' + b,
_ => b'a' + b - 10,
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/libcore/char/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
}
}
macro_rules! continuation_byte {
() => { continuation_byte!(0x80...0xBF) };
() => { continuation_byte!(0x80..=0xBF) };
($range: pat) => {
match self.0.peek() {
Some(&byte @ $range) => {
Expand All @@ -77,43 +77,43 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
}

match first_byte {
0x00...0x7F => {
0x00..=0x7F => {
first_byte!(0b1111_1111);
}
0xC2...0xDF => {
0xC2..=0xDF => {
first_byte!(0b0001_1111);
continuation_byte!();
}
0xE0 => {
first_byte!(0b0000_1111);
continuation_byte!(0xA0...0xBF); // 0x80...0x9F here are overlong
continuation_byte!(0xA0..=0xBF); // 0x80..=0x9F here are overlong
continuation_byte!();
}
0xE1...0xEC | 0xEE...0xEF => {
0xE1..=0xEC | 0xEE..=0xEF => {
first_byte!(0b0000_1111);
continuation_byte!();
continuation_byte!();
}
0xED => {
first_byte!(0b0000_1111);
continuation_byte!(0x80...0x9F); // 0xA0..0xBF here are surrogates
continuation_byte!(0x80..=0x9F); // 0xA0..0xBF here are surrogates
continuation_byte!();
}
0xF0 => {
first_byte!(0b0000_0111);
continuation_byte!(0x90...0xBF); // 0x80..0x8F here are overlong
continuation_byte!(0x90..=0xBF); // 0x80..0x8F here are overlong
continuation_byte!();
continuation_byte!();
}
0xF1...0xF3 => {
0xF1..=0xF3 => {
first_byte!(0b0000_0111);
continuation_byte!();
continuation_byte!();
continuation_byte!();
}
0xF4 => {
first_byte!(0b0000_0111);
continuation_byte!(0x80...0x8F); // 0x90..0xBF here are beyond char::MAX
continuation_byte!(0x80..=0x8F); // 0x90..0xBF here are beyond char::MAX
continuation_byte!();
continuation_byte!();
}
Expand Down
18 changes: 9 additions & 9 deletions src/libcore/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ impl char {
panic!("to_digit: radix is too high (maximum 36)");
}
let val = match self {
'0' ... '9' => self as u32 - '0' as u32,
'a' ... 'z' => self as u32 - 'a' as u32 + 10,
'A' ... 'Z' => self as u32 - 'A' as u32 + 10,
'0' ..= '9' => self as u32 - '0' as u32,
'a' ..= 'z' => self as u32 - 'a' as u32 + 10,
'A' ..= 'Z' => self as u32 - 'A' as u32 + 10,
_ => return None,
};
if val < radix { Some(val) }
Expand Down Expand Up @@ -305,7 +305,7 @@ impl char {
'\r' => EscapeDefaultState::Backslash('r'),
'\n' => EscapeDefaultState::Backslash('n'),
'\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
'\x20' ... '\x7e' => EscapeDefaultState::Char(self),
'\x20' ..= '\x7e' => EscapeDefaultState::Char(self),
_ => EscapeDefaultState::Unicode(self.escape_unicode())
};
EscapeDefault { state: init_state }
Expand Down Expand Up @@ -543,7 +543,7 @@ impl char {
#[inline]
pub fn is_alphabetic(self) -> bool {
match self {
'a'...'z' | 'A'...'Z' => true,
'a'..='z' | 'A'..='Z' => true,
c if c > '\x7f' => derived_property::Alphabetic(c),
_ => false,
}
Expand Down Expand Up @@ -599,7 +599,7 @@ impl char {
#[inline]
pub fn is_lowercase(self) -> bool {
match self {
'a'...'z' => true,
'a'..='z' => true,
c if c > '\x7f' => derived_property::Lowercase(c),
_ => false,
}
Expand Down Expand Up @@ -627,7 +627,7 @@ impl char {
#[inline]
pub fn is_uppercase(self) -> bool {
match self {
'A'...'Z' => true,
'A'..='Z' => true,
c if c > '\x7f' => derived_property::Uppercase(c),
_ => false,
}
Expand All @@ -654,7 +654,7 @@ impl char {
#[inline]
pub fn is_whitespace(self) -> bool {
match self {
' ' | '\x09'...'\x0d' => true,
' ' | '\x09'..='\x0d' => true,
c if c > '\x7f' => property::White_Space(c),
_ => false,
}
Expand Down Expand Up @@ -737,7 +737,7 @@ impl char {
#[inline]
pub fn is_numeric(self) -> bool {
match self {
'0'...'9' => true,
'0'..='9' => true,
c if c > '\x7f' => general_category::N(c),
_ => false,
}
Expand Down
14 changes: 7 additions & 7 deletions src/libcore/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,19 @@ macro_rules! radix {
fn digit(x: u8) -> u8 {
match x {
$($x => $conv,)+
x => panic!("number not in the range 0..{}: {}", Self::BASE - 1, x),
x => panic!("number not in the range 0..={}: {}", Self::BASE - 1, x),
}
}
}
}
}

radix! { Binary, 2, "0b", x @ 0 ... 1 => b'0' + x }
radix! { Octal, 8, "0o", x @ 0 ... 7 => b'0' + x }
radix! { LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x,
x @ 10 ... 15 => b'a' + (x - 10) }
radix! { UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x,
x @ 10 ... 15 => b'A' + (x - 10) }
radix! { Binary, 2, "0b", x @ 0 ..= 1 => b'0' + x }
radix! { Octal, 8, "0o", x @ 0 ..= 7 => b'0' + x }
radix! { LowerHex, 16, "0x", x @ 0 ..= 9 => b'0' + x,
x @ 10 ..= 15 => b'a' + (x - 10) }
radix! { UpperHex, 16, "0x", x @ 0 ..= 9 => b'0' + x,
x @ 10 ..= 15 => b'A' + (x - 10) }

macro_rules! int_base {
($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ impl<T> [T] {
/// assert_eq!(s.binary_search(&4), Err(7));
/// assert_eq!(s.binary_search(&100), Err(13));
/// let r = s.binary_search(&1);
/// assert!(match r { Ok(1...4) => true, _ => false, });
/// assert!(match r { Ok(1..=4) => true, _ => false, });
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
Expand Down Expand Up @@ -1268,7 +1268,7 @@ impl<T> [T] {
/// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
/// let seek = 1;
/// let r = s.binary_search_by(|probe| probe.cmp(&seek));
/// assert!(match r { Ok(1...4) => true, _ => false, });
/// assert!(match r { Ok(1..=4) => true, _ => false, });
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
Expand Down Expand Up @@ -1325,7 +1325,7 @@ impl<T> [T] {
/// assert_eq!(s.binary_search_by_key(&4, |&(a,b)| b), Err(7));
/// assert_eq!(s.binary_search_by_key(&100, |&(a,b)| b), Err(13));
/// let r = s.binary_search_by_key(&1, |&(a,b)| b);
/// assert!(match r { Ok(1...4) => true, _ => false, });
/// assert!(match r { Ok(1..=4) => true, _ => false, });
/// ```
#[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
#[inline]
Expand Down
14 changes: 7 additions & 7 deletions src/libcore/str/lossy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
}
3 => {
match (byte, safe_get(self.source, i)) {
(0xE0, 0xA0 ... 0xBF) => (),
(0xE1 ... 0xEC, 0x80 ... 0xBF) => (),
(0xED, 0x80 ... 0x9F) => (),
(0xEE ... 0xEF, 0x80 ... 0xBF) => (),
(0xE0, 0xA0 ..= 0xBF) => (),
(0xE1 ..= 0xEC, 0x80 ..= 0xBF) => (),
(0xED, 0x80 ..= 0x9F) => (),
(0xEE ..= 0xEF, 0x80 ..= 0xBF) => (),
_ => {
error!();
}
Expand All @@ -117,9 +117,9 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
}
4 => {
match (byte, safe_get(self.source, i)) {
(0xF0, 0x90 ... 0xBF) => (),
(0xF1 ... 0xF3, 0x80 ... 0xBF) => (),
(0xF4, 0x80 ... 0x8F) => (),
(0xF0, 0x90 ..= 0xBF) => (),
(0xF1 ..= 0xF3, 0x80 ..= 0xBF) => (),
(0xF4, 0x80 ..= 0x8F) => (),
_ => {
error!();
}
Expand Down
14 changes: 7 additions & 7 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1484,10 +1484,10 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
},
3 => {
match (first, next!()) {
(0xE0 , 0xA0 ... 0xBF) |
(0xE1 ... 0xEC, 0x80 ... 0xBF) |
(0xED , 0x80 ... 0x9F) |
(0xEE ... 0xEF, 0x80 ... 0xBF) => {}
(0xE0 , 0xA0 ..= 0xBF) |
(0xE1 ..= 0xEC, 0x80 ..= 0xBF) |
(0xED , 0x80 ..= 0x9F) |
(0xEE ..= 0xEF, 0x80 ..= 0xBF) => {}
_ => err!(Some(1))
}
if next!() & !CONT_MASK != TAG_CONT_U8 {
Expand All @@ -1496,9 +1496,9 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
}
4 => {
match (first, next!()) {
(0xF0 , 0x90 ... 0xBF) |
(0xF1 ... 0xF3, 0x80 ... 0xBF) |
(0xF4 , 0x80 ... 0x8F) => {}
(0xF0 , 0x90 ..= 0xBF) |
(0xF1 ..= 0xF3, 0x80 ..= 0xBF) |
(0xF4 , 0x80 ..= 0x8F) => {}
_ => err!(Some(1))
}
if next!() & !CONT_MASK != TAG_CONT_U8 {
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ fn test_binary_search() {
assert_eq!(b.binary_search(&0), Err(0));
assert_eq!(b.binary_search(&1), Ok(0));
assert_eq!(b.binary_search(&2), Err(1));
assert!(match b.binary_search(&3) { Ok(1...3) => true, _ => false });
assert!(match b.binary_search(&3) { Ok(1...3) => true, _ => false });
assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
assert_eq!(b.binary_search(&4), Err(4));
assert_eq!(b.binary_search(&5), Err(4));
assert_eq!(b.binary_search(&6), Err(4));
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3356,7 +3356,7 @@ impl<'a> LoweringContext<'a> {
PatKind::Ref(ref inner, mutbl) => {
hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
}
PatKind::Range(ref e1, ref e2, ref end) => hir::PatKind::Range(
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range(
P(self.lower_expr(e1)),
P(self.lower_expr(e2)),
self.lower_range_end(end),
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_apfloat/ieee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1753,9 +1753,9 @@ impl<S: Semantics> IeeeFloat<S> {
} else {
loss = Some(match hex_value {
0 => Loss::ExactlyZero,
1...7 => Loss::LessThanHalf,
1..=7 => Loss::LessThanHalf,
8 => Loss::ExactlyHalf,
9...15 => Loss::MoreThanHalf,
9..=15 => Loss::MoreThanHalf,
_ => unreachable!(),
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_utils/symbol_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
'-' | ':' => result.push('.'),

// These are legal symbols
'a'...'z' | 'A'...'Z' | '0'...'9' | '_' | '.' | '$' => result.push(c),
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => result.push(c),

_ => {
result.push('$');
Expand Down
38 changes: 38 additions & 0 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use std::collections::HashSet;

use syntax::ast;
use syntax::attr;
use syntax::codemap::Spanned;
use syntax::edition::Edition;
use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes};
use syntax_pos::{BytePos, Span, SyntaxContext};
Expand Down Expand Up @@ -1669,6 +1670,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
}
}


/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -1701,3 +1703,39 @@ impl LintPass for SoftLints {
)
}
}


declare_lint! {
pub ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
Allow,
"`...` range patterns are deprecated"
}


pub struct EllipsisInclusiveRangePatterns;

impl LintPass for EllipsisInclusiveRangePatterns {
fn get_lints(&self) -> LintArray {
lint_array!(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS)
}
}

impl EarlyLintPass for EllipsisInclusiveRangePatterns {
fn check_pat(&mut self, cx: &EarlyContext, pat: &ast::Pat) {
use self::ast::{PatKind, RangeEnd, RangeSyntax};

if let PatKind::Range(
_, _, Spanned { span, node: RangeEnd::Included(RangeSyntax::DotDotDot) }
) = pat.node {
let msg = "`...` range patterns are deprecated";
let mut err = cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, span, msg);
err.span_suggestion_short_with_applicability(
span, "use `..=` for an inclusive range", "..=".to_owned(),
// FIXME: outstanding problem with precedence in ref patterns:
// https://github.com/rust-lang/rust/issues/51043#issuecomment-392252285
Applicability::MaybeIncorrect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the MaybeIncorrect setting probably prevents rustfix from acting (cc @killercup, confirm?) — but otherwise it'd be nice to have some automated tests that use the suggestion (e.g., using the new // rustfix mode).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes -- MaybeIncorrect will prevent rustfix from applying this. It will not, however, prevent the rustfix compile tests as they currently exist from applying it! (Mostly because I haven't updated the test suite to also include a // run-rustfix --yolo mode.) So you can actually test edge cases if you want to. (Otherwise don't put them in the same file I guess.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, then @zackmdavis would you be up to add a // run-rustfix test for this? It's pretty straightforward: make a UI test and add that comment, and we will run rustfix and create a foo.fixed file. You can even use ./x.py test --bless to create the reference file automatically.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monday

);
err.emit()
}
}
}
4 changes: 3 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
AnonymousParameters,
UnusedDocComment,
BadRepr,
EllipsisInclusiveRangePatterns,
);

add_early_builtin_with_new!(sess,
Expand Down Expand Up @@ -188,7 +189,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
"rust_2018_idioms",
BARE_TRAIT_OBJECTS,
UNREACHABLE_PUB,
UNUSED_EXTERN_CRATES);
UNUSED_EXTERN_CRATES,
ELLIPSIS_INCLUSIVE_RANGE_PATTERNS);

// Guidelines for creating a future incompatibility lint:
//
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,9 @@ For example:
```compile_fail
match 5u32 {
// This range is ok, albeit pointless.
1 ... 1 => {}
1 ..= 1 => {}
// This range is empty, and the compiler can tell.
1000 ... 5 => {}
1000 ..= 5 => {}
}
```
"##,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/hair/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ fn check_exhaustive<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
let joined_patterns = match witnesses.len() {
0 => bug!(),
1 => format!("`{}`", witnesses[0]),
2...LIMIT => {
2..=LIMIT => {
let (tail, head) = witnesses.split_last().unwrap();
let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
format!("`{}` and `{}`", head.join("`, `"), tail)
Expand Down
Loading