Skip to content

Commit 3a07f3b

Browse files
authored
Rollup merge of rust-lang#67536 - Centril:move-is_range_literal, r=Mark-Simulacrum
Move `{hir::lowering -> hir}::is_range_literal` The function is never used inside lowering, but only ever in external crates. By moving it, we facilitate lowering as its own crate. Best read commit-by-commit. r? @Mark-Simulacrum
2 parents 6f38a15 + 4bb8346 commit 3a07f3b

File tree

4 files changed

+69
-72
lines changed

4 files changed

+69
-72
lines changed

src/librustc/hir/lowering.rs

-62
Original file line numberDiff line numberDiff line change
@@ -3437,65 +3437,3 @@ fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'hir>>) -> Vec<hir::BodyId>
34373437
body_ids.sort_by_key(|b| bodies[b].value.span);
34383438
body_ids
34393439
}
3440-
3441-
/// Checks if the specified expression is a built-in range literal.
3442-
/// (See: `LoweringContext::lower_expr()`).
3443-
pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
3444-
use hir::{Path, QPath, ExprKind, TyKind};
3445-
3446-
// Returns whether the given path represents a (desugared) range,
3447-
// either in std or core, i.e. has either a `::std::ops::Range` or
3448-
// `::core::ops::Range` prefix.
3449-
fn is_range_path(path: &Path) -> bool {
3450-
let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
3451-
let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
3452-
3453-
// "{{root}}" is the equivalent of `::` prefix in `Path`.
3454-
if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
3455-
(*std_core == "std" || *std_core == "core") && range.starts_with("Range")
3456-
} else {
3457-
false
3458-
}
3459-
};
3460-
3461-
// Check whether a span corresponding to a range expression is a
3462-
// range literal, rather than an explicit struct or `new()` call.
3463-
fn is_lit(sess: &Session, span: &Span) -> bool {
3464-
let source_map = sess.source_map();
3465-
let end_point = source_map.end_point(*span);
3466-
3467-
if let Ok(end_string) = source_map.span_to_snippet(end_point) {
3468-
!(end_string.ends_with("}") || end_string.ends_with(")"))
3469-
} else {
3470-
false
3471-
}
3472-
};
3473-
3474-
match expr.kind {
3475-
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
3476-
ExprKind::Struct(ref qpath, _, _) => {
3477-
if let QPath::Resolved(None, ref path) = **qpath {
3478-
return is_range_path(&path) && is_lit(sess, &expr.span);
3479-
}
3480-
}
3481-
3482-
// `..` desugars to its struct path.
3483-
ExprKind::Path(QPath::Resolved(None, ref path)) => {
3484-
return is_range_path(&path) && is_lit(sess, &expr.span);
3485-
}
3486-
3487-
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
3488-
ExprKind::Call(ref func, _) => {
3489-
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
3490-
if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
3491-
let new_call = segment.ident.name == sym::new;
3492-
return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
3493-
}
3494-
}
3495-
}
3496-
3497-
_ => {}
3498-
}
3499-
3500-
false
3501-
}

src/librustc/hir/mod.rs

+64-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ use syntax::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle,
2929
pub use syntax::ast::{BorrowKind, ImplPolarity, IsAuto};
3030
pub use syntax::ast::{CaptureBy, Constness, Movability, Mutability, Unsafety};
3131
use syntax::attr::{InlineAttr, OptimizeAttr};
32-
use syntax::source_map::Spanned;
33-
use syntax::symbol::{kw, Symbol};
3432
use syntax::tokenstream::TokenStream;
3533
use syntax::util::parser::ExprPrecedence;
34+
use syntax_pos::source_map::{SourceMap, Spanned};
35+
use syntax_pos::symbol::{kw, sym, Symbol};
3636
use syntax_pos::{MultiSpan, Span, DUMMY_SP};
3737

3838
/// HIR doesn't commit to a concrete storage type and has its own alias for a vector.
@@ -1564,6 +1564,68 @@ impl fmt::Debug for Expr {
15641564
}
15651565
}
15661566

1567+
/// Checks if the specified expression is a built-in range literal.
1568+
/// (See: `LoweringContext::lower_expr()`).
1569+
///
1570+
/// FIXME(#60607): This function is a hack. If and when we have `QPath::Lang(...)`,
1571+
/// we can use that instead as simpler, more reliable mechanism, as opposed to using `SourceMap`.
1572+
pub fn is_range_literal(sm: &SourceMap, expr: &Expr) -> bool {
1573+
// Returns whether the given path represents a (desugared) range,
1574+
// either in std or core, i.e. has either a `::std::ops::Range` or
1575+
// `::core::ops::Range` prefix.
1576+
fn is_range_path(path: &Path) -> bool {
1577+
let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
1578+
let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
1579+
1580+
// "{{root}}" is the equivalent of `::` prefix in `Path`.
1581+
if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
1582+
(*std_core == "std" || *std_core == "core") && range.starts_with("Range")
1583+
} else {
1584+
false
1585+
}
1586+
};
1587+
1588+
// Check whether a span corresponding to a range expression is a
1589+
// range literal, rather than an explicit struct or `new()` call.
1590+
fn is_lit(sm: &SourceMap, span: &Span) -> bool {
1591+
let end_point = sm.end_point(*span);
1592+
1593+
if let Ok(end_string) = sm.span_to_snippet(end_point) {
1594+
!(end_string.ends_with("}") || end_string.ends_with(")"))
1595+
} else {
1596+
false
1597+
}
1598+
};
1599+
1600+
match expr.kind {
1601+
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
1602+
ExprKind::Struct(ref qpath, _, _) => {
1603+
if let QPath::Resolved(None, ref path) = **qpath {
1604+
return is_range_path(&path) && is_lit(sm, &expr.span);
1605+
}
1606+
}
1607+
1608+
// `..` desugars to its struct path.
1609+
ExprKind::Path(QPath::Resolved(None, ref path)) => {
1610+
return is_range_path(&path) && is_lit(sm, &expr.span);
1611+
}
1612+
1613+
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1614+
ExprKind::Call(ref func, _) => {
1615+
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
1616+
if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
1617+
let new_call = segment.ident.name == sym::new;
1618+
return is_range_path(&path) && is_lit(sm, &expr.span) && new_call;
1619+
}
1620+
}
1621+
}
1622+
1623+
_ => {}
1624+
}
1625+
1626+
false
1627+
}
1628+
15671629
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
15681630
pub enum ExprKind {
15691631
/// A `box x` expression.

src/librustc_lint/types.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
use crate::hir::def_id::DefId;
44
use lint::{LateContext, LintArray, LintContext};
55
use lint::{LateLintPass, LintPass};
6-
use rustc::hir::lowering::is_range_literal;
7-
use rustc::hir::{ExprKind, Node};
6+
use rustc::hir::{is_range_literal, ExprKind, Node};
87
use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx};
98
use rustc::ty::subst::SubstsRef;
109
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
@@ -266,7 +265,7 @@ fn lint_int_literal<'a, 'tcx>(
266265
let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
267266
if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
268267
if let hir::ExprKind::Struct(..) = par_e.kind {
269-
if is_range_literal(cx.sess(), par_e)
268+
if is_range_literal(cx.sess().source_map(), par_e)
270269
&& lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
271270
{
272271
// The overflowing literal lint was overridden.
@@ -318,7 +317,7 @@ fn lint_uint_literal<'a, 'tcx>(
318317
return;
319318
}
320319
}
321-
hir::ExprKind::Struct(..) if is_range_literal(cx.sess(), par_e) => {
320+
hir::ExprKind::Struct(..) if is_range_literal(cx.sess().source_map(), par_e) => {
322321
let t = t.name_str();
323322
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
324323
// The overflowing literal lint was overridden.

src/librustc_typeck/check/demand.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use rustc::infer::InferOk;
33
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
44

55
use errors::{Applicability, DiagnosticBuilder};
6-
use rustc::hir;
7-
use rustc::hir::Node;
8-
use rustc::hir::{lowering::is_range_literal, print};
6+
use rustc::hir::{self, is_range_literal, print, Node};
97
use rustc::ty::adjustment::AllowTwoPhase;
108
use rustc::ty::{self, AssocItem, Ty};
119
use syntax::symbol::sym;
@@ -478,7 +476,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
478476
// parenthesize if needed (Issue #46756)
479477
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
480478
// parenthesize borrows of range literals (Issue #54505)
481-
_ if is_range_literal(self.tcx.sess, expr) => true,
479+
_ if is_range_literal(self.tcx.sess.source_map(), expr) => true,
482480
_ => false,
483481
};
484482
let sugg_expr = if needs_parens { format!("({})", src) } else { src };

0 commit comments

Comments
 (0)