diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-23 15:16:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-23 15:16:28 +0100 |
| commit | 3a07f3ba75d2f0a180be44915df2c929966d39cd (patch) | |
| tree | 93d43e0e112c32e4c15b42d45f1def8acaeb616b /src/librustc | |
| parent | 6f38a15c7b5a57abf024e7e38cb0239e39037e9f (diff) | |
| parent | 4bb83468a202c7402de529199dd363db5f307f33 (diff) | |
| download | rust-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
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/hir/lowering.rs | 62 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 66 |
2 files changed, 64 insertions, 64 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. |
