_ if self.is_range_literal(expr) => true,
_ => false,
};
- let sugg_expr = if needs_parens { format!("({})", src) } else { src };
+ let sugg_expr = if needs_parens {
+ format!("({})", src)
+ } else {
+ src
+ };
if let Some(sugg) = self.can_use_as_ref(expr) {
return Some(sugg);
None
}
- // This function checks if the specified expression is a built-in range literal
- // (See: librustc/hir/lowering.rs::LoweringContext::lower_expr() )
+ /// This function checks if the specified expression is a built-in range literal.
+ /// (See: ``librustc::hir::lowering::LoweringContext::lower_expr()``).
fn is_range_literal(&self, expr: &hir::Expr) -> bool {
use hir::{Path, QPath, ExprKind, TyKind};
- // we support `::std::ops::Range` and `::std::core::Range` prefixes
- // (via split on "|")
- let ops_path = ["{{root}}", "std|core", "ops"];
-
+ // We support `::std::ops::Range` and `::core::ops::Range` prefixes
let is_range_path = |path: &Path| {
- let ident_names: Vec<_> = path.segments
- .iter()
- .map(|seg| seg.ident.as_str())
- .collect();
-
- if let Some((last, preceding)) = ident_names.split_last() {
- last.starts_with("Range") &&
- preceding.len() == 3 &&
- preceding.iter()
- .zip(ops_path.iter())
- .all(|(seg, match_seg)| {
- match_seg.split("|")
- .into_iter()
- .any(|ref spl_seg| seg == spl_seg)
- })
+ let mut segs = path.segments.iter()
+ .map(|seg| seg.ident.as_str());
+
+ if let (Some(root), Some(std_core), Some(ops), Some(range), None) =
+ (segs.next(), segs.next(), segs.next(), segs.next(), segs.next())
+ {
+ // "{{root}}" is the equivalent of `::` prefix in Path
+ root == "{{root}}" && (std_core == "std" || std_core == "core")
+ && ops == "ops" && range.starts_with("Range")
} else {
false
}
};
- let is_range_struct_snippet = |span: &Span| {
- // Tell if expression span snippet looks like an explicit
- // Range struct or new() call. This is to allow rejecting
- // Ranges constructed with non-literals.
+ let is_range_literal = |span: &Span| {
+ // Tell if expression span snippet doesn't look like an explicit
+ // Range struct or `new()` call. This is to allow inferring
+ // that this is a range literal.
let source_map = self.tcx.sess.source_map();
let end_point = source_map.end_point(*span);
if let Ok(end_string) = source_map.span_to_snippet(end_point) {
- end_string.ends_with("}") || end_string.ends_with(")")
+ !(end_string.ends_with("}") || end_string.ends_with(")"))
} else {
false
}
-
};
match expr.node {
- // all built-in range literals but `..=` and `..`
- // desugar to Structs, `..` desugars to its struct path
+ // All built-in range literals but `..=` and `..` desugar to Structs
ExprKind::Struct(QPath::Resolved(None, ref path), _, _) |
+ // `..` desugars to its struct path
ExprKind::Path(QPath::Resolved(None, ref path)) => {
- return is_range_path(&path) && !is_range_struct_snippet(&expr.span);
+ return is_range_path(&path) && is_range_literal(&expr.span);
}
- // `..=` desugars into RangeInclusive::new(...)
+ // `..=` desugars into `::std::ops::RangeInclusive::new(...)`
ExprKind::Call(ref func, _) => {
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.node {
if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.node {
- let calls_new = segment.ident.as_str() == "new";
+ let call_to_new = segment.ident.as_str() == "new";
- return is_range_path(&path) && calls_new &&
- !is_range_struct_snippet(&expr.span);
+ return is_range_path(&path) && is_range_literal(&expr.span) && call_to_new;
}
}
}
-// Copyright 2018 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.
-
// run-rustfix
// Regression test for changes introduced while fixing #54505
-// Copyright 2018 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.
-
// run-rustfix
// Regression test for changes introduced while fixing #54505
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:26:16
+ --> $DIR/issue-54505-no-literals.rs:16:16
|
LL | take_range(std::ops::Range { start: 0, end: 1 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::Range<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:31:16
+ --> $DIR/issue-54505-no-literals.rs:21:16
|
LL | take_range(::std::ops::Range { start: 0, end: 1 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::Range<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:36:16
+ --> $DIR/issue-54505-no-literals.rs:26:16
|
LL | take_range(std::ops::RangeFrom { start: 1 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeFrom<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:41:16
+ --> $DIR/issue-54505-no-literals.rs:31:16
|
LL | take_range(::std::ops::RangeFrom { start: 1 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeFrom<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:46:16
+ --> $DIR/issue-54505-no-literals.rs:36:16
|
LL | take_range(std::ops::RangeFull {});
| ^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeFull`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:51:16
+ --> $DIR/issue-54505-no-literals.rs:41:16
|
LL | take_range(::std::ops::RangeFull {});
| ^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeFull`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:56:16
+ --> $DIR/issue-54505-no-literals.rs:46:16
|
LL | take_range(std::ops::RangeInclusive::new(0, 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeInclusive<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:61:16
+ --> $DIR/issue-54505-no-literals.rs:51:16
|
LL | take_range(::std::ops::RangeInclusive::new(0, 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeInclusive<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:66:16
+ --> $DIR/issue-54505-no-literals.rs:56:16
|
LL | take_range(std::ops::RangeTo { end: 5 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeTo<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:71:16
+ --> $DIR/issue-54505-no-literals.rs:61:16
|
LL | take_range(::std::ops::RangeTo { end: 5 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeTo<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:76:16
+ --> $DIR/issue-54505-no-literals.rs:66:16
|
LL | take_range(std::ops::RangeToInclusive { end: 5 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
found type `std::ops::RangeToInclusive<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-literals.rs:81:16
+ --> $DIR/issue-54505-no-literals.rs:71:16
|
LL | take_range(::std::ops::RangeToInclusive { end: 5 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// Copyright 2018 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.
-
// error-pattern: `#[panic_handler]` function required, but not found
// error-pattern: language item required, but not found: `eh_personality`
error: language item required, but not found: `eh_personality`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:31:16
+ --> $DIR/issue-54505-no-std.rs:21:16
|
LL | take_range(0..1);
| ^^^^
found type `core::ops::Range<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:36:16
+ --> $DIR/issue-54505-no-std.rs:26:16
|
LL | take_range(1..);
| ^^^
found type `core::ops::RangeFrom<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:41:16
+ --> $DIR/issue-54505-no-std.rs:31:16
|
LL | take_range(..);
| ^^
found type `core::ops::RangeFull`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:46:16
+ --> $DIR/issue-54505-no-std.rs:36:16
|
LL | take_range(0..=1);
| ^^^^^
found type `core::ops::RangeInclusive<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:51:16
+ --> $DIR/issue-54505-no-std.rs:41:16
|
LL | take_range(..5);
| ^^^
found type `core::ops::RangeTo<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:56:16
+ --> $DIR/issue-54505-no-std.rs:46:16
|
LL | take_range(..=42);
| ^^^^^
-// Copyright 2018 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.
-
// run-rustfix
// Regression test for #54505 - range borrowing suggestion had
-// Copyright 2018 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.
-
// run-rustfix
// Regression test for #54505 - range borrowing suggestion had
error[E0308]: mismatched types
- --> $DIR/issue-54505.rs:24:16
+ --> $DIR/issue-54505.rs:14:16
|
LL | take_range(0..1);
| ^^^^
found type `std::ops::Range<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505.rs:29:16
+ --> $DIR/issue-54505.rs:19:16
|
LL | take_range(1..);
| ^^^
found type `std::ops::RangeFrom<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505.rs:34:16
+ --> $DIR/issue-54505.rs:24:16
|
LL | take_range(..);
| ^^
found type `std::ops::RangeFull`
error[E0308]: mismatched types
- --> $DIR/issue-54505.rs:39:16
+ --> $DIR/issue-54505.rs:29:16
|
LL | take_range(0..=1);
| ^^^^^
found type `std::ops::RangeInclusive<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505.rs:44:16
+ --> $DIR/issue-54505.rs:34:16
|
LL | take_range(..5);
| ^^^
found type `std::ops::RangeTo<{integer}>`
error[E0308]: mismatched types
- --> $DIR/issue-54505.rs:49:16
+ --> $DIR/issue-54505.rs:39:16
|
LL | take_range(..=42);
| ^^^^^