about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-23 15:16:28 +0100
committerGitHub <noreply@github.com>2019-12-23 15:16:28 +0100
commit3a07f3ba75d2f0a180be44915df2c929966d39cd (patch)
tree93d43e0e112c32e4c15b42d45f1def8acaeb616b
parent6f38a15c7b5a57abf024e7e38cb0239e39037e9f (diff)
parent4bb83468a202c7402de529199dd363db5f307f33 (diff)
downloadrust-3a07f3ba75d2f0a180be44915df2c929966d39cd.tar.gz
rust-3a07f3ba75d2f0a180be44915df2c929966d39cd.zip
Rollup merge of #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
-rw-r--r--src/librustc/hir/lowering.rs62
-rw-r--r--src/librustc/hir/mod.rs66
-rw-r--r--src/librustc_lint/types.rs7
-rw-r--r--src/librustc_typeck/check/demand.rs6
4 files changed, 69 insertions, 72 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 83869951ea2..a702eb83984 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -3437,65 +3437,3 @@ fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'hir>>) -> Vec<hir::BodyId>
     body_ids.sort_by_key(|b| bodies[b].value.span);
     body_ids
 }
-
-/// Checks if the specified expression is a built-in range literal.
-/// (See: `LoweringContext::lower_expr()`).
-pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
-    use hir::{Path, QPath, ExprKind, TyKind};
-
-    // Returns whether the given path represents a (desugared) range,
-    // either in std or core, i.e. has either a `::std::ops::Range` or
-    // `::core::ops::Range` prefix.
-    fn is_range_path(path: &Path) -> bool {
-        let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
-        let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
-
-        // "{{root}}" is the equivalent of `::` prefix in `Path`.
-        if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
-            (*std_core == "std" || *std_core == "core") && range.starts_with("Range")
-        } else {
-            false
-        }
-    };
-
-    // Check whether a span corresponding to a range expression is a
-    // range literal, rather than an explicit struct or `new()` call.
-    fn is_lit(sess: &Session, span: &Span) -> bool {
-        let source_map = 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(")"))
-        } else {
-            false
-        }
-    };
-
-    match expr.kind {
-        // All built-in range literals but `..=` and `..` desugar to `Struct`s.
-        ExprKind::Struct(ref qpath, _, _) => {
-            if let QPath::Resolved(None, ref path) = **qpath {
-                return is_range_path(&path) && is_lit(sess, &expr.span);
-            }
-        }
-
-        // `..` desugars to its struct path.
-        ExprKind::Path(QPath::Resolved(None, ref path)) => {
-            return is_range_path(&path) && is_lit(sess, &expr.span);
-        }
-
-        // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
-        ExprKind::Call(ref func, _) => {
-            if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
-                if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
-                    let new_call = segment.ident.name == sym::new;
-                    return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
-                }
-            }
-        }
-
-        _ => {}
-    }
-
-    false
-}
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 4aa8c12a219..915b0afc48f 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -29,10 +29,10 @@ use syntax::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle,
 pub use syntax::ast::{BorrowKind, ImplPolarity, IsAuto};
 pub use syntax::ast::{CaptureBy, Constness, Movability, Mutability, Unsafety};
 use syntax::attr::{InlineAttr, OptimizeAttr};
-use syntax::source_map::Spanned;
-use syntax::symbol::{kw, Symbol};
 use syntax::tokenstream::TokenStream;
 use syntax::util::parser::ExprPrecedence;
+use syntax_pos::source_map::{SourceMap, Spanned};
+use syntax_pos::symbol::{kw, sym, Symbol};
 use syntax_pos::{MultiSpan, Span, DUMMY_SP};
 
 /// 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 {
     }
 }
 
+/// Checks if the specified expression is a built-in range literal.
+/// (See: `LoweringContext::lower_expr()`).
+///
+/// FIXME(#60607): This function is a hack. If and when we have `QPath::Lang(...)`,
+/// we can use that instead as simpler, more reliable mechanism, as opposed to using `SourceMap`.
+pub fn is_range_literal(sm: &SourceMap, expr: &Expr) -> bool {
+    // Returns whether the given path represents a (desugared) range,
+    // either in std or core, i.e. has either a `::std::ops::Range` or
+    // `::core::ops::Range` prefix.
+    fn is_range_path(path: &Path) -> bool {
+        let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
+        let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
+
+        // "{{root}}" is the equivalent of `::` prefix in `Path`.
+        if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
+            (*std_core == "std" || *std_core == "core") && range.starts_with("Range")
+        } else {
+            false
+        }
+    };
+
+    // Check whether a span corresponding to a range expression is a
+    // range literal, rather than an explicit struct or `new()` call.
+    fn is_lit(sm: &SourceMap, span: &Span) -> bool {
+        let end_point = sm.end_point(*span);
+
+        if let Ok(end_string) = sm.span_to_snippet(end_point) {
+            !(end_string.ends_with("}") || end_string.ends_with(")"))
+        } else {
+            false
+        }
+    };
+
+    match expr.kind {
+        // All built-in range literals but `..=` and `..` desugar to `Struct`s.
+        ExprKind::Struct(ref qpath, _, _) => {
+            if let QPath::Resolved(None, ref path) = **qpath {
+                return is_range_path(&path) && is_lit(sm, &expr.span);
+            }
+        }
+
+        // `..` desugars to its struct path.
+        ExprKind::Path(QPath::Resolved(None, ref path)) => {
+            return is_range_path(&path) && is_lit(sm, &expr.span);
+        }
+
+        // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
+        ExprKind::Call(ref func, _) => {
+            if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
+                if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
+                    let new_call = segment.ident.name == sym::new;
+                    return is_range_path(&path) && is_lit(sm, &expr.span) && new_call;
+                }
+            }
+        }
+
+        _ => {}
+    }
+
+    false
+}
+
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ExprKind {
     /// A `box x` expression.
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 8c9279d025d..45b8666c42b 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -3,8 +3,7 @@
 use crate::hir::def_id::DefId;
 use lint::{LateContext, LintArray, LintContext};
 use lint::{LateLintPass, LintPass};
-use rustc::hir::lowering::is_range_literal;
-use rustc::hir::{ExprKind, Node};
+use rustc::hir::{is_range_literal, ExprKind, Node};
 use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx};
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
@@ -266,7 +265,7 @@ fn lint_int_literal<'a, 'tcx>(
         let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
         if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
             if let hir::ExprKind::Struct(..) = par_e.kind {
-                if is_range_literal(cx.sess(), par_e)
+                if is_range_literal(cx.sess().source_map(), par_e)
                     && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
                 {
                     // The overflowing literal lint was overridden.
@@ -318,7 +317,7 @@ fn lint_uint_literal<'a, 'tcx>(
                         return;
                     }
                 }
-                hir::ExprKind::Struct(..) if is_range_literal(cx.sess(), par_e) => {
+                hir::ExprKind::Struct(..) if is_range_literal(cx.sess().source_map(), par_e) => {
                     let t = t.name_str();
                     if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
                         // The overflowing literal lint was overridden.
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 944b4f8fe56..3a25786365b 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -3,9 +3,7 @@ use rustc::infer::InferOk;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 
 use errors::{Applicability, DiagnosticBuilder};
-use rustc::hir;
-use rustc::hir::Node;
-use rustc::hir::{lowering::is_range_literal, print};
+use rustc::hir::{self, is_range_literal, print, Node};
 use rustc::ty::adjustment::AllowTwoPhase;
 use rustc::ty::{self, AssocItem, Ty};
 use syntax::symbol::sym;
@@ -478,7 +476,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             // parenthesize if needed (Issue #46756)
                             hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
                             // parenthesize borrows of range literals (Issue #54505)
-                            _ if is_range_literal(self.tcx.sess, expr) => true,
+                            _ if is_range_literal(self.tcx.sess.source_map(), expr) => true,
                             _ => false,
                         };
                         let sugg_expr = if needs_parens { format!("({})", src) } else { src };