Skip to content

Commit e1e5348

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 6f92548 + db4cc3b commit e1e5348

File tree

4 files changed

+70
-73
lines changed

4 files changed

+70
-73
lines changed

src/librustc/hir/lowering.rs

Lines changed: 0 additions & 62 deletions
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

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ use syntax::ast::{AttrVec, Attribute, Label, LitKind, StrStyle, FloatTy, IntTy,
2424
pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy};
2525
pub use syntax::ast::{IsAuto, ImplPolarity, BorrowKind};
2626
use syntax::attr::{InlineAttr, OptimizeAttr};
27-
use syntax::symbol::{Symbol, kw};
2827
use syntax::tokenstream::TokenStream;
2928
use syntax::util::parser::ExprPrecedence;
29+
use syntax_pos::symbol::{Symbol, kw, sym};
30+
use syntax_pos::source_map::SourceMap;
3031
use rustc_target::spec::abi::Abi;
3132
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
3233
use rustc_macros::HashStable;
@@ -1595,6 +1596,68 @@ impl fmt::Debug for Expr {
15951596
}
15961597
}
15971598

1599+
/// Checks if the specified expression is a built-in range literal.
1600+
/// (See: `LoweringContext::lower_expr()`).
1601+
///
1602+
/// FIXME(#60607): This function is a hack. If and when we have `QPath::Lang(...)`,
1603+
/// we can use that instead as simpler, more reliable mechanism, as opposed to using `SourceMap`.
1604+
pub fn is_range_literal(sm: &SourceMap, expr: &Expr) -> bool {
1605+
// Returns whether the given path represents a (desugared) range,
1606+
// either in std or core, i.e. has either a `::std::ops::Range` or
1607+
// `::core::ops::Range` prefix.
1608+
fn is_range_path(path: &Path) -> bool {
1609+
let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
1610+
let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
1611+
1612+
// "{{root}}" is the equivalent of `::` prefix in `Path`.
1613+
if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
1614+
(*std_core == "std" || *std_core == "core") && range.starts_with("Range")
1615+
} else {
1616+
false
1617+
}
1618+
};
1619+
1620+
// Check whether a span corresponding to a range expression is a
1621+
// range literal, rather than an explicit struct or `new()` call.
1622+
fn is_lit(sm: &SourceMap, span: &Span) -> bool {
1623+
let end_point = sm.end_point(*span);
1624+
1625+
if let Ok(end_string) = sm.span_to_snippet(end_point) {
1626+
!(end_string.ends_with("}") || end_string.ends_with(")"))
1627+
} else {
1628+
false
1629+
}
1630+
};
1631+
1632+
match expr.kind {
1633+
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
1634+
ExprKind::Struct(ref qpath, _, _) => {
1635+
if let QPath::Resolved(None, ref path) = **qpath {
1636+
return is_range_path(&path) && is_lit(sm, &expr.span);
1637+
}
1638+
}
1639+
1640+
// `..` desugars to its struct path.
1641+
ExprKind::Path(QPath::Resolved(None, ref path)) => {
1642+
return is_range_path(&path) && is_lit(sm, &expr.span);
1643+
}
1644+
1645+
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1646+
ExprKind::Call(ref func, _) => {
1647+
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
1648+
if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
1649+
let new_call = segment.ident.name == sym::new;
1650+
return is_range_path(&path) && is_lit(sm, &expr.span) && new_call;
1651+
}
1652+
}
1653+
}
1654+
1655+
_ => {}
1656+
}
1657+
1658+
false
1659+
}
1660+
15981661
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
15991662
pub enum ExprKind {
16001663
/// A `box x` expression.

src/librustc_lint/types.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#![allow(non_snake_case)]
22

3-
use rustc::hir::{ExprKind, Node};
4-
use crate::hir::def_id::DefId;
5-
use rustc::hir::lowering::is_range_literal;
3+
use rustc::hir::{ExprKind, Node, is_range_literal, def_id::DefId};
64
use rustc::ty::subst::SubstsRef;
75
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
86
use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx, SizeSkeleton};
@@ -275,7 +273,7 @@ fn lint_int_literal<'a, 'tcx>(
275273
let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
276274
if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
277275
if let hir::ExprKind::Struct(..) = par_e.kind {
278-
if is_range_literal(cx.sess(), par_e)
276+
if is_range_literal(cx.sess().source_map(), par_e)
279277
&& lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
280278
{
281279
// The overflowing literal lint was overridden.
@@ -328,7 +326,7 @@ fn lint_uint_literal<'a, 'tcx>(
328326
}
329327
}
330328
hir::ExprKind::Struct(..)
331-
if is_range_literal(cx.sess(), par_e) => {
329+
if is_range_literal(cx.sess().source_map(), par_e) => {
332330
let t = t.name_str();
333331
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
334332
// The overflowing literal lint was overridden.

src/librustc_typeck/check/demand.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ use crate::check::FnCtxt;
22
use rustc::infer::InferOk;
33
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
44

5-
use syntax::symbol::sym;
65
use syntax::util::parser::PREC_POSTFIX;
6+
use syntax_pos::symbol::sym;
77
use syntax_pos::Span;
8-
use rustc::hir;
9-
use rustc::hir::Node;
10-
use rustc::hir::{print, lowering::is_range_literal};
8+
use rustc::hir::{self, Node, print, is_range_literal};
119
use rustc::ty::{self, Ty, AssocItem};
1210
use rustc::ty::adjustment::AllowTwoPhase;
1311
use errors::{Applicability, DiagnosticBuilder};
@@ -466,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
466464
hir::ExprKind::Cast(_, _) |
467465
hir::ExprKind::Binary(_, _, _) => true,
468466
// parenthesize borrows of range literals (Issue #54505)
469-
_ if is_range_literal(self.tcx.sess, expr) => true,
467+
_ if is_range_literal(self.tcx.sess.source_map(), expr) => true,
470468
_ => false,
471469
};
472470
let sugg_expr = if needs_parens {

0 commit comments

Comments
 (0)