use std::cmp;
use std::collections::HashMap;
-use std::i16;
-use std::i32;
-use std::i64;
-use std::i8;
-use std::u16;
-use std::u32;
-use std::u64;
-use std::u8;
+use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use std::gc::Gc;
use syntax::abi;
use syntax::ast_map;
"literal out of range for its type");
}
},
-
+ ty::ty_float(t) => {
+ let (min, max) = float_ty_range(t);
+ let lit_val: f64 = match lit.node {
+ ast::LitFloat(ref v, _) |
+ ast::LitFloatUnsuffixed(ref v) => match from_str(v.get()) {
+ Some(f) => f,
+ None => return
+ },
+ _ => fail!()
+ };
+ if lit_val < min || lit_val > max {
+ cx.span_lint(TYPE_OVERFLOW, e.span,
+ "literal out of range for its type");
+ }
+ },
_ => ()
};
},
}
}
+ fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
+ match float_ty {
+ ast::TyF32 => (f32::MIN_VALUE as f64, f32::MAX_VALUE as f64),
+ ast::TyF64 => (f64::MIN_VALUE, f64::MAX_VALUE)
+ }
+ }
+
fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
l: &ast::Expr, r: &ast::Expr) -> bool {
let (lit, expr, swap) = match (&l.node, &r.node) {
def::DefTy(def_id) => {
if !adt::is_ffi_safe(cx.tcx, def_id) {
cx.span_lint(CTYPES, ty.span,
- "found enum type without foreign-function-safe \
- representation annotation in foreign module");
- // hmm... this message could be more helpful
+ "found enum type without foreign-function-safe
+ representation annotation in foreign module, consider \
+ adding a #[repr(...)] attribute to the enumeration");
}
}
_ => ()
if ast_util::is_local(did) {
match cx.tcx.map.get(did.node) {
ast_map::NodeItem(it) => {
- if attr::contains_name(it.attrs.as_slice(),
- "must_use") {
- cx.span_lint(UNUSED_MUST_USE, s.span,
- "unused result which must be used");
- warned = true;
- }
+ warned |= check_must_use(cx, it.attrs.as_slice(), s.span);
}
_ => {}
}
} else {
csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| {
- if attr::contains_name(attrs.as_slice(), "must_use") {
- cx.span_lint(UNUSED_MUST_USE, s.span,
- "unused result which must be used");
- warned = true;
- }
+ warned |= check_must_use(cx, attrs.as_slice(), s.span);
});
}
}
if !warned {
cx.span_lint(UNUSED_RESULT, s.span, "unused result");
}
+
+ fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
+ for attr in attrs.iter() {
+ if attr.check_name("must_use") {
+ let mut msg = "unused result which must be used".to_string();
+ // check for #[must_use="..."]
+ match attr.value_str() {
+ None => {}
+ Some(s) => {
+ msg.push_str(": ");
+ msg.push_str(s.get());
+ }
+ }
+ cx.span_lint(UNUSED_MUST_USE, sp, msg.as_slice());
+ return true;
+ }
+ }
+ false
+ }
}
}
}
}
+ let has_extern_repr = it.attrs.iter().fold(attr::ReprAny, |acc, attr| {
+ attr::find_repr_attr(cx.tcx.sess.diagnostic(), attr, acc)
+ }) == attr::ReprExtern;
+ if has_extern_repr { return }
+
match it.node {
ast::ItemTy(..) | ast::ItemStruct(..) => {
check_case(cx, "type", it.ident, it.span)
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+ // if the expression was produced by a macro expansion,
+ if e.span.expn_info.is_some() { return }
+
let id = match e.node {
ast::ExprPath(..) | ast::ExprStruct(..) => {
match cx.tcx.def_map.borrow().find(&e.id) {
typeck::MethodStatic(def_id) => {
def_id
}
+ typeck::MethodStaticUnboxedClosure(def_id) => {
+ def_id
+ }
typeck::MethodParam(typeck::MethodParam {
trait_id: trait_id,
method_num: index,