use rustc::cfg;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty};
-use rustc::traits::{self, Reveal};
+use rustc::traits;
use rustc::hir::map as hir_map;
use util::nodemap::NodeSet;
use lint::{LateContext, LintContext, LintArray};
if def.has_dtor(cx.tcx) {
return;
}
- let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
+ let param_env = ty::ParamEnv::empty();
if !ty.moves_by_default(cx.tcx, param_env, item.span) {
return;
}
}
}
-declare_lint! {
- pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
- Warn,
- "floating-point literals cannot be used in patterns"
-}
-
-/// Checks for floating point literals in patterns.
-#[derive(Clone)]
-pub struct IllegalFloatLiteralPattern;
-
-impl LintPass for IllegalFloatLiteralPattern {
- fn get_lints(&self) -> LintArray {
- lint_array!(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN)
- }
-}
-
-fn fl_lit_check_expr(cx: &EarlyContext, expr: &ast::Expr) {
- use self::ast::{ExprKind, LitKind};
- match expr.node {
- ExprKind::Lit(ref l) => {
- match l.node {
- LitKind::FloatUnsuffixed(..) |
- LitKind::Float(..) => {
- cx.span_lint(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
- l.span,
- "floating-point literals cannot be used in patterns");
- },
- _ => (),
- }
- }
- // These may occur in patterns
- // and can maybe contain float literals
- ExprKind::Unary(_, ref f) => fl_lit_check_expr(cx, f),
- // Other kinds of exprs can't occur in patterns so we don't have to check them
- // (ast_validation will emit an error if they occur)
- _ => (),
- }
-}
-
-impl EarlyLintPass for IllegalFloatLiteralPattern {
- fn check_pat(&mut self, cx: &EarlyContext, pat: &ast::Pat) {
- use self::ast::PatKind;
- pat.walk(&mut |p| {
- match p.node {
- // Wildcard patterns and paths are uninteresting for the lint
- PatKind::Wild |
- PatKind::Path(..) => (),
-
- // The walk logic recurses inside these
- PatKind::Ident(..) |
- PatKind::Struct(..) |
- PatKind::Tuple(..) |
- PatKind::TupleStruct(..) |
- PatKind::Ref(..) |
- PatKind::Box(..) |
- PatKind::Slice(..) => (),
-
- // Extract the expressions and check them
- PatKind::Lit(ref e) => fl_lit_check_expr(cx, e),
- PatKind::Range(ref st, ref en, _) => {
- fl_lit_check_expr(cx, st);
- fl_lit_check_expr(cx, en);
- },
-
- PatKind::Mac(_) => bug!("lint must run post-expansion"),
- }
- true
- });
- }
-}
-
declare_lint! {
pub UNUSED_DOC_COMMENT,
Warn,
pub struct UnreachablePub;
declare_lint! {
- UNREACHABLE_PUB,
+ pub UNREACHABLE_PUB,
Allow,
"`pub` items not reachable from crate root"
}
// visibility is token at start of declaration (can be macro
// variable rather than literal `pub`)
let pub_span = cx.tcx.sess.codemap().span_until_char(def_span, ' ');
- let replacement = if cx.tcx.sess.features.borrow().crate_visibility_modifier {
+ let replacement = if cx.tcx.features().crate_visibility_modifier {
"crate"
} else {
"pub(crate)"
}
}
-impl IgnoredGenericBounds {
- fn ensure_no_param_bounds(
- cx: &EarlyContext,
- generics: &Vec<ast::GenericParam>,
- thing: &'static str,
- ) {
- for param in generics.iter() {
- match param {
- &ast::GenericParam::Lifetime(ref lifetime) => {
- if !lifetime.bounds.is_empty() {
- let spans : Vec<_> = lifetime.bounds.iter().map(|b| b.span).collect();
- cx.span_lint(
- IGNORED_GENERIC_BOUNDS,
- spans,
- format!("bounds on generic lifetime parameters are ignored in {}",
- thing).as_ref()
- );
- }
- }
- &ast::GenericParam::Type(ref ty) => {
- if !ty.bounds.is_empty() {
- let spans : Vec<_> = ty.bounds.iter().map(|b| b.span()).collect();
- cx.span_lint(
- IGNORED_GENERIC_BOUNDS,
- spans,
- format!("bounds on generic type parameters are ignored in {}", thing)
- .as_ref()
- );
- }
- }
- }
- }
- }
-}
-
impl EarlyLintPass for IgnoredGenericBounds {
fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
- match item.node {
- ast::ItemKind::Ty(_, ref generics) => {
- if !generics.where_clause.predicates.is_empty() {
- let spans : Vec<_> = generics.where_clause.predicates.iter()
- .map(|pred| pred.span()).collect();
- cx.span_lint(IGNORED_GENERIC_BOUNDS, spans,
- "where clauses are ignored in type aliases");
- }
- IgnoredGenericBounds::ensure_no_param_bounds(cx, &generics.params,
- "type aliases");
- }
- _ => {}
- }
- }
-
- fn check_where_predicate(&mut self, cx: &EarlyContext, p: &ast::WherePredicate) {
- if let &ast::WherePredicate::BoundPredicate(ref bound_predicate) = p {
- // A type binding, eg `for<'c> Foo: Send+Clone+'c`
- IgnoredGenericBounds::ensure_no_param_bounds(cx,
- &bound_predicate.bound_generic_params, "higher-ranked trait bounds (i.e., `for`)");
+ let type_alias_generics = match item.node {
+ ast::ItemKind::Ty(_, ref generics) => generics,
+ _ => return,
+ };
+ // There must not be a where clause
+ if !type_alias_generics.where_clause.predicates.is_empty() {
+ let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter()
+ .map(|pred| pred.span()).collect();
+ cx.span_lint(IGNORED_GENERIC_BOUNDS, spans,
+ "where clauses are ignored in type aliases");
}
- }
-
- fn check_poly_trait_ref(&mut self, cx: &EarlyContext, t: &ast::PolyTraitRef,
- _: &ast::TraitBoundModifier) {
- IgnoredGenericBounds::ensure_no_param_bounds(cx, &t.bound_generic_params,
- "higher-ranked trait bounds (i.e., `for`)");
- }
-
- fn check_ty(&mut self, cx: &EarlyContext, ty: &ast::Ty) {
- match ty.node {
- ast::TyKind::BareFn(ref fn_ty) => {
- IgnoredGenericBounds::ensure_no_param_bounds(cx, &fn_ty.generic_params,
- "higher-ranked function types (i.e., `for`)");
+ // The parameters must not have bounds
+ for param in type_alias_generics.params.iter() {
+ let spans : Vec<_> = match param {
+ &ast::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(),
+ &ast::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(),
+ };
+ if !spans.is_empty() {
+ cx.span_lint(
+ IGNORED_GENERIC_BOUNDS,
+ spans,
+ "bounds on generic parameters are ignored in type aliases",
+ );
}
- _ => {}
}
}
}