Move unsugar_range to utils::higher
This commit is contained in:
@@ -13,7 +13,7 @@ use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::mem;
|
||||
use std::str::FromStr;
|
||||
use syntax::ast::{self, LitKind, RangeLimits};
|
||||
use syntax::ast::{self, LitKind};
|
||||
use syntax::codemap::{ExpnInfo, Span, ExpnFormat};
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::ptr::P;
|
||||
@@ -683,93 +683,6 @@ pub fn camel_case_from(s: &str) -> usize {
|
||||
last_i
|
||||
}
|
||||
|
||||
/// Represent a range akin to `ast::ExprKind::Range`.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct UnsugaredRange<'a> {
|
||||
pub start: Option<&'a Expr>,
|
||||
pub end: Option<&'a Expr>,
|
||||
pub limits: RangeLimits,
|
||||
}
|
||||
|
||||
/// Unsugar a `hir` range.
|
||||
pub fn unsugar_range(expr: &Expr) -> Option<UnsugaredRange> {
|
||||
// To be removed when ranges get stable.
|
||||
fn unwrap_unstable(expr: &Expr) -> &Expr {
|
||||
if let ExprBlock(ref block) = expr.node {
|
||||
if block.rules == BlockCheckMode::PushUnstableBlock || block.rules == BlockCheckMode::PopUnstableBlock {
|
||||
if let Some(ref expr) = block.expr {
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expr
|
||||
}
|
||||
|
||||
fn get_field<'a>(name: &str, fields: &'a [Field]) -> Option<&'a Expr> {
|
||||
let expr = &fields.iter()
|
||||
.find(|field| field.name.node.as_str() == name)
|
||||
.unwrap_or_else(|| panic!("missing {} field for range", name))
|
||||
.expr;
|
||||
|
||||
Some(unwrap_unstable(expr))
|
||||
}
|
||||
|
||||
// The range syntax is expanded to literal paths starting with `core` or `std` depending on
|
||||
// `#[no_std]`. Testing both instead of resolving the paths.
|
||||
|
||||
match unwrap_unstable(expr).node {
|
||||
ExprPath(None, ref path) => {
|
||||
if match_path(path, &paths::RANGE_FULL_STD) || match_path(path, &paths::RANGE_FULL) {
|
||||
Some(UnsugaredRange {
|
||||
start: None,
|
||||
end: None,
|
||||
limits: RangeLimits::HalfOpen,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
ExprStruct(ref path, ref fields, None) => {
|
||||
if match_path(path, &paths::RANGE_FROM_STD) || match_path(path, &paths::RANGE_FROM) {
|
||||
Some(UnsugaredRange {
|
||||
start: get_field("start", fields),
|
||||
end: None,
|
||||
limits: RangeLimits::HalfOpen,
|
||||
})
|
||||
} else if match_path(path, &paths::RANGE_INCLUSIVE_NON_EMPTY_STD) ||
|
||||
match_path(path, &paths::RANGE_INCLUSIVE_NON_EMPTY) {
|
||||
Some(UnsugaredRange {
|
||||
start: get_field("start", fields),
|
||||
end: get_field("end", fields),
|
||||
limits: RangeLimits::Closed,
|
||||
})
|
||||
} else if match_path(path, &paths::RANGE_STD) || match_path(path, &paths::RANGE) {
|
||||
Some(UnsugaredRange {
|
||||
start: get_field("start", fields),
|
||||
end: get_field("end", fields),
|
||||
limits: RangeLimits::HalfOpen,
|
||||
})
|
||||
} else if match_path(path, &paths::RANGE_TO_INCLUSIVE_STD) || match_path(path, &paths::RANGE_TO_INCLUSIVE) {
|
||||
Some(UnsugaredRange {
|
||||
start: None,
|
||||
end: get_field("end", fields),
|
||||
limits: RangeLimits::Closed,
|
||||
})
|
||||
} else if match_path(path, &paths::RANGE_TO_STD) || match_path(path, &paths::RANGE_TO) {
|
||||
Some(UnsugaredRange {
|
||||
start: None,
|
||||
end: get_field("end", fields),
|
||||
limits: RangeLimits::HalfOpen,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience function to get the return type of a function or `None` if the function diverges.
|
||||
pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> Option<ty::Ty<'tcx>> {
|
||||
let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, fn_item);
|
||||
|
||||
Reference in New Issue
Block a user